Compare commits
528 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f47402215 | |||
| 55e2983991 | |||
| 7c85ea2d43 | |||
| 1c49379ee1 | |||
| 481d81a8d2 | |||
| 68e25e10e8 | |||
| 88410333e9 | |||
| 6bbedc812f | |||
| 4e6dd05aa9 | |||
| a5684b2bf3 | |||
| 119bbe0bcb | |||
| 35b903e8a0 | |||
| 979597084d | |||
| 02742ee80f | |||
| a2bcc4d682 | |||
| cbd487e4ff | |||
| 37aaa98df6 | |||
| 2dcaa57aa3 | |||
| ba7379e752 | |||
| 6646aee01c | |||
| 7f8382f1b8 | |||
| 4bcdb03598 | |||
| 68e9be7901 | |||
| 9e3bac4a68 | |||
| 1fee7b8e49 | |||
| f668d7ac11 | |||
| 4a1c13154f | |||
| 68a9848748 | |||
| f5059166ed | |||
| ad7f209fc9 | |||
| 8b5bfb6e19 | |||
| 1efd17f6ee | |||
| b8caeb49e0 | |||
| a9fc259745 | |||
| bbc98fe282 | |||
| a445ddd89b | |||
| e874b2eb36 | |||
| a45faa4793 | |||
| 344f0da7ff | |||
| cea869c6ee | |||
| 8ad2887c38 | |||
| 2b1d2a512d | |||
| a55770d702 | |||
| 2e4b1cdd40 | |||
| 3ffc0b40d8 | |||
| cd2cde40da | |||
| efc656a72c | |||
| e1eb139aee | |||
| e7d25b2d0e | |||
| ce05ce577c | |||
| ae2cac48d1 | |||
| 37e9a05347 | |||
| 02cb8a0d3c | |||
| 6942f5fc23 | |||
| 6c4bf3f05a | |||
| 4bc8590ce9 | |||
| 5b68e33d1f | |||
| a70f7ee9c9 | |||
| 95a070413a | |||
| 223489e80d | |||
| f6a535d94c | |||
| dbc3e7d2bf | |||
| a3d44261bb | |||
| 9220fd568f | |||
| 17346e1b42 | |||
| c95ef6764d | |||
| d0f2d56bdb | |||
| fb037f2f2a | |||
| 2d94dddccb | |||
| d2d025a594 | |||
| 64abf640f6 | |||
| cb2b63320a | |||
| 951d3781d6 | |||
| 27bd0e579e | |||
| ff7d564de8 | |||
| a27b9e871a | |||
| eb497cbd39 | |||
| dd3091fc13 | |||
| 69d463713c | |||
| 5e918ff3aa | |||
| b4522c712d | |||
| fa9a9e89cb | |||
| d51a0d2258 | |||
| 580230b38b | |||
| 4b24906d2e | |||
| 2094a1cc0d | |||
| b8b639699a | |||
| 0b86c4f72b | |||
| 5c93384690 | |||
| b77db4a5bc | |||
| c704d94829 | |||
| 0373021b7a | |||
| 6de856b3e1 | |||
| a231d8f26c | |||
| 745a7eb38c | |||
| 78c40ebca7 | |||
| a39af1c3a3 | |||
| c2a0f9dff1 | |||
| 6be67258d2 | |||
| 6c76943bf4 | |||
| 9306f5be9d | |||
| 944ce79776 | |||
| 313c735956 | |||
| 007ed1701c | |||
| 7385709bb4 | |||
| da4cd4c482 | |||
| dee744725c | |||
| 2aca943de4 | |||
| 25f6bae120 | |||
| c92d841011 | |||
| 398c8c430a | |||
| 79dc8f8fc2 | |||
| 1545bc07cd | |||
| 44edef378a | |||
| 679efc22e8 | |||
| 1076dc54dc | |||
| e091f253d0 | |||
| 3206961b88 | |||
| 48b2029d19 | |||
| a2ca0ac6f7 | |||
| 4155dd3e5a | |||
| 5a3b7e311c | |||
| 991586a880 | |||
| de4165889a | |||
| 42c5ffb014 | |||
| e394615f84 | |||
| 1008ba4229 | |||
| f4328430b9 | |||
| 1d6bc847da | |||
| d76beb09ee | |||
| 026436b914 | |||
| ebc5fd7ee7 | |||
| 82a211753e | |||
| a258e9cb31 | |||
| 157885f71a | |||
| f227a9cba7 | |||
| 39360eefd7 | |||
| 6b5fb15c9b | |||
| 4e698d4049 | |||
| e20bd7fd0c | |||
| 7e62acf351 | |||
| 421bc2eb3b | |||
| db98fa5d5a | |||
| 5f28258d16 | |||
| 8f06488b33 | |||
| ac7ba1b12c | |||
| 67131a1482 | |||
| a92cba8697 | |||
| 52cca7233e | |||
| b2beed0fe0 | |||
| 1f301b6100 | |||
| c74ca4932f | |||
| fafcd67a2c | |||
| 390cc3bd8b | |||
| b2ccda1b34 | |||
| 69916e7756 | |||
| 3a7b6f1343 | |||
| 71a054749c | |||
| 06d87d5c52 | |||
| 98c576afe0 | |||
| 6d544f93f4 | |||
| 3c1a7ff1bb | |||
| ae8f80d6e9 | |||
| 9b933bd26d | |||
| baa8736276 | |||
| 73bedf4f55 | |||
| bae8d4651d | |||
| c75a7e9514 | |||
| 233f64e68f | |||
| f9127ce64d | |||
| 86338db67d | |||
| da7ebd6f61 | |||
| 8db1765505 | |||
| 2438d1d23a | |||
| f790736fd7 | |||
| 985b69ae33 | |||
| 6faf5ccde2 | |||
| 2e129d7b06 | |||
| 5d2e1ff608 | |||
| a9f8ef2ff3 | |||
| 2b7070e408 | |||
| 571a24b419 | |||
| 5f132ae3d3 | |||
| fe5a09281e | |||
| b66522de33 | |||
| e87ef178c2 | |||
| 0987496caf | |||
| 5ad9c48285 | |||
| ec6eb3e645 | |||
| 64c3363426 | |||
| 2023ba3f7d | |||
| 27c1823a54 | |||
| f111827545 | |||
| 7cdc1ba5a3 | |||
| 1d68a1ee8e | |||
| b426ccc04d | |||
| a1c448d8dd | |||
| 25d53338c2 | |||
| 6f7b614c3a | |||
| f02f29c543 | |||
| 06cfe1bb96 | |||
| 736353bbac | |||
| f4b3312672 | |||
| 3178bb5f27 | |||
| 552ce70231 | |||
| c2a79b2665 | |||
| f72c949563 | |||
| bdcb00d1bd | |||
| 42fcb1847b | |||
| a7b36280f3 | |||
| cdef3931be | |||
| d3f2587cc2 | |||
| d343f474e4 | |||
| b7fee9696e | |||
| 4f48337f62 | |||
| 96907d5952 | |||
| 3c5d2571fe | |||
| 7005bf43a4 | |||
| 4726cf4d35 | |||
| b971eda771 | |||
| 3ded6fe87d | |||
| 5195c23dfb | |||
| 5f1255a625 | |||
| 82accd45c1 | |||
| e46768b14b | |||
| 32307efd78 | |||
| e84df69f6f | |||
| 669f38a731 | |||
| afef5597b2 | |||
| 4a0bd638fa | |||
| 4bfb38b9d5 | |||
| 0d62cd9bbd | |||
| 913d5f60ca | |||
| 3dddbdf5cd | |||
| 3245f7fe75 | |||
| f144cda136 | |||
| d374e133f0 | |||
| 0c435a646d | |||
| d0ac226753 | |||
| d92344f2bb | |||
| 51c584c6c4 | |||
| 176bbec8a7 | |||
| b3ebb35d01 | |||
| a508da8b18 | |||
| 91ca84f77a | |||
| d27fdb9904 | |||
| 3b816e2a45 | |||
| 1ad96ce8ca | |||
| 36422c43b3 | |||
| 11a46ca58c | |||
| 6e0aec3bec | |||
| 11dd35af44 | |||
| 17fe5f0c9c | |||
| c8e2d88bb7 | |||
| c6ac9fbcf8 | |||
| e636e75b76 | |||
| a01346577f | |||
| 61a5e53351 | |||
| 739c17b4b6 | |||
| 144ef16b0b | |||
| 58c635cb9d | |||
| a39b9a7651 | |||
| 75889983de | |||
| e4a14b629c | |||
| 3640a17632 | |||
| 2a3f809e4e | |||
| d7dd7b9f80 | |||
| cd48e2de3b | |||
| 8f43efe282 | |||
| 025bcbba1d | |||
| d0131deb40 | |||
| 1325f83291 | |||
| 961acdbc76 | |||
| 6789d74abc | |||
| 062c92377e | |||
| 383f4c7abd | |||
| 4cc6161918 | |||
| c0ebbee347 | |||
| e3b4f5bd2d | |||
| 5df3ab6d98 | |||
| 63fb9a638b | |||
| d62d6946c3 | |||
| 7f0237ced4 | |||
| 23621630d5 | |||
| b3abcf73c3 | |||
| 1219e9bd80 | |||
| dced59b9a1 | |||
| 3bf2972089 | |||
| 6dd3ea5cc2 | |||
| 592a92ebdb | |||
| 1321742afe | |||
| f1f93124a0 | |||
| c8e9d1e012 | |||
| 7b0cd0939b | |||
| 3b5ab5089b | |||
| b36d919d8f | |||
| e22a207f03 | |||
| 24dbef52c9 | |||
| 5498b1e25c | |||
| 86851bb67e | |||
| b99e12c56f | |||
| 129b1b919e | |||
| 711c250cfc | |||
| 0f05216474 | |||
| c57b7c95c1 | |||
| 62e041ed8c | |||
| 2983454ce2 | |||
| 6d5046cb6d | |||
| 91fcf43da9 | |||
| aef1a57e1c | |||
| 71316bac6a | |||
| f1c4f06461 | |||
| 412bbd2a8b | |||
| be64cedfc3 | |||
| 2a6b35d658 | |||
| f51c5c36d0 | |||
| 5599901185 | |||
| fb235bf985 | |||
| 717d7a3fe3 | |||
| c91f468dce | |||
| 1f36657efd | |||
| b70ad5c808 | |||
| da56ef91fd | |||
| 9bd7a152d7 | |||
| 5c287d49bb | |||
| 942f15b49d | |||
| 20b61cda42 | |||
| b1b1d6d434 | |||
| c7ad32ef30 | |||
| 6016db837e | |||
| 2051e0b5d9 | |||
| fddb3f5707 | |||
| 096dd84511 | |||
| e16a2078fc | |||
| e388ae34e3 | |||
| b64c747082 | |||
| 8afa3ae47d | |||
| 1eba68e95b | |||
| 047b339006 | |||
| acd7415835 | |||
| a48460ef76 | |||
| 8ab3896e3a | |||
| 2d481c8a71 | |||
| 7968a4e5ed | |||
| 39d295f412 | |||
| 0bf2cc2a77 | |||
| 433f486091 | |||
| fee6604d5e | |||
| c339fced5c | |||
| a87351778d | |||
| 42687457e0 | |||
| 4a541402da | |||
| ecef487746 | |||
| df483b5623 | |||
| e4d3f5f9a4 | |||
| 02e164dcdf | |||
| ead94e7915 | |||
| dfc3c29439 | |||
| ab538f4bf7 | |||
| 00b6f8583a | |||
| 4cf4a99107 | |||
| 137289e843 | |||
| e7b066e75e | |||
| cd0828f3e0 | |||
| 563697f840 | |||
| 61fc814528 | |||
| 7c90dbabea | |||
| 5ee0f3c373 | |||
| 098bdd0076 | |||
| 40b6da6b44 | |||
| b083dabc6b | |||
| 7fcc3ed42d | |||
| 4ed362f226 | |||
| 39d98f79fb | |||
| c79f7ba245 | |||
| 16354ff435 | |||
| f3a191dd62 | |||
| cb0a5092fb | |||
| 8730f55308 | |||
| 932e98d19c | |||
| 3a69dcfa79 | |||
| 5930674d4a | |||
| df6b20d97f | |||
| 4200af5296 | |||
| b0c9c5be2e | |||
| f2bb1deac4 | |||
| 94ec83aa60 | |||
| e183eec3ea | |||
| b179771ec9 | |||
| d7380a09c1 | |||
| afc316cd1d | |||
| b6f820258a | |||
| 116b605cb1 | |||
| 9f5ce42393 | |||
| 9716d93c15 | |||
| 3465179379 | |||
| c7aad8d917 | |||
| 8ddc1c70e1 | |||
| 5230261be8 | |||
| 8cc8d6eb03 | |||
| 7a95e4c5a3 | |||
| 1c0f182bbc | |||
| 736e20e599 | |||
| c71c8e8c12 | |||
| 9c7a29f939 | |||
| 40bb15e46b | |||
| fb957b61d2 | |||
| 4da9dcb062 | |||
| 60f9302c3f | |||
| 2553f15e7b | |||
| e8d31f2020 | |||
| 4c693ccd60 | |||
| c550fb1848 | |||
| e49bd5a2a0 | |||
| 81be6ce7b9 | |||
| 2d6bf3d9dc | |||
| b2244b7f43 | |||
| 53dcd9c863 | |||
| 75f70d2b30 | |||
| 36b1df1a27 | |||
| 5a445c5c0b | |||
| df828ab2ba | |||
| db855ca99b | |||
| d79cb50aca | |||
| 371ff54d9c | |||
| df7b4ff81f | |||
| f22ea484db | |||
| 574041cf18 | |||
| ff2cc4f999 | |||
| 05c0b0a18b | |||
| 1b9738eace | |||
| 8ee5bc74d5 | |||
| 0a8cc414a5 | |||
| 7a682653cd | |||
| 9286ab6535 | |||
| 85736ab03f | |||
| 673f5c7a9b | |||
| 34d0bcbdfe | |||
| 7abf3027d4 | |||
| ffe3d44cac | |||
| dd23b848ac | |||
| 33cca03698 | |||
| d4d14dd866 | |||
| d6f0fdac50 | |||
| 080605510c | |||
| 1a7b789ef3 | |||
| cc4183a677 | |||
| c2bae56656 | |||
| 38a5c0cbb3 | |||
| 81a8eb698e | |||
| ee4bb7d7c4 | |||
| 8b0d5bddbf | |||
| ba75033f0a | |||
| eb2b90c6f2 | |||
| 3b5c34cb05 | |||
| 2fe22a62c2 | |||
| ff6307fcca | |||
| c6e80a0b6a | |||
| b957cc75be | |||
| fc18539472 | |||
| de7229aee7 | |||
| 53e66032a0 | |||
| 2fc6c30c8f | |||
| f05c5f1261 | |||
| 6af5591cf6 | |||
| 41cbe862e5 | |||
| 057b8273e2 | |||
| 6421c12408 | |||
| 0aca5aeb07 | |||
| bdbd3583b8 | |||
| 626d5b0e51 | |||
| 0bffa0039c | |||
| 9819c8cee8 | |||
| 53ab676750 | |||
| afa4872c97 | |||
| bf56d53faf | |||
| f03adb9206 | |||
| 529fa2e4a0 | |||
| 6df1b90e95 | |||
| 9cba0e6d15 | |||
| f16de3a20c | |||
| 8cfa41d09f | |||
| b59b501366 | |||
| 504bb50b13 | |||
| 969f1266e7 | |||
| fa680b7799 | |||
| e185c85d5e | |||
| acb0a5bd5e | |||
| 62ce576d4d | |||
| 161d3d9b17 | |||
| d88baa070f | |||
| 2b087dde51 | |||
| 7894a8fdc8 | |||
| 0f14e8335a | |||
| 7edf4bced8 | |||
| 4a5639780b | |||
| 0a21a582be | |||
| 0e663c02c4 | |||
| 21afe8165c | |||
| 0247fe5e7c | |||
| 50bad83fba | |||
| 9c93d6c2f3 | |||
| 4d9a50cf94 | |||
| bbdaac5d8d | |||
| 0417c43bcf | |||
| 15585b8f11 | |||
| 59755ec8a5 | |||
| b16dd260d8 | |||
| d37a5a37b7 | |||
| 79dfb4ae87 | |||
| 8b75b6e4c3 | |||
| bcaad08b61 | |||
| cbdeffd93a | |||
| 0ce477a3e7 | |||
| 44eb4d1834 | |||
| 2e26b73208 | |||
| de3fa3201e | |||
| f068aafbb5 | |||
| daedb07135 | |||
| 702e1e446d | |||
| ea87db1ae1 | |||
| b65800843a | |||
| e4c5d8645d | |||
| 85b06c29b4 | |||
| 5254d0c5ca | |||
| 9d038142a8 | |||
| c5573e438b | |||
| 8c7a0ac026 |
+2
-2
@@ -151,11 +151,11 @@ MyAdjustLoops( ICurve* pCurve, ICURVEPLIST& CrvLst)
|
|||||||
else {
|
else {
|
||||||
double dParA = vIccInfo[i].IciA[0].dU ;
|
double dParA = vIccInfo[i].IciA[0].dU ;
|
||||||
double dParB = vIccInfo[i].IciB[0].dU ;
|
double dParB = vIccInfo[i].IciB[0].dU ;
|
||||||
if ( abs( dParA - dEnd) < EPS_SMALL)
|
if ( dParA > dParB)
|
||||||
swap( dParA, dParB) ;
|
swap( dParA, dParB) ;
|
||||||
// verifico se uno dei due intervalli dà origine ad un tratto trascurabile
|
// verifico se uno dei due intervalli dà origine ad un tratto trascurabile
|
||||||
PtrOwner<ICurve> pCrv1( pMyCrv->CopyParamRange( dParA, dParB)) ;
|
PtrOwner<ICurve> pCrv1( pMyCrv->CopyParamRange( dParA, dParB)) ;
|
||||||
PtrOwner<ICurve> pCrv2( pMyCrv->CopyParamRange( dParB, dParA)) ;
|
PtrOwner<ICurve> pCrv2( pMyCrv->CopyParamRange( dParB, dParA)) ;
|
||||||
double dArea1 = 0, dArea2 = 0 ;
|
double dArea1 = 0, dArea2 = 0 ;
|
||||||
if ( ! IsNull( pCrv1))
|
if ( ! IsNull( pCrv1))
|
||||||
pCrv1->GetAreaXY( dArea1) ;
|
pCrv1->GetAreaXY( dArea1) ;
|
||||||
|
|||||||
+152
-109
@@ -311,7 +311,6 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
const Frame3d& frGrid, double dDimZ, double dLevel, double dStep, double dAngTol,
|
const Frame3d& frGrid, double dDimZ, double dLevel, double dStep, double dAngTol,
|
||||||
bool bAdvCorners)
|
bool bAdvCorners)
|
||||||
{
|
{
|
||||||
|
|
||||||
// se non ho polylinee, allora esco
|
// se non ho polylinee, allora esco
|
||||||
if ( vPL.empty())
|
if ( vPL.empty())
|
||||||
return true ;
|
return true ;
|
||||||
@@ -341,10 +340,45 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
if ( ! CalcRegionPolyLines( vPL, vtN, mIndMat, vbInv))
|
if ( ! CalcRegionPolyLines( vPL, vtN, mIndMat, vbInv))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
#if ENABLE_SHARPED_EDGES_DEBUG
|
||||||
|
vector<vector<IGeoObj*>> vvpGObj ; vvpGObj.resize( 7) ;
|
||||||
|
vector<vector<Color>> vvCol ; vvCol.resize( 7) ;
|
||||||
|
// ombra del tool
|
||||||
|
PtrOwner<ICurveArc> pCrvToolShape( CreateCurveArc()) ;
|
||||||
|
pCrvToolShape->Set( ORIG, Z_AX, cavTstm.GetToolRadius()) ;
|
||||||
|
// 1° gruppo, griglia di punti
|
||||||
|
for ( int j = 0 ; j <= nStepY ; ++ j) {
|
||||||
|
for ( int i = 0 ; i <= nStepX ; ++ i) {
|
||||||
|
Point3d ptP = Point3d( i * dStep, j * dStep, dDimZ) ;
|
||||||
|
PtrOwner<IGeoPoint3d> myPtGrid( CreateGeoPoint3d()) ;
|
||||||
|
myPtGrid->Set( ptP) ;
|
||||||
|
vvpGObj[0].emplace_back( static_cast<IGeoObj*>( Release( myPtGrid))) ;
|
||||||
|
vvCol[0].emplace_back( BLUE) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 2° gruppo, superfici
|
||||||
|
CISURFTMPVECTOR myStmVector = cavTstm.GetvStm() ;
|
||||||
|
for ( int i = 0 ; i < int( myStmVector.size()) ; ++ i) {
|
||||||
|
PtrOwner<ISurfTriMesh> pMyStm( CloneSurfTriMesh( myStmVector[i])) ;
|
||||||
|
if ( ! IsNull( pMyStm)) {
|
||||||
|
pMyStm->ToLoc( frGrid) ;
|
||||||
|
vvpGObj[1].emplace_back( static_cast<IGeoObj*>( Release( pMyStm))) ;
|
||||||
|
vvCol[1].emplace_back( Color( 0., 1., 0., .5)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// vettore delle polyline visitate ( viste però come curve composite)
|
||||||
|
ICRVCOMPOPOVECTOR vPL_AsCompo ; vPL_AsCompo.reserve( vPL.size()) ;
|
||||||
|
|
||||||
// scorro i Chunk della matrice di interi, quindi le righe
|
// scorro i Chunk della matrice di interi, quindi le righe
|
||||||
for ( int nChunk = 0 ; nChunk < int( mIndMat.size()) ; ++ nChunk) {
|
for ( int nChunk = 0 ; nChunk < int( mIndMat.size()) ; ++ nChunk) {
|
||||||
// scorro le PolyLinee presenti nel Chunk
|
// scorro le PolyLinee presenti nel Chunk
|
||||||
for ( int nPol = 0 ; nPol < int( vPL.size()) ; ++ nPol) {
|
for ( int nLoop = 0 ; nLoop < int( mIndMat[nChunk].size()) ; ++ nLoop) {
|
||||||
|
// recupero l'indice della PolyLine di riferimento
|
||||||
|
int nPol = mIndMat[nChunk][nLoop] ;
|
||||||
|
if ( nPol < 0 || nPol >= int( vPL.size()))
|
||||||
|
return false ;
|
||||||
// essendo chiusa, se presenti meno di 4 punti, non faccio nulla
|
// essendo chiusa, se presenti meno di 4 punti, non faccio nulla
|
||||||
int nPts = vPL[nPol].GetPointNbr() ;
|
int nPts = vPL[nPol].GetPointNbr() ;
|
||||||
if ( nPts < 4)
|
if ( nPts < 4)
|
||||||
@@ -380,33 +414,6 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
vAdvPt.emplace_back( make_pair( myPt, PointType::VALID)) ;
|
vAdvPt.emplace_back( make_pair( myPt, PointType::VALID)) ;
|
||||||
|
|
||||||
#if ENABLE_SHARPED_EDGES_DEBUG
|
#if ENABLE_SHARPED_EDGES_DEBUG
|
||||||
vector<vector<IGeoObj*>> vvpGObj ; vvpGObj.resize( 7) ;
|
|
||||||
vector<vector<Color>> vvCol ; vvCol.resize( 7) ;
|
|
||||||
// ombra del tool
|
|
||||||
PtrOwner<ICurveArc> pCrvToolShape( CreateCurveArc()) ;
|
|
||||||
pCrvToolShape->Set( ORIG, Z_AX, cavTstm.GetToolRadius()) ;
|
|
||||||
// 1° gruppo, griglia di punti
|
|
||||||
for ( int j = 0 ; j <= nStepY ; ++ j) {
|
|
||||||
for ( int i = 0 ; i <= nStepX ; ++ i) {
|
|
||||||
Point3d ptP = Point3d( i * dStep, j * dStep, dDimZ) ;
|
|
||||||
PtrOwner<IGeoPoint3d> myPtGrid( CreateGeoPoint3d()) ;
|
|
||||||
myPtGrid->Set( ptP) ;
|
|
||||||
vvpGObj[0].emplace_back( static_cast<IGeoObj*>( Release( myPtGrid))) ;
|
|
||||||
vvCol[0].emplace_back( BLUE) ;
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
// 2° gruppo, superfici
|
|
||||||
CISURFTMPVECTOR myStmVector = cavTstm.GetvStm() ;
|
|
||||||
for ( int i = 0 ; i < int( myStmVector.size()) ; ++ i) {
|
|
||||||
PtrOwner<ISurfTriMesh> pMyStm( CloneSurfTriMesh( myStmVector[i])) ;
|
|
||||||
if ( ! IsNull( pMyStm)) {
|
|
||||||
pMyStm->ToLoc( frGrid) ;
|
|
||||||
vvpGObj[1].emplace_back( static_cast<IGeoObj*>( Release( pMyStm))) ;
|
|
||||||
vvCol[1].emplace_back( Color( 0., 1., 0., .5)) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 3° gruppo, punti della PolyLine
|
// 3° gruppo, punti della PolyLine
|
||||||
for ( int i = 0 ; i < int( vAdvPt.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vAdvPt.size()) ; ++ i) {
|
||||||
PtrOwner<IGeoPoint3d> myPt( CreateGeoPoint3d()) ;
|
PtrOwner<IGeoPoint3d> myPt( CreateGeoPoint3d()) ;
|
||||||
@@ -416,23 +423,23 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// modifico la posizione dei punti
|
// modifico la posizione dei punti
|
||||||
if ( ! ModifyPolyLineToSharped( vAdvPt, cavTstm, frGrid, dAngTol, dStep, dSegLen))
|
if ( ! ModifyPolyLineToSharped( vAdvPt, cavTstm, frGrid, dAngTol, dStep, dSegLen))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// ricostrusico la polyLine
|
// ricostrusico la polyLine a partire da una vuota
|
||||||
vPL[nPol].Clear() ;
|
PolyLine PL_New ;
|
||||||
double dPar = -1 ;
|
double dPar = -1 ;
|
||||||
for ( int j = 0 ; j < int( vAdvPt.size()) ; ++ j) {
|
for ( int j = 0 ; j < int( vAdvPt.size()) ; ++ j) {
|
||||||
// se punto valido o sharped di angolo interno, lo aggiungo
|
// se punto valido o sharped di angolo interno, lo aggiungo
|
||||||
if ( j == 0 || j == int( vAdvPt.size() - 1) ||
|
if ( j == 0 || j == int( vAdvPt.size() - 1) ||
|
||||||
vAdvPt[j].second == PointType::VALID || vAdvPt[j].second == PointType::SHARPED_INT)
|
vAdvPt[j].second == PointType::VALID || vAdvPt[j].second == PointType::SHARPED_INT)
|
||||||
vPL[nPol].AddUPoint( ++ dPar, vAdvPt[j].first) ;
|
PL_New.AddUPoint( ++ dPar, vAdvPt[j].first) ;
|
||||||
// se è un punto sharped di un angolo esterno
|
// se è un punto sharped di un angolo esterno
|
||||||
else if ( vAdvPt[j].second == PointType::SHARPED_EXT) {
|
else if ( vAdvPt[j].second == PointType::SHARPED_EXT) {
|
||||||
// se non richiesto il calcolo avanzato del punto a minima distanza dallo spigolo, aggiungo il punto
|
// se non richiesto il calcolo avanzato del punto a minima distanza dallo spigolo, aggiungo il punto
|
||||||
if ( ! bAdvCorners)
|
if ( ! bAdvCorners)
|
||||||
vPL[nPol].AddUPoint( ++ dPar, vAdvPt[j].first) ;
|
PL_New.AddUPoint( ++ dPar, vAdvPt[j].first) ;
|
||||||
else {
|
else {
|
||||||
// ricavo il punto a minima distanza dal materiale mediante metodo di bisezione
|
// ricavo il punto a minima distanza dal materiale mediante metodo di bisezione
|
||||||
Vector3d vtPrev = ( vAdvPt[j-1].first - vAdvPt[j].first) ;
|
Vector3d vtPrev = ( vAdvPt[j-1].first - vAdvPt[j].first) ;
|
||||||
@@ -463,51 +470,29 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
DistPointLine distPtLSucc( ptTest, vAdvPt[j].first, vAdvPt[j+1].first) ;
|
DistPointLine distPtLSucc( ptTest, vAdvPt[j].first, vAdvPt[j+1].first) ;
|
||||||
distPtLPrev.GetMinDistPoint( ptMinDistA) ;
|
distPtLPrev.GetMinDistPoint( ptMinDistA) ;
|
||||||
distPtLSucc.GetMinDistPoint( ptMinDistB) ;
|
distPtLSucc.GetMinDistPoint( ptMinDistB) ;
|
||||||
vPL[nPol].AddUPoint( ++ dPar, ptMinDistA) ;
|
PL_New.AddUPoint( ++ dPar, ptMinDistA) ;
|
||||||
vPL[nPol].AddUPoint( ++ dPar, ptTest) ;
|
PL_New.AddUPoint( ++ dPar, ptTest) ;
|
||||||
vPL[nPol].AddUPoint( ++ dPar, ptMinDistB) ;
|
PL_New.AddUPoint( ++ dPar, ptMinDistB) ;
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLE_SHARPED_EDGES_DEBUG
|
#if ENABLE_SHARPED_EDGES_DEBUG
|
||||||
// 5° gruppo, punti minDist A e B e ptMid
|
// 5° gruppo, punti minDist A e B e ptMid
|
||||||
/*PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ;
|
PtrOwner<IGeoPoint3d> myPtA( CreateGeoPoint3d()) ;
|
||||||
myPtA->Set( ptMinDistA) ;
|
myPtA->Set( ptMinDistA) ;
|
||||||
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtA))) ;
|
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtA))) ;
|
||||||
vvCol[4].emplace_back( BROWN) ;
|
vvCol[4].emplace_back( BROWN) ;
|
||||||
PtrOwner<IGeoPoint3d> myPtB( CreateGeoPoint3d()) ;
|
PtrOwner<IGeoPoint3d> myPtB( CreateGeoPoint3d()) ;
|
||||||
myPtB->Set( ptMinDistB) ;
|
myPtB->Set( ptMinDistB) ;
|
||||||
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtB))) ;
|
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtB))) ;
|
||||||
vvCol[4].emplace_back( BROWN) ;
|
vvCol[4].emplace_back( BROWN) ;
|
||||||
PtrOwner<IGeoPoint3d> myPtMid( CreateGeoPoint3d()) ;
|
PtrOwner<IGeoPoint3d> myPtMid( CreateGeoPoint3d()) ;
|
||||||
myPtMid->Set( ptTest) ;
|
myPtMid->Set( ptTest) ;
|
||||||
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtMid))) ;
|
vvpGObj[4].emplace_back( static_cast<IGeoObj*>( Release( myPtMid))) ;
|
||||||
vvCol[4].emplace_back( BROWN) ;*/
|
vvCol[4].emplace_back( BROWN) ;
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// riposiziono la polyLine
|
|
||||||
#if ENABLE_SHARPED_EDGES_DEBUG
|
|
||||||
// 6° gruppo, curve composita derivante dalla polyline
|
|
||||||
PtrOwner<ICurveComposite> pCrvCompoPoly( CreateCurveComposite()) ;
|
|
||||||
pCrvCompoPoly->FromPolyLine( vPL[nPol]) ;
|
|
||||||
//pCrvCompoPoly->SetExtrusion( frGrid.VersZ()) ;
|
|
||||||
vvpGObj[5].emplace_back( static_cast<IGeoObj*>( CloneCurveComposite( pCrvCompoPoly))) ;
|
|
||||||
vvCol[5].emplace_back( RED) ;
|
|
||||||
// 7° gruppo, controOffset
|
|
||||||
OffsetCurve offsCrv ;
|
|
||||||
offsCrv.Make( pCrvCompoPoly, - ( cavTstm.GetToolRadius() - 2 * EPS_SMALL), ICurve::OFF_EXTEND) ;
|
|
||||||
pCrvCompoPoly.Set( ConvertCurveToComposite( offsCrv.GetLongerCurve())) ;
|
|
||||||
vvpGObj[6].emplace_back( static_cast<IGeoObj*>( Release( pCrvCompoPoly))) ;
|
|
||||||
vvCol[6].emplace_back( WHITE) ;
|
|
||||||
string myName = Sharped_Edges_Debug_File_Name +
|
|
||||||
to_string( nChunk) + "_" +
|
|
||||||
to_string( nPol) + "_" +
|
|
||||||
to_string( dLevel) + "_" +
|
|
||||||
to_string( dAngTol) + ".nge" ;
|
|
||||||
SaveGeoObj( vvpGObj, vvCol, myName) ;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// se la polyLinea si autointerseca, allora non la modifico ( essendo a distanza R dalla
|
// se la polyLinea si autointerseca, allora non la modifico ( essendo a distanza R dalla
|
||||||
// trimesh rischio di evere Chunk distinti uniti in un unico Chunk
|
// trimesh rischio di evere Chunk distinti uniti in un unico Chunk
|
||||||
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
PtrOwner<ICurveComposite> pCompo( CreateCurveComposite()) ;
|
||||||
@@ -515,11 +500,53 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
return false ;
|
return false ;
|
||||||
pCompo->FromPolyLine( vPL[nPol]) ;
|
pCompo->FromPolyLine( vPL[nPol]) ;
|
||||||
SelfIntersCurve SIC( *pCompo) ;
|
SelfIntersCurve SIC( *pCompo) ;
|
||||||
if ( SIC.GetCrossOrOverlapIntersCount() > 0)
|
bool bDiscard = ( SIC.GetCrossOrOverlapIntersCount() > 0) ;
|
||||||
continue ;
|
if ( ! bDiscard) {
|
||||||
|
// se la polyLine interseca una delle PolyLine precedenti, non la modifico
|
||||||
|
for ( auto& pCompoPL_Prev : vPL_AsCompo) {
|
||||||
|
IntersCurveCurve ICC( *pCompo, *pCompoPL_Prev) ;
|
||||||
|
if ( ICC.GetCrossOrOverlapIntersCount() > 0) {
|
||||||
|
bDiscard = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se nuova approssimazione da conservare, memorizzo i risultati
|
||||||
|
if ( ! bDiscard) {
|
||||||
|
vPL[nPol] = PL_New ;
|
||||||
|
vPL_AsCompo.emplace_back( Release( pCompo)) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLE_SHARPED_EDGES_DEBUG
|
||||||
|
ICURVEPVECTOR vpCrv ; vpCrv.reserve( vPL.size()) ;
|
||||||
|
for ( const auto& PL : vPL) {
|
||||||
|
// 6° gruppo, curve composita derivante dalla polyline
|
||||||
|
PtrOwner<ICurveComposite> pCrvCompoPoly( CreateCurveComposite()) ;
|
||||||
|
pCrvCompoPoly->FromPolyLine( PL) ;
|
||||||
|
vvpGObj[5].emplace_back( static_cast<IGeoObj*>( CloneCurveComposite( pCrvCompoPoly))) ;
|
||||||
|
vvCol[5].emplace_back( RED) ;
|
||||||
|
vpCrv.emplace_back( Release( pCrvCompoPoly)) ;
|
||||||
|
}
|
||||||
|
// 7° gruppo, controOffset
|
||||||
|
ICURVEPOVECTOR vCrvCompoOffs ;
|
||||||
|
if ( ! CalcOffsetCurves( vpCrv, vCrvCompoOffs, - ( cavTstm.GetToolRadius() - 2 * EPS_SMALL), ICurve::OFF_EXTEND)) {
|
||||||
|
for ( auto& pCrv : vpCrv) { delete( pCrv) ; pCrv = nullptr ;}
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
for ( auto& pCrv : vpCrv) { delete( pCrv) ; pCrv = nullptr ;}
|
||||||
|
for ( const auto& pCvrOffs : vCrvCompoOffs) {
|
||||||
|
vvpGObj[6].emplace_back( static_cast<IGeoObj*>( CloneCurveComposite( pCvrOffs))) ;
|
||||||
|
vvCol[6].emplace_back( WHITE) ;
|
||||||
|
}
|
||||||
|
string myName = Sharped_Edges_Debug_File_Name +
|
||||||
|
to_string( dLevel) + "_" +
|
||||||
|
to_string( dAngTol) + ".nge" ;
|
||||||
|
SaveGeoObj( vvpGObj, vvCol, myName) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,21 +812,31 @@ MarchingSquares( const DBLVECTOR& vdGrid, int nStepX, int nStepY, double dStep,
|
|||||||
if ( TestEdgesClosedPolyLines( vPL_Sharped, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, ANG_TOL_STD_DEG, false))
|
if ( TestEdgesClosedPolyLines( vPL_Sharped, cavTstm, nStepX, nStepY, frGrid, dDimZ, dLevel, dStep, ANG_TOL_STD_DEG, false))
|
||||||
swap( vPL_Sharped, vPL) ;
|
swap( vPL_Sharped, vPL) ;
|
||||||
|
|
||||||
|
// se vettore di PolyLine vuoto, non faccio nulla
|
||||||
|
if ( vPL.empty())
|
||||||
|
return true ;
|
||||||
|
|
||||||
// se non ho impostato un utensile, devo effettuare un contro-offset
|
// se non ho impostato un utensile, devo effettuare un contro-offset
|
||||||
if ( ! bTool) {
|
if ( ! bTool) {
|
||||||
POLYLINEVECTOR vPL_Offs ;
|
ICURVEPOVECTOR vpOwCrv ; vpOwCrv.reserve( vPL.size()) ;
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
ICURVEPVECTOR vpCrv ; vpCrv.reserve( vPL.size()) ;
|
||||||
CurveComposite crvCompo ;
|
for ( const auto& PL : vPL) {
|
||||||
if ( ! crvCompo.FromPolyLine( vPL[i]))
|
PtrOwner<ICurveComposite> pCrvCompoPoly( CreateCurveComposite()) ;
|
||||||
return false ;
|
pCrvCompoPoly->FromPolyLine( PL) ;
|
||||||
OffsetCurve offsCompo ;
|
vpOwCrv.emplace_back( Release( pCrvCompoPoly)) ;
|
||||||
offsCompo.Make( &crvCompo, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND) ;
|
vpCrv.emplace_back( vpOwCrv.back()) ;
|
||||||
PtrOwner<ICurve> pCrvOffset( offsCompo.GetLongerCurve()) ;
|
}
|
||||||
while ( ! IsNull( pCrvOffset)) {
|
// calcolo l'Offset
|
||||||
|
ICURVEPOVECTOR vpCrvOffs ;
|
||||||
|
if ( ! CalcOffsetCurves( vpCrv, vpCrvOffs, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND))
|
||||||
|
return false ;
|
||||||
|
// resituisco le PolyLine
|
||||||
|
POLYLINEVECTOR vPL_Offs ; vPL_Offs.reserve( vpCrvOffs.size()) ;
|
||||||
|
for ( auto& pCrv : vpCrvOffs) {
|
||||||
|
if ( pCrv != nullptr && pCrv->IsValid()) {
|
||||||
PolyLine myPolyLine ;
|
PolyLine myPolyLine ;
|
||||||
pCrvOffset->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, myPolyLine) ;
|
pCrv->ApproxWithLines( 10 * EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, myPolyLine) ;
|
||||||
vPL_Offs.emplace_back( myPolyLine) ;
|
vPL_Offs.emplace_back( myPolyLine) ;
|
||||||
pCrvOffset.Set( offsCompo.GetLongerCurve()) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
swap( vPL_Offs, vPL) ;
|
swap( vPL_Offs, vPL) ;
|
||||||
@@ -976,28 +1013,13 @@ CAvParSilhouettesSurfTm::Prepare( void)
|
|||||||
return false ;
|
return false ;
|
||||||
b3All.Add( b3Surf) ;
|
b3All.Add( b3Surf) ;
|
||||||
}
|
}
|
||||||
|
// espansione in Z del Box
|
||||||
// calcolo dati della griglia
|
|
||||||
const double EXTRA_XY = ( m_bTool ? m_dRad + 2 : 1.5 * m_dTol) ;
|
|
||||||
const double EXTRA_Z = 10 * m_dTol + ( m_dMaxDepth > EPS_SMALL ? max( 0., m_dMaxDepth - b3All.GetDimZ()) : 0) ;
|
const double EXTRA_Z = 10 * m_dTol + ( m_dMaxDepth > EPS_SMALL ? max( 0., m_dMaxDepth - b3All.GetDimZ()) : 0) ;
|
||||||
b3All.Expand( EXTRA_XY, EXTRA_XY, EXTRA_Z) ;
|
b3All.Expand( 0., 0., EXTRA_Z) ;
|
||||||
m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ;
|
|
||||||
m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ;
|
|
||||||
m_frGrid.ChangeOrig( GetToGlob( b3All.GetMin(), m_frGrid)) ;
|
|
||||||
m_dDimZ = b3All.GetDimZ() ;
|
m_dDimZ = b3All.GetDimZ() ;
|
||||||
m_dLevelOffs = - b3All.GetMin().z ;
|
|
||||||
|
|
||||||
// calcolo dei punti della griglia (sul top del cilindro)
|
// set utensile corrente per calcolo delle collisioni
|
||||||
PNTUVECTOR vPntM( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
|
double dExtraXY = m_dRad + m_dOffsR ;
|
||||||
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
|
|
||||||
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
|
|
||||||
int nInd = i + j * ( m_nStepX + 1) ;
|
|
||||||
Point3d ptP = GetToGlob( Point3d( i * m_dTol, j * m_dTol, m_dDimZ), m_frGrid) ;
|
|
||||||
vPntM[nInd] = { ptP, 0.} ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// esecuzione della verifica
|
|
||||||
if ( m_dSideAng < EPS_ANG_SMALL)
|
if ( m_dSideAng < EPS_ANG_SMALL)
|
||||||
m_cavTstm.SetStdTool( m_dDimZ + m_dOffsR, m_dRad + m_dOffsR, m_dCornRad + m_dOffsR) ;
|
m_cavTstm.SetStdTool( m_dDimZ + m_dOffsR, m_dRad + m_dOffsR, m_dCornRad + m_dOffsR) ;
|
||||||
else {
|
else {
|
||||||
@@ -1015,8 +1037,29 @@ CAvParSilhouettesSurfTm::Prepare( void)
|
|||||||
|
|
||||||
double dStemRad = m_dRad + dDeltaRad ;
|
double dStemRad = m_dRad + dDeltaRad ;
|
||||||
double dTipRad = m_dRad ;
|
double dTipRad = m_dRad ;
|
||||||
|
dExtraXY = dStemRad + m_dOffsR ;
|
||||||
m_cavTstm.SetAdvTool( m_dDimZ + m_dOffsR, dStemRad + m_dOffsR, m_dMaxMat, dTipRad + m_dOffsR, m_dCornRad + m_dOffsR) ;
|
m_cavTstm.SetAdvTool( m_dDimZ + m_dOffsR, dStemRad + m_dOffsR, m_dMaxMat, dTipRad + m_dOffsR, m_dCornRad + m_dOffsR) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// calcolo dati della griglia
|
||||||
|
const double EXTRA_XY = ( m_bTool ? dExtraXY + 2. : 1.5 * m_dTol) ;
|
||||||
|
b3All.Expand( EXTRA_XY, EXTRA_XY, 0.) ;
|
||||||
|
m_frGrid.ChangeOrig( GetToGlob( b3All.GetMin(), m_frGrid)) ;
|
||||||
|
m_dLevelOffs = - b3All.GetMin().z ;
|
||||||
|
m_nStepX = int( ceil( b3All.GetDimX() / m_dTol)) ;
|
||||||
|
m_nStepY = int( ceil( b3All.GetDimY() / m_dTol)) ;
|
||||||
|
|
||||||
|
// calcolo dei punti della griglia (sul top del cilindro)
|
||||||
|
PNTUVECTOR vPntM( ( m_nStepX + 1) * ( m_nStepY + 1)) ;
|
||||||
|
for ( int j = 0 ; j <= m_nStepY ; ++ j) {
|
||||||
|
for ( int i = 0 ; i <= m_nStepX ; ++ i) {
|
||||||
|
int nInd = i + j * ( m_nStepX + 1) ;
|
||||||
|
Point3d ptP = GetToGlob( Point3d( i * m_dTol, j * m_dTol, m_dDimZ), m_frGrid) ;
|
||||||
|
vPntM[nInd] = { ptP, 0.} ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// esecuzione verifica della collisione
|
||||||
if ( m_vpStm.empty() || ! m_cavTstm.SetSurfTm( *( m_vpStm[0])))
|
if ( m_vpStm.empty() || ! m_cavTstm.SetSurfTm( *( m_vpStm[0])))
|
||||||
return false ;
|
return false ;
|
||||||
for ( int k = 1 ; k < int( m_vpStm.size()) ; ++ k)
|
for ( int k = 1 ; k < int( m_vpStm.size()) ; ++ k)
|
||||||
|
|||||||
@@ -140,16 +140,20 @@ MyCAvSimpleSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
|||||||
if ( scInfoCurr.nType == SCI_LINE_LINE || scInfoCurr.nType == SCI_PNT_LINE) {
|
if ( scInfoCurr.nType == SCI_LINE_LINE || scInfoCurr.nType == SCI_PNT_LINE) {
|
||||||
m_SCollInfo = scInfoCurr ;
|
m_SCollInfo = scInfoCurr ;
|
||||||
m_SCollInfo.nChunkM = j ;
|
m_SCollInfo.nChunkM = j ;
|
||||||
|
m_SCollInfo.nLoopM = 0 ;
|
||||||
m_SCollInfo.nCrvM = k ;
|
m_SCollInfo.nCrvM = k ;
|
||||||
m_SCollInfo.nChunkF = i ;
|
m_SCollInfo.nChunkF = i ;
|
||||||
|
m_SCollInfo.nLoopF = 0 ;
|
||||||
m_SCollInfo.nCrvF = l ;
|
m_SCollInfo.nCrvF = l ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( dNewLenXY < dPrevLenXY) {
|
else if ( dNewLenXY < dPrevLenXY) {
|
||||||
m_SCollInfo = scInfoCurr ;
|
m_SCollInfo = scInfoCurr ;
|
||||||
m_SCollInfo.nChunkM = j ;
|
m_SCollInfo.nChunkM = j ;
|
||||||
|
m_SCollInfo.nLoopM = 0 ;
|
||||||
m_SCollInfo.nCrvM = k ;
|
m_SCollInfo.nCrvM = k ;
|
||||||
m_SCollInfo.nChunkF = i ;
|
m_SCollInfo.nChunkF = i ;
|
||||||
|
m_SCollInfo.nLoopF = 0 ;
|
||||||
m_SCollInfo.nCrvF = l ;
|
m_SCollInfo.nCrvF = l ;
|
||||||
}
|
}
|
||||||
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class MyCAvSimpleSurfFrMove
|
|||||||
const SCollInfo& GetSCollInfo()
|
const SCollInfo& GetSCollInfo()
|
||||||
{ return m_SCollInfo ;}
|
{ return m_SCollInfo ;}
|
||||||
|
|
||||||
private :
|
protected :
|
||||||
bool TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
bool TranslateCurveNoCollisionCurve( const ICurve* pCrv1, const ICurve* pCrv2,
|
||||||
const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) ;
|
const Vector3d& vtDir, double& dLen, SCollInfo& scInfo) ;
|
||||||
bool TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
bool TranslateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||||
@@ -40,7 +40,7 @@ class MyCAvSimpleSurfFrMove
|
|||||||
bool RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
bool RotateLineNoCollisionLine( const CurveLine* pLine1, const CurveLine* pLine2,
|
||||||
const Point3d& ptCen, double& dAng) ;
|
const Point3d& ptCen, double& dAng) ;
|
||||||
|
|
||||||
private :
|
protected :
|
||||||
const SurfFlatRegion* m_pRegM ;
|
const SurfFlatRegion* m_pRegM ;
|
||||||
const SurfFlatRegion* m_pRegF ;
|
const SurfFlatRegion* m_pRegF ;
|
||||||
SCollInfo m_SCollInfo ;
|
SCollInfo m_SCollInfo ;
|
||||||
|
|||||||
@@ -0,0 +1,257 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2026-2026
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : CASurfFrMove.cpp Data : 26.03.2026 Versione : 3.1c7
|
||||||
|
// Contenuto : Implementazione delle funzioni di movimento per SurfFlatRegion
|
||||||
|
// senza collisione con altri oggetti dello stesso tipo e nello
|
||||||
|
// stesso piano o in piani paralleli.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 26.03.2026 RE Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "CAvSurfFrMove.h"
|
||||||
|
#include "SurfFlatRegion.h"
|
||||||
|
#include "CurveLine.h"
|
||||||
|
#include "CurveArc.h"
|
||||||
|
#include "CurveComposite.h"
|
||||||
|
#include "IntersLineArc.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkCAvSurfFrMove.h"
|
||||||
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// CASurfFrMove
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
CAvSurfFrMove::CAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF)
|
||||||
|
{
|
||||||
|
// salvo puntatori alle regioni
|
||||||
|
m_pRegM = &SfrM ;
|
||||||
|
m_pRegF = &SfrF ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||||
|
{
|
||||||
|
MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ;
|
||||||
|
m_CollInfo.nType = SCI_NONE ;
|
||||||
|
if ( ! ScdMove.Translate( vtDir, dLen))
|
||||||
|
return false ;
|
||||||
|
m_CollInfo = ScdMove.GetCollInfo() ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng)
|
||||||
|
{
|
||||||
|
MyCAvSurfFrMove ScdMove( *m_pRegM, *m_pRegF) ;
|
||||||
|
m_CollInfo.nType = SCI_NONE ;
|
||||||
|
return ScdMove.Rotate( ptCen, dAng) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
MyCAvSurfFrMove::Translate( const Vector3d& vtDir, double& dLen)
|
||||||
|
{
|
||||||
|
// verifico validità regioni
|
||||||
|
if ( m_pRegM == nullptr || m_pRegF == nullptr)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico che le due regioni giacciano in piani paralleli
|
||||||
|
if ( ! AreSameVectorApprox( m_pRegM->m_frF.VersZ(), m_pRegF->m_frF.VersZ()))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// reset info di collisione
|
||||||
|
m_SCollInfo.nType = SCI_NONE ;
|
||||||
|
|
||||||
|
// porto il vettore di movimento nel riferimento intrinseco e ne annullo la componente Z
|
||||||
|
Vector3d vtDirL = vtDir ;
|
||||||
|
vtDirL.ToLoc( m_pRegM->m_frF) ;
|
||||||
|
vtDirL.z = 0 ;
|
||||||
|
double dLenXY = vtDirL.Len() ;
|
||||||
|
if ( dLenXY < EPS_SMALL)
|
||||||
|
return true ;
|
||||||
|
vtDirL /= dLenXY ;
|
||||||
|
dLenXY *= dLen ;
|
||||||
|
double dNewLenXY = dLenXY ;
|
||||||
|
|
||||||
|
// ciclo sui chunk della seconda superficie
|
||||||
|
for ( int nCF = 0 ; nCF < m_pRegF->GetChunkCount() ; ++ nCF) {
|
||||||
|
// ciclo sui bordi dei chunk
|
||||||
|
for ( int nLF = 0 ; nLF < m_pRegF->GetLoopCount( nCF) ; ++ nLF) {
|
||||||
|
|
||||||
|
// curva corrente del chunk della seconda regione in locale nel riferimento intrinseco della prima
|
||||||
|
const ICurve* pCrv2Loc = nullptr ;
|
||||||
|
PtrOwner<ICurve> pCopyCrv ;
|
||||||
|
if ( AreSameFrame( m_pRegM->m_frF, m_pRegF->m_frF))
|
||||||
|
pCrv2Loc = m_pRegF->GetMyLoop( nCF, nLF) ;
|
||||||
|
else {
|
||||||
|
pCopyCrv.Set( m_pRegF->GetMyLoop( nCF, nLF)->Clone()) ;
|
||||||
|
if ( IsNull( pCopyCrv))
|
||||||
|
return false ;
|
||||||
|
pCopyCrv->LocToLoc( m_pRegF->m_frF, m_pRegM->m_frF) ;
|
||||||
|
pCrv2Loc = pCopyCrv ;
|
||||||
|
}
|
||||||
|
const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ;
|
||||||
|
|
||||||
|
// ciclo sui chunk della prima superficie
|
||||||
|
for ( int nCM = 0 ; nCM < m_pRegM->GetChunkCount() ; ++ nCM) {
|
||||||
|
// ciclo sui bordi del chunk
|
||||||
|
for ( int nLM = 0 ; nLM < m_pRegM->GetLoopCount( nCM) ; ++ nLM) {
|
||||||
|
|
||||||
|
// per CAv non ha senso confrontare due loop interni tra di loro.
|
||||||
|
// posso confrontatare - due loop esterni (come per la CAvSimpleSurfFrMove)
|
||||||
|
// - un loop esterno con uno interno (nel caso in cui un Chunk sia contenuto dentro un isola)
|
||||||
|
if ( nLF > 0 && nLM > 0)
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// curva corrente del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
||||||
|
const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( nCM, nLM) ;
|
||||||
|
const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ;
|
||||||
|
|
||||||
|
// verifico la collisione tra le entità dei loop esterni dei due chunk
|
||||||
|
int k = 0 ;
|
||||||
|
const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ;
|
||||||
|
while ( pCrv1 != nullptr) {
|
||||||
|
int l = 0 ;
|
||||||
|
const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ;
|
||||||
|
while ( pCrv2 != nullptr) {
|
||||||
|
SCollInfo cInfoCurr ;
|
||||||
|
double dPrevLenXY = dNewLenXY ;
|
||||||
|
if ( ! TranslateCurveNoCollisionCurve( pCrv1, pCrv2, vtDirL, dNewLenXY, cInfoCurr))
|
||||||
|
return false ;
|
||||||
|
if ( abs( dNewLenXY - dPrevLenXY) < EPS_SMALL) {
|
||||||
|
if ( cInfoCurr.nType == SCI_LINE_LINE || cInfoCurr.nType == SCI_PNT_LINE) {
|
||||||
|
m_SCollInfo = cInfoCurr ;
|
||||||
|
m_SCollInfo.nChunkM = nCM ;
|
||||||
|
m_SCollInfo.nLoopM = nLM ;
|
||||||
|
m_SCollInfo.nCrvM = k ;
|
||||||
|
m_SCollInfo.nChunkF = nCF ;
|
||||||
|
m_SCollInfo.nLoopF = nLF ;
|
||||||
|
m_SCollInfo.nCrvF = l ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( dNewLenXY < dPrevLenXY) {
|
||||||
|
m_SCollInfo = cInfoCurr ;
|
||||||
|
m_SCollInfo.nChunkM = nCM ;
|
||||||
|
m_SCollInfo.nLoopM = nLM ;
|
||||||
|
m_SCollInfo.nCrvM = k ;
|
||||||
|
m_SCollInfo.nChunkF = nCF ;
|
||||||
|
m_SCollInfo.nLoopF = nLF ;
|
||||||
|
m_SCollInfo.nCrvF = l ;
|
||||||
|
}
|
||||||
|
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
||||||
|
++ l ;
|
||||||
|
}
|
||||||
|
pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ;
|
||||||
|
++ k ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se da limitare il movimento
|
||||||
|
if ( dNewLenXY < dLenXY - EPS_SMALL)
|
||||||
|
dLen *= dNewLenXY / dLenXY ;
|
||||||
|
|
||||||
|
// porto i punti e le direzioni di SCollInfo da intrinseco a locale della prima regione
|
||||||
|
if ( m_SCollInfo.nType != SCI_NONE) {
|
||||||
|
m_SCollInfo.ptP1.ToGlob( m_pRegM->m_frF) ;
|
||||||
|
m_SCollInfo.vtDirM.ToGlob( m_pRegM->m_frF) ;
|
||||||
|
m_SCollInfo.vtDirF.ToGlob( m_pRegM->m_frF) ;
|
||||||
|
}
|
||||||
|
if ( m_SCollInfo.nType == SCI_LINE_LINE)
|
||||||
|
m_SCollInfo.ptP2.ToGlob( m_pRegM->m_frF) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
MyCAvSurfFrMove::Rotate( const Point3d& ptCen, double& dAng)
|
||||||
|
{
|
||||||
|
// verifico validità regioni
|
||||||
|
if ( m_pRegM == nullptr || m_pRegF == nullptr)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico che le due regioni giacciano in piani paralleli
|
||||||
|
if ( ! AreSameVectorApprox( m_pRegM->m_frF.VersZ(), m_pRegF->m_frF.VersZ()))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// reset info di collisione
|
||||||
|
m_SCollInfo.nType = SCI_NONE ;
|
||||||
|
|
||||||
|
// porto il centro di rotazione nel riferimento intrinseco e ne annullo la componente Z
|
||||||
|
Point3d ptCenL = ptCen ;
|
||||||
|
ptCenL.ToLoc( m_pRegM->m_frF) ;
|
||||||
|
ptCenL.z = 0 ;
|
||||||
|
if ( abs( dAng) < EPS_ANG_SMALL)
|
||||||
|
return true ;
|
||||||
|
double dNewAng = dAng ;
|
||||||
|
|
||||||
|
// ciclo sui chunk della seconda superficie
|
||||||
|
for ( int nCF = 0 ; nCF < m_pRegF->GetChunkCount() ; ++ nCF) {
|
||||||
|
// ciclo sui bordi del Chunk
|
||||||
|
for ( int nLF = 0 ; nLF < m_pRegF->GetLoopCount( nCF) ; ++ nLF) {
|
||||||
|
|
||||||
|
// curva corrente del chunk della seconda regione in locale nel riferimento intrinseco della prima
|
||||||
|
const ICurve* pCrv2Loc = nullptr ;
|
||||||
|
PtrOwner<ICurve> pCopyCrv ;
|
||||||
|
if ( AreSameFrame( m_pRegM->m_frF, m_pRegF->m_frF))
|
||||||
|
pCrv2Loc = m_pRegF->GetMyLoop( nCF, nLF) ;
|
||||||
|
else {
|
||||||
|
pCopyCrv.Set( m_pRegF->GetMyLoop( nCF, nLF)->Clone()) ;
|
||||||
|
if ( IsNull( pCopyCrv))
|
||||||
|
return false ;
|
||||||
|
pCopyCrv->LocToLoc( m_pRegF->m_frF, m_pRegM->m_frF) ;
|
||||||
|
pCrv2Loc = pCopyCrv ;
|
||||||
|
}
|
||||||
|
const CurveComposite* pCompo2 = GetBasicCurveComposite( pCrv2Loc) ;
|
||||||
|
|
||||||
|
// ciclo sui chunk della prima superficie
|
||||||
|
for ( int nCM = 0 ; nCM < m_pRegM->GetChunkCount() ; ++ nCM) {
|
||||||
|
// ciclo sui bordi del chunk
|
||||||
|
for ( int nLM = 0 ; nLM < m_pRegM->GetLoopCount( nCM) ; ++ nLM) {
|
||||||
|
|
||||||
|
// per CAv non ha senso confrontare due loop interni tra di loro.
|
||||||
|
// posso confrontatare - due loop esterni (come per la CAvSimpleSurfFrMove)
|
||||||
|
// - un loop esterno con uno interno (nel caso in cui un Chunk sia contenuto dentro un isola)
|
||||||
|
if ( nLF > 0 && nLM > 0)
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
||||||
|
const ICurve* pCrv1Loc = m_pRegM->GetMyLoop( nCM, nLM) ;
|
||||||
|
const CurveComposite* pCompo1 = GetBasicCurveComposite( pCrv1Loc) ;
|
||||||
|
|
||||||
|
// verifico la collisione tra le entità dei loop esterni dei due chunk
|
||||||
|
const ICurve* pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetFirstCurve() : pCrv1Loc) ;
|
||||||
|
while ( pCrv1 != nullptr) {
|
||||||
|
const ICurve* pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetFirstCurve() : pCrv2Loc) ;
|
||||||
|
while ( pCrv2 != nullptr) {
|
||||||
|
if ( ! RotateCurveNoCollisionCurve( pCrv1, pCrv2, ptCenL, dNewAng))
|
||||||
|
return false ;
|
||||||
|
pCrv2 = ( pCompo2 != nullptr ? pCompo2->GetNextCurve() : nullptr) ;
|
||||||
|
}
|
||||||
|
pCrv1 = ( pCompo1 != nullptr ? pCompo1->GetNextCurve() : nullptr) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se da limitare il movimento
|
||||||
|
if ( ( dAng > 0 && dNewAng < dAng - EPS_ANG_SMALL) ||
|
||||||
|
( dAng < 0 && dNewAng > dAng + EPS_ANG_SMALL))
|
||||||
|
dAng = dNewAng ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2015-2018
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : CAvSurfFrMove.h Data : 27.04.18 Versione : 3.1c7
|
||||||
|
// Contenuto : Dich.ne classe privata per movimento di superfici flat region
|
||||||
|
// nel loro piano evitando collisioni
|
||||||
|
//
|
||||||
|
// Modifiche : 26.03.2026 RE Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CAvSimpleSurfFrMove.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
class MyCAvSurfFrMove : public MyCAvSimpleSurfFrMove
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
MyCAvSurfFrMove( const ISurfFlatRegion& SfrM, const ISurfFlatRegion& SfrF) :
|
||||||
|
MyCAvSimpleSurfFrMove( SfrM, SfrF) {} ;
|
||||||
|
|
||||||
|
public :
|
||||||
|
bool Translate( const Vector3d& vtDir, double& dLen) ;
|
||||||
|
bool Rotate( const Point3d& ptCen, double& dAng) ;
|
||||||
|
const SCollInfo& GetCollInfo()
|
||||||
|
{ return m_SCollInfo ; }
|
||||||
|
} ;
|
||||||
+2
-4
@@ -2440,12 +2440,10 @@ CAvDiskTriangle( const Point3d& ptDiskCen, const Vector3d& vtDiskAx, double dDis
|
|||||||
// Allontanamento dall'interno
|
// Allontanamento dall'interno
|
||||||
double dEscapeDist = max( DiskTriaInteriorEscapeDistGenMot( ptDiskCen, vtDiskAx, dDiskRad, trTria, vtMove), 0.) ;
|
double dEscapeDist = max( DiskTriaInteriorEscapeDistGenMot( ptDiskCen, vtDiskAx, dDiskRad, trTria, vtMove), 0.) ;
|
||||||
// Allontanamento dalla frontiera
|
// Allontanamento dalla frontiera
|
||||||
Vector3d vtMoveOrt = vtMove - vtMove * vtDiskAx * vtDiskAx ;
|
Vector3d vtMoveOrt = OrthoCompo( vtMove, vtDiskAx) ;
|
||||||
vtMoveOrt.Normalize() ;
|
vtMoveOrt.Normalize() ;
|
||||||
Frame3d DiskFrame ;
|
Frame3d DiskFrame ;
|
||||||
Vector3d vtJ = vtDiskAx ^ vtMoveOrt ;
|
DiskFrame.Set( ptDiskCen, vtDiskAx, vtMoveOrt) ;
|
||||||
vtJ.Normalize() ;
|
|
||||||
DiskFrame.Set( ptDiskCen, vtMoveOrt, vtJ, vtDiskAx) ;
|
|
||||||
Triangle3d trTriaLoc = trTria ;
|
Triangle3d trTriaLoc = trTria ;
|
||||||
Vector3d vtMoveLoc = vtMove ;
|
Vector3d vtMoveLoc = vtMove ;
|
||||||
trTriaLoc.ToLoc( DiskFrame) ;
|
trTriaLoc.ToLoc( DiskFrame) ;
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2020-2024
|
// EgalTech 2020-2026
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : CDeClosedSurfTmClosedSurfTm.h Data : 24.03.24 Versione : 2.6c2
|
// File : CDeClosedSurfTmClosedSurfTm.h Data : 23.01.26 Versione : 3.1a3
|
||||||
// Contenuto : Implementazione funzione verifica collisione tra
|
// Contenuto : Implementazione funzione verifica collisione tra
|
||||||
// SurfTm e SurfTm.
|
// SurfTm e SurfTm.
|
||||||
//
|
//
|
||||||
// Modifiche : 13.11.20 LM Creazione modulo.
|
// Modifiche : 13.11.20 LM Creazione modulo.
|
||||||
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
|
// 24.03.24 DS Aggiunta TestSurfTmSurfTm.
|
||||||
|
// 23.01.26 DS In TestSurfTmSurfTm aggiunto flag per collisione quando una delle due è chiusa e contiene l'altra.
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -45,10 +46,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
BBox3d b3BoxA, b3BoxB ;
|
BBox3d b3BoxA, b3BoxB ;
|
||||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||||
if ( dSafeDist > EPS_SMALL)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxB.Expand( dSafeDist) ;
|
b3BoxB.Expand( dSafeDist) ;
|
||||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||||
return false ;
|
return false ;
|
||||||
// Recupero i triangoli di A che interferiscono col box di B
|
// Recupero i triangoli di A che interferiscono col box di B
|
||||||
@@ -61,13 +62,13 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
continue ;
|
continue ;
|
||||||
BBox3d b3BoxTriaA ;
|
BBox3d b3BoxTriaA ;
|
||||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||||
if ( dSafeDist > EPS_SMALL)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxTriaA.Expand( dSafeDist) ;
|
b3BoxTriaA.Expand( dSafeDist) ;
|
||||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||||
// Settare tutti i triangoli come già processati.
|
// Settare tutti i triangoli come già processati.
|
||||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||||
pSrfB->ResetTempInts() ;
|
pSrfB->ResetTempInts() ;
|
||||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||||
@@ -84,14 +85,14 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
// Ciclo sui vertici del triangolo.
|
// Ciclo sui vertici del triangolo.
|
||||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||||
// non è stato processato, processo il vertice e l'edge.
|
// non è stato processato, processo il vertice e l'edge.
|
||||||
int nAdjTriaTempFlag ;
|
int nAdjTriaTempFlag ;
|
||||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||||
continue ;
|
continue ;
|
||||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||||
return true ;
|
return true ;
|
||||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||||
double dEdgeLen = vtEdgeV.Len() ;
|
double dEdgeLen = vtEdgeV.Len() ;
|
||||||
vtEdgeV /= dEdgeLen ;
|
vtEdgeV /= dEdgeLen ;
|
||||||
@@ -111,10 +112,10 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non ho trovato collisioni fra triangoli delle superfici.
|
// Non ho trovato collisioni fra triangoli delle superfici.
|
||||||
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
|
||||||
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
|
||||||
return false ;
|
return false ;
|
||||||
// La collisione c'è se una superficie è dentro l'altra.
|
// La collisione c'è se una superficie è dentro l'altra.
|
||||||
Point3d ptPointA, ptPointB ;
|
Point3d ptPointA, ptPointB ;
|
||||||
pSrfA->GetFirstVertex( ptPointA) ;
|
pSrfA->GetFirstVertex( ptPointA) ;
|
||||||
pSrfB->GetFirstVertex( ptPointB) ;
|
pSrfB->GetFirstVertex( ptPointB) ;
|
||||||
@@ -127,7 +128,7 @@ CDeClosedSurfTmClosedSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& Surf
|
|||||||
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
|
// Verifica l'interferenza tra le due superfici : restituisce true in caso di interferenza.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist)
|
TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double dSafeDist, bool bTestEnclosion)
|
||||||
{
|
{
|
||||||
// Recupero le superfici base
|
// Recupero le superfici base
|
||||||
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
const SurfTriMesh* pSrfA = GetBasicSurfTriMesh( &SurfA) ;
|
||||||
@@ -140,10 +141,10 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
BBox3d b3BoxA, b3BoxB ;
|
BBox3d b3BoxA, b3BoxB ;
|
||||||
pSrfA->GetLocalBBox( b3BoxA) ;
|
pSrfA->GetLocalBBox( b3BoxA) ;
|
||||||
pSrfB->GetLocalBBox( b3BoxB) ;
|
pSrfB->GetLocalBBox( b3BoxB) ;
|
||||||
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
// Se è necessario, espando il box di B di una costante additiva pari alla distanza di sicurezza.
|
||||||
if ( dSafeDist > EPS_SMALL)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxB.Expand( dSafeDist) ;
|
b3BoxB.Expand( dSafeDist) ;
|
||||||
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
|
||||||
if ( ! b3BoxA.Overlaps( b3BoxB))
|
if ( ! b3BoxA.Overlaps( b3BoxB))
|
||||||
return false ;
|
return false ;
|
||||||
// Recupero i triangoli di A che interferiscono col box di B
|
// Recupero i triangoli di A che interferiscono col box di B
|
||||||
@@ -156,13 +157,13 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
continue ;
|
continue ;
|
||||||
BBox3d b3BoxTriaA ;
|
BBox3d b3BoxTriaA ;
|
||||||
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
trTriaA.GetLocalBBox( b3BoxTriaA) ;
|
||||||
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
|
||||||
if ( dSafeDist > EPS_SMALL)
|
if ( dSafeDist > EPS_SMALL)
|
||||||
b3BoxTriaA.Expand( dSafeDist) ;
|
b3BoxTriaA.Expand( dSafeDist) ;
|
||||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
pSrfB->GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
|
||||||
// Settare tutti i triangoli come già processati.
|
// Settare tutti i triangoli come già processati.
|
||||||
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
// Al termine della chiamata i TempInt dei triangoli valgono 0.
|
||||||
pSrfB->ResetTempInts() ;
|
pSrfB->ResetTempInts() ;
|
||||||
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
|
||||||
@@ -179,14 +180,14 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
// Ciclo sui vertici del triangolo.
|
// Ciclo sui vertici del triangolo.
|
||||||
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||||
// Se il triangolo adiacente al triangolo corrente su questo edge
|
// Se il triangolo adiacente al triangolo corrente su questo edge
|
||||||
// non è stato processato, processo il vertice e l'edge.
|
// non è stato processato, processo il vertice e l'edge.
|
||||||
int nAdjTriaTempFlag ;
|
int nAdjTriaTempFlag ;
|
||||||
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
if ( ! ( pSrfB->GetTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
|
||||||
continue ;
|
continue ;
|
||||||
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
|
||||||
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
|
||||||
return true ;
|
return true ;
|
||||||
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
|
||||||
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
Vector3d vtEdgeV = trTriaB.GetP( ( nVB + 1) % 3) - trTriaB.GetP( nVB) ;
|
||||||
double dEdgeLen = vtEdgeV.Len() ;
|
double dEdgeLen = vtEdgeV.Len() ;
|
||||||
vtEdgeV /= dEdgeLen ;
|
vtEdgeV /= dEdgeLen ;
|
||||||
@@ -205,6 +206,25 @@ TestSurfTmSurfTm( const ISurfTriMesh& SurfA, const ISurfTriMesh& SurfB, double d
|
|||||||
pSrfB->SetTempInt( nTB, 1) ;
|
pSrfB->SetTempInt( nTB, 1) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Non c'è interferenza
|
// Se non richiesto test di inclusione, non c'è interferenza
|
||||||
|
if ( ! bTestEnclosion)
|
||||||
|
return false ;
|
||||||
|
// Se la prima superficie è chiusa, verifico se include totalmente la seconda
|
||||||
|
if ( pSrfA->IsClosed() && b3BoxA.Encloses( b3BoxB)) {
|
||||||
|
Point3d ptPointB ;
|
||||||
|
pSrfB->GetFirstVertex( ptPointB) ;
|
||||||
|
DistPointSurfTm DistPoinBSrfA( ptPointB, *pSrfA) ;
|
||||||
|
if ( DistPoinBSrfA.IsPointInside() || DistPoinBSrfA.IsEpsilon( dSafeDist))
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// Se la seconda superficie è chiusa, verifico se include totalmente la prima
|
||||||
|
if ( pSrfB->IsClosed() && b3BoxB.Encloses( b3BoxA)) {
|
||||||
|
Point3d ptPointA ;
|
||||||
|
pSrfA->GetFirstVertex( ptPointA) ;
|
||||||
|
DistPointSurfTm DistPoinASrfB( ptPointA, *pSrfB) ;
|
||||||
|
if ( DistPoinASrfB.IsPointInside() || DistPoinASrfB.IsEpsilon( dSafeDist))
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// Non c'è interferenza
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,233 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2026
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : CalcDerivate.cpp Data : 03.02.26 Versione : 1.5h1
|
||||||
|
// Contenuto : Funzioni per calcolo derivate secondo Bessel e Akima.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 03.02.26 DB Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "CalcDerivate.h"
|
||||||
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||||
|
{
|
||||||
|
// pulisco i vettori dei parametri e delle tangenti
|
||||||
|
vPrevDer.clear() ;
|
||||||
|
vNextDer.clear() ;
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// calcolo le derivate
|
||||||
|
vPrevDer.reserve( nSize) ;
|
||||||
|
vNextDer.reserve( nSize) ;
|
||||||
|
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||||
|
if ( nSize == 2) {
|
||||||
|
// non esiste derivata prima del primo punto
|
||||||
|
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||||
|
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||||
|
vPrevDer.push_back( vNextDer[0]) ;
|
||||||
|
// non esiste derivata dopo il secondo e ultimo punto
|
||||||
|
vNextDer.emplace_back( 0, 0, 0) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||||
|
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||||
|
// calcolo le derivate
|
||||||
|
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||||
|
Vector3d vtPrevDer ;
|
||||||
|
Vector3d vtNextDer ;
|
||||||
|
// primo punto
|
||||||
|
if ( i == 0) {
|
||||||
|
// se curva chiusa, come precedente uso il penultimo punto
|
||||||
|
if ( bClosed) {
|
||||||
|
// se non ci sono almeno 5 punti
|
||||||
|
if ( nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = vtNextDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[nSize-3] - vPar[nSize-1], vPnt[nSize-3], vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// altrimenti, uso arco sui primi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcCircleStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ultimo punto
|
||||||
|
else if ( i == nSize - 1) {
|
||||||
|
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||||
|
if ( bClosed) {
|
||||||
|
vtPrevDer = vPrevDer[0] ;
|
||||||
|
vtNextDer = vNextDer[0] ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso arco sugli ultimi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcCircleEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// punti intermedi
|
||||||
|
else {
|
||||||
|
// se secondo punto
|
||||||
|
if ( i == 1) {
|
||||||
|
// se curva aperta o non ci sono almeno 5 punti
|
||||||
|
if ( ! bClosed || nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se penultimo punto
|
||||||
|
else if ( i == nSize - 2) {
|
||||||
|
// se curva aperta o non ci sono almeno 5 punti
|
||||||
|
if ( ! bClosed || nSize < 5) {
|
||||||
|
if ( ! CalcCircleMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[1] + vPar[i+1], vPnt[1], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
if ( ! CalcAkimaMidDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], bDetectCorner,
|
||||||
|
vtPrevDer, vtNextDer))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// salvo la derivata
|
||||||
|
vPrevDer.push_back( vtPrevDer) ;
|
||||||
|
vNextDer.push_back( vtNextDer) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer)
|
||||||
|
{
|
||||||
|
// pulisco i vettori dei parametri e delle tangenti
|
||||||
|
vPrevDer.clear() ;
|
||||||
|
vNextDer.clear() ;
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// calcolo le derivate
|
||||||
|
vPrevDer.reserve( nSize) ;
|
||||||
|
vNextDer.reserve( nSize) ;
|
||||||
|
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
||||||
|
if ( nSize == 2) {
|
||||||
|
// non esiste derivata prima del primo punto
|
||||||
|
vPrevDer.emplace_back( 0, 0, 0) ;
|
||||||
|
vNextDer.push_back( ( vPnt[1] - vPnt[0]) / ( vPar[1] - vPar[0])) ;
|
||||||
|
vPrevDer.push_back( vNextDer[0]) ;
|
||||||
|
// non esiste derivata dopo il secondo e ultimo punto
|
||||||
|
vNextDer.emplace_back( 0, 0, 0) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
||||||
|
bool bClosed = AreSamePointApprox( vPnt.front(), vPnt.back()) ;
|
||||||
|
// calcolo le derivate
|
||||||
|
for ( int i = 0 ; i < nSize ; ++ i) {
|
||||||
|
Vector3d vtPrevDer ;
|
||||||
|
Vector3d vtNextDer ;
|
||||||
|
// primo punto
|
||||||
|
if ( i == 0) {
|
||||||
|
// se curva chiusa, come precedente uso il penultimo punto
|
||||||
|
if ( bClosed) {
|
||||||
|
if ( ! CalcBesselMidDer( vPar[nSize-2] - vPar[nSize-1], vPnt[nSize-2], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = vtNextDer ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso i primi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselStartDer( vPar[i], vPnt[i], vPar[i+1], vPnt[i+1],
|
||||||
|
vPar[i+2], vPnt[i+2], vtNextDer))
|
||||||
|
return false ;
|
||||||
|
vtPrevDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ultimo punto
|
||||||
|
else if ( i == nSize - 1) {
|
||||||
|
// se curva chiusa, le tg devono coincidere con quelle del primo
|
||||||
|
if ( bClosed) {
|
||||||
|
vtPrevDer = vPrevDer[0] ;
|
||||||
|
vtNextDer = vNextDer[0] ;
|
||||||
|
}
|
||||||
|
// altrimenti, uso gli ultimi tre punti
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselEndDer( vPar[i-2], vPnt[i-2], vPar[i-1], vPnt[i-1],
|
||||||
|
vPar[i], vPnt[i], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = Vector3d( 0, 0, 0) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// punti intermedi
|
||||||
|
else {
|
||||||
|
if ( ! CalcBesselMidDer( vPar[i-1], vPnt[i-1], vPar[i], vPnt[i],
|
||||||
|
vPar[i+1], vPnt[i+1], vtPrevDer))
|
||||||
|
return false ;
|
||||||
|
vtNextDer = vtPrevDer ;
|
||||||
|
}
|
||||||
|
// salvo la derivata
|
||||||
|
vPrevDer.push_back( vtPrevDer) ;
|
||||||
|
vNextDer.push_back( vtNextDer) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumCollection.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -179,3 +181,6 @@ CalcAkimaMidDer( double dU0, const Point3d& ptP0, double dU1, const Point3d& ptP
|
|||||||
}
|
}
|
||||||
return ( ! vtPrevDer.IsZero() && ! vtNextDer.IsZero()) ;
|
return ( ! vtPrevDer.IsZero() && ! vtNextDer.IsZero()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ComputeAkimaTangents( bool bDetectCorner, const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||||
|
bool ComputeBesselTangents( const DBLVECTOR& vPar, const PNTVECTOR& vPnt, VCT3DVECTOR& vPrevDer, VCT3DVECTOR& vNextDer) ;
|
||||||
+2995
-1692
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -16,6 +16,7 @@
|
|||||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
#include "/EgtDev/Include/EGkGeomDB.h"
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
||||||
#include "/EgtDev/Include/EGkCurve.h"
|
#include "/EgtDev/Include/EGkCurve.h"
|
||||||
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
@@ -168,7 +169,7 @@ ChainCurves::GetChainFromPoint( const Point3d& ptStart, const Vector3d& vtStart,
|
|||||||
ptCurr = bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart ;
|
ptCurr = bEquiv ? m_vCrvData[nId].ptEnd : m_vCrvData[nId].ptStart ;
|
||||||
vtCurr = bEquiv ? m_vCrvData[nId].vtEnd : - m_vCrvData[nId].vtStart ;
|
vtCurr = bEquiv ? m_vCrvData[nId].vtEnd : - m_vCrvData[nId].vtStart ;
|
||||||
// verifico se sono arrivato al punto di chiusura
|
// verifico se sono arrivato al punto di chiusura
|
||||||
if ( AreSamePointEpsilon( ptCurr, ptStop, m_dToler)) {
|
if ( AreSamePointEpsilon( ptCurr, ptStop, 0.5 * EPS_SMALL)) {
|
||||||
bStopped = true ;
|
bStopped = true ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,8 @@ static const NamedColor StdColor[] = {
|
|||||||
{ "FUCHSIA", FUCHSIA},
|
{ "FUCHSIA", FUCHSIA},
|
||||||
{ "PURPLE", PURPLE},
|
{ "PURPLE", PURPLE},
|
||||||
{ "ORANGE", ORANGE},
|
{ "ORANGE", ORANGE},
|
||||||
{ "BROWN", BROWN}
|
{ "BROWN", BROWN},
|
||||||
|
{ "INVISIBLE", INVISIBLE}
|
||||||
} ;
|
} ;
|
||||||
static const int NUM_STDCOLOR = ( sizeof(StdColor) / sizeof(StdColor[0]) ) ;
|
static const int NUM_STDCOLOR = ( sizeof(StdColor) / sizeof(StdColor[0]) ) ;
|
||||||
|
|
||||||
@@ -127,7 +128,7 @@ GetHSVFromColor( const Color& cCol)
|
|||||||
hsv.dSat = dDelta / dMax ;
|
hsv.dSat = dDelta / dMax ;
|
||||||
if ( cCol.GetRed() >= dMax) // tra giallo e magenta
|
if ( cCol.GetRed() >= dMax) // tra giallo e magenta
|
||||||
hsv.dHue = ( cCol.GetGreen() - cCol.GetBlue()) / dDelta ;
|
hsv.dHue = ( cCol.GetGreen() - cCol.GetBlue()) / dDelta ;
|
||||||
else if( cCol.GetGreen() >= dMax) // tra ciano e giallo
|
else if ( cCol.GetGreen() >= dMax) // tra ciano e giallo
|
||||||
hsv.dHue = 2.0 + ( cCol.GetBlue() - cCol.GetRed()) / dDelta ;
|
hsv.dHue = 2.0 + ( cCol.GetBlue() - cCol.GetRed()) / dDelta ;
|
||||||
else // tra magenta e ciano
|
else // tra magenta e ciano
|
||||||
hsv.dHue = 4.0 + ( cCol.GetRed() - cCol.GetGreen()) / dDelta ;
|
hsv.dHue = 4.0 + ( cCol.GetRed() - cCol.GetGreen()) / dDelta ;
|
||||||
|
|||||||
+2
-2
@@ -1294,7 +1294,7 @@ CurveArc::Invert( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveArc::SimpleOffset( double dDist, int nType)
|
CurveArc::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||||
{
|
{
|
||||||
// la curva deve essere validata
|
// la curva deve essere validata
|
||||||
if ( m_nStatus != OK)
|
if ( m_nStatus != OK)
|
||||||
@@ -1329,7 +1329,7 @@ CurveArc::SimpleOffset( double dDist, int nType)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveArc::MyExtendedOffset( double dDist, bool bAll, int nType)
|
CurveArc::MyExtendedOffset( double dDist, bool bAll)
|
||||||
{
|
{
|
||||||
// bAll == true fa accettare raggi nulli ==> da usare solo internamente
|
// bAll == true fa accettare raggi nulli ==> da usare solo internamente
|
||||||
// quando si è sicuri di aumentare subito il raggio o di cancellare
|
// quando si è sicuri di aumentare subito il raggio o di cancellare
|
||||||
|
|||||||
+4
-4
@@ -116,7 +116,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
|||||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||||
bool Invert( void) override ;
|
bool Invert( void) override ;
|
||||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||||
@@ -178,8 +178,8 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
|||||||
bool ChangeDeltaN( double dNewDeltaN) override ;
|
bool ChangeDeltaN( double dNewDeltaN) override ;
|
||||||
bool ChangeAngCenter( double dNewAngCenDeg) override ;
|
bool ChangeAngCenter( double dNewAngCenDeg) override ;
|
||||||
bool ChangeStartPoint( double dU) override ;
|
bool ChangeStartPoint( double dU) override ;
|
||||||
bool ExtendedOffset( double dDist, int nType = OFF_FILLET) override
|
bool ExtendedOffset( double dDist) override
|
||||||
{ return MyExtendedOffset( dDist, false, nType) ; }
|
{ return MyExtendedOffset( dDist, false) ; }
|
||||||
bool ToExplementary( void) override ;
|
bool ToExplementary( void) override ;
|
||||||
bool Flip( void) override ;
|
bool Flip( void) override ;
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ class CurveArc : public ICurveArc, public IGeoObjRW
|
|||||||
{ if ( ! CopyFrom( caSrc))
|
{ if ( ! CopyFrom( caSrc))
|
||||||
LOG_ERROR( GetEGkLogger(), "CurveArc : copy error")
|
LOG_ERROR( GetEGkLogger(), "CurveArc : copy error")
|
||||||
return *this ; }
|
return *this ; }
|
||||||
bool MyExtendedOffset( double dDist, bool bAll, int nType = OFF_FILLET) ;
|
bool MyExtendedOffset( double dDist, bool bAll) ;
|
||||||
bool MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, double dLinTol) const ;
|
bool MyCalcPointParamPosiz( const Point3d& ptP, double& dU, int& nPos, double dLinTol) const ;
|
||||||
Voronoi* GetVoronoiObject( void) const ;
|
Voronoi* GetVoronoiObject( void) const ;
|
||||||
void ResetVoronoiObject( void) const ;
|
void ResetVoronoiObject( void) const ;
|
||||||
|
|||||||
+909
-161
File diff suppressed because it is too large
Load Diff
+2
-1
@@ -33,5 +33,6 @@ bool CurveGetArea( const ICurve& crvC, Plane3d& plPlane, double& dArea) ;
|
|||||||
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
bool CurveDump( const ICurve& crvC, std::string& sOut, bool bMM, const char* szNewLine) ;
|
||||||
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
bool CopyExtrusion( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||||
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
bool CopyThickness( const ICurve* pSouCrv, ICurve* pDestCrv) ;
|
||||||
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurveBezier* pCrvBez) ;
|
ICurveBezier* ApproxCurveBezierWithSingleCubic( const ICurve* pCrv) ;
|
||||||
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
Voronoi* GetCurveVoronoi( const ICurve& crvC) ;
|
||||||
|
bool GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert) ;
|
||||||
+136
-47
@@ -93,8 +93,11 @@ CurveBezier::Init( int nDeg, bool bIsRational)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl)
|
||||||
{
|
{
|
||||||
// verifico validità indice
|
// verifico validità indice e punto
|
||||||
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg)
|
if ( m_nStatus != OK || m_bRat || nInd < 0 || nInd > m_nDeg || ! ptCtrl.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
if ( abs( ptCtrl.x) > INFINITO || abs( ptCtrl.y) > INFINITO || abs( ptCtrl.z) > INFINITO)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// assegno il valore
|
// assegno il valore
|
||||||
@@ -123,8 +126,11 @@ CurveBezier::SetControlPoint( int nInd, const Point3d& ptCtrl, double dW)
|
|||||||
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd > m_nDeg)
|
if ( m_nStatus != OK || ! m_bRat || nInd < 0 || nInd > m_nDeg)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico che il peso non sia nullo o negativo
|
// verifico che il punto sia valido e il peso non sia nullo o negativo
|
||||||
if ( dW < EPS_SMALL)
|
if ( ! ptCtrl.IsValid() || dW < EPS_SMALL || ! isfinite( dW) || dW > INFINITO)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
if ( abs( ptCtrl.x) > INFINITO || abs( ptCtrl.y) > INFINITO || abs( ptCtrl.z) > INFINITO)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// assegno il valore e il peso
|
// assegno il valore e il peso
|
||||||
@@ -151,7 +157,7 @@ CurveBezier::SetControlWeight( int nInd, double dW)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico che il peso non sia nullo o negativo
|
// verifico che il peso non sia nullo o negativo
|
||||||
if ( dW < EPS_SMALL)
|
if ( dW < EPS_SMALL || ! isfinite( dW) || dW > INFINITO)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// assegno il valore e il peso
|
// assegno il valore e il peso
|
||||||
@@ -267,22 +273,21 @@ CurveBezier::FromArc( const ICurveArc& crArc)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::FromLine( const ICurveLine& crLine)
|
CurveBezier::FromLine( const ICurveLine& crLine)
|
||||||
{
|
{
|
||||||
if ( ! crLine.IsValid())
|
if ( m_nStatus != OK || ! crLine.IsValid())
|
||||||
return false ;
|
return false ;
|
||||||
double dWeight = 1 ;
|
|
||||||
int nCount = 0 ;
|
int nCount = 0 ;
|
||||||
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
|
Point3d ptStart ; crLine.GetStartPoint( ptStart) ;
|
||||||
SetControlPoint( nCount, ptStart, dWeight) ;
|
SetControlPoint( nCount, ptStart) ;
|
||||||
++nCount ;
|
++nCount ;
|
||||||
double dPart = 1. / m_nDeg ;
|
double dPart = 1. / m_nDeg ;
|
||||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
||||||
double dU = i * dPart ;
|
double dU = i * dPart ;
|
||||||
Point3d ptMid ; crLine.GetPointD1D2( dU, ICurve::FROM_MINUS, ptMid) ;
|
Point3d ptMid ; crLine.GetPointD1D2( dU, ICurve::FROM_MINUS, ptMid) ;
|
||||||
SetControlPoint( nCount, ptMid, dWeight) ;
|
SetControlPoint( nCount, ptMid) ;
|
||||||
++nCount ;
|
++nCount ;
|
||||||
}
|
}
|
||||||
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
|
Point3d ptEnd ; crLine.GetEndPoint( ptEnd) ;
|
||||||
SetControlPoint( nCount, ptEnd, dWeight) ;
|
SetControlPoint( nCount, ptEnd) ;
|
||||||
++nCount ;
|
++nCount ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -367,8 +372,11 @@ CurveBezier::CopyFrom( const CurveBezier& cbSrc)
|
|||||||
{
|
{
|
||||||
if ( &cbSrc == this)
|
if ( &cbSrc == this)
|
||||||
return true ;
|
return true ;
|
||||||
|
if ( ! cbSrc.IsValid())
|
||||||
|
return false ;
|
||||||
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
|
if ( ! Init( cbSrc.m_nDeg, cbSrc.m_bRat))
|
||||||
return false ;
|
return false ;
|
||||||
|
m_dParSing = cbSrc.m_dParSing ;
|
||||||
m_vPtCtrl = cbSrc.m_vPtCtrl ;
|
m_vPtCtrl = cbSrc.m_vPtCtrl ;
|
||||||
if ( cbSrc.m_bRat)
|
if ( cbSrc.m_bRat)
|
||||||
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
m_vWeCtrl = cbSrc.m_vWeCtrl ;
|
||||||
@@ -516,21 +524,21 @@ bool
|
|||||||
CurveBezier::Validate( void)
|
CurveBezier::Validate( void)
|
||||||
{
|
{
|
||||||
if ( m_nStatus == TO_VERIFY) {
|
if ( m_nStatus == TO_VERIFY) {
|
||||||
for ( const auto& ptP : m_vPtCtrl) {
|
for ( const auto& ptP : m_vPtCtrl) {
|
||||||
if ( ! ptP.IsValid()) {
|
if ( ! ptP.IsValid()) {
|
||||||
m_nStatus = ERR ;
|
m_nStatus = ERR ;
|
||||||
break ;
|
break ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ( m_nStatus == TO_VERIFY) {
|
if ( m_nStatus == TO_VERIFY) {
|
||||||
for ( const auto& dWe : m_vWeCtrl) {
|
for ( const auto& dWe : m_vWeCtrl) {
|
||||||
if ( ! isfinite( dWe)) {
|
if ( ! isfinite( dWe)) {
|
||||||
m_nStatus = ERR ;
|
m_nStatus = ERR ;
|
||||||
break ;
|
break ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if ( m_nStatus == TO_VERIFY)
|
if ( m_nStatus == TO_VERIFY)
|
||||||
m_nStatus = ( ( m_nDeg >= 1 && m_vPtCtrl.size() >= 2) ? OK : ERR) ;
|
m_nStatus = ( ( m_nDeg >= 1 && m_vPtCtrl.size() >= 2) ? OK : ERR) ;
|
||||||
|
|
||||||
@@ -1657,6 +1665,10 @@ CurveBezier::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAngTo
|
|||||||
ICurve*
|
ICurve*
|
||||||
CurveBezier::CopyParamRange( double dUStart, double dUEnd) const
|
CurveBezier::CopyParamRange( double dUStart, double dUEnd) const
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
||||||
if ( dUStart < - EPS_PARAM || dUStart > 1 + EPS_PARAM ||
|
if ( dUStart < - EPS_PARAM || dUStart > 1 + EPS_PARAM ||
|
||||||
dUEnd < - EPS_PARAM || dUEnd > 1 + EPS_PARAM)
|
dUEnd < - EPS_PARAM || dUEnd > 1 + EPS_PARAM)
|
||||||
@@ -1799,6 +1811,10 @@ CurveBezier::TrimEndAtParam( double dUTrim)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
// i parametri start ed end devono essere compresi nel dominio parametrico della curva
|
||||||
if ( dUStartTrim < - EPS_PARAM || dUStartTrim > 1 + EPS_PARAM ||
|
if ( dUStartTrim < - EPS_PARAM || dUStartTrim > 1 + EPS_PARAM ||
|
||||||
dUEndTrim < - EPS_PARAM || dUEndTrim > 1 + EPS_PARAM)
|
dUEndTrim < - EPS_PARAM || dUEndTrim > 1 + EPS_PARAM)
|
||||||
@@ -1808,19 +1824,19 @@ CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
|||||||
return false ;
|
return false ;
|
||||||
// se razionale devo trovare il punto di trim iniziale per ricalcolare il parametro di trim
|
// se razionale devo trovare il punto di trim iniziale per ricalcolare il parametro di trim
|
||||||
Point3d ptStart ;
|
Point3d ptStart ;
|
||||||
if( m_bRat)
|
if ( m_bRat)
|
||||||
GetPointD1D2( dUStartTrim, ptStart) ;
|
GetPointD1D2( dUStartTrim, ptStart) ;
|
||||||
// trim finale
|
// trim finale
|
||||||
if ( ! TrimEndAtParam( dUEndTrim))
|
if ( ! TrimEndAtParam( dUEndTrim))
|
||||||
return false ;
|
return false ;
|
||||||
// trim iniziale con il parametro opportunamente ricalcolato
|
// trim iniziale con il parametro opportunamente ricalcolato
|
||||||
double dNewUStartTrim ;
|
double dNewUStartTrim ;
|
||||||
if( m_bRat)
|
if ( m_bRat)
|
||||||
GetParamAtPoint( ptStart, dNewUStartTrim) ;
|
GetParamAtPoint( ptStart, dNewUStartTrim) ;
|
||||||
else
|
else
|
||||||
dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
dNewUStartTrim = dUStartTrim / dUEndTrim ;
|
||||||
//trim iniziale
|
//trim iniziale
|
||||||
if( ! TrimStartAtParam( dNewUStartTrim))
|
if ( ! TrimStartAtParam( dNewUStartTrim))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -1830,6 +1846,10 @@ CurveBezier::TrimStartEndAtParam( double dUStartTrim, double dUEndTrim)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::TrimStartAtLen( double dLenTrim)
|
CurveBezier::TrimStartAtLen( double dLenTrim)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// lunghezze negative vengono considerate nulle
|
// lunghezze negative vengono considerate nulle
|
||||||
dLenTrim = max( dLenTrim, 0.) ;
|
dLenTrim = max( dLenTrim, 0.) ;
|
||||||
|
|
||||||
@@ -1839,7 +1859,7 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// utilizzo il trim sui parametri
|
// utilizzo il trim sui parametri
|
||||||
if( ! TrimStartAtParam( dUTrim))
|
if ( ! TrimStartAtParam( dUTrim))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -1849,6 +1869,10 @@ CurveBezier::TrimStartAtLen( double dLenTrim)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::TrimEndAtLen( double dLenTrim)
|
CurveBezier::TrimEndAtLen( double dLenTrim)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// lunghezze negative vengono considerate nulle
|
// lunghezze negative vengono considerate nulle
|
||||||
dLenTrim = max( dLenTrim, 0.) ;
|
dLenTrim = max( dLenTrim, 0.) ;
|
||||||
|
|
||||||
@@ -1858,7 +1882,7 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// utilizzo il trim sui parametri
|
// utilizzo il trim sui parametri
|
||||||
if( ! TrimEndAtParam( dUTrim))
|
if ( ! TrimEndAtParam( dUTrim))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -1868,6 +1892,10 @@ CurveBezier::TrimEndAtLen( double dLenTrim)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::ExtendStartByLen( double dLenExt)
|
CurveBezier::ExtendStartByLen( double dLenExt)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// la lunghezza deve essere positiva
|
// la lunghezza deve essere positiva
|
||||||
if ( dLenExt < - EPS_ZERO)
|
if ( dLenExt < - EPS_ZERO)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -1919,6 +1947,10 @@ CurveBezier::ExtendStartByLen( double dLenExt)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::ExtendEndByLen( double dLenExt)
|
CurveBezier::ExtendEndByLen( double dLenExt)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// la lunghezza deve essere positiva
|
// la lunghezza deve essere positiva
|
||||||
if ( dLenExt < - EPS_ZERO)
|
if ( dLenExt < - EPS_ZERO)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -2258,6 +2290,10 @@ CurveBezier::ResetVoronoiObject() const
|
|||||||
bool
|
bool
|
||||||
CurveBezier::MakeRational( void)
|
CurveBezier::MakeRational( void)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
if ( m_bRat)
|
if ( m_bRat)
|
||||||
return true ;
|
return true ;
|
||||||
// creo il vettore dei pesi e li setto tutti a 1
|
// creo il vettore dei pesi e li setto tutti a 1
|
||||||
@@ -2272,19 +2308,23 @@ CurveBezier::MakeRational( void)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::MakeRationalStandardForm( void)
|
CurveBezier::MakeRationalStandardForm( void)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
if ( ! m_bRat)
|
if ( ! m_bRat)
|
||||||
return false ;
|
return false ;
|
||||||
double dW0 = m_vWeCtrl[0] ;
|
double dW0 = m_vWeCtrl.front() ;
|
||||||
double dWn = m_vWeCtrl.back() ;
|
double dWn = m_vWeCtrl.back() ;
|
||||||
if( dW0 > 1- EPS_ZERO && dWn > 1 - EPS_ZERO)
|
if ( dW0 > 1 - EPS_ZERO && dWn > 1 - EPS_ZERO)
|
||||||
return true ;
|
return true ;
|
||||||
if( dW0 < EPS_ZERO || dWn < EPS_ZERO)
|
if ( dW0 < EPS_ZERO || dWn < EPS_ZERO)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// formula del Farin
|
// formula del Farin
|
||||||
double dCoeff = pow( dW0 / dWn, 1. / m_nDeg) ;
|
double dCoeff = pow( dW0 / dWn, 1. / m_nDeg) ;
|
||||||
for ( int i = 0 ; i < m_nDeg + 1 ; ++i)
|
for ( int i = 0 ; i < m_nDeg + 1 ; ++i)
|
||||||
m_vWeCtrl[i] *= pow( dCoeff, i) / dW0 ;
|
m_vWeCtrl[i] *= Pow( dCoeff, i) / dW0 ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -2293,13 +2333,17 @@ CurveBezier::MakeRationalStandardForm( void)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::MakeNonRational( double dTol)
|
CurveBezier::MakeNonRational( double dTol)
|
||||||
{
|
{
|
||||||
if( ! m_bRat)
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
if ( ! m_bRat)
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
// controllo se i pesi sono tutti == 1 allora è una finta razionale e mi basta fare una copia dei punti di controllo
|
// controllo se i pesi sono tutti == 1 allora è una finta razionale e mi basta fare una copia dei punti di controllo
|
||||||
bool bIsActualRat = false ;
|
bool bIsActualRat = false ;
|
||||||
for ( int i = 0 ; i < m_nDeg ; ++i) {
|
for ( int i = 0 ; i < m_nDeg ; ++i) {
|
||||||
if ( abs(m_vWeCtrl[i] - 1) > EPS_SMALL) {
|
if ( abs( m_vWeCtrl[i] - 1) > EPS_SMALL) {
|
||||||
bIsActualRat = true ;
|
bIsActualRat = true ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -2307,15 +2351,44 @@ CurveBezier::MakeNonRational( double dTol)
|
|||||||
|
|
||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
if ( ! bIsActualRat) {
|
if ( ! bIsActualRat) {
|
||||||
PtrOwner<CurveBezier> pNewBez( CreateBasicCurveBezier()) ;
|
// semplicemente tolgo il booleano della razionalità e i punti restano gli stessi
|
||||||
for ( int p = 0 ; p < m_nDeg ; ++p) {
|
m_bRat = false ;
|
||||||
Point3d pt = GetControlPoint( p) ;
|
|
||||||
pNewBez->SetControlPoint( p, pt) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// provo ad approssimare la curva di bezier con una controparte non razionale
|
// provo ad approssimare la curva di bezier con una controparte non razionale
|
||||||
int nDeg = m_nDeg ;
|
int nDeg = m_nDeg ;
|
||||||
|
// se ho una curva razionale di grado 2 verifico se è un arco, in quel caso la converto in una curva di grado 3 non razionale con la funzione dedicata
|
||||||
|
if ( nDeg == 2 && m_bRat) {
|
||||||
|
// prendo due punti sulla curva e calcolo l'intersezione dei due assi dei segmenti formati da pt2-pt0 e pt3-pt1
|
||||||
|
Point3d pt0 ; GetStartPoint( pt0) ;
|
||||||
|
Point3d pt1 ; GetPointD1D2( 0.3, pt1) ;
|
||||||
|
Point3d pt2 ; GetPointD1D2( 0.6, pt2) ;
|
||||||
|
Point3d pt3 ; GetEndPoint( pt3) ;
|
||||||
|
|
||||||
|
Vector3d vtDir1 = pt2 - pt0 ;
|
||||||
|
Vector3d vtDir2 = pt3 - pt1 ;
|
||||||
|
Vector3d vtN = vtDir2 ^ vtDir1 ;
|
||||||
|
|
||||||
|
CurveLine cl1 ; cl1.Set( pt1, pt1 + (vtDir1 ^ vtN) * 5) ;
|
||||||
|
CurveLine cl2 ; cl1.Set( pt2, pt2 + (vtDir2 ^ vtN) * 5) ;
|
||||||
|
IntersLineLine ill( cl1, cl2, false) ;
|
||||||
|
IntCrvCrvInfo iccInfo ; ill.GetIntCrvCrvInfo( iccInfo) ;
|
||||||
|
Point3d ptCen = iccInfo.IciA[0].ptI ;
|
||||||
|
|
||||||
|
// se sia l'inizio che la fine della curva distano uguale dal punto di intersezione tra i due assi trovati allora la curva è un arco di circonferenza
|
||||||
|
if ( abs(Dist( pt0, ptCen) - Dist( pt3, ptCen)) < EPS_SMALL) {
|
||||||
|
PtrOwner<ICurveBezier> pNew ( ApproxArcCurveBezierWithSingleCubic( this, ptCen, vtN)) ;
|
||||||
|
|
||||||
|
if ( IsNull( pNew) || ! pNew->IsValid())
|
||||||
|
return false ;
|
||||||
|
Init( 3, false) ;
|
||||||
|
for ( int i = 0 ; i < 3 ; ++i)
|
||||||
|
SetControlPoint( i, pNew->GetControlPoint(i)) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// punto di rientro in caso fallisca il primo tentativo
|
// punto di rientro in caso fallisca il primo tentativo
|
||||||
retry :
|
retry :
|
||||||
nDeg += 2 ;
|
nDeg += 2 ;
|
||||||
@@ -2323,8 +2396,8 @@ CurveBezier::MakeNonRational( double dTol)
|
|||||||
pNewBez->Init( nDeg, false) ;
|
pNewBez->Init( nDeg, false) ;
|
||||||
PNTVECTOR vPntCtrl ;
|
PNTVECTOR vPntCtrl ;
|
||||||
PNTVECTOR vPntSampling ;
|
PNTVECTOR vPntSampling ;
|
||||||
for ( int p = 0 ; p < nDeg + 1; ++p) {
|
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
||||||
Point3d pt ; GetPointD1D2( double(p) / nDeg, pt) ;
|
Point3d pt ; GetPointD1D2( double( p) / nDeg, pt) ;
|
||||||
pNewBez->SetControlPoint( p, pt) ;
|
pNewBez->SetControlPoint( p, pt) ;
|
||||||
vPntCtrl.push_back( pt) ;
|
vPntCtrl.push_back( pt) ;
|
||||||
}
|
}
|
||||||
@@ -2334,11 +2407,11 @@ CurveBezier::MakeNonRational( double dTol)
|
|||||||
while ( dErr > dTol && c < 100) {
|
while ( dErr > dTol && c < 100) {
|
||||||
double dErrMax = 0 ;
|
double dErrMax = 0 ;
|
||||||
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
// calcolo le differenze tra i punti di sampling sulla nuova curva e quelli sulla curva originale
|
||||||
for ( int p = 0 ; p < nDeg + 1; ++p) {
|
for ( int p = 0 ; p < nDeg + 1 ; ++p) {
|
||||||
Point3d pt ; pNewBez->GetPointD1D2( double(p) / nDeg, pt) ;
|
Point3d pt ; pNewBez->GetPointD1D2( double( p) / nDeg, pt) ;
|
||||||
Vector3d vDiff = vPntSampling[p] - pt ;
|
Vector3d vDiff = vPntSampling[p] - pt ;
|
||||||
double dErrLoc = vDiff.Len() ;
|
double dErrLoc = vDiff.Len() ;
|
||||||
if( dErrLoc > dErrMax)
|
if ( dErrLoc > dErrMax)
|
||||||
dErrMax = dErrLoc ;
|
dErrMax = dErrLoc ;
|
||||||
// aggiorno il vettore dei punti di controllo della nuova curva
|
// aggiorno il vettore dei punti di controllo della nuova curva
|
||||||
vPntCtrl[p] += vDiff ;
|
vPntCtrl[p] += vDiff ;
|
||||||
@@ -2351,17 +2424,17 @@ CurveBezier::MakeNonRational( double dTol)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// calcolo l'errore di approssimazione sulla curva
|
// calcolo l'errore di approssimazione sulla curva
|
||||||
CalcBezierApproxError( this, pNewBez, dErr) ;
|
CalcApproxError( this, pNewBez, dErr) ;
|
||||||
bOk = dErr < dTol ;
|
bOk = dErr < dTol ;
|
||||||
if( bOk) {
|
if ( bOk) {
|
||||||
// aggiorno la curva di bezier originale con quella approssimata
|
// aggiorno la curva di bezier originale con quella approssimata
|
||||||
Init( nDeg, false) ;
|
Init( nDeg, false) ;
|
||||||
for( int i = 0 ; i < nDeg + 1 ; ++i) {
|
for ( int i = 0 ; i < nDeg + 1 ; ++i) {
|
||||||
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
SetControlPoint( i, pNewBez->GetControlPoint( i)) ;
|
||||||
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
SetControlWeight( i, pNewBez->GetControlWeight( i)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( nDeg < m_nDeg + 4)
|
else if ( nDeg < m_nDeg + 4)
|
||||||
goto retry ;
|
goto retry ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2372,14 +2445,30 @@ CurveBezier::MakeNonRational( double dTol)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::IsALine( void) const
|
CurveBezier::IsALine( void) const
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
Point3d ptStart ; GetStartPoint( ptStart) ;
|
Point3d ptStart ; GetStartPoint( ptStart) ;
|
||||||
Point3d ptEnd ; GetEndPoint( ptEnd) ;
|
Point3d ptEnd ; GetEndPoint( ptEnd) ;
|
||||||
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
for ( int i = 1 ; i < m_nDeg ; ++i) {
|
||||||
Point3d ptCtrl = GetControlPoint( i) ;
|
Point3d ptCtrl = GetControlPoint( i) ;
|
||||||
DistPointLine dpl( ptCtrl, ptStart, ptEnd) ;
|
DistPointLine dpl( ptCtrl, ptStart, ptEnd) ;
|
||||||
double dDist = 0 ; dpl.GetDist( dDist) ;
|
double dDist = 0 ; dpl.GetDist( dDist) ;
|
||||||
if( dDist > EPS_SMALL)
|
if ( dDist > EPS_SMALL)
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
PNTVECTOR
|
||||||
|
CurveBezier::GetAllControlPoints( void) const
|
||||||
|
{
|
||||||
|
PNTVECTOR vPntCtrl ;
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return vPntCtrl ;
|
||||||
|
|
||||||
|
return m_vPtCtrl ;
|
||||||
|
}
|
||||||
+2
-1
@@ -116,7 +116,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
|||||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||||
bool Invert( void) override ;
|
bool Invert( void) override ;
|
||||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override
|
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override
|
||||||
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
|
{ return false ; } // l'offset di crvBezier non è crvBezier tranne in casi molto particolari
|
||||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||||
@@ -153,6 +153,7 @@ class CurveBezier : public ICurveBezier, public IGeoObjRW
|
|||||||
bool MakeRationalStandardForm( void) override ;
|
bool MakeRationalStandardForm( void) override ;
|
||||||
bool MakeNonRational( double dTol) override ;
|
bool MakeNonRational( double dTol) override ;
|
||||||
bool IsALine( void) const override ;
|
bool IsALine( void) const override ;
|
||||||
|
PNTVECTOR GetAllControlPoints( void) const ; // non aggiunta in interfaccia
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
|
|||||||
+7
-203
@@ -202,213 +202,14 @@ CurveByApprox::CalcParameterization( void)
|
|||||||
bool
|
bool
|
||||||
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
CurveByApprox::CalcAkimaTangents( bool bDetectCorner)
|
||||||
{
|
{
|
||||||
// pulisco i vettori delle tangenti
|
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
// se non ci sono almeno 5 punti
|
|
||||||
if ( nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sui primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sugli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
// se secondo punto
|
|
||||||
if ( i == 1) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se penultimo punto
|
|
||||||
else if ( i == nSize - 2) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveByApprox::CalcBesselTangents( void)
|
CurveByApprox::CalcBesselTangents( void)
|
||||||
{
|
{
|
||||||
// pulisco i vettori delle tangenti
|
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso i primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso gli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -502,8 +303,9 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
m_vPrevDer[nI].ToSpherical( nullptr, nullptr, &dDir1Deg) ;
|
||||||
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
// costruisco un biarco sulla polilinea (secondo metodo di Z. Sir)
|
||||||
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
pCrv.Set( GetBiArc( ptP0, dDir0Deg, ptP1, dDir1Deg, PL, dMaxDist, dLinTol)) ;
|
||||||
|
// forzo la spezzatura della curva
|
||||||
if ( IsNull( pCrv))
|
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) {
|
else if ( PL.GetPointNbr() == 2) {
|
||||||
@@ -524,13 +326,15 @@ CurveByApprox::BiArcOrSplit( int nLev, PolyLine& PL, double dLinTol, double dAng
|
|||||||
|
|
||||||
// se raggiunto il massimo livello di recursione, forzo l'accettazione del biarco
|
// se raggiunto il massimo livello di recursione, forzo l'accettazione del biarco
|
||||||
if ( nLev >= MAX_LEV) {
|
if ( nLev >= MAX_LEV) {
|
||||||
|
if ( IsNull( pCrv))
|
||||||
|
return false ;
|
||||||
dMaxDist = 0 ;
|
dMaxDist = 0 ;
|
||||||
// segnalo situazione per debug
|
// segnalo situazione per debug
|
||||||
if ( GetEGkDebugLev() >= 5)
|
if ( GetEGkDebugLev() >= 5)
|
||||||
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Exceeded recursions")
|
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 ;
|
double dLen ;
|
||||||
if ( PL.GetApproxLength( dLen) && dLen < 10 * EPS_SMALL)
|
if ( PL.GetApproxLength( dLen) && dLen < 10 * EPS_SMALL)
|
||||||
dMaxDist = 0 ;
|
dMaxDist = 0 ;
|
||||||
|
|||||||
+34
-225
@@ -50,7 +50,37 @@ CurveByInterp::AddPoint( const Point3d& ptP)
|
|||||||
ICurve*
|
ICurve*
|
||||||
CurveByInterp::GetCurve( int nMethod, int nType)
|
CurveByInterp::GetCurve( int nMethod, int nType)
|
||||||
{
|
{
|
||||||
// calcolo le tangenti
|
// se richieste curve di Bezier cubiche (ottenute da interpolazione con Nurbs)
|
||||||
|
if ( nType == CUBIC_BEZIERS_LONG) {
|
||||||
|
// creo la curva composita
|
||||||
|
PtrOwner<ICurve> pCrv ;
|
||||||
|
//pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 50 * EPS_SMALL, 50)) ;
|
||||||
|
//debug
|
||||||
|
pCrv.Set( InterpolatePointSetWithBezier( m_vPnt, 0.1, 100)) ;
|
||||||
|
if ( IsNull(pCrv) || ! pCrv->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
return Release( pCrv) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// numero di punti
|
||||||
|
int nSize = int( m_vPnt.size()) ;
|
||||||
|
|
||||||
|
// sono necessari almeno due punti
|
||||||
|
if ( nSize < 2)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// calcolo le distanze tra i punti per derivarne i parametri
|
||||||
|
m_vPar.reserve( nSize) ;
|
||||||
|
double dPar = 0 ;
|
||||||
|
m_vPar.push_back( dPar) ;
|
||||||
|
|
||||||
|
for ( int i = 1 ; i < nSize ; ++ i) {
|
||||||
|
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
||||||
|
dPar += dDist ;
|
||||||
|
m_vPar.push_back( dPar) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// calcolo le tangenti
|
||||||
if ( nMethod == BESSEL) {
|
if ( nMethod == BESSEL) {
|
||||||
if ( ! CalcBesselTangents())
|
if ( ! CalcBesselTangents())
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
@@ -110,233 +140,12 @@ CurveByInterp::GetCurve( int nMethod, int nType)
|
|||||||
bool
|
bool
|
||||||
CurveByInterp::CalcAkimaTangents( bool bDetectCorner)
|
CurveByInterp::CalcAkimaTangents( bool bDetectCorner)
|
||||||
{
|
{
|
||||||
// pulisco i vettori dei parametri e delle tangenti
|
return ComputeAkimaTangents( bDetectCorner, m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPar.clear() ;
|
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le distanze tra i punti per derivarne i parametri
|
|
||||||
m_vPar.reserve( nSize) ;
|
|
||||||
double dPar = 0 ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
|
||||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
|
||||||
dPar += dDist ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
// se non ci sono almeno 5 punti
|
|
||||||
if ( nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-3] - m_vPar[nSize-1], m_vPnt[nSize-3], m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sui primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso arco sugli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcCircleEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
// se secondo punto
|
|
||||||
if ( i == 1) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// se penultimo punto
|
|
||||||
else if ( i == nSize - 2) {
|
|
||||||
// se curva aperta o non ci sono almeno 5 punti
|
|
||||||
if ( ! bClosed || nSize < 5) {
|
|
||||||
if ( ! CalcCircleMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[1] + m_vPar[i+1], m_vPnt[1], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// altrimenti
|
|
||||||
else {
|
|
||||||
if ( ! CalcAkimaMidDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], bDetectCorner,
|
|
||||||
vtPrevDer, vtNextDer))
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveByInterp::CalcBesselTangents( void)
|
CurveByInterp::CalcBesselTangents( void)
|
||||||
{
|
{
|
||||||
// pulisco i vettori dei parametri e delle tangenti
|
return ComputeBesselTangents( m_vPar, m_vPnt, m_vPrevDer, m_vNextDer) ;
|
||||||
m_vPar.clear() ;
|
}
|
||||||
m_vPrevDer.clear() ;
|
|
||||||
m_vNextDer.clear() ;
|
|
||||||
|
|
||||||
// numero di punti
|
|
||||||
int nSize = int( m_vPnt.size()) ;
|
|
||||||
|
|
||||||
// sono necessari almeno due punti
|
|
||||||
if ( nSize < 2)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// calcolo le distanze tra i punti per derivarne i parametri
|
|
||||||
m_vPar.reserve( nSize) ;
|
|
||||||
double dPar = 0 ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
for ( int i = 1 ; i < nSize ; ++ i) {
|
|
||||||
double dDist = Dist( m_vPnt[i-1], m_vPnt[i]) ;
|
|
||||||
dPar += dDist ;
|
|
||||||
m_vPar.push_back( dPar) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// calcolo le derivate
|
|
||||||
m_vPrevDer.reserve( nSize) ;
|
|
||||||
m_vNextDer.reserve( nSize) ;
|
|
||||||
// se ci sono solo 2 punti, le tangenti devono essere dirette lungo la linea che li unisce
|
|
||||||
if ( nSize == 2) {
|
|
||||||
// non esiste derivata prima del primo punto
|
|
||||||
m_vPrevDer.emplace_back( 0, 0, 0) ;
|
|
||||||
m_vNextDer.push_back( ( m_vPnt[1] - m_vPnt[0]) / ( m_vPar[1] - m_vPar[0])) ;
|
|
||||||
m_vPrevDer.push_back( m_vNextDer[0]) ;
|
|
||||||
// non esiste derivata dopo il secondo e ultimo punto
|
|
||||||
m_vNextDer.emplace_back( 0, 0, 0) ;
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
// verifico se curva chiusa (primo e ultimo punto coincidono)
|
|
||||||
bool bClosed = AreSamePointApprox( m_vPnt.front(), m_vPnt.back()) ;
|
|
||||||
// calcolo le derivate
|
|
||||||
for ( int i = 0 ; i < nSize ; ++ i) {
|
|
||||||
Vector3d vtPrevDer ;
|
|
||||||
Vector3d vtNextDer ;
|
|
||||||
// primo punto
|
|
||||||
if ( i == 0) {
|
|
||||||
// se curva chiusa, come precedente uso il penultimo punto
|
|
||||||
if ( bClosed) {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[nSize-2] - m_vPar[nSize-1], m_vPnt[nSize-2], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = vtNextDer ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso i primi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselStartDer( m_vPar[i], m_vPnt[i], m_vPar[i+1], m_vPnt[i+1],
|
|
||||||
m_vPar[i+2], m_vPnt[i+2], vtNextDer))
|
|
||||||
return false ;
|
|
||||||
vtPrevDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ultimo punto
|
|
||||||
else if ( i == nSize - 1) {
|
|
||||||
// se curva chiusa, le tg devono coincidere con quelle del primo
|
|
||||||
if ( bClosed) {
|
|
||||||
vtPrevDer = m_vPrevDer[0] ;
|
|
||||||
vtNextDer = m_vNextDer[0] ;
|
|
||||||
}
|
|
||||||
// altrimenti, uso gli ultimi tre punti
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselEndDer( m_vPar[i-2], m_vPnt[i-2], m_vPar[i-1], m_vPnt[i-1],
|
|
||||||
m_vPar[i], m_vPnt[i], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = Vector3d( 0, 0, 0) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// punti intermedi
|
|
||||||
else {
|
|
||||||
if ( ! CalcBesselMidDer( m_vPar[i-1], m_vPnt[i-1], m_vPar[i], m_vPnt[i],
|
|
||||||
m_vPar[i+1], m_vPnt[i+1], vtPrevDer))
|
|
||||||
return false ;
|
|
||||||
vtNextDer = vtPrevDer ;
|
|
||||||
}
|
|
||||||
// salvo la derivata
|
|
||||||
m_vPrevDer.push_back( vtPrevDer) ;
|
|
||||||
m_vNextDer.push_back( vtNextDer) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
+245
-40
@@ -192,7 +192,7 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// verifico lo stato
|
// 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 ;
|
return false ;
|
||||||
|
|
||||||
// controllo la tolleranza
|
// controllo la tolleranza
|
||||||
@@ -224,8 +224,11 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
// lunghezza della curva originale
|
// lunghezza della curva originale
|
||||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||||
// eseguo modifica
|
// eseguo modifica
|
||||||
if ( ! pCrv->ModifyStart( ptEnd))
|
if ( ! pCrv->ModifyStart( ptEnd)) {
|
||||||
return false ;
|
CurveLine crvLine ;
|
||||||
|
if ( ! crvLine.Set( ptEnd, ptCrvEnd) || ! pCrv.Set( crvLine.Clone()))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
// verifico che la lunghezza non sia variata troppo
|
// verifico che la lunghezza non sia variata troppo
|
||||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||||
@@ -246,8 +249,11 @@ CurveComposite::AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart, double dLinT
|
|||||||
// lunghezza della curva originale
|
// lunghezza della curva originale
|
||||||
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
double dOldLen ; pCrv->GetLength( dOldLen) ;
|
||||||
// eseguo modifica
|
// eseguo modifica
|
||||||
if ( ! pCrv->ModifyEnd( ptStart))
|
if ( ! pCrv->ModifyEnd( ptStart)) {
|
||||||
return false ;
|
CurveLine crvLine ;
|
||||||
|
if ( ! crvLine.Set( ptCrvStart, ptStart) || ! pCrv.Set( crvLine.Clone()))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
// verifico che la lunghezza non sia variata troppo
|
// verifico che la lunghezza non sia variata troppo
|
||||||
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
double dNewLen ; pCrv->GetLength( dNewLen) ;
|
||||||
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
if ( abs( dNewLen - dOldLen) > 10 * dLinTol)
|
||||||
@@ -375,9 +381,10 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// ciclo di inserimento dei segmenti che uniscono i punti
|
// ciclo di inserimento dei segmenti che uniscono i punti
|
||||||
|
double dParIni, dParFin ;
|
||||||
Point3d ptIni, ptFin ;
|
Point3d ptIni, ptFin ;
|
||||||
PL.GetFirstPoint( ptIni) ;
|
PL.GetFirstUPoint( &dParIni, &ptIni) ;
|
||||||
while ( PL.GetNextPoint( ptFin)) {
|
while ( PL.GetNextUPoint( &dParFin, &ptFin)) {
|
||||||
// se i punti della coppia coincidono, passo alla coppia successiva
|
// se i punti della coppia coincidono, passo alla coppia successiva
|
||||||
if ( AreSamePointApprox( ptIni, ptFin))
|
if ( AreSamePointApprox( ptIni, ptFin))
|
||||||
continue ;
|
continue ;
|
||||||
@@ -388,10 +395,14 @@ CurveComposite::FromPolyLine( const PolyLine& PL)
|
|||||||
// assegno i punti estremi
|
// assegno i punti estremi
|
||||||
if ( ! pCrvLine->Set( ptIni, ptFin))
|
if ( ! pCrvLine->Set( ptIni, ptFin))
|
||||||
return false ;
|
return false ;
|
||||||
|
// assegno i parametri degli estremi
|
||||||
|
pCrvLine->SetTempParam( dParIni, 0) ;
|
||||||
|
pCrvLine->SetTempParam( dParFin, 1) ;
|
||||||
// aggiungo la retta alla curva composita
|
// aggiungo la retta alla curva composita
|
||||||
if ( ! AddSimpleCurve( Release( pCrvLine)))
|
if ( ! AddSimpleCurve( Release( pCrvLine)))
|
||||||
return false ;
|
return false ;
|
||||||
// aggiorno dati prossimo punto iniziale
|
// aggiorno dati prossimo punto iniziale
|
||||||
|
dParIni = dParFin ;
|
||||||
ptIni = ptFin ;
|
ptIni = ptFin ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -878,14 +889,21 @@ CurveComposite::Validate( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveComposite::TestClosure( void)
|
CurveComposite::TestClosure( double dLinTol)
|
||||||
{
|
{
|
||||||
// se non è chiusa, esco subito
|
// se non valida o vuota, esco subito
|
||||||
if ( ! IsClosed())
|
if ( m_nStatus != OK || m_CrvSmplS.empty())
|
||||||
|
return true ;
|
||||||
|
// se non è chiusa entro la tolleranza, esco subito
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
if ( ! m_CrvSmplS.front()->GetStartPoint( ptStart) ||
|
||||||
|
! m_CrvSmplS.back()->GetEndPoint( ptEnd) ||
|
||||||
|
! AreSamePointEpsilon( ptStart, ptEnd, dLinTol))
|
||||||
|
return true ;
|
||||||
|
// se singola retta, esco subito
|
||||||
|
if ( m_CrvSmplS.size() == 1 && m_CrvSmplS.front()->GetType() == CRV_LINE)
|
||||||
return true ;
|
return true ;
|
||||||
// verifico ed eventualmente aggiusto coincidenza punti estremi
|
// verifico ed eventualmente aggiusto coincidenza punti estremi
|
||||||
Point3d ptStart ; m_CrvSmplS.front()->GetStartPoint( ptStart) ;
|
|
||||||
Point3d ptEnd ; m_CrvSmplS.back()->GetEndPoint( ptEnd) ;
|
|
||||||
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
// se distanza superiore al limite ridotto forzo i punti a coincidere
|
||||||
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
|
if ( ! AreSamePointEpsilon( ptStart, ptEnd, EPS_CONNECT)) {
|
||||||
// se un solo arco
|
// se un solo arco
|
||||||
@@ -1696,7 +1714,7 @@ CurveComposite::Invert( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveComposite::SimpleOffset( double dDist, int nType)
|
CurveComposite::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||||
{
|
{
|
||||||
// se distanza di offset nulla, non devo fare alcunché
|
// se distanza di offset nulla, non devo fare alcunché
|
||||||
if ( abs( dDist) < EPS_SMALL)
|
if ( abs( dDist) < EPS_SMALL)
|
||||||
@@ -1718,7 +1736,7 @@ CurveComposite::SimpleOffset( double dDist, int nType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eseguo l'offset nel piano XY
|
// eseguo l'offset nel piano XY
|
||||||
bool bOk = SimpleOffsetXY( dDist, nType) ;
|
bool bOk = SimpleOffsetXY( dDist, nType, dMaxAngExt) ;
|
||||||
|
|
||||||
// riporto la curva nel riferimento originale
|
// riporto la curva nel riferimento originale
|
||||||
if ( bNeedRef)
|
if ( bNeedRef)
|
||||||
@@ -1778,10 +1796,11 @@ bool
|
|||||||
CurveComposite::AddPoint( const Point3d& ptStart)
|
CurveComposite::AddPoint( const Point3d& ptStart)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != TO_VERIFY)
|
if ( m_nStatus != TO_VERIFY && m_nStatus != IS_A_POINT)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno il punto
|
// assegno il punto e setto lo stato
|
||||||
m_ptStart = ptStart ;
|
m_ptStart = ptStart ;
|
||||||
|
m_nStatus = IS_A_POINT ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -1825,7 +1844,7 @@ bool
|
|||||||
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
CurveComposite::AddLine( const Point3d& ptNew, bool bEndOrStart)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK && m_nStatus != TO_VERIFY)
|
if ( m_nStatus != OK && m_nStatus != IS_A_POINT)
|
||||||
return false ;
|
return false ;
|
||||||
// costruisco la linea
|
// costruisco la linea
|
||||||
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
PtrOwner<CurveLine> pLine( CreateBasicCurveLine()) ;
|
||||||
@@ -1948,7 +1967,120 @@ CurveComposite::AddJoint( double dU)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint, double dTol)
|
||||||
|
{
|
||||||
|
int nCrvCount = GetCurveCount() ;
|
||||||
|
// verifico l'indice della giunzione
|
||||||
|
if ( nU < 0 || nU > nCrvCount)
|
||||||
|
return false ;
|
||||||
|
// salvo le vecchie curve e nel caso le ripristino
|
||||||
|
int nPrevCrv = -1 ;
|
||||||
|
// recupero l'indice e il puntatore alla curva precedente (se esiste)
|
||||||
|
if ( nU >= 0)
|
||||||
|
nPrevCrv = nU - 1 ;
|
||||||
|
else if ( IsClosed())
|
||||||
|
nPrevCrv = nCrvCount - 1 ;
|
||||||
|
PtrOwner<CurveComposite> pOrigCrv( CreateBasicCurveComposite()) ;
|
||||||
|
if ( nPrevCrv >= 0)
|
||||||
|
pOrigCrv->AddCurve( m_CrvSmplS[ nPrevCrv]->Clone()) ;
|
||||||
|
// recupero il puntatore alla curva successiva (se esiste)
|
||||||
|
int nNextCrv = -1 ;
|
||||||
|
if ( nU < nCrvCount)
|
||||||
|
nNextCrv = nU ;
|
||||||
|
else if ( IsClosed())
|
||||||
|
nNextCrv = 0 ;
|
||||||
|
else
|
||||||
|
nNextCrv = - 1 ;
|
||||||
|
if ( nNextCrv >= 0)
|
||||||
|
pOrigCrv->AddCurve( m_CrvSmplS[ nNextCrv]->Clone()) ;
|
||||||
|
|
||||||
|
int nCrvNmbr = GetCurveCount() ;
|
||||||
|
int nFlagDel = DeletedCurve::NONE ;
|
||||||
|
if ( ! ModifyJoint( nU, ptNewJoint, &nFlagDel))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
bool bErasedSomeCrv = nCrvCount > GetCurveCount() ;
|
||||||
|
bool bErasedPrev = ( nFlagDel == DeletedCurve::PREV) ;
|
||||||
|
bool bErasedNext = ( nFlagDel == DeletedCurve::NEXT) ;
|
||||||
|
if ( ( bErasedPrev && nNextCrv == -1) || ( bErasedNext && nPrevCrv == -1)) {
|
||||||
|
// se sono su un estremo di una curva aperta e ho cancellato la sottocurva di estremità devo verificare che fosse più piccola della tolleranza
|
||||||
|
if ( bErasedPrev && nNextCrv == -1) {
|
||||||
|
Point3d ptOrigEnd ; pOrigCrv->GetEndPoint( ptOrigEnd) ;
|
||||||
|
Point3d ptNewEnd ; GetEndPoint( ptNewEnd) ;
|
||||||
|
if ( Dist( ptOrigEnd, ptNewEnd) > dTol)
|
||||||
|
m_CrvSmplS.push_back( Release( pOrigCrv)) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
if ( bErasedNext && nPrevCrv == -1) {
|
||||||
|
Point3d ptOrigStart ; pOrigCrv->GetStartPoint( ptOrigStart) ;
|
||||||
|
Point3d ptNewStart ; GetStartPoint( ptNewStart) ;
|
||||||
|
if ( Dist( ptOrigStart, ptNewStart) > dTol)
|
||||||
|
m_CrvSmplS.insert( m_CrvSmplS.begin(), Release( pOrigCrv)) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
double dStart ;
|
||||||
|
double dEnd ;
|
||||||
|
if ( bErasedPrev) {
|
||||||
|
dStart = nU ;
|
||||||
|
dEnd = nNextCrv + 1 ;
|
||||||
|
}
|
||||||
|
else if ( bErasedNext) {
|
||||||
|
dStart = nPrevCrv ;
|
||||||
|
dEnd = nU ;
|
||||||
|
if ( nU == 0)
|
||||||
|
dStart -= 1 ;
|
||||||
|
}
|
||||||
|
else { // ! bErasedSomeCrv
|
||||||
|
dStart = ( nPrevCrv != -1 ? nPrevCrv : 0) ;
|
||||||
|
dEnd = ( nNextCrv != -1 ? nNextCrv + 1 : nCrvNmbr) ;
|
||||||
|
}
|
||||||
|
PtrOwner<ICurve> pNewCurve( CopyParamRange( dStart, dEnd)) ;
|
||||||
|
double dErr = 0 ;
|
||||||
|
if ( ! CalcApproxError( pOrigCrv, pNewCurve, dErr, 6) || dErr > dTol) {
|
||||||
|
// se ho fallito il check o la variazione è superiore alla tolleranza richiesta, ripristino le curve originali
|
||||||
|
if ( ! bErasedSomeCrv) {
|
||||||
|
if ( nNextCrv != -1) {
|
||||||
|
delete m_CrvSmplS[nNextCrv] ;
|
||||||
|
m_CrvSmplS[nNextCrv] = pOrigCrv->RemoveFirstOrLastCurve( true) ;
|
||||||
|
}
|
||||||
|
if ( nPrevCrv != -1) {
|
||||||
|
delete m_CrvSmplS[nPrevCrv] ;
|
||||||
|
m_CrvSmplS[nPrevCrv] = pOrigCrv->RemoveFirstOrLastCurve( true) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( bErasedNext) {
|
||||||
|
int nPos = nU == 0 ? nPrevCrv - 1 : nU ;
|
||||||
|
delete m_CrvSmplS[nPos] ;
|
||||||
|
if ( nU == 0) {
|
||||||
|
m_CrvSmplS[nPos] = pOrigCrv->RemoveFirstOrLastCurve( false) ;
|
||||||
|
nPos = 0 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_CrvSmplS[nPos] = pOrigCrv->RemoveFirstOrLastCurve( true) ;
|
||||||
|
m_CrvSmplS.insert( m_CrvSmplS.begin() + nPos, pOrigCrv->RemoveFirstOrLastCurve( true)) ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int nPos = nU == 0 ? nU : nPrevCrv ;
|
||||||
|
delete m_CrvSmplS[nPos] ;
|
||||||
|
if ( nU == 0) {
|
||||||
|
m_CrvSmplS[nPos] = pOrigCrv->RemoveFirstOrLastCurve( true) ;
|
||||||
|
nPos = nCrvNmbr - 1 ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_CrvSmplS[nPos] = pOrigCrv->RemoveFirstOrLastCurve( true) ;
|
||||||
|
m_CrvSmplS.insert( m_CrvSmplS.begin() + nPos, pOrigCrv->RemoveFirstOrLastCurve( true)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint, int* pnFlagDel)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK)
|
if ( m_nStatus != OK)
|
||||||
@@ -1958,6 +2090,8 @@ CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
|||||||
// verifico l'indice della giunzione
|
// verifico l'indice della giunzione
|
||||||
if ( nU < 0 || nU > nCrvCount)
|
if ( nU < 0 || nU > nCrvCount)
|
||||||
return false ;
|
return false ;
|
||||||
|
if ( pnFlagDel != nullptr)
|
||||||
|
*pnFlagDel = DeletedCurve::NONE ;
|
||||||
// recupero l'indice e il puntatore alla curva precedente (se esiste)
|
// recupero l'indice e il puntatore alla curva precedente (se esiste)
|
||||||
int nPrevCrv = -1 ;
|
int nPrevCrv = -1 ;
|
||||||
if ( nU > 0)
|
if ( nU > 0)
|
||||||
@@ -1986,6 +2120,8 @@ CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
|||||||
if ( AreSamePointApprox( ptStart, ptNewJoint)) {
|
if ( AreSamePointApprox( ptStart, ptNewJoint)) {
|
||||||
delete pPrevCrv ;
|
delete pPrevCrv ;
|
||||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nPrevCrv) ;
|
m_CrvSmplS.erase( m_CrvSmplS.begin() + nPrevCrv) ;
|
||||||
|
if ( pnFlagDel != nullptr)
|
||||||
|
*pnFlagDel = DeletedCurve::PREV ;
|
||||||
}
|
}
|
||||||
// altrimenti diventa un segmento di retta
|
// altrimenti diventa un segmento di retta
|
||||||
else {
|
else {
|
||||||
@@ -2005,6 +2141,8 @@ CurveComposite::ModifyJoint( int nU, const Point3d& ptNewJoint)
|
|||||||
if ( AreSamePointApprox( ptNewJoint, ptEnd)) {
|
if ( AreSamePointApprox( ptNewJoint, ptEnd)) {
|
||||||
delete pNextCrv ;
|
delete pNextCrv ;
|
||||||
m_CrvSmplS.erase( m_CrvSmplS.begin() + nNextCrv) ;
|
m_CrvSmplS.erase( m_CrvSmplS.begin() + nNextCrv) ;
|
||||||
|
if ( pnFlagDel != nullptr)
|
||||||
|
*pnFlagDel = DeletedCurve::NEXT ;
|
||||||
}
|
}
|
||||||
// altrimenti diventa un segmento di retta
|
// altrimenti diventa un segmento di retta
|
||||||
else {
|
else {
|
||||||
@@ -3034,7 +3172,7 @@ CurveComposite::ArcsToBezierCurves( void)
|
|||||||
// se arco, devo trasformare in una o più curve di Bezier
|
// se arco, devo trasformare in una o più curve di Bezier
|
||||||
if ( (*Iter)->GetType() == CRV_ARC) {
|
if ( (*Iter)->GetType() == CRV_ARC) {
|
||||||
// eseguo trasformazione
|
// eseguo trasformazione
|
||||||
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( (*Iter))) ;
|
PtrOwner<ICurve> pNewCrv( ArcToBezierCurve( GetCurveArc( *Iter))) ;
|
||||||
if ( IsNull( pNewCrv))
|
if ( IsNull( pNewCrv))
|
||||||
return false ;
|
return false ;
|
||||||
// se risultato è singola curva
|
// se risultato è singola curva
|
||||||
@@ -3168,11 +3306,26 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// se precedente molto corta
|
// se precedente molto corta
|
||||||
double dLenP ;
|
double dLenP ;
|
||||||
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
|
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
|
||||||
// se abbastanza allineata alla successiva
|
// se abbastanza allineata alla successiva
|
||||||
Vector3d vtDirP, vtDirC ;
|
Vector3d vtDirP, vtDirC ;
|
||||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||||
Point3d ptStart ;
|
bool bModifStart = ( pCrvC->GetType() != CRV_ARC) ;
|
||||||
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
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
|
// se corrente molto corta
|
||||||
@@ -3181,10 +3334,24 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// se abbastanza allineata alla precedente
|
// se abbastanza allineata alla precedente
|
||||||
Vector3d vtDirP, vtDirC ;
|
Vector3d vtDirP, vtDirC ;
|
||||||
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
|
||||||
Point3d ptEnd ;
|
bool bModifEnd = ( pCrvP->GetType() != CRV_ARC) ;
|
||||||
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
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
|
// coefficiente deduzione tolleranza
|
||||||
const double COEFF_TOL = 0.7 ;
|
const double COEFF_TOL = 0.7 ;
|
||||||
// se entrambe rette
|
// se entrambe rette
|
||||||
@@ -3264,11 +3431,12 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
if ( ! bPlaneArcs) {
|
if ( ! bPlaneArcs) {
|
||||||
ptP1.Scale( frRef, 1, 1, 0) ;
|
ptP1.Scale( frRef, 1, 1, 0) ;
|
||||||
ptP2.Scale( frRef, 1, 1, 0) ;
|
ptP2.Scale( frRef, 1, 1, 0) ;
|
||||||
ptP3.Scale( frRef, 1, 1, 0) ;
|
ptP3.Scale( frRef, 1, 1, 0) ;
|
||||||
|
ptC1Fin.Scale( frRef, 1, 1, 0) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico se circonferenza completa
|
// verifico se circonferenza completa
|
||||||
bool bCirc = ( AreSamePointApprox( ptP1, ptP3)) ;
|
bool bCirc = ( AreSamePointEpsilon( ptP1, ptP3, dCurrLinTol)) ;
|
||||||
if ( bCirc) {
|
if ( bCirc) {
|
||||||
pArcC->GetMidPoint( ptP3) ;
|
pArcC->GetMidPoint( ptP3) ;
|
||||||
if ( ! bPlaneArcs)
|
if ( ! bPlaneArcs)
|
||||||
@@ -3277,6 +3445,10 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
|
|
||||||
CurveArc NewArc ;
|
CurveArc NewArc ;
|
||||||
if ( NewArc.Set3P( ptP1, ptP2, ptP3, bCirc)) {
|
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
|
// verifico normale al piano dell'arco
|
||||||
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
|
||||||
NewArc.InvertN() ;
|
NewArc.InvertN() ;
|
||||||
@@ -3794,19 +3966,6 @@ CurveComposite::ResetVoronoiObject() const
|
|||||||
m_pVoronoiObj = nullptr ;
|
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
|
bool
|
||||||
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
||||||
@@ -3818,3 +3977,49 @@ CurveComposite::GetOnlyPoint(Point3d& ptStart) const
|
|||||||
ptStart = m_ptStart ;
|
ptStart = m_ptStart ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
CurveComposite::ReplaceSingleCurve( int nSubCrv, ICurve* pNewCurveToAdd, double dTolStartEnd, double dTolAlong)
|
||||||
|
{
|
||||||
|
// prendo il possesso e verifico la curva
|
||||||
|
PtrOwner<ICurve> pNewCurve( pNewCurveToAdd) ;
|
||||||
|
if ( IsNull( pNewCurve) || ! pNewCurve->IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico lo stato
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico l'indice sia sensato
|
||||||
|
if ( nSubCrv < 0 || nSubCrv > GetCurveCount())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico che start e end coincidano entro la tolleranza
|
||||||
|
Point3d ptStart ; m_CrvSmplS[nSubCrv]->GetStartPoint( ptStart) ;
|
||||||
|
Point3d ptEnd ; m_CrvSmplS[nSubCrv]->GetEndPoint( ptEnd) ;
|
||||||
|
Point3d ptNewStart ; pNewCurve->GetStartPoint( ptNewStart) ;
|
||||||
|
Point3d ptNewEnd ; pNewCurve->GetEndPoint( ptNewEnd) ;
|
||||||
|
if ( ! AreSamePointApprox( ptStart, ptNewStart) || ! AreSamePointApprox( ptEnd, ptNewEnd)) {
|
||||||
|
// se i punti di inizio e fine non sono entro EPS_SMALL ma sono entro la tolleranza passata allora modifico la curva da aggiungere
|
||||||
|
if ( AreSamePointEpsilon( ptStart, ptNewStart, dTolStartEnd) && AreSamePointEpsilon( ptEnd, ptNewEnd, dTolStartEnd)) {
|
||||||
|
if ( ! pNewCurve->ModifyStart( ptStart) || ! pNewCurve->ModifyEnd( ptEnd))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se presente una tolleranza lungo la curva controllo che sia rispettata
|
||||||
|
if ( dTolAlong < INFINITO) {
|
||||||
|
double dErr = 0 ;
|
||||||
|
CalcApproxError( m_CrvSmplS[nSubCrv], pNewCurve, dErr, 20) ;
|
||||||
|
if ( dErr > dTolAlong)
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_CrvSmplS[nSubCrv] ;
|
||||||
|
m_CrvSmplS[nSubCrv] = Release( pNewCurve) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
+12
-6
@@ -26,6 +26,9 @@ class Voronoi ;
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class CurveComposite : public ICurveComposite, public IGeoObjRW
|
class CurveComposite : public ICurveComposite, public IGeoObjRW
|
||||||
{
|
{
|
||||||
|
public :
|
||||||
|
enum DeletedCurve { NONE = 0, PREV = 1, NEXT = 2 } ;
|
||||||
|
|
||||||
public : // IGeoObj
|
public : // IGeoObj
|
||||||
~CurveComposite( void) override ;
|
~CurveComposite( void) override ;
|
||||||
CurveComposite* Clone( void) const override ;
|
CurveComposite* Clone( void) const override ;
|
||||||
@@ -113,7 +116,7 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
|||||||
bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const override ;
|
bool ApproxWithArcsEx( double dLinTol, double dAngTolDeg, double dLinFea, PolyArc& PA) const override ;
|
||||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||||
bool Invert( void) override ;
|
bool Invert( void) override ;
|
||||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||||
@@ -156,7 +159,9 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
|||||||
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
|
bool AddArc2P( const Point3d& ptOther, const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||||
bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
bool AddArcTg( const Point3d& ptNew, bool bEndOrStart = true) override ;
|
||||||
bool AddJoint( double dU) override ;
|
bool AddJoint( double dU) override ;
|
||||||
bool ModifyJoint( int nU, const Point3d& ptNewJoint) override ;
|
bool ModifyJoint( int nU, const Point3d& ptNewJoint) override
|
||||||
|
{ return ModifyJoint( nU, ptNewJoint, nullptr) ; }
|
||||||
|
bool ModifyJoint( int nU, const Point3d& ptNewJoint, double dTol) override ; // verifico se le curve interessate sono in tolleranza con la versione prima della modifica
|
||||||
bool RemoveJoint( int nU) override ;
|
bool RemoveJoint( int nU) override ;
|
||||||
bool MoveCurve( int nCrv, const Vector3d& vtMove) override ;
|
bool MoveCurve( int nCrv, const Vector3d& vtMove) override ;
|
||||||
bool ModifyCurveToArc( int nCrv, const Point3d& ptMid) override ;
|
bool ModifyCurveToArc( int nCrv, const Point3d& ptMid) override ;
|
||||||
@@ -177,8 +182,8 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
|||||||
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
bool GetCurveTempProp( int nCrv, int& nProp, int nPropInd = 0) const override ;
|
||||||
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
bool SetCurveTempParam( int nCrv, double dParam, int nParamInd = 0) override ;
|
||||||
bool GetCurveTempParam( int nCrv, double& dParam, int nParamInd = 0) const 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 ;
|
||||||
bool GetOnlyPoint( Point3d& ptStart) const override ; // funzione per recuperare l'unico punto da cui è composta la curva ( degenere)
|
bool ReplaceSingleCurve( int nSubCrv, ICurve* pNewCurve, double dTolStartEnd, double dTolAlong = INFINITO) override ;
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -199,19 +204,20 @@ class CurveComposite : public ICurveComposite, public IGeoObjRW
|
|||||||
return *this ; }
|
return *this ; }
|
||||||
bool RelocateFrom( CurveComposite& ccSrc) ;
|
bool RelocateFrom( CurveComposite& ccSrc) ;
|
||||||
bool GetApproxLength( double& dLen) const ;
|
bool GetApproxLength( double& dLen) const ;
|
||||||
|
bool TestClosure( double dLinTol = EPS_SMALL) ;
|
||||||
Voronoi* GetVoronoiObject( void) const ;
|
Voronoi* GetVoronoiObject( void) const ;
|
||||||
void ResetVoronoiObject( void) const ;
|
void ResetVoronoiObject( void) const ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool CopyFrom( const CurveComposite& ccSrc) ;
|
bool CopyFrom( const CurveComposite& ccSrc) ;
|
||||||
bool Validate( void) ;
|
bool Validate( void) ;
|
||||||
bool TestClosure( void) ;
|
|
||||||
bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
bool AddCurveByRelocate( CurveComposite& ccSrc, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
||||||
bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
bool AddSimpleCurve( ICurve* pSmplCrv, bool bEndOrStart = true, double dLinTol = EPS_SMALL) ;
|
||||||
bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ;
|
bool GetIndSCurveAndLocPar( double dU, Side nS, int& nSCrv, double& dLocU) const ;
|
||||||
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET) ;
|
bool SimpleOffsetXY( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) ;
|
||||||
bool IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const ;
|
bool IsOneCircle( Point3d& ptCen, Vector3d& vtN, double& dRad, bool& bCCW) const ;
|
||||||
bool CalcVoronoiObject( void) const ;
|
bool CalcVoronoiObject( void) const ;
|
||||||
|
bool ModifyJoint( int nU, const Point3d& ptNewJoint, int* pnFlagDel) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2, IS_A_POINT = 3} ;
|
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2, IS_A_POINT = 3} ;
|
||||||
|
|||||||
+14
-10
@@ -19,6 +19,7 @@
|
|||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
#include "/EgtDev/Include/EGkCurve.h"
|
#include "/EgtDev/Include/EGkCurve.h"
|
||||||
#include "/EgtDev/Include/EGkIntersCurves.h"
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||||
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
@@ -30,14 +31,14 @@ static const int TP_IS_VERT_LINE = 1 ;
|
|||||||
static bool IsVerticalLine( const ICurve* pCrv, double* pdLenZ) ;
|
static bool IsVerticalLine( const ICurve* pCrv, double* pdLenZ) ;
|
||||||
static bool VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
static bool VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
||||||
static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
static bool VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux) ;
|
||||||
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
|
static bool VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType, double dMaxAngExt,
|
||||||
CurveComposite& ccAux) ;
|
CurveComposite& ccAux) ;
|
||||||
static bool AddFirstLastVerticalLines( CurveComposite& ccOffs, double dLenVertFirst, double dLenVertLast) ;
|
static bool AddFirstLastVerticalLines( CurveComposite& ccOffs, double dLenVertFirst, double dLenVertLast) ;
|
||||||
static bool MediaInternalAngleDeltaZ( CurveComposite& ccOffs) ;
|
static bool MediaInternalAngleDeltaZ( CurveComposite& ccOffs) ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
CurveComposite::SimpleOffsetXY( double dDist, int nType, double dMaxAngExt)
|
||||||
{
|
{
|
||||||
// creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
|
// creo una copia formata solo da rette e archi che giacciono nel piano XY (VtExtr è Z+)
|
||||||
CurveComposite ccCopy ;
|
CurveComposite ccCopy ;
|
||||||
@@ -98,7 +99,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
|||||||
CurveComposite ccTemp ;
|
CurveComposite ccTemp ;
|
||||||
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrv2, ccTemp) ||
|
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrv2, ccTemp) ||
|
||||||
VerifyAndAdjustInternalAngle( pCrvPrev, pCrv2, ccTemp) ||
|
VerifyAndAdjustInternalAngle( pCrvPrev, pCrv2, ccTemp) ||
|
||||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrv2, dDist, nType, ccTemp)) {
|
VerifyAndAdjustExternalAngle( pCrvPrev, pCrv2, dDist, nType, dMaxAngExt, ccTemp)) {
|
||||||
if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
if ( ccTemp.GetCurveCount() > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -122,7 +123,7 @@ CurveComposite::SimpleOffsetXY( double dDist, int nType)
|
|||||||
CurveComposite ccTemp ;
|
CurveComposite ccTemp ;
|
||||||
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrvNext, ccTemp) ||
|
if ( VerifyAndAdjustSamePoint( pCrvPrev, pCrvNext, ccTemp) ||
|
||||||
VerifyAndAdjustInternalAngle( pCrvPrev, pCrvNext, ccTemp) ||
|
VerifyAndAdjustInternalAngle( pCrvPrev, pCrvNext, ccTemp) ||
|
||||||
VerifyAndAdjustExternalAngle( pCrvPrev, pCrvNext, dDist, nType, ccTemp)) {
|
VerifyAndAdjustExternalAngle( pCrvPrev, pCrvNext, dDist, nType, dMaxAngExt, ccTemp)) {
|
||||||
int nCrvCount = ccTemp.GetCurveCount() ;
|
int nCrvCount = ccTemp.GetCurveCount() ;
|
||||||
if ( nCrvCount > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
if ( nCrvCount > 0 && ! ccOffs.AddCurveByRelocate( ccTemp))
|
||||||
return false ;
|
return false ;
|
||||||
@@ -174,7 +175,7 @@ bool
|
|||||||
VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
VerifyAndAdjustSamePoint( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
||||||
{
|
{
|
||||||
// verifica dei puntatori
|
// verifica dei puntatori
|
||||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// pulisco la curva ausiliaria
|
// pulisco la curva ausiliaria
|
||||||
@@ -218,7 +219,7 @@ bool
|
|||||||
VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAux)
|
||||||
{
|
{
|
||||||
// verifica dei puntatori
|
// verifica dei puntatori
|
||||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// pulisco la curva ausiliaria
|
// pulisco la curva ausiliaria
|
||||||
@@ -259,11 +260,11 @@ VerifyAndAdjustInternalAngle( ICurve* pCrv1, ICurve* pCrv2, CurveComposite& ccAu
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType,
|
VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nType, double dMaxAngExt,
|
||||||
CurveComposite& ccAux)
|
CurveComposite& ccAux)
|
||||||
{
|
{
|
||||||
// verifica dei puntatori
|
// verifica dei puntatori
|
||||||
if ( pCrv1 == nullptr || pCrv2 == nullptr || &ccAux == nullptr)
|
if ( pCrv1 == nullptr || pCrv2 == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// pulisco la curva ausiliaria
|
// pulisco la curva ausiliaria
|
||||||
@@ -272,6 +273,9 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nT
|
|||||||
// elimino dal tipo le parti estranee all'angolo esterno
|
// elimino dal tipo le parti estranee all'angolo esterno
|
||||||
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
|
nType &= ( ICurve::OFF_FILLET | ICurve::OFF_CHAMFER | ICurve::OFF_EXTEND) ;
|
||||||
|
|
||||||
|
// porto il massimo angolo per tipo Extend in limiti accettabili (90° - 150°)
|
||||||
|
dMaxAngExt = Clamp( dMaxAngExt, ANG_RIGHT, 1.667 * ANG_RIGHT) ;
|
||||||
|
|
||||||
// calcolo direzioni tangenti sull'estremo in comune
|
// calcolo direzioni tangenti sull'estremo in comune
|
||||||
Vector3d vtDir1, vtDir2 ;
|
Vector3d vtDir1, vtDir2 ;
|
||||||
if ( ! pCrv1->GetEndDir( vtDir1) || ! pCrv2->GetStartDir( vtDir2))
|
if ( ! pCrv1->GetEndDir( vtDir1) || ! pCrv2->GetStartDir( vtDir2))
|
||||||
@@ -319,8 +323,8 @@ VerifyAndAdjustExternalAngle( ICurve* pCrv1, ICurve* pCrv2, double dDist, int nT
|
|||||||
( dDist > 0 && dAngDeg < 0)))
|
( dDist > 0 && dAngDeg < 0)))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// se l'angolo esterno supera il retto, offset extend diventa offset chamfer
|
// se l'angolo esterno supera il limite, offset extend diventa offset chamfer
|
||||||
if ( nType == ICurve::OFF_EXTEND && abs( dAngDeg) > ANG_RIGHT + EPS_ANG_SMALL)
|
if ( nType == ICurve::OFF_EXTEND && abs( dAngDeg) > dMaxAngExt + EPS_ANG_SMALL)
|
||||||
nType = ICurve::OFF_CHAMFER ;
|
nType = ICurve::OFF_CHAMFER ;
|
||||||
|
|
||||||
// se angolo esterno molto piccolo, semplifico tutto
|
// se angolo esterno molto piccolo, semplifico tutto
|
||||||
|
|||||||
+1
-1
@@ -577,7 +577,7 @@ CurveLine::Invert( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
CurveLine::SimpleOffset( double dDist, int nType)
|
CurveLine::SimpleOffset( double dDist, int nType, double dMaxAngExt)
|
||||||
{
|
{
|
||||||
// verifico lo stato
|
// verifico lo stato
|
||||||
if ( m_nStatus != OK)
|
if ( m_nStatus != OK)
|
||||||
|
|||||||
+1
-1
@@ -117,7 +117,7 @@ class CurveLine : public ICurveLine, public IGeoObjRW
|
|||||||
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
{ return ApproxWithArcs( dLinTol, dAngTolDeg, PA) ; }
|
||||||
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
ICurve* CopyParamRange( double dUStart, double dUEnd) const override ;
|
||||||
bool Invert( void) override ;
|
bool Invert( void) override ;
|
||||||
bool SimpleOffset( double dDist, int nType = OFF_FILLET) override ;
|
bool SimpleOffset( double dDist, int nType = OFF_FILLET, double dMaxAngExt = ANG_RIGHT) override ;
|
||||||
bool ModifyStart( const Point3d& ptNewStart) override ;
|
bool ModifyStart( const Point3d& ptNewStart) override ;
|
||||||
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
bool ModifyEnd( const Point3d& ptNewEnd) override ;
|
||||||
bool SetExtrusion( const Vector3d& vtExtr) override
|
bool SetExtrusion( const Vector3d& vtExtr) override
|
||||||
|
|||||||
+15
-2
@@ -116,6 +116,7 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
|
|||||||
vtDiff = ptQ - ptP ;
|
vtDiff = ptQ - ptP ;
|
||||||
// angolo tra vettore e tangente
|
// angolo tra vettore e tangente
|
||||||
dTemp = vtDer1 * vtDiff ;
|
dTemp = vtDer1 * vtDiff ;
|
||||||
|
bool bEquiverse = dTemp > 0 ;
|
||||||
if ( abs( dTemp) > EPS_ZERO)
|
if ( abs( dTemp) > EPS_ZERO)
|
||||||
dSqCosA = dTemp * dTemp / ( vtDer1.SqLen() * vtDiff.SqLen()) ;
|
dSqCosA = dTemp * dTemp / ( vtDer1.SqLen() * vtDiff.SqLen()) ;
|
||||||
else
|
else
|
||||||
@@ -123,8 +124,20 @@ PolishMinDistPointCurve( const Point3d& ptP, const ICurve& cCurve,
|
|||||||
// stima prossimo valore del parametro (Newton : Unext = U - F(U) / F'(U))
|
// stima prossimo valore del parametro (Newton : Unext = U - F(U) / F'(U))
|
||||||
dPrevPar = dPar ;
|
dPrevPar = dPar ;
|
||||||
dTemp = vtDer2 * vtDiff + vtDer1.SqLen() ;
|
dTemp = vtDer2 * vtDiff + vtDer1.SqLen() ;
|
||||||
if ( abs( dTemp) > EPS_ZERO)
|
|
||||||
dPar = dPrevPar - ( vtDer1 * vtDiff) / dTemp ;
|
// se il coseno tra questi due vettori è troppo grande potrei aver avuto una cattiva stima iniziale
|
||||||
|
// provo quindi ad aggiustare a mano, anziché usare il segno suggerito da newton, che con queste premesse potrebbe divergere
|
||||||
|
double dCos75 = 0.2588 ;
|
||||||
|
if ( abs( dTemp) > EPS_ZERO) {
|
||||||
|
double dDelta = ( vtDer1 * vtDiff) / dTemp ;
|
||||||
|
if ( dSqCosA > dCos75) {
|
||||||
|
if ( ( bEquiverse && dDelta > 0) || ( ! bEquiverse && dDelta < 0))
|
||||||
|
dDelta *= -1 ;
|
||||||
|
dPar = dPrevPar + dDelta ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
dPar = dPrevPar - dDelta ;
|
||||||
|
}
|
||||||
// clipping parametro
|
// clipping parametro
|
||||||
if ( dPar < approxMin.dParMin) {
|
if ( dPar < approxMin.dParMin) {
|
||||||
if ( approxMin.bParMinSing && ! bClampedFromSing) {
|
if ( approxMin.bParMinSing && ! bClampedFromSing) {
|
||||||
|
|||||||
+12
-1
@@ -26,7 +26,7 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier&
|
|||||||
// distanza non calcolata
|
// distanza non calcolata
|
||||||
m_dDist = - 1 ;
|
m_dDist = - 1 ;
|
||||||
|
|
||||||
if ( &CrvBez == nullptr || ! CrvBez.IsValid())
|
if ( ! CrvBez.IsValid())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// determino tolleranza di approssimazione in base a ingombro curva
|
// determino tolleranza di approssimazione in base a ingombro curva
|
||||||
@@ -42,6 +42,17 @@ DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier&
|
|||||||
if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
int nDeg = CrvBez.GetDegree() ;
|
||||||
|
if ( PL.GetPointNbr() < nDeg + 1) {
|
||||||
|
// costruisco una polilinea con un numero di curve scelto in base al grado della curva
|
||||||
|
PL.Clear() ;
|
||||||
|
for ( int i = 0 ; i <= nDeg + 1 ; ++i) {
|
||||||
|
double dU = double(i) / (nDeg + 1) ;
|
||||||
|
Point3d ptBez ;
|
||||||
|
CrvBez.GetPointD1D2( dU, ICurve::Side::FROM_MINUS, ptBez) ;
|
||||||
|
PL.AddUPoint( dU, ptBez) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
// cerco la minima distanza per la polilinea
|
// cerco la minima distanza per la polilinea
|
||||||
MDCVECTOR vApproxMin ;
|
MDCVECTOR vApproxMin ;
|
||||||
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
|
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
|
||||||
|
|||||||
+22
-11
@@ -152,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 ;
|
double dParam ;
|
||||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
if ( i == 0 ||
|
if ( i == 0 ||
|
||||||
@@ -197,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) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
if ( i == 0 ||
|
if ( i == 0 ||
|
||||||
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
abs( m_Info[i].dPar - dNearParam) < abs( dParam - dNearParam)) {
|
||||||
@@ -211,13 +211,13 @@ DistPointCurve::GetParamAtMinDistPoint( double dNearParam, double& dParam, int&
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide) const
|
DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide, double dTol) const
|
||||||
{
|
{
|
||||||
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
if ( m_dDist < 0 || nInd < 0 || nInd >= (int) m_Info.size())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// se distanza nulla, il punto giace sulla curva
|
// se distanza nulla, il punto giace sulla curva
|
||||||
if ( m_dDist <= EPS_SMALL) {
|
if ( m_dDist <= dTol) {
|
||||||
nSide = MDS_ON ;
|
nSide = MDS_ON ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -232,9 +232,20 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
|||||||
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
Vector3d vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||||
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
// se tangenti opposte, si deve ricalcolare spostandosi un poco
|
||||||
if ( ! vtTg.Normalize()) {
|
if ( ! vtTg.Normalize()) {
|
||||||
double dDeltaU = 1000 * EPS_PARAM ;
|
double dDeltaU = 1000 * EPS_PARAM ;
|
||||||
if ( ! m_pCurve->GetPointTang( m_Info[nInd].dPar - dDeltaU, ICurve::FROM_MINUS, ptQ, vtPreTg) ||
|
double dParPre = m_Info[nInd].dPar - dDeltaU ;
|
||||||
! m_pCurve->GetPointTang( m_Info[nInd].dPar + dDeltaU, ICurve::FROM_PLUS, ptQ, vtPostTg))
|
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 ;
|
return false ;
|
||||||
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
vtTg = 0.5 * ( vtPreTg + vtPostTg) ;
|
||||||
if ( ! vtTg.Normalize( EPS_ZERO))
|
if ( ! vtTg.Normalize( EPS_ZERO))
|
||||||
@@ -248,7 +259,7 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
|||||||
|
|
||||||
// determino il lato di giacitura del punto
|
// determino il lato di giacitura del punto
|
||||||
double dSide = vtRef * ( m_ptP - ptQ) ;
|
double dSide = vtRef * ( m_ptP - ptQ) ;
|
||||||
if ( abs( dSide) < EPS_SMALL)
|
if ( abs( dSide) < dTol)
|
||||||
nSide = MDS_ON ;
|
nSide = MDS_ON ;
|
||||||
else if ( dSide > 0)
|
else if ( dSide > 0)
|
||||||
nSide = MDS_LEFT ;
|
nSide = MDS_LEFT ;
|
||||||
@@ -259,12 +270,12 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide) const
|
DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, int& nSide, double dTol) const
|
||||||
{
|
{
|
||||||
if ( m_dDist < 0 || m_Info.empty())
|
if ( m_dDist < 0 || m_Info.empty())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// cerco punto discreto più vicino (anche estremi di zone continue)
|
// cerco punto discreto più vicino (anche estremi di zone continue)
|
||||||
int nInd ;
|
int nInd ;
|
||||||
double dParam ;
|
double dParam ;
|
||||||
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
for ( int i = 0 ; i < (int) m_Info.size() ; ++ i) {
|
||||||
@@ -275,7 +286,7 @@ DistPointCurve::GetSideAtMinDistPoint( double dNearParam, const Vector3d& vtN, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// mi sono ricondotto al caso precedente
|
// mi sono ricondotto al caso precedente
|
||||||
return GetSideAtMinDistPoint( nInd, vtN, nSide) ;
|
return GetSideAtMinDistPoint( nInd, vtN, nSide, dTol) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -0,0 +1,120 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2025
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : DistPointSurfBz.cpp Data : 29.10.25 Versione : 2.7j3
|
||||||
|
// Contenuto : Implementazione della classe distanza Punto da superficie Bezier.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 29.10.25 DB Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "SurfTriMesh.h"
|
||||||
|
#include "SurfBezier.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointSurfBz.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
DistPointSurfBz::DistPointSurfBz( const Point3d& ptP, const ISurfBezier& pSrfBz)
|
||||||
|
: m_dDist( -1), m_bIsInside( false), m_bIsSurfClosed( false)
|
||||||
|
{
|
||||||
|
// Bezier non valida
|
||||||
|
if ( ! pSrfBz.IsValid())
|
||||||
|
return ;
|
||||||
|
// Calcolo la distanza
|
||||||
|
Calculate( ptP, pSrfBz) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
DistPointSurfBz::Calculate( const Point3d& ptP, const ISurfBezier& srfBz)
|
||||||
|
{
|
||||||
|
// Inizializzo distanza non calcolata
|
||||||
|
m_dDist = -1 ;
|
||||||
|
|
||||||
|
// Controllo se la superficie è chiusa
|
||||||
|
m_bIsSurfClosed = srfBz.IsClosed() ;
|
||||||
|
|
||||||
|
// Lavoro con l'oggetto superficie trimesh di base
|
||||||
|
const ISurfTriMesh* pStmRef = srfBz.GetAuxSurfRefined() ;
|
||||||
|
if ( pStmRef == nullptr)
|
||||||
|
return ;
|
||||||
|
|
||||||
|
DistPointSurfTm dpst( ptP, *pStmRef) ;
|
||||||
|
|
||||||
|
// recupero il punto a distanza minima sulla trimesh e lo raffino, prima di restituire distanza e punto minimo
|
||||||
|
Point3d ptMinTm ; dpst.GetMinDistPoint( ptMinTm) ;
|
||||||
|
int nT ; dpst.GetMinDistTriaIndex( nT) ;
|
||||||
|
// salvo il punto corrispondente nel parametrico
|
||||||
|
srfBz.UnprojectPointFromStm( nT, ptMinTm, m_ptParam) ;
|
||||||
|
// salvo il punto a minima distanza sulla superficie e la normale alla superficie in quel punto
|
||||||
|
srfBz.GetPointNrmD1D2( m_ptParam.x, m_ptParam.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, m_ptMinDistPoint, m_vtN) ;
|
||||||
|
|
||||||
|
// salvo la distanza minima
|
||||||
|
m_dDist = Dist( ptP, m_ptMinDistPoint) ;
|
||||||
|
// se il punto è sulla superficie
|
||||||
|
if ( m_dDist < EPS_SMALL) {
|
||||||
|
m_bIsInside = false ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_bIsInside = ( ( ptP - m_ptMinDistPoint) * m_vtN < - EPS_SMALL) ;
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DistPointSurfBz::GetDist( double& dDist) const
|
||||||
|
{
|
||||||
|
// Distanza non valida
|
||||||
|
if ( m_dDist < -EPS_ZERO)
|
||||||
|
return false ;
|
||||||
|
// Distanza valida
|
||||||
|
dDist = m_dDist ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DistPointSurfBz::GetMinDistPoint( Point3d& ptMinDistPoint) const
|
||||||
|
{
|
||||||
|
// Distanza non valida
|
||||||
|
if ( m_dDist < -EPS_ZERO)
|
||||||
|
return false ;
|
||||||
|
// Distanza valida
|
||||||
|
ptMinDistPoint = m_ptMinDistPoint ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DistPointSurfBz::GetParamsAtMinDistPoint( double& dU, double& dV) const
|
||||||
|
{
|
||||||
|
// Distanza non valida
|
||||||
|
if ( m_dDist < -EPS_ZERO)
|
||||||
|
return false ;
|
||||||
|
// Distanza valida
|
||||||
|
dU = m_ptParam.x ;
|
||||||
|
dV = m_ptParam.y ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DistPointSurfBz::GetNorm( Vector3d& vtN) const
|
||||||
|
{
|
||||||
|
// Distanza non valida
|
||||||
|
if ( m_dDist < -EPS_ZERO)
|
||||||
|
return false ;
|
||||||
|
// Distanza valida
|
||||||
|
vtN = m_vtN ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
@@ -94,6 +94,8 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
{
|
{
|
||||||
// Inizializzo distanza non calcolata
|
// Inizializzo distanza non calcolata
|
||||||
m_dDist = - 1. ;
|
m_dDist = - 1. ;
|
||||||
|
// Vettore di indici dei triangoli più vicini inizialmente vuoto
|
||||||
|
m_vnMinDistTriaIndex.clear() ;
|
||||||
// Controllo se la superficie è chiusa
|
// Controllo se la superficie è chiusa
|
||||||
m_bIsSurfClosed = tmSurf.IsClosed() ;
|
m_bIsSurfClosed = tmSurf.IsClosed() ;
|
||||||
|
|
||||||
@@ -184,6 +186,10 @@ DistPointSurfTm::Calculate( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
|||||||
if ( nMinDistTriaIndex == SVT_NULL)
|
if ( nMinDistTriaIndex == SVT_NULL)
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
|
// Inizializzo il vettore dei triangoli a minima distanza
|
||||||
|
for ( auto& Tria : vTria)
|
||||||
|
m_vnMinDistTriaIndex.emplace_back( Tria.first) ;
|
||||||
|
|
||||||
// salvo la distanza minima
|
// salvo la distanza minima
|
||||||
m_dDist = dMinDist ;
|
m_dDist = dMinDist ;
|
||||||
// salvo il punto a distanza minima
|
// salvo il punto a distanza minima
|
||||||
@@ -279,6 +285,18 @@ DistPointSurfTm::GetMinDistTriaIndex( int& nMinDistIndex) const
|
|||||||
return true ;
|
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
|
int
|
||||||
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
GetSurfTmNearestVertex( const Point3d& ptP, const ISurfTriMesh& tmSurf)
|
||||||
|
|||||||
+12
-3
@@ -159,11 +159,20 @@ InitFontManager( const string& sNfeFontDir, const string& sDefaultFont)
|
|||||||
{
|
{
|
||||||
// recupero il font manager
|
// recupero il font manager
|
||||||
FontManager& fntMgr = FontManager::GetFontManager() ;
|
FontManager& fntMgr = FontManager::GetFontManager() ;
|
||||||
|
|
||||||
// lo inizializzo
|
// lo inizializzo
|
||||||
fntMgr.Init( sNfeFontDir, sDefaultFont) ;
|
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&
|
const string&
|
||||||
GetNfeFontDir( void)
|
GetNfeFontDir( void)
|
||||||
@@ -185,11 +194,11 @@ GetDefaultFont( void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static pfProcEvents s_pFunProcEvents = nullptr ;
|
static psfProcEvents s_pFunProcEvents = nullptr ;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SetEGkProcessEvents( pfProcEvents pFun)
|
SetEGkProcessEvents( psfProcEvents pFun)
|
||||||
{
|
{
|
||||||
s_pFunProcEvents = pFun ;
|
s_pFunProcEvents = pFun ;
|
||||||
return ( pFun != nullptr) ;
|
return ( pFun != nullptr) ;
|
||||||
|
|||||||
Binary file not shown.
+15
-4
@@ -116,7 +116,7 @@
|
|||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<EnablePREfast>false</EnablePREfast>
|
<EnablePREfast>false</EnablePREfast>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -151,7 +151,7 @@ copy $(TargetPath) \EgtProg\DllD32</Command>
|
|||||||
<MinimalRebuild>false</MinimalRebuild>
|
<MinimalRebuild>false</MinimalRebuild>
|
||||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
@@ -199,7 +199,7 @@ copy $(TargetPath) \EgtProg\DllD64</Command>
|
|||||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Windows</SubSystem>
|
<SubSystem>Windows</SubSystem>
|
||||||
@@ -245,7 +245,7 @@ copy $(TargetPath) \EgtProg\Dll32</Command>
|
|||||||
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
<EnableFiberSafeOptimizations>false</EnableFiberSafeOptimizations>
|
||||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
<DebugInformationFormat>None</DebugInformationFormat>
|
<DebugInformationFormat>None</DebugInformationFormat>
|
||||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
<AdditionalOptions>-Wno-tautological-undefined-compare</AdditionalOptions>
|
||||||
<IntelJCCErratum>true</IntelJCCErratum>
|
<IntelJCCErratum>true</IntelJCCErratum>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -281,8 +281,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="BBox3d.cpp" />
|
<ClCompile Include="BBox3d.cpp" />
|
||||||
<ClCompile Include="BiArcs.cpp" />
|
<ClCompile Include="BiArcs.cpp" />
|
||||||
<ClCompile Include="CalcPocketing.cpp" />
|
<ClCompile Include="CalcPocketing.cpp" />
|
||||||
|
<ClCompile Include="CalcDerivate.cpp" />
|
||||||
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
<ClCompile Include="CAvSilhouetteSurfTm.cpp" />
|
||||||
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
<ClCompile Include="CAvSimpleSurfFrMove.cpp" />
|
||||||
|
<ClCompile Include="CAvSurfFrMove.cpp" />
|
||||||
<ClCompile Include="CAvToolSurfTm.cpp" />
|
<ClCompile Include="CAvToolSurfTm.cpp" />
|
||||||
<ClCompile Include="CAvToolTriangle.cpp" />
|
<ClCompile Include="CAvToolTriangle.cpp" />
|
||||||
<ClCompile Include="CDeBoxClosedSurfTm.cpp" />
|
<ClCompile Include="CDeBoxClosedSurfTm.cpp" />
|
||||||
@@ -310,7 +312,9 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="CurveByApprox.cpp" />
|
<ClCompile Include="CurveByApprox.cpp" />
|
||||||
<ClCompile Include="CurveByInterp.cpp" />
|
<ClCompile Include="CurveByInterp.cpp" />
|
||||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||||
|
<ClCompile Include="DistPointSurfBz.cpp" />
|
||||||
<ClCompile Include="DistPointSurfFr.cpp" />
|
<ClCompile Include="DistPointSurfFr.cpp" />
|
||||||
|
<ClCompile Include="IntersCurvePlane.cpp" />
|
||||||
<ClCompile Include="IntersCurveSurfTm.cpp">
|
<ClCompile Include="IntersCurveSurfTm.cpp">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
@@ -320,6 +324,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClCompile Include="IntersLineVolZmap.cpp" />
|
<ClCompile Include="IntersLineVolZmap.cpp" />
|
||||||
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
<ClCompile Include="IntersPlaneVolZmap.cpp" />
|
||||||
<ClCompile Include="IntersLineSurfBez.cpp" />
|
<ClCompile Include="IntersLineSurfBez.cpp" />
|
||||||
|
<ClCompile Include="Trimming.cpp" />
|
||||||
|
<ClCompile Include="MultiGeomDB.cpp" />
|
||||||
|
<ClCompile Include="SurfTriMeshOffset.cpp" />
|
||||||
|
<ClCompile Include="VolZmapOffset.cpp" />
|
||||||
<ClCompile Include="PolygonElevation.cpp" />
|
<ClCompile Include="PolygonElevation.cpp" />
|
||||||
<ClCompile Include="Quaternion.cpp" />
|
<ClCompile Include="Quaternion.cpp" />
|
||||||
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
<ClCompile Include="RotationMinimizingFrame.cpp" />
|
||||||
@@ -338,12 +346,15 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
|||||||
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
<ClInclude Include="..\Include\EGkIntersLineVolZmap.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
<ClInclude Include="..\Include\EGkIntersPlaneBox.h" />
|
||||||
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
<ClInclude Include="..\Include\EGkIntersPlaneVolZmap.h" />
|
||||||
|
<ClInclude Include="..\Include\EGkMultiGeomDB.h" />
|
||||||
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
<ClInclude Include="..\Include\EGkPolygonElevation.h" />
|
||||||
<ClInclude Include="..\Include\EGkQuaternion.h" />
|
<ClInclude Include="..\Include\EGkQuaternion.h" />
|
||||||
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
<ClInclude Include="..\Include\EGkRotationMinimizingFrame.h" />
|
||||||
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
<ClInclude Include="..\Include\EGkRotationXplaneFrame.h" />
|
||||||
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
<ClInclude Include="..\Include\EGkSubtractProjectedFacesOnStmFace.h" />
|
||||||
|
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h" />
|
||||||
<ClInclude Include="CAvSilhouetteSurfTm.h" />
|
<ClInclude Include="CAvSilhouetteSurfTm.h" />
|
||||||
|
<ClInclude Include="CAvSurfFrMove.h" />
|
||||||
<ClInclude Include="CDeBoxTria.h" />
|
<ClInclude Include="CDeBoxTria.h" />
|
||||||
<ClInclude Include="CDeCapsTria.h" />
|
<ClInclude Include="CDeCapsTria.h" />
|
||||||
<ClInclude Include="CDeConeFrustumTria.h" />
|
<ClInclude Include="CDeConeFrustumTria.h" />
|
||||||
|
|||||||
@@ -55,6 +55,9 @@
|
|||||||
<Filter Include="File di origine\GeoCollisionDetection">
|
<Filter Include="File di origine\GeoCollisionDetection">
|
||||||
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
<UniqueIdentifier>{865b76ee-b10d-41fc-861c-b48ce52fa277}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="File di origine\GeoStriping">
|
||||||
|
<UniqueIdentifier>{54901321-08f6-4428-80c7-a1f859136a32}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Vector3d.cpp">
|
<ClCompile Include="Vector3d.cpp">
|
||||||
@@ -546,6 +549,33 @@
|
|||||||
<ClCompile Include="DistPointSurfFr.cpp">
|
<ClCompile Include="DistPointSurfFr.cpp">
|
||||||
<Filter>File di origine\GeoDist</Filter>
|
<Filter>File di origine\GeoDist</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="VolZmapOffset.cpp">
|
||||||
|
<Filter>File di origine\Geo</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="SurfTriMeshOffset.cpp">
|
||||||
|
<Filter>File di origine\GeoOffset</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="MultiGeomDB.cpp">
|
||||||
|
<Filter>File di origine\Gdb</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="DistPointSurfBz.cpp">
|
||||||
|
<Filter>File di origine\GeoDist</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="IntersCurvePlane.cpp">
|
||||||
|
<Filter>File di origine\GeoInters</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Trimming.cpp">
|
||||||
|
<Filter>File di origine\GeoStriping</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CalcDerivate.cpp">
|
||||||
|
<Filter>File di origine\Geo</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="CAvSurfFrMove.cpp">
|
||||||
|
<Filter>File di origine\GeoCollisionAvoid</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Trimming.cpp">
|
||||||
|
<Filter>File di origine\GeoStriping</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="stdafx.h">
|
<ClInclude Include="stdafx.h">
|
||||||
@@ -1226,6 +1256,15 @@
|
|||||||
<ClInclude Include="CAvSilhouetteSurfTm.h">
|
<ClInclude Include="CAvSilhouetteSurfTm.h">
|
||||||
<Filter>File di intestazione</Filter>
|
<Filter>File di intestazione</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\EGkSurfTriMeshAux.h">
|
||||||
|
<Filter>File di intestazione\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Include\EGkMultiGeomDB.h">
|
||||||
|
<Filter>File di intestazione\Include</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="CAvSurfFrMove.h">
|
||||||
|
<Filter>File di intestazione</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||||
|
|||||||
+1
-1
@@ -1087,7 +1087,7 @@ ExtDimension::Update( void) const
|
|||||||
if ( m_nType == DT_RADIAL)
|
if ( m_nType == DT_RADIAL)
|
||||||
sVal = "R " + sVal ;
|
sVal = "R " + sVal ;
|
||||||
else if ( m_nType == DT_DIAMETRAL)
|
else if ( m_nType == DT_DIAMETRAL)
|
||||||
sVal = u8"\u00D8 " + sVal ;
|
sVal = reinterpret_cast<const char *>( u8"\u00D8") + sVal ;
|
||||||
ReplaceString( m_sCalcText, IS_MEASURE, sVal) ;
|
ReplaceString( m_sCalcText, IS_MEASURE, sVal) ;
|
||||||
}
|
}
|
||||||
// punto di inserimento del testo
|
// punto di inserimento del testo
|
||||||
|
|||||||
+3
-1
@@ -29,6 +29,8 @@ class FontManager
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
bool Init( const std::string& sNfeFontDir, const std::string& sDefaultFont) ;
|
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,
|
bool SetCurrFont( const std::string& sFont, int nWeight, bool bItalic,
|
||||||
double dHeight, double dRatio, double dAddAdvance) ;
|
double dHeight, double dRatio, double dAddAdvance) ;
|
||||||
const std::string& GetNfeFontDir( void) const
|
const std::string& GetNfeFontDir( void) const
|
||||||
@@ -54,7 +56,7 @@ class FontManager
|
|||||||
OsFont m_OsFont ;
|
OsFont m_OsFont ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
FontManager( void) {}
|
FontManager( void) : m_bCurrNfeFont( false) {}
|
||||||
FontManager( FontManager const& copy) = delete ;
|
FontManager( FontManager const& copy) = delete ;
|
||||||
FontManager& operator=( FontManager const& copy) = delete ;
|
FontManager& operator=( FontManager const& copy) = delete ;
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
+2
-2
@@ -336,7 +336,7 @@ GdbGeo::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoe
|
|||||||
// curva originale
|
// curva originale
|
||||||
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
ICurve* pCrv = GetCurve( m_pGeoObj) ;
|
||||||
// trasformo in curva di Bezier (semplice o composta)
|
// trasformo in curva di Bezier (semplice o composta)
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( pCrv) ;
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( pCrv)) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
// 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() ||
|
if ( ! pArc->IsPlane() ||
|
||||||
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
! AreSameOrOppositeVectorExact( pArc->GetNormVersor(), vtNorm)) {
|
||||||
// trasformo in curva di Bezier (semplice o composta)
|
// trasformo in curva di Bezier (semplice o composta)
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( GetCurve( m_pGeoObj)) ;
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc( m_pGeoObj)) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// assegno alla nuova curva estrusione e spessore di quella originale
|
// assegno alla nuova curva estrusione e spessore di quella originale
|
||||||
|
|||||||
+14
@@ -101,6 +101,20 @@ GdbObj::CopyFrom( const GdbObj* pSou)
|
|||||||
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
return ( CopyAttribsFrom( pSou) && CopyTextureDataFrom( pSou) && CopyUserObjFrom( pSou)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
GdbObj::CopyStippleDataFrom( const GdbObj* pSou)
|
||||||
|
{
|
||||||
|
// se l'oggetto sorgente non esiste
|
||||||
|
if ( pSou == nullptr)
|
||||||
|
return false ;
|
||||||
|
// copio stipple
|
||||||
|
m_nStpFactor = pSou->m_nStpFactor ;
|
||||||
|
m_nStpPattern = pSou->m_nStpPattern ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
GdbObj::CopyAttribsFrom( const GdbObj* pSou)
|
GdbObj::CopyAttribsFrom( const GdbObj* pSou)
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ class GdbObj
|
|||||||
GdbObj( void) ;
|
GdbObj( void) ;
|
||||||
bool CopyFrom( const GdbObj* pSou) ;
|
bool CopyFrom( const GdbObj* pSou) ;
|
||||||
bool CopyAttribsFrom( const GdbObj* pSou) ;
|
bool CopyAttribsFrom( const GdbObj* pSou) ;
|
||||||
|
bool CopyStippleDataFrom( const GdbObj* pSou) ;
|
||||||
bool CopyTextureDataFrom( const GdbObj* pSou) ;
|
bool CopyTextureDataFrom( const GdbObj* pSou) ;
|
||||||
bool CopyUserObjFrom( const GdbObj* pSou) ;
|
bool CopyUserObjFrom( const GdbObj* pSou) ;
|
||||||
|
|
||||||
|
|||||||
+35
-35
@@ -28,41 +28,6 @@
|
|||||||
#define GEOOBJ_NGEIDTOTYPE( nNgeId) GeoObjFactory::NgeIdToType( nNgeId)
|
#define GEOOBJ_NGEIDTOTYPE( nNgeId) GeoObjFactory::NgeIdToType( nNgeId)
|
||||||
#define GEOOBJ_CREATE( nKey) GeoObjFactory::Create( nKey)
|
#define GEOOBJ_CREATE( nKey) GeoObjFactory::Create( nKey)
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
template <class T>
|
|
||||||
class GeoObjRegister
|
|
||||||
{
|
|
||||||
public :
|
|
||||||
static bool DoRegister( int nKey, int nNgeId)
|
|
||||||
{ if ( ! GeoObjFactory::Register( nKey, NgeAscKeyW[nNgeId], nNgeId, Create))
|
|
||||||
return false ;
|
|
||||||
GetTypePrivate() = nKey ;
|
|
||||||
GetKeyPrivate() = NgeAscKeyW[nNgeId] ;
|
|
||||||
GetNgeIdPrivate() = nNgeId ;
|
|
||||||
return true ; }
|
|
||||||
static IGeoObj* Create( void)
|
|
||||||
{ return new( std::nothrow) T ; }
|
|
||||||
static int GetType( void)
|
|
||||||
{ return GetTypePrivate() ; }
|
|
||||||
static const std::string& GetKey( void)
|
|
||||||
{ return GetKeyPrivate() ; }
|
|
||||||
static int GetNgeId( void)
|
|
||||||
{ return GetNgeIdPrivate() ; }
|
|
||||||
|
|
||||||
private :
|
|
||||||
GeoObjRegister( void) {}
|
|
||||||
~GeoObjRegister( void) {}
|
|
||||||
static int& GetTypePrivate( void)
|
|
||||||
{ static int s_nType ;
|
|
||||||
return s_nType ; }
|
|
||||||
static std::string& GetKeyPrivate( void)
|
|
||||||
{ static std::string s_sKey ;
|
|
||||||
return s_sKey ; }
|
|
||||||
static int& GetNgeIdPrivate( void)
|
|
||||||
{ static int s_nNgeId ;
|
|
||||||
return s_nNgeId ; }
|
|
||||||
} ;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class GeoObjFactory
|
class GeoObjFactory
|
||||||
{
|
{
|
||||||
@@ -117,3 +82,38 @@ class GeoObjFactory
|
|||||||
{ static CreatorMap s_CreatorMap ;
|
{ static CreatorMap s_CreatorMap ;
|
||||||
return s_CreatorMap ; }
|
return s_CreatorMap ; }
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
template <class T>
|
||||||
|
class GeoObjRegister
|
||||||
|
{
|
||||||
|
public :
|
||||||
|
static bool DoRegister( int nKey, int nNgeId)
|
||||||
|
{ if ( ! GeoObjFactory::Register( nKey, NgeAscKeyW[nNgeId], nNgeId, Create))
|
||||||
|
return false ;
|
||||||
|
GetTypePrivate() = nKey ;
|
||||||
|
GetKeyPrivate() = NgeAscKeyW[nNgeId] ;
|
||||||
|
GetNgeIdPrivate() = nNgeId ;
|
||||||
|
return true ; }
|
||||||
|
static IGeoObj* Create( void)
|
||||||
|
{ return new( std::nothrow) T ; }
|
||||||
|
static int GetType( void)
|
||||||
|
{ return GetTypePrivate() ; }
|
||||||
|
static const std::string& GetKey( void)
|
||||||
|
{ return GetKeyPrivate() ; }
|
||||||
|
static int GetNgeId( void)
|
||||||
|
{ return GetNgeIdPrivate() ; }
|
||||||
|
|
||||||
|
private :
|
||||||
|
GeoObjRegister( void) {}
|
||||||
|
~GeoObjRegister( void) {}
|
||||||
|
static int& GetTypePrivate( void)
|
||||||
|
{ static int s_nType ;
|
||||||
|
return s_nType ; }
|
||||||
|
static std::string& GetKeyPrivate( void)
|
||||||
|
{ static std::string s_sKey ;
|
||||||
|
return s_sKey ; }
|
||||||
|
static int& GetNgeIdPrivate( void)
|
||||||
|
{ static int s_nNgeId ;
|
||||||
|
return s_nNgeId ; }
|
||||||
|
} ;
|
||||||
|
|||||||
+13
-11
@@ -38,20 +38,22 @@ using namespace std ;
|
|||||||
class LockAddErase
|
class LockAddErase
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
LockAddErase(std::atomic_flag& bAddEraseOn, bool bUse = true): m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
LockAddErase( atomic_flag& bAddEraseOn, bool bUse = true)
|
||||||
|
: m_bAddEraseOn( bAddEraseOn), m_bUse( bUse)
|
||||||
{ if ( ! m_bUse) return ;
|
{ if ( ! m_bUse) return ;
|
||||||
while ( m_bAddEraseOn.test_and_set()) {
|
while ( m_bAddEraseOn.test_and_set( memory_order_acquire)) {
|
||||||
this_thread::sleep_for( chrono::nanoseconds{ 1}) ;
|
m_bAddEraseOn.wait( true, memory_order_relaxed) ;
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
~LockAddErase( void)
|
~LockAddErase( void)
|
||||||
{ if ( ! m_bUse) return ;
|
{ if ( ! m_bUse) return ;
|
||||||
m_bAddEraseOn.clear() ;
|
m_bAddEraseOn.clear( memory_order_release) ;
|
||||||
|
m_bAddEraseOn.notify_one() ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
std::atomic_flag& m_bAddEraseOn ;
|
atomic_flag& m_bAddEraseOn ;
|
||||||
bool m_bUse ;
|
bool m_bUse ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
@@ -611,7 +613,7 @@ GeomDB::GetGdbObj( int nId) const
|
|||||||
// radice
|
// radice
|
||||||
else if ( nId == GDB_ID_ROOT)
|
else if ( nId == GDB_ID_ROOT)
|
||||||
return &m_GrpRadix ;
|
return &m_GrpRadix ;
|
||||||
// un nodo qualubque
|
// un nodo qualunque
|
||||||
else
|
else
|
||||||
return m_IdManager.FindObj( nId) ;
|
return m_IdManager.FindObj( nId) ;
|
||||||
}
|
}
|
||||||
@@ -658,7 +660,7 @@ GeomDB::InsertInGeomDB( GdbObj* pGObj, int nRefId, int nSonBeforeAfter, bool bLo
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// inserisco come figlio, in testa alla lista del padre
|
// inserisco come figlio, in testa alla lista del padre
|
||||||
else if ( nSonBeforeAfter == GDB_FIRST_SON){
|
else if ( nSonBeforeAfter == GDB_FIRST_SON) {
|
||||||
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
GdbGroup* pGroup = ::GetGdbGroup( pGRef) ;
|
||||||
if ( pGroup == nullptr)
|
if ( pGroup == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
@@ -877,7 +879,7 @@ GeomDB::GetFirstNameInGroup( int nGroupId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbO->GetName( 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) ;
|
return ( pGdbO->m_nId) ;
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
pGdbO = pGdbO->GetNext() ;
|
pGdbO = pGdbO->GetNext() ;
|
||||||
@@ -905,7 +907,7 @@ GeomDB::GetNextName( int nId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbNext->GetName( 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) ;
|
return ( pGdbNext->m_nId) ;
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
pGdbNext = pGdbNext->GetNext() ;
|
pGdbNext = pGdbNext->GetNext() ;
|
||||||
@@ -933,7 +935,7 @@ GeomDB::GetLastNameInGroup( int nGroupId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbO->GetName( 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) ;
|
return ( pGdbO->m_nId) ;
|
||||||
// passo al precedente
|
// passo al precedente
|
||||||
pGdbO = pGdbO->GetPrev() ;
|
pGdbO = pGdbO->GetPrev() ;
|
||||||
@@ -961,7 +963,7 @@ GeomDB::GetPrevName( int nId, const string& sName) const
|
|||||||
// se ha il nome o la parte iniziale di nome cercato
|
// se ha il nome o la parte iniziale di nome cercato
|
||||||
string sObjName ;
|
string sObjName ;
|
||||||
if ( pGdbPrev->GetName( 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) ;
|
return ( pGdbPrev->m_nId) ;
|
||||||
// passo al precedente
|
// passo al precedente
|
||||||
pGdbPrev = pGdbPrev->GetPrev() ;
|
pGdbPrev = pGdbPrev->GetPrev() ;
|
||||||
|
|||||||
@@ -29,6 +29,10 @@ class GeomDB : public IGeomDB
|
|||||||
friend class GdbObj ;
|
friend class GdbObj ;
|
||||||
friend class GdbGroup ;
|
friend class GdbGroup ;
|
||||||
friend class GdbGeo ;
|
friend class GdbGeo ;
|
||||||
|
friend int CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||||
|
friend int CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob) ;
|
||||||
|
friend int DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId) ;
|
||||||
|
friend int DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp) ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
~GeomDB( void) override ;
|
~GeomDB( void) override ;
|
||||||
|
|||||||
+510
-137
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,9 @@ class IntersCrvCompoCrvCompo
|
|||||||
bool bAutoInters, bool bClosed, int nCurvesNbr) ;
|
bool bAutoInters, bool bClosed, int nCurvesNbr) ;
|
||||||
bool EraseCurrentInfo( int& nIndCurr, int& nIndOther) ;
|
bool EraseCurrentInfo( int& nIndCurr, int& nIndOther) ;
|
||||||
bool EraseOtherInfo( int& nIndCurr, int& nIndOther) ;
|
bool EraseOtherInfo( int& nIndCurr, int& nIndOther) ;
|
||||||
|
bool EraseBothInfo( int& nIndCurr, int& nIndOther) ;
|
||||||
|
bool CalcSide( int j, int i,const ICurve* pThisCrv, const ICurve* pOtherCrv, bool bCrvAOrB, int& nType) ;
|
||||||
|
bool MergeNewOverlap( int i, bool bCrvAOrB) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool m_bOverlaps ;
|
bool m_bOverlaps ;
|
||||||
|
|||||||
+104
-18
@@ -47,7 +47,7 @@ IntersCurveCurve::IntersCurveCurve( const ICurve& CurveA, const ICurve& CurveB,
|
|||||||
|
|
||||||
// ciclo sulle curve per verificare se da approssimare
|
// ciclo sulle curve per verificare se da approssimare
|
||||||
for ( int i = 0 ; i < 2 ; ++ i) {
|
for ( int i = 0 ; i < 2 ; ++ i) {
|
||||||
// se curva è arco da approssimare oppure è curva di Bezier
|
// se curva è arco da approssimare oppure è curva di Bezier
|
||||||
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
|
if ( ( m_pCurve[i]->GetType() == CRV_ARC && IsArcToApprox( *m_pCurve[i])) ||
|
||||||
m_pCurve[i]->GetType() == CRV_BEZIER) {
|
m_pCurve[i]->GetType() == CRV_BEZIER) {
|
||||||
// approssimo con rette
|
// approssimo con rette
|
||||||
@@ -127,7 +127,7 @@ IntersCurveCurve::IsArcToApprox( const ICurve& Curve)
|
|||||||
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
||||||
if ( pArc == nullptr)
|
if ( pArc == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico se non è nel piano XY o ha più di un giro al centro
|
// verifico se non è nel piano XY o ha più di un giro al centro
|
||||||
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
||||||
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||||
}
|
}
|
||||||
@@ -252,10 +252,10 @@ IntersCurveCurve::CrvCompoCrvCompoCalculate( const ICurve& CurveA, const ICurve&
|
|||||||
bool
|
bool
|
||||||
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
IntersCurveCurve::AdjustIntersParams( bool bAdjCrvA, bool bAdjCrvB)
|
||||||
{
|
{
|
||||||
// se non ci sono intersezioni, non va fatto alcunché
|
// se non ci sono intersezioni, non va fatto alcunché
|
||||||
if ( m_Info.empty())
|
if ( m_Info.empty())
|
||||||
return true ;
|
return true ;
|
||||||
// se le curve originali non sono state approssimate, non va fatto alcunché
|
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||||
if ( ! bAdjCrvA && ! bAdjCrvB)
|
if ( ! bAdjCrvA && ! bAdjCrvB)
|
||||||
return true ;
|
return true ;
|
||||||
// procedo ad aggiustare
|
// procedo ad aggiustare
|
||||||
@@ -291,6 +291,24 @@ IntersCurveCurve::GetIntersCount( void)
|
|||||||
return m_nIntersCount ;
|
return m_nIntersCount ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
IntersCurveCurve::GetInters3DCount( void)
|
||||||
|
{
|
||||||
|
int nCount = 0 ;
|
||||||
|
for ( int i = 0 ; i < m_nIntersCount ; ++i) {
|
||||||
|
if ( ! m_Info[i].bOverlap || ( m_Info[i].bOverlap && m_Info[i].bCBOverEq)) {
|
||||||
|
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[0].ptI.z) < EPS_SMALL)
|
||||||
|
++nCount ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[1].ptI.z) < EPS_SMALL)
|
||||||
|
++nCount ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nCount ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
IntersCurveCurve::GetCrossIntersCount( void)
|
IntersCurveCurve::GetCrossIntersCount( void)
|
||||||
@@ -340,6 +358,30 @@ IntersCurveCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurveCurve::GetInt3DCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
|
||||||
|
{
|
||||||
|
if ( nInd < 0 || nInd >= GetInters3DCount())
|
||||||
|
return false ;
|
||||||
|
int nCount = - 1 ;
|
||||||
|
for ( int i = 0 ; i < m_nIntersCount ; ++i) {
|
||||||
|
if ( ! m_Info[i].bOverlap || ( m_Info[i].bOverlap && m_Info[i].bCBOverEq)) {
|
||||||
|
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[0].ptI.z) < EPS_SMALL)
|
||||||
|
++nCount ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( abs( m_Info[i].IciA[0].ptI.z - m_Info[i].IciB[1].ptI.z) < EPS_SMALL)
|
||||||
|
++nCount ;
|
||||||
|
}
|
||||||
|
if ( nCount == nInd) {
|
||||||
|
aInfo = m_Info[nInd] ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d& ptI)
|
IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d& ptI)
|
||||||
@@ -347,11 +389,11 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d
|
|||||||
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
|
if ( m_nIntersCount == 0 || nCrv < 0 || nCrv > 1)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// ricerca del punto più vicino tra le intersezioni singole
|
// ricerca del punto più vicino tra le intersezioni singole
|
||||||
bool bFound = false ;
|
bool bFound = false ;
|
||||||
double dMinSqDist = SQ_INFINITO ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||||
// se è un'intersezione singola
|
// se è un'intersezione singola
|
||||||
if ( ! m_Info[i].bOverlap) {
|
if ( ! m_Info[i].bOverlap) {
|
||||||
// faccio la verifica sul punto
|
// faccio la verifica sul punto
|
||||||
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
|
Point3d ptP = ( nCrv == 0 ? m_Info[i].IciA[0].ptI : m_Info[i].IciB[0].ptI) ;
|
||||||
@@ -416,7 +458,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
|
|||||||
// se esiste almeno una intersezione
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ;
|
||||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||||
else
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ;
|
||||||
}
|
}
|
||||||
@@ -433,7 +475,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR&
|
|||||||
// se esiste almeno una intersezione
|
// se esiste almeno una intersezione
|
||||||
if ( m_nIntersCount >= 1)
|
if ( m_nIntersCount >= 1)
|
||||||
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ;
|
||||||
// altrimenti la curva è completamente interna oppure completamente esterna
|
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||||
else
|
else
|
||||||
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ;
|
||||||
}
|
}
|
||||||
@@ -498,7 +540,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
double dU2 = Info[j].IciA[1].dU ;
|
double dU2 = Info[j].IciA[1].dU ;
|
||||||
if ( dU2 < dU1 && pCurve->IsClosed())
|
if ( dU2 < dU1 && pCurve->IsClosed())
|
||||||
dU2 += dEndPar ;
|
dU2 += dEndPar ;
|
||||||
// se cade nell'intervallo è da saltare
|
// se cade nell'intervallo è da saltare
|
||||||
if ( Info[i].IciA[0].dU >= dU1 && Info[i].IciA[0].dU <= dU2) {
|
if ( Info[i].IciA[0].dU >= dU1 && Info[i].IciA[0].dU <= dU2) {
|
||||||
bToSkip = true ;
|
bToSkip = true ;
|
||||||
break ;
|
break ;
|
||||||
@@ -517,7 +559,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
double dCurrPar = dStartPar ;
|
double dCurrPar = dStartPar ;
|
||||||
double dCurrLen = 0 ;
|
double dCurrLen = 0 ;
|
||||||
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
||||||
// se è chiusa, recupero come finisce
|
// se è chiusa, recupero come finisce
|
||||||
if ( pCurve->IsClosed()) {
|
if ( pCurve->IsClosed()) {
|
||||||
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
||||||
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
|
nLastTy = InfoCorr[nNumInters-1].IciA[0].nNextTy ;
|
||||||
@@ -534,9 +576,25 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// costruisco il vettore delle classificazioni
|
// costruisco il vettore delle classificazioni
|
||||||
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||||
// se è definito un tratto precedente
|
// se è definito un tratto precedente
|
||||||
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ;
|
||||||
|
/*int j = i < nNumInters - 1 ? i + 1 : -1 ;
|
||||||
|
if ( pCurve->IsClosed() && j == - 1)
|
||||||
|
j = 0 ;*/
|
||||||
|
int j = i == 0 ? -1 : i - 1 ;
|
||||||
|
if ( pCurve->IsClosed() && j == - 1)
|
||||||
|
j = nNumInters - 1 ;
|
||||||
|
bool bSpike = false ;
|
||||||
|
if ( j != -1) {
|
||||||
|
bSpike = InfoCorr[i].bOverlap && InfoCorr[j].bOverlap && InfoCorr[i].bCBOverEq != InfoCorr[j].bCBOverEq ;
|
||||||
|
if ( bSpike) {
|
||||||
|
bSpike = abs( InfoCorr[i].IciA[0].dU - InfoCorr[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( InfoCorr[i].IciA[0].dU - InfoCorr[j].IciA[1].dU) < EPS_PARAM ||
|
||||||
|
abs( InfoCorr[i].IciA[1].dU - InfoCorr[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( InfoCorr[i].IciA[1].dU - InfoCorr[j].IciA[1].dU) < EPS_PARAM ;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||||
// verifico che la definizione sul tratto sia omogenea e valida
|
// verifico che la definizione sul tratto sia omogenea e valida
|
||||||
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ;
|
||||||
@@ -557,7 +615,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
// altrimenti, salvo il tipo
|
// altrimenti, salvo il tipo
|
||||||
else
|
else
|
||||||
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
|
nLastTy = InfoCorr[i].IciA[0].nNextTy ;
|
||||||
// se è definito un tratto in sovrapposizione
|
// se è definito un tratto in sovrapposizione
|
||||||
if ( InfoCorr[i].bOverlap) {
|
if ( InfoCorr[i].bOverlap) {
|
||||||
// assegno i dati
|
// assegno i dati
|
||||||
CrvClass segClass ;
|
CrvClass segClass ;
|
||||||
@@ -568,7 +626,11 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO
|
|||||||
// salvo dati correnti
|
// salvo dati correnti
|
||||||
dCurrPar = InfoCorr[i].IciA[1].dU ;
|
dCurrPar = InfoCorr[i].IciA[1].dU ;
|
||||||
dCurrLen = dLenU ;
|
dCurrLen = dLenU ;
|
||||||
nLastTy = InfoCorr[i].IciA[1].nNextTy ;
|
// se sono in un caso di spike devo trattare l'overlap in modo diverso
|
||||||
|
if ( ! bSpike)
|
||||||
|
nLastTy = InfoCorr[i].IciA[1].nNextTy ;
|
||||||
|
else
|
||||||
|
nLastTy = InfoCorr[i].IciA[0].nPrevTy ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// eventuale tratto finale rimasto
|
// eventuale tratto finale rimasto
|
||||||
@@ -597,7 +659,7 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
|||||||
double dStartParB, dEndParB ;
|
double dStartParB, dEndParB ;
|
||||||
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
|
if ( ! pCurveB->GetDomain( dStartParB, dEndParB))
|
||||||
return false ;
|
return false ;
|
||||||
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
|
// se almeno un punto di ciascuna curva è esterno al box dell'altra, sono sicuramente esterne
|
||||||
BBox3d boxCrvA, boxCrvB ;
|
BBox3d boxCrvA, boxCrvB ;
|
||||||
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
|
if ( ! pCurveA->GetLocalBBox( boxCrvA) ||
|
||||||
! pCurveB->GetLocalBBox( boxCrvB))
|
! pCurveB->GetLocalBBox( boxCrvB))
|
||||||
@@ -640,13 +702,37 @@ IntersCurveCurve::CalcCurveInOrOut( const ICurve* pCurveA, const ICurve* pCurveB
|
|||||||
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
||||||
// dichiaro la classe della curva per default
|
// dichiaro la classe della curva per default
|
||||||
int nClass = CRVC_OUT ;
|
int nClass = CRVC_OUT ;
|
||||||
// se c'è almeno una intersezione
|
// se c'è almeno una intersezione
|
||||||
if ( iCC.GetIntersCount() > 0) {
|
if ( iCC.GetIntersCount() > 0) {
|
||||||
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
||||||
IntCrvCrvInfo aInfo ;
|
IntCrvCrvInfo aInfo ;
|
||||||
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
||||||
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||||
nClass = CRVC_IN ;
|
nClass = CRVC_IN ;
|
||||||
|
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
|
||||||
|
nClass = CRVC_OUT ;
|
||||||
|
else if ( aInfo.IciA[0].nPrevTy == ICCT_NULL) {
|
||||||
|
// se il primo punto scelto non va bene allora ne cerco uno che mi dia informazioni sull'essere interno o esterno
|
||||||
|
CurveLine clLine ;
|
||||||
|
Point3d ptNewChoice ; pCurveA->GetPointD1D2( 0.25, ICurve::FROM_MINUS, ptNewChoice) ;
|
||||||
|
if ( ! clLine.SetPDL( ptNewChoice, 0, dLen))
|
||||||
|
return false ;
|
||||||
|
// calcolo l'intersezione
|
||||||
|
IntersCurveCurve iCC( clLine, *pCurveB) ;
|
||||||
|
if ( iCC.GetIntersCount() > 0) {
|
||||||
|
// se quanto precede la prima intersezione è interno, allora la curva è interna
|
||||||
|
IntCrvCrvInfo aInfo ;
|
||||||
|
iCC.GetIntCrvCrvInfo( 0, aInfo) ;
|
||||||
|
if ( aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||||
|
nClass = CRVC_IN ;
|
||||||
|
else if ( aInfo.IciA[0].nPrevTy == ICCT_OUT)
|
||||||
|
nClass = CRVC_OUT ;
|
||||||
|
else
|
||||||
|
return false ; // se arrivo qui potrei ritentare la ricerca
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// altrimenti sono esterni tra loro
|
// altrimenti sono esterni tra loro
|
||||||
else {
|
else {
|
||||||
@@ -670,7 +756,7 @@ IntersCurveCurve::GetCurveOutClass( const ICurve* pCurve, int& nClass)
|
|||||||
double dArea ;
|
double dArea ;
|
||||||
if ( ! pCurve->GetAreaXY( dArea))
|
if ( ! pCurve->GetAreaXY( dArea))
|
||||||
return false ;
|
return false ;
|
||||||
nClass = (( dArea > 0) ? CRVC_OUT : CRVC_IN) ;
|
nClass = (( dArea >= 0) ? CRVC_OUT : CRVC_IN) ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,459 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2025
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : IntersCurvePlane.cpp Data : 07.11.25 Versione : 2.7k1
|
||||||
|
// Contenuto : Implementazione della classe intersezione curva-piano.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 07.11.25 DB Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "GeoConst.h"
|
||||||
|
#include "CurveLine.h"
|
||||||
|
#include "CurveComposite.h"
|
||||||
|
#include "IntersLineLine.h"
|
||||||
|
#include "IntersLineArc.h"
|
||||||
|
#include "IntersArcArc.h"
|
||||||
|
#include "IntersCrvCompoCrvCompo.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLinePlane.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersCurvePlane.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
|
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||||
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
IntersCurvePlane::IntersCurvePlane( const ICurve& Curve, const Point3d& ptOrig, const Vector3d& vtN)
|
||||||
|
{
|
||||||
|
// Le intersezioni sono calcolate nel piano XY locale.
|
||||||
|
// Il flag bAreSegments vale solo per intersezione tra due linee e riguarda entrambe.
|
||||||
|
|
||||||
|
// inizializzazioni
|
||||||
|
m_nIntersCount = 0 ;
|
||||||
|
m_pCurve = &Curve ;
|
||||||
|
m_plPlane.Set( ptOrig, vtN) ;
|
||||||
|
|
||||||
|
// puntatore alla curva usata nei calcoli (originali o temporanee)
|
||||||
|
const ICurve* pCalcCrv ;
|
||||||
|
// per eventuale esplosione temporanea delle curve
|
||||||
|
PtrOwner<ICurve> pTmpCrv ;
|
||||||
|
|
||||||
|
// se curva è arco da approssimare oppure è curva di Bezier
|
||||||
|
if ( m_pCurve->GetType() == CRV_ARC || m_pCurve->GetType() == CRV_BEZIER || m_pCurve->GetType() == CRV_COMPO) {
|
||||||
|
// approssimo con rette
|
||||||
|
PolyLine PL ;
|
||||||
|
if ( ! m_pCurve->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
||||||
|
return ;
|
||||||
|
pTmpCrv.Set( CreateBasicCurveComposite()) ;
|
||||||
|
if ( IsNull( pTmpCrv))
|
||||||
|
return ;
|
||||||
|
if ( ! GetBasicCurveComposite( pTmpCrv)->FromPolyLine( PL))
|
||||||
|
return ;
|
||||||
|
pCalcCrv = pTmpCrv ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pCalcCrv = m_pCurve ;
|
||||||
|
|
||||||
|
m_Info.clear() ;
|
||||||
|
if ( pCalcCrv->GetType() == CRV_LINE) {
|
||||||
|
CalcIntersLinePlane( m_plPlane, *pCalcCrv) ;
|
||||||
|
}
|
||||||
|
else if ( pCalcCrv->GetType() == CRV_COMPO){
|
||||||
|
for ( int i = 0 ; i < GetBasicCurveComposite( pCalcCrv)->GetCurveCount(); ++i) {
|
||||||
|
const ICurve& subCurve = *GetBasicCurveComposite( pCalcCrv)->GetCurve( i) ;
|
||||||
|
CalcIntersLinePlane( m_plPlane, subCurve, i) ;
|
||||||
|
}
|
||||||
|
OrderAndCompleteIntersections() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// per curve approssimate, sistemo...
|
||||||
|
AdjustIntersParams( pCalcCrv != m_pCurve) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::CalcIntersLinePlane( const Plane3d& plPlane, const ICurve& Curve, int nCrv)
|
||||||
|
{
|
||||||
|
if ( Curve.GetType() != CRV_LINE)
|
||||||
|
return false ;
|
||||||
|
Point3d ptStart ; Curve.GetStartPoint( ptStart) ;
|
||||||
|
Point3d ptEnd ; Curve.GetEndPoint( ptEnd) ;
|
||||||
|
Point3d ptInt ;
|
||||||
|
double dLen = 0 ; Curve.GetLength( dLen) ;
|
||||||
|
int nIntersType = IntersLinePlane( ptStart, ptEnd, m_plPlane, ptInt, true) ;
|
||||||
|
// intersezione con attraversamento
|
||||||
|
if ( nIntersType == ILPT_YES) {
|
||||||
|
IntCrvPlnInfo icpi ;
|
||||||
|
icpi.Ici[0].ptI = ptInt ;
|
||||||
|
icpi.Ici[0].dU = Dist( ptInt, ptStart) / dLen + nCrv ;
|
||||||
|
Vector3d vtPos = ptStart - m_plPlane.GetPoint() ;
|
||||||
|
icpi.Ici[0].nPrevTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||||
|
icpi.Ici[0].nNextTy = icpi.Ici[0].nPrevTy == ICPT_IN ? ICPT_OUT : ICPT_IN ;
|
||||||
|
m_Info.push_back( icpi) ;
|
||||||
|
}
|
||||||
|
// intersezione con tocco
|
||||||
|
else if ( nIntersType == ILPT_START || nIntersType == ILPT_END) {
|
||||||
|
IntCrvPlnInfo icpi ;
|
||||||
|
icpi.Ici[0].ptI = ptInt ;
|
||||||
|
icpi.Ici[0].dU = nIntersType == ILPT_START ? 0 : 1 + nCrv ;
|
||||||
|
|
||||||
|
if ( nIntersType == ILPT_START) {
|
||||||
|
Vector3d vtPos = ptEnd - m_plPlane.GetPoint() ;
|
||||||
|
icpi.Ici[0].nNextTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||||
|
icpi.Ici[0].nPrevTy = ICPT_NULL ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Vector3d vtPos = ptStart - m_plPlane.GetPoint() ;
|
||||||
|
icpi.Ici[0].nPrevTy = vtPos * m_plPlane.GetVersN() > 0 ? ICPT_OUT : ICPT_IN ;
|
||||||
|
icpi.Ici[0].nNextTy = ICPT_NULL ;
|
||||||
|
}
|
||||||
|
m_Info.push_back( icpi) ;
|
||||||
|
}
|
||||||
|
// intersezione con sovrapposizione
|
||||||
|
else if ( nIntersType == ILPT_INPLANE) {
|
||||||
|
IntCrvPlnInfo icpi ;
|
||||||
|
icpi.bOverlap = true ;
|
||||||
|
icpi.Ici[0].ptI = ptStart ;
|
||||||
|
icpi.Ici[0].dU = 0 + nCrv;
|
||||||
|
icpi.Ici[1].ptI = ptEnd ;
|
||||||
|
icpi.Ici[1].dU = 1 + nCrv ;
|
||||||
|
icpi.Ici[0].nPrevTy = ICPT_NULL ;
|
||||||
|
icpi.Ici[0].nNextTy = ICPT_ON ;
|
||||||
|
icpi.Ici[1].nPrevTy = ICPT_ON ;
|
||||||
|
icpi.Ici[1].nNextTy = ICPT_NULL ;
|
||||||
|
m_Info.push_back( icpi) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void
|
||||||
|
IntersCurvePlane::OrderAndCompleteIntersections()
|
||||||
|
{
|
||||||
|
// cancello le interesezioni puntuali adiacenti a tratti di sovrapposizione
|
||||||
|
// riempio le info PrevTy e NexyTy
|
||||||
|
sort( m_Info.begin(), m_Info.end(), []( IntCrvPlnInfo& icpA, IntCrvPlnInfo& icpB) { return icpA.Ici[0].dU < icpA.Ici[0].dU ;}) ;
|
||||||
|
for ( int curr = m_Info.size() - 1 ; curr > - 1 ; --curr) {
|
||||||
|
int prev = curr == 0 ? m_Info.size() - 1 : curr - 1 ;
|
||||||
|
int next = curr == m_Info.size() - 1 ? 0 : curr + 1 ;
|
||||||
|
bool bErasedCurr = false ;
|
||||||
|
// solo le intersezioni di sovrapposizione o puntuali sullo start o end delle curve possono avere il PrevTy o NextTy non definito
|
||||||
|
if ( ! m_Info[curr].bOverlap) {
|
||||||
|
if ( m_Info[curr].Ici[0].nPrevTy == ICPT_NULL) {
|
||||||
|
if ( ! m_Info[prev].bOverlap) {
|
||||||
|
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[0].nNextTy ;
|
||||||
|
// se ho due puntuali che coincidono cancello il successivo tra i due ( corrente)
|
||||||
|
if ( AreSamePointApprox( m_Info[curr].Ici[0].ptI, m_Info[prev].Ici[0].ptI)) {
|
||||||
|
m_Info.erase(m_Info.begin() + curr) ;
|
||||||
|
bErasedCurr = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se ho un'intersezione puntuale che in realtà è la fine di un tratto di sovrapposizione, la cancello
|
||||||
|
else {
|
||||||
|
m_Info[prev].Ici[1].nNextTy = m_Info[curr].Ici[0].nNextTy ;
|
||||||
|
m_Info.erase(m_Info.begin() + curr) ;
|
||||||
|
bErasedCurr = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! bErasedCurr && m_Info[curr].Ici[0].nNextTy == ICPT_NULL){
|
||||||
|
if ( ! m_Info[prev].bOverlap)
|
||||||
|
m_Info[curr].Ici[0].nNextTy = m_Info[next].Ici[0].nPrevTy ;
|
||||||
|
// se ho un'intersezione puntuale che in realtà è la fine di un tratto di sovrapposizione, la cancello
|
||||||
|
else {
|
||||||
|
m_Info[next].Ici[0].nPrevTy = m_Info[curr].Ici[0].nPrevTy ;
|
||||||
|
m_Info.erase(m_Info.begin() + curr) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[curr].Ici[0].nPrevTy == ICPT_NULL) {
|
||||||
|
if ( ! m_Info[prev].bOverlap)
|
||||||
|
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[0].nNextTy ;
|
||||||
|
else
|
||||||
|
m_Info[curr].Ici[0].nPrevTy = m_Info[prev].Ici[1].nNextTy ;
|
||||||
|
}
|
||||||
|
if ( m_Info[curr].Ici[1].nNextTy == ICPT_NULL) {
|
||||||
|
if ( ! m_Info[next].bOverlap)
|
||||||
|
m_Info[curr].Ici[0].nNextTy = m_Info[prev].Ici[0].nPrevTy ;
|
||||||
|
else
|
||||||
|
m_Info[curr].Ici[0].nNextTy = m_Info[prev].Ici[1].nPrevTy ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_nIntersCount = m_Info.size() ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::IsArcToApprox( const ICurve& Curve)
|
||||||
|
{
|
||||||
|
// recupero l'arco
|
||||||
|
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
|
||||||
|
if ( pArc == nullptr)
|
||||||
|
return false ;
|
||||||
|
// verifico se non è nel piano XY o ha più di un giro al centro
|
||||||
|
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
|
||||||
|
abs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::AdjustIntersParams( bool bAdjCrv)
|
||||||
|
{
|
||||||
|
// se non ci sono intersezioni, non va fatto alcunché
|
||||||
|
if ( m_Info.empty())
|
||||||
|
return true ;
|
||||||
|
// se le curve originali non sono state approssimate, non va fatto alcunché
|
||||||
|
if ( ! bAdjCrv)
|
||||||
|
return true ;
|
||||||
|
// procedo ad aggiustare
|
||||||
|
for ( auto& aInfo : m_Info) {
|
||||||
|
// se curve originali approssimate, devo ricalcolare i parametri dei punti di intersezione
|
||||||
|
if ( bAdjCrv) {
|
||||||
|
if ( ! m_pCurve->GetParamAtPoint( aInfo.Ici[0].ptI, aInfo.Ici[0].dU, 10 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
if ( aInfo.bOverlap && ! m_pCurve->GetParamAtPoint( aInfo.Ici[1].ptI, aInfo.Ici[1].dU, 10 * EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
IntersCurvePlane::GetIntersCount( void)
|
||||||
|
{
|
||||||
|
return m_nIntersCount ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::GetIntCrvPlnInfo( int nInd, IntCrvPlnInfo& aInfo)
|
||||||
|
{
|
||||||
|
if ( nInd < 0 || nInd >= m_nIntersCount)
|
||||||
|
return false ;
|
||||||
|
aInfo = m_Info[nInd] ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI, double& dParam)
|
||||||
|
{
|
||||||
|
if ( m_nIntersCount == 0)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// ricerca del punto più vicino tra le intersezioni singole
|
||||||
|
bool bFound = false ;
|
||||||
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
|
for ( int i = 0 ; i < m_nIntersCount ; ++ i) {
|
||||||
|
// se è un'intersezione singola
|
||||||
|
if ( ! m_Info[i].bOverlap) {
|
||||||
|
// faccio la verifica sul punto
|
||||||
|
Point3d ptP = m_Info[i].Ici[0].ptI ;
|
||||||
|
double dSqDist = SqDist( ptNear, ptP) ;
|
||||||
|
if ( dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
ptI = ptP ;
|
||||||
|
dParam = m_Info[i].Ici[0].dU ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// altrimenti
|
||||||
|
else {
|
||||||
|
// recupero il tratto di sovrapposizione
|
||||||
|
double dUStartTrim, dUEndTrim ;
|
||||||
|
dUStartTrim = m_Info[i].Ici[0].dU ;
|
||||||
|
dUEndTrim = m_Info[i].Ici[1].dU ;
|
||||||
|
PtrOwner<ICurve> pCrv( m_pCurve->CopyParamRange( dUStartTrim, dUEndTrim)) ;
|
||||||
|
if ( IsNull( pCrv))
|
||||||
|
continue ;
|
||||||
|
// cerco il punto
|
||||||
|
int nFlag ;
|
||||||
|
Point3d ptP ;
|
||||||
|
if ( DistPointCurve( ptNear, *pCrv).GetMinDistPoint( 0.5, ptP, nFlag)) {
|
||||||
|
// faccio la verifica
|
||||||
|
double dSqDist = SqDist( ptNear, ptP) ;
|
||||||
|
if ( dSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dSqDist ;
|
||||||
|
ptI = ptP ;
|
||||||
|
m_pCurve->GetParamAtPoint( ptP, dParam) ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bFound ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::GetCurveClassification( double dLenMin, CRVPLNCVECTOR& ccClass)
|
||||||
|
{
|
||||||
|
// pulisco vettore classificazioni
|
||||||
|
ccClass.clear() ;
|
||||||
|
|
||||||
|
// verifico definizione della curva
|
||||||
|
if ( m_pCurve == nullptr)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// se esiste almeno una intersezione
|
||||||
|
if ( m_nIntersCount >= 1)
|
||||||
|
return CalcCurveClassification( m_pCurve, m_Info, dLenMin, ccClass) ;
|
||||||
|
// altrimenti la curva è completamente interna oppure completamente esterna
|
||||||
|
else
|
||||||
|
return CalcCurveInOrOut( m_pCurve, ccClass) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::CalcCurveClassification( const ICurve* pCurve, const ICPIVECTOR& Info, double dLenMin, CRVPLNCVECTOR& ccClass)
|
||||||
|
{
|
||||||
|
// numero intersezioni
|
||||||
|
int nNumInters = int( Info.size()) ;
|
||||||
|
if ( nNumInters < 1)
|
||||||
|
return false ;
|
||||||
|
// recupero il dominio parametrico della curva in esame
|
||||||
|
double dStartPar, dEndPar ;
|
||||||
|
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||||
|
return false ;
|
||||||
|
// limito lunghezza minima
|
||||||
|
dLenMin = max( dLenMin, EPS_ZERO) ;
|
||||||
|
// elimino intersezioni senza attraversamento che giacciono in intervalli di sovrapposizione
|
||||||
|
ICPIVECTOR InfoCorr ;
|
||||||
|
InfoCorr.reserve( Info.size()) ;
|
||||||
|
for ( size_t i = 0 ; i < Info.size() ; ++ i) {
|
||||||
|
// se intersezione puntuale senza attraversamento
|
||||||
|
if ( ! Info[i].bOverlap && Info[i].Ici[0].nPrevTy == Info[i].Ici[0].nNextTy) {
|
||||||
|
// confronto con le intersezioni con sovrapposizione
|
||||||
|
bool bToSkip = false ;
|
||||||
|
for ( size_t j = 0 ; j < Info.size() ; ++ j) {
|
||||||
|
// se coincide o puntuale
|
||||||
|
if ( j == i || ! Info[j].bOverlap)
|
||||||
|
continue ;
|
||||||
|
// determino l'intervallo parametrico tenendo conto di eventuale avvolgimento attorno all'inizio
|
||||||
|
double dU1 = Info[j].Ici[0].dU ;
|
||||||
|
double dU2 = Info[j].Ici[1].dU ;
|
||||||
|
if ( dU2 < dU1 && pCurve->IsClosed())
|
||||||
|
dU2 += dEndPar ;
|
||||||
|
// se cade nell'intervallo è da saltare
|
||||||
|
if ( Info[i].Ici[0].dU >= dU1 && Info[i].Ici[0].dU <= dU2) {
|
||||||
|
bToSkip = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bToSkip)
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// salvo dati intersezione
|
||||||
|
InfoCorr.emplace_back( Info[i]) ;
|
||||||
|
}
|
||||||
|
// aggiorno numero di intersezioni da considerare
|
||||||
|
nNumInters = int( InfoCorr.size()) ;
|
||||||
|
// recupero la classificazione all'inizio della curva
|
||||||
|
int nLastTy = ICCT_NULL ;
|
||||||
|
double dCurrPar = dStartPar ;
|
||||||
|
double dCurrLen = 0 ;
|
||||||
|
double dEndLen ; pCurve->GetLength( dEndLen) ;
|
||||||
|
// se è chiusa, recupero come finisce
|
||||||
|
if ( pCurve->IsClosed()) {
|
||||||
|
if ( ! InfoCorr[nNumInters-1].bOverlap)
|
||||||
|
nLastTy = InfoCorr[nNumInters-1].Ici[0].nNextTy ;
|
||||||
|
else {
|
||||||
|
nLastTy = InfoCorr[nNumInters-1].Ici[1].nNextTy ;
|
||||||
|
// se attraversa il punto di giunzione (parametro di fine minore di quello di inizio)
|
||||||
|
if ( InfoCorr[nNumInters-1].Ici[1].dU < InfoCorr[nNumInters-1].Ici[0].dU) {
|
||||||
|
dCurrPar = InfoCorr[nNumInters-1].Ici[1].dU ;
|
||||||
|
double dTmpLen ; pCurve->GetLengthAtParam( dCurrPar, dTmpLen) ;
|
||||||
|
dCurrLen = dTmpLen - dEndLen ;
|
||||||
|
dEndPar = dCurrPar ;
|
||||||
|
dEndLen = dTmpLen ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// costruisco il vettore delle classificazioni
|
||||||
|
for ( int i = 0 ; i < nNumInters ; ++ i) {
|
||||||
|
// se è definito un tratto precedente
|
||||||
|
double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].Ici[0].dU, dLenU) ;
|
||||||
|
if ( InfoCorr[i].Ici[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) {
|
||||||
|
// verifico che la definizione sul tratto sia omogenea e valida
|
||||||
|
int nPrevTy = InfoCorr[i].Ici[0].nPrevTy ;
|
||||||
|
if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) ||
|
||||||
|
nPrevTy == ICCT_NULL || nPrevTy == ICCT_ON)
|
||||||
|
return false ;
|
||||||
|
// assegno i dati
|
||||||
|
CrvPlaneClass segClass ;
|
||||||
|
segClass.dParS = dCurrPar ;
|
||||||
|
segClass.dParE = InfoCorr[i].Ici[0].dU ;
|
||||||
|
segClass.nClass = (( nPrevTy == ICCT_IN) ? CRVC_IN : CRVC_OUT) ;
|
||||||
|
ccClass.push_back( segClass) ;
|
||||||
|
// salvo dati correnti
|
||||||
|
dCurrPar = InfoCorr[i].Ici[0].dU ;
|
||||||
|
dCurrLen = dLenU ;
|
||||||
|
nLastTy = InfoCorr[i].Ici[0].nNextTy ;
|
||||||
|
}
|
||||||
|
// altrimenti, salvo il tipo
|
||||||
|
else
|
||||||
|
nLastTy = InfoCorr[i].Ici[0].nNextTy ;
|
||||||
|
// se è definito un tratto in sovrapposizione
|
||||||
|
if ( InfoCorr[i].bOverlap) {
|
||||||
|
// assegno i dati
|
||||||
|
CrvPlaneClass segClass ;
|
||||||
|
segClass.dParS = dCurrPar ;
|
||||||
|
segClass.dParE = InfoCorr[i].Ici[1].dU ;
|
||||||
|
segClass.nClass = CRVPLN_ON ;
|
||||||
|
ccClass.push_back( segClass) ;
|
||||||
|
// salvo dati correnti
|
||||||
|
dCurrPar = InfoCorr[i].Ici[1].dU ;
|
||||||
|
dCurrLen = dLenU ;
|
||||||
|
nLastTy = InfoCorr[i].Ici[1].nNextTy ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// eventuale tratto finale rimasto
|
||||||
|
if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > dLenMin) {
|
||||||
|
// verifico che la definizione sul tratto sia valida
|
||||||
|
if ( nLastTy == ICCT_NULL || nLastTy == ICCT_ON)
|
||||||
|
return false ;
|
||||||
|
// assegno i dati
|
||||||
|
CrvPlaneClass segClass ;
|
||||||
|
segClass.dParS = dCurrPar ;
|
||||||
|
segClass.dParE = dEndPar ;
|
||||||
|
segClass.nClass = (( nLastTy == ICCT_IN) ? CRVC_IN : CRVC_OUT) ;
|
||||||
|
ccClass.push_back( segClass) ;
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCurvePlane::CalcCurveInOrOut( const ICurve* pCurve, CRVPLNCVECTOR& ccClass)
|
||||||
|
{
|
||||||
|
// controllo di non avere intersezioni
|
||||||
|
int nNumInters = int( m_Info.size()) ;
|
||||||
|
if ( nNumInters > 0)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// se non ho intersezioni tra curva e piano devo solo capire da che parte del piano sta la curva
|
||||||
|
CrvPlaneClass cpClass ;
|
||||||
|
double dStartPar, dEndPar ;
|
||||||
|
if ( pCurve == nullptr || ! pCurve->GetDomain( dStartPar, dEndPar))
|
||||||
|
return false ;
|
||||||
|
Point3d ptStart ; pCurve->GetStartPoint( ptStart) ;
|
||||||
|
Vector3d vtCrv = ptStart - m_plPlane.GetPoint() ;
|
||||||
|
CrvPlaneClass segClass ;
|
||||||
|
segClass.dParS = dStartPar ;
|
||||||
|
segClass.dParE = dEndPar ;
|
||||||
|
segClass.nClass = ( (vtCrv * m_plPlane.GetVersN() < 0) ? CRVC_IN : CRVC_OUT) ;
|
||||||
|
ccClass.push_back( segClass) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
+17
-5
@@ -113,7 +113,7 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
|||||||
double dU1, dU2 ;
|
double dU1, dU2 ;
|
||||||
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
bool bInters = IntersLineBox( ptL, vtL, b3Box.GetMin(), b3Box.GetMax(), dU1, dU2) ;
|
||||||
|
|
||||||
// Se non c'è intersezione
|
// Se non c'è intersezione
|
||||||
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
if ( ! bInters || ( bFinite && ( dU1 > dLen + EPS_SMALL || dU2 < -EPS_SMALL)))
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
@@ -144,8 +144,14 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
|||||||
else if ( dU2 < EPS_SMALL)
|
else if ( dU2 < EPS_SMALL)
|
||||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||||
else {
|
else {
|
||||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
if ( dU1 < - EPS_SMALL)
|
||||||
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
vInters.emplace_back( ILBT_TG_INSIDE, 0.) ;
|
||||||
|
else
|
||||||
|
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
||||||
|
if ( dU2 > dLen + EPS_SMALL)
|
||||||
|
vInters.emplace_back( ILBT_TG_INSIDE, dLen) ;
|
||||||
|
else
|
||||||
|
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
@@ -162,8 +168,14 @@ IntersLineBox( const Point3d& ptL, const Vector3d& vtL, double dLen, const BBox3
|
|||||||
else if ( dU2 < EPS_SMALL)
|
else if ( dU2 < EPS_SMALL)
|
||||||
vInters.emplace_back( ILBT_OUT, 0) ;
|
vInters.emplace_back( ILBT_OUT, 0) ;
|
||||||
else {
|
else {
|
||||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
if ( dU1 < - EPS_SMALL)
|
||||||
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
vInters.emplace_back( ILBT_INSIDE, 0.) ;
|
||||||
|
else
|
||||||
|
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
||||||
|
if ( dU2 > dLen + EPS_SMALL)
|
||||||
|
vInters.emplace_back( ILBT_INSIDE, dLen) ;
|
||||||
|
else
|
||||||
|
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
|
|||||||
+171
-53
@@ -15,6 +15,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "IntersLineCyl.h"
|
#include "IntersLineCyl.h"
|
||||||
#include "/EgtDev/Include/EGkFrame3d.h"
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineCylinder.h"
|
||||||
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
@@ -25,99 +26,176 @@ using namespace std ;
|
|||||||
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
IntersLineCyl( const Point3d& ptP, const Vector3d& vtV, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||||
double dRad, double dHeight,
|
double& dU1, Point3d& ptInt1, Vector3d& vtN1, double& dU2, Point3d& ptInt2, Vector3d& vtN2, bool bIgnoreTap, bool bInvertNormals)
|
||||||
double& dU1, double& dU2)
|
|
||||||
{
|
{
|
||||||
// Verifico il versore
|
dU1 = NAN ;
|
||||||
if ( vtL.IsSmall())
|
dU2 = NAN ;
|
||||||
|
|
||||||
|
// Verifico il versore
|
||||||
|
if ( vtV.IsSmall())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// Verifico il cilindro
|
// Verifico il cilindro
|
||||||
if ( dRad < EPS_SMALL || dHeight < EPS_SMALL)
|
if ( dRad < EPS_SMALL || dH < EPS_SMALL)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
||||||
int nBasInt = 0 ;
|
int nBasInt = 0 ;
|
||||||
if ( abs( vtL.z) > EPS_ZERO) {
|
if ( abs( vtV.z) > EPS_ZERO) {
|
||||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
// le linee tangenti al cilindro non sono considerate intersecanti
|
||||||
double EpsRad = ( vtL.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
double dEpsRad = ( vtV.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
||||||
Point3d ptInt1 = ptL + ( ( 0 - ptL.z) / vtL.z) * vtL ;
|
if ( bIgnoreTap)
|
||||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * EpsRad) {
|
dEpsRad = 0. ;
|
||||||
dU1 = ( ptInt1 - ptL) * vtL ;
|
ptInt1 = ptP + ( ( 0 - ptP.z) / vtV.z) * vtV ;
|
||||||
|
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||||
nBasInt += 1 ;
|
nBasInt += 1 ;
|
||||||
|
vtN1 = - Z_AX ;
|
||||||
|
dU1 = ( ( 0 - ptP.z) / vtV.z) ;
|
||||||
}
|
}
|
||||||
Point3d ptInt2 = ptL + ( ( dHeight - ptL.z) / vtL.z) * vtL ;
|
ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ;
|
||||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * EpsRad) {
|
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
||||||
dU2 = ( ptInt2 - ptL) * vtL ;
|
|
||||||
nBasInt += 2 ;
|
nBasInt += 2 ;
|
||||||
|
vtN2 = Z_AX ;
|
||||||
|
dU2 = ( ( dH - ptP.z) / vtV.z) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
||||||
if ( nBasInt == 3) {
|
if ( nBasInt == 3) {
|
||||||
if ( dU1 > dU2)
|
if ( dU1 > dU2) {
|
||||||
swap( dU1, dU2) ;
|
swap( dU1, dU2) ;
|
||||||
// Trovate intersezioni
|
swap( ptInt1, ptInt2) ;
|
||||||
|
swap( vtN1, vtN2) ;
|
||||||
|
}
|
||||||
|
if ( bInvertNormals) {
|
||||||
|
vtN1 *= - 1 ;
|
||||||
|
vtN2 *= - 1 ;
|
||||||
|
}
|
||||||
|
// Trovate intersezioni
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determino le intersezioni con la superficie laterale del cilindro
|
// Determino le intersezioni con la superficie laterale del cilindro
|
||||||
DBLVECTOR vdCoeff{ ptL.x * ptL.x + ptL.y * ptL.y - dRad * dRad,
|
DBLVECTOR vdCoeff{ ptP.x * ptP.x + ptP.y * ptP.y - dRad * dRad,
|
||||||
2 * ( ptL.x * vtL.x + ptL.y * vtL.y),
|
2 * ( ptP.x * vtV.x + ptP.y * vtV.y),
|
||||||
vtL.x * vtL.x + vtL.y * vtL.y} ;
|
vtV.x * vtV.x + vtV.y * vtV.y} ;
|
||||||
DBLVECTOR vdRoots ;
|
DBLVECTOR vdRoots ;
|
||||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||||
|
|
||||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
// Epsilon per piani di tappo
|
||||||
|
double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ;
|
||||||
|
double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ;
|
||||||
|
if ( bIgnoreTap) {
|
||||||
|
dEpsLow = 0. ;
|
||||||
|
dEpsUp = 0. ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
||||||
if ( nRoot == 2) {
|
if ( nRoot == 2) {
|
||||||
double dIntZ2 = ptL.z + vdRoots[1] * vtL.z ;
|
double dIntZ2 = ptP.z + vdRoots[1] * vtV.z ;
|
||||||
if ( dIntZ2 < 0 - EPS_SMALL || dIntZ2 > dHeight + EPS_SMALL)
|
if ( dIntZ2 < 0 + dEpsLow || dIntZ2 > dH + dEpsUp)
|
||||||
-- nRoot ;
|
-- nRoot ;
|
||||||
}
|
}
|
||||||
if ( nRoot >= 1) {
|
if ( nRoot >= 1) {
|
||||||
double dIntZ1 = ptL.z + vdRoots[0] * vtL.z ;
|
double dIntZ1 = ptP.z + vdRoots[0] * vtV.z ;
|
||||||
if ( dIntZ1 < 0 - EPS_SMALL || dIntZ1 > dHeight + EPS_SMALL) {
|
if ( dIntZ1 < 0 + dEpsLow || dIntZ1 > dH + dEpsUp) {
|
||||||
if ( nRoot == 2)
|
if ( nRoot == 2)
|
||||||
vdRoots[0] = vdRoots[1] ;
|
vdRoots[0] = vdRoots[1] ;
|
||||||
-- nRoot ;
|
-- nRoot ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
// Due soluzioni: la retta interseca due volte la superficie laterale
|
||||||
if ( nRoot == 2) {
|
if ( nRoot == 2) {
|
||||||
|
// Punti di intersezione con la superficie del cilindro
|
||||||
|
ptInt1 = ptP + vdRoots[0] * vtV ;
|
||||||
|
ptInt2 = ptP + vdRoots[1] * vtV ;
|
||||||
dU1 = vdRoots[0] ;
|
dU1 = vdRoots[0] ;
|
||||||
dU2 = vdRoots[1] ;
|
dU2 = vdRoots[1] ;
|
||||||
if ( dU1 > dU2)
|
// Determino le normali
|
||||||
|
vtN1.Set( ptInt1.x, ptInt1.y, 0) ;
|
||||||
|
vtN1.Normalize() ;
|
||||||
|
vtN2.Set( ptInt2.x, ptInt2.y, 0) ;
|
||||||
|
vtN2.Normalize() ;
|
||||||
|
if ( dU1 > dU2) {
|
||||||
swap( dU1, dU2) ;
|
swap( dU1, dU2) ;
|
||||||
// Trovate intersezioni
|
swap( ptInt1, ptInt2) ;
|
||||||
return true ;
|
swap( vtN1, vtN2) ;
|
||||||
}
|
|
||||||
|
|
||||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
|
||||||
else if ( nRoot == 1) {
|
|
||||||
// Se piano superiore
|
|
||||||
if ( nBasInt == 2) {
|
|
||||||
dU1 = vdRoots[0] ;
|
|
||||||
}
|
}
|
||||||
// altrimenti piano inferiore
|
if ( bInvertNormals) {
|
||||||
else if ( nBasInt == 1) {
|
vtN1 *= - 1 ;
|
||||||
dU2 = vdRoots[0] ;
|
vtN2 *= - 1 ;
|
||||||
}
|
}
|
||||||
// altrimenti niente
|
// Trovate intersezioni
|
||||||
else
|
|
||||||
return false ;
|
|
||||||
if ( dU1 > dU2)
|
|
||||||
swap( dU1, dU2) ;
|
|
||||||
// Trovate intersezioni
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nessuna soluzione : nessuna intersezione
|
// Una soluzione : la retta interseca la superficie laterale e un piano
|
||||||
|
else if ( nRoot == 1) {
|
||||||
|
// Se piano superiore
|
||||||
|
if ( nBasInt == 2) {
|
||||||
|
// Punto di intersezione
|
||||||
|
dU1 = vdRoots[0] ;
|
||||||
|
ptInt1 = ptP + vdRoots[0] * vtV ;
|
||||||
|
// Normale alla superficie del cilindro verso l'interno
|
||||||
|
vtN1.Set( ptInt1.x, ptInt1.y, 0) ;
|
||||||
|
vtN1.Normalize() ;
|
||||||
|
}
|
||||||
|
// altrimenti piano inferiore
|
||||||
|
else if ( nBasInt == 1) {
|
||||||
|
// Punto di intersezione
|
||||||
|
dU2 = vdRoots[0] ;
|
||||||
|
ptInt2 = ptP + vdRoots[0] * vtV ;
|
||||||
|
// Normale alla superficie del cilindro verso l'interno
|
||||||
|
vtN2.Set( ptInt2.x, ptInt2.y, 0) ;
|
||||||
|
vtN2.Normalize() ;
|
||||||
|
}
|
||||||
|
// altrimenti niente
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
if ( dU1 > dU2) {
|
||||||
|
swap( dU1, dU2) ;
|
||||||
|
swap( ptInt1, ptInt2) ;
|
||||||
|
swap( vtN1, vtN2) ;
|
||||||
|
}
|
||||||
|
if ( bInvertNormals) {
|
||||||
|
vtN1 *= - 1 ;
|
||||||
|
vtN2 *= - 1 ;
|
||||||
|
}
|
||||||
|
// Trovate intersezioni
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Nessuna soluzione : nessuna intersezione
|
||||||
else
|
else
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Riferimento con origine nel centro della base e asse di simmetria coincidente con l'asse Z.
|
||||||
|
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersLineCyl( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||||
|
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||||
|
double& dU1, Point3d& ptInt1, Vector3d& vtN1, double& dU2, Point3d& ptInt2, Vector3d& vtN2, bool bIgnoreTap, bool bInvertNormals)
|
||||||
|
{
|
||||||
|
// Porto la linea nel riferimento del cilindro
|
||||||
|
Point3d ptP = GetToLoc( ptLineSt, CylFrame) ;
|
||||||
|
Vector3d vtV = GetToLoc( vtLineDir, CylFrame) ;
|
||||||
|
if ( IntersLineCyl( ptP, vtV, dH, dRad, bTapLow, bTapUp,
|
||||||
|
dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, bIgnoreTap, bInvertNormals))
|
||||||
|
{
|
||||||
|
ptInt1.ToGlob( CylFrame) ;
|
||||||
|
vtN1.ToGlob( CylFrame) ;
|
||||||
|
ptInt2.ToGlob( CylFrame) ;
|
||||||
|
vtN2.ToGlob( CylFrame) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Linea e cilindro sono nel medesimo riferimento.
|
// Linea e cilindro sono nel medesimo riferimento.
|
||||||
// Il cilindro è definito con centro della base, asse, raggio e altezza.
|
// Il cilindro è definito con centro della base, asse, raggio e altezza.
|
||||||
@@ -133,7 +211,13 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
if ( ! frCyl.Set( ptCyl, vtCyl))
|
if ( ! frCyl.Set( ptCyl, vtCyl))
|
||||||
return false ;
|
return false ;
|
||||||
// Ora eseguo i conti nel riferimento intrinseco
|
// Ora eseguo i conti nel riferimento intrinseco
|
||||||
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
|
bool bTapLow = false ;
|
||||||
|
bool bTapUp = false ;
|
||||||
|
bool bIgnoreTap = true ;
|
||||||
|
Point3d ptInt1, ptInt2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
|
return IntersLineCyl( ptL, vtL, frCyl, dHeight, dRad, bTapLow, bTapUp,
|
||||||
|
dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, bIgnoreTap) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -144,7 +228,7 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
bool
|
bool
|
||||||
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||||
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
||||||
double& dU1, double& dU2)
|
double& dU1, double& dU2)
|
||||||
{
|
{
|
||||||
// Determino asse ed altezza del cilindro
|
// Determino asse ed altezza del cilindro
|
||||||
Vector3d vtCyl = ptCyl2 - ptCyl1 ;
|
Vector3d vtCyl = ptCyl2 - ptCyl1 ;
|
||||||
@@ -157,5 +241,39 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
if ( ! frCyl.Set( ptCyl1, vtCyl))
|
if ( ! frCyl.Set( ptCyl1, vtCyl))
|
||||||
return false ;
|
return false ;
|
||||||
// Ora eseguo i conti nel riferimento intrinseco
|
// Ora eseguo i conti nel riferimento intrinseco
|
||||||
return IntersLineCyl( GetToLoc( ptL, frCyl), GetToLoc( vtL, frCyl), dRad, dHeight, dU1, dU2) ;
|
bool bTapLow = false ;
|
||||||
|
bool bTapUp = false ;
|
||||||
|
bool bIgnoreTap = true ;
|
||||||
|
Point3d ptInt1, ptInt2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
|
return IntersLineCyl( ptL, vtL, frCyl, dHeight, dRad, bTapLow, bTapUp,
|
||||||
|
dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, bIgnoreTap) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// linea già nel riferimento intrinseco del cilindro
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||||
|
double dRad, double dHeight,
|
||||||
|
double& dU1, double& dU2)
|
||||||
|
{
|
||||||
|
Point3d ptInt1, ptInt2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
|
bool bTapLow = false, bTapUp = false ;
|
||||||
|
bool bIgnoreTap = true ;
|
||||||
|
return IntersLineCyl( ptL, vtL, dHeight, dRad, bTapLow, bTapUp,
|
||||||
|
dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, bIgnoreTap) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// funzione esposta per altre dll
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersLineCyl( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||||
|
const Frame3d& CylFrame, double dH, double dRad,
|
||||||
|
double& dU1, Point3d& ptInt1, Vector3d& vtN1, double& dU2, Point3d& ptInt2, Vector3d& vtN2)
|
||||||
|
{
|
||||||
|
return IntersLineCyl( ptLineSt, vtLineDir, CylFrame, dH, dRad, false, false,
|
||||||
|
dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, true, false) ;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-4
@@ -20,17 +20,27 @@
|
|||||||
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
// Il cilindro è centrato sull'asse Z e appoggiato sul piano XY.
|
||||||
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
// Con intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
bool
|
||||||
double dRad, double dHeight,
|
IntersLineCyl( const Point3d& ptP, const Vector3d& vtV, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||||
double& dU1, double& dU2) ;
|
double& dU1, Point3d& ptInt1, Vector3d& vtN1, double& dU2, Point3d& ptInt2, Vector3d& vtN2, bool bIgnoreTap = false, bool bInvertNormals = false) ;
|
||||||
|
|
||||||
|
// come sopra ma passo il riferimento intrinseco del cilindro in cui portare la linea
|
||||||
|
bool
|
||||||
|
IntersLineCyl( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||||
|
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
||||||
|
double& dU1, Point3d& ptInt1, Vector3d& vtN1, double& dU2, Point3d& ptInt2, Vector3d& vtN2, bool bIgnoreTap = false, bool bInvertNormals = false) ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
inline bool
|
inline bool
|
||||||
TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
TestIntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||||
double dRad, double dHeight)
|
double dRad, double dHeight)
|
||||||
{
|
{
|
||||||
|
Point3d ptInt1, ptInt2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
double dU1, dU2 ;
|
double dU1, dU2 ;
|
||||||
return IntersLineCyl( ptL, vtL, dRad, dHeight, dU1, dU2) ;
|
bool bTapLow = false, bTapUp = false ;
|
||||||
|
bool bIgnoreTap = true ;
|
||||||
|
return IntersLineCyl( ptL, vtL, dHeight, dRad, bTapLow, bTapUp, dU1, ptInt1, vtN1, dU2, ptInt2, vtN2, bIgnoreTap) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -50,3 +60,12 @@ bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||||
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
const Point3d& ptCyl1, const Point3d& ptCyl2, double dRad,
|
||||||
double& dU1, double& dU2) ;
|
double& dU1, double& dU2) ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// // Linea e cilindro sono nel medesimo riferimento.
|
||||||
|
// Il cilindro è definito con raggio e altezza. ( la linea è già nel riferimento intrinseco del cilindro)
|
||||||
|
// In caso di intersezione viene restituito true e i parametri in dU1 e dU2.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
||||||
|
double dRad, double dHeight,
|
||||||
|
double& dU1, double& dU2) ;
|
||||||
|
|||||||
@@ -159,6 +159,36 @@ IntersLineLine::IntersFiniteLines( const CurveLine& Line1, const CurveLine& Line
|
|||||||
// flag per segmenti che si allontanano significativamente
|
// flag per segmenti che si allontanano significativamente
|
||||||
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
bool bFarEnds = ( nS1Side != 0 || nE1Side != 0 || nS2Side != 0 || nE2Side != 0) ;
|
||||||
|
|
||||||
|
// analisi casi speciali di quasi parallelismo
|
||||||
|
// segmento sovrapposto all'altro
|
||||||
|
double dDist1, dDist2 ;
|
||||||
|
if ( nS1Side == 0 || nE1Side == 0 || nS1Side == nE1Side) {
|
||||||
|
dDist1 = CrossXY( ptS1 - ptS2, vtDir2) ;
|
||||||
|
dDist2 = CrossXY( ptE1 - ptS2, vtDir2) ;
|
||||||
|
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen2XY) {
|
||||||
|
bParallel = true ;
|
||||||
|
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( nS2Side == 0 || nE2Side == 0 || nS2Side == nE2Side) {
|
||||||
|
dDist1 = CrossXY( ptS2 - ptS1, vtDir1) ;
|
||||||
|
dDist2 = CrossXY( ptE2 - ptS1, vtDir1) ;
|
||||||
|
if ( abs( dDist1 - dDist2) < EPS_SMALL * dLen1XY) {
|
||||||
|
bParallel = true ;
|
||||||
|
bFarEnds = ! ( (nS1Side == 0 && nE1Side == 0) || (nS2Side == 0 && nE2Side == 0)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// estremità sovrapposte di poco
|
||||||
|
if ( ! bParallel && abs( dCrossXY) < ( 0.1 * DEGTORAD) * ( dLen1XY * dLen2XY)) {
|
||||||
|
if (( nS1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptS1, ptS2, 2 * EPS_SMALL)) ||
|
||||||
|
( nS1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptS1, ptE2, 2 * EPS_SMALL)) ||
|
||||||
|
( nE1Side == 0 && nS2Side == 0 && ScalarXY( vtDir1, vtDir2) > 0 && ! AreSamePointXYEpsilon( ptE1, ptS2, 2 * EPS_SMALL)) ||
|
||||||
|
( nE1Side == 0 && nE2Side == 0 && ScalarXY( vtDir1, vtDir2) < 0 && ! AreSamePointXYEpsilon( ptE1, ptE2, 2 * EPS_SMALL))) {
|
||||||
|
bParallel = true ;
|
||||||
|
bFarEnds = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// se non sono paralleli e si allontanano tra loro abbastanza
|
// se non sono paralleli e si allontanano tra loro abbastanza
|
||||||
if ( ! bParallel && bFarEnds) {
|
if ( ! bParallel && bFarEnds) {
|
||||||
// posizioni parametriche dell'intersezione sulle linee
|
// posizioni parametriche dell'intersezione sulle linee
|
||||||
|
|||||||
+623
-28
@@ -14,11 +14,17 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
|
#include "CurveBezier.h"
|
||||||
|
#include "CurveComposite.h"
|
||||||
|
#include "SurfFlatRegion.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointSurfFr.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfBez.h"
|
||||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||||
|
#include "/EgtDev/Include/ENkPolynomialRoots.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -28,7 +34,6 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b
|
|||||||
const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz)
|
const ISurfBezier* pSurfBz, Point3d& ptSP, Point3d& ptIBz)
|
||||||
{
|
{
|
||||||
// la funzione raffina la posisione del punto ptSP, minimizzando la distanza dalla retta e restituisce il punto di intersezione ptIBz
|
// la funzione raffina la posisione del punto ptSP, minimizzando la distanza dalla retta e restituisce il punto di intersezione ptIBz
|
||||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
|
||||||
// usando un algoritmo di newton cerco di avvicinarmi il più possibile alla retta
|
// usando un algoritmo di newton cerco di avvicinarmi il più possibile alla retta
|
||||||
DistPointLine dpl( ptIBz, ptL, vtL, dLen, bFinite) ;
|
DistPointLine dpl( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||||
double dDistNew = 0, dDistPre = 0 ;
|
double dDistNew = 0, dDistPre = 0 ;
|
||||||
@@ -42,18 +47,18 @@ RefineIntersNewton( const Point3d& ptL, const Vector3d& vtL, double dLen, bool b
|
|||||||
while ( dDistNew > EPS_SMALL && nCount < 100) {
|
while ( dDistNew > EPS_SMALL && nCount < 100) {
|
||||||
dDistPre = dDistNew ;
|
dDistPre = dDistNew ;
|
||||||
Point3d ptIBzNew1 ;
|
Point3d ptIBzNew1 ;
|
||||||
pSurfBz->GetPointD1D2( ( ptSP.x + dh) / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ;
|
pSurfBz->GetPointD1D2( ( ptSP.x + dh), ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew1) ;
|
||||||
DistPointLine dplNewU( ptIBzNew1, ptL, vtL, dLen, bFinite) ;
|
DistPointLine dplNewU( ptIBzNew1, ptL, vtL, dLen, bFinite) ;
|
||||||
dplNewU.GetDist( dDistNew) ;
|
dplNewU.GetDist( dDistNew) ;
|
||||||
double dfdU = ( dDistNew - dDistPre) / dh ;
|
double dfdU = ( dDistNew - dDistPre) / dh ;
|
||||||
Point3d ptIBzNew2 ;
|
Point3d ptIBzNew2 ;
|
||||||
pSurfBz->GetPointD1D2( ptSP.x / SBZ_TREG_COEFF, ( ptSP.y + dh) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ;
|
pSurfBz->GetPointD1D2( ptSP.x, ( ptSP.y + dh), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBzNew2) ;
|
||||||
DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ;
|
DistPointLine dplNewV( ptIBzNew2, ptL, vtL, dLen, bFinite) ;
|
||||||
dplNewV.GetDist( dDistNew) ;
|
dplNewV.GetDist( dDistNew) ;
|
||||||
double dfdV = ( dDistNew - dDistPre) / dh ;
|
double dfdV = ( dDistNew - dDistPre) / dh ;
|
||||||
// mi avvicino cercando di annullare la distanza in un colpo solo
|
// mi avvicino cercando di annullare la distanza in un colpo solo
|
||||||
double dr = - dDistPre / ( dfdU + dfdV) ;
|
double dr = - dDistPre / ( dfdU + dfdV) ;
|
||||||
pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU) / SBZ_TREG_COEFF, ( ptSP.y + dr * dfdV) / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
pSurfBz->GetPointD1D2(( ptSP.x + dr * dfdU), ( ptSP.y + dr * dfdV), ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz) ;
|
||||||
DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ;
|
DistPointLine dplNew( ptIBz, ptL, vtL, dLen, bFinite) ;
|
||||||
dplNew.GetDist( dDistNew) ;
|
dplNew.GetDist( dDistNew) ;
|
||||||
++ nCount ;
|
++ nCount ;
|
||||||
@@ -67,14 +72,28 @@ static void
|
|||||||
UpdateInfoIntersLineSurfBz( const Point3d& ptL, const Vector3d& vtDir, int nILT, int nT, const Point3d& ptSP, const Point3d& ptIBz, double dCos,
|
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)
|
const Point3d& ptSP2, const Point3d& ptIBz2, double dCos2, ILSBIVECTOR& vInfo)
|
||||||
{
|
{
|
||||||
if ( nILT == ILTT_IN || nILT == ILTT_EDGE || nILT == ILTT_VERT) {
|
int nType = LSBT_NONE ;
|
||||||
|
if ( dCos > EPS_ZERO)
|
||||||
|
nType = LSBT_IN ;
|
||||||
|
else if ( dCos < EPS_ZERO)
|
||||||
|
nType = LSBT_OUT ;
|
||||||
|
else
|
||||||
|
nType = LSBT_TOUCH ;
|
||||||
|
|
||||||
|
if ( nILT == ILTA_IN || nILT == ILTA_EDGE || nILT == ILTA_VERT || nILT == ILTA_NO_TRIA) {
|
||||||
double dU = ( ptIBz - ptL) * vtDir ;
|
double dU = ( ptIBz - ptL) * vtDir ;
|
||||||
vInfo.emplace_back( nILT, dU, nT, dCos, ptIBz, ptSP) ;
|
vInfo.emplace_back( nType, 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 dU = ( ptIBz - ptL) * vtDir ;
|
||||||
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
double dU2 = ( ptIBz2 - ptL) * vtDir ;
|
||||||
vInfo.emplace_back( nILT, dU, dU2, nT, dCos2, ptIBz, ptIBz2, ptSP, ptSP2) ;
|
int nType2 = LSBT_NONE ;
|
||||||
|
if ( dCos2 > EPS_ZERO)
|
||||||
|
nType2 = LSBT_IN ;
|
||||||
|
else if ( dCos2 < EPS_ZERO)
|
||||||
|
nType2 = LSBT_OUT ;
|
||||||
|
vInfo.emplace_back( nType, dU, 0, nT, dCos, ptIBz, P_INVALID, ptSP, P_INVALID) ;
|
||||||
|
vInfo.emplace_back( nType2, dU2, 0, nT, dCos2, ptIBz2, P_INVALID, ptSP2, P_INVALID) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +107,7 @@ OrderInfoIntersLineSurfBz( ILSBIVECTOR& vInfo)
|
|||||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
||||||
sort( vInfo.begin(), vInfo.end(),
|
sort( vInfo.begin(), vInfo.end(),
|
||||||
[]( const IntLinSbzInfo& a, const IntLinSbzInfo& b)
|
[]( 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) ;
|
{ return ( a.dU < b.dU) ; }) ;
|
||||||
double dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
|
||||||
return ( dUa < dUb) ; }) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -137,16 +154,16 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
pSurfTm->GetTriangle( InfoTm.nT, nVert) ;
|
pSurfTm->GetTriangle( InfoTm.nT, nVert) ;
|
||||||
double dU0, dV0 ;
|
double dU0, dV0 ;
|
||||||
pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ;
|
pSurfTm->GetVertexParam( nVert[0], dU0, dV0) ;
|
||||||
ptSP = ptSP + Point3d(dU0, dV0, 0) ;
|
ptSP = ptSP + Point3d( dU0, dV0, 0) ;
|
||||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
Vector3d vtN ;
|
Vector3d vtN ;
|
||||||
pSurfBz->GetPointNrmD1D2(ptSP.x / SBZ_TREG_COEFF, ptSP.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ;
|
pSurfBz->GetPointNrmD1D2(ptSP.x, ptSP.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz, vtN) ;
|
||||||
double dCos = vtN * vtL ;
|
double dCos = vtN * vtL ;
|
||||||
double dCos2 = 0 ;
|
double dCos2 = 0 ;
|
||||||
// eventualmente ripeto tutto per ptI2 ( se ho un'intersezione con sovrapposizione)
|
// 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) ;
|
pSurfBz->UnprojectPointFromStm( InfoTm.nT, InfoTm.ptI2, ptSP2, InfoTm.nILTT) ;
|
||||||
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
if ( ! RefineIntersNewton(ptL, vtL, dLen, bFinite, pSurfBz, ptSP2, ptIBz2) ) {
|
||||||
int nVert[3] ;
|
int nVert[3] ;
|
||||||
@@ -157,7 +174,7 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
if ( ! RefineIntersNewton( ptL,vtL, dLen, bFinite, pSurfBz, ptSP, ptIBz))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
pSurfBz->GetPointNrmD1D2( ptSP2.x / SBZ_TREG_COEFF, ptSP2.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ;
|
pSurfBz->GetPointNrmD1D2( ptSP2.x, ptSP2.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptIBz2, vtN) ;
|
||||||
dCos2 = vtN * vtL ;
|
dCos2 = vtN * vtL ;
|
||||||
}
|
}
|
||||||
UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ;
|
UpdateInfoIntersLineSurfBz( ptL, vtL, InfoTm.nILTT, InfoTm.nT, ptSP, ptIBz, dCos, ptSP2, ptIBz2, dCos2, vInfo) ;
|
||||||
@@ -176,19 +193,9 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
// ciclo sulle intersezioni
|
// ciclo sulle intersezioni
|
||||||
for ( const auto& Info : vInfo) {
|
for ( const auto& Info : vInfo) {
|
||||||
// se intersezione puntuale
|
// se intersezione puntuale
|
||||||
if ( Info.nILTT == ILTT_VERT || Info.nILTT == ILTT_EDGE || Info.nILTT == ILTT_IN) {
|
vInters.emplace_back( Info.nILSB, Info.dU) ;
|
||||||
int nFlag = LSBT_TOUCH ;
|
// se intersezione sovrapposta
|
||||||
if ( Info.dCosDN > EPS_ZERO)
|
// da sviluppare
|
||||||
nFlag = LSBT_OUT ;
|
|
||||||
else if ( Info.dCosDN < -EPS_ZERO)
|
|
||||||
nFlag = LSBT_IN ;
|
|
||||||
vInters.emplace_back( nFlag, Info.dU) ;
|
|
||||||
}
|
|
||||||
// se altrimenti intersezione con coincidenza
|
|
||||||
else if ( Info.nILTT == ILTT_SEGM || Info.nILTT == ILTT_SEGM_ON_EDGE) {
|
|
||||||
vInters.emplace_back( LSBT_TG_INI, Info.dU) ;
|
|
||||||
vInters.emplace_back( LSBT_TG_FIN, Info.dU2) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// elimino intersezioni ripetute
|
// elimino intersezioni ripetute
|
||||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||||
@@ -232,3 +239,591 @@ FilterLineSurfBzInters( const ILSBIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Intersezione di una linea con una superficie di Bezier di grado 3x1 monopatch
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersLineSurfBzCubicLinear( 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 di grado 3x1
|
||||||
|
if ( nDegU != 3 || nDegV != 1 || nSpanU > 1 || nSpanV > 1 || bRat)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
int nInters = int( vInfo.size()) ;
|
||||||
|
|
||||||
|
Point3d r = ptL ;
|
||||||
|
Vector3d q = vtL ;
|
||||||
|
bool bNeedToRotX = AreSameVectorApprox( q, X_AX) ;
|
||||||
|
bool bNeedToRotY = AreSameVectorApprox( q, Y_AX) ;
|
||||||
|
bool bNeedToRot = bNeedToRotX || bNeedToRotY ;
|
||||||
|
Frame3d frRot ;
|
||||||
|
if ( bNeedToRotX)
|
||||||
|
frRot.Set( ORIG, X_AX) ;
|
||||||
|
if ( bNeedToRotY)
|
||||||
|
frRot.Set( ORIG, Y_AX) ;
|
||||||
|
if ( bNeedToRot) {
|
||||||
|
r.ToLoc( frRot) ;
|
||||||
|
q.ToLoc( frRot) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
PNTVECTOR vPntCtrl = pSurfBz->GetAllControlPoints() ;
|
||||||
|
|
||||||
|
if ( bNeedToRot) {
|
||||||
|
for ( Point3d& pt: vPntCtrl)
|
||||||
|
pt.ToLoc( frRot) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d A = vPntCtrl[4] - vPntCtrl[0] ;
|
||||||
|
Vector3d B = vPntCtrl[5] - vPntCtrl[1] ;
|
||||||
|
Vector3d C = vPntCtrl[6] - vPntCtrl[2] ;
|
||||||
|
Vector3d D = vPntCtrl[7] - vPntCtrl[3] ;
|
||||||
|
Vector3d E = vPntCtrl[0] - ORIG ;
|
||||||
|
Vector3d F = vPntCtrl[1] - ORIG ;
|
||||||
|
Vector3d G = vPntCtrl[2] - ORIG ;
|
||||||
|
Vector3d H = vPntCtrl[3] - ORIG ;
|
||||||
|
|
||||||
|
Vector3d a3 = -A + 3 * B - 3 * C + D ;
|
||||||
|
Vector3d a2 = 3 * A - 6 * B + 3 * C ;
|
||||||
|
Vector3d a1 = -3 * A + 3 * B ;
|
||||||
|
Vector3d a0 = A ;
|
||||||
|
|
||||||
|
Vector3d b3 = -E + 3 * F - 3 * G + H ;
|
||||||
|
Vector3d b2 = 3 * E - 6 * F + 3 * G ;
|
||||||
|
Vector3d b1 = -3 * E + 3 * F ;
|
||||||
|
Vector3d b0 = E ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
DBLVECTOR vdCoeff, vdRoots ;
|
||||||
|
// coefficienti dal grado più basso al grado più alto
|
||||||
|
vdCoeff = { // c0
|
||||||
|
q.x*q.z*a0.y*b0.z - q.x*q.y*a0.z*b0.z // 3
|
||||||
|
- r.z*q.x*q.z*a0.y + r.z*q.x*q.y*a0.z + // 3
|
||||||
|
q.y*q.z*a0.z*b0.z - q.z*q.z*a0.y*b0.x // 4
|
||||||
|
- r.x*q.y*q.z*a0.z + r.x*q.z*q.z*a0.y + // 4
|
||||||
|
q.z*q.z*a0.x*b0.y - q.y*q.z*a0.x*b0.z - q.x*q.z*a0.z*b0.y + q.x*q.y*a0.z*b0.z // 5
|
||||||
|
- r.y*q.z*q.z*a0.x + r.z*q.y*q.z*a0.x + r.y*q.x*q.z*a0.z - r.z*q.x*q.y*a0.z, // 5
|
||||||
|
|
||||||
|
// c1
|
||||||
|
q.x*q.z*(a1.y*b0.z + a0.y*b1.z) - q.x*q.y*(a1.z*b0.z + a0.z*b1.z) // 3
|
||||||
|
- r.z*q.x*q.z*a1.y + r.z*q.x*q.y*a1.z + // 3
|
||||||
|
q.y*q.z*(a1.z*b0.x + a0.z*b1.x) - q.z*q.z*(a1.y*b0.x + a0.y*b1.x) // 4
|
||||||
|
- r.x*q.y*q.z*a1.z + r.x*q.z*q.z*a1.y + // 4
|
||||||
|
q.z*q.z*(a1.x*b0.y + a0.x*b1.y) - q.y*q.z*(a1.x*b0.z + a0.x*b1.z) // 5
|
||||||
|
- q.x*q.z*(a1.z*b0.y + a0.z*b1.y) + q.x*q.y*(a1.z*b0.z + a0.z*b1.z) // 5
|
||||||
|
- r.y*q.z*q.z*a1.x + r.z*q.y*q.z*a1.x + r.y*q.x*q.z*a1.z - r.z*q.x*q.y*a1.z, // 5
|
||||||
|
|
||||||
|
// c2
|
||||||
|
q.x*q.z*(a2.y*b0.z + a1.y*b1.z + a0.y*b2.z) - q.x*q.y*(a2.z*b0.z + a1.z*b1.z + a0.z*b2.z) // 3
|
||||||
|
- r.z*q.x*q.z*a2.y + r.z*q.x*q.y*a2.z + // 3
|
||||||
|
q.y*q.z*(a2.z*b0.x + a1.z*b1.x + a0.z*b2.x) - q.z*q.z*(a2.y*b0.x + a1.y*b1.x + a0.y*b2.x) // 4
|
||||||
|
- r.x*q.y*q.z*a2.z + r.x*q.z*q.z*a2.y + // 4
|
||||||
|
q.z*q.z*(a2.x*b0.y + a1.x*b1.y + a0.x*b2.y) - q.y*q.z*(a2.x*b0.z + a1.x*b1.z + a0.x*b2.z) // 5
|
||||||
|
- q.x*q.z*(a2.z*b0.y + a1.z*b1.y + a0.z*b2.y) + q.x*q.y*(a2.z*b0.z + a1.z*b1.z + a0.z*b2.z)// 5
|
||||||
|
- r.y*q.z*q.z*a2.x + r.z*q.y*q.z*a2.x + r.y*q.x*q.z*a2.z - r.z*q.x*q.y*a2.z, // 5
|
||||||
|
|
||||||
|
// c3
|
||||||
|
q.x*q.z*(a3.y*b0.z + a2.y*b1.z + a1.y*b2.z + a0.y*b3.z) - q.x*q.y*(a3.z*b0.z + a2.z*b1.z + a1.z*b2.z + a0.z*b3.z) // 3
|
||||||
|
- r.z*q.x*q.z*a3.y + r.z*q.x*q.y*a3.z + // 3
|
||||||
|
q.y*q.z*(a3.z*b0.x + a2.z*b1.x + a1.z*b2.x + a0.z*b3.x) - q.z*q.z*(a3.y*b0.x + a2.y*b1.x + a1.y*b2.x + a0.y*b3.x) // 4
|
||||||
|
- r.x*q.y*q.z*a3.z + r.x*q.z*q.z*a3.y + // 4
|
||||||
|
q.z*q.z*(a3.x*b0.y + a2.x*b1.y + a1.x*b2.y + a0.x*b3.y) - q.y*q.z*(a3.x*b0.z + a2.x*b1.z + a1.x*b2.z + a0.x*b3.z) // 5
|
||||||
|
- q.x*q.z*(a3.z*b0.y + a2.z*b1.y + a1.z*b2.y + a0.z*b3.y) + q.x*q.y*(a3.z*b0.z + a2.z*b1.z + a1.z*b2.z + a0.z*b3.z)// 5
|
||||||
|
- r.y*q.z*q.z*a3.x + r.z*q.y*q.z*a3.x + r.y*q.x*q.z*a3.z - r.z*q.x*q.y*a3.z, // 5
|
||||||
|
|
||||||
|
// c4
|
||||||
|
q.x*q.z*(a3.y*b1.z + a2.y*b2.z + a1.y*b3.z) - q.x*q.y*(a3.z*b1.z + a2.z*b2.z + a1.z*b3.z) + // 3
|
||||||
|
q.y*q.z*(a3.z*b1.x + a2.z*b2.x + a1.z*b3.x) - q.z*q.z*(a3.y*b1.x + a2.y*b2.x + a1.y*b3.x) + // 4
|
||||||
|
q.z*q.z*(a3.x*b1.y + a2.x*b2.y + a1.x*b3.y) - q.y*q.z*(a3.x*b1.z + a2.x*b2.z + a1.x*b3.z) // 5
|
||||||
|
- q.x*q.z*(a3.z*b1.y + a2.z*b2.y + a1.z*b3.y) + q.x*q.y*(a3.z*b1.z + a2.z*b2.z + a1.z*b3.z), // 5
|
||||||
|
|
||||||
|
// c5
|
||||||
|
q.x*q.z*(a3.y*b2.z + a2.y*b3.z) - q.x*q.y*(a3.z*b2.z + a2.z*b3.z) + // 3
|
||||||
|
q.y*q.z*(a3.z*b2.x + a2.z*b3.x) - q.z*q.z*(a3.y*b2.x + a2.y*b3.x) + // 4
|
||||||
|
q.z*q.z*(a3.x*b2.y + a2.x*b3.y) - q.y*q.z*(a3.x*b2.z + a2.x*b3.z) // 5
|
||||||
|
- q.x*q.z*(a3.z*b2.y + a2.z*b3.y) + q.x*q.y*(a3.z*b2.z + a2.z*b3.z), // 5
|
||||||
|
|
||||||
|
// c6
|
||||||
|
q.x*q.z*a3.y*b3.z - q.x*q.y*a3.z*b3.z + // 3
|
||||||
|
q.y*q.z*a3.z*b3.x - q.z*q.z*a3.y*b3.x + // 4
|
||||||
|
q.z*q.z*a3.x*b3.y - q.y*q.z*a3.x*b3.z - q.x*q.z*a3.z*b3.y + q.x*q.y*a3.z*b3.z} ; // 5
|
||||||
|
int nRoots = PolynomialRoots( 6, vdCoeff, vdRoots) ;
|
||||||
|
bool bFound = false ;
|
||||||
|
for ( int w = 0 ; w < nRoots ; ++w) {
|
||||||
|
double dU = 0, dV = 0 ;
|
||||||
|
if ( vdRoots[w] > 0 - EPS_ZERO && vdRoots[w] < 1 + EPS_ZERO) {
|
||||||
|
dU = 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( dU - vdRoots[k]) < EPS_PARAM) ;
|
||||||
|
if ( ! bAlreadyFound) {
|
||||||
|
Vector3d vAlpha = a3 * pow(dU, 3) + a2 * pow( dU, 2) + a1 * dU + a0 ;
|
||||||
|
Vector3d vBeta = b3 * pow(dU, 3) + b2 * pow( dU, 2) + b1 * dU + b0 ;
|
||||||
|
double dDen = ( vAlpha.x * q.z - vAlpha.z * q.x) ;
|
||||||
|
if ( abs( dDen) > EPS_ZERO)
|
||||||
|
dV = ( ( vBeta.z - r.z) * q.x - ( vBeta.x - r.x ) * q.z) / dDen ;
|
||||||
|
else {
|
||||||
|
// se la prima equazione risulta un x/0 allora uso la seconda equazione per trovare il secondo parametro
|
||||||
|
double dDen2 = ( vAlpha.y * q.z - vAlpha.z * q.y) ;
|
||||||
|
dV = ( ( vBeta.z - r.z) * q.y - ( vBeta.y - r.y ) * q.z) / dDen2 ;
|
||||||
|
}
|
||||||
|
if ( dV > - EPS_ZERO && dV < 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 ;
|
||||||
|
int nType = ILTA_NO_TRIA ;
|
||||||
|
UpdateInfoIntersLineSurfBz( ptL, vtL, nType, -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 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Intersezione di una linea con una superficie di Bezier bilineare monopatch
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersLineSurfBzBilinear( const Point3d& ptL, const Vector3d& vtL, double dLen, const ISurfBezier* pSurfBz,
|
||||||
|
ILSBIVECTOR& vInfo, bool bFinite)
|
||||||
|
{
|
||||||
|
int nDegU, nDegV, nSpanU, nSpanV ;
|
||||||
|
bool bRat, bTrimmed ;
|
||||||
|
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
||||||
|
|
||||||
|
// funzione pensata per funzionare solo con una monopatch bilineare
|
||||||
|
if ( nDegU > 1 || nDegV > 1 || nSpanU > 1 || nSpanV > 1 || bRat)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
int nInters = int( vInfo.size()) ;
|
||||||
|
|
||||||
|
PNTVECTOR vPntCtrl ;
|
||||||
|
for ( int p = 0 ; p < 4 ; ++p) {
|
||||||
|
bool bOk = false ;
|
||||||
|
vPntCtrl.push_back( pSurfBz->GetControlPoint( p, &bOk)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3d a = vPntCtrl[3] - vPntCtrl[1] + ( vPntCtrl[0] - vPntCtrl[2]) ;
|
||||||
|
Vector3d b = vPntCtrl[1] - vPntCtrl[0] ;
|
||||||
|
Vector3d c = vPntCtrl[2] - vPntCtrl[0] ;
|
||||||
|
Vector3d d = vPntCtrl[0] - ORIG ;
|
||||||
|
|
||||||
|
double A1 = a.x * vtL.z - a.z * vtL.x ;
|
||||||
|
double B1 = b.x * vtL.z - b.z * vtL.x ;
|
||||||
|
double C1 = c.x * vtL.z - c.z * vtL.x ;
|
||||||
|
double A2 = a.y * vtL.z - a.z * vtL.y ;
|
||||||
|
double B2 = b.y * vtL.z - b.z * vtL.y ;
|
||||||
|
double C2 = c.y * vtL.z - c.z * vtL.y ;
|
||||||
|
|
||||||
|
double D1 = ( d.x - ptL.x) * vtL.z - ( d.z - ptL.z) * vtL.x ;
|
||||||
|
double D2 = ( d.y - ptL.y) * vtL.z - ( d.z - ptL.z) * vtL.y ;
|
||||||
|
|
||||||
|
DBLVECTOR vdCoeff, vdRoots ;
|
||||||
|
vdCoeff = { (B2 * D1 - B1 * D2), ( A2 * D1 - A1 * D2 + B2 * C1 - B1 * C2), ( A2 * C1 - A1 * C2)} ;
|
||||||
|
int nRoots = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
||||||
|
bool bFound = false ;
|
||||||
|
for ( int w = 0 ; w < nRoots ; ++w) {
|
||||||
|
if ( vdRoots[w] > 0 - EPS_ZERO && vdRoots[w] < 1 + EPS_ZERO ) {
|
||||||
|
double dU = 0, dV = vdRoots[w] ;
|
||||||
|
// verifico che non sia una soluzione con molteplicità > 1
|
||||||
|
bool bAlreadyFound = false ;
|
||||||
|
for ( int k = w - 1 ; k >= 0 && ! bAlreadyFound ; --k)
|
||||||
|
bAlreadyFound = abs( dV - vdRoots[k]) < EPS_PARAM ;
|
||||||
|
if ( ! bAlreadyFound) {
|
||||||
|
dU = (dV * (C1 - C2) + ( D1 - D2)) / ( dV * ( A2 - A1) + ( B2 - B1)) ;
|
||||||
|
if ( dU > - EPS_ZERO && dU < 1 + EPS_ZERO) {
|
||||||
|
Point3d ptIBez, ptIBez2 ;
|
||||||
|
Vector3d vtN ;
|
||||||
|
pSurfBz->GetPointNrmD1D2(dU, dV, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez, vtN) ;
|
||||||
|
Point3d ptSP( dU, dV, 0), ptSP2 ;
|
||||||
|
double dCos = vtN * vtL, dCos2 = 0 ;
|
||||||
|
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP, ptIBez, dCos, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se tutti i coefficienti sono zero allora potrei avere una linea che giace sulla superficie
|
||||||
|
// per trovare i punti di inizio e fine sovrapposizione trovo i punti a minima distanza tra la linea e gli edge della superficie
|
||||||
|
if ( ! bFound && abs( vdCoeff[0]) < EPS_ZERO && abs( vdCoeff[1]) < EPS_ZERO && abs( vdCoeff[2]) < EPS_ZERO) {
|
||||||
|
ICRVCOMPOPOVECTOR vCrvEdge( 4) ;
|
||||||
|
vCrvEdge[0].Set(pSurfBz->GetCurveOnU( 0)) ;
|
||||||
|
vCrvEdge[1].Set(pSurfBz->GetCurveOnV( 1)) ;
|
||||||
|
vCrvEdge[2].Set(pSurfBz->GetCurveOnU( 1)) ;
|
||||||
|
vCrvEdge[3].Set(pSurfBz->GetCurveOnV( 0)) ;
|
||||||
|
double dAngTolDeg = 5 ;
|
||||||
|
for ( int i = 0 ; i < 4 ; ++i) {
|
||||||
|
PolyLine plApprox ; vCrvEdge[0]->ApproxWithLines( EPS_SMALL, dAngTolDeg, ICurve::ApprLineType::APL_STD, plApprox) ;
|
||||||
|
//CurveComposite cCC ;
|
||||||
|
//cCC.FromPolyLine( plApprox) ;
|
||||||
|
int nClosestLine = -1 ;
|
||||||
|
double dMinDist = INFINITO ;
|
||||||
|
Point3d pt ; plApprox.GetFirstPoint( pt) ;
|
||||||
|
Point3d ptClosest ;
|
||||||
|
int c = 0 ;
|
||||||
|
int nTot = plApprox.GetPointNbr() ;
|
||||||
|
for ( int j = 0 ; j < nTot ; ++j) {
|
||||||
|
DistPointLine dpl( pt, ptL, vtL, dLen, bFinite) ;
|
||||||
|
double dDist = INFINITO ;
|
||||||
|
dpl.GetDist( dDist) ;
|
||||||
|
if ( dDist < dMinDist) {
|
||||||
|
nClosestLine = c ;
|
||||||
|
dMinDist = dDist ;
|
||||||
|
}
|
||||||
|
plApprox.GetNextPoint( pt) ;
|
||||||
|
++ c ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point3d ptInt1, ptInt2 ;
|
||||||
|
if ( nClosestLine < nTot - 1 && nClosestLine > 0) {
|
||||||
|
// tra i due tratti dell'approssimazione che arrivano al punto selezionato come più vicino, devo trovare quale si avvicina di più
|
||||||
|
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||||
|
Point3d ptEnd ;
|
||||||
|
for ( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
||||||
|
plApprox.GetNextPoint( ptStart) ;
|
||||||
|
plApprox.GetNextPoint( ptEnd) ;
|
||||||
|
// linea precedente al punto
|
||||||
|
Vector3d vtLinePre = ptEnd - ptStart ;
|
||||||
|
double dLenPre = vtLinePre.Len() ;
|
||||||
|
DistLineLine dllPre( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
||||||
|
double dDistPre = INFINITO ;
|
||||||
|
dllPre.GetDist( dDistPre) ;
|
||||||
|
// linea che inzia con quel punto
|
||||||
|
ptStart = ptEnd ;
|
||||||
|
plApprox.GetNextPoint( ptEnd) ;
|
||||||
|
Vector3d vtLineCurr = ptEnd - ptStart ;
|
||||||
|
double dLenCurr = vtLineCurr.Len() ;
|
||||||
|
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
||||||
|
double dDistCurr = INFINITO ;
|
||||||
|
dllCurr.GetDist( dDistCurr) ;
|
||||||
|
|
||||||
|
if ( dDistPre < dDistCurr)
|
||||||
|
dllPre.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||||
|
else
|
||||||
|
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||||
|
}
|
||||||
|
else if ( nClosestLine == 0) {
|
||||||
|
// il punto più vicino è sulla prima linea
|
||||||
|
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||||
|
Point3d ptEnd ; plApprox.GetNextPoint( ptEnd) ;
|
||||||
|
Vector3d vtLineCurr = ptEnd - ptStart ;
|
||||||
|
double dLenCurr = vtLineCurr.Len() ;
|
||||||
|
DistLineLine dllCurr( ptStart, vtLineCurr, dLenCurr, ptL, vtL,dLen) ;
|
||||||
|
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||||
|
}
|
||||||
|
else if ( nClosestLine == nTot- 1) {
|
||||||
|
// il punto più vicino è sull'ultima linea
|
||||||
|
Point3d ptStart ; plApprox.GetFirstPoint( ptStart) ;
|
||||||
|
Point3d ptEnd ;
|
||||||
|
for ( int z = 1 ; z < nClosestLine - 1 ; ++z)
|
||||||
|
plApprox.GetNextPoint( ptStart) ;
|
||||||
|
plApprox.GetNextPoint( ptEnd) ;
|
||||||
|
Vector3d vtLinePre = ptEnd - ptStart ;
|
||||||
|
double dLenPre = vtLinePre.Len() ;
|
||||||
|
DistLineLine dllCurr( ptStart, vtLinePre, dLenPre, ptL, vtL,dLen) ;
|
||||||
|
dllCurr.GetMinDistPoints( ptInt1, ptInt2) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dU1 = 0, dV1 = 0, dU2 = 0, dV2 = 0 ;
|
||||||
|
// se ho trovato due punti vuol dire che la linea coincide con un edge e ho trovato tutto quello che serve
|
||||||
|
if ( ! AreSamePointExact( ptInt2, ORIG)) {
|
||||||
|
if ( i == 0) {
|
||||||
|
//dV1 = 0 ; dV2 = 0 ;
|
||||||
|
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
||||||
|
vCrvEdge[0]->GetParamAtPoint( ptInt2, dU2) ;
|
||||||
|
}
|
||||||
|
else if ( i == 1) {
|
||||||
|
//dU1 = 1 ; dU2 = 1 ;
|
||||||
|
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
||||||
|
vCrvEdge[1]->GetParamAtPoint( ptInt2, dV2) ;
|
||||||
|
}
|
||||||
|
else if ( i == 2){
|
||||||
|
//dV1 = 1 ; dV2 = 1 ;
|
||||||
|
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
||||||
|
vCrvEdge[2]->GetParamAtPoint( ptInt2, dU2) ;
|
||||||
|
}
|
||||||
|
else if ( i == 3){
|
||||||
|
//dU1 = 0 ; dU2 = 0 ;
|
||||||
|
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
||||||
|
vCrvEdge[3]->GetParamAtPoint( ptInt2, dV2) ;
|
||||||
|
}
|
||||||
|
Point3d ptIBez1, ptIBez2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
|
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
||||||
|
pSurfBz->GetPointNrmD1D2(dU2, dV2, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez2, vtN2) ;
|
||||||
|
Point3d ptSP1( dU1, dV1, 0) ;
|
||||||
|
double dCos1 = vtN1 * vtL ;
|
||||||
|
Point3d ptSP2( dU2, dV2, 0) ;
|
||||||
|
double dCos2 = vtN2 * vtL ;
|
||||||
|
// se avevo già trovato un punto singolo che coincide col primo punto di questa intersezione sovrapposta, allora cancello l'intersezione singola che
|
||||||
|
// avevo salvato e aggiungo quella sovrapposto che ho trovato ora
|
||||||
|
if ( bFound) {
|
||||||
|
int nNewTot = int(vInfo.size()) ;
|
||||||
|
int nNewInters = nNewTot - nInters ;
|
||||||
|
bool bAlreadyFound = false ;
|
||||||
|
for ( int i = 0 ; i < nNewInters ; ++i) {
|
||||||
|
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) || AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP2) ;
|
||||||
|
if ( bAlreadyFound) {
|
||||||
|
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||||
|
bFound = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
// se ho trovato un punto a distanza zero dalla linea allora ho trovato l'intersezione
|
||||||
|
else if ( dMinDist < EPS_SMALL) {
|
||||||
|
if ( i == 0) {
|
||||||
|
//dV1 = 0 ;
|
||||||
|
vCrvEdge[0]->GetParamAtPoint( ptInt1, dU1) ;
|
||||||
|
}
|
||||||
|
else if ( i == 1) {
|
||||||
|
//dU1 = 1 ;
|
||||||
|
vCrvEdge[1]->GetParamAtPoint( ptInt1, dV1) ;
|
||||||
|
}
|
||||||
|
else if ( i == 2) {
|
||||||
|
//dV1 = 1 ;
|
||||||
|
vCrvEdge[2]->GetParamAtPoint( ptInt1, dU1) ;
|
||||||
|
}
|
||||||
|
else if ( i == 3) {
|
||||||
|
//dU1 = 0 ;
|
||||||
|
vCrvEdge[3]->GetParamAtPoint( ptInt1, dV1) ;
|
||||||
|
}
|
||||||
|
Point3d ptSP1( dU1, dV1, 0), ptSP2 ;
|
||||||
|
// se avevo trovato già altri punti controllo di non essere esattamente su una diagonale ( e quindi avere un'intersezione con ogni edge, ma due sono doppie)
|
||||||
|
if ( bFound) {
|
||||||
|
int nNewTot = int(vInfo.size()) ;
|
||||||
|
int nNewInters = nNewTot - nInters ;
|
||||||
|
bool bAlreadyFound = false ;
|
||||||
|
for ( int i = 0 ; i < nNewInters ; ++i)
|
||||||
|
bAlreadyFound = AreSamePointApprox(vInfo[nNewTot - i].ptUV, ptSP1) ;
|
||||||
|
if ( bAlreadyFound)
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point3d ptIBez1, ptIBez2 ;
|
||||||
|
Vector3d vtN1, vtN2 ;
|
||||||
|
pSurfBz->GetPointNrmD1D2(dU1, dV1, ISurfBezier::Side::FROM_MINUS, ISurfBezier::Side::FROM_MINUS, ptIBez1, vtN1) ;
|
||||||
|
double dCos1 = vtN1 * vtL, dCos2 = 0 ;
|
||||||
|
UpdateInfoIntersLineSurfBz( ptL, vtL, ILTA_NO_TRIA, -1, ptSP1, ptIBez1, dCos1, ptSP2, ptIBez2, dCos2, vInfo) ;
|
||||||
|
bFound = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// se la superficie è trimmed verifico che i punti trovati siano all'interno del parametrico trimmato
|
||||||
|
if ( bTrimmed && bFound) {
|
||||||
|
int nNewTot = int(vInfo.size()) ;
|
||||||
|
int nNewInters = nNewTot - nInters ;
|
||||||
|
const ISurfFlatRegion* pFRTrim = pSurfBz->GetTrimRegion() ;
|
||||||
|
for ( int i = 0 ; i < nNewInters ; ++i) {
|
||||||
|
Point3d ptTest = vInfo[nNewTot - i].ptUV * SBZ_TREG_COEFF ;
|
||||||
|
bool bInside = false ;
|
||||||
|
double dDist = INFINITO ;
|
||||||
|
IsPointInsideSurfFr( ptTest, pFRTrim, dDist, bInside) ;
|
||||||
|
if ( ! bInside)
|
||||||
|
vInfo.erase( vInfo.begin() + nNewTot - i) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1662,7 +1662,7 @@ LineTorus( const Point3d& ptLine, const Vector3d& vtLine,
|
|||||||
// Riordino le soluzioni
|
// Riordino le soluzioni
|
||||||
for ( int ni = 0 ; ni < int( vdPar.size()) - 1 ; ++ ni) {
|
for ( int ni = 0 ; ni < int( vdPar.size()) - 1 ; ++ ni) {
|
||||||
for ( int nj = ni ; nj < int( vdPar.size()) ; ++ nj) {
|
for ( int nj = ni ; nj < int( vdPar.size()) ; ++ nj) {
|
||||||
if( vdPar[ni] > vdPar[nj]) {
|
if ( vdPar[ni] > vdPar[nj]) {
|
||||||
swap( vdPar[ni], vdPar[nj]) ;
|
swap( vdPar[ni], vdPar[nj]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+106
-21
@@ -23,20 +23,20 @@ using namespace std ;
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
UpdateInfoIntersLineSurfTm( const Point3d& ptL, const Vector3d& vtDir, double dLen,
|
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 ;
|
Point3d ptInt, ptInt2 ;
|
||||||
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
int nRes = IntersLineTria( ptL, vtDir, dLen, Tria, ptInt, ptInt2, bFinite) ;
|
||||||
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
if ( nRes == ILTT_IN || nRes == ILTT_EDGE || nRes == ILTT_VERT) {
|
||||||
double dU = ( ptInt - ptL) * vtDir ;
|
double dU = ( ptInt - ptL) * vtDir ;
|
||||||
double dCosDN = vtDir * Tria.GetN() ;
|
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) {
|
else if ( nRes == ILTT_SEGM || nRes == ILTT_SEGM_ON_EDGE) {
|
||||||
double dU = ( ptInt - ptL) * vtDir ;
|
double dU = ( ptInt - ptL) * vtDir ;
|
||||||
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
double dU2 = ( ptInt2 - ptL) * vtDir ;
|
||||||
double dCosDN = vtDir * Tria.GetN() ;
|
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) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ OrderInfoIntersLineSurfTm( ILSIVECTOR& vInfo)
|
|||||||
if ( vInfo.empty())
|
if ( vInfo.empty())
|
||||||
return ;
|
return ;
|
||||||
// ordino il vettore delle intersezioni secondo il senso crescente del parametro di linea
|
// 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)
|
[]( 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 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 dUb = ( ( b.nILTT == ILTT_SEGM || b.nILTT == ILTT_SEGM_ON_EDGE) ? ( b.dU + b.dU2) / 2 : b.dU) ;
|
||||||
@@ -108,7 +108,7 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
Triangle3d Tria ;
|
Triangle3d Tria ;
|
||||||
Stm.GetTriangle( nT, Tria) ;
|
Stm.GetTriangle( nT, Tria) ;
|
||||||
// aggiorno info con intersezione
|
// aggiorno info con intersezione
|
||||||
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, nT, Tria, vInfo, bFinite) ;
|
UpdateInfoIntersLineSurfTm( ptL, vtDir, dLen, 0, nT, Tria, vInfo, bFinite) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,19 +124,23 @@ IntersLineSurfTm( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
// Intersezione di molte linee parallele con una superficie TriMesh
|
// Intersezione di molte linee parallele con una superficie TriMesh
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfTriMesh& Stm)
|
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
|
// verifico esistenza superficie
|
||||||
if ( m_pSTm == nullptr || ! m_pSTm->IsValid())
|
if ( m_vpSTm[0] == nullptr || ! m_vpSTm[0]->IsValid())
|
||||||
return ;
|
return ;
|
||||||
|
|
||||||
// creo HashGrid 2d
|
// aggiorno il vettore degli indici di base per mappare i triangoli con le rispettivi superfici
|
||||||
const int LIM_HG_TRIA = 127 ;
|
// ( in questo caso la superficie è unica, quindi ho solo due elementi)
|
||||||
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
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 ;
|
Triangle3d Tria ;
|
||||||
int nT = Stm.GetFirstTriangle( Tria) ;
|
int nT = m_vpSTm[0]->GetFirstTriangle( Tria) ;
|
||||||
while ( nT != SVT_NULL) {
|
while ( nT != SVT_NULL) {
|
||||||
// calcolo il BBox del triangolo nel riferimento scelto
|
// calcolo il BBox del triangolo nel riferimento scelto
|
||||||
Tria.ToLoc( m_frLines) ;
|
Tria.ToLoc( m_frLines) ;
|
||||||
@@ -145,10 +149,55 @@ IntersParLinesSurfTm::IntersParLinesSurfTm( const Frame3d& frLines, const ISurfT
|
|||||||
b3Tria.Add( Tria.GetP( 1)) ;
|
b3Tria.Add( Tria.GetP( 1)) ;
|
||||||
b3Tria.Add( Tria.GetP( 2)) ;
|
b3Tria.Add( Tria.GetP( 2)) ;
|
||||||
// inserisco nella griglia
|
// inserisco nella griglia
|
||||||
if ( ! m_HGrids.Add( nT, b3Tria))
|
if ( ! m_HGrids.Add( nT, b3Tria)) // ( 0 + nT, Tria)
|
||||||
return ;
|
return ;
|
||||||
// passo al prossimo triangolo
|
// passo al prossimo triangolo
|
||||||
nT = Stm.GetNextTriangle( nT, Tria) ;
|
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
|
// aggiorno
|
||||||
m_bOk = m_HGrids.Update() ;
|
m_bOk = m_HGrids.Update() ;
|
||||||
@@ -162,7 +211,7 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
if ( &vInfo == nullptr)
|
if ( &vInfo == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
vInfo.clear() ;
|
vInfo.clear() ;
|
||||||
// verifico validità
|
// verifico validità
|
||||||
if ( ! m_bOk)
|
if ( ! m_bOk)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -174,15 +223,22 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
Point3d ptLL = ptL ;
|
Point3d ptLL = ptL ;
|
||||||
ptLL.ToGlob( m_frLines) ;
|
ptLL.ToGlob( m_frLines) ;
|
||||||
|
|
||||||
// recupero indici triangoli che intersecano box in 2d
|
// recupero indici triangoli che intersecano box in 2d
|
||||||
INTVECTOR vnIds ;
|
INTVECTOR vnIds ;
|
||||||
if ( m_HGrids.Find( b3Line, vnIds)) {
|
if ( m_HGrids.Find( b3Line, vnIds)) {
|
||||||
for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
|
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 ;
|
Triangle3d Tria ;
|
||||||
m_pSTm->GetTriangle( nT, Tria) ;
|
if ( ! m_vpSTm[nSurf]->GetTriangle( nT, Tria))
|
||||||
|
return false ;
|
||||||
// aggiorno info con intersezione
|
// 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) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,6 +248,35 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
return true ;
|
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
|
bool
|
||||||
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
||||||
@@ -217,7 +302,7 @@ FilterLineSurfTmInters( const ILSIVECTOR& vInfo, INTDBLVECTOR& vInters)
|
|||||||
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
for ( size_t j = 1 ; j < vInters.size() ; ) {
|
||||||
// intersezione precedente
|
// intersezione precedente
|
||||||
size_t i = j - 1 ;
|
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) {
|
if ( abs( vInters[i].second - vInters[j].second) < EPS_SMALL) {
|
||||||
// se sono entrambe entranti o uscenti, elimino la seconda
|
// se sono entrambe entranti o uscenti, elimino la seconda
|
||||||
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
if ( ( vInters[i].first == LST_IN && vInters[j].first == LST_IN) ||
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Intersezione di unpiano con la superficie di un solido VolZmap
|
// Intersezione di un piano con la superficie di un solido VolZmap
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
|
IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR& vpLoop)
|
||||||
@@ -28,9 +28,6 @@ IntersPlaneVolZmap( const Plane3d& plPlane, const IVolZmap& Vzm, ICURVEPOVECTOR&
|
|||||||
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
const VolZmap* pVzm = GetBasicVolZmap( &Vzm) ;
|
||||||
if ( pVzm == nullptr)
|
if ( pVzm == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// verifico parametro di ritorno
|
|
||||||
if ( &vpLoop == nullptr)
|
|
||||||
return false ;
|
|
||||||
|
|
||||||
// eseguo intersezione
|
// eseguo intersezione
|
||||||
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
|
return pVzm->GetPlaneIntersection( plPlane, vpLoop) ;
|
||||||
|
|||||||
+258
@@ -0,0 +1,258 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2025-2025
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : MultiGeomDB.cpp Data : 08.10.25 Versione : 2.7j1
|
||||||
|
// Contenuto : Implementazione delle funzioni tra due GeomDB.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 08.10.25 DS Creazione modulo.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "GeomDB.h"
|
||||||
|
#include "/EgtDev/Include/EGkMultiGeomDB.h"
|
||||||
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
CopyGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||||
|
{
|
||||||
|
// recupero l'oggetto da copiare dal GeomDB sorgente
|
||||||
|
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
|
||||||
|
if ( IsNull( pGObj))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// se in globale
|
||||||
|
if ( bGlob) {
|
||||||
|
// recupero il riferimento del sorgente
|
||||||
|
Frame3d frSou ;
|
||||||
|
if ( ! pSouGDB->GetGlobFrame( nSouId, frSou))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// recupero il riferimento del gruppo destinazione
|
||||||
|
Frame3d frDest ;
|
||||||
|
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||||
|
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// porto la copia da riferimento sorgente a quello destinazione
|
||||||
|
pGObj->LocToLoc( frSou, frDest) ;
|
||||||
|
}
|
||||||
|
// lo inserisco nel GeomDB destinazione
|
||||||
|
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, nSonBeforeAfter, Release( pGObj)) ;
|
||||||
|
if ( nNewId == GDB_ID_NULL)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// copio le caratteristiche non geometriche
|
||||||
|
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||||
|
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||||
|
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nNewId ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
CopyGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||||
|
{
|
||||||
|
// recupero il riferimento del gruppo
|
||||||
|
Frame3d frFrame = *( pSouGDB->GetGroupFrame( nSouId)) ;
|
||||||
|
// se in globale
|
||||||
|
if ( bGlob) {
|
||||||
|
// recupero il riferimento del gruppo in globale
|
||||||
|
if ( ! pSouGDB->GetGroupGlobFrame( nSouId, frFrame))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// recupero il riferimento del gruppo destinazione
|
||||||
|
Frame3d frDest ;
|
||||||
|
int nDestParentId = ( IS_GDB_SON( nSonBeforeAfter) ? nRefId : pDstGDB->GetParentId( nRefId)) ;
|
||||||
|
if ( ! pDstGDB->GetGroupGlobFrame( nDestParentId, frDest))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// porto la copia da riferimento sorgente a quello destinazione
|
||||||
|
frFrame.ToLoc( frDest) ;
|
||||||
|
}
|
||||||
|
// inserisco un nuovo gruppo nel GeomDB destinazione
|
||||||
|
int nNewId = pDstGDB->InsertGroup( nDestId, nRefId, nSonBeforeAfter, frFrame) ;
|
||||||
|
if ( nNewId == GDB_ID_NULL)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// copio le caratteristiche non geometriche
|
||||||
|
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||||
|
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||||
|
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
// copio gli eventuali figli
|
||||||
|
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
|
||||||
|
while ( nSonSouId != GDB_ID_NULL) {
|
||||||
|
// nuovo identificativo oggetto destinazione
|
||||||
|
int nSonNewId = GDB_ID_NULL ;
|
||||||
|
// recupero il tipo di oggetto sorgente
|
||||||
|
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
|
||||||
|
// se l'oggetto da copiare è geometrico
|
||||||
|
if ( nSonSouType == GDB_TY_GEO)
|
||||||
|
nSonNewId = CopyGeoObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||||
|
// se altrimenti è un gruppo
|
||||||
|
else if ( nSonSouType == GDB_TY_GROUP)
|
||||||
|
nSonNewId = CopyGroupObj( pSouGDB, nSonSouId, pDstGDB, GDB_ID_NULL, nNewId, GDB_LAST_SON, false) ;
|
||||||
|
// se copia non riuscita, esco con errore
|
||||||
|
if ( nSonNewId == GDB_ID_NULL)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// passo al figlio successivo
|
||||||
|
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nNewId ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter, bool bGlob)
|
||||||
|
{
|
||||||
|
// adatto e verifico i GeomDB
|
||||||
|
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
|
||||||
|
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// il sorgente non può essere il gruppo radice
|
||||||
|
if ( nSouId == GDB_ID_ROOT)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// nuovo identificativo oggetto destinazione
|
||||||
|
int nNewId = GDB_ID_NULL ;
|
||||||
|
// recupero il tipo di oggetto sorgente
|
||||||
|
int nSouType = pSouGDB->GetGdbType( nSouId) ;
|
||||||
|
// se l'oggetto da copiare è geometrico
|
||||||
|
if ( nSouType == GDB_TY_GEO) {
|
||||||
|
nNewId = CopyGeoObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||||
|
}
|
||||||
|
// se altrimenti è un gruppo
|
||||||
|
else if ( nSouType == GDB_TY_GROUP) {
|
||||||
|
nNewId = CopyGroupObj( pSouGDB, nSouId, pDstGDB, nDestId, nRefId, nSonBeforeAfter, bGlob) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nNewId ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
Copy( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||||
|
{
|
||||||
|
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, false) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
int
|
||||||
|
CopyGlob( IGeomDB* pSouGeomDB, int nSouId, IGeomDB* pDestGeomDB, int nDestId, int nRefId, int nSonBeforeAfter)
|
||||||
|
{
|
||||||
|
return Copy( pSouGeomDB, nSouId, pDestGeomDB, nDestId, nRefId, nSonBeforeAfter, true) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
DuplicateGeoObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId)
|
||||||
|
{
|
||||||
|
// recupero l'oggetto da copiare dal GeomDB sorgente
|
||||||
|
PtrOwner<IGeoObj> pGObj( pSouGDB->GetGeoObj( nSouId)->Clone()) ;
|
||||||
|
if ( IsNull( pGObj))
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
// lo inserisco nel GeomDB destinazione
|
||||||
|
int nNewId = pDstGDB->InsertGeoObj( nDestId, nRefId, GDB_LAST_SON, Release( pGObj)) ;
|
||||||
|
if ( nNewId != nDestId) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
// copio le caratteristiche non geometriche
|
||||||
|
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||||
|
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||||
|
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nNewId ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static int
|
||||||
|
DuplicateGroupObj( const GeomDB* pSouGDB, int nSouId, GeomDB* pDstGDB, int nDestId, int nRefId, bool bSkipTemp)
|
||||||
|
{
|
||||||
|
int nNewId = GDB_ID_ROOT ;
|
||||||
|
if ( nSouId != GDB_ID_ROOT) {
|
||||||
|
// recupero il riferimento del gruppo
|
||||||
|
Frame3d frFrame = *( pSouGDB->GetGroupFrame( nSouId)) ;
|
||||||
|
// inserisco un nuovo gruppo nel GeomDB destinazione
|
||||||
|
nNewId = pDstGDB->InsertGroup( nDestId, nRefId, GDB_LAST_SON, frFrame) ;
|
||||||
|
if ( nNewId != nSouId) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
// copio le caratteristiche non geometriche
|
||||||
|
const GdbObj* pSouGdbObj = pSouGDB->GetGdbObj( nSouId) ;
|
||||||
|
GdbObj* pDstGdbObj = pDstGDB->GetGdbObj( nNewId) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGdbObj == nullptr ||
|
||||||
|
! pDstGdbObj->CopyAttribsFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyTextureDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyStippleDataFrom( pSouGdbObj) ||
|
||||||
|
! pDstGdbObj->CopyUserObjFrom( pSouGdbObj)) {
|
||||||
|
pDstGDB->Erase( nNewId) ;
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// copio gli eventuali figli
|
||||||
|
int nSonSouId = pSouGDB->GetFirstInGroup( nSouId) ;
|
||||||
|
while ( nSonSouId != GDB_ID_NULL) {
|
||||||
|
// verifico se non richiesto di saltare i temporanei oppure non lo è
|
||||||
|
int nLevel ;
|
||||||
|
if ( ! bSkipTemp || ! pSouGDB->GetLevel( nSonSouId, nLevel) || nLevel != GDB_LV_TEMP) {
|
||||||
|
// nuovo identificativo oggetto destinazione
|
||||||
|
int nSonNewId = GDB_ID_NULL ;
|
||||||
|
// recupero il tipo di oggetto sorgente
|
||||||
|
int nSonSouType = pSouGDB->GetGdbType( nSonSouId) ;
|
||||||
|
// se l'oggetto da copiare è geometrico
|
||||||
|
if ( nSonSouType == GDB_TY_GEO)
|
||||||
|
nSonNewId = DuplicateGeoObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId) ;
|
||||||
|
// se altrimenti è un gruppo
|
||||||
|
else if ( nSonSouType == GDB_TY_GROUP)
|
||||||
|
nSonNewId = DuplicateGroupObj( pSouGDB, nSonSouId, pDstGDB, nSonSouId, nNewId, bSkipTemp) ;
|
||||||
|
// se copia non riuscita, esco con errore
|
||||||
|
if ( nSonNewId != nSonSouId)
|
||||||
|
return GDB_ID_NULL ;
|
||||||
|
}
|
||||||
|
// passo al figlio successivo
|
||||||
|
nSonSouId = pSouGDB->GetNext( nSonSouId) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nNewId ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
DuplicateGeomDB( IGeomDB* pSouGeomDB, IGeomDB* pDestGeomDB, bool bSkipTemp)
|
||||||
|
{
|
||||||
|
// adatto e verifico i GeomDB
|
||||||
|
const GeomDB* pSouGDB = static_cast<GeomDB*>( pSouGeomDB) ;
|
||||||
|
GeomDB* pDstGDB = static_cast<GeomDB*>( pDestGeomDB) ;
|
||||||
|
if ( pSouGDB == nullptr || pDstGDB == nullptr)
|
||||||
|
return false ;
|
||||||
|
// verifico che la destinazione sia vuota
|
||||||
|
if ( pDstGDB->GetFirstInGroup( GDB_ID_ROOT) != GDB_ID_NULL)
|
||||||
|
return false ;
|
||||||
|
// eseguo la copia di tutto (se richiesto salto gli oggetti temporanei)
|
||||||
|
return ( DuplicateGroupObj( pSouGDB, GDB_ID_ROOT, pDstGDB, GDB_ID_ROOT, GDB_ID_ROOT, bSkipTemp) != GDB_ID_NULL) ;
|
||||||
|
}
|
||||||
+63
-74
@@ -17,6 +17,7 @@
|
|||||||
#include "NgeKeyW.h"
|
#include "NgeKeyW.h"
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
#include "/EgtDev/Include/EgtStringConverter.h"
|
#include "/EgtDev/Include/EgtStringConverter.h"
|
||||||
|
#include "/EgtDev/Extern/zlib/Include/zlib.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -34,8 +35,12 @@ NgeReader::Init( const string& sFileIn)
|
|||||||
break ;
|
break ;
|
||||||
case NGE_BINARY :
|
case NGE_BINARY :
|
||||||
m_bBinary = true ;
|
m_bBinary = true ;
|
||||||
m_InFile.open( stringtoW( sFileIn), ios::in | ios::binary, _SH_DENYWR) ;
|
m_InFile = gzopen_w( stringtoW( sFileIn), "rb") ;
|
||||||
return ( ! m_InFile.fail()) ;
|
if ( m_InFile == nullptr)
|
||||||
|
return false ;
|
||||||
|
const int DIM_BUFFER = 65536 ;
|
||||||
|
gzbuffer( m_InFile, DIM_BUFFER) ;
|
||||||
|
return true ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
return false ;
|
return false ;
|
||||||
@@ -46,10 +51,12 @@ bool
|
|||||||
NgeReader::Close( void)
|
NgeReader::Close( void)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
bool bOk = ( m_InFile.good() && m_InFile.is_open()) ;
|
if ( m_InFile != nullptr) {
|
||||||
if ( m_InFile.is_open())
|
bool bOk = ( gzclose( m_InFile) == Z_OK) ;
|
||||||
m_InFile.close() ;
|
m_InFile = nullptr ;
|
||||||
return bOk ;
|
return bOk ;
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return m_Scan.Terminate() ;
|
return m_Scan.Terminate() ;
|
||||||
@@ -59,31 +66,24 @@ NgeReader::Close( void)
|
|||||||
int
|
int
|
||||||
NgeReader::NgeType( const string& sFile)
|
NgeReader::NgeType( const string& sFile)
|
||||||
{
|
{
|
||||||
// apertura del file di ingresso
|
// apertura file
|
||||||
ifstream InFile ;
|
gzFile_s* InFile = gzopen_w( stringtoW( sFile), "rb") ;
|
||||||
InFile.open( stringtoW( sFile), ios::in | ios::binary) ;
|
if ( InFile == nullptr)
|
||||||
if ( InFile.fail())
|
|
||||||
return NGE_ERROR ;
|
return NGE_ERROR ;
|
||||||
|
// lettura dei primi caratteri
|
||||||
// lettura dei primi 31 byte
|
char szBuff[9] = "\0\0\0\0\0\0\0\0" ;
|
||||||
char cBuff[32] ;
|
int nLen = gzread( InFile, &szBuff, 8) ;
|
||||||
InFile.read( cBuff, 31) ;
|
if ( gzclose( InFile) != Z_OK || nLen == Z_ERRNO)
|
||||||
cBuff[InFile.gcount()] = '\0' ;
|
return NGE_ERROR ;
|
||||||
|
// se binario
|
||||||
// chiusura del file
|
if ( szBuff[0] == '\x0F' && szBuff[1] == '\x0F')
|
||||||
InFile.close() ;
|
|
||||||
|
|
||||||
// verifico se file compresso (gz)
|
|
||||||
if ( cBuff[0] == '\x1F' && cBuff[1] == '\x8B')
|
|
||||||
return NGE_ASCII ;
|
|
||||||
|
|
||||||
// verifico se iniziano con "START"
|
|
||||||
string sBuff = cBuff ;
|
|
||||||
size_t nPos = sBuff.find( "START") ;
|
|
||||||
if ( nPos != string::npos && nPos < 10)
|
|
||||||
return NGE_ASCII ;
|
|
||||||
else
|
|
||||||
return NGE_BINARY ;
|
return NGE_BINARY ;
|
||||||
|
// se testo
|
||||||
|
string sBuff{ szBuff} ;
|
||||||
|
if ( sBuff.find( "START") != string::npos)
|
||||||
|
return NGE_ASCII ;
|
||||||
|
// altrimenti errore
|
||||||
|
return NGE_ERROR ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -91,7 +91,7 @@ int
|
|||||||
NgeReader::GetCurrPos( void)
|
NgeReader::GetCurrPos( void)
|
||||||
{
|
{
|
||||||
if ( m_bBinary)
|
if ( m_bBinary)
|
||||||
return int( m_InFile.tellg()) ;
|
return int( gztell( m_InFile)) ;
|
||||||
else
|
else
|
||||||
return m_Scan.GetCurrLineNbr() ;
|
return m_Scan.GetCurrLineNbr() ;
|
||||||
}
|
}
|
||||||
@@ -131,10 +131,9 @@ bool
|
|||||||
NgeReader::ReadUchar( unsigned char& ucVal, const char* szSep, bool bEndL)
|
NgeReader::ReadUchar( unsigned char& ucVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &ucVal, sizeof( ucVal)) ;
|
return ( gzread( m_InFile, &ucVal, sizeof( ucVal)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -154,10 +153,9 @@ bool
|
|||||||
NgeReader::ReadBool( bool& bVal, const char* szSep, bool bEndL)
|
NgeReader::ReadBool( bool& bVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &bVal, sizeof( bVal)) ;
|
return ( gzread( m_InFile, &bVal, sizeof( bVal)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -173,10 +171,9 @@ bool
|
|||||||
NgeReader::ReadInt( int& nVal, const char* szSep, bool bEndL)
|
NgeReader::ReadInt( int& nVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
|
return ( gzread( m_InFile, &nVal, sizeof( nVal)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -203,10 +200,9 @@ bool
|
|||||||
NgeReader::ReadDouble( double& dVal, const char* szSep, bool bEndL)
|
NgeReader::ReadDouble( double& dVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &dVal, sizeof( dVal)) ;
|
return ( gzread( m_InFile, &dVal, sizeof( dVal)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -222,10 +218,9 @@ bool
|
|||||||
NgeReader::ReadVector( Vector3d& vtV, const char* szSep, bool bEndL)
|
NgeReader::ReadVector( Vector3d& vtV, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &vtV.v, sizeof( vtV.v)) ;
|
return ( gzread( m_InFile, &vtV.v, sizeof( vtV.v)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -241,10 +236,9 @@ bool
|
|||||||
NgeReader::ReadPoint( Point3d& ptP, const char* szSep, bool bEndL)
|
NgeReader::ReadPoint( Point3d& ptP, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
|
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -260,11 +254,10 @@ bool
|
|||||||
NgeReader::ReadPointW( Point3d& ptP, double& dW, const char* szSep, bool bEndL)
|
NgeReader::ReadPointW( Point3d& ptP, double& dW, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( (char*) &ptP.v, sizeof( ptP.v)) ;
|
return ( gzread( m_InFile, &ptP.v, sizeof( ptP.v)) != Z_ERRNO &&
|
||||||
m_InFile.read( (char*) &dW, sizeof( dW)) ;
|
gzread( m_InFile, &dW, sizeof( dW)) != Z_ERRNO) ;
|
||||||
return m_InFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recupero il token
|
// recupero il token
|
||||||
@@ -280,17 +273,13 @@ bool
|
|||||||
NgeReader::ReadFrame( Frame3d& frF, const char* szSep, bool bEndL)
|
NgeReader::ReadFrame( Frame3d& frF, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
Point3d ptOrig ;
|
Point3d ptOrig ; Vector3d vtDirX, vtDirY, vtDirZ ;
|
||||||
m_InFile.read( (char*) &ptOrig.v, sizeof( ptOrig.v)) ;
|
if ( gzread( m_InFile, &ptOrig.v, sizeof( ptOrig.v)) == Z_ERRNO ||
|
||||||
Vector3d vtDirX ;
|
gzread( m_InFile, &vtDirX.v, sizeof( vtDirX.v)) == Z_ERRNO ||
|
||||||
m_InFile.read( (char*) &vtDirX.v, sizeof( vtDirX.v)) ;
|
gzread( m_InFile, &vtDirY.v, sizeof( vtDirY.v)) == Z_ERRNO ||
|
||||||
Vector3d vtDirY ;
|
gzread( m_InFile, &vtDirZ.v, sizeof( vtDirZ.v)) == Z_ERRNO)
|
||||||
m_InFile.read( (char*) &vtDirY.v, sizeof( vtDirY.v)) ;
|
|
||||||
Vector3d vtDirZ ;
|
|
||||||
m_InFile.read( (char*) &vtDirZ.v, sizeof( vtDirZ.v)) ;
|
|
||||||
if ( ! m_InFile.good())
|
|
||||||
return false ;
|
return false ;
|
||||||
return frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ;
|
return frF.Set( ptOrig, vtDirX, vtDirY, vtDirZ) ;
|
||||||
}
|
}
|
||||||
@@ -308,18 +297,20 @@ bool
|
|||||||
NgeReader::ReadString( string& sVal, const char* szSep, bool bEndL)
|
NgeReader::ReadString( string& sVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
|
if ( m_InFile == nullptr)
|
||||||
|
return false ;
|
||||||
const int MAX_STR_DIM = 65535 ;
|
const int MAX_STR_DIM = 65535 ;
|
||||||
if ( ! m_InFile.is_open())
|
|
||||||
return false ;
|
|
||||||
int nDim ;
|
int nDim ;
|
||||||
m_InFile.read( (char*) &nDim, sizeof( nDim)) ;
|
if ( gzread( m_InFile, &nDim, sizeof( nDim)) == Z_ERRNO || nDim > MAX_STR_DIM)
|
||||||
if ( nDim > MAX_STR_DIM || ! m_InFile.good())
|
|
||||||
return false ;
|
return false ;
|
||||||
|
if ( nDim == 0) {
|
||||||
|
sVal = "" ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
char* szBuff = new( nothrow) char[ nDim + 1] ;
|
char* szBuff = new( nothrow) char[ nDim + 1] ;
|
||||||
if ( szBuff == nullptr)
|
if ( szBuff == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_InFile.read( szBuff, nDim) ;
|
if ( gzread( m_InFile, szBuff, nDim) == Z_ERRNO) {
|
||||||
if ( ! m_InFile.good()) {
|
|
||||||
delete[] szBuff ;
|
delete[] szBuff ;
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
@@ -348,12 +339,11 @@ NgeReader::ReadKey( int& nKey)
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// leggo il dato
|
// leggo il dato
|
||||||
int nVal ;
|
int nVal ;
|
||||||
m_InFile.read( (char*) &nVal, sizeof( nVal)) ;
|
if ( gzread( m_InFile, &nVal, sizeof( nVal)) == Z_ERRNO)
|
||||||
if ( ! m_InFile.good())
|
|
||||||
return false ;
|
return false ;
|
||||||
// ricavo l'indice
|
// ricavo l'indice
|
||||||
for ( int i = 0 ; i <= NGE_LAST_ID ; ++ i) {
|
for ( int i = 0 ; i <= NGE_LAST_ID ; ++ i) {
|
||||||
@@ -386,11 +376,10 @@ bool
|
|||||||
NgeReader::ReadCol( Color& cCol, const char* szSep, bool bEndL)
|
NgeReader::ReadCol( Color& cCol, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_InFile.is_open())
|
if ( m_InFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
unsigned char ucCol[4] ;
|
unsigned char ucCol[4] ;
|
||||||
m_InFile.read( (char*) &ucCol, sizeof( ucCol)) ;
|
if ( gzread( m_InFile, &ucCol, sizeof( ucCol)) == Z_ERRNO)
|
||||||
if ( ! m_InFile.good())
|
|
||||||
return false ;
|
return false ;
|
||||||
cCol.Set( ucCol[0], ucCol[1], ucCol[2], ucCol[3]) ;
|
cCol.Set( ucCol[0], ucCol[1], ucCol[2], ucCol[3]) ;
|
||||||
return true ;
|
return true ;
|
||||||
|
|||||||
+7
-5
@@ -1,7 +1,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2014-2014
|
// EgalTech 2014-2025
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : NgeReader.h Data : 14.04.14 Versione : 1.5d5
|
// File : NgeReader.h Data : 29.12.25 Versione : 2.7l6
|
||||||
// Contenuto : Dichiarazione della classe NgeReader.
|
// Contenuto : Dichiarazione della classe NgeReader.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -18,14 +18,16 @@
|
|||||||
#include "/EgtDev/Include/EGkColor.h"
|
#include "/EgtDev/Include/EGkColor.h"
|
||||||
#include "/EgtDev/Include/EGnScanner.h"
|
#include "/EgtDev/Include/EGnScanner.h"
|
||||||
#include "/EgtDev/Include/EgtStringBase.h"
|
#include "/EgtDev/Include/EgtStringBase.h"
|
||||||
#include <fstream>
|
|
||||||
|
struct gzFile_s ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class NgeReader
|
class NgeReader
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
NgeReader( void)
|
NgeReader( void)
|
||||||
: m_iPosStart( std::string::npos), m_bUngetKey( false), m_nFileVer() {}
|
: m_bBinary( false), m_InFile( nullptr), m_iPosStart( std::string::npos),
|
||||||
|
m_bUngetKey( false), m_nLastKey(), m_nFileVer() {}
|
||||||
~NgeReader( void)
|
~NgeReader( void)
|
||||||
{ Close() ; }
|
{ Close() ; }
|
||||||
bool Init( const std::string& sFileIn) ;
|
bool Init( const std::string& sFileIn) ;
|
||||||
@@ -60,7 +62,7 @@ class NgeReader
|
|||||||
private :
|
private :
|
||||||
bool m_bBinary ;
|
bool m_bBinary ;
|
||||||
// per file binari
|
// per file binari
|
||||||
std::ifstream m_InFile ;
|
gzFile_s* m_InFile ;
|
||||||
// per file ASCII
|
// per file ASCII
|
||||||
Scanner m_Scan ;
|
Scanner m_Scan ;
|
||||||
std::string::size_type m_iPosStart ;
|
std::string::size_type m_iPosStart ;
|
||||||
|
|||||||
+64
-86
@@ -23,23 +23,23 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
inline bool
|
static bool
|
||||||
WriteStringOutTxt( gzFile OutTxtFile, const char* szVal, const char* szSep, bool bEndL)
|
WriteStringOutTxt( gzFile OutFile, const char* szVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
// verifico apertura file
|
// verifico apertura file
|
||||||
if ( OutTxtFile == nullptr)
|
if ( OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
// scrivo stringa
|
// scrivo stringa
|
||||||
if ( gzputs( OutTxtFile, szVal) == Z_ERRNO)
|
if ( gzputs( OutFile, szVal) == Z_ERRNO)
|
||||||
return false ;
|
return false ;
|
||||||
// se fornito, scrivo separatore
|
// se fornito, scrivo separatore
|
||||||
if ( szSep != nullptr && szSep[0] != '\0') {
|
if ( szSep != nullptr && szSep[0] != '\0') {
|
||||||
if ( gzputs( OutTxtFile, szSep) == Z_ERRNO)
|
if ( gzputs( OutFile, szSep) == Z_ERRNO)
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se richiesto, scrivo fine linea
|
// se richiesto, scrivo fine linea
|
||||||
if ( bEndL) {
|
if ( bEndL) {
|
||||||
if ( gzputs( OutTxtFile, "\r\n") == Z_ERRNO)
|
if ( gzputs( OutFile, "\r\n") == Z_ERRNO)
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
@@ -50,27 +50,22 @@ bool
|
|||||||
NgeWriter::Init( const string& sFileOut, int nFlag)
|
NgeWriter::Init( const string& sFileOut, int nFlag)
|
||||||
{
|
{
|
||||||
// salvo tipo file
|
// salvo tipo file
|
||||||
m_bBinary = ( nFlag == GDB_SV_BIN) ;
|
m_bBinary = ( nFlag == GDB_SV_BIN || nFlag == GDB_SV_CMPBIN) ;
|
||||||
|
|
||||||
// apertura del file di uscita
|
// apertura del file di uscita
|
||||||
if ( m_bBinary) {
|
if ( nFlag == GDB_SV_TXT || nFlag == GDB_SV_BIN) {
|
||||||
ios_base::openmode nMode = ios::out | ( m_bBinary ? ios::binary : 0) ;
|
m_OutFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
|
||||||
int nProt = _SH_DENYWR ;
|
return ( m_OutFile != nullptr) ;
|
||||||
m_OutBinFile.open( stringtoW( sFileOut), nMode, nProt) ;
|
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else { // GDB_SV_CMPTXT o GDB_SV_CMPBIN
|
||||||
if ( nFlag == GDB_SV_TXT)
|
m_OutFile = gzopen_w( stringtoW( sFileOut), "wb") ;
|
||||||
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wbT") ;
|
if ( m_OutFile == nullptr)
|
||||||
else // GDB_SV_CMPTXT
|
|
||||||
m_OutTxtFile = gzopen_w( stringtoW( sFileOut), "wb") ;
|
|
||||||
if ( m_OutTxtFile == nullptr)
|
|
||||||
return false ;
|
return false ;
|
||||||
const int DIM_BUFFER = 65536 ;
|
const int DIM_BUFFER = 65536 ;
|
||||||
if ( gzbuffer( m_OutTxtFile, DIM_BUFFER) != Z_OK)
|
if ( gzbuffer( m_OutFile, DIM_BUFFER) != Z_OK)
|
||||||
return false ;
|
return false ;
|
||||||
const int COMPR_LEVEL = 3 ; // 0 = no compression ... 9 = max compression
|
const int COMPR_LEVEL = 3 ; // 0 = no compression ... 9 = max compression
|
||||||
if ( gzsetparams( m_OutTxtFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
if ( gzsetparams( m_OutFile, COMPR_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||||
return false ;
|
return false ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -80,20 +75,12 @@ NgeWriter::Init( const string& sFileOut, int nFlag)
|
|||||||
bool
|
bool
|
||||||
NgeWriter::Close( void)
|
NgeWriter::Close( void)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_OutFile != nullptr) {
|
||||||
bool bOk = ( m_OutBinFile.good() && m_OutBinFile.is_open()) ;
|
bool bOk = ( gzclose( m_OutFile) == Z_OK) ;
|
||||||
if ( m_OutBinFile.is_open())
|
m_OutFile = nullptr ;
|
||||||
m_OutBinFile.close() ;
|
|
||||||
return bOk ;
|
return bOk ;
|
||||||
}
|
}
|
||||||
else {
|
return true ;
|
||||||
if ( m_OutTxtFile != nullptr) {
|
|
||||||
bool bOk = ( gzclose( m_OutTxtFile) == Z_OK) ;
|
|
||||||
m_OutTxtFile = nullptr ;
|
|
||||||
return bOk ;
|
|
||||||
}
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -101,13 +88,12 @@ bool
|
|||||||
NgeWriter::WriteUchar( unsigned char ucVal, const char* szSep, bool bEndL)
|
NgeWriter::WriteUchar( unsigned char ucVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &ucVal, sizeof( ucVal)) ;
|
return ( gzwrite( m_OutFile, &ucVal, sizeof( ucVal)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ucVal).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( ucVal).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,13 +102,12 @@ bool
|
|||||||
NgeWriter::WriteBool( bool bVal, const char* szSep, bool bEndL)
|
NgeWriter::WriteBool( bool bVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &bVal, sizeof( bVal)) ;
|
return ( gzwrite( m_OutFile, &bVal, sizeof( bVal)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( bVal).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( bVal).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,13 +116,12 @@ bool
|
|||||||
NgeWriter::WriteInt( int nVal, const char* szSep, bool bEndL)
|
NgeWriter::WriteInt( int nVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &nVal, sizeof( nVal)) ;
|
return ( gzwrite( m_OutFile, &nVal, sizeof( nVal)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( nVal).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( nVal).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,13 +130,12 @@ bool
|
|||||||
NgeWriter::WriteDouble( double dVal, const char* szSep, bool bEndL, int nPrec)
|
NgeWriter::WriteDouble( double dVal, const char* szSep, bool bEndL, int nPrec)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &dVal, sizeof( dVal)) ;
|
return ( gzwrite( m_OutFile, &dVal, sizeof( dVal)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( dVal, nPrec).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,15 +144,14 @@ bool
|
|||||||
NgeWriter::WriteString( const string& sVal, const char* szSep, bool bEndL)
|
NgeWriter::WriteString( const string& sVal, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
int nDim = int( sVal.size()) ;
|
int nDim = ssize( sVal) ;
|
||||||
m_OutBinFile.write( (char*) &nDim, sizeof( nDim)) ;
|
return ( gzwrite( m_OutFile, &nDim, sizeof( nDim)) > 0 &&
|
||||||
m_OutBinFile.write( sVal.c_str(), sVal.size()) ;
|
( nDim == 0 || gzwrite( m_OutFile, sVal.c_str(), sVal.size()) > 0)) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, sVal.c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,13 +160,12 @@ bool
|
|||||||
NgeWriter::WriteVector( const Vector3d& vtV, const char* szSep, bool bEndL, int nPrec)
|
NgeWriter::WriteVector( const Vector3d& vtV, const char* szSep, bool bEndL, int nPrec)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &vtV.v, sizeof( vtV.v)) ;
|
return ( gzwrite( m_OutFile, &vtV.v, sizeof( vtV.v)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( vtV, nPrec).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,13 +174,12 @@ bool
|
|||||||
NgeWriter::WritePoint( const Point3d& ptP, const char* szSep, bool bEndL, int nPrec)
|
NgeWriter::WritePoint( const Point3d& ptP, const char* szSep, bool bEndL, int nPrec)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
|
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( ptP, nPrec).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,14 +188,13 @@ bool
|
|||||||
NgeWriter::WritePointW( const Point3d& ptP, double dW, const char* szSep, bool bEndL, int nPrecP, int nPrecW)
|
NgeWriter::WritePointW( const Point3d& ptP, double dW, const char* szSep, bool bEndL, int nPrecP, int nPrecW)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &ptP.v, sizeof( ptP.v)) ;
|
return ( gzwrite( m_OutFile, &ptP.v, sizeof( ptP.v)) > 0 &&
|
||||||
m_OutBinFile.write( (char*) &dW, sizeof( dW)) ;
|
gzwrite( m_OutFile, &dW, sizeof( dW)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( ptP, dW, nPrecP, nPrecW).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,16 +203,15 @@ bool
|
|||||||
NgeWriter::WriteFrame( const Frame3d& frF, const char* szSep, bool bEndL, int nPrecP, int nPrecV)
|
NgeWriter::WriteFrame( const Frame3d& frF, const char* szSep, bool bEndL, int nPrecP, int nPrecV)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &frF.Orig().v, sizeof( frF.Orig().v)) ;
|
return ( gzwrite( m_OutFile, &frF.Orig().v, sizeof( frF.Orig().v)) > 0 &&
|
||||||
m_OutBinFile.write( (char*) &frF.VersX().v, sizeof( frF.VersX().v)) ;
|
gzwrite( m_OutFile, &frF.VersX().v, sizeof( frF.VersX().v)) > 0 &&
|
||||||
m_OutBinFile.write( (char*) &frF.VersY().v, sizeof( frF.VersY().v)) ;
|
gzwrite( m_OutFile, &frF.VersY().v, sizeof( frF.VersY().v)) > 0 &&
|
||||||
m_OutBinFile.write( (char*) &frF.VersZ().v, sizeof( frF.VersZ().v)) ;
|
gzwrite( m_OutFile, &frF.VersZ().v, sizeof( frF.VersZ().v)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( frF, nPrecP, nPrecV).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +223,12 @@ NgeWriter::WriteKey( int nKey)
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
m_OutBinFile.write( (char*) &NgeBinKeyW[nKey], sizeof( int)) ;
|
return ( gzwrite( m_OutFile, &NgeBinKeyW[nKey], sizeof( int)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
|
return WriteStringOutTxt( m_OutFile, NgeAscKeyW[nKey].c_str(), nullptr, true) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,18 +237,17 @@ bool
|
|||||||
NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
|
NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
|
||||||
{
|
{
|
||||||
if ( m_bBinary) {
|
if ( m_bBinary) {
|
||||||
if ( ! m_OutBinFile.is_open())
|
if ( m_OutFile == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
unsigned char ucCol[4] ;
|
unsigned char ucCol[4] ;
|
||||||
ucCol[0] = cCol.GetIntRed() ;
|
ucCol[0] = cCol.GetIntRed() ;
|
||||||
ucCol[1] = cCol.GetIntGreen() ;
|
ucCol[1] = cCol.GetIntGreen() ;
|
||||||
ucCol[2] = cCol.GetIntBlue() ;
|
ucCol[2] = cCol.GetIntBlue() ;
|
||||||
ucCol[3] = cCol.GetIntAlpha() ;
|
ucCol[3] = cCol.GetIntAlpha() ;
|
||||||
m_OutBinFile.write( (char*) ucCol, sizeof( ucCol)) ;
|
return ( gzwrite( m_OutFile, ucCol, sizeof( ucCol)) > 0) ;
|
||||||
return m_OutBinFile.good() ;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return WriteStringOutTxt( m_OutTxtFile, ToString( cCol).c_str(), szSep, bEndL) ;
|
return WriteStringOutTxt( m_OutFile, ToString( cCol).c_str(), szSep, bEndL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,9 +255,11 @@ NgeWriter::WriteCol( const Color& cCol, const char* szSep, bool bEndL)
|
|||||||
bool
|
bool
|
||||||
NgeWriter::WriteRemark( const string& sVal)
|
NgeWriter::WriteRemark( const string& sVal)
|
||||||
{
|
{
|
||||||
if ( m_bBinary)
|
if ( m_bBinary) {
|
||||||
return true ;
|
return true ;
|
||||||
else
|
}
|
||||||
return ( WriteStringOutTxt( m_OutTxtFile, "//", nullptr, false) &&
|
else {
|
||||||
WriteStringOutTxt( m_OutTxtFile, sVal.c_str(), nullptr, true)) ;
|
return ( WriteStringOutTxt( m_OutFile, "//", nullptr, false) &&
|
||||||
|
WriteStringOutTxt( m_OutFile, sVal.c_str(), nullptr, true)) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-9
@@ -1,7 +1,7 @@
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// EgalTech 2014-2014
|
// EgalTech 2014-2025
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// File : NgeWriter.h Data : 12.04.14 Versione : 1.5d5
|
// File : NgeWriter.h Data : 29.12.25 Versione : 2.7l6
|
||||||
// Contenuto : Dichiarazione della classe NgeWriter.
|
// Contenuto : Dichiarazione della classe NgeWriter.
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
@@ -16,7 +16,6 @@
|
|||||||
#include "NgeConst.h"
|
#include "NgeConst.h"
|
||||||
#include "/EgtDev/Include/EGkPoint3d.h"
|
#include "/EgtDev/Include/EGkPoint3d.h"
|
||||||
#include "/EgtDev/Include/EGkColor.h"
|
#include "/EgtDev/Include/EGkColor.h"
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
struct gzFile_s ;
|
struct gzFile_s ;
|
||||||
|
|
||||||
@@ -24,7 +23,7 @@ struct gzFile_s ;
|
|||||||
class NgeWriter
|
class NgeWriter
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
NgeWriter( void) : m_bBinary( false), m_OutTxtFile( nullptr) {}
|
NgeWriter( void) : m_bBinary( false), m_OutFile( nullptr) {}
|
||||||
~NgeWriter( void)
|
~NgeWriter( void)
|
||||||
{ Close() ; }
|
{ Close() ; }
|
||||||
bool Init( const std::string& sFileOut, int nFlag) ;
|
bool Init( const std::string& sFileOut, int nFlag) ;
|
||||||
@@ -44,9 +43,6 @@ class NgeWriter
|
|||||||
bool WriteRemark( const std::string& sVal /* bEndL = true*/) ;
|
bool WriteRemark( const std::string& sVal /* bEndL = true*/) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool m_bBinary ;
|
bool m_bBinary ;
|
||||||
// per file binari
|
gzFile_s* m_OutFile ;
|
||||||
std::ofstream m_OutBinFile ;
|
|
||||||
// per file ASCII
|
|
||||||
gzFile_s* m_OutTxtFile ;
|
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
+149
-25
@@ -16,9 +16,17 @@
|
|||||||
#include "CurveArc.h"
|
#include "CurveArc.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||||
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
|
|
||||||
using namespace std ;
|
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
|
bool
|
||||||
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||||
@@ -52,36 +60,76 @@ IsFillet( const ICurve* pCrv, double dDist)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType)
|
AdjustCurveFillets( ICURVEPOVECTOR& vOffset, double dDist, int nType)
|
||||||
{
|
{
|
||||||
ICURVEPLIST CrvLst ;
|
if ( vOffset.empty())
|
||||||
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
return true ;
|
||||||
while ( ! IsNull( pCrv)) {
|
|
||||||
// se identificato come fillet lo trasformo in smusso o estensione
|
// suddivido le curve di offset individuando i fillet e isolandoli dagli altri tratti
|
||||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
ICRVCOMPOPVECTOR vCrvs ;
|
||||||
CurveComposite ccTemp ;
|
for ( int i = 0 ; i < int( vOffset.size()) ; i ++) {
|
||||||
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
CurveComposite* pCompo = GetBasicCurveComposite( vOffset[i]) ;
|
||||||
// metto in lista le curve risultanti
|
if ( pCompo == nullptr)
|
||||||
if ( ccTemp.GetCurveCount() > 0) {
|
return false ;
|
||||||
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
bool bNewCrv = true ;
|
||||||
while ( ! IsNull( pCrv2)) {
|
PtrOwner<ICurve> pCrv( pCompo->RemoveFirstOrLastCurve(false)) ;
|
||||||
CrvLst.push_back( Release( pCrv2)) ;
|
while ( ! IsNull( pCrv)) {
|
||||||
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
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
|
vOffset.clear() ;
|
||||||
for ( auto pCrv : CrvLst) {
|
|
||||||
pCrvCo->AddCurve( pCrv) ;
|
// 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 ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -175,3 +223,79 @@ ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux)
|
|||||||
}
|
}
|
||||||
return false ;
|
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 ;
|
||||||
|
}
|
||||||
|
|||||||
+1
-3
@@ -16,6 +16,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
||||||
bool IsFillet( const ICurve* pCrv, double dDist) ;
|
bool AdjustCurveFillets( ICURVEPOVECTOR& vCrvs, double dDist, int nType) ;
|
||||||
bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ;
|
|
||||||
bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
|
||||||
+17
-9
@@ -243,11 +243,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
if ( IsNull( pCrv1))
|
if ( IsNull( pCrv1))
|
||||||
return false ;
|
return false ;
|
||||||
pCrv1->SetTempProp( nInd1) ;
|
pCrv1->SetTempProp( nInd1) ;
|
||||||
if ( ! pCrv1->SimpleOffset( dDist, ICurve::OFF_FILLET)) {
|
if ( ! pCrv1->SimpleOffset( dDist)) {
|
||||||
CurveArc* pArc = GetBasicCurveArc( pCrv1) ;
|
CurveArc* pArc = GetBasicCurveArc( pCrv1) ;
|
||||||
if ( pArc == nullptr)
|
if ( pArc == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
|
if ( pArc->MyExtendedOffset( dDist, true))
|
||||||
pCrv1->SetTempProp( - nInd1) ;
|
pCrv1->SetTempProp( - nInd1) ;
|
||||||
}
|
}
|
||||||
// curve successive
|
// curve successive
|
||||||
@@ -255,11 +255,11 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
while ( ! IsNull( pCrv2)) {
|
while ( ! IsNull( pCrv2)) {
|
||||||
// eseguo semplice offset
|
// eseguo semplice offset
|
||||||
pCrv2->SetTempProp( nInd1 + 1) ;
|
pCrv2->SetTempProp( nInd1 + 1) ;
|
||||||
if ( ! pCrv2->SimpleOffset( dDist, ICurve::OFF_FILLET)) {
|
if ( ! pCrv2->SimpleOffset( dDist)) {
|
||||||
CurveArc* pArc = GetBasicCurveArc( pCrv2) ;
|
CurveArc* pArc = GetBasicCurveArc( pCrv2) ;
|
||||||
if ( pArc == nullptr)
|
if ( pArc == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
if ( pArc->MyExtendedOffset( dDist, true, ICurve::OFF_FILLET))
|
if ( pArc->MyExtendedOffset( dDist, true))
|
||||||
pCrv2->SetTempProp( - ( nInd1 + 1)) ;
|
pCrv2->SetTempProp( - ( nInd1 + 1)) ;
|
||||||
}
|
}
|
||||||
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
// verifico relazione con la curva precedente e aggiungo eventuali curve intermedie
|
||||||
@@ -674,12 +674,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
// 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) {
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
||||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
|
ICURVEPOVECTOR vCrvs ;
|
||||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
vCrvs.reserve( m_CrvLst.size()) ;
|
||||||
IdentifyFillets( pCrvCo, dDist) ;
|
for ( auto pCrv : m_CrvLst) {
|
||||||
AdjustCurveFillets( pCrvCo, dDist, nType) ;
|
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])) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
//--------------------------- Include ----------------------------------------
|
//--------------------------- Include ----------------------------------------
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "PointsPCA.h"
|
#include "PointsPCA.h"
|
||||||
|
#define EIGEN_NO_IO
|
||||||
#include "/EgtDev/Extern/Eigen/Dense"
|
#include "/EgtDev/Extern/Eigen/Dense"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+331
-14
@@ -18,6 +18,8 @@
|
|||||||
#include "PolygonPlane.h"
|
#include "PolygonPlane.h"
|
||||||
#include "PointsPCA.h"
|
#include "PointsPCA.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
|
#include "CurveComposite.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include "/EgtDev/Include/EGkPolyLine.h"
|
#include "/EgtDev/Include/EGkPolyLine.h"
|
||||||
#include "/EgtDev/Include/EGkPlane3d.h"
|
#include "/EgtDev/Include/EGkPlane3d.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||||
@@ -773,7 +775,7 @@ DouglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
PolyLine::RemoveAlignedPoints( double dToler)
|
PolyLine::RemoveAlignedPoints( double dToler, bool bStartEnd)
|
||||||
{
|
{
|
||||||
// se non ci sono almeno 3 punti, esco subito
|
// se non ci sono almeno 3 punti, esco subito
|
||||||
if ( m_lUPoints.size() < 3)
|
if ( m_lUPoints.size() < 3)
|
||||||
@@ -796,7 +798,7 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
|||||||
vInd.push_back( 0) ;
|
vInd.push_back( 0) ;
|
||||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vInd))
|
||||||
return false ;
|
return false ;
|
||||||
vInd.push_back( vPtU.size() - 1) ;
|
vInd.push_back( int( vPtU.size()) - 1) ;
|
||||||
}
|
}
|
||||||
// altrimenti chiusa
|
// altrimenti chiusa
|
||||||
else {
|
else {
|
||||||
@@ -817,15 +819,15 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
|||||||
vInd.push_back( nMaxInd) ;
|
vInd.push_back( nMaxInd) ;
|
||||||
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
if ( ! DouglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vInd))
|
||||||
return false ;
|
return false ;
|
||||||
vInd.push_back( vPtU.size() - 1) ;
|
vInd.push_back( int( vPtU.size()) - 1) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ordino in senso crescente
|
// ordino in senso crescente
|
||||||
sort( vInd.begin(), vInd.end()) ;
|
sort( vInd.begin(), vInd.end()) ;
|
||||||
|
|
||||||
// se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
|
// se richiesto e chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti
|
||||||
if ( IsClosed() && vInd.size() >= 4) {
|
if ( bStartEnd && IsClosed() && vInd.size() >= 4) {
|
||||||
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[vInd.size()-2]].first).IsEpsilon( dToler)) {
|
if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[int(vInd.size())-2]].first).IsEpsilon( dToler)) {
|
||||||
vInd.erase( vInd.begin()) ;
|
vInd.erase( vInd.begin()) ;
|
||||||
vInd.back() = vInd.front() ;
|
vInd.back() = vInd.front() ;
|
||||||
}
|
}
|
||||||
@@ -1445,7 +1447,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
}
|
}
|
||||||
// Determino tangente di riferimento
|
// Determino tangente di riferimento
|
||||||
Vector3d vtTang ;
|
Vector3d vtTang ;
|
||||||
// se minima distanza nell'estremo iniziale del segmento
|
// se minima distanza nell'estremo iniziale del segmento
|
||||||
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
if ( AreSamePointApprox( ptMinDist, prev( itMinDistEnd)->first)) {
|
||||||
// direzione del segmento
|
// direzione del segmento
|
||||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
@@ -1461,7 +1463,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
vtTang = vtPrevTg + vtCurrTg ;
|
vtTang = vtPrevTg + vtCurrTg ;
|
||||||
vtTang.Normalize() ;
|
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)) {
|
else if ( AreSamePointApprox( ptMinDist, itMinDistEnd->first)) {
|
||||||
// direzione del segmento
|
// direzione del segmento
|
||||||
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
Vector3d vtCurrTg = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
@@ -1477,7 +1479,7 @@ IsPointInsidePolyLine( const Point3d& ptP, const PolyLine& plPoly, double dToler
|
|||||||
vtTang = vtCurrTg + vtNextTg ;
|
vtTang = vtCurrTg + vtNextTg ;
|
||||||
vtTang.Normalize() ;
|
vtTang.Normalize() ;
|
||||||
}
|
}
|
||||||
// altrimenti minima distanza con l'interno
|
// altrimenti minima distanza con l'interno
|
||||||
else {
|
else {
|
||||||
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
vtTang = itMinDistEnd->first - prev( itMinDistEnd)->first ;
|
||||||
}
|
}
|
||||||
@@ -1529,6 +1531,10 @@ ChangePolyLineStart( PolyLine& plPoly, const Point3d& ptNewStart, double dToler)
|
|||||||
return false ;
|
return false ;
|
||||||
// Riferimento alla lista dei punti
|
// Riferimento alla lista dei punti
|
||||||
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
PNTULIST& LoopList = const_cast<PolyLine&>( plPoly).GetUPointList() ;
|
||||||
|
// Se il punto inziale è già quello, non faccio nulla
|
||||||
|
if ( AreSamePointEpsilon( LoopList.begin()->first, ptNewStart, dToler))
|
||||||
|
return true ;
|
||||||
|
|
||||||
// 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 ;
|
double dMinSqDist = SQ_INFINITO ;
|
||||||
auto itMinDistEnd = LoopList.end() ;
|
auto itMinDistEnd = LoopList.end() ;
|
||||||
@@ -1612,8 +1618,9 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
int nPnt2 = PL2.GetPointNbr() ;
|
int nPnt2 = PL2.GetPointNbr() ;
|
||||||
if ( nPnt1 == 0 || nPnt2 == 0)
|
if ( nPnt1 == 0 || nPnt2 == 0)
|
||||||
return false ;
|
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()) ;
|
vPnt1.reserve( PL1.GetPointNbr()) ;
|
||||||
Point3d ptP1 ;
|
Point3d ptP1 ;
|
||||||
@@ -1657,7 +1664,7 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
nMinJ = nLastJ ;
|
nMinJ = nLastJ ;
|
||||||
|
|
||||||
// verifica se è un punto interno in comune con l'altra polyline
|
// 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)
|
if ( i < nTotP1 - 1 && dDist < EPS_SMALL && abs( dMinDistPar - floor( dMinDistPar + 0.5)) < EPS_SMALL)
|
||||||
bCommonInternalPoints = true ;
|
bCommonInternalPoints = true ;
|
||||||
|
|
||||||
vPnt1[i].second = nMinJ ;
|
vPnt1[i].second = nMinJ ;
|
||||||
@@ -1687,12 +1694,322 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
if ( nMinI < nLastI)
|
if ( nMinI < nLastI)
|
||||||
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 ;
|
bCommonInternalPoints = true ;
|
||||||
|
|
||||||
vPnt2[j].second = nMinI ;
|
vPnt2[j].second = nMinI ;
|
||||||
nLastI = 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 ;
|
||||||
|
while ( nAddedSpan < nPnt) {
|
||||||
|
if ( nCrv1 >= nPnt1)
|
||||||
|
nCrv1 = nPnt1 - 1 ;
|
||||||
|
if ( nCrv2 >= nPnt2)
|
||||||
|
nCrv2 = nPnt2 - 1 ;
|
||||||
|
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 ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -173,7 +173,7 @@ Polygon3d::FromPlaneTrimmedWithBox( const Point3d& ptOn, const Vector3d& vtN,
|
|||||||
{
|
{
|
||||||
Plane3d plPlane ;
|
Plane3d plPlane ;
|
||||||
plPlane.Set( ptOn, vtN) ;
|
plPlane.Set( ptOn, vtN) ;
|
||||||
return FromPlaneTrimmedWithBox( plPlane, ptMin, ptMax, bOnEq, bOnCt) ;
|
return FromPlaneTrimmedWithBox( plPlane, ptMin, ptMax, bOnEq, bOnCt, dToler) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+29
-16
@@ -150,12 +150,18 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
Vector3d vtN = pgFacet.GetVersN() ;
|
Vector3d vtN = pgFacet.GetVersN() ;
|
||||||
PolyLine PL = pgFacet.GetPolyLine() ;
|
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 ;
|
const double RAY_LEN = 100000 ;
|
||||||
dElev = 0 ;
|
dElev = 0 ;
|
||||||
|
PNTVECTOR vptP ; vptP.reserve( PL.GetPointNbr()) ;
|
||||||
Point3d ptP ;
|
Point3d ptP ;
|
||||||
bool bFound = PL.GetFirstPoint( ptP) ;
|
bool bFound = PL.GetFirstPoint( ptP) ;
|
||||||
while ( bFound) {
|
while ( bFound) {
|
||||||
|
vptP.push_back( ptP) ;
|
||||||
|
bFound = PL.GetNextPoint( ptP, true) ;
|
||||||
|
}
|
||||||
|
vptP.push_back( ptCen) ;
|
||||||
|
for ( const Point3d& ptP : vptP) {
|
||||||
ILSIVECTOR vInters ;
|
ILSIVECTOR vInters ;
|
||||||
IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
|
IntersLineSurfTm( ptP, vtN, RAY_LEN, CldStm, vInters, true) ;
|
||||||
for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vInters.size()) ; ++ i) {
|
||||||
@@ -166,12 +172,11 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ( Inters.nILTT == ILTT_VERT || Inters.nILTT == ILTT_EDGE || Inters.nILTT == ILTT_IN) && Inters.dCosDN > EPS_ZERO)
|
else if ( ( Inters.nILTT == ILTT_VERT || Inters.nILTT == ILTT_EDGE || Inters.nILTT == ILTT_IN) && Inters.dCosDN > EPS_ZERO)
|
||||||
dElev = max( dElev, Inters.dU) ;
|
dElev = max( dElev, Inters.dU) ;
|
||||||
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
|
else if ( Inters.nILTT == ILTT_SEGM || Inters.nILTT == ILTT_SEGM_ON_EDGE)
|
||||||
dElev = max( dElev, Inters.dU2) ;
|
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
|
// 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() ;
|
int nEdgeCnt = CldStm.GetEdgeCount() ;
|
||||||
@@ -201,22 +206,30 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
|
if ( vEdges[i].first.z < EPS_SMALL && vEdges[i].second.z < EPS_SMALL)
|
||||||
continue ;
|
continue ;
|
||||||
// calcolo il segmento di linea
|
// calcolo il segmento di linea
|
||||||
CurveLine clLine ;
|
CurveLine clLine ;
|
||||||
if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
|
if ( ! clLine.Set( vEdges[i].first, vEdges[i].second))
|
||||||
return false ;
|
return false ;
|
||||||
// l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
|
// l'elevazione va aggiornata con la massima Z delle eventuali intersezioni dell'edge con il loop
|
||||||
IntersCurveCurve intLL( clLine, ccLoop) ;
|
IntersCurveCurve intLL( clLine, ccLoop) ;
|
||||||
IntCrvCrvInfo aInfo ;
|
if ( intLL.GetIntersCount() == 0) {
|
||||||
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
Point3d ptM = Media( vEdges[i].first, vEdges[i].second) ;
|
||||||
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
ptM.z = 0 ;
|
||||||
if ( aInfo.bOverlap)
|
if ( IsPointInsidePolyLine( ptM, PL, -EPS_SMALL))
|
||||||
dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
|
dElev = max( dElev, max( vEdges[i].first.z, vEdges[i].second.z)) ;
|
||||||
// se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
|
}
|
||||||
if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
|
else {
|
||||||
dElev = max( dElev, vEdges[i].first.z) ;
|
IntCrvCrvInfo aInfo ;
|
||||||
// se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
|
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
||||||
else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
|
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
||||||
dElev = max( dElev, vEdges[i].second.z) ;
|
if ( aInfo.bOverlap)
|
||||||
|
dElev = max( dElev, aInfo.IciA[1].ptI.z) ;
|
||||||
|
// se prima intersezione va da interno ad esterno allora devo considerare il punto iniziale del segmento (vertice)
|
||||||
|
if ( j == 0 && aInfo.IciA[0].nPrevTy == ICCT_IN)
|
||||||
|
dElev = max( dElev, vEdges[i].first.z) ;
|
||||||
|
// se ultima intersezione va da esterno a interno allora devo considerare il punto finale del segmento (vertice)
|
||||||
|
else if ( j == intLL.GetIntersCount() - 1 && aInfo.IciA[ aInfo.bOverlap ? 1 : 0].nNextTy == ICCT_IN)
|
||||||
|
dElev = max( dElev, vEdges[i].second.z) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -19,10 +19,10 @@
|
|||||||
void
|
void
|
||||||
PolygonPlane::AddPoint( const Point3d& ptP)
|
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) {
|
if ( m_nPntNbr == -1) {
|
||||||
// inizializzazioni
|
// inizializzazioni
|
||||||
m_dLenN = 0 ;
|
m_dLenN = -1 ;
|
||||||
m_vtN = V_NULL ;
|
m_vtN = V_NULL ;
|
||||||
m_ptMid = ORIG ;
|
m_ptMid = ORIG ;
|
||||||
m_dSXy = 0 ; m_dSXz = 0 ;
|
m_dSXy = 0 ; m_dSXz = 0 ;
|
||||||
@@ -60,16 +60,16 @@ PolygonPlane::AddPoint( const Point3d& ptP)
|
|||||||
bool
|
bool
|
||||||
PolygonPlane::Finalize( void)
|
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)
|
if ( m_nPntNbr + 1 < 3)
|
||||||
return false ;
|
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)) {
|
if ( ! AreSamePointExact( m_ptFirst, m_ptLast)) {
|
||||||
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
// aggiungo il primo punto per far eseguire i conti sul lato di chiusura
|
||||||
AddPoint( m_ptFirst) ;
|
AddPoint( m_ptFirst) ;
|
||||||
}
|
}
|
||||||
// se non effettuato, eseguo il calcolo finale
|
// se non effettuato, eseguo il calcolo finale
|
||||||
if ( m_dLenN < EPS_SMALL) {
|
if ( m_dLenN < 0) {
|
||||||
// lunghezza della normale (doppio dell'area del poligono)
|
// lunghezza della normale (doppio dell'area del poligono)
|
||||||
m_dLenN = m_vtN.Len() ;
|
m_dLenN = m_vtN.Len() ;
|
||||||
if ( m_dLenN < SQ_EPS_SMALL)
|
if ( m_dLenN < SQ_EPS_SMALL)
|
||||||
|
|||||||
+719
-370
File diff suppressed because it is too large
Load Diff
@@ -92,11 +92,18 @@ RotationMinimizingFrame::GetFrameAtParam( const Frame3d& frAct, const double dPa
|
|||||||
Vector3d vtCurrR = frAct.VersX() ;
|
Vector3d vtCurrR = frAct.VersX() ;
|
||||||
Vector3d vtCurrT = frAct.VersZ() ;
|
Vector3d vtCurrT = frAct.VersZ() ;
|
||||||
|
|
||||||
// punto i-esimo sulla curva e suo vettore tangente
|
// punto i-esimo sulla curva e suo vettore tangente medio
|
||||||
|
Point3d ptNextM, ptNextP ;
|
||||||
|
Vector3d vtNextM, vtNextP ;
|
||||||
|
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNextM, &vtNextM) ||
|
||||||
|
! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_PLUS, ptNextP, &vtNextP) ||
|
||||||
|
! vtNextM.Normalize() || ! vtNextP.Normalize())
|
||||||
|
return false ;
|
||||||
Point3d ptNext ;
|
Point3d ptNext ;
|
||||||
Vector3d vtNextT ;
|
Vector3d vtNextT ;
|
||||||
if ( ! m_pCrv->GetPointD1D2( dParNext, ICurve::FROM_MINUS, ptNext, &vtNextT) ||
|
ptNext = Media( ptNextM, ptNextP) ;
|
||||||
! vtNextT.Normalize())
|
vtNextT = Media( vtNextM, vtNextP) ;
|
||||||
|
if ( ! vtNextT.Normalize())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// controllo per casi degeneri
|
// controllo per casi degeneri
|
||||||
|
|||||||
+126
-689
File diff suppressed because it is too large
Load Diff
+3
-2
@@ -115,7 +115,8 @@ GetSurfFlatRegionDisk( double dRadius)
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfFlatRegion*
|
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
|
// metodo di calcolo impostato da USE_VORONOI
|
||||||
|
|
||||||
@@ -330,7 +331,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
|
|||||||
else {
|
else {
|
||||||
// calcolo la fat curve con Voronoi
|
// calcolo la fat curve con Voronoi
|
||||||
ICURVEPOVECTOR vFatCurves ;
|
ICURVEPOVECTOR vFatCurves ;
|
||||||
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids))
|
if ( ! CalcCurveFatCurve( *pCurve, vFatCurves, dRadius, bSquareEnds, bSquareMids, bMergeOnlySameProps))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
// costruisco la superficie a partire dalle curve
|
// costruisco la superficie a partire dalle curve
|
||||||
|
|||||||
+1122
-543
File diff suppressed because it is too large
Load Diff
+14
-7
@@ -76,11 +76,18 @@ FromString( const string& sVal, Frame3d& frFrame)
|
|||||||
bool
|
bool
|
||||||
FromString( const string& sVal, Color& cCol)
|
FromString( const string& sVal, Color& cCol)
|
||||||
{
|
{
|
||||||
// devono essere 4 parametri : Red, Green, Blue, Alpha
|
// dovrebbero essere 4 parametri : Red, Green, Blue, Alpha
|
||||||
int vnVal[4] ;
|
int vnRGBA[4] ;
|
||||||
if ( ! FromString( sVal, vnVal))
|
if ( FromString( sVal, vnRGBA)) {
|
||||||
return false ;
|
cCol.Set( vnRGBA[0], vnRGBA[1], vnRGBA[2], vnRGBA[3]) ;
|
||||||
// assegno il colore
|
return true ;
|
||||||
cCol.Set( vnVal[0], vnVal[1], vnVal[2], vnVal[3]) ;
|
}
|
||||||
return true ;
|
// riprovo con 3 parametri : Red, Green, Blue
|
||||||
|
int vnRGB[3] ;
|
||||||
|
if ( FromString( sVal, vnRGB)) {
|
||||||
|
cCol.Set( vnRGB[0], vnRGB[1], vnRGB[2]) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// altrimenti errore
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -302,7 +302,7 @@ SetTmpPropByOverlap( ICurveComposite* pCrvCheck, const int nInd, const ICurveCom
|
|||||||
// ultimo tratto di curva della Composita iniziale
|
// ultimo tratto di curva della Composita iniziale
|
||||||
PtrOwner<CurveComposite> pCrvB( GetBasicCurveComposite( pCrvCheck->CopyParamRange( nInd + 1, pCrvCheck->GetCurveCount()))) ;
|
PtrOwner<CurveComposite> pCrvB( GetBasicCurveComposite( pCrvCheck->CopyParamRange( nInd + 1, pCrvCheck->GetCurveCount()))) ;
|
||||||
if ( ! IsNull( pCrvB) && pCrvB->GetCurveCount() > 0 && pCrvB->IsValid())
|
if ( ! IsNull( pCrvB) && pCrvB->GetCurveCount() > 0 && pCrvB->IsValid())
|
||||||
if( ! pCrvToReturn->AddCurve( Release( pCrvB))) {
|
if ( ! pCrvToReturn->AddCurve( Release( pCrvB))) {
|
||||||
nStat = 2 ;
|
nStat = 2 ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
+324
-78
@@ -24,6 +24,14 @@
|
|||||||
#include "/EgtDev/Include/EGkSurfAux.h"
|
#include "/EgtDev/Include/EGkSurfAux.h"
|
||||||
#include "/EgtDev/Include/EGkSfrCreate.h"
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SAVEMKUNIF_CRVS 0
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
std::vector<IGeoObj*> vGeo ;
|
||||||
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -37,12 +45,12 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
bool bIsRational = snData.bRat ;
|
bool bIsRational = snData.bRat ;
|
||||||
// vettore dei nodi
|
// vettore dei nodi
|
||||||
DBLVECTOR vU ;
|
DBLVECTOR vU ;
|
||||||
int nKnot = (int) snData.vU.size() ;
|
int nKnot = ssize( snData.vU) ;
|
||||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||||
double dKnot = snData.vU[k] ;
|
double dKnot = snData.vU[k] ;
|
||||||
vU.push_back( dKnot) ;
|
vU.push_back( dKnot) ;
|
||||||
}
|
}
|
||||||
for( int j = 0 ; j < snData.nCPV ; ++j) {
|
for ( int j = 0 ; j < snData.nCPV ; ++j) {
|
||||||
CNurbsData nuCurve ;
|
CNurbsData nuCurve ;
|
||||||
nuCurve.bPeriodic = true ;
|
nuCurve.bPeriodic = true ;
|
||||||
nuCurve.bRat = snData.bRat ;
|
nuCurve.bRat = snData.bRat ;
|
||||||
@@ -66,12 +74,16 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
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 ( 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() ) {
|
if ( snData.mCP.size() != nuCurve.vCP.size() ) {
|
||||||
snData.mCP.resize( nuCurve.vCP.size()) ;
|
snData.mCP.resize( nuCurve.vCP.size()) ;
|
||||||
if( snData.bRat)
|
if ( snData.bRat)
|
||||||
snData.mW.resize( nuCurve.vW.size()) ;
|
snData.mW.resize( nuCurve.vW.size()) ;
|
||||||
}
|
}
|
||||||
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
for ( int i = 0 ; i < ssize( nuCurve.vCP) ; ++i) {
|
||||||
|
if ( snData.mCP[i].empty())
|
||||||
|
snData.mCP[i].resize( snData.nCPV) ;
|
||||||
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
snData.mCP[i][j] = nuCurve.vCP[i] ;
|
||||||
if( snData.bRat) {
|
if ( snData.bRat) {
|
||||||
|
if ( snData.mW[i].empty())
|
||||||
|
snData.mW[i].resize( snData.nCPV) ;
|
||||||
snData.mW[i][j] = nuCurve.vW[i] ;
|
snData.mW[i][j] = nuCurve.vW[i] ;
|
||||||
snData.mCP[i][j] *= nuCurve.vW[i] ;
|
snData.mCP[i][j] *= nuCurve.vW[i] ;
|
||||||
}
|
}
|
||||||
@@ -80,18 +92,18 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
snData.bPeriodicU = false ;
|
snData.bPeriodicU = false ;
|
||||||
snData.nCPU = int( snData.mCP.size()) ;
|
snData.nCPU = ssize( snData.mCP) ;
|
||||||
}
|
}
|
||||||
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
if ( snData.bPeriodicV || ! snData.bClampedV) {
|
||||||
bool bIsRational = snData.bRat ;
|
bool bIsRational = snData.bRat ;
|
||||||
// vettore dei nodi
|
// vettore dei nodi
|
||||||
DBLVECTOR vV ;
|
DBLVECTOR vV ;
|
||||||
int nKnot = (int) snData.vV.size() ;
|
int nKnot = ssize( snData.vV) ;
|
||||||
for ( int k = 0 ; k < nKnot ; ++k ) {
|
for ( int k = 0 ; k < nKnot ; ++k ) {
|
||||||
double dKnot = snData.vV[k] ;
|
double dKnot = snData.vV[k] ;
|
||||||
vV.push_back( dKnot) ;
|
vV.push_back( dKnot) ;
|
||||||
}
|
}
|
||||||
for( int i = 0 ; i < snData.nCPU ; ++i) {
|
for ( int i = 0 ; i < snData.nCPU ; ++i) {
|
||||||
CNurbsData nuCurve ;
|
CNurbsData nuCurve ;
|
||||||
nuCurve.bPeriodic = true ;
|
nuCurve.bPeriodic = true ;
|
||||||
nuCurve.bRat = snData.bRat ;
|
nuCurve.bRat = snData.bRat ;
|
||||||
@@ -132,7 +144,7 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
snData.bPeriodicV = false ;
|
snData.bPeriodicV = false ;
|
||||||
snData.nCPV = int( snData.mCP[0].size()) ;
|
snData.nCPV = ssize( snData.mCP[0]) ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -526,6 +538,25 @@ NurbsToBezierSurface(const SNurbsSurfData& snData)
|
|||||||
return Release( pSrfBz) ;
|
return Release( pSrfBz) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ICurveComposite*
|
||||||
|
GetRectangleCurve( const Point3d& ptStart, double dWidth, double dHeight)
|
||||||
|
{
|
||||||
|
PolyLine PL ;
|
||||||
|
PL.AddUPoint( 0, ptStart) ;
|
||||||
|
PL.AddUPoint( 1, Point3d( ptStart.x + dWidth, ptStart.y)) ;
|
||||||
|
PL.AddUPoint( 2, Point3d( ptStart.x + dWidth, ptStart.y + dHeight, 0)) ;
|
||||||
|
PL.AddUPoint( 3, Point3d( ptStart.x , ptStart.y + dHeight, 0)) ;
|
||||||
|
PL.AddUPoint( 4, ptStart) ;
|
||||||
|
// creo la curva e la inserisco nel GDB
|
||||||
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
||||||
|
bool bOk = true ;
|
||||||
|
bOk = bOk && ! IsNull( pCrvCompo) ;
|
||||||
|
// inserisco i segmenti che uniscono i punti
|
||||||
|
bOk = bOk && pCrvCompo->FromPolyLine( PL) ;
|
||||||
|
return Release( pCrvCompo) ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, const DBLVECTOR& vV0,
|
MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, const DBLVECTOR& vV0,
|
||||||
@@ -535,36 +566,33 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
bool bRescaledU = false ;
|
bool bRescaledU = false ;
|
||||||
bool bRescaledV = false ;
|
bool bRescaledV = false ;
|
||||||
int nSpanU = 1, nSpanV = 1 ;
|
int nSpanU = 1, nSpanV = 1 ;
|
||||||
PtrOwner<ISurfFlatRegion> pRescaledSfr( CreateSurfFlatRegion()) ;
|
ICRVCOMPOPOVECTOR vUniformedCurves ;
|
||||||
|
BOOLVECTOR vbUniform(2) ;
|
||||||
|
fill( vbUniform.begin(), vbUniform.end(), true) ;
|
||||||
|
DBLMATRIX mKnots(2) ;
|
||||||
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
|
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
|
||||||
// vettore dei nodi
|
// vettore dei nodi
|
||||||
DBLVECTOR vU ;
|
DBLVECTOR& vU = mKnots[nDir] ;
|
||||||
int nExtraKnots = 0 ;
|
int nExtraKnots = 0 ;
|
||||||
// controllo in U
|
// controllo in U
|
||||||
if ( nDir == 0) {
|
if ( nDir == 0) {
|
||||||
if ( nDegU > 1) {
|
for ( int i = nExtraKnots ; i < ssize( vU0) - nExtraKnots ; ++i ) {
|
||||||
nExtraKnots = nDegU - 1 ;
|
|
||||||
}
|
|
||||||
for ( int i = nExtraKnots ; i < int( vU0.size()) - nExtraKnots ; ++i ) {
|
|
||||||
double dKnot = vU0[i] * SBZ_TREG_COEFF ;
|
double dKnot = vU0[i] * SBZ_TREG_COEFF ;
|
||||||
// lo aggiungo solo se è diverso dal precedente
|
// lo aggiungo solo se è diverso dal precedente
|
||||||
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
|
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL)
|
||||||
vU.push_back( dKnot) ;
|
vU.push_back( dKnot) ;
|
||||||
}
|
}
|
||||||
nSpanU = (int)vU.size() - 1 ;
|
nSpanU = ssize( vU) - 1 ;
|
||||||
}
|
}
|
||||||
// controllo in V
|
// controllo in V
|
||||||
else if ( nDir == 1 ) {
|
else if ( nDir == 1 ) {
|
||||||
if ( nDegV > 1) {
|
for ( int i = nExtraKnots ; i < ssize( vV0) - nExtraKnots ; ++i ) {
|
||||||
nExtraKnots = nDegV - 1 ;
|
|
||||||
}
|
|
||||||
for ( int i = nExtraKnots ; i < int( vV0.size()) - nExtraKnots ; ++i ) {
|
|
||||||
double dKnot = vV0[i] * SBZ_TREG_COEFF ;
|
double dKnot = vV0[i] * SBZ_TREG_COEFF ;
|
||||||
// lo aggiungo solo se è diverso dal precedente
|
// lo aggiungo solo se è diverso dal precedente
|
||||||
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
|
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL)
|
||||||
vU.push_back( dKnot) ;
|
vU.push_back( dKnot) ;
|
||||||
}
|
}
|
||||||
nSpanV = (int)vU.size() - 1 ;
|
nSpanV = ssize( vU) - 1 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// controllo se il vettore dei nodi è uniforme
|
// controllo se il vettore dei nodi è uniforme
|
||||||
@@ -577,76 +605,268 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
if ( b < (int)vU.size())
|
if ( b < (int)vU.size())
|
||||||
d1 = abs( vU[b] - vU[a]) ;
|
d1 = abs( vU[b] - vU[a]) ;
|
||||||
}
|
}
|
||||||
if ( b != (int)vU.size()) {
|
if ( b != (int)vU.size())
|
||||||
|
vbUniform[nDir] = false ;
|
||||||
|
}
|
||||||
|
// vettore delle curve di loop della regione di trim
|
||||||
|
ICRVCOMPOPOVECTOR vLoop ;
|
||||||
|
if ( ! vbUniform[0] || ! vbUniform[1]) {
|
||||||
|
for ( int c = 0 ; c < pSfr->GetChunkCount() ; ++c) {
|
||||||
|
for ( int l = 0 ; l < pSfr->GetLoopCount( c); ++l)
|
||||||
|
vLoop.emplace_back( ConvertCurveToComposite( pSfr->GetLoop( c, l))) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
for( int i = 0 ; i < ssize( vLoop); ++i){
|
||||||
|
vGeo.push_back(vLoop[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_loops.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
|
||||||
|
DBLVECTOR& vU = mKnots[nDir] ;
|
||||||
|
if ( ! vbUniform[nDir]) {
|
||||||
nDir == 0 ? bRescaledU = true : bRescaledV = true ;
|
nDir == 0 ? bRescaledU = true : bRescaledV = true ;
|
||||||
pRescaledSfr.Set( CreateSurfFlatRegion()) ;
|
// creo il vettore delle curve all'interno di una striscia
|
||||||
if ( IsNull( pRescaledSfr))
|
ICRVCOMPOPOVECTOR vCrvStrip ;
|
||||||
return false ;
|
for ( int p = 0 ; p < ssize(vU) - 1 ; ++p) {
|
||||||
for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) {
|
|
||||||
PtrOwner<ISurfFlatRegion> pSfr_copy( pSfr->Clone()) ;
|
|
||||||
if ( IsNull( pSfr_copy))
|
|
||||||
return false ;
|
|
||||||
double dLenStrip = abs( vU[p+1] - vU[p]) ;
|
double dLenStrip = abs( vU[p+1] - vU[p]) ;
|
||||||
if ( dLenStrip < EPS_SMALL)
|
if ( dLenStrip < EPS_SMALL)
|
||||||
continue ;
|
continue ;
|
||||||
// creo la maschera per tagliare la superficie originale e ottenere una striscia
|
// creo la maschera per tagliare la superficie originale e ottenere una striscia
|
||||||
PtrOwner<ISurfFlatRegion> pSfrTrim( CreateSurfFlatRegion()) ;
|
PtrOwner<ICurveComposite> pTrimMask ;
|
||||||
|
|
||||||
// ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale
|
// ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale
|
||||||
Vector3d vtTrim ;
|
|
||||||
if ( nDir == 0) {
|
if ( nDir == 0) {
|
||||||
pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenStrip, dScaleV + 2)) ;
|
Point3d ptStart( abs(vU[p] - vU.front()), - 1, 0) ;
|
||||||
vtTrim.Set( abs(vU[p] - vU.front()), - 1, 0) ;
|
pTrimMask.Set( GetRectangleCurve( ptStart, dLenStrip, dScaleV + 2)) ;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU + 2, dLenStrip)) ;
|
Point3d ptStart( - 1, abs(vU[p] - vU.front()), 0) ;
|
||||||
vtTrim.Set( - 1, abs(vU[p] - vU.front()), 0) ;
|
pTrimMask.Set( GetRectangleCurve( ptStart, dScaleU + 2, dLenStrip)) ;
|
||||||
}
|
}
|
||||||
pSfrTrim->Translate( vtTrim) ;
|
|
||||||
|
|
||||||
if ( ! pSfr_copy->Intersect( *pSfrTrim))
|
// qui potrei decidere di eliminare tutti i tratti dei loop paralleli alla direzione del parametro che sto analizzando ( e di valore coincidente a quello di un nodo)
|
||||||
return false ;
|
|
||||||
|
|
||||||
// aggiungo la nuova striscia solo se è valida
|
for ( int l = 0 ; l < ssize( vLoop); ++l) {
|
||||||
if ( pSfr_copy->IsValid() ) {
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
vGeo.push_back(pTrimMask->Clone()) ;
|
||||||
|
vGeo.push_back(vLoop[l]->Clone()) ;
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_inters.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
IntersCurveCurve icc( *vLoop[l], *pTrimMask) ;
|
||||||
|
int nInters = icc.GetIntersCount() ;
|
||||||
|
ICCIVECTOR vICCI ;
|
||||||
|
for ( int i = 0 ; i < nInters ; ++i) {
|
||||||
|
IntCrvCrvInfo icci ; icc.GetIntCrvCrvInfo( i, icci) ;
|
||||||
|
vICCI.push_back( std::move( icci)) ;
|
||||||
|
}
|
||||||
|
CRVCVECTOR vCrvClass, vMaskClass ;
|
||||||
|
icc.GetCurveClassification( 0, EPS_SMALL, vCrvClass) ;
|
||||||
|
icc.GetCurveClassification( 1, EPS_SMALL, vMaskClass) ;
|
||||||
|
// se dei pezzi di trim risultano esterni allo spazio parametrico tengo il bordo della maschera di trim
|
||||||
|
double dLastParam1 = 0 ;
|
||||||
|
double dStartA = 0, dEndA = 0 ; vLoop[l]->GetDomain( dStartA, dEndA) ;
|
||||||
|
double dEndB = 4 ;
|
||||||
|
for ( int i = 0 ; i < ssize( vCrvClass); ++i) {
|
||||||
|
if ( vCrvClass[i].nClass == CRVC_IN || vCrvClass[i].nClass == CRVC_ON_P) {
|
||||||
|
vCrvStrip.emplace_back( ConvertCurveToComposite( vLoop[l]->CopyParamRange( vCrvClass[i].dParS, vCrvClass[i].dParE))) ;
|
||||||
|
|
||||||
|
for ( int j = 0 ; j < ssize( vICCI) ; ++j) {
|
||||||
|
int k = vICCI[j].bOverlap ? 1 : 0 ;
|
||||||
|
if ( abs( vICCI[j].IciA[k].dU - vCrvClass[i].dParE) < EPS_PARAM) {
|
||||||
|
dLastParam1 = vICCI[j].IciB[k].dU ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( vCrvClass[i].nClass == CRVC_OUT && ( p == 0 || p == ssize(vU) - 2)){
|
||||||
|
double dMin, dMax ;
|
||||||
|
if ( p == 0) {
|
||||||
|
dMin = nDir == 0 ? 3 : 0 ;
|
||||||
|
dMax = nDir == 0 ? 4 : 1 ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dMin = nDir == 0 ? 1 : 2 ;
|
||||||
|
dMax = nDir == 0 ? 2 : 3 ;
|
||||||
|
}
|
||||||
|
// aggiungo la parte di curva di edge al posto della parte di curva che esce dal parametrico
|
||||||
|
// se non ho ancora aggiunto un tratto parto dal primo punto di intersezione
|
||||||
|
if ( ssize( vCrvStrip) == 0) {
|
||||||
|
double dPar0 = vCrvClass[i].dParS ;
|
||||||
|
for ( int j = 0 ; j < ssize( vICCI) ; ++j) {
|
||||||
|
int k = vICCI[j].bOverlap ? 1 : 0 ;
|
||||||
|
if ( abs(vICCI[j].IciA[k].dU - dPar0) < EPS_PARAM ||
|
||||||
|
( abs( dEndA - vICCI[j].IciA[k].dU - dPar0) < EPS_PARAM)) {
|
||||||
|
if ( abs( dEndB - vICCI[j].IciB[k].dU) < EPS_PARAM)
|
||||||
|
dLastParam1 = 0 ;
|
||||||
|
else
|
||||||
|
dLastParam1 = vICCI[j].IciB[k].dU ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int c = 0 ;
|
||||||
|
while ( c < ssize( vMaskClass) - 1 && abs( vMaskClass[c].dParS - dLastParam1) > EPS_PARAM)
|
||||||
|
++c ;
|
||||||
|
|
||||||
|
if ( vMaskClass[c].nClass == CRVC_IN && vMaskClass[c].dParS < dMax && vMaskClass[c].dParS >= dMin) {
|
||||||
|
vCrvStrip.emplace_back( ConvertCurveToComposite( pTrimMask->CopyParamRange( vMaskClass[c].dParS, vMaskClass[c].dParE))) ;
|
||||||
|
dLastParam1 = vMaskClass[c].dParE ;
|
||||||
|
// se sono alla fine curva verifico se devo aggiungere anche un pezzo di inizio
|
||||||
|
if ( dLastParam1 == dEndB && vMaskClass[0].nClass == CRVC_IN) {
|
||||||
|
c = 0 ;
|
||||||
|
vCrvStrip.emplace_back( ConvertCurveToComposite( pTrimMask->CopyParamRange( vMaskClass[c].dParS, vMaskClass[c].dParE))) ;
|
||||||
|
dLastParam1 = vMaskClass[c].dParE ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrvStrip); ++i){
|
||||||
|
vGeo.push_back(vCrvStrip[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_strip.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// riscalo le curve nella striscia
|
||||||
|
if ( ! vCrvStrip.empty()) {
|
||||||
|
double dCoeffX = 1, dCoeffY = 1 ;
|
||||||
|
|
||||||
if ( nDir == 0)
|
if ( nDir == 0)
|
||||||
pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
dCoeffX = SBZ_TREG_COEFF / dLenStrip ;
|
||||||
else
|
else
|
||||||
pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
dCoeffY = SBZ_TREG_COEFF / dLenStrip ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrvStrip); ++i) {
|
||||||
// prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
|
if( ! IsNull( vCrvStrip[i]))
|
||||||
|
vCrvStrip[i]->Scale( GLOB_FRM, dCoeffX, dCoeffY, 1) ;
|
||||||
Point3d pt ;
|
else
|
||||||
nDir == 0 ? pt.Set( abs(vU[p] - vU.front()), 0, 0) : pt.Set( 0,abs(vU[p] - vU.front()), 0) ;
|
|
||||||
if ( nDir == 0)
|
|
||||||
pt.Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
|
||||||
else
|
|
||||||
pt.Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
|
||||||
|
|
||||||
Vector3d vtJoin ;
|
|
||||||
if ( nDir == 0)
|
|
||||||
vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
|
|
||||||
else
|
|
||||||
vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ;
|
|
||||||
pSfr_copy->Translate( vtJoin) ;
|
|
||||||
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
|
|
||||||
if ( bRetry)
|
|
||||||
pSfr_copy->Offset( 10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // OFFSET
|
|
||||||
if ( pRescaledSfr->IsValid()) {
|
|
||||||
if ( ! pRescaledSfr->Add( *pSfr_copy))
|
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
pRescaledSfr.Set( pSfr_copy) ;
|
// prima di riunire le curve al resto devo traslarle sul bordo destro della superificie che sto ricostruendo (nDir == 0)
|
||||||
|
// oppure sul bordo superiore ( nDir == 1)
|
||||||
|
Point3d pt ;
|
||||||
|
Vector3d vtJoin ;
|
||||||
|
if ( nDir == 0) {
|
||||||
|
pt.Set( abs( vU[p] - vU.front()), 0, 0) ;
|
||||||
|
pt.Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
||||||
|
vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pt.Set( 0, abs(vU[p] - vU.front()), 0) ;
|
||||||
|
pt.Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
||||||
|
vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
for( int i = 0 ; i < ssize( vCrvStrip); ++i)
|
||||||
|
vCrvStrip[i]->Translate( vtJoin) ;
|
||||||
|
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrvStrip); ++i){
|
||||||
|
vGeo.push_back(vCrvStrip[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_strip.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// faccio la chain con le curve delle striscie precedenti
|
||||||
|
|
||||||
|
if ( ! vUniformedCurves.empty() || ! vCrvStrip.empty()) {
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
for( int i = 0 ; i < ssize( vUniformedCurves); ++i){
|
||||||
|
vGeo.push_back(vUniformedCurves[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_unif.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ChainCurves chainCrv ;
|
||||||
|
double dChainTol = 5 * EPS_SMALL ;
|
||||||
|
chainCrv.Init( false, dChainTol, max(ssize( vUniformedCurves), ssize(vCrvStrip))) ;
|
||||||
|
for ( int c = 0 ; c < ssize( vUniformedCurves) ; ++c) {
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
Vector3d vtStart, vtEnd ;
|
||||||
|
vUniformedCurves[c]->GetStartPoint( ptStart) ;
|
||||||
|
vUniformedCurves[c]->GetEndPoint( ptEnd) ;
|
||||||
|
vUniformedCurves[c]->GetStartDir( vtStart) ;
|
||||||
|
vUniformedCurves[c]->GetEndDir( vtEnd) ;
|
||||||
|
chainCrv.AddCurve( 1 + c, ptStart, vtStart, ptEnd, vtEnd) ;
|
||||||
|
}
|
||||||
|
for ( int c = 0 ; c < ssize( vCrvStrip); ++c) {
|
||||||
|
Point3d ptStart, ptEnd ;
|
||||||
|
Vector3d vtStart, vtEnd ;
|
||||||
|
vCrvStrip[c]->GetStartPoint( ptStart) ;
|
||||||
|
vCrvStrip[c]->GetEndPoint( ptEnd) ;
|
||||||
|
vCrvStrip[c]->GetStartDir( vtStart) ;
|
||||||
|
vCrvStrip[c]->GetEndDir( vtEnd) ;
|
||||||
|
chainCrv.AddCurve( 1 + ssize( vUniformedCurves) + c, ptStart, vtStart, ptEnd, vtEnd) ;
|
||||||
|
}
|
||||||
|
INTVECTOR vIds ;
|
||||||
|
ICRVCOMPOPOVECTOR vNewCrv ;
|
||||||
|
int nCrvPrec = ssize( vUniformedCurves) ;
|
||||||
|
while ( chainCrv.GetChainFromNear( ORIG, false, vIds)) {
|
||||||
|
// se ho una solo curva piccola allora la salto
|
||||||
|
if ( ssize(vIds) == 1) {
|
||||||
|
double dLen = 0 ;
|
||||||
|
int nId = vIds[0] - 1 ;
|
||||||
|
bool bSkip = false ;
|
||||||
|
if ( nId < nCrvPrec)
|
||||||
|
bSkip = vUniformedCurves[nId]->GetLength( dLen) && dLen < dChainTol ;
|
||||||
|
else
|
||||||
|
bSkip = vCrvStrip[nId - ssize(vUniformedCurves)]->GetLength(dLen) && dLen < dChainTol ;
|
||||||
|
|
||||||
|
if ( bSkip)
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
|
||||||
|
vNewCrv.emplace_back( CreateBasicCurveComposite()) ;
|
||||||
|
for ( int nId : vIds) {
|
||||||
|
nId -= 1 ;
|
||||||
|
if ( nId < nCrvPrec)
|
||||||
|
vNewCrv.back()->AddCurve( Release( vUniformedCurves[nId]), true, dChainTol) ;
|
||||||
|
else
|
||||||
|
vNewCrv.back()->AddCurve( Release( vCrvStrip[nId - ssize( vUniformedCurves)]), true, dChainTol) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vGeo.clear() ;
|
||||||
|
for( int i = 0 ; i < ssize( vNewCrv); ++i){
|
||||||
|
vGeo.push_back(vNewCrv[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\trim_crv_unif_AFTERchain.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// aggiorno le curve
|
||||||
|
vUniformedCurves.clear() ;
|
||||||
|
vUniformedCurves.swap( vNewCrv) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
vCrvStrip.clear() ;
|
||||||
}
|
}
|
||||||
if ( nDir == 0) {
|
if ( nDir == 0) {
|
||||||
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
||||||
if ( pRescaledSfr->IsValid()) {
|
if( ! vbUniform[1]) {
|
||||||
if ( bRetry)
|
vLoop.swap( vUniformedCurves) ;
|
||||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; //contro OFFSET
|
vUniformedCurves.clear() ;
|
||||||
delete pSfr ;
|
|
||||||
pSfr = Release( pRescaledSfr) ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -654,12 +874,38 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
if ( ! vUniformedCurves.empty()) {
|
||||||
if ( bRetry)
|
#if SAVEMKUNIF_CRVS
|
||||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
|
//debug
|
||||||
delete pSfr ;
|
vector<IGeoObj*> vGeo ;
|
||||||
pSfr = Release( pRescaledSfr) ;
|
for( int i = 0 ; i < ssize( vUniformedCurves); ++i){
|
||||||
|
vGeo.push_back(vUniformedCurves[i]->Clone()) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\bezier\\import3dm\\trim_error\\failed_trim_crv_unif.nge") ;
|
||||||
|
//debug
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// controllo che tutte le curve siano chiuse, sennò vuol dire che ho perso qualche pezzo durante le intersezioni
|
||||||
|
for ( int i = 0 ; i < ssize( vUniformedCurves); ++i) {
|
||||||
|
if ( ! vUniformedCurves[i]->IsClosed() && ! vUniformedCurves[i]->Close())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// creo una regione dalle curve riscalate
|
||||||
|
SurfFlatRegionByContours sfrRescaled ;
|
||||||
|
for ( int i = 0 ; i < ssize( vUniformedCurves); ++i)
|
||||||
|
sfrRescaled.AddCurve( Release( vUniformedCurves[i])) ;
|
||||||
|
|
||||||
|
PtrOwner<ISurfFlatRegion> pRescaledSfr( sfrRescaled.GetSurf()) ;
|
||||||
|
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
||||||
|
delete pSfr ;
|
||||||
|
pSfr = Release( pRescaledSfr) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
}
|
}
|
||||||
|
else if( ! vbUniform[0] || ! vbUniform[1])
|
||||||
|
return false ;
|
||||||
|
|
||||||
if ( ! bRescaledU && ! bRescaledV)
|
if ( ! bRescaledU && ! bRescaledV)
|
||||||
pSfr->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
|
pSfr->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
|
||||||
|
|||||||
+3026
-699
File diff suppressed because it is too large
Load Diff
+42
-46
@@ -20,19 +20,9 @@
|
|||||||
#include "SurfTriMesh.h"
|
#include "SurfTriMesh.h"
|
||||||
#include "SurfFlatRegion.h"
|
#include "SurfFlatRegion.h"
|
||||||
#include "/EgtDev/Include/EGkSurfBezier.h"
|
#include "/EgtDev/Include/EGkSurfBezier.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersLineTria.h"
|
||||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||||
|
|
||||||
using namespace std ;
|
|
||||||
class Tree ;
|
|
||||||
|
|
||||||
struct PairHashIntInt {
|
|
||||||
std::size_t operator()(const std::pair<int, int>& key) const {
|
|
||||||
std::size_t h1 = std::hash<int>{}(key.first);
|
|
||||||
std::size_t h2 = std::hash<int>{}(key.second);
|
|
||||||
return h1 ^ (h2 << 1); // Combine hashes
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class SurfBezier : public ISurfBezier, public IGeoObjRW
|
class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||||
{
|
{
|
||||||
@@ -77,16 +67,15 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
public : // ISurf
|
public : // ISurf
|
||||||
bool IsSimple( void) const override
|
bool IsSimple( void) const override
|
||||||
{ return true ; }
|
{ return true ; }
|
||||||
bool IsClosed( void) const override
|
bool IsClosed( void) const override ;
|
||||||
{ return false ; }
|
|
||||||
bool GetArea( double& dArea) const override ;
|
bool GetArea( double& dArea) const override ;
|
||||||
bool GetVolume( double& dVolume) const override
|
bool GetVolume( double& dVolume) const override
|
||||||
{ if ( &dVolume == nullptr)
|
{ if ( &dVolume == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
if( m_pSTM == nullptr)
|
if ( m_pSTM == nullptr)
|
||||||
GetAuxSurf() ;
|
GetAuxSurf() ;
|
||||||
dVolume = 0 ;
|
dVolume = 0 ;
|
||||||
if( m_pSTM != nullptr)
|
if ( m_pSTM != nullptr)
|
||||||
m_pSTM->GetVolume( dVolume) ;
|
m_pSTM->GetVolume( dVolume) ;
|
||||||
return true ; }
|
return true ; }
|
||||||
bool GetCentroid( Point3d& ptCen) const override ;
|
bool GetCentroid( Point3d& ptCen) const override ;
|
||||||
@@ -127,18 +116,17 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ;
|
||||||
const SurfTriMesh* GetAuxSurf( void) const override ;
|
const SurfTriMesh* GetAuxSurf( void) const override ;
|
||||||
const SurfTriMesh* GetAuxSurfRefined( void) const override ;
|
const SurfTriMesh* GetAuxSurfRefined( void) const override ;
|
||||||
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL) const override ;
|
SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 10 * EPS_SMALL, bool bUpdateEdges = false) const override ;
|
||||||
// funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione.
|
// 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 GetLeaves( std::vector<std::tuple<int, Point3d, Point3d>>& vLeaves, bool bRefined = false) const override ;
|
||||||
bool GetTriangles2D( std::vector<std::tuple<int,Point3d, Point3d, Point3d>>& vTria2D) 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
|
// 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
|
bool UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, int nIL = IntLineTriaType::ILTT_IN) const override ;
|
||||||
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 ;
|
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
|
// 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
|
// 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
|
// 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 ;
|
bool UnprojectPoint( const Point3d& pt3D, Point3d& ptParam, const Point3d& ptIPrev = P_INVALID, 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 ;
|
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).
|
// funzione per tagliare una superficie di bezier con un piano ( cancello la parte dal lato positivo della normale del piano).
|
||||||
@@ -148,16 +136,26 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
|
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 ;
|
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
|
// 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
|
// restituisce un vettore con i loop della superficie ( più di uno solo se è trimmata con un parametrico con buchi o più di un chunk)
|
||||||
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 GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier) const override ;
|
||||||
|
// restituisce il singolo edge della superficie non trimmata
|
||||||
|
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const override ;
|
||||||
bool IsPlanar( void) const override ;
|
bool IsPlanar( void) const override ;
|
||||||
bool CreateByFlatContour( const PolyLine& PL) override ;
|
bool CreateByFlatContour( const PolyLine& PL) override ;
|
||||||
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
bool CreateByRegion( const POLYLINEVECTOR& vPL) override ;
|
||||||
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr, bool bDeg3OrDeg2 = false) override ;
|
bool CreateByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr) override ;
|
||||||
bool CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector3d& vtAx, double dAngRotDeg, double dMove) 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 CreateByPointCurve( const Point3d& pt, const ICurve* pCurve) override ;
|
||||||
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
bool CreateByTwoCurves( const ICurve* pCurve1, const ICurve* pCurve2, int nType) override ;
|
||||||
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
bool CreateBySetOfCurves( const ICURVEPOVECTOR& vCrvBez, bool bReduceToDeg3) override ;
|
||||||
|
PNTVECTOR GetAllControlPoints( void) const override ;
|
||||||
|
bool GetAllPatchesIsocurves( bool bUorV, ICURVEPOVECTOR& vCrv) const ;
|
||||||
|
bool CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, const BIPNTVECTOR& vCrv) ;
|
||||||
|
bool RemoveCollapsedSpans( void) override ;
|
||||||
|
bool SwapParameters( void) ;
|
||||||
|
bool LimitSurfToTrimmedRegion( void) override ;
|
||||||
|
bool CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen) override ;
|
||||||
|
bool CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen, BIPNTVECTOR& vSyncLines) override ;
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -169,7 +167,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
|
|
||||||
public :
|
public :
|
||||||
SurfBezier( void) ;
|
SurfBezier( void) ;
|
||||||
SurfBezier( const SurfBezier& sbSrc)
|
SurfBezier( const SurfBezier& sbSrc) : m_pSTM( nullptr), m_pSTMRefined( nullptr), m_pTrimReg(nullptr)
|
||||||
{ if ( ! CopyFrom( sbSrc))
|
{ if ( ! CopyFrom( sbSrc))
|
||||||
LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") }
|
LOG_ERROR( GetEGkLogger(), "SurfBezier : copy constructor error") }
|
||||||
SurfBezier& operator =( const SurfBezier& sbSrc)
|
SurfBezier& operator =( const SurfBezier& sbSrc)
|
||||||
@@ -211,8 +209,6 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
// funzione che proietta nello spazio parametrico un trim derivante da un taglio con un piano, categorizzandolo come aperto o chiuso ( nel parametrico)
|
// 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 ;
|
bool AddCurveCompoToCuts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed, double dToler = EPS_SMALL, const Plane3d* pPlCut = nullptr) const ;
|
||||||
ISurfFlatRegion* CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed) const ;
|
ISurfFlatRegion* CreateTrimRegionFromCuts( ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed) const ;
|
||||||
// restituisce il singolo edge della superficie non trimmata
|
|
||||||
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
|
|
||||||
// funzione che calcola se gli edge sono collassati in poli
|
// funzione che calcola se gli edge sono collassati in poli
|
||||||
bool CalcPoles( void) const ;
|
bool CalcPoles( void) const ;
|
||||||
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
|
bool FindMatchByParam( const PolyLine& pl0, const PolyLine& pl1, INTVECTOR& vMatch, int& nLong) const ;
|
||||||
@@ -221,27 +217,27 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
bool GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const ;
|
bool GetBernstein( double dU, int nDegU, DBLVECTOR& vBernU) const ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria per la visualizzazione
|
mutable SurfTriMesh* m_pSTM ; // superficie trimesh ausiliaria per la visualizzazione
|
||||||
mutable SurfTriMesh* m_pSTMRefined ; // superficie trimesh ausiliaria raffinata per i calcoli
|
mutable SurfTriMesh* m_pSTMRefined ; // superficie trimesh ausiliaria raffinata per i calcoli
|
||||||
Status m_nStatus ; // stato
|
Status m_nStatus ; // stato
|
||||||
int m_nDegU ; // grado in U
|
int m_nDegU ; // grado in U
|
||||||
int m_nDegV ; // grado in V
|
int m_nDegV ; // grado in V
|
||||||
int m_nSpanU ; // numero di pezze in U
|
int m_nSpanU ; // numero di pezze in U
|
||||||
int m_nSpanV ; // numero di pezze in V
|
int m_nSpanV ; // numero di pezze in V
|
||||||
bool m_bRat ; // flag di razionale/polinomiale
|
bool m_bRat ; // flag di razionale/polinomiale
|
||||||
bool m_bTrimmed ; // flag per presenza regione di trim
|
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_bClosedU ; // flag che indica se la superficie è chiusa lungo il parametro U ( gli edge a V=0 e V=1 coincidono)
|
||||||
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V
|
mutable bool m_bClosedV ; // flag che indica se la superficie è chiusa lungo il parametro V ( gli edge a U=0 e U=1 coincidono)
|
||||||
mutable BOOLVECTOR m_vbPole ; // vettore di flag che indicano se i lati sono collassati in dei poli
|
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
|
PNTVECTOR m_vPtCtrl ; // vettore dei punti di controllo
|
||||||
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
DBLVECTOR m_vWeCtrl ; // vettore dei pesi di controllo
|
||||||
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
|
||||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
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 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 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 int m_nIsPlanar ; // enum che indica se la superficie è piana ( -1, non è stato calcolato)
|
||||||
mutable DBLVECTOR m_vBernU ;
|
mutable DBLVECTOR m_vBernU ;
|
||||||
mutable PNTVECTOR m_ptTemp ;
|
mutable PNTVECTOR m_ptTemp ;
|
||||||
mutable DBLVECTOR m_vBernV ;
|
mutable DBLVECTOR m_vBernV ;
|
||||||
|
|||||||
+190
-36
@@ -28,6 +28,13 @@
|
|||||||
#include "/EgtDev/Include/EGkIntervals.h"
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
|
#define SAVECLASSCRV 0
|
||||||
|
#define SAVEADJUSTCRV 0
|
||||||
|
#if SAVECLASSCRV || SAVEADJUSTCRV
|
||||||
|
std::vector<IGeoObj*> vGeo ;
|
||||||
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -56,6 +63,7 @@ SurfFlatRegion::Clear( void)
|
|||||||
for ( auto& pLoop : m_vpLoop)
|
for ( auto& pLoop : m_vpLoop)
|
||||||
delete pLoop ;
|
delete pLoop ;
|
||||||
m_vpLoop.clear() ;
|
m_vpLoop.clear() ;
|
||||||
|
m_vExtInd.clear() ;
|
||||||
|
|
||||||
m_nTempProp[0] = 0 ;
|
m_nTempProp[0] = 0 ;
|
||||||
m_nTempProp[1] = 0 ;
|
m_nTempProp[1] = 0 ;
|
||||||
@@ -106,8 +114,20 @@ SurfFlatRegion::AddExtLoop( ICurve* pCrv)
|
|||||||
pMyCrv->SetThickness( 0) ;
|
pMyCrv->SetThickness( 0) ;
|
||||||
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
// rimuovo eventuali sovrapposizioni (calcolate nel suo piano)
|
||||||
ICURVEPLIST CrvLst ;
|
ICURVEPLIST CrvLst ;
|
||||||
|
|
||||||
|
#if SAVEADJUSTCRV
|
||||||
|
SaveGeoObj( pMyCrv->Clone(), "D:\\Temp\\inters\\CrvCrvInters\\before_adjust.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
if ( ! AdjustLoops( Release( pMyCrv), CrvLst, true))
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
#if SAVEADJUSTCRV
|
||||||
|
for ( auto& pSingCrv : CrvLst)
|
||||||
|
vGeo.push_back( pSingCrv->Clone()) ;
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\inters\\CrvCrvInters\\after_adjust.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
// aggiungo le singole curve
|
// aggiungo le singole curve
|
||||||
int nExtAdded = 0 ;
|
int nExtAdded = 0 ;
|
||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
@@ -168,14 +188,18 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
|||||||
Vector3d vtExtr ;
|
Vector3d vtExtr ;
|
||||||
if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
|
if ( pMyCrv->GetExtrusion( vtExtr) && ! vtExtr.IsSmall())
|
||||||
pMyCrv->SetExtrusion( Z_AX) ;
|
pMyCrv->SetExtrusion( Z_AX) ;
|
||||||
// verifico non abbia auto-intersezioni che si attraversano o si sovrappongano
|
|
||||||
SelfIntersCurve sInt( *pMyCrv) ;
|
|
||||||
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
|
|
||||||
return false ;
|
|
||||||
// verifico che sia esterna alle curve esterne degli altri chunk
|
// verifico che sia esterna alle curve esterne degli altri chunk
|
||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
CRVCVECTOR ccClass ;
|
CRVCVECTOR ccClass ;
|
||||||
for ( auto i : m_vExtInd) {
|
for ( auto i : m_vExtInd) {
|
||||||
|
#if SAVEADJUSTCRV
|
||||||
|
vGeo.clear() ;
|
||||||
|
vGeo.push_back( pMyCrv->Clone()) ;
|
||||||
|
vGeo.push_back( m_vpLoop[i]->Clone()) ;
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\inters\\CrvCrvInters\\during_add_simpleExt.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ;
|
||||||
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
if ( ccInt.GetCrossOrOverlapIntersCount() > 0 ||
|
||||||
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) ||
|
||||||
@@ -215,14 +239,9 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv, bool& bAdded)
|
|||||||
bool
|
bool
|
||||||
SurfFlatRegion::MyAddExtLoop( ICurve* pCrv)
|
SurfFlatRegion::MyAddExtLoop( ICurve* pCrv)
|
||||||
{
|
{
|
||||||
try {
|
m_vpLoop.push_back( pCrv) ;
|
||||||
m_vpLoop.push_back( pCrv) ;
|
m_vExtInd.push_back( int( m_vpLoop.size()) - 1) ;
|
||||||
m_vExtInd.push_back( int( m_vpLoop.size()) - 1) ;
|
m_nStatus = OK ;
|
||||||
m_nStatus = OK ;
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -303,10 +322,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
|||||||
// sistemo il senso di rotazione (deve essere CW -> se N==Z+ area < 0, se N==Z- area > 0)
|
// sistemo il senso di rotazione (deve essere CW -> se N==Z+ area < 0, se N==Z- area > 0)
|
||||||
if ( ( plPlane.GetVersN().z > 0 && dArea > 0) || ( plPlane.GetVersN().z < 0 && dArea < 0))
|
if ( ( plPlane.GetVersN().z > 0 && dArea > 0) || ( plPlane.GetVersN().z < 0 && dArea < 0))
|
||||||
pMyCrv->Invert() ;
|
pMyCrv->Invert() ;
|
||||||
// verifico non abbia auto-intersezioni
|
|
||||||
SelfIntersCurve sInt( *pMyCrv) ;
|
|
||||||
if ( sInt.GetCrossOrOverlapIntersCount() > 0)
|
|
||||||
return false ;
|
|
||||||
// ricerca del chunk in cui andrebbe inserito
|
// ricerca del chunk in cui andrebbe inserito
|
||||||
int nChunk = -1 ;
|
int nChunk = -1 ;
|
||||||
for ( int i = 0 ; i < int( m_vExtInd.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( m_vExtInd.size()) ; ++ i) {
|
||||||
@@ -353,23 +369,18 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv)
|
|||||||
bool
|
bool
|
||||||
SurfFlatRegion::MyAddIntLoop( ICurve* pCrv, int nChunk)
|
SurfFlatRegion::MyAddIntLoop( ICurve* pCrv, int nChunk)
|
||||||
{
|
{
|
||||||
try {
|
//se da aggiungere all'ultimo chunk
|
||||||
// se da aggiungere all'ultimo chunk
|
if ( nChunk == -1)
|
||||||
if ( nChunk == -1)
|
m_vpLoop.push_back( pCrv) ;
|
||||||
m_vpLoop.push_back( pCrv) ;
|
//altrimenti aggiungo al chunck indicato
|
||||||
// altrimenti aggiungo al chunck indicato
|
else {
|
||||||
else {
|
int nLoopCnt = GetLoopCount( nChunk) ;
|
||||||
int nLoopCnt = GetLoopCount( nChunk) ;
|
if ( nLoopCnt == 0)
|
||||||
if ( nLoopCnt == 0)
|
return false ;
|
||||||
return false ;
|
int nOffset = m_vExtInd[nChunk] + nLoopCnt ;
|
||||||
int nOffset = m_vExtInd[nChunk] + nLoopCnt ;
|
m_vpLoop.insert( m_vpLoop.begin() + nOffset, pCrv) ;
|
||||||
m_vpLoop.insert( m_vpLoop.begin() + nOffset, pCrv) ;
|
for ( int i = nChunk + 1 ; i < int( m_vExtInd.size()) ; ++ i)
|
||||||
for ( int i = nChunk + 1 ; i < int( m_vExtInd.size()) ; ++ i)
|
++ m_vExtInd[i] ;
|
||||||
++ m_vExtInd[i] ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
return false ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -827,7 +838,7 @@ SurfFlatRegion::ConvertArcsToBezierCurves( void)
|
|||||||
// ciclo sui loop
|
// ciclo sui loop
|
||||||
for ( auto& pLoop : m_vpLoop) {
|
for ( auto& pLoop : m_vpLoop) {
|
||||||
if ( pLoop->GetType() == CRV_ARC) {
|
if ( pLoop->GetType() == CRV_ARC) {
|
||||||
ICurve* pCrvNew = ArcToBezierCurve( pLoop) ;
|
ICurve* pCrvNew = ArcToBezierCurve( GetCurveArc(pLoop)) ;
|
||||||
if ( pCrvNew == nullptr)
|
if ( pCrvNew == nullptr)
|
||||||
return false ;
|
return false ;
|
||||||
delete pLoop ;
|
delete pLoop ;
|
||||||
@@ -1373,6 +1384,15 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRV
|
|||||||
for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) {
|
for ( int nLoop = 0 ; nLoop < GetLoopCount( nChunk) ; ++ nLoop) {
|
||||||
const ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
const ICurve* pLoop = GetMyLoop( nChunk, nLoop) ;
|
||||||
// intersezione
|
// intersezione
|
||||||
|
|
||||||
|
#if SAVECLASSCRV
|
||||||
|
//debug
|
||||||
|
vector<IGeoObj*> vGeo ;
|
||||||
|
vGeo.push_back( Crv.Clone()) ;
|
||||||
|
vGeo.push_back( pLoop->Clone()) ;
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\inters\\CrvCrvInters\\crv_and_loop.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
IntersCurveCurve ccInt( Crv, *pLoop) ;
|
IntersCurveCurve ccInt( Crv, *pLoop) ;
|
||||||
// classificazione
|
// classificazione
|
||||||
CRVCVECTOR ccPart ;
|
CRVCVECTOR ccPart ;
|
||||||
@@ -1536,7 +1556,7 @@ SurfFlatRegion::GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion&
|
|||||||
// classifico il loop esterno del chunk della prima regione rispetto a quello del chunk della seconda
|
// classifico il loop esterno del chunk della prima regione rispetto a quello del chunk della seconda
|
||||||
IntersCurveCurve ccInt( *pCrv1Loc, *pCrv2Loc) ;
|
IntersCurveCurve ccInt( *pCrv1Loc, *pCrv2Loc) ;
|
||||||
int nClass = ccInt.GetRegionCurveClassification() ;
|
int nClass = ccInt.GetRegionCurveClassification() ;
|
||||||
switch ( nClass){
|
switch ( nClass) {
|
||||||
default : // CCREGC_NULL
|
default : // CCREGC_NULL
|
||||||
return REGC_NULL ;
|
return REGC_NULL ;
|
||||||
case CCREGC_IN1 :
|
case CCREGC_IN1 :
|
||||||
@@ -1549,7 +1569,141 @@ SurfFlatRegion::GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion&
|
|||||||
return REGC_OUT ;
|
return REGC_OUT ;
|
||||||
case CCREGC_INTERS :
|
case CCREGC_INTERS :
|
||||||
return REGC_INTERS ;
|
return REGC_INTERS ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfFlatRegion::CheckChunkInterference( int nChunk, const ISurfFlatRegion& Other, int nOthChunk, bool& bInterference) const
|
||||||
|
{
|
||||||
|
bInterference = false ;
|
||||||
|
// verifico lo stato e il numero di chunk
|
||||||
|
if ( m_nStatus != OK || m_vpLoop.empty() || nChunk >= GetChunkCount())
|
||||||
|
return false ;
|
||||||
|
// recupero rappresentazione base dell'altra regione
|
||||||
|
const SurfFlatRegion& Reg2 = *GetBasicSurfFlatRegion( &Other) ;
|
||||||
|
// verifico lo stato e il numero di chunk dell'altra regione
|
||||||
|
if ( Reg2.m_nStatus != OK || Reg2.m_vpLoop.empty() || nOthChunk >= Reg2.GetChunkCount())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico che le due regioni giacciano in piani paralleli
|
||||||
|
if ( ! AreSameVectorApprox( m_frF.VersZ(), Reg2.m_frF.VersZ()))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// classifico il loop esterno del chunk della prima regione rispetto a quello del chunk della seconda
|
||||||
|
int nClass = GetChunkSimpleClassification( nChunk, Other, nOthChunk) ;
|
||||||
|
if ( nClass == REGC_NULL)
|
||||||
|
return false ;
|
||||||
|
// se le regioni non hanno isole, allora ho già identificato se i Chunks fanno interferenza
|
||||||
|
int nLoopCnt = GetLoopCount( nChunk) ;
|
||||||
|
int nOtherLoopCnt = Other.GetLoopCount( nOthChunk) ;
|
||||||
|
if ( nLoopCnt == 1 && nOtherLoopCnt == 1) {
|
||||||
|
bInterference = ( nClass != REGC_OUT) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- a prescindere dalle isole presenti nei 2 Chunks in esame :
|
||||||
|
// se i due loop esterni si intersecano tra loro o sono gli stessi, allora fanno per forza interferenza
|
||||||
|
if ( nClass == REGC_INTERS || nClass == CCREGC_SAME) {
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// se invece sono esterni tra loro, allora non c'è interferenza
|
||||||
|
else if ( nClass == REGC_OUT)
|
||||||
|
return true ;
|
||||||
|
// --- Analisi del loop interni :
|
||||||
|
// se la curva esterna corrente è interna alla curva esterna dell'altro chunk
|
||||||
|
else if ( nClass == REGC_IN1) {
|
||||||
|
// se l'altro chunk non ha isole, c'è interferenza (a prescinere da numero di loop interni del primo chunk)
|
||||||
|
if ( nOtherLoopCnt == 1) {
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
||||||
|
const ICurve* pCrv1Loc = GetMyLoop( nChunk, 0) ;
|
||||||
|
// per ogni loop interno (isole)
|
||||||
|
for ( int i = 1 ; i < nOtherLoopCnt ; ++ i) {
|
||||||
|
const ICurve* pCrv2Loc = nullptr ;
|
||||||
|
PtrOwner<ICurve> pCopyCrv ;
|
||||||
|
if ( AreSameFrame( m_frF, Reg2.m_frF))
|
||||||
|
pCrv2Loc = Reg2.GetMyLoop( nOthChunk, i) ;
|
||||||
|
else {
|
||||||
|
pCopyCrv.Set( Reg2.GetMyLoop( nOthChunk, i)->Clone()) ;
|
||||||
|
if ( IsNull( pCopyCrv))
|
||||||
|
return false ;
|
||||||
|
pCopyCrv->LocToLoc( Reg2.m_frF, m_frF) ;
|
||||||
|
pCrv2Loc = pCopyCrv ;
|
||||||
|
}
|
||||||
|
// classifico il loop esterno del chunk della prima regione rispetto all'interno corrente del chunk della seconda
|
||||||
|
IntersCurveCurve ccInt( *pCrv1Loc, *pCrv2Loc) ;
|
||||||
|
int nInternalClass = ccInt.GetRegionCurveClassification() ;
|
||||||
|
// se le curve non sono classificabili, errore
|
||||||
|
if ( nInternalClass == REGC_NULL)
|
||||||
|
return false ;
|
||||||
|
// se la curva di bordo corrente è interna (le isole girano al contrario) all'isola corrente
|
||||||
|
else if ( nInternalClass == REGC_IN1)
|
||||||
|
; // non faccio nulla, potrebbe non essere l'isola adatta per la classificazione
|
||||||
|
// se la curva di bordo corrente è esterna (le isole girano al contrario) all'isola corrente, allora non ho interferenza
|
||||||
|
else if ( nInternalClass == REGC_OUT)
|
||||||
|
return true ;
|
||||||
|
// se la curva di bordo corrente interseca l'isola o coincide con essa allora c'è interferenza
|
||||||
|
else if ( nInternalClass == REGC_INTERS || nInternalClass == REGC_SAME) {
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// negli altri casi ho un orientamento errato dei loop o delle regioni
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se la curva esterna dell'altro chunk è interna alla curva esterna corrente
|
||||||
|
else if ( nClass == REGC_IN2) {
|
||||||
|
// se l'altro chunk non ha isole, c'è interferenza
|
||||||
|
if ( nLoopCnt == 1) {
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// curva esterna del chunk della prima regione (ovviamente già in locale al riferimento intrinseco)
|
||||||
|
const ICurve* pCrv2Loc = Reg2.GetMyLoop( nChunk, 0) ;
|
||||||
|
// per ogni loop interno (isole)
|
||||||
|
for ( int i = 1 ; i < nLoopCnt ; ++ i) {
|
||||||
|
const ICurve* pCrv1Loc = nullptr ;
|
||||||
|
PtrOwner<ICurve> pCopyCrv ;
|
||||||
|
if ( AreSameFrame( Reg2.m_frF, m_frF))
|
||||||
|
pCrv1Loc = GetMyLoop( nOthChunk, i) ;
|
||||||
|
else {
|
||||||
|
pCopyCrv.Set( GetMyLoop( nOthChunk, i)->Clone()) ;
|
||||||
|
if ( IsNull( pCopyCrv))
|
||||||
|
return false ;
|
||||||
|
pCopyCrv->LocToLoc( m_frF, Reg2.m_frF) ;
|
||||||
|
pCrv1Loc = pCopyCrv ;
|
||||||
|
}
|
||||||
|
// classifico il loop esterno del chunk della prima regione rispetto a quello del chunk della seconda
|
||||||
|
IntersCurveCurve ccInt( *pCrv2Loc, *pCrv1Loc) ;
|
||||||
|
int nInternalClass = ccInt.GetRegionCurveClassification() ;
|
||||||
|
// se le curve non sono classificabili, errore
|
||||||
|
if ( nInternalClass == REGC_NULL)
|
||||||
|
return false ;
|
||||||
|
// se la curva di bordo corrente è interna (le isole girano al contrario) all'isola corrente
|
||||||
|
else if ( nInternalClass == REGC_IN1)
|
||||||
|
; // non faccio nulla, potrebbe non essere l'isola adatta per la classificazione
|
||||||
|
// se la curva di bordo corrente è esterna (le isole girano al contrario) all'isola corrente, allora non ho interferenza
|
||||||
|
else if ( nInternalClass == REGC_OUT)
|
||||||
|
return true ;
|
||||||
|
// se la curva di bordo corrente interseca l'isola o coincide con essa allora c'è interferenza
|
||||||
|
else if ( nInternalClass == REGC_INTERS || nInternalClass == REGC_SAME) {
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// negli altri casi ho un orientamento errato dei loop o delle regioni
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// in questo la curva di bordo è interna ad ogni isola ma interna anche al loop esterno, quindi esiste interferenza
|
||||||
|
bInterference = true ;
|
||||||
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
bool GetChunkArea( int nChunk, double& dArea) const override ;
|
bool GetChunkArea( int nChunk, double& dArea) const override ;
|
||||||
bool GetChunkPerimeter( int nChunk, double& dLen) const override ;
|
bool GetChunkPerimeter( int nChunk, double& dLen) const override ;
|
||||||
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides
|
||||||
|
bool CheckChunkInterference( int nChunk, const ISurfFlatRegion& Other, int nOthChunk, bool& bInterference) const override ; // compare alls
|
||||||
bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ;
|
bool GetChunkMaxOffset( int nChunk, double& dOffs) const override ;
|
||||||
int GetLoopCount( int nChunk) const override ;
|
int GetLoopCount( int nChunk) const override ;
|
||||||
int GetLoopCurveCount( int nChunk, int nLoop) const override ;
|
int GetLoopCurveCount( int nChunk, int nLoop) const override ;
|
||||||
@@ -139,6 +140,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW
|
|||||||
SurfTriMesh* CalcAuxSurf( double dLinTol, double dAngTolDeg) const ;
|
SurfTriMesh* CalcAuxSurf( double dLinTol, double dAngTolDeg) const ;
|
||||||
|
|
||||||
friend class MyCAvSimpleSurfFrMove ;
|
friend class MyCAvSimpleSurfFrMove ;
|
||||||
|
friend class MyCAvSurfFrMove ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
||||||
|
|||||||
@@ -20,6 +20,12 @@
|
|||||||
#include "/EgtDev/Include/EGkIntervals.h"
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
#include "/EgtDev/Include/EgtPointerOwner.h"
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
||||||
|
|
||||||
|
#define SAVELOOPS 0
|
||||||
|
#if SAVELOOPS
|
||||||
|
std::vector<IGeoObj*> vGeo ;
|
||||||
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -172,6 +178,13 @@ SurfFlatRegion::Subtract( const ISurfFlatRegion& Other)
|
|||||||
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
pSfr.Set( new( nothrow) SurfFlatRegion) ;
|
||||||
else
|
else
|
||||||
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
pSfr.Set( MyNewSurfFromLoops( vpLoop)) ;
|
||||||
|
|
||||||
|
#if SAVELOOPS
|
||||||
|
for (int i = 0 ; i < ssize( vpLoop) ; ++i)
|
||||||
|
vGeo.push_back( vpLoop[i]) ;
|
||||||
|
SaveGeoObj( vGeo, "D:\\Temp\\inters\\CrvCrvInters\\NewLoops.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
if ( IsNull( pSfr)) {
|
if ( IsNull( pSfr)) {
|
||||||
MyTestAndDelete( vpCurve) ;
|
MyTestAndDelete( vpCurve) ;
|
||||||
MyTestAndDelete( vpLoop) ;
|
MyTestAndDelete( vpLoop) ;
|
||||||
|
|||||||
+346
-56
@@ -234,9 +234,13 @@ SurfTriMesh::AddTriangle( const int nIdVert[3], int nTFlag)
|
|||||||
m_vPart.clear() ;
|
m_vPart.clear() ;
|
||||||
m_OGrMgr.Reset() ;
|
m_OGrMgr.Reset() ;
|
||||||
ResetHashGrids3d() ;
|
ResetHashGrids3d() ;
|
||||||
|
if ( ! vtN.Normalize( EPS_ZERO))
|
||||||
|
return SVT_DEL ;
|
||||||
// inserisco il triangolo
|
// inserisco il triangolo
|
||||||
try { m_vTria.emplace_back( nIdVert, nTFlag) ;}
|
try { m_vTria.emplace_back( nIdVert, nTFlag) ;}
|
||||||
catch(...) { return SVT_NULL ;}
|
catch(...) { return SVT_NULL ;}
|
||||||
|
// aggiorno la sua normale
|
||||||
|
m_vTria.back().vtN = vtN ;
|
||||||
// aggiorno massimo TFlag
|
// aggiorno massimo TFlag
|
||||||
m_nMaxTFlag = max( m_nMaxTFlag, nTFlag) ;
|
m_nMaxTFlag = max( m_nMaxTFlag, nTFlag) ;
|
||||||
// ne determino l'indice
|
// ne determino l'indice
|
||||||
@@ -513,9 +517,9 @@ SurfTriMesh::GetVertexParam( int nId, double& dU, double& dV) const
|
|||||||
// verifico esistenza del vertice
|
// verifico esistenza del vertice
|
||||||
if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL)
|
if ( nId < 0 || nId >= GetVertexSize() || m_vVert[nId].nIdTria == SVT_DEL)
|
||||||
return false ;
|
return false ;
|
||||||
// recupero i dati
|
// recupero i dati (verso l'esterno sempre in 0..1..2..3..)
|
||||||
dU = m_vVert[nId].dU ;
|
dU = m_vVert[nId].dU / PREC_SCALE_COEFF ;
|
||||||
dV = m_vVert[nId].dV ;
|
dV = m_vVert[nId].dV / PREC_SCALE_COEFF ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -866,15 +870,21 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
|
|||||||
if ( nPos == -1)
|
if ( nPos == -1)
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// medio le normali, finch� non incontro degli spigoli
|
// medio le normali, finchè non incontro degli spigoli
|
||||||
vtN = m_vTria[nT].vtN ;
|
double dAngW = 1 ;
|
||||||
|
GetTriangleVertexAngle( nT, nV, dAngW) ;
|
||||||
|
vtN = dAngW * m_vTria[nT].vtN ;
|
||||||
// parto dal triangolo e vado in direzione positiva
|
// parto dal triangolo e vado in direzione positiva
|
||||||
int nLim = nPos ;
|
int nLim = nPos ;
|
||||||
for ( int i = NextIndAroundVertex( nPos, nTria, bCirc) ;
|
for ( int i = NextIndAroundVertex( nPos, nTria, bCirc) ;
|
||||||
i != nPos && i < int( vT.size()) ;
|
i != nPos && i < int( vT.size()) ;
|
||||||
i = NextIndAroundVertex( i, nTria, bCirc)) {
|
i = NextIndAroundVertex( i, nTria, bCirc)) {
|
||||||
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
|
if ( m_vTria[nT].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng) {
|
||||||
vtN += m_vTria[vT[i]].vtN ;
|
int nK ; double dAngW = 1 ;
|
||||||
|
if ( FindVertexInTria( m_vTria[nT].nIdVert[nV], vT[i], nK) &&
|
||||||
|
GetTriangleVertexAngle( vT[i], nK, dAngW))
|
||||||
|
vtN += dAngW * m_vTria[vT[i]].vtN ;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break ;
|
break ;
|
||||||
nLim = i ;
|
nLim = i ;
|
||||||
@@ -883,8 +893,12 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
|
|||||||
for ( int i = PrevIndAroundVertex( nPos, nTria, bCirc) ;
|
for ( int i = PrevIndAroundVertex( nPos, nTria, bCirc) ;
|
||||||
i != nLim && i >= 0 ;
|
i != nLim && i >= 0 ;
|
||||||
i = PrevIndAroundVertex( i, nTria, bCirc)) {
|
i = PrevIndAroundVertex( i, nTria, bCirc)) {
|
||||||
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
|
if ( m_vTria[nT].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng) {
|
||||||
vtN += m_vTria[vT[i]].vtN ;
|
int nK ; double dAngW = 1 ;
|
||||||
|
if ( FindVertexInTria( m_vTria[nT].nIdVert[nV], vT[i], nK) &&
|
||||||
|
GetTriangleVertexAngle( vT[i], nK, dAngW))
|
||||||
|
vtN += dAngW * m_vTria[vT[i]].vtN ;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -893,6 +907,23 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetTriangleVertexAngle( int nT, int nV, double& dAng) const
|
||||||
|
{
|
||||||
|
// verifico esistenza del triangolo e validità vertice
|
||||||
|
if ( nT < 0 || nT >= GetTriangleSize() || m_vTria[nT].nIdVert[0] == SVT_DEL || nV < 0 || nV > 2)
|
||||||
|
return false ;
|
||||||
|
// determino i vettori dei due lati che partono dal vertice
|
||||||
|
Point3d ptVert = m_vVert[ m_vTria[nT].nIdVert[nV]].ptP ;
|
||||||
|
Point3d ptPrev = m_vVert[ m_vTria[nT].nIdVert[Prev( nV)]].ptP ;
|
||||||
|
Point3d ptNext = m_vVert[ m_vTria[nT].nIdVert[Next( nV)]].ptP ;
|
||||||
|
Vector3d vtPrev = ptPrev - ptVert ;
|
||||||
|
Vector3d vtNext = ptNext - ptVert ;
|
||||||
|
// determino l'angolo tra i due lati
|
||||||
|
return vtPrev.GetAngle( vtNext, dAng) ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
SurfTriMesh*
|
SurfTriMesh*
|
||||||
SurfTriMesh::CloneTriangle( int nT) const
|
SurfTriMesh::CloneTriangle( int nT) const
|
||||||
@@ -1157,8 +1188,10 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
|||||||
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||||
if ( IsNull( pSfr))
|
if ( IsNull( pSfr))
|
||||||
pSfr.Set( pSfrTria) ;
|
pSfr.Set( pSfrTria) ;
|
||||||
else
|
else {
|
||||||
pSfr->Add( *pSfrTria) ;
|
if ( ! pSfr->Add( *pSfrTria))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// passo al successivo
|
// passo al successivo
|
||||||
@@ -1170,14 +1203,18 @@ SurfTriMesh::GetSilhouette( const Vector3d& vtDir, double dTol, POLYLINEVECTOR&
|
|||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// Effettuo contro-offset
|
// Effettuo contro-offset
|
||||||
pSfr->Offset( -dTol, ICurve::OFF_EXTEND) ;
|
if ( ! pSfr->Offset( -dTol, ICurve::OFF_EXTEND))
|
||||||
|
return false ;
|
||||||
|
|
||||||
// Recupero i contorni della regione
|
// Recupero i contorni della regione
|
||||||
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
||||||
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
if ( pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
if ( ! pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) {
|
||||||
vPL.emplace_back( PL) ;
|
vPL.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
vPL.emplace_back( PL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1220,16 +1257,19 @@ SurfTriMesh::GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR&
|
|||||||
// se rimasto qualcosa
|
// se rimasto qualcosa
|
||||||
if ( pgTria.GetSideCount() > 0) {
|
if ( pgTria.GetSideCount() > 0) {
|
||||||
// lo proietto sul piano e creo la regione
|
// lo proietto sul piano e creo la regione
|
||||||
pgTria.Scale( frOCS, 1, 1, 0) ;
|
if ( pgTria.Scale( frOCS, 1, 1, 0)) {
|
||||||
PtrOwner<SurfFlatRegion> pSfrTria( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLine( pgTria.GetPolyLine()))) ;
|
PtrOwner<SurfFlatRegion> pSfrTria( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLine( pgTria.GetPolyLine()))) ;
|
||||||
if ( ! IsNull( pSfrTria)) {
|
if ( ! IsNull( pSfrTria)) {
|
||||||
if ( bAllTria && Tria.GetN() * vtVers < 0)
|
if ( bAllTria && Tria.GetN() * vtVers < 0)
|
||||||
pSfrTria->Invert() ;
|
pSfrTria->Invert() ;
|
||||||
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
pSfrTria->Offset( dTol, ICurve::OFF_FILLET) ;
|
||||||
if ( IsNull( pSfr))
|
if ( IsNull( pSfr))
|
||||||
pSfr.Set( pSfrTria) ;
|
pSfr.Set( pSfrTria) ;
|
||||||
else
|
else {
|
||||||
pSfr->Add( *pSfrTria) ;
|
if ( ! pSfr->Add( *pSfrTria))
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1242,14 +1282,18 @@ SurfTriMesh::GetSilhouette( const Plane3d& plPlane, double dTol, POLYLINEVECTOR&
|
|||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
// Effettuo contro-offset
|
// Effettuo contro-offset
|
||||||
pSfr->Offset( -dTol, ICurve::OFF_EXTEND) ;
|
if ( ! pSfr->Offset( -dTol, ICurve::OFF_EXTEND))
|
||||||
|
return false ;
|
||||||
|
|
||||||
// Recupero i contorni della regione
|
// Recupero i contorni della regione
|
||||||
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
for ( int i = 0 ; i < pSfr->GetChunkCount() ; ++ i) {
|
||||||
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
for ( int j = 0 ; j < pSfr->GetLoopCount( i) ; ++ j) {
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
if ( pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
|
if ( ! pSfr->ApproxLoopWithLines( i, j, LIN_TOL_STD, ANG_TOL_STD_DEG, ICurve::APL_STD, PL)) {
|
||||||
vPL.emplace_back( PL) ;
|
vPL.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
vPL.emplace_back( PL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1335,6 +1379,8 @@ SurfTriMesh::GetTitle( void) const
|
|||||||
bool
|
bool
|
||||||
SurfTriMesh::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
SurfTriMesh::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
||||||
{
|
{
|
||||||
|
// visualizzazione spigoli
|
||||||
|
sOut += "ShowEdges=" + ToString( GetShowEdges()) + szNewLine ;
|
||||||
// area
|
// area
|
||||||
double dArea ;
|
double dArea ;
|
||||||
GetArea( dArea) ;
|
GetArea( dArea) ;
|
||||||
@@ -1687,11 +1733,13 @@ SurfTriMesh::AdjustVertices( void)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::AdjustAdjacencies( void)
|
SurfTriMesh::AdjustAdjacencies( bool AdjustVert)
|
||||||
{
|
{
|
||||||
// sistemo le relazioni tra triangoli e vertici
|
// sistemo le relazioni tra triangoli e vertici
|
||||||
if ( ! AdjustVertices())
|
if ( AdjustVert) {
|
||||||
return false ;
|
if ( ! AdjustVertices())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
// matrice di incidenza vertici-triangoli
|
// matrice di incidenza vertici-triangoli
|
||||||
INTMATRIX mVertTria( GetVertexSize()) ;
|
INTMATRIX mVertTria( GetVertexSize()) ;
|
||||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||||
@@ -1874,7 +1922,7 @@ SurfTriMesh::TestSealing( void)
|
|||||||
m_vTria[i].nIdAdjac[1] == SVT_NULL ||
|
m_vTria[i].nIdAdjac[1] == SVT_NULL ||
|
||||||
m_vTria[i].nIdAdjac[2] == SVT_NULL) {
|
m_vTria[i].nIdAdjac[2] == SVT_NULL) {
|
||||||
bClosed = false ;
|
bClosed = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1936,7 +1984,7 @@ SurfTriMesh::PackVertices( void)
|
|||||||
++ nFirstFree ;
|
++ nFirstFree ;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
vVId.push_back( nId) ;
|
vVId.push_back( nId) ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ( nFirstFree == SVT_NULL)
|
if ( nFirstFree == SVT_NULL)
|
||||||
@@ -3043,7 +3091,7 @@ SurfTriMesh::AddBiTriangle( const int nIdVert[4])
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::DoCompacting( double dTol)
|
SurfTriMesh::DoCompacting( double dTol)
|
||||||
{
|
{
|
||||||
// imposto ricalcolo
|
// imposto ricalcolo
|
||||||
m_nStatus = ERR ;
|
m_nStatus = ERR ;
|
||||||
m_OGrMgr.Reset() ;
|
m_OGrMgr.Reset() ;
|
||||||
@@ -3084,6 +3132,7 @@ SurfTriMesh::DoCompacting( double dTol)
|
|||||||
int nVIdSize = int( vVId.size()) ;
|
int nVIdSize = int( vVId.size()) ;
|
||||||
|
|
||||||
// sistemo gli indici dei vertici nei triangoli
|
// sistemo gli indici dei vertici nei triangoli
|
||||||
|
INTVECTOR vInvalidIds ;
|
||||||
for ( int nId = 0 ; nId < GetTriangleSize() ; ++ nId) {
|
for ( int nId = 0 ; nId < GetTriangleSize() ; ++ nId) {
|
||||||
// salto i triangoli cancellati
|
// salto i triangoli cancellati
|
||||||
if ( m_vTria[nId].nIdVert[0] == SVT_DEL)
|
if ( m_vTria[nId].nIdVert[0] == SVT_DEL)
|
||||||
@@ -3100,15 +3149,51 @@ SurfTriMesh::DoCompacting( double dTol)
|
|||||||
// aggiorno il triangolo
|
// aggiorno il triangolo
|
||||||
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
|
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
|
||||||
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
|
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
|
||||||
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
|
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
|
||||||
// se due vertici coincidono o la normale non è calcolabile, cancello il triangolo
|
|
||||||
if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1] ||
|
// verifico se triangolo da rimuovere per vertici coincidenti
|
||||||
m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2] ||
|
bool bRemove = false ;
|
||||||
m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2] ||
|
int nTAdj1 = SVT_NULL, nTAdj2 = SVT_NULL ;
|
||||||
! CalcTriangleNormal( nId))
|
if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1]) {
|
||||||
RemoveTriangle( nId) ;
|
nTAdj1 = m_vTria[nId].nIdAdjac[1] ;
|
||||||
|
nTAdj2 = m_vTria[nId].nIdAdjac[2] ;
|
||||||
|
bRemove = true ;
|
||||||
|
}
|
||||||
|
else if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2]) {
|
||||||
|
nTAdj1 = m_vTria[nId].nIdAdjac[0] ;
|
||||||
|
nTAdj2 = m_vTria[nId].nIdAdjac[1] ;
|
||||||
|
bRemove = true ;
|
||||||
|
}
|
||||||
|
else if ( m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2]) {
|
||||||
|
nTAdj1 = m_vTria[nId].nIdAdjac[0] ;
|
||||||
|
nTAdj2 = m_vTria[nId].nIdAdjac[2] ;
|
||||||
|
bRemove = true ;
|
||||||
|
}
|
||||||
|
if ( bRemove) {
|
||||||
|
// sistemo le contro adiacenze
|
||||||
|
if ( nTAdj1 != SVT_NULL) {
|
||||||
|
for ( int j = 0 ; j < 3 ; ++ j)
|
||||||
|
if ( m_vTria[nTAdj1].nIdAdjac[j] == nId)
|
||||||
|
m_vTria[nTAdj1].nIdAdjac[j] = nTAdj2 ;
|
||||||
|
}
|
||||||
|
if ( nTAdj2 != SVT_NULL) {
|
||||||
|
for ( int j = 0 ; j < 3 ; ++ j)
|
||||||
|
if ( m_vTria[nTAdj2].nIdAdjac[j] == nId)
|
||||||
|
m_vTria[nTAdj2].nIdAdjac[j] = nTAdj1 ;
|
||||||
|
}
|
||||||
|
// rimuovo il triangolo
|
||||||
|
RemoveTriangle( nId) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifico se il triangolo va rimosso per normale non calcolabile
|
||||||
|
else if ( ! CalcTriangleNormal( nId))
|
||||||
|
vInvalidIds.emplace_back( nId) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// elimino triangoli invalidi ( con gestione speciale per evitare T-junctions)
|
||||||
|
if ( ! vInvalidIds.empty())
|
||||||
|
RemoveInvalidTriangles( vInvalidIds) ;
|
||||||
|
|
||||||
// compatto il vettore dei vertici
|
// compatto il vettore dei vertici
|
||||||
if ( ! PackVertices())
|
if ( ! PackVertices())
|
||||||
return false ;
|
return false ;
|
||||||
@@ -3345,22 +3430,23 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double
|
|||||||
bMirror = ( bMirror ? ( dCoeffY > 0) : ( dCoeffY < 0)) ;
|
bMirror = ( bMirror ? ( dCoeffY > 0) : ( dCoeffY < 0)) ;
|
||||||
bMirror = ( bMirror ? ( dCoeffZ > 0) : ( dCoeffZ < 0)) ;
|
bMirror = ( bMirror ? ( dCoeffZ > 0) : ( dCoeffZ < 0)) ;
|
||||||
|
|
||||||
// aggiorno le facce
|
// se c'è mirror, devo invertire le facce
|
||||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
if ( bMirror) {
|
||||||
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
|
for ( int i = 0 ; i < GetTriangleSize() ; ++ i)
|
||||||
// se c'è mirror, devo invertire la faccia
|
if ( m_vTria[i].nIdVert[0] != SVT_DEL)
|
||||||
if ( bMirror)
|
InvertTriangle( i) ;
|
||||||
InvertTriangle( i) ;
|
|
||||||
// aggiorno la normale
|
|
||||||
if ( ! CalcTriangleNormal( i)) {
|
|
||||||
// elimino il triangolo
|
|
||||||
RemoveTriangle( i) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rimuovo i triangoli resi invalidi dalla scalatura
|
||||||
|
bool bOk = DoCompacting() ;
|
||||||
|
|
||||||
return DoCompacting() ;
|
// rimuovo i triangoli doppi
|
||||||
|
bool bModified = false ;
|
||||||
|
bOk = bOk && RemoveDoubleTriangles( bModified) ;
|
||||||
|
if ( bModified)
|
||||||
|
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||||
|
|
||||||
|
return bOk ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -3592,6 +3678,18 @@ SurfTriMesh::Invert( void)
|
|||||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i)
|
for ( int i = 0 ; i < GetTriangleSize() ; ++ i)
|
||||||
InvertTriangle( i) ;
|
InvertTriangle( i) ;
|
||||||
|
|
||||||
|
// se bordi della sfaccettatura validi
|
||||||
|
if ( m_bFacEdged) {
|
||||||
|
for ( int nE = 0 ; nE < GetEdgeCount() ; ++ nE) {
|
||||||
|
// inversione dei vertici nel vettore delle sfaccettature
|
||||||
|
swap( m_vFacEdge[nE].nIdVert[0], m_vFacEdge[nE].nIdVert[1]) ;
|
||||||
|
// inversione delle adiacenze nel vettore delle sfaccettature
|
||||||
|
swap( m_vFacEdge[nE].nIdFacAdj[0], m_vFacEdge[nE].nIdFacAdj[1]) ;
|
||||||
|
// inversione dell'angolo interno
|
||||||
|
m_vFacEdge[nE].dIntAng *= -1. ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3724,12 +3822,19 @@ SurfTriMesh::VerifyConnection( bool bShellsAndParts) const
|
|||||||
BBox3d b3Box ;
|
BBox3d b3Box ;
|
||||||
PtrOwner<ISurfTriMesh> pStmShell ;
|
PtrOwner<ISurfTriMesh> pStmShell ;
|
||||||
} ;
|
} ;
|
||||||
|
// vettore di shell con vettori dei propri triangoli (per accelerare nei casi degeneri)
|
||||||
|
INTMATRIX mShellTria( m_nShells) ;
|
||||||
|
for ( int i = 0 ; i < ssize( m_vTria) ; ++ i) {
|
||||||
|
if ( m_vTria[i].nShell < m_nShells)
|
||||||
|
mShellTria[m_vTria[i].nShell].push_back( i) ;
|
||||||
|
}
|
||||||
|
// classificazione delle shell
|
||||||
vector<SHELLINFO> vOuterShells ;
|
vector<SHELLINFO> vOuterShells ;
|
||||||
vector<SHELLINFO> vInnerShells ;
|
vector<SHELLINFO> vInnerShells ;
|
||||||
INTVECTOR vOpenShells ;
|
INTVECTOR vOpenShells ;
|
||||||
for ( int nSh = 0 ; nSh < m_nShells ; ++ nSh) {
|
for ( int nSh = 0 ; nSh < m_nShells ; ++ nSh) {
|
||||||
// se la shell è chiusa
|
// se la shell è chiusa
|
||||||
if ( IsShellClosed( nSh)) {
|
if ( ssize( mShellTria[nSh]) >= 4 && IsShellClosed( nSh)) {
|
||||||
// creo una superficie clonata dalla shell
|
// creo una superficie clonata dalla shell
|
||||||
PtrOwner<ISurfTriMesh> pStmShell( CloneShell( nSh)) ;
|
PtrOwner<ISurfTriMesh> pStmShell( CloneShell( nSh)) ;
|
||||||
if ( IsNull( pStmShell) || ! pStmShell->IsValid())
|
if ( IsNull( pStmShell) || ! pStmShell->IsValid())
|
||||||
@@ -3741,7 +3846,9 @@ SurfTriMesh::VerifyConnection( bool bShellsAndParts) const
|
|||||||
BBox3d b3Box ;
|
BBox3d b3Box ;
|
||||||
pStmShell->GetLocalBBox( b3Box, BBF_STANDARD) ;
|
pStmShell->GetLocalBBox( b3Box, BBF_STANDARD) ;
|
||||||
// la inserisco nel vettore opportuno
|
// la inserisco nel vettore opportuno
|
||||||
if ( dVol > 0)
|
if ( abs( dVol) < 1 * 1 * EPS_SMALL)
|
||||||
|
vOpenShells.push_back( nSh) ;
|
||||||
|
else if ( dVol > 0)
|
||||||
vOuterShells.emplace_back( nSh, dVol, b3Box, Release( pStmShell)) ;
|
vOuterShells.emplace_back( nSh, dVol, b3Box, Release( pStmShell)) ;
|
||||||
else
|
else
|
||||||
vInnerShells.emplace_back( nSh, dVol, b3Box, Release( pStmShell)) ;
|
vInnerShells.emplace_back( nSh, dVol, b3Box, Release( pStmShell)) ;
|
||||||
@@ -3893,6 +4000,7 @@ SurfTriMesh::IsShellClosed( int nShell) const
|
|||||||
return false ;
|
return false ;
|
||||||
// ciclo sui triangoli della shell
|
// ciclo sui triangoli della shell
|
||||||
bool bClosed = true ;
|
bool bClosed = true ;
|
||||||
|
int nTriaCnt = 0 ;
|
||||||
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
|
||||||
// se triangolo non cancellato e della shell
|
// se triangolo non cancellato e della shell
|
||||||
if ( m_vTria[i].nIdVert[0] != SVT_DEL && m_vTria[i].nShell == nShell) {
|
if ( m_vTria[i].nIdVert[0] != SVT_DEL && m_vTria[i].nShell == nShell) {
|
||||||
@@ -3903,10 +4011,12 @@ SurfTriMesh::IsShellClosed( int nShell) const
|
|||||||
bClosed = false ;
|
bClosed = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
++ nTriaCnt ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// restituisco il risultato
|
// restituisco il risultato
|
||||||
return bClosed ;
|
return ( bClosed && nTriaCnt >= 4) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -3984,6 +4094,56 @@ SurfTriMesh::CloneShell( int nShell) const
|
|||||||
return Release( pSurfTM) ;
|
return Release( pSurfTM) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetPartLocalBBox( int nP, BBox3d& b3Loc) const
|
||||||
|
{
|
||||||
|
// verifico esistenza della parte
|
||||||
|
if ( nP < 0 || nP >= GetPartCount())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// assegno il box in locale
|
||||||
|
b3Loc.Reset() ;
|
||||||
|
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||||
|
// recupero il vettore delle Shell della parte corrente
|
||||||
|
const auto& vShell = m_vPart[nP].vShell ;
|
||||||
|
// scorro i triangoli validi contenuti nella Shell
|
||||||
|
if ( m_vTria[i].nIdVert[0] != SVT_DEL &&
|
||||||
|
find( vShell.begin(), vShell.end(), m_vTria[i].nShell) != vShell.end()) {
|
||||||
|
// ciclo sui tre vertici
|
||||||
|
for ( int j = 0 ; j < 3 ; ++ j)
|
||||||
|
b3Loc.Add( m_vVert[m_vTria[i].nIdVert[j]].ptP) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetPartBBox( int nP, const Frame3d& frRef, BBox3d& b3Ref) const
|
||||||
|
{
|
||||||
|
// verifico esistenza della parte
|
||||||
|
if ( nP < 0 || nP >= GetPartCount())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// assegno il box in locale
|
||||||
|
b3Ref.Reset() ;
|
||||||
|
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||||
|
// recupero il vettore delle Shell della parte corrente
|
||||||
|
const auto& vShell = m_vPart[nP].vShell ;
|
||||||
|
// scorro i triangoli validi contenuti nella Shell
|
||||||
|
if ( m_vTria[i].nIdVert[0] != SVT_DEL &&
|
||||||
|
find( vShell.begin(), vShell.end(), m_vTria[i].nShell) != vShell.end()) {
|
||||||
|
// ciclo sui tre vertici
|
||||||
|
for ( int j = 0 ; j < 3 ; ++ j)
|
||||||
|
b3Ref.Add( GetToGlob( m_vVert[m_vTria[i].nIdVert[j]].ptP, frRef)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
SurfTriMesh::GetPartCount( void) const
|
SurfTriMesh::GetPartCount( void) const
|
||||||
@@ -4279,6 +4439,35 @@ SurfTriMesh::ClonePart( int nPart) const
|
|||||||
return Release( pSurfTM) ;
|
return Release( pSurfTM) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetPartAndShellFromFacet( int nFacet, int& nPart, int& nShell) const
|
||||||
|
{
|
||||||
|
// l'indice della faccia deve essere nei limiti
|
||||||
|
if ( nFacet < 0 || nFacet >= int( m_vFacet.size()))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// mi assicuro che siano calcolate il numero di parti e di shell
|
||||||
|
int nParts = GetPartCount() ;
|
||||||
|
|
||||||
|
int nTria = m_vFacet[nFacet] ;
|
||||||
|
nShell = m_vTria[nTria].nShell ;
|
||||||
|
|
||||||
|
// scopro in quale part è la shell
|
||||||
|
int nPartTemp = 0 ;
|
||||||
|
nPart = - 1 ;
|
||||||
|
while ( nPartTemp < nParts && nPart == - 1) {
|
||||||
|
for ( int i : m_vPart[nPartTemp].vShell) {
|
||||||
|
if ( i == nShell) {
|
||||||
|
nPart = nPartTemp ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++nPartTemp ;
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::ResetTFlags( void)
|
SurfTriMesh::ResetTFlags( void)
|
||||||
@@ -4322,3 +4511,104 @@ SurfTriMesh::SetTempInt( int nId, int nTempInt) const
|
|||||||
m_vTria[nId].nTemp = nTempInt ;
|
m_vTria[nId].nTemp = nTempInt ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::AddTriaFromZMap( const TRIA3DEXVECTOR& vTria, PointGrid3d& VertGrid, double dVertexTol)
|
||||||
|
{
|
||||||
|
// scorro i triangoli
|
||||||
|
for ( const Triangle3dEx& Tria : vTria) {
|
||||||
|
// ciclo sui tre vertici
|
||||||
|
int nIdV[3]{} ;
|
||||||
|
for ( int nV = 0 ; nV < 3 ; ++ nV) {
|
||||||
|
// verifico se vertice già presente
|
||||||
|
int nId ;
|
||||||
|
if ( ! VertGrid.Find( Tria.GetP( nV), dVertexTol, nId)) {
|
||||||
|
// se non presente, lo aggiugo
|
||||||
|
nIdV[nV] = AddVertex( Tria.GetP( nV)) ;
|
||||||
|
if ( nIdV[nV] == SVT_NULL)
|
||||||
|
return false ;
|
||||||
|
VertGrid.InsertPoint( Tria.GetP( nV), nIdV[nV]) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nIdV[nV] = nId ;
|
||||||
|
}
|
||||||
|
// se i vertici sono tutti diversi tra loro, inserisco il triangolo
|
||||||
|
if ( nIdV[0] != nIdV[1] && nIdV[0] != nIdV[2] && nIdV[1] != nIdV[2]) {
|
||||||
|
int nT = AddTriangle( nIdV, Tria.GetGrade()) ;
|
||||||
|
if ( nT != SVT_NULL && nT != SVT_DEL) {
|
||||||
|
// associo relazione vertice-triangolo
|
||||||
|
for ( int i = 0 ; i < 3 ; ++ i)
|
||||||
|
m_vVert[nIdV[i]].nIdTria = nT ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::AdjustTopologyFromZMap( void)
|
||||||
|
{
|
||||||
|
// cancello tutti i vertici che puntano a triangoli cancellati
|
||||||
|
bool bPack = false ;
|
||||||
|
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
|
||||||
|
if ( m_vVert[i].nIdTria == SVT_NULL) {
|
||||||
|
m_vVert[i].nIdTria = SVT_DEL ;
|
||||||
|
bPack = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bPack)
|
||||||
|
PackVertices() ;
|
||||||
|
m_nStatus = SurfTriMesh::OK ;
|
||||||
|
|
||||||
|
// calcolo le adiacenze
|
||||||
|
if ( ! AdjustAdjacencies())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// verifico l'orientamento ( TODO -- Da migliorare...)
|
||||||
|
// Ora per funzionare è necessario che il ciclo sui triangoli parta da un triangolo orientato
|
||||||
|
// correttamente e che i triangoli invertiti siano "circondati" da triangoli tutti orientati correttamente
|
||||||
|
if ( ! AdjustOrientations())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// calcolo le facce
|
||||||
|
if ( ! VerifyFaceting())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// rimozione delle TJunction
|
||||||
|
bool bModified = false ;
|
||||||
|
if ( ! RemoveTJunctions( bModified, SQ_EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
if ( bModified) {
|
||||||
|
if ( ! AdjustVertices() || ! DoCompacting())
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
TestSealing() ;
|
||||||
|
|
||||||
|
// semplifico le facce ( anche più piccola)
|
||||||
|
if ( ! SimplifyFacets( MAX_EDGE_LEN_STD, false, 5. * EPS_SMALL))
|
||||||
|
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::AdjustTopologyFromZMap")
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetTriaFromFace( int nF, int& nT) const
|
||||||
|
{
|
||||||
|
// la superficie deve essere validata
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
// verifico stato sfaccettatura
|
||||||
|
if ( ! VerifyFaceting())
|
||||||
|
return false ;
|
||||||
|
// l'indice della faccia deve essere nei limiti
|
||||||
|
if ( nF < 0 || nF >= int( m_vFacet.size()))
|
||||||
|
return false ;
|
||||||
|
// recupero la normale di un triangolo della faccetta
|
||||||
|
nT = m_vFacet[nF] ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
+24
-5
@@ -18,6 +18,7 @@
|
|||||||
#include "GeoObjRW.h"
|
#include "GeoObjRW.h"
|
||||||
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||||
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
#include "/EgtDev/Include/EGkHashGrids3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkPointGrid3d.h"
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
@@ -321,13 +322,15 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool GetEdge( int nInd, int& nV1, int& nV2, int& nFl, int& nFr, double& dAng) const override ;
|
bool GetEdge( int nInd, int& nV1, int& nV2, int& nFl, int& nFr, double& dAng) const override ;
|
||||||
bool GetEdge( int nInd, Point3d& ptP1, Point3d& ptP2, double& dAng) const override ;
|
bool GetEdge( int nInd, Point3d& ptP1, Point3d& ptP2, double& dAng) const override ;
|
||||||
bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ;
|
bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ;
|
||||||
|
bool GetCurvature( int nV,
|
||||||
|
double& dMinK, Vector3d& vtMinK, double& dMaxK, Vector3d& vtMaxK, bool& bPlanar, Vector3d& vtNorm) const override ;
|
||||||
bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ;
|
bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ;
|
||||||
bool GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) override ;
|
bool GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) override ;
|
||||||
bool Add( const ISurfTriMesh& Other) override ;
|
bool Add( const ISurfTriMesh& Other) override ;
|
||||||
bool Intersect( const ISurfTriMesh& Other) override ;
|
bool Intersect( const ISurfTriMesh& Other) override ;
|
||||||
bool Subtract( const ISurfTriMesh& Other) override ;
|
bool Subtract( const ISurfTriMesh& Other) override ;
|
||||||
bool GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
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 CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bool bSaveOnEq) override ;
|
||||||
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
bool Repair( double dMaxEdgeLen = MAX_EDGE_LEN_STD) override ;
|
||||||
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
bool GetAllTriaOverlapBox( const BBox3d& b3Box, INTVECTOR& vT) const override ;
|
||||||
@@ -336,12 +339,15 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool GetShellArea( int nShell, double& dArea) const override ;
|
bool GetShellArea( int nShell, double& dArea) const override ;
|
||||||
bool RemoveShell( int nShell) override ;
|
bool RemoveShell( int nShell) override ;
|
||||||
SurfTriMesh* CloneShell( int nShell) const 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 ;
|
int GetPartCount( void) const override ;
|
||||||
bool RemovePart( int nPart) override ;
|
bool RemovePart( int nPart) override ;
|
||||||
bool GetPartArea( int nPart, double& dArea) const override ;
|
bool GetPartArea( int nPart, double& dArea) const override ;
|
||||||
bool GetPartVolume( int nPart, double& dVolume) const override ;
|
bool GetPartVolume( int nPart, double& dVolume) const override ;
|
||||||
bool GetPartLoops( int nPart, POLYLINEVECTOR& vPL) const override ;
|
bool GetPartLoops( int nPart, POLYLINEVECTOR& vPL) const override ;
|
||||||
SurfTriMesh* ClonePart( int nPart) const override ;
|
SurfTriMesh* ClonePart( int nPart) const override ;
|
||||||
|
bool GetPartAndShellFromFacet( int nFacet, int& nPart, int& nShell) const override ;
|
||||||
bool SetTFlag( int nId, int nTFlag) override ;
|
bool SetTFlag( int nId, int nTFlag) override ;
|
||||||
bool GetTFlag( int nId, int& nFlag) const override ;
|
bool GetTFlag( int nId, int& nFlag) const override ;
|
||||||
int GetMaxTFlag( void) const override
|
int GetMaxTFlag( void) const override
|
||||||
@@ -373,6 +379,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool GetTempInt( int nId, int& nTempInt) const ;
|
bool GetTempInt( int nId, int& nTempInt) const ;
|
||||||
bool ResetTempInts( void) const ;
|
bool ResetTempInts( void) const ;
|
||||||
bool SetTempInt( int nId, int nTempInt) const ;
|
bool SetTempInt( int nId, int nTempInt) const ;
|
||||||
|
bool AddTriaFromZMap( const TRIA3DEXVECTOR& vTria, PointGrid3d& VertGrid, double dVertexTol = 2 * EPS_SMALL) ;
|
||||||
|
bool AdjustTopologyFromZMap( void) ;
|
||||||
|
bool GetTriaFromFace( int nF, int& nT) const ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
typedef std::vector<StmVert> VERTVECTOR ;
|
typedef std::vector<StmVert> VERTVECTOR ;
|
||||||
@@ -388,7 +397,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool CopyFrom( const SurfTriMesh& clSrc) ;
|
bool CopyFrom( const SurfTriMesh& clSrc) ;
|
||||||
bool Validate( bool bCorrect = false) ;
|
bool Validate( bool bCorrect = false) ;
|
||||||
bool AdjustVertices( void) ;
|
bool AdjustVertices( void) ;
|
||||||
bool AdjustAdjacencies( void) ;
|
bool AdjustAdjacencies( bool AdjustVert = true) ;
|
||||||
bool AdjustOrientations( void) ;
|
bool AdjustOrientations( void) ;
|
||||||
bool AdjustTriaOrientation( TRINTDEQUE& S3iQ) ;
|
bool AdjustTriaOrientation( TRINTDEQUE& S3iQ) ;
|
||||||
bool TestSealing( void) ;
|
bool TestSealing( void) ;
|
||||||
@@ -406,6 +415,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
int NextIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
int NextIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
||||||
int PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
int PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
|
||||||
bool GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const ;
|
bool GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const ;
|
||||||
|
bool GetTriangleVertexAngle( int nT, int nV, double& dAng) const ;
|
||||||
bool MarchAlongLoop( int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
|
bool MarchAlongLoop( int nT, int nV, int nTimeStamp, PolyLine& PL) const ;
|
||||||
bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
bool MarchOneTria( int& nT, int& nV, int nTimeStamp, PolyLine& PL, bool& bEnd) const ;
|
||||||
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
|
bool VerifyPolylinesForTwoCurves( const PolyLine& PL1, const PolyLine& PL2) const ;
|
||||||
@@ -433,14 +443,16 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
|||||||
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
|
||||||
bool IdentifyShells( void) const ;
|
bool IdentifyShells( void) const ;
|
||||||
bool RemoveDoubleTriangles( bool& bModified) ;
|
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 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 AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||||
bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) ;
|
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 :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
Status m_nStatus ; // stato
|
Status m_nStatus ; // stato
|
||||||
@@ -483,3 +495,10 @@ inline SurfTriMesh* GetBasicSurfTriMesh( IGeoObj* pGObj)
|
|||||||
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
{ if ( pGObj == nullptr || pGObj->GetType() != SRF_TRIMESH)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
return ( static_cast<SurfTriMesh*>( pGObj)) ; }
|
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
|
||||||
|
|||||||
+43
-84
@@ -41,7 +41,7 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const double BOOLEAN_SCALE = 1024 ;
|
const double BOOLEAN_SCALE = PREC_SCALE_COEFF ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
@@ -502,9 +502,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// -------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
// Creo il loop chiuso padre di tutti, il perimetro del triangolo. Questo viene diviso in sotto-loop
|
// Creo il loop chiuso padre di tutti, il perimetro del triangolo. Questo viene diviso in sotto-loop
|
||||||
// chiusi mediante quelli aperti. I loop chiusi trovati precedentemente sono interni a uno dei
|
// chiusi mediante quelli aperti. I loop chiusi trovati precedentemente sono interni a uno dei
|
||||||
// sotto-loop chiusi di cui è formato il perimetro.
|
// sotto-loop chiusi di cui è formato il perimetro.
|
||||||
@@ -704,16 +702,18 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Elimino loop interni non validi
|
// Verifico se i loop interni sono validi
|
||||||
bool bDouble = true ;
|
bool bAllInvalid = true ;
|
||||||
for ( int nInnLoop = 0 ; nInnLoop < int( vInnerLoop.size()) ; ++ nInnLoop) {
|
for ( int nInnLoop = 0 ; nInnLoop < int( vInnerLoop.size()) ; ++ nInnLoop) {
|
||||||
if ( cvClosedChain[vInnerLoop[nInnLoop]].size() > 2) {
|
// se chain formata da tre segmenti significa che si tratta di due linee sovrapposte ( il terzo tratto è quello aggiunto
|
||||||
bDouble = false ;
|
// per forzare la chiusura)
|
||||||
|
if ( cvClosedChain[vInnerLoop[nInnLoop]].size() > 3) {
|
||||||
|
bAllInvalid = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( vInnerLoop.empty() || bDouble) {
|
if ( vInnerLoop.empty() || bAllInvalid) {
|
||||||
// Eseguo triangolazione
|
// Eseguo triangolazione
|
||||||
PNTVECTOR vPt ;
|
PNTVECTOR vPt ;
|
||||||
INTVECTOR vTr ;
|
INTVECTOR vTr ;
|
||||||
@@ -753,63 +753,20 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
vPolygons.emplace_back( CurLoop) ;
|
vPolygons.emplace_back( CurLoop) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// poligono
|
// controllo la direzione della normale del triangolo con quella del poligono di area maggiore
|
||||||
Polygon3d pgPol ;
|
// ( per gestire eventuali inscatolamenti)
|
||||||
pgPol.FromPolyLine( vPolygons[1]) ;
|
Vector3d vtPoly = V_NULL ;
|
||||||
|
double dMaxArea = -1 ;
|
||||||
// controllo direzioni delle normali
|
for ( int i = 1 ; i < int( vPolygons.size()) ; i ++) {
|
||||||
bool bCodirectedNormals = trTria.GetN() * pgPol.GetVersN() > 0. ;
|
Plane3d plPoly ;
|
||||||
|
double dAreaPoly ;
|
||||||
// Aggiungo al loop esterno i punti dei loop interni che si trovano su di esso
|
vPolygons[i].IsClosedAndFlat( plPoly, dAreaPoly) ;
|
||||||
PNTULIST& ExternLoopList = vPolygons[0].GetUPointList() ;
|
if ( dAreaPoly > dMaxArea) {
|
||||||
// Ciclo sui segmenti del loop esterno
|
vtPoly = plPoly.GetVersN() ;
|
||||||
auto itSt = ExternLoopList.begin() ;
|
dMaxArea = dAreaPoly ;
|
||||||
auto itEn = itSt ;
|
}
|
||||||
++ itEn ;
|
|
||||||
for ( ; itSt != ExternLoopList.end() && itEn != ExternLoopList.end() ; ++ itSt, ++ itEn) {
|
|
||||||
// Estremi del segmento corrente del loop esterno e scorrispondente vettore
|
|
||||||
Point3d ptSt = itSt->first ;
|
|
||||||
Point3d ptEn = itEn->first ;
|
|
||||||
Vector3d vtSeg = ptEn - ptSt ;
|
|
||||||
double dSegLen = vtSeg.Len() ;
|
|
||||||
vtSeg /= dSegLen ;
|
|
||||||
// Vettore dei punti dei loop interni che stanno sul segmento del loop esterno
|
|
||||||
PNTUVECTOR vPointWithOrder ;
|
|
||||||
// Ciclo sui loop interni
|
|
||||||
for ( int nInnPoly = 1 ; nInnPoly < int( vPolygons.size()) ; ++ nInnPoly) {
|
|
||||||
// Ciclo sui punti dei loop interni
|
|
||||||
Point3d ptInnPoint ;
|
|
||||||
bool bIsFirst = true ;
|
|
||||||
bool bContinue = vPolygons[nInnPoly].GetFirstPoint( ptInnPoint) ;
|
|
||||||
while ( bContinue) {
|
|
||||||
DistPointLine DistCalculator( ptInnPoint, ptSt, ptEn) ;
|
|
||||||
double dDist ;
|
|
||||||
DistCalculator.GetDist( dDist) ;
|
|
||||||
double dLongPos = ( ptInnPoint - ptSt) * vtSeg ;
|
|
||||||
if ( dDist < EPS_SMALL && dLongPos > 0. && dLongPos < dSegLen) {
|
|
||||||
POINTU NewPointU ;
|
|
||||||
NewPointU.first = ptInnPoint ;
|
|
||||||
NewPointU.second = dLongPos ;
|
|
||||||
if ( ! bIsFirst)
|
|
||||||
vPointWithOrder.emplace_back( NewPointU) ;
|
|
||||||
}
|
|
||||||
bIsFirst = false ;
|
|
||||||
bContinue = vPolygons[nInnPoly].GetNextPoint( ptInnPoint) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Riordino i punti interni sul segmento esterno in funzione della distanza dall'origine di esso
|
|
||||||
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) - 1 ; ++ nPi) {
|
|
||||||
for ( int nPj = nPi + 1 ; nPj < int( vPointWithOrder.size()) ; ++ nPj) {
|
|
||||||
if ( vPointWithOrder[nPi].second > vPointWithOrder[nPj].second) {
|
|
||||||
swap( vPointWithOrder[nPi], vPointWithOrder[nPj]) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Aggiungo i punti al loop esterno
|
|
||||||
for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) {
|
|
||||||
itSt = ExternLoopList.emplace( itEn, vPointWithOrder[nPi]) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
bool bCodirectedNormals = trTria.GetN() * vtPoly > 0. ;
|
||||||
|
|
||||||
PNTVECTOR vPt ;
|
PNTVECTOR vPt ;
|
||||||
INTVECTOR vTr ;
|
INTVECTOR vTr ;
|
||||||
@@ -836,6 +793,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Divido i loop che si autointercettano
|
// Divido i loop che si autointercettano
|
||||||
|
// TO DO : da verificare. Questa porzione di codice non dovrebbe andare prima della triangolazione?
|
||||||
int nInitialLoopNum = int( vPolygons.size()) ;
|
int nInitialLoopNum = int( vPolygons.size()) ;
|
||||||
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
for ( int nL = 1 ; nL < nInitialLoopNum ; ++ nL) {
|
||||||
// Lista dei punti della PolyLine Loop corrente
|
// Lista dei punti della PolyLine Loop corrente
|
||||||
@@ -883,11 +841,11 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
itSt2 = LoopPointList.emplace( itEn2, vAddingPointWithOrder[nPi]) ;
|
itSt2 = LoopPointList.emplace( itEn2, vAddingPointWithOrder[nPi]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spezzo i loop autointersecantesi
|
// Spezzo i loop autointersecantesi
|
||||||
POLYLINEVECTOR vAuxPolygons ;
|
POLYLINEVECTOR vAuxPolygons ;
|
||||||
vAuxPolygons.emplace_back( vPolygons[nL]) ;
|
vAuxPolygons.emplace_back( vPolygons[nL]) ;
|
||||||
|
|
||||||
bool bSplitted = true ;
|
bool bSplitted = true ;
|
||||||
while ( bSplitted) {
|
while ( bSplitted) {
|
||||||
bSplitted = false ;
|
bSplitted = false ;
|
||||||
@@ -956,16 +914,13 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
vPolygons.erase( vPolygons.begin() + i) ;
|
vPolygons.erase( vPolygons.begin() + i) ;
|
||||||
else
|
else
|
||||||
++ i ;
|
++ i ;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// eventuale inversione della prima curva ( che determina il verso della triangolazione) per averla orientata
|
||||||
bool bCordirectedNormals_intLoop = bCodirectedNormals ;
|
// come il triangolo
|
||||||
if ( ! vPolygons.empty()) {
|
if ( ! vPolygons.empty()) {
|
||||||
Polygon3d pgPol ;
|
Polygon3d pgPol ;
|
||||||
pgPol.FromPolyLine( vPolygons[0]) ;
|
pgPol.FromPolyLine( vPolygons[0]) ;
|
||||||
// controllo direzioni delle normali
|
if ( trTria.GetN() * pgPol.GetVersN() < 0.)
|
||||||
bCordirectedNormals_intLoop = trTria.GetN() * pgPol.GetVersN() > 0. ;
|
|
||||||
if ( ! bCordirectedNormals_intLoop)
|
|
||||||
vPolygons[0].Invert() ;
|
vPolygons[0].Invert() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -981,7 +936,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
|||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[0] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[0] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[1] = 0 ;
|
||||||
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
Surf.m_vTria[nNewTriaNum].nETempFlag[2] = 0 ;
|
||||||
if ( bCordirectedNormals_intLoop)
|
if ( bCodirectedNormals)
|
||||||
Surf.m_vTria[nNewTriaNum].nTempShell = 1 ;
|
Surf.m_vTria[nNewTriaNum].nTempShell = 1 ;
|
||||||
else
|
else
|
||||||
Surf.m_vTria[nNewTriaNum].nTempShell = -1 ;
|
Surf.m_vTria[nNewTriaNum].nTempShell = -1 ;
|
||||||
@@ -1123,7 +1078,7 @@ SurfTriMesh::AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Su
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||||
{
|
{
|
||||||
bool bModif = false ;
|
bool bModif = false ;
|
||||||
SurfTriMesh& SurfB = Other ;
|
SurfTriMesh& SurfB = Other ;
|
||||||
|
|
||||||
@@ -1176,7 +1131,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||||
|
|
||||||
// I scorro tutti i triangoli di B che intersecano il box di A
|
// Scorro tutti i triangoli di B che intersecano il box di A
|
||||||
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
||||||
|
|
||||||
// Se il triangolo B non è valido, continuo
|
// Se il triangolo B non è valido, continuo
|
||||||
@@ -1365,7 +1320,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
// Triangoli sovrapposti
|
// Triangoli sovrapposti
|
||||||
if ( bContinue) {
|
if ( bContinue) {
|
||||||
int nTriaNum2A = GetTriangleSize() ;
|
int nTriaNum2A = GetTriangleSize() ;
|
||||||
// Resetto e ricalcolo la HashGrid della superficie B
|
// Resetto e ricalcolo la HashGrid della superficie B
|
||||||
SurfB.ResetHashGrids3d() ;
|
SurfB.ResetHashGrids3d() ;
|
||||||
for ( int nTA = 0 ; nTA < nTriaNum2A ; ++ nTA) {
|
for ( int nTA = 0 ; nTA < nTriaNum2A ; ++ nTA) {
|
||||||
// Se il triangolo A non è valido, continuo
|
// Se il triangolo A non è valido, continuo
|
||||||
@@ -1375,15 +1330,19 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
// Box del triangolo A
|
// Box del triangolo A
|
||||||
BBox3d b3dTriaA ;
|
BBox3d b3dTriaA ;
|
||||||
trTriaA.GetLocalBBox( b3dTriaA) ;
|
trTriaA.GetLocalBBox( b3dTriaA) ;
|
||||||
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
// Recupero i triangoli di B che interferiscono col box del triangolo di A
|
||||||
INTVECTOR vNearTria ;
|
INTVECTOR vNearTria ;
|
||||||
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||||
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
||||||
// Se il triangolo B non è valido, continuo
|
// Se il triangolo B non è valido, continuo
|
||||||
Triangle3d trTriaB ;
|
Triangle3d trTriaB ;
|
||||||
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
||||||
continue ;
|
continue ;
|
||||||
// Se i triangoli sono sovrapposti
|
// Se sono già stati classificati entrambi come sovrapposti continuo
|
||||||
|
if ( abs( m_vTria[nTA].nTempShell) == 2 && abs( SurfB.m_vTria[vNearTria[nTB]].nTempShell) == 2)
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// Se i triangoli sono sovrapposti
|
||||||
TRIA3DVECTOR vTriaAB ;
|
TRIA3DVECTOR vTriaAB ;
|
||||||
Point3d ptTempA, ptTempB ;
|
Point3d ptTempA, ptTempB ;
|
||||||
int nIntTypeAB = IntersTriaTria( trTriaA, trTriaB, ptTempA, ptTempB, vTriaAB) ;
|
int nIntTypeAB = IntersTriaTria( trTriaA, trTriaB, ptTempA, ptTempB, vTriaAB) ;
|
||||||
@@ -1475,7 +1434,7 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
|||||||
// tengo una copia di B ( la superficie B viene modificata durante la ritriangolazione )
|
// tengo una copia di B ( la superficie B viene modificata durante la ritriangolazione )
|
||||||
SurfTriMesh SurfA_cl ;
|
SurfTriMesh SurfA_cl ;
|
||||||
SurfA_cl.CopyFrom( this) ;
|
SurfA_cl.CopyFrom( this) ;
|
||||||
|
|
||||||
// ritriangolo le due superfici mediante ogni intersezione Triangolo-Triangolo
|
// ritriangolo le due superfici mediante ogni intersezione Triangolo-Triangolo
|
||||||
IntersectTriMeshTriangle( SurfB) ;
|
IntersectTriMeshTriangle( SurfB) ;
|
||||||
|
|
||||||
@@ -1625,12 +1584,12 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
|||||||
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// sistemazioni varie
|
// sistemazioni varie
|
||||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||||
bool bModified = false ;
|
bool bModified = false ;
|
||||||
bOk = bOk && RemoveDoubleTriangles( bModified) ;
|
bOk = bOk && RemoveDoubleTriangles( bModified) ;
|
||||||
if ( bModified)
|
if ( bModified)
|
||||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||||
bOk = bOk && RemoveTJunctions( bModified) ;
|
bOk = bOk && RemoveTJunctions( bModified) ;
|
||||||
if ( bModified)
|
if ( bModified)
|
||||||
|
|||||||
+1
-1
@@ -26,7 +26,7 @@
|
|||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
const double CUT_SCALE = 1024 ;
|
const double CUT_SCALE = PREC_SCALE_COEFF ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
|
|||||||
+167
-19
@@ -21,6 +21,8 @@
|
|||||||
#include <array>
|
#include <array>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#define EIGEN_NO_IO
|
||||||
|
#include "/EgtDev/Extern/Eigen/Dense"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ SurfTriMesh::UpdateFaceting( void)
|
|||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
for ( int j = 0 ; j < int( vOldFacet.size()) ; ++ j) {
|
for ( int j = 0 ; j < int( vOldFacet.size()) ; ++ j) {
|
||||||
int i = vOldFacet[j] ;
|
int i = vOldFacet[j] ;
|
||||||
// salto triangoli inesistenti o già assegnati
|
// salto triangoli inesistenti o già assegnati
|
||||||
if ( i >= int( m_vTria.size()) ||
|
if ( i >= int( m_vTria.size()) ||
|
||||||
m_vTria[i].nIdVert[0] == SVT_DEL ||
|
m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||||
m_vTria[i].nIdFacet != SVT_NULL)
|
m_vTria[i].nIdFacet != SVT_NULL)
|
||||||
@@ -69,7 +71,7 @@ SurfTriMesh::UpdateFaceting( void)
|
|||||||
|
|
||||||
// ricostruisco le altre sfaccettature
|
// ricostruisco le altre sfaccettature
|
||||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||||
// salto triangoli cancellati o già assegnati
|
// salto triangoli cancellati o già assegnati
|
||||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||||
m_vTria[i].nIdFacet != SVT_NULL)
|
m_vTria[i].nIdFacet != SVT_NULL)
|
||||||
continue ;
|
continue ;
|
||||||
@@ -103,7 +105,7 @@ SurfTriMesh::UpdateOneFace( int nFacet, int nT)
|
|||||||
// set di triangoli da aggiornare
|
// set di triangoli da aggiornare
|
||||||
set<int> stTria ;
|
set<int> stTria ;
|
||||||
stTria.insert( nT) ;
|
stTria.insert( nT) ;
|
||||||
// finchè set non vuoto
|
// finchè set non vuoto
|
||||||
bool bOk = true ;
|
bool bOk = true ;
|
||||||
while ( ! stTria.empty()) {
|
while ( ! stTria.empty()) {
|
||||||
// tolgo un triangolo dal set
|
// tolgo un triangolo dal set
|
||||||
@@ -421,7 +423,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const
|
|||||||
if ( ! MarchAlongFacetLoop( nF, nT, 1, m_nTimeStamp, vPL.back()))
|
if ( ! MarchAlongFacetLoop( nF, nT, 1, m_nTimeStamp, vPL.back()))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se il lato 0 è di contorno
|
// se il lato 0 è di contorno
|
||||||
else if ( nAdjF[0] != nF) {
|
else if ( nAdjF[0] != nF) {
|
||||||
// ho trovato l'inizio di un loop
|
// ho trovato l'inizio di un loop
|
||||||
vPL.emplace_back() ;
|
vPL.emplace_back() ;
|
||||||
@@ -433,7 +435,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const
|
|||||||
if ( ! MarchAlongFacetLoop( nF, nT, 1, m_nTimeStamp, vPL.back()))
|
if ( ! MarchAlongFacetLoop( nF, nT, 1, m_nTimeStamp, vPL.back()))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se il lato 1 è di contorno
|
// se il lato 1 è di contorno
|
||||||
else if ( nAdjF[1] != nF) {
|
else if ( nAdjF[1] != nF) {
|
||||||
// ho trovato l'inizio di un loop
|
// ho trovato l'inizio di un loop
|
||||||
vPL.emplace_back() ;
|
vPL.emplace_back() ;
|
||||||
@@ -445,7 +447,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const
|
|||||||
if ( ! MarchAlongFacetLoop( nF, nT, 2, m_nTimeStamp, vPL.back()))
|
if ( ! MarchAlongFacetLoop( nF, nT, 2, m_nTimeStamp, vPL.back()))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// se il lato 2 è di contorno
|
// se il lato 2 è di contorno
|
||||||
else if ( nAdjF[2] != nF) {
|
else if ( nAdjF[2] != nF) {
|
||||||
// ho trovato l'inizio di un loop
|
// ho trovato l'inizio di un loop
|
||||||
vPL.emplace_back() ;
|
vPL.emplace_back() ;
|
||||||
@@ -457,7 +459,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const
|
|||||||
if ( ! MarchAlongFacetLoop( nF, nT, 0, m_nTimeStamp, vPL.back()))
|
if ( ! MarchAlongFacetLoop( nF, nT, 0, m_nTimeStamp, vPL.back()))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
// altrimenti non c'è contorno
|
// altrimenti non c'è contorno
|
||||||
else {
|
else {
|
||||||
// marco il triangolo come verificato
|
// marco il triangolo come verificato
|
||||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||||
@@ -476,7 +478,7 @@ SurfTriMesh::GetFacetLoops( int nF, POLYLINEVECTOR& vPL) const
|
|||||||
return false ;
|
return false ;
|
||||||
// se loop esterno
|
// se loop esterno
|
||||||
if ( vtN * plPlane.GetVersN() > 0) {
|
if ( vtN * plPlane.GetVersN() > 0) {
|
||||||
// se non c'è ancora loop esterno in prima posizione
|
// se non c'è ancora loop esterno in prima posizione
|
||||||
if ( ! bOutFirst) {
|
if ( ! bOutFirst) {
|
||||||
// lo sposto in prima posizione
|
// lo sposto in prima posizione
|
||||||
if ( i != 0)
|
if ( i != 0)
|
||||||
@@ -517,7 +519,7 @@ SurfTriMesh::MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp,
|
|||||||
// verifico appartenga alla stessa faccia
|
// verifico appartenga alla stessa faccia
|
||||||
if ( m_vTria[nAdjT].nIdFacet != nF)
|
if ( m_vTria[nAdjT].nIdFacet != nF)
|
||||||
return false ;
|
return false ;
|
||||||
// recupero il suo lato di adiacenza (e verifico non abbia più adiacenze con il triangolo di partenza)
|
// recupero il suo lato di adiacenza (e verifico non abbia più adiacenze con il triangolo di partenza)
|
||||||
int nAdjS = SVT_NULL ;
|
int nAdjS = SVT_NULL ;
|
||||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||||
if ( m_vTria[nAdjT].nIdAdjac[i] == nT) {
|
if ( m_vTria[nAdjT].nIdAdjac[i] == nT) {
|
||||||
@@ -531,11 +533,11 @@ SurfTriMesh::MarchOneFacetTria( int nF, int& nT, int& nV, int nTimeStamp,
|
|||||||
return false ;
|
return false ;
|
||||||
// vertice di fine adiacenza e indice del successivo lato
|
// vertice di fine adiacenza e indice del successivo lato
|
||||||
int nAdjV = Next( nAdjS) ;
|
int nAdjV = Next( nAdjS) ;
|
||||||
// verifico se il lato successivo è un bordo
|
// verifico se il lato successivo è un bordo
|
||||||
int nNextT = m_vTria[nAdjT].nIdAdjac[nAdjV] ;
|
int nNextT = m_vTria[nAdjT].nIdAdjac[nAdjV] ;
|
||||||
int nNextF = ( nNextT != SVT_NULL ? m_vTria[nNextT].nIdFacet : SVT_NULL) ;
|
int nNextF = ( nNextT != SVT_NULL ? m_vTria[nNextT].nIdFacet : SVT_NULL) ;
|
||||||
if ( nNextF != nF) {
|
if ( nNextF != nF) {
|
||||||
// se già recuperato
|
// se già recuperato
|
||||||
if ( m_vTria[nAdjT].nTemp == nTimeStamp) {
|
if ( m_vTria[nAdjT].nTemp == nTimeStamp) {
|
||||||
bEnd = true ;
|
bEnd = true ;
|
||||||
return true ;
|
return true ;
|
||||||
@@ -593,7 +595,7 @@ SurfTriMesh::GetFacetsContact( int nF1, int nF2, bool& bAdjac, Point3d& ptP1, Po
|
|||||||
// verifico esistenza seconda faccia
|
// verifico esistenza seconda faccia
|
||||||
if ( nF2 < 0 || nF2 >= int( m_vFacet.size()))
|
if ( nF2 < 0 || nF2 >= int( m_vFacet.size()))
|
||||||
return false ;
|
return false ;
|
||||||
// verifico se c'è un contatto con la seconda faccia e recupero i punti estremi della eventuale linea di contatto
|
// verifico se c'è un contatto con la seconda faccia e recupero i punti estremi della eventuale linea di contatto
|
||||||
bAdjac = false ;
|
bAdjac = false ;
|
||||||
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
for ( int i = 0 ; i < int( vPL.size()) ; ++ i) {
|
||||||
double dUs, dUe ;
|
double dUs, dUe ;
|
||||||
@@ -606,7 +608,7 @@ SurfTriMesh::GetFacetsContact( int nF1, int nF2, bool& bAdjac, Point3d& ptP1, Po
|
|||||||
ptP2 = ptPe ;
|
ptP2 = ptPe ;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// parametri del segmento già definito
|
// parametri del segmento già definito
|
||||||
Vector3d vtT ;
|
Vector3d vtT ;
|
||||||
double dLen ;
|
double dLen ;
|
||||||
DirDist( ptP1, ptP2, vtT, dLen) ;
|
DirDist( ptP1, ptP2, vtT, dLen) ;
|
||||||
@@ -646,7 +648,7 @@ SurfTriMesh::GetFacetCenter( int nF, Point3d& ptCen, Vector3d& vtN) const
|
|||||||
POLYLINEVECTOR vPL ;
|
POLYLINEVECTOR vPL ;
|
||||||
if ( ! GetFacetLoops( nF, vPL) || vPL.empty())
|
if ( ! GetFacetLoops( nF, vPL) || vPL.empty())
|
||||||
return false ;
|
return false ;
|
||||||
// calcolo il centro del loop esterno (è il primo)
|
// calcolo il centro del loop esterno (è il primo)
|
||||||
PolygonPlane PolyPlane ;
|
PolygonPlane PolyPlane ;
|
||||||
Point3d ptP ;
|
Point3d ptP ;
|
||||||
for ( bool bFound = vPL[0].GetFirstPoint( ptP) ; bFound ; bFound = vPL[0].GetNextPoint( ptP))
|
for ( bool bFound = vPL[0].GetFirstPoint( ptP) ; bFound ; bFound = vPL[0].GetNextPoint( ptP))
|
||||||
@@ -730,7 +732,7 @@ SurfTriMesh::CloneFacet( int nF) const
|
|||||||
// ciclo sui tre vertici
|
// ciclo sui tre vertici
|
||||||
int nIdV[3] ;
|
int nIdV[3] ;
|
||||||
for ( int j = 0 ; j < 3 ; ++ j) {
|
for ( int j = 0 ; j < 3 ; ++ j) {
|
||||||
// verifico se vertice già presente
|
// verifico se vertice già presente
|
||||||
const auto it = PntMap.find( m_vTria[nT].nIdVert[j]) ;
|
const auto it = PntMap.find( m_vTria[nT].nIdVert[j]) ;
|
||||||
if ( it == PntMap.end()) {
|
if ( it == PntMap.end()) {
|
||||||
// aggiungo il vertice
|
// aggiungo il vertice
|
||||||
@@ -773,7 +775,7 @@ SurfTriMesh::RemoveFacet( int nF)
|
|||||||
if ( ! DoCompacting())
|
if ( ! DoCompacting())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
||||||
m_OGrMgr.Reset() ;
|
m_OGrMgr.Reset() ;
|
||||||
ResetHashGrids3d() ;
|
ResetHashGrids3d() ;
|
||||||
|
|
||||||
@@ -878,7 +880,7 @@ SurfTriMesh::UpdateFacetEdging( void)
|
|||||||
m_bFacEdged = false ;
|
m_bFacEdged = false ;
|
||||||
m_vFacEdge.clear() ;
|
m_vFacEdge.clear() ;
|
||||||
|
|
||||||
// verifico validità sfaccettatura
|
// verifico validità sfaccettatura
|
||||||
if ( ! VerifyFaceting())
|
if ( ! VerifyFaceting())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -957,7 +959,7 @@ SurfTriMesh::GetEdge( int nInd, int& nV1, int& nV2, int& nFl, int& nFr, double&
|
|||||||
// verifico stato bordi sfaccettatura
|
// verifico stato bordi sfaccettatura
|
||||||
if ( ! VerifyFacetEdging())
|
if ( ! VerifyFacetEdging())
|
||||||
return false ;
|
return false ;
|
||||||
// verifico la validità dell'indice
|
// verifico la validità dell'indice
|
||||||
if ( nInd < 0 || nInd > int( m_vFacEdge.size()))
|
if ( nInd < 0 || nInd > int( m_vFacEdge.size()))
|
||||||
return SVT_NULL ;
|
return SVT_NULL ;
|
||||||
// recupero i dati
|
// recupero i dati
|
||||||
@@ -980,7 +982,7 @@ SurfTriMesh::GetEdge( int nInd, Point3d& ptP1, Point3d& ptP2, double& dAng) cons
|
|||||||
// verifico stato bordi sfaccettatura
|
// verifico stato bordi sfaccettatura
|
||||||
if ( ! VerifyFacetEdging())
|
if ( ! VerifyFacetEdging())
|
||||||
return false ;
|
return false ;
|
||||||
// verifico la validità dell'indice
|
// verifico la validità dell'indice
|
||||||
if ( nInd < 0 || nInd > int( m_vFacEdge.size()))
|
if ( nInd < 0 || nInd > int( m_vFacEdge.size()))
|
||||||
return SVT_NULL ;
|
return SVT_NULL ;
|
||||||
// recupero i dati
|
// recupero i dati
|
||||||
@@ -1015,3 +1017,149 @@ SurfTriMesh::GetEdges( ICURVEPOVECTOR& vpCurve) const
|
|||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Funzione per il calcolo della curvatura massima e minima in un vertice della superficie TriMesh
|
||||||
|
// dMinK : curvatura minima
|
||||||
|
// vtMinK : versore direzione curvatura minima
|
||||||
|
// dMaxK : curvatura massima
|
||||||
|
// vtMaxK : versore direzione curvatura massima
|
||||||
|
// bPlanar : Flag per indicare le superficie localmente piana
|
||||||
|
// vtNorm : versore normale del piano tangente alla supericie nel vertice
|
||||||
|
bool
|
||||||
|
SurfTriMesh::GetCurvature( int nV,
|
||||||
|
double& dMinK, Vector3d& vtMinK, double& dMaxK, Vector3d& vtMaxK, bool& bPlanar, Vector3d& vtNorm) const
|
||||||
|
{
|
||||||
|
// Controllo la validità della TriMesh e del Vertice
|
||||||
|
if ( ! IsValid())
|
||||||
|
return false ;
|
||||||
|
Point3d ptCurr ;
|
||||||
|
if ( ! GetVertex( nV, ptCurr))
|
||||||
|
return false ;
|
||||||
|
bPlanar = false ;
|
||||||
|
|
||||||
|
// Recupero tutti i vertici attorno al vertice corrente ( se presenza di lato libero, allora errore)
|
||||||
|
INTVECTOR vT ;
|
||||||
|
bool bCirc ;
|
||||||
|
if ( ! GetAllTriaAroundVertex( nV, vT, bCirc) || ! bCirc)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Calcolo la normale del vertice pesata mediante angolo sotteso e distanza baricentrica
|
||||||
|
// ["Estimation Normal Vector of Triangular Mesh Vertex by Angle and Centroid Weights"]
|
||||||
|
// Controllo anche di non essere in presenza di uno spigolo vivo
|
||||||
|
INTSET setIndTriaNeightbors ;
|
||||||
|
bool bFirstTria = true ;
|
||||||
|
Vector3d vtNFirstTria = V_NULL ;
|
||||||
|
for ( const int& nT : vT) {
|
||||||
|
// Recupero il triangolo corrente
|
||||||
|
Triangle3d Tria ;
|
||||||
|
int nIdVert[3] ;
|
||||||
|
if ( ! GetTriangle( nT, Tria) || ! GetTriangle( nT, nIdVert))
|
||||||
|
return false ;
|
||||||
|
// Se il triangolo ha area troppo piccola, lo scarto
|
||||||
|
if ( Tria.GetArea() < EPS_SMALL)
|
||||||
|
continue ;
|
||||||
|
// Se primo triangolo salvo la sua normale di riferimento per successivi confronti
|
||||||
|
if ( bFirstTria) {
|
||||||
|
vtNFirstTria = Tria.GetN() ;
|
||||||
|
bFirstTria = false ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Se spigolo vivo, la curvatura non può esistere
|
||||||
|
if ( Tria.GetN() * vtNFirstTria < m_dCosSmAng - EPS_SMALL)
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
// Recupero le direzioni delle semirette per l'angolo al vertice corrente
|
||||||
|
Vector3d vtDir0 = V_NULL, vtDir1 = V_NULL ;
|
||||||
|
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||||
|
if ( AreSamePointApprox( Tria.GetP( i), ptCurr)) {
|
||||||
|
vtDir0 = Tria.GetP( ( i + 1) % 3) - Tria.GetP( i) ;
|
||||||
|
vtDir0.Normalize() ;
|
||||||
|
vtDir1 = Tria.GetP( ( i + 2) % 3) - Tria.GetP( i) ;
|
||||||
|
vtDir1.Normalize() ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||||
|
if ( nV == nIdVert[i]) {
|
||||||
|
setIndTriaNeightbors.insert( nIdVert[( i + 1) % 3]) ;
|
||||||
|
setIndTriaNeightbors.insert( nIdVert[( i + 2) % 3]) ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Calcolo l'angolo sotteso
|
||||||
|
double dCosTheta = max( -1., min( 1., ( vtDir0 * vtDir1))) ;
|
||||||
|
double dTheta = acos( dCosTheta) ;
|
||||||
|
// Calcolo la distanza baricentrica
|
||||||
|
double dSqBarDist = max( EPS_SMALL, ( ptCurr - Tria.GetCentroid()).SqLen()) ;
|
||||||
|
// Aggiorno il contributo della normale al vertice
|
||||||
|
vtNorm += ( ( dTheta / dSqBarDist) * Tria.GetN()) ;
|
||||||
|
}
|
||||||
|
vtNorm.Normalize() ;
|
||||||
|
|
||||||
|
// [ESTIMATING CURVATURE ON TRIANGULAR MESHES, cap. 2.1. Fitting Methods,
|
||||||
|
// par. 2.1.2. Quadric Fitting]
|
||||||
|
// [https://people.eecs.berkeley.edu/~jrs/meshpapers/GatzkeGrimm.pdf]
|
||||||
|
|
||||||
|
// Definisco il piano tangente al vertice corrente
|
||||||
|
Plane3d plTan ;
|
||||||
|
if ( ! plTan.Set( ptCurr, vtNorm))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// Proietto i punti Neightbors(1) sul piano tangete ( senza ripeterli)
|
||||||
|
BIPNTVECTOR vPtPtProj ; vPtPtProj.reserve( setIndTriaNeightbors.size()) ;
|
||||||
|
for ( auto nIter = setIndTriaNeightbors.begin() ; nIter != setIndTriaNeightbors.end() ; ++ nIter) {
|
||||||
|
Point3d ptNeightbors ;
|
||||||
|
if ( ! GetVertex( *nIter, ptNeightbors))
|
||||||
|
return false ;
|
||||||
|
vPtPtProj.emplace_back( make_pair( ptNeightbors, ProjectPointOnPlane( ptNeightbors, plTan))) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recupero due versori perpendicolari nel piano definito
|
||||||
|
Vector3d vtTan1 = V_NULL ;
|
||||||
|
if ( abs( vtNorm.x) < 1./64. && abs( vtNorm.y) < 1./64.)
|
||||||
|
vtTan1 = Y_AX ^ vtNorm ;
|
||||||
|
else
|
||||||
|
vtTan1 = Z_AX ^ vtNorm ;
|
||||||
|
vtTan1.Normalize() ;
|
||||||
|
Vector3d vtTan2 = vtNorm ^ vtTan1 ;
|
||||||
|
vtTan2.Normalize() ;
|
||||||
|
|
||||||
|
// Sistema da risolvere mediante minimi quadrati : z(u,v) = Au^2 + Buv + Cv^2
|
||||||
|
// Questo sistema è molto più semplice e robusto rispetto a z(u,v) = Au^2 + Buv + Cv^2 + Du + Ev + F
|
||||||
|
// per il fatto che ora le coordinate sono in locale al piano tangente alla superficie ( mettendo
|
||||||
|
// quindi a 0 i coefficienti del primo ordine e il termine noto F)
|
||||||
|
// Definizione della matrice A(Nx3)
|
||||||
|
const int nPts = int( vPtPtProj.size()) ;
|
||||||
|
Eigen::MatrixXd mat_A( nPts, 3) ;
|
||||||
|
Eigen::VectorXd vec_b( nPts) ;
|
||||||
|
for ( int i = 0 ; i < nPts ; ++ i) {
|
||||||
|
Vector3d vtEdgeProj = vPtPtProj[i].second - ptCurr ;
|
||||||
|
Vector3d vtEdge = ( vPtPtProj[i].first - vPtPtProj[i].second) ;
|
||||||
|
double dU = vtEdgeProj * vtTan1 ;
|
||||||
|
double dV = vtEdgeProj * vtTan2 ;
|
||||||
|
double dW = vtEdge * vtNorm ;
|
||||||
|
mat_A( i, 0) = dU * dU ;
|
||||||
|
mat_A( i, 1) = dU * dV ;
|
||||||
|
mat_A( i, 2) = dV * dV ;
|
||||||
|
vec_b( i) = dW ;
|
||||||
|
}
|
||||||
|
// Risoluzione del sistema
|
||||||
|
Eigen::VectorXd vec_x = mat_A.colPivHouseholderQr().solve( vec_b) ;
|
||||||
|
|
||||||
|
// Costruzione della matrice hessiana
|
||||||
|
Eigen::Matrix2d mat_H {{ 2. * vec_x( 0), vec_x( 1)},
|
||||||
|
{ vec_x( 1), 2. * vec_x( 2)}} ;
|
||||||
|
|
||||||
|
// Calcolo gli autovalori ( quindi le curvature principali) e restituisco i risultati
|
||||||
|
Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> Solver( mat_H) ;
|
||||||
|
dMinK = Solver.eigenvalues()( 0) ;
|
||||||
|
dMaxK = Solver.eigenvalues()( 1) ;
|
||||||
|
Eigen::Vector2d dir_Min = Solver.eigenvectors().col( 0) ;
|
||||||
|
Eigen::Vector2d dir_Max = Solver.eigenvectors().col( 1) ;
|
||||||
|
vtMinK = dir_Min( 0) * vtTan1 + dir_Min( 1) * vtTan2 ;
|
||||||
|
vtMaxK = dir_Max( 0) * vtTan1 + dir_Max( 1) * vtTan2 ;
|
||||||
|
bPlanar = ( abs( dMinK) < EPS_SMALL && abs( dMaxK) < EPS_SMALL) ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,791 @@
|
|||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// EgalTech 2025
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// File : SurfTriMeshOffset.cpp Data : 07.07.25 Versione : 2.7g1
|
||||||
|
// Contenuto : Implementazione funzione per Offset di Superfici TriMesh.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Modifiche : 10.06.25 RE Creazione modulo.
|
||||||
|
// 10.06.25 RE Offset di superfici chiuse.
|
||||||
|
// 04.07.25 RE Thickening Offset di superfici generiche.
|
||||||
|
// 10.12.25 RE Creazione superfici Shell.
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//--------------------------- Include ----------------------------------------
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "VolZmap.h"
|
||||||
|
#include "SurfTriMesh.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointSurfTm.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
|
#include "/EgtDev/Include/EGkDistPointTria.h"
|
||||||
|
#include "/EgtDev/Include/EGkSurfTriMeshAux.h"
|
||||||
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||||
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||||
|
#include <future>
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#if DEBUG
|
||||||
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkGeoVector3d.h"
|
||||||
|
#include "/EgtDev/Include/EGkStmStandard.h"
|
||||||
|
#include "/EgtDev/Include/EgtPerfCounter.h"
|
||||||
|
std::vector<IGeoObj*> VT ;
|
||||||
|
std::vector<Color> VC ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static ISurfTriMesh*
|
||||||
|
SumStm( const CISURFTMPVECTOR& vStm)
|
||||||
|
{
|
||||||
|
// se vettore vuoto, non faccio nulla
|
||||||
|
if ( vStm.empty())
|
||||||
|
return nullptr ;
|
||||||
|
// definisco la superficie somma tra tutte ( la prima deve essere valida)
|
||||||
|
PtrOwner<ISurfTriMesh> pStmAdd( CreateSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pStmAdd))
|
||||||
|
return nullptr ;
|
||||||
|
// scorro le superfici
|
||||||
|
for ( const ISurfTriMesh* pStm : vStm) {
|
||||||
|
if ( pStm == nullptr || ! pStm->IsValid() || pStm->GetTriangleCount() == 0)
|
||||||
|
continue ;
|
||||||
|
if ( ! pStmAdd->IsValid() || pStmAdd->GetTriangleCount() == 0) {
|
||||||
|
if ( ! pStmAdd->CopyFrom( pStm))
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pStmAdd->Add( *pStm) ;
|
||||||
|
}
|
||||||
|
// restituisco la superficie ottenuta
|
||||||
|
return ( Release( pStmAdd)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Funzioni per la distanza tra punto e superficie TriMesh in parallelo
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
BoundingBoxDifference( const BBox3d& boxA, const BBox3d& boxB, BOXVECTOR& vBoxDiff)
|
||||||
|
{
|
||||||
|
// svuoto il risultato
|
||||||
|
vBoxDiff.clear() ;
|
||||||
|
// se box A vuoto, risultato vuoto
|
||||||
|
if ( boxA.IsEmpty())
|
||||||
|
return false ;
|
||||||
|
// 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) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// recupero i punti estremi dei box A e Intersezione
|
||||||
|
Point3d ptMinA, ptMaxA ; boxA.GetMinMax( ptMinA, ptMaxA) ;
|
||||||
|
Point3d ptMinInt, ptMaxInt ; boxInt.GetMinMax( ptMinInt, ptMaxInt) ;
|
||||||
|
// sotto
|
||||||
|
if ( ptMinInt.z - ptMinA.z > EPS_SMALL) {
|
||||||
|
BBox3d boxD( ptMinA, Point3d( ptMaxA.x, ptMaxA.y, ptMinInt.z)) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// sopra
|
||||||
|
if ( ptMaxA.z - ptMaxInt.z > EPS_SMALL) {
|
||||||
|
BBox3d boxD( Point3d( ptMinA.x, ptMinA.y, ptMaxInt.z), ptMaxA) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// davanti
|
||||||
|
if ( ptMinInt.y - ptMinA.y > EPS_SMALL) {
|
||||||
|
BBox3d boxD( Point3d( ptMinA.x, ptMinA.y, ptMinInt.z), Point3d( ptMaxA.x, ptMinInt.y, ptMaxInt.z)) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// dietro
|
||||||
|
if ( ptMaxA.y - ptMaxInt.y > EPS_SMALL) {
|
||||||
|
BBox3d boxD( Point3d( ptMinA.x, ptMaxInt.y, ptMinInt.z), Point3d( ptMaxA.x, ptMaxA.y, ptMaxInt.z)) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// sinistra
|
||||||
|
if ( ptMinInt.x - ptMinA.x > EPS_SMALL) {
|
||||||
|
BBox3d boxD( Point3d( ptMinA.x, ptMinInt.y, ptMinInt.z), Point3d( ptMinInt.x, ptMaxInt.y, ptMaxInt.z)) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// destra
|
||||||
|
if ( ptMaxA.y - ptMaxInt.y > EPS_SMALL) {
|
||||||
|
BBox3d boxD( Point3d( ptMaxInt.x, ptMinInt.y, ptMinInt.z), Point3d( ptMaxA.x, ptMaxInt.y, ptMaxInt.z)) ;
|
||||||
|
vBoxDiff.emplace_back( boxD) ;
|
||||||
|
}
|
||||||
|
// risultato
|
||||||
|
return ( ! vBoxDiff.empty()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
DistPointSurfTmMultiThread( const Point3d& ptP, const SurfTriMesh& SurfTm, double& dDist,
|
||||||
|
bool& bIsInside, INTVECTOR& vIndClosestTria)
|
||||||
|
{
|
||||||
|
// verifico che la supercicie sia valida
|
||||||
|
if ( ! SurfTm.IsValid())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// inizializzo distanza non calcolata
|
||||||
|
dDist = - 1. ;
|
||||||
|
// vettore di indici dei triangoli più vicini inizialmente vuoto
|
||||||
|
vIndClosestTria.clear() ;
|
||||||
|
// vettore dei flag temporanei inizialmente tutto a 0
|
||||||
|
INTVECTOR vIntFlags( SurfTm.GetTriangleCount(), 0) ;
|
||||||
|
|
||||||
|
// recupero e verifico il box locale della superficie
|
||||||
|
BBox3d b3Stm = SurfTm.GetAllTriaBox() ;
|
||||||
|
if ( b3Stm.IsEmpty())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// 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 ;
|
||||||
|
double dBoxHalfLenY = max( max( ptMin.y - ptP.y, ptP.y - ptMax.y), 0.) + dDeltaLen ;
|
||||||
|
double dBoxHalfLenZ = max( max( ptMin.z - ptP.z, ptP.z - ptMax.z), 0.) + dDeltaLen ;
|
||||||
|
// considero anche il box precedente per poter analizzare solo il volume differenza tra i due
|
||||||
|
BBox3d boxPPrev( ptP) ;
|
||||||
|
BBox3d boxP( ptP, dBoxHalfLenX, dBoxHalfLenY, dBoxHalfLenZ) ;
|
||||||
|
// variabili distanza minima, indice del triangolo di distanza minima, punto di distanza minima
|
||||||
|
double dMinDist = DBL_MAX ;
|
||||||
|
int nMinDistTriaIndex = SVT_NULL ;
|
||||||
|
Point3d ptMinDistPoint ;
|
||||||
|
// finché non si verifica la condizione di terminazione ingrandisco il box.
|
||||||
|
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
|
||||||
|
BOXVECTOR vBox ;
|
||||||
|
BoundingBoxDifference( boxP, boxPPrev, vBox) ;
|
||||||
|
// Ciclo sui box differenza
|
||||||
|
bool bCollide = false ;
|
||||||
|
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.DistFromPoint( ptP) > dMinDist)
|
||||||
|
continue ;
|
||||||
|
// ricerca sui triangoli nel box
|
||||||
|
bCollide = true ;
|
||||||
|
INTVECTOR vnIds ;
|
||||||
|
if ( SurfTm.GetAllTriaOverlapBox( b3Int, vnIds)) {
|
||||||
|
// ciclo sui triangoli del sotto-box corrente
|
||||||
|
for ( auto nT : vnIds) {
|
||||||
|
Triangle3d trCurTria ;
|
||||||
|
if ( vIntFlags[nT] == 0 && SurfTm.GetTriangle( nT, trCurTria)) {
|
||||||
|
vIntFlags[nT] = 1 ;
|
||||||
|
DistPointTriangle distPT( ptP, trCurTria) ;
|
||||||
|
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 || dMinDist < EPS_SMALL)
|
||||||
|
bContinue = false ;
|
||||||
|
else {
|
||||||
|
boxPPrev = boxP ;
|
||||||
|
boxP.Expand( dDeltaLen) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se non ho trovato nessun triangolo, errore
|
||||||
|
if ( nMinDistTriaIndex == SVT_NULL)
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// riempio il vettore dei triangoli a minima distanza
|
||||||
|
for ( auto& Tria : vTria)
|
||||||
|
vIndClosestTria.emplace_back( Tria.first) ;
|
||||||
|
// salvo la distanza
|
||||||
|
dDist = dMinDist ;
|
||||||
|
|
||||||
|
// determino il Side
|
||||||
|
if ( dDist < EPS_SMALL) {
|
||||||
|
bIsInside = false ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
// se ho solo un triangolo
|
||||||
|
else if ( int( vTria.size()) == 1) {
|
||||||
|
bIsInside = ( ( ptP - ptMinDistPoint) * vTria.back().second.GetN() < - EPS_SMALL) ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
if ( ( ptP - vTria[i].second.GetP( 0)) * vTria[i].second.GetN() < - EPS_SMALL)
|
||||||
|
bInside = true ;
|
||||||
|
else
|
||||||
|
bOutside = true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bIsInside = false ;
|
||||||
|
if ( bOutside == bInside) {
|
||||||
|
Point3d ptBar_tot ;
|
||||||
|
for ( const auto& Tria : vTria)
|
||||||
|
ptBar_tot += Tria.second.GetCentroid() ;
|
||||||
|
for ( const auto& Tria : vTria) {
|
||||||
|
Point3d ptInters1, ptInters2 ;
|
||||||
|
int nType = IntersLineTria( ptP, ptBar_tot, Tria.second, ptInters1, ptInters2) ;
|
||||||
|
if ( nType == ILTT_IN) {
|
||||||
|
DistPointTriangle( ptP, Tria.second).GetMinDistPoint( ptMinDistPoint) ;
|
||||||
|
bIsInside = ( ( ptP - ptMinDistPoint) * Tria.second.GetN() < - EPS_SMALL) ;
|
||||||
|
nMinDistTriaIndex = Tria.first ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bIsInside = bInside ;
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool
|
||||||
|
ClassifyTrianglesMultiThread( const TRIA3DEXVECTOR& vTria, int nIndS, int nIndE,
|
||||||
|
const SurfTriMesh& SurfTm, double dOffs, double dPrec,
|
||||||
|
bool bSaveInside, BOOLVECTOR& vbSafe)
|
||||||
|
{
|
||||||
|
// verifico che la superficie sia valida
|
||||||
|
if ( ! SurfTm.IsValid())
|
||||||
|
return false ;
|
||||||
|
// verifico la validità degli indici
|
||||||
|
if ( nIndS < 0 || nIndE >= int( vTria.size()))
|
||||||
|
return false ;
|
||||||
|
// verifico la dimensione dei vettori
|
||||||
|
if ( vTria.size() != vbSafe.size())
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// scorro gli indici dei triangoli da classificare
|
||||||
|
for ( int k = nIndS ; k <= nIndE ; ++ k) {
|
||||||
|
// recupero il triangolo corrente
|
||||||
|
const Triangle3dEx& Tria = vTria[k] ;
|
||||||
|
// preparo gli elementi di classificazione
|
||||||
|
DBLVECTOR vDists ; vDists.resize( 3) ;
|
||||||
|
INTMATRIX matIndClosestTria ; matIndClosestTria.resize( 3) ;
|
||||||
|
// verifico che i suoi punti siano distanti almeno |dOffs| - dTol dalla superficie
|
||||||
|
vbSafe[k] = true ;
|
||||||
|
for ( int i = 0 ; vbSafe[k] && i < 3 ; ++ i) {
|
||||||
|
bool bIsInside = false ;
|
||||||
|
DistPointSurfTmMultiThread( Tria.GetP( i), SurfTm, vDists[i], bIsInside, matIndClosestTria[i]) ;
|
||||||
|
vbSafe[k] = ( ( vDists[i] > abs( dOffs) - 0.25 * dPrec) &&
|
||||||
|
( vDists[i] < abs( dOffs) + 0.25 * dPrec) &&
|
||||||
|
( bIsInside == bSaveInside)) ;
|
||||||
|
}
|
||||||
|
// se tutti sufficientemente distanti
|
||||||
|
if ( vbSafe[k]) {
|
||||||
|
// i triangoli a minima distanza devono avere normale simile
|
||||||
|
bool bPerp = true ;
|
||||||
|
for ( int i = 0 ; bPerp && i < 3 ; ++ i) {
|
||||||
|
for ( int j = 0 ; bPerp && j < int( matIndClosestTria[i].size()) ; ++ j) {
|
||||||
|
Triangle3d TriaCloser ;
|
||||||
|
SurfTm.GetTriangle( matIndClosestTria[i][j], TriaCloser) ;
|
||||||
|
bPerp = ( abs( Tria.GetN() * TriaCloser.GetN()) < cos( 30. * DEGTORAD)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vbSafe[k] = ( ! bPerp) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Funzione che crea l'Offset di una superficie TriMesh
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
CreateSurfTriMeshOffset( const ISurfTriMesh* pStm, double dOffs, double dPrec, int nType)
|
||||||
|
{
|
||||||
|
return ( CreateSurfTriMeshesOffset( { pStm}, dOffs, dPrec, nType)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Funzione che crea il Fat Offset di una superficie TriMesh
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
CreateSurfTriMeshThickeningOffset( const ISurfTriMesh* pStm, double dOffs, double dPrec, int nType)
|
||||||
|
{
|
||||||
|
return ( CreateSurfTriMeshesThickeningOffset( { pStm}, dOffs, dPrec, nType)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Funzione che crea l'Offset di un insieme di superfici
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
CreateSurfTriMeshesOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dPrec, int nType)
|
||||||
|
{
|
||||||
|
// se vettore delle superfici vuoto, non faccio nulla
|
||||||
|
if ( vStm.empty())
|
||||||
|
return nullptr ;
|
||||||
|
// controllo sul valore di tolleranza lineare
|
||||||
|
double dMyPrec = max( dPrec, 100. * EPS_SMALL) ;
|
||||||
|
// --- NB. ( Il valore di Offset deve essere maggiore di 10 * EPS_SMALL in valore assoluto)
|
||||||
|
// Nel caso sia minore, restituisco semplicemente la somma delle superfici
|
||||||
|
// ( questo valore serve per rimanere coerente con l'Offset delle curve)
|
||||||
|
if ( abs( dOffs) < 10. * EPS_SMALL)
|
||||||
|
return SumStm( vStm) ;
|
||||||
|
|
||||||
|
// creo lo Zmap associato alle superfici TriMesh
|
||||||
|
VolZmap myVolZmap ;
|
||||||
|
if ( ! myVolZmap.CreateFromTriMeshOffset( vStm, dOffs, dMyPrec, nType))
|
||||||
|
return nullptr ;
|
||||||
|
if ( ! myVolZmap.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// recupero le superfici aperte
|
||||||
|
CISURFTMPVECTOR vStmOpen ;
|
||||||
|
for ( const ISurfTriMesh* pStm : vStm) {
|
||||||
|
if ( pStm != nullptr && pStm->IsValid() && ! pStm->IsClosed())
|
||||||
|
vStmOpen.emplace_back( pStm) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- se non ho superfici aperte
|
||||||
|
if ( vStmOpen.empty()) {
|
||||||
|
// restituisco la superficie TriMesh di Offset
|
||||||
|
return ( myVolZmap.GetSurfTriMesh()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- se ho delle superfici chiuse
|
||||||
|
TRIA3DEXVECTOR vAllTria, vTriaOffs ;
|
||||||
|
for ( int nB = 0 ; nB < myVolZmap.GetBlockCount() ; ++ nB) {
|
||||||
|
TRIA3DEXVECTOR vTria, vTriaSafe ;
|
||||||
|
myVolZmap.GetBlockTriangles( nB, vTria) ;
|
||||||
|
#if DEBUG
|
||||||
|
TRIA3DVECTOR vTriaUnsafe ;
|
||||||
|
#endif
|
||||||
|
for ( int nT = 0 ; nT < int( vTria.size()) ; ++ nT) {
|
||||||
|
Triangle3dEx& Tria = vTria[nT] ;
|
||||||
|
BBox3d BBoxTria ;
|
||||||
|
Tria.GetLocalBBox( BBoxTria) ;
|
||||||
|
// azzero flag di colore
|
||||||
|
vAllTria.push_back( Tria) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// classifico i triangoli
|
||||||
|
PtrOwner<const SurfTriMesh> pStmBasic( nullptr) ;
|
||||||
|
if ( int( vStmOpen.size() == 1))
|
||||||
|
pStmBasic.Set( GetBasicSurfTriMesh( CloneSurfTriMesh( vStmOpen[0]))) ;
|
||||||
|
else {
|
||||||
|
StmFromTriangleSoup AllOpenStmSoup ; AllOpenStmSoup.Start() ;
|
||||||
|
for ( const ISurfTriMesh* pStmOpen : vStmOpen) {
|
||||||
|
if ( pStmOpen != nullptr && pStmOpen->IsValid()) {
|
||||||
|
for ( int nT = 0 ; nT < pStmOpen->GetTriangleCount() ; ++ nT) {
|
||||||
|
Triangle3d Tria ;
|
||||||
|
if ( pStmOpen->GetTriangle( nT, Tria))
|
||||||
|
AllOpenStmSoup.AddTriangle( Tria) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AllOpenStmSoup.End() ;
|
||||||
|
pStmBasic.Set( GetBasicSurfTriMesh( AllOpenStmSoup.GetSurf())) ;
|
||||||
|
}
|
||||||
|
if ( pStmBasic == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
BBox3d b3Stm = pStmBasic->GetAllTriaBox() ;
|
||||||
|
if ( b3Stm.IsEmpty())
|
||||||
|
return nullptr ;
|
||||||
|
// numero di triangoli da analizzare
|
||||||
|
int nTriaCnt = int( vAllTria.size()) ;
|
||||||
|
// definisco un vettore di Flag per i triangoli già visitati
|
||||||
|
INTVECTOR vIntFlags( pStmBasic->GetTriangleCount()) ;
|
||||||
|
// numero massimo di thread concorrenti
|
||||||
|
int nThreadMax = thread::hardware_concurrency() ;
|
||||||
|
bool bOk = true ;
|
||||||
|
BOOLVECTOR vbSafeTria( vAllTria.size(), true) ;
|
||||||
|
if ( nThreadMax <= 1 || nTriaCnt < 50)
|
||||||
|
ClassifyTrianglesMultiThread( vAllTria, 0, nTriaCnt - 1, *pStmBasic, abs( dOffs), dPrec, ( dOffs < 0.), vbSafeTria) ;
|
||||||
|
else {
|
||||||
|
const int MAX_PARTS = 32 ;
|
||||||
|
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||||
|
// calcolo le parti del vettore
|
||||||
|
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||||
|
int nPartDim = nTriaCnt / nPartCnt + 1 ;
|
||||||
|
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||||
|
vFstLst[i].first = i * nPartDim ;
|
||||||
|
vFstLst[i].second = min( ( i + 1) * nPartDim, nTriaCnt) - 1 ;
|
||||||
|
}
|
||||||
|
// processo le parti
|
||||||
|
future<bool> vRes[MAX_PARTS] ;
|
||||||
|
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||||
|
vRes[i] = async( launch::async, &ClassifyTrianglesMultiThread, cref( vAllTria), vFstLst[i].first,
|
||||||
|
vFstLst[i].second, cref( *pStmBasic), abs( dOffs), dPrec, ( dOffs < 0.), ref( vbSafeTria)) ;
|
||||||
|
}
|
||||||
|
// attendo i risultati
|
||||||
|
int nFin = 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 ( ! bOk)
|
||||||
|
return nullptr ;
|
||||||
|
TRIA3DEXVECTOR vTriaSafe ; vTriaSafe.reserve( vAllTria.size()) ;
|
||||||
|
#if DEBUG
|
||||||
|
TRIA3DEXVECTOR vTriaUnSafe ; vTriaUnSafe.reserve( vAllTria.size()) ;
|
||||||
|
#endif
|
||||||
|
for ( int i = 0 ; i < int( vAllTria.size()) ; ++ i) {
|
||||||
|
if ( vbSafeTria[i])
|
||||||
|
vTriaSafe.emplace_back( vAllTria[i]) ;
|
||||||
|
#if DEBUG
|
||||||
|
if ( ! vbSafeTria[i])
|
||||||
|
vTriaUnSafe.emplace_back( vAllTria[i]) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// definisco la superficie con i soli triangoli validi
|
||||||
|
StmFromTriangleSoup TriaSoup ; TriaSoup.Start() ;
|
||||||
|
for ( const Triangle3d& SafeTria : vTriaSafe)
|
||||||
|
TriaSoup.AddTriangle( SafeTria) ;
|
||||||
|
TriaSoup.End() ;
|
||||||
|
PtrOwner<ISurfTriMesh> pStmOffs( TriaSoup.GetSurf()) ;
|
||||||
|
if ( IsNull( pStmOffs) || ! pStmOffs->IsValid() || pStmOffs->GetTriangleCount() == 0)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
StmFromTriangleSoup _invalidSoup ; _invalidSoup.Start() ;
|
||||||
|
for ( const Triangle3d& _unsafeTria : vTriaUnSafe)
|
||||||
|
_invalidSoup.AddTriangle( _unsafeTria) ;
|
||||||
|
_invalidSoup.End() ;
|
||||||
|
VT.emplace_back( pStmOffs->Clone()) ;
|
||||||
|
VC.emplace_back( LIME) ;
|
||||||
|
VT.emplace_back( _invalidSoup.GetSurf()) ;
|
||||||
|
VC.emplace_back( RED) ;
|
||||||
|
SaveGeoObj( VT, VC, "C:\\Temp\\TriangleSelection.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ( Release( pStmOffs)) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
//* Funzione che crea il Fat Offset di un insieme di superfici
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
CreateSurfTriMeshesThickeningOffset( const CISURFTMPVECTOR& vStm, double dOffs, double dPrec, int nType)
|
||||||
|
{
|
||||||
|
// se vettore delle superfici vuoto, non faccio nulla
|
||||||
|
if ( vStm.empty())
|
||||||
|
return nullptr ;
|
||||||
|
// controllo sul valore di tolleranza lineare
|
||||||
|
double dMyPrec = max( dPrec, 100 * EPS_SMALL) ;
|
||||||
|
// --- NB. ( Il valore di Offset deve essere maggiore di 10 * EPS_SMALL in valore assoluto)
|
||||||
|
// Nel caso sia minore, restituisco semplicemente la somma delle superfici
|
||||||
|
// ( questo valore serve per rimanere coerente con l'Offset delle curve)
|
||||||
|
if ( abs( dOffs) < 10 * EPS_SMALL)
|
||||||
|
return SumStm( vStm) ;
|
||||||
|
|
||||||
|
// creo lo Zmap associato alle superfici TriMesh
|
||||||
|
VolZmap OneVolZmap ;
|
||||||
|
if ( ! OneVolZmap.CreateFromTriMeshThickeningOffset( vStm, dOffs, dMyPrec, nType))
|
||||||
|
return nullptr ;
|
||||||
|
if ( ! OneVolZmap.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// restituisco la superficie TriMesh
|
||||||
|
return ( OneVolZmap.GetSurfTriMesh()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Funzione per creare la Superficie TriMesh Shell da una Trimesh aperta
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
CreateSurfTriMeshShell( const ISurfTriMesh* pStm, double dThick, double dPrec)
|
||||||
|
{
|
||||||
|
// verifico che la superficie sia valida ed aperta
|
||||||
|
if ( pStm == nullptr || ! pStm->IsValid() || pStm->IsClosed())
|
||||||
|
return nullptr ;
|
||||||
|
// lo spessore deve essere sempre positivo, il verso è sempre dato dalla normale dei triangoli
|
||||||
|
dThick = - max( 10. * EPS_SMALL, abs( dThick)) ;
|
||||||
|
|
||||||
|
// creo il suo Offset ( salvandomi lo Zmap per l'orientamento)
|
||||||
|
#if DEBUG
|
||||||
|
PerformanceCounter PC ; PC.Start() ;
|
||||||
|
#endif
|
||||||
|
VolZmap myVolZMap ;
|
||||||
|
if ( ! myVolZMap.CreateFromTriMeshOffset( { pStm}, dThick, dPrec))
|
||||||
|
return nullptr ;
|
||||||
|
if ( ! myVolZMap.IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
#if DEBUG
|
||||||
|
LOG_INFO( GetEGkLogger(), ( string{ "Tria Time : "} + ToString( PC.Stop())).c_str()) ;
|
||||||
|
VT.clear() ; VC.clear() ;
|
||||||
|
VT.emplace_back( myVolZMap.Clone()) ;
|
||||||
|
VC.emplace_back( BLACK) ;
|
||||||
|
VT.emplace_back( pStm->Clone()) ;
|
||||||
|
VC.emplace_back( YELLOW) ;
|
||||||
|
SaveGeoObj( VT, VC, "C:\\Temp\\VolZMapOffs.nge") ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
VT.clear() ; VC.clear() ;
|
||||||
|
PC.Start() ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// recupero i triangoli dallo ZMap creato
|
||||||
|
TRIA3DEXVECTOR vAllTria, vTriaOffs ;
|
||||||
|
for ( int nB = 0 ; nB < myVolZMap.GetBlockCount() ; ++ nB) {
|
||||||
|
TRIA3DEXVECTOR vTria, vTriaSafe ;
|
||||||
|
myVolZMap.GetBlockTriangles( nB, vTria) ;
|
||||||
|
#if DEBUG
|
||||||
|
TRIA3DVECTOR vTriaUnsafe ;
|
||||||
|
#endif
|
||||||
|
for ( int nT = 0 ; nT < int( vTria.size()) ; ++ nT) {
|
||||||
|
Triangle3dEx& Tria = vTria[nT] ;
|
||||||
|
BBox3d BBoxTria ;
|
||||||
|
Tria.GetLocalBBox( BBoxTria) ;
|
||||||
|
// azzero flag di colore
|
||||||
|
vAllTria.push_back( Tria) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// classifico i triangoli
|
||||||
|
const SurfTriMesh* pStmBasic = GetBasicSurfTriMesh( pStm) ;
|
||||||
|
if ( pStmBasic == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
BBox3d b3Stm = pStmBasic->GetAllTriaBox() ;
|
||||||
|
if ( b3Stm.IsEmpty())
|
||||||
|
return nullptr ;
|
||||||
|
// numero di triangoli da analizzare
|
||||||
|
int nTriaCnt = int( vAllTria.size()) ;
|
||||||
|
// definisco un vettore di Flag per i triangoli già visitati
|
||||||
|
INTVECTOR vIntFlags( pStmBasic->GetTriangleCount()) ;
|
||||||
|
// numero massimo di thread concorrenti
|
||||||
|
int nThreadMax = thread::hardware_concurrency() ;
|
||||||
|
bool bOk = true ;
|
||||||
|
BOOLVECTOR vbSafeTria( vAllTria.size(), true) ;
|
||||||
|
if ( nThreadMax <= 1 || nTriaCnt < 50)
|
||||||
|
ClassifyTrianglesMultiThread( vAllTria, 0, nTriaCnt - 1, *pStmBasic, dThick, dPrec, true, vbSafeTria) ;
|
||||||
|
else {
|
||||||
|
const int MAX_PARTS = 32 ;
|
||||||
|
INTINTVECTOR vFstLst( MAX_PARTS) ;
|
||||||
|
// calcolo le parti del vettore
|
||||||
|
int nPartCnt = min( nThreadMax, MAX_PARTS) ;
|
||||||
|
int nPartDim = nTriaCnt / nPartCnt + 1 ;
|
||||||
|
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||||
|
vFstLst[i].first = i * nPartDim ;
|
||||||
|
vFstLst[i].second = min( ( i + 1) * nPartDim, nTriaCnt) - 1 ;
|
||||||
|
}
|
||||||
|
// processo le parti
|
||||||
|
future<bool> vRes[MAX_PARTS] ;
|
||||||
|
for ( int i = 0 ; i < nPartCnt ; ++ i) {
|
||||||
|
vRes[i] = async( launch::async, &ClassifyTrianglesMultiThread, cref( vAllTria), vFstLst[i].first,
|
||||||
|
vFstLst[i].second, cref( *pStmBasic), dThick, dPrec, true, ref( vbSafeTria)) ;
|
||||||
|
}
|
||||||
|
// attendo i risultati
|
||||||
|
int nFin = 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 ( ! bOk)
|
||||||
|
return nullptr ;
|
||||||
|
TRIA3DEXVECTOR vTriaSafe ; vTriaSafe.reserve( vAllTria.size()) ;
|
||||||
|
#if DEBUG
|
||||||
|
TRIA3DEXVECTOR vTriaUnSafe ; vTriaUnSafe.reserve( vAllTria.size()) ;
|
||||||
|
#endif
|
||||||
|
for ( int i = 0 ; i < int( vAllTria.size()) ; ++ i) {
|
||||||
|
if ( vbSafeTria[i])
|
||||||
|
vTriaSafe.emplace_back( vAllTria[i]) ;
|
||||||
|
#if DEBUG
|
||||||
|
if ( ! vbSafeTria[i])
|
||||||
|
vTriaUnSafe.emplace_back( vAllTria[i]) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// definisco la superficie con i soli triangoli validi
|
||||||
|
StmFromTriangleSoup TriaSoup ; TriaSoup.Start() ;
|
||||||
|
for ( const Triangle3d& SafeTria : vTriaSafe)
|
||||||
|
TriaSoup.AddTriangle( SafeTria) ;
|
||||||
|
TriaSoup.End() ;
|
||||||
|
PtrOwner<ISurfTriMesh> pStmOffs( TriaSoup.GetSurf()) ;
|
||||||
|
if ( IsNull( pStmOffs) || ! pStmOffs->IsValid() || pStmOffs->GetTriangleCount() == 0)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
LOG_INFO( GetEGkLogger(), ( string{ "Tria Time ( exceed Approx) : "} + ToString( PC.Stop())).c_str()) ;
|
||||||
|
StmFromTriangleSoup _invalidSoup ; _invalidSoup.Start() ;
|
||||||
|
for ( const Triangle3d& _unsafeTria : vTriaUnSafe)
|
||||||
|
_invalidSoup.AddTriangle( _unsafeTria) ;
|
||||||
|
_invalidSoup.End() ;
|
||||||
|
VT.emplace_back( pStmOffs->Clone()) ;
|
||||||
|
VC.emplace_back( LIME) ;
|
||||||
|
VT.emplace_back( _invalidSoup.GetSurf()) ;
|
||||||
|
VC.emplace_back( RED) ;
|
||||||
|
SaveGeoObj( VT, VC, "C:\\Temp\\TriangleSelection.nge") ;
|
||||||
|
VT.clear() ; VC.clear() ;
|
||||||
|
PC.Start() ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// recupero i loops della superficie originaria e del suo Offset orientato ( non devono essere diminuiti)
|
||||||
|
POLYLINEVECTOR vPL, vPLOffs ;
|
||||||
|
if ( ! pStm->GetLoops( vPL) || ! pStmOffs->GetLoops( vPLOffs))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// trasformo ogni loop in curve composite ( devono essere chiuse)
|
||||||
|
ICRVCOMPOPOVECTOR vCompoLoops ; vCompoLoops.reserve( vPL.size()) ;
|
||||||
|
for ( const PolyLine& PL : vPL) {
|
||||||
|
if ( PL.IsClosed()) {
|
||||||
|
if ( ! vCompoLoops.emplace_back( CreateCurveComposite()) ||
|
||||||
|
! vCompoLoops.back()->FromPolyLine( PL) ||
|
||||||
|
! vCompoLoops.back()->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ICRVCOMPOPOVECTOR vCompoOffsLoops ; vCompoOffsLoops.reserve( vPLOffs.size()) ;
|
||||||
|
for ( const PolyLine& PLOffs : vPLOffs) {
|
||||||
|
if ( PLOffs.IsClosed()) {
|
||||||
|
if ( ! vCompoOffsLoops.emplace_back( CreateCurveComposite()) ||
|
||||||
|
! vCompoOffsLoops.back()->FromPolyLine( PLOffs) ||
|
||||||
|
! vCompoOffsLoops.back()->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
VT.emplace_back( pStmOffs->Clone()) ;
|
||||||
|
VC.emplace_back( YELLOW) ;
|
||||||
|
for ( ICurveComposite* pCompo : vCompoLoops) {
|
||||||
|
VT.emplace_back( pCompo->Clone()) ;
|
||||||
|
VC.emplace_back( AQUA) ;
|
||||||
|
}
|
||||||
|
for ( ICurveComposite* pCompoOffs : vCompoOffsLoops) {
|
||||||
|
VT.emplace_back( pCompoOffs->Clone()) ;
|
||||||
|
VC.emplace_back( ORANGE) ;
|
||||||
|
}
|
||||||
|
SaveGeoObj( VT, VC, "C:\\Temp\\myCurve.nge") ;
|
||||||
|
VT.clear() ; VC.clear() ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// per ogni curva della superficie originale cerco la sua associata
|
||||||
|
// NB. per la creazione della superficie ruled la prima curva è quellla che determina il verso
|
||||||
|
// dei triangoli associati. Per un corretto ed automatico orientamento della superficie
|
||||||
|
// la prima curva deve essere sempre definita dalla superficie originale ed invertita ( le
|
||||||
|
// curve nella rigata devono seguire lo stesso orientamento
|
||||||
|
ISURFTMPOVECTOR vStmRuled ; vStmRuled.reserve( vCompoLoops.size()) ;
|
||||||
|
BOOLVECTOR vIndMatched( vCompoOffsLoops.size(), false) ;
|
||||||
|
for ( ICurveComposite* pCompoLoop : vCompoLoops) {
|
||||||
|
// sposto il punto iniziale della curva nel tratto più lungo
|
||||||
|
double dMaxLen = - INFINITO ;
|
||||||
|
int nIndCrv = 0 ;
|
||||||
|
for ( int nCrv = 0 ; nCrv < pCompoLoop->GetCurveCount() ; ++ nCrv) {
|
||||||
|
const ICurve* pCurve = pCompoLoop->GetCurve( nCrv) ;
|
||||||
|
if ( pCurve != nullptr && pCurve->IsValid()) {
|
||||||
|
double dCurrLen = 0. ;
|
||||||
|
pCurve->GetLength( dCurrLen) ;
|
||||||
|
if ( dCurrLen > dMaxLen) {
|
||||||
|
dMaxLen = dCurrLen ;
|
||||||
|
nIndCrv = nCrv ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pCompoLoop->ChangeStartPoint( nIndCrv + 0.5) ;
|
||||||
|
Point3d ptStart ; pCompoLoop->GetStartPoint( ptStart) ;
|
||||||
|
// dalle altre curve derivanti dalla superficie di Offset cerco quella più vicina al punto inziale
|
||||||
|
double dMinSqDist = INFINITO ;
|
||||||
|
int nIndOffsCrv = -1 ;
|
||||||
|
Point3d ptMinDist ;
|
||||||
|
for ( int nOffsCrv = 0 ; nOffsCrv < int( vCompoOffsLoops.size()) ; ++ nOffsCrv) {
|
||||||
|
if ( vIndMatched[nOffsCrv])
|
||||||
|
continue ;
|
||||||
|
// recupero la curva e calcolo la distanza
|
||||||
|
const ICurveComposite* pCompoOffsLoop = vCompoOffsLoops[nOffsCrv] ;
|
||||||
|
int nFlag = 0 ;
|
||||||
|
Point3d ptCurrMinDist ;
|
||||||
|
if ( DistPointCurve( ptStart, *pCompoOffsLoop).GetMinDistPoint( 0., ptCurrMinDist, nFlag)) {
|
||||||
|
double dCurrSqDist = SqDist( ptStart, ptCurrMinDist) ;
|
||||||
|
if ( dCurrSqDist < dMinSqDist) {
|
||||||
|
dMinSqDist = dCurrSqDist ;
|
||||||
|
nIndOffsCrv = nOffsCrv ;
|
||||||
|
ptMinDist = ptCurrMinDist ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( nIndOffsCrv == -1)
|
||||||
|
return nullptr ;
|
||||||
|
vIndMatched[ nIndOffsCrv] = true ;
|
||||||
|
// associo le due curve
|
||||||
|
ICurveComposite* pCompoOffsLoop = vCompoOffsLoops[nIndOffsCrv] ;
|
||||||
|
double dParMinDist = 0. ;
|
||||||
|
pCompoOffsLoop->GetParamAtPoint( ptMinDist, dParMinDist, 10. * EPS_SMALL) ;
|
||||||
|
pCompoOffsLoop->ChangeStartPoint( dParMinDist) ;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
Color _cCol = Color( double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, double( rand()) / RAND_MAX, 1.) ;
|
||||||
|
VT.emplace_back( pCompoLoop->Clone()) ;
|
||||||
|
VC.emplace_back( _cCol) ;
|
||||||
|
VT.emplace_back( pCompoOffsLoop->Clone()) ;
|
||||||
|
VC.emplace_back( _cCol) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// creo la superficie tra queste due curve e la oriento in modo da definire un volume
|
||||||
|
pCompoLoop->Invert() ;
|
||||||
|
PtrOwner<ISurfTriMesh> pStmRuled( GetSurfTriMeshRuled( pCompoLoop, pCompoOffsLoop, ISurfTriMesh::RuledType::RLT_MINDIST)) ;
|
||||||
|
if ( IsNull( pStmRuled) || ! pStmRuled->IsValid() ||
|
||||||
|
! vStmRuled.emplace_back( Release( pStmRuled)))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
LOG_INFO( GetEGkLogger(), ( string{ "Strip generation : "} + ToString( PC.Stop())).c_str()) ;
|
||||||
|
VT.emplace_back( vStmRuled.back()->Clone()) ;
|
||||||
|
VC.emplace_back( _cCol) ;
|
||||||
|
_cCol.SetAlpha( .5) ;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
SaveGeoObj( VT, VC, "C:\\Temp\\Strips.nge") ;
|
||||||
|
PC.Start() ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// compongo la superficie finale
|
||||||
|
PtrOwner<ISurfTriMesh> pStmOrig( CloneSurfTriMesh( pStm)) ;
|
||||||
|
if ( IsNull( pStmOrig) || ! pStmOrig->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
PtrOwner<ISurfTriMesh> pStmRef( Release( pStmOrig)) ;
|
||||||
|
if ( IsNull( pStmRef) || ! pStmRef->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
for ( int nStrip = 0 ; nStrip < int( vStmRuled.size()) ; ++ nStrip) {
|
||||||
|
if ( ! pStmRef->DoSewing( *vStmRuled[nStrip]))
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
if ( ! pStmRef->DoSewing( *pStmOffs))
|
||||||
|
return nullptr ;
|
||||||
|
pStmRef->Repair() ;
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
LOG_INFO( GetEGkLogger(), ( string{ "Sewing : "} + ToString( PC.Stop())).c_str()) ;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ( ( ! IsNull( pStmRef) && pStmRef->IsValid()) ? Release( pStmRef) : nullptr) ;
|
||||||
|
}
|
||||||
+204
-31
@@ -17,7 +17,6 @@
|
|||||||
#include "Triangulate.h"
|
#include "Triangulate.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointLine.h"
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
||||||
#include "/EgtDev/Include/EGkDistLineLine.h"
|
#include "/EgtDev/Include/EGkDistLineLine.h"
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -35,6 +34,7 @@ SurfTriMesh::RemoveDoubleTriangles( bool& bModified)
|
|||||||
// recupero i vertici dei triangoli
|
// recupero i vertici dei triangoli
|
||||||
int nIdV[3] ;
|
int nIdV[3] ;
|
||||||
GetTriangle( nT, nIdV) ;
|
GetTriangle( nT, nIdV) ;
|
||||||
|
bool bToRemove = false ;
|
||||||
// ciclo sui triangoli adiacenti
|
// ciclo sui triangoli adiacenti
|
||||||
for ( int nE = 0 ; nE < 3 ; ++ nE) {
|
for ( int nE = 0 ; nE < 3 ; ++ nE) {
|
||||||
// recupero triangolo adiacente, se non esiste passo al successivo
|
// recupero triangolo adiacente, se non esiste passo al successivo
|
||||||
@@ -53,10 +53,14 @@ SurfTriMesh::RemoveDoubleTriangles( bool& bModified)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( nCoinc == 3) {
|
if ( nCoinc == 3) {
|
||||||
RemoveTriangle( nAdjT) ;
|
// se i vertici coincidono rimuovo entrambi i triangoli
|
||||||
|
bToRemove = true ;
|
||||||
bModified = true ;
|
bModified = true ;
|
||||||
|
RemoveTriangle( nAdjT) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ( bToRemove)
|
||||||
|
RemoveTriangle( nT) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
@@ -86,8 +90,8 @@ SurfTriMesh::FlipTriangles( int nTA, int nTB)
|
|||||||
// Recupero i vertici del triangolo A
|
// Recupero i vertici del triangolo A
|
||||||
Point3d ptSegSt, ptSegEn, ptVertA ;
|
Point3d ptSegSt, ptSegEn, ptVertA ;
|
||||||
if ( ! GetVertex( m_vTria[nTA].nIdVert[nEdgeA], ptSegSt) ||
|
if ( ! GetVertex( m_vTria[nTA].nIdVert[nEdgeA], ptSegSt) ||
|
||||||
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 1) % 3], ptSegEn) ||
|
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 1) % 3], ptSegEn) ||
|
||||||
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3], ptVertA))
|
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3], ptVertA))
|
||||||
return false ;
|
return false ;
|
||||||
// Recupero il vertice opposto del triangolo B
|
// Recupero il vertice opposto del triangolo B
|
||||||
Point3d ptVertB ;
|
Point3d ptVertB ;
|
||||||
@@ -98,23 +102,43 @@ SurfTriMesh::FlipTriangles( int nTA, int nTB)
|
|||||||
if ( ! DiagDist.IsSmall())
|
if ( ! DiagDist.IsSmall())
|
||||||
return false ;
|
return false ;
|
||||||
double dPos1, dPos2 ;
|
double dPos1, dPos2 ;
|
||||||
if ( ! DiagDist.GetPositionsAtMinDistPoints( dPos1, dPos2) ||
|
if ( ! DiagDist.GetPositionsAtMinDistPoints( dPos1, dPos2))
|
||||||
dPos1 < EPS_SMALL || dPos1 > ( ptSegEn - ptSegSt).Len() - EPS_SMALL ||
|
return false ;
|
||||||
dPos2 < EPS_SMALL || dPos2 > ( ptVertB - ptVertA).Len() - EPS_SMALL)
|
if ( dPos1 < - EPS_SMALL || dPos1 > ( ptSegEn - ptSegSt).Len() + EPS_SMALL ||
|
||||||
return false ;
|
dPos2 < - EPS_SMALL || dPos2 > ( ptVertB - ptVertA).Len() + EPS_SMALL)
|
||||||
|
return false ;
|
||||||
|
|
||||||
// Eseguo il flipping
|
// Eseguo il flipping
|
||||||
m_vTria[nTA].nIdVert[nEdgeA] = m_vTria[nTB].nIdVert[( nEdgeB + 2) % 3] ;
|
m_vTria[nTA].nIdVert[nEdgeA] = m_vTria[nTB].nIdVert[( nEdgeB + 2) % 3] ;
|
||||||
m_vTria[nTB].nIdVert[nEdgeB] = m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3] ;
|
m_vTria[nTB].nIdVert[nEdgeB] = m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3] ;
|
||||||
m_vTria[nTA].nIdAdjac[nEdgeA] = m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] ;
|
m_vTria[nTA].nIdAdjac[nEdgeA] = m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] ;
|
||||||
m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] = nTB ;
|
|
||||||
m_vTria[nTB].nIdAdjac[nEdgeB] = m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] ;
|
m_vTria[nTB].nIdAdjac[nEdgeB] = m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] ;
|
||||||
|
m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] = nTB ;
|
||||||
m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] = nTA ;
|
m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] = nTA ;
|
||||||
|
|
||||||
|
// sistemo anche le contro-adiacenze
|
||||||
|
int nTC = m_vTria[nTA].nIdAdjac[nEdgeA] ;
|
||||||
|
if ( nTC != SVT_NULL) {
|
||||||
|
for ( int i = 0 ; i < 3 ; i++)
|
||||||
|
if ( m_vTria[nTC].nIdAdjac[i] == nTB) {
|
||||||
|
m_vTria[nTC].nIdAdjac[i] = nTA ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int nTD = m_vTria[nTB].nIdAdjac[nEdgeB] ;
|
||||||
|
if ( nTD != SVT_NULL) {
|
||||||
|
for ( int i = 0 ; i < 3 ; i++)
|
||||||
|
if ( m_vTria[nTD].nIdAdjac[i] == nTA) {
|
||||||
|
m_vTria[nTD].nIdAdjac[i] = nTB ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::RemoveTJunctions( bool& bModified)
|
SurfTriMesh::RemoveTJunctions( bool& bModified, double dMinSqDist)
|
||||||
{
|
{
|
||||||
bModified = false ;
|
bModified = false ;
|
||||||
|
|
||||||
@@ -123,6 +147,11 @@ SurfTriMesh::RemoveTJunctions( bool& bModified)
|
|||||||
|
|
||||||
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
||||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||||
|
// se adiacenze tutte valide, passo al successivo
|
||||||
|
if ( m_vTria[nT].nIdAdjac[0] != SVT_DEL && m_vTria[nT].nIdAdjac[0] != SVT_NULL &&
|
||||||
|
m_vTria[nT].nIdAdjac[1] != SVT_DEL && m_vTria[nT].nIdAdjac[1] != SVT_NULL &&
|
||||||
|
m_vTria[nT].nIdAdjac[2] != SVT_DEL && m_vTria[nT].nIdAdjac[2] != SVT_NULL)
|
||||||
|
continue ;
|
||||||
// Se il triangolo non è valido, passo al successivo
|
// Se il triangolo non è valido, passo al successivo
|
||||||
Triangle3d trTria ;
|
Triangle3d trTria ;
|
||||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||||
@@ -150,6 +179,8 @@ SurfTriMesh::RemoveTJunctions( bool& bModified)
|
|||||||
if ( dSegLen < EPS_SMALL)
|
if ( dSegLen < EPS_SMALL)
|
||||||
continue ;
|
continue ;
|
||||||
vtSeg /= dSegLen ;
|
vtSeg /= dSegLen ;
|
||||||
|
int nV1 = m_vTria[nT].nIdVert[nSeg] ;
|
||||||
|
int nV2 = m_vTria[nT].nIdVert[Next( nSeg)] ;
|
||||||
// Ciclo sui triangoli vicini
|
// Ciclo sui triangoli vicini
|
||||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||||
// Salto il triangolo se è quello di riferimento
|
// Salto il triangolo se è quello di riferimento
|
||||||
@@ -157,13 +188,16 @@ SurfTriMesh::RemoveTJunctions( bool& bModified)
|
|||||||
continue ;
|
continue ;
|
||||||
// Cerco i vertici che stanno sul lato del triangolo
|
// Cerco i vertici che stanno sul lato del triangolo
|
||||||
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
||||||
|
int nCurrVert = m_vTria[vNearTria[nI]].nIdVert[nVert] ;
|
||||||
|
if ( nCurrVert == nV1 || nCurrVert == nV2)
|
||||||
|
continue ;
|
||||||
Point3d ptVert ;
|
Point3d ptVert ;
|
||||||
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
||||||
continue ;
|
continue ;
|
||||||
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
||||||
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
||||||
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H)
|
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < dMinSqDist)
|
||||||
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Riordino i vertici sul segmento
|
// Riordino i vertici sul segmento
|
||||||
@@ -307,16 +341,42 @@ ChooseGoodStartPoint( PNTULIST& PointList)
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
// -------------------------------------------------------------
|
||||||
static bool
|
bool
|
||||||
AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
SurfTriMesh::AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, double dTolAlign, bool& bModif) const
|
||||||
{
|
{
|
||||||
|
// vettore dei loop della faccia adiacente
|
||||||
|
POLYLINEVECTOR LoopVec ;
|
||||||
// Ciclo sui punti del loop
|
// Ciclo sui punti del loop
|
||||||
auto itLast = PointList.begin() ;
|
auto itLast = PointList.begin() ;
|
||||||
for ( auto it = next( itLast) ; it != PointList.end() ; ++ it) {
|
for ( auto it = next( itLast) ; it != PointList.end() ; ++ it) {
|
||||||
|
|
||||||
// Se dal punto corrente inizia un segmento adiacente a un'altra faccia
|
// bisogna fermarsi per analizzare il tratto corrente alla ricerca di punti allineati se dal punto corrente
|
||||||
if ( itLast->second != it->second) {
|
// inizia un tratto adiacente ad un'altra faccia oppure se il punto corrente non verrà eliminato dal loop
|
||||||
|
// della faccia adiacente
|
||||||
|
|
||||||
|
bool bAnalyze = ( itLast->second != it->second) ;
|
||||||
|
if ( bAnalyze)
|
||||||
|
LoopVec.clear() ;
|
||||||
|
if ( ! bAnalyze && itLast->second != - 1) {
|
||||||
|
if ( LoopVec.empty())
|
||||||
|
GetFacetLoops( int( itLast->second), LoopVec) ;
|
||||||
|
for ( int i = 0 ; i < int( LoopVec.size()) && ! bAnalyze ; i ++) {
|
||||||
|
const PNTULIST& PointListAdj = LoopVec[i].GetUPointList() ;
|
||||||
|
int nSamePoints = 0 ;
|
||||||
|
for ( auto itAdj = PointListAdj.begin() ; itAdj != prev( PointListAdj.end()) ; ++ itAdj) {
|
||||||
|
// cerco il punto corrente sul loop della faccia adiacente
|
||||||
|
if ( AreSamePointApprox( it->first, itAdj->first))
|
||||||
|
++ nSamePoints ;
|
||||||
|
if ( ( nSamePoints == 1 && int( PointListAdj.size()) <= 4) || nSamePoints > 1) {
|
||||||
|
bAnalyze = true ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( bAnalyze) {
|
||||||
// Raccolgo i punti in una polyline
|
// Raccolgo i punti in una polyline
|
||||||
PolyLine PL ;
|
PolyLine PL ;
|
||||||
int nPar = -1 ;
|
int nPar = -1 ;
|
||||||
@@ -326,7 +386,7 @@ AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
|||||||
}
|
}
|
||||||
PL.AddUPoint( ++nPar, it->first) ;
|
PL.AddUPoint( ++nPar, it->first) ;
|
||||||
// Provo ad eliminare i punti allineati
|
// Provo ad eliminare i punti allineati
|
||||||
PL.RemoveAlignedPoints( 50 * EPS_SMALL) ;
|
PL.RemoveAlignedPoints( dTolAlign) ;
|
||||||
if ( PL.GetPointNbr() < nPar + 1) {
|
if ( PL.GetPointNbr() < nPar + 1) {
|
||||||
// rimuovo dalla lista dei punti gli eliminati (salto gli estremi)
|
// rimuovo dalla lista dei punti gli eliminati (salto gli estremi)
|
||||||
int nUCurr = 1 ;
|
int nUCurr = 1 ;
|
||||||
@@ -418,7 +478,7 @@ AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced, double dTolAlign)
|
||||||
{
|
{
|
||||||
// La trimesh deve essere valida
|
// La trimesh deve essere valida
|
||||||
if ( ! IsValid())
|
if ( ! IsValid())
|
||||||
@@ -433,8 +493,8 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
|||||||
// Ciclo sulle facce della mesh per trovare quelle da ritriangolare
|
// Ciclo sulle facce della mesh per trovare quelle da ritriangolare
|
||||||
unordered_map< int, pair< PNTVECTOR, INTVECTOR>> FacetMap ;
|
unordered_map< int, pair< PNTVECTOR, INTVECTOR>> FacetMap ;
|
||||||
for ( int nF = 0 ; nF < nFacetCnt ; ++ nF) {
|
for ( int nF = 0 ; nF < nFacetCnt ; ++ nF) {
|
||||||
|
|
||||||
// Recupero i loop della faccia (il parametro indica la faccia adiacente)
|
// Recupero i loop della faccia ( il parametro indica la faccia adiacente)
|
||||||
POLYLINEVECTOR LoopVec ;
|
POLYLINEVECTOR LoopVec ;
|
||||||
GetFacetLoops( nF, LoopVec) ;
|
GetFacetLoops( nF, LoopVec) ;
|
||||||
|
|
||||||
@@ -445,13 +505,17 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
|||||||
// Lista dei punti del loop
|
// Lista dei punti del loop
|
||||||
PNTULIST& PointList = LoopVec[nL].GetUPointList() ;
|
PNTULIST& PointList = LoopVec[nL].GetUPointList() ;
|
||||||
|
|
||||||
|
// Se il loop è un triangolo, non va modificato
|
||||||
|
if ( int( PointList.size()) <= 4)
|
||||||
|
continue ;
|
||||||
|
|
||||||
// Mi assicuro che il punto iniziale/finale non sia all'interno di un possibile segmento
|
// Mi assicuro che il punto iniziale/finale non sia all'interno di un possibile segmento
|
||||||
if ( ! ChooseGoodStartPoint( PointList))
|
if ( ! ChooseGoodStartPoint( PointList))
|
||||||
continue ;
|
continue ;
|
||||||
|
|
||||||
// Sistemo il loop
|
// Sistemo il loop
|
||||||
bool bModif = false ;
|
bool bModif = false ;
|
||||||
if ( ! AdjustLoop( PointList, dMaxEdgeLen, bModif))
|
if ( ! AdjustLoop( PointList, dMaxEdgeLen, dTolAlign, bModif))
|
||||||
return false ;
|
return false ;
|
||||||
if ( bModif)
|
if ( bModif)
|
||||||
bToRetriangulate = true ;
|
bToRetriangulate = true ;
|
||||||
@@ -479,9 +543,8 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
|||||||
// Eseguo la ritriangolazione della faccia
|
// Eseguo la ritriangolazione della faccia
|
||||||
PNTVECTOR vPt ;
|
PNTVECTOR vPt ;
|
||||||
INTVECTOR vTr ;
|
INTVECTOR vTr ;
|
||||||
if ( Triangulate().Make( LoopVec, vPt, vTr)) {
|
if ( Triangulate().Make( LoopVec, vPt, vTr) && ! vTr.empty())
|
||||||
FacetMap.emplace( nF, make_pair( vPt, vTr)) ;
|
FacetMap.emplace( nF, make_pair( vPt, vTr)) ;
|
||||||
}
|
|
||||||
// Se non riesco a triangolare anche solo questa faccia, interrompo tutto
|
// Se non riesco a triangolare anche solo questa faccia, interrompo tutto
|
||||||
else
|
else
|
||||||
return false ;
|
return false ;
|
||||||
@@ -502,17 +565,17 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
|||||||
// Cancello i triangoli
|
// Cancello i triangoli
|
||||||
for ( int nT : vDelTria)
|
for ( int nT : vDelTria)
|
||||||
RemoveTriangle( nT) ;
|
RemoveTriangle( nT) ;
|
||||||
|
|
||||||
// Applico le nuove triangolazioni delle facce
|
// Applico le nuove triangolazioni delle facce
|
||||||
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||||
const PNTVECTOR& vPt = itF->second.first ;
|
const PNTVECTOR& vPt = itF->second.first ;
|
||||||
const INTVECTOR& vTr = itF->second.second ;
|
const INTVECTOR& vTr = itF->second.second ;
|
||||||
// Inserisco i nuovi triangoli
|
// Inserisco i nuovi triangoli
|
||||||
bool bFirstTria = true ;
|
bool bFirstTria = true ;
|
||||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||||
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
||||||
AddVertex( vPt[vTr[n + 1]]),
|
AddVertex( vPt[vTr[n + 1]]),
|
||||||
AddVertex( vPt[vTr[n + 2]])} ;
|
AddVertex( vPt[vTr[n + 2]])} ;
|
||||||
auto itCol = ColorMap.find( itF->first) ;
|
auto itCol = ColorMap.find( itF->first) ;
|
||||||
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
||||||
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
||||||
@@ -525,7 +588,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
// dichiaro necessità ricalcolo della grafica e di hashgrids3d
|
||||||
m_OGrMgr.Reset() ;
|
m_OGrMgr.Reset() ;
|
||||||
ResetHashGrids3d() ;
|
ResetHashGrids3d() ;
|
||||||
@@ -722,3 +785,113 @@ SurfTriMesh::SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECT
|
|||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::FindAdjacentOnLongerEdge( int nT, int& nEdge, int& nAdjTrg) const
|
||||||
|
{
|
||||||
|
// recupero il lato più lungo del triangolo
|
||||||
|
double dLen0 = SqDist( m_vVert[m_vTria[nT].nIdVert[0]].ptP, m_vVert[m_vTria[nT].nIdVert[1]].ptP) ;
|
||||||
|
double dLen1 = SqDist( m_vVert[m_vTria[nT].nIdVert[1]].ptP, m_vVert[m_vTria[nT].nIdVert[2]].ptP) ;
|
||||||
|
double dLen2 = SqDist( m_vVert[m_vTria[nT].nIdVert[2]].ptP, m_vVert[m_vTria[nT].nIdVert[0]].ptP) ;
|
||||||
|
nEdge = -1 ;
|
||||||
|
if ( dLen0 > dLen1 && dLen0 > dLen2)
|
||||||
|
nEdge = 0 ;
|
||||||
|
else if ( dLen1 > dLen2)
|
||||||
|
nEdge = 1 ;
|
||||||
|
else
|
||||||
|
nEdge = 2 ;
|
||||||
|
|
||||||
|
// recupero il triangolo adiacente sul lato più lungo
|
||||||
|
nAdjTrg = m_vTria[nT].nIdAdjac[nEdge] ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
SurfTriMesh::RemoveInvalidTriangles( const INTVECTOR& vIds)
|
||||||
|
{
|
||||||
|
// al momento gestito solo per trimesh con adiacenze definite, eventualmente da estendere.
|
||||||
|
// Analoga a RemoveFistInvalidTrg in Triangulate.cpp
|
||||||
|
// TO DO da capire e gestire casi in cui flip lascia triangoli invalidi
|
||||||
|
|
||||||
|
unordered_map<int, bool> InvalidMap ;
|
||||||
|
for ( auto nId : vIds)
|
||||||
|
InvalidMap[nId] = true ;
|
||||||
|
|
||||||
|
for ( int i = 0 ; i < int( vIds.size()) ; i++) {
|
||||||
|
|
||||||
|
int nTA = vIds[i] ;
|
||||||
|
if ( ! InvalidMap[nTA])
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
// recupero il triangolo adiacente sul suo lato più lungo
|
||||||
|
int nTB, nEdgeA ;
|
||||||
|
FindAdjacentOnLongerEdge( nTA, nEdgeA, nTB) ;
|
||||||
|
|
||||||
|
// se adiacente è nullo posso rimuovere tranquillamente il triangolo senza creare TJunctions
|
||||||
|
if ( nTB == SVT_NULL) {
|
||||||
|
RemoveTriangle( nTA) ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
// se adiacente è valido posso fare il flip per rendere valido nTA
|
||||||
|
else if ( ! InvalidMap[nTB]) {
|
||||||
|
FlipTriangles( nTA, nTB) ;
|
||||||
|
InvalidMap[nTA] = false ;
|
||||||
|
}
|
||||||
|
// se adiacente è invalido creo una catena da risolvere non appena si trova un triangolo valido
|
||||||
|
else {
|
||||||
|
INTVECTOR vChain = {nTA} ;
|
||||||
|
INTVECTOR vChainEdges = {nEdgeA} ;
|
||||||
|
int nTCurr = nTB ;
|
||||||
|
|
||||||
|
while ( nTCurr != SVT_NULL && InvalidMap[nTCurr]) {
|
||||||
|
|
||||||
|
// calcolo il successivo
|
||||||
|
int nTOther, nEdgeCurr ;
|
||||||
|
FindAdjacentOnLongerEdge( nTCurr, nEdgeCurr, nTOther) ;
|
||||||
|
|
||||||
|
if ( nTOther == vChain.back()) {
|
||||||
|
// se ho trovato un'adiacenza ambigua ( ovvero due triangoli invalidi adiacenti sui loro lati più lunghi)
|
||||||
|
// flip dei due triangoli per modificare il lato più lungo e togliere adiacenza ambigua
|
||||||
|
FlipTriangles( nTCurr, nTOther) ;
|
||||||
|
if ( vChain.size() > 1) {
|
||||||
|
vChain.pop_back() ;
|
||||||
|
vChainEdges.pop_back() ;
|
||||||
|
// individuo il nuovo adiacente all'ultimo triangolo della catena dopo aver fatto flip
|
||||||
|
nTOther = m_vTria[vChain.back()].nIdAdjac[vChainEdges.back()] ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vChain.emplace_back( nTCurr) ;
|
||||||
|
vChainEdges.emplace_back( nEdgeCurr) ;
|
||||||
|
}
|
||||||
|
// aggiorno per iterazione successiva
|
||||||
|
nTCurr = nTOther ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// se la catena termina su triangolo nullo, posso rimuovere tutti i triangoli della catena
|
||||||
|
if ( nTCurr == SVT_NULL) {
|
||||||
|
for ( int k = 0 ; k < int( vChain.size()) ; k++) {
|
||||||
|
RemoveTriangle( vChain[k]) ;
|
||||||
|
InvalidMap[vChain[k]] = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// se catena termina su un triangolo valido, applico il flip a cascata a partire dall'ultimo triangolo invalido trovato
|
||||||
|
else {
|
||||||
|
FlipTriangles( vChain.back(), nTCurr) ;
|
||||||
|
InvalidMap[vChain.back()] = false ;
|
||||||
|
for ( int i = int( vChain.size()) - 2 ; i >= 0 ; i--) {
|
||||||
|
int nTA = vChain[i] ;
|
||||||
|
if ( ! InvalidMap[nTA])
|
||||||
|
continue ;
|
||||||
|
// eseguo il flip con il triangolo adiacente sul suo lato più lungo
|
||||||
|
int nTOther = m_vTria[nTA].nIdAdjac[vChainEdges[i]] ;
|
||||||
|
FlipTriangles( nTA, nTOther) ;
|
||||||
|
InvalidMap[nTA] = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
@@ -36,25 +36,25 @@ class Tool
|
|||||||
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRc, int nToolNum) ;
|
bool SetAdditiveTool( const std::string& sToolName, double dH, double dR, double dRc, int nToolNum) ;
|
||||||
bool SetToolNum( int nToolNum)
|
bool SetToolNum( int nToolNum)
|
||||||
{ m_nCurrentNum = nToolNum ; return true ; }
|
{ m_nCurrentNum = nToolNum ; return true ; }
|
||||||
int GetType() const
|
int GetType( void) const
|
||||||
{ return m_nType ; }
|
{ return m_nType ; }
|
||||||
int GetToolNum() const
|
int GetToolNum( void) const
|
||||||
{ return m_nCurrentNum ; }
|
{ return m_nCurrentNum ; }
|
||||||
double GetHeigth() const
|
double GetHeigth( void) const
|
||||||
{ return m_dHeight ; }
|
{ return m_dHeight ; }
|
||||||
double GetTipHeigth() const
|
double GetTipHeigth( void) const
|
||||||
{ return m_dTipHeight ; }
|
{ return m_dTipHeight ; }
|
||||||
double GetRadius() const
|
double GetRadius( void) const
|
||||||
{ return m_dRadius ; }
|
{ return m_dRadius ; }
|
||||||
double GetTipRadius() const
|
double GetTipRadius( void) const
|
||||||
{ return m_dTipRadius ; }
|
{ return m_dTipRadius ; }
|
||||||
double GetCornRadius() const
|
double GetCornRadius( void) const
|
||||||
{ return m_dRCorner ; }
|
{ return m_dRCorner ; }
|
||||||
double GetRefRadius() const
|
double GetRefRadius( void) const
|
||||||
{ return m_dRefRadius ; }
|
{ return m_dRefRadius ; }
|
||||||
double GetMrtChsWidth() const
|
double GetMrtChsWidth( void) const
|
||||||
{ return m_dMrtChsWidth ; }
|
{ return m_dMrtChsWidth ; }
|
||||||
double GetMrtChsThickness() const
|
double GetMrtChsThickness( void) const
|
||||||
{ return m_dMrtChsThickness ; }
|
{ return m_dMrtChsThickness ; }
|
||||||
const CurveComposite& GetOutline( void) const
|
const CurveComposite& GetOutline( void) const
|
||||||
{ return ( m_Outline) ; }
|
{ return ( m_Outline) ; }
|
||||||
|
|||||||
@@ -23,32 +23,39 @@
|
|||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
struct PairHashInt64 {
|
struct PairHashInt64 {
|
||||||
size_t operator()(const pair<int64_t, int64_t>& key) const {
|
size_t
|
||||||
|
operator()( const std::pair<int64_t, int64_t>& key) const {
|
||||||
size_t h1 = std::hash<int64_t>{}(key.first) ;
|
size_t h1 = std::hash<int64_t>{}(key.first) ;
|
||||||
size_t h2 = std::hash<int64_t>{}(key.second) ;
|
size_t h2 = std::hash<int64_t>{}(key.second) ;
|
||||||
return h1 ^ (h2 << 1); // Combine hashes
|
return h1 ^ (h2 << 1); // Combine hashes
|
||||||
}
|
}
|
||||||
};
|
} ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
struct Inters {
|
struct Inters {
|
||||||
int nIn ;
|
int nIn ;
|
||||||
PNTVECTOR vpt ;
|
|
||||||
int nOut ;
|
int nOut ;
|
||||||
|
PNTVECTOR vpt ;
|
||||||
bool bCCW ;
|
bool bCCW ;
|
||||||
int nChunk ;
|
int nChunk ;
|
||||||
bool bSortedbyStart ;
|
bool bSortedbyStart ;
|
||||||
// riordino le intersezioni per lato in senso antiorario dal top
|
|
||||||
// se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
|
// nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario
|
||||||
bool operator < ( Inters& b)
|
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
|
||||||
|
// -1 se la curva è sempre dentro la cella
|
||||||
|
|
||||||
|
// riordino le intersezioni per lato in senso antiorario dal top
|
||||||
|
// se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
|
||||||
|
bool
|
||||||
|
operator < ( Inters& b)
|
||||||
{
|
{
|
||||||
// trovo in che ordine stanno i due start, tenendo conto anche della possibilità che siano vertici
|
// trovo in che ordine stanno i due start, tenendo conto anche della possibilità che siano vertici
|
||||||
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
||||||
const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ;
|
const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ;
|
||||||
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
||||||
const auto iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ;
|
const auto iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ;
|
||||||
int nPos2 = std::distance( vEdges.begin(), iter2) ;
|
int nPos2 = std::distance( vEdges.begin(), iter2) ;
|
||||||
// se sono loop interni li ordino in modo decrescente rispetto all'area
|
// se sono loop interni li ordino in modo decrescente rispetto all'area
|
||||||
bool bEqIn = ( nIn == b.nIn) ;
|
bool bEqIn = ( nIn == b.nIn) ;
|
||||||
double dAreaA = 0 , dAreaB = 0 ;
|
double dAreaA = 0 , dAreaB = 0 ;
|
||||||
if ( bEqIn && nIn == -1) {
|
if ( bEqIn && nIn == -1) {
|
||||||
@@ -63,7 +70,7 @@ struct Inters {
|
|||||||
pl.Close() ;
|
pl.Close() ;
|
||||||
pl.GetAreaXY( dAreaB) ;
|
pl.GetAreaXY( dAreaB) ;
|
||||||
}
|
}
|
||||||
// se nIn è un vertice sistemo il valore
|
// se nIn è un vertice sistemo il valore
|
||||||
int nEdgeIn = nIn ;
|
int nEdgeIn = nIn ;
|
||||||
if ( nIn > 3)
|
if ( nIn > 3)
|
||||||
nEdgeIn = nIn - 4 ;
|
nEdgeIn = nIn - 4 ;
|
||||||
@@ -75,13 +82,14 @@ struct Inters {
|
|||||||
( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y)) ;
|
( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y)) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FirstEncounter ( Inters& a, Inters& b)
|
static bool
|
||||||
|
FirstEncounter( Inters& a, Inters& b)
|
||||||
{
|
{
|
||||||
// riordino in base al lato toccato, o dall'uscita o dall'ingresso, che viene prima.
|
// riordino in base al lato toccato, o dall'uscita o dall'ingresso, che viene prima.
|
||||||
// ottengo l'ordine che avrei percorrendo il bordo da ptTR e considerando i loop che incontro, indipendentemente se li incontro nel punto di uscita o ingresso
|
// ottengo l'ordine che avrei percorrendo il bordo da ptTR e considerando i loop che incontro, indipendentemente se li incontro nel punto di uscita o ingresso
|
||||||
// nell'intersezione salvo se il taglio è stato ordinato guardando l'ingresso o l'uscita
|
// nell'intersezione salvo se il taglio è stato ordinato guardando l'ingresso o l'uscita
|
||||||
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
||||||
// trovo i lati di ingresso e uscita
|
// trovo i lati di ingresso e uscita
|
||||||
const auto iter1 = find( vEdges.begin(), vEdges.end(), a.nIn) ;
|
const auto iter1 = find( vEdges.begin(), vEdges.end(), a.nIn) ;
|
||||||
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
||||||
const auto iter2 = find( vEdges.begin(), vEdges.end(), a.nOut) ;
|
const auto iter2 = find( vEdges.begin(), vEdges.end(), a.nOut) ;
|
||||||
@@ -92,13 +100,13 @@ struct Inters {
|
|||||||
int nPos4 = std::distance( vEdges.begin(), iter4) ;
|
int nPos4 = std::distance( vEdges.begin(), iter4) ;
|
||||||
int nFirstA = 0 ;
|
int nFirstA = 0 ;
|
||||||
int nFirstB = 0 ;
|
int nFirstB = 0 ;
|
||||||
// salvo l'indice del primo punto dell'intersezione che ho incontrato scorrendo il bordo da ptTR
|
// salvo l'indice del primo punto dell'intersezione che ho incontrato scorrendo il bordo da ptTR
|
||||||
// salvo il lato che viene prima confrontando ingresso e uscita
|
// salvo il lato che viene prima confrontando ingresso e uscita
|
||||||
if ( nPos2 < nPos1) {
|
if ( nPos2 < nPos1) {
|
||||||
nPos1 = nPos2 ;
|
nPos1 = nPos2 ;
|
||||||
nFirstA = int( a.vpt.size()) - 1 ;
|
nFirstA = int( a.vpt.size()) - 1 ;
|
||||||
}
|
}
|
||||||
// se ingresso e uscita sono sullo stesso lato allora confronto le coordinate per capire se viene prima l'ingresso o l'uscita
|
// se ingresso e uscita sono sullo stesso lato allora confronto le coordinate per capire se viene prima l'ingresso o l'uscita
|
||||||
else if ( nPos2 == nPos1 ) {
|
else if ( nPos2 == nPos1 ) {
|
||||||
if ( nPos1 == 0 )
|
if ( nPos1 == 0 )
|
||||||
nFirstA = a.vpt[0].x > a.vpt.back().x ? 0 : ( int( a.vpt.size()) - 1) ;
|
nFirstA = a.vpt[0].x > a.vpt.back().x ? 0 : ( int( a.vpt.size()) - 1) ;
|
||||||
@@ -125,28 +133,28 @@ struct Inters {
|
|||||||
}
|
}
|
||||||
a.bSortedbyStart = nFirstA == 0 ;
|
a.bSortedbyStart = nFirstA == 0 ;
|
||||||
b.bSortedbyStart = nFirstB == 0 ;
|
b.bSortedbyStart = nFirstB == 0 ;
|
||||||
// se sono diversi ritorno il confronto
|
// se sono diversi ritorno il confronto
|
||||||
if ( nPos1 != nPos3)
|
if ( nPos1 != nPos3)
|
||||||
return nPos1 < nPos3 ;
|
return nPos1 < nPos3 ;
|
||||||
// se sono uguali devo valutare il punto di intersezione
|
// se sono uguali devo valutare il punto di intersezione
|
||||||
return ( nPos1 == 0 && a.vpt[nFirstA].x > b.vpt[nFirstB].x) ||
|
return ( nPos1 == 0 && a.vpt[nFirstA].x > b.vpt[nFirstB].x) ||
|
||||||
( nPos1 == 1 && a.vpt[nFirstA].y > b.vpt[nFirstB].y) ||
|
( nPos1 == 1 && a.vpt[nFirstA].y > b.vpt[nFirstB].y) ||
|
||||||
( nPos1 == 2 && a.vpt[nFirstA].x < b.vpt[nFirstB].x) ||
|
( nPos1 == 2 && a.vpt[nFirstA].x < b.vpt[nFirstB].x) ||
|
||||||
( nPos1 == 3 && a.vpt[nFirstA].y < b.vpt[nFirstB].y) ;
|
( nPos1 == 3 && a.vpt[nFirstA].y < b.vpt[nFirstB].y) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator == ( Inters& b)
|
bool
|
||||||
|
operator == ( Inters& b)
|
||||||
{
|
{
|
||||||
return AreSamePointExact( vpt[0], b.vpt[0]) ;
|
return AreSamePointExact( vpt[0], b.vpt[0]) ;
|
||||||
}
|
}
|
||||||
bool operator != ( Inters& b)
|
|
||||||
|
bool
|
||||||
|
operator != ( Inters& b)
|
||||||
{
|
{
|
||||||
return ! AreSamePointExact( vpt[0], b.vpt[0]) ;
|
return ! AreSamePointExact( vpt[0], b.vpt[0]) ;
|
||||||
}
|
}
|
||||||
} ;
|
} ;
|
||||||
// nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario
|
|
||||||
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
|
|
||||||
// -1 se la curva è sempre dentro la cella
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
class Cell
|
class Cell
|
||||||
@@ -160,20 +168,25 @@ class Cell
|
|||||||
// | |
|
// | |
|
||||||
// |_________________|
|
// |_________________|
|
||||||
// Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE)
|
// Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE)
|
||||||
|
|
||||||
|
public :
|
||||||
|
enum Collapsed { TO_VERIFY = -1, // da verificare
|
||||||
|
NO_COLLAPSE = 0, // non ho coppie di lati collassati
|
||||||
|
VERT_EDGES = 1, // coppia di lati verticali(1-3) sono collassati
|
||||||
|
HORIZ_EDGES = 2} ; // coppia di lati verticali(0-2) sono collassati
|
||||||
|
|
||||||
public :
|
public :
|
||||||
~Cell( void) {}
|
~Cell( void) {}
|
||||||
Cell( void)
|
Cell( void)
|
||||||
: m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0),
|
: m_nId( -1), m_nTop( -2), m_nBottom( -2), m_nLeft( -2), m_nRight( -2), m_nParent( -2), m_nDepth( 0),
|
||||||
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( false), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
|
m_dSplit( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( false), m_nRightEdgeIn( -1),
|
||||||
m_ptPbl( ORIG), m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true)
|
m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1), m_nCollapsed( -1), m_ptPbl( ORIG),
|
||||||
{
|
m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) {}
|
||||||
Point3d ptTr ( 1 * SBZ_TREG_COEFF, 1 * SBZ_TREG_COEFF) ;
|
|
||||||
m_ptPtr = ptTr ;
|
|
||||||
}
|
|
||||||
Cell( const Point3d& ptBL, const Point3d& ptTR)
|
Cell( const Point3d& ptBL, const Point3d& ptTR)
|
||||||
: m_nId( -1),m_nTop ( -2), m_nBottom( -2), m_nLeft( -2), m_nRight ( -2), m_nParent( -2), m_nDepth( 0),
|
: m_nId( -1), m_nTop( -2), m_nBottom( -2), m_nLeft( -2), m_nRight( -2), m_nParent( -2), m_nDepth( 0),
|
||||||
m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( 0), m_nRightEdgeIn( -1), m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1),
|
m_dSplit( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( 0), m_nRightEdgeIn( -1),
|
||||||
m_ptPbl( ptBL), m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {}
|
m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1), m_nCollapsed( -1), m_ptPbl( ptBL),
|
||||||
|
m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {}
|
||||||
bool IsSame( const Cell& cOtherCell) const
|
bool IsSame( const Cell& cOtherCell) const
|
||||||
{ return ( m_nId == cOtherCell.m_nId) ; }
|
{ return ( m_nId == cOtherCell.m_nId) ; }
|
||||||
void SetBottomLeft( const Point3d& ptBL)
|
void SetBottomLeft( const Point3d& ptBL)
|
||||||
@@ -192,9 +205,11 @@ class Cell
|
|||||||
{ return Point3d( m_ptPbl.x, m_ptPtr.y) ; }
|
{ return Point3d( m_ptPbl.x, m_ptPtr.y) ; }
|
||||||
Point3d GetBottomRight( void) const
|
Point3d GetBottomRight( void) const
|
||||||
{ return Point3d( m_ptPtr.x, m_ptPbl.y); }
|
{ return Point3d( m_ptPtr.x, m_ptPbl.y); }
|
||||||
|
Point3d GetCenter( void) const
|
||||||
|
{ return ( m_ptPbl + m_ptPtr) / 2 ; }
|
||||||
double GetSplitValue( void) const
|
double GetSplitValue( void) const
|
||||||
{ return m_dSplit ; }
|
{ return m_dSplit ; }
|
||||||
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente
|
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, altrimenti orizzontalmente
|
||||||
{ return m_bSplitVert ; }
|
{ return m_bSplitVert ; }
|
||||||
bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia
|
bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia
|
||||||
{ return ( m_nChild1 == -2 && m_nChild2 == -2) ; }
|
{ return ( m_nChild1 == -2 && m_nChild2 == -2) ; }
|
||||||
@@ -231,6 +246,7 @@ class Cell
|
|||||||
int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo
|
int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo
|
||||||
// contati in senso CCW a partire dal bottom left
|
// contati in senso CCW a partire dal bottom left
|
||||||
INTVECTOR m_vnPolyId ; // indici dei poligoni associati a questa cella nel vettore m_vPolygons del Tree
|
INTVECTOR m_vnPolyId ; // indici dei poligoni associati a questa cella nel vettore m_vPolygons del Tree
|
||||||
|
int m_nCollapsed ; // flag che indica se la coppia di lati verticali (1) o orizzontali(2) sono collassati
|
||||||
|
|
||||||
private :
|
private :
|
||||||
Point3d m_ptPbl ; // punto bottom left
|
Point3d m_ptPbl ; // punto bottom left
|
||||||
@@ -245,41 +261,43 @@ class Tree
|
|||||||
public :
|
public :
|
||||||
~Tree( void) ;
|
~Tree( void) ;
|
||||||
Tree( void) ;
|
Tree( void) ;
|
||||||
//Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
|
Tree( const Point3d ptBl, const Point3d ptTr) ; // da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
|
||||||
Tree( const Point3d ptBl, const Point3d ptTr) ; // creatore da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
|
bool SetSurf( const SurfBezier* pSrfBz, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
|
||||||
bool SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
|
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
|
||||||
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
|
bool BuildTree( double dLinTol = LIN_TOL_STD,
|
||||||
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
|
double dSideMin = 1, // è la minima lunghezza del lato di una cella
|
||||||
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
|
double dSideMax = INFINITO) ; // è la massima dimensione di un triangolo della trimesh
|
||||||
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
|
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, std::vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops, bool bUpdateEdges) ;
|
||||||
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops) ;
|
|
||||||
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
|
||||||
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
|
||||||
// ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
|
// ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
|
||||||
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
bool GetLeaves( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
||||||
bool GetEdges3D ( vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
|
bool GetEdges3D( std::vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
|
||||||
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle
|
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // restituisce i loop splitatti ai confini delle celle
|
||||||
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i) vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ; return true ; };
|
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i)
|
||||||
void SetTestMode( void) { m_bTestMode = true ;} ; // attivando la test mode, per la costruzione dell'albero viene usata la funzione BuiltTree_test e viene corretta di conseguenza la FindCell
|
vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ;
|
||||||
|
return true ; }
|
||||||
// funzioni da usare per ricostruire tagli che vanno aggiunti allo spazio parametrico
|
// funzioni da usare per ricostruire tagli che vanno aggiunti allo spazio parametrico
|
||||||
bool AddCutsToRoot( POLYLINEVECTOR& vCuts) ; // aggiunge i tagli al tree
|
bool AddCutsToRoot( POLYLINEVECTOR& vCuts) ; // aggiunge i tagli al tree
|
||||||
bool CreateCellContour( POLYLINEMATRIX& vPolygons) ; // crea il nuovo contorno esterno, tenendo conto dei tagli
|
bool CreateCellContour( POLYLINEMATRIX& vPolygons) ; // crea il nuovo contorno esterno, tenendo conto dei tagli
|
||||||
bool IsClosedU( void) const { return m_bClosedU ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro U
|
bool IsClosedU( void) const // restituisce flag di chiusara in U
|
||||||
bool IsClosedV( void) const { return m_bClosedV ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro V
|
{ return m_bClosedU ; }
|
||||||
std::vector<bool> GetPoles( void) { return m_vbPole ;} ; // funzione che restituisce i flag che indicano se i lati sono collassati in dei poli
|
bool IsClosedV( void) const // restituisce flag di chiusara in V
|
||||||
|
{ return m_bClosedV ; }
|
||||||
|
BOOLVECTOR GetPoles( void) // restituisce i flag che indicano se i lati sono collassati in dei poli
|
||||||
|
{ return m_vbPole ; }
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
||||||
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
|
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
|
||||||
void Balance( void) ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profondità di +- 1
|
int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
|
||||||
int GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
|
int GetDepth( int nId, int nRef) const ; // livello del nodo nId
|
||||||
int GetDepth( int nId, int nRef) const ; // livello del nodo nId
|
void GetTopNeigh( int nId, INTVECTOR& vTopNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato top ( la coppia di double è per dare un intervallo diverso su cui limitare i vicini)
|
||||||
void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top
|
void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
||||||
void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
||||||
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato right
|
||||||
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right
|
|
||||||
void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario
|
void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario
|
||||||
void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero
|
void ResetTree( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero
|
||||||
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
||||||
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
||||||
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
||||||
@@ -304,31 +322,27 @@ class Tree
|
|||||||
bool UpdateSplitLoop( ICurveComposite* pCC, Point3d& pt) ;
|
bool UpdateSplitLoop( ICurveComposite* pCC, Point3d& pt) ;
|
||||||
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
|
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
|
||||||
bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ;
|
bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ;
|
||||||
bool GetPoint(double dU, double dV, Point3d& pt) const ;
|
bool GetPoint(double dU, double dV, Point3d& ptP) const ;
|
||||||
bool SavePoint( double dU, double dV, Point3d& pt) ;
|
bool SavePoint( double dU, double dV, const Point3d& ptP) ;
|
||||||
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
||||||
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
|
|
||||||
bool m_bTrimmed ; // superficie trimmata
|
bool m_bTrimmed ; // superficie trimmata
|
||||||
unordered_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
|
std::unordered_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
|
||||||
vector<tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
|
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
|
||||||
bool m_bBilinear ; // superficie bilineare
|
bool m_bBilinear ; // superficie bilineare
|
||||||
bool m_bMulti ; // superficie multi-patch
|
bool m_bMulti ; // superficie multi-patch
|
||||||
bool m_bClosedU ; // superficie chiusa lungo il parametro U
|
bool m_bClosedU ; // superficie chiusa lungo il parametro U
|
||||||
bool m_bClosedV ; // superficie chiusa lungo il parametro V
|
bool m_bClosedV ; // superficie chiusa lungo il parametro V
|
||||||
BOOLVECTOR m_vbPole ; // vettore che indica se i vari lati sono collassati in poli ( indici riferiti all'ordine degli edge)
|
BOOLVECTOR m_vbPole ; // vettore che indica se i vari lati sono collassati in poli ( indici riferiti all'ordine degli edge)
|
||||||
bool m_bSplitPatches ; // flag che indica se le patches sono state divise prima della creazione dell'albero
|
|
||||||
int m_nDegU ; // grado della superficie nel parametro U
|
int m_nDegU ; // grado della superficie nel parametro U
|
||||||
int m_nDegV ; // grado della superficie nel parametro V
|
int m_nDegV ; // grado della superficie nel parametro V
|
||||||
int m_nSpanU ; // numero di span lungo il parametro U
|
int m_nSpanU ; // numero di span lungo il parametro U
|
||||||
int m_nSpanV ; // numero di span lungo il parametro V
|
int m_nSpanV ; // numero di span lungo il parametro V
|
||||||
unordered_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
|
std::unordered_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
|
||||||
mutable unordered_map<pair<int64_t, int64_t>,Point3d, PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int)
|
mutable std::unordered_map<std::pair<int64_t,int64_t>,Point3d,PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int)
|
||||||
INTVECTOR m_vnLeaves ; // vettore delle foglie
|
INTVECTOR m_vnLeaves ; // vettore delle foglie
|
||||||
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
|
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
|
||||||
bool m_bTestMode ; // bool che indica se la test mode è attiva
|
|
||||||
ICRVCOMPOPOVECTOR m_vCCLoop2D ; // vettore che contiene le CurveCompo che rappresentano i loop di trim tenendo conto della divisione in celle
|
ICRVCOMPOPOVECTOR m_vCCLoop2D ; // vettore che contiene le CurveCompo che rappresentano i loop di trim tenendo conto della divisione in celle
|
||||||
vector<pair<BIPNTVECTOR, ChainCurves>> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim.
|
std::vector<std::pair<BIPNTVECTOR, ChainCurves>> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim.
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
+53
-34
@@ -818,7 +818,7 @@ Triangulate::TestTriangle( const PNTVECTOR& vPt, const INTVECTOR& vPol,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If vertex k is inside the ear triangle, then this is not an ear
|
// If vertex k is inside the ear triangle, then this is not an ear
|
||||||
else if ( TestPointInTriangle( vPt[vPol[k]], vPt[vPol[vPrev[i]]], vPt[vPol[i]], vPt[vPol[vNext[i]]])) {
|
else if ( TestPointInOrOnTriangle( vPt[vPol[k]], vPt[vPol[vPrev[i]]], vPt[vPol[i]], vPt[vPol[vNext[i]]])) {
|
||||||
bIsEar = false ;
|
bIsEar = false ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
@@ -978,6 +978,28 @@ Triangulate::TestPointInTriangle( const Point3d& ptP, const Point3d& ptA, const
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// test if point p is inside or on the border of triangle (a, b, c)
|
||||||
|
bool
|
||||||
|
Triangulate::TestPointInOrOnTriangle( const Point3d& ptP, const Point3d& ptA, const Point3d& ptB, const Point3d& ptC)
|
||||||
|
{
|
||||||
|
// If P is on a vertex is considered inside
|
||||||
|
if ( AreSamePoint( ptP, ptA))
|
||||||
|
return true ;
|
||||||
|
if ( AreSamePoint( ptP, ptB))
|
||||||
|
return true ;
|
||||||
|
if ( AreSamePoint( ptP, ptC))
|
||||||
|
return true ;
|
||||||
|
// If P is on the right of at least one edge is outside
|
||||||
|
if ( TriangleIsCCW( ptA, ptP, ptB, EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
if ( TriangleIsCCW( ptB, ptP, ptC, EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
if ( TriangleIsCCW( ptC, ptP, ptA, EPS_SMALL))
|
||||||
|
return false ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
Triangulate::SortInternalLoops( const POLYLINEVECTOR& vPL, INTVECTOR& vOrd)
|
Triangulate::SortInternalLoops( const POLYLINEVECTOR& vPL, INTVECTOR& vOrd)
|
||||||
@@ -1385,6 +1407,7 @@ RemoveFistInvalidTrg( PNTVECTOR& vPt, INTVECTOR& vTr)
|
|||||||
// I triangoli cap se eliminati danno origine a T-junctions, quindi devono essere gestiti opportunamente con dei flip.
|
// I triangoli cap se eliminati danno origine a T-junctions, quindi devono essere gestiti opportunamente con dei flip.
|
||||||
// I triangoli needle se eliminati non sono problematici, ma i loro vertici coincidenti vanno gestiti opportunamente nel
|
// I triangoli needle se eliminati non sono problematici, ma i loro vertici coincidenti vanno gestiti opportunamente nel
|
||||||
// calcolo delle adiacenze dei triangoli cap.
|
// calcolo delle adiacenze dei triangoli cap.
|
||||||
|
// TO DO da capire e gestire casi in cui flip lascia triangoli invalidi
|
||||||
|
|
||||||
int nTria = int( vTr.size()) / 3 ;
|
int nTria = int( vTr.size()) / 3 ;
|
||||||
INTVECTOR vCapTria ;
|
INTVECTOR vCapTria ;
|
||||||
@@ -1482,46 +1505,40 @@ RemoveFistInvalidTrg( PNTVECTOR& vPt, INTVECTOR& vTr)
|
|||||||
INTVECTOR vChain, vChainEdges ;
|
INTVECTOR vChain, vChainEdges ;
|
||||||
vChain.emplace_back( nTA) ;
|
vChain.emplace_back( nTA) ;
|
||||||
vChainEdges.emplace_back( nEA) ;
|
vChainEdges.emplace_back( nEA) ;
|
||||||
|
int nTCurr = nTB ;
|
||||||
while ( nTB != -1 && ! vbIsValidTria[nTB]) {
|
int nEOther ;
|
||||||
// aggiungo alla catena
|
while ( nTCurr != -1 && ! vbIsValidTria[nTCurr]) {
|
||||||
vChain.emplace_back( nTB) ;
|
|
||||||
|
|
||||||
// calcolo il successivo
|
// calcolo il successivo
|
||||||
nTA = nTB ;
|
int nTOther, nECurr ;
|
||||||
FindAdjacentOnLongerEdge( vPt, vTr, nTA, nEA, nTB, nEB) ;
|
FindAdjacentOnLongerEdge( vPt, vTr, nTCurr, nECurr, nTOther, nEOther) ;
|
||||||
vChainEdges.emplace_back( nEA) ;
|
|
||||||
|
|
||||||
// verifico di non aver trovato un'adiacenza ambigua ( ovvero due triangoli invalidi adiacenti sui loro lati più lunghi)
|
if ( nTOther == vChain.back()) {
|
||||||
// e quindi di non essere entrato in un loop
|
// se ho trovato un'adiacenza ambigua ( ovvero due triangoli invalidi adiacenti sui loro lati più lunghi)
|
||||||
if ( nTB == vChain[vChain.size()-2]) {
|
|
||||||
// flip dei due triangoli per modificare il lato più lungo e togliere adiacenza ambigua
|
// flip dei due triangoli per modificare il lato più lungo e togliere adiacenza ambigua
|
||||||
FlipTrg( vTr, nTA, nTB, nEA, nEB) ;
|
FlipTrg( vTr, nTCurr, nTOther, nECurr, nEOther) ;
|
||||||
// aggiorno per iterazione successiva
|
if ( vChain.size() > 1) {
|
||||||
if ( vChain.size() == 2) {
|
|
||||||
vChain.pop_back() ;
|
vChain.pop_back() ;
|
||||||
vChainEdges.pop_back() ;
|
vChainEdges.pop_back() ;
|
||||||
FindAdjacentOnLongerEdge( vPt, vTr, vChain.back(), nEA, nTB, nEB) ;
|
// individuo il nuovo adiacente all'ultimo triangolo della catena tra i due appena flippati
|
||||||
vChainEdges[0] = nEA ;
|
TestAdjacentOnEdge( vTr, vChain.back(), vChainEdges.back(), nTCurr, nTOther, nTB, nEB) ;
|
||||||
|
nTOther = nTB ;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// elimino gli ultimi due triangoli che sono appena stati flippati e ricalcolo adiacenza del triangolo
|
|
||||||
// precedente
|
|
||||||
vChain.pop_back() ;
|
|
||||||
vChain.pop_back() ;
|
|
||||||
vChainEdges.pop_back() ;
|
|
||||||
vChainEdges.pop_back() ;
|
|
||||||
int nTTest1 = nTA ;
|
|
||||||
int nTTest2 = nTB ;
|
|
||||||
TestAdjacentOnEdge( vTr, vChain.back(), vChainEdges.back(), nTTest1, nTTest2, nTB, nEB) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
vChain.emplace_back( nTCurr) ;
|
||||||
|
vChainEdges.emplace_back( nECurr) ;
|
||||||
|
}
|
||||||
|
// aggiorno per iterazione successiva
|
||||||
|
nTCurr = nTOther ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// se la catena termina su triangolo nullo, annullo tutti i triangoli della catena
|
// se la catena termina su triangolo nullo, annullo tutti i triangoli della catena
|
||||||
if ( nTB == -1) {
|
if ( nTCurr == -1) {
|
||||||
bRemovedTrg = true ;
|
bRemovedTrg = true ;
|
||||||
for ( int k = 0 ; k < int( vChain.size()) ; k++) {
|
for ( int k = 0 ; k < int( vChain.size()) ; k++) {
|
||||||
|
if ( vbIsValidTria[vChain[k]])
|
||||||
|
continue ;
|
||||||
vTr[3*vChain[k]] = -1 ;
|
vTr[3*vChain[k]] = -1 ;
|
||||||
vTr[3*vChain[k] + 1] = -1 ;
|
vTr[3*vChain[k] + 1] = -1 ;
|
||||||
vTr[3*vChain[k] + 2] = -1 ;
|
vTr[3*vChain[k] + 2] = -1 ;
|
||||||
@@ -1530,14 +1547,16 @@ RemoveFistInvalidTrg( PNTVECTOR& vPt, INTVECTOR& vTr)
|
|||||||
}
|
}
|
||||||
// se catena termina su un triangolo valido, applico il flip a cascata a partire dall'ultimo triangolo invalido
|
// se catena termina su un triangolo valido, applico il flip a cascata a partire dall'ultimo triangolo invalido
|
||||||
else {
|
else {
|
||||||
FlipTrg( vTr, vChain.back(), nTB, vChainEdges.back(), nEB) ;
|
FlipTrg( vTr, vChain.back(), nTCurr, vChainEdges.back(), nEOther) ;
|
||||||
vbIsValidTria[vChain.back()] = true ;
|
vbIsValidTria[vChain.back()] = true ;
|
||||||
int nTrgTest1 = vChain.back() ;
|
int nTrgTest1 = vChain.back() ;
|
||||||
int nTrgTest2 = nTB ;
|
int nTrgTest2 = nTCurr ;
|
||||||
for ( int i = int( vChain.size()-2) ; i >= 0 ; i--) {
|
for ( int j = int( vChain.size()-2) ; j >= 0 ; j--) {
|
||||||
// triangolo corrente
|
// triangolo corrente
|
||||||
int nTA = vChain[i] ;
|
int nTA = vChain[j] ;
|
||||||
int nEA = vChainEdges[i] ;
|
if ( vbIsValidTria[nTA])
|
||||||
|
continue ;
|
||||||
|
int nEA = vChainEdges[j] ;
|
||||||
// devo trovare il nuovo adiacente dopo il flip dei successivi nella catena
|
// devo trovare il nuovo adiacente dopo il flip dei successivi nella catena
|
||||||
TestAdjacentOnEdge( vTr, nTA, nEA, nTrgTest1, nTrgTest2, nTB, nEB) ;
|
TestAdjacentOnEdge( vTr, nTA, nEA, nTrgTest1, nTrgTest2, nTB, nEB) ;
|
||||||
// flip per rendere valido il triangolo corrente
|
// flip per rendere valido il triangolo corrente
|
||||||
@@ -1608,7 +1627,7 @@ MakeByFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr)
|
|||||||
vPt.reserve( fist.c_vertex.num_vertices) ;
|
vPt.reserve( fist.c_vertex.num_vertices) ;
|
||||||
for ( int i = 0 ; i < fist.c_vertex.num_vertices ; i ++)
|
for ( int i = 0 ; i < fist.c_vertex.num_vertices ; i ++)
|
||||||
vPt.emplace_back( fist.c_vertex.vertices[i].x, fist.c_vertex.vertices[i].y, fist.c_vertex.vertices[i].z) ;
|
vPt.emplace_back( fist.c_vertex.vertices[i].x, fist.c_vertex.vertices[i].y, fist.c_vertex.vertices[i].z) ;
|
||||||
|
|
||||||
// recupero i triangoli da fist
|
// recupero i triangoli da fist
|
||||||
vTr.reserve( 3 * fist.c_vertex.num_triangles) ;
|
vTr.reserve( 3 * fist.c_vertex.num_triangles) ;
|
||||||
for ( int i = 0 ; i < fist.c_vertex.num_triangles ; i ++) {
|
for ( int i = 0 ; i < fist.c_vertex.num_triangles ; i ++) {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ class Triangulate
|
|||||||
bool TriangleIsCCW( const Point3d& ptA, const Point3d& ptB, const Point3d& ptC, double dToler = 0.1 * EPS_SMALL) ;
|
bool TriangleIsCCW( const Point3d& ptA, const Point3d& ptB, const Point3d& ptC, double dToler = 0.1 * EPS_SMALL) ;
|
||||||
bool TestIntersection( const Point3d& ptA1, const Point3d& ptA2, const Point3d& ptB1, const Point3d& ptB2) ;
|
bool TestIntersection( const Point3d& ptA1, const Point3d& ptA2, const Point3d& ptB1, const Point3d& ptB2) ;
|
||||||
bool TestPointInTriangle( const Point3d& ptP, const Point3d& ptA, const Point3d& ptB, const Point3d& ptC) ;
|
bool TestPointInTriangle( const Point3d& ptP, const Point3d& ptA, const Point3d& ptB, const Point3d& ptC) ;
|
||||||
|
bool TestPointInOrOnTriangle( const Point3d& ptP, const Point3d& ptA, const Point3d& ptB, const Point3d& ptC) ;
|
||||||
bool SortInternalLoops( const POLYLINEVECTOR& vPL, INTVECTOR& vOrd) ;
|
bool SortInternalLoops( const POLYLINEVECTOR& vPL, INTVECTOR& vOrd) ;
|
||||||
bool GetPntVectorFromPolyline( const PolyLine& PL, bool bXmaxStart, PNTVECTOR& vPi) ;
|
bool GetPntVectorFromPolyline( const PolyLine& PL, bool bXmaxStart, PNTVECTOR& vPi) ;
|
||||||
bool GetOuterPntToJoin( const PNTVECTOR& vPt, const Point3d& ptP, int& nI) ;
|
bool GetOuterPntToJoin( const PNTVECTOR& vPt, const Point3d& ptP, int& nI) ;
|
||||||
|
|||||||
+5483
File diff suppressed because it is too large
Load Diff
+536
-140
File diff suppressed because it is too large
Load Diff
@@ -18,11 +18,15 @@
|
|||||||
#include "Tool.h"
|
#include "Tool.h"
|
||||||
#include "/EgtDev/Include/EGkVolZmap.h"
|
#include "/EgtDev/Include/EGkVolZmap.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
#include "/EgtDev/Include/EGkIntersLineVolZmap.h"
|
||||||
|
#include "/EgtDev/Include/EGkSurfTriMesh.h"
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <mutex>
|
#include <tuple>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
typedef std::pair<Point3d, Vector3d> PNTVEC3D ;
|
||||||
|
typedef std::vector<PNTVEC3D> PNTVEC3DVECTOR ; // vettore di intersezioni punto, vettore, tipo superficie
|
||||||
|
|
||||||
// ------------------------- FORWARD -------------------------------------------------------------
|
// ------------------------- FORWARD -------------------------------------------------------------
|
||||||
class IntersParLinesSurfTm ;
|
class IntersParLinesSurfTm ;
|
||||||
|
|
||||||
@@ -77,13 +81,14 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
public : // IVolZmap
|
public : // IVolZmap
|
||||||
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
bool CopyFrom( const IGeoObj* pGObjSrc) override ;
|
||||||
bool Clear( void) override ;
|
bool Clear( void) override ;
|
||||||
bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
|
bool Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex, int* nError = nullptr) override ;
|
||||||
bool CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex) override ;
|
bool CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex, int* nError = nullptr) override ;
|
||||||
bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex) override ;
|
bool CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex, int* nError = nullptr) override ;
|
||||||
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex) override ;
|
bool CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox = 0, int* nError = nullptr) override ;
|
||||||
int GetBlockCount( void) const override ;
|
int GetBlockCount( void) const override ;
|
||||||
int GetBlockUpdatingCounter( int nBlock) const override ;
|
int GetBlockUpdatingCounter( int nBlock) const override ;
|
||||||
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
|
bool GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const override ;
|
||||||
|
ISurfTriMesh* GetSurfTriMesh( void) const override ;
|
||||||
bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ;
|
bool GetEdges( ICURVEPOVECTOR& vpCurve) const override ;
|
||||||
bool GetVolume( double& dVol) const override ;
|
bool GetVolume( double& dVol) const override ;
|
||||||
bool IsTriDexel( void) const override
|
bool IsTriDexel( void) const override
|
||||||
@@ -93,7 +98,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
{ return m_nDexVoxRatio ; }
|
{ return m_nDexVoxRatio ; }
|
||||||
bool ChangeResolution( int nDexVoxRatio) override ;
|
bool ChangeResolution( int nDexVoxRatio) override ;
|
||||||
void SetShowEdges( bool bShow) override
|
void SetShowEdges( bool bShow) override
|
||||||
{ m_bShowEdges = bShow ; // qui è necessario far ricreare la grafica
|
{ m_bShowEdges = bShow ; // qui è necessario far ricreare la grafica
|
||||||
m_OGrMgr.Clear() ; }
|
m_OGrMgr.Clear() ; }
|
||||||
bool GetShowEdges( void) const override
|
bool GetShowEdges( void) const override
|
||||||
{ return m_bShowEdges ; }
|
{ return m_bShowEdges ; }
|
||||||
@@ -144,7 +149,10 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
bool RemovePart( int nPart) override ;
|
bool RemovePart( int nPart) override ;
|
||||||
int GetPartMinDistFromPoint( const Point3d& ptP) const override ;
|
int GetPartMinDistFromPoint( const Point3d& ptP) const override ;
|
||||||
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
|
bool AddSurfTm( const ISurfTriMesh* pStm) override ;
|
||||||
bool MakeUniform( double dToler) override ;
|
bool SubtractSurfTm( const ISurfTriMesh* pStm) override ;
|
||||||
|
bool MakeUniform( double dToler, bool bIsExtensionFirst, int nToolNum) override ;
|
||||||
|
bool RemoveFins( const Vector3d& vtDir, double dThick) override ;
|
||||||
|
bool Offset( double dOffs, int nType) override ;
|
||||||
|
|
||||||
public : // IGeoObjRW
|
public : // IGeoObjRW
|
||||||
int GetNgeId( void) const override ;
|
int GetNgeId( void) const override ;
|
||||||
@@ -165,6 +173,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
return *this ; }
|
return *this ; }
|
||||||
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const ;
|
bool GetLineIntersection( const Point3d& ptP, const Vector3d& vtD, ILZIVECTOR& vIntersInfo) const ;
|
||||||
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const ;
|
bool GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) const ;
|
||||||
|
bool CreateFromTriMeshOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) ;
|
||||||
|
bool CreateFromTriMeshThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol, int nType = STMOFF_FILLET) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
enum CubeType { VOX_EXTERN = 1,
|
enum CubeType { VOX_EXTERN = 1,
|
||||||
@@ -217,7 +227,16 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
typedef std::unordered_map<int, Voxel> VoxelContainer ;
|
typedef std::unordered_map<int, Voxel> VoxelContainer ;
|
||||||
// Unordered map per la coerenza topologica
|
// Unordered map per la coerenza topologica
|
||||||
typedef std::unordered_map<int, bool> InterVoxMatter ;
|
typedef std::unordered_map<int, bool> InterVoxMatter ;
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
// Numero massimo approssimativo di Dexel per versione 32-bit per evitare Crash con memoria
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
static const int MAX_DEXEL_32_BIT = 3000000 + 1 ;
|
||||||
|
#else
|
||||||
|
static const int MAX_DEXEL_32_BIT = 5000000 + 1 ;
|
||||||
|
#endif
|
||||||
|
static int m_nDexelNbr ; // numero corrente di Dexel presenti
|
||||||
|
#endif
|
||||||
|
|
||||||
private :
|
private :
|
||||||
bool CopyFrom( const VolZmap& clSrc) ;
|
bool CopyFrom( const VolZmap& clSrc) ;
|
||||||
bool ResetGraphics( void) ;
|
bool ResetGraphics( void) ;
|
||||||
@@ -250,17 +269,22 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
bool AddIntervals( int nGrid, int nI, int nJ,
|
bool AddIntervals( int nGrid, int nI, int nJ,
|
||||||
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||||
int nToolNum, bool bSkipSwap = false) ;
|
int nToolNum, bool bSkipSwap = false) ;
|
||||||
bool AddMissingIntervalsInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, double dZ, double dToler,
|
bool UniformIntervalsInVoxel( int nGrid, int nI, int nJ, double dZMin, double dZMax,
|
||||||
Vector3d vtToolMin, Vector3d vtToolMax, int nToolNum) ;
|
double dToler, bool bAdd, int nToolNum, const Vector3d& vtToolMin,
|
||||||
bool AddSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
|
const Vector3d& vtToolMax) ;
|
||||||
Vector3d& vtMin, Vector3d& vtMax) ;
|
bool AddStripInterval( int nGrid, int nI, int nJ, double dZMin, double dZMax, int nToolNum) ;
|
||||||
|
bool ManageSubIntervalInVoxel( VolZmap* VolZmapRef, int nGrid, int nI, int nJ, int nK, double& dMin, double& dMax,
|
||||||
|
Vector3d& vtMin, Vector3d& vtMax) ;
|
||||||
// Spostamenti utensile
|
// Spostamenti utensile
|
||||||
bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ;
|
bool MillingTranslationStep( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtD, const Vector3d& vtA) ;
|
||||||
bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
bool MillingGeneralMotionStep( const Point3d& ptPs, const Vector3d& vtDs, const Vector3d& vtAs,
|
||||||
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) ;
|
const Point3d& ptPe, const Vector3d& vtDe, const Vector3d& vtAe) ;
|
||||||
|
bool SelectGeneralMotion( int nGrid, const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtLs, const Vector3d& vtLe, int n5AxisType) ;
|
||||||
bool SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtL, const Vector3d& vtAL) ;
|
bool SelectMotion( int nGrid, const Point3d& ptLs, const Point3d& ptLe, const Vector3d& vtL, const Vector3d& vtAL) ;
|
||||||
bool InitializePointsAndVectors( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtAs,
|
bool InitializePointsAndVectors( const Point3d& ptPs, const Point3d& ptPe, const Vector3d& vtDs, const Vector3d& vtAs,
|
||||||
Point3d ptLs[3], Point3d ptLe[3], Vector3d vtLs[3], Vector3d vtALs[3]) ;
|
Point3d ptLs[3], Point3d ptLe[3], Vector3d vtLs[3], Vector3d vtALs[3]) ;
|
||||||
|
bool InitializeAuxPoints( Point3d ptTop1s[3], Point3d ptTop1e[3], Point3d ptTop2s[3], Point3d ptTop2e[3],
|
||||||
|
Point3d ptBottom1s[3], Point3d ptBottom1e[3], Point3d ptBottom2s[3], Point3d ptBottom2e[3]) ;
|
||||||
// SOTTRAZIONI
|
// SOTTRAZIONI
|
||||||
// UTENSILI
|
// UTENSILI
|
||||||
// Asse di simmetria parallelo a Z
|
// Asse di simmetria parallelo a Z
|
||||||
@@ -288,11 +312,16 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
bool Conus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
bool Conus_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
||||||
bool Conus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
bool Conus_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
||||||
bool Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ;
|
bool Mrt_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ;
|
||||||
bool Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ; // E' in realtà un Perp
|
bool Mrt_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ; // E' in realt� un Perp
|
||||||
bool Chs_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ;
|
bool Chs_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ;
|
||||||
bool Chs_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ; // E' in realtà un Perp
|
bool Chs_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir, const Vector3d& vtAux) ; // E' in realt� un Perp
|
||||||
bool GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
bool GenTool_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
||||||
bool GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
bool GenTool_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir) ;
|
||||||
|
// lavorazioni a 5 assi
|
||||||
|
bool GenTool_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
|
||||||
|
bool Cyl_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, double dHeightCorr = 0, int n5AxisType = ACROSS) ;
|
||||||
|
bool CylBall_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
|
||||||
|
bool Conus_5AxisMilling(int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe, int nToolNum, int n5AxisType = ACROSS) ;
|
||||||
|
|
||||||
// COMPONENTI
|
// COMPONENTI
|
||||||
// Asse di simmetria diretto come l'asse Z
|
// Asse di simmetria diretto come l'asse Z
|
||||||
@@ -311,7 +340,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum) ;
|
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum) ;
|
||||||
bool CompPar_ZMilling( int nGrid, double dLenX, double dLenY, double dLenZ,
|
bool CompPar_ZMilling( int nGrid, double dLenX, double dLenY, double dLenZ,
|
||||||
const Point3d& ptS, const Point3d& ptE,
|
const Point3d& ptS, const Point3d& ptE,
|
||||||
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
|
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realt� MillingPerp
|
||||||
// Asse di simmetria con orientazione generica
|
// Asse di simmetria con orientazione generica
|
||||||
bool CompCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
bool CompCyl_Drilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDir,
|
||||||
double dHei, double dRad, bool bTapB, bool bTapT, int nToolNum) ;
|
double dHei, double dRad, bool bTapB, bool bTapT, int nToolNum) ;
|
||||||
@@ -327,7 +356,15 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum) ;
|
const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum) ;
|
||||||
bool CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ,
|
bool CompPar_Milling( int nGrid, double dLenX, double dLenY, double dLenZ,
|
||||||
const Point3d& ptS, const Point3d& ptE,
|
const Point3d& ptS, const Point3d& ptE,
|
||||||
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
|
const Vector3d& vtToolDir, const Vector3d& vtAux, int nToolNum) ; // E' in realtà MillingPerp
|
||||||
|
// lavorazioni a 5 assi
|
||||||
|
bool Comp_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
|
||||||
|
double dHeight, double dMaxRad, double dMinRad, int nToolNum, int n5AxisType) ;
|
||||||
|
bool CompCyl_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtLs, const Vector3d& vtLe,
|
||||||
|
double dHeight, double dRadius, int nToolNum, int n5AxisType) ;
|
||||||
|
bool CompConus_5AxisMilling( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtToolDirS, const Vector3d& vtToolDirE, double dHei, double dMaxRad, double dMinRad,
|
||||||
|
bool bTapB, bool bTapT, const Vector3d& vtArcNormMaxR, const Vector3d& vtArcNormMinR, int nToolNum, int n5AxisType) ;
|
||||||
|
|
||||||
// Generica traslazione sfera
|
// Generica traslazione sfera
|
||||||
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
|
bool CompBall_Milling( int nGrid, const Point3d& ptS, const Point3d& ptE, double dRad, int nToolNum) ;
|
||||||
// Additivi
|
// Additivi
|
||||||
@@ -341,7 +378,7 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
// BBox per utensili e solidi semplici con movimenti di traslazione
|
// BBox per utensili e solidi semplici con movimenti di traslazione
|
||||||
inline bool TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
|
inline bool TestToolBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
|
||||||
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
|
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
|
||||||
inline bool TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV,
|
inline bool TestCompoBBox( int nGrid, const Point3d& ptP1, const Point3d& ptP2, const Vector3d& vtV, const Vector3d& vtV2,
|
||||||
double dRad, double dTipRad, double dHei,
|
double dRad, double dTipRad, double dHei,
|
||||||
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
|
int& nStI, int& nStJ, int& nEnI, int& nEnJ) ;
|
||||||
inline bool TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA,
|
inline bool TestParaBBox( int nGrid, const Point3d& ptS, const Point3d& ptE, const Vector3d& vtD, const Vector3d& vtA,
|
||||||
@@ -356,9 +393,6 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
double& dU1, double& dU2) const ;
|
double& dU1, double& dU2) const ;
|
||||||
bool GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ;
|
bool GetDepthWithDexel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ;
|
||||||
bool GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ;
|
bool GetDepthWithVoxel( const Point3d& ptP, const Vector3d& vtDir, double& dInLength, double& dOutLength) const ;
|
||||||
bool IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
|
||||||
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
|
||||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const ;
|
|
||||||
bool IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
bool IntersLineEllipticalCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
||||||
const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen,
|
const Frame3d& CircFrame, double dRad, double dLongMvLen, double dOrtMvLen,
|
||||||
bool bTapLow, bool bTapUp,
|
bool bTapLow, bool bTapUp,
|
||||||
@@ -432,17 +466,62 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
bool AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
bool AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
|
bool SubtractMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
|
// Funzioni per Offset di superfici
|
||||||
|
bool InitVolZMapOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||||
|
bool InitVolZMapThickeningOffset( const CISURFTMPVECTOR& vSurf, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapByOpenSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapByOpenSurfSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapByClosedSurfFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapByClosedSurfSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapBySurfThickeningFilletOffset( const ISurfTriMesh* Surf, double dOffs, double dTol) ;
|
||||||
|
bool UpdateVolZMapBySurfThickeningSharpedOffset( const ISurfTriMesh* Surf, int nType, double dOffs, double dTol) ;
|
||||||
|
bool CreateOffsetSphereOnVertex( const Point3d& ptV, double dOffs, int nGrid, int nVertexType = 0) ;
|
||||||
|
bool CreateOffsetCylinderOnEdge( const Point3d& ptP1, const Point3d& ptP2, double dOffs, int nGrid, int nVertexType = 0) ;
|
||||||
|
bool CreateFatOffsetExtrusionFace( const ISurfTriMesh* Surf, double dOffs, bool bThickle, int nTool = 0) ;
|
||||||
|
bool CreateOrientedOffsetExtrusionFace( const ISurfTriMesh* Surf, double dOffs) ;
|
||||||
|
bool SubtractIntervalsForOffset( int nGrid, int nI, int nJ,
|
||||||
|
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||||
|
int nToolNum, bool bSkipSwap = false) ;
|
||||||
|
bool AddIntervalsForOffset( int nGrid, int nI, int nJ,
|
||||||
|
double dMin, double dMax, const Vector3d& vtNMin, const Vector3d& vtNMax,
|
||||||
|
int nToolMin, int nToolMax, bool bSkipSwap = false) ;
|
||||||
|
bool CutByPlaneForOffset( const Plane3d& plCut) ;
|
||||||
|
bool AddSurfTmForOffset( const ISurfTriMesh* pStm, int nTool) ;
|
||||||
|
bool AddMapPartForOffset( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
|
const ISurfTriMesh& Surf, int nTool, IntersParLinesSurfTm& intPLSTM) ;
|
||||||
|
// Funzioni per Offset di Zmap
|
||||||
|
bool OffsetFillet( double dOffs) ;
|
||||||
|
bool OffsetSharped( double dOffs, int nType) ;
|
||||||
|
// Funzione analisi punti/Normali per Alette
|
||||||
|
bool GetLocalPoint( int nGrid, int nI, int nJ, double dZ, Point3d& ptLoc) ;
|
||||||
|
bool ComputePointAndNormalForRemovingFins( int nGrid, int nI, int nJ, double dZ,
|
||||||
|
const Vector3d& vtDir, double dThick, bool bMinVsMax, int nTool,
|
||||||
|
Vector3d& vtN, double& dNewZ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;
|
enum Move5Axis {
|
||||||
enum Shape { GENERIC = 0, BOX = 1, EXTRUSION = 2} ;
|
ALONG_CONVEX = 0 ,
|
||||||
|
ALONG_CONCAVE = 1 ,
|
||||||
|
ACROSS = 2 ,
|
||||||
|
NO_BASE_INTERS = 3} ;
|
||||||
|
enum Status {
|
||||||
|
ERR = 0,
|
||||||
|
OK = 1,
|
||||||
|
TO_VERIFY = 2} ;
|
||||||
|
enum Shape {
|
||||||
|
GENERIC = 0,
|
||||||
|
BOX = 1,
|
||||||
|
EXTRUSION = 2,
|
||||||
|
OFFSET = 3} ;
|
||||||
static const int N_MAPS = 3 ;
|
static const int N_MAPS = 3 ;
|
||||||
static const int N_VOXBLOCK = 32 ;
|
static const int N_VOXBLOCK = 32 ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
|
||||||
Status m_nStatus ; // stato
|
Status m_nStatus ; // stato
|
||||||
int m_nTempProp[2] ; // vettore proprietà temporanee
|
int m_nTempProp[2] ; // vettore proprietà temporanee
|
||||||
double m_dTempParam[2] ; // vettore parametri temporanei
|
double m_dTempParam[2] ; // vettore parametri temporanei
|
||||||
bool m_bShowEdges ; // flag di visualizzazione spigoli vivi
|
bool m_bShowEdges ; // flag di visualizzazione spigoli vivi
|
||||||
Frame3d m_MapFrame ; // riferimento intrinseco dello Zmap
|
Frame3d m_MapFrame ; // riferimento intrinseco dello Zmap
|
||||||
@@ -476,8 +555,8 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
mutable BOOLVECTOR m_BlockToUpdate ;
|
mutable BOOLVECTOR m_BlockToUpdate ;
|
||||||
mutable INTVECTOR m_BlockUpdatingCounter ;
|
mutable INTVECTOR m_BlockUpdatingCounter ;
|
||||||
|
|
||||||
int m_nConnectedCompoCount ; // Se == - 1 il numero di componenti non è noto
|
int m_nConnectedCompoCount ; // Se == - 1 il numero di componenti non è noto
|
||||||
// Se >= 0 è il numero di componenti connesse
|
// Se >= 0 è il numero di componenti connesse
|
||||||
|
|
||||||
mutable std::vector<VoxelContainer> m_InterBlockVox ;
|
mutable std::vector<VoxelContainer> m_InterBlockVox ;
|
||||||
mutable SharpTriaMatrix m_InterBlockOriginalSharpTria ;
|
mutable SharpTriaMatrix m_InterBlockOriginalSharpTria ;
|
||||||
@@ -490,9 +569,9 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
mutable std::vector<InterVoxMatter> m_SliceXY ;
|
mutable std::vector<InterVoxMatter> m_SliceXY ;
|
||||||
mutable std::vector<InterVoxMatter> m_SliceXZ ;
|
mutable std::vector<InterVoxMatter> m_SliceXZ ;
|
||||||
mutable std::vector<InterVoxMatter> m_SliceYZ ;
|
mutable std::vector<InterVoxMatter> m_SliceYZ ;
|
||||||
mutable std::mutex m_SliceMutex ;
|
mutable std::atomic_flag m_SliceFlag ;
|
||||||
|
|
||||||
std::atomic<bool> m_bIsBox ;
|
bool m_bIsBox ;
|
||||||
|
|
||||||
int m_nCurrTool ;
|
int m_nCurrTool ;
|
||||||
std::vector<Tool> m_vTool ;
|
std::vector<Tool> m_vTool ;
|
||||||
@@ -500,6 +579,12 @@ class VolZmap : public IVolZmap, public IGeoObjRW
|
|||||||
double m_dToolAngTolDeg ;
|
double m_dToolAngTolDeg ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
// Offset
|
||||||
|
enum {
|
||||||
|
VOLZMAP_OFFS_FILLET = 0,
|
||||||
|
VOLZMAP_OFFS_CHANFER = 1,
|
||||||
|
VOLZMAP_OFFS_EXTENDED = 2
|
||||||
|
} ;
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
inline VolZmap* CreateBasicVolZmap( void)
|
inline VolZmap* CreateBasicVolZmap( void)
|
||||||
|
|||||||
+24
-143
@@ -2071,127 +2071,6 @@ VolZmap::CDeSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecise)
|
|||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
// Riferimento con origine nel centro della base e asse di simmetria coincidente con l'asse Z.
|
|
||||||
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
|
||||||
//----------------------------------------------------------------------------
|
|
||||||
bool
|
|
||||||
VolZmap::IntersLineCylinder( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
|
||||||
const Frame3d& CylFrame, double dH, double dRad, bool bTapLow, bool bTapUp,
|
|
||||||
Point3d& ptInt1, Vector3d& vtN1, Point3d& ptInt2, Vector3d& vtN2) const
|
|
||||||
{
|
|
||||||
// Porto la linea nel riferimento del cilindro
|
|
||||||
Point3d ptP = GetToLoc( ptLineSt, CylFrame) ;
|
|
||||||
Vector3d vtV = GetToLoc( vtLineDir, CylFrame) ;
|
|
||||||
|
|
||||||
// Determino le eventuali intersezioni con le due basi a quota minima e massima (solo se linea non parallela ad esse)
|
|
||||||
int nBasInt = 0 ;
|
|
||||||
if ( abs( vtV.z) > EPS_ZERO) {
|
|
||||||
// le linee tangenti al cilindro non sono considerate intersecanti
|
|
||||||
double dEpsRad = ( vtV.IsZeroXY() ? - EPS_SMALL : EPS_SMALL) ;
|
|
||||||
ptInt1 = ptP + ( ( 0 - ptP.z) / vtV.z) * vtV ;
|
|
||||||
if ( ptInt1.x * ptInt1.x + ptInt1.y * ptInt1.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
|
||||||
nBasInt += 1 ;
|
|
||||||
vtN1 = Z_AX ;
|
|
||||||
}
|
|
||||||
ptInt2 = ptP + ( ( dH - ptP.z) / vtV.z) * vtV ;
|
|
||||||
if ( ptInt2.x * ptInt2.x + ptInt2.y * ptInt2.y < dRad * dRad + 2 * dRad * dEpsRad) {
|
|
||||||
nBasInt += 2 ;
|
|
||||||
vtN2 = - Z_AX ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Se la linea interseca entrambe le basi, si sono trovate le due intersezioni
|
|
||||||
if ( nBasInt == 3) {
|
|
||||||
// Porto i punti e i versori nel riferimento globale
|
|
||||||
ptInt1.ToGlob( CylFrame) ;
|
|
||||||
vtN1.ToGlob( CylFrame) ;
|
|
||||||
ptInt2.ToGlob( CylFrame) ;
|
|
||||||
vtN2.ToGlob( CylFrame) ;
|
|
||||||
// Trovate intersezioni
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determino le intersezioni con la superficie laterale del cilindro
|
|
||||||
DBLVECTOR vdCoeff{ ptP.x * ptP.x + ptP.y * ptP.y - dRad * dRad,
|
|
||||||
2 * ( ptP.x * vtV.x + ptP.y * vtV.y),
|
|
||||||
vtV.x * vtV.x + vtV.y * vtV.y} ;
|
|
||||||
DBLVECTOR vdRoots ;
|
|
||||||
int nRoot = PolynomialRoots( 2, vdCoeff, vdRoots) ;
|
|
||||||
|
|
||||||
// Epsilon per piani di tappo
|
|
||||||
double dEpsLow = ( bTapLow ? - EPS_SMALL : EPS_SMALL) ;
|
|
||||||
double dEpsUp = ( bTapUp ? EPS_SMALL : - EPS_SMALL) ;
|
|
||||||
|
|
||||||
// Elimino le soluzioni cha danno intersezioni fuori dai limiti in Z del cilindro
|
|
||||||
if ( nRoot == 2) {
|
|
||||||
double dIntZ2 = ptP.z + vdRoots[1] * vtV.z ;
|
|
||||||
if ( dIntZ2 < 0 + dEpsLow || dIntZ2 > dH + dEpsUp)
|
|
||||||
-- nRoot ;
|
|
||||||
}
|
|
||||||
if ( nRoot >= 1) {
|
|
||||||
double dIntZ1 = ptP.z + vdRoots[0] * vtV.z ;
|
|
||||||
if ( dIntZ1 < 0 + dEpsLow || dIntZ1 > dH + dEpsUp) {
|
|
||||||
if ( nRoot == 2)
|
|
||||||
vdRoots[0] = vdRoots[1] ;
|
|
||||||
-- nRoot ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Due soluzioni: la retta interseca due volte la superficie laterale
|
|
||||||
if ( nRoot == 2) {
|
|
||||||
// Punti di intersezione con la superficie del cilindro
|
|
||||||
ptInt1 = ptP + vdRoots[0] * vtV ;
|
|
||||||
ptInt2 = ptP + vdRoots[1] * vtV ;
|
|
||||||
// Determino le normali
|
|
||||||
vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ;
|
|
||||||
vtN1.Normalize() ;
|
|
||||||
vtN2.Set( -ptInt2.x, -ptInt2.y, 0) ;
|
|
||||||
vtN2.Normalize() ;
|
|
||||||
// Porto i punti e i versori nel riferimento globale
|
|
||||||
ptInt1.ToGlob( CylFrame) ;
|
|
||||||
vtN1.ToGlob( CylFrame) ;
|
|
||||||
ptInt2.ToGlob( CylFrame) ;
|
|
||||||
vtN2.ToGlob( CylFrame) ;
|
|
||||||
// Trovate intersezioni
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Una soluzione : la retta interseca la superficie laterale e un piano
|
|
||||||
else if ( nRoot == 1) {
|
|
||||||
// Se piano superiore
|
|
||||||
if ( nBasInt == 2) {
|
|
||||||
// Punto di intersezione
|
|
||||||
ptInt1 = ptP + vdRoots[0] * vtV ;
|
|
||||||
// Normale alla superficie del cilindro verso l'interno
|
|
||||||
vtN1.Set( -ptInt1.x, -ptInt1.y, 0) ;
|
|
||||||
vtN1.Normalize() ;
|
|
||||||
}
|
|
||||||
// altrimenti piano inferiore
|
|
||||||
else if ( nBasInt == 1) {
|
|
||||||
// Punto di intersezione
|
|
||||||
ptInt2 = ptP + vdRoots[0] * vtV ;
|
|
||||||
// Normale alla superficie del cilindro verso l'interno
|
|
||||||
vtN2.Set( -ptInt2.x, -ptInt2.y, 0) ;
|
|
||||||
vtN2.Normalize() ;
|
|
||||||
}
|
|
||||||
// altrimenti niente
|
|
||||||
else
|
|
||||||
return false ;
|
|
||||||
// Porto i punti e i versori nel riferimento globale
|
|
||||||
ptInt1.ToGlob( CylFrame) ;
|
|
||||||
vtN1.ToGlob( CylFrame) ;
|
|
||||||
ptInt2.ToGlob( CylFrame) ;
|
|
||||||
vtN2.ToGlob( CylFrame) ;
|
|
||||||
// Trovate intersezioni
|
|
||||||
return true ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Nessuna soluzione : nessuna intersezione
|
|
||||||
else
|
|
||||||
return false ;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Riferimento con origine nel vertice del cono e asse di simmetria coincidente con l'asse Z.
|
// Riferimento con origine nel vertice del cono e asse di simmetria coincidente con l'asse Z.
|
||||||
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
// La funzione restituisce true in caso di intersezione, false altrimenti.
|
||||||
@@ -2294,7 +2173,7 @@ VolZmap::IntersLineConus( const Point3d& ptLineSt, const Vector3d& vtLineDir,
|
|||||||
vtN1.Normalize() ;
|
vtN1.Normalize() ;
|
||||||
}
|
}
|
||||||
// altrimenti piano inferiore
|
// altrimenti piano inferiore
|
||||||
else if( nBasInt == 1) {
|
else if ( nBasInt == 1) {
|
||||||
// Punto di intersezione
|
// Punto di intersezione
|
||||||
ptInt2 = ptP + vdRoots[0] * vtV ;
|
ptInt2 = ptP + vdRoots[0] * vtV ;
|
||||||
// Normale alla superficie del cono verso l'interno
|
// Normale alla superficie del cono verso l'interno
|
||||||
@@ -3080,17 +2959,18 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
return false ;
|
return false ;
|
||||||
// Se c'è intersezione valuto tutti i voxel interni
|
// Se c'è intersezione valuto tutti i voxel interni
|
||||||
if ( TestIntersPlaneBox( plPlaneLoc, b3BlockBox)) {
|
if ( TestIntersPlaneBox( plPlaneLoc, b3BlockBox)) {
|
||||||
// Ciclo sui voxel del blocco.
|
|
||||||
// Triangoli smooth
|
// Triangoli smooth
|
||||||
for ( int nV = 0 ; nV < int( m_BlockSmoothTria[nB].size()) ; ++ nV) {
|
// ciclo sui voxel del blocco.
|
||||||
|
for ( int nV = 0 ; nV < ssize( m_BlockSmoothTria[nB]) ; ++ nV) {
|
||||||
// Box del voxel
|
// Box del voxel
|
||||||
BBox3d b3Vox ;
|
BBox3d b3Vox ;
|
||||||
GetVoxelBox( m_BlockSmoothTria[nB][nV].i, m_BlockSmoothTria[nB][nV].j, m_BlockSmoothTria[nB][nV].k, b3Vox) ;
|
GetVoxelBox( m_BlockSmoothTria[nB][nV].i, m_BlockSmoothTria[nB][nV].j, m_BlockSmoothTria[nB][nV].k, b3Vox) ;
|
||||||
// Se non c'è intersezione col voxel, passo al successivo.
|
// Se non c'è intersezione col voxel, passo al successivo.
|
||||||
if ( ! TestIntersPlaneBox( plPlaneLoc, b3Vox))
|
if ( ! TestIntersPlaneBox( plPlaneLoc, b3Vox))
|
||||||
continue ;
|
continue ;
|
||||||
for ( int nT = 0 ; nT < int( m_BlockSmoothTria[nB][nV].vTria.size()) ; ++ nT) {
|
// ciclo sui triangoli del voxel
|
||||||
Triangle3d trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
for ( int nT = 0 ; nT < ssize( m_BlockSmoothTria[nB][nV].vTria) ; ++ nT) {
|
||||||
|
const Triangle3d& trTria = m_BlockSmoothTria[nB][nV].vTria[nT] ;
|
||||||
Point3d ptSt, ptEn ;
|
Point3d ptSt, ptEn ;
|
||||||
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
||||||
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
||||||
@@ -3102,18 +2982,18 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Triangoli sharp interni al blocco
|
// Triangoli sharp interni al blocco
|
||||||
for ( int nV = 0 ; nV < int( m_BlockSharpTria[nB].size()) ; ++ nV) {
|
// ciclo sui voxel del blocco.
|
||||||
|
for ( int nV = 0 ; nV < ssize( m_BlockSharpTria[nB]) ; ++ nV) {
|
||||||
// Box del voxel
|
// Box del voxel
|
||||||
BBox3d b3Vox ;
|
BBox3d b3Vox ;
|
||||||
GetVoxelBox( m_BlockSharpTria[nB][nV].i, m_BlockSharpTria[nB][nV].j, m_BlockSharpTria[nB][nV].k, b3Vox) ;
|
GetVoxelBox( m_BlockSharpTria[nB][nV].i, m_BlockSharpTria[nB][nV].j, m_BlockSharpTria[nB][nV].k, b3Vox) ;
|
||||||
// Se non c'è intersezione col voxel, passo al successivo.
|
|
||||||
// Ciclo sulle componenti connesse
|
// Ciclo sulle componenti connesse
|
||||||
for ( int nC = 0 ; nC < int( m_BlockSharpTria[nB][nV].vCompoTria.size()) ; ++ nC) {
|
for ( int nC = 0 ; nC < ssize( m_BlockSharpTria[nB][nV].vCompoTria) ; ++ nC) {
|
||||||
for ( int nT = 0 ; nT < int( m_BlockSharpTria[nB][nV].vCompoTria[nC].size()) ; ++ nT) {
|
for ( int nT = 0 ; nT < ssize( m_BlockSharpTria[nB][nV].vCompoTria[nC]) ; ++ nT) {
|
||||||
Triangle3d trTria = m_BlockSharpTria[nB][nV].vCompoTria[nC][nT] ;
|
const Triangle3d& trTria = m_BlockSharpTria[nB][nV].vCompoTria[nC][nT] ;
|
||||||
Point3d ptSt, ptEn ;
|
Point3d ptSt, ptEn ;
|
||||||
int nIntersType = IntersPlaneTria(plPlane, trTria, ptSt, ptEn) ;
|
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
||||||
if (nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
||||||
// Costruisco il tratto di curva
|
// Costruisco il tratto di curva
|
||||||
CurveLine cvLine ;
|
CurveLine cvLine ;
|
||||||
if ( cvLine.Set(ptSt, ptEn))
|
if ( cvLine.Set(ptSt, ptEn))
|
||||||
@@ -3123,10 +3003,10 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Triangoli grandi del blocco
|
// Triangoli grandi del blocco
|
||||||
for ( int nT = 0 ; nT < int( m_BlockBigTria[nB].size()) ; ++ nT) {
|
for ( int nT = 0 ; nT < ssize( m_BlockBigTria[nB]) ; ++ nT) {
|
||||||
Triangle3d trTria = m_BlockBigTria[nB][nT] ;
|
const Triangle3d& trTria = m_BlockBigTria[nB][nT] ;
|
||||||
Point3d ptSt, ptEn ;
|
Point3d ptSt, ptEn ;
|
||||||
int nIntersType = IntersPlaneTria(plPlane, trTria, ptSt, ptEn) ;
|
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
||||||
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
||||||
// Costruisco il tratto di curva
|
// Costruisco il tratto di curva
|
||||||
CurveLine cvLine ;
|
CurveLine cvLine ;
|
||||||
@@ -3136,11 +3016,11 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// In ogni caso valuto i triangoli sharp fra blocchi
|
// In ogni caso valuto i triangoli sharp fra blocchi
|
||||||
for ( int nV = 0 ; nV < int( m_InterBlockSharpTria[nB].size()) ; ++ nV) {
|
for ( int nV = 0 ; nV < ssize( m_InterBlockSharpTria[nB]) ; ++ nV) {
|
||||||
// Ciclo sulle componenti connesse
|
// Ciclo sulle componenti connesse
|
||||||
for ( int nC = 0 ; nC < int( m_InterBlockSharpTria[nB][nV].vCompoTria.size()) ; ++ nC) {
|
for ( int nC = 0 ; nC < ssize( m_InterBlockSharpTria[nB][nV].vCompoTria) ; ++ nC) {
|
||||||
for ( int nT = 0 ; nT < int( m_InterBlockSharpTria[nB][nV].vCompoTria[nC].size()) ; ++ nT) {
|
for ( int nT = 0 ; nT < ssize( m_InterBlockSharpTria[nB][nV].vCompoTria[nC]) ; ++ nT) {
|
||||||
Triangle3d trTria = m_InterBlockSharpTria[nB][nV].vCompoTria[nC][nT] ;
|
const Triangle3d& trTria = m_InterBlockSharpTria[nB][nV].vCompoTria[nC][nT] ;
|
||||||
Point3d ptSt, ptEn ;
|
Point3d ptSt, ptEn ;
|
||||||
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
int nIntersType = IntersPlaneTria( plPlane, trTria, ptSt, ptEn) ;
|
||||||
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
if ( nIntersType == IPTT_EDGE || nIntersType == IPTT_YES) {
|
||||||
@@ -3156,9 +3036,9 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
|
|
||||||
// Creo i loop
|
// Creo i loop
|
||||||
ChainCurves LoopCreator ;
|
ChainCurves LoopCreator ;
|
||||||
LoopCreator.Init( false, EPS_SMALL, int( vLine.size())) ;
|
LoopCreator.Init( false, EPS_SMALL, ssize( vLine)) ;
|
||||||
// Carico le curve per concatenarle
|
// Carico le curve per concatenarle
|
||||||
for ( int nCv = 0 ; nCv < int( vLine.size()) ; ++ nCv) {
|
for ( int nCv = 0 ; nCv < ssize( vLine) ; ++ nCv) {
|
||||||
Point3d ptSt = vLine[nCv].GetStart() ;
|
Point3d ptSt = vLine[nCv].GetStart() ;
|
||||||
Point3d ptEn = vLine[nCv].GetEnd() ;
|
Point3d ptEn = vLine[nCv].GetEnd() ;
|
||||||
Vector3d vtDir; vLine[nCv].GetStartDir(vtDir) ;
|
Vector3d vtDir; vLine[nCv].GetStartDir(vtDir) ;
|
||||||
@@ -3176,6 +3056,7 @@ VolZmap::GetPlaneIntersection( const Plane3d& plPlane, ICURVEPOVECTOR& vpLoop) c
|
|||||||
if ( ! pLoop->AddCurve( vLine[i - 1], true, 10 * EPS_SMALL))
|
if ( ! pLoop->AddCurve( vLine[i - 1], true, 10 * EPS_SMALL))
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
pLoop->TestClosure( 10 * EPS_SMALL) ;
|
||||||
pLoop->SetExtrusion( plPlane.GetVersN()) ;
|
pLoop->SetExtrusion( plPlane.GetVersN()) ;
|
||||||
pLoop->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
|
pLoop->MergeCurves( 10 * EPS_SMALL, ANG_TOL_STD_DEG) ;
|
||||||
// Inserisco la curva composita nella raccolta da ritornare
|
// Inserisco la curva composita nella raccolta da ritornare
|
||||||
|
|||||||
+245
-69
@@ -17,6 +17,7 @@
|
|||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "VolZmap.h"
|
#include "VolZmap.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkStmFromCurves.h"
|
||||||
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
#include "/EgtDev/Include/EGkIntersLineSurfTm.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
#include <future>
|
#include <future>
|
||||||
@@ -26,8 +27,8 @@ using namespace std ;
|
|||||||
// ------------------------- CREAZIONE MAPPA --------------------------------------------------------------------------------------
|
// ------------------------- CREAZIONE MAPPA --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex)
|
VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex, int* nError)
|
||||||
{
|
{
|
||||||
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
|
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
|
||||||
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
|
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
|
||||||
@@ -50,7 +51,7 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
m_nNx[0] = max( int( ( dDimX + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
m_nNx[0] = max( int( ( dDimX + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
||||||
m_nNy[0] = max( int( ( dDimY + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
m_nNy[0] = max( int( ( dDimY + EPS_SMALL) / m_dStep + 0.5), 1) ;
|
||||||
|
|
||||||
// Numero di componenti connesse
|
// Numero di componenti connesse
|
||||||
m_nConnectedCompoCount = 1 ;
|
m_nConnectedCompoCount = 1 ;
|
||||||
|
|
||||||
// Se tridexel
|
// Se tridexel
|
||||||
@@ -66,7 +67,7 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
m_nNx[1] = 0 ;
|
m_nNx[1] = 0 ;
|
||||||
m_nNy[1] = 0 ;
|
m_nNy[1] = 0 ;
|
||||||
m_nNx[2] = 0 ;
|
m_nNx[2] = 0 ;
|
||||||
m_nNy[2] = 0 ;
|
m_nNy[2] = 0 ;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definisco il numero di blocchi lungo x,y e z
|
// Definisco il numero di blocchi lungo x,y e z
|
||||||
@@ -80,12 +81,24 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||||
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
||||||
|
|
||||||
|
// Se versione 32-bit controllo di non superare il numero di Dexel massimo
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
for ( int i = 0 ; i < ssize( m_nDim) ; ++ i)
|
||||||
|
m_nDexelNbr += m_nDim[i] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Creazione delle celle per ogni mappa
|
// Creazione delle celle per ogni mappa
|
||||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||||
m_Values[i].resize( m_nDim[i]) ;
|
m_Values[i].resize( m_nDim[i]) ;
|
||||||
|
|
||||||
// Riempimento delle celle
|
// Riempimento delle celle
|
||||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
for ( int i = 0 ; i < m_nMapNum ; ++ i) {
|
||||||
for ( int j = 0 ; j < m_nDim[i] ; ++ j) {
|
for ( int j = 0 ; j < m_nDim[i] ; ++ j) {
|
||||||
|
|
||||||
// Aggiungo il tratto al dexel vuoto
|
// Aggiungo il tratto al dexel vuoto
|
||||||
@@ -97,7 +110,7 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
switch ( i) {
|
switch ( i) {
|
||||||
case 0 :
|
case 0 :
|
||||||
m_Values[i][j][0].vtMinN = - Z_AX ;
|
m_Values[i][j][0].vtMinN = - Z_AX ;
|
||||||
m_Values[i][j][0].dMax = dDimZ ;
|
m_Values[i][j][0].dMax = dDimZ ;
|
||||||
m_Values[i][j][0].vtMaxN = Z_AX ;
|
m_Values[i][j][0].vtMaxN = Z_AX ;
|
||||||
m_Values[i][j][0].nToolMax = 0 ;
|
m_Values[i][j][0].nToolMax = 0 ;
|
||||||
break ;
|
break ;
|
||||||
@@ -112,9 +125,10 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
m_Values[i][j][0].dMax = dDimY ;
|
m_Values[i][j][0].dMax = dDimY ;
|
||||||
m_Values[i][j][0].vtMaxN = Y_AX ;
|
m_Values[i][j][0].vtMaxN = Y_AX ;
|
||||||
m_Values[i][j][0].nToolMax = 0 ;
|
m_Values[i][j][0].nToolMax = 0 ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Definizione delle limitazioni iniziali in Z per ogni mappa
|
// Definizione delle limitazioni iniziali in Z per ogni mappa
|
||||||
m_dMinZ[0] = 0 ;
|
m_dMinZ[0] = 0 ;
|
||||||
@@ -135,7 +149,7 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex)
|
VolZmap::CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, double dStep, bool bTriDex, int* nError)
|
||||||
{
|
{
|
||||||
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
|
// Controlli sull'ammissibilità delle dimensioni lineari del grezzo e del passo
|
||||||
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
|
if ( dStep < EPS_SMALL || dDimX < EPS_SMALL || dDimY < EPS_SMALL || dDimZ < EPS_SMALL)
|
||||||
@@ -186,6 +200,18 @@ VolZmap::CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDi
|
|||||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||||
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
m_nDim[i] = m_nNx[i] * m_nNy[i] ;
|
||||||
|
|
||||||
|
// Se versione 32-bit controllo di non superare il numero di Dexel massimo
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
for ( int i = 0 ; i < ssize( m_nDim) ; ++ i)
|
||||||
|
m_nDexelNbr += m_nDim[i] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Creazione delle celle per ogni mappa
|
// Creazione delle celle per ogni mappa
|
||||||
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
for ( int i = 0 ; i < m_nMapNum ; ++ i)
|
||||||
m_Values[i].resize( m_nDim[i]) ;
|
m_Values[i].resize( m_nDim[i]) ;
|
||||||
@@ -209,7 +235,7 @@ VolZmap::CreateEmpty( const Point3d& ptO, double dDimX, double dDimY, double dDi
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex)
|
VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double dStep, bool bTriDex, int* nError)
|
||||||
{
|
{
|
||||||
// Aggiorno la dimensione della mappa 1 o 3
|
// Aggiorno la dimensione della mappa 1 o 3
|
||||||
m_nMapNum = ( bTriDex ? 3 : 1) ;
|
m_nMapNum = ( bTriDex ? 3 : 1) ;
|
||||||
@@ -249,14 +275,35 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double
|
|||||||
m_nNx[1] = m_nNy[0] ;
|
m_nNx[1] = m_nNy[0] ;
|
||||||
m_nNy[1] = int( ( dDimZ + EPS_SMALL) / m_dStep + 0.5) ;
|
m_nNy[1] = int( ( dDimZ + EPS_SMALL) / m_dStep + 0.5) ;
|
||||||
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
||||||
m_Values[1].resize( m_nDim[1]) ;
|
|
||||||
m_nNx[2] = m_nNy[1] ;
|
m_nNx[2] = m_nNy[1] ;
|
||||||
m_nNy[2] = m_nNx[0] ;
|
m_nNy[2] = m_nNx[0] ;
|
||||||
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
||||||
|
// Se versione 32-bit controllo di non superare il numero di Dexel massimo
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
for ( int i = 0 ; i < ssize( m_nDim) ; ++ i)
|
||||||
|
m_nDexelNbr += m_nDim[i] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_Values[1].resize( m_nDim[1]) ;
|
||||||
m_Values[2].resize( m_nDim[2]) ;
|
m_Values[2].resize( m_nDim[2]) ;
|
||||||
}
|
}
|
||||||
|
// Se dimensione singola
|
||||||
else {
|
else {
|
||||||
|
// Se versione 32-bit controllo di non superare il numero di Dexel massimo
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
m_nDexelNbr += m_nDim[0] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_nNx[1] = 0 ;
|
m_nNx[1] = 0 ;
|
||||||
m_nNy[1] = 0 ;
|
m_nNy[1] = 0 ;
|
||||||
m_nDim[1] = 0 ;
|
m_nDim[1] = 0 ;
|
||||||
@@ -504,6 +551,8 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
nSupJ < 0 || nSupJ > m_nNy[nMap])
|
nSupJ < 0 || nSupJ > m_nNy[nMap])
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
|
double dCosSmall = sin( EPS_ANG_SMALL * DEGTORAD) ;
|
||||||
|
|
||||||
// Determinazione e ridimensionamento dei dexel interni alla trimesh
|
// Determinazione e ridimensionamento dei dexel interni alla trimesh
|
||||||
for ( int i = nInfI ; i < nSupI ; ++ i) {
|
for ( int i = nInfI ; i < nSupI ; ++ i) {
|
||||||
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
|
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
|
||||||
@@ -551,7 +600,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
double dCos = IntersectionResults[k].dCosDN ;
|
double dCos = IntersectionResults[k].dCosDN ;
|
||||||
|
|
||||||
// entro nella superficie trimesh
|
// entro nella superficie trimesh
|
||||||
if ( dCos < - EPS_SMALL) {
|
if ( dCos < - dCosSmall) {
|
||||||
|
|
||||||
ptIn = IntersectionResults[k].ptI ;
|
ptIn = IntersectionResults[k].ptI ;
|
||||||
|
|
||||||
@@ -564,7 +613,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// esco dalla superficie trimesh
|
// esco dalla superficie trimesh
|
||||||
else if ( dCos > EPS_SMALL && bInside) {
|
else if ( dCos > dCosSmall && bInside) {
|
||||||
|
|
||||||
Point3d ptOut = IntersectionResults[k].ptI ;
|
Point3d ptOut = IntersectionResults[k].ptI ;
|
||||||
|
|
||||||
@@ -597,6 +646,7 @@ VolZmap::CreateMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, co
|
|||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
VolZmap::AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
|
||||||
@@ -691,7 +741,100 @@ VolZmap::AddMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex)
|
VolZmap::SubtractMapPart( int nMap, int nInfI, int nSupI, int nInfJ, int nSupJ, const Vector3d& vtLen, const Point3d& ptMapOrig,
|
||||||
|
const ISurfTriMesh& Surf, IntersParLinesSurfTm& intPLSTM)
|
||||||
|
{
|
||||||
|
// controllo sui parametri
|
||||||
|
if ( nMap < 0 || nMap > 2 ||
|
||||||
|
nInfI < 0 || nInfI > m_nNx[nMap] ||
|
||||||
|
nSupI < 0 || nSupI > m_nNx[nMap] ||
|
||||||
|
nInfJ < 0 || nInfJ > m_nNy[nMap] ||
|
||||||
|
nSupJ < 0 || nSupJ > m_nNy[nMap])
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// determinazione e ridimensionamento dei dexel interni alla trimesh
|
||||||
|
for ( int i = nInfI ; i < nSupI ; ++ i) {
|
||||||
|
for ( int j = nInfJ ; j < nSupJ ; ++ j) {
|
||||||
|
|
||||||
|
// definisco la retta da intersecare con la trimesh
|
||||||
|
double dX = ( i + 0.5) * m_dStep ;
|
||||||
|
double dY = ( j + 0.5) * m_dStep ;
|
||||||
|
Point3d ptP0( dX, dY, 0) ;
|
||||||
|
|
||||||
|
// intersezioni della retta con la TriMesh
|
||||||
|
ILSIVECTOR IntersectionResults ;
|
||||||
|
intPLSTM.GetInters( ptP0, vtLen.v[(nMap+2)%3], IntersectionResults) ;
|
||||||
|
|
||||||
|
// rimuovo le intersezioni in eccesso
|
||||||
|
for ( int nI = 0 ; nI < int( IntersectionResults.size()) - 3 ; ++ nI) {
|
||||||
|
int nJ = nI + 1 ; // prima successiva
|
||||||
|
int nK = nJ + 1 ; // seconda successiva
|
||||||
|
int nT = nK + 1 ; // terza successiva
|
||||||
|
// determino i segni delle 4 intersezioni tra la linea e il trangolo della TriMesh
|
||||||
|
int nSgnI = IntersectionResults[nI].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nI].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||||
|
int nSgnJ = IntersectionResults[nJ].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nJ].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||||
|
int nSgnK = IntersectionResults[nK].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nK].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||||
|
int nSgnT = IntersectionResults[nT].dCosDN > EPS_SMALL ? 1 : IntersectionResults[nT].dCosDN > -EPS_SMALL ? 0 : - 1 ;
|
||||||
|
// parametri dell'intersezione sulla linea
|
||||||
|
double dUJ = IntersectionResults[nJ].dU ;
|
||||||
|
double dUK = IntersectionResults[nK].dU ;
|
||||||
|
// controllo coerenza con segni...
|
||||||
|
if ( nSgnI != 0 && nSgnI == nSgnJ &&
|
||||||
|
nSgnK != 0 && nSgnK == nSgnT &&
|
||||||
|
nSgnI == - nSgnT &&
|
||||||
|
abs( dUJ - dUK) < EPS_SMALL) {
|
||||||
|
// ... ed elimino le intersezioni in eccesso...
|
||||||
|
IntersectionResults.erase( IntersectionResults.begin() + nK) ;
|
||||||
|
IntersectionResults.erase( IntersectionResults.begin() + nJ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int nInt = int( IntersectionResults.size()) ; // numero di intersezioni valide
|
||||||
|
bool bInside = false ; // Flag entrata/uscita per tratto di retta
|
||||||
|
Point3d ptIn ; Vector3d vtInN ;
|
||||||
|
|
||||||
|
// per ogni intersezione valida trovata...
|
||||||
|
for ( int k = 0 ; k < nInt ; ++ k) {
|
||||||
|
// ricavo il tipo di intersezione
|
||||||
|
int nIntType = IntersectionResults[k].nILTT ;
|
||||||
|
// se c'è intersezione
|
||||||
|
if ( nIntType != ILTT_NO) {
|
||||||
|
// ricavo il cos tra i vettori ( normale del triangolo e tangente alla retta)
|
||||||
|
double dCos = IntersectionResults[k].dCosDN ;
|
||||||
|
|
||||||
|
// se entro nella superficie trimesh...
|
||||||
|
if ( dCos < - EPS_SMALL) {
|
||||||
|
ptIn = IntersectionResults[k].ptI ; // punto di intersezione
|
||||||
|
int nT = IntersectionResults[k].nT ; // triangolo di interesse
|
||||||
|
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
|
||||||
|
Surf.GetFacetNormal( nF, vtInN) ;
|
||||||
|
bInside = true ; // entrata
|
||||||
|
}
|
||||||
|
// ...se esco dalla superficie trimesh ( prima sono per forza entrato)
|
||||||
|
else if ( dCos > EPS_SMALL && bInside) {
|
||||||
|
Point3d ptOut = IntersectionResults[k].ptI ; // punto di intersezione
|
||||||
|
int nT = IntersectionResults[k].nT ; // triangolo di interesse
|
||||||
|
int nF = Surf.GetFacetFromTria( nT) ; // faccia di interesse
|
||||||
|
Vector3d vtOutN ; Surf.GetFacetNormal( nF, vtOutN) ; // vettore d'uscita
|
||||||
|
|
||||||
|
// Aggiungo un tratto al dexel
|
||||||
|
SubtractIntervals( nMap, i, j,
|
||||||
|
ptIn.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
|
||||||
|
ptOut.v[(nMap+2)%3] - ptMapOrig.v[(nMap+2)%3],
|
||||||
|
- vtInN, - vtOutN, 0, true) ;
|
||||||
|
bInside = false ; // uscita
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex, double dExtraBox, int* nError)
|
||||||
{
|
{
|
||||||
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
|
// Se la superficie non è chiusa oppure orientata al contrario non ha senso continuare
|
||||||
double dVol ;
|
double dVol ;
|
||||||
@@ -704,14 +847,17 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
// Determino il bounding box della TriMesh
|
// Determino il bounding box della TriMesh
|
||||||
BBox3d SurfBBox ;
|
BBox3d SurfBBox ;
|
||||||
Surf.GetLocalBBox( SurfBBox) ;
|
Surf.GetLocalBBox( SurfBBox) ;
|
||||||
|
|
||||||
// Determino i punti estremi del bounding box
|
|
||||||
Point3d ptMapOrig, ptMapEnd ;
|
|
||||||
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
|
|
||||||
|
|
||||||
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
|
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
|
||||||
// quindi espandiamo il bounding box per ovviare al problema.
|
// quindi espandiamo il bounding box per ovviare al problema.
|
||||||
SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ;
|
if ( dExtraBox > EPS_ZERO)
|
||||||
|
SurfBBox.Expand( dExtraBox) ;
|
||||||
|
else
|
||||||
|
dExtraBox = 0 ;
|
||||||
|
|
||||||
|
// Determino i punti estremi del bounding box
|
||||||
|
Point3d ptMapOrig, ptMapEnd ;
|
||||||
|
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
|
||||||
|
|
||||||
// Sistema di riferimento intrinseco dello Zmap
|
// Sistema di riferimento intrinseco dello Zmap
|
||||||
m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ;
|
m_MapFrame.Set( ptMapOrig, Frame3d::TOP) ;
|
||||||
@@ -738,14 +884,33 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
m_nNx[1] = m_nNy[0] ;
|
m_nNx[1] = m_nNy[0] ;
|
||||||
m_nNy[1] = int( ( vtLen.z + EPS_SMALL) / m_dStep + 0.5) ;
|
m_nNy[1] = int( ( vtLen.z + EPS_SMALL) / m_dStep + 0.5) ;
|
||||||
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
m_nDim[1] = m_nNx[1] * m_nNy[1] ;
|
||||||
m_Values[1].resize( m_nDim[1]) ;
|
|
||||||
m_nNx[2] = m_nNy[1] ;
|
m_nNx[2] = m_nNy[1] ;
|
||||||
m_nNy[2] = m_nNx[0] ;
|
m_nNy[2] = m_nNx[0] ;
|
||||||
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
m_nDim[2] = m_nNx[2] * m_nNy[2] ;
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
for ( int i = 0 ; i < ssize( m_nDim) ; ++ i)
|
||||||
|
m_nDexelNbr += m_nDim[i] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
m_Values[1].resize( m_nDim[1]) ;
|
||||||
m_Values[2].resize( m_nDim[2]) ;
|
m_Values[2].resize( m_nDim[2]) ;
|
||||||
}
|
}
|
||||||
|
// Se a dimensione singola
|
||||||
else {
|
else {
|
||||||
|
#if !defined(_WIN64)
|
||||||
|
m_nDexelNbr += m_nDim[0] ;
|
||||||
|
if ( m_nDexelNbr >= MAX_DEXEL_32_BIT) {
|
||||||
|
Clear() ;
|
||||||
|
if ( nError != nullptr)
|
||||||
|
*nError = 1 ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
m_nNx[1] = 0 ;
|
m_nNx[1] = 0 ;
|
||||||
m_nNy[1] = 0 ;
|
m_nNy[1] = 0 ;
|
||||||
m_nDim[1] = 0 ;
|
m_nDim[1] = 0 ;
|
||||||
@@ -760,72 +925,83 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
|
|
||||||
// ciclo sulle griglie
|
// ciclo sulle griglie
|
||||||
bool bCompleted = true ;
|
bool bCompleted = true ;
|
||||||
for ( int g = 0 ; g < m_nMapNum ; ++ g) {
|
for ( int nG = 0 ; nG < m_nMapNum ; ++ nG) {
|
||||||
|
|
||||||
// Definisco dei sistemi di riferimento ausiliari
|
// Definisco dei sistemi di riferimento ausiliari
|
||||||
Frame3d frMapFrame ;
|
Frame3d frMapFrame ;
|
||||||
if ( g == 0)
|
if ( nG == 0)
|
||||||
frMapFrame = m_MapFrame ;
|
frMapFrame = m_MapFrame ;
|
||||||
else if ( g == 1)
|
else if ( nG == 1)
|
||||||
frMapFrame.Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
|
frMapFrame.Set( ptMapOrig, Y_AX, Z_AX, X_AX) ;
|
||||||
else if ( g == 2)
|
else if ( nG == 2)
|
||||||
frMapFrame.Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
|
frMapFrame.Set( ptMapOrig, Z_AX, X_AX, Y_AX) ;
|
||||||
|
|
||||||
// Oggetto per calcolo massivo intersezioni
|
// Oggetto per calcolo massivo intersezioni
|
||||||
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
|
IntersParLinesSurfTm intPLSTM( frMapFrame, Surf) ;
|
||||||
|
|
||||||
// Numero massimo di thread
|
// Standarda è multithread
|
||||||
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
|
constexpr bool MULTITHREAD = true ;
|
||||||
vector< future<bool>> vRes ;
|
if ( MULTITHREAD) {
|
||||||
vRes.resize( nThreadMax) ;
|
|
||||||
if ( m_nNx[g] > m_nNy[g]) {
|
// Numero massimo di thread
|
||||||
int nDexNum = m_nNx[g] / nThreadMax ;
|
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
|
||||||
int nRemainder = m_nNx[g] % nThreadMax ;
|
vector< future<bool>> vRes ;
|
||||||
int nInfI = 0 ;
|
vRes.resize( nThreadMax) ;
|
||||||
int nSupI = 0 ;
|
if ( m_nNx[nG] > m_nNy[nG]) {
|
||||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
int nDexNum = m_nNx[nG] / nThreadMax ;
|
||||||
nInfI = nSupI ;
|
int nRemainder = m_nNx[nG] % nThreadMax ;
|
||||||
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
int nInfI = 0 ;
|
||||||
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, g,
|
int nSupI = 0 ;
|
||||||
nInfI, nSupI, 0, m_nNy[g], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
|
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||||
}
|
nInfI = nSupI ;
|
||||||
}
|
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||||
else {
|
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
|
||||||
int nDexNum = m_nNy[g] / nThreadMax ;
|
nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
|
||||||
int nRemainder = m_nNy[g] % nThreadMax ;
|
|
||||||
int nInfJ = 0 ;
|
|
||||||
int nSupJ = 0 ;
|
|
||||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
|
||||||
nInfJ = nSupJ ;
|
|
||||||
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
|
||||||
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, g,
|
|
||||||
0, m_nNx[g], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ciclo per attendere che tutti gli async abbiano terminato.
|
|
||||||
int nTerminated = 0 ;
|
|
||||||
while ( nTerminated < nThreadMax) {
|
|
||||||
for ( int nL = 0 ; nL < nThreadMax ; ++ nL) {
|
|
||||||
// Async terminato
|
|
||||||
if ( vRes[nL].valid() && vRes[nL].wait_for( chrono::microseconds{ 1}) == future_status::ready) {
|
|
||||||
++ nTerminated ;
|
|
||||||
bCompleted = bCompleted && vRes[nL].get() ;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
int nDexNum = m_nNy[nG] / nThreadMax ;
|
||||||
|
int nRemainder = m_nNy[nG] % nThreadMax ;
|
||||||
|
int nInfJ = 0 ;
|
||||||
|
int nSupJ = 0 ;
|
||||||
|
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||||
|
nInfJ = nSupJ ;
|
||||||
|
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||||
|
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
|
||||||
|
0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ciclo per attendere che tutti gli async abbiano terminato.
|
||||||
|
int nTerminated = 0 ;
|
||||||
|
while ( nTerminated < nThreadMax) {
|
||||||
|
for ( int nL = 0 ; nL < nThreadMax ; ++ nL) {
|
||||||
|
// Async terminato
|
||||||
|
if ( vRes[nL].valid() && vRes[nL].wait_for( chrono::microseconds{ 1}) == future_status::ready) {
|
||||||
|
++ nTerminated ;
|
||||||
|
bCompleted = bCompleted && vRes[nL].get() ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// !!!! NON MULTITHREAD : SOLO PER DEBUG !!!!
|
||||||
|
else {
|
||||||
|
CreateMapPart( nG, 0, m_nNx[nG], 0, m_nNy[nG], vtLen, ptMapOrig, Surf, intPLSTM) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assegno il minimo e massimo valore di Z della mappa
|
// Assegno il minimo e massimo valore di Z della mappa
|
||||||
m_dMinZ[0] = 0 ;
|
m_dMinZ[0] = dExtraBox ;
|
||||||
m_dMaxZ[0] = vtLen.z ;
|
m_dMaxZ[0] = vtLen.z - dExtraBox ;
|
||||||
m_dMinZ[1] = 0 ;
|
m_dMinZ[1] = ( bTriDex ? dExtraBox : 0) ;
|
||||||
m_dMaxZ[1] = ( bTriDex ? vtLen.x : 0) ;
|
m_dMaxZ[1] = ( bTriDex ? vtLen.x - dExtraBox : 0) ;
|
||||||
m_dMinZ[2] = 0 ;
|
m_dMinZ[2] = ( bTriDex ? dExtraBox : 0) ;
|
||||||
m_dMaxZ[2] = ( bTriDex ? vtLen.y : 0) ;
|
m_dMaxZ[2] = ( bTriDex ? vtLen.y - dExtraBox : 0) ;
|
||||||
|
|
||||||
// Tipologia
|
// Tipologia
|
||||||
m_nShape = ( IsBox() ? BOX : GENERIC) ;
|
// Con espansione non va considerato box (calcolo trimesh va in crash)
|
||||||
|
m_nShape = ( dExtraBox <= EPS_ZERO && IsBox() ? BOX : GENERIC) ;
|
||||||
|
|
||||||
// Aggiornamento dello stato
|
// Aggiornamento dello stato
|
||||||
m_nStatus = OK ;
|
m_nStatus = OK ;
|
||||||
|
|||||||
+88
-29
@@ -19,10 +19,12 @@
|
|||||||
#include "MC_Tables.h"
|
#include "MC_Tables.h"
|
||||||
#include "PolygonPlane.h"
|
#include "PolygonPlane.h"
|
||||||
#include "IntersLineBox.h"
|
#include "IntersLineBox.h"
|
||||||
|
#include "SurfTriMesh.h"
|
||||||
#include "/EgtDev/Include/EGkIntervals.h"
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
||||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||||
|
#define EIGEN_NO_IO
|
||||||
#include "/EgtDev/Extern/Eigen/Core"
|
#include "/EgtDev/Extern/Eigen/Core"
|
||||||
#include "/EgtDev/Extern/Eigen/SVD"
|
#include "/EgtDev/Extern/Eigen/SVD"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
@@ -571,6 +573,35 @@ VolZmap::GetBlockTriangles( int nBlock, TRIA3DEXVECTOR& vTria) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
ISurfTriMesh*
|
||||||
|
VolZmap::GetSurfTriMesh( void) const
|
||||||
|
{
|
||||||
|
// controllo che lo Zmap sia valido
|
||||||
|
if ( ! IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// inizializzo la superficie
|
||||||
|
PtrOwner<SurfTriMesh> pStm( CreateBasicSurfTriMesh()) ;
|
||||||
|
if ( IsNull( pStm) || ! pStm->Init( 3, 1))
|
||||||
|
return nullptr ;
|
||||||
|
PointGrid3d VertGrid ; VertGrid.Init( 50000) ;
|
||||||
|
|
||||||
|
// ciclo lungo i blocchi dello Zmap
|
||||||
|
for ( int nB = 0 ; nB < GetBlockCount() ; ++ nB) {
|
||||||
|
TRIA3DEXVECTOR vTria ;
|
||||||
|
GetBlockTriangles( nB, vTria) ;
|
||||||
|
if ( ! pStm->AddTriaFromZMap( vTria, VertGrid))
|
||||||
|
return nullptr ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sistemo la topologia
|
||||||
|
if ( ! pStm->AdjustTopologyFromZMap())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
return ( Release( pStm)) ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
int
|
int
|
||||||
VolZmap::GetBlockCount( void) const
|
VolZmap::GetBlockCount( void) const
|
||||||
@@ -920,25 +951,41 @@ VolZmap::UpdateTripleMapGraphics( void) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calcolo i triangoli sui blocchi
|
// Standard è multithread
|
||||||
int nBlockUpdated = 0 ;
|
constexpr bool MULTITHREAD = true ;
|
||||||
vector< future<bool>> vRes ;
|
if ( MULTITHREAD) {
|
||||||
vRes.resize( m_nNumBlock) ;
|
|
||||||
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
// Calcolo i triangoli sui blocchi
|
||||||
// Se il blocco deve essere processato
|
int nBlockUpdated = 0 ;
|
||||||
if ( m_BlockToUpdate[i]) {
|
vector< future<bool>> vRes ;
|
||||||
// processo ...
|
vRes.resize( m_nNumBlock) ;
|
||||||
++ nBlockUpdated ;
|
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
||||||
vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ;
|
// Se il blocco deve essere processato
|
||||||
|
if ( m_BlockToUpdate[i]) {
|
||||||
|
// processo ...
|
||||||
|
++ nBlockUpdated ;
|
||||||
|
vRes[i] = async( launch::async, &VolZmap::ExtMarchingCubes, this, i, ref( vVoxContainerVec[i])) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool bOk = true ;
|
||||||
|
int nTerminated = 0 ;
|
||||||
|
while ( nTerminated < nBlockUpdated) {
|
||||||
|
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
||||||
|
if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
||||||
|
bOk = vRes[i].get() && bOk ;
|
||||||
|
++ nTerminated ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool bOk = true ;
|
else {
|
||||||
int nTerminated = 0 ;
|
// Calcolo i triangoli sui blocchi
|
||||||
while ( nTerminated < nBlockUpdated) {
|
bool bOk = true ;
|
||||||
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
||||||
if ( m_BlockToUpdate[i] && vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
// Se il blocco deve essere processato
|
||||||
bOk = vRes[i].get() && bOk ;
|
if ( m_BlockToUpdate[i]) {
|
||||||
++ nTerminated ;
|
// processo ...
|
||||||
|
bOk = ExtMarchingCubes( i, vVoxContainerVec[i]) && bOk ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1142,7 +1189,7 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Controllo se il voxel ha una sola faccia che giace in un piano canonico e quindi ha gestione speciale
|
// Controllo se il voxel ha una sola faccia che giace in un piano canonico e quindi ha gestione speciale
|
||||||
if ( m_nShape != BOX) {
|
if ( m_nShape != BOX && m_nShape != OFFSET) {
|
||||||
// Faccia XY normale Z+
|
// Faccia XY normale Z+
|
||||||
if ( nIndex == 15) {
|
if ( nIndex == 15) {
|
||||||
int nTool ; double dPos ;
|
int nTool ; double dPos ;
|
||||||
@@ -1224,13 +1271,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
auto it = m_SliceYZ[nSlBlockN].find( nSliceN) ;
|
auto it = m_SliceYZ[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceYZ[nSlBlockN].end()) {
|
if ( it != m_SliceYZ[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs( nAdjVox3[nCount]) == 2) {
|
else if ( abs( nAdjVox3[nCount]) == 2) {
|
||||||
@@ -1240,13 +1289,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
auto it = m_SliceXZ[nSlBlockN].find( nSliceN) ;
|
auto it = m_SliceXZ[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceXZ[nSlBlockN].end()) {
|
if ( it != m_SliceXZ[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs( nAdjVox3[nCount]) == 3) {
|
else if ( abs( nAdjVox3[nCount]) == 3) {
|
||||||
@@ -1256,13 +1307,15 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
if ( GetBlockNFromIJK( nSlBlockIJK, nSlBlockN)) {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
auto it = m_SliceXY[nSlBlockN].find( nSliceN) ;
|
auto it = m_SliceXY[nSlBlockN].find( nSliceN) ;
|
||||||
if ( it != m_SliceXY[nSlBlockN].end()) {
|
if ( it != m_SliceXY[nSlBlockN].end()) {
|
||||||
bMatOnSlice = it->second ;
|
bMatOnSlice = it->second ;
|
||||||
bDefTopology = true ;
|
bDefTopology = true ;
|
||||||
}
|
}
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1327,27 +1380,33 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
|
|||||||
if ( nSlBlockN == nBlock)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceYZ.emplace( nSliceN, bMatOnSlice) ;
|
SliceYZ.emplace( nSliceN, bMatOnSlice) ;
|
||||||
else {
|
else {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
m_SliceYZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
m_SliceYZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs(nAdjVox3[nCount]) == 2) {
|
else if ( abs(nAdjVox3[nCount]) == 2) {
|
||||||
if ( nSlBlockN == nBlock)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceXZ.emplace( nSliceN, bMatOnSlice) ;
|
SliceXZ.emplace( nSliceN, bMatOnSlice) ;
|
||||||
else {
|
else {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
m_SliceXZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
m_SliceXZ[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( abs(nAdjVox3[nCount]) == 3) {
|
else if ( abs(nAdjVox3[nCount]) == 3) {
|
||||||
if ( nSlBlockN == nBlock)
|
if ( nSlBlockN == nBlock)
|
||||||
SliceXY.emplace(nSliceN, bMatOnSlice) ;
|
SliceXY.emplace(nSliceN, bMatOnSlice) ;
|
||||||
else {
|
else {
|
||||||
m_SliceMutex.lock() ;
|
while ( m_SliceFlag.test_and_set( memory_order_acquire))
|
||||||
|
m_SliceFlag.wait( true, memory_order_relaxed) ;
|
||||||
m_SliceXY[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
m_SliceXY[nSlBlockN].emplace( nSliceN, bMatOnSlice) ;
|
||||||
m_SliceMutex.unlock() ;
|
m_SliceFlag.clear( memory_order_release) ;
|
||||||
|
m_SliceFlag.notify_one() ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2808
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