Compare commits
516 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 466f92384b | |||
| 326f85c3d2 | |||
| 00b6f8583a | |||
| 4cf4a99107 | |||
| 137289e843 | |||
| e7b066e75e | |||
| cd0828f3e0 | |||
| 563697f840 | |||
| 61fc814528 | |||
| 7c90dbabea | |||
| 5ee0f3c373 | |||
| 098bdd0076 | |||
| 40b6da6b44 | |||
| b083dabc6b | |||
| 7fcc3ed42d | |||
| ccefe1314f | |||
| 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 | |||
| e490c173e8 | |||
| 7e165a6dea | |||
| 49ff6e79a8 | |||
| 1160e3d067 | |||
| 91d667bcfc | |||
| b23df89cd3 | |||
| cf9737a48e | |||
| ae52115bda | |||
| 3dd9466938 | |||
| c0f7eb6727 | |||
| 76e2843ed3 | |||
| faa2004c29 | |||
| c9a59dc5ea | |||
| aaaf951990 | |||
| cc263089ca | |||
| d99b8f4c86 | |||
| f5e5441469 | |||
| 4206a4822f | |||
| 788a5bc4eb |
@@ -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 ;
|
||||
} ;
|
||||
+526
-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,40 +122,227 @@ 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)
|
||||
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 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 ;
|
||||
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)
|
||||
return false ;
|
||||
// Se lista vuota, non devo fare alcunché
|
||||
// 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 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
|
||||
@@ -140,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 {
|
||||
@@ -161,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 ;
|
||||
@@ -173,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 ;
|
||||
@@ -185,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
|
||||
@@ -206,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
|
||||
@@ -222,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 ;
|
||||
}
|
||||
@@ -236,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 ;
|
||||
@@ -249,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
|
||||
@@ -258,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
|
||||
@@ -271,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() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -293,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 ;
|
||||
@@ -313,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) {
|
||||
@@ -330,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 ;
|
||||
}
|
||||
|
||||
@@ -345,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 ;
|
||||
@@ -372,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
-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 ;
|
||||
|
||||
+7938
-1834
File diff suppressed because it is too large
Load Diff
+26
-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.
|
||||
//
|
||||
//
|
||||
@@ -43,10 +43,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 +68,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 +82,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 +93,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 +102,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 +113,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 +258,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 +273,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 +281,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 +305,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 +322,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 +346,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 +390,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 +407,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 +431,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"
|
||||
|
||||
+2
-1
@@ -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)
|
||||
|
||||
+1105
-49
File diff suppressed because it is too large
Load Diff
@@ -33,4 +33,5 @@ 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) ;
|
||||
|
||||
+246
-6
@@ -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 ;
|
||||
@@ -138,6 +142,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)
|
||||
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 +225,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 +263,30 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::FromLine( const ICurveLine& crLine)
|
||||
{
|
||||
if ( ! crLine.IsValid())
|
||||
return false ;
|
||||
double dWeight = 1 ;
|
||||
int nCount = 0 ;
|
||||
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
|
||||
SetControlPoint( nCount, ptStart, dWeight) ;
|
||||
++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, dWeight) ;
|
||||
++nCount ;
|
||||
}
|
||||
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
|
||||
SetControlPoint( nCount, ptEnd, dWeight) ;
|
||||
++nCount ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::IsAPoint( void) const
|
||||
@@ -286,6 +369,7 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
||||
return true ;
|
||||
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 ;
|
||||
@@ -1486,7 +1570,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 ;
|
||||
}
|
||||
@@ -1723,12 +1807,24 @@ 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 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1744,7 +1840,10 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimStartAtParam( dUTrim) ;
|
||||
if( ! TrimStartAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1760,7 +1859,10 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
||||
return false ;
|
||||
|
||||
// utilizzo il trim sui parametri
|
||||
return TrimEndAtParam( dUTrim) ;
|
||||
if( ! TrimEndAtParam( dUTrim))
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -2152,3 +2254,141 @@ CurveBezier::ResetVoronoiObject() const
|
||||
delete m_pVoronoiObj ;
|
||||
m_pVoronoiObj = nullptr ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
CurveBezier::MakeRational( void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
||||
for ( int p = 0 ; p < m_nDeg ; ++p) {
|
||||
Point3d pt = GetControlPoint( p) ;
|
||||
pNewBez->SetControlPoint( p, pt) ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// provo ad approssimare la curva di bezier con una controparte non razionale
|
||||
int nDeg = m_nDeg ;
|
||||
// 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
|
||||
CalcBezierApproxError( 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
|
||||
{
|
||||
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 = m_vPtCtrl ;
|
||||
return vPntCtrl ;
|
||||
}
|
||||
+8
-1
@@ -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
|
||||
|
||||
+14
-11
@@ -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"
|
||||
@@ -439,12 +439,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 +483,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 +501,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 +525,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 +564,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 +572,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) ;
|
||||
}
|
||||
|
||||
+144
-91
@@ -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 ;
|
||||
@@ -878,10 +899,15 @@ CurveComposite::TestClosure( void)
|
||||
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 +963,8 @@ CurveComposite::IsFlat( Plane3d& plPlane, bool bUseExtrusion, double dToler) con
|
||||
return false ;
|
||||
}
|
||||
} break ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
@@ -1761,10 +1789,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 +1837,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 +3001,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 +3046,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 +3180,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 +3208,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 +3280,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 +3840,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
|
||||
|
||||
+1
-2
@@ -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 ;
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+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 ;
|
||||
} ;
|
||||
+2
-2
@@ -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"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
+20
-7
@@ -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)) {
|
||||
@@ -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))
|
||||
@@ -262,7 +275,7 @@ DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, i
|
||||
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) {
|
||||
|
||||
+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,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"
|
||||
|
||||
|
||||
|
||||
+10
-1
@@ -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)
|
||||
|
||||
Binary file not shown.
+14
-6
@@ -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>
|
||||
@@ -117,6 +117,7 @@
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>C:\EgtDev\Extern\abseil\Include</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -281,6 +282,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="BBox3d.cpp" />
|
||||
<ClCompile Include="BiArcs.cpp" />
|
||||
<ClCompile Include="CalcPocketing.cpp" />
|
||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||
@@ -309,6 +311,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CurveByApprox.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||
<ClCompile Include="DistPointSurfFr.cpp" />
|
||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||
@@ -318,16 +321,21 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||
<ClCompile Include="IntersLineSurfBez.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" />
|
||||
@@ -338,6 +346,8 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<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 +433,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 +605,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" />
|
||||
|
||||
@@ -486,7 +486,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 +537,21 @@
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -593,9 +608,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 +1130,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 +1223,18 @@
|
||||
<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>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
+4
-4
@@ -612,14 +612,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 +659,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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,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 ;
|
||||
|
||||
+6
-6
@@ -877,7 +877,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 +905,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 +933,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 +961,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 +2310,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 +2318,7 @@ GeomDB::SetMark( int nId)
|
||||
return false ;
|
||||
|
||||
// imposto la marcatura
|
||||
return pGdbObj->SetMark() ;
|
||||
return pGdbObj->SetMark( nMark) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
@@ -136,7 +136,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
|
||||
|
||||
@@ -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])) ;
|
||||
@@ -245,7 +253,7 @@ bool
|
||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
||||
{
|
||||
// se non ci sono intersezioni, non va fatto alcunché
|
||||
if ( m_Info.size() == 0)
|
||||
if ( m_Info.empty())
|
||||
return true ;
|
||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||
|
||||
@@ -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(),
|
||||
|
||||
+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 ;
|
||||
|
||||
+29
-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,36 @@ 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) ;
|
||||
|
||||
// se non sono paralleli e si allontanano tra loro abbastanza
|
||||
if ( ! bParallel && bFarEnds) {
|
||||
@@ -168,6 +172,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 +182,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 +195,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
|
||||
|
||||
+268
-10
@@ -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 ;
|
||||
|
||||
@@ -67,11 +73,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 +89,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) ; }) ;
|
||||
}
|
||||
|
||||
@@ -146,7 +152,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
||||
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] ;
|
||||
@@ -176,7 +182,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 +191,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 +238,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 ;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
+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) ;
|
||||
+84
-28
@@ -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 ;
|
||||
@@ -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()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
+41
-31
@@ -14,36 +14,28 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "PointsPCA.h"
|
||||
#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 +50,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() ;
|
||||
|
||||
+448
-89
@@ -1,4 +1,4 @@
|
||||
//----------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2013-2013
|
||||
//----------------------------------------------------------------------------
|
||||
// File : PolyLine.cpp Data : 22.12.13 Versione : 1.4l3
|
||||
@@ -14,13 +14,15 @@
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "CurveLine.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "IntersLineLine.h"
|
||||
#include "PolygonPlane.h"
|
||||
#include "PointsPCA.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
|
||||
@@ -53,8 +55,8 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
||||
{
|
||||
// se da aggiungere in coda
|
||||
if ( bEndOrStart) {
|
||||
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
|
||||
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
|
||||
// se il punto è uguale all'ultimo (ignoro parametro), non lo inserisco ma ok
|
||||
if ( ! m_lUPoints.empty() && AreSamePointApprox( ptP, m_lUPoints.back().first)) {
|
||||
++ m_nRejected ;
|
||||
return true ;
|
||||
}
|
||||
@@ -68,8 +70,8 @@ PolyLine::AddUPoint( double dPar, const Point3d& ptP, bool bEndOrStart)
|
||||
}
|
||||
// altrimenti si aggiunge in testa
|
||||
else {
|
||||
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
|
||||
if ( m_lUPoints.size() > 0 && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
|
||||
// se il punto è uguale al primo (ignoro parametro), non lo inserisco ma ok
|
||||
if ( ! m_lUPoints.empty() && AreSamePointApprox( ptP, m_lUPoints.front().first)) {
|
||||
++ m_nRejected ;
|
||||
return true ;
|
||||
}
|
||||
@@ -92,7 +94,7 @@ PolyLine::Close( void)
|
||||
// ci devono essere almeno 2 punti
|
||||
if ( m_lUPoints.size() < 2)
|
||||
return false ;
|
||||
// verifico non sia già chiuso
|
||||
// verifico non sia già chiuso
|
||||
if ( AreSamePointApprox( m_lUPoints.front().first, m_lUPoints.back().first))
|
||||
return false ;
|
||||
// aggiungo un punto uguale al primo in coda
|
||||
@@ -219,7 +221,7 @@ PolyLine::ToLoc( const Frame3d& frRef)
|
||||
bool
|
||||
PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
{
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
// se i due riferimenti coincidono, non devo fare alcunché
|
||||
if ( AreSameFrame( frOri, frDest))
|
||||
return true ;
|
||||
// ciclo sui punti
|
||||
@@ -233,11 +235,11 @@ PolyLine::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
PolyLine::Join( PolyLine& PL, double dOffsetPar)
|
||||
{
|
||||
// se l'altra polilinea non contiene alcunchè, esco con ok
|
||||
if ( PL.m_lUPoints.size() == 0)
|
||||
// se l'altra polilinea non contiene alcunchè, esco con ok
|
||||
if ( PL.m_lUPoints.empty())
|
||||
return true ;
|
||||
// verifico che l'ultimo punto di questa polilinea coincida con il primo dell'altra
|
||||
if ( m_lUPoints.size() > 0 && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first))
|
||||
if ( ! m_lUPoints.empty() && ! AreSamePointApprox( m_lUPoints.back().first, PL.m_lUPoints.front().first))
|
||||
return false ;
|
||||
// cancello l'ultimo di questa
|
||||
EraseLastUPoint() ;
|
||||
@@ -385,7 +387,7 @@ PolyLine::GetPrevUPoint( double* pdPar, Point3d* pptP, bool bNotFirst) const
|
||||
bool
|
||||
PolyLine::GetCurrUPoint( double* pdPar, Point3d* pptP) const
|
||||
{
|
||||
// verifico validità punto corrente
|
||||
// verifico validità punto corrente
|
||||
if ( m_iter == m_lUPoints.end())
|
||||
return false ;
|
||||
|
||||
@@ -426,7 +428,7 @@ PolyLine::GetFirstULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d*
|
||||
bool
|
||||
PolyLine::GetNextULine( double* pdIni, Point3d* pptIni, double* pdFin, Point3d* pptFin) const
|
||||
{
|
||||
// parametro e punto iniziali (è il precedente finale)
|
||||
// parametro e punto iniziali (è il precedente finale)
|
||||
if ( m_iter == m_lUPoints.end())
|
||||
return false ;
|
||||
if ( pdIni != nullptr)
|
||||
@@ -510,19 +512,19 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
|
||||
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.25), dLen / 2) ;
|
||||
ptsPCA.AddPoint( Media( ptP1, ptP2, 0.75), dLen / 2) ;
|
||||
}
|
||||
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
|
||||
// recupero il rango, ovvero la dimensionalità dell'insieme di punti
|
||||
nRank = ptsPCA.GetRank() ;
|
||||
// se dimensione nulla, o non ci sono punti o sono tutti praticamente coincidenti
|
||||
if ( nRank == 0)
|
||||
return ptsPCA.GetCenter( ptCen) ;
|
||||
// se dimensione 1, allora i punti sono distribuiti su una linea
|
||||
if ( nRank == 1) {
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
ptsPCA.GetPrincipalComponent( 0, vtDir) ;
|
||||
return true ;
|
||||
}
|
||||
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
|
||||
// altrimenti dimensione 2 o 3, allora è determinato un piano principale, verifico se tutti i punti vi giacciono
|
||||
// Center and normal vector
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
Vector3d vtX, vtY ;
|
||||
@@ -530,9 +532,9 @@ PolyLine::IsFlat( int& nRank, Point3d& ptCen, Vector3d& vtDir, double dToler) co
|
||||
ptsPCA.GetPrincipalComponent( 1, vtY) ;
|
||||
vtDir = vtX ^ vtY ;
|
||||
if ( ! vtDir.Normalize()) {
|
||||
// riduco la dimensionalità a lineare
|
||||
// riduco la dimensionalità a lineare
|
||||
nRank = 1 ;
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
// assegno il centro e la direzione della linea (il verso è indifferente)
|
||||
ptsPCA.GetCenter( ptCen) ;
|
||||
vtDir = vtX ;
|
||||
return true ;
|
||||
@@ -561,12 +563,12 @@ PolyLine::IsFlat( Plane3d& plPlane, double dToler) const
|
||||
plPlane.Reset() ;
|
||||
return false ;
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
// recupero dati sulla planarità della polilinea
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||
// imposto il piano a seconda della dimensionalità
|
||||
// imposto il piano a seconda della dimensionalità
|
||||
switch ( nRank) {
|
||||
case 0 : // punto
|
||||
plPlane.Set( ptCen, Z_AX) ;
|
||||
@@ -587,18 +589,29 @@ PolyLine::IsClosedAndFlat( Plane3d& plPlane, double& dArea, double dToler) const
|
||||
// Test if closed
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// Compute a representative plane for the polygon
|
||||
Point3d ptP ;
|
||||
// Calcolo il centro (per minimizzare gli errori nelle successive operazioni)
|
||||
Point3d ptCen = ORIG ;
|
||||
int nCount = 0 ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||
ptCen += ptP ;
|
||||
++ nCount ;
|
||||
}
|
||||
ptCen /= nCount ;
|
||||
Vector3d vtMove = ptCen - ORIG ;
|
||||
// Compute a representative plane for the polygon (faccio il calcolo nel centro e poi traslo al contrario il piano)
|
||||
PolygonPlane PolyPlane ;
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP))
|
||||
PolyPlane.AddPoint( ptP) ;
|
||||
PolyPlane.AddPoint( ptP - vtMove) ;
|
||||
if ( ! PolyPlane.GetPlane( plPlane) || ! PolyPlane.GetArea( dArea)) {
|
||||
dArea = 0 ;
|
||||
return IsFlat( plPlane, dToler) ;
|
||||
}
|
||||
plPlane.Translate( vtMove) ;
|
||||
// Sistemo il piano per l'offset utilizzato
|
||||
// Test each vertex to see if it is farther from plane than allowed max distance
|
||||
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
|
||||
double dDist = ( ( ptP - ORIG) * plPlane.GetVersN()) - plPlane.GetDist() ;
|
||||
double dDist = DistPointPlane( ptP, plPlane) ;
|
||||
if ( abs( dDist) > dToler)
|
||||
return false ;
|
||||
}
|
||||
@@ -639,13 +652,13 @@ PolyLine::GetAreaXY( double& dArea) const
|
||||
// verifico sia chiusa
|
||||
if ( ! IsClosed())
|
||||
return false ;
|
||||
// calcolo l'area considerando solo XY (è la Z di Newell)
|
||||
// calcolo l'area considerando solo XY (è la Z di Newell)
|
||||
dArea = 0 ;
|
||||
Point3d ptIni, ptFin ;
|
||||
for ( bool bFound = GetFirstLine( ptIni, ptFin) ; bFound ; bFound = GetNextLine( ptIni, ptFin)) {
|
||||
dArea += ( ptIni.x - ptFin.x) * ( ptIni.y + ptFin.y) ; // projection on xy
|
||||
}
|
||||
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
|
||||
// considero anche la linea tra l'ultimo e il primo punto perchè in alcuni casi potrebbero definire area
|
||||
// significativa anche se sono coincidenti per le nostre tolleranze
|
||||
ptIni = ptFin ;
|
||||
GetFirstPoint( ptFin) ;
|
||||
@@ -746,7 +759,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
|
||||
}
|
||||
}
|
||||
|
||||
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
||||
if ( dMaxSqDist > dSqTol) {
|
||||
// inserisco il punto
|
||||
@@ -785,11 +798,11 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
||||
vInd.push_back( 0) ;
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
||||
return false ;
|
||||
vInd.push_back( vPtU.size() - 1) ;
|
||||
vInd.push_back( int( vPtU.size()) - 1) ;
|
||||
}
|
||||
// altrimenti chiusa
|
||||
else {
|
||||
// cerco il punto più distante dal primo
|
||||
// cerco il punto più distante dal primo
|
||||
double dMaxDist = 0. ;
|
||||
int nMaxInd = 0 ;
|
||||
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
||||
@@ -806,12 +819,20 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
||||
vInd.push_back( nMaxInd) ;
|
||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
||||
return false ;
|
||||
vInd.push_back( vPtU.size() - 1) ;
|
||||
vInd.push_back( int( vPtU.size()) - 1) ;
|
||||
}
|
||||
|
||||
// ordino in senso crescente
|
||||
sort( vInd.begin(), vInd.end()) ;
|
||||
|
||||
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
|
||||
if ( IsClosed() && vInd.size() >= 4) {
|
||||
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[int(vInd.size())-2]].first).IsEpsilon( dToler)) {
|
||||
vInd.erase( vInd.begin()) ;
|
||||
vInd.back() = vInd.front() ;
|
||||
}
|
||||
}
|
||||
|
||||
// rimetto in lista i soli punti rimasti
|
||||
m_lUPoints.clear() ;
|
||||
for ( auto Ind : vInd)
|
||||
@@ -958,7 +979,7 @@ PolyLine::MyApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
|
||||
}
|
||||
}
|
||||
}
|
||||
// non è stato eliminato alcunché
|
||||
// non è stato eliminato alcunché
|
||||
// ripristino la tolleranza corrente
|
||||
dCurrToler = dToler ;
|
||||
// avanzo il terzetto di uno step
|
||||
@@ -999,7 +1020,7 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||
bool
|
||||
PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||
{
|
||||
// ciclo i controlli finchè non ci sono rimozioni
|
||||
// ciclo i controlli finchè non ci sono rimozioni
|
||||
bool bRemoved = true ;
|
||||
while ( bRemoved) {
|
||||
bRemoved = false ;
|
||||
@@ -1027,7 +1048,7 @@ PolyLine::MyMakeConvex( const Vector3d& vtN, bool bLeftSide)
|
||||
bRemoved = true ;
|
||||
continue ;
|
||||
}
|
||||
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
||||
// non è stato eliminato alcunché : avanzo il terzetto di uno step
|
||||
precP = currP ;
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
@@ -1054,7 +1075,7 @@ PolyLine::Invert( bool bInvertU)
|
||||
m_lUPoints.reverse() ;
|
||||
// se richiesto, inverto anche il parametro U
|
||||
if ( bInvertU) {
|
||||
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
|
||||
// recupero il primo valore di U che è il vecchio finale ed è il riferimento di inversione
|
||||
double dUfin = m_lUPoints.front().second ;
|
||||
// ciclo su tutti gli elementi
|
||||
for ( auto& UPoint : m_lUPoints) {
|
||||
@@ -1064,6 +1085,35 @@ PolyLine::Invert( bool bInvertU)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::MyRemoveSamePoints( double dToler)
|
||||
{
|
||||
// elimino i punti consecutivi diventati coincidenti (almeno 2)
|
||||
if ( m_lUPoints.size() < 2)
|
||||
return true ;
|
||||
// punto precedente
|
||||
auto precP = m_lUPoints.begin() ;
|
||||
// punto corrente
|
||||
auto currP = next( precP) ;
|
||||
// mentre esiste un corrente
|
||||
while ( currP != m_lUPoints.end()) {
|
||||
// se coincidono
|
||||
if ( AreSamePointEpsilon( precP->first, currP->first, dToler)) {
|
||||
// elimino il punto corrente
|
||||
currP = m_lUPoints.erase( currP) ;
|
||||
// il precedente rimane inalterato
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// avanzo la coppia di uno step
|
||||
precP = currP ;
|
||||
++ currP ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::Flatten( double dZ)
|
||||
@@ -1072,31 +1122,39 @@ PolyLine::Flatten( double dZ)
|
||||
if ( m_lUPoints.empty())
|
||||
return true ;
|
||||
// ciclo su tutti gli elementi per portarli alla Z indicata
|
||||
for ( auto& UPoint : m_lUPoints) {
|
||||
for ( auto& UPoint : m_lUPoints)
|
||||
UPoint.first.z = dZ ;
|
||||
}
|
||||
// elimino i punti consecutivi diventati coincidenti (almeno 2)
|
||||
if ( m_lUPoints.size() < 2)
|
||||
// elimino i punti consecutivi diventati coincidenti
|
||||
MyRemoveSamePoints() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::FlattenInAutoPlane( double dToler)
|
||||
{
|
||||
// verifico non sia vuota
|
||||
if ( m_lUPoints.empty())
|
||||
return true ;
|
||||
// punto precedente
|
||||
auto precP = m_lUPoints.begin() ;
|
||||
// punto corrente
|
||||
auto currP = next( precP) ;
|
||||
// mentre esiste un corrente
|
||||
while ( currP != m_lUPoints.end()) {
|
||||
// se coincidono
|
||||
if ( AreSamePointApprox( precP->first, currP->first)) {
|
||||
// elimino il punto corrente
|
||||
currP = m_lUPoints.erase( currP) ;
|
||||
// il precedente rimane inalterato
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// avanzo la coppia di uno step
|
||||
precP = currP ;
|
||||
++ currP ;
|
||||
}
|
||||
}
|
||||
// recupero dati sulla planarità della polilinea
|
||||
int nRank ;
|
||||
Point3d ptCen ;
|
||||
Vector3d vtDir ;
|
||||
bool bFlat = IsFlat( nRank, ptCen, vtDir, dToler) ;
|
||||
// se non planare entro la tolleranza, esco
|
||||
if ( ! bFlat)
|
||||
return false ;
|
||||
// se punto o linea, non devo fare alcunché
|
||||
if ( nRank == 0 || nRank == 1)
|
||||
return true ;
|
||||
// assegno il piano medio
|
||||
Plane3d plPlane ;
|
||||
plPlane.Set( ptCen, vtDir) ;
|
||||
// proietto i punti su questo piano
|
||||
for ( auto& UPoint : m_lUPoints)
|
||||
UPoint.first = ProjectPointOnPlane( UPoint.first, plPlane) ;
|
||||
// elimino i punti consecutivi diventati coincidenti
|
||||
MyRemoveSamePoints() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -1269,8 +1327,8 @@ PolyLine::GetMinAreaRectangleXY( Point3d& ptCen, Vector3d& vtAx, double& dLen, d
|
||||
bool
|
||||
PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut)
|
||||
{
|
||||
// se vuota non faccio alcunché
|
||||
if ( m_lUPoints.size() == 0)
|
||||
// se vuota non faccio alcunché
|
||||
if ( m_lUPoints.empty())
|
||||
return false ;
|
||||
|
||||
// determino le intersezioni dei lati con il piano
|
||||
@@ -1371,7 +1429,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
PNTULIST& List = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
Point3d ptMinDist ;
|
||||
auto itMinDistEnd = List.end() ;
|
||||
@@ -1389,7 +1447,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
||||
}
|
||||
// Determino tangente di riferimento
|
||||
Vector3d vtTang ;
|
||||
// se minima distanza nell'estremo iniziale del segmento
|
||||
// se minima distanza nell'estremo iniziale del segmento
|
||||
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
||||
// direzione del segmento
|
||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
@@ -1405,7 +1463,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
||||
vtTang = vtPrevTg + vtCurrTg ;
|
||||
vtTang.Normalize() ;
|
||||
}
|
||||
// se altrimenti minima distanza nell'estremo finale del segmento
|
||||
// se altrimenti minima distanza nell'estremo finale del segmento
|
||||
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
||||
// direzione del segmento
|
||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
@@ -1421,7 +1479,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
||||
vtTang = vtCurrTg + vtNextTg ;
|
||||
vtTang.Normalize() ;
|
||||
}
|
||||
// altrimenti minima distanza con l'interno
|
||||
// altrimenti minima distanza con l'interno
|
||||
else {
|
||||
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||
}
|
||||
@@ -1460,7 +1518,7 @@ GetPointParamOnPolyLine( const Point3d& ptP, const PolyLine& plPoly, double dTol
|
||||
// assegno nuovo inizio
|
||||
ptStart = ptEnd ;
|
||||
}
|
||||
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
||||
// Il punto è sulla linea se la sua distanza rispetta la tolleranza
|
||||
return ( dMinSqDist < dToler * dToler) ;
|
||||
}
|
||||
|
||||
@@ -1473,7 +1531,7 @@ ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
@@ -1517,7 +1575,7 @@ SplitPolyLineAtPoint( const PolyLine& plPoly, const Point3d& ptP, double dToler,
|
||||
return false ;
|
||||
// Riferimento alla lista dei punti
|
||||
const PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
// Ciclo sui segmenti della polilinea per cercare il segmento più vicino al punto
|
||||
double dMinSqDist = SQ_INFINITO ;
|
||||
auto itMinDistEnd = LoopList.end() ;
|
||||
auto itStart = LoopList.begin() ;
|
||||
@@ -1556,8 +1614,9 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
int nPnt2 = PL2.GetPointNbr() ;
|
||||
if ( nPnt1 == 0 || nPnt2 == 0)
|
||||
return false ;
|
||||
|
||||
bCommonInternalPoints = false ; // indica la presenza di punti interni in comune tra le due polylines
|
||||
|
||||
// indica la presenza di punti interni in comune tra le due polylines
|
||||
bCommonInternalPoints = false ;
|
||||
|
||||
vPnt1.reserve( PL1.GetPointNbr()) ;
|
||||
Point3d ptP1 ;
|
||||
@@ -1581,10 +1640,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
int nLastJ = 0 ;
|
||||
vPnt1[0].second = 0 ;
|
||||
|
||||
double dFirstDist, dFirstParMinDist ;
|
||||
DistPointPolyLine( vPnt1[0].first, PL2, dFirstDist, dFirstParMinDist) ;
|
||||
int nFirstMinJ = ( int)( dFirstParMinDist + 0.5) ;
|
||||
|
||||
for ( int i = 1 ; i < nTotP1 ; ++ i) {
|
||||
|
||||
double dDist = INFINITO ;
|
||||
@@ -1593,7 +1648,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine PointLineDistCalc( vPnt1[i].first, vPnt2[j-1].first, vPnt2[j].first) ;
|
||||
double dPlDist ;
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist) {
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
||||
dDist = dPlDist ;
|
||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||
dMinDistPar += j - 1 ;
|
||||
@@ -1601,15 +1656,11 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
}
|
||||
int nMinJ = ( int)( dMinDistPar + 0.5) ;
|
||||
|
||||
// eventuale correzione per i primi punti ( da forzare nel vertice 0)
|
||||
if ( nLastJ == 0 && nFirstMinJ > 0.5 * nTotP2 && nMinJ >= nFirstMinJ)
|
||||
nMinJ = 0 ;
|
||||
|
||||
if ( nMinJ < nLastJ)
|
||||
nMinJ = nLastJ ;
|
||||
|
||||
// verifica se è un punto interno in comune con l'altra polyline
|
||||
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||
// verifica se è un punto interno in comune con l'altra polyline
|
||||
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||
bCommonInternalPoints = true ;
|
||||
|
||||
vPnt1[i].second = nMinJ ;
|
||||
@@ -1619,9 +1670,6 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// calcoli per seconda curva
|
||||
int nLastI = 0 ;
|
||||
vPnt2[0].second = 0 ;
|
||||
|
||||
DistPointPolyLine( vPnt2[0].first, PL1, dFirstDist, dFirstParMinDist) ;
|
||||
int nFirstMinI = ( int)( dFirstParMinDist + 0.5) ;
|
||||
|
||||
for ( int j = 1 ; j < nTotP2 ; ++ j) {
|
||||
|
||||
@@ -1631,8 +1679,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
// distanza del punto dal segmento della polilinea
|
||||
DistPointLine PointLineDistCalc( vPnt2[j].first, vPnt1[i-1].first, vPnt1[i].first) ;
|
||||
double dPlDist ;
|
||||
PointLineDistCalc.GetDist( dPlDist) ;
|
||||
if ( dPlDist < dDist) {
|
||||
if ( PointLineDistCalc.GetDist( dPlDist) && dPlDist < dDist - EPS_SMALL) {
|
||||
dDist = dPlDist ;
|
||||
PointLineDistCalc.GetParamAtMinDistPoint( dMinDistPar) ;
|
||||
dMinDistPar += i - 1 ;
|
||||
@@ -1640,19 +1687,331 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
||||
}
|
||||
int nMinI = ( int)( dMinDistPar + 0.5) ;
|
||||
|
||||
// eventuale correzione per primi punti
|
||||
if ( nLastI == 0 && nFirstMinI > 0.5 * nTotP1 && nMinI >= nFirstMinI)
|
||||
nMinI = 0 ;
|
||||
|
||||
if ( nMinI < nLastI)
|
||||
nMinI = nLastI ;
|
||||
|
||||
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||
if ( j < nTotP2 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||
bCommonInternalPoints = true ;
|
||||
|
||||
vPnt2[j].second = nMinI ;
|
||||
nLastI = nMinI ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
MatchPolyLinesAddingPoints( const PolyLine& PL1, const PolyLine& PL2, int nType, PNTIVECTOR& vPnt1, PNTIVECTOR& vPnt2)
|
||||
{
|
||||
// prima trovo le associazioni senza aggiunte di punti
|
||||
Point3d ptP2 ;
|
||||
CurveComposite cc1, cc2 ;
|
||||
cc1.FromPolyLine( PL1) ;
|
||||
cc2.FromPolyLine( PL2) ;
|
||||
int nPnt1 = PL1.GetPointNbr() ;
|
||||
int nPnt2 = PL2.GetPointNbr() ;
|
||||
vector<POINTU> vMatch2 ;
|
||||
PL2.GetFirstPoint( ptP2) ;
|
||||
while ( PL2.GetNextPoint( ptP2, true)) {
|
||||
DistPointCurve dpc( ptP2, cc1, false) ;
|
||||
int nFlag = 0 ;
|
||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
||||
vMatch2.emplace_back( ptJoint, dParam) ;
|
||||
}
|
||||
|
||||
int nAtStart2 = 0 ; // match ripetuti dalla curva U0 allo start della curva U1
|
||||
int nAtEnd2 = 0 ;
|
||||
Point3d ptP1 ; PL1.GetFirstPoint( ptP1) ;
|
||||
int c = 0 ;
|
||||
int nRep1 = 0 ; // match interni consecutivi uguali di punti della curva U0 con punti della curva U1
|
||||
int nRep2 = 0 ;
|
||||
double dLastParamMatch = 0 ;
|
||||
Point3d ptLastPointMatch = ptP1 ;
|
||||
BOOLVECTOR vbRep1( nPnt1) ;
|
||||
INTVECTOR vnAddedOrNextIsRep1 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
|
||||
DBLVECTOR vdSplit1 ;
|
||||
DBLVECTOR vdMatch1 ;
|
||||
fill( vbRep1.begin(), vbRep1.end(), false) ;
|
||||
while ( PL1.GetNextPoint( ptP1, true)) {
|
||||
// devo salvarmi se matcho più punti con lo start o l'end della curva totale
|
||||
DistPointCurve dpc( ptP1, cc2, false) ;
|
||||
int nFlag = 0 ;
|
||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
||||
vdMatch1.push_back( dParam) ;
|
||||
if ( dParam < EPS_SMALL ) {
|
||||
++nAtStart2 ;
|
||||
vbRep1[c] = true ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
else if ( dParam > nPnt2 - EPS_SMALL ) {
|
||||
vbRep1[c] = nAtEnd2 == 0 ? false : true ;
|
||||
vbRep1.back() = true ;
|
||||
++ nAtEnd2 ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
|
||||
dParam = dLastParamMatch ;
|
||||
vbRep1[c] = true ;
|
||||
++ nRep1 ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
else {
|
||||
dLastParamMatch = dParam ;
|
||||
ptLastPointMatch = ptJoint ;
|
||||
// se sono già troppo vicino ad un split esistente allora non faccio nulla
|
||||
if ( abs(dParam - round( dParam)) < 100 * EPS_PARAM) {
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
vdSplit1.push_back( dParam) ;
|
||||
// verifico se ho un match per questo punto
|
||||
// in tal caso vuol dire che sto creando una ripetizione nRep1
|
||||
int nCase = 0 ;
|
||||
for ( int j = 0 ; j < int( vMatch2.size()) ; ++j) {
|
||||
if ( abs(vMatch2[j].second - (c + 1)) < EPS_SMALL) {
|
||||
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
|
||||
bool bFoundMatch = false ;
|
||||
for ( int z = int( vMatch2[j].second) ; z < int( vdMatch1.size()) ; ++z) {
|
||||
if ( abs( vdMatch1[z] - ( j + 1 )) < EPS_SMALL ) {
|
||||
bFoundMatch = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bFoundMatch) {
|
||||
++ nRep2 ;
|
||||
// capisco se il punto è rep o se lo è il suo successivo
|
||||
if ( j + 1 < dParam)
|
||||
nCase = 1 ;
|
||||
else
|
||||
nCase = 2 ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
vnAddedOrNextIsRep1.push_back( nCase) ;
|
||||
}
|
||||
++c ;
|
||||
}
|
||||
int nAtStart1 = 0 ;
|
||||
int nAtEnd1 = 0 ;
|
||||
PL2.GetFirstPoint( ptP2) ;
|
||||
c = 0 ;
|
||||
dLastParamMatch = 0 ;
|
||||
ptLastPointMatch = ptP2 ;
|
||||
INTVECTOR vnAddedOrNextIsRep2 ; // 0 non Rep, 1 Rep, 2 Next is Rep ;
|
||||
DBLVECTOR vdSplit2 ;
|
||||
BOOLVECTOR vbRep2( nPnt2) ;
|
||||
fill( vbRep2.begin(), vbRep2.end(), false) ;
|
||||
while ( PL2.GetNextPoint( ptP2, true)) {
|
||||
DistPointCurve dpc( ptP2, cc1, false) ;
|
||||
int nFlag = 0 ;
|
||||
double dParam ; dpc.GetParamAtMinDistPoint( 0, dParam, nFlag) ;
|
||||
Point3d ptJoint ; dpc.GetMinDistPoint( 0, ptJoint, nFlag) ;
|
||||
if ( dParam < EPS_SMALL ) {
|
||||
++nAtStart1 ;
|
||||
vbRep2[c] = true ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
else if ( dParam > nPnt1 - EPS_SMALL ) {
|
||||
vbRep2[c] = ( nAtEnd1 == 0 ? false : true) ;
|
||||
vbRep2.back() = true ;
|
||||
++ nAtEnd1 ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
if ( dParam <= dLastParamMatch || AreSamePointApprox( ptJoint, ptLastPointMatch)) {
|
||||
dParam = dLastParamMatch ;
|
||||
vbRep2[c] = true ;
|
||||
++ nRep2 ;
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
else {
|
||||
dLastParamMatch = dParam ;
|
||||
ptLastPointMatch = ptJoint ;
|
||||
// se sono troppo vicino ad uno split esistente allora non faccio nulla
|
||||
if ( abs( dParam - round( dParam)) < 100 * EPS_PARAM) {
|
||||
++c ;
|
||||
continue ;
|
||||
}
|
||||
vdSplit2.push_back( dParam) ;
|
||||
// verifico se ho un match per questo punto
|
||||
// in tal caso vuol dire che sto creando una ripetizione nRep0
|
||||
int nCase = 0 ;
|
||||
for ( int j = 0 ; j < int( vdMatch1.size()) ; ++j) {
|
||||
if ( abs( vdMatch1[j] - (c + 1)) < EPS_SMALL) {
|
||||
// devo però verificare che non ci sia un match successivo, perché in quel caso non ho una ripetizione
|
||||
bool bFoundMatch = false ;
|
||||
for ( int z = int( vdMatch1[j]) ; z < int( vMatch2.size()) ; ++z) {
|
||||
if ( abs( vMatch2[z].second - ( j + 1 )) < EPS_SMALL) {
|
||||
bFoundMatch = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! bFoundMatch) {
|
||||
++nRep1 ;
|
||||
// capisco se il punto è rep o se lo è il suo successivo
|
||||
if ( j + 1 < dParam)
|
||||
nCase = 1 ;
|
||||
else
|
||||
nCase = 2 ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
vnAddedOrNextIsRep2.push_back( nCase) ;
|
||||
}
|
||||
++c ;
|
||||
}
|
||||
|
||||
// applico effettivamente gli split e aggiungo gli elementi ai vettori vbRep
|
||||
int nUnit = 0 ;
|
||||
if ( ! vdSplit1.empty())
|
||||
nUnit = int( vdSplit1.back()) ;
|
||||
for ( int z = int( vdSplit1.size()) - 1 ; z >= 0 ; --z) {
|
||||
double dSplit = vdSplit1[z] ;
|
||||
int nSplit = int( dSplit) ;
|
||||
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
|
||||
// riscalare
|
||||
if ( nSplit == nUnit && z < int( vdSplit1.size()) - 1) {
|
||||
dSplit = nSplit + ( dSplit - nSplit) / ( vdSplit1[z+1] - nSplit) ;
|
||||
}
|
||||
nUnit = nSplit ;
|
||||
cc2.AddJoint( dSplit) ;
|
||||
switch ( vnAddedOrNextIsRep1[z]) {
|
||||
case 0 :
|
||||
if ( vbRep2[nSplit])
|
||||
++ nRep2 ;
|
||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
vbRep2.insert( vbRep2.begin() + nSplit, vbRep2[nSplit]) ;
|
||||
break ;
|
||||
case 1 :
|
||||
vbRep2.insert( vbRep2.begin() + nSplit, true) ;
|
||||
break ;
|
||||
case 2 :
|
||||
if ( vbRep2[nSplit])
|
||||
--nRep2 ;
|
||||
else
|
||||
vbRep2[nSplit] = true ;
|
||||
vbRep2.insert( vbRep2.begin() + nSplit, false) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( ! vdSplit2.empty())
|
||||
nUnit = int( vdSplit2.back()) ;
|
||||
for ( int z = int( vdSplit2.size()) - 1 ; z >= 0 ; --z) {
|
||||
double dSplit = vdSplit2[z] ;
|
||||
int nSplit = int( dSplit) ;
|
||||
// se sto cercando di fare uno split sulla stessa curva che ho già splittato al passaggio precedente allora devo
|
||||
// riscalare
|
||||
if ( nSplit == nUnit && z < int( vdSplit2.size()) - 1) {
|
||||
dSplit = nSplit + ( dSplit - nSplit) / (vdSplit2[z+1] - nSplit) ;
|
||||
}
|
||||
nUnit = nSplit ;
|
||||
cc1.AddJoint( dSplit) ;
|
||||
switch ( vnAddedOrNextIsRep2[z]) {
|
||||
case 0 :
|
||||
if ( vbRep1[nSplit])
|
||||
++ nRep1 ;
|
||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ;
|
||||
break ;
|
||||
case 1 :
|
||||
vbRep1.insert( vbRep1.begin() + nSplit, true) ;
|
||||
break ;
|
||||
case 2 :
|
||||
if ( vbRep1[nSplit])
|
||||
-- nRep1 ;
|
||||
else
|
||||
vbRep1[nSplit] = true ;
|
||||
vbRep1.insert( vbRep1.begin() + nSplit, false) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
nPnt1 = cc1.GetCurveCount() ;
|
||||
nPnt2 = cc2.GetCurveCount() ;
|
||||
//aggiusto i vettori delle ripetizioni in modo in modo che non arrivino mai ad essere contemporaneamente true
|
||||
int nAddedSpan = 0 ;
|
||||
int nCrv1 = 0 ;
|
||||
int nCrv2 = 0 ;
|
||||
while ( nAddedSpan < nPnt1 + nAtStart1 + nAtEnd1 + nRep2) {
|
||||
if ( nCrv1 >= nPnt1)
|
||||
nCrv1 = nPnt1 - 1 ;
|
||||
if ( nCrv2 >= nPnt2)
|
||||
nCrv2 = nPnt2 - 1 ;
|
||||
bool bRep1 = vbRep1[nCrv1] ;
|
||||
bool bRep2 = vbRep2[nCrv2] ;
|
||||
if ( bRep1 && bRep2) {
|
||||
vbRep1[nCrv1] = false ;
|
||||
bRep1 = false ;
|
||||
vbRep2[nCrv2] = false ;
|
||||
bRep2 = false ;
|
||||
-- nRep1 ;
|
||||
-- nRep2 ;
|
||||
}
|
||||
if ( ! bRep1 || nCrv2 == nPnt2 - 1)
|
||||
++ nCrv2 ;
|
||||
if ( ! bRep2 || nCrv1 == nPnt1 - 1)
|
||||
++ nCrv1 ;
|
||||
++ nAddedSpan ;
|
||||
}
|
||||
// se non sono arrivato all'ultima curva su U0 o U1 vuol dire che ho creato delle ripetizioni che non ho contato prima
|
||||
if ( nCrv2 < nPnt2) {
|
||||
nRep2 += nPnt2 - nCrv2 ;
|
||||
for ( int z = int( vbRep2.size()) - 1 ; z >= nCrv2 ; --z)
|
||||
vbRep2[z] = true ;
|
||||
}
|
||||
if( nCrv1 < nPnt1) {
|
||||
nRep1 += nPnt1 - nCrv1 ;
|
||||
for ( int z = int( vbRep1.size()) - 1 ; z >= nCrv1 ; --z)
|
||||
vbRep1[z] = true ;
|
||||
}
|
||||
|
||||
// trovo il numero di span che dovrà avere la superficie
|
||||
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
|
||||
int nPnt = nPnt1 + nAtStart1 + nAtEnd1 + nRep2 ;
|
||||
|
||||
if ( nPnt != nPnt2 + nAtStart2 + nAtEnd2 + nRep1)
|
||||
LOG_DBG_ERR( GetEGkLogger(), "There could be an error in the creation of a ruled surface in mode RLT_B_MINDIST_PLUS") ;
|
||||
|
||||
// aggiungo i punti di controllo scorrendo in contemporanea le due curve
|
||||
nAddedSpan = 0 ;
|
||||
nCrv1 = 0 ;
|
||||
nCrv2 = 0 ;
|
||||
bool bLast1 = false ;
|
||||
bool bLast2 = false ;
|
||||
while ( nAddedSpan < nPnt) {
|
||||
if ( nCrv1 >= nPnt1) {
|
||||
nCrv1 = nPnt1 - 1 ;
|
||||
bLast1 = true ;
|
||||
}
|
||||
if ( nCrv2 >= nPnt2) {
|
||||
nCrv2 = nPnt2 - 1 ;
|
||||
bLast2 = true ;
|
||||
}
|
||||
bool bRep1 = vbRep1[nCrv1] ;
|
||||
bool bRep2 = vbRep2[nCrv2] ;
|
||||
const ICurve* pSubCrv1 = cc1.GetCurve( nCrv1) ;
|
||||
Point3d ptStart1 ; pSubCrv1->GetStartPoint( ptStart1) ;
|
||||
vPnt1.emplace_back( ptStart1, nAddedSpan) ;
|
||||
const ICurve* pSubCrv2 = cc2.GetCurve( nCrv2) ;
|
||||
Point3d ptStart2 ; pSubCrv2->GetStartPoint( ptStart2) ;
|
||||
vPnt2.emplace_back( ptStart2, nAddedSpan) ;
|
||||
if ( ! bRep2)
|
||||
++ nCrv1 ;
|
||||
if ( ! bRep1)
|
||||
++ nCrv2 ;
|
||||
++ nAddedSpan ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,12 +150,18 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
||||
Vector3d vtN = pgFacet.GetVersN() ;
|
||||
PolyLine PL = pgFacet.GetPolyLine() ;
|
||||
|
||||
// calcolo elevazione massima del contorno della faccia
|
||||
// calcolo elevazione massima del contorno della faccia e nel suo centro
|
||||
const double RAY_LEN = 100000 ;
|
||||
dElev = 0 ;
|
||||
PNTVECTOR vptP ; vptP.reserve( PL.GetPointNbr()) ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstPoint( ptP) ;
|
||||
while ( bFound) {
|
||||
vptP.push_back( ptP) ;
|
||||
bFound = PL.GetNextPoint( ptP, true) ;
|
||||
}
|
||||
vptP.push_back( ptCen) ;
|
||||
for ( const Point3d& ptP : vptP) {
|
||||
ILSIVECTOR vInters ;
|
||||
IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
|
||||
for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
|
||||
@@ -171,7 +177,6 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
||||
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
|
||||
dElev = max( dElev, Inters.dU2) ;
|
||||
}
|
||||
bFound = PL.GetNextPoint( ptP, true) ;
|
||||
}
|
||||
// calcolo elevazione massima degli eventuali spigoli (e vertici) della superficie chiusa dalla parte positiva della faccia e che cadono in essa
|
||||
int nEdgeCnt = CldStm.GetEdgeCount() ;
|
||||
|
||||
+5
-5
@@ -19,10 +19,10 @@
|
||||
void
|
||||
PolygonPlane::AddPoint( const Point3d& ptP)
|
||||
{
|
||||
// se è il primo punto (parto da -1 perchè verrà contato alla chiusura)
|
||||
// se è il primo punto (parto da -1 perchè verrà contato alla chiusura)
|
||||
if ( m_nPntNbr == -1) {
|
||||
// inizializzazioni
|
||||
m_dLenN = 0 ;
|
||||
m_dLenN = -1 ;
|
||||
m_vtN = V_NULL ;
|
||||
m_ptMid = ORIG ;
|
||||
m_dSXy = 0 ; m_dSXz = 0 ;
|
||||
@@ -60,16 +60,16 @@ PolygonPlane::AddPoint( const Point3d& ptP)
|
||||
bool
|
||||
PolygonPlane::Finalize( void)
|
||||
{
|
||||
// almeno 3 punti (il triangolo è il poligono con minimo numero di lati)
|
||||
// almeno 3 punti (il triangolo è il poligono con minimo numero di lati)
|
||||
if ( m_nPntNbr + 1 < 3)
|
||||
return false ;
|
||||
// se il poligono non è stato chiuso, aggiungo calcolo per ultimo lato
|
||||
// se il poligono non è stato chiuso, aggiungo calcolo per ultimo lato
|
||||
if ( ! AreSamePointExact( m_ptFirst, m_ptLast)) {
|
||||
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
||||
AddPoint( m_ptFirst) ;
|
||||
}
|
||||
// se non effettuato, eseguo il calcolo finale
|
||||
if ( m_dLenN < EPS_SMALL) {
|
||||
if ( m_dLenN < 0) {
|
||||
// lunghezza della normale (doppio dell'area del poligono)
|
||||
m_dLenN = m_vtN.Len() ;
|
||||
if ( m_dLenN < SQ_EPS_SMALL)
|
||||
|
||||
@@ -0,0 +1,915 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ProjectCurveSurfTm.cpp Data : 29.08.25 Versione : 2.7h2
|
||||
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 31.08.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkProjectCurveSurf.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Angolo limite tra normale al triangolo e direzione di proiezione 89°
|
||||
const double COS_ANG_LIM = 0.0175 ;
|
||||
// Angolo massimo tra normali per effettuare bisezione su spigolo
|
||||
const double COS_ANG_MAX_CORNER = 0.8660 ;
|
||||
// Tipologia di punto
|
||||
const int P5AX_TO_DELETE = -1 ; // da cancellare
|
||||
const int P5AX_OUT = 0 ; // aggiunto prima di inizio o dopo fine
|
||||
const int P5AX_STD = 1 ; // standard
|
||||
const int P5AX_CVEX = 2 ; // su angolo convesso
|
||||
const int P5AX_CONC = 3 ; // in angolo concavo
|
||||
const int P5AX_BEFORE_CONC = 4 ; // adiacente ad angolo concavo
|
||||
const int P5AX_AFTER_CONC = 5 ; // adiacente ad angolo concavo
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static double
|
||||
GetSurfBezierTol( double dLinTol)
|
||||
{
|
||||
return max( dLinTol / 10, EPS_SMALL) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
||||
{
|
||||
for ( int i = nPrec + 1 ; i < nCurr ; ++ i) {
|
||||
double dSqDist ;
|
||||
if ( ! DistPointLine( vPt5ax[i].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
RemovePointsInExcess( PNT5AXVECTOR& vPt5ax, double dLinTol, double dMaxSegmLen, bool bTestDir)
|
||||
{
|
||||
// Parametri di riferimento
|
||||
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
||||
double dSqTol = dLinTol * dLinTol ;
|
||||
const double LENREF = 200 ;
|
||||
double dCosAngLim = 1 - dSqTol / ( 2 * LENREF * LENREF) ;
|
||||
// Cerco gli angoli interni e marco opportunamente i punti nelle vicinanze fino ai limiti prima e dopo
|
||||
int nInd = 0 ;
|
||||
while ( nInd < int( vPt5ax.size())) {
|
||||
if ( vPt5ax[nInd].nFlag == P5AX_CONC) {
|
||||
// analizzo i punti appena precedenti
|
||||
int nIpv = nInd - 1 ;
|
||||
while ( nIpv >= 0) {
|
||||
double dSqLen = SqDist( vPt5ax[nInd].ptP, vPt5ax[nIpv].ptP) ;
|
||||
if ( dSqLen < dSqMaxLen)
|
||||
vPt5ax[nIpv].nFlag = P5AX_TO_DELETE ;
|
||||
else {
|
||||
vPt5ax[nIpv].nFlag = P5AX_BEFORE_CONC ;
|
||||
break ;
|
||||
}
|
||||
-- nIpv ;
|
||||
}
|
||||
// analizzo i punti appena successivi
|
||||
int nInx = nInd + 1 ;
|
||||
while ( nInx < int( vPt5ax.size())) {
|
||||
double dSqLen = SqDist( vPt5ax[nInd].ptP, vPt5ax[nInx].ptP) ;
|
||||
if ( dSqLen < dSqMaxLen)
|
||||
vPt5ax[nInx].nFlag = P5AX_TO_DELETE ;
|
||||
else {
|
||||
vPt5ax[nInx].nFlag = P5AX_AFTER_CONC ;
|
||||
break ;
|
||||
}
|
||||
++ nInx ;
|
||||
}
|
||||
}
|
||||
++ nInd ;
|
||||
}
|
||||
// Rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
int nCnt = 0 ;
|
||||
int nPrec = 0 ;
|
||||
int nCurr = 1 ;
|
||||
int nNext = 2 ;
|
||||
while ( nNext < int( vPt5ax.size())) {
|
||||
bool bRemove = false ;
|
||||
// lunghezza del segmento che unisce gli adiacenti
|
||||
double dSqLen = SqDist( vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP) ;
|
||||
// se rimovibile (Flag standard) e lunghezza inferiore al massimo, passo agli altri controlli
|
||||
if ( vPt5ax[nCurr].nFlag == P5AX_STD && dSqLen <= dSqMaxLen) {
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( vPt5ax[nCurr].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP) ;
|
||||
double dSqDist ;
|
||||
// se distanza inferiore a tolleranza lineare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
||||
// verifico se errore angolare inferiore a limite
|
||||
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
||||
if ( bTestDir) {
|
||||
Vector3d vtNew = Media( vPt5ax[nPrec].vtDir1, vPt5ax[nNext].vtDir1, dPar) ;
|
||||
if ( vtNew.Normalize() && vtNew * vPt5ax[nCurr].vtDir1 > dCosAngLim)
|
||||
bRemove = true ;
|
||||
}
|
||||
else {
|
||||
Vector3d vtNew = Media( vPt5ax[nPrec].vtDir2, vPt5ax[nNext].vtDir2, dPar) ;
|
||||
if ( vtNew.Normalize() && vtNew * vPt5ax[nCurr].vtDir2 > dCosAngLim)
|
||||
bRemove = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// se da eliminare
|
||||
if ( bRemove) {
|
||||
// dichiaro da eliminare il punto
|
||||
vPt5ax[nCurr].nFlag = P5AX_TO_DELETE ;
|
||||
// avanzo con corrente e successivo
|
||||
nCurr = nNext ;
|
||||
++ nNext ;
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// avanzo il terzetto di uno step
|
||||
nPrec = nCurr ;
|
||||
nCurr = nNext ;
|
||||
++ nNext ;
|
||||
// incremento contatore dei punti conservati
|
||||
++ nCnt ;
|
||||
}
|
||||
}
|
||||
|
||||
// Copio i punti da conservare in un vettore temporaneo
|
||||
PNT5AXVECTOR vMyPt5ax ;
|
||||
vMyPt5ax.reserve( nCnt) ;
|
||||
for ( const auto& Pt5ax : vPt5ax) {
|
||||
if ( Pt5ax.nFlag != P5AX_TO_DELETE)
|
||||
vMyPt5ax.emplace_back( Pt5ax) ;
|
||||
}
|
||||
// scambio i due vettori
|
||||
vPt5ax.swap( vMyPt5ax) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
// --- vettore di oggetti intersezione massiva rette parallele SurfTM --------
|
||||
typedef std::vector<IntersParLinesSurfTm*> INTPARLINESTMPVECTOR ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const Frame3d& frRefLine, const INTPARLINESTMPVECTOR& vpIntPLSTM,
|
||||
double dPar, Point5ax& Pt5ax)
|
||||
{
|
||||
// intersezione retta di proiezione con superfici (conservo l'intersezione più alta)
|
||||
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
||||
int nInd = -1 ;
|
||||
IntLinStmInfo IntRes ;
|
||||
for ( int i = 0 ; i < int( vpIntPLSTM.size()) ; ++ i) {
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( vpIntPLSTM[i]->GetInters( ptL, 1, vIntRes, false)) {
|
||||
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
||||
--nI ;
|
||||
// se trovata
|
||||
if ( nI >= 0) {
|
||||
if ( nInd < 0) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
else {
|
||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
||||
if ( dU > dUref) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovata
|
||||
if ( nInd >= 0) {
|
||||
// calcolo il punto
|
||||
Point3d ptInt ;
|
||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = IntRes.ptI2 ;
|
||||
else
|
||||
ptInt = IntRes.ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
||||
vtN = trTria.GetN() ;
|
||||
// assegno valori al punto 5assi
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = vtN ;
|
||||
Pt5ax.vtDir2 = frRefLine.VersZ() ;
|
||||
Pt5ax.dPar = dPar ;
|
||||
Pt5ax.nFlag = P5AX_STD ;
|
||||
// ritorno con successo
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const Vector3d& vtDir,
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// sistemazioni per tipo di superficie
|
||||
CISRFTMPVECTOR vpSurfTm ;
|
||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
||||
const SurfTriMesh* pSurfTm = nullptr ;
|
||||
switch ( vpSurf[i]->GetType()) {
|
||||
case SRF_TRIMESH :
|
||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
||||
break ;
|
||||
case SRF_BEZIER :
|
||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
||||
} break ;
|
||||
case SRF_FLATRGN :
|
||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
if ( pSurfTm == nullptr)
|
||||
return false ;
|
||||
vpSurfTm.emplace_back( pSurfTm) ;
|
||||
}
|
||||
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
// approssimo la curva con una polilinea alla massima risoluzione
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Oggetti per calcolo massivo intersezioni tra linee di proiezione e superfici
|
||||
Frame3d frRefLine ;
|
||||
if ( ! frRefLine.Set( ORIG, vtDir))
|
||||
return false ;
|
||||
INTPARLINESTMPVECTOR vpIntPLSTM ; vpIntPLSTM.reserve( vpSurfTm.size()) ;
|
||||
for ( int i = 0 ; i < int( vpSurfTm.size()) ; ++ i) {
|
||||
IntersParLinesSurfTm* pIntPLSTM = new IntersParLinesSurfTm( frRefLine, *vpSurfTm[i]) ;
|
||||
if ( pIntPLSTM == nullptr) {
|
||||
for ( int j = 0 ; j < int( vpIntPLSTM.size()) ; ++ j)
|
||||
delete vpIntPLSTM[j] ;
|
||||
return false ;
|
||||
}
|
||||
vpIntPLSTM.emplace_back( pIntPLSTM) ;
|
||||
}
|
||||
|
||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
||||
vPt5ax.clear() ;
|
||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, frRefLine, vpIntPLSTM, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// Libero oggetti per calcolo massivo
|
||||
for ( int i = 0 ; i < int( vpIntPLSTM.size()) ; ++ i)
|
||||
delete vpIntPLSTM[i] ;
|
||||
|
||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
||||
if ( bSharpEdges) {
|
||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
||||
// precedente
|
||||
int j = i - 1 ;
|
||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
||||
// intersezione tra le due facce
|
||||
Plane3d plPlane1 ; plPlane1.Set( vPt5ax[j].ptP, vPt5ax[j].vtDir1) ;
|
||||
Plane3d plPlane2 ; plPlane2.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir1) ;
|
||||
Point3d ptEdge ; Vector3d vtEdge ;
|
||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptEdge, vtEdge) == IPPT_YES) {
|
||||
Plane3d plPlane3 ; plPlane3.Set( vPt5ax[i].ptP, ( vPt5ax[i].ptP - vPt5ax[j].ptP) ^ vtDir) ;
|
||||
Point3d ptInt ;
|
||||
if ( IntersLinePlane( ptEdge, vtEdge, 1, plPlane3, ptInt, false) == ILPT_YES) {
|
||||
// verifico se spigolo convesso o concavo
|
||||
bool bConvex ;
|
||||
if ( ! AreSamePointApprox( ptInt, vPt5ax[j].ptP))
|
||||
bConvex = ( ( vPt5ax[j].vtDir1 ^ ( ptInt - vPt5ax[j].ptP)) * vtEdge > 0) ;
|
||||
else
|
||||
bConvex = (( vPt5ax[i].vtDir1 ^ ( ptInt - vPt5ax[i].ptP)) * vtEdge < 0) ;
|
||||
// se convesso, metto due punti con direzione appena prima e appena dopo
|
||||
if ( bConvex) {
|
||||
Vector3d vtLine1 = ptInt - vPt5ax[j].ptP ; double dLen1 = vtLine1.Len() ;
|
||||
Vector3d vtLine2 = vPt5ax[i].ptP - ptInt ; double dLen2 = vtLine2.Len() ;
|
||||
if ( dLen1 > 2 * EPS_SMALL) {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt - vtLine1 / dLen1 * 2 * EPS_SMALL ;
|
||||
Pt5ax.vtDir1 = vPt5ax[j].vtDir1 ;
|
||||
Pt5ax.vtDir2 = vtDir ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CVEX ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
if ( dLen2 > 2 * EPS_SMALL) {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt + vtLine2 / dLen2 * 2 * EPS_SMALL ;
|
||||
Pt5ax.vtDir1 = vPt5ax[i].vtDir1 ;
|
||||
Pt5ax.vtDir2 = vtDir ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CVEX ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
// altrimenti concavo, aggiungo un solo punto con la direzione media
|
||||
else {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = Media( vPt5ax[i].vtDir1, vPt5ax[j].vtDir1) ;
|
||||
Pt5ax.vtDir2 = vtDir ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CONC ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rimozione punti in eccesso rispetto alle tolleranze
|
||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const IGeoPoint3d& gpRef, double dPar, Point5ax& Pt5ax)
|
||||
{
|
||||
// punto di riferimento
|
||||
Point3d ptMin = gpRef.GetPoint() ;
|
||||
// intersezione della retta di minima distanza con le superfici
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL) {
|
||||
vtLine /= dLineLen ;
|
||||
// conservo l'intersezione più alta
|
||||
int nInd = -1 ;
|
||||
IntLinStmInfo IntRes ;
|
||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], vIntRes, false)) {
|
||||
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
||||
--nI ;
|
||||
// se trovata
|
||||
if ( nI >= 0) {
|
||||
if ( nInd < 0) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
else {
|
||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
||||
if ( dU > dUref) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovata
|
||||
if ( nInd >= 0) {
|
||||
// calcolo il punto
|
||||
Point3d ptInt ;
|
||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = IntRes.ptI2 ;
|
||||
else
|
||||
ptInt = IntRes.ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
||||
vtN = trTria.GetN() ;
|
||||
// assegno valori al punto 5assi
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = vtN ;
|
||||
Pt5ax.vtDir2 = vtLine ;
|
||||
Pt5ax.dPar = dPar ;
|
||||
Pt5ax.nFlag = P5AX_STD ;
|
||||
// ritorno con successo
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const IGeoPoint3d& gpRef,
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// sistemazioni per tipo di superficie
|
||||
CISRFTMPVECTOR vpSurfTm ;
|
||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
||||
const SurfTriMesh* pSurfTm = nullptr ;
|
||||
switch ( vpSurf[i]->GetType()) {
|
||||
case SRF_TRIMESH :
|
||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
||||
break ;
|
||||
case SRF_BEZIER :
|
||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
||||
} break ;
|
||||
case SRF_FLATRGN :
|
||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
if ( pSurfTm == nullptr)
|
||||
return false ;
|
||||
vpSurfTm.emplace_back( pSurfTm) ;
|
||||
}
|
||||
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
||||
vPt5ax.clear() ;
|
||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione data dal punto di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, gpRef, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
||||
if ( bSharpEdges) {
|
||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
||||
// precedente
|
||||
int j = i - 1 ;
|
||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
||||
// punto medio
|
||||
Point3d ptMid = Media( vPt5ax[i].ptP, vPt5ax[j].ptP) ;
|
||||
double dMid = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptMid, vpSurfTm, gpRef, dMid, Pt5ax)) {
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
-- i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rimozione punti in eccesso rispetto alle tolleranze
|
||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const ICurve& crRef, double dPar, Point5ax& Pt5ax)
|
||||
{
|
||||
// punto a minima distanza
|
||||
DistPointCurve dPC( ptP, crRef) ;
|
||||
Point3d ptMin ;
|
||||
int nFlag ;
|
||||
if ( dPC.GetMinDistPoint( 0, ptMin, nFlag)) {
|
||||
// intersezione della retta di minima distanza con le superfici
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL) {
|
||||
vtLine /= dLineLen ;
|
||||
// conservo l'intersezione più alta
|
||||
int nInd = -1 ;
|
||||
IntLinStmInfo IntRes ;
|
||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], vIntRes, false)) {
|
||||
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
||||
--nI ;
|
||||
// se trovata
|
||||
if ( nI >= 0) {
|
||||
if ( nInd < 0) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
else {
|
||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
||||
if ( dU > dUref) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovata
|
||||
if ( nInd >= 0) {
|
||||
// assegno il punto
|
||||
Point3d ptInt ;
|
||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = IntRes.ptI2 ;
|
||||
else
|
||||
ptInt = IntRes.ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcNormal( ptInt, trTria, vtN))
|
||||
vtN = trTria.GetN() ;
|
||||
// assegno valori al punto 5assi
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = vtN ;
|
||||
Pt5ax.vtDir2 = vtLine ;
|
||||
Pt5ax.dPar = dPar ;
|
||||
Pt5ax.nFlag = P5AX_STD ;
|
||||
// ritorno con successo
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ICurve& crRef,
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// Sistemazioni per tipo di superficie
|
||||
CISRFTMPVECTOR vpSurfTm ;
|
||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
||||
const SurfTriMesh* pSurfTm = nullptr ;
|
||||
switch ( vpSurf[i]->GetType()) {
|
||||
case SRF_TRIMESH :
|
||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
||||
break ;
|
||||
case SRF_BEZIER :
|
||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
||||
} break ;
|
||||
case SRF_FLATRGN :
|
||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
if ( pSurfTm == nullptr)
|
||||
return false ;
|
||||
vpSurfTm.emplace_back( pSurfTm) ;
|
||||
}
|
||||
|
||||
// Controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// Approssimo la curva con una polilinea alla massima risoluzione
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
||||
vPt5ax.clear() ;
|
||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, crRef, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
||||
if ( bSharpEdges) {
|
||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
||||
// precedente
|
||||
int j = i - 1 ;
|
||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
||||
// intersezione tra le due facce
|
||||
Plane3d plPlane1 ; plPlane1.Set( vPt5ax[j].ptP, vPt5ax[j].vtDir1) ;
|
||||
Plane3d plPlane2 ; plPlane2.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir1) ;
|
||||
Point3d ptEdge ; Vector3d vtEdge ;
|
||||
if ( IntersPlanePlane( plPlane1, plPlane2, ptEdge, vtEdge) == IPPT_YES) {
|
||||
Plane3d plPlane3 ; plPlane3.Set( vPt5ax[i].ptP, vPt5ax[i].vtDir2 ^ vPt5ax[j].vtDir2) ;
|
||||
Point3d ptInt ;
|
||||
if ( IntersLinePlane( ptEdge, vtEdge, 1, plPlane3, ptInt, false) == ILPT_YES) {
|
||||
// verifico se spigolo convesso o concavo
|
||||
bool bConvex ;
|
||||
if ( ! AreSamePointApprox( ptInt, vPt5ax[j].ptP))
|
||||
bConvex = ( ( vPt5ax[j].vtDir1 ^ ( ptInt - vPt5ax[j].ptP)) * vtEdge > 0) ;
|
||||
else
|
||||
bConvex = (( vPt5ax[i].vtDir1 ^ ( ptInt - vPt5ax[i].ptP)) * vtEdge < 0) ;
|
||||
// se convesso, metto due punti con direzione appena prima e appena dopo
|
||||
if ( bConvex) {
|
||||
Vector3d vtLine1 = ptInt - vPt5ax[j].ptP ; double dLen1 = vtLine1.Len() ;
|
||||
Vector3d vtLine2 = vPt5ax[i].ptP - ptInt ; double dLen2 = vtLine2.Len() ;
|
||||
if ( dLen1 > 2 * EPS_SMALL) {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt - vtLine1 / dLen1 * 2 * EPS_SMALL ;
|
||||
Pt5ax.vtDir1 = vPt5ax[j].vtDir1 ;
|
||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CVEX ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
if ( dLen2 > 2 * EPS_SMALL) {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt + vtLine2 / dLen2 * 2 * EPS_SMALL ;
|
||||
Pt5ax.vtDir1 = vPt5ax[i].vtDir1 ;
|
||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CVEX ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
// altrimenti concavo, aggiungo un solo punto con la direzione media
|
||||
else {
|
||||
Point5ax Pt5ax ;
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = Media( vPt5ax[i].vtDir1, vPt5ax[j].vtDir1) ;
|
||||
Pt5ax.vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ;
|
||||
Pt5ax.dPar = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
Pt5ax.nFlag = P5AX_CONC ;
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
++ i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rimozione punti in eccesso rispetto alle tolleranze
|
||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
ProjectPointOnSurf( const Point3d& ptP, const CISRFTMPVECTOR& vpStm, const SurfTriMesh& stmRef, double dPar, Point5ax& Pt5ax)
|
||||
{
|
||||
// punto sulla superficie guida a minima distanza
|
||||
DistPointSurfTm dPS( ptP, stmRef) ;
|
||||
Point3d ptMin ;
|
||||
int nTriaMin ;
|
||||
if ( dPS.GetMinDistPoint( ptMin) && dPS.GetMinDistTriaIndex ( nTriaMin)) {
|
||||
// recupero direzione della retta di minima distanza, altrimenti normale alla superficie
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL)
|
||||
vtLine /= dLineLen ;
|
||||
else {
|
||||
// calcolo la normale della superficie guida
|
||||
Triangle3dEx trGuide ;
|
||||
if ( ! stmRef.GetTriangle( nTriaMin, trGuide))
|
||||
return false ;
|
||||
if ( ! CalcNormal( ptMin, trGuide, vtLine))
|
||||
vtLine = trGuide.GetN() ;
|
||||
dLineLen = 100 ;
|
||||
}
|
||||
// intersezione della retta con le superfici (conservo l'intersezione più alta)
|
||||
int nInd = -1 ;
|
||||
IntLinStmInfo IntRes ;
|
||||
for ( int i = 0 ; i < int( vpStm.size()) ; ++ i) {
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, *vpStm[i], vIntRes, false)) {
|
||||
// cerco la prima intersezione valida a partire dall'ultima (è la più alta)
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
while ( nI >= 0 && abs( vIntRes[nI].dCosDN) < COS_ANG_LIM)
|
||||
--nI ;
|
||||
// se trovata
|
||||
if ( nI >= 0) {
|
||||
if ( nInd < 0) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
else {
|
||||
double dUref = (( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE) ? IntRes.dU2 : IntRes.dU) ;
|
||||
double dU = (( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE) ? vIntRes[nI].dU2 : vIntRes[nI].dU) ;
|
||||
if ( dU > dUref) {
|
||||
IntRes = vIntRes[nI] ;
|
||||
nInd = i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovata
|
||||
if ( nInd >= 0) {
|
||||
// calcolo il punto
|
||||
Point3d ptInt ;
|
||||
if ( IntRes.nILTT == ILTT_SEGM || IntRes.nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = IntRes.ptI2 ;
|
||||
else
|
||||
ptInt = IntRes.ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! vpStm[nInd]->GetTriangle( IntRes.nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcNormal( ptMin, trTria, vtN))
|
||||
vtN = trTria.GetN() ;
|
||||
// calcolo la normale della superficie guida
|
||||
Triangle3dEx trGuide ;
|
||||
if ( ! stmRef.GetTriangle( nTriaMin, trGuide))
|
||||
return false ;
|
||||
Vector3d vtN2 ;
|
||||
if ( ! CalcNormal( ptMin, trGuide, vtN2))
|
||||
vtN2 = trGuide.GetN() ;
|
||||
// assegno valori al punto 5assi
|
||||
Pt5ax.ptP = ptInt ;
|
||||
Pt5ax.vtDir1 = vtN ;
|
||||
Pt5ax.vtDir2 = vtN2 ;
|
||||
Pt5ax.dPar = dPar ;
|
||||
Pt5ax.nFlag = P5AX_STD ;
|
||||
// ritorno con successo
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, const ISurf& sfRef,
|
||||
double dLinTol, double dMaxSegmLen, bool bSharpEdges, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// sistemazioni per tipo di superficie
|
||||
CISRFTMPVECTOR vpSurfTm ;
|
||||
for ( int i = 0 ; i < int( vpSurf.size()) ; ++ i) {
|
||||
const SurfTriMesh* pSurfTm = nullptr ;
|
||||
switch ( vpSurf[i]->GetType()) {
|
||||
case SRF_TRIMESH :
|
||||
pSurfTm = GetBasicSurfTriMesh( vpSurf[i]) ;
|
||||
break ;
|
||||
case SRF_BEZIER :
|
||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
||||
pSurfTm = GetBasicSurfBezier( vpSurf[i])->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
||||
} break ;
|
||||
case SRF_FLATRGN :
|
||||
pSurfTm = GetBasicSurfFlatRegion( vpSurf[i])->GetAuxSurf() ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
if ( pSurfTm == nullptr)
|
||||
return false ;
|
||||
vpSurfTm.emplace_back( pSurfTm) ;
|
||||
}
|
||||
|
||||
// sistemazioni per tipo di superficie di riferimento
|
||||
const SurfTriMesh* pRefTm = nullptr ;
|
||||
switch ( sfRef.GetType()) {
|
||||
case SRF_TRIMESH :
|
||||
pRefTm = GetBasicSurfTriMesh( &sfRef) ;
|
||||
break ;
|
||||
case SRF_BEZIER :
|
||||
{ double dOldLinTol = GetSurfBezierAuxSurfRefinedTol() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( GetSurfBezierTol( dLinTol)) ;
|
||||
pRefTm = GetBasicSurfBezier( &sfRef)->GetAuxSurfRefined() ;
|
||||
SetSurfBezierAuxSurfRefinedTol( dOldLinTol) ;
|
||||
} break ;
|
||||
case SRF_FLATRGN :
|
||||
pRefTm = GetBasicSurfFlatRegion( &sfRef)->GetAuxSurf() ;
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
if ( pRefTm == nullptr)
|
||||
return false ;
|
||||
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 0.977) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Pulisco e riservo spazio nel vettore dei punti risultanti
|
||||
vPt5ax.clear() ;
|
||||
vPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptP, vpSurfTm, *pRefTm, dPar, Pt5ax))
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
// passo al successivo
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// se richiesto, inserimento punti intermedi in presenza di spigoli
|
||||
if ( bSharpEdges) {
|
||||
for ( int i = 1 ; i < int( vPt5ax.size()) ; ++ i) {
|
||||
// precedente
|
||||
int j = i - 1 ;
|
||||
// se normali tra corrente e precedente oltre limite e punti abbastanza lontani
|
||||
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER &&
|
||||
SqDist( vPt5ax[i].ptP, vPt5ax[j].ptP) > 25 * SQ_EPS_SMALL) {
|
||||
// punto medio
|
||||
Point3d ptMid = Media( vPt5ax[i].ptP, vPt5ax[j].ptP) ;
|
||||
double dMid = ( vPt5ax[i].dPar + vPt5ax[j].dPar) / 2 ;
|
||||
// se trovo proiezione, la salvo
|
||||
Point5ax Pt5ax ;
|
||||
if ( ProjectPointOnSurf( ptMid, vpSurfTm, *pRefTm, dMid, Pt5ax)) {
|
||||
vPt5ax.insert( vPt5ax.begin() + i, Pt5ax) ;
|
||||
-- i ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rimozione punti in eccesso rispetto alle tolleranze
|
||||
RemovePointsInExcess( vPt5ax, dLinTol, dMaxSegmLen, bSharpEdges) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -1,393 +0,0 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2023-2023
|
||||
//----------------------------------------------------------------------------
|
||||
// File : ProjectCurveSurfTm.cpp Data : 16.11.23 Versione : 2.5kh3
|
||||
// Contenuto : Implementazione funzioni proiezione curve su superficie Trimesh.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Modifiche : 31.08.23 DS Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "GeoConst.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||
#include "/EgtDev/Include/EGkProjectCurveSurfTm.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
PointsInTolerance( const PNT5AXVECTOR& vPt5ax, int nPrec, int nCurr, int nNext, double dSqTol)
|
||||
{
|
||||
for ( int i = nPrec + 1 ; i < nCurr ; ++ i) {
|
||||
double dSqDist ;
|
||||
if ( ! DistPointLine( vPt5ax[i].ptP, vPt5ax[nPrec].ptP, vPt5ax[nNext].ptP).GetSqDist( dSqDist) || dSqDist > dSqTol)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
RemovePointsInExcess( PNT5AXVECTOR& vMyPt5ax, double dLinTol, double dMaxSegmLen)
|
||||
{
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
double dSqMaxLen = dMaxSegmLen * dMaxSegmLen ;
|
||||
double dSqTol = dLinTol * dLinTol ;
|
||||
int nPrec = 0 ;
|
||||
int nCurr = 1 ;
|
||||
int nNext = 2 ;
|
||||
while ( nNext < int( vMyPt5ax.size())) {
|
||||
bool bRemove = false ;
|
||||
// lunghezza del segmento che unisce gli adiacenti
|
||||
double dSqLen = SqDist( vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
||||
// se lunghezza inferiore al massimo, passo agli altri controlli
|
||||
if ( dSqLen <= dSqMaxLen) {
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( vMyPt5ax[nCurr].ptP, vMyPt5ax[nPrec].ptP, vMyPt5ax[nNext].ptP) ;
|
||||
double dSqDist ;
|
||||
// se distanza inferiore a tolleranza lineare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vMyPt5ax, nPrec, nCurr, nNext, dSqTol)) {
|
||||
// verifico se errore angolare inferiore a limite
|
||||
double dPar ; dPL.GetParamAtMinDistPoint( dPar) ;
|
||||
Vector3d vtNew = Media( vMyPt5ax[nPrec].vtDir, vMyPt5ax[nNext].vtDir, dPar) ;
|
||||
if ( vtNew.Normalize() && vtNew * vMyPt5ax[nCurr].vtDir > cos( 2 * DEGTORAD))
|
||||
bRemove = true ;
|
||||
}
|
||||
}
|
||||
// se da eliminare
|
||||
if ( bRemove) {
|
||||
// dichiaro da eliminare il punto
|
||||
vMyPt5ax[nCurr].nFlag = -1 ;
|
||||
// avanzo con corrente e successivo
|
||||
nCurr = nNext ;
|
||||
++ nNext ;
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// avanzo il terzetto di uno step
|
||||
nPrec = nCurr ;
|
||||
nCurr = nNext ;
|
||||
++ nNext ;
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const Vector3d& vtDir, double dLinTol, double dMaxSegmLen,
|
||||
PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Oggetto per calcolo massivo intersezioni tra linee di proiezione e superficie
|
||||
Frame3d frRefLine ;
|
||||
if ( ! frRefLine.Set( ORIG, vtDir))
|
||||
return false ;
|
||||
IntersParLinesSurfTm intPLSTM( frRefLine, tmSurf) ;
|
||||
|
||||
// Vettore locale dei punti risultanti
|
||||
PNT5AXVECTOR vMyPt5ax ;
|
||||
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
Point3d ptL = GetToLoc( ptP, frRefLine) ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
intPLSTM.GetInters( ptL, 1, vIntRes, false) ;
|
||||
if ( ! vIntRes.empty()) {
|
||||
// calcolo il punto
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
Point3d ptInt ;
|
||||
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = vIntRes[nI].ptI2 ;
|
||||
else
|
||||
ptInt = vIntRes[nI].ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
double dU, dV, dW ;
|
||||
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||
if ( ! vtN.Normalize())
|
||||
vtN = trTria.GetN() ;
|
||||
// aggiungo al vettore dei proiettati
|
||||
vMyPt5ax.emplace_back( ptInt, vtN, dPar, 1) ;
|
||||
}
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
||||
|
||||
// copio i punti rimasti nel vettore di ritorno
|
||||
vPt5ax.clear() ;
|
||||
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||
if ( Pt5ax.nFlag != -1)
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const IGeoPoint3d& gpRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Vettore locale dei punti risultanti
|
||||
PNT5AXVECTOR vMyPt5ax ;
|
||||
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione data dal punto di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// punto di riferimento
|
||||
Point3d ptMin = gpRef.GetPoint() ;
|
||||
// intersezione della retta di minima distanza con la superficie
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL) {
|
||||
vtLine /= dLineLen ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||
if ( vIntRes.size() > 0) {
|
||||
// calcolo il punto
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
Point3d ptInt ;
|
||||
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = vIntRes[nI].ptI2 ;
|
||||
else
|
||||
ptInt = vIntRes[nI].ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
double dU, dV, dW ;
|
||||
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||
if ( ! vtN.Normalize())
|
||||
vtN = trTria.GetN() ;
|
||||
// aggiungo al vettore dei proiettati
|
||||
vMyPt5ax.emplace_back( ptInt, vtN, vtLine, dPar, 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
||||
|
||||
// copio i punti rimasti nel vettore di ritorno
|
||||
vPt5ax.clear() ;
|
||||
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||
if ( Pt5ax.nFlag != -1)
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ICurve& crRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Vettore locale dei punti risultanti
|
||||
PNT5AXVECTOR vMyPt5ax ;
|
||||
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// punto sulla curva a minima distanza
|
||||
DistPointCurve dPC( ptP, crRef) ;
|
||||
Point3d ptMin ;
|
||||
int nFlag ;
|
||||
if ( dPC.GetMinDistPoint( 0, ptMin, nFlag)) {
|
||||
// intersezione della retta di minima distanza con la superficie
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL) {
|
||||
vtLine /= dLineLen ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||
if ( vIntRes.size() > 0) {
|
||||
// calcolo il punto
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
Point3d ptInt ;
|
||||
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = vIntRes[nI].ptI2 ;
|
||||
else
|
||||
ptInt = vIntRes[nI].ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
double dU, dV, dW ;
|
||||
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||
if ( ! vtN.Normalize())
|
||||
vtN = trTria.GetN() ;
|
||||
// aggiungo al vettore dei proiettati
|
||||
vMyPt5ax.emplace_back( ptInt, vtN, vtLine, dPar, 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
||||
|
||||
// copio i punti rimasti nel vettore di ritorno
|
||||
vPt5ax.clear() ;
|
||||
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||
if ( Pt5ax.nFlag != -1)
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
ProjectCurveOnSurfTm( const ICurve& crCrv, const ISurfTriMesh& tmSurf, const ISurfTriMesh& tmRef,
|
||||
double dLinTol, double dMaxSegmLen, PNT5AXVECTOR& vPt5ax)
|
||||
{
|
||||
// controllo le tolleranze
|
||||
dLinTol = max( dLinTol, LIN_TOL_MIN) ;
|
||||
dMaxSegmLen = max( dMaxSegmLen, 10 * EPS_SMALL) ;
|
||||
|
||||
// approssimo la curva con una polilinea entro la metà della tolleranza
|
||||
PolyLine PL ;
|
||||
if ( ! crCrv.ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
||||
return false ;
|
||||
const double MAX_SEG_LEN = min( dMaxSegmLen, 1.) ;
|
||||
if ( ! PL.AdjustForMaxSegmentLen( MAX_SEG_LEN))
|
||||
return false ;
|
||||
|
||||
// Vettore locale dei punti risultanti
|
||||
PNT5AXVECTOR vMyPt5ax ;
|
||||
vMyPt5ax.reserve( PL.GetPointNbr()) ;
|
||||
|
||||
// proietto i punti della polilinea sulla superficie con direzione normale alla curva di riferimento
|
||||
double dPar ;
|
||||
Point3d ptP ;
|
||||
bool bFound = PL.GetFirstUPoint( &dPar, &ptP) ;
|
||||
while ( bFound) {
|
||||
// punto sulla superficie guida a minima distanza
|
||||
DistPointSurfTm dPS( ptP, tmRef) ;
|
||||
Point3d ptMin ;
|
||||
int nTriaMin ;
|
||||
if ( dPS.GetMinDistPoint( ptMin) && dPS.GetMinDistTriaIndex ( nTriaMin)) {
|
||||
// intersezione della retta di minima distanza con la superficie
|
||||
Vector3d vtLine = ptP - ptMin ;
|
||||
double dLineLen = vtLine.Len() ;
|
||||
if ( dLineLen > EPS_SMALL) {
|
||||
vtLine /= dLineLen ;
|
||||
ILSIVECTOR vIntRes ;
|
||||
if ( IntersLineSurfTm( ptP, vtLine, dLineLen, tmSurf, vIntRes, false)) {
|
||||
if ( vIntRes.size() > 0) {
|
||||
// calcolo il punto
|
||||
int nI = int( vIntRes.size()) - 1 ;
|
||||
Point3d ptInt ;
|
||||
if ( vIntRes[nI].nILTT == ILTT_SEGM || vIntRes[nI].nILTT == ILTT_SEGM_ON_EDGE)
|
||||
ptInt = vIntRes[nI].ptI2 ;
|
||||
else
|
||||
ptInt = vIntRes[nI].ptI ;
|
||||
// calcolo la normale (si calcola smooth, in caso di errore si prende quella del triangolo)
|
||||
Triangle3dEx trTria ;
|
||||
if ( ! tmSurf.GetTriangle( vIntRes[nI].nT, trTria))
|
||||
return false ;
|
||||
Vector3d vtN ;
|
||||
double dU, dV, dW ;
|
||||
if ( BarycentricCoord( ptInt, trTria, dU, dV, dW))
|
||||
vtN = dU * trTria.GetVertexNorm( 0) + dV * trTria.GetVertexNorm( 1) + dW * trTria.GetVertexNorm( 2) ;
|
||||
if ( ! vtN.Normalize())
|
||||
vtN = trTria.GetN() ;
|
||||
// calcolo la normale della superficie guida
|
||||
Triangle3dEx trGuide ;
|
||||
if ( ! tmRef.GetTriangle( nTriaMin, trGuide))
|
||||
return false ;
|
||||
Vector3d vtN2 ;
|
||||
double dU2, dV2, dW2 ;
|
||||
if ( BarycentricCoord( ptMin, trGuide, dU2, dV2, dW2))
|
||||
vtN2 = dU2 * trGuide.GetVertexNorm( 0) + dV2 * trGuide.GetVertexNorm( 1) + dW2 * trGuide.GetVertexNorm( 2) ;
|
||||
if ( ! vtN2.Normalize())
|
||||
vtN2 = trGuide.GetN() ;
|
||||
// aggiungo al vettore dei proiettati
|
||||
vMyPt5ax.emplace_back( ptInt, vtN, vtN2, dPar, 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bFound = PL.GetNextUPoint( &dPar, &ptP) ;
|
||||
}
|
||||
|
||||
// rimuovo i punti allineati entro la tolleranza e non più lontani tra loro del massimo
|
||||
RemovePointsInExcess( vMyPt5ax, dLinTol, dMaxSegmLen) ;
|
||||
|
||||
// copio i punti rimasti nel vettore di ritorno
|
||||
vPt5ax.clear() ;
|
||||
for ( const auto& Pt5ax : vMyPt5ax) {
|
||||
if ( Pt5ax.nFlag != -1)
|
||||
vPt5ax.emplace_back( Pt5ax) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
@@ -15,8 +15,8 @@
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "DistPointLine.h"
|
||||
#include "RemoveCurveDefects.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
@@ -0,0 +1,772 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 20024
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SbzFromCurves.cpp Data : 07.05.24 Versione : 2.6e2
|
||||
// Contenuto : Implementazione di funzioni per creazione di superfici Sbz
|
||||
// a partire da curve, con diversi metodi.
|
||||
//
|
||||
//
|
||||
// Modifiche : 07.05.24 DB Creazione modulo.
|
||||
//
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
//--------------------------- Include ----------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "GeoConst.h"
|
||||
#include "CurveLine.h"
|
||||
#include "CurveArc.h"
|
||||
#include "CurveComposite.h"
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "Voronoi.h"
|
||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||
#include "/EgtDev/Include/EGkOffsetCurve.h"
|
||||
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EGkRotationMinimizingFrame.h"
|
||||
#include "/EgtDev/Include/EGkRotationXplaneFrame.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||
#include <future>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve == nullptr)
|
||||
return nullptr ;
|
||||
// calcolo la polilinea che approssima la curva
|
||||
PolyLine PL ;
|
||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||
return nullptr ;
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByFlatContour( PL))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &vpCurve == nullptr || vpCurve.empty())
|
||||
return nullptr ;
|
||||
// calcolo le polilinee che approssimano le curve della regione
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
Vector3d vtN ;
|
||||
INTMATRIX vnPLIndMat ;
|
||||
BOOLVECTOR vbInvert ;
|
||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat,vbInvert))
|
||||
return nullptr ;
|
||||
POLYLINEVECTOR vPLOrd ;
|
||||
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) {
|
||||
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++j){
|
||||
vPLOrd.push_back(vPL[vnPLIndMat[i][j]]) ;
|
||||
if( vbInvert[vnPLIndMat[i][j]])
|
||||
vPLOrd.back().Invert() ;
|
||||
}
|
||||
}
|
||||
// creo e setto la superficie di bezier
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByRegion( vPLOrd))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
||||
bool bCapEnds, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve == nullptr || &vtExtr == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
PtrOwner<const ICurve> pBezierForm( CurveToBezierCurve( pCurve)) ;
|
||||
// creo e setto la superficie di Bezier
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
////-------------------------------------------------------------------------------
|
||||
//ISurfCompo*
|
||||
//GetSurfBezierByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d& vtExtr, double dLinTol) ///// RICHIEDE LE SURF COMPO/////////////////
|
||||
//{
|
||||
// // verifica parametri
|
||||
// if ( &vpCurve == nullptr || vpCurve.empty() || &vtExtr == nullptr)
|
||||
// return nullptr ;
|
||||
// // se una sola curva, uso la funzione precedente
|
||||
// if ( vpCurve.size() == 1 )
|
||||
// return GetSurfBezierByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
||||
// // calcolo le polilinee che approssimano le curve della regione
|
||||
// POLYLINEVECTOR vPL ;
|
||||
// Vector3d vtN ;
|
||||
// if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
// return nullptr ;
|
||||
// // verifico la direzione di estrusione
|
||||
// double dOrthoExtr = vtN * vtExtr ;
|
||||
// if ( ( abs( dOrthoExtr) < EPS_SMALL))
|
||||
// return nullptr ;
|
||||
// // se componente estrusione negativa, inverto tutti i percorsi
|
||||
// if ( dOrthoExtr < 0) {
|
||||
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i)
|
||||
// vPL[i].Invert() ;
|
||||
// }
|
||||
// // creo la prima superficie di estremità
|
||||
// PtrOwner<SurfBezier> pSbz1( CreateBasicSurfBezier()) ;
|
||||
// if ( IsNull( pSbz1) || ! pSbz1->CreateByRegion( vPL))
|
||||
// return nullptr ;
|
||||
// // creo la seconda superficie come copia della prima e poi inverto la prima
|
||||
// PtrOwner<ISurfBezier> pSbz2( pSbz1->Clone()) ;
|
||||
// pSbz1->Invert() ;
|
||||
//
|
||||
// // creo e unisco le diverse superfici di estrusione
|
||||
// for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// // estrusione
|
||||
// SurfBezier SbzLat ;
|
||||
// if ( ! SbzLat.CreateByExtrusion( vPL[i], vtExtr)) // qui mi serve la curva e non la polyline della curva. vuol dire che dalla CalcRegionPolyLines devo farmi restituire anche le curve ordinate
|
||||
// return nullptr ;
|
||||
// }
|
||||
// // restituisco la superficie
|
||||
// return Release( pSrfCompo) ; // in realtà dovrei restituire tre superfici!!! due basi e una sup laterale( e quindi fare una SurfCompo) oppure dovrei spezzare le basi in tot pezzi e creare una superficie unica
|
||||
//}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
bool bCapEnds, double dLinTol) // con l'aggiunta delle SURFCOMPO posso gestire anche i cap e curve che attraversano l'asse
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
return nullptr ;
|
||||
// limite minimo su tolleranza
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, ANG_FULL, 0))
|
||||
return nullptr ;
|
||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||
double dVol ;
|
||||
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
||||
pSbz->Invert() ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx,
|
||||
double dAngRotDeg, double dMove, bool bCapEnds, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve == nullptr || &ptAx == nullptr || &vtAx == nullptr)
|
||||
return nullptr ;
|
||||
// limite minimo su tolleranza
|
||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||
|
||||
// creo e setto la superficie bezier
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove))
|
||||
return nullptr ;
|
||||
|
||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||
double dVol ;
|
||||
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
||||
pSbz->Invert() ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
|
||||
{
|
||||
// riferimento all'inizio della linea guida
|
||||
Frame3d frStart ;
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ;
|
||||
pGuide->GetStartDir( vtStart) ;
|
||||
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
||||
|
||||
// capisco se la guida è una linea spezzata o una curva
|
||||
bool bGuideIsPolyLine = false ;
|
||||
switch ( pGuide->GetType()) {
|
||||
case CRV_COMPO : {
|
||||
bGuideIsPolyLine = true ;
|
||||
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
||||
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
||||
const ICurve* pCrv = pCC->GetCurve( i) ;
|
||||
if( pCrv->GetType() != CRV_LINE) {
|
||||
if ( pCrv->GetType() == CRV_BEZIER) {
|
||||
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
||||
}
|
||||
else
|
||||
bGuideIsPolyLine = false ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
case CRV_LINE :
|
||||
bGuideIsPolyLine = true ;
|
||||
break ;
|
||||
case CRV_BEZIER : {
|
||||
// controllo se i punti di controllo sono allineati
|
||||
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
||||
break ;
|
||||
}
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
|
||||
bool bRat = false ;
|
||||
int nSpanV = 0 ;
|
||||
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
||||
if ( bGuideIsPolyLine ) {
|
||||
if( pGuide->GetType() == CRV_LINE)
|
||||
nSpanV = 1 ;
|
||||
else if ( pGuide->GetType() == CRV_COMPO)
|
||||
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
||||
}
|
||||
else {
|
||||
//converto in bezier la guida ( grado 3, non razionale)
|
||||
if ( pGuide->GetType() != CRV_BEZIER)
|
||||
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
||||
else {
|
||||
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
||||
if( ! pGuideBez->IsRational())
|
||||
pCrvV->AddCurve( pGuide->Clone()) ;
|
||||
else
|
||||
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
||||
}
|
||||
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
||||
return nullptr ;
|
||||
nSpanV = pCrvV->GetCurveCount() ;
|
||||
}
|
||||
|
||||
// converto in bezier la sezione ( grado 3, non razionale)
|
||||
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
||||
if ( pSect->GetType() != CRV_BEZIER)
|
||||
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
||||
else {
|
||||
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
||||
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
||||
}
|
||||
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
||||
return nullptr ;
|
||||
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
||||
|
||||
int nDegV = 3 ;
|
||||
if ( bGuideIsPolyLine)
|
||||
nDegV = 1 ;
|
||||
|
||||
int nDegU = 3 ;
|
||||
// superficie swept
|
||||
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
||||
if ( bGuideIsPolyLine) {
|
||||
frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
||||
// porto la sezione nel sistema di riferimento del piano in cui giace
|
||||
pCrvU->ToLoc( frStart) ;
|
||||
// la guida è una linea spezzata, quindi posso lavorare con gli offset
|
||||
ICRVCOMPOPOVECTOR vCC ;
|
||||
INTMATRIX mRep ; mRep.resize( nSpanU * nDegU + 1) ;
|
||||
int nMaxSpanV = nSpanV ;
|
||||
for( int i = 0 ; i < nSpanU ; ++i) {
|
||||
const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
||||
for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
||||
Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
||||
// faccio l'offset della guida nel punto di controllo della sezione
|
||||
OffsetCurve OffsCrv ;
|
||||
if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
||||
return nullptr ;
|
||||
vCC.emplace_back() ;
|
||||
vCC.back()->AddCurve(OffsCrv.GetLongerCurve()) ;
|
||||
if ( IsNull( pCrvV))
|
||||
return nullptr ;
|
||||
vCC.back()->Translate( ptCtrl.y * frStart.VersY()) ;
|
||||
//mRep[ i * nDegU + j].resize(vCC.back()->GetCurveCount()) ;
|
||||
nMaxSpanV = max ( nMaxSpanV, vCC.back()->GetCurveCount()) ;
|
||||
}
|
||||
}
|
||||
|
||||
// devo capire quante span in V devo creare e a quale span appartengono i tratti degli offset
|
||||
for ( int k = 0 ; k < int( vCC.size()) ; ++k) {
|
||||
const ICurveComposite* pCC = vCC[k] ;
|
||||
mRep[k].resize( nMaxSpanV) ;
|
||||
for ( int z = 0 ; z < int( mRep[k].size()) ; ++z) {
|
||||
int nProp = - 1 ; pCC->GetCurveTempProp( z, nProp) ;
|
||||
if ( nProp == 0) {
|
||||
// ho trovato almeno una curva di offset che ha un tratto non derivante direttamente dalla curva originale
|
||||
// tutte le altre curve che hanno curve di offeset che non hanno questo tratto bonus dovranno ripetere il punto di controllo
|
||||
for ( int w = 0 ; w < int( vCC.size()) ; ++w) {
|
||||
const ICurveComposite* pCCOther = vCC[w] ;
|
||||
int nPropCheck = -1 ; pCCOther->GetCurveTempProp( z, nPropCheck) ;
|
||||
if( nPropCheck != 0)
|
||||
mRep[w][z] = 1 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// conto in quante colonne di mRep la somma degli elementi è != 0
|
||||
// questo numero va aggiunto all'attuale nSpanV
|
||||
int nSpanPlus = 0 ;
|
||||
for( int z = 0 ; z < nMaxSpanV ; ++z) {
|
||||
int nPosTot = 0 ;
|
||||
for ( int k = 0 ; k < int( mRep.size()) ; ++k )
|
||||
nPosTot += mRep[k][z] ;
|
||||
if( nPosTot != 0)
|
||||
nSpanPlus += 1 ;
|
||||
}
|
||||
nMaxSpanV = max( nMaxSpanV, nSpanV + nSpanPlus) ;
|
||||
nSpanV = nMaxSpanV ;
|
||||
|
||||
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
||||
//// aggiungo i punti di controllo alla superficie
|
||||
//for( int i = 0 ; i < nSpanU ; ++i) {
|
||||
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
||||
// const ICurveComposite* pOffsetCrv = vCC[i*nDegU + j] ;
|
||||
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
||||
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
||||
// if( pCL == nullptr)
|
||||
// return nullptr ;
|
||||
// if( z == 0) {
|
||||
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
||||
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
||||
// }
|
||||
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
||||
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//// aggiungo i punti di controllo alla superficie /// DA CORREGGERE L'AGGIUNTA DEI PUNTI DI CONTROLLO
|
||||
//for( int i = 0 ; i < int( vCC.size()) ; ++i) {
|
||||
// const ICurveComposite* pOffsetCrv = vCC[i] ;
|
||||
// for ( int z = 0 ; z < pOffsetCrv->GetCurveCount() ; ++z) {
|
||||
// const ICurveLine* pCL = GetCurveLine( pOffsetCrv->GetCurve( z)) ;
|
||||
// if( pCL == nullptr)
|
||||
// return nullptr ;
|
||||
// if( z == 0) {
|
||||
// Point3d ptSubStart ; pCL->GetStartPoint( ptSubStart) ;
|
||||
// pSurfBez->SetControlPoint( i * nDegU + j, 0, ptSubStart) ;
|
||||
// }
|
||||
// Point3d ptSubEnd ; pCL->GetEndPoint( ptSubEnd) ;
|
||||
// pSurfBez->SetControlPoint( i * nDegU + j, z + 1, ptSubEnd) ;
|
||||
// }
|
||||
//}
|
||||
|
||||
}
|
||||
else {
|
||||
pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ;
|
||||
|
||||
// VERSIONE con le copie della sezione ( superficie skinned)
|
||||
|
||||
// creo delle copie della curva e faccio la skinned
|
||||
// per ogni sottocurva della guida ( che sarà composta da curve di bezier di grado 3)
|
||||
// posiziono una copia della curva di sezione per ogni punto di controllo
|
||||
frStart.Set( ptStart, vtStart) ;
|
||||
pCrvU->ToLoc( frStart) ;
|
||||
ICURVEPOVECTOR vCrvSet ;
|
||||
CICURVEPVECTOR vpCrv ;
|
||||
RotationMinimizingFrame rmfGuide ; rmfGuide.Set( pCrvV, frStart) ;
|
||||
//double dStep = 0.25 ;
|
||||
FRAME3DVECTOR vFrame ;
|
||||
int nSpanV = pCrvV->GetCurveCount() ;
|
||||
int nSplit = 8 * nSpanV ;
|
||||
rmfGuide.GetFramesBySplit( nSplit, vFrame) ;
|
||||
|
||||
for ( int i = 0 ; i < nSpanV ; ++i) {
|
||||
for ( int j = i==0 ? 0 : 1 ; j < nSplit + 1 ; ++j) {
|
||||
ICurve* pNewSect = pCrvU->Clone() ;
|
||||
pNewSect->ToGlob( vFrame[j]) ; // da sistemare se ho più curve ( la pGuide è una compo) e in base allo step di divisione!!!!!!!!! ///////
|
||||
vpCrv.push_back( pNewSect) ;
|
||||
vCrvSet.emplace_back( pNewSect) ;
|
||||
}
|
||||
}
|
||||
|
||||
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
||||
|
||||
|
||||
|
||||
//////VERSIONE con l'offset dei punti di controllo // richiede l'interpolazione dei punti
|
||||
//
|
||||
//// faccio l'offset della guida e poi riconverto i risultati in curve di bezier tramite interpolazione
|
||||
//
|
||||
//frStart.Set( ptStart, -vtStart, vtStart ^ vtNorm) ;
|
||||
//// porto la sezione nel sistema di riferimento del piano in cui giace
|
||||
//pCrvU->ToLoc( frStart) ;
|
||||
//for( int i = 0 ; i < nSpanU ; ++i) {
|
||||
// const ICurveBezier* pSubCrv = GetCurveBezier( pCrvU->GetCurve( i)) ;
|
||||
// for ( int j = i==0 ? 0 : 1 ; j < nDegU + 1 ; ++j ) {
|
||||
// Point3d ptCtrl = pSubCrv->GetControlPoint( j) ;
|
||||
// // faccio l'offset della guida nel punto di controllo della sezione
|
||||
// OffsetCurve OffsCrv ;
|
||||
// if ( ! OffsCrv.Make( pGuide, ptCtrl.x, ICurve::OFF_EXTEND) || OffsCrv.GetCurveCount() == 0)
|
||||
// return nullptr ;
|
||||
// PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
||||
// pCrvV->AddCurve( OffsCrv.GetLongerCurve()) ;
|
||||
// if ( IsNull( pCrvV))
|
||||
// return nullptr ;
|
||||
// pCrvV->Translate( ptCtrl.y * frStart.VersY()) ;
|
||||
// PNTVECTOR vPnt ;
|
||||
// int nOffCrvs = pCrvV->GetCurveCount() ;
|
||||
// for ( int z = 0 ; z < nOffCrvs ; ++z) {
|
||||
// Point3d ptCtrl ;
|
||||
// if ( z == 0) {
|
||||
// pCrvV->GetCurve(z)->GetStartPoint( ptCtrl) ;
|
||||
// vPnt.push_back( ptCtrl) ;
|
||||
// }
|
||||
// pCrvV->GetCurve(z)->GetEndPoint( ptCtrl) ;
|
||||
// vPnt.push_back( ptCtrl) ;
|
||||
// }
|
||||
// pCrvV.Set( CreateCurveComposite()) ;
|
||||
// pCrvV->AddCurve( InterpolatePointSetWithBezier( vPnt, dLinTol)) ;
|
||||
//
|
||||
//
|
||||
// nSpanV = pCrvV->GetCurveCount() ;
|
||||
// pSurfBez->Init( nDegU,nDegV, nSpanU, nSpanV, bRat) ; /// NON POSSO REINIZIALIZZARE LA SURF QUI!
|
||||
// /// QUANDO INIZIO A INSERIRE I PUNTI DI CONTROLLO DEVO AVER DEFINITO nSpanV
|
||||
//
|
||||
//
|
||||
// // aggiungo i punti di controllo alla superficie
|
||||
// for ( int z = 0 ; z < nSpanV ; ++z) {
|
||||
// const ICurveBezier* pCrvBez = GetCurveBezier( pCrvV->GetCurve( z)) ;
|
||||
// if( pCrvBez == nullptr)
|
||||
// return nullptr ;
|
||||
// for ( int k = z == 0 ? 0 : 1 ; k < nDegV ; ++k) {
|
||||
// Point3d ptCtrl = pCrvBez->GetControlPoint( k) ;
|
||||
// pSurfBez->SetControlPoint( i * nDegU + j, z * nDegV + k, ptCtrl) ;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
////// se richiesti caps e sezione chiusa e guida aperta /// in attesa della SurfCompo, al momento viene fatto nell'executor
|
||||
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
||||
// // verifico che le due estremità siano chiuse e piatte
|
||||
|
||||
//}
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSurfBez) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
||||
{
|
||||
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
|
||||
bool bRMF = vtAx.IsSmall() ;
|
||||
|
||||
// riferimento all'inizio della linea guida
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ;
|
||||
pGuide->GetStartDir( vtStart) ;
|
||||
Frame3d frStart ;
|
||||
if ( bRMF) {
|
||||
if ( ! frStart.Set( ptStart, vtStart))
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
Vector3d vtAxX = vtAx ^ vtStart ;
|
||||
if ( vtAxX.IsSmall()) {
|
||||
vtAxX = FromUprightOrtho( vtAx) ;
|
||||
vtAxX.Rotate( vtAx, 0, 1) ;
|
||||
}
|
||||
if ( ! frStart.Set( ptStart, vtStart, vtAxX))
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
// capisco se la guida è una linea spezzata o una curva
|
||||
bool bGuideIsPolyLine = false ;
|
||||
switch( pGuide->GetType()) {
|
||||
case CRV_COMPO : {
|
||||
bGuideIsPolyLine = true ;
|
||||
const ICurveComposite* pCC = GetCurveComposite( pGuide) ;
|
||||
for ( int i = 0 ; i < pCC->GetCurveCount() && bGuideIsPolyLine ; ++i) {
|
||||
const ICurve* pCrv = pCC->GetCurve( i) ;
|
||||
if ( pCrv->GetType() != CRV_LINE) {
|
||||
if ( pCrv->GetType() == CRV_BEZIER) {
|
||||
const ICurveBezier* pCrvBez = GetCurveBezier( pCrv) ;
|
||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
||||
}
|
||||
else
|
||||
bGuideIsPolyLine = false ;
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
case CRV_LINE :
|
||||
bGuideIsPolyLine = true ;
|
||||
break ;
|
||||
case CRV_BEZIER : {
|
||||
// controllo se i punti di controllo sono allineati
|
||||
const ICurveBezier* pCrvBez = GetCurveBezier( pGuide) ;
|
||||
bGuideIsPolyLine = pCrvBez->IsALine() ;
|
||||
break ;
|
||||
}
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
|
||||
bool bRat = false ;
|
||||
int nSpanV = 0 ;
|
||||
PtrOwner<ICurveComposite> pCrvV( CreateCurveComposite()) ;
|
||||
if ( bGuideIsPolyLine) {
|
||||
if ( pGuide->GetType() == CRV_LINE)
|
||||
nSpanV = 1 ;
|
||||
else if ( pGuide->GetType() == CRV_COMPO)
|
||||
nSpanV = GetCurveComposite( pGuide)->GetCurveCount() ;
|
||||
}
|
||||
else {
|
||||
// converto in bezier la guida ( grado 3, non razionale)
|
||||
if ( pGuide->GetType() != CRV_BEZIER)
|
||||
pCrvV->AddCurve( CurveToBezierCurve( pGuide, 3, false)) ;
|
||||
else {
|
||||
const ICurveBezier* pGuideBez = GetCurveBezier( pGuide) ;
|
||||
if ( ! pGuideBez->IsRational())
|
||||
pCrvV->AddCurve( pGuide->Clone()) ;
|
||||
else
|
||||
pCrvV->AddCurve( EditBezierCurve( pGuideBez, 3, false)) ;
|
||||
}
|
||||
if ( IsNull( pCrvV) || ! pCrvV->IsValid())
|
||||
return nullptr ;
|
||||
nSpanV = pCrvV->GetCurveCount() ;
|
||||
}
|
||||
|
||||
// converto in bezier la sezione ( grado 3, non razionale)
|
||||
PtrOwner<ICurveComposite> pCrvU( CreateCurveComposite()) ;
|
||||
if ( pSect->GetType() != CRV_BEZIER)
|
||||
pCrvU->AddCurve( CurveToBezierCurve( pSect, 3, false)) ;
|
||||
else {
|
||||
const ICurveBezier* pSectBez = GetCurveBezier( pSect) ;
|
||||
if( ! pSectBez->IsRational())
|
||||
pCrvU->AddCurve( pSect->Clone()) ; ///// questa curva potrebbe non essere di grado 3!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
else
|
||||
pCrvU->AddCurve( EditBezierCurve( pSectBez, 3, false)) ;
|
||||
}
|
||||
if ( IsNull( pCrvU) || ! pCrvU->IsValid())
|
||||
return nullptr ;
|
||||
|
||||
// calcolo il vettore di Frames campionati lungo la guida mediante la tolleranza definita
|
||||
FRAME3DVECTOR vFrames ;
|
||||
if ( bRMF) {
|
||||
RotationMinimizingFrame RMF ;
|
||||
if ( bGuideIsPolyLine) {
|
||||
if ( ! RMF.Set( pGuide, frStart) ||
|
||||
! RMF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
if ( ! RMF.Set( pGuide, frStart) ||
|
||||
! RMF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
RotationXplaneFrame RXF ;
|
||||
if ( bGuideIsPolyLine) {
|
||||
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
||||
! RXF.GetFramesBySplit( nSpanV, vFrames) || vFrames.empty())
|
||||
return nullptr ;
|
||||
}
|
||||
else {
|
||||
if ( ! RXF.Set( pGuide, vtAx, frStart.VersX()) ||
|
||||
! RXF.GetFramesByTolerance( dLinTol, vFrames) || vFrames.empty())
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
|
||||
// per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
|
||||
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
||||
int nDegU = 9 ; // debug
|
||||
int nDegV = 3 ;
|
||||
if ( bGuideIsPolyLine){
|
||||
nDegV = 1 ;
|
||||
// superficie swept
|
||||
PtrOwner<ISurfBezier> pSurfBez( CreateSurfBezier()) ;
|
||||
pSurfBez->Init( nDegU, nDegV, nSpanU, nSpanV, bRat) ;
|
||||
pCrvU->ToLoc( frStart) ;
|
||||
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
||||
PtrOwner<ICurveComposite> pNewSect( pCrvU->Clone()) ;
|
||||
pNewSect->ToGlob( vFrames[f]) ;
|
||||
for ( int i = 0 ; i < nSpanU ; ++i) {
|
||||
const ICurveBezier* pSubCrvBez = GetCurveBezier( pNewSect->GetCurve( i)) ;
|
||||
for ( int j = 0 ; j < nDegU + 1 ; ++j) {
|
||||
Point3d ptCtrl = pSubCrvBez->GetControlPoint( j) ;
|
||||
pSurfBez->SetControlPoint( i * nDegU + j, f, ptCtrl) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Release( pSurfBez) ;
|
||||
}
|
||||
else {
|
||||
// porto la sezione nel sistema di riferimento del piano in cui giace
|
||||
pCrvU->ToLoc( frStart) ;
|
||||
ICURVEPOVECTOR vCrvSet ;
|
||||
CICURVEPVECTOR vpCrv ;
|
||||
for ( int f = 0 ; f < int( vFrames.size()) ; ++f) {
|
||||
ICurve* pNewSect = pCrvU->Clone() ;
|
||||
// porto la curva nel frame corrente
|
||||
pNewSect->ToGlob( vFrames[f]) ;
|
||||
vpCrv.push_back( pNewSect) ;
|
||||
vCrvSet.emplace_back( pNewSect) ;
|
||||
}
|
||||
|
||||
return GetSurfBezierSkinned( vpCrv, dLinTol) ;
|
||||
}
|
||||
|
||||
//// se richiesti caps e sezione chiusa e guida aperta
|
||||
//if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
||||
|
||||
// // aggiungo il cap sull'inizio ( portandolo nel frame del punto iniziale della guida )
|
||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
||||
// return nullptr ;
|
||||
// pSci->ToGlob( vFrames.front()) ;
|
||||
// // aggiungo
|
||||
// StmFts.AddSurfTriMesh( *pSci) ;
|
||||
|
||||
// // aggiungo il cap sulla fine ( portandolo nel frame del punto finale della guida )
|
||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
||||
// return nullptr ;
|
||||
// pSce->ToGlob( vFrames.back()) ;
|
||||
// // inverto
|
||||
// pSce->Invert() ;
|
||||
// // aggiungo
|
||||
// StmFts.AddSurfTriMesh( *pSce) ;
|
||||
//}
|
||||
|
||||
//// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||
//double dVol ;
|
||||
//if ( pSTM->GetVolume( dVol) && dVol < 0)
|
||||
// pSTM->Invert() ;
|
||||
|
||||
// restituisco la superficie
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( &ptP == nullptr || pCurve == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, double dLinTol)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||
return nullptr ;
|
||||
|
||||
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||
if ( pCurve1->GetType() != CRV_BEZIER)
|
||||
pCC1->AddCurve( CurveToBezierCurve( pCurve1, true, false)) ;
|
||||
else
|
||||
pCC1->AddCurve( pCurve1->Clone()) ;
|
||||
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
||||
return nullptr ;
|
||||
|
||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||
if ( pCurve2->GetType() != CRV_BEZIER)
|
||||
pCC2->AddCurve( CurveToBezierCurve( pCurve2, true, false)) ;
|
||||
else
|
||||
pCC2->AddCurve( pCurve2->Clone()) ;
|
||||
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
||||
return nullptr ;
|
||||
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierSkinned( const CICURVEPVECTOR& vCrv, double dLinTol)
|
||||
{
|
||||
// verifico che le curve siano valide
|
||||
for ( int i = 0 ; i < int( vCrv.size()) ; ++i) {
|
||||
if( vCrv[i] == nullptr || ! vCrv[i]->IsValid())
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
// se ho solo due curve allora faccio la rigata
|
||||
if( vCrv.size() == 2)
|
||||
return GetSurfBezierRuled( vCrv[0], vCrv[1], ISurfBezier::RLT_B_MINDIST_PLUS, dLinTol) ;
|
||||
|
||||
//trasformo le curve in curve di bezier, pareggio il numero di sottocurve e il grado
|
||||
|
||||
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||
ICURVEPOVECTOR vCrvBez ;
|
||||
for( int c = 0 ; c < int( vCrv.size()) ; ++c){
|
||||
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
|
||||
if ( vCrv[c]->GetType() != CRV_BEZIER )
|
||||
pCC->AddCurve( CurveToBezierCurve( vCrv[c])) ;
|
||||
else
|
||||
pCC->AddCurve( vCrv[c]->Clone()) ;
|
||||
if ( IsNull( pCC) || ! pCC->IsValid())
|
||||
return nullptr ;
|
||||
vCrvBez.emplace_back( Release( pCC)) ;
|
||||
}
|
||||
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateBySetOfCurves( vCrvBez, true))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSbz) ;
|
||||
}
|
||||
+34
-1
@@ -17,12 +17,13 @@
|
||||
#include "SurfTriMesh.h"
|
||||
#include "SurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkSbzStandard.h"
|
||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
CreateBezierSphere( const Point3d& ptCenter, double dR)
|
||||
GetSurfBezierSphere( const Point3d& ptCenter, double dR)
|
||||
{
|
||||
// creo una superficie di Bezier di grado 2 con 45 punti di controllo
|
||||
PtrOwner<ISurfBezier> pSrfBez( CreateSurfBezier()) ;
|
||||
@@ -78,3 +79,35 @@ CreateBezierSphere( const Point3d& ptCenter, double dR)
|
||||
|
||||
return Release( pSrfBez) ;
|
||||
}
|
||||
|
||||
////-------------------------------------------------------------------------------
|
||||
//ISurfBezier*
|
||||
//GetSurfBezierCone( const Point3d& ptCenter, double dRadius, const Vector3d& dHeight)
|
||||
//{
|
||||
// // le dimensioni devono essere significative
|
||||
// if ( dRadius < EPS_SMALL || abs( dHeight) < EPS_SMALL)
|
||||
// return nullptr ;
|
||||
// // creo la circonferenza di base
|
||||
// CurveArc cArc ;
|
||||
// cArc.Set( ORIG, Z_AX, dRadius) ;
|
||||
// if ( dHeight < 0)
|
||||
// cArc.Invert() ;
|
||||
// // punto di vertice
|
||||
// Point3d ptTip( 0, 0, dHeight) ;
|
||||
// // creo la superficie laterale del cono
|
||||
// PtrOwner<ISurfBezier> pSbz( GetSurfBezierRuled( ptTip, &cArc)) ;
|
||||
// if ( IsNull( pSbz))
|
||||
// return nullptr ;
|
||||
//
|
||||
// //// creo la superficie di base e la inverto
|
||||
// //PtrOwner<ISurfTriMesh> pSTM1( GetSurfTriMeshByFlatContour( &cArc, dLinTol)) ;
|
||||
// //if ( IsNull( pSTM1))
|
||||
// // return nullptr ;
|
||||
// //pSTM1->Invert() ;
|
||||
// //// la unisco alla superficie del fianco
|
||||
// //if ( ! pSTM->DoSewing( *pSTM1))
|
||||
// // return nullptr ;
|
||||
//
|
||||
// // restituisco la superficie
|
||||
// return Release( pSbz) ;
|
||||
//}
|
||||
|
||||
+3
-1
@@ -88,6 +88,8 @@ SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
|
||||
}
|
||||
}
|
||||
break ;
|
||||
default :
|
||||
break ;
|
||||
}
|
||||
// per curva approssimata, sistemo...
|
||||
AdjustIntersParams( ( pCalcCrv != m_pCurve), pCalcCrv, vTmpPar) ;
|
||||
@@ -133,7 +135,7 @@ bool
|
||||
SelfIntersCurve::AdjustIntersParams( bool bAdjCrv, const ICurve* pCalcCrv, const DBLVECTOR& vCalcPar)
|
||||
{
|
||||
// se la curva originale non è stata approssimata o non ci sono auto-intersezioni, non va fatto alcunché
|
||||
if ( ! bAdjCrv || m_Info.size() == 0)
|
||||
if ( ! bAdjCrv || m_Info.empty())
|
||||
return true ;
|
||||
// procedo ad aggiustare
|
||||
for ( auto& aInfo : m_Info) {
|
||||
|
||||
+144
-32
@@ -115,7 +115,8 @@ GetSurfFlatRegionDisk( double dRadius)
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, double dOffsLinTol)
|
||||
GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, bool bSquareMids, double dOffsLinTol,
|
||||
bool bMergeOnlySameProps)
|
||||
{
|
||||
// metodo di calcolo impostato da USE_VORONOI
|
||||
|
||||
@@ -330,7 +331,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
||||
else {
|
||||
// calcolo la fat curve con Voronoi
|
||||
ICURVEPOVECTOR vFatCurves ;
|
||||
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids))
|
||||
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids, bMergeOnlySameProps))
|
||||
return nullptr ;
|
||||
|
||||
// costruisco la superficie a partire dalle curve
|
||||
@@ -367,25 +368,14 @@ GetSurfFlatRegionFromTriangle( const Triangle3d& Tria)
|
||||
ISurfFlatRegion*
|
||||
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
|
||||
{
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr))
|
||||
return nullptr ;
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( ContourPolyLine))
|
||||
return nullptr ;
|
||||
// Creo la regione.
|
||||
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
|
||||
if ( IsNull( pSfr) || ! pSfr->AddExtLoop( Release( pLoop)))
|
||||
return nullptr ;
|
||||
Point3d ptSt, ptEn ;
|
||||
bool bContinue = ContourPolyLine.GetFirstPoint( ptSt) &&
|
||||
ContourPolyLine.GetNextPoint( ptEn) ;
|
||||
while ( bContinue) {
|
||||
CurveLine cvLine ;
|
||||
cvLine.Set( ptSt, ptEn) ;
|
||||
pLoop->AddCurve( cvLine) ;
|
||||
ptSt = ptEn ;
|
||||
bContinue = ContourPolyLine.GetNextPoint( ptEn) ;
|
||||
}
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
@@ -401,25 +391,17 @@ GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
|
||||
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
|
||||
// Creo curva composita.
|
||||
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
|
||||
if ( IsNull( pLoop))
|
||||
if ( IsNull( pLoop) || ! pLoop->FromPolyLine( vContoursPolyLineVec[nL]))
|
||||
return nullptr ;
|
||||
Point3d ptSt, ptEn ;
|
||||
bool bContinue = vContoursPolyLineVec[nL].GetFirstPoint( ptSt) &&
|
||||
vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||
while ( bContinue) {
|
||||
CurveLine cvLine ;
|
||||
cvLine.Set( ptSt, ptEn) ;
|
||||
pLoop->AddCurve( cvLine) ;
|
||||
ptSt = ptEn ;
|
||||
bContinue = vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
|
||||
}
|
||||
// Loop esterno
|
||||
if ( nL == 0) {
|
||||
pSfr->AddExtLoop( Release( pLoop)) ;
|
||||
if ( ! pSfr->AddExtLoop( Release( pLoop)))
|
||||
return nullptr ;
|
||||
}
|
||||
// Loop interno
|
||||
else {
|
||||
pSfr->AddIntLoop( Release( pLoop)) ;
|
||||
if ( ! pSfr->AddIntLoop( Release( pLoop)))
|
||||
return nullptr ;
|
||||
}
|
||||
}
|
||||
return Release( pSfr) ;
|
||||
@@ -590,4 +572,134 @@ SurfFlatRegionByContours::GetUnusedCurveTempProps( INTVECTOR& vId)
|
||||
vId.push_back( pCrv->GetTempProp()) ;
|
||||
}
|
||||
return ( ! vId.empty()) ;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
CalcRegionPolyLines( const POLYLINEVECTOR& vPL, Vector3d& vtN, INTMATRIX& vnPLIndMat, BOOLVECTOR& vbInvert)
|
||||
{
|
||||
// vnPLIndMat : ogni riga corrisponde ad un chunk, in posizione 0 c'è il loop esterno e nelle successive i loop interni
|
||||
// vbInvert : riferito al vettore delle polyline, riporta true se la polyline è stata invertita
|
||||
|
||||
// ricavo versore normale
|
||||
Plane3d plPlane ; double dArea ;
|
||||
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
vtN = plPlane.GetVersN() ;
|
||||
|
||||
typedef std::pair<int,double> INDAREA ;
|
||||
std::vector<INDAREA> m_vArea ;
|
||||
// calcolo piano medio e area delle curve
|
||||
m_vArea.reserve( vPL.size()) ;
|
||||
VCT3DVECTOR vvtN ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN))
|
||||
return false ;
|
||||
// salvo la normale
|
||||
vvtN.push_back( plPlane.GetVersN()) ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.GetVersN() * vtN) > 0)
|
||||
m_vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
m_vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
// ordino in senso decrescente sull'area
|
||||
sort( m_vArea.begin(), m_vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||
|
||||
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||
Frame3d frRef ; frRef.Set( ORIG, vtN) ;
|
||||
if ( ! frRef.IsValid())
|
||||
return false ;
|
||||
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||
vCrvCompo[i]->ToLoc( frRef) ;
|
||||
}
|
||||
|
||||
// restituisco la normale del loop più grande
|
||||
bool bInvertAll = vvtN[m_vArea[0].first] * vtN < 0 ;
|
||||
vtN = vvtN[m_vArea[0].first] ;
|
||||
|
||||
//// vettore di indici per ordinare le PolyLine
|
||||
INTVECTOR vPL_IndOrder ; vPL_IndOrder.resize( int( vPL.size())) ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i)
|
||||
vPL_IndOrder[i] = m_vArea[i].first ;
|
||||
|
||||
// aggiungo le diverse curve
|
||||
bool bFirstCrv ;
|
||||
Plane3d plExtLoop ;
|
||||
double dAreaExtLoop = 0. ;
|
||||
vbInvert.resize( vPL.size()) ;
|
||||
fill( vbInvert.begin(), vbInvert.end(), false) ;
|
||||
do {
|
||||
bFirstCrv = true ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||
// recupero indice di percorso e verifico sia valido
|
||||
int j = m_vArea[i].first ;
|
||||
if ( j < 0)
|
||||
continue ;
|
||||
// lo inserisco come esterno...
|
||||
if ( bFirstCrv) {
|
||||
vnPLIndMat.push_back({ j}) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
dAreaExtLoop = m_vArea[i].second ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second < EPS_SMALL) {
|
||||
vCrvCompo[j]->Invert() ;
|
||||
dAreaExtLoop *= -1 ;
|
||||
vbInvert[j] = true ;
|
||||
}
|
||||
bFirstCrv = false ;
|
||||
}
|
||||
// ... altrimenti verifico se il loop è interno o no
|
||||
else {
|
||||
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||
// verifica rispetto loop esterno
|
||||
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// verifica rispetto ai loop interni
|
||||
bool bOk = true ;
|
||||
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bOk) {
|
||||
// inserisco nella matrice
|
||||
vnPLIndMat.back().push_back( j) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
||||
vCrvCompo[j]->Invert() ;
|
||||
vbInvert[j] = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( ! bFirstCrv) ;
|
||||
|
||||
if ( bInvertAll) {
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i)
|
||||
vbInvert[i] = ! vbInvert[i] ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+433
-239
@@ -31,10 +31,6 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static bool CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN) ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshByFlatContour( const ICurve* pCurve, double dLinTol)
|
||||
@@ -65,12 +61,25 @@ GetSurfTriMeshByRegion( const CICURVEPVECTOR& vpCurve, double dLinTol)
|
||||
return nullptr ;
|
||||
// calcolo le polilinee che approssimano le curve della regione
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
INTMATRIX vnPLIndMat ;
|
||||
BOOLVECTOR vbInvert ;
|
||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat, vbInvert))
|
||||
return nullptr ;
|
||||
for ( int i = 0 ; i < int( vnPLIndMat.size()) ; ++i) {
|
||||
for ( int j = 0 ; j < int( vnPLIndMat[i].size()) ; ++j){
|
||||
if( vbInvert[vnPLIndMat[i][j]])
|
||||
vPL[vnPLIndMat[i][j]].Invert() ;
|
||||
}
|
||||
}
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL, vnPLIndMat))
|
||||
return nullptr ;
|
||||
// salvo tolleranza lineare usata
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
@@ -145,9 +154,20 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
||||
return GetSurfTriMeshByExtrusion( vpCurve[0], vtExtr, true, dLinTol) ;
|
||||
// calcolo le polilinee che approssimano le curve della regione
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||
return nullptr ;
|
||||
}
|
||||
Vector3d vtN ;
|
||||
if ( ! CalcRegionPolyLines( vpCurve, dLinTol, vPL, vtN))
|
||||
INTMATRIX vnPLIndMat ;
|
||||
BOOLVECTOR vbInvert ;
|
||||
if ( ! CalcRegionPolyLines( vPL, vtN, vnPLIndMat, vbInvert))
|
||||
return nullptr ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++i) {
|
||||
if( vbInvert[i])
|
||||
vPL[i].Invert() ;
|
||||
}
|
||||
// verifico la direzione di estrusione
|
||||
double dOrthoExtr = vtN * vtExtr ;
|
||||
if ( ( abs( dOrthoExtr) < EPS_SMALL))
|
||||
@@ -159,7 +179,8 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
|
||||
}
|
||||
// creo la prima superficie di estremità
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL))
|
||||
// alla funzione CreateByRegion passo anche la matrice che contiene la struttura dei chunk. Le polyline hanno già il verso giusto
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByRegion( vPL, vnPLIndMat))
|
||||
return nullptr ;
|
||||
// creo la seconda superficie e la unisco alla prima
|
||||
{ // copio la prima superficie
|
||||
@@ -330,9 +351,11 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
{
|
||||
// verifico che la linea guida sia piana
|
||||
Plane3d plGuide ;
|
||||
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
||||
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
|
||||
return nullptr ;
|
||||
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
|
||||
if ( vtNorm.IsSmall())
|
||||
vtNorm = Z_AX ;
|
||||
// determino se la guida è chiusa
|
||||
bool bGuideClosed = pGuide->IsClosed() ;
|
||||
// curve di offset
|
||||
@@ -355,7 +378,7 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
||||
if ( IsNull( pSrfBot))
|
||||
return nullptr ;
|
||||
pSrfBot->Translate( -dDimV * vtNorm) ;
|
||||
pSrfBot->Translate( - dDimV * vtNorm) ;
|
||||
pSrfBot->Invert() ;
|
||||
PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
|
||||
if ( IsNull( pSrfRgt))
|
||||
@@ -365,74 +388,188 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide,
|
||||
if ( IsNull( pSrfLft))
|
||||
return nullptr ;
|
||||
// unisco le parti
|
||||
PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
||||
pSTM->DoSewing( *pSrfRgt) ;
|
||||
pSTM->DoSewing( *pSrfLft) ;
|
||||
pSTM->DoSewing( *pSrfBot) ;
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
int nBuckets = max( 2 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
||||
StmFromTriangleSoup stmSoup ;
|
||||
if ( ! stmSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
||||
stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
||||
PtrOwner<ISurfTriMesh> pSTM ;
|
||||
// se guida aperta e tappi piatti
|
||||
if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
POLYLINEVECTOR vPL ;
|
||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
return nullptr ;
|
||||
Plane3d plEnds ; double dArea ;
|
||||
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
||||
if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
return nullptr ;
|
||||
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
||||
if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
||||
return nullptr ;
|
||||
// aggiungo il cap sull'inizio
|
||||
// calcolo il cap sull'inizio
|
||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
// calcolo il cap sulla fine
|
||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
// cucio i tappi all'estrusione
|
||||
if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
|
||||
return nullptr ;
|
||||
}
|
||||
// se altrimenti guida aperta e tappi arrotondati
|
||||
if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// step di rotazione per rispettare la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ;
|
||||
pGuide->GetStartDir( vtStart) ;
|
||||
vtStart.Rotate( vtNorm, 0, 1) ;
|
||||
PolyLine PLStart ;
|
||||
PLStart.AddUPoint( 0, ptStart) ;
|
||||
PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ;
|
||||
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ;
|
||||
PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ;
|
||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
// se l'offset interno alla guida è chiuso
|
||||
if ( pCrvL->IsClosed()) {
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
|
||||
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
|
||||
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
|
||||
Point3d ptCenter = Media( ptRight, ptLeft) ;
|
||||
Vector3d vtRight = ptRight - ptCenter ;
|
||||
Vector3d vtLeft = ptLeft - ptCenter ;
|
||||
double dAng = ANG_STRAIGHT ;
|
||||
vtRight.GetAngle( vtLeft, dAng) ;
|
||||
vtRight.Normalize() ;
|
||||
PolyLine plLoop ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptRight) ; // primo punto
|
||||
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptRight ;
|
||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
|
||||
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
|
||||
// superificie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop) ;
|
||||
// superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
|
||||
pStmBottom->Translate( - dDimV * vtNorm) ;
|
||||
pStmBottom->Invert() ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom) ;
|
||||
// superificie perpendicolare
|
||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
|
||||
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp) || ! pStmPerp->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
||||
! pStmPerp->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp) ;
|
||||
}
|
||||
// se l'offset interno della guida è aperto...
|
||||
else {
|
||||
// aggiungo il cap sull'inizio
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
|
||||
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
|
||||
Vector3d vtLeft = ptSLeft - ptStart ;
|
||||
Vector3d vtRight = ptSRight - ptStart ;
|
||||
double dAng = ANG_STRAIGHT ;
|
||||
vtLeft.GetAngle( vtRight, dAng) ;
|
||||
vtLeft.Normalize() ;
|
||||
PolyLine plLoop ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
|
||||
double dAngStep = ceil( dAng / dStepRotDeg) ;
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSLeft ;
|
||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
|
||||
// creo la superficie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
|
||||
// superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
|
||||
pStmBottom_start->Translate( - dDimV * vtNorm) ;
|
||||
pStmBottom_start->Invert() ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
|
||||
// superificie perpendicolare
|
||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp_start) || ! pStmPerp_start->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
||||
! pStmPerp_start->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
pCrvL->GetEndPoint( ptSLeft) ;
|
||||
pCrvR->GetEndPoint( ptSRight) ;
|
||||
vtLeft = ptSLeft - ptEnd ;
|
||||
vtRight = ptSRight - ptEnd ;
|
||||
dAng = ANG_STRAIGHT ;
|
||||
vtRight.GetAngle( vtLeft, dAng) ;
|
||||
vtRight.Normalize() ;
|
||||
plLoop.Clear() ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptSRight) ;
|
||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSRight ;
|
||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
|
||||
// creo la superficie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
|
||||
// creo la superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom_end( CloneSurfTriMesh( pStmTop_end)) ;
|
||||
pStmBottom_end->Translate( - dDimV * vtNorm) ;
|
||||
pStmBottom_end->Invert() ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
|
||||
// creo la superificie perpendicolare alla guida
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp_end) || ! pStmPerp_end->CreateByExtrusion( plLoop, - vtNorm * dDimV) ||
|
||||
! pStmPerp_end->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
|
||||
}
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
pSTM->DoSewing( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
Vector3d vtEnd ;
|
||||
pGuide->GetEndDir( vtEnd) ;
|
||||
vtEnd.Rotate( vtNorm, 0, -1) ;
|
||||
PolyLine PLEnd ;
|
||||
PLEnd.AddUPoint( 0, ptEnd) ;
|
||||
PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ;
|
||||
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ;
|
||||
PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ;
|
||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
pSTM->DoSewing( *pSce) ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
else {
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
}
|
||||
// salvo tolleranza lineare usata e imposto angolo per smooth
|
||||
pSTM->SetLinearTolerance( dLinTol) ;
|
||||
pSTM->SetSmoothAngle( 20) ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
@@ -445,13 +582,13 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
|
||||
// verifico che la linea guida sia piana
|
||||
Plane3d plGuide ;
|
||||
if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
||||
if ( ! pGuide->IsFlat( plGuide, true, 10 * EPS_SMALL))
|
||||
return nullptr ;
|
||||
// assegno la normale del piano
|
||||
Vector3d vtNorm = plGuide.GetVersN() ;
|
||||
Vector3d vtNorm ; pGuide->GetExtrusion( vtNorm) ;
|
||||
if ( vtNorm.IsSmall())
|
||||
vtNorm = Z_AX ;
|
||||
// determino il punto centrale della sezione
|
||||
Point3d ptCen ;
|
||||
pGuide->GetStartPoint( ptCen) ;
|
||||
Point3d ptCen ; pGuide->GetStartPoint( ptCen) ;
|
||||
ptCen -= dDimV / 2 * vtNorm ;
|
||||
// determino se la guida è chiusa
|
||||
bool bGuideClosed = pGuide->IsClosed() ;
|
||||
@@ -480,7 +617,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
||||
bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
||||
}
|
||||
|
||||
if ( ! bOk ||
|
||||
vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
||||
vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
||||
@@ -549,10 +685,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
pSTM.Set( stmSoup.GetSurf()) ;
|
||||
// preparo seconda zuppa di triangoli per inserire i tappi
|
||||
StmFromTriangleSoup stmCapSoup ;
|
||||
if ( ! stmCapSoup.Start( nBuckets))
|
||||
return nullptr ;
|
||||
// verifico che le due estremità siano chiuse e piatte
|
||||
POLYLINEVECTOR vPL ;
|
||||
if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
||||
@@ -580,42 +712,236 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
||||
// step di rotazione per rispettare il tipo o la tolleranza
|
||||
double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
||||
// aggiungo il cap sull'inizio
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ;
|
||||
pGuide->GetStartDir( vtStart) ;
|
||||
vtStart.Rotate( vtNorm, 0, 1) ;
|
||||
PolyLine PLStart ;
|
||||
PLStart.AddUPoint( 0, ptStart) ;
|
||||
PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ;
|
||||
PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ;
|
||||
PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ;
|
||||
PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ;
|
||||
PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ;
|
||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
// se l'offset interno della guida è chiuso...
|
||||
if ( pCrvL->IsClosed()) {
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
Point3d ptRight ; pCrvR->GetEndPoint( ptRight) ;
|
||||
Point3d ptLeft ; pCrvR->GetStartPoint( ptLeft) ;
|
||||
Point3d ptJunction ; pCrvL->GetStartPoint( ptJunction) ;
|
||||
Point3d ptCenter = Media( ptRight, ptLeft) ;
|
||||
Vector3d vtRight = ptRight - ptCenter ;
|
||||
Vector3d vtLeft = ptLeft - ptCenter ;
|
||||
double dAng = ANG_STRAIGHT ;
|
||||
vtRight.GetAngle( vtLeft, dAng) ;
|
||||
vtRight.Normalize() ;
|
||||
PolyLine plLoop ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptRight) ; // primo punto
|
||||
double dAngStep = ceil( dAng / dStepRotDeg) ; // aggiusto lo step
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptRight ;
|
||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ; // punto intermedio sulla circonferenza
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep ++, ptLeft) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep ++, ptJunction) ; // punto centrale sull'offset chiuso
|
||||
plLoop.AddUPoint( dAngStep, ptRight) ; // polyLine chiusa
|
||||
// superificie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop) || ! pStmTop->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop) ;
|
||||
// superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom( CloneSurfTriMesh( pStmTop)) ;
|
||||
if ( IsNull( pStmBottom) || ! pStmBottom->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom) ;
|
||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
||||
// NB. Questo angolo va ricalcolato, il bevel è inclinato rispetto alla normale della guida
|
||||
ptCenter.Translate( - dBevelV * vtNorm) ;
|
||||
Point3d ptbRight ; pCrvRb->GetEndPoint( ptbRight) ;
|
||||
Point3d ptbLeft ; pCrvRb->GetStartPoint( ptbLeft) ;
|
||||
Vector3d vtbLeft = ptbLeft - ptCenter ;
|
||||
Vector3d vtbRight = ptbRight - ptCenter ;
|
||||
dAng = ANG_STRAIGHT ;
|
||||
vtbRight.GetAngle( vtbLeft, dAng) ;
|
||||
vtbRight.Normalize() ;
|
||||
// la PolyLine che utilizzo la posso ricavare da quella calcolata sopra
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
plLoop.EraseLastUPoint() ; // tolgo il punto di contatto sull'offset
|
||||
// creo il loop defininendo i punti
|
||||
PolyLine plLoopB ;
|
||||
plLoopB.AddUPoint( 0, ptbRight) ;
|
||||
dAngStep = ceil( dAng / dStepRotDeg) ;
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptbRight ;
|
||||
ptRot.Rotate( ptCenter, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoopB.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoopB.AddUPoint( dAngStep, ptbLeft) ;
|
||||
// creo la superficie Top Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmbTop_start) ||
|
||||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmbTop_start->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
|
||||
// creo la superificie Bottom Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
|
||||
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
|
||||
// creo la superficie perpendicolare alla guida
|
||||
PolyLine plLoopB1 = plLoopB ;
|
||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
||||
PtrOwner<ISurfTriMesh> pStmPerp( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp) ||
|
||||
! pStmPerp->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmPerp->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp) ;
|
||||
}
|
||||
// se l'offset interno della guida è aperto...
|
||||
else {
|
||||
// aggiungo il cap sull'inizio
|
||||
Point3d ptStart ;
|
||||
pGuide->GetStartPoint( ptStart) ;
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
Point3d ptSLeft ; pCrvL->GetStartPoint( ptSLeft) ;
|
||||
Point3d ptSRight ; pCrvR->GetStartPoint( ptSRight) ;
|
||||
Vector3d vtLeft = ptSLeft - ptStart ;
|
||||
Vector3d vtRight = ptSRight - ptStart ;
|
||||
double dAng = ANG_STRAIGHT ;
|
||||
vtLeft.GetAngle( vtRight, dAng) ;
|
||||
vtLeft.Normalize() ;
|
||||
PolyLine plLoop ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptSLeft) ; // primo punto
|
||||
double dAngStep = ceil( dAng / dStepRotDeg) ;
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSLeft ;
|
||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep, ptSRight) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep + 1, ptSLeft) ; // polyline chiusa
|
||||
// creo la superficie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop_start) || ! pStmTop_start->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop_start) ;
|
||||
// creo la superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom_start( CloneSurfTriMesh( pStmTop_start)) ;
|
||||
if ( IsNull( pStmBottom_start) || ! pStmBottom_start->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom_start) ;
|
||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
||||
ptStart.Translate( - dBevelV * vtNorm) ;
|
||||
Point3d ptSbLeft ; pCrvLb->GetStartPoint( ptSbLeft) ;
|
||||
Point3d ptSbRight ; pCrvRb->GetStartPoint( ptSbRight) ;
|
||||
Vector3d vtbLeft = ptSbLeft - ptStart ;
|
||||
Vector3d vtbRight = ptSbRight - ptStart ;
|
||||
dAng = ANG_STRAIGHT ;
|
||||
vtbLeft.GetAngle( vtbRight, dAng) ;
|
||||
vtbLeft.Normalize() ;
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
// creo il loop defininendo i punti
|
||||
PolyLine plLoopB ;
|
||||
plLoopB.AddUPoint( 0, ptSbLeft) ;
|
||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSbLeft ;
|
||||
ptRot.Rotate( ptStart, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoopB.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoopB.AddUPoint( dAngStep, ptSbRight) ; // ultimo punto
|
||||
// creo la superficie Top Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbTop_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmbTop_start) ||
|
||||
! pStmbTop_start->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmbTop_start->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbTop_start) ;
|
||||
// creo la superificie Bottom Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbBottom_start( CloneSurfTriMesh( pStmbTop_start)) ;
|
||||
if ( IsNull( pStmbBottom_start) || ! pStmbBottom_start->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbBottom_start) ;
|
||||
// creo la superficie perpendicolare alla guida
|
||||
PolyLine plLoopB1 = plLoopB ;
|
||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
||||
PtrOwner<ISurfTriMesh> pStmPerp_start( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp_start) ||
|
||||
! pStmPerp_start->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmPerp_start->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp_start) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
// calcolo l'angolo di rotazione per screwing faccia Top e Bottom
|
||||
pCrvL->GetEndPoint( ptSLeft) ;
|
||||
pCrvR->GetEndPoint( ptSRight) ;
|
||||
vtLeft = ptSLeft - ptEnd ;
|
||||
vtRight = ptSRight - ptEnd ;
|
||||
dAng = ANG_STRAIGHT ;
|
||||
vtRight.GetAngle( vtLeft, dAng) ;
|
||||
vtRight.Normalize() ;
|
||||
plLoop.Clear() ;
|
||||
// creo il loop defininendo i punti
|
||||
plLoop.AddUPoint( 0, ptSRight) ;
|
||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSRight ;
|
||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoop.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoop.AddUPoint( dAngStep, ptSLeft) ; // ultimo punto
|
||||
plLoop.AddUPoint( dAngStep + 1, ptSRight) ; // polyline chiusa
|
||||
// creo la superficie Top
|
||||
PtrOwner<ISurfTriMesh> pStmTop_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmTop_end) || ! pStmTop_end->CreateByFlatContour( plLoop))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmTop_end) ;
|
||||
// creo la superificie Bottom
|
||||
PtrOwner<ISurfTriMesh> pStmBottom_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmBottom_end) ||
|
||||
! pStmBottom_end->CopyFrom( pStmTop_end) ||
|
||||
! pStmBottom_end->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmBottom_end) ;
|
||||
// calcolo l'angolo di rotazione per la faccia Top del bevel
|
||||
ptEnd.Translate( - dBevelV * vtNorm) ;
|
||||
pCrvLb->GetEndPoint( ptSbLeft) ;
|
||||
pCrvRb->GetEndPoint( ptSbRight) ;
|
||||
vtbLeft = ptSbLeft - ptEnd ;
|
||||
vtbRight = ptSbRight - ptEnd ;
|
||||
dAng = ANG_STRAIGHT ;
|
||||
vtbRight.GetAngle( vtbLeft, dAng) ;
|
||||
vtbRight.Normalize() ;
|
||||
plLoop.EraseLastUPoint() ; // apro il loop
|
||||
// creo il loop defininendo i punti
|
||||
plLoopB.Clear() ;
|
||||
plLoopB.AddUPoint( 0, ptSbRight) ;
|
||||
dAngStep = ceil( dAng / dStepRotDeg) ; // primo punto
|
||||
for ( int i = 1 ; i < dAngStep ; ++ i) {
|
||||
Point3d ptRot = ptSbRight ;
|
||||
ptRot.Rotate( ptEnd, vtNorm, i * ( dAng / dAngStep)) ;
|
||||
plLoopB.AddUPoint( i, ptRot) ;
|
||||
}
|
||||
plLoopB.AddUPoint( dAngStep, ptSbLeft) ; // ultimo punto
|
||||
// creo la superficie Top Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbTop_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmbTop_end) ||
|
||||
! pStmbTop_end->CreateByTwoCurves( plLoop, plLoopB, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmbTop_end->Invert())
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbTop_end) ;
|
||||
// creo la superificie Bottom Bevel
|
||||
PtrOwner<ISurfTriMesh> pStmbBottom_end( CloneSurfTriMesh( pStmbTop_end)) ;
|
||||
if ( IsNull( pStmbBottom_end) || ! pStmbBottom_end->Mirror( ptCen, vtNorm))
|
||||
return nullptr ;
|
||||
stmSoup.AddSurfTriMesh( *pStmbBottom_end) ;
|
||||
// creo la superficie perpendicolare alla guida
|
||||
plLoopB1 = plLoopB ;
|
||||
plLoopB1.Mirror( ptCen, vtNorm) ;
|
||||
PtrOwner<ISurfTriMesh> pStmPerp_end( CreateSurfTriMesh()) ;
|
||||
if ( IsNull( pStmPerp_end) ||
|
||||
! pStmPerp_end->CreateByTwoCurves( plLoopB, plLoopB1, ISurfTriMesh::RLT_MINDIST) ||
|
||||
! pStmPerp_end->Invert())
|
||||
return nullptr ;
|
||||
pSci->Invert() ;
|
||||
stmSoup.AddSurfTriMesh( *pSci) ;
|
||||
// aggiungo il cap sulla fine
|
||||
Point3d ptEnd ;
|
||||
pGuide->GetEndPoint( ptEnd) ;
|
||||
Vector3d vtEnd ;
|
||||
pGuide->GetEndDir( vtEnd) ;
|
||||
vtEnd.Rotate( vtNorm, 0, -1) ;
|
||||
PolyLine PLEnd ;
|
||||
PLEnd.AddUPoint( 0, ptEnd) ;
|
||||
PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ;
|
||||
PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ;
|
||||
PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ;
|
||||
PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ;
|
||||
PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ;
|
||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
||||
return nullptr ;
|
||||
pSce->Invert() ;
|
||||
stmSoup.AddSurfTriMesh( *pSce) ;
|
||||
stmSoup.AddSurfTriMesh( *pStmPerp_end) ;
|
||||
}
|
||||
// completo unione e recupero la superficie risultante
|
||||
if ( ! stmSoup.End())
|
||||
return nullptr ;
|
||||
@@ -634,6 +960,7 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol)
|
||||
@@ -973,8 +1300,9 @@ GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, cons
|
||||
}
|
||||
}
|
||||
// creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
|
||||
PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
|
||||
if ( ! pSci->CreateByRegion( vPLi))
|
||||
PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
||||
INTMATRIX vnPLIndMat ;
|
||||
if ( ! pSci->CreateByRegion( vPLi, vnPLIndMat))
|
||||
return nullptr ;
|
||||
pStmSwept->DoSewing( *pSci) ;
|
||||
// recupero i loops alla fine
|
||||
@@ -982,8 +1310,9 @@ GetSurfTriMeshSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, cons
|
||||
if ( ! pStmSwept->GetLoops( vPLe))
|
||||
return nullptr ;
|
||||
// creo la superficie alla fine e la attacco
|
||||
PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
||||
if ( ! pSce->CreateByRegion( vPLe))
|
||||
PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
||||
vnPLIndMat.clear() ;
|
||||
if ( ! pSce->CreateByRegion( vPLe, vnPLIndMat))
|
||||
return nullptr ;
|
||||
// attacco la superficie finale alla swept
|
||||
pSce->Invert() ;
|
||||
@@ -1127,138 +1456,3 @@ GetSurfTriMeshRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, do
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
bool
|
||||
CalcRegionPolyLines( const CICURVEPVECTOR& vpCurve, double dLinTol,
|
||||
POLYLINEVECTOR& vPL, Vector3d& vtN)
|
||||
{
|
||||
// se non ho curve, non faccio nulla
|
||||
if ( int( vpCurve.size()) == 0)
|
||||
return true ;
|
||||
|
||||
// calcolo le polilinee che approssimano le curve
|
||||
vPL.resize( vpCurve.size()) ;
|
||||
for ( int i = 0 ; i < int( vpCurve.size()) ; ++ i) {
|
||||
if ( ! vpCurve[i]->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPL[i]))
|
||||
return false ;
|
||||
}
|
||||
|
||||
// ricavo versore normale
|
||||
Plane3d plPlane ; double dArea ;
|
||||
if ( ! vPL[0].IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL))
|
||||
return false ;
|
||||
vtN = plPlane.GetVersN() ;
|
||||
|
||||
typedef std::pair<int,double> INDAREA ;
|
||||
std::vector<INDAREA> m_vArea ;
|
||||
// calcolo piano medio e area delle curve
|
||||
m_vArea.reserve( vPL.size()) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
// calcolo piano medio e area
|
||||
Plane3d plPlane ;
|
||||
double dArea ;
|
||||
if ( ! vPL[i].IsClosedAndFlat( plPlane, dArea))
|
||||
return false ;
|
||||
// verifico che le normali siano molto vicine
|
||||
if ( ! AreSameOrOppositeVectorApprox( plPlane.GetVersN(), vtN))
|
||||
return false ;
|
||||
// assegno il segno all'area secondo il verso della normale
|
||||
if ( ( plPlane.GetVersN() * vtN) > 0)
|
||||
m_vArea.emplace_back( i, dArea) ;
|
||||
else
|
||||
m_vArea.emplace_back( i, - dArea) ;
|
||||
}
|
||||
// ordino in senso decrescente sull'area
|
||||
sort( m_vArea.begin(), m_vArea.end(),
|
||||
[]( const INDAREA& a, const INDAREA& b) { return ( abs( a.second) > abs( b.second)) ; }) ;
|
||||
|
||||
// dalle PolyLine passo alle curve nel piano XY ( prendo la prima come riferimento, trascuro le Z delle successive)
|
||||
Frame3d frRef ; frRef.Set( ORIG, vtN) ;
|
||||
if ( ! frRef.IsValid())
|
||||
return false ;
|
||||
ICRVCOMPOPOVECTOR vCrvCompo( int( vPL.size())) ;
|
||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||
vCrvCompo[i].Set( CreateCurveComposite()) ;
|
||||
vCrvCompo[i]->FromPolyLine( vPL[i]) ;
|
||||
vCrvCompo[i]->ToLoc( frRef) ;
|
||||
}
|
||||
|
||||
// creo una matrice di interi ; ogni riga corrisponde ad un chunk, dove in posizione 0 c'è il loop esterno e nelle
|
||||
// successive i loop interni
|
||||
INTMATRIX vnPLIndMat ;
|
||||
|
||||
// vettore di indici per ordinare le PolyLine
|
||||
INTVECTOR vPL_IndOrder ; vPL_IndOrder.resize( int( vPL.size())) ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i)
|
||||
vPL_IndOrder[i] = m_vArea[i].first ;
|
||||
|
||||
// aggiungo le diverse curve
|
||||
bool bFirstCrv ;
|
||||
Plane3d plExtLoop ;
|
||||
double dAreaExtLoop = 0. ;
|
||||
do {
|
||||
bFirstCrv = true ;
|
||||
for ( int i = 0 ; i < int( m_vArea.size()) ; ++ i) {
|
||||
// recupero indice di percorso e verifico sia valido
|
||||
int j = m_vArea[i].first ;
|
||||
if ( j < 0)
|
||||
continue ;
|
||||
// lo inserisco come esterno...
|
||||
if ( bFirstCrv) {
|
||||
vnPLIndMat.push_back({ j}) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
dAreaExtLoop = m_vArea[i].second ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second < EPS_SMALL) {
|
||||
vPL[j].Invert() ;
|
||||
vCrvCompo[j]->Invert() ;
|
||||
dAreaExtLoop *= -1 ;
|
||||
}
|
||||
bFirstCrv = false ;
|
||||
}
|
||||
// ... altrimenti verifico se il loop è interno o no
|
||||
else {
|
||||
// il loop è interno se è sia interno al loop esterno della riga di vnPLIndMat e allo stesso tempo
|
||||
// esterno a tutti i loop già inseriti nella riga attuale.
|
||||
// verifica rispetto loop esterno
|
||||
IntersCurveCurve ccInt( *vCrvCompo[vnPLIndMat.back().front()], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass ;
|
||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt.GetCurveClassification( 1, EPS_SMALL, ccClass) ||
|
||||
ccClass.empty() || ccClass[0].nClass != CRVC_IN)
|
||||
continue ;
|
||||
// verifica rispetto ai loop interni
|
||||
bool bOk = true ;
|
||||
for ( int k = 1 ; k < int( vnPLIndMat.back().size()) ; ++ k) {
|
||||
IntersCurveCurve ccInt2( *vCrvCompo[vnPLIndMat.back()[k]], *vCrvCompo[j]) ;
|
||||
CRVCVECTOR ccClass2 ;
|
||||
if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 ||
|
||||
! ccInt2.GetCurveClassification( 1, EPS_SMALL, ccClass2) ||
|
||||
ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) {
|
||||
bOk = false ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bOk) {
|
||||
// inserisco nella matrice
|
||||
vnPLIndMat.back().push_back( j) ;
|
||||
m_vArea[i].first = -1 ;
|
||||
// inverto se necessario
|
||||
if ( m_vArea[i].second * dAreaExtLoop > 0.) {
|
||||
vPL[j].Invert() ;
|
||||
vCrvCompo[j]->Invert() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ( ! bFirstCrv) ;
|
||||
|
||||
// ordino le PolyLine per area
|
||||
POLYLINEVECTOR vPL_tmp ;
|
||||
for ( int i = 0 ; i < int( vPL_IndOrder.size()) ; ++ i)
|
||||
vPL_tmp.push_back( vPL[ vPL_IndOrder[i]]) ;
|
||||
swap( vPL, vPL_tmp) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
+123
-6
@@ -22,6 +22,18 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshEmpty( void)
|
||||
{
|
||||
// creo oggetto con superficie vuota
|
||||
PtrOwner<SurfTriMesh> pStm( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pStm) || ! pStm->AdjustTopology())
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pStm) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
static SurfTriMesh*
|
||||
GetStandardSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
|
||||
@@ -160,15 +172,15 @@ GetSurfTriMeshPyramid( double dDimX, double dDimY, double dHeight)
|
||||
return nullptr ;
|
||||
// creo la polilinea del contorno della base
|
||||
PolyLine PL ;
|
||||
PL.AddUPoint( 0, ORIG) ;
|
||||
PL.AddUPoint( 1, Point3d( dDimX, 0, 0)) ;
|
||||
PL.AddUPoint( 2, Point3d( dDimX, dDimY, 0)) ;
|
||||
PL.AddUPoint( 3, Point3d( 0, dDimY, 0)) ;
|
||||
PL.AddUPoint( 4, ORIG) ;
|
||||
PL.AddUPoint( 0, Point3d( -dDimX / 2, -dDimY / 2, 0)) ;
|
||||
PL.AddUPoint( 1, Point3d( dDimX / 2, -dDimY / 2, 0)) ;
|
||||
PL.AddUPoint( 2, Point3d( dDimX / 2, dDimY / 2, 0)) ;
|
||||
PL.AddUPoint( 3, Point3d( -dDimX / 2, dDimY / 2, 0)) ;
|
||||
PL.AddUPoint( 4, Point3d( -dDimX / 2, -dDimY / 2, 0)) ;
|
||||
if ( dHeight < 0)
|
||||
PL.Invert() ;
|
||||
// punto di vertice
|
||||
Point3d ptTip( 0.5 * dDimX, 0.5 * dDimY, dHeight) ;
|
||||
Point3d ptTip( 0, 0, dHeight) ;
|
||||
// creo e setto la superficie trimesh laterale
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByPointCurve( ptTip, PL))
|
||||
@@ -245,6 +257,111 @@ GetSurfTriMeshSphere( double dRadius, double dLinTol)
|
||||
return GetSurfTriMeshByRevolve( &cArc, ORIG, Z_AX, true, dLinTol) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshPyramidFrustum( double dBaseDimX, double dBaseDimY, double dTopDimX, double dTopDimY, double dHeight)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( ( min( dBaseDimX, dBaseDimY) < EPS_SMALL && min( dTopDimX, dTopDimY) < EPS_SMALL) || abs( dHeight) < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// se piramide
|
||||
if ( min( dTopDimX, dTopDimY) < EPS_SMALL)
|
||||
return GetSurfTriMeshPyramid( dBaseDimX, dBaseDimY, dHeight) ;
|
||||
// se piramide inversa
|
||||
if ( min( dBaseDimX, dBaseDimY) < EPS_SMALL)
|
||||
return GetSurfTriMeshPyramid( dTopDimX, dTopDimY, -dHeight) ;
|
||||
// se parallelepipedo
|
||||
// continuo qui per avere l'origine in centro e non sullo spigolo in basso a sinistra
|
||||
// creo la polilinea del contorno della base
|
||||
PolyLine PL1 ;
|
||||
PL1.AddUPoint( 0, Point3d( -dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
||||
PL1.AddUPoint( 1, Point3d( dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
||||
PL1.AddUPoint( 2, Point3d( dBaseDimX / 2 , dBaseDimY / 2, 0)) ;
|
||||
PL1.AddUPoint( 3, Point3d( -dBaseDimX / 2, dBaseDimY / 2, 0)) ;
|
||||
PL1.AddUPoint( 4, Point3d( -dBaseDimX / 2, -dBaseDimY / 2, 0)) ;
|
||||
if ( dHeight < 0)
|
||||
PL1.Invert() ;
|
||||
// creo la polilinea del contorno di sopra
|
||||
PolyLine PL2 ;
|
||||
PL2.AddUPoint( 0, Point3d( -dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
||||
PL2.AddUPoint( 1, Point3d( dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
||||
PL2.AddUPoint( 2, Point3d( dTopDimX / 2, dTopDimY / 2, dHeight)) ;
|
||||
PL2.AddUPoint( 3, Point3d( -dTopDimX / 2, dTopDimY / 2, dHeight)) ;
|
||||
PL2.AddUPoint( 4, Point3d( -dTopDimX / 2, -dTopDimY / 2, dHeight)) ;
|
||||
if ( dHeight < 0)
|
||||
PL2.Invert() ;
|
||||
// creo e setto la superficie trimesh laterale
|
||||
PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pSTM) || ! pSTM->CreateByTwoCurves( PL1, PL2, ISurfTriMesh::RLT_ISOPAR_SMOOTH))
|
||||
return nullptr ;
|
||||
// creo la superficie di base e ne inverto la normale
|
||||
SurfTriMesh STM1 ;
|
||||
if ( ! STM1.CreateByFlatContour( PL1))
|
||||
return nullptr ;
|
||||
STM1.Invert() ;
|
||||
// la unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( STM1))
|
||||
return nullptr ;
|
||||
// creo la superficie sopra
|
||||
SurfTriMesh STM2 ;
|
||||
if ( ! STM2.CreateByFlatContour( PL2))
|
||||
return nullptr ;
|
||||
// la unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( STM2))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshConeFrustum( double dBaseRad, double dTopRad, double dHeight, double dLinTol)
|
||||
{
|
||||
// le dimensioni devono essere significative
|
||||
if ( ( dBaseRad < EPS_SMALL && dTopRad < EPS_SMALL) || abs( dHeight) < EPS_SMALL)
|
||||
return nullptr ;
|
||||
// se cono
|
||||
if ( dTopRad < EPS_SMALL)
|
||||
return GetSurfTriMeshCone( dBaseRad, dHeight, dLinTol) ;
|
||||
// se cono rovescio
|
||||
if ( dBaseRad < EPS_SMALL)
|
||||
return GetSurfTriMeshCone( dTopRad, -dHeight, dLinTol) ;
|
||||
// se cilindro
|
||||
if ( abs( dTopRad - dBaseRad) < EPS_SMALL)
|
||||
return GetSurfTriMeshCylinder( dBaseRad, dHeight, dLinTol) ;
|
||||
// creo la circonferenza sotto
|
||||
CurveArc cArc1 ;
|
||||
cArc1.Set( ORIG, Z_AX, dBaseRad) ;
|
||||
if ( dHeight < 0)
|
||||
cArc1.Invert() ;
|
||||
// creo la circonferenza sopra
|
||||
CurveArc cArc2 ;
|
||||
cArc2.Set( Point3d( 0, 0, dHeight), Z_AX, dTopRad) ;
|
||||
if ( dHeight < 0)
|
||||
cArc2.Invert() ;
|
||||
// creo la superficie laterale del cono
|
||||
PtrOwner<ISurfTriMesh> pSTM( GetSurfTriMeshRuled( &cArc1, &cArc2, ISurfTriMesh::RLT_ISOPAR_SMOOTH, dLinTol)) ;
|
||||
if ( IsNull( pSTM))
|
||||
return nullptr ;
|
||||
// creo la superficie sotto e la inverto
|
||||
PtrOwner<ISurfTriMesh> pSTM1( GetSurfTriMeshByFlatContour( &cArc1, dLinTol)) ;
|
||||
if ( IsNull( pSTM1))
|
||||
return nullptr ;
|
||||
pSTM1->Invert() ;
|
||||
// la unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( *pSTM1))
|
||||
return nullptr ;
|
||||
// creo la superficie sopra
|
||||
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMeshByFlatContour( &cArc2, dLinTol)) ;
|
||||
if ( IsNull( pSTM2))
|
||||
return nullptr ;
|
||||
// la unisco alla superficie del fianco
|
||||
if ( ! pSTM->DoSewing( *pSTM2))
|
||||
return nullptr ;
|
||||
// restituisco la superficie
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfTriMesh*
|
||||
GetSurfTriMeshPlaneInBox( const Plane3d& plPlane, const BBox3d& b3Box, bool bOnEq, bool bOnCt)
|
||||
|
||||
+41
-12
@@ -45,6 +45,7 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.bRat = snData.bRat ;
|
||||
nuCurve.nDeg = snData.nDegU ;
|
||||
nuCurve.vU = vU ;
|
||||
// vettore dei punti di controllo
|
||||
@@ -62,13 +63,24 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
|
||||
if ( snData.mCP.size() != nuCurve.vCP.size() ) {
|
||||
snData.mCP.resize( nuCurve.vCP.size()) ;
|
||||
if( snData.bRat)
|
||||
snData.mW.resize( nuCurve.vW.size()) ;
|
||||
}
|
||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||
if( snData.bRat) {
|
||||
snData.mW[i][j] = nuCurve.vW[i] ;
|
||||
snData.mCP[i][j] *= nuCurve.vW[i] ;
|
||||
}
|
||||
}
|
||||
snData.vU = nuCurve.vU ;
|
||||
}
|
||||
snData.vU = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicU = false ;
|
||||
snData.nCPU = int( snData.mCP.size()) ;
|
||||
}
|
||||
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
||||
bool bIsRational = snData.bRat ;
|
||||
@@ -82,6 +94,7 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||
CNurbsData nuCurve ;
|
||||
nuCurve.bPeriodic = true ;
|
||||
nuCurve.bRat = snData.bRat ;
|
||||
nuCurve.nDeg = snData.nDegV ;
|
||||
nuCurve.vU = vV ;
|
||||
// vettore dei punti di controllo
|
||||
@@ -99,15 +112,29 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
||||
nuCurve.vCP = vPtCtrl ;
|
||||
nuCurve.vW = vWeCtrl ;
|
||||
// i punti dell' oggetto nuCurve devono essere in forma non omogenea
|
||||
NurbsCurveCanonicalize( nuCurve) ;
|
||||
for ( int j = 0 ; j < snData.nCPV ; ++j ) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||
if ( NurbsCurveCanonicalize( nuCurve)) { // se NurbsCurveCanonicalize ha restituito false (la curva potrebbe esserre un punto di polo) allora non modifico i punti e il vettore dei nodi della superficie
|
||||
if ( snData.mCP[i].size() != nuCurve.vCP.size()){
|
||||
snData.mCP[i].clear() ;
|
||||
snData.mCP[i].resize( nuCurve.vCP.size()) ;
|
||||
if ( snData.bRat ) {
|
||||
snData.mW[i].clear() ;
|
||||
snData.mW[i].resize( nuCurve.vW.size()) ;
|
||||
}
|
||||
}
|
||||
for ( int j = 0 ; j < int( nuCurve.vCP.size()) ; ++j ) {
|
||||
snData.mCP[i][j] = nuCurve.vCP[j] ;
|
||||
if ( snData.bRat ) {
|
||||
snData.mW[i][j] = nuCurve.vW[j] ;
|
||||
snData.mCP[i][j] *= nuCurve.vW[j] ;
|
||||
}
|
||||
}
|
||||
snData.vV = nuCurve.vU ;
|
||||
}
|
||||
snData.vV = nuCurve.vU ;
|
||||
}
|
||||
snData.bPeriodicV = false ;
|
||||
snData.nCPV = int( snData.mCP[0].size()) ;
|
||||
}
|
||||
return true;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -604,7 +631,7 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
||||
pSfr_copy->Translate( vtJoin) ;
|
||||
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
|
||||
if ( bRetry)
|
||||
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_FILLET) ; // OFFSET
|
||||
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET
|
||||
if ( pRescaledSfr->IsValid()) {
|
||||
if ( ! pRescaledSfr->Add( *pSfr_copy))
|
||||
return false ;
|
||||
@@ -617,7 +644,8 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
||||
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
||||
if ( pRescaledSfr->IsValid()) {
|
||||
if ( bRetry)
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; //contro OFFSET
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET
|
||||
delete pSfr ;
|
||||
pSfr = Release( pRescaledSfr) ;
|
||||
}
|
||||
}
|
||||
@@ -628,7 +656,8 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
||||
|
||||
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
||||
if ( bRetry)
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_FILLET) ; // contro OFFSET
|
||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
|
||||
delete pSfr ;
|
||||
pSfr = Release( pRescaledSfr) ;
|
||||
}
|
||||
|
||||
|
||||
+2739
-519
File diff suppressed because it is too large
Load Diff
+60
-36
@@ -22,9 +22,6 @@
|
||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
|
||||
using namespace std ;
|
||||
class Tree ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
{
|
||||
@@ -69,13 +66,16 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
public : // ISurf
|
||||
bool IsSimple( void) const override
|
||||
{ return true ; }
|
||||
bool IsClosed( void) const override
|
||||
{ return false ; }
|
||||
bool IsClosed( void) const override ;
|
||||
bool GetArea( double& dArea) const override ;
|
||||
bool GetVolume( double& dVolume) const override
|
||||
{ if ( &dVolume == nullptr)
|
||||
return false ;
|
||||
if ( m_pSTM == nullptr)
|
||||
GetAuxSurf() ;
|
||||
dVolume = 0 ;
|
||||
if ( m_pSTM != nullptr)
|
||||
m_pSTM->GetVolume( dVolume) ;
|
||||
return true ; }
|
||||
bool GetCentroid( Point3d& ptCen) const override ;
|
||||
bool Invert( void) override ;
|
||||
@@ -99,6 +99,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
{ return GetControlWeight( GetInd( nIndU, nIndV), pbOk) ; }
|
||||
double GetControlWeight( int nInd, bool* pbOk) const override ;
|
||||
bool IsAPoint( void) const override ;
|
||||
bool GetPoint( double dU, double dV, Side nUs, Side nVs, Point3d& ptPos) const override ;
|
||||
bool GetPointD1D2( double dU, double dV, Side nUs, Side nVs,
|
||||
Point3d& ptPos,
|
||||
Vector3d* pvtDerU = nullptr, Vector3d* pvtDerV = nullptr,
|
||||
@@ -109,35 +110,43 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
Vector3d* pvtDerUU = nullptr, Vector3d* pvtDerVV = nullptr, Vector3d* pvtDerUV = nullptr) const override ;
|
||||
CurveComposite* GetCurveOnU( double dV) const override ;
|
||||
CurveComposite* GetCurveOnV( double dU) const override ;
|
||||
CurveComposite* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni)
|
||||
CurveComposite* GetLoop( int nLoop) const override ; // nLoop 0-based (1°esterno, successivi interni)
|
||||
bool GetControlCurveOnU( int nIndV, PolyLine& plCtrlU) const override ;
|
||||
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||
const SurfTriMesh* GetAuxSurfRefined( void) const override ;
|
||||
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL) const override ;
|
||||
// funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione.
|
||||
bool GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves) const override ;
|
||||
bool GetTriangles2D( std::vector<std::tuple<int,Point3d, Point3d, Point3d>>& vTria2D) const override ;
|
||||
// funzioni che servono per ricavare l'immagine nel parametrico di un punto appartenente alla trimesh ausiliaria della superficie di Bezier
|
||||
// a nIL si può passare 5 come valore di default
|
||||
// a nIL si può passare 5 come valore di default
|
||||
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL = 5) const override ;
|
||||
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL, const Point3d& ptIPrev, bool* bTroughEdge = nullptr) const override ;
|
||||
// restituisce il corrispettivo parametrico di un punto qualunque della trimesh associata alla superficie
|
||||
// ptIPrev è un punto addizionale che precede o segue il punto pt3D nel caso in cui il punto faccia parte di una curva 3d sulla superficie
|
||||
// pPlCut è il piano di taglio su cui dovrebbe giacere il punto raffinato
|
||||
// ptIPrev è un punto addizionale che precede o segue il punto pt3D nel caso in cui il punto faccia parte di una curva 3d sulla superficie
|
||||
// pPlCut è il piano di taglio su cui dovrebbe giacere il punto raffinato
|
||||
bool UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d& ptIPrev, bool* bTroughEdge = nullptr, const Plane3d* plCut = nullptr) const override ;
|
||||
// pPlCut è il piano di taglio su cui giace la curva
|
||||
// pPlCut è il piano di taglio su cui giace la curva
|
||||
bool UnprojectCurveFromStm( const ICurveComposite* pCC, ICRVCOMPOPVECTOR& vpCC, const Plane3d* pPlCut) const override ;
|
||||
// funzione per tagliare una superficie di bezier con un piano ( cancello la parte dal lato positivo della normale del piano).
|
||||
// bSaveOnEq indica se tenere i triangoli (della trimesh associata) che sono sul piano
|
||||
bool Cut( const Plane3d& plPlane, bool bSaveOnEq = false) override ;
|
||||
// funzione che calcola se gli edge sono collassati in poli. DEVE ESSERE STATA CHIAMATA PRIMA DI UN CUT
|
||||
bool CalcPoles( void) override ;
|
||||
// funzioni per incrementare le coordinate restando dentro lo spazio parametrico
|
||||
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
|
||||
bool IncreaseUV( Point3d& ptUV, Vector3d vtH , Point3d* ptUVCopy, bool bModifyOrig) const override ;
|
||||
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
|
||||
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
|
||||
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
|
||||
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
|
||||
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ; // se la superficie non è trimmata restituisce un vettore di 4 elementi. Se la superficie è chiusa lungo un parametro i lati algi estremi di quel parametro saranno null.
|
||||
bool IsPlanar( void) const override ;
|
||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
||||
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
||||
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, bool bDeg3OrDeg2 = false) override ;
|
||||
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) override ;
|
||||
bool CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
|
||||
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
||||
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
||||
PNTVECTOR GetAllControlPoints( void) const ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -149,7 +158,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
|
||||
public :
|
||||
SurfBezier( void) ;
|
||||
SurfBezier( const SurfBezier& sbSrc)
|
||||
SurfBezier( const SurfBezier& sbSrc) : m_pSTM( nullptr), m_pSTMRefined( nullptr), m_pTrimReg(nullptr)
|
||||
{ if ( ! CopyFrom( sbSrc))
|
||||
LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") }
|
||||
SurfBezier& operator =( const SurfBezier& sbSrc)
|
||||
@@ -160,7 +169,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
private :
|
||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||
enum ParDir { ON_U = 1, ON_V = 2} ;
|
||||
static const int MAXDEG = 11 ;
|
||||
static const int MAXDEG = 21 ;
|
||||
|
||||
private :
|
||||
bool CopyFrom( const SurfBezier& sbSrc) ;
|
||||
@@ -190,30 +199,45 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
double GetCurveOnVApproxLen( double dU) const ;
|
||||
// funzione che proietta nello spazio parametrico un trim derivante da un taglio con un piano, categorizzandolo come aperto o chiuso ( nel parametrico)
|
||||
bool AddCurveCompoToCuts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed, double dToler = EPS_SMALL, const Plane3d* pPlCut = nullptr) const ;
|
||||
ISurfFlatRegion* CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed) const ;
|
||||
// restituisce il singolo edge della superficie non trimmata
|
||||
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
|
||||
bool UpdateEdgesFromTree( Tree& tr) const ;
|
||||
// funzione che calcola se gli edge sono collassati in poli
|
||||
bool CalcPoles( void) const ;
|
||||
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
|
||||
bool ReorderPntVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
|
||||
bool ReorderPntEnhancedVector( const POLYLINEVECTOR& vPL, bool bTriangulatedIn3D, const PNTVECTOR& vPnt, const POLYLINEVECTOR& vPLToOrd, PNTVECTOR& vPntOrd) const ;
|
||||
bool GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const ;
|
||||
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria
|
||||
Status m_nStatus ; // stato
|
||||
int m_nDegU ; // grado in U
|
||||
int m_nDegV ; // grado in V
|
||||
int m_nSpanU ; // numero di pezze in U
|
||||
int m_nSpanV ; // numero di pezze in V
|
||||
bool m_bRat ; // flag di razionale/polinomiale
|
||||
bool m_bTrimmed ; // flag per presenza regione di trim
|
||||
mutable bool m_bClosedU ; // flag che indica se la superficie è chiusa lungo il parametro U
|
||||
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V
|
||||
mutable BOOLVECTOR m_vbPole ; // vettore di flag che indicano se i lati sono collassati in dei poli
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable vector<ICRVCOMPOPOVECTOR> m_mCCEdge ;// vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
|
||||
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria per la visualizzazione
|
||||
mutable SurfTriMesh* m_pSTMRefined ; // superficie trimesh ausiliaria raffinata per i calcoli
|
||||
Status m_nStatus ; // stato
|
||||
int m_nDegU ; // grado in U
|
||||
int m_nDegV ; // grado in V
|
||||
int m_nSpanU ; // numero di pezze in U
|
||||
int m_nSpanV ; // numero di pezze in V
|
||||
bool m_bRat ; // flag di razionale/polinomiale
|
||||
bool m_bTrimmed ; // flag per presenza regione di trim
|
||||
mutable bool m_bClosedU ; // flag che indica se la superficie è chiusa lungo il parametro U
|
||||
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V
|
||||
mutable BOOLVECTOR m_vbPole ; // vettore di flag che indicano se i lati sono collassati in dei poli
|
||||
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
mutable std::vector<ICRVCOMPOPOVECTOR> m_mCCEdge ; // vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
|
||||
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
|
||||
mutable int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
|
||||
mutable DBLVECTOR m_vBernU ;
|
||||
mutable PNTVECTOR m_ptTemp ;
|
||||
mutable DBLVECTOR m_vBernV ;
|
||||
mutable PNTVECTOR m_ptTempW ;
|
||||
mutable DBLVECTOR m_dTempW ;
|
||||
mutable PNTVECTOR m_vPtWCtrlLoc ;
|
||||
mutable DBLVECTOR m_vWeCtrlLoc ;
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+299
-29
@@ -109,18 +109,25 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||
return false ;
|
||||
// aggiungo le singole curve
|
||||
int nExtAdded = 0 ;
|
||||
bool bOk = true ;
|
||||
for ( auto& pSingCrv : CrvLst) {
|
||||
if ( ! AddSimpleExtLoop( pSingCrv))
|
||||
bool bAdded = false ;
|
||||
if ( AddSimpleExtLoop( pSingCrv, bAdded))
|
||||
++ nExtAdded ;
|
||||
else
|
||||
bOk = false ;
|
||||
|
||||
}
|
||||
return bOk ;
|
||||
return ( bOk && nExtAdded > 0) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
||||
{
|
||||
// default
|
||||
bAdded = false ;
|
||||
// acquisisco la curva
|
||||
PtrOwner<ICurve> pMyCrv( pCrv) ;
|
||||
if ( IsNull( pMyCrv))
|
||||
@@ -133,8 +140,10 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
Plane3d plPlane ;
|
||||
if ( ! pMyCrv->GetArea( plPlane, dArea))
|
||||
return false ;
|
||||
if ( dArea < SQ_EPS_SMALL)
|
||||
return true ;
|
||||
// se sto costruendo il primo chunk
|
||||
if ( m_vExtInd.size() == 0) {
|
||||
if ( m_vExtInd.empty()) {
|
||||
// assegno il riferimento intrinseco
|
||||
if ( ! m_frF.Set( ORIG + plPlane.GetVersN() * plPlane.GetDist(), plPlane.GetVersN()))
|
||||
return false ;
|
||||
@@ -198,6 +207,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv)
|
||||
m_OGrMgr.Reset() ;
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
bAdded = true ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -547,7 +557,7 @@ SurfFlatRegion::Load( NgeReader& ngeIn)
|
||||
string sName ;
|
||||
int j ;
|
||||
bool bOk = ngeIn.ReadString( sName, ";") &&
|
||||
FromString( sName.substr(2), j) && i == j ;
|
||||
FromString( sName.substr( 2), j) && i == j ;
|
||||
int nChunk = 0, nLoop = 0 ;
|
||||
bOk = ngeIn.ReadInt( nChunk, ",") &&
|
||||
ngeIn.ReadInt( nLoop, ";", true) ;
|
||||
@@ -817,7 +827,7 @@ SurfFlatRegion::ConvertArcsToBezierCurves( void)
|
||||
// ciclo sui loop
|
||||
for ( auto& pLoop : m_vpLoop) {
|
||||
if ( pLoop->GetType() == CRV_ARC) {
|
||||
ICurve* pCrvNew = ArcToBezierCurve( pLoop) ;
|
||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc(pLoop)) ;
|
||||
if ( pCrvNew == nullptr)
|
||||
return false ;
|
||||
delete pLoop ;
|
||||
@@ -912,9 +922,6 @@ SurfFlatRegion::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
||||
bool
|
||||
SurfFlatRegion::GetArea( double& dArea) const
|
||||
{
|
||||
// controllo parametro di ritorno
|
||||
if ( &dArea == nullptr)
|
||||
return false ;
|
||||
// inizio con area nulla
|
||||
dArea = 0 ;
|
||||
// la regione deve essere validata
|
||||
@@ -937,9 +944,6 @@ SurfFlatRegion::GetArea( double& dArea) const
|
||||
bool
|
||||
SurfFlatRegion::GetGrossArea( double& dArea) const
|
||||
{
|
||||
// controllo parametro di ritorno
|
||||
if ( &dArea == nullptr)
|
||||
return false ;
|
||||
// inizio con area nulla
|
||||
dArea = 0 ;
|
||||
// la regione deve essere validata
|
||||
@@ -963,9 +967,6 @@ SurfFlatRegion::GetGrossArea( double& dArea) const
|
||||
bool
|
||||
SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
||||
{
|
||||
// controllo parametro di ritorno
|
||||
if ( &ptCen == nullptr)
|
||||
return false ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
@@ -991,13 +992,20 @@ SurfFlatRegion::GetCentroid( Point3d& ptCen) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetChunkCount( void) const
|
||||
{
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return 0 ;
|
||||
return int( m_vExtInd.size()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const
|
||||
{
|
||||
// controllo parametro di ritorno
|
||||
if ( &ptCen == nullptr)
|
||||
return false ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
@@ -1011,13 +1019,53 @@ SurfFlatRegion::GetChunkCentroid( int nChunk, Point3d& ptCen) const
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetChunkCount( void) const
|
||||
bool
|
||||
SurfFlatRegion::GetChunkArea( int nChunk, double& dArea) const
|
||||
{
|
||||
// default, area nulla
|
||||
dArea = 0 ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK)
|
||||
return 0 ;
|
||||
return int( m_vExtInd.size()) ;
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// il chunk deve esistere
|
||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
||||
return false ;
|
||||
// calcolo l'area
|
||||
bool bOk = true ;
|
||||
for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) {
|
||||
const ICurve* pLoop = GetMyLoop( nChunk, nL) ;
|
||||
double dLoopArea ;
|
||||
if ( pLoop != nullptr && pLoop->GetAreaXY( dLoopArea))
|
||||
dArea += dLoopArea ;
|
||||
else
|
||||
bOk = false ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetChunkPerimeter( int nChunk, double& dLen) const
|
||||
{
|
||||
// default, perimetro nullo
|
||||
dLen = 0 ;
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// il chunk deve esistere
|
||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
||||
return false ;
|
||||
// calcolo il perimetro
|
||||
bool bOk = true ;
|
||||
for ( int nL = 0 ; nL < GetLoopCount( nChunk) ; ++ nL) {
|
||||
const ICurve* pLoop = GetMyLoop( nChunk, nL) ;
|
||||
double dLoopLen ;
|
||||
if ( pLoop != nullptr && pLoop->GetLength( dLoopLen))
|
||||
dLen += dLoopLen ;
|
||||
else
|
||||
bOk = false ;
|
||||
}
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -1118,6 +1166,19 @@ SurfFlatRegion::GetLoop( int nChunk, int nLoop) const
|
||||
return pCrv ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
int
|
||||
SurfFlatRegion::GetLoopCurveCount( int nChunk, int nLoop) const
|
||||
{
|
||||
// recupero il loop nel riferimento intrinseco
|
||||
const ICurve* pMyCrv = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pMyCrv == nullptr)
|
||||
return 0 ;
|
||||
// restituisco il numero di curve di cui è composto
|
||||
const ICurveComposite* pMyCompo = GetCurveComposite( pMyCrv) ;
|
||||
return ( pMyCompo == nullptr ? 1 : pMyCompo->GetCurveCount()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const
|
||||
@@ -1149,21 +1210,26 @@ SurfFlatRegion::CalcAuxSurf( double dLinTol, double dAngTolDeg) const
|
||||
for ( int i = 0 ; i < GetChunkCount() ; ++ i) {
|
||||
// calcolo le polilinee che approssimano i loop
|
||||
POLYLINEVECTOR vPL ;
|
||||
vPL.resize( GetLoopCount( i)) ;
|
||||
vPL.reserve( GetLoopCount( i)) ;
|
||||
int j = 0 ;
|
||||
ICurve* pLoop = GetMyLoop( i, j) ;
|
||||
ICurve* pLoop = GetMyLoop( i, j) ;
|
||||
while ( pLoop != nullptr) {
|
||||
// approssimo con linee a destra per non avere problemi in punti di contatto tra esterni e interni
|
||||
if ( ! pLoop->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_RIGHT, vPL[j]))
|
||||
vPL.emplace_back( PolyLine()) ;
|
||||
if ( ! pLoop->ApproxWithLines( dLinTol, dAngTolDeg, ICurve::APL_RIGHT, vPL.back()))
|
||||
return nullptr ;
|
||||
double dLoopArea ;
|
||||
if ( ! vPL.back().GetAreaXY( dLoopArea) || abs( dLoopArea) <= 25 * SQ_EPS_SMALL)
|
||||
vPL.pop_back() ;
|
||||
pLoop = GetMyLoop( i, ++j) ;
|
||||
}
|
||||
// se chunk abbastanza grande, creo la superficie trimesh relativa
|
||||
double dArea ;
|
||||
if ( vPL[0].GetAreaXY( dArea) && dArea > 100 * SQ_EPS_SMALL) {
|
||||
if ( ! vPL.empty() && vPL[0].GetAreaXY( dArea) && dArea > 25 * SQ_EPS_SMALL) {
|
||||
// creo, setto la superficie trimesh ed elimino punti ripetuti
|
||||
PtrOwner<SurfTriMesh> pChSTM( CreateBasicSurfTriMesh()) ;
|
||||
if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL) || ! pChSTM->DoCompacting())
|
||||
INTMATRIX vnPLIndMat ;
|
||||
if ( IsNull( pChSTM) || ! pChSTM->CreateByRegion( vPL, vnPLIndMat) || ! pChSTM->DoCompacting())
|
||||
return nullptr ;
|
||||
// porto la trimesh in globale al riferimento intrinseco
|
||||
pChSTM->ToGlob( m_frF) ;
|
||||
@@ -1171,7 +1237,10 @@ SurfFlatRegion::CalcAuxSurf( double dLinTol, double dAngTolDeg) const
|
||||
pSTM->DoSewing( *pChSTM) ;
|
||||
}
|
||||
}
|
||||
// la restituisco
|
||||
// se vuota
|
||||
if ( pSTM->IsEmpty())
|
||||
pSTM->AdjustTopology() ;
|
||||
// la restituisco
|
||||
return Release( pSTM) ;
|
||||
}
|
||||
|
||||
@@ -1226,6 +1295,56 @@ SurfFlatRegion::CloneChunk( int nChunk) const
|
||||
return Release( pSfr) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::EraseChunk(int nChunk)
|
||||
{
|
||||
// la regione deve essere validata
|
||||
if ( m_nStatus != OK || m_vpLoop.empty())
|
||||
return false ;
|
||||
// il chunk deve esistere
|
||||
if ( nChunk < 0 || nChunk >= GetChunkCount())
|
||||
return false ;
|
||||
// se un solo chunk, resetto la regione
|
||||
if ( GetChunkCount() == 1) {
|
||||
Clear() ;
|
||||
return true ;
|
||||
}
|
||||
// se ultimo chunk
|
||||
if ( nChunk == m_vExtInd.size() - 1) {
|
||||
// elimino i loop
|
||||
for ( int i = m_vExtInd[nChunk] ; i < int( m_vpLoop.size()) ; ++ i) {
|
||||
delete m_vpLoop[i] ;
|
||||
m_vpLoop[i] = nullptr ;
|
||||
}
|
||||
m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.end()) ;
|
||||
// elimino indice di loop esterno
|
||||
m_vExtInd.pop_back() ;
|
||||
}
|
||||
// altrimenti
|
||||
else {
|
||||
// numero di loop da eliminare
|
||||
int nLoopCnt = m_vExtInd[nChunk+1] - m_vExtInd[nChunk] ;
|
||||
// elimino i loop
|
||||
for ( int i = m_vExtInd[nChunk] ; i < m_vExtInd[nChunk+1] ; ++ i) {
|
||||
delete m_vpLoop[i] ;
|
||||
m_vpLoop[i] = nullptr ;
|
||||
}
|
||||
m_vpLoop.erase( m_vpLoop.begin() + m_vExtInd[nChunk], m_vpLoop.begin() + m_vExtInd[nChunk+1]) ;
|
||||
// elimino indice di loop esterno
|
||||
m_vExtInd.erase( m_vExtInd.begin() + nChunk) ;
|
||||
// aggiorno indice inizio chunk successivi
|
||||
for ( int i = nChunk ; i < int( m_vExtInd.size()) ; ++i)
|
||||
m_vExtInd[i] -= nLoopCnt ;
|
||||
}
|
||||
// imposto ricalcolo della grafica
|
||||
m_OGrMgr.Reset() ;
|
||||
ResetAuxSurf() ;
|
||||
// imposto ricalcolo Voronoi
|
||||
ResetVoronoiObject() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const
|
||||
@@ -1480,3 +1599,154 @@ SurfFlatRegion::CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const
|
||||
|
||||
return m_pVoronoiObj->CalcMedialAxis( vCrvs, nSide) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetChunkMaxOffset( int nChunk, double& dOffs) const
|
||||
{
|
||||
// verifico se è stato calcolato Voronoi
|
||||
if ( m_pVoronoiObj == nullptr)
|
||||
if ( ! CalcVoronoiObject())
|
||||
return false ;
|
||||
|
||||
// il massimo offset per il chunk è il massimo offset del suo loop esterno
|
||||
// ( il diagramma di Voronoi tiene già conto della limitazione con i loop interni)
|
||||
int nInd = GetIndFromChunkLoop( nChunk, 0) ;
|
||||
return m_pVoronoiObj->CalcLimitOffset( nInd, true, dOffs) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetMaxOffset( double& dOffs) const
|
||||
{
|
||||
int nChunks = GetChunkCount() ;
|
||||
if ( nChunks == 0)
|
||||
return false ;
|
||||
|
||||
// calcolo il massimo fra gli offset limite di tutti i suoi chunks
|
||||
if ( ! GetChunkMaxOffset( 0, dOffs))
|
||||
return false ;
|
||||
for ( int i = 1 ; i < nChunks ; i++) {
|
||||
double dCurrOffs ;
|
||||
if ( ! GetChunkMaxOffset( i, dCurrOffs))
|
||||
return false ;
|
||||
if ( dCurrOffs > dOffs)
|
||||
dOffs = dCurrOffs ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd)
|
||||
{
|
||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pLoop == nullptr)
|
||||
return false ;
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
if ( nCrv != 0)
|
||||
return false ;
|
||||
pLoop->SetTempProp( nProp, nPropInd) ;
|
||||
return true ;
|
||||
}
|
||||
return GetBasicCurveComposite( pLoop)->SetCurveTempProp( nCrv, nProp, nPropInd) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd) const
|
||||
{
|
||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pLoop == nullptr)
|
||||
return false ;
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
if ( nCrv != 0)
|
||||
return false ;
|
||||
nProp = pLoop->GetTempProp( nPropInd) ;
|
||||
return true ;
|
||||
}
|
||||
return GetBasicCurveComposite( pLoop)->GetCurveTempProp( nCrv, nProp, nPropInd) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::ResetAllCurveTempProps( void)
|
||||
{
|
||||
for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) {
|
||||
ICurve* pLoop = GetMyLoop( nC, nL) ;
|
||||
if ( pLoop != nullptr) {
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
pLoop->SetTempProp( 0, 0) ;
|
||||
pLoop->SetTempProp( 0, 1) ;
|
||||
}
|
||||
else {
|
||||
CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ;
|
||||
for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) {
|
||||
pCompoLoop->SetCurveTempProp( nI, 0, 0) ;
|
||||
pCompoLoop->SetCurveTempProp( nI, 0, 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd)
|
||||
{
|
||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pLoop == nullptr)
|
||||
return false ;
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
if ( nCrv != 0)
|
||||
return false ;
|
||||
pLoop->SetTempParam( dParam, nParamInd) ;
|
||||
return true ;
|
||||
}
|
||||
return GetBasicCurveComposite( pLoop)->SetCurveTempParam( nCrv, dParam, nParamInd) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dParam, int nParamInd) const
|
||||
{
|
||||
ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||
if ( pLoop == nullptr)
|
||||
return false ;
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
if ( nCrv != 0)
|
||||
return false ;
|
||||
dParam = pLoop->GetTempParam( nParamInd) ;
|
||||
return true ;
|
||||
}
|
||||
return GetBasicCurveComposite( pLoop)->GetCurveTempParam( nCrv, dParam, nParamInd) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfFlatRegion::ResetAllCurveTempParams( void)
|
||||
{
|
||||
for ( int nC = 0 ; nC < GetChunkCount() ; ++ nC) {
|
||||
for ( int nL = 0 ; nL < GetLoopCount( nC) ; ++ nL) {
|
||||
ICurve* pLoop = GetMyLoop( nC, nL) ;
|
||||
if ( pLoop != nullptr) {
|
||||
if ( pLoop->GetType() != CRV_COMPO) {
|
||||
pLoop->SetTempParam( 0, 0) ;
|
||||
pLoop->SetTempParam( 0, 1) ;
|
||||
}
|
||||
else {
|
||||
CurveComposite* pCompoLoop = GetBasicCurveComposite( pLoop) ;
|
||||
for ( int nI = 0 ; nI < pCompoLoop->GetCurveCount() ; ++ nI) {
|
||||
pCompoLoop->SetCurveTempParam( nI, 0, 0) ;
|
||||
pCompoLoop->SetCurveTempParam( nI, 0, 1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
+21
-9
@@ -94,18 +94,30 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
{ return m_frF.Orig() ; }
|
||||
const Vector3d& GetNormVersor( void) const override
|
||||
{ return m_frF.VersZ() ; }
|
||||
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ;
|
||||
void ResetVoronoiObject( void) const override ;
|
||||
bool GetMaxOffset( double& dOffs) const override ;
|
||||
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ;
|
||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
||||
int GetChunkCount( void) const override ;
|
||||
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
||||
bool EraseChunk(int nChunk) override ;
|
||||
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
||||
bool GetChunkArea( int nChunk, double& dArea) const override ;
|
||||
bool GetChunkPerimeter( int nChunk, double& dLen) const override ;
|
||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||
bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ;
|
||||
int GetLoopCount( int nChunk) const override ;
|
||||
int GetLoopCurveCount( int nChunk, int nLoop) const override ;
|
||||
ICurve* GetLoop( int nChunk, int nLoop) const override ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni)
|
||||
bool ApproxLoopWithLines( int nChunk, int nLoop, double dLinTol, double dAngTolDeg, int nType, PolyLine& PL) const override ;
|
||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||
SurfFlatRegion* CloneChunk( int nChunk) const override ;
|
||||
bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ;
|
||||
bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ;
|
||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||
bool CalcVoronoiDiagram( ICURVEPOVECTOR& vCrvs, int nBound = 3) const override ;
|
||||
bool CalcMedialAxis( ICURVEPOVECTOR& vCrvs, int nSide) const override ;
|
||||
void ResetVoronoiObject( void) const override ;
|
||||
bool SetCurveTempProp( int nChunk, int nLoop, int nCrv, int nProp, int nPropInd = 0) override ;
|
||||
bool GetCurveTempProp( int nChunk, int nLoop, int nCrv, int& nProp, int nPropInd = 0) const override ;
|
||||
bool ResetAllCurveTempProps( void) override ;
|
||||
bool SetCurveTempParam( int nChunk, int nLoop, int nCrv, double dParam, int nParamInd = 0) override ;
|
||||
bool GetCurveTempParam( int nChunk, int nLoop, int nCrv, double& dParam, int nParamInd = 0) const override ;
|
||||
bool ResetAllCurveTempParams( void) override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
@@ -136,7 +148,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
||||
|
||||
private :
|
||||
bool CopyFrom( const SurfFlatRegion& clSrc) ;
|
||||
bool AddSimpleExtLoop( ICurve* pCrv) ;
|
||||
bool AddSimpleExtLoop( ICurve* pCrv, bool& bAdded) ;
|
||||
bool MyAddExtLoop( ICurve* pCrv) ;
|
||||
bool AddSimpleIntLoop( ICurve* pCrv) ;
|
||||
bool MyAddIntLoop( ICurve* pCrv, int nChunk) ;
|
||||
|
||||
@@ -168,7 +168,7 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
|
||||
|
||||
// creo una nuova regione a partire da questi loop
|
||||
PtrOwner<SurfFlatRegion> pSfr ;
|
||||
if ( vpLoop.size() == 0)
|
||||
if ( vpLoop.empty())
|
||||
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
||||
else
|
||||
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
||||
@@ -258,7 +258,7 @@ SurfFlatRegion::Intersect( const ISurfFlatRegion& Other)
|
||||
|
||||
// creo una nuova regione a partire da questi loop
|
||||
PtrOwner<SurfFlatRegion> pSfr ;
|
||||
if ( vpLoop.size() == 0)
|
||||
if ( vpLoop.empty())
|
||||
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
||||
else
|
||||
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
||||
|
||||
@@ -148,7 +148,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
||||
return nullptr ;
|
||||
|
||||
// costruisco la superficie
|
||||
if ( vOffs.size() > 0) {
|
||||
if ( ! vOffs.empty()) {
|
||||
PCRV_DEQUE vLoops ;
|
||||
for ( int i = 0 ; i < int( vOffs.size()) ; i ++) {
|
||||
vOffs[i]->ToLoc( m_frF) ;
|
||||
@@ -162,7 +162,7 @@ SurfFlatRegion::CreateOffsetSurf( double dDist, int nType) const
|
||||
}
|
||||
|
||||
// verifico di avere ancora dei loops
|
||||
if ( vLoops.size() > 0) {
|
||||
if ( ! vLoops.empty()) {
|
||||
pSfr.Set( MyNewSurfFromLoops( vLoops)) ;
|
||||
if ( IsNull( pSfr)) {
|
||||
MyTestAndDelete( vLoops) ;
|
||||
|
||||
+880
-91
File diff suppressed because it is too large
Load Diff
+64
-21
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2014-2023
|
||||
// EgalTech 2014-2025
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMesh.h Data : 09.12.23 Versione : 2.5l2
|
||||
// File : SurfTriMesh.h Data : 28.03.25 Versione : 2.7c4
|
||||
// Contenuto : Dichiarazione della classe Superficie TriMesh.
|
||||
//
|
||||
//
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "GeoObjRW.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
||||
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||
#include <deque>
|
||||
#include <set>
|
||||
|
||||
@@ -52,16 +53,16 @@ class StmTria
|
||||
public :
|
||||
StmTria( void)
|
||||
: nIdVert{ SVT_NULL, SVT_NULL, SVT_NULL}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
||||
StmTria( const int nIdV[3])
|
||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( 0), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
||||
StmTria( const int nIdV[3], int nTF)
|
||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ SVT_NULL, SVT_NULL, SVT_NULL}, nETempFlag{ 0, 0, 0},
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( 0), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||
vtN(), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( 0), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
||||
StmTria( const int nIdV[3], const int nIdA[3], const Vector3d& vtV, int nTF, int nEF)
|
||||
: nIdVert{ nIdV[0], nIdV[1], nIdV[2]}, nIdAdjac{ nIdA[0], nIdA[1], nIdA[2]}, nETempFlag{ 0, 0, 0},
|
||||
vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nPart( SVT_NULL), nTemp( 0), nTempPart{ 0} {}
|
||||
vtN( vtV), nIdFacet( SVT_NULL), nTFlag( nTF), nEFlag( nEF), nShell( SVT_NULL), nTemp( 0), nTempShell{ 0} {}
|
||||
public :
|
||||
int nIdVert[3] ;
|
||||
int nIdAdjac[3] ;
|
||||
@@ -70,9 +71,25 @@ class StmTria
|
||||
int nIdFacet ;
|
||||
int nTFlag ;
|
||||
int nEFlag ;
|
||||
mutable int nPart ;
|
||||
mutable int nShell ;
|
||||
mutable int nTemp ;
|
||||
mutable int nTempPart ;
|
||||
mutable int nTempShell ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Classe Part
|
||||
class StmPart
|
||||
{
|
||||
public :
|
||||
StmPart( void)
|
||||
: bClosed( false) {}
|
||||
StmPart( bool bClo, const INTVECTOR& vSh)
|
||||
: bClosed( bClo), vShell( vSh) {}
|
||||
int GetShellCount( void)
|
||||
{ return ( vShell.empty() ? 0 : int( vShell.size()) - ( vShell[0] == -1 ? 1 : 0)) ; }
|
||||
public :
|
||||
bool bClosed ;
|
||||
INTVECTOR vShell ;
|
||||
} ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -235,7 +252,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool RemoveTriangle( int nId) override ;
|
||||
bool AdjustTopology( void) override ;
|
||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
||||
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
||||
bool CreateByPolygonWithHoles( const POLYLINEVECTOR& vPL) override ;
|
||||
bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) override ;
|
||||
bool CreateByPointCurve( const Point3d& ptP, const PolyLine& PL) override ;
|
||||
bool CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2, int nRuledType) override ;
|
||||
@@ -279,6 +296,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
SurfTriMesh* CloneTriangle( int nT) const override ;
|
||||
bool GetLoops( POLYLINEVECTOR& vPL) const override ;
|
||||
bool GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ;
|
||||
bool GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR& vPL, bool bAllTria = false) const override ;
|
||||
int GetFacetCount( void) const override ;
|
||||
int GetFacetSize( void) const override
|
||||
{ return int( m_vFacet.size()) ; }
|
||||
@@ -310,14 +328,25 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool Intersect( const ISurfTriMesh& Other) override ;
|
||||
bool Subtract( const ISurfTriMesh& Other) override ;
|
||||
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
||||
INTVECTOR& vTriaIn, INTVECTOR& vTriaOut, INTVECTOR& vTriaOnP, INTVECTOR& vTriaOnM, INTVECTOR& vTriaIndef) override ;
|
||||
bool CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
||||
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
||||
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
||||
const BBox3d& GetAllTriaBox( void) const override ;
|
||||
int GetPartCount( void) const override ;
|
||||
int GetShellCount( void) const override ;
|
||||
bool GetShellArea( int nShell, double& dArea) const override ;
|
||||
bool RemoveShell( int nShell) override ;
|
||||
SurfTriMesh* CloneShell( int nShell) const override ;
|
||||
bool GetPartLocalBBox( int nP, BBox3d& b3Loc) const override ;
|
||||
bool GetPartBBox( int nP, const Frame3d& frRef, BBox3d& b3Ref) const override ;
|
||||
int GetPartCount( void) const override ;
|
||||
bool RemovePart( int nPart) override ;
|
||||
bool GetPartArea( int nPart, double& dArea) const override ;
|
||||
bool GetPartVolume( int nPart, double& dVolume) const override ;
|
||||
bool GetPartLoops( int nPart, POLYLINEVECTOR& vPL) const override ;
|
||||
SurfTriMesh* ClonePart( int nPart) const override ;
|
||||
bool SetTFlag( int nId, int nTFlag) override ;
|
||||
bool GetTFlag( int nId, int& nFlag) const override ;
|
||||
int GetMaxTFlag( void) const override
|
||||
{ return m_nMaxTFlag ; }
|
||||
bool ResetTFlags( void) override ;
|
||||
@@ -340,18 +369,20 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
LOG_ERROR( GetEGkLogger(), "SurfTriMesh : copy error")
|
||||
return *this ; }
|
||||
bool Clear( void) ;
|
||||
bool CreateByRegion( const POLYLINEVECTOR& vPL, const INTMATRIX& vnPLIndMat) ;
|
||||
bool ExistsTriangle( int nT) const
|
||||
{ return ( nT >= 0 && nT < GetTriangleSize() && m_vTria[nT].nIdVert[0] != SVT_DEL) ; }
|
||||
bool GetTriangleAdjacencies( int nId, int nIdAdjTriaId[3]) const ;
|
||||
bool GetTFlag( int nId, int& nFlag) const ;
|
||||
bool GetTempInt( int nId, int& nTempInt) const ;
|
||||
bool ResetTempInts( void) const ;
|
||||
bool SetTFlag( int nId, int nTFlag) ;
|
||||
bool SetTempInt( int nId, int nTempInt) const ;
|
||||
bool AddTriaFromZMap( const TRIA3DEXVECTOR& vTria, PointGrid3d& VertGrid, double dVertexTol = 2 * EPS_SMALL) ;
|
||||
bool AdjustTopologyFromZMap( void) ;
|
||||
|
||||
private :
|
||||
typedef std::vector<StmVert> VERTVECTOR ;
|
||||
typedef std::vector<StmTria> TRIAVECTOR ;
|
||||
typedef std::vector<StmPart> PARTVECTOR ;
|
||||
typedef std::vector<StmFacEdge> FACEDGEVECTOR ;
|
||||
typedef std::deque<Stm3Int> TRINTDEQUE ;
|
||||
|
||||
@@ -362,7 +393,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool CopyFrom( const SurfTriMesh& clSrc) ;
|
||||
bool Validate( bool bCorrect = false) ;
|
||||
bool AdjustVertices( void) ;
|
||||
bool AdjustAdjacencies( void) ;
|
||||
bool AdjustAdjacencies( bool AdjustVert = true) ;
|
||||
bool AdjustOrientations( void) ;
|
||||
bool AdjustTriaOrientation( TRINTDEQUE& S3iQ) ;
|
||||
bool TestSealing( void) ;
|
||||
@@ -396,23 +427,27 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool UpdateFacetEdging( void) ;
|
||||
void ResetHashGrids3d( void) const ;
|
||||
bool VerifyHashGrids3d( void) const ;
|
||||
bool VerifyConnection( void) const ;
|
||||
bool VerifyConnection( bool bShellsAndParts = true) const ;
|
||||
bool IsShellClosed( int nShell) const ;
|
||||
bool IsPartClosed( int nPart) const ;
|
||||
bool CutTriangleByPlane( int nTriaId, const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||
bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ;
|
||||
bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ;
|
||||
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
|
||||
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
|
||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||
bool IdentifyParts( void) const ;
|
||||
bool IdentifyShells( void) const ;
|
||||
bool RemoveDoubleTriangles( bool& bModified) ;
|
||||
bool RemoveTJunctions( bool& bModified) ;
|
||||
bool RemoveTJunctions( bool& bModified, double dMinSqDist = SQ_EPS_TRIA_H) ;
|
||||
bool FlipTriangles( int nTA, int nTB) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen = MAX_EDGE_LEN_STD, bool bForced = true, double dTolAlign = 50 * EPS_SMALL) ;
|
||||
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||
bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) ;
|
||||
|
||||
bool AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, double dTolAlign, bool& bModif) const ;
|
||||
bool RemoveInvalidTriangles( const INTVECTOR& vIds) ;
|
||||
bool FindAdjacentOnLongerEdge( int nT, int& nEdge, int& nAdjTrg) const ;
|
||||
private :
|
||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||
Status m_nStatus ; // stato
|
||||
@@ -434,9 +469,10 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||
int m_nMaxTFlag ; // massimo valore dei TFlag dei triangoli
|
||||
mutable int m_nParts ; // numero di parti connesse (-1 se da calcolare)
|
||||
mutable int m_nShells ; // numero di gusci connessi (-1 se da calcolare)
|
||||
mutable PARTVECTOR m_vPart ; // vettore delle parti (flag chiusura e elenco shell, prima sempre esterna o infinita)
|
||||
mutable HashGrids3d* m_pHGrd3d ; // Hash Grid 3d nel suo riferimento
|
||||
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
|
||||
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
|
||||
} ;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -454,3 +490,10 @@ inline SurfTriMesh* GetBasicSurfTriMesh( IGeoObj* pGObj)
|
||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
||||
return nullptr ;
|
||||
return ( static_cast<SurfTriMesh*>( pGObj)) ; }
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Raccolte di puntatori a SurfTriMesh
|
||||
typedef std::vector<const SurfTriMesh*> CISRFTMPVECTOR ; // vettore di puntatori a const SurfTriMesh
|
||||
typedef std::vector<SurfTriMesh*> ISRFTMPVECTOR ; // vettore di puntatori a SurfTriMesh
|
||||
typedef std::list<SurfTriMesh*> ISRFTMPLIST ; // lista di puntatori a SurfTriMesh
|
||||
typedef std::vector<PtrOwner<SurfTriMesh>> ISRFTMPOVECTOR ; // vettore di puntatori esclusivi a SurfTriMesh
|
||||
|
||||
+286
-389
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user