Compare commits
721 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5a3b7e311c | |||
| 991586a880 | |||
| de4165889a | |||
| 42c5ffb014 | |||
| e394615f84 | |||
| 1008ba4229 | |||
| f4328430b9 | |||
| 1d6bc847da | |||
| d76beb09ee | |||
| 026436b914 | |||
| ebc5fd7ee7 | |||
| 82a211753e | |||
| a258e9cb31 | |||
| 157885f71a | |||
| f227a9cba7 | |||
| 39360eefd7 | |||
| 6b5fb15c9b | |||
| 4e698d4049 | |||
| e20bd7fd0c | |||
| 7e62acf351 | |||
| 421bc2eb3b | |||
| db98fa5d5a | |||
| 5f28258d16 | |||
| 8f06488b33 | |||
| ac7ba1b12c | |||
| 67131a1482 | |||
| a92cba8697 | |||
| 52cca7233e | |||
| b2beed0fe0 | |||
| 1f301b6100 | |||
| c74ca4932f | |||
| fafcd67a2c | |||
| 390cc3bd8b | |||
| b2ccda1b34 | |||
| 69916e7756 | |||
| 3a7b6f1343 | |||
| 71a054749c | |||
| 06d87d5c52 | |||
| 6d544f93f4 | |||
| 3c1a7ff1bb | |||
| 73bedf4f55 | |||
| bae8d4651d | |||
| f9127ce64d | |||
| 86338db67d | |||
| 2438d1d23a | |||
| f790736fd7 | |||
| 985b69ae33 | |||
| 6faf5ccde2 | |||
| 2e129d7b06 | |||
| 2b7070e408 | |||
| 571a24b419 | |||
| 5f132ae3d3 | |||
| fe5a09281e | |||
| b66522de33 | |||
| e87ef178c2 | |||
| 0987496caf | |||
| 5ad9c48285 | |||
| ec6eb3e645 | |||
| 64c3363426 | |||
| 2023ba3f7d | |||
| 27c1823a54 | |||
| f111827545 | |||
| 7cdc1ba5a3 | |||
| 1d68a1ee8e | |||
| b426ccc04d | |||
| 6f7b614c3a | |||
| f02f29c543 | |||
| 06cfe1bb96 | |||
| 736353bbac | |||
| f4b3312672 | |||
| 3178bb5f27 | |||
| 552ce70231 | |||
| c2a79b2665 | |||
| f72c949563 | |||
| bdcb00d1bd | |||
| 42fcb1847b | |||
| a7b36280f3 | |||
| cdef3931be | |||
| d3f2587cc2 | |||
| d343f474e4 | |||
| b7fee9696e | |||
| 4f48337f62 | |||
| 96907d5952 | |||
| 3c5d2571fe | |||
| 7005bf43a4 | |||
| 4726cf4d35 | |||
| b971eda771 | |||
| 3ded6fe87d | |||
| 5195c23dfb | |||
| 5f1255a625 | |||
| 82accd45c1 | |||
| e46768b14b | |||
| 32307efd78 | |||
| e84df69f6f | |||
| 669f38a731 | |||
| afef5597b2 | |||
| 4a0bd638fa | |||
| 4bfb38b9d5 | |||
| 0d62cd9bbd | |||
| 913d5f60ca | |||
| 3dddbdf5cd | |||
| 3245f7fe75 | |||
| f144cda136 | |||
| d374e133f0 | |||
| 0c435a646d | |||
| d0ac226753 | |||
| d92344f2bb | |||
| 51c584c6c4 | |||
| 176bbec8a7 | |||
| a508da8b18 | |||
| 91ca84f77a | |||
| d27fdb9904 | |||
| 3b816e2a45 | |||
| 11a46ca58c | |||
| 6e0aec3bec | |||
| 11dd35af44 | |||
| 17fe5f0c9c | |||
| c8e2d88bb7 | |||
| c6ac9fbcf8 | |||
| e636e75b76 | |||
| a01346577f | |||
| 61a5e53351 | |||
| 739c17b4b6 | |||
| 144ef16b0b | |||
| 58c635cb9d | |||
| a39b9a7651 | |||
| 75889983de | |||
| e4a14b629c | |||
| 3640a17632 | |||
| 2a3f809e4e | |||
| d7dd7b9f80 | |||
| cd48e2de3b | |||
| 8f43efe282 | |||
| 025bcbba1d | |||
| d0131deb40 | |||
| 1325f83291 | |||
| 961acdbc76 | |||
| 6789d74abc | |||
| 062c92377e | |||
| 383f4c7abd | |||
| 4cc6161918 | |||
| c0ebbee347 | |||
| e3b4f5bd2d | |||
| 5df3ab6d98 | |||
| 63fb9a638b | |||
| d62d6946c3 | |||
| 7f0237ced4 | |||
| 23621630d5 | |||
| b3abcf73c3 | |||
| 1219e9bd80 | |||
| dced59b9a1 | |||
| 3bf2972089 | |||
| 6dd3ea5cc2 | |||
| 592a92ebdb | |||
| 1321742afe | |||
| f1f93124a0 | |||
| c8e9d1e012 | |||
| 7b0cd0939b | |||
| 3b5ab5089b | |||
| b36d919d8f | |||
| e22a207f03 | |||
| 24dbef52c9 | |||
| 5498b1e25c | |||
| 86851bb67e | |||
| b99e12c56f | |||
| 129b1b919e | |||
| 711c250cfc | |||
| 0f05216474 | |||
| c57b7c95c1 | |||
| 62e041ed8c | |||
| 2983454ce2 | |||
| 6d5046cb6d | |||
| 91fcf43da9 | |||
| aef1a57e1c | |||
| 71316bac6a | |||
| f1c4f06461 | |||
| 412bbd2a8b | |||
| be64cedfc3 | |||
| 2a6b35d658 | |||
| f51c5c36d0 | |||
| 5599901185 | |||
| fb235bf985 | |||
| 717d7a3fe3 | |||
| c91f468dce | |||
| 1f36657efd | |||
| b70ad5c808 | |||
| da56ef91fd | |||
| 9bd7a152d7 | |||
| 5c287d49bb | |||
| 942f15b49d | |||
| 20b61cda42 | |||
| b1b1d6d434 | |||
| c7ad32ef30 | |||
| 6016db837e | |||
| 2051e0b5d9 | |||
| fddb3f5707 | |||
| 096dd84511 | |||
| e16a2078fc | |||
| e388ae34e3 | |||
| b64c747082 | |||
| 8afa3ae47d | |||
| 1eba68e95b | |||
| 047b339006 | |||
| acd7415835 | |||
| a48460ef76 | |||
| 8ab3896e3a | |||
| 2d481c8a71 | |||
| 7968a4e5ed | |||
| 39d295f412 | |||
| 0bf2cc2a77 | |||
| 433f486091 | |||
| fee6604d5e | |||
| c339fced5c | |||
| a87351778d | |||
| 42687457e0 | |||
| 4a541402da | |||
| ecef487746 | |||
| df483b5623 | |||
| e4d3f5f9a4 | |||
| 02e164dcdf | |||
| ead94e7915 | |||
| dfc3c29439 | |||
| ab538f4bf7 | |||
| 00b6f8583a | |||
| 4cf4a99107 | |||
| 137289e843 | |||
| e7b066e75e | |||
| cd0828f3e0 | |||
| 563697f840 | |||
| 61fc814528 | |||
| 7c90dbabea | |||
| 5ee0f3c373 | |||
| 098bdd0076 | |||
| 40b6da6b44 | |||
| b083dabc6b | |||
| 7fcc3ed42d | |||
| 4ed362f226 | |||
| 39d98f79fb | |||
| c79f7ba245 | |||
| 16354ff435 | |||
| f3a191dd62 | |||
| cb0a5092fb | |||
| 8730f55308 | |||
| 932e98d19c | |||
| 3a69dcfa79 | |||
| 5930674d4a | |||
| df6b20d97f | |||
| 4200af5296 | |||
| b0c9c5be2e | |||
| f2bb1deac4 | |||
| 94ec83aa60 | |||
| e183eec3ea | |||
| b179771ec9 | |||
| d7380a09c1 | |||
| afc316cd1d | |||
| b6f820258a | |||
| 116b605cb1 | |||
| 9f5ce42393 | |||
| 9716d93c15 | |||
| 3465179379 | |||
| c7aad8d917 | |||
| 8ddc1c70e1 | |||
| 5230261be8 | |||
| 8cc8d6eb03 | |||
| 7a95e4c5a3 | |||
| 1c0f182bbc | |||
| 736e20e599 | |||
| c71c8e8c12 | |||
| 9c7a29f939 | |||
| 40bb15e46b | |||
| fb957b61d2 | |||
| 4da9dcb062 | |||
| 60f9302c3f | |||
| 2553f15e7b | |||
| e8d31f2020 | |||
| 4c693ccd60 | |||
| c550fb1848 | |||
| e49bd5a2a0 | |||
| 81be6ce7b9 | |||
| 2d6bf3d9dc | |||
| b2244b7f43 | |||
| 53dcd9c863 | |||
| 75f70d2b30 | |||
| 36b1df1a27 | |||
| 5a445c5c0b | |||
| df828ab2ba | |||
| db855ca99b | |||
| d79cb50aca | |||
| 371ff54d9c | |||
| df7b4ff81f | |||
| f22ea484db | |||
| 574041cf18 | |||
| ff2cc4f999 | |||
| 05c0b0a18b | |||
| 1b9738eace | |||
| 8ee5bc74d5 | |||
| 0a8cc414a5 | |||
| 7a682653cd | |||
| 9286ab6535 | |||
| 85736ab03f | |||
| 673f5c7a9b | |||
| 34d0bcbdfe | |||
| 7abf3027d4 | |||
| ffe3d44cac | |||
| dd23b848ac | |||
| 33cca03698 | |||
| d4d14dd866 | |||
| d6f0fdac50 | |||
| 080605510c | |||
| 1a7b789ef3 | |||
| cc4183a677 | |||
| c2bae56656 | |||
| 38a5c0cbb3 | |||
| 81a8eb698e | |||
| ee4bb7d7c4 | |||
| 8b0d5bddbf | |||
| ba75033f0a | |||
| eb2b90c6f2 | |||
| 3b5c34cb05 | |||
| 2fe22a62c2 | |||
| ff6307fcca | |||
| c6e80a0b6a | |||
| b957cc75be | |||
| fc18539472 | |||
| de7229aee7 | |||
| 53e66032a0 | |||
| 2fc6c30c8f | |||
| f05c5f1261 | |||
| 6af5591cf6 | |||
| 41cbe862e5 | |||
| 057b8273e2 | |||
| 6421c12408 | |||
| 0aca5aeb07 | |||
| bdbd3583b8 | |||
| 626d5b0e51 | |||
| 0bffa0039c | |||
| 9819c8cee8 | |||
| 53ab676750 | |||
| afa4872c97 | |||
| bf56d53faf | |||
| f03adb9206 | |||
| 529fa2e4a0 | |||
| 6df1b90e95 | |||
| 9cba0e6d15 | |||
| f16de3a20c | |||
| 8cfa41d09f | |||
| b59b501366 | |||
| 504bb50b13 | |||
| 969f1266e7 | |||
| fa680b7799 | |||
| e185c85d5e | |||
| acb0a5bd5e | |||
| 62ce576d4d | |||
| 161d3d9b17 | |||
| d88baa070f | |||
| 2b087dde51 | |||
| 7894a8fdc8 | |||
| 0f14e8335a | |||
| 7edf4bced8 | |||
| 4a5639780b | |||
| 0a21a582be | |||
| 0e663c02c4 | |||
| 21afe8165c | |||
| 0247fe5e7c | |||
| 50bad83fba | |||
| 9c93d6c2f3 | |||
| 4d9a50cf94 | |||
| bbdaac5d8d | |||
| 0417c43bcf | |||
| 15585b8f11 | |||
| 59755ec8a5 | |||
| b16dd260d8 | |||
| d37a5a37b7 | |||
| 79dfb4ae87 | |||
| 8b75b6e4c3 | |||
| bcaad08b61 | |||
| cbdeffd93a | |||
| 0ce477a3e7 | |||
| 44eb4d1834 | |||
| 2e26b73208 | |||
| de3fa3201e | |||
| f068aafbb5 | |||
| daedb07135 | |||
| 702e1e446d | |||
| ea87db1ae1 | |||
| b65800843a | |||
| e4c5d8645d | |||
| 85b06c29b4 | |||
| 5254d0c5ca | |||
| 292c2bf87a | |||
| 9d038142a8 | |||
| c5573e438b | |||
| 8c7a0ac026 | |||
| e45bbf2afd | |||
| fc6de68d83 | |||
| a008c169ae | |||
| 3cd6c9299f | |||
| 8e5801d656 | |||
| 1691b7f84a | |||
| 76e4197729 | |||
| fb8bac8681 | |||
| 55a9685add | |||
| afa4be3717 | |||
| 57c03a54c9 | |||
| 91a9adaea4 | |||
| 8657fa32c5 | |||
| b7a4f0bff3 | |||
| f0716e2727 | |||
| b1acf7f4f0 | |||
| 851c053f7c | |||
| 71276a8de3 | |||
| b2e799e1d6 | |||
| eb9aaef53a | |||
| 49340d2629 | |||
| 0b9c9f375c | |||
| cd56f80790 | |||
| 65d826168b | |||
| ea012988df | |||
| 67f3df353f | |||
| 9d34df708d | |||
| 72947f1e36 | |||
| 1cdae73b24 | |||
| a2825b2b6d | |||
| 5bc7036e98 | |||
| 7e545aecd7 | |||
| 0fc8291ef5 | |||
| 0d668c1a4a | |||
| 4b1270f231 | |||
| 9263dc0516 | |||
| b0f7cb93fd | |||
| add3788db4 | |||
| 37c23faae3 | |||
| fa6f12ba3b | |||
| 730dd396f4 | |||
| 3b9f6773f2 | |||
| 97315f6ca4 | |||
| b2be420e36 | |||
| 4ee34b79f8 | |||
| e4ee403d24 | |||
| b709776f5f | |||
| b5a2490fd4 | |||
| 7a18cd1c5c | |||
| 26e1448bbb | |||
| a1ebdb4eb6 | |||
| 6603061f81 | |||
| 1c3d7bf2a6 | |||
| a4a030b776 | |||
| 64a8294ea0 | |||
| 847383d82d | |||
| c16d916a63 | |||
| 91cae44533 | |||
| 56c3e28ac3 | |||
| 3238c86cec | |||
| f050e682ef | |||
| 01c875b34f | |||
| 50b8a8aa94 | |||
| 9f1aad5e49 | |||
| a38c50197b | |||
| fe54dde44e | |||
| 62a3405d6a | |||
| cb9dd807ce | |||
| d60d38a24b | |||
| e598e7986f | |||
| 9bebd2f2ad | |||
| 36d5c39094 | |||
| 1b08f4bbdd | |||
| 4a952b1c9b | |||
| 7a25927054 | |||
| cf022921a7 | |||
| dc798aaaba | |||
| eed89dab37 | |||
| 990bc1a1e4 | |||
| 03433fe3af | |||
| e02611504b | |||
| a835433be4 | |||
| da8f40db17 | |||
| 5468e3f4fa | |||
| 88684e305f | |||
| f8ca8029d7 | |||
| aa9c46cbb5 | |||
| f0cf3c9559 | |||
| 9a638b9470 | |||
| b07fbfc72e | |||
| 0317c37557 | |||
| a98b6bcc09 | |||
| c19861a911 | |||
| 8f8597d442 | |||
| 0c0eb9ef8f | |||
| 4ffb7087bd | |||
| dc070c4556 | |||
| 60729d5f39 | |||
| da7e9dd6e2 | |||
| aeff9fb418 | |||
| e9e897593b | |||
| bfc09d135c | |||
| 0998d0fffc | |||
| 93c87ee720 | |||
| a67a0502fa | |||
| cec0a48be4 | |||
| 0cc63d40eb | |||
| 623eb6e630 | |||
| 1f22299096 | |||
| 3f6c439983 | |||
| 8e22267476 | |||
| aa2b6ccde5 | |||
| ec6cb79a8d | |||
| 76dceb4fc9 | |||
| b1564f7de0 | |||
| 21e4bd6d93 | |||
| 2101d72abe | |||
| 7a01f67c8b | |||
| 2267343afe | |||
| 9a5fe24781 | |||
| 4050aa11c5 | |||
| b75ddae396 | |||
| 2d3f8487ee | |||
| 964647d7e6 | |||
| f78dd0fa83 | |||
| 55ce22b06c | |||
| 50df4f3503 | |||
| 5c8f0c79f6 | |||
| de3f187ddf | |||
| f649954ee1 | |||
| 6e08f2a878 | |||
| 887922a715 | |||
| 640fef2e0a | |||
| 1a338a1a82 | |||
| 4f3fe68283 | |||
| 3908e11d18 | |||
| 4e6c5112e4 | |||
| e1ab88302f | |||
| 2b4090619b | |||
| b90289e42b | |||
| 5e84408685 | |||
| b53c2f833a | |||
| b5fcceaa75 | |||
| f0bfbb6c85 | |||
| 2710f735d1 | |||
| ddffbd2c88 | |||
| fde952499d | |||
| b28102a8cc | |||
| f46db233dc | |||
| df10b45c6b | |||
| 1b13580340 | |||
| 742305b99b | |||
| 1261de4dbb | |||
| b50588f974 | |||
| 9b87de9fa2 | |||
| 5bab4a9aa8 | |||
| c3e7d3d8c7 | |||
| 89c22ffd06 | |||
| 5375752609 | |||
| 0a8f26c993 | |||
| cba9c253e1 | |||
| 71f3bf8809 | |||
| d491536eb4 | |||
| e68465c80b | |||
| dfb8fd2160 | |||
| 746fa61e08 | |||
| d0e0c46e2c | |||
| 19c7f63303 | |||
| 87f6a29db3 | |||
| b04d1ed7a9 | |||
| 54dba7ab41 | |||
| 146c06d27f | |||
| 7c45c1e287 | |||
| d6dc5b8428 | |||
| 28695f9138 | |||
| 66cec4a872 | |||
| 8d1d3f766a | |||
| befed079c8 | |||
| b9138029db | |||
| 2246dbc284 | |||
| 67180b3569 | |||
| 3a2aa2c679 | |||
| 9dd4e043d4 | |||
| 4748bd5ac8 | |||
| 649f97e933 | |||
| 21feed172d | |||
| e853ff7f13 | |||
| 95ff8b21b9 | |||
| a7be952e11 | |||
| 7a67ce9333 | |||
| 695350d3f6 | |||
| aade1d19f1 | |||
| fd4677d099 | |||
| f7a28447fb | |||
| 79b470b18b | |||
| f6d3873ecb | |||
| 92a8cdad99 | |||
| 0c346e2bc7 | |||
| d54caf4ae3 | |||
| ff9ea34ae1 | |||
| c7035305e2 | |||
| bc3c1e377e | |||
| 98eff1b0b9 | |||
| 052cc9e841 | |||
| b6a7ce4eef | |||
| 7a66ad27d8 | |||
| b4878f1ac0 | |||
| 447ebe11e5 | |||
| 8981057d29 | |||
| 3270b573a8 | |||
| 6df0cf3203 | |||
| d67cca385e | |||
| f9d67442d6 | |||
| dea96ccbcc | |||
| 0f4be10330 | |||
| 121abf5864 | |||
| 38e836de2b | |||
| 376c4e3693 | |||
| 48ffd52b16 | |||
| 9a16259ff5 | |||
| 10ae269882 | |||
| 9d845179a4 | |||
| 88bf84cca1 | |||
| 5ba8f1df36 | |||
| c4a05bcb2f | |||
| 5841c9cae0 | |||
| 4fd03a78de | |||
| 420c072670 | |||
| 36477623b8 | |||
| 84d859dfe2 | |||
| 09220bfd68 | |||
| 42aaf6f3eb | |||
| 3f1f365451 | |||
| 9a29ee0e27 | |||
| 619905d720 | |||
| 36ce855ef3 | |||
| 9b0f2c7f59 | |||
| c637ccec47 | |||
| 8f27154604 | |||
| 5d02732db6 | |||
| 36657e17c4 | |||
| e2008bd479 | |||
| e32b85bc2d | |||
| 6dfc50e630 | |||
| b4820ff255 | |||
| 515247a394 | |||
| b5c649821f | |||
| 9ba0c6f4cc | |||
| 35fc94d8cb | |||
| a0316e280c | |||
| 84bcc715a8 | |||
| b34d31029b | |||
| f67865f9cc | |||
| f48053a541 | |||
| 8e917aa6d2 | |||
| f08dee836b | |||
| 261e9ac0c8 | |||
| b51d0c3e64 | |||
| ac23938dd0 | |||
| b9bac347e8 | |||
| 980a1f62df | |||
| 10c5d0fffe | |||
| d7d36b670a | |||
| 581551ee3e | |||
| 487ce0c84b | |||
| 5679733028 | |||
| cd0fc4e449 | |||
| e20b4b5b78 | |||
| b931582120 | |||
| bf14ab1332 | |||
| 3b81a6b92e | |||
| 01bf44cf1e | |||
| b5d879cd3d | |||
| 2b3c285190 | |||
| 99bb83211c | |||
| b854c9588b | |||
| 2361225321 | |||
| eaf1138624 | |||
| ef5c67a4d5 | |||
| 3e924113d3 | |||
| dcc3fc772a | |||
| a48f373e4d | |||
| ffd714d069 | |||
| dc082d495e | |||
| e8e57ff793 | |||
| 3e16c4b56c | |||
| 77d3fcc7af | |||
| 7322bf5034 | |||
| 2ed2a34d55 | |||
| d340505593 | |||
| 247849d112 | |||
| fcbdee1dba | |||
| 33d1ef4123 | |||
| fe2aba43e5 | |||
| c0b5f38301 | |||
| 1c157f323e | |||
| 3e6aa0d81b | |||
| 34089648b0 | |||
| 0bef1638d0 | |||
| 1d4bccac4b | |||
| cc7aa66904 | |||
| 303a270359 | |||
| 17759877d4 | |||
| 5f56152a8b | |||
| d6567e94c4 | |||
| d00064a671 | |||
| dc91f932f7 | |||
| a3f05c41fe | |||
| d911862c84 | |||
| 1b025ec60e | |||
| 9d18e1a9ba | |||
| 3143c00729 | |||
| 3a8900983a | |||
| 971a76e473 | |||
| 621bf93ee9 | |||
| 35c019a03e | |||
| de97f249a2 | |||
| 81f0cc23bf | |||
| 8a0234093e | |||
| 88d355f2f7 | |||
| 20fd06d67c | |||
| 52f2785e67 | |||
| 2e2bd0ceec | |||
| e4c3c9a2a4 | |||
| 1160e3d067 | |||
| 91d667bcfc | |||
| 3dd9466938 | |||
| 76e2843ed3 |
@@ -317,6 +317,8 @@ AdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst, bool bNeedSameProp)
|
||||
pCrvCo->RemoveSmallDefects( 2 * LIN_TOL_MIN, ANG_TOL_STD_DEG, true) ;
|
||||
// unisco eventuali tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bNeedSameProp) ;
|
||||
// richiudo i loop per sicurezza
|
||||
pCrvCo->Close() ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkArcPntDirTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
+2
-1
@@ -134,7 +134,8 @@ GetArc3P( const Point3d& ptStart, const Point3d& ptOther, const Point3d& ptEnd,
|
||||
|
||||
// calcolo arco non riuscito, se i punti sono allineati nel giusto verso per essere una retta
|
||||
// verifico se i punti sono allineati nel giusto verso
|
||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO) {
|
||||
if ( ( ptOther - ptStart) * ( ptEnd - ptOther) > EPS_ZERO ||
|
||||
AreSamePointApprox( ptOther, ptStart) || AreSamePointApprox( ptEnd, ptOther)) {
|
||||
// creo l'oggetto retta
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
if ( IsNull( pLine))
|
||||
|
||||
+8
-8
@@ -133,22 +133,22 @@ Attribs::Load( NgeReader& ngeIn)
|
||||
unsigned char ucLev ;
|
||||
if ( ! ngeIn.ReadUchar( ucLev, ","))
|
||||
return false ;
|
||||
m_Data[LEVEL] = CLIP( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
m_Data[LEVEL] = Clamp( ucLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
// modo
|
||||
unsigned char ucMode ;
|
||||
if ( ! ngeIn.ReadUchar( ucMode, ","))
|
||||
return false ;
|
||||
m_Data[MODE] = CLIP( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
m_Data[MODE] = Clamp( ucMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
// stato (se SEL è convertito in ON)
|
||||
unsigned char ucStat ;
|
||||
if ( ! ngeIn.ReadUchar( ucStat, ","))
|
||||
return false ;
|
||||
m_Data[STATUS] = CLIP( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
m_Data[STATUS] = Clamp( ucStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
// marcatura (sempre OFF)
|
||||
unsigned char ucMark ;
|
||||
if ( ! ngeIn.ReadUchar( ucMark, ";"))
|
||||
return false ;
|
||||
m_Data[MARK] = CLIP( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
m_Data[MARK] = Clamp( ucMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
// materiale
|
||||
if ( ! ngeIn.ReadInt( m_Material, ";"))
|
||||
return false ;
|
||||
@@ -185,22 +185,22 @@ Attribs::DataFromString( const string& sParam)
|
||||
int nLev ;
|
||||
if ( ! FromString( vsParams[0], nLev))
|
||||
return false ;
|
||||
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ;
|
||||
// modo
|
||||
int nMode ;
|
||||
if ( ! FromString( vsParams[1], nMode))
|
||||
return false ;
|
||||
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ;
|
||||
// stato (ammessi solo OFF e ON)
|
||||
int nStat ;
|
||||
if ( ! FromString( vsParams[2], nStat))
|
||||
return false ;
|
||||
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_ON) ;
|
||||
// marcatura (ammesso solo OFF)
|
||||
int nMark ;
|
||||
if ( ! FromString( vsParams[3], nMark))
|
||||
return false ;
|
||||
m_Data[MARK] = CLIP( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_OFF) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -16,14 +16,12 @@
|
||||
#include "/EgtDev/Include/EGkGdbConst.h"
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
#include "/EgtDev/Include/EgtStringBase.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
|
||||
class NgeWriter ;
|
||||
class NgeReader ;
|
||||
class GeomDB ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
#define CLIP( nV, nMIN, nMAX) (( nV < nMIN) ? nMIN : (( nV > nMAX) ? nMAX : nV))
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class Attribs
|
||||
{
|
||||
@@ -46,14 +44,14 @@ class Attribs
|
||||
bool Load( NgeReader& ngeIn) ;
|
||||
void SetLevel( int nLev)
|
||||
{ m_OldData[LEVEL] = m_Data[LEVEL] ;
|
||||
m_Data[LEVEL] = CLIP( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
||||
m_Data[LEVEL] = Clamp( nLev, GDB_LV_USER, GDB_LV_TEMP) ; }
|
||||
void RevertLevel( void)
|
||||
{ std::swap( m_Data[LEVEL], m_OldData[LEVEL]) ; }
|
||||
int GetLevel( void) const
|
||||
{ return m_Data[LEVEL] ; }
|
||||
void SetMode( int nMode)
|
||||
{ m_OldData[MODE] = m_Data[MODE] ;
|
||||
m_Data[MODE] = CLIP( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
||||
m_Data[MODE] = Clamp( nMode, GDB_MD_STD, GDB_MD_HIDDEN) ; }
|
||||
void RevertMode( void)
|
||||
{ std::swap( m_Data[MODE], m_OldData[MODE]) ; }
|
||||
int GetMode( void) const
|
||||
@@ -61,13 +59,13 @@ class Attribs
|
||||
void SetStatus( int nStat)
|
||||
{ if ( m_Data[STATUS] != GDB_ST_SEL)
|
||||
m_OldData[STATUS] = m_Data[STATUS] ;
|
||||
m_Data[STATUS] = CLIP( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
||||
m_Data[STATUS] = Clamp( nStat, GDB_ST_OFF, GDB_ST_SEL) ; }
|
||||
void RevertStatus( void)
|
||||
{ SetStatus( m_OldData[STATUS]) ; }
|
||||
int GetStatus( void) const
|
||||
{ return m_Data[STATUS] ; }
|
||||
void SetMark( void)
|
||||
{ m_Data[MARK] = GDB_MK_ON ; }
|
||||
void SetMark( int nMark)
|
||||
{ m_Data[MARK] = Clamp( nMark, GDB_MK_OFF, GDB_MK_ON_2) ; }
|
||||
void ResetMark( void)
|
||||
{ m_Data[MARK] = GDB_MK_OFF ; }
|
||||
int GetMark( void) const
|
||||
|
||||
+9
-6
@@ -83,7 +83,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
//----------------------------------------------------------------------------
|
||||
ICurve*
|
||||
GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||
const PolyLine& PL, double& dDist)
|
||||
const PolyLine& PL, double& dDist, double dTol)
|
||||
{
|
||||
// calcolo la curva dove giacciono i punti di giunzione tra i due archi del biarco
|
||||
PtrOwner<ICurve> pJCrv( CalcJCurve( ptP0, dDir0Deg, ptP1, dDir1Deg)) ;
|
||||
@@ -122,7 +122,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
}
|
||||
}
|
||||
}
|
||||
// non c'è intersezione, assegno valore medio
|
||||
// non c'è intersezione, assegno valore medio
|
||||
if ( dU < -0.5)
|
||||
dU = 0.5 ;
|
||||
// elimino casi vicino agli estremi, danno solo problemi
|
||||
@@ -142,7 +142,10 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
Point3d ptPrev = ptCurr ;
|
||||
while ( bPnt) {
|
||||
double dLen = Dist( ptCurr, ptPrev) ;
|
||||
int nStep = ( dLen < STEP ? 2 : 1) * int( dLen / STEP) + 1 ;
|
||||
int nStep = int( dLen / STEP) + 1 ;
|
||||
int nMinStep = ( dLen > 50 * dTol ? 3 : ( dLen > 10 * dTol ? 2 : 1)) ;
|
||||
int nMaxStep = 10 ;
|
||||
nStep = Clamp( nStep, nMinStep, nMaxStep) ;
|
||||
for ( int i = 1 ; i <= nStep ; ++ i) {
|
||||
double dCoeff = double( i) / nStep ;
|
||||
Point3d ptP = Media( ptPrev, ptCurr, dCoeff) ;
|
||||
@@ -163,7 +166,7 @@ GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir
|
||||
static ICurve*
|
||||
CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg)
|
||||
{
|
||||
// se i due punti coincidono, non si può fare alcunché
|
||||
// se i due punti coincidono, non si può fare alcunché
|
||||
if ( AreSamePointApprox( ptP0, ptP1))
|
||||
return nullptr ;
|
||||
|
||||
@@ -205,14 +208,14 @@ CalcJCurve( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dD
|
||||
double dDir0RelDeg = DiffAngle( dDir0Deg, dDirDiffDeg) ;
|
||||
// direzione iniziale secondo arco limite rispetto a direzione P0->P1 (dalla finale simmetrico e invert)
|
||||
double dDir1RelDeg = - DiffAngle( dDir1Deg, dDirDiffDeg) ;
|
||||
// nel caso di direzioni a 180deg si sceglie la più compatta
|
||||
// nel caso di direzioni a 180deg si sceglie la più compatta
|
||||
if ( abs( abs( dDir1RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
||||
dDir1RelDeg = ( dDir0RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||
else if ( abs( abs( dDir0RelDeg) - ANG_STRAIGHT) < EPS_SMALL)
|
||||
dDir0RelDeg = ( dDir1RelDeg > 0 ? ANG_STRAIGHT : - ANG_STRAIGHT) ;
|
||||
// intervallo angolare ammissibile a partire da direzione iniziale primo arco ammissibile ( == Dir0)
|
||||
double dDeltaAngDeg = - dDir0RelDeg + dDir1RelDeg ;
|
||||
// se non è nella regione, prendo l'altra parte di arco
|
||||
// se non è nella regione, prendo l'altra parte di arco
|
||||
if ( ! AngleInSpan( dDirStartRelDeg, dDir0RelDeg, dDeltaAngDeg))
|
||||
pArc->ToExplementary() ;
|
||||
// inverto per avere parametrizzazione crescente allontanandosi da Dir0 e avvicinandosi a Dir1
|
||||
|
||||
@@ -17,5 +17,5 @@
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
ICurve* GetBiArc( const Point3d& ptP0, double dDir0Deg, const Point3d& ptP1, double dDir1Deg,
|
||||
const PolyLine& PL, double& dDist) ;
|
||||
const PolyLine& PL, double& dDist, double dTol) ;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2024-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CAvSilhouetteSurfTm.h Data : 16.06.24 Versione : 2.6f2
|
||||
// Contenuto : Dichiarazione della classe calcolo multi-silhouette.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 10.06.24 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CAvToolSurfTm.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkCAvSilhouetteSurfTm.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CAvParSilhouettesSurfTm : public ICAvParSilhouettesSurfTm
|
||||
{
|
||||
public :
|
||||
// generica
|
||||
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol) override ;
|
||||
bool SetData( const CISURFTMPVECTOR& vpStm, const Frame3d& frPlanes, double dTol,
|
||||
double dSideAng, double dDiam, double dCornRad, double dMaxMat, double dOffsR,
|
||||
double dMaxDepth) override ;
|
||||
bool GetSilhouette( double dLevel, POLYLINEVECTOR& vPL) override ;
|
||||
|
||||
public :
|
||||
CAvParSilhouettesSurfTm( void) ;
|
||||
|
||||
private :
|
||||
bool Prepare( void) ;
|
||||
|
||||
private :
|
||||
CISURFTMPVECTOR m_vpStm ;
|
||||
CAvToolSurfTm m_cavTstm ;
|
||||
Frame3d m_frGrid ;
|
||||
double m_dTol ;
|
||||
double m_dSharpedTol ;
|
||||
int m_nStepX ;
|
||||
int m_nStepY ;
|
||||
double m_dRad ;
|
||||
double m_dCornRad ;
|
||||
double m_dMaxMat ;
|
||||
double m_dSideAng ;
|
||||
double m_dOffsR ;
|
||||
double m_dDimZ ;
|
||||
double m_dLevelOffs ;
|
||||
double m_dMaxDepth ;
|
||||
bool m_bGridOk ;
|
||||
bool m_bTool ;
|
||||
DBLVECTOR m_vdGrid ;
|
||||
} ;
|
||||
+520
-55
@@ -1,21 +1,21 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2018-2018
|
||||
// EgalTech 2018-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CAvToolSurfTm.cpp Data : 08.05.18 Versione : 1.9e2
|
||||
// File : CAvToolSurfTm.cpp Data : 07.06.24 Versione : 2.6f2
|
||||
// Contenuto : Implementazione della classe CAvToolSurfTm.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 27.04.18 DS Creazione modulo.
|
||||
//
|
||||
// 07.06.24 DS Con tolleranza lineare negativa non si controlla il punto medio.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CAvToolTriangle.h"
|
||||
#include "CAvToolSurfTm.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include <thread>
|
||||
#include <future>
|
||||
@@ -24,6 +24,7 @@ using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
const int STEP_PE = 50 ;
|
||||
const double MAX_MOVE = 20000 ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
ICAvToolSurfTm*
|
||||
@@ -37,10 +38,29 @@ CreateCAvToolSurfTm( void)
|
||||
// CAvToolSurfTm
|
||||
//----------------------------------------------------------------------------
|
||||
CAvToolSurfTm::CAvToolSurfTm( void)
|
||||
: m_Tool( false)
|
||||
: m_frMove( false), m_Tool( false)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::Clear( void)
|
||||
{
|
||||
// pulisco la lista dei puntatori a Stm
|
||||
m_vSTM.clear() ;
|
||||
// pulisco e inizializzo la prima posizione della lista delle basi per gli indici dei triangoli
|
||||
m_vBaseInd.clear() ;
|
||||
m_vBaseInd.emplace_back( 0) ;
|
||||
// pulisco HashGrid 2d
|
||||
m_HGrids.Clear() ;
|
||||
// reset utensile
|
||||
m_Tool.Clear() ;
|
||||
// reset riferimento
|
||||
m_frMove.Reset( false) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||
@@ -50,6 +70,9 @@ CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||
// pulisco e inizializzo la prima posizione della lista delle basi per gli indici dei triangoli
|
||||
m_vBaseInd.clear() ;
|
||||
m_vBaseInd.emplace_back( 0) ;
|
||||
// pulisco HashGrid 2d
|
||||
m_HGrids.Clear() ;
|
||||
// non tocco l'utensile
|
||||
// aggiungo la superficie
|
||||
return AddSurfTm( Stm) ;
|
||||
}
|
||||
@@ -58,7 +81,7 @@ CAvToolSurfTm::SetSurfTm( const ISurfTriMesh& Stm)
|
||||
bool
|
||||
CAvToolSurfTm::AddSurfTm( const ISurfTriMesh& Stm)
|
||||
{
|
||||
// verifico validità superficie
|
||||
// verifico validità superficie
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &Stm) ;
|
||||
if ( pStm == nullptr || ! pStm->IsValid())
|
||||
return false ;
|
||||
@@ -99,7 +122,8 @@ CAvToolSurfTm::SetGenTool( const ICurveComposite* pToolOutline)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist)
|
||||
CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, Vector3d* pvtTriaN) const
|
||||
{
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
@@ -107,20 +131,78 @@ CAvToolSurfTm::TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Ve
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Imposto il riferimento di movimento
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
m_frMove.Set( ORIG, vtMove) ;
|
||||
// Eseguo controllo
|
||||
// Se riferimento di movimento già presente
|
||||
if ( m_frMove.IsValid()) {
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d
|
||||
if ( AreSameFrame( frMove, m_frMove)) {
|
||||
// Eseguo controllo
|
||||
Point3d ptCurr = ptT ;
|
||||
Vector3d vtTriaN ;
|
||||
dTotDist = MyTestPositionHG( ptCurr, vtDir, vtTriaN) ;
|
||||
if ( pvtTriaN != nullptr)
|
||||
*pvtTriaN = vtTriaN ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
// Altrimenti eseguo controllo diretto
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPosition( ptCurr, vtDir) ;
|
||||
Vector3d vtTriaN ;
|
||||
dTotDist = MyTestPosition( ptCurr, vtDir, vtMove, vtTriaN) ;
|
||||
if ( pvtTriaN != nullptr)
|
||||
*pvtTriaN = vtTriaN ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol)
|
||||
CAvToolSurfTm::TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, VCT3DVECTOR& vVtN) const
|
||||
{
|
||||
// Funzione per calcolo collisione tra utensile e superfici ;
|
||||
// dToTDist è la distanza di traslazione del punto ptT lungo vtDir per evitare la collisione,
|
||||
// vVtN è la normale del triangolo che genera collsione ( NB. Nel caso di più triangoli concorrenti,
|
||||
// vengono restituite tutte le normali trovate)
|
||||
|
||||
// Inizializzazione parametri
|
||||
dTotDist = 0 ;
|
||||
vVtN.clear() ;
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se riferimento di movimento già presente
|
||||
if ( m_frMove.IsValid()) {
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimenti di movimento uguali, sfrutto HashGrid 2d
|
||||
if ( AreSameFrame( frMove, m_frMove)) {
|
||||
// Eseguo controllo
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPositionHGAdv( ptCurr, vtDir, vVtN) ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
}
|
||||
// Altrimenti eseguo controllo diretto
|
||||
Point3d ptCurr = ptT ;
|
||||
dTotDist = MyTestPositionAdv( ptCurr, vtDir, vtMove, vVtN) ;
|
||||
return ( dTotDist > - EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff)
|
||||
{
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
@@ -128,17 +210,139 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
||||
// Salvo nuovo riferimento
|
||||
m_frMove = frMove ;
|
||||
// Ricalcolo HashGrid
|
||||
if ( ! PrepareHashGrid())
|
||||
return false ;
|
||||
}
|
||||
// Determino il numero di punti dell'insieme
|
||||
m_nTotPnt = int( vPntM.size()) ;
|
||||
// Recupero il numero massimo di thread concorrenti
|
||||
int nThreadMax = thread::hardware_concurrency() ;
|
||||
bool bOk = true ;
|
||||
// Se un solo thread o pochi punti
|
||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||
m_nCurrPnt = 0 ;
|
||||
bOk = TestSubSeries( -1, vPntM, vtDir, 0, m_nTotPnt - 1, dProgCoeff) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
const int MAX_PARTS = 32 ;
|
||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||
// calcolo le parti del vettore
|
||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||
int nPartDim = m_nTotPnt / nPartCnt + 1 ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
vFstLst[i].first = i * nPartDim ;
|
||||
vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
|
||||
}
|
||||
// processo le parti
|
||||
m_nCurrPnt = 0 ;
|
||||
m_bBreak = false ;
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubSeries, this, i, ref( vPntM), cref( vtDir), vFstLst[i].first, vFstLst[i].second, dProgCoeff) ;
|
||||
// attendo i risultati
|
||||
int nFin = 0 ;
|
||||
int nNextPE = 0 ;
|
||||
while ( nFin < nPartCnt) {
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
||||
bOk = vRes[i].get() && bOk ;
|
||||
++ nFin ;
|
||||
}
|
||||
}
|
||||
if ( m_nCurrPnt > nNextPE) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
||||
nNextPE += STEP_PE ;
|
||||
if ( nRes == 1)
|
||||
m_bBreak = true ;
|
||||
}
|
||||
}
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff)
|
||||
{
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Ciclo sui punti da verificare
|
||||
for ( int i = nFirst ; i <= nLast ; ++ i) {
|
||||
// verifico il punto
|
||||
Vector3d vtTriaN ;
|
||||
double dMove = MyTestPositionHG( vPntM[i].first, vtDir, vtTriaN) ;
|
||||
vPntM[i].second = dMove ;
|
||||
if ( dMove < - EPS_SMALL)
|
||||
return false ;
|
||||
++ m_nCurrPnt ;
|
||||
// se singolo thread
|
||||
if ( nId == -1) {
|
||||
// gestione eventi (ogni STEP_PE punti)
|
||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
||||
if ( nRes == 1)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti multithread
|
||||
else {
|
||||
if ( m_bBreak)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff)
|
||||
{
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
if ( lPntM.empty())
|
||||
return true ;
|
||||
// Imposto il riferimento di movimento
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
m_frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
// Controllo la tolleranza lineare (se negativa non vanno fatti controlli sui punti medi)
|
||||
if ( dLinTol > -EPS_ZERO)
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
else
|
||||
m_frMove.Set( ORIG, vtMove) ;
|
||||
// Predispongo Hash Grid
|
||||
if ( ! PrepareHashGrid())
|
||||
return false ;
|
||||
dLinTol = -1 ;
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
||||
// Salvo nuovo riferimento
|
||||
m_frMove = frMove ;
|
||||
// Ricalcolo HashGrid
|
||||
if ( ! PrepareHashGrid())
|
||||
return false ;
|
||||
}
|
||||
// Determino il numero di punti del path
|
||||
m_nTotPnt = int( lPntM.size()) ;
|
||||
// Recupero il numero massimo di thread concorrenti
|
||||
@@ -146,8 +350,9 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
bool bOk = true ;
|
||||
// Se un solo thread o pochi punti
|
||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol) ;
|
||||
ProcessEvents( 100, 0) ;
|
||||
m_nCurrPnt = 0 ;
|
||||
bOk = TestSubPath( -1, lPntM, vtDir, dLinTol, dProgCoeff) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
@@ -167,7 +372,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
m_bBreak = false ;
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol) ;
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubPath, this, i, ref( vlPntM[i]), cref( vtDir), dLinTol, dProgCoeff) ;
|
||||
// attendo i risultati
|
||||
int nFin = 0 ;
|
||||
int nNextPE = 0 ;
|
||||
@@ -179,7 +384,7 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
}
|
||||
}
|
||||
if ( m_nCurrPnt > nNextPE) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 10) ;
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
||||
nNextPE += STEP_PE ;
|
||||
if ( nRes == 1)
|
||||
m_bBreak = true ;
|
||||
@@ -191,18 +396,98 @@ CAvToolSurfTm::TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d&
|
||||
lPntM.pop_back() ;
|
||||
lPntM.splice( lPntM.end(), vlPntM[i]) ;
|
||||
}
|
||||
ProcessEvents( 100, 0) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// pulisco HashGrid 2d
|
||||
m_HGrids.Clear() ;
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol)
|
||||
CAvToolSurfTm::TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff)
|
||||
{
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
// NB. la posizione del punto non viene modificata :
|
||||
// get<0> vPntM[i] è il punto su cui viene posizionata la testa dell'utensile ( const)
|
||||
// get<1> vPntM[i] è il parametro di traslazione del punto lungo vtDir per evitare collisioni con i triangoli
|
||||
// get<2> vPntM[i] è un vettore di Vector3d contenente tutte le normali di tangenza ( a meno di 10 * EPS_SMALL)
|
||||
|
||||
// Se utensile non definito, errore
|
||||
if ( m_Tool.GetType() == Tool::UNDEF)
|
||||
return false ;
|
||||
// Se direzioni non definite, errore
|
||||
if ( vtDir.IsSmall() || vtMove.IsSmall())
|
||||
return false ;
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Calcolo nuovo riferimento di movimento
|
||||
Frame3d frMove ;
|
||||
if ( ! AreSameOrOppositeVectorApprox( vtDir, vtMove))
|
||||
frMove.Set( ORIG, vtMove, vtDir) ;
|
||||
else
|
||||
frMove.Set( ORIG, vtMove) ;
|
||||
// Se riferimento di movimento non presente o diverso dal calcolato
|
||||
if ( ! m_frMove.IsValid() || ! AreSameFrame( frMove, m_frMove)) {
|
||||
// Salvo nuovo riferimento
|
||||
m_frMove = frMove ;
|
||||
// Ricalcolo HashGrid
|
||||
if ( ! PrepareHashGrid())
|
||||
return false ;
|
||||
}
|
||||
// Determino il numero di punti del path
|
||||
m_nTotPnt = int( vPntM.size()) ;
|
||||
// Recupero il numero massimo di thread concorrenti
|
||||
int nThreadMax = thread::hardware_concurrency() ;
|
||||
bool bOk = true ;
|
||||
// Se un solo thread o pochi punti
|
||||
if ( nThreadMax <= 1 || m_nTotPnt < 500) {
|
||||
m_nCurrPnt = 0 ;
|
||||
bOk = TestSubSeriesAdv( -1, vPntM, vtDir, 0, m_nTotPnt - 1, dProgCoeff) ;
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
const int MAX_PARTS = 32 ;
|
||||
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||
// calcolo le parti del vettore
|
||||
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||
int nPartDim = m_nTotPnt / nPartCnt + 1 ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
vFstLst[i].first = i * nPartDim ;
|
||||
vFstLst[i].second = min( ( i + 1) * nPartDim, m_nTotPnt) - 1 ;
|
||||
}
|
||||
// processo le parti
|
||||
m_nCurrPnt = 0 ;
|
||||
m_bBreak = false ;
|
||||
future<bool> vRes[MAX_PARTS] ;
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i)
|
||||
vRes[i] = async( launch::async, &CAvToolSurfTm::TestSubSeriesAdv, this, i, ref( vPntM), cref( vtDir), vFstLst[i].first, vFstLst[i].second, dProgCoeff) ;
|
||||
// attendo i risultati
|
||||
int nFin = 0 ;
|
||||
int nNextPE = 0 ;
|
||||
while ( nFin < nPartCnt) {
|
||||
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||
if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
||||
bOk = vRes[i].get() && bOk ;
|
||||
++ nFin ;
|
||||
}
|
||||
}
|
||||
if ( m_nCurrPnt > nNextPE) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 10) ;
|
||||
nNextPE += STEP_PE ;
|
||||
if ( nRes == 1)
|
||||
m_bBreak = true ;
|
||||
}
|
||||
}
|
||||
ProcessEvents( int( 100 * dProgCoeff), 0) ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff)
|
||||
{
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
if ( lPntM.empty())
|
||||
return true ;
|
||||
// Ciclo sui punti
|
||||
@@ -212,11 +497,13 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
while ( itPntMCurr != lPntM.end()) {
|
||||
// verifico il punto
|
||||
ptCurr = itPntMCurr->first ;
|
||||
itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ;
|
||||
if ( itPntMCurr->second < - EPS_SMALL)
|
||||
Vector3d vtTriaN ;
|
||||
double dMove = MyTestPositionHG( itPntMCurr->first, vtDir, vtTriaN) ;
|
||||
itPntMCurr->second = dMove ;
|
||||
if ( dMove < - EPS_SMALL)
|
||||
return false ;
|
||||
// se esiste il punto precedente devo verificare il medio
|
||||
if ( itPntMPrev != lPntM.end()) {
|
||||
// se esiste il punto precedente e richiesto devo verificare il medio
|
||||
if ( itPntMPrev != lPntM.end() && dLinTol > 0) {
|
||||
MyTestMidPointHG( lPntM, itPntMPrev, itPntMCurr, ptPrev, ptCurr, vtDir, dLinTol, 1) ;
|
||||
}
|
||||
// passo al successivo
|
||||
@@ -228,7 +515,7 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
if ( nId == -1) {
|
||||
// gestione eventi (ogni STEP_PE punti)
|
||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt), 0) ;
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
||||
if ( nRes == 1)
|
||||
return false ;
|
||||
}
|
||||
@@ -242,10 +529,44 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff)
|
||||
{
|
||||
// Se vettore vuoto, non devo fare alcunché
|
||||
if ( vPntM.empty())
|
||||
return true ;
|
||||
// Ciclo sui punti da verificare
|
||||
for ( int i = nFirst ; i <= nLast ; ++ i) {
|
||||
// verifico il punto
|
||||
Point3d ptCurr = get<0>( vPntM[i]) ;
|
||||
get<1>( vPntM[i]) = MyTestPositionHGAdv( ptCurr, vtDir, get<2>( vPntM[i])) ;
|
||||
if ( get<1>( vPntM[i]) < - EPS_SMALL)
|
||||
return false ;
|
||||
++ m_nCurrPnt ;
|
||||
// se singolo thread
|
||||
if ( nId == -1) {
|
||||
// gestione eventi (ogni STEP_PE punti)
|
||||
if (( m_nCurrPnt % STEP_PE) == 0) {
|
||||
int nRes = ProcessEvents( int( m_nCurrPnt * 100. / m_nTotPnt * dProgCoeff), 0) ;
|
||||
if ( nRes == 1)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti multithread
|
||||
else {
|
||||
if ( m_bBreak)
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev)
|
||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const
|
||||
{
|
||||
// se superato limite di ricursione, esco
|
||||
const int MAX_LEV = 10 ;
|
||||
@@ -255,7 +576,8 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
||||
Point3d ptMid = Media( ptPrev, ptCurr, 0.5) ;
|
||||
// ne effettuo la correzione per evitare la collisione
|
||||
Point3d ptNewMid = ptMid ;
|
||||
double dMidMove = MyTestPositionHG( ptNewMid, vtDir) ;
|
||||
Vector3d vtTriaN ;
|
||||
double dMidMove = MyTestPositionHG( ptNewMid, vtDir, vtTriaN) ;
|
||||
if ( dMidMove < - EPS_SMALL)
|
||||
return false ;
|
||||
// massima distanza ammissibile
|
||||
@@ -264,7 +586,7 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
||||
if ( abs(( Media( itPntMPrev->first, itPntMCurr->first, 0.5) - ptNewMid) * m_frMove.VersZ()) > 0.5 * dLinTol ||
|
||||
SqDist( itPntMPrev->first, itPntMCurr->first) > dMaxSqDist) {
|
||||
// aggiungo
|
||||
lPntM.emplace( itPntMCurr, ptNewMid, - dMidMove) ;
|
||||
lPntM.emplace( itPntMCurr, ptNewMid, dMidMove) ;
|
||||
auto itPntMMid = itPntMCurr ;
|
||||
-- itPntMMid ;
|
||||
// verifico intervallo precedente
|
||||
@@ -277,20 +599,48 @@ CAvToolSurfTm::MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPn
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
|
||||
CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const
|
||||
{
|
||||
// box dell'utensile con suo movimento
|
||||
BBox3d b3Tool ;
|
||||
// utensile
|
||||
b3Tool.Add( ptT) ;
|
||||
b3Tool.Add( ptT - vtDir * m_Tool.GetHeigth()) ;
|
||||
if ( vtDir.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDir.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDir.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDir.x * vtDir.x) ;
|
||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDir.y * vtDir.y) ;
|
||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDir.z * vtDir.z) ;
|
||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
||||
}
|
||||
// aggiungo movimento
|
||||
BBox3d b3Moved = b3Tool ;
|
||||
b3Moved.Translate( MAX_MOVE * vtMove) ;
|
||||
b3Tool.Add( b3Moved) ;
|
||||
|
||||
// determino movimento minimo per evitare collisione con superfici
|
||||
double dTotDist = 0 ;
|
||||
vtTriaN = V_NULL ;
|
||||
for ( auto pStm : m_vSTM) {
|
||||
Triangle3d Tria ;
|
||||
for ( int nTria = pStm->GetFirstTriangle( Tria) ;
|
||||
nTria != SVT_NULL ;
|
||||
nTria = pStm->GetNextTriangle( nTria, Tria)) {
|
||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
|
||||
if ( dDist < - EPS_SMALL)
|
||||
return -1 ;
|
||||
if ( dDist > EPS_SMALL) {
|
||||
dTotDist += dDist ;
|
||||
ptT += dDist * m_frMove.VersZ() ;
|
||||
INTVECTOR vTria ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Tool, vTria)) {
|
||||
for ( int nTria : vTria) {
|
||||
Triangle3d Tria ;
|
||||
if ( pStm->GetTriangle( nTria, Tria)) {
|
||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
|
||||
if ( dDist < - EPS_SMALL)
|
||||
return -1 ;
|
||||
if ( dDist > EPS_SMALL) {
|
||||
dTotDist += dDist ;
|
||||
ptT += dDist * vtMove ;
|
||||
vtTriaN = Tria.GetN() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -299,7 +649,61 @@ CAvToolSurfTm::MyTestPosition( Point3d& ptT, const Vector3d& vtDir)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
CAvToolSurfTm::MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const
|
||||
{
|
||||
// box dell'utensile con suo movimento
|
||||
BBox3d b3Tool ;
|
||||
// utensile
|
||||
b3Tool.Add( ptT) ;
|
||||
b3Tool.Add( ptT - vtDir * m_Tool.GetHeigth()) ;
|
||||
if ( vtDir.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDir.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDir.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDir.x * vtDir.x) ;
|
||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDir.y * vtDir.y) ;
|
||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDir.z * vtDir.z) ;
|
||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
||||
}
|
||||
// aggiungo movimento
|
||||
BBox3d b3Moved = b3Tool ;
|
||||
b3Moved.Translate( MAX_MOVE * vtMove) ;
|
||||
b3Tool.Add( b3Moved) ;
|
||||
|
||||
// determino movimento minimo per evitare collisione con superfici
|
||||
double dTotDist = 0 ;
|
||||
vVtTriaN.clear() ;
|
||||
for ( auto pStm : m_vSTM) {
|
||||
INTVECTOR vTria ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Tool, vTria)) {
|
||||
for ( int nTria : vTria) {
|
||||
Triangle3d Tria ;
|
||||
if ( pStm->GetTriangle( nTria, Tria)) {
|
||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, vtMove) ;
|
||||
if ( dDist < - EPS_SMALL)
|
||||
return -1 ;
|
||||
// se devo traslare il punto, c'è collisione
|
||||
if ( dDist > EPS_SMALL) {
|
||||
if ( dDist > 10 * EPS_SMALL) {
|
||||
vVtTriaN.clear() ;
|
||||
dTotDist += dDist ;
|
||||
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
|
||||
}
|
||||
vVtTriaN.push_back( Tria.GetN()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return dTotDist ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const
|
||||
{
|
||||
// calcolo box utensile nel riferimento di movimento
|
||||
BBox3d b3Tool ;
|
||||
@@ -319,8 +723,10 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
|
||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
||||
}
|
||||
// ciclo sui triangoli che intersecano box in 2d
|
||||
|
||||
// ciclo sui triangoli che intersecano box in 2d
|
||||
double dTotDist = 0 ;
|
||||
vtTriaN = V_NULL ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
@@ -336,11 +742,70 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
|
||||
if ( dDist > EPS_SMALL) {
|
||||
dTotDist += dDist ;
|
||||
ptT += dDist * m_frMove.VersZ() ;
|
||||
vtTriaN = Tria.GetN() ;
|
||||
}
|
||||
else if ( dDist < -EPS_SMALL)
|
||||
return -1 ;
|
||||
}
|
||||
}
|
||||
|
||||
return dTotDist ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CAvToolSurfTm::MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const
|
||||
{
|
||||
// calcolo box utensile nel riferimento di movimento
|
||||
BBox3d b3Tool ;
|
||||
Point3d ptTL = ptT ; ptTL.ToLoc( m_frMove) ;
|
||||
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
|
||||
b3Tool.Add( ptTL) ;
|
||||
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
|
||||
if ( vtDirL.IsX())
|
||||
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsY())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
|
||||
else if ( vtDirL.IsZ())
|
||||
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
|
||||
else {
|
||||
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
|
||||
double dExpandY = m_Tool.GetRadius() * sqrt( 1 - vtDirL.y * vtDirL.y) ;
|
||||
double dExpandZ = m_Tool.GetRadius() * sqrt( 1 - vtDirL.z * vtDirL.z) ;
|
||||
b3Tool.Expand( dExpandX, dExpandY, dExpandZ) ;
|
||||
}
|
||||
|
||||
// ciclo sui triangoli che intersecano box in 2d
|
||||
double dTotDist = 0. ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( m_HGrids.Find( b3Tool, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
// recupero la superficie
|
||||
int nInd = vnIds[i] ;
|
||||
int nSurf = GetSurfInd( nInd) ;
|
||||
if ( nSurf == -1)
|
||||
return -1 ;
|
||||
// recupero il triangolo
|
||||
int nT = nInd - m_vBaseInd[nSurf] ;
|
||||
Triangle3d Tria ;
|
||||
if ( ! m_vSTM[nSurf]->GetTriangle( nT, Tria))
|
||||
return -1 ;
|
||||
// calcolo della collisione
|
||||
double dDist = CAvToolTriangle( m_Tool, ptT, vtDir, Tria, m_frMove.VersZ()) ;
|
||||
if ( dDist < - EPS_SMALL)
|
||||
return -1 ;
|
||||
// se devo traslare il punto, c'è collisione
|
||||
if ( dDist > EPS_SMALL) {
|
||||
if ( dDist > 10 * EPS_SMALL) {
|
||||
vVtTriaN.clear() ;
|
||||
dTotDist += dDist ;
|
||||
ptT += ( dDist - 5 * EPS_SMALL) * m_frMove.VersZ() ;
|
||||
}
|
||||
vVtTriaN.push_back( Tria.GetN()) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dTotDist ;
|
||||
}
|
||||
|
||||
@@ -351,7 +816,7 @@ CAvToolSurfTm::PrepareHashGrid( void)
|
||||
// pulisco HashGrid 2d
|
||||
m_HGrids.Clear() ;
|
||||
// verifico esistenza superfici
|
||||
if ( m_vSTM.size() == 0 || m_vBaseInd.size() < m_vSTM.size() + 1)
|
||||
if ( m_vSTM.empty() || m_vBaseInd.size() < m_vSTM.size() + 1)
|
||||
return false ;
|
||||
// creo HashGrid 2d
|
||||
const int LIM_HG_TRIA = 256 ;
|
||||
@@ -378,7 +843,7 @@ CAvToolSurfTm::PrepareHashGrid( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
CAvToolSurfTm::GetSurfInd( int nT)
|
||||
CAvToolSurfTm::GetSurfInd( int nT) const
|
||||
{
|
||||
// verifico la presenza di almeno un intervallo
|
||||
if ( m_vBaseInd.size() < 2)
|
||||
|
||||
+32
-7
@@ -34,22 +34,47 @@ class CAvToolSurfTm : public ICAvToolSurfTm
|
||||
{ return m_Tool.GetRadius() ; }
|
||||
double GetToolHeight( void) const override
|
||||
{ return m_Tool.GetHeigth() ; }
|
||||
double GetToolTipHeight( void) const override
|
||||
{ return m_Tool.GetTipHeigth() ; } ;
|
||||
double GetToolTipRadius( void) const override
|
||||
{ return m_Tool.GetTipRadius() ; } ;
|
||||
double GetToolCornRadius( void) const override
|
||||
{ return m_Tool.GetCornRadius() ; } ;
|
||||
CISURFTMPVECTOR GetvStm( void) const {
|
||||
CISURFTMPVECTOR vcStm ;
|
||||
for ( int i = 0 ; i < int( m_vSTM.size()) ; ++ i)
|
||||
vcStm.emplace_back( CloneSurfTriMesh( m_vSTM[i])) ;
|
||||
return vcStm ;
|
||||
}
|
||||
const ICurveComposite& GetToolOutline( bool bApprox = false) const override
|
||||
{ return ( bApprox ? m_Tool.GetApproxOutline() : m_Tool.GetOutline()) ;}
|
||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, double& dTotDist) override ;
|
||||
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol) override ;
|
||||
|
||||
bool TestPosition( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, Vector3d* pvtTriaN = nullptr) const override ;
|
||||
bool TestPositionAdv( const Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove,
|
||||
double& dTotDist, VCT3DVECTOR& vVtN) const override ;
|
||||
|
||||
bool TestSeries( PNTUVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
|
||||
bool TestSeriesAdv( PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dProgCoeff = 1) override ;
|
||||
|
||||
bool TestPath( PNTULIST& lPntM, const Vector3d& vtDir, const Vector3d& vtMove, double dLinTol, double dProgCoeff = 1) override ;
|
||||
|
||||
public :
|
||||
CAvToolSurfTm( void) ;
|
||||
bool Clear( void) ;
|
||||
|
||||
private :
|
||||
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol) ;
|
||||
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir) ;
|
||||
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir) ;
|
||||
bool TestSubSeries( int nId, PNTUVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
|
||||
bool TestSubSeriesAdv( int nId, PNTUVVECTVECTOR& vPntM, const Vector3d& vtDir, int nFirst, int nLast, double dProgCoeff) ;
|
||||
bool TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, double dLinTol, double dProgCoeff) ;
|
||||
double MyTestPosition( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, Vector3d& vtTriaN) const ;
|
||||
double MyTestPositionAdv( Point3d& ptT, const Vector3d& vtDir, const Vector3d& vtMove, VCT3DVECTOR& vVtTriaN) const ;
|
||||
double MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir, Vector3d& vtTriaN) const ;
|
||||
double MyTestPositionHGAdv( Point3d& ptT, const Vector3d& vtDir, VCT3DVECTOR& vVtTriaN) const ;
|
||||
bool MyTestMidPointHG( PNTULIST& lPntM, const PNTULIST::iterator& itPntMPrev, const PNTULIST::iterator& itPntMCurr,
|
||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) ;
|
||||
const Point3d& ptPrev, const Point3d& ptCurr, const Vector3d& vtDir, double dLinTol, int nLev) const ;
|
||||
bool PrepareHashGrid( void) ;
|
||||
int GetSurfInd( int nT) ;
|
||||
int GetSurfInd( int nT) const ;
|
||||
|
||||
private :
|
||||
typedef std::vector<const SurfTriMesh*> CSURFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@
|
||||
#include "CAvToolTriangle.h"
|
||||
#include "IntersLineSurfStd.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "CDeUtility.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
@@ -2503,7 +2503,7 @@ DiskSegmentEscapeDistLongMot( const Point3d& ptDiskCen, double dDiskRad,
|
||||
double dSegDist = 0. ;
|
||||
for ( int nSol = 0 ; nSol < nRoot ; ++ nSol) {
|
||||
// Soluzione interna al segmento
|
||||
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen) {
|
||||
if ( vdRoots[nSol] > 0. && vdRoots[nSol] < dSegLen + EPS_ZERO) {
|
||||
Point3d ptC = ptSeg + vdRoots[nSol] * vtSeg ;
|
||||
// Distanza del punto soluzione dal piano del disco nella posizione iniziale
|
||||
double dCurDist = PointPlaneSignedDist( ptC, ptDiskCen, vtMove) ;
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2024
|
||||
// EgalTech 2020-2026
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CDeClosedSurfTmClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2
|
||||
// File : CDeClosedSurfTmClosedSurfTm.h Data : 23.01.26 Versione : 3.1a3
|
||||
// Contenuto : Implementazione funzione verifica collisione tra
|
||||
// SurfTm e SurfTm.
|
||||
//
|
||||
// Modifiche : 13.11.20 LM Creazione modulo.
|
||||
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
|
||||
// 23.01.26 DS In TestSurfTmSurfTm aggiunto flag per collisione quando una delle due è chiusa e contiene l'altra.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -45,10 +46,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxB.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di A che interferiscono col box di B
|
||||
@@ -61,13 +62,13 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
continue ;
|
||||
BBox3d b3BoxTriaA ;
|
||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxTriaA.Expand( dSafeDist) ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vNearTria ;
|
||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||
pSrfB->ResetTempInts() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
@@ -84,14 +85,14 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
continue ;
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
@@ -111,10 +112,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
}
|
||||
}
|
||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
||||
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
||||
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||
return false ;
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
// La collisione c'è se una superficie è dentro l'altra.
|
||||
Point3d ptPointA, ptPointB ;
|
||||
pSrfA->GetFirstVertex( ptPointA) ;
|
||||
pSrfB->GetFirstVertex( ptPointB) ;
|
||||
@@ -127,7 +128,7 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
||||
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
||||
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist, bool bTestEnclosion)
|
||||
{
|
||||
// Recupero le superfici base
|
||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||
@@ -140,10 +141,10 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
||||
BBox3d b3BoxA, b3BoxB ;
|
||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxB.Expand( dSafeDist) ;
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||
return false ;
|
||||
// Recupero i triangoli di A che interferiscono col box di B
|
||||
@@ -156,13 +157,13 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
||||
continue ;
|
||||
BBox3d b3BoxTriaA ;
|
||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||
if ( dSafeDist > EPS_SMALL)
|
||||
b3BoxTriaA.Expand( dSafeDist) ;
|
||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||
INTVECTOR vNearTria ;
|
||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Settare tutti i triangoli come già processati.
|
||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||
pSrfB->ResetTempInts() ;
|
||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||
@@ -179,14 +180,14 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
||||
// Ciclo sui vertici del triangolo.
|
||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
// non è stato processato, processo il vertice e l'edge.
|
||||
int nAdjTriaTempFlag ;
|
||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||
continue ;
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||
return true ;
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||
double dEdgeLen = vtEdgeV.Len() ;
|
||||
vtEdgeV /= dEdgeLen ;
|
||||
@@ -205,6 +206,25 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
||||
pSrfB->SetTempInt( nTB, 1) ;
|
||||
}
|
||||
}
|
||||
// Non c'è interferenza
|
||||
// Se non richiesto test di inclusione, non c'è interferenza
|
||||
if ( ! bTestEnclosion)
|
||||
return false ;
|
||||
// Se la prima superficie è chiusa, verifico se include totalmente la seconda
|
||||
if ( pSrfA->IsClosed() && b3BoxA.Encloses( b3BoxB)) {
|
||||
Point3d ptPointB ;
|
||||
pSrfB->GetFirstVertex( ptPointB) ;
|
||||
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
|
||||
if ( DistPoinBSrfA.IsPointInside() || DistPoinBSrfA.IsEpsilon( dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
// Se la seconda superficie è chiusa, verifico se include totalmente la prima
|
||||
if ( pSrfB->IsClosed() && b3BoxB.Encloses( b3BoxA)) {
|
||||
Point3d ptPointA ;
|
||||
pSrfA->GetFirstVertex( ptPointA) ;
|
||||
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ;
|
||||
if ( DistPoinASrfB.IsPointInside() || DistPoinASrfB.IsEpsilon( dSafeDist))
|
||||
return true ;
|
||||
}
|
||||
// Non c'è interferenza
|
||||
return false ;
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "CDeCylTria.h"
|
||||
#include "CDeConvexTorusTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+1
-2
@@ -12,11 +12,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "CDeTriaTria.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
#include "stdafx.h"
|
||||
#include "CDeUtility.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2026
|
||||
//----------------------------------------------------------------------------
|
||||
// File : CalcDerivate.cpp Data : 03.02.26 Versione : 1.5h1
|
||||
// Contenuto : Funzioni per calcolo derivate secondo Bessel e Akima.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 03.02.26 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "CalcDerivate.h"
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
vPrevDer.clear() ;
|
||||
vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le derivate
|
||||
vPrevDer.reserve( nSize) ;
|
||||
vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||
vPrevDer.push_back( vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
// se non ci sono almeno 5 punti
|
||||
if ( nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( vPar[nSize-3] - vPar[nSize-1], vPnt[nSize-3], vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2],
|
||||
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti, uso arco sui primi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = vPrevDer[0] ;
|
||||
vtNextDer = vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso arco sugli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||
vPar[i], vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
// se secondo punto
|
||||
if ( i == 1) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i-1], vPnt[i-1],
|
||||
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se penultimo punto
|
||||
else if ( i == nSize - 2) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[1] + vPar[i+1], vPnt[1], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// salvo la derivata
|
||||
vPrevDer.push_back( vtPrevDer) ;
|
||||
vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
vPrevDer.clear() ;
|
||||
vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le derivate
|
||||
vPrevDer.reserve( nSize) ;
|
||||
vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||
vPrevDer.push_back( vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
if ( ! CalcBesselMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti, uso i primi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = vPrevDer[0] ;
|
||||
vtNextDer = vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso gli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||
vPar[i], vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
if ( ! CalcBesselMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// salvo la derivata
|
||||
vPrevDer.push_back( vtPrevDer) ;
|
||||
vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -179,3 +181,6 @@ CalcAkimaMidDer( double dU0, const Point3d& ptP0, double dU1, const Point3d& ptP
|
||||
}
|
||||
return ( ! vtPrevDer.IsZero() && ! vtNextDer.IsZero()) ;
|
||||
}
|
||||
|
||||
bool ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||
bool ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||
+8386
-1842
File diff suppressed because it is too large
Load Diff
+27
-23
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2013-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ChainCurves.cpp Data : 20.07.14 Versione : 1.5g3
|
||||
// Contenuto : Implementazione della funzione ChainCurves, per creare una o più
|
||||
// Contenuto : Implementazione della funzione ChainCurves, per creare una o più
|
||||
// curve composite a partire dalle curve date.
|
||||
//
|
||||
//
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
@@ -43,10 +44,10 @@ bool
|
||||
ChainCurves::AddCurve( int nId, const Point3d& ptStart, const Vector3d& vtStart,
|
||||
const Point3d& ptEnd, const Vector3d& vtEnd)
|
||||
{
|
||||
// verifico validità Id
|
||||
// verifico validità Id
|
||||
if ( nId <= 0)
|
||||
return false ;
|
||||
// verifico non sia già stata aggiunta la stessa entità
|
||||
// verifico non sia già stata aggiunta la stessa entità
|
||||
if ( ! m_sCrvId.insert( nId).second)
|
||||
return true ;
|
||||
// inserisco i dati della curva nel vettore
|
||||
@@ -68,7 +69,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
||||
m_bIsFork = false ;
|
||||
m_vFork.clear() ;
|
||||
|
||||
// recupero l'entità più vicina al punto di start
|
||||
// recupero l'entità più vicina al punto di start
|
||||
int nStart ;
|
||||
INTVECTOR vStart ;
|
||||
if ( ! m_PointGrid.FindNearest( ptStart, vStart) ||
|
||||
@@ -82,7 +83,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
||||
// tolgo dal grid
|
||||
RemoveEntityFromGrid( nId) ;
|
||||
|
||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||
bool bSkip = false ;
|
||||
if ( bHaltOnFork) {
|
||||
auto iIter = GetForkPoint( m_vCrvData[nId].ptEnd) ;
|
||||
@@ -93,7 +94,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
||||
}
|
||||
}
|
||||
|
||||
// concateno dopo la fine dell'entità di partenza
|
||||
// concateno dopo la fine dell'entità di partenza
|
||||
INTVECTOR vIdsAfter ;
|
||||
bool bClosed = false ;
|
||||
if ( ! bSkip && ! GetChainFromPoint( m_vCrvData[nId].ptEnd, m_vCrvData[nId].vtEnd,
|
||||
@@ -102,7 +103,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||
// se devo fermarmi su biforcazione, verifico se sono già su vecchia biforcazione
|
||||
bool bRevSkip = false ;
|
||||
if ( bHaltOnFork) {
|
||||
auto iIter = GetForkPoint( m_vCrvData[nId].ptStart) ;
|
||||
@@ -113,7 +114,7 @@ ChainCurves::GetChainFromNear( const Point3d& ptStart, bool bHaltOnFork, INTVECT
|
||||
}
|
||||
}
|
||||
|
||||
// se non ho già chiuso l'anello, concateno prima dell'inizio dell'entità di partenza
|
||||
// se non ho già chiuso l'anello, concateno prima dell'inizio dell'entità di partenza
|
||||
INTVECTOR vIdsBefore ;
|
||||
if ( ! bClosed) {
|
||||
bool bRevClosed ;
|
||||
@@ -258,7 +259,7 @@ ChainCurves::RemoveEntityFromGrid( int nId)
|
||||
bool
|
||||
ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int& nStart)
|
||||
{
|
||||
// numero di entità candidate
|
||||
// numero di entità candidate
|
||||
int nSize = int( vStart.size()) ;
|
||||
|
||||
// se nessuna, errore
|
||||
@@ -273,7 +274,7 @@ ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int&
|
||||
|
||||
// altrimenti, cerco la migliore
|
||||
int nI = - 1 ;
|
||||
double dSqDistMin = SQ_INFINITO ;
|
||||
double dDistMin = INFINITO ;
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
// recupero indice e verso
|
||||
int nId = abs( vStart[i]) - 1 ;
|
||||
@@ -281,9 +282,12 @@ ChainCurves::ChooseStart( const Point3d& ptStart, const INTVECTOR& vStart, int&
|
||||
// calcolo un punto vicino all'estremo lungo la tangente
|
||||
Point3d ptNear = ( bEquiv ? m_vCrvData[nId].ptStart + m_vCrvData[nId].vtStart :
|
||||
m_vCrvData[nId].ptEnd - m_vCrvData[nId].vtEnd) ;
|
||||
double dSqDist = SqDist( ptStart, ptNear) ;
|
||||
if ( dSqDist < dSqDistMin) {
|
||||
dSqDistMin = dSqDist ;
|
||||
double dDist = Dist( ptStart, ptNear) ;
|
||||
// tengo il segmento più vicino al punto
|
||||
// favorendo eventualmente quello equiverso se entro EPS da un concorrente
|
||||
if ( dDist < dDistMin - EPS_SMALL ||
|
||||
((dDist < dDistMin + EPS_SMALL) && bEquiv && vStart[nI] < 0)) {
|
||||
dDistMin = dDist ;
|
||||
nI = i ;
|
||||
}
|
||||
}
|
||||
@@ -302,7 +306,7 @@ bool
|
||||
ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vNext, bool bHaltOnFork, int& nNext)
|
||||
{
|
||||
INTVECTOR vMyNext = vNext ;
|
||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||
int nM = -1 ;
|
||||
Point3d ptRef ;
|
||||
double dSqMinDist = m_dToler * m_dToler ;
|
||||
@@ -319,19 +323,19 @@ ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
||||
}
|
||||
}
|
||||
for ( int i = 0 ; i < int( vMyNext.size()) ; ++ i) {
|
||||
// salto l'entità più vicina
|
||||
// salto l'entità più vicina
|
||||
if ( i == nM)
|
||||
continue ;
|
||||
// recupero indice e verso
|
||||
int nId = abs( vMyNext[i]) - 1 ;
|
||||
bool bEquiv = ( vMyNext[i] > 0) ;
|
||||
// verifico se più vicino al più vicino
|
||||
// verifico se più vicino al più vicino
|
||||
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
||||
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptStart : m_vCrvData[nId].ptEnd)) ;
|
||||
if ( dRefSqDist < dCurrSqDist)
|
||||
vMyNext[i] = 0 ;
|
||||
}
|
||||
// cerco la direzione più vicina
|
||||
// cerco la direzione più vicina
|
||||
int nI = -1 ;
|
||||
int nF = 0 ;
|
||||
INTVECTOR vFork ;
|
||||
@@ -343,7 +347,7 @@ ChainCurves::ChooseNext( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
||||
// recupero indice e verso
|
||||
int nId = abs( vMyNext[i]) - 1 ;
|
||||
bool bEquiv = ( vMyNext[i] > 0) ;
|
||||
// incremento contatore indice entità tra cui scegliere
|
||||
// incremento contatore indice entità tra cui scegliere
|
||||
++ nF ;
|
||||
vFork.push_back( vMyNext[i]) ;
|
||||
// se vietata inversione, salto se controverso
|
||||
@@ -387,7 +391,7 @@ bool
|
||||
ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const INTVECTOR& vPrev, bool bHaltOnFork, int& nPrev)
|
||||
{
|
||||
INTVECTOR vMyPrev = vPrev ;
|
||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||
// scarto quelle entità che sono più vicine all'altro estremo del più vicino
|
||||
int nM = -1 ;
|
||||
Point3d ptRef ;
|
||||
double dSqMinDist = m_dToler * m_dToler ;
|
||||
@@ -404,19 +408,19 @@ ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
||||
}
|
||||
}
|
||||
for ( int i = 0 ; i < int( vMyPrev.size()) ; ++ i) {
|
||||
// salto l'entità più vicina
|
||||
// salto l'entità più vicina
|
||||
if ( i == nM)
|
||||
continue ;
|
||||
// recupero indice e verso
|
||||
int nId = abs( vMyPrev[i]) - 1 ;
|
||||
bool bEquiv = ( vMyPrev[i] < 0) ;
|
||||
// verifico se più vicino al più vicino
|
||||
// verifico se più vicino al più vicino
|
||||
double dCurrSqDist = SqDist( ptCurr, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
||||
double dRefSqDist = SqDist( ptRef, ( bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart)) ;
|
||||
if ( dRefSqDist < dCurrSqDist)
|
||||
vMyPrev[i] = 0 ;
|
||||
}
|
||||
// cerco la direzione più vicina
|
||||
// cerco la direzione più vicina
|
||||
int nI = - 1 ;
|
||||
int nF = 0 ;
|
||||
double dProScaMax = - 1.1 ;
|
||||
@@ -428,7 +432,7 @@ ChainCurves::ChoosePrev( const Point3d& ptCurr, const Vector3d& vtCurr, const IN
|
||||
// recupero indice e verso
|
||||
int nId = abs( vMyPrev[i]) - 1 ;
|
||||
bool bEquiv = ( vMyPrev[i] < 0) ;
|
||||
// incremento contatore indice entità tra cui scegliere
|
||||
// incremento contatore indice entità tra cui scegliere
|
||||
++ nF ;
|
||||
vFork.push_back( vMyPrev[i]) ;
|
||||
// se vietata inversione, salto se controverso
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCircleCenTgCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
@@ -45,7 +45,8 @@ static const NamedColor StdColor[] = {
|
||||
{ "FUCHSIA", FUCHSIA},
|
||||
{ "PURPLE", PURPLE},
|
||||
{ "ORANGE", ORANGE},
|
||||
{ "BROWN", BROWN}
|
||||
{ "BROWN", BROWN},
|
||||
{ "INVISIBLE", INVISIBLE}
|
||||
} ;
|
||||
static const int NUM_STDCOLOR = ( sizeof(StdColor) / sizeof(StdColor[0]) ) ;
|
||||
|
||||
@@ -127,7 +128,7 @@ GetHSVFromColor( const Color& cCol)
|
||||
hsv.dSat = dDelta / dMax ;
|
||||
if ( cCol.GetRed() >= dMax) // tra giallo e magenta
|
||||
hsv.dHue = ( cCol.GetGreen() - cCol.GetBlue()) / dDelta ;
|
||||
else if( cCol.GetGreen() >= dMax) // tra ciano e giallo
|
||||
else if ( cCol.GetGreen() >= dMax) // tra ciano e giallo
|
||||
hsv.dHue = 2.0 + ( cCol.GetBlue() - cCol.GetRed()) / dDelta ;
|
||||
else // tra magenta e ciano
|
||||
hsv.dHue = 4.0 + ( cCol.GetRed() - cCol.GetGreen()) / dDelta ;
|
||||
|
||||
+4
-3
@@ -398,7 +398,7 @@ CurveArc::Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bo
|
||||
if ( dLenA > ( dRad - EPS_ZERO))
|
||||
dLenH = 0 ;
|
||||
else
|
||||
dLenH= sqrt( dRad * dRad - dLenA * dLenA) ;
|
||||
dLenH = sqrt( dRad * dRad - dLenA * dLenA) ;
|
||||
// versore dal punto medio della corda al centro
|
||||
Vector3d vtH = vtA / dLenA ;
|
||||
vtH.Rotate( Z_AX, 0, ( bCCW ? 1 : -1)) ;
|
||||
@@ -410,6 +410,7 @@ CurveArc::Set2PRS( const Point3d& ptStart, const Point3d& ptEnd, double dRad, bo
|
||||
m_dRad = dRad ;
|
||||
// calcolo il versore di start
|
||||
m_VtS = ( ptStart - m_PtCen) / m_dRad ;
|
||||
m_VtS.Normalize() ;
|
||||
// calcolo l'angolo al centro
|
||||
bool bDet ;
|
||||
if ( ! m_VtS.GetRotation( ( ptEnd - m_PtCen), m_VtN, m_dAngCenDeg, bDet) || ! bDet)
|
||||
@@ -1293,7 +1294,7 @@ CurveArc::Invert( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::SimpleOffset( double dDist, int nType)
|
||||
CurveArc::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||
{
|
||||
// la curva deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
@@ -1328,7 +1329,7 @@ CurveArc::SimpleOffset( double dDist, int nType)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveArc::MyExtendedOffset( double dDist, bool bAll, int nType)
|
||||
CurveArc::MyExtendedOffset( double dDist, bool bAll)
|
||||
{
|
||||
// bAll == true fa accettare raggi nulli ==> da usare solo internamente
|
||||
// quando si è sicuri di aumentare subito il raggio o di cancellare
|
||||
|
||||
+4
-4
@@ -116,7 +116,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||
bool Invert( void) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||
@@ -178,8 +178,8 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
bool ChangeDeltaN( double dNewDeltaN) override ;
|
||||
bool ChangeAngCenter( double dNewAngCenDeg) override ;
|
||||
bool ChangeStartPoint( double dU) override ;
|
||||
bool ExtendedOffset( double dDist, int nType = OFF_FILLET) override
|
||||
{ return MyExtendedOffset( dDist, false, nType) ; }
|
||||
bool ExtendedOffset( double dDist) override
|
||||
{ return MyExtendedOffset( dDist, false) ; }
|
||||
bool ToExplementary( void) override ;
|
||||
bool Flip( void) override ;
|
||||
|
||||
@@ -200,7 +200,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
||||
{ if ( ! CopyFrom( caSrc))
|
||||
LOG_ERROR( GetEGkLogger(), "CurveArc : copy error")
|
||||
return *this ; }
|
||||
bool MyExtendedOffset( double dDist, bool bAll, int nType = OFF_FILLET) ;
|
||||
bool MyExtendedOffset( double dDist, bool bAll) ;
|
||||
bool MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, double dLinTol) const ;
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
+1574
-68
File diff suppressed because it is too large
Load Diff
@@ -33,4 +33,6 @@ bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
||||
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
|
||||
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
||||
bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ;
|
||||
|
||||
+340
-20
@@ -13,13 +13,13 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveAux.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointCrvBezier.h"
|
||||
#include "BiArcs.h"
|
||||
#include "GeoConst.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
@@ -27,12 +27,16 @@
|
||||
#include "Bernstein.h"
|
||||
#include "deCasteljau.h"
|
||||
#include "Voronoi.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EGkUiUnits.h"
|
||||
#include "/EgtDev/Include/ENkPolynomial.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include <array>
|
||||
|
||||
using namespace std ;
|
||||
@@ -89,8 +93,11 @@ CurveBezier::Init( int nDeg, bool bIsRational)
|
||||
bool
|
||||
CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
||||
{
|
||||
// verifico validità indice
|
||||
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg)
|
||||
// verifico validità indice e punto
|
||||
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg || ! ptCtrl.IsValid())
|
||||
return false ;
|
||||
|
||||
if ( abs( ptCtrl.x) > INFINITO || abs( ptCtrl.y) > INFINITO || abs( ptCtrl.z) > INFINITO)
|
||||
return false ;
|
||||
|
||||
// assegno il valore
|
||||
@@ -119,8 +126,11 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
||||
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd > m_nDeg)
|
||||
return false ;
|
||||
|
||||
// verifico che il peso non sia nullo o negativo
|
||||
if ( dW < EPS_SMALL)
|
||||
// verifico che il punto sia valido e il peso non sia nullo o negativo
|
||||
if ( ! ptCtrl.IsValid() || dW < EPS_SMALL || ! isfinite( dW) || dW > INFINITO)
|
||||
return false ;
|
||||
|
||||
if ( abs( ptCtrl.x) > INFINITO || abs( ptCtrl.y) > INFINITO || abs( ptCtrl.z) > INFINITO)
|
||||
return false ;
|
||||
|
||||
// assegno il valore e il peso
|
||||
@@ -138,6 +148,32 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::SetControlWeight( int nInd, double dW)
|
||||
{
|
||||
// verifico validità, razionalità e indice
|
||||
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd > m_nDeg)
|
||||
return false ;
|
||||
|
||||
// verifico che il peso non sia nullo o negativo
|
||||
if ( dW < EPS_SMALL || ! isfinite( dW) || dW > INFINITO)
|
||||
return false ;
|
||||
|
||||
// assegno il valore e il peso
|
||||
m_vWeCtrl[nInd] = dW ;
|
||||
|
||||
// annullo analisi presenza singolarità
|
||||
m_dParSing = - 2 ;
|
||||
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
@@ -195,6 +231,35 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
SetControlPoint( 1, ptNew1, dW) ;
|
||||
SetControlPoint( 2, ptNew2, dW) ;
|
||||
SetControlPoint( 3, ptEnd, 1) ;
|
||||
|
||||
//// anziché usare una bezier cubica approssimo le eliche con più bezier quadratiche razionali.
|
||||
//// più è grande l'angolo al centro dell'arco e maggiore sarà l'errore di approssimazione
|
||||
//
|
||||
// // quadratica razionale
|
||||
// // peso del punto di controllo intermedio
|
||||
// double dW = dCosAhalf ;
|
||||
// // calcolo dei punti di controllo
|
||||
// Point3d ptStart ;
|
||||
// crArc.GetStartPoint( ptStart) ;
|
||||
// Point3d ptEnd ;
|
||||
// crArc.GetEndPoint( ptEnd) ;
|
||||
// // Point3d ptMed = Media( ptStart, ptEnd, 0.5) ;
|
||||
// //Vector3d vtDir = ptMed - crArc.GetCenter() ;
|
||||
// // Point3d ptNew = crArc.GetCenter() + vtDir / ( dCosAhalf * dCosAhalf) ;
|
||||
// Vector3d vtStart ; crArc.GetStartDir( vtStart) ;
|
||||
// Vector3d vtEnd ; crArc.GetEndDir( vtEnd) ;
|
||||
// PtrOwner<CurveLine> pCrvLine1( CreateBasicCurveLine()) ;
|
||||
// pCrvLine1->SetPVL( ptStart, vtStart, 10) ;
|
||||
// PtrOwner<CurveLine> pCrvLine2( CreateBasicCurveLine()) ;
|
||||
// pCrvLine2->SetPVL( ptEnd, vtEnd, 10) ;
|
||||
// IntersLineLine ill( *pCrvLine1, *pCrvLine2, false) ;
|
||||
// IntCrvCrvInfo iccInfo ; ill.GetIntCrvCrvInfo( iccInfo) ;
|
||||
// Point3d ptNew = 0.5 * (iccInfo.IciA->ptI + iccInfo.IciB->ptI) ;
|
||||
// // inserimento nella curva dei punti di controllo con i pesi
|
||||
// Init( 2, true) ;
|
||||
// SetControlPoint( 0, ptStart, 1) ;
|
||||
// SetControlPoint( 1, ptNew, dW) ;
|
||||
// SetControlPoint( 2, ptEnd, 1) ;
|
||||
}
|
||||
|
||||
// copio estrusione e spessore
|
||||
@@ -204,6 +269,29 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::FromLine( const ICurveLine& crLine)
|
||||
{
|
||||
if ( m_nStatus != OK || ! crLine.IsValid())
|
||||
return false ;
|
||||
int nCount = 0 ;
|
||||
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
|
||||
SetControlPoint( nCount, ptStart) ;
|
||||
++nCount ;
|
||||
double dPart = 1. / m_nDeg ;
|
||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
||||
double dU = i * dPart ;
|
||||
Point3d ptMid ; crLine.GetPointD1D2( dU, ICurve::FROM_MINUS, ptMid) ;
|
||||
SetControlPoint( nCount, ptMid) ;
|
||||
++nCount ;
|
||||
}
|
||||
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
|
||||
SetControlPoint( nCount, ptEnd) ;
|
||||
++nCount ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::IsAPoint( void) const
|
||||
@@ -284,8 +372,11 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
||||
{
|
||||
if ( &cbSrc == this)
|
||||
return true ;
|
||||
if ( ! cbSrc.IsValid())
|
||||
return false ;
|
||||
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
|
||||
return false ;
|
||||
m_dParSing = cbSrc.m_dParSing ;
|
||||
m_vPtCtrl = cbSrc.m_vPtCtrl ;
|
||||
if ( cbSrc.m_bRat)
|
||||
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
||||
@@ -433,21 +524,21 @@ bool
|
||||
CurveBezier::Validate( void)
|
||||
{
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& ptP : m_vPtCtrl) {
|
||||
if ( ! ptP.IsValid()) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
for ( const auto& ptP : m_vPtCtrl) {
|
||||
if ( ! ptP.IsValid()) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_nStatus == TO_VERIFY) {
|
||||
for ( const auto& dWe : m_vWeCtrl) {
|
||||
if ( ! isfinite( dWe)) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
for ( const auto& dWe : m_vWeCtrl) {
|
||||
if ( ! isfinite( dWe)) {
|
||||
m_nStatus = ERR ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( m_nStatus == TO_VERIFY)
|
||||
m_nStatus = ( ( m_nDeg >= 1 && m_vPtCtrl.size() >= 2) ? OK : ERR) ;
|
||||
|
||||
@@ -1486,7 +1577,7 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
return false ;
|
||||
vtDir.ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
}
|
||||
@@ -1574,6 +1665,10 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
||||
ICurve*
|
||||
CurveBezier::CopyParamRange( double dUStart, double dUEnd) const
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return nullptr ;
|
||||
|
||||
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
||||
if ( dUStart < - EPS_PARAM || dUStart > 1 + EPS_PARAM ||
|
||||
dUEnd < - EPS_PARAM || dUEnd > 1 + EPS_PARAM)
|
||||
@@ -1716,6 +1811,10 @@ CurveBezier::TrimEndAtParam( double dUTrim)
|
||||
bool
|
||||
CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
||||
if ( dUStartTrim < - EPS_PARAM || dUStartTrim > 1 + EPS_PARAM ||
|
||||
dUEndTrim < - EPS_PARAM || dUEndTrim > 1 + EPS_PARAM)
|
||||
@@ -1723,18 +1822,34 @@ CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||
// verifico che i trim non cancellino interamente la curva
|
||||
if ( dUStartTrim > dUEndTrim - EPS_PARAM)
|
||||
return false ;
|
||||
// se razionale devo trovare il punto di trim iniziale per ricalcolare il parametro di trim
|
||||
Point3d ptStart ;
|
||||
if ( m_bRat)
|
||||
GetPointD1D2( dUStartTrim, ptStart) ;
|
||||
// trim finale
|
||||
if ( ! TrimEndAtParam( dUEndTrim))
|
||||
return false ;
|
||||
// trim iniziale con il parametro opportunamente ricalcolato
|
||||
double dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||
return TrimStartAtParam( dNewUStartTrim) ;
|
||||
double dNewUStartTrim ;
|
||||
if ( m_bRat)
|
||||
GetParamAtPoint( ptStart, dNewUStartTrim) ;
|
||||
else
|
||||
dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||
//trim iniziale
|
||||
if ( ! TrimStartAtParam( dNewUStartTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::TrimStartAtLen( double dLenTrim)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// lunghezze negative vengono considerate nulle
|
||||
dLenTrim = max( dLenTrim, 0.) ;
|
||||
|
||||
@@ -1744,13 +1859,20 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimStartAtParam( dUTrim) ;
|
||||
if ( ! TrimStartAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::TrimEndAtLen( double dLenTrim)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// lunghezze negative vengono considerate nulle
|
||||
dLenTrim = max( dLenTrim, 0.) ;
|
||||
|
||||
@@ -1760,13 +1882,20 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimEndAtParam( dUTrim) ;
|
||||
if ( ! TrimEndAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::ExtendStartByLen( double dLenExt)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// la lunghezza deve essere positiva
|
||||
if ( dLenExt < - EPS_ZERO)
|
||||
return false ;
|
||||
@@ -1818,6 +1947,10 @@ CurveBezier::ExtendStartByLen( double dLenExt)
|
||||
bool
|
||||
CurveBezier::ExtendEndByLen( double dLenExt)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
// la lunghezza deve essere positiva
|
||||
if ( dLenExt < - EPS_ZERO)
|
||||
return false ;
|
||||
@@ -2152,3 +2285,190 @@ CurveBezier::ResetVoronoiObject() const
|
||||
delete m_pVoronoiObj ;
|
||||
m_pVoronoiObj = nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::MakeRational( void)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
if ( m_bRat)
|
||||
return true ;
|
||||
// creo il vettore dei pesi e li setto tutti a 1
|
||||
m_vWeCtrl.assign( m_nDeg + 1, 1) ;
|
||||
// aggiorno il flag rational
|
||||
m_bRat = true ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::MakeRationalStandardForm( void)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
if ( ! m_bRat)
|
||||
return false ;
|
||||
double dW0 = m_vWeCtrl.front() ;
|
||||
double dWn = m_vWeCtrl.back() ;
|
||||
if ( dW0 > 1 - EPS_ZERO && dWn > 1 - EPS_ZERO)
|
||||
return true ;
|
||||
if ( dW0 < EPS_ZERO || dWn < EPS_ZERO)
|
||||
return false ;
|
||||
|
||||
// formula del Farin
|
||||
double dCoeff = pow( dW0 / dWn, 1. / m_nDeg) ;
|
||||
for ( int i = 0 ; i < m_nDeg + 1 ; ++i)
|
||||
m_vWeCtrl[i] *= Pow( dCoeff, i) / dW0 ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::MakeNonRational( double dTol)
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
if ( ! m_bRat)
|
||||
return true ;
|
||||
|
||||
// controllo se i pesi sono tutti == 1 allora è una finta razionale e mi basta fare una copia dei punti di controllo
|
||||
bool bIsActualRat = false ;
|
||||
for ( int i = 0 ; i < m_nDeg ; ++i) {
|
||||
if ( abs( m_vWeCtrl[i] - 1) > EPS_SMALL) {
|
||||
bIsActualRat = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bOk = true ;
|
||||
if ( ! bIsActualRat) {
|
||||
// semplicemente tolgo il booleano della razionalità e i punti restano gli stessi
|
||||
m_bRat = false ;
|
||||
}
|
||||
else {
|
||||
// provo ad approssimare la curva di bezier con una controparte non razionale
|
||||
int nDeg = m_nDeg ;
|
||||
// se ho una curva razionale di grado 2 verifico se è un arco, in quel caso la converto in una curva di grado 3 non razionale con la funzione dedicata
|
||||
if ( nDeg == 2 && m_bRat) {
|
||||
// prendo due punti sulla curva e calcolo l'intersezione dei due assi dei segmenti formati da pt2-pt0 e pt3-pt1
|
||||
Point3d pt0 ; GetStartPoint( pt0) ;
|
||||
Point3d pt1 ; GetPointD1D2( 0.3, pt1) ;
|
||||
Point3d pt2 ; GetPointD1D2( 0.6, pt2) ;
|
||||
Point3d pt3 ; GetEndPoint( pt3) ;
|
||||
|
||||
Vector3d vtDir1 = pt2 - pt0 ;
|
||||
Vector3d vtDir2 = pt3 - pt1 ;
|
||||
Vector3d vtN = vtDir2 ^ vtDir1 ;
|
||||
|
||||
CurveLine cl1 ; cl1.Set( pt1, pt1 + (vtDir1 ^ vtN) * 5) ;
|
||||
CurveLine cl2 ; cl1.Set( pt2, pt2 + (vtDir2 ^ vtN) * 5) ;
|
||||
IntersLineLine ill( cl1, cl2, false) ;
|
||||
IntCrvCrvInfo iccInfo ; ill.GetIntCrvCrvInfo( iccInfo) ;
|
||||
Point3d ptCen = iccInfo.IciA[0].ptI ;
|
||||
|
||||
// se sia l'inizio che la fine della curva distano uguale dal punto di intersezione tra i due assi trovati allora la curva è un arco di circonferenza
|
||||
if ( abs(Dist( pt0, ptCen) - Dist( pt3, ptCen)) < EPS_SMALL) {
|
||||
PtrOwner<ICurveBezier> pNew ( ApproxArcCurveBezierWithSingleCubic( this, ptCen, vtN)) ;
|
||||
|
||||
if ( IsNull( pNew) || ! pNew->IsValid())
|
||||
return false ;
|
||||
Init( 3, false) ;
|
||||
for ( int i = 0 ; i < 3 ; ++i)
|
||||
SetControlPoint( i, pNew->GetControlPoint(i)) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
|
||||
// punto di rientro in caso fallisca il primo tentativo
|
||||
retry :
|
||||
nDeg += 2 ;
|
||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
||||
pNewBez->Init( nDeg, false) ;
|
||||
PNTVECTOR vPntCtrl ;
|
||||
PNTVECTOR vPntSampling ;
|
||||
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
||||
Point3d pt ; GetPointD1D2( double( p) / nDeg, pt) ;
|
||||
pNewBez->SetControlPoint( p, pt) ;
|
||||
vPntCtrl.push_back( pt) ;
|
||||
}
|
||||
vPntSampling = vPntCtrl ;
|
||||
int c = 0 ;
|
||||
double dErr = INFINITO ;
|
||||
while ( dErr > dTol && c < 100) {
|
||||
double dErrMax = 0 ;
|
||||
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
||||
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
||||
Point3d pt ; pNewBez->GetPointD1D2( double( p) / nDeg, pt) ;
|
||||
Vector3d vDiff = vPntSampling[p] - pt ;
|
||||
double dErrLoc = vDiff.Len() ;
|
||||
if ( dErrLoc > dErrMax)
|
||||
dErrMax = dErrLoc ;
|
||||
// aggiorno il vettore dei punti di controllo della nuova curva
|
||||
vPntCtrl[p] += vDiff ;
|
||||
}
|
||||
dErr = dErrMax ;
|
||||
// aggiorno i punti di controllo della nuova curva
|
||||
for ( int i = 0 ; i < nDeg + 1 ; ++i)
|
||||
pNewBez->SetControlPoint( i, vPntCtrl[i]) ;
|
||||
++c ;
|
||||
}
|
||||
|
||||
// calcolo l'errore di approssimazione sulla curva
|
||||
CalcApproxError( this, pNewBez, dErr) ;
|
||||
bOk = dErr < dTol ;
|
||||
if ( bOk) {
|
||||
// aggiorno la curva di bezier originale con quella approssimata
|
||||
Init( nDeg, false) ;
|
||||
for ( int i = 0 ; i < nDeg + 1 ; ++i) {
|
||||
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
||||
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
||||
}
|
||||
}
|
||||
else if ( nDeg < m_nDeg + 4)
|
||||
goto retry ;
|
||||
}
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::IsALine( void) const
|
||||
{
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
|
||||
Point3d ptStart ; GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; GetEndPoint( ptEnd) ;
|
||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
||||
Point3d ptCtrl = GetControlPoint( i) ;
|
||||
DistPointLine dpl( ptCtrl, ptStart, ptEnd) ;
|
||||
double dDist = 0 ; dpl.GetDist( dDist) ;
|
||||
if ( dDist > EPS_SMALL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
PNTVECTOR
|
||||
CurveBezier::GetAllControlPoints( void) const
|
||||
{
|
||||
PNTVECTOR vPntCtrl ;
|
||||
// la curva deve essere valida
|
||||
if ( m_nStatus != OK)
|
||||
return vPntCtrl ;
|
||||
|
||||
return m_vPtCtrl ;
|
||||
}
|
||||
+9
-2
@@ -116,7 +116,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||
bool Invert( void) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override
|
||||
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
|
||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||
@@ -137,7 +137,9 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
bool Init( int nDeg, bool bIsRational) override ;
|
||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl) override ;
|
||||
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
|
||||
bool SetControlWeight( int nInd, double dW) override ;
|
||||
bool FromArc( const ICurveArc& crArc) override ;
|
||||
bool FromLine( const ICurveLine& crLine) override ;
|
||||
int GetDegree( void) const override
|
||||
{ return m_nDeg ; }
|
||||
bool IsRational( void) const override
|
||||
@@ -147,6 +149,11 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
double GetControlWeight( int nInd, bool* pbOk = NULL) const override ;
|
||||
bool GetControlPolygonLength( double& dLen) const override ;
|
||||
int GetSingularParam( double& dPar) const override ;
|
||||
bool MakeRational( void) override ;
|
||||
bool MakeRationalStandardForm( void) override ;
|
||||
bool MakeNonRational( double dTol) override ;
|
||||
bool IsALine( void) const override ;
|
||||
PNTVECTOR GetAllControlPoints( void) const ; // non aggiunta in interfaccia
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -190,7 +197,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
||||
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
static const int MAXDEG = 11 ;
|
||||
static const int MAXDEG = 21 ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
|
||||
+16
-212
@@ -16,8 +16,8 @@
|
||||
#include "CurveComposite.h"
|
||||
#include "CalcDerivate.h"
|
||||
#include "BiArcs.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||
@@ -202,213 +202,14 @@ CurveByApprox::CalcParameterization( void)
|
||||
bool
|
||||
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||
{
|
||||
// pulisco i vettori delle tangenti
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
// se non ci sono almeno 5 punti
|
||||
if ( nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti, uso arco sui primi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = m_vPrevDer[0] ;
|
||||
vtNextDer = m_vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso arco sugli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
// se secondo punto
|
||||
if ( i == 1) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se penultimo punto
|
||||
else if ( i == nSize - 2) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// salvo la derivata
|
||||
m_vPrevDer.push_back( vtPrevDer) ;
|
||||
m_vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByApprox::CalcBesselTangents( void)
|
||||
{
|
||||
// pulisco i vettori delle tangenti
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti, uso i primi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = m_vPrevDer[0] ;
|
||||
vtNextDer = m_vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso gli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// salvo la derivata
|
||||
m_vPrevDer.push_back( vtPrevDer) ;
|
||||
m_vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -439,12 +240,12 @@ CurveByApprox::CalcSplitPoints( double dLinTol, double dAngTolDeg, double dLinFe
|
||||
m_vSplits.push_back(i) ;
|
||||
continue ;
|
||||
}
|
||||
// verifico linearità del tratto precedente
|
||||
// verifico linearità del tratto precedente
|
||||
bool bPrevLin = vtPrev.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i-1] * m_vPrevDer[i]) > dAngTolCos &&
|
||||
( vtPrev ^ m_vNextDer[i-1]).SqLen() < dSqLinTol &&
|
||||
( vtPrev ^ m_vPrevDer[i]).SqLen() < dSqLinTol ;
|
||||
// verifico linearità del tratto successivo
|
||||
// verifico linearità del tratto successivo
|
||||
bool bNextLin = vtNext.SqLen() > dSqLinFea &&
|
||||
( m_vNextDer[i] * m_vPrevDer[i+1]) > dAngTolCos &&
|
||||
( vtNext ^ m_vNextDer[i]).SqLen() < dSqLinTol &&
|
||||
@@ -483,7 +284,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
double dMaxDist ;
|
||||
|
||||
// se la polilinea ha più di 2 punti
|
||||
// se la polilinea ha più di 2 punti
|
||||
if ( PL.GetPointNbr() > 2) {
|
||||
// calcolo punti e direzioni agli estremi della polilinea usando la curva di Bezier
|
||||
int nI ;
|
||||
@@ -501,11 +302,12 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
ptP1 = m_vPnt[nI] ;
|
||||
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist)) ;
|
||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
||||
// forzo la spezzatura della curva
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
dMaxDist = 2 * dLinTol ;
|
||||
}
|
||||
// se la polilinea è formata da 2 punti
|
||||
// se la polilinea è formata da 2 punti
|
||||
else if ( PL.GetPointNbr() == 2) {
|
||||
// se molto vicini, esco
|
||||
double dLen ;
|
||||
@@ -524,13 +326,15 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
|
||||
// se raggiunto il massimo livello di recursione, forzo l'accettazione del biarco
|
||||
if ( nLev >= MAX_LEV) {
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
dMaxDist = 0 ;
|
||||
// segnalo situazione per debug
|
||||
if ( GetEGkDebugLev() >= 5)
|
||||
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions")
|
||||
}
|
||||
|
||||
// se lunghezza abbastanza picccola, forzo l'accettazione della curva
|
||||
// se lunghezza abbastanza piccola, forzo l'accettazione della curva
|
||||
double dLen ;
|
||||
if ( PL.GetApproxLength( dLen) && dLen < 10 * EPS_SMALL)
|
||||
dMaxDist = 0 ;
|
||||
@@ -561,7 +365,7 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
return false ;
|
||||
}
|
||||
|
||||
// spezzo l'intervallo in due parti a metà
|
||||
// spezzo l'intervallo in due parti a metà
|
||||
double dParStart, dParEnd ;
|
||||
if ( ! PL.GetFirstU( dParStart) || ! PL.GetLastU( dParEnd))
|
||||
return false ;
|
||||
@@ -569,9 +373,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
||||
PolyLine PL2 ;
|
||||
if ( ! PL.Split( dParMid, PL2))
|
||||
return false ;
|
||||
// prima metà
|
||||
// prima metà
|
||||
if ( ! BiArcOrSplit( nLev + 1, PL, dLinTol, dAngTolDeg, PA))
|
||||
return false ;
|
||||
// seconda metà
|
||||
// seconda metà
|
||||
return BiArcOrSplit( nLev + 1, PL2, dLinTol, dAngTolDeg, PA) ;
|
||||
}
|
||||
|
||||
+34
-225
@@ -50,7 +50,37 @@ CurveByInterp::AddPoint( const Point3d& ptP)
|
||||
ICurve*
|
||||
CurveByInterp::GetCurve( int nMethod, int nType)
|
||||
{
|
||||
// calcolo le tangenti
|
||||
// se richieste curve di Bezier cubiche (ottenute da interpolazione con Nurbs)
|
||||
if ( nType == CUBIC_BEZIERS_LONG) {
|
||||
// creo la curva composita
|
||||
PtrOwner<ICurve> pCrv ;
|
||||
//pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 50 * EPS_SMALL, 50)) ;
|
||||
//debug
|
||||
pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 0.1, 100)) ;
|
||||
if ( IsNull(pCrv) || ! pCrv->IsValid())
|
||||
return nullptr ;
|
||||
return Release( pCrv) ;
|
||||
}
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return nullptr ;
|
||||
|
||||
// calcolo le distanze tra i punti per derivarne i parametri
|
||||
m_vPar.reserve( nSize) ;
|
||||
double dPar = 0 ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
|
||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||
dPar += dDist ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
}
|
||||
|
||||
// calcolo le tangenti
|
||||
if ( nMethod == BESSEL) {
|
||||
if ( ! CalcBesselTangents())
|
||||
return nullptr ;
|
||||
@@ -110,233 +140,12 @@ CurveByInterp::GetCurve( int nMethod, int nType)
|
||||
bool
|
||||
CurveByInterp::CalcAkimaTangents( bool bDetectCorner)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
m_vPar.clear() ;
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le distanze tra i punti per derivarne i parametri
|
||||
m_vPar.reserve( nSize) ;
|
||||
double dPar = 0 ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||
dPar += dDist ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
}
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
// se non ci sono almeno 5 punti
|
||||
if ( nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti, uso arco sui primi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = m_vPrevDer[0] ;
|
||||
vtNextDer = m_vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso arco sugli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
// se secondo punto
|
||||
if ( i == 1) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// se penultimo punto
|
||||
else if ( i == nSize - 2) {
|
||||
// se curva aperta o non ci sono almeno 5 punti
|
||||
if ( ! bClosed || nSize < 5) {
|
||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
||||
vtPrevDer, vtNextDer))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// salvo la derivata
|
||||
m_vPrevDer.push_back( vtPrevDer) ;
|
||||
m_vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveByInterp::CalcBesselTangents( void)
|
||||
{
|
||||
// pulisco i vettori dei parametri e delle tangenti
|
||||
m_vPar.clear() ;
|
||||
m_vPrevDer.clear() ;
|
||||
m_vNextDer.clear() ;
|
||||
|
||||
// numero di punti
|
||||
int nSize = int( m_vPnt.size()) ;
|
||||
|
||||
// sono necessari almeno due punti
|
||||
if ( nSize < 2)
|
||||
return false ;
|
||||
|
||||
// calcolo le distanze tra i punti per derivarne i parametri
|
||||
m_vPar.reserve( nSize) ;
|
||||
double dPar = 0 ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||
dPar += dDist ;
|
||||
m_vPar.push_back( dPar) ;
|
||||
}
|
||||
|
||||
// calcolo le derivate
|
||||
m_vPrevDer.reserve( nSize) ;
|
||||
m_vNextDer.reserve( nSize) ;
|
||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||
if ( nSize == 2) {
|
||||
// non esiste derivata prima del primo punto
|
||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
||||
// non esiste derivata dopo il secondo e ultimo punto
|
||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
||||
return true ;
|
||||
}
|
||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
||||
// calcolo le derivate
|
||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||
Vector3d vtPrevDer ;
|
||||
Vector3d vtNextDer ;
|
||||
// primo punto
|
||||
if ( i == 0) {
|
||||
// se curva chiusa, come precedente uso il penultimo punto
|
||||
if ( bClosed) {
|
||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = vtNextDer ;
|
||||
}
|
||||
// altrimenti, uso i primi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
||||
return false ;
|
||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// ultimo punto
|
||||
else if ( i == nSize - 1) {
|
||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||
if ( bClosed) {
|
||||
vtPrevDer = m_vPrevDer[0] ;
|
||||
vtNextDer = m_vNextDer[0] ;
|
||||
}
|
||||
// altrimenti, uso gli ultimi tre punti
|
||||
else {
|
||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||
}
|
||||
}
|
||||
// punti intermedi
|
||||
else {
|
||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
||||
return false ;
|
||||
vtNextDer = vtPrevDer ;
|
||||
}
|
||||
// salvo la derivata
|
||||
m_vPrevDer.push_back( vtPrevDer) ;
|
||||
m_vNextDer.push_back( vtNextDer) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||
}
|
||||
+158
-98
@@ -14,7 +14,6 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistPointCrvComposite.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
@@ -27,6 +26,7 @@
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "Voronoi.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveByApprox.h"
|
||||
#include "/EgtDev/Include/EGkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
@@ -192,7 +192,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
return false ;
|
||||
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK && ! ( m_CrvSmplS.empty() && m_nStatus == TO_VERIFY))
|
||||
if ( m_nStatus != OK && ! ( m_CrvSmplS.empty() && ( m_nStatus == TO_VERIFY || m_nStatus == IS_A_POINT)))
|
||||
return false ;
|
||||
|
||||
// controllo la tolleranza
|
||||
@@ -224,8 +224,11 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
// lunghezza della curva originale
|
||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||
// eseguo modifica
|
||||
if ( ! pCrv->ModifyStart( ptEnd))
|
||||
return false ;
|
||||
if ( ! pCrv->ModifyStart( ptEnd)) {
|
||||
CurveLine crvLine ;
|
||||
if ( ! crvLine.Set( ptEnd, ptCrvEnd) || ! pCrv.Set( crvLine.Clone()))
|
||||
return false ;
|
||||
}
|
||||
// verifico che la lunghezza non sia variata troppo
|
||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||
@@ -246,8 +249,11 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
||||
// lunghezza della curva originale
|
||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||
// eseguo modifica
|
||||
if ( ! pCrv->ModifyEnd( ptStart))
|
||||
return false ;
|
||||
if ( ! pCrv->ModifyEnd( ptStart)) {
|
||||
CurveLine crvLine ;
|
||||
if ( ! crvLine.Set( ptCrvStart, ptStart) || ! pCrv.Set( crvLine.Clone()))
|
||||
return false ;
|
||||
}
|
||||
// verifico che la lunghezza non sia variata troppo
|
||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||
@@ -291,9 +297,15 @@ CurveComposite::Close( void)
|
||||
return true ;
|
||||
// se molto vicini li modifico
|
||||
if ( AreSamePointEpsilon( ptStart, ptEnd, 10 * EPS_SMALL)) {
|
||||
// se un solo arco
|
||||
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_ARC) {
|
||||
CurveArc* pArc = GetBasicCurveArc( m_CrvSmplS.front()) ;
|
||||
return pArc->ChangeAngCenter( pArc->GetAngCenter() > 0 ? ANG_FULL : -ANG_FULL) ;
|
||||
}
|
||||
// caso generale
|
||||
Point3d ptMid = Media( ptStart, ptEnd) ;
|
||||
if ( ! ModifyStart( ptMid) ||
|
||||
! ModifyEnd( ptMid))
|
||||
if ( ! m_CrvSmplS.front()->ModifyStart( ptMid) ||
|
||||
! m_CrvSmplS.back()->ModifyEnd( ptMid))
|
||||
return false ;
|
||||
}
|
||||
// altrimenti aggiungo la linea di chiusura
|
||||
@@ -369,9 +381,10 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
||||
return false ;
|
||||
|
||||
// ciclo di inserimento dei segmenti che uniscono i punti
|
||||
double dParIni, dParFin ;
|
||||
Point3d ptIni, ptFin ;
|
||||
PL.GetFirstPoint( ptIni) ;
|
||||
while ( PL.GetNextPoint( ptFin)) {
|
||||
PL.GetFirstUPoint( &dParIni, &ptIni) ;
|
||||
while ( PL.GetNextUPoint( &dParFin, &ptFin)) {
|
||||
// se i punti della coppia coincidono, passo alla coppia successiva
|
||||
if ( AreSamePointApprox( ptIni, ptFin))
|
||||
continue ;
|
||||
@@ -382,10 +395,14 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
||||
// assegno i punti estremi
|
||||
if ( ! pCrvLine->Set( ptIni, ptFin))
|
||||
return false ;
|
||||
// assegno i parametri degli estremi
|
||||
pCrvLine->SetTempParam( dParIni, 0) ;
|
||||
pCrvLine->SetTempParam( dParFin, 1) ;
|
||||
// aggiungo la retta alla curva composita
|
||||
if ( ! AddSimpleCurve( Release( pCrvLine)))
|
||||
return false ;
|
||||
// aggiorno dati prossimo punto iniziale
|
||||
dParIni = dParFin ;
|
||||
ptIni = ptFin ;
|
||||
}
|
||||
|
||||
@@ -598,6 +615,10 @@ CurveComposite::CopyFrom( const CurveComposite& ccSrc)
|
||||
if ( ! AddCurve( *pCrv))
|
||||
return false ;
|
||||
}
|
||||
if ( ccSrc.m_nStatus == IS_A_POINT) {
|
||||
m_ptStart = ccSrc.m_ptStart ;
|
||||
m_nStatus = IS_A_POINT ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -656,7 +677,7 @@ CurveComposite::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||
while ( pCrvSmpl != nullptr && i < MAX_CRV) {
|
||||
// assegno ed emetto nome e tipo della curva semplice
|
||||
sOut += "#" + ToString( i) + " " + pCrvSmpl->GetTitle() + szNewLine ;
|
||||
// salvataggio della curva semplice
|
||||
// dati della curva semplice
|
||||
if ( ! pCrvSmpl->Dump( sOut, bMM, szNewLine))
|
||||
return false ;
|
||||
// passo alla successiva
|
||||
@@ -745,7 +766,7 @@ CurveComposite::Load( NgeReader& ngeIn)
|
||||
ICurve* pCrv = ::GetCurve( pGeoO) ;
|
||||
bOk = bOk && ( pCrv != nullptr && pCrv->IsSimple()) ;
|
||||
// aggiungo questa curva (sicuramente semplice)
|
||||
bOk = bOk && AddSimpleCurve( pCrv) ;
|
||||
bOk = bOk && AddSimpleCurve( pCrv, true, 10 * EPS_SMALL) ;
|
||||
// se errore
|
||||
if ( ! bOk)
|
||||
return false ;
|
||||
@@ -868,20 +889,32 @@ CurveComposite::Validate( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::TestClosure( void)
|
||||
CurveComposite::TestClosure( double dLinTol)
|
||||
{
|
||||
// se non è chiusa, esco subito
|
||||
if ( ! IsClosed())
|
||||
// se non valida o vuota, esco subito
|
||||
if ( m_nStatus != OK || m_CrvSmplS.empty())
|
||||
return true ;
|
||||
// se non è chiusa entro la tolleranza, esco subito
|
||||
Point3d ptStart, ptEnd ;
|
||||
if ( ! m_CrvSmplS.front()->GetStartPoint( ptStart) ||
|
||||
! m_CrvSmplS.back()->GetEndPoint( ptEnd) ||
|
||||
! AreSamePointEpsilon( ptStart, ptEnd, dLinTol))
|
||||
return true ;
|
||||
// se singola retta, esco subito
|
||||
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_LINE)
|
||||
return true ;
|
||||
// verifico ed eventualmente aggiusto coincidenza punti estremi
|
||||
Point3d ptStart ; m_CrvSmplS.front()->GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
|
||||
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
||||
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
|
||||
// se un solo arco
|
||||
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_ARC) {
|
||||
CurveArc* pArc = GetBasicCurveArc( m_CrvSmplS.front()) ;
|
||||
return pArc->ChangeAngCenter( pArc->GetAngCenter() > 0 ? ANG_FULL : -ANG_FULL) ;
|
||||
}
|
||||
// caso generale
|
||||
Point3d ptM = Media( ptStart, ptEnd) ;
|
||||
if ( ! m_CrvSmplS.front()->ModifyStart( ptM) ||
|
||||
! m_CrvSmplS.back()->ModifyEnd( ptM))
|
||||
return false ;
|
||||
return ( m_CrvSmplS.front()->ModifyStart( ptM) &&
|
||||
m_CrvSmplS.back()->ModifyEnd( ptM)) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
@@ -937,6 +970,8 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
}
|
||||
} break ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
@@ -1679,7 +1714,7 @@ CurveComposite::Invert( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::SimpleOffset( double dDist, int nType)
|
||||
CurveComposite::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||
{
|
||||
// se distanza di offset nulla, non devo fare alcunché
|
||||
if ( abs( dDist) < EPS_SMALL)
|
||||
@@ -1701,7 +1736,7 @@ CurveComposite::SimpleOffset( double dDist, int nType)
|
||||
}
|
||||
|
||||
// eseguo l'offset nel piano XY
|
||||
bool bOk = SimpleOffsetXY( dDist, nType) ;
|
||||
bool bOk = SimpleOffsetXY( dDist, nType, dMaxAngExt) ;
|
||||
|
||||
// riporto la curva nel riferimento originale
|
||||
if ( bNeedRef)
|
||||
@@ -1761,10 +1796,11 @@ bool
|
||||
CurveComposite::AddPoint( const Point3d& ptStart)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != TO_VERIFY)
|
||||
if ( m_nStatus != TO_VERIFY && m_nStatus != IS_A_POINT)
|
||||
return false ;
|
||||
// assegno il punto
|
||||
// assegno il punto e setto lo stato
|
||||
m_ptStart = ptStart ;
|
||||
m_nStatus = IS_A_POINT ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -1808,7 +1844,7 @@ bool
|
||||
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK && m_nStatus != TO_VERIFY)
|
||||
if ( m_nStatus != OK && m_nStatus != IS_A_POINT)
|
||||
return false ;
|
||||
// costruisco la linea
|
||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||
@@ -2972,7 +3008,7 @@ CurveComposite::RemoveFirstOrLastCurve( bool bLast)
|
||||
m_CrvSmplS.pop_front() ;
|
||||
}
|
||||
// eseguo mini verifica
|
||||
m_nStatus = ( m_CrvSmplS.size() > 0 ? OK : TO_VERIFY) ;
|
||||
m_nStatus = ( ! m_CrvSmplS.empty() ? OK : TO_VERIFY) ;
|
||||
// assegno estrusione e spessore della curva composita
|
||||
pCrv->SetExtrusion( m_VtExtr) ;
|
||||
pCrv->SetThickness( m_dThick) ;
|
||||
@@ -3017,7 +3053,7 @@ CurveComposite::ArcsToBezierCurves( void)
|
||||
// se arco, devo trasformare in una o più curve di Bezier
|
||||
if ( (*Iter)->GetType() == CRV_ARC) {
|
||||
// eseguo trasformazione
|
||||
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( (*Iter))) ;
|
||||
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( GetCurveArc( *Iter))) ;
|
||||
if ( IsNull( pNewCrv))
|
||||
return false ;
|
||||
// se risultato è singola curva
|
||||
@@ -3151,11 +3187,26 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// se precedente molto corta
|
||||
double dLenP ;
|
||||
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
|
||||
// se abbastanza allineata alla successiva
|
||||
// se abbastanza allineata alla successiva
|
||||
Vector3d vtDirP, vtDirC ;
|
||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||
Point3d ptStart ;
|
||||
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
||||
bool bModifStart = ( pCrvC->GetType() != CRV_ARC) ;
|
||||
if ( ! bModifStart) {
|
||||
/* nel caso in cui la curva corrente sia un arco, bisogna controllare che la somma tra
|
||||
l'angolo al centro e l'angolo sotteso dalla curva precedente non superi l'angolo giro; in
|
||||
caso positivo, la modifica del punto inziale dell'arco ( curva corrente) rimoverebbe
|
||||
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
||||
Point3d ptS ; pCrvP->GetStartPoint( ptS) ;
|
||||
Point3d ptE ; pCrvC->GetStartPoint( ptE) ;
|
||||
const ICurveArc* pArcC = GetBasicCurveArc( pCrvC) ;
|
||||
double dAngRef = ( Dist( ptS, ptE) / pArcC->GetRadius()) * RADTODEG ;
|
||||
bModifStart = ( abs( pArcC->GetAngCenter()) + dAngRef < ANG_FULL - 10 * EPS_ANG_SMALL) ;
|
||||
|
||||
}
|
||||
if ( bModifStart) {
|
||||
Point3d ptStart ;
|
||||
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se corrente molto corta
|
||||
@@ -3164,10 +3215,24 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// se abbastanza allineata alla precedente
|
||||
Vector3d vtDirP, vtDirC ;
|
||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||
Point3d ptEnd ;
|
||||
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
||||
bool bModifEnd = ( pCrvP->GetType() != CRV_ARC) ;
|
||||
if ( ! bModifEnd) {
|
||||
/* nel caso in cui la curva predecente sia un arco, bisogna controllare che la somma tra
|
||||
l'angolo al centro e l'angolo sotteso dalla curva corrente non superi l'angolo giro; in
|
||||
caso positivo, la modifica del punto finale dell'arco ( curva precedente) rimoverebbe
|
||||
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
||||
Point3d ptS ; pCrvP->GetEndPoint( ptS) ;
|
||||
Point3d ptE ; pCrvC->GetEndPoint( ptE) ;
|
||||
const CurveArc* pArcP = GetBasicCurveArc( pCrvP) ;
|
||||
double dAngRef = ( Dist( ptS, ptE) / pArcP->GetRadius()) * RADTODEG ;
|
||||
bModifEnd = ( abs( pArcP->GetAngCenter()) + dAngRef < ANG_FULL - 10. * EPS_ANG_SMALL) ;
|
||||
}
|
||||
if ( bModifEnd) {
|
||||
Point3d ptEnd ;
|
||||
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// coefficiente deduzione tolleranza
|
||||
const double COEFF_TOL = 0.7 ;
|
||||
// se entrambe rette
|
||||
@@ -3222,61 +3287,69 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
||||
// verifico di non superare l'angolo giro al centro
|
||||
if ( abs( pArcP->GetAngCenter() + pArcC->GetAngCenter()) > ANG_FULL + EPS_ANG_SMALL)
|
||||
return 0 ;
|
||||
// se archi piatti
|
||||
if ( pArcP->IsPlane() && pArcC->IsPlane()) {
|
||||
// se calcolo nuovo arco ok, procedo con l'unione
|
||||
Point3d ptP1 ;
|
||||
pArcP->GetStartPoint( ptP1) ;
|
||||
Point3d ptP2 ;
|
||||
pArcP->GetEndPoint( ptP2) ;
|
||||
Point3d ptP3 ;
|
||||
pArcC->GetEndPoint( ptP3) ;
|
||||
// verifico se circonferenza completa
|
||||
bool bCirc = ( AreSamePointApprox( ptP1, ptP3)) ;
|
||||
if ( bCirc)
|
||||
pArcC->GetMidPoint( ptP3) ;
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
||||
// verifico normale al piano dell'arco
|
||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||
NewArc.InvertN() ;
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
}
|
||||
else
|
||||
// verifico se archi piatti
|
||||
bool bPlaneArcs = pArcP->IsPlane() && pArcC->IsPlane() ;
|
||||
// se archi non piatti verifico coincidenza pendenza sulla normale
|
||||
if ( ! bPlaneArcs) {
|
||||
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
||||
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
||||
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) > dCurrLinTol)
|
||||
return 0 ;
|
||||
}
|
||||
// verifico coincidenza pendenza sulla normale
|
||||
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
|
||||
if ( abs(( pArcC->GetDeltaN() * pArcP->GetAngCenter() - dN * pArcP->GetDeltaN() * pArcC->GetAngCenter()) /
|
||||
( pArcP->GetAngCenter() + pArcC->GetAngCenter())) < dCurrLinTol) {
|
||||
// se calcolo nuovo arco ok, procedo con l'unione
|
||||
Point3d ptP1 ;
|
||||
pArcP->GetStartPoint( ptP1) ;
|
||||
Vector3d vtDir1 ;
|
||||
pArcP->GetStartDir( vtDir1) ;
|
||||
Point3d ptP3 ;
|
||||
pArcC->GetEndPoint( ptP3) ;
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
}
|
||||
else
|
||||
return 0 ;
|
||||
|
||||
// se calcolo nuovo arco ok, procedo con l'unione
|
||||
Point3d ptP1 ;
|
||||
pArcP->GetStartPoint( ptP1) ;
|
||||
Point3d ptP2 ;
|
||||
pArcP->GetEndPoint( ptP2) ;
|
||||
Point3d ptP3 ;
|
||||
pArcC->GetEndPoint( ptP3) ;
|
||||
|
||||
// se archi non piani costruisco arco sul piano definito dalla normale e dal punto di partenza del primo arco
|
||||
Frame3d frRef ;
|
||||
if ( ! frRef.Set( ptP1, pArcP->GetNormVersor()))
|
||||
return 0 ;
|
||||
if ( ! bPlaneArcs) {
|
||||
ptP1.Scale( frRef, 1, 1, 0) ;
|
||||
ptP2.Scale( frRef, 1, 1, 0) ;
|
||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
||||
ptC1Fin.Scale( frRef, 1, 1, 0) ;
|
||||
}
|
||||
|
||||
// verifico se circonferenza completa
|
||||
bool bCirc = ( AreSamePointEpsilon( ptP1, ptP3, dCurrLinTol)) ;
|
||||
if ( bCirc) {
|
||||
pArcC->GetMidPoint( ptP3) ;
|
||||
if ( ! bPlaneArcs)
|
||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
||||
}
|
||||
|
||||
CurveArc NewArc ;
|
||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
||||
// se vicino a circonferenza arco per 3 punti potrebbe non dare il risultato desiderato quindi faccio controllo su raggio e centro
|
||||
if ( Dist( NewArc.GetCenter(), ptC1Fin) > 2 * dCurrLinTol || abs( NewArc.GetRadius() - pArcP->GetRadius()) > 2 * dCurrLinTol)
|
||||
return 0 ;
|
||||
|
||||
// verifico normale al piano dell'arco
|
||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||
NewArc.InvertN() ;
|
||||
// se archi non piani ripristino il deltaN
|
||||
if ( ! bPlaneArcs) {
|
||||
double dDeltaN1 = pArcP->GetDeltaN() ;
|
||||
double dDeltaN2 = pArcC->GetDeltaN() ;
|
||||
NewArc.ChangeDeltaN( dDeltaN1 + dDeltaN2) ;
|
||||
}
|
||||
// se curve originali con la stessa proprietà, la riporto
|
||||
if ( nTpr0P == nTpr0C)
|
||||
NewArc.SetTempProp( nTpr0C, 0) ;
|
||||
if ( nTpr1P == nTpr1C)
|
||||
NewArc.SetTempProp( nTpr1C, 1) ;
|
||||
// aggiorno l'arco corrente e torno flag modifica
|
||||
*pArcC = NewArc ;
|
||||
return -1 ;
|
||||
}
|
||||
else
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
// nessuna fusione
|
||||
@@ -3774,19 +3847,6 @@ CurveComposite::ResetVoronoiObject() const
|
||||
m_pVoronoiObj = nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::FromPoint(Point3d& ptStart)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != TO_VERIFY)
|
||||
return false ;
|
||||
// assegno il punto e setto lo stato
|
||||
m_ptStart = ptStart ;
|
||||
m_nStatus = IS_A_POINT ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
||||
|
||||
+4
-5
@@ -113,7 +113,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const override ;
|
||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||
bool Invert( void) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||
@@ -177,8 +177,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
||||
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
||||
bool GetCurveTempParam( int nCrv, double& dParam, int nParamInd = 0) const override ;
|
||||
bool FromPoint( Point3d& ptStart) override ; // funzione per settare la curva ad un unico punto
|
||||
bool GetOnlyPoint( Point3d& ptStart) const override ; // funzione per recuperare l'unico punto da cui è composta la curva ( degenere)
|
||||
bool GetOnlyPoint( Point3d& ptStart) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -199,17 +198,17 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||
return *this ; }
|
||||
bool RelocateFrom( CurveComposite& ccSrc) ;
|
||||
bool GetApproxLength( double& dLen) const ;
|
||||
bool TestClosure( double dLinTol = EPS_SMALL) ;
|
||||
Voronoi* GetVoronoiObject( void) const ;
|
||||
void ResetVoronoiObject( void) const ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const CurveComposite& ccSrc) ;
|
||||
bool Validate( void) ;
|
||||
bool TestClosure( void) ;
|
||||
bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
||||
bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
||||
bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ;
|
||||
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ;
|
||||
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) ;
|
||||
bool IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const ;
|
||||
bool CalcVoronoiObject( void) const ;
|
||||
|
||||
|
||||
+14
-10
@@ -19,6 +19,7 @@
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkCurve.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
@@ -30,14 +31,14 @@ static const int TP_IS_VERT_LINE = 1 ;
|
||||
static bool IsVerticalLine( const ICurve* pCrv, double* pdLenZ) ;
|
||||
static bool VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
||||
static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
||||
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
|
||||
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType, double dMaxAngExt,
|
||||
CurveComposite& ccAux) ;
|
||||
static bool AddFirstLastVerticalLines( CurveComposite& ccOffs, double dLenVertFirst, double dLenVertLast) ;
|
||||
static bool MediaInternalAngleDeltaZ( CurveComposite& ccOffs) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
CurveComposite::SimpleOffsetXY( double dDist, int nType, double dMaxAngExt)
|
||||
{
|
||||
// creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
|
||||
CurveComposite ccCopy ;
|
||||
@@ -98,7 +99,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
CurveComposite ccTemp ;
|
||||
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustInternalAngle( pCrvPrev, pCrv2, ccTemp) ||
|
||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrv2, dDist, nType, ccTemp)) {
|
||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrv2, dDist, nType, dMaxAngExt, ccTemp)) {
|
||||
if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
return false ;
|
||||
}
|
||||
@@ -122,7 +123,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
||||
CurveComposite ccTemp ;
|
||||
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrvNext, ccTemp) ||
|
||||
VerifyAndAdjustInternalAngle( pCrvPrev, pCrvNext, ccTemp) ||
|
||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrvNext, dDist, nType, ccTemp)) {
|
||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrvNext, dDist, nType, dMaxAngExt, ccTemp)) {
|
||||
int nCrvCount = ccTemp.GetCurveCount() ;
|
||||
if ( nCrvCount > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||
return false ;
|
||||
@@ -174,7 +175,7 @@ bool
|
||||
VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
||||
{
|
||||
// verifica dei puntatori
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||
return false ;
|
||||
|
||||
// pulisco la curva ausiliaria
|
||||
@@ -218,7 +219,7 @@ bool
|
||||
VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
||||
{
|
||||
// verifica dei puntatori
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||
return false ;
|
||||
|
||||
// pulisco la curva ausiliaria
|
||||
@@ -259,11 +260,11 @@ VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAu
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
|
||||
VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType, double dMaxAngExt,
|
||||
CurveComposite& ccAux)
|
||||
{
|
||||
// verifica dei puntatori
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
||||
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||
return false ;
|
||||
|
||||
// pulisco la curva ausiliaria
|
||||
@@ -272,6 +273,9 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nT
|
||||
// elimino dal tipo le parti estranee all'angolo esterno
|
||||
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
|
||||
|
||||
// porto il massimo angolo per tipo Extend in limiti accettabili (90° - 150°)
|
||||
dMaxAngExt = Clamp( dMaxAngExt, ANG_RIGHT, 1.667 * ANG_RIGHT) ;
|
||||
|
||||
// calcolo direzioni tangenti sull'estremo in comune
|
||||
Vector3d vtDir1, vtDir2 ;
|
||||
if ( ! pCrv1->GetEndDir( vtDir1) || ! pCrv2->GetStartDir( vtDir2))
|
||||
@@ -319,8 +323,8 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nT
|
||||
( dDist > 0 && dAngDeg < 0)))
|
||||
return false ;
|
||||
|
||||
// se l'angolo esterno supera il retto, offset extend diventa offset chamfer
|
||||
if ( nType == ICurve::OFF_EXTEND && abs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
|
||||
// se l'angolo esterno supera il limite, offset extend diventa offset chamfer
|
||||
if ( nType == ICurve::OFF_EXTEND && abs( dAngDeg) > dMaxAngExt + EPS_ANG_SMALL)
|
||||
nType = ICurve::OFF_CHAMFER ;
|
||||
|
||||
// se angolo esterno molto piccolo, semplifico tutto
|
||||
|
||||
+2
-2
@@ -14,11 +14,11 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoObjFactory.h"
|
||||
#include "NgeWriter.h"
|
||||
#include "NgeReader.h"
|
||||
#include "Voronoi.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
@@ -577,7 +577,7 @@ CurveLine::Invert( void)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveLine::SimpleOffset( double dDist, int nType)
|
||||
CurveLine::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||
{
|
||||
// verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
|
||||
+1
-1
@@ -117,7 +117,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||
bool Invert( void) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||
|
||||
+3
-4
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2022
|
||||
// EgalTech 2020-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistLineLine.h Data : 12.08.22 Versione : 2.4h1
|
||||
// File : DistLineLine.cpp Data : 10.05.24 Versione : 2.6e3
|
||||
// Contenuto : Implementazione della classe distanza fra elementi lineari.
|
||||
//
|
||||
//
|
||||
@@ -12,11 +12,10 @@
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
#include "/EgtDev/Include/EGkGeoConst.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2020-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistLineLine.h Data : 06.11.20 Versione : 2.2k1
|
||||
// Contenuto : Dichiarazione della classe distanza fra elementi lineari.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 06.11.20 LM Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkVector3d.h"
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class DistLineLine
|
||||
{
|
||||
public :
|
||||
DistLineLine( const Point3d& ptSt1, const Point3d& ptEn1,
|
||||
const Point3d& ptSt2, const Point3d& ptEn2,
|
||||
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
|
||||
DistLineLine( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||
bool bIsSegment1 = true, bool bIsSegment2 = true) ;
|
||||
|
||||
public :
|
||||
bool GetSqDist( double& dSqDist) const ;
|
||||
bool GetDist( double& dDist) const ;
|
||||
bool IsEpsilon( double dTol) const
|
||||
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
|
||||
bool IsSmall( void) const
|
||||
{ return IsEpsilon( EPS_SMALL) ; }
|
||||
bool IsZero( void) const
|
||||
{ return IsEpsilon( EPS_ZERO) ; }
|
||||
bool GetMinDistPoints( Point3d& ptMinDist1, Point3d& ptMinDist2) const ;
|
||||
bool GetPositionsAtMinDistPoints( double& dPos1, double& dPos2) const ;
|
||||
|
||||
private :
|
||||
void Calculate( const Point3d& ptSt1, const Vector3d& vtD1, double dLen1,
|
||||
const Point3d& ptSt2, const Vector3d& vtD2, double dLen2,
|
||||
bool bIsSegment1, bool bIsSegment2) ;
|
||||
private:
|
||||
double m_dSqDist ;
|
||||
mutable double m_dDist ;
|
||||
double m_dPos1 ;
|
||||
double m_dPos2 ;
|
||||
Point3d m_ptMinDist1 ;
|
||||
Point3d m_ptMinDist2 ;
|
||||
} ;
|
||||
+17
-4
@@ -14,9 +14,9 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DllMain.h"
|
||||
#include "DistPointCrvAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "DistPointCrvAux.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -116,6 +116,7 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
|
||||
vtDiff = ptQ - ptP ;
|
||||
// angolo tra vettore e tangente
|
||||
dTemp = vtDer1 * vtDiff ;
|
||||
bool bEquiverse = dTemp > 0 ;
|
||||
if ( abs( dTemp) > EPS_ZERO)
|
||||
dSqCosA = dTemp * dTemp / ( vtDer1.SqLen() * vtDiff.SqLen()) ;
|
||||
else
|
||||
@@ -123,8 +124,20 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
|
||||
// stima prossimo valore del parametro (Newton : Unext = U - F(U) / F'(U))
|
||||
dPrevPar = dPar ;
|
||||
dTemp = vtDer2 * vtDiff + vtDer1.SqLen() ;
|
||||
if ( abs( dTemp) > EPS_ZERO)
|
||||
dPar = dPrevPar - ( vtDer1 * vtDiff) / dTemp ;
|
||||
|
||||
// se il coseno tra questi due vettori è troppo grande potrei aver avuto una cattiva stima iniziale
|
||||
// provo quindi ad aggiustare a mano, anziché usare il segno suggerito da newton, che con queste premesse potrebbe divergere
|
||||
double dCos75 = 0.2588 ;
|
||||
if ( abs( dTemp) > EPS_ZERO) {
|
||||
double dDelta = ( vtDer1 * vtDiff) / dTemp ;
|
||||
if ( dSqCosA > dCos75) {
|
||||
if ( ( bEquiverse && dDelta > 0) || ( ! bEquiverse && dDelta < 0))
|
||||
dDelta *= -1 ;
|
||||
dPar = dPrevPar + dDelta ;
|
||||
}
|
||||
else
|
||||
dPar = dPrevPar - dDelta ;
|
||||
}
|
||||
// clipping parametro
|
||||
if ( dPar < approxMin.dParMin) {
|
||||
if ( approxMin.bParMinSing && ! bClampedFromSing) {
|
||||
|
||||
+12
-1
@@ -26,7 +26,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier&
|
||||
// distanza non calcolata
|
||||
m_dDist = - 1 ;
|
||||
|
||||
if ( &CrvBez == nullptr || ! CrvBez.IsValid())
|
||||
if ( ! CrvBez.IsValid())
|
||||
return ;
|
||||
|
||||
// determino tolleranza di approssimazione in base a ingombro curva
|
||||
@@ -42,6 +42,17 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier&
|
||||
if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
||||
return ;
|
||||
|
||||
int nDeg = CrvBez.GetDegree() ;
|
||||
if ( PL.GetPointNbr() < nDeg + 1) {
|
||||
// costruisco una polilinea con un numero di curve scelto in base al grado della curva
|
||||
PL.Clear() ;
|
||||
for ( int i = 0 ; i <= nDeg + 1 ; ++i) {
|
||||
double dU = double(i) / (nDeg + 1) ;
|
||||
Point3d ptBez ;
|
||||
CrvBez.GetPointD1D2( dU, ICurve::Side::FROM_MINUS, ptBez) ;
|
||||
PL.AddUPoint( dU, ptBez) ;
|
||||
}
|
||||
}
|
||||
// cerco la minima distanza per la polilinea
|
||||
MDCVECTOR vApproxMin ;
|
||||
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
|
||||
|
||||
@@ -50,7 +50,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
||||
}
|
||||
// altrimenti, per curve successive
|
||||
else {
|
||||
// verifico se la distanza minima dal box è superiore al minimo già trovato
|
||||
// verifico se la distanza minima dal box è superiore al minimo già trovato
|
||||
BBox3d b3B ;
|
||||
if ( pCrvSmpl->GetLocalBBox( b3B) &&
|
||||
b3B.SqDistFromPoint( ptP) <= m_dDist * m_dDist) {
|
||||
@@ -105,7 +105,7 @@ DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveCo
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
// con minima distanza più bassa
|
||||
// con minima distanza più bassa
|
||||
else if ( dCurrDist < m_dDist) {
|
||||
// aggiorno i minimi
|
||||
m_dDist = dCurrDist ;
|
||||
|
||||
+25
-12
@@ -13,10 +13,10 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistPointArc.h"
|
||||
#include "DistPointCrvBezier.h"
|
||||
#include "DistPointCrvComposite.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ DistPointCurve::DistPointCurve( const Point3d& ptP, const ICurve& Curve, bool bI
|
||||
case CRV_COMPO :
|
||||
CrvCompositeCalculate( ptP, Curve) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// salvo il punto
|
||||
m_ptP = ptP ;
|
||||
@@ -150,7 +152,7 @@ DistPointCurve::GetMinDistPoint( double dNearParam, Point3d& ptMinDist, int& nFl
|
||||
}
|
||||
}
|
||||
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
double dParam ;
|
||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||
if ( i == 0 ||
|
||||
@@ -195,7 +197,7 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int&
|
||||
}
|
||||
}
|
||||
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||
if ( i == 0 ||
|
||||
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
||||
@@ -209,13 +211,13 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int&
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide) const
|
||||
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide, double dTol) const
|
||||
{
|
||||
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
||||
return false ;
|
||||
|
||||
// se distanza nulla, il punto giace sulla curva
|
||||
if ( m_dDist <= EPS_SMALL) {
|
||||
if ( m_dDist <= dTol) {
|
||||
nSide = MDS_ON ;
|
||||
return true ;
|
||||
}
|
||||
@@ -230,9 +232,20 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
||||
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
||||
if ( ! vtTg.Normalize()) {
|
||||
double dDeltaU = 1000 * EPS_PARAM ;
|
||||
if ( ! m_pCurve->GetPointTang( m_Info[nInd].dPar - dDeltaU, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
||||
! m_pCurve->GetPointTang( m_Info[nInd].dPar + dDeltaU, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
||||
double dDeltaU = 1000 * EPS_PARAM ;
|
||||
double dParPre = m_Info[nInd].dPar - dDeltaU ;
|
||||
double dParPost = m_Info[nInd].dPar + dDeltaU ;
|
||||
// verifico se il parametro deve essere modificato per adattarsi a curva chiusa
|
||||
if ( m_pCurve->IsClosed()) {
|
||||
double dParS, dParE ;
|
||||
m_pCurve->GetDomain( dParS, dParE) ;
|
||||
if ( dParPre < dParS)
|
||||
dParPre = dParE - dDeltaU ;
|
||||
if ( dParPost > dParE)
|
||||
dParPost = dParS + dDeltaU ;
|
||||
}
|
||||
if ( ! m_pCurve->GetPointTang( dParPre, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
||||
! m_pCurve->GetPointTang( dParPost, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
||||
return false ;
|
||||
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||
if ( ! vtTg.Normalize( EPS_ZERO))
|
||||
@@ -246,7 +259,7 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
||||
|
||||
// determino il lato di giacitura del punto
|
||||
double dSide = vtRef * ( m_ptP - ptQ) ;
|
||||
if ( abs( dSide) < EPS_SMALL)
|
||||
if ( abs( dSide) < dTol)
|
||||
nSide = MDS_ON ;
|
||||
else if ( dSide > 0)
|
||||
nSide = MDS_LEFT ;
|
||||
@@ -257,12 +270,12 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide) const
|
||||
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide, double dTol) const
|
||||
{
|
||||
if ( m_dDist < 0 || m_Info.empty())
|
||||
return false ;
|
||||
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||
int nInd ;
|
||||
double dParam ;
|
||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||
@@ -273,7 +286,7 @@ DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, i
|
||||
}
|
||||
}
|
||||
// mi sono ricondotto al caso precedente
|
||||
return GetSideAtMinDistPoint( nInd, vtN, nSide) ;
|
||||
return GetSideAtMinDistPoint( nInd, vtN, nSide, dTol) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+4
-4
@@ -1,19 +1,19 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
// EgalTech 2013-2024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistPointLine.cpp Data : 17.12.13 Versione : 1.4l1
|
||||
// File : DistPointLine.cpp Data : 20.05.24 Versione : 2.6e5
|
||||
// Contenuto : Implementazione della classe distanza punto da linea/segmento.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 17.12.13 DS Creazione modulo.
|
||||
//
|
||||
// 20.05.24 DS Reso pubblico in Include.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2014
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistPointLine.h Data : 02.01.14 Versione : 1.5a1
|
||||
// Contenuto : Dichiarazione della classe distanza punto da linea/segmento.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 30.12.12 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class DistPointLine
|
||||
{
|
||||
friend class DistPointCurve ;
|
||||
|
||||
public :
|
||||
DistPointLine( const Point3d& ptP,
|
||||
const ICurveLine& crvLine, bool bIsSegment = true) ;
|
||||
DistPointLine( const Point3d& ptP,
|
||||
const Point3d& ptIni, const Point3d& ptFin, bool bIsSegment = true) ;
|
||||
DistPointLine( const Point3d& ptP,
|
||||
const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment = true) ;
|
||||
|
||||
public :
|
||||
bool GetSqDist( double& dSqDist) const ;
|
||||
bool GetDist( double& dDist) const ;
|
||||
bool IsEpsilon( double dTol) const
|
||||
{ double dSqDist ; return ( GetSqDist( dSqDist) && ( dSqDist < SQ_EPS_ZERO || dSqDist < dTol * dTol)) ; }
|
||||
bool IsSmall( void) const
|
||||
{ return IsEpsilon( EPS_SMALL) ; }
|
||||
bool IsZero( void) const
|
||||
{ return IsEpsilon( EPS_ZERO) ; }
|
||||
int GetNbrMinDist( void) const
|
||||
{ return (( m_dSqDist < 0) ? 0 : 1) ; }
|
||||
bool GetMinDistPoint( Point3d& ptMinDist) const ;
|
||||
bool GetParamAtMinDistPoint( double& dParam) const ;
|
||||
|
||||
private :
|
||||
DistPointLine( void) ;
|
||||
void Calculate( const Point3d& ptP,
|
||||
const Point3d& ptIni, const Vector3d& vtDir, double dLen, bool bIsSegment) ;
|
||||
|
||||
private :
|
||||
double m_dSqDist ;
|
||||
mutable double m_dDist ;
|
||||
double m_dParam ;
|
||||
Point3d m_ptMinDist ;
|
||||
} ;
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistPointSurfBz.cpp Data : 29.10.25 Versione : 2.7j3
|
||||
// Contenuto : Implementazione della classe distanza Punto da superficie Bezier.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 29.10.25 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfBz.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DistPointSurfBz::DistPointSurfBz( const Point3d& ptP, const ISurfBezier& pSrfBz)
|
||||
: m_dDist( -1), m_bIsInside( false), m_bIsSurfClosed( false)
|
||||
{
|
||||
// Bezier non valida
|
||||
if ( ! pSrfBz.IsValid())
|
||||
return ;
|
||||
// Calcolo la distanza
|
||||
Calculate( ptP, pSrfBz) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
DistPointSurfBz::Calculate( const Point3d& ptP, const ISurfBezier& srfBz)
|
||||
{
|
||||
// Inizializzo distanza non calcolata
|
||||
m_dDist = -1 ;
|
||||
|
||||
// Controllo se la superficie è chiusa
|
||||
m_bIsSurfClosed = srfBz.IsClosed() ;
|
||||
|
||||
// Lavoro con l'oggetto superficie trimesh di base
|
||||
const ISurfTriMesh* pStmRef = srfBz.GetAuxSurfRefined() ;
|
||||
if ( pStmRef == nullptr)
|
||||
return ;
|
||||
|
||||
DistPointSurfTm dpst( ptP, *pStmRef) ;
|
||||
|
||||
// recupero il punto a distanza minima sulla trimesh e lo raffino, prima di restituire distanza e punto minimo
|
||||
Point3d ptMinTm ; dpst.GetMinDistPoint( ptMinTm) ;
|
||||
int nT ; dpst.GetMinDistTriaIndex( nT) ;
|
||||
// salvo il punto corrispondente nel parametrico
|
||||
srfBz.UnprojectPointFromStm( nT, ptMinTm, m_ptParam) ;
|
||||
// salvo il punto a minima distanza sulla superficie e la normale alla superficie in quel punto
|
||||
srfBz.GetPointNrmD1D2( m_ptParam.x, m_ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, m_ptMinDistPoint, m_vtN) ;
|
||||
|
||||
// salvo la distanza minima
|
||||
m_dDist = Dist( ptP, m_ptMinDistPoint) ;
|
||||
// se il punto è sulla superficie
|
||||
if ( m_dDist < EPS_SMALL) {
|
||||
m_bIsInside = false ;
|
||||
return ;
|
||||
}
|
||||
else {
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * m_vtN < - EPS_SMALL) ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfBz::GetDist( double& dDist) const
|
||||
{
|
||||
// Distanza non valida
|
||||
if ( m_dDist < -EPS_ZERO)
|
||||
return false ;
|
||||
// Distanza valida
|
||||
dDist = m_dDist ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfBz::GetMinDistPoint( Point3d& ptMinDistPoint) const
|
||||
{
|
||||
// Distanza non valida
|
||||
if ( m_dDist < -EPS_ZERO)
|
||||
return false ;
|
||||
// Distanza valida
|
||||
ptMinDistPoint = m_ptMinDistPoint ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfBz::GetParamsAtMinDistPoint( double& dU, double& dV) const
|
||||
{
|
||||
// Distanza non valida
|
||||
if ( m_dDist < -EPS_ZERO)
|
||||
return false ;
|
||||
// Distanza valida
|
||||
dU = m_ptParam.x ;
|
||||
dV = m_ptParam.y ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfBz::GetNorm( Vector3d& vtN) const
|
||||
{
|
||||
// Distanza non valida
|
||||
if ( m_dDist < -EPS_ZERO)
|
||||
return false ;
|
||||
// Distanza valida
|
||||
vtN = m_vtN ;
|
||||
return true ;
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2018-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : DistPointSurfTm.cpp Data : 19.12.20 Versione : 2.2l3
|
||||
// Contenuto : Implementazione della classe distanza Punto da Trimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 07.12.18 LM Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
DistPointSurfFr::DistPointSurfFr( const Point3d& ptP, const ISurfFlatRegion& frSurf)
|
||||
: m_dDist( -1)
|
||||
{
|
||||
// FlatRegion non valida
|
||||
if ( &frSurf == nullptr || ! frSurf.IsValid())
|
||||
return ;
|
||||
// Calcolo la distanza
|
||||
Calculate( ptP, frSurf) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
DistPointSurfFr::Calculate( const Point3d& ptP, const ISurfFlatRegion& frSurf)
|
||||
{
|
||||
// Inizializzo distanza non calcolata
|
||||
m_dDist = -1 ;
|
||||
|
||||
// Converto regione in classe base
|
||||
const SurfFlatRegion* pSfr = GetBasicSurfFlatRegion( &frSurf) ;
|
||||
if ( pSfr == nullptr)
|
||||
return ;
|
||||
|
||||
// ciclo sulle parti della regione
|
||||
for ( int nC = 0 ; nC < pSfr->GetChunkCount() ; nC ++) {
|
||||
// ciclo sui loop della parte di regione
|
||||
for ( int nL = 0 ; nL < pSfr->GetLoopCount( nC) ; nL ++) {
|
||||
PtrOwner<ICurve> pLoop( pSfr->GetLoop( nC, nL)) ;
|
||||
if ( IsNull( pLoop)) {
|
||||
m_dDist = -1 ;
|
||||
return ;
|
||||
}
|
||||
DistPointCurve DPL( ptP, *pLoop) ;
|
||||
double dDist ;
|
||||
if ( DPL.GetDist( dDist) && ( m_dDist < -EPS_SMALL || dDist < m_dDist)) {
|
||||
m_dDist = dDist ;
|
||||
int nFlag ;
|
||||
m_nMinChunk = nC ;
|
||||
m_nMinLoop = nL ;
|
||||
DPL.GetParamAtMinDistPoint( 0, m_dMinPar, nFlag) ;
|
||||
DPL.GetMinDistPoint( 0, m_ptMinDistPoint, nFlag) ;
|
||||
DPL.GetSideAtMinDistPoint( 0, pSfr->GetNormVersor(), m_nSide) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovata, aggiorno minima distanza sul piano
|
||||
if ( m_dDist > - EPS_SMALL) {
|
||||
Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ;
|
||||
m_dDistOnPlane = min( Dist( ptOn, m_ptMinDistPoint), m_dDist) ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfFr::GetDist( double& dDist) const
|
||||
{
|
||||
if ( m_dDist < 0)
|
||||
return false ;
|
||||
dDist = m_dDist ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfFr::GetDistOnRegionPlane( double& dDist) const
|
||||
{
|
||||
if ( m_dDist < 0)
|
||||
return false ;
|
||||
dDist = m_dDistOnPlane ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfFr::GetPointAtMinDist( Point3d& ptMinDist) const
|
||||
{
|
||||
if ( m_dDist < 0)
|
||||
return false ;
|
||||
ptMinDist = m_ptMinDistPoint ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfFr::GetParamAtMinDist( int& nMinChunk, int& nMinLoop, double& dMinPar) const
|
||||
{
|
||||
if ( m_dDist < 0)
|
||||
return false ;
|
||||
nMinChunk = m_nMinChunk ;
|
||||
nMinLoop = m_nMinLoop ;
|
||||
dMinPar = m_dMinPar ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfFr::GetSideAtMinDist( int& nSide) const
|
||||
{
|
||||
if ( m_dDist < 0)
|
||||
return false ;
|
||||
nSide = m_nSide ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IsPointInsideSurfFr( const Point3d& ptP, const ISurfFlatRegion* pSfr, double dMinDist, bool& bInside, int& nChunk)
|
||||
{
|
||||
// default non include
|
||||
bInside = false ;
|
||||
nChunk = -1 ;
|
||||
// verifica regione
|
||||
if ( pSfr == nullptr || ! pSfr->IsValid())
|
||||
return false ;
|
||||
// verifico se la proiezione del punto sul piano della regione sta nel suo box
|
||||
Point3d ptOn = ptP - ( ptP - pSfr->GetPlanePoint()) * pSfr->GetNormVersor() * pSfr->GetNormVersor() ;
|
||||
BBox3d b3Box ;
|
||||
pSfr->GetLocalBBox( b3Box) ;
|
||||
b3Box.Expand( dMinDist) ;
|
||||
if ( ! b3Box.Encloses( ptOn))
|
||||
return true ;
|
||||
// determino dove sta il punto
|
||||
DistPointSurfFr DPR( ptP, *pSfr) ;
|
||||
double dDist ; int nMinCh, nMinL; double dMinPar ; int nSide ;
|
||||
if ( DPR.GetDistOnRegionPlane( dDist) && DPR.GetParamAtMinDist( nMinCh, nMinL, dMinPar) && DPR.GetSideAtMinDist( nSide)) {
|
||||
if ( abs( dMinDist) < EPS_SMALL)
|
||||
bInside = ( nSide != PRS_OUT) ;
|
||||
else if ( dMinDist < 0)
|
||||
bInside = ( nSide == PRS_IN && dDist > abs( dMinDist) - EPS_SMALL) ;
|
||||
else
|
||||
bInside = ( nSide != PRS_OUT || dDist < dMinDist + EPS_SMALL) ;
|
||||
if ( bInside)
|
||||
nChunk = nMinCh ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
+117
-30
@@ -15,15 +15,16 @@
|
||||
#include "SurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Calcola la differenza fra i bounding-box A e B.
|
||||
// L'insieme differenza non è un bounding-box, ma è esprimibile come unione di al più sei bounding-box.
|
||||
// L'insieme differenza non è un bounding-box, ma è esprimibile come unione di al più sei bounding-box.
|
||||
// Se l'insieme differenza fra i box non ha misura nulla viene restituito true, false altrimenti.
|
||||
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
|
||||
// nel box B; uno di questi si verifica se il box A è vuoto.
|
||||
// I casi in cui non vengono trovati box di misura positiva sono quelli in cui o il box A è contenuto
|
||||
// nel box B; uno di questi si verifica se il box A è vuoto.
|
||||
// Nel vettore vBoxDiff vengono restituiti i box la cui unione costituisce la differenza fra A e B.
|
||||
static bool
|
||||
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||
@@ -33,7 +34,7 @@ BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDi
|
||||
// Se box A vuoto, risultato vuoto
|
||||
if ( boxA.IsEmpty())
|
||||
return false ;
|
||||
// Se box B vuoto o i box non si intersecano, risultato è ancora A
|
||||
// Se box B vuoto o i box non si intersecano, risultato è ancora A
|
||||
BBox3d boxInt ;
|
||||
if ( boxB.IsSmall() || ! boxA.FindIntersection( boxB, boxInt)) {
|
||||
vBoxDiff.emplace_back( boxA) ;
|
||||
@@ -93,6 +94,10 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
{
|
||||
// Inizializzo distanza non calcolata
|
||||
m_dDist = - 1. ;
|
||||
// Vettore di indici dei triangoli più vicini inizialmente vuoto
|
||||
m_vnMinDistTriaIndex.clear() ;
|
||||
// Controllo se la superficie è chiusa
|
||||
m_bIsSurfClosed = tmSurf.IsClosed() ;
|
||||
|
||||
// Lavoro con l'oggetto superficie trimesh di base
|
||||
const SurfTriMesh* pStm = GetBasicSurfTriMesh( &tmSurf) ;
|
||||
@@ -104,8 +109,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( b3Stm.IsEmpty())
|
||||
return ;
|
||||
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||
@@ -115,14 +120,17 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
BBox3d boxPPrev( ptP) ;
|
||||
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||
// Variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
int nMinDistTriaIndex = SVT_NULL ;
|
||||
Point3d ptMinDistPoint ;
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
pStm->ResetTempInts() ;
|
||||
bool bContinue = true ;
|
||||
|
||||
// creazione del vettore dei triangoli più vicini a ptP
|
||||
vector<pair<int, Triangle3d>> vTria ; // <indice triangolo, Triangolo>
|
||||
while ( bContinue) {
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
BOXVECTOR vBox ;
|
||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||
// Ciclo sui box differenza
|
||||
@@ -130,12 +138,12 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
for ( const auto& b3Box : vBox) {
|
||||
// interseco il box con quello della superficie e ne verifico la distanza minima dal punto
|
||||
BBox3d b3Int ;
|
||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.SqDistFromPoint( ptP) > dMinSqDist)
|
||||
if ( ! b3Box.FindIntersection( b3Stm, b3Int) || b3Int.DistFromPoint( ptP) > dMinDist)
|
||||
continue ;
|
||||
// ricerca sui triangoli nel box
|
||||
bCollide = true ;
|
||||
INTVECTOR vnIds ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
INTVECTOR vnIds ;
|
||||
if ( pStm->GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||
// Ciclo sui triangoli del sotto-box corrente
|
||||
for ( auto nT : vnIds) {
|
||||
int nTriaTemp ;
|
||||
@@ -143,19 +151,30 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( pStm->GetTempInt( nT, nTriaTemp) && nTriaTemp == 0 && pStm->GetTriangle( nT, trCurTria)) {
|
||||
pStm->SetTempInt( nT, 1) ;
|
||||
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||
double dCurSqDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetSqDist( dCurSqDist) && dCurSqDist < dMinSqDist) {
|
||||
dMinSqDist = dCurSqDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
double dCurrDist ;
|
||||
// Se la distanza del triangolo è valida e minore di quella attuale aggiorno
|
||||
if ( distPT.GetDist( dCurrDist)) {
|
||||
// se distanze uguali...
|
||||
if ( abs( dCurrDist - dMinDist) < EPS_SMALL)
|
||||
// aggiungo il triangolo
|
||||
vTria.emplace_back( make_pair( nT, trCurTria)) ;
|
||||
// se minore...
|
||||
else if ( dCurrDist < dMinDist) {
|
||||
// pulisco il vettore
|
||||
vTria.clear() ;
|
||||
dMinDist = dCurrDist ;
|
||||
nMinDistTriaIndex = nT ;
|
||||
distPT.GetMinDistPoint( ptMinDistPoint) ;
|
||||
// aggiungo il triangolo
|
||||
vTria.emplace_back( make_pair( nT, trCurTria)) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Se si verifica la condizione di terminazione arresto il ciclo altrimenti aggiorno i box
|
||||
if ( ! bCollide || dMinSqDist < EPS_SMALL * EPS_SMALL)
|
||||
if ( ! bCollide || dMinDist < EPS_SMALL)
|
||||
bContinue = false ;
|
||||
else {
|
||||
boxPPrev = boxP ;
|
||||
@@ -163,15 +182,71 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
}
|
||||
}
|
||||
|
||||
if ( nMinDistTriaIndex != SVT_NULL) {
|
||||
m_dDist = sqrt( max( dMinSqDist, 0.)) ;
|
||||
// se non ho trovato nessun triangolo, esco
|
||||
if ( nMinDistTriaIndex == SVT_NULL)
|
||||
return ;
|
||||
|
||||
// Inizializzo il vettore dei triangoli a minima distanza
|
||||
for ( auto& Tria : vTria)
|
||||
m_vnMinDistTriaIndex.emplace_back( Tria.first) ;
|
||||
|
||||
// salvo la distanza minima
|
||||
m_dDist = dMinDist ;
|
||||
// salvo il punto a distanza minima
|
||||
m_ptMinDistPoint = ptMinDistPoint ;
|
||||
// se il punto è sulla TriMesh...
|
||||
if ( m_dDist < EPS_SMALL) {
|
||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
||||
m_ptMinDistPoint = ptMinDistPoint ;
|
||||
Triangle3d trMinDistTria ;
|
||||
pStm->GetTriangle( m_nMinDistTriaIndex, trMinDistTria) ;
|
||||
trMinDistTria.Validate() ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * trMinDistTria.GetN() < - EPS_SMALL) && pStm->IsClosed() ;
|
||||
m_bIsInside = false ;
|
||||
return ;
|
||||
}
|
||||
// se ho un solo triangolo, allora deduco le informazioni da lui
|
||||
else if ( int( vTria.size()) == 1) {
|
||||
m_nMinDistTriaIndex = vTria.back().first ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * vTria.back().second.GetN() < - EPS_SMALL) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
// controllo se tutti i triangoli a minima distanza forniscono la stessa informazione
|
||||
// ( il punto potrebbe essere esterno a tutti, interno a tutti o indefinito )
|
||||
bool bInside = false ;
|
||||
bool bOutside = false ;
|
||||
for ( int i = 0 ; i < int( vTria.size()) ; ++ i) { // scorro i triangoli a minima distanza
|
||||
if ( ( ptP - vTria[i].second.GetP( 0)) * vTria[i].second.GetN() < - EPS_SMALL)
|
||||
bInside = true ;
|
||||
else
|
||||
bOutside = true ;
|
||||
}
|
||||
|
||||
// inizializzo le variabili membro
|
||||
m_nMinDistTriaIndex = nMinDistTriaIndex ;
|
||||
m_bIsInside = false ;
|
||||
|
||||
// se le informazioni non sono coerenti, allora :
|
||||
// 1) calcolo i centroidi dei triangoli in questione
|
||||
// 2) ottengo il punto medio di questi centroidi
|
||||
// 3) controllo quale triangolo interseca il segmento che parte da ptP e arriva a tale punto
|
||||
// 4) userò questo triangolo per classificare ptP
|
||||
if ( bOutside == bInside) {
|
||||
// calcolo il baricentro complessivo
|
||||
Point3d ptBar_tot ;
|
||||
for ( auto& Tria : vTria)
|
||||
ptBar_tot += Tria.second.GetCentroid() ;
|
||||
ptBar_tot /= int( vTria.size()) ;
|
||||
// per ogni triangolo, cerco quello che interseca il segmento
|
||||
for ( auto& Tria : vTria) {
|
||||
Point3d ptInters1, ptInters2 ;
|
||||
int nType = IntersLineTria( ptP, ptBar_tot, Tria.second, ptInters1, ptInters2) ;
|
||||
if ( nType == ILTT_IN) { // se intersezione ho finito
|
||||
DistPointTriangle( ptP, Tria.second).GetMinDistPoint( m_ptMinDistPoint) ;
|
||||
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * Tria.second.GetN() < - EPS_SMALL) ;
|
||||
m_nMinDistTriaIndex = Tria.first ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // se informazioni coerenti
|
||||
m_bIsInside = bInside ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -210,6 +285,18 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DistPointSurfTm::GetMinDistTriaIndices( INTVECTOR& vMinDistTriaIndex) const
|
||||
{
|
||||
// Distanza non valida
|
||||
if ( m_dDist < - EPS_ZERO)
|
||||
return false ;
|
||||
// Distanza valida
|
||||
vMinDistTriaIndex = m_vnMinDistTriaIndex ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
@@ -224,8 +311,8 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
if ( b3Stm.IsEmpty())
|
||||
return SVT_NULL ;
|
||||
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
// Cerco triangoli in box centrati sul punto dato di ampiezza crescente ed escludendo le parti già verificate.
|
||||
// Termino quando non trovo più triangoli che possano soddisfare la richiesta.
|
||||
Point3d ptMin, ptMax ; b3Stm.GetMinMax( ptMin, ptMax) ;
|
||||
double dDeltaLen = max( min( min( b3Stm.GetDimX(), b3Stm.GetDimY()), b3Stm.GetDimZ()) / 40., 20.) ;
|
||||
double dBoxHalfLenX = max( max( ptMin.x - ptP.x, ptP.x - ptMax.x), 0.) + dDeltaLen ;
|
||||
@@ -237,11 +324,11 @@ GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||
// Variabili distanza minima
|
||||
int nVert = SVT_NULL ;
|
||||
double dMinSqDist = DBL_MAX ;
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
// Finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||
pStm->ResetTempInts() ;
|
||||
bool bContinue = true ;
|
||||
while ( bContinue) {
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
// Calcolo il box differenza con il precedente per non esplorare parti già considerate
|
||||
BOXVECTOR vBox ;
|
||||
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||
// Ciclo sui box differenza
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||
|
||||
|
||||
|
||||
+12
-3
@@ -159,11 +159,20 @@ InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
|
||||
{
|
||||
// recupero il font manager
|
||||
FontManager& fntMgr = FontManager::GetFontManager() ;
|
||||
|
||||
// lo inizializzo
|
||||
fntMgr.Init( sNfeFontDir, sDefaultFont) ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void
|
||||
SetDefaultFont( const string& sDefaultFont)
|
||||
{
|
||||
// recupero il font manager
|
||||
FontManager& fntMgr = FontManager::GetFontManager() ;
|
||||
// imposto il dato
|
||||
fntMgr.SetDefaultFont( sDefaultFont) ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
const string&
|
||||
GetNfeFontDir( void)
|
||||
@@ -185,11 +194,11 @@ GetDefaultFont( void)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static pfProcEvents s_pFunProcEvents = nullptr ;
|
||||
static psfProcEvents s_pFunProcEvents = nullptr ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool
|
||||
SetEGkProcessEvents( pfProcEvents pFun)
|
||||
SetEGkProcessEvents( psfProcEvents pFun)
|
||||
{
|
||||
s_pFunProcEvents = pFun ;
|
||||
return ( pFun != nullptr) ;
|
||||
|
||||
Binary file not shown.
+23
-10
@@ -22,7 +22,7 @@
|
||||
<ProjectGuid>{9A98A202-2853-454A-84CA-DCD1714176C9}</ProjectGuid>
|
||||
<RootNamespace>EgtGeomKernel</RootNamespace>
|
||||
<Keyword>MFCDLLProj</Keyword>
|
||||
<WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@@ -30,7 +30,7 @@
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>v141_xp</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -46,7 +46,7 @@
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<PlatformToolset>v141_xp</PlatformToolset>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
@@ -116,7 +116,7 @@
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -151,7 +151,7 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
@@ -199,7 +199,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -245,7 +245,7 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||
<IntelJCCErratum>true</IntelJCCErratum>
|
||||
</ClCompile>
|
||||
@@ -281,6 +281,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="BBox3d.cpp" />
|
||||
<ClCompile Include="BiArcs.cpp" />
|
||||
<ClCompile Include="CalcPocketing.cpp" />
|
||||
<ClCompile Include="CalcDerivate.cpp" />
|
||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||
@@ -309,6 +311,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CurveByApprox.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||
<ClCompile Include="DistPointSurfBz.cpp" />
|
||||
<ClCompile Include="DistPointSurfFr.cpp" />
|
||||
<ClCompile Include="IntersCurvePlane.cpp" />
|
||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||
@@ -318,26 +323,36 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||
<ClCompile Include="IntersLineSurfBez.cpp" />
|
||||
<ClCompile Include="Trimming.cpp" />
|
||||
<ClCompile Include="MultiGeomDB.cpp" />
|
||||
<ClCompile Include="SurfTriMeshOffset.cpp" />
|
||||
<ClCompile Include="VolZmapOffset.cpp" />
|
||||
<ClCompile Include="PolygonElevation.cpp" />
|
||||
<ClCompile Include="Quaternion.cpp" />
|
||||
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
||||
<ClCompile Include="RotationXplaneFrame.cpp" />
|
||||
<ClCompile Include="SbzFromCurves.cpp" />
|
||||
<ClCompile Include="SbzStandard.cpp" />
|
||||
<ClCompile Include="Voronoi.cpp" />
|
||||
<ClInclude Include="..\Include\EGkCDeClosedSurfTmClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeConeFrustumClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeConvexTorusClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkCDeRectPrismoidClosedSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkDistLineLine.h" />
|
||||
<ClInclude Include="..\Include\EGkDistPointLine.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersCurveSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersLineBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
||||
<ClInclude Include="..\Include\EGkMultiGeomDB.h" />
|
||||
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
||||
<ClInclude Include="..\Include\EGkQuaternion.h" />
|
||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
||||
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
||||
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
||||
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h" />
|
||||
<ClInclude Include="CAvSilhouetteSurfTm.h" />
|
||||
<ClInclude Include="CDeBoxTria.h" />
|
||||
<ClInclude Include="CDeCapsTria.h" />
|
||||
<ClInclude Include="CDeConeFrustumTria.h" />
|
||||
@@ -423,7 +438,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="OffsetCurveOnX.cpp" />
|
||||
<ClCompile Include="Polygon3d.cpp" />
|
||||
<ClCompile Include="AdjustLoops.cpp" />
|
||||
<ClCompile Include="ProjectCurveSurfTm.cpp" />
|
||||
<ClCompile Include="ProjectCurveSurf.cpp" />
|
||||
<ClCompile Include="RemoveCurveDefects.cpp" />
|
||||
<ClCompile Include="SelfIntersCurve.cpp" />
|
||||
<ClCompile Include="SfrCreate.cpp" />
|
||||
@@ -595,12 +610,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="CAvSimpleSurfFrMove.h" />
|
||||
<ClInclude Include="CAvToolSurfTm.h" />
|
||||
<ClInclude Include="CreateCurveAux.h" />
|
||||
<ClInclude Include="DistLineLine.h" />
|
||||
<ClInclude Include="DistPointArc.h" />
|
||||
<ClInclude Include="DistPointCrvAux.h" />
|
||||
<ClInclude Include="DistPointCrvBezier.h" />
|
||||
<ClInclude Include="DistPointCrvComposite.h" />
|
||||
<ClInclude Include="DistPointLine.h" />
|
||||
<ClInclude Include="DllMain.h" />
|
||||
<ClInclude Include="earcut.hpp" />
|
||||
<ClInclude Include="ExtDimension.h" />
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
<Filter Include="File di origine\GeoCollisionDetection">
|
||||
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="File di origine\GeoStriping">
|
||||
<UniqueIdentifier>{54901321-08f6-4428-80c7-a1f859136a32}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Vector3d.cpp">
|
||||
@@ -486,7 +489,7 @@
|
||||
<ClCompile Include="IntersLineCaps.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ProjectCurveSurfTm.cpp">
|
||||
<ClCompile Include="ProjectCurveSurf.cpp">
|
||||
<Filter>File di origine\GeoProject</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SubtractProjectedFacesOnStmFace.cpp">
|
||||
@@ -537,6 +540,36 @@
|
||||
<ClCompile Include="Quaternion.cpp">
|
||||
<Filter>File di origine\Base</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp">
|
||||
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SbzFromCurves.cpp">
|
||||
<Filter>File di origine\GeoCreate</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DistPointSurfFr.cpp">
|
||||
<Filter>File di origine\GeoDist</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="VolZmapOffset.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SurfTriMeshOffset.cpp">
|
||||
<Filter>File di origine\GeoOffset</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MultiGeomDB.cpp">
|
||||
<Filter>File di origine\Gdb</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DistPointSurfBz.cpp">
|
||||
<Filter>File di origine\GeoDist</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersCurvePlane.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Trimming.cpp">
|
||||
<Filter>File di origine\GeoStriping</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CalcDerivate.cpp">
|
||||
<Filter>File di origine\Geo</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -593,9 +626,6 @@
|
||||
<ClInclude Include="DistPointArc.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistPointLine.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistPointCrvBezier.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
@@ -1118,9 +1148,6 @@
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DistLineLine.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CDeUtility.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
@@ -1214,6 +1241,21 @@
|
||||
<ClInclude Include="..\Include\EGkQuaternion.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkDistLineLine.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkDistPointLine.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CAvSilhouetteSurfTm.h">
|
||||
<Filter>File di intestazione</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkMultiGeomDB.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+1
-1
@@ -1087,7 +1087,7 @@ ExtDimension::Update( void) const
|
||||
if ( m_nType == DT_RADIAL)
|
||||
sVal = "R " + sVal ;
|
||||
else if ( m_nType == DT_DIAMETRAL)
|
||||
sVal = u8"\u00D8 " + sVal ;
|
||||
sVal = reinterpret_cast<const char *>( u8"\u00D8") + sVal ;
|
||||
ReplaceString( m_sCalcText, IS_MEASURE, sVal) ;
|
||||
}
|
||||
// punto di inserimento del testo
|
||||
|
||||
@@ -147,6 +147,10 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
// verifico il minimo raggio
|
||||
if ( dRadius < 10 * EPS_SMALL)
|
||||
return nullptr ;
|
||||
|
||||
// eseguo calcoli
|
||||
Point3d ptCen, ptTg1, ptTg2 ;
|
||||
int nSide1, nSide2 ;
|
||||
@@ -165,6 +169,11 @@ CreateFillet( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
// verifico dimensione minima
|
||||
double dLen = Dist( ptTg1, ptTg2) ;
|
||||
if ( dLen < 2 * EPS_SMALL)
|
||||
return nullptr ;
|
||||
|
||||
// orientamento tra le curve
|
||||
bool bCCW = ( dSinA > 0) ;
|
||||
|
||||
@@ -207,6 +216,10 @@ CreateChamfer( const ICurve& cCrv1, const Point3d& ptNear1,
|
||||
&vtNorm == nullptr || &dPar1 == nullptr || &dPar2 == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
// verifico lo smusso minimo
|
||||
if ( dDist < 10 * EPS_SMALL)
|
||||
return nullptr ;
|
||||
|
||||
// calcolo un riferimento sul piano perpendicolare alla normale
|
||||
Frame3d frIntr ;
|
||||
if ( ! frIntr.Set( ORIG, vtNorm))
|
||||
|
||||
+3
-1
@@ -29,6 +29,8 @@ class FontManager
|
||||
|
||||
public :
|
||||
bool Init( const std::string& sNfeFontDir, const std::string& sDefaultFont) ;
|
||||
bool SetDefaultFont( const std::string& sDefaultFont)
|
||||
{ m_sDefaultFont = sDefaultFont ; return true ; }
|
||||
bool SetCurrFont( const std::string& sFont, int nWeight, bool bItalic,
|
||||
double dHeight, double dRatio, double dAddAdvance) ;
|
||||
const std::string& GetNfeFontDir( void) const
|
||||
@@ -54,7 +56,7 @@ class FontManager
|
||||
OsFont m_OsFont ;
|
||||
|
||||
private :
|
||||
FontManager( void) {}
|
||||
FontManager( void) : m_bCurrNfeFont( false) {}
|
||||
FontManager( FontManager const& copy) = delete ;
|
||||
FontManager& operator=( FontManager const& copy) = delete ;
|
||||
} ;
|
||||
|
||||
+2
-2
@@ -493,7 +493,7 @@ NfeFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECT
|
||||
int nLbLen ;
|
||||
if ( IsLineBreak( vCode, i, nLbLen)) {
|
||||
// salvo la linea, se contiene qualcosa
|
||||
if ( vTmpCode.size() > 0) {
|
||||
if ( ! vTmpCode.empty()) {
|
||||
string sLine ;
|
||||
SetCodePoints( vTmpCode, sLine) ;
|
||||
vLine.push_back( sLine) ;
|
||||
@@ -523,7 +523,7 @@ NfeFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECT
|
||||
dMaxW = vtMove.x ;
|
||||
}
|
||||
// salvo eventuale ultima linea
|
||||
if ( vTmpCode.size() > 0) {
|
||||
if ( ! vTmpCode.empty()) {
|
||||
string sLine ;
|
||||
SetCodePoints( vTmpCode, sLine) ;
|
||||
vLine.push_back( sLine) ;
|
||||
|
||||
+2
-2
@@ -619,7 +619,7 @@ OsFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTO
|
||||
int nLbLen ;
|
||||
if ( IsLineBreak( vCode, i, nLbLen)) {
|
||||
// salvo la linea, se contiene qualcosa
|
||||
if ( vTmpCode.size() > 0) {
|
||||
if ( ! vTmpCode.empty()) {
|
||||
string sLine ;
|
||||
SetCodePoints( vTmpCode, sLine) ;
|
||||
vLine.push_back( sLine) ;
|
||||
@@ -646,7 +646,7 @@ OsFont::GetTextLines( const string& sText, int nInsPos, PNTVECTOR& vPt, STRVECTO
|
||||
dMaxW = vtMove.x ;
|
||||
}
|
||||
// salvo eventuale ultima linea
|
||||
if ( vTmpCode.size() > 0) {
|
||||
if ( ! vTmpCode.empty()) {
|
||||
string sLine ;
|
||||
SetCodePoints( vTmpCode, sLine) ;
|
||||
vLine.push_back( sLine) ;
|
||||
|
||||
+17
@@ -37,6 +37,23 @@ Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX,
|
||||
! m_vtVersZ.Normalize())
|
||||
return false ;
|
||||
|
||||
// se ci sono errori molto piccoli di ortogonalità, li correggo
|
||||
double dOrtXZ = m_vtVersX * m_vtVersZ ;
|
||||
if ( dOrtXZ > EPS_ZERO && dOrtXZ < 10 * EPS_ZERO) {
|
||||
m_vtVersX = OrthoCompo( m_vtVersX, m_vtVersZ) ;
|
||||
m_vtVersX.Normalize() ;
|
||||
}
|
||||
double dOrtYX = m_vtVersY * m_vtVersX ;
|
||||
if ( dOrtYX > EPS_ZERO && dOrtYX < 10 * EPS_ZERO) {
|
||||
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersX) ;
|
||||
m_vtVersY.Normalize() ;
|
||||
}
|
||||
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
||||
if ( dOrtYZ > EPS_ZERO && dOrtYZ < 10 * EPS_ZERO) {
|
||||
m_vtVersY = OrthoCompo( m_vtVersY, m_vtVersZ) ;
|
||||
m_vtVersY.Normalize() ;
|
||||
}
|
||||
|
||||
// verifica della ortogonalità dei versori e del senso destrorso
|
||||
if ( ! Verify())
|
||||
return false ;
|
||||
|
||||
+5
-5
@@ -2267,7 +2267,7 @@ bool
|
||||
GdbExecutor::SurfTriMeshEnd( const STRVECTOR& vsParams)
|
||||
{
|
||||
// nessun parametro
|
||||
if ( vsParams.size() != 0)
|
||||
if ( ! vsParams.empty())
|
||||
return false ;
|
||||
// recupero la superficie
|
||||
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
|
||||
@@ -6632,7 +6632,7 @@ GdbExecutor::ExecuteDeselect( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// deselezione di tutto
|
||||
else if ( sCmd2 == "ALL") {
|
||||
// nessun parametro
|
||||
if ( vsParams.size() != 0)
|
||||
if ( ! vsParams.empty())
|
||||
return false ;
|
||||
// cancello selezione oggetti
|
||||
if ( ! m_pGDB->ClearSelection())
|
||||
@@ -7773,7 +7773,7 @@ bool
|
||||
GdbExecutor::ExecuteNew( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
{
|
||||
// nessun parametro
|
||||
if ( vsParams.size() != 0)
|
||||
if ( ! vsParams.empty())
|
||||
return false ;
|
||||
// pulizia e reinizializzazione del DB geometrico
|
||||
m_pGDB->Clear() ;
|
||||
@@ -7946,7 +7946,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
// chiudo il file di uscita Tsc
|
||||
else if ( sCmd2 == "CLOSE") {
|
||||
// nessun parametro
|
||||
if ( vsParams.size() != 0)
|
||||
if ( ! vsParams.empty())
|
||||
return false ;
|
||||
// scrivo terminazioni e chiudo il file
|
||||
return m_OutTsc.Close() ;
|
||||
@@ -7969,7 +7969,7 @@ GdbExecutor::ExecuteOutTsc( const string& sCmd2, const STRVECTOR& vsParams)
|
||||
else if ( sCmd2 == "SETGR") {
|
||||
Frame3d frF ;
|
||||
// nessun parametro
|
||||
if ( vsParams.size() == 0)
|
||||
if ( vsParams.empty())
|
||||
frF.Reset() ;
|
||||
// un parametro ( Id del gruppo)
|
||||
else if ( vsParams.size() == 1) {
|
||||
|
||||
+2
-2
@@ -336,7 +336,7 @@ GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe
|
||||
// curva originale
|
||||
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
||||
// trasformo in curva di Bezier (semplice o composta)
|
||||
ICurve* pCrvNew = ArcToBezierCurve( pCrv) ;
|
||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( pCrv)) ;
|
||||
if ( pCrvNew == nullptr)
|
||||
return false ;
|
||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
||||
@@ -389,7 +389,7 @@ GdbGeo::Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDi
|
||||
if ( ! pArc->IsPlane() ||
|
||||
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
||||
// trasformo in curva di Bezier (semplice o composta)
|
||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
|
||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( m_pGeoObj)) ;
|
||||
if ( pCrvNew == nullptr)
|
||||
return false ;
|
||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
||||
|
||||
+2
-2
@@ -1254,13 +1254,13 @@ GdbIterator::GetCalcStatus( int& nStat) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbIterator::SetMark( void)
|
||||
GdbIterator::SetMark( int nMark)
|
||||
{
|
||||
if ( m_pGDB == nullptr || m_pCurrObj == nullptr)
|
||||
return false ;
|
||||
|
||||
// imposto la marcatura
|
||||
return m_pCurrObj->SetMark() ;
|
||||
return m_pCurrObj->SetMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+1
-1
@@ -103,7 +103,7 @@ class GdbIterator : public IGdbIterator
|
||||
bool RevertStatus( void) override ;
|
||||
bool GetStatus( int& nStat) const override ;
|
||||
bool GetCalcStatus( int& nStat) const override ;
|
||||
bool SetMark( void) override ;
|
||||
bool SetMark( int nMark = GDB_MK_ON) override ;
|
||||
bool ResetMark( void) override ;
|
||||
bool GetMark( int& nMark) const override ;
|
||||
bool GetCalcMark( int& nMark) const override ;
|
||||
|
||||
+18
-4
@@ -101,6 +101,20 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
||||
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::CopyStippleDataFrom( const GdbObj* pSou)
|
||||
{
|
||||
// se l'oggetto sorgente non esiste
|
||||
if ( pSou == nullptr)
|
||||
return false ;
|
||||
// copio stipple
|
||||
m_nStpFactor = pSou->m_nStpFactor ;
|
||||
m_nStpPattern = pSou->m_nStpPattern ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::CopyAttribsFrom( const GdbObj* pSou)
|
||||
@@ -612,14 +626,14 @@ GdbObj::GetCalcStatus( int& nStat, int nLev) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GdbObj::SetMark( void)
|
||||
GdbObj::SetMark( int nMark)
|
||||
{
|
||||
// verifico esistenza (con eventuale creazione) degli attributi
|
||||
if ( GetSafeAttribs() == nullptr)
|
||||
return false ;
|
||||
|
||||
// assegno la marcatura
|
||||
m_pAttribs->SetMark() ;
|
||||
m_pAttribs->SetMark( nMark) ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -659,8 +673,8 @@ GdbObj::GetCalcMark( int& nMark) const
|
||||
nObjMark = m_pAttribs->GetMark() ;
|
||||
|
||||
// se la marcatura è ON, non ho bisogno di sapere altro
|
||||
if ( nObjMark == GDB_MK_ON) {
|
||||
nMark = GDB_MK_ON ;
|
||||
if ( nObjMark == GDB_MK_ON || nObjMark == GDB_MK_ON_2) {
|
||||
nMark = nObjMark ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class GdbObj
|
||||
GdbObj( void) ;
|
||||
bool CopyFrom( const GdbObj* pSou) ;
|
||||
bool CopyAttribsFrom( const GdbObj* pSou) ;
|
||||
bool CopyStippleDataFrom( const GdbObj* pSou) ;
|
||||
bool CopyTextureDataFrom( const GdbObj* pSou) ;
|
||||
bool CopyUserObjFrom( const GdbObj* pSou) ;
|
||||
|
||||
@@ -81,7 +82,7 @@ class GdbObj
|
||||
bool IsSelected( void) const ;
|
||||
bool GetStatus( int& nStat) const ;
|
||||
bool GetCalcStatus( int& nStat, int nLev = 0) const ;
|
||||
bool SetMark( void) ;
|
||||
bool SetMark( int nMark) ;
|
||||
bool ResetMark( void) ;
|
||||
bool GetMark( int& nMark) const ;
|
||||
bool GetCalcMark( int& nMark) const ;
|
||||
|
||||
+35
-35
@@ -28,41 +28,6 @@
|
||||
#define GEOOBJ_NGEIDTOTYPE( nNgeId) GeoObjFactory::NgeIdToType( nNgeId)
|
||||
#define GEOOBJ_CREATE( nKey) GeoObjFactory::Create( nKey)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
class GeoObjRegister
|
||||
{
|
||||
public :
|
||||
static bool DoRegister( int nKey, int nNgeId)
|
||||
{ if ( ! GeoObjFactory::Register( nKey, NgeAscKeyW[nNgeId], nNgeId, Create))
|
||||
return false ;
|
||||
GetTypePrivate() = nKey ;
|
||||
GetKeyPrivate() = NgeAscKeyW[nNgeId] ;
|
||||
GetNgeIdPrivate() = nNgeId ;
|
||||
return true ; }
|
||||
static IGeoObj* Create( void)
|
||||
{ return new( std::nothrow) T ; }
|
||||
static int GetType( void)
|
||||
{ return GetTypePrivate() ; }
|
||||
static const std::string& GetKey( void)
|
||||
{ return GetKeyPrivate() ; }
|
||||
static int GetNgeId( void)
|
||||
{ return GetNgeIdPrivate() ; }
|
||||
|
||||
private :
|
||||
GeoObjRegister( void) {}
|
||||
~GeoObjRegister( void) {}
|
||||
static int& GetTypePrivate( void)
|
||||
{ static int s_nType ;
|
||||
return s_nType ; }
|
||||
static std::string& GetKeyPrivate( void)
|
||||
{ static std::string s_sKey ;
|
||||
return s_sKey ; }
|
||||
static int& GetNgeIdPrivate( void)
|
||||
{ static int s_nNgeId ;
|
||||
return s_nNgeId ; }
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class GeoObjFactory
|
||||
{
|
||||
@@ -117,3 +82,38 @@ class GeoObjFactory
|
||||
{ static CreatorMap s_CreatorMap ;
|
||||
return s_CreatorMap ; }
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
template <class T>
|
||||
class GeoObjRegister
|
||||
{
|
||||
public :
|
||||
static bool DoRegister( int nKey, int nNgeId)
|
||||
{ if ( ! GeoObjFactory::Register( nKey, NgeAscKeyW[nNgeId], nNgeId, Create))
|
||||
return false ;
|
||||
GetTypePrivate() = nKey ;
|
||||
GetKeyPrivate() = NgeAscKeyW[nNgeId] ;
|
||||
GetNgeIdPrivate() = nNgeId ;
|
||||
return true ; }
|
||||
static IGeoObj* Create( void)
|
||||
{ return new( std::nothrow) T ; }
|
||||
static int GetType( void)
|
||||
{ return GetTypePrivate() ; }
|
||||
static const std::string& GetKey( void)
|
||||
{ return GetKeyPrivate() ; }
|
||||
static int GetNgeId( void)
|
||||
{ return GetNgeIdPrivate() ; }
|
||||
|
||||
private :
|
||||
GeoObjRegister( void) {}
|
||||
~GeoObjRegister( void) {}
|
||||
static int& GetTypePrivate( void)
|
||||
{ static int s_nType ;
|
||||
return s_nType ; }
|
||||
static std::string& GetKeyPrivate( void)
|
||||
{ static std::string s_sKey ;
|
||||
return s_sKey ; }
|
||||
static int& GetNgeIdPrivate( void)
|
||||
{ static int s_nNgeId ;
|
||||
return s_nNgeId ; }
|
||||
} ;
|
||||
|
||||
+15
-13
@@ -38,20 +38,22 @@ using namespace std ;
|
||||
class LockAddErase
|
||||
{
|
||||
public :
|
||||
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
LockAddErase( atomic_flag& bAddEraseOn, bool bUse = true)
|
||||
: m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||
{ if ( ! m_bUse) return ;
|
||||
while ( m_bAddEraseOn.test_and_set()) {
|
||||
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
|
||||
while ( m_bAddEraseOn.test_and_set( memory_order_acquire)) {
|
||||
m_bAddEraseOn.wait( true, memory_order_relaxed) ;
|
||||
}
|
||||
} ;
|
||||
|
||||
~LockAddErase( void)
|
||||
{ if ( ! m_bUse) return ;
|
||||
m_bAddEraseOn.clear() ;
|
||||
m_bAddEraseOn.clear( memory_order_release) ;
|
||||
m_bAddEraseOn.notify_one() ;
|
||||
} ;
|
||||
|
||||
private :
|
||||
std::atomic_flag& m_bAddEraseOn ;
|
||||
atomic_flag& m_bAddEraseOn ;
|
||||
bool m_bUse ;
|
||||
} ;
|
||||
|
||||
@@ -611,7 +613,7 @@ GeomDB::GetGdbObj( int nId) const
|
||||
// radice
|
||||
else if ( nId == GDB_ID_ROOT)
|
||||
return &m_GrpRadix ;
|
||||
// un nodo qualubque
|
||||
// un nodo qualunque
|
||||
else
|
||||
return m_IdManager.FindObj( nId) ;
|
||||
}
|
||||
@@ -658,7 +660,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLo
|
||||
return false ;
|
||||
}
|
||||
// inserisco come figlio, in testa alla lista del padre
|
||||
else if ( nSonBeforeAfter == GDB_FIRST_SON){
|
||||
else if ( nSonBeforeAfter == GDB_FIRST_SON) {
|
||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||
if ( pGroup == nullptr)
|
||||
return false ;
|
||||
@@ -877,7 +879,7 @@ GeomDB::GetFirstNameInGroup( int nGroupId, const string& sName) const
|
||||
// se ha il nome o la parte iniziale di nome cercato
|
||||
string sObjName ;
|
||||
if ( pGdbO->GetName( sObjName) &&
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
||||
return ( pGdbO->m_nId) ;
|
||||
// passo al successivo
|
||||
pGdbO = pGdbO->GetNext() ;
|
||||
@@ -905,7 +907,7 @@ GeomDB::GetNextName( int nId, const string& sName) const
|
||||
// se ha il nome o la parte iniziale di nome cercato
|
||||
string sObjName ;
|
||||
if ( pGdbNext->GetName( sObjName) &&
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
||||
return ( pGdbNext->m_nId) ;
|
||||
// passo al successivo
|
||||
pGdbNext = pGdbNext->GetNext() ;
|
||||
@@ -933,7 +935,7 @@ GeomDB::GetLastNameInGroup( int nGroupId, const string& sName) const
|
||||
// se ha il nome o la parte iniziale di nome cercato
|
||||
string sObjName ;
|
||||
if ( pGdbO->GetName( sObjName) &&
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
||||
return ( pGdbO->m_nId) ;
|
||||
// passo al precedente
|
||||
pGdbO = pGdbO->GetPrev() ;
|
||||
@@ -961,7 +963,7 @@ GeomDB::GetPrevName( int nId, const string& sName) const
|
||||
// se ha il nome o la parte iniziale di nome cercato
|
||||
string sObjName ;
|
||||
if ( pGdbPrev->GetName( sObjName) &&
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.find( sToFind) == 0)))
|
||||
(( ! bWild && sObjName == sToFind) || ( bWild && sObjName.rfind( sToFind, 0) == 0)))
|
||||
return ( pGdbPrev->m_nId) ;
|
||||
// passo al precedente
|
||||
pGdbPrev = pGdbPrev->GetPrev() ;
|
||||
@@ -2310,7 +2312,7 @@ GeomDB::GetCalcStatus( int nId, int& nStat) const
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GeomDB::SetMark( int nId)
|
||||
GeomDB::SetMark( int nId, int nMark)
|
||||
{
|
||||
// recupero l'oggetto
|
||||
GdbObj* pGdbObj = GetGdbObj( nId) ;
|
||||
@@ -2318,7 +2320,7 @@ GeomDB::SetMark( int nId)
|
||||
return false ;
|
||||
|
||||
// imposto la marcatura
|
||||
return pGdbObj->SetMark() ;
|
||||
return pGdbObj->SetMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -29,6 +29,10 @@ class GeomDB : public IGeomDB
|
||||
friend class GdbObj ;
|
||||
friend class GdbGroup ;
|
||||
friend class GdbGeo ;
|
||||
friend int CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
friend int CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||
friend int DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId) ;
|
||||
friend int DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp) ;
|
||||
|
||||
public :
|
||||
~GeomDB( void) override ;
|
||||
@@ -136,7 +140,7 @@ class GeomDB : public IGeomDB
|
||||
bool RevertStatus( int nId) override ;
|
||||
bool GetStatus( int nId, int& nStat) const override ;
|
||||
bool GetCalcStatus( int nId, int& nStat) const override ;
|
||||
bool SetMark( int nId) override ;
|
||||
bool SetMark( int nId, int nMark = GDB_MK_ON) override ;
|
||||
bool ResetMark( int nId) override ;
|
||||
bool GetMark( int nId, int& nMark) const override ;
|
||||
bool GetCalcMark( int nId, int& nMark) const override ;
|
||||
|
||||
+13
-13
@@ -116,7 +116,7 @@ HashGrid1d::~HashGrid1d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -396,8 +396,10 @@ HashGrid1d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_CellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_CellCount *= 2 ;
|
||||
@@ -569,7 +571,7 @@ HashGrids1d::Update( void)
|
||||
// Salvo stato di precedente attivazione delle griglie
|
||||
bool bGridActivePrev = m_bGridActive ;
|
||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||
if ( m_objsToAdd.size() > 0 ) {
|
||||
if ( ! m_objsToAdd.empty()) {
|
||||
for ( auto pObj : m_objsToAdd) {
|
||||
if ( m_bGridActive)
|
||||
addGrid( *pObj) ;
|
||||
@@ -634,24 +636,22 @@ HashGrids1d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
sort( vnIds.begin(), vnIds.end()) ;
|
||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
return ( ! vnIds.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids1d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+13
-13
@@ -125,7 +125,7 @@ HashGrid2d::~HashGrid2d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -445,8 +445,10 @@ HashGrid2d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_xCellCount *= 2 ;
|
||||
@@ -623,7 +625,7 @@ HashGrids2d::Update( void)
|
||||
// Salvo stato di precedente attivazione delle griglie
|
||||
bool bGridActivePrev = m_bGridActive ;
|
||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||
if ( m_objsToAdd.size() > 0 ) {
|
||||
if ( ! m_objsToAdd.empty()) {
|
||||
for ( auto pObj : m_objsToAdd) {
|
||||
if ( m_bGridActive)
|
||||
addGrid( *pObj) ;
|
||||
@@ -688,24 +690,22 @@ HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
sort( vnIds.begin(), vnIds.end()) ;
|
||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
return ( ! vnIds.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
HashGrids2d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+13
-13
@@ -132,7 +132,7 @@ HashGrid3d::~HashGrid3d( void)
|
||||
{
|
||||
Clear() ;
|
||||
|
||||
for ( Cell* pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
for ( Cell* pCell = m_cell ; pCell != nullptr && pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
}
|
||||
@@ -486,8 +486,10 @@ HashGrid3d::Enlarge( void)
|
||||
for ( auto pCell = m_cell ; pCell < m_cell + m_xyzCellCount ; ++ pCell) {
|
||||
if ( pCell->m_neighborOffset != m_stdNeighborOffset)
|
||||
delete[] pCell->m_neighborOffset ;
|
||||
pCell->m_neighborOffset = nullptr ;
|
||||
}
|
||||
delete[] m_cell ;
|
||||
m_cell = nullptr ;
|
||||
|
||||
// ... the number of cells is doubled in each coordinate direction, ...
|
||||
m_xCellCount *= 2 ;
|
||||
@@ -667,7 +669,7 @@ HashGrids3d::Update( void)
|
||||
// Salvo stato di precedente attivazione delle griglie
|
||||
bool bGridActivePrev = m_bGridActive ;
|
||||
// Inseriamo gli oggetti presenti nel vettore m_objsToAdd
|
||||
if ( m_objsToAdd.size() > 0 ) {
|
||||
if ( ! m_objsToAdd.empty()) {
|
||||
for ( auto pObj : m_objsToAdd) {
|
||||
if ( m_bGridActive)
|
||||
addGrid( *pObj) ;
|
||||
@@ -731,7 +733,7 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
sort( vnIds.begin(), vnIds.end()) ;
|
||||
vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
return ( ! vnIds.empty()) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -739,17 +741,15 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
void
|
||||
HashGrids3d::Clear( void)
|
||||
{
|
||||
for ( auto pGrid : m_GridList) {
|
||||
delete pGrid ;
|
||||
}
|
||||
m_GridList.clear() ;
|
||||
|
||||
m_bGridActive = false ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
|
||||
m_ObjsList.clear() ;
|
||||
m_ObjsMap.clear() ;
|
||||
m_objsToAdd.clear() ;
|
||||
|
||||
m_nonGridObjs.clear() ;
|
||||
for ( auto pGrid : m_GridList)
|
||||
delete pGrid ;
|
||||
m_GridList.clear() ;
|
||||
m_bActivate = true ;
|
||||
m_bGridActive = false ;
|
||||
m_b3Objs.Reset() ;
|
||||
}
|
||||
|
||||
|
||||
+8
-5
@@ -17,6 +17,9 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static const double EPS_INTER_ARC = 0.1 * EPS_SMALL ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
{
|
||||
@@ -60,15 +63,15 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
vtDir /= dDist ;
|
||||
|
||||
// cerchi esterni -> nessuna intersezione
|
||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_SMALL)
|
||||
if ( dDist > m_Arc1.GetRadius() + m_Arc2.GetRadius() + EPS_INTER_ARC)
|
||||
return ;
|
||||
|
||||
// cerchi interni -> nessuna intersezione
|
||||
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_SMALL)
|
||||
if ( dDist < abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) - EPS_INTER_ARC)
|
||||
return ;
|
||||
|
||||
// cerchi coincidenti -> sovrapposizioni e/o intersezioni agli estremi
|
||||
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_SMALL) {
|
||||
if ( dDist < EPS_SMALL && abs( m_Arc1.GetRadius() - m_Arc2.GetRadius()) < EPS_INTER_ARC) {
|
||||
// coefficiente da parametro dell'arco 1 a lunghezza
|
||||
double dU2L = abs( m_Arc1.GetAngCenter()) * DEGTORAD * m_Arc1.GetRadius() ;
|
||||
// determino se sono equiversi o controversi
|
||||
@@ -236,7 +239,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
double dSqH = m_Arc1.GetRadius() * m_Arc1.GetRadius() - dA * dA ;
|
||||
|
||||
// cerchi tangenti esterni -> una intersezione
|
||||
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
if ( abs( dDist - ( m_Arc1.GetRadius() + m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
||||
// tolleranza tangenziale sull'intersezione
|
||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||
// calcolo il punto di intersezione
|
||||
@@ -358,7 +361,7 @@ IntersArcArc::IntersArcArc( const CurveArc& Arc1, const CurveArc& Arc2)
|
||||
}
|
||||
|
||||
// cerchi tangenti interni -> una intersezione
|
||||
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_SMALL) {
|
||||
if ( abs( dDist - abs( m_Arc1.GetRadius() - m_Arc2.GetRadius())) < EPS_INTER_ARC) {
|
||||
// tolleranza tangenziale sull'intersezione
|
||||
double dTgTol = ( dSqH > SQ_EPS_SMALL ? sqrt( dSqH) : EPS_SMALL) ;
|
||||
// determino quale dei due contiene l'altro
|
||||
|
||||
+455
-128
@@ -19,14 +19,15 @@
|
||||
#include "/EgtDev/Include/EGkAngle.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids2d.h"
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//--------------------------- Local functions --------------------------------
|
||||
static bool CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||
bool bCrvAClosed, double dCrvASpan) ;
|
||||
bool bCrvAClosed, double dCrvASpan, bool bOrderedOnB = false) ;
|
||||
static bool CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||
bool bCrvBClosed, double dCrvBSpan) ;
|
||||
bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB = false) ;
|
||||
static void MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crvCompo) ;
|
||||
static int GetCrvBDirAPrev( IntCrvCrvInfo& Icci) ;
|
||||
static int GetCrvBDirANext( IntCrvCrvInfo& Icci) ;
|
||||
@@ -197,7 +198,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// se coincidono U e ptInt tra A e B
|
||||
if ( abs( m_Info[i].IciA[0].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
|
||||
AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL)) {
|
||||
// se non è alla fine di curva chiusa
|
||||
// se non è alla fine di curva chiusa
|
||||
if ( ! bCrvAClosed || abs( m_Info[j].IciA[0].dU - dCrvBSpan) > EPS_SMALL)
|
||||
// elimino la seconda
|
||||
EraseOtherInfo( i, j) ;
|
||||
@@ -261,10 +262,9 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM &&
|
||||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso DET-NULL -> NULL-DET per prima curva
|
||||
// caso DET-(NULL) -> (NULL)-DET per prima curva
|
||||
else if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) {
|
||||
// per la prima curva tengo i determinati
|
||||
@@ -272,16 +272,22 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
// se overlap equiverso
|
||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
|
||||
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||
}
|
||||
// se overlap equiverso
|
||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||
@@ -292,6 +298,13 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
}
|
||||
|
||||
// medio parametri e punti separatamente per le due curve
|
||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||
@@ -306,7 +319,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
EraseCurrentInfo( i, j) ;
|
||||
}
|
||||
}
|
||||
// caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa)
|
||||
// caso (NULL)-DET -> DET-(NULL) per prima curva (possibile su inizio/fine di curva chiusa)
|
||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
||||
m_Info[i].IciA[ki].nPrevTy != ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
// per la prima curva tengo i determinati
|
||||
@@ -314,28 +327,41 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
// se overlap equiverso
|
||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||
}
|
||||
// se overlap equiverso
|
||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||
m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
}
|
||||
|
||||
// medio parametri e punti separatamente per le due curve
|
||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||
@@ -356,8 +382,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-DET -> NULL-DET per prima curva con NULL-NULL -> NULL-NULL su seconda curva
|
||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
||||
@@ -365,18 +390,25 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-NULL per corrente di prima curva
|
||||
else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
m_Info[j].IciA[kj].nNextTy = ICCT_NULL ;
|
||||
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
||||
EraseCurrentInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-NULL per precedente di prima curva
|
||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
|
||||
m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
|
||||
m_Info[i].IciA[ki].nPrevTy = ICCT_NULL ;
|
||||
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
||||
EraseOtherInfo( i, j) ;
|
||||
}
|
||||
@@ -395,22 +427,21 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
continue ;
|
||||
}
|
||||
// calcolo sottoindici
|
||||
int ki = 0 ; // del successivo si prende sempre il primo
|
||||
int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
||||
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
|
||||
// verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL)
|
||||
if ( AreSamePointXYEpsilon( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI, 10 * EPS_SMALL) &&
|
||||
AreSamePointXYEpsilon( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI, 10 * EPS_SMALL) &&
|
||||
CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan) &&
|
||||
CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan)) {
|
||||
CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan, true) &&
|
||||
CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan, true)) {
|
||||
// caso entrambi Overlap ma di tipo opposto e sullo stesso tratto
|
||||
if ( m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq &&
|
||||
abs( m_Info[i].IciB[0].dU - m_Info[j].IciB[0].dU) < EPS_PARAM &&
|
||||
abs( m_Info[i].IciB[1].dU - m_Info[j].IciB[1].dU) < EPS_PARAM) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso DET-NULL -> NULL-DET per seconda curva
|
||||
// caso DET-(NULL) -> (NULL)-DET per seconda curva
|
||||
else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
|
||||
// per la seconda curva tengo i determinati
|
||||
@@ -418,28 +449,40 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
// se overlap equiverso
|
||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||
}
|
||||
// se overlap equiverso
|
||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
}
|
||||
// medio parametri e punti separatamente per le due curve
|
||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||
@@ -454,7 +497,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
EraseCurrentInfo( i, j) ;
|
||||
}
|
||||
}
|
||||
// caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa)
|
||||
// caso (NULL)-DET -> DET-(NULL) per seconda curva (possibile su inizio/fine di curva chiusa)
|
||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
||||
m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||
// per la seconda curva tengo i determinati
|
||||
@@ -462,28 +505,40 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
// se overlap equiverso
|
||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||
}
|
||||
// se overlap equiverso
|
||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||
}
|
||||
// se altrimenti overlap controverso
|
||||
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||
}
|
||||
else {
|
||||
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
}
|
||||
// medio parametri e punti separatamente per le due curve
|
||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||
@@ -504,8 +559,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-DET -> NULL-DET per seconda curva con NULL-NULL -> NULL-NULL su prima curva
|
||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
||||
@@ -513,22 +567,25 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
// cancello entrambe
|
||||
EraseOtherInfo( i, j) ;
|
||||
EraseCurrentInfo( i, j) ;
|
||||
EraseBothInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-NULL per corrente di seconda curva
|
||||
else if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||
if ( m_Info[i].IciA[ki].dU > m_Info[j].IciA[kj].dU + EPS_PARAM)
|
||||
m_Info[j].IciB[kj].nNextTy = ICCT_NULL ;
|
||||
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
||||
EraseCurrentInfo( i, j) ;
|
||||
}
|
||||
// caso NULL-NULL per precedente di seconda curva
|
||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL) {
|
||||
m_Info[i].IciB[0].nPrevTy = m_Info[j].IciB[0].nPrevTy ;
|
||||
if ( m_Info[j].IciA[0].dU < m_Info[i].IciA[0].dU - EPS_PARAM)
|
||||
m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
|
||||
m_Info[i].IciB[ki].nPrevTy = ICCT_NULL ;
|
||||
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
||||
EraseOtherInfo( i, j) ;
|
||||
}
|
||||
@@ -537,16 +594,16 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// ripristino ordinamento su prima curva
|
||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
|
||||
|
||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità
|
||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
// se il tipo di accostamento per la curva A non è definito
|
||||
// se il tipo di accostamento per la curva A non è definito
|
||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||
if ( i > 0 || ( bCrvAClosed && ! bAutoInters)) {
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
||||
}
|
||||
}
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
int ki = ( m_Info[i].bOverlap ? 1 : 0) ;
|
||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||
if ( i < m_nNumInters - 1 || ( bCrvAClosed && ! bAutoInters)) {
|
||||
@@ -556,21 +613,23 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
}
|
||||
}
|
||||
|
||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva B e cerco di risolverle per continuità
|
||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva B e cerco di risolverle per continuità
|
||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
// se il tipo di accostamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
||||
// se il tipo di accostamento per la curva B non è definito
|
||||
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL) {
|
||||
if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) {
|
||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||
m_Info[i].IciB[ki].nPrevTy = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||
}
|
||||
}
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
ki = ( m_Info[i].bOverlap && m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||
if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) {
|
||||
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
||||
m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
||||
m_Info[i].IciB[ki].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -581,7 +640,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
// in assenza di overlap
|
||||
if ( ! m_Info[i].bOverlap) {
|
||||
// se il tipo di accostamento per la curva A non è definito
|
||||
// se il tipo di accostamento per la curva A non è definito
|
||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
@@ -590,7 +649,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
}
|
||||
// se il tipo di accostamento per la curva B non è definito
|
||||
// se il tipo di accostamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
@@ -599,7 +658,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// aggiorno il tipo di accostamento della curva B alla curva A
|
||||
m_Info[i].IciB[0].nPrevTy = nType ;
|
||||
}
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
// se il tipo di allontanamento per la curva A non è definito
|
||||
if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
@@ -608,7 +667,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[0].nNextTy = nType ;
|
||||
}
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
// se il tipo di allontanamento per la curva B non è definito
|
||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
@@ -620,66 +679,68 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
}
|
||||
// in presenza di overlap
|
||||
else {
|
||||
// se il tipo di accostamento è non definito per la curva A
|
||||
// se il tipo di accostamento è non definito per la curva A
|
||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||
// se autointersezione con spike
|
||||
double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ;
|
||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
||||
CCompoB, m_Info[i].IciB[0].dU, nType)) {
|
||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[0].nNextTy = nType ;
|
||||
}
|
||||
// caso standard
|
||||
else {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
||||
CCompoB, m_Info[i].IciB[0].dU, nType)) {
|
||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[0].nNextTy = nType ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se il tipo di allontanamento è non definito per la curva A
|
||||
// se il tipo di allontanamento è non definito per la curva A
|
||||
if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) {
|
||||
// se autointersezione con spike
|
||||
double dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ;
|
||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
||||
CCompoB, m_Info[i].IciB[1].dU, nType)) {
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[1].nNextTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||
}
|
||||
// caso standard
|
||||
else {
|
||||
// devo studiare un intorno dell'intersezione
|
||||
int nType ;
|
||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
||||
CCompoB, m_Info[i].IciB[1].dU, nType)) {
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[1].nNextTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( bAutoInters) {
|
||||
// controllo l'eventuale presenza di spike
|
||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||
if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||
// se secondo tratto dello spike
|
||||
double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ;
|
||||
if ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM)) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[0].nNextTy = nType ;
|
||||
}
|
||||
// se primo tratto dello spike
|
||||
dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ;
|
||||
if ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM)) {
|
||||
// è punta di spike
|
||||
int nType = ICCT_SPK ;
|
||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||
m_Info[i].IciA[1].nNextTy = nType ;
|
||||
// aggiorno anche il corrispondente tipo sulla curva B
|
||||
if ( m_Info[i].bCBOverEq)
|
||||
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
||||
else
|
||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -693,10 +754,10 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
// se prima curva aperta, salto alla prossima
|
||||
if ( ! CCompoA.IsClosed())
|
||||
continue ;
|
||||
// è chiusa quindi prendo l'ultima
|
||||
// è chiusa quindi prendo l'ultima
|
||||
j = m_nNumInters - 1 ;
|
||||
}
|
||||
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
||||
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
||||
if ( i == j)
|
||||
break ;
|
||||
// assegno sottoindici (considero solo intersezioni overlap)
|
||||
@@ -724,7 +785,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
}
|
||||
}
|
||||
|
||||
// se è rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse
|
||||
// se è rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse
|
||||
if ( m_nNumInters == 1 && CCompoA.IsClosed() && CCompoB.IsClosed() &&
|
||||
m_Info[0].IciA[0].nPrevTy == ICCT_ON && m_Info[0].IciA[1].nNextTy == ICCT_ON &&
|
||||
GetCrvBDirANext( m_Info[0]) == ICCT_ON && GetCrvBDirAPrev( m_Info[0]) == ICCT_ON) {
|
||||
@@ -738,10 +799,243 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
||||
m_Info[0].IciB[1].dU = ( m_Info[0].bCBOverEq ? dEnd : dStart) ;
|
||||
}
|
||||
|
||||
// verifico se una curva ha tutte le info e queste info sono coerenti
|
||||
if ( m_nNumInters > 1 && ! bAutoInters) {
|
||||
bool bCoherent = true ;
|
||||
INTVECTOR vIncoherenceWithPrev ;
|
||||
INTVECTOR vNewOverlap ;
|
||||
// salvo eventuali incoerenze col precedente
|
||||
for ( int i = bCrvAClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
|
||||
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
|
||||
int kj = m_Info[j].bOverlap ? 1 : 0 ;
|
||||
if ( (m_Info[j].IciA[kj].nNextTy == ICCT_NULL || m_Info[i].IciA[0].nPrevTy == ICCT_NULL || m_Info[j].IciA[kj].nNextTy != m_Info[i].IciA[0].nPrevTy) &&
|
||||
m_Info[j].IciA[kj].nNextTy != ICCT_SPK && m_Info[i].IciA[0].nPrevTy != ICCT_SPK) {
|
||||
vIncoherenceWithPrev.push_back( i) ;
|
||||
bCoherent = false ;
|
||||
}
|
||||
}
|
||||
// incoerenze sulla curva A
|
||||
if ( ! bCoherent) {
|
||||
for ( int i : vIncoherenceWithPrev) {
|
||||
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
|
||||
int kj = m_Info[j].bOverlap ? 1 : 0 ;
|
||||
int nType = 0 ;
|
||||
CalcSide( j, i, &CCompoA, &CCompoB, true, nType) ;
|
||||
if ( nType != ICCT_ON) {
|
||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||
m_Info[j].IciA[kj].nNextTy = nType ;
|
||||
}
|
||||
else
|
||||
vNewOverlap.push_back( i) ;
|
||||
}
|
||||
}
|
||||
|
||||
// faccio il merge se ho trasformato delle intersezioni in overlap
|
||||
for ( int i : views::reverse( vNewOverlap))
|
||||
MergeNewOverlap( i, true) ;
|
||||
|
||||
vNewOverlap.clear() ;
|
||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
|
||||
bCoherent = true ;
|
||||
vIncoherenceWithPrev.clear() ;
|
||||
// salvo eventuali incoerenze col precedente
|
||||
for ( int i = bCrvBClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
|
||||
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
|
||||
int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ;
|
||||
int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ;
|
||||
if ( ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL || m_Info[i].IciB[ki].nPrevTy == ICCT_NULL || m_Info[j].IciB[kj].nNextTy != m_Info[i].IciB[ki].nPrevTy) &&
|
||||
m_Info[j].IciB[kj].nNextTy != ICCT_SPK && m_Info[i].IciB[ki].nPrevTy != ICCT_SPK) {
|
||||
vIncoherenceWithPrev.push_back( i) ;
|
||||
bCoherent = false ;
|
||||
}
|
||||
}
|
||||
// incoerenze sulla curva B
|
||||
if ( ! bCoherent) {
|
||||
for ( int i : vIncoherenceWithPrev) {
|
||||
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
|
||||
int ki = m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0 ;
|
||||
int kj = m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0 ;
|
||||
int nType = 0 ;
|
||||
CalcSide( j, i, &CCompoB, &CCompoA, false, nType) ;
|
||||
if ( nType != ICCT_ON) {
|
||||
m_Info[i].IciB[ki].nPrevTy = nType ;
|
||||
m_Info[j].IciB[kj].nNextTy = nType ;
|
||||
}
|
||||
else
|
||||
vNewOverlap.push_back( i) ;
|
||||
}
|
||||
}
|
||||
|
||||
// faccio il merge se ho trasformato delle intersezioni in overlap
|
||||
for ( int i : views::reverse( vNewOverlap))
|
||||
MergeNewOverlap( i, false) ;
|
||||
}
|
||||
else {
|
||||
// posso completare A guardando B e viceversa
|
||||
}
|
||||
|
||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
|
||||
// verifiche su intersezioni in zone non-manifold
|
||||
OrderNonManifoldInters( m_Info, CCompoA, CCompoB) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICurve* pOtherCrv, bool bCrvAOrB, int& nType)
|
||||
{
|
||||
const IntCrvCrvInfo& Icci1 = m_Info[j] ;
|
||||
const IntCrvCrvInfo& Icci2 = m_Info[i] ;
|
||||
// calcolo tra l'intersezione 1 e 2 se la curva sta dentro o fuori
|
||||
int kj = Icci1.bOverlap ? 1 : 0 ;
|
||||
double dU = 0 ;
|
||||
bool bPrevIsBefore = true ;
|
||||
if ( bCrvAOrB) {
|
||||
// se precedente minore del successivo faccio la media
|
||||
if ( Icci1.IciA[kj].dU < Icci2.IciA[0].dU)
|
||||
dU = ( Icci2.IciA[0].dU + Icci1.IciA[kj].dU) / 2 ;
|
||||
// altrimenti guardo tra lo start e il successivo
|
||||
else {
|
||||
bPrevIsBefore = false ;
|
||||
dU = ( Icci2.IciA[0].dU + 0.) / 2 ;
|
||||
if ( dU < EPS_SMALL) {
|
||||
double dStart, dEnd ;
|
||||
pThisCrv->GetDomain( dStart, dEnd) ;
|
||||
double dUNew = dEnd - Icci1.IciA[kj].dU / 2 ;
|
||||
if ( dUNew > dU)
|
||||
dU = dUNew ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// se precedente minore del successivo faccio la media
|
||||
if ( Icci1.IciB[kj].dU < Icci2.IciB[0].dU)
|
||||
dU = ( Icci2.IciB[0].dU + Icci1.IciB[kj].dU) / 2 ;
|
||||
// altrimenti guardi tra lo start e il successivo
|
||||
else {
|
||||
bPrevIsBefore = false ;
|
||||
dU = ( Icci2.IciB[0].dU + 0.) / 2 ;
|
||||
if ( dU < EPS_SMALL) {
|
||||
double dStart, dEnd ;
|
||||
pThisCrv->GetDomain( dStart, dEnd) ;
|
||||
double dUNew = dEnd - Icci1.IciB[kj].dU / 2 ;
|
||||
if ( dUNew > dU)
|
||||
dU = dUNew ;
|
||||
}
|
||||
}
|
||||
}
|
||||
Point3d ptTest ; pThisCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptTest) ;
|
||||
DistPointCurve dpc( ptTest, *pOtherCrv) ;
|
||||
dpc.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ;
|
||||
if ( nType == MDS_LEFT)
|
||||
nType = ICCT_IN ;
|
||||
else if ( nType == MDS_RIGHT)
|
||||
nType = ICCT_OUT ;
|
||||
// se lo trovo sulla curva controllo se posso definire un tratto overlap
|
||||
if ( nType == MDS_ON) {
|
||||
double dFactor = 1./3. ;
|
||||
DBLVECTOR vdU(2) ;
|
||||
bool bIsOn = false ;
|
||||
if ( bCrvAOrB) {
|
||||
if ( bPrevIsBefore) {
|
||||
vdU[0] = ( 1 - dFactor) * Icci2.IciA[0].dU + dFactor * Icci1.IciA[kj].dU ;
|
||||
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[0].dU + 2 * dFactor * Icci1.IciA[kj].dU ;
|
||||
}
|
||||
else if ( Icci2.IciA[0].dU > 2 * EPS_SMALL){
|
||||
vdU[0] = ( Icci2.IciA[0].dU + 0.) * dFactor ;
|
||||
vdU[1] = ( Icci2.IciA[0].dU + 0.) * 2 * dFactor ;
|
||||
}
|
||||
else
|
||||
bIsOn = true ;
|
||||
}
|
||||
else {
|
||||
if ( bPrevIsBefore) {
|
||||
vdU[0] = ( 1 - dFactor) * Icci2.IciB[0].dU + dFactor * Icci1.IciB[kj].dU ;
|
||||
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[0].dU + 2 * dFactor * Icci1.IciB[kj].dU ;
|
||||
}
|
||||
else if ( Icci2.IciB[0].dU > 2 * EPS_SMALL) {
|
||||
vdU[0] = ( Icci2.IciB[0].dU + 0.) * dFactor ;
|
||||
vdU[1] = ( Icci2.IciB[0].dU + 0.) * 2 * dFactor ;
|
||||
}
|
||||
else
|
||||
bIsOn = true ;
|
||||
}
|
||||
if ( ! bIsOn) {
|
||||
bIsOn = true ;
|
||||
for ( int k = 0 ; k < ssize(vdU) && bIsOn ; ++k) {
|
||||
Point3d ptTest2 ; pThisCrv->GetPointD1D2( vdU[k], ICurve::FROM_MINUS, ptTest2) ;
|
||||
DistPointCurve dpc2( ptTest2, *pOtherCrv) ;
|
||||
dpc2.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ;
|
||||
if ( nType != MDS_ON)
|
||||
bIsOn = false ;
|
||||
}
|
||||
}
|
||||
if ( bIsOn) {
|
||||
m_Info[i].bOverlap = true ;
|
||||
Vector3d vtDirThis, vtDirOther ;
|
||||
Point3d ptCommon ;
|
||||
double dUThis = 0 ;
|
||||
if ( bCrvAOrB)
|
||||
dUThis = m_Info[i].IciA[0].dU ;
|
||||
else
|
||||
dUThis = m_Info[i].IciB[0].dU ;
|
||||
pThisCrv->GetPointD1D2( dUThis, ICurve::Side::FROM_MINUS, ptCommon, &vtDirThis) ;
|
||||
double dUOther = 0 ; pOtherCrv->GetParamAtPoint( ptCommon, dUOther) ;
|
||||
pOtherCrv->GetPointD1D2( dUOther, ICurve::Side::FROM_MINUS, ptCommon, &vtDirOther) ;
|
||||
m_Info[i].bCBOverEq = vtDirThis * vtDirOther > 0 ;
|
||||
if ( m_Info[i].bCBOverEq) {
|
||||
m_Info[i].IciA[1] = m_Info[i].IciA[0] ;
|
||||
m_Info[i].IciB[1] = m_Info[i].IciB[0] ;
|
||||
m_Info[i].IciA[0] = m_Info[j].IciA[kj] ;
|
||||
m_Info[i].IciB[0] = m_Info[j].IciB[kj] ;
|
||||
m_Info[i].IciA[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciB[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciA[0].nNextTy = ICCT_ON ;
|
||||
m_Info[i].IciB[0].nNextTy = ICCT_ON ;
|
||||
}
|
||||
else {
|
||||
if ( bCrvAOrB) {
|
||||
m_Info[i].IciA[1] = m_Info[i].IciA[0] ;
|
||||
m_Info[i].IciA[0] = m_Info[j].IciA[kj] ;
|
||||
m_Info[i].IciA[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciA[0].nNextTy = ICCT_ON ;
|
||||
m_Info[i].IciB[1] = m_Info[j].IciB[kj] ;
|
||||
m_Info[i].IciB[0].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciB[1].nNextTy = ICCT_ON ;
|
||||
}
|
||||
else {
|
||||
m_Info[i].IciB[1] = m_Info[i].IciB[0] ;
|
||||
m_Info[i].IciB[0] = m_Info[j].IciB[kj] ;
|
||||
m_Info[i].IciB[1].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciB[0].nNextTy = ICCT_ON ;
|
||||
m_Info[i].IciA[1] = m_Info[j].IciA[kj] ;
|
||||
m_Info[i].IciA[0].nPrevTy = ICCT_ON ;
|
||||
m_Info[i].IciA[1].nNextTy = ICCT_ON ;
|
||||
}
|
||||
}
|
||||
nType = ICCT_ON ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCrvCompoCrvCompo::MergeNewOverlap( int i, bool bCrvAOrB)
|
||||
{
|
||||
// faccio il merge col precedente
|
||||
int j = i == 0 ? m_nNumInters - 1 : i - 1 ;
|
||||
if ( m_Info[j].bOverlap) {
|
||||
m_Info[i].IciA[0] = m_Info[j].IciA[0] ;
|
||||
m_Info[i].IciB[0] = m_Info[j].IciB[0] ;
|
||||
}
|
||||
m_Info.erase( m_Info.begin() + j) ;
|
||||
-- j ;
|
||||
-- m_nNumInters ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB,
|
||||
@@ -806,13 +1100,27 @@ bool
|
||||
IntersCrvCompoCrvCompo::EraseOtherInfo( int& nIndCurr, int& nIndOther)
|
||||
{
|
||||
m_Info.erase( m_Info.begin() + nIndOther) ;
|
||||
if ( nIndOther < nIndCurr)
|
||||
-- nIndCurr ;
|
||||
-- nIndCurr ;
|
||||
-- nIndOther ;
|
||||
-- m_nNumInters ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCrvCompoCrvCompo::EraseBothInfo( int& nIndCurr, int& nIndOther)
|
||||
{
|
||||
m_Info.erase( m_Info.begin() + nIndOther) ;
|
||||
-- nIndCurr ;
|
||||
-- nIndOther ;
|
||||
-- m_nNumInters ;
|
||||
m_Info.erase( m_Info.begin() + nIndCurr) ;
|
||||
if ( nIndCurr != -1)
|
||||
-- nIndCurr ;
|
||||
-- m_nNumInters ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Global functions
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -879,7 +1187,7 @@ SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
|
||||
bool
|
||||
OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& CurveB)
|
||||
{
|
||||
// questi controlli sono validi solo se la curva B è chiusa
|
||||
// questi controlli sono validi solo se la curva B è chiusa
|
||||
if ( ! CurveB.IsClosed())
|
||||
return false ;
|
||||
|
||||
@@ -908,7 +1216,7 @@ OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& Cu
|
||||
// se prima curva aperta, salto alla prossima
|
||||
if ( ! CurveA.IsClosed())
|
||||
continue ;
|
||||
// è chiusa quindi prendo l'ultima
|
||||
// è chiusa quindi prendo l'ultima
|
||||
j = nNumInters - 1 ;
|
||||
}
|
||||
// se i due indici coincidono, salto
|
||||
@@ -960,11 +1268,20 @@ OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& Cu
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||
bool bCrvAClosed, double dCrvASpan)
|
||||
bool bCrvAClosed, double dCrvASpan, bool bOrderedOnB)
|
||||
{
|
||||
int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
||||
if ( abs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) > 0.1 * SPAN_PARAM &&
|
||||
( ! bCrvAClosed || abs( abs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) - dCrvASpan) > 0.1 * SPAN_PARAM))
|
||||
int ki = 0 ;
|
||||
int kj = 0 ;
|
||||
if ( ! bOrderedOnB) {
|
||||
ki = 0 ;
|
||||
kj = Icci1.bOverlap ? 1 : 0 ;
|
||||
}
|
||||
else {
|
||||
ki = Icci2.bOverlap && ! Icci2.bCBOverEq ? 1 : 0 ;
|
||||
kj = Icci1.bOverlap && Icci1.bCBOverEq ? 1 : 0 ;
|
||||
}
|
||||
if ( abs( Icci1.IciA[kj].dU - Icci2.IciA[ki].dU) > 0.1 * SPAN_PARAM &&
|
||||
( ! bCrvAClosed || abs( abs( Icci1.IciA[kj].dU - Icci2.IciA[ki].dU) - dCrvASpan) > 0.1 * SPAN_PARAM))
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
@@ -972,11 +1289,21 @@ CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||
bool bCrvBClosed, double dCrvBSpan)
|
||||
bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB)
|
||||
{
|
||||
int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
||||
if ( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) > 0.1 * SPAN_PARAM &&
|
||||
( ! bCrvBClosed || abs( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM))
|
||||
int ki = 0 ;
|
||||
int kj = 0 ;
|
||||
if ( ! bOrderedOnB) {
|
||||
ki = 0 ;
|
||||
kj = Icci1.bOverlap ? 1 : 0 ;
|
||||
}
|
||||
else {
|
||||
ki = Icci2.bOverlap && ! Icci2.bCBOverEq ? 1 : 0 ;
|
||||
kj = Icci1.bOverlap && Icci1.bCBOverEq ? 1 : 0 ;
|
||||
}
|
||||
|
||||
if ( abs( Icci1.IciB[kj].dU - Icci2.IciB[ki].dU) > 0.1 * SPAN_PARAM &&
|
||||
( ! bCrvBClosed || abs( abs( Icci1.IciB[kj].dU - Icci2.IciB[ki].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM))
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
@@ -998,7 +1325,7 @@ MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crv
|
||||
//Point3d ptMed ;
|
||||
//if ( ! crvCompo.GetPointD1D2( dUmed, ICurve::FROM_MINUS, ptMed))
|
||||
// return ;
|
||||
// verifico che non sia più lontano dei punti originali dal loro medio
|
||||
// verifico che non sia più lontano dei punti originali dal loro medio
|
||||
//if ( SqDist( Ici1.ptI, ptMed) > dSqDist / 4)
|
||||
// return ;
|
||||
// medio i parametri
|
||||
@@ -1012,13 +1339,13 @@ MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crv
|
||||
static int
|
||||
GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
||||
{
|
||||
// non è overlap, è il prev del primo punto
|
||||
// non è overlap, è il prev del primo punto
|
||||
if ( ! Icci.bOverlap)
|
||||
return Icci.IciB[0].nPrevTy ;
|
||||
// è overlap equiverso, è il prev del primo punto
|
||||
// è overlap equiverso, è il prev del primo punto
|
||||
if ( Icci.bCBOverEq)
|
||||
return Icci.IciB[0].nPrevTy ;
|
||||
// è overlap controverso, è il next del primo punto
|
||||
// è overlap controverso, è il next del primo punto
|
||||
return Icci.IciB[0].nNextTy ;
|
||||
}
|
||||
|
||||
@@ -1028,13 +1355,13 @@ GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
||||
static int
|
||||
GetCrvBDirANext( IntCrvCrvInfo& Icci)
|
||||
{
|
||||
// non è overlap, è il next del primo punto
|
||||
// non è overlap, è il next del primo punto
|
||||
if ( ! Icci.bOverlap)
|
||||
return Icci.IciB[0].nNextTy ;
|
||||
// è overlap equiverso, è il next del secondo punto
|
||||
// è overlap equiverso, è il next del secondo punto
|
||||
if ( Icci.bCBOverEq)
|
||||
return Icci.IciB[1].nNextTy ;
|
||||
// è overlap controverso, è il prev del secondo punto
|
||||
// è overlap controverso, è il prev del secondo punto
|
||||
return Icci.IciB[1].nPrevTy ;
|
||||
}
|
||||
|
||||
@@ -1078,7 +1405,7 @@ CalcATypeFromDisk( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
||||
return false ;
|
||||
if ( dAngBpDeg < 0)
|
||||
dAngBpDeg += ANG_FULL ;
|
||||
// se l'angolo di DirA è compreso tra DirBn e DirBp (muovendosi in senso CCW) allora è IN, altrimenti OUT
|
||||
// se l'angolo di DirA è compreso tra DirBn e DirBp (muovendosi in senso CCW) allora è IN, altrimenti OUT
|
||||
if ( dAngADeg > 0 && dAngADeg < dAngBpDeg)
|
||||
nType = ICCT_IN ;
|
||||
else
|
||||
@@ -1151,12 +1478,12 @@ CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
||||
// li ordino in senso crescente
|
||||
if ( dAngB1pDeg > dAngB2pDeg)
|
||||
swap( dAngB1pDeg, dAngB2pDeg) ;
|
||||
// se non ci sono variazioni angolari significative, non posso decidere alcunché
|
||||
// se non ci sono variazioni angolari significative, non posso decidere alcunché
|
||||
const double MIN_DEV_ANG = 2 ;
|
||||
if ( abs( DiffAngle( dAngB1pDeg + ANG_STRAIGHT, 0)) < MIN_DEV_ANG &&
|
||||
abs( DiffAngle( dAngB2pDeg + ANG_STRAIGHT, dAngB2nDeg)) < MIN_DEV_ANG)
|
||||
return false ;
|
||||
// IN è tra 0 e dAngB1pDeg e tra dAngB2nDeg e dAngB2pDeg
|
||||
// IN è tra 0 e dAngB1pDeg e tra dAngB2nDeg e dAngB2pDeg
|
||||
if ( ( dAngADeg > 0 && dAngADeg < dAngB1pDeg) ||
|
||||
( dAngADeg > dAngB2nDeg && dAngADeg < dAngB2pDeg))
|
||||
nType = ICCT_IN ;
|
||||
|
||||
@@ -43,6 +43,9 @@ class IntersCrvCompoCrvCompo
|
||||
bool bAutoInters, bool bClosed, int nCurvesNbr) ;
|
||||
bool EraseCurrentInfo( int& nIndCurr, int& nIndOther) ;
|
||||
bool EraseOtherInfo( int& nIndCurr, int& nIndOther) ;
|
||||
bool EraseBothInfo( int& nIndCurr, int& nIndOther) ;
|
||||
bool CalcSide( int j, int i,const ICurve* pThisCrv, const ICurve* pOtherCrv, bool bCrvAOrB, int& nType) ;
|
||||
bool MergeNewOverlap( int i, bool bCrvAOrB) ;
|
||||
|
||||
private :
|
||||
bool m_bOverlaps ;
|
||||
|
||||
+90
-16
@@ -47,7 +47,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
|
||||
// ciclo sulle curve per verificare se da approssimare
|
||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
|
||||
m_pCurve[i]->GetType() == CRV_BEZIER) {
|
||||
// approssimo con rette
|
||||
@@ -78,6 +78,8 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
LineCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_ARC :
|
||||
@@ -91,6 +93,8 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
ArcCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
case CRV_COMPO :
|
||||
@@ -104,8 +108,12 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
||||
case CRV_COMPO :
|
||||
CrvCompoCrvCompoCalculate( *pCalcCrv[0], *pCalcCrv[1]) ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// per curve approssimate, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv[0] != m_pCurve[0]), ( pCalcCrv[1] != m_pCurve[1])) ;
|
||||
@@ -119,7 +127,7 @@ IntersCurveCurve::IsArcToApprox( const ICurve& Curve)
|
||||
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
||||
if ( pArc == nullptr)
|
||||
return false ;
|
||||
// verifico se non è nel piano XY o ha più di un giro al centro
|
||||
// verifico se non è nel piano XY o ha più di un giro al centro
|
||||
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
||||
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||
}
|
||||
@@ -244,10 +252,10 @@ IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve&
|
||||
bool
|
||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
||||
{
|
||||
// se non ci sono intersezioni, non va fatto alcunché
|
||||
if ( m_Info.size() == 0)
|
||||
// se non ci sono intersezioni, non va fatto alcunché
|
||||
if ( m_Info.empty())
|
||||
return true ;
|
||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
@@ -283,6 +291,24 @@ IntersCurveCurve::GetIntersCount( void)
|
||||
return m_nIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
IntersCurveCurve::GetInters3DCount( void)
|
||||
{
|
||||
int nCount = 0 ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++i) {
|
||||
if ( ! m_Info[i].bOverlap || ( m_Info[i].bOverlap && m_Info[i].bCBOverEq)) {
|
||||
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[0].ptI.z) < EPS_SMALL)
|
||||
++nCount ;
|
||||
}
|
||||
else {
|
||||
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[1].ptI.z) < EPS_SMALL)
|
||||
++nCount ;
|
||||
}
|
||||
}
|
||||
return nCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
IntersCurveCurve::GetCrossIntersCount( void)
|
||||
@@ -332,6 +358,30 @@ IntersCurveCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::GetInt3DCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||
{
|
||||
if ( nInd < 0 || nInd >= GetInters3DCount())
|
||||
return false ;
|
||||
int nCount = - 1 ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++i) {
|
||||
if ( ! m_Info[i].bOverlap || ( m_Info[i].bOverlap && m_Info[i].bCBOverEq)) {
|
||||
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[0].ptI.z) < EPS_SMALL)
|
||||
++nCount ;
|
||||
}
|
||||
else {
|
||||
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[1].ptI.z) < EPS_SMALL)
|
||||
++nCount ;
|
||||
}
|
||||
if ( nCount == nInd) {
|
||||
aInfo = m_Info[nInd] ;
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d& ptI)
|
||||
@@ -339,11 +389,11 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
||||
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
|
||||
return false ;
|
||||
|
||||
// ricerca del punto più vicino tra le intersezioni singole
|
||||
// ricerca del punto più vicino tra le intersezioni singole
|
||||
bool bFound = false ;
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se è un'intersezione singola
|
||||
// se è un'intersezione singola
|
||||
if ( ! m_Info[i].bOverlap) {
|
||||
// faccio la verifica sul punto
|
||||
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
|
||||
@@ -408,7 +458,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
||||
}
|
||||
@@ -425,7 +475,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
||||
}
|
||||
@@ -490,7 +540,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
double dU2 = Info[j].IciA[1].dU ;
|
||||
if ( dU2 < dU1 && pCurve->IsClosed())
|
||||
dU2 += dEndPar ;
|
||||
// se cade nell'intervallo è da saltare
|
||||
// se cade nell'intervallo è da saltare
|
||||
if ( Info[i].IciA[0].dU >= dU1 && Info[i].IciA[0].dU <= dU2) {
|
||||
bToSkip = true ;
|
||||
break ;
|
||||
@@ -509,7 +559,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
double dCurrPar = dStartPar ;
|
||||
double dCurrLen = 0 ;
|
||||
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
||||
// se è chiusa, recupero come finisce
|
||||
// se è chiusa, recupero come finisce
|
||||
if ( pCurve->IsClosed()) {
|
||||
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
||||
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
|
||||
@@ -527,7 +577,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
}
|
||||
// costruisco il vettore delle classificazioni
|
||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||
// se è definito un tratto precedente
|
||||
// se è definito un tratto precedente
|
||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia omogenea e valida
|
||||
@@ -549,7 +599,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
||||
// altrimenti, salvo il tipo
|
||||
else
|
||||
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
|
||||
// se è definito un tratto in sovrapposizione
|
||||
// se è definito un tratto in sovrapposizione
|
||||
if ( InfoCorr[i].bOverlap) {
|
||||
// assegno i dati
|
||||
CrvClass segClass ;
|
||||
@@ -589,7 +639,7 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
||||
double dStartParB, dEndParB ;
|
||||
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
|
||||
return false ;
|
||||
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
|
||||
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
|
||||
BBox3d boxCrvA, boxCrvB ;
|
||||
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
|
||||
! pCurveB->GetLocalBBox( boxCrvB))
|
||||
@@ -632,13 +682,37 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
||||
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
||||
// dichiaro la classe della curva per default
|
||||
int nClass = CRVC_OUT ;
|
||||
// se c'è almeno una intersezione
|
||||
// se c'è almeno una intersezione
|
||||
if ( iCC.GetIntersCount() > 0) {
|
||||
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
||||
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
||||
IntCrvCrvInfo aInfo ;
|
||||
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
||||
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||
nClass = CRVC_IN ;
|
||||
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
|
||||
nClass = CRVC_OUT ;
|
||||
else if ( aInfo.IciA[0].nPrevTy == ICCT_NULL) {
|
||||
// se il primo punto scelto non va bene allora ne cerco uno che mi dia informazioni sull'essere interno o esterno
|
||||
CurveLine clLine ;
|
||||
Point3d ptNewChoice ; pCurveA->GetPointD1D2( 0.25, ICurve::FROM_MINUS, ptNewChoice) ;
|
||||
if ( ! clLine.SetPDL( ptNewChoice, 0, dLen))
|
||||
return false ;
|
||||
// calcolo l'intersezione
|
||||
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
||||
if ( iCC.GetIntersCount() > 0) {
|
||||
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
||||
IntCrvCrvInfo aInfo ;
|
||||
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
||||
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||
nClass = CRVC_IN ;
|
||||
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
|
||||
nClass = CRVC_OUT ;
|
||||
else
|
||||
return false ; // se arrivo qui potrei ritentare la ricerca
|
||||
}
|
||||
else
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// altrimenti sono esterni tra loro
|
||||
else {
|
||||
|
||||
@@ -0,0 +1,449 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : IntersCurvePlane.cpp Data : 07.11.25 Versione : 2.7k1
|
||||
// Contenuto : Implementazione della classe intersezione curva-piano.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 07.11.25 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "IntersLineArc.h"
|
||||
#include "IntersArcArc.h"
|
||||
#include "IntersCrvCompoCrvCompo.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurvePlane.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
IntersCurvePlane::IntersCurvePlane( const ICurve& Curve, const Point3d& ptOrig, const Vector3d& vtN)
|
||||
{
|
||||
// Le intersezioni sono calcolate nel piano XY locale.
|
||||
// Il flag bAreSegments vale solo per intersezione tra due linee e riguarda entrambe.
|
||||
|
||||
// inizializzazioni
|
||||
m_nIntersCount = 0 ;
|
||||
m_pCurve = &Curve ;
|
||||
m_plPlane.Set( ptOrig, vtN) ;
|
||||
|
||||
// puntatore alla curva usata nei calcoli (originali o temporanee)
|
||||
const ICurve* pCalcCrv ;
|
||||
// per eventuale esplosione temporanea delle curve
|
||||
PtrOwner<ICurve> pTmpCrv ;
|
||||
|
||||
// se curva è arco da approssimare oppure è curva di Bezier
|
||||
if ( m_pCurve->GetType() == CRV_ARC || m_pCurve->GetType() == CRV_BEZIER || m_pCurve->GetType() == CRV_COMPO) {
|
||||
// approssimo con rette
|
||||
PolyLine PL ;
|
||||
if ( ! m_pCurve->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return ;
|
||||
pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pTmpCrv))
|
||||
return ;
|
||||
if ( ! GetBasicCurveComposite( pTmpCrv)->FromPolyLine( PL))
|
||||
return ;
|
||||
pCalcCrv = pTmpCrv ;
|
||||
}
|
||||
else
|
||||
pCalcCrv = m_pCurve ;
|
||||
|
||||
m_Info.clear() ;
|
||||
if ( pCalcCrv->GetType() == CRV_LINE) {
|
||||
CalcIntersLinePlane( m_plPlane, *pCalcCrv) ;
|
||||
}
|
||||
else if ( pCalcCrv->GetType() == CRV_COMPO){
|
||||
for ( int i = 0 ; i < GetBasicCurveComposite( pCalcCrv)->GetCurveCount(); ++i) {
|
||||
const ICurve& subCurve = *GetBasicCurveComposite( pCalcCrv)->GetCurve( i) ;
|
||||
CalcIntersLinePlane( m_plPlane, subCurve, i) ;
|
||||
}
|
||||
OrderAndCompleteIntersections() ;
|
||||
}
|
||||
|
||||
// per curve approssimate, sistemo...
|
||||
AdjustIntersParams( pCalcCrv != m_pCurve) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::CalcIntersLinePlane( const Plane3d& plPlane, const ICurve& Curve, int nCrv)
|
||||
{
|
||||
if ( Curve.GetType() != CRV_LINE)
|
||||
return false ;
|
||||
Point3d ptStart ; Curve.GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; Curve.GetEndPoint( ptEnd) ;
|
||||
Point3d ptInt ;
|
||||
double dLen = 0 ; Curve.GetLength( dLen) ;
|
||||
int nIntersType = IntersLinePlane( ptStart, ptEnd, m_plPlane, ptInt, true) ;
|
||||
// intersezione con attraversamento
|
||||
if ( nIntersType == ILPT_YES) {
|
||||
IntCrvPlnInfo icpi ;
|
||||
icpi.Ici[0].ptI = ptInt ;
|
||||
icpi.Ici[0].dU = Dist( ptInt, ptStart) / dLen + nCrv ;
|
||||
Vector3d vtPos = ptStart - m_plPlane.GetPoint() ;
|
||||
icpi.Ici[0].nPrevTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||
icpi.Ici[0].nNextTy = icpi.Ici[0].nPrevTy == ICPT_IN ? ICPT_OUT : ICPT_IN ;
|
||||
m_Info.push_back( icpi) ;
|
||||
}
|
||||
// intersezione con tocco
|
||||
else if ( nIntersType == ILPT_START || nIntersType == ILPT_END) {
|
||||
IntCrvPlnInfo icpi ;
|
||||
icpi.Ici[0].ptI = ptInt ;
|
||||
icpi.Ici[0].dU = nIntersType == ILPT_START ? 0 : 1 + nCrv ;
|
||||
|
||||
if ( nIntersType == ILPT_START) {
|
||||
Vector3d vtPos = ptEnd - m_plPlane.GetPoint() ;
|
||||
icpi.Ici[0].nNextTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||
icpi.Ici[0].nPrevTy = ICPT_NULL ;
|
||||
}
|
||||
else {
|
||||
Vector3d vtPos = ptStart - m_plPlane.GetPoint() ;
|
||||
icpi.Ici[0].nPrevTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||
icpi.Ici[0].nNextTy = ICPT_NULL ;
|
||||
}
|
||||
m_Info.push_back( icpi) ;
|
||||
}
|
||||
// intersezione con sovrapposizione
|
||||
else if ( nIntersType == ILPT_INPLANE) {
|
||||
IntCrvPlnInfo icpi ;
|
||||
icpi.bOverlap = true ;
|
||||
icpi.Ici[0].ptI = ptStart ;
|
||||
icpi.Ici[0].dU = 0 + nCrv;
|
||||
icpi.Ici[1].ptI = ptEnd ;
|
||||
icpi.Ici[1].dU = 1 + nCrv ;
|
||||
icpi.Ici[0].nPrevTy = ICPT_NULL ;
|
||||
icpi.Ici[0].nNextTy = ICPT_ON ;
|
||||
icpi.Ici[1].nPrevTy = ICPT_ON ;
|
||||
icpi.Ici[1].nNextTy = ICPT_NULL ;
|
||||
m_Info.push_back( icpi) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
IntersCurvePlane::OrderAndCompleteIntersections()
|
||||
{
|
||||
// cancello le interesezioni puntuali adiacenti a tratti di sovrapposizione
|
||||
// riempio le info PrevTy e NexyTy
|
||||
sort( m_Info.begin(), m_Info.end(), []( IntCrvPlnInfo& icpA, IntCrvPlnInfo& icpB) { return icpA.Ici[0].dU < icpA.Ici[0].dU ;}) ;
|
||||
for ( int curr = m_Info.size() - 1 ; curr > - 1 ; --curr) {
|
||||
int prev = curr == 0 ? m_Info.size() - 1 : curr - 1 ;
|
||||
int next = curr == m_Info.size() - 1 ? 0 : curr + 1 ;
|
||||
bool bErasedCurr = false ;
|
||||
// solo le intersezioni di sovrapposizione o puntuali sullo start o end delle curve possono avere il PrevTy o NextTy non definito
|
||||
if ( ! m_Info[curr].bOverlap) {
|
||||
if ( m_Info[curr].Ici[0].nPrevTy == ICPT_NULL) {
|
||||
if ( ! m_Info[prev].bOverlap) {
|
||||
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[0].nNextTy ;
|
||||
// se ho due puntuali che coincidono cancello il successivo tra i due ( corrente)
|
||||
if ( AreSamePointApprox( m_Info[curr].Ici[0].ptI, m_Info[prev].Ici[0].ptI)) {
|
||||
m_Info.erase(m_Info.begin() + curr) ;
|
||||
bErasedCurr = true ;
|
||||
}
|
||||
}
|
||||
// se ho un'intersezione puntuale che in realtà è la fine di un tratto di sovrapposizione, la cancello
|
||||
else {
|
||||
m_Info[prev].Ici[1].nNextTy = m_Info[curr].Ici[0].nNextTy ;
|
||||
m_Info.erase(m_Info.begin() + curr) ;
|
||||
bErasedCurr = true ;
|
||||
}
|
||||
}
|
||||
if ( ! bErasedCurr && m_Info[curr].Ici[0].nNextTy == ICPT_NULL){
|
||||
if ( ! m_Info[prev].bOverlap)
|
||||
m_Info[curr].Ici[0].nNextTy = m_Info[next].Ici[0].nPrevTy ;
|
||||
// se ho un'intersezione puntuale che in realtà è la fine di un tratto di sovrapposizione, la cancello
|
||||
else {
|
||||
m_Info[next].Ici[0].nPrevTy = m_Info[curr].Ici[0].nPrevTy ;
|
||||
m_Info.erase(m_Info.begin() + curr) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( m_Info[curr].Ici[0].nPrevTy == ICPT_NULL) {
|
||||
if ( ! m_Info[prev].bOverlap)
|
||||
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[0].nNextTy ;
|
||||
else
|
||||
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[1].nNextTy ;
|
||||
}
|
||||
if ( m_Info[curr].Ici[1].nNextTy == ICPT_NULL) {
|
||||
if ( ! m_Info[next].bOverlap)
|
||||
m_Info[curr].Ici[0].nNextTy = m_Info[prev].Ici[0].nPrevTy ;
|
||||
else
|
||||
m_Info[curr].Ici[0].nNextTy = m_Info[prev].Ici[1].nPrevTy ;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_nIntersCount = m_Info.size() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::IsArcToApprox( const ICurve& Curve)
|
||||
{
|
||||
// recupero l'arco
|
||||
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
||||
if ( pArc == nullptr)
|
||||
return false ;
|
||||
// verifico se non è nel piano XY o ha più di un giro al centro
|
||||
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
||||
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::AdjustIntersParams( bool bAdjCrv)
|
||||
{
|
||||
// se non ci sono intersezioni, non va fatto alcunché
|
||||
if ( m_Info.empty())
|
||||
return true ;
|
||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||
if ( ! bAdjCrv)
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
for ( auto& aInfo : m_Info) {
|
||||
// se curve originali approssimate, devo ricalcolare i parametri dei punti di intersezione
|
||||
if ( bAdjCrv) {
|
||||
if ( ! m_pCurve->GetParamAtPoint( aInfo.Ici[0].ptI, aInfo.Ici[0].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
if ( aInfo.bOverlap && ! m_pCurve->GetParamAtPoint( aInfo.Ici[1].ptI, aInfo.Ici[1].dU, 10 * EPS_SMALL))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
IntersCurvePlane::GetIntersCount( void)
|
||||
{
|
||||
return m_nIntersCount ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI, double& dParam)
|
||||
{
|
||||
if ( m_nIntersCount == 0)
|
||||
return false ;
|
||||
|
||||
// ricerca del punto più vicino tra le intersezioni singole
|
||||
bool bFound = false ;
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||
// se è un'intersezione singola
|
||||
if ( ! m_Info[i].bOverlap) {
|
||||
// faccio la verifica sul punto
|
||||
Point3d ptP = m_Info[i].Ici[0].ptI ;
|
||||
double dSqDist = SqDist( ptNear, ptP) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
ptI = ptP ;
|
||||
dParam = m_Info[i].Ici[0].dU ;
|
||||
bFound = true ;
|
||||
}
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
// recupero il tratto di sovrapposizione
|
||||
double dUStartTrim, dUEndTrim ;
|
||||
dUStartTrim = m_Info[i].Ici[0].dU ;
|
||||
dUEndTrim = m_Info[i].Ici[1].dU ;
|
||||
PtrOwner<ICurve> pCrv( m_pCurve->CopyParamRange( dUStartTrim, dUEndTrim)) ;
|
||||
if ( IsNull( pCrv))
|
||||
continue ;
|
||||
// cerco il punto
|
||||
int nFlag ;
|
||||
Point3d ptP ;
|
||||
if ( DistPointCurve( ptNear, *pCrv).GetMinDistPoint( 0.5, ptP, nFlag)) {
|
||||
// faccio la verifica
|
||||
double dSqDist = SqDist( ptNear, ptP) ;
|
||||
if ( dSqDist < dMinSqDist) {
|
||||
dMinSqDist = dSqDist ;
|
||||
ptI = ptP ;
|
||||
m_pCurve->GetParamAtPoint( ptP, dParam) ;
|
||||
bFound = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return bFound ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::GetCurveClassification( double dLenMin, CRVPLNCVECTOR& ccClass)
|
||||
{
|
||||
// pulisco vettore classificazioni
|
||||
ccClass.clear() ;
|
||||
|
||||
// verifico definizione della curva
|
||||
if ( m_pCurve == nullptr)
|
||||
return false ;
|
||||
|
||||
// se esiste almeno una intersezione
|
||||
if ( m_nIntersCount >= 1)
|
||||
return CalcCurveClassification( m_pCurve, m_Info, dLenMin, ccClass) ;
|
||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||
else
|
||||
return CalcCurveInOrOut( m_pCurve, ccClass) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::CalcCurveClassification( const ICurve* pCurve, const ICPIVECTOR& Info, double dLenMin, CRVPLNCVECTOR& ccClass)
|
||||
{
|
||||
// numero intersezioni
|
||||
int nNumInters = int( Info.size()) ;
|
||||
if ( nNumInters < 1)
|
||||
return false ;
|
||||
// recupero il dominio parametrico della curva in esame
|
||||
double dStartPar, dEndPar ;
|
||||
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||
return false ;
|
||||
// limito lunghezza minima
|
||||
dLenMin = max( dLenMin, EPS_ZERO) ;
|
||||
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
||||
ICPIVECTOR InfoCorr ;
|
||||
InfoCorr.reserve( Info.size()) ;
|
||||
for ( size_t i = 0 ; i < Info.size() ; ++ i) {
|
||||
// se intersezione puntuale senza attraversamento
|
||||
if ( ! Info[i].bOverlap && Info[i].Ici[0].nPrevTy == Info[i].Ici[0].nNextTy) {
|
||||
// confronto con le intersezioni con sovrapposizione
|
||||
bool bToSkip = false ;
|
||||
for ( size_t j = 0 ; j < Info.size() ; ++ j) {
|
||||
// se coincide o puntuale
|
||||
if ( j == i || ! Info[j].bOverlap)
|
||||
continue ;
|
||||
// determino l'intervallo parametrico tenendo conto di eventuale avvolgimento attorno all'inizio
|
||||
double dU1 = Info[j].Ici[0].dU ;
|
||||
double dU2 = Info[j].Ici[1].dU ;
|
||||
if ( dU2 < dU1 && pCurve->IsClosed())
|
||||
dU2 += dEndPar ;
|
||||
// se cade nell'intervallo è da saltare
|
||||
if ( Info[i].Ici[0].dU >= dU1 && Info[i].Ici[0].dU <= dU2) {
|
||||
bToSkip = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bToSkip)
|
||||
continue ;
|
||||
}
|
||||
// salvo dati intersezione
|
||||
InfoCorr.emplace_back( Info[i]) ;
|
||||
}
|
||||
// aggiorno numero di intersezioni da considerare
|
||||
nNumInters = int( InfoCorr.size()) ;
|
||||
// recupero la classificazione all'inizio della curva
|
||||
int nLastTy = ICCT_NULL ;
|
||||
double dCurrPar = dStartPar ;
|
||||
double dCurrLen = 0 ;
|
||||
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
||||
// se è chiusa, recupero come finisce
|
||||
if ( pCurve->IsClosed()) {
|
||||
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
||||
nLastTy = InfoCorr[nNumInters-1].Ici[0].nNextTy ;
|
||||
else {
|
||||
nLastTy = InfoCorr[nNumInters-1].Ici[1].nNextTy ;
|
||||
// se attraversa il punto di giunzione (parametro di fine minore di quello di inizio)
|
||||
if ( InfoCorr[nNumInters-1].Ici[1].dU < InfoCorr[nNumInters-1].Ici[0].dU) {
|
||||
dCurrPar = InfoCorr[nNumInters-1].Ici[1].dU ;
|
||||
double dTmpLen ; pCurve->GetLengthAtParam( dCurrPar, dTmpLen) ;
|
||||
dCurrLen = dTmpLen - dEndLen ;
|
||||
dEndPar = dCurrPar ;
|
||||
dEndLen = dTmpLen ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// costruisco il vettore delle classificazioni
|
||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||
// se è definito un tratto precedente
|
||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].Ici[0].dU, dLenU) ;
|
||||
if ( InfoCorr[i].Ici[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia omogenea e valida
|
||||
int nPrevTy = InfoCorr[i].Ici[0].nPrevTy ;
|
||||
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
||||
nPrevTy == ICCT_NULL || nPrevTy == ICCT_ON)
|
||||
return false ;
|
||||
// assegno i dati
|
||||
CrvPlaneClass segClass ;
|
||||
segClass.dParS = dCurrPar ;
|
||||
segClass.dParE = InfoCorr[i].Ici[0].dU ;
|
||||
segClass.nClass = (( nPrevTy == ICCT_IN) ? CRVC_IN : CRVC_OUT) ;
|
||||
ccClass.push_back( segClass) ;
|
||||
// salvo dati correnti
|
||||
dCurrPar = InfoCorr[i].Ici[0].dU ;
|
||||
dCurrLen = dLenU ;
|
||||
nLastTy = InfoCorr[i].Ici[0].nNextTy ;
|
||||
}
|
||||
// altrimenti, salvo il tipo
|
||||
else
|
||||
nLastTy = InfoCorr[i].Ici[0].nNextTy ;
|
||||
// se è definito un tratto in sovrapposizione
|
||||
if ( InfoCorr[i].bOverlap) {
|
||||
// assegno i dati
|
||||
CrvPlaneClass segClass ;
|
||||
segClass.dParS = dCurrPar ;
|
||||
segClass.dParE = InfoCorr[i].Ici[1].dU ;
|
||||
segClass.nClass = CRVPLN_ON ;
|
||||
ccClass.push_back( segClass) ;
|
||||
// salvo dati correnti
|
||||
dCurrPar = InfoCorr[i].Ici[1].dU ;
|
||||
dCurrLen = dLenU ;
|
||||
nLastTy = InfoCorr[i].Ici[1].nNextTy ;
|
||||
}
|
||||
}
|
||||
// eventuale tratto finale rimasto
|
||||
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
|
||||
// verifico che la definizione sul tratto sia valida
|
||||
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
||||
return false ;
|
||||
// assegno i dati
|
||||
CrvPlaneClass segClass ;
|
||||
segClass.dParS = dCurrPar ;
|
||||
segClass.dParE = dEndPar ;
|
||||
segClass.nClass = (( nLastTy == ICCT_IN) ? CRVC_IN : CRVC_OUT) ;
|
||||
ccClass.push_back( segClass) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersCurvePlane::CalcCurveInOrOut( const ICurve* pCurve, CRVPLNCVECTOR& ccClass)
|
||||
{
|
||||
// controllo di non avere intersezioni
|
||||
int nNumInters = int( m_Info.size()) ;
|
||||
if ( nNumInters > 0)
|
||||
return false ;
|
||||
|
||||
// se non ho intersezioni tra curva e piano devo solo capire da che parte del piano sta la curva
|
||||
CrvPlaneClass cpClass ;
|
||||
double dStartPar, dEndPar ;
|
||||
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||
return false ;
|
||||
Point3d ptStart ; pCurve->GetStartPoint( ptStart) ;
|
||||
Vector3d vtCrv = ptStart - m_plPlane.GetPoint() ;
|
||||
CrvPlaneClass segClass ;
|
||||
segClass.dParS = dStartPar ;
|
||||
segClass.dParE = dEndPar ;
|
||||
segClass.nClass = ( (vtCrv * m_plPlane.GetVersN() < 0) ? CRVC_IN : CRVC_OUT) ;
|
||||
ccClass.push_back( segClass) ;
|
||||
return true ;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ static void
|
||||
OrderInfoIntersCurveSurfTm( ICSIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
if ( vInfo.size() == 0)
|
||||
if ( vInfo.empty())
|
||||
return ;
|
||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
|
||||
+17
-5
@@ -113,7 +113,7 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
||||
double dU1, dU2 ;
|
||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||
|
||||
// Se non c'è intersezione
|
||||
// Se non c'è intersezione
|
||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||
return true ;
|
||||
|
||||
@@ -144,8 +144,14 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
if ( dU1 < - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TG_INSIDE, 0.) ;
|
||||
else
|
||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||
if ( dU2 > dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_TG_INSIDE, dLen) ;
|
||||
else
|
||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
@@ -162,8 +168,14 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
||||
else if ( dU2 < EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||
else {
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
if ( dU1 < - EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_INSIDE, 0.) ;
|
||||
else
|
||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||
if ( dU2 > dLen + EPS_SMALL)
|
||||
vInters.emplace_back( ILBT_INSIDE, dLen) ;
|
||||
else
|
||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "IntersLineCaps.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSphere.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
+59
-24
@@ -19,20 +19,18 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Il punto è esterno al FatSegment se dista da questo più di Tol e la sua proiezione sta sul segmento
|
||||
bool
|
||||
IsPointOutFatSegment( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol)
|
||||
// Posizione del punto rispetto alla linea (+1=a destra, 0=nella banda di tolleranza, -1=a sinistra)
|
||||
static int
|
||||
GetPointToLineSide( const Point3d& ptP, const Point3d& ptS, const Vector3d& vtDir, double dLenXY, double dTol)
|
||||
{
|
||||
// distanza del punto dalla linea del segmento (con compensazione piccolissimi errori)
|
||||
if ( abs( CrossXY( ( ptP - ptS), vtDir)) < ( dTol + EPS_ZERO) * dLenXY)
|
||||
return false ;
|
||||
// distanza con segno della proiezione del punto sul segmento dall'inizio per lunghezza segmento
|
||||
double dDistXY = ScalarXY( ( ptP - ptS), vtDir) ;
|
||||
// se il punto non si proietta sul segmento entro la tolleranza
|
||||
if ( dDistXY < - dTol * dLenXY || dDistXY > ( dLenXY + dTol) * dLenXY)
|
||||
return false ;
|
||||
// altrimenti
|
||||
return true ;
|
||||
double dCross = CrossXY( ( ptP - ptS), vtDir) ;
|
||||
double dFat = ( dTol + EPS_ZERO) * dLenXY ;
|
||||
if ( dCross > dFat)
|
||||
return +1 ;
|
||||
else if ( dCross < - dFat)
|
||||
return -1 ;
|
||||
else
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -44,7 +42,7 @@ IntersLineLine::IntersLineLine( const CurveLine& Line1, const CurveLine& Line2,
|
||||
m_bOverlaps = false ;
|
||||
m_nNumInters = 0 ;
|
||||
|
||||
// verifico validità linee
|
||||
// verifico validità linee
|
||||
if ( ! Line1.IsValid() || ! Line2.IsValid())
|
||||
return ;
|
||||
|
||||
@@ -130,30 +128,66 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
||||
if ( ! boxL1.OverlapsXY( boxL2))
|
||||
return ;
|
||||
|
||||
// linea 1 : Start, End, Direzione e Lunghezza
|
||||
// segmento 1 : Start, End, Direzione e Lunghezza
|
||||
Point3d ptS1 = Line1.GetStart() ;
|
||||
Point3d ptE1 = Line1.GetEnd() ;
|
||||
Vector3d vtDir1 = ptE1 - ptS1 ;
|
||||
double dLen1XY = vtDir1.LenXY() ;
|
||||
if ( dLen1XY < EPS_SMALL)
|
||||
return ;
|
||||
// linea 2 : Start, Direzione e Lunghezza
|
||||
// segmento 2 : Start, Direzione e Lunghezza
|
||||
Point3d ptS2 = Line2.GetStart() ;
|
||||
Point3d ptE2 = Line2.GetEnd() ;
|
||||
Vector3d vtDir2 = ptE2 - ptS2 ;
|
||||
double dLen2XY = vtDir2.LenXY() ;
|
||||
if ( dLen2XY < EPS_SMALL)
|
||||
return ;
|
||||
// posizioni estremi segmento 1 rispetto a linea 2
|
||||
int nS1Side = GetPointToLineSide( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ;
|
||||
int nE1Side = GetPointToLineSide( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ;
|
||||
if ( ( nS1Side == 1 && nE1Side == 1) || ( nS1Side == -1 && nE1Side == -1))
|
||||
return ;
|
||||
// posizioni estremi segmento 2 rispetto a linea 1
|
||||
int nS2Side = GetPointToLineSide( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ;
|
||||
int nE2Side = GetPointToLineSide( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ;
|
||||
if ( ( nS2Side == 1 && nE2Side == 1) || ( nS2Side == -1 && nE2Side == -1))
|
||||
return ;
|
||||
// prodotto vettoriale nel piano XY tra le direzioni delle linee
|
||||
double dCrossXY = CrossXY( vtDir1, vtDir2) ;
|
||||
// flag per linee parallele
|
||||
bool bParallel = ( abs( dCrossXY) < SIN_EPS_ANG_ZERO * ( dLen1XY * dLen2XY)) ;
|
||||
// flag per segmenti che si allontanano significativamente
|
||||
bool bFarEnds = ( /*( abs( dCrossXY) > SIN_EPS_ANG_SMALL * ( dLen1XY * dLen2XY)) ||*/
|
||||
IsPointOutFatSegment( ptS1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ||
|
||||
IsPointOutFatSegment( ptE1, ptS2, vtDir2, dLen2XY, EPS_SMALL) ||
|
||||
IsPointOutFatSegment( ptS2, ptS1, vtDir1, dLen1XY, EPS_SMALL) ||
|
||||
IsPointOutFatSegment( ptE2, ptS1, vtDir1, dLen1XY, EPS_SMALL)) ;
|
||||
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
||||
|
||||
// analisi casi speciali di quasi parallelismo
|
||||
// segmento sovrapposto all'altro
|
||||
double dDist1, dDist2 ;
|
||||
if ( nS1Side == 0 || nE1Side == 0 || nS1Side == nE1Side) {
|
||||
dDist1 = CrossXY( ptS1 - ptS2, vtDir2) ;
|
||||
dDist2 = CrossXY( ptE1 - ptS2, vtDir2) ;
|
||||
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen2XY) {
|
||||
bParallel = true ;
|
||||
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
|
||||
}
|
||||
}
|
||||
else if ( nS2Side == 0 || nE2Side == 0 || nS2Side == nE2Side) {
|
||||
dDist1 = CrossXY( ptS2 - ptS1, vtDir1) ;
|
||||
dDist2 = CrossXY( ptE2 - ptS1, vtDir1) ;
|
||||
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen1XY) {
|
||||
bParallel = true ;
|
||||
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
|
||||
}
|
||||
}
|
||||
// estremità sovrapposte di poco
|
||||
if ( ! bParallel && abs( dCrossXY) < ( 0.1 * DEGTORAD) * ( dLen1XY * dLen2XY)) {
|
||||
if (( nS1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) ||
|
||||
( nS1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) ||
|
||||
( nE1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptE1, ptS2, 2 * EPS_SMALL)) ||
|
||||
( nE1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptE1, ptE2, 2 * EPS_SMALL))) {
|
||||
bParallel = true ;
|
||||
bFarEnds = false ;
|
||||
}
|
||||
}
|
||||
|
||||
// se non sono paralleli e si allontanano tra loro abbastanza
|
||||
if ( ! bParallel && bFarEnds) {
|
||||
@@ -168,6 +202,8 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
||||
nPos1 = ICurve::PP_END ; // vicino a fine
|
||||
else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1)
|
||||
nPos1 = ICurve::PP_MID ; // nell'interno
|
||||
else
|
||||
return ;
|
||||
// verifica posizione intersezione su seconda linea
|
||||
int nPos2 = ICurve::PP_NULL ; // fuori
|
||||
if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL)
|
||||
@@ -176,8 +212,7 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
||||
nPos2 = ICurve::PP_END ; // vicino a fine
|
||||
else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1)
|
||||
nPos2 = ICurve::PP_MID ; // nell'interno
|
||||
// se soluzione non accettata, esco
|
||||
if ( nPos1 == ICurve::PP_NULL || nPos2 == ICurve::PP_NULL)
|
||||
else
|
||||
return ;
|
||||
// limito i parametri a stare sui segmenti (0...1)
|
||||
m_Info.IciA[0].dU = min( max( m_Info.IciA[0].dU, 0.), 1.) ;
|
||||
@@ -190,7 +225,7 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
||||
m_Info.IciA[0].nNextTy = ICCT_NULL ;
|
||||
m_Info.IciB[0].nPrevTy = ICCT_NULL ;
|
||||
m_Info.IciB[0].nNextTy = ICCT_NULL ;
|
||||
// si incontrano alle estremità, non si può dire alcunché
|
||||
// si incontrano alle estremità, non si può dire alcunché
|
||||
if ( ( nPos1 == ICurve::PP_START || nPos1 == ICurve::PP_END) &&
|
||||
( nPos2 == ICurve::PP_START || nPos2 == ICurve::PP_END)) {
|
||||
; // rimangono tutti NULL
|
||||
|
||||
+274
-17
@@ -13,12 +13,18 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveBezier.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfFlatRegion.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "CurveLine.h"
|
||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -28,7 +34,6 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b
|
||||
const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz)
|
||||
{
|
||||
// la funzione raffina la posisione del punto ptSP, minimizzando la distanza dalla retta e restituisce il punto di intersezione ptIBz
|
||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
// usando un algoritmo di newton cerco di avvicinarmi il più possibile alla retta
|
||||
DistPointLine dpl( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||
double dDistNew = 0, dDistPre = 0 ;
|
||||
@@ -42,18 +47,18 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b
|
||||
while ( dDistNew > EPS_SMALL && nCount < 100) {
|
||||
dDistPre = dDistNew ;
|
||||
Point3d ptIBzNew1 ;
|
||||
pSurfBz->GetPointD1D2( ( ptSP.x + dh) / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ;
|
||||
pSurfBz->GetPointD1D2( ( ptSP.x + dh), ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ;
|
||||
DistPointLine dplNewU( ptIBzNew1, ptL, vtL, dLen, bFinite) ;
|
||||
dplNewU.GetDist( dDistNew) ;
|
||||
double dfdU = ( dDistNew - dDistPre) / dh ;
|
||||
Point3d ptIBzNew2 ;
|
||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ( ptSP.y + dh) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ;
|
||||
pSurfBz->GetPointD1D2( ptSP.x, ( ptSP.y + dh), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ;
|
||||
DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ;
|
||||
dplNewV.GetDist( dDistNew) ;
|
||||
double dfdV = ( dDistNew - dDistPre) / dh ;
|
||||
// mi avvicino cercando di annullare la distanza in un colpo solo
|
||||
double dr = - dDistPre / ( dfdU + dfdV) ;
|
||||
pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU) / SBZ_TREG_COEFF, ( ptSP.y + dr * dfdV) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU), ( ptSP.y + dr * dfdV), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||
DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||
dplNew.GetDist( dDistNew) ;
|
||||
++ nCount ;
|
||||
@@ -67,11 +72,11 @@ static void
|
||||
UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos,
|
||||
const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo)
|
||||
{
|
||||
if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) {
|
||||
if ( nILT == ILTA_IN || nILT == ILTA_EDGE || nILT == ILTA_VERT || nILT == ILTA_NO_TRIA) {
|
||||
double dU = ( ptIBz - ptL) * vtDir ;
|
||||
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
|
||||
}
|
||||
else if ( nILT == ILTT_SEGM || nILT == ILTT_SEGM_ON_EDGE) {
|
||||
else if ( nILT == ILTA_SEGM || nILT == ILTA_SEGM_ON_EDGE) {
|
||||
double dU = ( ptIBz - ptL) * vtDir ;
|
||||
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
||||
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
|
||||
@@ -83,13 +88,13 @@ static void
|
||||
OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
if ( vInfo.size() == 0)
|
||||
if ( vInfo.empty())
|
||||
return ;
|
||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
|
||||
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||
{ double dUa = ( ( a.nILTA == ILTA_SEGM || a.nILTA == ILTA_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||
double dUb = ( ( b.nILTA == ILTA_SEGM || b.nILTA == ILTA_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||
return ( dUa < dUb) ; }) ;
|
||||
}
|
||||
|
||||
@@ -137,16 +142,16 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
pSurfTm->GetTriangle( InfoTm.nT, nVert) ;
|
||||
double dU0, dV0 ;
|
||||
pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ;
|
||||
ptSP = ptSP + Point3d(dU0, dV0, 0) ;
|
||||
ptSP = ptSP + Point3d( dU0, dV0, 0) ;
|
||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||
return false ;
|
||||
}
|
||||
Vector3d vtN ;
|
||||
pSurfBz->GetPointNrmD1D2(ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ;
|
||||
pSurfBz->GetPointNrmD1D2(ptSP.x, ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ;
|
||||
double dCos = vtN * vtL ;
|
||||
double dCos2 = 0 ;
|
||||
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
|
||||
if ( InfoTm.nILTT == ILTT_SEGM || InfoTm.nILTT == ILTT_SEGM_ON_EDGE ) {
|
||||
if ( InfoTm.nILTT == ILTA_SEGM || InfoTm.nILTT == ILTA_SEGM_ON_EDGE ) {
|
||||
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
|
||||
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
||||
int nVert[3] ;
|
||||
@@ -157,7 +162,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||
return false ;
|
||||
}
|
||||
pSurfBz->GetPointNrmD1D2( ptSP2.x / SBZ_TREG_COEFF, ptSP2.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ;
|
||||
pSurfBz->GetPointNrmD1D2( ptSP2.x, ptSP2.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ;
|
||||
dCos2 = vtN * vtL ;
|
||||
}
|
||||
UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ;
|
||||
@@ -176,7 +181,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
// ciclo sulle intersezioni
|
||||
for ( const auto& Info : vInfo) {
|
||||
// se intersezione puntuale
|
||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
||||
if ( Info.nILTA == ILTA_VERT || Info.nILTA == ILTA_EDGE || Info.nILTA == ILTA_IN) {
|
||||
int nFlag = LSBT_TOUCH ;
|
||||
if ( Info.dCosDN > EPS_ZERO)
|
||||
nFlag = LSBT_OUT ;
|
||||
@@ -185,7 +190,7 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
vInters.emplace_back( nFlag, Info.dU) ;
|
||||
}
|
||||
// se altrimenti intersezione con coincidenza
|
||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
||||
else if ( Info.nILTA == ILTA_SEGM || Info.nILTA == ILTA_SEGM_ON_EDGE) {
|
||||
vInters.emplace_back( LSBT_TG_INI, Info.dU) ;
|
||||
vInters.emplace_back( LSBT_TG_FIN, Info.dU2) ;
|
||||
}
|
||||
@@ -232,3 +237,255 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di una linea con una superficie di Bezier
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersLineSurfBzBilinear( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz,
|
||||
ILSBIVECTOR& vInfo, bool bFinite)
|
||||
{
|
||||
int nDegU, nDegV, nSpanU, nSpanV ;
|
||||
bool bRat, bTrimmed ;
|
||||
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
||||
|
||||
// funzione pensata per funzionare solo con una monopatch bilineare
|
||||
if ( nDegU > 1 || nDegV > 1 || nSpanU > 1 || nSpanV > 1 || bRat)
|
||||
return false ;
|
||||
|
||||
int nInters = int( vInfo.size()) ;
|
||||
|
||||
PNTVECTOR vPntCtrl ;
|
||||
for ( int p = 0 ; p < 4 ; ++p) {
|
||||
bool bOk = false ;
|
||||
vPntCtrl.push_back( pSurfBz->GetControlPoint( p, &bOk)) ;
|
||||
}
|
||||
|
||||
Vector3d a = vPntCtrl[3] - vPntCtrl[1] + ( vPntCtrl[0] - vPntCtrl[2]) ;
|
||||
Vector3d b = vPntCtrl[1] - vPntCtrl[0] ;
|
||||
Vector3d c = vPntCtrl[2] - vPntCtrl[0] ;
|
||||
Vector3d d = vPntCtrl[0] - ORIG ;
|
||||
|
||||
double A1 = a.x * vtL.z - a.z * vtL.x ;
|
||||
double B1 = b.x * vtL.z - b.z * vtL.x ;
|
||||
double C1 = c.x * vtL.z - c.z * vtL.x ;
|
||||
double A2 = a.y * vtL.z - a.z * vtL.y ;
|
||||
double B2 = b.y * vtL.z - b.z * vtL.y ;
|
||||
double C2 = c.y * vtL.z - c.z * vtL.y ;
|
||||
|
||||
double D1 = ( d.x - ptL.x) * vtL.z - ( d.z - ptL.z) * vtL.x ;
|
||||
double D2 = ( d.y - ptL.y) * vtL.z - ( d.z - ptL.z) * vtL.y ;
|
||||
|
||||
DBLVECTOR vdCoeff, vdRoots ;
|
||||
vdCoeff = { (B2 * D1 - B1 * D2), ( A2 * D1 - A1 * D2 + B2 * C1 - B1 * C2), ( A2 * C1 - A1 * C2)} ;
|
||||
int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||
bool bFound = false ;
|
||||
for ( int w = 0 ; w < nRoots ; ++w) {
|
||||
if ( vdRoots[w] > 0 - EPS_ZERO && vdRoots[w] < 1 + EPS_ZERO ) {
|
||||
double dU = 0, dV = vdRoots[w] ;
|
||||
// verifico che non sia una soluzione con molteplicità > 1
|
||||
bool bAlreadyFound = false ;
|
||||
for ( int k = w - 1 ; k >= 0 && ! bAlreadyFound ; --k)
|
||||
bAlreadyFound = abs( dV - vdRoots[k]) < EPS_PARAM ;
|
||||
if ( ! bAlreadyFound) {
|
||||
dU = (dV * (C1 - C2) + ( D1 - D2)) / ( dV * ( A2 - A1) + ( B2 - B1)) ;
|
||||
if ( dU > - EPS_ZERO && dU < 1 + EPS_ZERO) {
|
||||
Point3d ptIBez, ptIBez2 ;
|
||||
Vector3d vtN ;
|
||||
pSurfBz->GetPointNrmD1D2(dU, dV, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez, vtN) ;
|
||||
Point3d ptSP( dU, dV, 0), ptSP2 ;
|
||||
double dCos = vtN * vtL, dCos2 = 0 ;
|
||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP, ptIBez, dCos, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||
bFound = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se tutti i coefficienti sono zero allora potrei avere una linea che giace sulla superficie
|
||||
// per trovare i punti di inizio e fine sovrapposizione trovo i punti a minima distanza tra la linea e gli edge della superficie
|
||||
if ( ! bFound && abs( vdCoeff[0]) < EPS_ZERO && abs( vdCoeff[1]) < EPS_ZERO && abs( vdCoeff[2]) < EPS_ZERO) {
|
||||
ICRVCOMPOPOVECTOR vCrvEdge( 4) ;
|
||||
vCrvEdge[0].Set(pSurfBz->GetCurveOnU( 0)) ;
|
||||
vCrvEdge[1].Set(pSurfBz->GetCurveOnV( 1)) ;
|
||||
vCrvEdge[2].Set(pSurfBz->GetCurveOnU( 1)) ;
|
||||
vCrvEdge[3].Set(pSurfBz->GetCurveOnV( 0)) ;
|
||||
double dAngTolDeg = 5 ;
|
||||
for ( int i = 0 ; i < 4 ; ++i) {
|
||||
PolyLine plApprox ; vCrvEdge[0]->ApproxWithLines( EPS_SMALL, dAngTolDeg, ICurve::ApprLineType::APL_STD, plApprox) ;
|
||||
//CurveComposite cCC ;
|
||||
//cCC.FromPolyLine( plApprox) ;
|
||||
int nClosestLine = -1 ;
|
||||
double dMinDist = INFINITO ;
|
||||
Point3d pt ; plApprox.GetFirstPoint( pt) ;
|
||||
Point3d ptClosest ;
|
||||
int c = 0 ;
|
||||
int nTot = plApprox.GetPointNbr() ;
|
||||
for ( int j = 0 ; j < nTot ; ++j) {
|
||||
DistPointLine dpl( pt, ptL, vtL, dLen, bFinite) ;
|
||||
double dDist = INFINITO ;
|
||||
dpl.GetDist( dDist) ;
|
||||
if ( dDist < dMinDist) {
|
||||
nClosestLine = c ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
plApprox.GetNextPoint( pt) ;
|
||||
++ c ;
|
||||
}
|
||||
|
||||
Point3d ptInt1, ptInt2 ;
|
||||
if ( nClosestLine < nTot - 1 && nClosestLine > 0) {
|
||||
// tra i due tratti dell'approssimazione che arrivano al punto selezionato come più vicino, devo trovare quale si avvicina di più
|
||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||
Point3d ptEnd ;
|
||||
for ( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
||||
plApprox.GetNextPoint( ptStart) ;
|
||||
plApprox.GetNextPoint( ptEnd) ;
|
||||
// linea precedente al punto
|
||||
Vector3d vtLinePre = ptEnd - ptStart ;
|
||||
double dLenPre = vtLinePre.Len() ;
|
||||
DistLineLine dllPre( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
||||
double dDistPre = INFINITO ;
|
||||
dllPre.GetDist( dDistPre) ;
|
||||
// linea che inzia con quel punto
|
||||
ptStart = ptEnd ;
|
||||
plApprox.GetNextPoint( ptEnd) ;
|
||||
Vector3d vtLineCurr = ptEnd - ptStart ;
|
||||
double dLenCurr = vtLineCurr.Len() ;
|
||||
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
||||
double dDistCurr = INFINITO ;
|
||||
dllCurr.GetDist( dDistCurr) ;
|
||||
|
||||
if ( dDistPre < dDistCurr)
|
||||
dllPre.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||
else
|
||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||
}
|
||||
else if ( nClosestLine == 0) {
|
||||
// il punto più vicino è sulla prima linea
|
||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||
Point3d ptEnd ; plApprox.GetNextPoint( ptEnd) ;
|
||||
Vector3d vtLineCurr = ptEnd - ptStart ;
|
||||
double dLenCurr = vtLineCurr.Len() ;
|
||||
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||
}
|
||||
else if ( nClosestLine == nTot- 1) {
|
||||
// il punto più vicino è sull'ultima linea
|
||||
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||
Point3d ptEnd ;
|
||||
for ( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
||||
plApprox.GetNextPoint( ptStart) ;
|
||||
plApprox.GetNextPoint( ptEnd) ;
|
||||
Vector3d vtLinePre = ptEnd - ptStart ;
|
||||
double dLenPre = vtLinePre.Len() ;
|
||||
DistLineLine dllCurr( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
||||
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||
}
|
||||
|
||||
double dU1 = 0, dV1 = 0, dU2 = 0, dV2 = 0 ;
|
||||
// se ho trovato due punti vuol dire che la linea coincide con un edge e ho trovato tutto quello che serve
|
||||
if ( ! AreSamePointExact( ptInt2, ORIG)) {
|
||||
if ( i == 0) {
|
||||
//dV1 = 0 ; dV2 = 0 ;
|
||||
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
||||
vCrvEdge[0]->GetParamAtPoint( ptInt2, dU2) ;
|
||||
}
|
||||
else if ( i == 1) {
|
||||
//dU1 = 1 ; dU2 = 1 ;
|
||||
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
||||
vCrvEdge[1]->GetParamAtPoint( ptInt2, dV2) ;
|
||||
}
|
||||
else if ( i == 2){
|
||||
//dV1 = 1 ; dV2 = 1 ;
|
||||
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
||||
vCrvEdge[2]->GetParamAtPoint( ptInt2, dU2) ;
|
||||
}
|
||||
else if ( i == 3){
|
||||
//dU1 = 0 ; dU2 = 0 ;
|
||||
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
||||
vCrvEdge[3]->GetParamAtPoint( ptInt2, dV2) ;
|
||||
}
|
||||
Point3d ptIBez1, ptIBez2 ;
|
||||
Vector3d vtN1, vtN2 ;
|
||||
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
||||
pSurfBz->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez2, vtN2) ;
|
||||
Point3d ptSP1( dU1, dV1, 0) ;
|
||||
double dCos1 = vtN1 * vtL ;
|
||||
Point3d ptSP2( dU2, dV2, 0) ;
|
||||
double dCos2 = vtN2 * vtL ;
|
||||
// se avevo già trovato un punto singolo che coincide col primo punto di questa intersezione sovrapposta, allora cancello l'intersezione singola che
|
||||
// avevo salvato e aggiungo quella sovrapposto che ho trovato ora
|
||||
if ( bFound) {
|
||||
int nNewTot = int(vInfo.size()) ;
|
||||
int nNewInters = nNewTot - nInters ;
|
||||
bool bAlreadyFound = false ;
|
||||
for ( int i = 0 ; i < nNewInters ; ++i) {
|
||||
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) || AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP2) ;
|
||||
if ( bAlreadyFound) {
|
||||
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||
bFound = true ;
|
||||
break ;
|
||||
}
|
||||
// se ho trovato un punto a distanza zero dalla linea allora ho trovato l'intersezione
|
||||
else if ( dMinDist < EPS_SMALL) {
|
||||
if ( i == 0) {
|
||||
//dV1 = 0 ;
|
||||
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
||||
}
|
||||
else if ( i == 1) {
|
||||
//dU1 = 1 ;
|
||||
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
||||
}
|
||||
else if ( i == 2) {
|
||||
//dV1 = 1 ;
|
||||
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
||||
}
|
||||
else if ( i == 3) {
|
||||
//dU1 = 0 ;
|
||||
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
||||
}
|
||||
Point3d ptSP1( dU1, dV1, 0), ptSP2 ;
|
||||
// se avevo trovato già altri punti controllo di non essere esattamente su una diagonale ( e quindi avere un'intersezione con ogni edge, ma due sono doppie)
|
||||
if ( bFound) {
|
||||
int nNewTot = int(vInfo.size()) ;
|
||||
int nNewInters = nNewTot - nInters ;
|
||||
bool bAlreadyFound = false ;
|
||||
for ( int i = 0 ; i < nNewInters ; ++i)
|
||||
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) ;
|
||||
if ( bAlreadyFound)
|
||||
continue ;
|
||||
}
|
||||
|
||||
Point3d ptIBez1, ptIBez2 ;
|
||||
Vector3d vtN1, vtN2 ;
|
||||
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
||||
double dCos1 = vtN1 * vtL, dCos2 = 0 ;
|
||||
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||
bFound = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// se la superficie è trimmed verifico che i punti trovati siano all'interno del parametrico trimmato
|
||||
if ( bTrimmed && bFound) {
|
||||
int nNewTot = int(vInfo.size()) ;
|
||||
int nNewInters = nNewTot - nInters ;
|
||||
const ISurfFlatRegion* pFRTrim = pSurfBz->GetTrimRegion() ;
|
||||
for ( int i = 0 ; i < nNewInters ; ++i) {
|
||||
Point3d ptTest = vInfo[nNewTot - i].ptUV * SBZ_TREG_COEFF ;
|
||||
bool bInside = false ;
|
||||
double dDist = INFINITO ;
|
||||
IsPointInsideSurfFr( ptTest, pFRTrim, dDist, bInside) ;
|
||||
if ( ! bInside)
|
||||
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1662,7 +1662,7 @@ LineTorus( const Point3d& ptLine, const Vector3d& vtLine,
|
||||
// Riordino le soluzioni
|
||||
for ( int ni = 0 ; ni < int( vdPar.size()) - 1 ; ++ ni) {
|
||||
for ( int nj = ni ; nj < int( vdPar.size()) ; ++ nj) {
|
||||
if( vdPar[ni] > vdPar[nj]) {
|
||||
if ( vdPar[ni] > vdPar[nj]) {
|
||||
swap( vdPar[ni], vdPar[nj]) ;
|
||||
}
|
||||
}
|
||||
@@ -1670,7 +1670,7 @@ LineTorus( const Point3d& ptLine, const Vector3d& vtLine,
|
||||
|
||||
// Studio le soluzioni
|
||||
int nIntType = T_ERROR ;
|
||||
if ( vdPar.size() == 0)
|
||||
if ( vdPar.empty())
|
||||
nIntType = T_NO_INT ;
|
||||
else if ( vdPar.size() == 1) {
|
||||
nIntType = T_ONE_TAN ;
|
||||
|
||||
+109
-22
@@ -23,20 +23,20 @@ using namespace std ;
|
||||
//----------------------------------------------------------------------------
|
||||
static void
|
||||
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
||||
int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
||||
int nStm, int nT, const Triangle3d& Tria, ILSIVECTOR& vInfo, bool bFinite)
|
||||
{
|
||||
Point3d ptInt, ptInt2 ;
|
||||
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
||||
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
||||
double dU = ( ptInt - ptL) * vtDir ;
|
||||
double dCosDN = vtDir * Tria.GetN() ;
|
||||
vInfo.emplace_back( nRes, dU, nT, dCosDN, ptInt) ;
|
||||
vInfo.emplace_back( nRes, dU, nStm, nT, dCosDN, ptInt) ;
|
||||
}
|
||||
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
||||
double dU = ( ptInt - ptL) * vtDir ;
|
||||
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
||||
double dCosDN = vtDir * Tria.GetN() ;
|
||||
vInfo.emplace_back( nRes, dU, dU2, nT, dCosDN, ptInt, ptInt2) ;
|
||||
vInfo.emplace_back( nRes, dU, dU2, nStm, nT, dCosDN, ptInt, ptInt2) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +45,15 @@ static void
|
||||
OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
||||
{
|
||||
// se non trovati, esco
|
||||
if ( vInfo.size() == 0)
|
||||
if ( vInfo.empty())
|
||||
return ;
|
||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
sort( vInfo.begin(), vInfo.end(),
|
||||
[]( const IntLinStmInfo& a, const IntLinStmInfo& b)
|
||||
{ double dUa = ( ( a.nILTT == ILTT_SEGM || a.nILTT == ILTT_SEGM_ON_EDGE) ? ( a.dU + a.dU2) / 2 : a.dU) ;
|
||||
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||
if ( abs( dUa - dUb) < EPS_SMALL)
|
||||
return ( a.dCosDN < b.dCosDN) ;
|
||||
return ( dUa < dUb) ; }) ;
|
||||
}
|
||||
|
||||
@@ -106,7 +108,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
Triangle3d Tria ;
|
||||
Stm.GetTriangle( nT, Tria) ;
|
||||
// aggiorno info con intersezione
|
||||
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ;
|
||||
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, 0, nT, Tria, vInfo, bFinite) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,19 +124,23 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
// Intersezione di molte linee parallele con una superficie TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm)
|
||||
: m_bOk( false), m_frLines( frLines), m_pSTm( &Stm)
|
||||
: m_bOk( false), m_frLines( frLines), m_vpSTm( {&Stm})
|
||||
{
|
||||
// verifico esistenza superficie
|
||||
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
|
||||
if ( m_vpSTm[0] == nullptr || ! m_vpSTm[0]->IsValid())
|
||||
return ;
|
||||
|
||||
// creo HashGrid 2d
|
||||
const int LIM_HG_TRIA = 127 ;
|
||||
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
||||
// aggiorno il vettore degli indici di base per mappare i triangoli con le rispettivi superfici
|
||||
// ( in questo caso la superficie è unica, quindi ho solo due elementi)
|
||||
m_vBaseInd = { 0, m_vpSTm[0]->GetTriangleCount()} ;
|
||||
|
||||
// riempio HashGrid
|
||||
// creo HashGrid 2d ed eventualmente attivo la griglia
|
||||
const int LIM_HG_TRIA = 127 ;
|
||||
m_HGrids.SetActivationGrid( m_vBaseInd.back() > LIM_HG_TRIA) ;
|
||||
|
||||
// riempio HashGrid
|
||||
Triangle3d Tria ;
|
||||
int nT = Stm.GetFirstTriangle( Tria) ;
|
||||
int nT = m_vpSTm[0]->GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// calcolo il BBox del triangolo nel riferimento scelto
|
||||
Tria.ToLoc( m_frLines) ;
|
||||
@@ -143,10 +149,55 @@ IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfT
|
||||
b3Tria.Add( Tria.GetP( 1)) ;
|
||||
b3Tria.Add( Tria.GetP( 2)) ;
|
||||
// inserisco nella griglia
|
||||
if ( ! m_HGrids.Add( nT, b3Tria))
|
||||
if ( ! m_HGrids.Add( nT, b3Tria)) // ( 0 + nT, Tria)
|
||||
return ;
|
||||
// passo al prossimo triangolo
|
||||
nT = Stm.GetNextTriangle( nT, Tria) ;
|
||||
// passo al prossimo triangolo
|
||||
nT = m_vpSTm[0]->GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
// aggiorno
|
||||
m_bOk = m_HGrids.Update() ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di molte linee parallele con un vettore di superfici TriMesh
|
||||
//----------------------------------------------------------------------------
|
||||
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const CISURFTMPVECTOR& vStm)
|
||||
: m_bOk( false), m_frLines( frLines), m_vpSTm( vStm), m_vBaseInd( {0})
|
||||
{
|
||||
// verifico esistenza superfici
|
||||
if ( m_vpSTm.empty())
|
||||
return ;
|
||||
for ( const ISurfTriMesh* pStm : m_vpSTm) {
|
||||
if ( pStm == nullptr || ! pStm->IsValid())
|
||||
return ;
|
||||
}
|
||||
|
||||
// aggiorno il vettore degli indici di base per mappare i triangoli con le rispettivi superfici
|
||||
// NB. dal costruttore è già inizializzato a {0}
|
||||
for ( int i = 0 ; i < int( m_vpSTm.size()) ; ++ i)
|
||||
m_vBaseInd.emplace_back( m_vBaseInd.back() + m_vpSTm[i]->GetTriangleCount()) ;
|
||||
|
||||
// creo HashGrid 2d ed eventualmente attivo la griglia
|
||||
const int LIM_HG_TRIA = 256 ;
|
||||
m_HGrids.SetActivationGrid( m_vBaseInd.back() > LIM_HG_TRIA) ;
|
||||
|
||||
// riempio HashGrid
|
||||
for ( int i = 0 ; i < int( m_vpSTm.size()) ; ++ i) {
|
||||
Triangle3d Tria ;
|
||||
int nT = m_vpSTm[i]->GetFirstTriangle( Tria) ;
|
||||
while ( nT != SVT_NULL) {
|
||||
// calcolo il BBox del triangolo nel riferimento scelto
|
||||
Tria.ToLoc( m_frLines) ;
|
||||
BBox3d b3Tria ;
|
||||
b3Tria.Add( Tria.GetP( 0)) ;
|
||||
b3Tria.Add( Tria.GetP( 1)) ;
|
||||
b3Tria.Add( Tria.GetP( 2)) ;
|
||||
// inserisco nella griglia ( aggiungo shift per indice del triangolo)
|
||||
if ( ! m_HGrids.Add( m_vBaseInd[i] + nT, b3Tria))
|
||||
return ;
|
||||
// passo al prossimo triangolo
|
||||
nT = m_vpSTm[i]->GetNextTriangle( nT, Tria) ;
|
||||
}
|
||||
}
|
||||
// aggiorno
|
||||
m_bOk = m_HGrids.Update() ;
|
||||
@@ -160,7 +211,7 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
||||
if ( &vInfo == nullptr)
|
||||
return false ;
|
||||
vInfo.clear() ;
|
||||
// verifico validità
|
||||
// verifico validità
|
||||
if ( ! m_bOk)
|
||||
return false ;
|
||||
|
||||
@@ -172,15 +223,22 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
||||
Point3d ptLL = ptL ;
|
||||
ptLL.ToGlob( m_frLines) ;
|
||||
|
||||
// recupero indici triangoli che intersecano box in 2d
|
||||
// recupero indici triangoli che intersecano box in 2d
|
||||
INTVECTOR vnIds ;
|
||||
if ( m_HGrids.Find( b3Line, vnIds)) {
|
||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
||||
int nT = vnIds[i] ;
|
||||
// recupero la superficie
|
||||
int nInd = vnIds[i] ;
|
||||
int nSurf = GetSurfInd( nInd) ;
|
||||
if ( nSurf == -1)
|
||||
return false ;
|
||||
// recupero il triangolo
|
||||
int nT = nInd - m_vBaseInd[nSurf] ;
|
||||
Triangle3d Tria ;
|
||||
m_pSTm->GetTriangle( nT, Tria) ;
|
||||
if ( ! m_vpSTm[nSurf]->GetTriangle( nT, Tria))
|
||||
return false ;
|
||||
// aggiorno info con intersezione
|
||||
UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nT, Tria, vInfo, bFinite) ;
|
||||
UpdateInfoIntersLineSurfTm( ptLL, m_frLines.VersZ(), dLen, nSurf, nT, Tria, vInfo, bFinite) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,6 +248,35 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
IntersParLinesSurfTm::GetSurfInd( int nT) const
|
||||
{
|
||||
// verifico la presenza di almeno un intervallo
|
||||
if ( m_vBaseInd.size() < 2)
|
||||
return -1 ;
|
||||
// se la superficie è unica, allora non devo cercarla
|
||||
if ( int( m_vBaseInd.size()) == 2)
|
||||
return 0 ;
|
||||
// ricerca binaria dell'intervallo contenente la posizione del triangolo
|
||||
int nS = 0 ;
|
||||
int nE = int( m_vBaseInd.size()) - 1 ;
|
||||
while ( true) {
|
||||
if ( nT < m_vBaseInd[nS] || nT >= m_vBaseInd[nE])
|
||||
return -1 ;
|
||||
if ( nE - nS == 1)
|
||||
return nS ;
|
||||
int nM = ( nS + nE) / 2 ;
|
||||
if ( nT == m_vBaseInd[nM])
|
||||
return nM ;
|
||||
if ( nT < m_vBaseInd[nM])
|
||||
nE = nM ;
|
||||
else
|
||||
nS = nM ;
|
||||
}
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
@@ -215,7 +302,7 @@ FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||
// intersezione precedente
|
||||
size_t i = j - 1 ;
|
||||
// se hanno lo stesso parametro
|
||||
// se hanno lo stesso parametro
|
||||
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
||||
|
||||
+2
-2
@@ -17,8 +17,8 @@
|
||||
#include "CurveLine.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "DistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <array>
|
||||
|
||||
@@ -42,5 +42,5 @@ Inters3Planes( const Plane3d& plPlane1, const Plane3d& plPlane2, const Plane3d&
|
||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptL, vtL) != IPPT_YES)
|
||||
return IPPT_NO ;
|
||||
// intersezione della linea con il terzo piano
|
||||
return ( IntersLinePlane( ptL, vtL, 1, plPlane3, ptInt) == ILPT_YES ? IPPT_YES : IPPT_NO) ;
|
||||
return ( IntersLinePlane( ptL, vtL, 1, plPlane3, ptInt, false) == ILPT_YES ? IPPT_YES : IPPT_NO) ;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "ProjPlane.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Intersezione di unpiano con la superficie di un solido VolZmap
|
||||
// Intersezione di un piano con la superficie di un solido VolZmap
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
|
||||
@@ -28,9 +28,6 @@ IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR&
|
||||
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||
if ( pVzm == nullptr)
|
||||
return false ;
|
||||
// verifico parametro di ritorno
|
||||
if ( &vpLoop == nullptr)
|
||||
return false ;
|
||||
|
||||
// eseguo intersezione
|
||||
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "IntersLineTria.h"
|
||||
#include "DllMain.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkIntersSurfTmSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersTriaTria.h"
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkLineTgCurvePerpCurve.h"
|
||||
#include "/EgtDev/Include/EGkLinePntTgCurve.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CreateCurveAux.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkLineTgTwoCurves.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2025-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : MultiGeomDB.cpp Data : 08.10.25 Versione : 2.7j1
|
||||
// Contenuto : Implementazione delle funzioni tra due GeomDB.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 08.10.25 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeomDB.h"
|
||||
#include "/EgtDev/Include/EGkMultiGeomDB.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// recupero l'oggetto da copiare dal GeomDB sorgente
|
||||
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
|
||||
if ( IsNull( pGObj))
|
||||
return GDB_ID_NULL ;
|
||||
// se in globale
|
||||
if ( bGlob) {
|
||||
// recupero il riferimento del sorgente
|
||||
Frame3d frSou ;
|
||||
if ( ! pSouGDB->GetGlobFrame( nSouId, frSou))
|
||||
return GDB_ID_NULL ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||
return GDB_ID_NULL ;
|
||||
// porto la copia da riferimento sorgente a quello destinazione
|
||||
pGObj->LocToLoc( frSou, frDest) ;
|
||||
}
|
||||
// lo inserisco nel GeomDB destinazione
|
||||
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, nSonBeforeAfter, Release( pGObj)) ;
|
||||
if ( nNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// recupero il riferimento del gruppo
|
||||
Frame3d frFrame = *( pSouGDB->GetGroupFrame( nSouId)) ;
|
||||
// se in globale
|
||||
if ( bGlob) {
|
||||
// recupero il riferimento del gruppo in globale
|
||||
if ( ! pSouGDB->GetGroupGlobFrame( nSouId, frFrame))
|
||||
return GDB_ID_NULL ;
|
||||
// recupero il riferimento del gruppo destinazione
|
||||
Frame3d frDest ;
|
||||
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||
return GDB_ID_NULL ;
|
||||
// porto la copia da riferimento sorgente a quello destinazione
|
||||
frFrame.ToLoc( frDest) ;
|
||||
}
|
||||
// inserisco un nuovo gruppo nel GeomDB destinazione
|
||||
int nNewId = pDstGDB->InsertGroup( nDestId, nRefId, nSonBeforeAfter, frFrame) ;
|
||||
if ( nNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
// copio gli eventuali figli
|
||||
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
|
||||
while ( nSonSouId != GDB_ID_NULL) {
|
||||
// nuovo identificativo oggetto destinazione
|
||||
int nSonNewId = GDB_ID_NULL ;
|
||||
// recupero il tipo di oggetto sorgente
|
||||
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
|
||||
// se l'oggetto da copiare è geometrico
|
||||
if ( nSonSouType == GDB_TY_GEO)
|
||||
nSonNewId = CopyGeoObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||
// se altrimenti è un gruppo
|
||||
else if ( nSonSouType == GDB_TY_GROUP)
|
||||
nSonNewId = CopyGroupObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||
// se copia non riuscita, esco con errore
|
||||
if ( nSonNewId == GDB_ID_NULL)
|
||||
return GDB_ID_NULL ;
|
||||
// passo al figlio successivo
|
||||
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||
{
|
||||
// adatto e verifico i GeomDB
|
||||
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
|
||||
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
|
||||
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||
return GDB_ID_NULL ;
|
||||
// il sorgente non può essere il gruppo radice
|
||||
if ( nSouId == GDB_ID_ROOT)
|
||||
return GDB_ID_NULL ;
|
||||
// nuovo identificativo oggetto destinazione
|
||||
int nNewId = GDB_ID_NULL ;
|
||||
// recupero il tipo di oggetto sorgente
|
||||
int nSouType = pSouGDB->GetGdbType( nSouId) ;
|
||||
// se l'oggetto da copiare è geometrico
|
||||
if ( nSouType == GDB_TY_GEO) {
|
||||
nNewId = CopyGeoObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||
}
|
||||
// se altrimenti è un gruppo
|
||||
else if ( nSouType == GDB_TY_GROUP) {
|
||||
nNewId = CopyGroupObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||
{
|
||||
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, false) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
CopyGlob( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||
{
|
||||
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, true) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId)
|
||||
{
|
||||
// recupero l'oggetto da copiare dal GeomDB sorgente
|
||||
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
|
||||
if ( IsNull( pGObj))
|
||||
return GDB_ID_NULL ;
|
||||
// lo inserisco nel GeomDB destinazione
|
||||
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, GDB_LAST_SON, Release( pGObj)) ;
|
||||
if ( nNewId != nDestId) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static int
|
||||
DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp)
|
||||
{
|
||||
int nNewId = GDB_ID_ROOT ;
|
||||
if ( nSouId != GDB_ID_ROOT) {
|
||||
// recupero il riferimento del gruppo
|
||||
Frame3d frFrame = *( pSouGDB->GetGroupFrame( nSouId)) ;
|
||||
// inserisco un nuovo gruppo nel GeomDB destinazione
|
||||
nNewId = pDstGDB->InsertGroup( nDestId, nRefId, GDB_LAST_SON, frFrame) ;
|
||||
if ( nNewId != nSouId) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
// copio le caratteristiche non geometriche
|
||||
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||
pDstGDB->Erase( nNewId) ;
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
}
|
||||
// copio gli eventuali figli
|
||||
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
|
||||
while ( nSonSouId != GDB_ID_NULL) {
|
||||
// verifico se non richiesto di saltare i temporanei oppure non lo è
|
||||
int nLevel ;
|
||||
if ( ! bSkipTemp || ! pSouGDB->GetLevel( nSonSouId, nLevel) || nLevel != GDB_LV_TEMP) {
|
||||
// nuovo identificativo oggetto destinazione
|
||||
int nSonNewId = GDB_ID_NULL ;
|
||||
// recupero il tipo di oggetto sorgente
|
||||
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
|
||||
// se l'oggetto da copiare è geometrico
|
||||
if ( nSonSouType == GDB_TY_GEO)
|
||||
nSonNewId = DuplicateGeoObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId) ;
|
||||
// se altrimenti è un gruppo
|
||||
else if ( nSonSouType == GDB_TY_GROUP)
|
||||
nSonNewId = DuplicateGroupObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId, bSkipTemp) ;
|
||||
// se copia non riuscita, esco con errore
|
||||
if ( nSonNewId != nSonSouId)
|
||||
return GDB_ID_NULL ;
|
||||
}
|
||||
// passo al figlio successivo
|
||||
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
|
||||
}
|
||||
|
||||
return nNewId ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
DuplicateGeomDB( IGeomDB* pSouGeomDB, IGeomDB* pDestGeomDB, bool bSkipTemp)
|
||||
{
|
||||
// adatto e verifico i GeomDB
|
||||
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
|
||||
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
|
||||
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||
return false ;
|
||||
// verifico che la destinazione sia vuota
|
||||
if ( pDstGDB->GetFirstInGroup( GDB_ID_ROOT) != GDB_ID_NULL)
|
||||
return false ;
|
||||
// eseguo la copia di tutto (se richiesto salto gli oggetti temporanei)
|
||||
return ( DuplicateGroupObj( pSouGDB, GDB_ID_ROOT, pDstGDB, GDB_ID_ROOT, GDB_ID_ROOT, bSkipTemp) != GDB_ID_NULL) ;
|
||||
}
|
||||
+63
-74
@@ -17,6 +17,7 @@
|
||||
#include "NgeKeyW.h"
|
||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||
#include "/EgtDev/Include/EgtStringConverter.h"
|
||||
#include "/EgtDev/Extern/zlib/Include/zlib.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -34,8 +35,12 @@ NgeReader::Init( const string& sFileIn)
|
||||
break ;
|
||||
case NGE_BINARY :
|
||||
m_bBinary = true ;
|
||||
m_InFile.open( stringtoW( sFileIn), ios::in | ios::binary, _SH_DENYWR) ;
|
||||
return ( ! m_InFile.fail()) ;
|
||||
m_InFile = gzopen_w( stringtoW( sFileIn), "rb") ;
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
const int DIM_BUFFER = 65536 ;
|
||||
gzbuffer( m_InFile, DIM_BUFFER) ;
|
||||
return true ;
|
||||
break ;
|
||||
}
|
||||
return false ;
|
||||
@@ -46,10 +51,12 @@ bool
|
||||
NgeReader::Close( void)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
bool bOk = ( m_InFile.good() && m_InFile.is_open()) ;
|
||||
if ( m_InFile.is_open())
|
||||
m_InFile.close() ;
|
||||
return bOk ;
|
||||
if ( m_InFile != nullptr) {
|
||||
bool bOk = ( gzclose( m_InFile) == Z_OK) ;
|
||||
m_InFile = nullptr ;
|
||||
return bOk ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
else
|
||||
return m_Scan.Terminate() ;
|
||||
@@ -59,31 +66,24 @@ NgeReader::Close( void)
|
||||
int
|
||||
NgeReader::NgeType( const string& sFile)
|
||||
{
|
||||
// apertura del file di ingresso
|
||||
ifstream InFile ;
|
||||
InFile.open( stringtoW( sFile), ios::in | ios::binary) ;
|
||||
if ( InFile.fail())
|
||||
// apertura file
|
||||
gzFile_s* InFile = gzopen_w( stringtoW( sFile), "rb") ;
|
||||
if ( InFile == nullptr)
|
||||
return NGE_ERROR ;
|
||||
|
||||
// lettura dei primi 31 byte
|
||||
char cBuff[32] ;
|
||||
InFile.read( cBuff, 31) ;
|
||||
cBuff[InFile.gcount()] = '\0' ;
|
||||
|
||||
// chiusura del file
|
||||
InFile.close() ;
|
||||
|
||||
// verifico se file compresso (gz)
|
||||
if ( cBuff[0] == '\x1F' && cBuff[1] == '\x8B')
|
||||
return NGE_ASCII ;
|
||||
|
||||
// verifico se iniziano con "START"
|
||||
string sBuff = cBuff ;
|
||||
size_t nPos = sBuff.find( "START") ;
|
||||
if ( nPos != string::npos && nPos < 10)
|
||||
return NGE_ASCII ;
|
||||
else
|
||||
// lettura dei primi caratteri
|
||||
char szBuff[9] = "\0\0\0\0\0\0\0\0" ;
|
||||
int nLen = gzread( InFile, &szBuff, 8) ;
|
||||
if ( gzclose( InFile) != Z_OK || nLen == Z_ERRNO)
|
||||
return NGE_ERROR ;
|
||||
// se binario
|
||||
if ( szBuff[0] == '\x0F' && szBuff[1] == '\x0F')
|
||||
return NGE_BINARY ;
|
||||
// se testo
|
||||
string sBuff{ szBuff} ;
|
||||
if ( sBuff.find( "START") != string::npos)
|
||||
return NGE_ASCII ;
|
||||
// altrimenti errore
|
||||
return NGE_ERROR ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -91,7 +91,7 @@ int
|
||||
NgeReader::GetCurrPos( void)
|
||||
{
|
||||
if ( m_bBinary)
|
||||
return int( m_InFile.tellg()) ;
|
||||
return int( gztell( m_InFile)) ;
|
||||
else
|
||||
return m_Scan.GetCurrLineNbr() ;
|
||||
}
|
||||
@@ -131,10 +131,9 @@ bool
|
||||
NgeReader::ReadUchar( unsigned char& ucVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &ucVal, sizeof( ucVal)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &ucVal, sizeof( ucVal)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -154,10 +153,9 @@ bool
|
||||
NgeReader::ReadBool( bool& bVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &bVal, sizeof( bVal)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &bVal, sizeof( bVal)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -173,10 +171,9 @@ bool
|
||||
NgeReader::ReadInt( int& nVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &nVal, sizeof( nVal)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -203,10 +200,9 @@ bool
|
||||
NgeReader::ReadDouble( double& dVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &dVal, sizeof( dVal)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &dVal, sizeof( dVal)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -222,10 +218,9 @@ bool
|
||||
NgeReader::ReadVector( Vector3d& vtV, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &vtV.v, sizeof( vtV.v)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &vtV.v, sizeof( vtV.v)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -241,10 +236,9 @@ bool
|
||||
NgeReader::ReadPoint( Point3d& ptP, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -260,11 +254,10 @@ bool
|
||||
NgeReader::ReadPointW( Point3d& ptP, double& dW, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
|
||||
m_InFile.read( (char*) &dW, sizeof( dW)) ;
|
||||
return m_InFile.good() ;
|
||||
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO &&
|
||||
gzread( m_InFile, &dW, sizeof( dW)) != Z_ERRNO) ;
|
||||
}
|
||||
else {
|
||||
// recupero il token
|
||||
@@ -280,17 +273,13 @@ bool
|
||||
NgeReader::ReadFrame( Frame3d& frF, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
Point3d ptOrig ;
|
||||
m_InFile.read( (char*) &ptOrig.v, sizeof( ptOrig.v)) ;
|
||||
Vector3d vtDirX ;
|
||||
m_InFile.read( (char*) &vtDirX.v, sizeof( vtDirX.v)) ;
|
||||
Vector3d vtDirY ;
|
||||
m_InFile.read( (char*) &vtDirY.v, sizeof( vtDirY.v)) ;
|
||||
Vector3d vtDirZ ;
|
||||
m_InFile.read( (char*) &vtDirZ.v, sizeof( vtDirZ.v)) ;
|
||||
if ( ! m_InFile.good())
|
||||
Point3d ptOrig ; Vector3d vtDirX, vtDirY, vtDirZ ;
|
||||
if ( gzread( m_InFile, &ptOrig.v, sizeof( ptOrig.v)) == Z_ERRNO ||
|
||||
gzread( m_InFile, &vtDirX.v, sizeof( vtDirX.v)) == Z_ERRNO ||
|
||||
gzread( m_InFile, &vtDirY.v, sizeof( vtDirY.v)) == Z_ERRNO ||
|
||||
gzread( m_InFile, &vtDirZ.v, sizeof( vtDirZ.v)) == Z_ERRNO)
|
||||
return false ;
|
||||
return frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ;
|
||||
}
|
||||
@@ -308,18 +297,20 @@ bool
|
||||
NgeReader::ReadString( string& sVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
const int MAX_STR_DIM = 65535 ;
|
||||
if ( ! m_InFile.is_open())
|
||||
return false ;
|
||||
int nDim ;
|
||||
m_InFile.read( (char*) &nDim, sizeof( nDim)) ;
|
||||
if ( nDim > MAX_STR_DIM || ! m_InFile.good())
|
||||
if ( gzread( m_InFile, &nDim, sizeof( nDim)) == Z_ERRNO || nDim > MAX_STR_DIM)
|
||||
return false ;
|
||||
if ( nDim == 0) {
|
||||
sVal = "" ;
|
||||
return true ;
|
||||
}
|
||||
char* szBuff = new( nothrow) char[ nDim + 1] ;
|
||||
if ( szBuff == nullptr)
|
||||
return false ;
|
||||
m_InFile.read( szBuff, nDim) ;
|
||||
if ( ! m_InFile.good()) {
|
||||
if ( gzread( m_InFile, szBuff, nDim) == Z_ERRNO) {
|
||||
delete[] szBuff ;
|
||||
return false ;
|
||||
}
|
||||
@@ -348,12 +339,11 @@ NgeReader::ReadKey( int& nKey)
|
||||
return true ;
|
||||
}
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
// leggo il dato
|
||||
int nVal ;
|
||||
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
|
||||
if ( ! m_InFile.good())
|
||||
if ( gzread( m_InFile, &nVal, sizeof( nVal)) == Z_ERRNO)
|
||||
return false ;
|
||||
// ricavo l'indice
|
||||
for ( int i = 0 ; i <= NGE_LAST_ID ; ++ i) {
|
||||
@@ -386,11 +376,10 @@ bool
|
||||
NgeReader::ReadCol( Color& cCol, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_InFile.is_open())
|
||||
if ( m_InFile == nullptr)
|
||||
return false ;
|
||||
unsigned char ucCol[4] ;
|
||||
m_InFile.read( (char*) &ucCol, sizeof( ucCol)) ;
|
||||
if ( ! m_InFile.good())
|
||||
if ( gzread( m_InFile, &ucCol, sizeof( ucCol)) == Z_ERRNO)
|
||||
return false ;
|
||||
cCol.Set( ucCol[0], ucCol[1], ucCol[2], ucCol[3]) ;
|
||||
return true ;
|
||||
|
||||
+7
-5
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
// EgalTech 2014-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : NgeReader.h Data : 14.04.14 Versione : 1.5d5
|
||||
// File : NgeReader.h Data : 29.12.25 Versione : 2.7l6
|
||||
// Contenuto : Dichiarazione della classe NgeReader.
|
||||
//
|
||||
//
|
||||
@@ -18,14 +18,16 @@
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
#include "/EgtDev/Include/EGnScanner.h"
|
||||
#include "/EgtDev/Include/EgtStringBase.h"
|
||||
#include <fstream>
|
||||
|
||||
struct gzFile_s ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class NgeReader
|
||||
{
|
||||
public :
|
||||
NgeReader( void)
|
||||
: m_iPosStart( std::string::npos), m_bUngetKey( false), m_nFileVer() {}
|
||||
: m_bBinary( false), m_InFile( nullptr), m_iPosStart( std::string::npos),
|
||||
m_bUngetKey( false), m_nLastKey(), m_nFileVer() {}
|
||||
~NgeReader( void)
|
||||
{ Close() ; }
|
||||
bool Init( const std::string& sFileIn) ;
|
||||
@@ -60,7 +62,7 @@ class NgeReader
|
||||
private :
|
||||
bool m_bBinary ;
|
||||
// per file binari
|
||||
std::ifstream m_InFile ;
|
||||
gzFile_s* m_InFile ;
|
||||
// per file ASCII
|
||||
Scanner m_Scan ;
|
||||
std::string::size_type m_iPosStart ;
|
||||
|
||||
+64
-86
@@ -23,23 +23,23 @@
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
inline bool
|
||||
WriteStringOutTxt( gzFile OutTxtFile, const char* szVal, const char* szSep, bool bEndL)
|
||||
static bool
|
||||
WriteStringOutTxt( gzFile OutFile, const char* szVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
// verifico apertura file
|
||||
if ( OutTxtFile == nullptr)
|
||||
if ( OutFile == nullptr)
|
||||
return false ;
|
||||
// scrivo stringa
|
||||
if ( gzputs( OutTxtFile, szVal) == Z_ERRNO)
|
||||
if ( gzputs( OutFile, szVal) == Z_ERRNO)
|
||||
return false ;
|
||||
// se fornito, scrivo separatore
|
||||
if ( szSep != nullptr && szSep[0] != '\0') {
|
||||
if ( gzputs( OutTxtFile, szSep) == Z_ERRNO)
|
||||
if ( gzputs( OutFile, szSep) == Z_ERRNO)
|
||||
return false ;
|
||||
}
|
||||
// se richiesto, scrivo fine linea
|
||||
if ( bEndL) {
|
||||
if ( gzputs( OutTxtFile, "\r\n") == Z_ERRNO)
|
||||
if ( gzputs( OutFile, "\r\n") == Z_ERRNO)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
@@ -50,27 +50,22 @@ bool
|
||||
NgeWriter::Init( const string& sFileOut, int nFlag)
|
||||
{
|
||||
// salvo tipo file
|
||||
m_bBinary = ( nFlag == GDB_SV_BIN) ;
|
||||
m_bBinary = ( nFlag == GDB_SV_BIN || nFlag == GDB_SV_CMPBIN) ;
|
||||
|
||||
// apertura del file di uscita
|
||||
if ( m_bBinary) {
|
||||
ios_base::openmode nMode = ios::out | ( m_bBinary ? ios::binary : 0) ;
|
||||
int nProt = _SH_DENYWR ;
|
||||
m_OutBinFile.open( stringtoW( sFileOut), nMode, nProt) ;
|
||||
return m_OutBinFile.good() ;
|
||||
if ( nFlag == GDB_SV_TXT || nFlag == GDB_SV_BIN) {
|
||||
m_OutFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
|
||||
return ( m_OutFile != nullptr) ;
|
||||
}
|
||||
else {
|
||||
if ( nFlag == GDB_SV_TXT)
|
||||
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
|
||||
else // GDB_SV_CMPTXT
|
||||
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wb") ;
|
||||
if ( m_OutTxtFile == nullptr)
|
||||
else { // GDB_SV_CMPTXT o GDB_SV_CMPBIN
|
||||
m_OutFile = gzopen_w( stringtoW( sFileOut), "wb") ;
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
const int DIM_BUFFER = 65536 ;
|
||||
if ( gzbuffer( m_OutTxtFile, DIM_BUFFER) != Z_OK)
|
||||
if ( gzbuffer( m_OutFile, DIM_BUFFER) != Z_OK)
|
||||
return false ;
|
||||
const int COMPR_LEVEL = 3 ; // 0 = no compression ... 9 = max compression
|
||||
if ( gzsetparams( m_OutTxtFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
if ( gzsetparams( m_OutFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
@@ -80,20 +75,12 @@ NgeWriter::Init( const string& sFileOut, int nFlag)
|
||||
bool
|
||||
NgeWriter::Close( void)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
bool bOk = ( m_OutBinFile.good() && m_OutBinFile.is_open()) ;
|
||||
if ( m_OutBinFile.is_open())
|
||||
m_OutBinFile.close() ;
|
||||
if ( m_OutFile != nullptr) {
|
||||
bool bOk = ( gzclose( m_OutFile) == Z_OK) ;
|
||||
m_OutFile = nullptr ;
|
||||
return bOk ;
|
||||
}
|
||||
else {
|
||||
if ( m_OutTxtFile != nullptr) {
|
||||
bool bOk = ( gzclose( m_OutTxtFile) == Z_OK) ;
|
||||
m_OutTxtFile = nullptr ;
|
||||
return bOk ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -101,13 +88,12 @@ bool
|
||||
NgeWriter::WriteUchar( unsigned char ucVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &ucVal, sizeof( ucVal)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &ucVal, sizeof( ucVal)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ucVal).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( ucVal).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,13 +102,12 @@ bool
|
||||
NgeWriter::WriteBool( bool bVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &bVal, sizeof( bVal)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &bVal, sizeof( bVal)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( bVal).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( bVal).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,13 +116,12 @@ bool
|
||||
NgeWriter::WriteInt( int nVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &nVal, sizeof( nVal)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &nVal, sizeof( nVal)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( nVal).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( nVal).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,13 +130,12 @@ bool
|
||||
NgeWriter::WriteDouble( double dVal, const char* szSep, bool bEndL, int nPrec)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &dVal, sizeof( dVal)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &dVal, sizeof( dVal)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,15 +144,14 @@ bool
|
||||
NgeWriter::WriteString( const string& sVal, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
int nDim = int( sVal.size()) ;
|
||||
m_OutBinFile.write( (char*) &nDim, sizeof( nDim)) ;
|
||||
m_OutBinFile.write( sVal.c_str(), sVal.size()) ;
|
||||
return m_OutBinFile.good() ;
|
||||
int nDim = ssize( sVal) ;
|
||||
return ( gzwrite( m_OutFile, &nDim, sizeof( nDim)) > 0 &&
|
||||
( nDim == 0 || gzwrite( m_OutFile, sVal.c_str(), sVal.size()) > 0)) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, sVal.c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,13 +160,12 @@ bool
|
||||
NgeWriter::WriteVector( const Vector3d& vtV, const char* szSep, bool bEndL, int nPrec)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &vtV.v, sizeof( vtV.v)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &vtV.v, sizeof( vtV.v)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,13 +174,12 @@ bool
|
||||
NgeWriter::WritePoint( const Point3d& ptP, const char* szSep, bool bEndL, int nPrec)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,14 +188,13 @@ bool
|
||||
NgeWriter::WritePointW( const Point3d& ptP, double dW, const char* szSep, bool bEndL, int nPrecP, int nPrecW)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
|
||||
m_OutBinFile.write( (char*) &dW, sizeof( dW)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0 &&
|
||||
gzwrite( m_OutFile, &dW, sizeof( dW)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,16 +203,15 @@ bool
|
||||
NgeWriter::WriteFrame( const Frame3d& frF, const char* szSep, bool bEndL, int nPrecP, int nPrecV)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &frF.Orig().v, sizeof( frF.Orig().v)) ;
|
||||
m_OutBinFile.write( (char*) &frF.VersX().v, sizeof( frF.VersX().v)) ;
|
||||
m_OutBinFile.write( (char*) &frF.VersY().v, sizeof( frF.VersY().v)) ;
|
||||
m_OutBinFile.write( (char*) &frF.VersZ().v, sizeof( frF.VersZ().v)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &frF.Orig().v, sizeof( frF.Orig().v)) > 0 &&
|
||||
gzwrite( m_OutFile, &frF.VersX().v, sizeof( frF.VersX().v)) > 0 &&
|
||||
gzwrite( m_OutFile, &frF.VersY().v, sizeof( frF.VersY().v)) > 0 &&
|
||||
gzwrite( m_OutFile, &frF.VersZ().v, sizeof( frF.VersZ().v)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,13 +223,12 @@ NgeWriter::WriteKey( int nKey)
|
||||
return false ;
|
||||
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
m_OutBinFile.write( (char*) &NgeBinKeyW[nKey], sizeof( int)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, &NgeBinKeyW[nKey], sizeof( int)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
|
||||
return WriteStringOutTxt( m_OutFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,18 +237,17 @@ bool
|
||||
NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
|
||||
{
|
||||
if ( m_bBinary) {
|
||||
if ( ! m_OutBinFile.is_open())
|
||||
if ( m_OutFile == nullptr)
|
||||
return false ;
|
||||
unsigned char ucCol[4] ;
|
||||
ucCol[0] = cCol.GetIntRed() ;
|
||||
ucCol[1] = cCol.GetIntGreen() ;
|
||||
ucCol[2] = cCol.GetIntBlue() ;
|
||||
ucCol[3] = cCol.GetIntAlpha() ;
|
||||
m_OutBinFile.write( (char*) ucCol, sizeof( ucCol)) ;
|
||||
return m_OutBinFile.good() ;
|
||||
return ( gzwrite( m_OutFile, ucCol, sizeof( ucCol)) > 0) ;
|
||||
}
|
||||
else {
|
||||
return WriteStringOutTxt( m_OutTxtFile, ToString( cCol).c_str(), szSep, bEndL) ;
|
||||
return WriteStringOutTxt( m_OutFile, ToString( cCol).c_str(), szSep, bEndL) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +255,11 @@ NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
|
||||
bool
|
||||
NgeWriter::WriteRemark( const string& sVal)
|
||||
{
|
||||
if ( m_bBinary)
|
||||
if ( m_bBinary) {
|
||||
return true ;
|
||||
else
|
||||
return ( WriteStringOutTxt( m_OutTxtFile, "//", nullptr, false) &&
|
||||
WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), nullptr, true)) ;
|
||||
}
|
||||
else {
|
||||
return ( WriteStringOutTxt( m_OutFile, "//", nullptr, false) &&
|
||||
WriteStringOutTxt( m_OutFile, sVal.c_str(), nullptr, true)) ;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-9
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2014
|
||||
// EgalTech 2014-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : NgeWriter.h Data : 12.04.14 Versione : 1.5d5
|
||||
// File : NgeWriter.h Data : 29.12.25 Versione : 2.7l6
|
||||
// Contenuto : Dichiarazione della classe NgeWriter.
|
||||
//
|
||||
//
|
||||
@@ -16,7 +16,6 @@
|
||||
#include "NgeConst.h"
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
#include "/EgtDev/Include/EGkColor.h"
|
||||
#include <fstream>
|
||||
|
||||
struct gzFile_s ;
|
||||
|
||||
@@ -24,7 +23,7 @@ struct gzFile_s ;
|
||||
class NgeWriter
|
||||
{
|
||||
public :
|
||||
NgeWriter( void) : m_bBinary( false), m_OutTxtFile( nullptr) {}
|
||||
NgeWriter( void) : m_bBinary( false), m_OutFile( nullptr) {}
|
||||
~NgeWriter( void)
|
||||
{ Close() ; }
|
||||
bool Init( const std::string& sFileOut, int nFlag) ;
|
||||
@@ -44,9 +43,6 @@ class NgeWriter
|
||||
bool WriteRemark( const std::string& sVal /* bEndL = true*/) ;
|
||||
|
||||
private :
|
||||
bool m_bBinary ;
|
||||
// per file binari
|
||||
std::ofstream m_OutBinFile ;
|
||||
// per file ASCII
|
||||
gzFile_s* m_OutTxtFile ;
|
||||
bool m_bBinary ;
|
||||
gzFile_s* m_OutFile ;
|
||||
} ;
|
||||
|
||||
+155
-33
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// File : OffsetAux.cpp Data : 23.11.23 Versione : 2.5k5
|
||||
// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve.
|
||||
// Contenuto : Implementazione di alcune funzioni di utilità per gli offset delle curve.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -16,20 +16,24 @@
|
||||
#include "CurveArc.h"
|
||||
#include "CurveLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkIntervals.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool IsFillet( const ICurve* pCrv, double dDist) ;
|
||||
static bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
||||
static bool AdjustIntersections( ICRVCOMPOPVECTOR& CrvList) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||
{
|
||||
// identifico le sottocurve di tipo fillet e assegno loro temp param 1.0 per riconoscerle nella funzione AdjustCurveFillets
|
||||
for ( int i = 0 ; i < pCrvCo->GetCurveCount() ; i ++) {
|
||||
// recupero la curva
|
||||
PtrOwner<ICurve> pCrv( pCrvCo->GetCurve(i)->Clone()) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
if ( IsFillet( pCrv, dDist))
|
||||
if ( IsFillet( pCrvCo->GetCurve( i), dDist))
|
||||
pCrvCo->SetCurveTempParam( i, 1.0) ;
|
||||
else
|
||||
pCrvCo->SetCurveTempParam( i, 0.0) ;
|
||||
@@ -39,12 +43,14 @@ IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
IsFillet( ICurve* pCrv, double dDist)
|
||||
IsFillet( const ICurve* pCrv, double dDist)
|
||||
{
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// deve essere un arco
|
||||
if ( pCrv->GetType() != CRV_ARC)
|
||||
return false ;
|
||||
CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||
const CurveArc* pArc = GetBasicCurveArc( pCrv) ;
|
||||
// deve avere raggio uguale alla distanza di offset
|
||||
if ( abs( pArc->GetRadius() - abs( dDist)) > EPS_SMALL)
|
||||
return false ;
|
||||
@@ -54,36 +60,76 @@ IsFillet( ICurve* pCrv, double dDist)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType)
|
||||
AdjustCurveFillets( ICURVEPOVECTOR& vOffset, double dDist, int nType)
|
||||
{
|
||||
ICURVEPLIST CrvLst ;
|
||||
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
||||
while ( ! IsNull( pCrv)) {
|
||||
// se identificato come fillet lo trasformo in smusso o estensione
|
||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
||||
CurveComposite ccTemp ;
|
||||
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
||||
// metto in lista le curve risultanti
|
||||
if ( ccTemp.GetCurveCount() > 0) {
|
||||
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
||||
while ( ! IsNull( pCrv2)) {
|
||||
CrvLst.push_back( Release( pCrv2)) ;
|
||||
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
||||
}
|
||||
if ( vOffset.empty())
|
||||
return true ;
|
||||
|
||||
// suddivido le curve di offset individuando i fillet e isolandoli dagli altri tratti
|
||||
ICRVCOMPOPVECTOR vCrvs ;
|
||||
for ( int i = 0 ; i < int( vOffset.size()) ; i ++) {
|
||||
CurveComposite* pCompo = GetBasicCurveComposite( vOffset[i]) ;
|
||||
if ( pCompo == nullptr)
|
||||
return false ;
|
||||
bool bNewCrv = true ;
|
||||
PtrOwner<ICurve> pCrv( pCompo->RemoveFirstOrLastCurve(false)) ;
|
||||
while ( ! IsNull( pCrv)) {
|
||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
||||
// se fillet calcolo il nuovo raccordo
|
||||
CurveComposite* ccTemp = CreateBasicCurveComposite() ;
|
||||
ModifyFillet( pCrv, dDist, nType, *ccTemp) ;
|
||||
// assegno temp param per identificarlo nei conti successivi
|
||||
ccTemp->SetTempParam( 1) ;
|
||||
vCrvs.push_back( ccTemp) ;
|
||||
bNewCrv = true ;
|
||||
}
|
||||
else {
|
||||
// aggiungo la curva
|
||||
if ( bNewCrv) {
|
||||
bNewCrv = false ;
|
||||
CurveComposite* pCompo = ConvertCurveToBasicComposite( Release( pCrv)) ;
|
||||
if ( pCompo == nullptr)
|
||||
return false ;
|
||||
vCrvs.push_back( pCompo) ;
|
||||
}
|
||||
else
|
||||
vCrvs.back()->AddCurve( Release( pCrv)) ;
|
||||
}
|
||||
// passo alla curva successiva
|
||||
pCrv.Set( pCompo->RemoveFirstOrLastCurve( false)) ;
|
||||
}
|
||||
// altrimenti salvo in lista
|
||||
else
|
||||
CrvLst.push_back( Release( pCrv)) ;
|
||||
// passo alla curva successiva
|
||||
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
||||
}
|
||||
// rimetto le curve nella composita
|
||||
for ( auto pCrv : CrvLst) {
|
||||
pCrvCo->AddCurve( pCrv) ;
|
||||
vOffset.clear() ;
|
||||
|
||||
// gestione delle intersezioni
|
||||
if ( ! AdjustIntersections( vCrvs))
|
||||
return false ;
|
||||
|
||||
// concateno i tratti ottenuti
|
||||
ChainCurves ChainCrv ;
|
||||
ChainCrv.Init( false, 2 * EPS_SMALL, vCrvs.size()) ;
|
||||
for ( int i = 0 ; i < int( vCrvs.size()); ++ i) {
|
||||
Point3d ptS, ptE ;
|
||||
Vector3d vtS, vtE ;
|
||||
vCrvs[i]->GetStartPoint( ptS) ;
|
||||
vCrvs[i]->GetEndPoint( ptE) ;
|
||||
vCrvs[i]->GetStartDir( vtS) ;
|
||||
vCrvs[i]->GetEndDir( vtE) ;
|
||||
ChainCrv.AddCurve( i + 1, ptS, vtS, ptE, vtE) ;
|
||||
}
|
||||
// recupero i concatenamenti
|
||||
Point3d ptRef ; vCrvs[0]->GetStartPoint( ptRef) ;
|
||||
INTVECTOR vIds ;
|
||||
while ( ChainCrv.GetChainFromNear( ptRef, false, vIds)) {
|
||||
PtrOwner<CurveComposite> pCompo( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pCompo))
|
||||
return false ;
|
||||
for ( auto i : vIds)
|
||||
pCompo->AddCurve( vCrvs[i-1]) ;
|
||||
pCompo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
pCompo->GetEndPoint( ptRef) ;
|
||||
vOffset.emplace_back( Release( pCompo)) ;
|
||||
}
|
||||
// unisco tratti allineati
|
||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -177,3 +223,79 @@ ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux)
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
AdjustIntersections( ICRVCOMPOPVECTOR& vCrvs)
|
||||
{
|
||||
// sistema le curve nel vettore vCrvs eliminando le parti coinvolte nelle intersezioni
|
||||
|
||||
vector<Intervals> vIntervals( vCrvs.size()) ;
|
||||
INTVECTOR vFillets ;
|
||||
for ( int i = 0 ; i < int( vCrvs.size()) ; i ++) {
|
||||
// salvo i parametri della curva
|
||||
double dParS, dParE ;
|
||||
vCrvs[i]->GetDomain( dParS, dParE) ;
|
||||
vIntervals[i].Set( dParS, dParE) ;
|
||||
// verifico se raccordo
|
||||
if ( vCrvs[i]->GetTempParam() > EPS_SMALL)
|
||||
vFillets.emplace_back( i) ;
|
||||
}
|
||||
|
||||
// verifico se i raccordi intersecano le altre curve
|
||||
bool bInters = false ;
|
||||
for ( int i = 0 ; i < int( vFillets.size()) ; i ++) {
|
||||
int nIdx = vFillets[i] ;
|
||||
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++) {
|
||||
if ( j == nIdx)
|
||||
continue ;
|
||||
|
||||
IntersCurveCurve intCC( *vCrvs[nIdx], *vCrvs[j]) ;
|
||||
int nCnt = intCC.GetIntersCount() ;
|
||||
if ( nCnt > 1) {
|
||||
// aggiorno gli intervalli della curva sottraendo la parte coinvolta dall'intersezione
|
||||
for ( int k = 0 ; k < nCnt - 1 ; k = k+2) {
|
||||
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||
intCC.GetIntCrvCrvInfo( k, iccInfo1) ;
|
||||
// verifico non sia intersezione nell'estremo iniziale o sovrapposizione
|
||||
if ( iccInfo1.IciA[0].dU < EPS_SMALL || iccInfo1.bOverlap) {
|
||||
k-- ;
|
||||
continue ;
|
||||
}
|
||||
intCC.GetIntCrvCrvInfo( k+1, iccInfo2) ;
|
||||
|
||||
vIntervals[nIdx].Subtract( iccInfo1.IciA[0].dU, iccInfo2.IciA[0].dU) ;
|
||||
vIntervals[j].Subtract( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
||||
bInters = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bInters)
|
||||
return true ;
|
||||
|
||||
// aggiorno le curve eliminando i tratti coinvolti nelle intersezioni
|
||||
for ( int i = 0 ; i < int( vIntervals.size()) ; i++) {
|
||||
if ( vIntervals[i].GetCount() > 1) {
|
||||
PtrOwner<CurveComposite> pCompo( CloneBasicCurveComposite( vCrvs[i])) ;
|
||||
if ( IsNull( pCompo))
|
||||
return false ;
|
||||
double dParS, dParE ;
|
||||
vIntervals[i].GetFirst( dParS, dParE) ;
|
||||
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
||||
while ( vIntervals[i].GetNext( dParS, dParE)) {
|
||||
CurveComposite* pCrv = ConvertCurveToBasicComposite( pCompo->CopyParamRange( dParS, dParE)) ;
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
vCrvs.emplace_back( pCrv) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
double dParS, dParE ;
|
||||
vIntervals[i].GetFirst( dParS, dParE) ;
|
||||
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
+2
-4
@@ -2,7 +2,7 @@
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// File : OffsetAux.h Data : 23.11.23 Versione : 2.5k5
|
||||
// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve.
|
||||
// Contenuto : Dichiarazione di alcune funzioni di utilità per gli offset delle curve.
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -16,6 +16,4 @@
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
||||
bool IsFillet( ICurve* pCrv, double dDist) ;
|
||||
bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ;
|
||||
bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
||||
bool AdjustCurveFillets( ICURVEPOVECTOR& vCrvs, double dDist, int nType) ;
|
||||
+88
-32
@@ -60,6 +60,8 @@ OffsetCurve::Reset( void)
|
||||
}
|
||||
}
|
||||
m_CrvLst.clear() ;
|
||||
m_ptOffs = P_INVALID ;
|
||||
m_vtOut = V_INVALID ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -74,7 +76,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// verifico che la curva esista
|
||||
if ( pCrv == nullptr)
|
||||
return false ;
|
||||
// verifico se la curva è un segmento di retta
|
||||
// verifico se la curva è un segmento di retta
|
||||
bool bIsLine = false ;
|
||||
const CurveLine* pLine = GetBasicCurveLine( pCrv) ;
|
||||
if ( pLine != nullptr)
|
||||
@@ -85,7 +87,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( pCompo != nullptr && pCompo->IsALine( m_dLinTol, ptStart, ptEnd))
|
||||
bIsLine = true ;
|
||||
}
|
||||
// verifico che la curva sia piana (per le linee è comunque sempre vero)
|
||||
// verifico che la curva sia piana (per le linee è comunque sempre vero)
|
||||
Plane3d plPlane ;
|
||||
if ( ! pCrv->IsFlat( plPlane, bIsLine, 10 * EPS_SMALL) && ! bIsLine)
|
||||
return false ;
|
||||
@@ -167,7 +169,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// -------------------- OFFSET STANDARD ---------------------------------
|
||||
if ( ! USE_VORONOI) {
|
||||
|
||||
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
||||
// verifico che la curva sia fatta solo da rette e archi che giacciono nel piano XY (VtExtr è ora Z+)
|
||||
if ( ! ccCopy.ArcsBezierCurvesToArcsPerpExtr( m_dLinTol, ANG_TOL_STD_DEG))
|
||||
return false ;
|
||||
|
||||
@@ -187,11 +189,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( ! ccCopy.MergeCurves( m_dLinTol, ANG_TOL_STD_DEG, bClosed, true))
|
||||
return false ;
|
||||
|
||||
// verifico se il punto iniziale è stato modificato
|
||||
// verifico se il punto iniziale è stato modificato
|
||||
Point3d ptNewStart ; ccCopy.GetStartPoint( ptNewStart) ;
|
||||
bChangeStart = ( ! AreSamePointApprox( ptNewStart, ptStart)) ;
|
||||
|
||||
// calcolo le lunghezze delle diverse entità
|
||||
// calcolo le lunghezze delle diverse entità
|
||||
DBLVECTOR vLens ;
|
||||
{
|
||||
const ICurve* pCrv1 = ccCopy.GetFirstCurve() ;
|
||||
@@ -203,7 +205,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
pCrv1 = ccCopy.GetNextCurve() ;
|
||||
}
|
||||
}
|
||||
// calcolo gli angoli tra le diverse entità
|
||||
// calcolo gli angoli tra le diverse entità
|
||||
DBLVECTOR vAngs ;
|
||||
{
|
||||
vAngs.push_back( 0) ;
|
||||
@@ -230,7 +232,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
vAngs.push_back( 0) ;
|
||||
}
|
||||
|
||||
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
|
||||
// primo passo : estraggo entità dalla copia, loro offset elementare e aggiunta raccordi esterni (sempre fillet)
|
||||
CurveComposite ccCopy2 ;
|
||||
if ( ! ccCopy2.CopyFrom( &ccCopy))
|
||||
return false ;
|
||||
@@ -241,11 +243,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
if ( IsNull( pCrv1))
|
||||
return false ;
|
||||
pCrv1->SetTempProp( nInd1) ;
|
||||
if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET)) {
|
||||
if ( ! pCrv1->SimpleOffset( dDist)) {
|
||||
CurveArc* pArc = GetBasicCurveArc( pCrv1) ;
|
||||
if ( pArc == nullptr)
|
||||
return false ;
|
||||
if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
|
||||
if ( pArc->MyExtendedOffset( dDist, true))
|
||||
pCrv1->SetTempProp( - nInd1) ;
|
||||
}
|
||||
// curve successive
|
||||
@@ -253,11 +255,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
while ( ! IsNull( pCrv2)) {
|
||||
// eseguo semplice offset
|
||||
pCrv2->SetTempProp( nInd1 + 1) ;
|
||||
if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET)) {
|
||||
if ( ! pCrv2->SimpleOffset( dDist)) {
|
||||
CurveArc* pArc = GetBasicCurveArc( pCrv2) ;
|
||||
if ( pArc == nullptr)
|
||||
return false ;
|
||||
if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
|
||||
if ( pArc->MyExtendedOffset( dDist, true))
|
||||
pCrv2->SetTempProp( - ( nInd1 + 1)) ;
|
||||
}
|
||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||
@@ -285,9 +287,9 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
|
||||
// se originale chiuso, devo confrontare anche ultima e prima curva
|
||||
if ( bClosed && m_CrvLst.size() >= 2) {
|
||||
// la curva precedente è l'ultima dell'offset
|
||||
// la curva precedente è l'ultima dell'offset
|
||||
ICurve* pCrv1 = m_CrvLst.back() ;
|
||||
// la curva successiva ora è la prima dell'offset
|
||||
// la curva successiva ora è la prima dell'offset
|
||||
ICurve* pCrv2 = m_CrvLst.front() ;
|
||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||
CurveComposite ccTemp ;
|
||||
@@ -334,7 +336,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
bool bNextInt = NextIsLine( iIter, m_CrvLst, bClosed) &&
|
||||
NextIsLonger( nInd1, vLens, bClosed) &&
|
||||
( ( dDist < 0 && vAngs[nInd1] > 0) || ( dDist > 0 && vAngs[nInd1] < 0)) ;
|
||||
// calcolo la massima estensione di offset (Voronoi con entità adiacenti)
|
||||
// calcolo la massima estensione di offset (Voronoi con entità adiacenti)
|
||||
double dMaxDist = INFINITO ;
|
||||
if ( bPrevInt && bNextInt) {
|
||||
double dTgA = tan( 0.5 * ( ANG_STRAIGHT - abs( vAngs[nInd1-1])) * DEGTORAD) ;
|
||||
@@ -502,7 +504,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
|
||||
// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
|
||||
if ( ! bClosed) {
|
||||
// ciconferenza sull'estremità iniziale
|
||||
// ciconferenza sull'estremità iniziale
|
||||
Point3d ptStart ; ccCopy.GetStartPoint( ptStart) ;
|
||||
PtrOwner<CurveArc> pCircS( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCircS) || ! pCircS->Set( ptStart, Z_AX, abs( dDist)))
|
||||
@@ -551,7 +553,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// passo alla successiva
|
||||
++ iIter ;
|
||||
}
|
||||
// circonferenza sull'estremità finale
|
||||
// circonferenza sull'estremità finale
|
||||
Point3d ptEnd ; ccCopy.GetEndPoint( ptEnd) ;
|
||||
PtrOwner<CurveArc> pCircE( CreateBasicCurveArc()) ;
|
||||
if ( IsNull( pCircE) || ! pCircE->Set( ptEnd, Z_AX, abs( dDist)))
|
||||
@@ -672,12 +674,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
}
|
||||
|
||||
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
||||
// NB questa parte non è gestita in modo efficiente perchè dovrebbe essere sempre disabilitata.
|
||||
// Le funzioni sono state ottimizzate per lavorare con voronoi
|
||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
|
||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
||||
IdentifyFillets( pCrvCo, dDist) ;
|
||||
AdjustCurveFillets( pCrvCo, dDist, nType) ;
|
||||
}
|
||||
ICURVEPOVECTOR vCrvs ;
|
||||
vCrvs.reserve( m_CrvLst.size()) ;
|
||||
for ( auto pCrv : m_CrvLst) {
|
||||
IdentifyFillets( GetCurveComposite( pCrv), dDist) ;
|
||||
vCrvs.emplace_back( pCrv) ;
|
||||
}
|
||||
if ( ! AdjustCurveFillets( vCrvs, dDist, nType))
|
||||
return false ;
|
||||
m_CrvLst.clear() ;
|
||||
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++)
|
||||
m_CrvLst.emplace_back( Release( vCrvs[j])) ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -697,6 +707,27 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
// calcolo offset con Voronoi
|
||||
ICURVEPOVECTOR vOffs ;
|
||||
voronoiObj->CalcOffset( vOffs, dDist, nType) ;
|
||||
if ( vOffs.empty()) {
|
||||
// se non ho ottenuto offset e sono circa al valore limite ritento con valore leggermente diverso per le tolleranze di vroni
|
||||
double dMaxOffs ;
|
||||
if ( ! pCrv->IsClosed() || ( voronoiObj->CalcLimitOffset( 0, dDist < 0, dMaxOffs) && abs( dMaxOffs - abs( dDist)) < EPS_SMALL)) {
|
||||
double dCorr = ( dDist > 0 ? - VRONI_OFFS_TOL : VRONI_OFFS_TOL) ;
|
||||
voronoiObj->CalcOffset( vOffs, dDist + dCorr, nType) ;
|
||||
}
|
||||
// se ancora vuoto calcolo i punti speciali di offset ( punti e direzioni sui bisettore alla distanza richiesta)
|
||||
if ( vOffs.empty()) {
|
||||
PNTVECTVECTOR vPntOffs ;
|
||||
voronoiObj->CalcSpecialPointOffset( vPntOffs, dDist) ;
|
||||
// NB al momento vengono gestiti solo i casi in cui vi è un unico punto di offset. Se si ottengono più punti di offset
|
||||
// ( e.g. alcune curve aperte) non se ne restiusce nessuno. Da estendere, se necessario, individuando i punti dal lato
|
||||
// di offset richiesto
|
||||
if ( vPntOffs.size() == 1) {
|
||||
m_ptOffs = vPntOffs[0].first ;
|
||||
m_vtOut = vPntOffs[0].second ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0 ; i < ( int)vOffs.size() ; i ++)
|
||||
m_CrvLst.emplace_back( Release( vOffs[i])) ;
|
||||
|
||||
@@ -724,10 +755,21 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
||||
pCrv->Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
||||
pCrv->ToGlob( frCopy) ;
|
||||
}
|
||||
if ( m_ptOffs.IsValid()) {
|
||||
m_ptOffs.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
||||
m_ptOffs.ToGlob( frCopy) ;
|
||||
m_vtOut.Scale( GLOB_FRM, 1 / dExtrOnN, 1, 1) ;
|
||||
m_vtOut.ToGlob( frCopy) ;
|
||||
}
|
||||
|
||||
}
|
||||
else if ( bNeedRef) {
|
||||
for ( auto pCrv : m_CrvLst)
|
||||
pCrv->ToGlob( frCopy) ;
|
||||
if ( m_ptOffs.IsValid()) {
|
||||
m_ptOffs.ToGlob( frCopy) ;
|
||||
m_vtOut.ToGlob( frCopy) ;
|
||||
}
|
||||
}
|
||||
|
||||
// assegno estrusione e spessore come curva originale e unisco parti allineate
|
||||
@@ -805,6 +847,20 @@ OffsetCurve::GetShorterCurve( void)
|
||||
return pCrv ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
OffsetCurve::GetPointOffset( Point3d& ptOffs, Vector3d& vtOut)
|
||||
{
|
||||
// verifico se valori validi da restituire
|
||||
if ( ! m_ptOffs.IsValid() || ! m_vtOut.IsValid())
|
||||
return false ;
|
||||
|
||||
ptOffs = m_ptOffs ;
|
||||
vtOut = m_vtOut ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool bClosed)
|
||||
@@ -817,7 +873,7 @@ PreviousIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bo
|
||||
// se non esiste e curva chiusa prendo l'ultimo
|
||||
if ( iPrev == CrvLst.end() && bClosed)
|
||||
-- iPrev ;
|
||||
// se non esiste o non è una linea, test fallito
|
||||
// se non esiste o non è una linea, test fallito
|
||||
if ( iPrev == CrvLst.end() || (*iPrev)->GetType() != CRV_LINE )
|
||||
return false ;
|
||||
// test superato
|
||||
@@ -830,7 +886,7 @@ PreviousIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
||||
{
|
||||
// massimo indice nel vettore
|
||||
int nMax = int( vLens.size()) - 1 ;
|
||||
// verifico validità indice (questo indice è incrementato di 1)
|
||||
// verifico validità indice (questo indice è incrementato di 1)
|
||||
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
||||
return false ;
|
||||
// indice del precedente nel vettore di lunghezze
|
||||
@@ -854,7 +910,7 @@ NextIsLine( ICURVEPLIST::const_iterator iIter, const ICURVEPLIST& CrvLst, bool b
|
||||
// se non esiste e curva chiusa prendo il primo
|
||||
if ( iNext == CrvLst.end() && bClosed)
|
||||
iNext = CrvLst.begin() ;
|
||||
// se non esiste o non è una linea, test fallito
|
||||
// se non esiste o non è una linea, test fallito
|
||||
if ( iNext == CrvLst.end() || (*iNext)->GetType() != CRV_LINE )
|
||||
return false ;
|
||||
// test superato
|
||||
@@ -867,7 +923,7 @@ NextIsLonger( int nInd1, const DBLVECTOR& vLens, bool bClosed)
|
||||
{
|
||||
// massimo indice nel vettore
|
||||
int nMax = int( vLens.size()) - 1 ;
|
||||
// verifico validità indice (questo indice è incrementato di 1)
|
||||
// verifico validità indice (questo indice è incrementato di 1)
|
||||
if ( nInd1 < 1 || nInd1 > nMax + 1)
|
||||
return false ;
|
||||
// indice del successivo nel vettore di lunghezze
|
||||
@@ -946,7 +1002,7 @@ VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
||||
nRes = 4 ;
|
||||
return true ;
|
||||
}
|
||||
// se coincidono esattamente, va bene così
|
||||
// se coincidono esattamente, va bene così
|
||||
if ( AreSamePointExact( ptP1, ptP2)) {
|
||||
nRes = 0 ;
|
||||
return true ;
|
||||
@@ -976,7 +1032,7 @@ VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, int& nRes)
|
||||
IntersCurveCurve intCC( *pCrv1, *pCrv2) ;
|
||||
if ( intCC.GetIntersCount() == 0)
|
||||
return false ;
|
||||
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
|
||||
// prendo l'intersezione più vicina al punto medio tra gli estremi delle curve
|
||||
Point3d ptP1, ptP2 ;
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
@@ -1024,7 +1080,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
vtDir2.Invert() ;
|
||||
}
|
||||
|
||||
// verifico sia angolo esterno (accetto se entità quasi esattamente sovrapposte)
|
||||
// verifico sia angolo esterno (accetto se entità quasi esattamente sovrapposte)
|
||||
if ( abs( dAngDeg) < ( ANG_STRAIGHT - 10 * EPS_ANG_ZERO) &&
|
||||
( ( dDist < 0 && dAngDeg > 0) ||
|
||||
( dDist > 0 && dAngDeg < 0)))
|
||||
@@ -1066,7 +1122,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
return false ;
|
||||
ptP1a = ptP1 + vtDir1 * dLen ;
|
||||
ptP2a = ptP2 - vtDir2 * dLen ;
|
||||
// se prima c'è linea posso allungarla
|
||||
// se prima c'è linea posso allungarla
|
||||
if ( pCrv1->GetType() == CRV_LINE)
|
||||
pCrv1->ModifyEnd( ptP1a) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1085,7 +1141,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||
return false ;
|
||||
}
|
||||
// se dopo c'è linea posso allungarla
|
||||
// se dopo c'è linea posso allungarla
|
||||
if ( pCrv2->GetType() == CRV_LINE)
|
||||
pCrv2->ModifyStart( ptP2a) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1108,7 +1164,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! pCrv1->GetEndPoint( ptP1) || ! pCrv2->GetStartPoint( ptP2))
|
||||
return false ;
|
||||
ptPc = ptP1 + vtDir1 * dLen ;
|
||||
// se prima c'è linea o angolo molto piccolo posso allungarla
|
||||
// se prima c'è linea o angolo molto piccolo posso allungarla
|
||||
if ( ( pCrv1->GetType() == CRV_LINE) || bAngSmall)
|
||||
pCrv1->ModifyEnd( ptPc) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
@@ -1119,7 +1175,7 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dAngDeg, doub
|
||||
if ( ! ccAux.AddCurve( Release( pCrv)))
|
||||
return false ;
|
||||
}
|
||||
// se dopo c'è linea o angolo molto piccolo posso allungarla
|
||||
// se dopo c'è linea o angolo molto piccolo posso allungarla
|
||||
if ( ( pCrv2->GetType() == CRV_LINE) || bAngSmall)
|
||||
pCrv2->ModifyStart( ptPc) ;
|
||||
// altrimenti, devo aggiungere una nuova linea
|
||||
|
||||
+2
-2
@@ -195,7 +195,7 @@ PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds) const
|
||||
}
|
||||
}
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
return ( ! vnIds.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -221,7 +221,7 @@ PointGrid3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds) const
|
||||
}
|
||||
}
|
||||
|
||||
return ( vnIds.size() > 0) ;
|
||||
return ( ! vnIds.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+42
-31
@@ -14,36 +14,29 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "PointsPCA.h"
|
||||
#define EIGEN_NO_IO
|
||||
#include "/EgtDev/Extern/Eigen/Dense"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
PointsPCA::PointsPCA( void)
|
||||
{
|
||||
// azzero numero punti
|
||||
m_dTotW = 0 ;
|
||||
// azzero il baricentro
|
||||
m_ptCen.Set( 0, 0, 0) ;
|
||||
// azzero matrice di covarianza
|
||||
m_CovMat.setZero() ;
|
||||
// inizializzo il rank ad un valore assurdo
|
||||
m_nRank = - 1 ;
|
||||
// inizializzo baricentro
|
||||
m_ptCen.Set( 0, 0, 0) ;
|
||||
// inizializzo il peso totale
|
||||
m_dTotW = 0 ;
|
||||
// riservo memoria per la matrice di punti e pesi
|
||||
m_vPntW.reserve( 128) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
PointsPCA::AddPoint( const Point3d& ptP, double dW)
|
||||
{
|
||||
// incremento numero punti
|
||||
m_dTotW += dW ;
|
||||
// aggiorno il baricentro
|
||||
m_ptCen += dW * ptP ;
|
||||
// aggiorno la matrice di covarianza (solo triangolo superiore perchč simmetrica)
|
||||
m_CovMat(0,0) += dW * ( ptP.x * ptP.x) ;
|
||||
m_CovMat(1,1) += dW * ( ptP.y * ptP.y) ;
|
||||
m_CovMat(2,2) += dW * ( ptP.z * ptP.z) ;
|
||||
m_CovMat(0,1) += dW * ( ptP.x * ptP.y) ;
|
||||
m_CovMat(0,2) += dW * ( ptP.x * ptP.z) ;
|
||||
m_CovMat(1,2) += dW * ( ptP.y * ptP.z) ;
|
||||
// salvo i dati
|
||||
m_vPntW.emplace_back( ptP, dW) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -58,29 +51,47 @@ PointsPCA::Finalize( void)
|
||||
m_nRank = 0 ;
|
||||
|
||||
// se non sono stati assegnati punti, esco
|
||||
if ( m_dTotW < EPS_ZERO)
|
||||
if ( m_vPntW.empty())
|
||||
return false ;
|
||||
|
||||
// fattore di scala per numero di punti
|
||||
// calcolo del peso totale
|
||||
for ( const auto& PntW : m_vPntW)
|
||||
m_dTotW += PntW.second ;
|
||||
if ( m_dTotW < EPS_ZERO)
|
||||
return false ;
|
||||
// fattore di scala
|
||||
double dScale = 1 / m_dTotW ;
|
||||
|
||||
// calcolo del baricentro
|
||||
for ( const auto& PntW : m_vPntW)
|
||||
m_ptCen += PntW.second * PntW.first ;
|
||||
m_ptCen *= dScale ;
|
||||
|
||||
// completo la matrice di covarianza
|
||||
m_CovMat(0,0) = m_CovMat(0,0) * dScale - m_ptCen.x * m_ptCen.x ;
|
||||
m_CovMat(1,1) = m_CovMat(1,1) * dScale - m_ptCen.y * m_ptCen.y ;
|
||||
m_CovMat(2,2) = m_CovMat(2,2) * dScale - m_ptCen.z * m_ptCen.z ;
|
||||
m_CovMat(0,1) = m_CovMat(0,1) * dScale - m_ptCen.x * m_ptCen.y ;
|
||||
m_CovMat(0,2) = m_CovMat(0,2) * dScale - m_ptCen.x * m_ptCen.z ;
|
||||
m_CovMat(1,2) = m_CovMat(1,2) * dScale - m_ptCen.y * m_ptCen.z ;
|
||||
m_CovMat(1,0) = m_CovMat(0,1) ;
|
||||
m_CovMat(2,0) = m_CovMat(0,2) ;
|
||||
m_CovMat(2,1) = m_CovMat(1,2) ;
|
||||
// matrice di covarianza
|
||||
Eigen::Matrix3d CovMat ;
|
||||
CovMat.setZero() ;
|
||||
for ( const auto& PntW : m_vPntW) {
|
||||
Point3d ptP( PntW.first.x - m_ptCen.x, PntW.first.y - m_ptCen.y, PntW.first.z - m_ptCen.z) ;
|
||||
CovMat(0,0) += PntW.second * ( ptP.x * ptP.x) ;
|
||||
CovMat(1,1) += PntW.second * ( ptP.y * ptP.y) ;
|
||||
CovMat(2,2) += PntW.second * ( ptP.z * ptP.z) ;
|
||||
CovMat(0,1) += PntW.second * ( ptP.x * ptP.y) ;
|
||||
CovMat(0,2) += PntW.second * ( ptP.x * ptP.z) ;
|
||||
CovMat(1,2) += PntW.second * ( ptP.y * ptP.z) ;
|
||||
}
|
||||
CovMat(0,0) = CovMat(0,0) * dScale ;
|
||||
CovMat(1,1) = CovMat(1,1) * dScale ;
|
||||
CovMat(2,2) = CovMat(2,2) * dScale ;
|
||||
CovMat(0,1) = CovMat(0,1) * dScale ;
|
||||
CovMat(0,2) = CovMat(0,2) * dScale ;
|
||||
CovMat(1,2) = CovMat(1,2) * dScale ;
|
||||
CovMat(1,0) = CovMat(0,1) ;
|
||||
CovMat(2,0) = CovMat(0,2) ;
|
||||
CovMat(2,1) = CovMat(1,2) ;
|
||||
|
||||
// calcolo gli autovalori e autovettori (essendo matrice 3x3 uso metodo diretto)
|
||||
// calcolo gli autovalori e autovettori
|
||||
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> es ;
|
||||
es.compute( m_CovMat) ; // non usare computeDirect : errore nell'ordine degli autovettori
|
||||
es.compute( CovMat) ; // non usare computeDirect : errore nell'ordine degli autovettori
|
||||
if ( es.info() == Eigen::NoConvergence)
|
||||
return false ;
|
||||
|
||||
|
||||
+3
-4
@@ -13,8 +13,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||
#include "/EgtDev/Extern/Eigen/Dense"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class PointsPCA
|
||||
@@ -33,9 +32,9 @@ class PointsPCA
|
||||
static const int MAX_RANK = 3 ;
|
||||
|
||||
private :
|
||||
double m_dTotW ; // peso totale (se pesi tutti unitari, allora è numero punti)
|
||||
PNTUVECTOR m_vPntW ; // vettore dei punti con i loro pesi
|
||||
Point3d m_ptCen ; // baricentro
|
||||
Eigen::Matrix3d m_CovMat ; // matrice di covarianza
|
||||
double m_dTotW ; // peso totale
|
||||
int m_nRank ; // numero delle componenti principali (MAX_RANK = 3)
|
||||
Vector3d m_vtPC[MAX_RANK] ; // direzioni delle componenti principali
|
||||
} ;
|
||||
+4
-4
@@ -13,9 +13,9 @@
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveArc.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkPolyArc.h"
|
||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||
#include <algorithm>
|
||||
@@ -62,7 +62,7 @@ bool
|
||||
PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge)
|
||||
{
|
||||
// se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok
|
||||
if ( m_lUPointBs.size() > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) {
|
||||
if ( ! m_lUPointBs.empty() && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) {
|
||||
// assegno parametro e bulge
|
||||
m_lUPointBs.back().dU = dPar ;
|
||||
m_lUPointBs.back().dB = dBulge ;
|
||||
@@ -285,10 +285,10 @@ bool
|
||||
PolyArc::Join( PolyArc& PA, double dOffsetPar)
|
||||
{
|
||||
// se l'altro poliarco non contiene alcunchè, esco con ok
|
||||
if ( PA.m_lUPointBs.size() == 0)
|
||||
if ( PA.m_lUPointBs.empty())
|
||||
return true ;
|
||||
// verifico che l'ultimo punto di questo poliarco coincida con il primo dell'altro
|
||||
if ( m_lUPointBs.size() > 0 && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP))
|
||||
if ( ! m_lUPointBs.empty() && ! AreSamePointApprox( m_lUPointBs.back().ptP, PA.m_lUPointBs.front().ptP))
|
||||
return false ;
|
||||
// cancello l'ultimo di questo
|
||||
EraseLastUPoint() ;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user