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 |
+1
-1
@@ -151,7 +151,7 @@ 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)) ;
|
||||||
|
|||||||
+135
-92
@@ -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()) ;
|
||||||
@@ -420,19 +427,19 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
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,14 +470,13 @@ 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) ;
|
||||||
@@ -481,32 +487,11 @@ TestEdgesClosedPolyLines( POLYLINEVECTOR& vPL, const CAvToolSurfTm& cavTstm, int
|
|||||||
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
|
||||||
@@ -515,10 +500,52 @@ 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()) ;
|
||||||
|
pCrvCompoPoly->FromPolyLine( PL) ;
|
||||||
|
vpOwCrv.emplace_back( Release( pCrvCompoPoly)) ;
|
||||||
|
vpCrv.emplace_back( vpOwCrv.back()) ;
|
||||||
|
}
|
||||||
|
// calcolo l'Offset
|
||||||
|
ICURVEPOVECTOR vpCrvOffs ;
|
||||||
|
if ( ! CalcOffsetCurves( vpCrv, vpCrvOffs, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND))
|
||||||
return false ;
|
return false ;
|
||||||
OffsetCurve offsCompo ;
|
// resituisco le PolyLine
|
||||||
offsCompo.Make( &crvCompo, - ( dRad - 2 * EPS_SMALL), ICurve::OFF_EXTEND) ;
|
POLYLINEVECTOR vPL_Offs ; vPL_Offs.reserve( vpCrvOffs.size()) ;
|
||||||
PtrOwner<ICurve> pCrvOffset( offsCompo.GetLongerCurve()) ;
|
for ( auto& pCrv : vpCrvOffs) {
|
||||||
while ( ! IsNull( pCrvOffset)) {
|
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) ;
|
||||||
+2696
-1393
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]) ) ;
|
||||||
|
|
||||||
|
|||||||
+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 ;
|
||||||
|
|||||||
+879
-131
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) ;
|
||||||
+107
-18
@@ -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 ;
|
||||||
@@ -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)
|
||||||
@@ -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.) ;
|
||||||
|
|
||||||
@@ -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.) ;
|
||||||
|
|
||||||
@@ -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,9 +2308,13 @@ 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 ;
|
||||||
@@ -2284,7 +2324,7 @@ CurveBezier::MakeRationalStandardForm( void)
|
|||||||
// 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,6 +2333,10 @@ CurveBezier::MakeRationalStandardForm( void)
|
|||||||
bool
|
bool
|
||||||
CurveBezier::MakeNonRational( double dTol)
|
CurveBezier::MakeNonRational( double dTol)
|
||||||
{
|
{
|
||||||
|
// la curva deve essere valida
|
||||||
|
if ( m_nStatus != OK)
|
||||||
|
return false ;
|
||||||
|
|
||||||
if ( ! m_bRat)
|
if ( ! m_bRat)
|
||||||
return true ;
|
return true ;
|
||||||
|
|
||||||
@@ -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 ;
|
||||||
@@ -2351,7 +2424,7 @@ 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
|
||||||
@@ -2372,6 +2445,10 @@ 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) {
|
||||||
@@ -2383,3 +2460,15 @@ CurveBezier::IsALine( void) const
|
|||||||
}
|
}
|
||||||
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 ;
|
||||||
|
|||||||
+32
-223
@@ -50,6 +50,36 @@ CurveByInterp::AddPoint( const Point3d& ptP)
|
|||||||
ICurve*
|
ICurve*
|
||||||
CurveByInterp::GetCurve( int nMethod, int nType)
|
CurveByInterp::GetCurve( int nMethod, int nType)
|
||||||
{
|
{
|
||||||
|
// 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
|
// calcolo le tangenti
|
||||||
if ( nMethod == BESSEL) {
|
if ( nMethod == BESSEL) {
|
||||||
if ( ! CalcBesselTangents())
|
if ( ! CalcBesselTangents())
|
||||||
@@ -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 ;
|
|
||||||
}
|
}
|
||||||
+236
-31
@@ -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)) {
|
||||||
|
CurveLine crvLine ;
|
||||||
|
if ( ! crvLine.Set( ptEnd, ptCrvEnd) || ! pCrv.Set( crvLine.Clone()))
|
||||||
return false ;
|
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)) {
|
||||||
|
CurveLine crvLine ;
|
||||||
|
if ( ! crvLine.Set( ptCrvStart, ptStart) || ! pCrv.Set( crvLine.Clone()))
|
||||||
return false ;
|
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
|
||||||
@@ -3171,20 +3309,49 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
// 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) {
|
||||||
|
bool bModifStart = ( pCrvC->GetType() != CRV_ARC) ;
|
||||||
|
if ( ! bModifStart) {
|
||||||
|
/* nel caso in cui la curva corrente sia un arco, bisogna controllare che la somma tra
|
||||||
|
l'angolo al centro e l'angolo sotteso dalla curva precedente non superi l'angolo giro; in
|
||||||
|
caso positivo, la modifica del punto inziale dell'arco ( curva corrente) rimoverebbe
|
||||||
|
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
||||||
|
Point3d ptS ; pCrvP->GetStartPoint( ptS) ;
|
||||||
|
Point3d ptE ; pCrvC->GetStartPoint( ptE) ;
|
||||||
|
const ICurveArc* pArcC = GetBasicCurveArc( pCrvC) ;
|
||||||
|
double dAngRef = ( Dist( ptS, ptE) / pArcC->GetRadius()) * RADTODEG ;
|
||||||
|
bModifStart = ( abs( pArcC->GetAngCenter()) + dAngRef < ANG_FULL - 10 * EPS_ANG_SMALL) ;
|
||||||
|
|
||||||
|
}
|
||||||
|
if ( bModifStart) {
|
||||||
Point3d ptStart ;
|
Point3d ptStart ;
|
||||||
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// se corrente molto corta
|
// se corrente molto corta
|
||||||
double dLenC ;
|
double dLenC ;
|
||||||
if ( pCrvC->GetLength( dLenC) && dLenC < dCurrLinTol) {
|
if ( pCrvC->GetLength( dLenC) && dLenC < dCurrLinTol) {
|
||||||
// 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) {
|
||||||
|
bool bModifEnd = ( pCrvP->GetType() != CRV_ARC) ;
|
||||||
|
if ( ! bModifEnd) {
|
||||||
|
/* nel caso in cui la curva predecente sia un arco, bisogna controllare che la somma tra
|
||||||
|
l'angolo al centro e l'angolo sotteso dalla curva corrente non superi l'angolo giro; in
|
||||||
|
caso positivo, la modifica del punto finale dell'arco ( curva precedente) rimoverebbe
|
||||||
|
tutti gli angoli superiori a 360deg [curve a ricciolo per regioni non svuotate in Pocketing] */
|
||||||
|
Point3d ptS ; pCrvP->GetEndPoint( ptS) ;
|
||||||
|
Point3d ptE ; pCrvC->GetEndPoint( ptE) ;
|
||||||
|
const CurveArc* pArcP = GetBasicCurveArc( pCrvP) ;
|
||||||
|
double dAngRef = ( Dist( ptS, ptE) / pArcP->GetRadius()) * RADTODEG ;
|
||||||
|
bModifEnd = ( abs( pArcP->GetAngCenter()) + dAngRef < ANG_FULL - 10. * EPS_ANG_SMALL) ;
|
||||||
|
}
|
||||||
|
if ( bModifEnd) {
|
||||||
Point3d ptEnd ;
|
Point3d ptEnd ;
|
||||||
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
|
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
|
||||||
@@ -3265,10 +3432,11 @@ MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAn
|
|||||||
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))
|
||||||
|
|||||||
+21
-10
@@ -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 ;
|
||||||
}
|
}
|
||||||
@@ -233,8 +233,19 @@ DistPointCurve::GetSideAtMinDistPoint( int nInd, const Vector3d& vtN, int& nSide
|
|||||||
// 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 ; }
|
||||||
|
} ;
|
||||||
|
|||||||
+12
-10
@@ -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) ;
|
||||||
}
|
}
|
||||||
@@ -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 ;
|
||||||
|
|||||||
+496
-123
@@ -19,14 +19,15 @@
|
|||||||
#include "/EgtDev/Include/EGkAngle.h"
|
#include "/EgtDev/Include/EGkAngle.h"
|
||||||
#include "/EgtDev/Include/EGkHashGrids2d.h"
|
#include "/EgtDev/Include/EGkHashGrids2d.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
//--------------------------- Local functions --------------------------------
|
//--------------------------- Local functions --------------------------------
|
||||||
static bool CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
static bool CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||||
bool bCrvAClosed, double dCrvASpan) ;
|
bool bCrvAClosed, double dCrvASpan, bool bOrderedOnB = false) ;
|
||||||
static bool CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
static bool CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||||
bool bCrvBClosed, double dCrvBSpan) ;
|
bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB = false) ;
|
||||||
static void MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crvCompo) ;
|
static void MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crvCompo) ;
|
||||||
static int GetCrvBDirAPrev( IntCrvCrvInfo& Icci) ;
|
static int GetCrvBDirAPrev( IntCrvCrvInfo& Icci) ;
|
||||||
static int GetCrvBDirANext( IntCrvCrvInfo& Icci) ;
|
static int GetCrvBDirANext( IntCrvCrvInfo& Icci) ;
|
||||||
@@ -197,13 +198,16 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// se coincidono U e ptInt tra A e B
|
// se coincidono U e ptInt tra A e B
|
||||||
if ( abs( m_Info[i].IciA[0].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
|
if ( abs( m_Info[i].IciA[0].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
|
||||||
AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL)) {
|
AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL)) {
|
||||||
// se non è alla fine di curva chiusa
|
// se j è alla fine di curva chiusa
|
||||||
if ( ! bCrvAClosed || abs( m_Info[j].IciA[0].dU - dCrvBSpan) > EPS_SMALL)
|
// se j è alla fine di curva chiusa e la prima intersezione è di overlap con partenza dall'inizio ( compreso nel caso precedente)
|
||||||
// elimino la seconda
|
// oppure se i è all'inizio di curva chiusa e l'intersezione successiva a j è di overlap con lo stesso parametro
|
||||||
EraseOtherInfo( i, j) ;
|
if ( bCrvAClosed && (( abs( m_Info[j].IciA[0].dU - dCrvBSpan) < EPS_SMALL) ||
|
||||||
else
|
( i == 0 && ssize(m_Info) > 2 && m_Info[i].IciA[0].dU < EPS_SMALL && m_Info[j+1].bOverlap && abs( m_Info[j].IciA[0].dU - m_Info[j+1].IciA[0].dU) < EPS_SMALL)))
|
||||||
// elimino la prima
|
// elimino la prima
|
||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
|
else
|
||||||
|
// elimino la seconda
|
||||||
|
EraseOtherInfo( i, j) ;
|
||||||
break ;
|
break ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,10 +265,9 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM &&
|
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM &&
|
||||||
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM) {
|
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso DET-NULL -> NULL-DET per prima curva
|
// caso DET-(NULL) -> (NULL)-DET per prima curva
|
||||||
else if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
else if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) {
|
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) {
|
||||||
// per la prima curva tengo i determinati
|
// per la prima curva tengo i determinati
|
||||||
@@ -272,16 +275,22 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||||
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||||
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
|
||||||
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||||
|
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||||
|
}
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||||
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||||
@@ -292,6 +301,13 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
|
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
|
}
|
||||||
|
|
||||||
// medio parametri e punti separatamente per le due curve
|
// medio parametri e punti separatamente per le due curve
|
||||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||||
@@ -306,7 +322,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa)
|
// caso (NULL)-DET -> DET-(NULL) per prima curva (possibile su inizio/fine di curva chiusa)
|
||||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
||||||
m_Info[i].IciA[ki].nPrevTy != ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciA[ki].nPrevTy != ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||||
// per la prima curva tengo i determinati
|
// per la prima curva tengo i determinati
|
||||||
@@ -314,28 +330,41 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||||
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||||
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||||
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||||
|
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||||
|
}
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
// per la seconda curva ogni sottotipo è il duale di quello della prima
|
||||||
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
|
||||||
m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
// per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
|
||||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
|
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
|
}
|
||||||
|
|
||||||
// medio parametri e punti separatamente per le due curve
|
// medio parametri e punti separatamente per le due curve
|
||||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||||
@@ -356,8 +385,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso NULL-DET -> NULL-DET per prima curva con NULL-NULL -> NULL-NULL su seconda curva
|
// caso NULL-DET -> NULL-DET per prima curva con NULL-NULL -> NULL-NULL su seconda curva
|
||||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy != ICCT_NULL &&
|
||||||
@@ -365,18 +393,23 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso NULL-NULL per corrente di prima curva
|
// caso NULL-NULL per corrente di prima curva
|
||||||
else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
if ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
|
if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
}
|
}
|
||||||
// caso NULL-NULL per precedente di prima curva
|
// caso NULL-NULL per precedente di prima curva
|
||||||
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
|
else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
|
||||||
m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
|
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
|
||||||
|
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
|
||||||
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
||||||
EraseOtherInfo( i, j) ;
|
EraseOtherInfo( i, j) ;
|
||||||
}
|
}
|
||||||
@@ -395,22 +428,21 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
continue ;
|
continue ;
|
||||||
}
|
}
|
||||||
// calcolo sottoindici
|
// calcolo sottoindici
|
||||||
int ki = 0 ; // del successivo si prende sempre il primo
|
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
|
||||||
// verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL)
|
// verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL)
|
||||||
if ( AreSamePointXYEpsilon( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI, 10 * EPS_SMALL) &&
|
if ( AreSamePointXYEpsilon( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI, 10 * EPS_SMALL) &&
|
||||||
AreSamePointXYEpsilon( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI, 10 * EPS_SMALL) &&
|
AreSamePointXYEpsilon( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI, 10 * EPS_SMALL) &&
|
||||||
CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan) &&
|
CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan, true) &&
|
||||||
CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan)) {
|
CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan, true)) {
|
||||||
// caso entrambi Overlap ma di tipo opposto e sullo stesso tratto
|
// caso entrambi Overlap ma di tipo opposto e sullo stesso tratto
|
||||||
if ( m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq &&
|
if ( m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq &&
|
||||||
abs( m_Info[i].IciB[0].dU - m_Info[j].IciB[0].dU) < EPS_PARAM &&
|
abs( m_Info[i].IciB[0].dU - m_Info[j].IciB[0].dU) < EPS_PARAM &&
|
||||||
abs( m_Info[i].IciB[1].dU - m_Info[j].IciB[1].dU) < EPS_PARAM) {
|
abs( m_Info[i].IciB[1].dU - m_Info[j].IciB[1].dU) < EPS_PARAM) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso DET-NULL -> NULL-DET per seconda curva
|
// caso DET-(NULL) -> (NULL)-DET per seconda curva
|
||||||
else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
|
m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
|
||||||
// per la seconda curva tengo i determinati
|
// per la seconda curva tengo i determinati
|
||||||
@@ -418,28 +450,40 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||||
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||||
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||||
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||||
|
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||||
|
}
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||||
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||||
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
|
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
|
}
|
||||||
// medio parametri e punti separatamente per le due curve
|
// medio parametri e punti separatamente per le due curve
|
||||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||||
@@ -454,7 +498,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa)
|
// caso (NULL)-DET -> DET-(NULL) per seconda curva (possibile su inizio/fine di curva chiusa)
|
||||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
||||||
m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||||
// per la seconda curva tengo i determinati
|
// per la seconda curva tengo i determinati
|
||||||
@@ -462,28 +506,40 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||||
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||||
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||||
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||||
|
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||||
|
}
|
||||||
// se overlap equiverso
|
// se overlap equiverso
|
||||||
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
// per la prima curva ogni sottotipo è il duale di quello della seconda
|
||||||
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
|
||||||
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
|
||||||
}
|
}
|
||||||
// se altrimenti overlap controverso
|
// se altrimenti overlap controverso
|
||||||
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
|
||||||
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
// per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
|
||||||
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
|
||||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
|
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
|
}
|
||||||
// medio parametri e punti separatamente per le due curve
|
// medio parametri e punti separatamente per le due curve
|
||||||
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj], CCompoA) ;
|
||||||
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj], CCompoB) ;
|
||||||
@@ -504,8 +560,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso NULL-DET -> NULL-DET per seconda curva con NULL-NULL -> NULL-NULL su prima curva
|
// caso NULL-DET -> NULL-DET per seconda curva con NULL-NULL -> NULL-NULL su prima curva
|
||||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
|
||||||
@@ -513,22 +568,23 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
|
||||||
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||||
// cancello entrambe
|
// cancello entrambe
|
||||||
EraseOtherInfo( i, j) ;
|
EraseBothInfo( i, j) ;
|
||||||
EraseCurrentInfo( i, j) ;
|
|
||||||
}
|
}
|
||||||
// caso NULL-NULL per corrente di seconda curva
|
// caso NULL-NULL per corrente di seconda curva
|
||||||
else if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
else if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||||
m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
|
if ( m_Info[j].IciA[kj].nNextTy == ICCT_NULL)
|
||||||
if ( m_Info[i].IciA[ki].dU > m_Info[j].IciA[kj].dU + EPS_PARAM)
|
|
||||||
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
|
||||||
|
if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL)
|
||||||
|
m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
|
||||||
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
// cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
|
||||||
EraseCurrentInfo( i, j) ;
|
EraseCurrentInfo( i, j) ;
|
||||||
}
|
}
|
||||||
// caso NULL-NULL per precedente di seconda curva
|
// caso NULL-NULL per precedente di seconda curva
|
||||||
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL) {
|
else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL) {
|
||||||
m_Info[i].IciB[0].nPrevTy = m_Info[j].IciB[0].nPrevTy ;
|
if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL)
|
||||||
if ( m_Info[j].IciA[0].dU < m_Info[i].IciA[0].dU - EPS_PARAM)
|
m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
|
||||||
m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
|
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL)
|
||||||
|
m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
|
||||||
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
// cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
|
||||||
EraseOtherInfo( i, j) ;
|
EraseOtherInfo( i, j) ;
|
||||||
}
|
}
|
||||||
@@ -537,16 +593,16 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// ripristino ordinamento su prima curva
|
// ripristino ordinamento su prima curva
|
||||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
|
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
|
||||||
|
|
||||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità
|
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità
|
||||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||||
// se il tipo di accostamento per la curva A non è definito
|
// se il tipo di accostamento per la curva A non è definito
|
||||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||||
if ( i > 0 || ( bCrvAClosed && ! bAutoInters)) {
|
if ( i > 0 || ( bCrvAClosed && ! bAutoInters)) {
|
||||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||||
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
m_Info[i].IciA[0].nPrevTy = ( m_Info[j].bOverlap ? m_Info[j].IciA[1].nNextTy : m_Info[j].IciA[0].nNextTy) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// se il tipo di allontanamento per la curva A non è definito
|
// se il tipo di allontanamento per la curva A non è definito
|
||||||
int ki = ( m_Info[i].bOverlap ? 1 : 0) ;
|
int ki = ( m_Info[i].bOverlap ? 1 : 0) ;
|
||||||
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
|
||||||
if ( i < m_nNumInters - 1 || ( bCrvAClosed && ! bAutoInters)) {
|
if ( i < m_nNumInters - 1 || ( bCrvAClosed && ! bAutoInters)) {
|
||||||
@@ -556,21 +612,23 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva B e cerco di risolverle per continuità
|
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva B e cerco di risolverle per continuità
|
||||||
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
|
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
|
||||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||||
// se il tipo di accostamento per la curva B non è definito
|
// se il tipo di accostamento per la curva B non è definito
|
||||||
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
|
if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL) {
|
||||||
if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) {
|
if ( i > 0 || ( bCrvBClosed && ! bAutoInters)) {
|
||||||
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
int j = ( i > 0 ? i - 1 : m_nNumInters - 1) ;
|
||||||
m_Info[i].IciB[0].nPrevTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
m_Info[i].IciB[ki].nPrevTy = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nNextTy : m_Info[j].IciB[0].nNextTy) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// se il tipo di allontanamento per la curva B non è definito
|
// se il tipo di allontanamento per la curva B non è definito
|
||||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
ki = ( m_Info[i].bOverlap && m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
|
if ( m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
|
||||||
if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) {
|
if ( i < m_nNumInters - 1 || ( bCrvBClosed && ! bAutoInters)) {
|
||||||
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
int j = ( i < m_nNumInters - 1 ? i + 1 : 0) ;
|
||||||
m_Info[i].IciB[0].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
m_Info[i].IciB[ki].nNextTy = ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq ? m_Info[j].IciB[1].nPrevTy : m_Info[j].IciB[0].nPrevTy) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -581,7 +639,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||||
// in assenza di overlap
|
// in assenza di overlap
|
||||||
if ( ! m_Info[i].bOverlap) {
|
if ( ! m_Info[i].bOverlap) {
|
||||||
// se il tipo di accostamento per la curva A non è definito
|
// se il tipo di accostamento per la curva A non è definito
|
||||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
@@ -590,7 +648,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// aggiorno il tipo di accostamento della curva A alla curva B
|
// aggiorno il tipo di accostamento della curva A alla curva B
|
||||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||||
}
|
}
|
||||||
// se il tipo di accostamento per la curva B non è definito
|
// se il tipo di accostamento per la curva B non è definito
|
||||||
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
if ( m_Info[i].IciB[0].nPrevTy == ICCT_NULL) {
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
@@ -599,7 +657,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// aggiorno il tipo di accostamento della curva B alla curva A
|
// aggiorno il tipo di accostamento della curva B alla curva A
|
||||||
m_Info[i].IciB[0].nPrevTy = nType ;
|
m_Info[i].IciB[0].nPrevTy = nType ;
|
||||||
}
|
}
|
||||||
// se il tipo di allontanamento per la curva A non è definito
|
// se il tipo di allontanamento per la curva A non è definito
|
||||||
if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[0].nNextTy == ICCT_NULL) {
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
@@ -608,7 +666,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||||
m_Info[i].IciA[0].nNextTy = nType ;
|
m_Info[i].IciA[0].nNextTy = nType ;
|
||||||
}
|
}
|
||||||
// se il tipo di allontanamento per la curva B non è definito
|
// se il tipo di allontanamento per la curva B non è definito
|
||||||
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
if ( m_Info[i].IciB[0].nNextTy == ICCT_NULL) {
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
@@ -620,23 +678,8 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
}
|
}
|
||||||
// in presenza di overlap
|
// in presenza di overlap
|
||||||
else {
|
else {
|
||||||
// se il tipo di accostamento è non definito per la curva A
|
// se il tipo di accostamento è non definito per la curva A
|
||||||
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[0].nPrevTy == ICCT_NULL) {
|
||||||
// se autointersezione con spike
|
|
||||||
double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ;
|
|
||||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
|
||||||
// è punta di spike
|
|
||||||
int nType = ICCT_SPK ;
|
|
||||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
|
||||||
m_Info[i].IciA[0].nPrevTy = nType ;
|
|
||||||
// aggiorno anche il corrispondente tipo sulla curva B
|
|
||||||
if ( m_Info[i].bCBOverEq)
|
|
||||||
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
|
||||||
else
|
|
||||||
m_Info[i].IciB[0].nNextTy = nType ;
|
|
||||||
}
|
|
||||||
// caso standard
|
|
||||||
else {
|
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[0].dU, ICurve::FROM_MINUS,
|
||||||
@@ -650,24 +693,8 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[i].IciB[0].nNextTy = nType ;
|
m_Info[i].IciB[0].nNextTy = nType ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// se il tipo di allontanamento è non definito per la curva A
|
||||||
// se il tipo di allontanamento è non definito per la curva A
|
|
||||||
if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) {
|
if ( m_Info[i].IciA[1].nNextTy == ICCT_NULL) {
|
||||||
// se autointersezione con spike
|
|
||||||
double dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ;
|
|
||||||
if ( bAutoInters && ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM))) {
|
|
||||||
// è punta di spike
|
|
||||||
int nType = ICCT_SPK ;
|
|
||||||
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
|
||||||
m_Info[i].IciA[1].nNextTy = nType ;
|
|
||||||
// aggiorno anche il corrispondente tipo sulla curva B
|
|
||||||
if ( m_Info[i].bCBOverEq)
|
|
||||||
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
|
||||||
else
|
|
||||||
m_Info[i].IciB[1].nPrevTy = nType ;
|
|
||||||
}
|
|
||||||
// caso standard
|
|
||||||
else {
|
|
||||||
// devo studiare un intorno dell'intersezione
|
// devo studiare un intorno dell'intersezione
|
||||||
int nType ;
|
int nType ;
|
||||||
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
if ( CalcATypeFromDisk( CCompoA, m_Info[i].IciA[1].dU, ICurve::FROM_PLUS,
|
||||||
@@ -683,6 +710,39 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( bAutoInters) {
|
||||||
|
// controllo l'eventuale presenza di spike
|
||||||
|
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
|
||||||
|
if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
|
||||||
|
// se secondo tratto dello spike
|
||||||
|
double dDeltaU = abs( m_Info[i].IciA[0].dU - m_Info[i].IciB[0].dU) ;
|
||||||
|
if ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM)) {
|
||||||
|
// è punta di spike
|
||||||
|
int nType = ICCT_SPK ;
|
||||||
|
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||||
|
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||||
|
// aggiorno anche il corrispondente tipo sulla curva B
|
||||||
|
if ( m_Info[i].bCBOverEq)
|
||||||
|
m_Info[i].IciB[0].nPrevTy = GetDualIcct( nType) ;
|
||||||
|
else
|
||||||
|
m_Info[i].IciB[0].nNextTy = nType ;
|
||||||
|
}
|
||||||
|
// se primo tratto dello spike
|
||||||
|
dDeltaU = abs( m_Info[i].IciA[1].dU - m_Info[i].IciB[1].dU) ;
|
||||||
|
if ( dDeltaU < EPS_PARAM || ( bCrvAClosed && abs( dDeltaU - dCrvASpan) < EPS_PARAM)) {
|
||||||
|
// è punta di spike
|
||||||
|
int nType = ICCT_SPK ;
|
||||||
|
// aggiorno il tipo di allontanamento della curva A dalla curva B
|
||||||
|
m_Info[i].IciA[1].nNextTy = nType ;
|
||||||
|
// aggiorno anche il corrispondente tipo sulla curva B
|
||||||
|
if ( m_Info[i].bCBOverEq)
|
||||||
|
m_Info[i].IciB[1].nNextTy = GetDualIcct( nType) ;
|
||||||
|
else
|
||||||
|
m_Info[i].IciB[1].nPrevTy = nType ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// verifico se due intersezioni consecutive di tipo overlap si possono ridurre a una sola
|
// verifico se due intersezioni consecutive di tipo overlap si possono ridurre a una sola
|
||||||
@@ -693,10 +753,10 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
// se prima curva aperta, salto alla prossima
|
// se prima curva aperta, salto alla prossima
|
||||||
if ( ! CCompoA.IsClosed())
|
if ( ! CCompoA.IsClosed())
|
||||||
continue ;
|
continue ;
|
||||||
// è chiusa quindi prendo l'ultima
|
// è chiusa quindi prendo l'ultima
|
||||||
j = m_nNumInters - 1 ;
|
j = m_nNumInters - 1 ;
|
||||||
}
|
}
|
||||||
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
// se i due indici coincidono, c'è una sola intersezione e posso uscire
|
||||||
if ( i == j)
|
if ( i == j)
|
||||||
break ;
|
break ;
|
||||||
// assegno sottoindici (considero solo intersezioni overlap)
|
// assegno sottoindici (considero solo intersezioni overlap)
|
||||||
@@ -724,7 +784,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// se è rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse
|
// se è rimasta una sola intersezione con overlap anche ad entrambi gli estremi e le curve sono chiuse
|
||||||
if ( m_nNumInters == 1 && CCompoA.IsClosed() && CCompoB.IsClosed() &&
|
if ( m_nNumInters == 1 && CCompoA.IsClosed() && CCompoB.IsClosed() &&
|
||||||
m_Info[0].IciA[0].nPrevTy == ICCT_ON && m_Info[0].IciA[1].nNextTy == ICCT_ON &&
|
m_Info[0].IciA[0].nPrevTy == ICCT_ON && m_Info[0].IciA[1].nNextTy == ICCT_ON &&
|
||||||
GetCrvBDirANext( m_Info[0]) == ICCT_ON && GetCrvBDirAPrev( m_Info[0]) == ICCT_ON) {
|
GetCrvBDirANext( m_Info[0]) == ICCT_ON && GetCrvBDirAPrev( m_Info[0]) == ICCT_ON) {
|
||||||
@@ -738,10 +798,286 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
|
|||||||
m_Info[0].IciB[1].dU = ( m_Info[0].bCBOverEq ? dEnd : dStart) ;
|
m_Info[0].IciB[1].dU = ( m_Info[0].bCBOverEq ? dEnd : dStart) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// verifico se una curva ha tutte le info e queste info sono coerenti
|
||||||
|
if ( m_nNumInters > 1 && ! bAutoInters) {
|
||||||
|
bool bCoherent = true ;
|
||||||
|
INTVECTOR vIncoherenceWithPrev ;
|
||||||
|
INTVECTOR vNewOverlap ;
|
||||||
|
// salvo eventuali incoerenze col precedente
|
||||||
|
for ( int i = bCrvAClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
|
||||||
|
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
|
||||||
|
int kj = ( m_Info[j].bOverlap ? 1 : 0) ;
|
||||||
|
bool bSpike = m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq ;
|
||||||
|
if ( bSpike) {
|
||||||
|
bSpike = abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ;
|
||||||
|
}
|
||||||
|
if ( (m_Info[j].IciA[kj].nNextTy == ICCT_NULL || m_Info[i].IciA[0].nPrevTy == ICCT_NULL || m_Info[j].IciA[kj].nNextTy != m_Info[i].IciA[0].nPrevTy) &&
|
||||||
|
m_Info[j].IciA[kj].nNextTy != ICCT_SPK && m_Info[i].IciA[0].nPrevTy != ICCT_SPK) {
|
||||||
|
if ( vIncoherenceWithPrev.empty() || vIncoherenceWithPrev.back() != i)
|
||||||
|
vIncoherenceWithPrev.push_back( i) ;
|
||||||
|
if ( bSpike) {
|
||||||
|
// se ho uno spike sistemo anche il successivo
|
||||||
|
int k = i == m_nNumInters - 1 ? -1 : i + 1 ;
|
||||||
|
if ( k == -1 && bCrvAClosed)
|
||||||
|
k = 0 ;
|
||||||
|
|
||||||
|
if ( k != -1)
|
||||||
|
vIncoherenceWithPrev.push_back( k) ;
|
||||||
|
}
|
||||||
|
bCoherent = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// incoerenze sulla curva A
|
||||||
|
if ( ! bCoherent) {
|
||||||
|
for ( int i : vIncoherenceWithPrev) {
|
||||||
|
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
|
||||||
|
int kj = ( m_Info[j].bOverlap ? 1 : 0) ;
|
||||||
|
int nType = 0 ;
|
||||||
|
CalcSide( j, i, &CCompoA, &CCompoB, true, nType) ;
|
||||||
|
if ( nType != ICCT_ON) {
|
||||||
|
m_Info[i].IciA[0].nPrevTy = nType ;
|
||||||
|
m_Info[j].IciA[kj].nNextTy = nType ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vNewOverlap.push_back( i) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// faccio il merge se ho trasformato delle intersezioni in overlap
|
||||||
|
for ( int i : views::reverse( vNewOverlap))
|
||||||
|
MergeNewOverlap( i, true) ;
|
||||||
|
|
||||||
|
vNewOverlap.clear() ;
|
||||||
|
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
|
||||||
|
bCoherent = true ;
|
||||||
|
vIncoherenceWithPrev.clear() ;
|
||||||
|
// salvo eventuali incoerenze col precedente
|
||||||
|
for ( int i = bCrvBClosed ? 0 : 1 ; i < m_nNumInters ; ++i) {
|
||||||
|
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
|
||||||
|
int ki = ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
|
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
|
||||||
|
bool bSpike = m_Info[i].bOverlap && m_Info[j].bOverlap && m_Info[i].bCBOverEq != m_Info[j].bCBOverEq ;
|
||||||
|
if ( bSpike) {
|
||||||
|
bSpike = abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[0].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[0].dU) < EPS_PARAM ||
|
||||||
|
abs( m_Info[i].IciA[1].dU - m_Info[j].IciA[1].dU) < EPS_PARAM ;
|
||||||
|
}
|
||||||
|
if ( ( m_Info[j].IciB[kj].nNextTy == ICCT_NULL || m_Info[i].IciB[ki].nPrevTy == ICCT_NULL || m_Info[j].IciB[kj].nNextTy != m_Info[i].IciB[ki].nPrevTy) &&
|
||||||
|
m_Info[j].IciB[kj].nNextTy != ICCT_SPK && m_Info[i].IciB[ki].nPrevTy != ICCT_SPK) {
|
||||||
|
if ( vIncoherenceWithPrev.empty() || vIncoherenceWithPrev.back() != i)
|
||||||
|
vIncoherenceWithPrev.push_back( i) ;
|
||||||
|
if ( bSpike) {
|
||||||
|
// se ho uno spike sistemo anche il successivo
|
||||||
|
int k = ( i == m_nNumInters - 1 ? -1 : i + 1) ;
|
||||||
|
if ( k == -1 && bCrvBClosed)
|
||||||
|
k = 0 ;
|
||||||
|
|
||||||
|
if ( k != -1)
|
||||||
|
vIncoherenceWithPrev.push_back( k) ;
|
||||||
|
}
|
||||||
|
bCoherent = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// incoerenze sulla curva B
|
||||||
|
if ( ! bCoherent) {
|
||||||
|
for ( int i : vIncoherenceWithPrev) {
|
||||||
|
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
|
||||||
|
int ki = ( m_Info[i].bOverlap && !m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
|
int kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
|
||||||
|
int nType = 0 ;
|
||||||
|
CalcSide( j, i, &CCompoB, &CCompoA, false, nType) ;
|
||||||
|
if ( nType != ICCT_ON) {
|
||||||
|
m_Info[i].IciB[ki].nPrevTy = nType ;
|
||||||
|
m_Info[j].IciB[kj].nNextTy = nType ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vNewOverlap.push_back( i) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// faccio il merge se ho trasformato delle intersezioni in overlap
|
||||||
|
for ( int i : views::reverse( vNewOverlap))
|
||||||
|
MergeNewOverlap( i, false) ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// posso completare A guardando B e viceversa
|
||||||
|
}
|
||||||
|
|
||||||
|
stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
|
||||||
// verifiche su intersezioni in zone non-manifold
|
// verifiche su intersezioni in zone non-manifold
|
||||||
OrderNonManifoldInters( m_Info, CCompoA, CCompoB) ;
|
OrderNonManifoldInters( m_Info, CCompoA, CCompoB) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCrvCompoCrvCompo::CalcSide( int j, int i,const ICurve* pThisCrv, const ICurve* pOtherCrv, bool bCrvAOrB, int& nType)
|
||||||
|
{
|
||||||
|
const IntCrvCrvInfo& Icci1 = m_Info[j] ;
|
||||||
|
const IntCrvCrvInfo& Icci2 = m_Info[i] ;
|
||||||
|
// calcolo tra l'intersezione 1 e 2 se la curva sta dentro o fuori
|
||||||
|
int ki = 0 ;
|
||||||
|
int kj = ( Icci1.bOverlap ? 1 : 0) ;
|
||||||
|
if ( ! bCrvAOrB) {
|
||||||
|
ki = ( m_Info[i].bOverlap && !m_Info[i].bCBOverEq ? 1 : 0) ;
|
||||||
|
kj = ( m_Info[j].bOverlap && m_Info[j].bCBOverEq ? 1 : 0) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
double dU = 0 ;
|
||||||
|
bool bPrevIsBefore = true ;
|
||||||
|
if ( bCrvAOrB) {
|
||||||
|
// se precedente minore del successivo faccio la media
|
||||||
|
if ( Icci1.IciA[kj].dU < Icci2.IciA[ki].dU)
|
||||||
|
dU = ( Icci2.IciA[ki].dU + Icci1.IciA[kj].dU) / 2 ;
|
||||||
|
// altrimenti guardo tra lo start e il successivo
|
||||||
|
else {
|
||||||
|
bPrevIsBefore = false ;
|
||||||
|
dU = ( Icci2.IciA[0].dU + 0.) / 2 ;
|
||||||
|
if ( dU < EPS_SMALL) {
|
||||||
|
double dStart, dEnd ;
|
||||||
|
pThisCrv->GetDomain( dStart, dEnd) ;
|
||||||
|
double dUNew = dEnd - Icci1.IciA[kj].dU / 2 ;
|
||||||
|
if ( dUNew > dU)
|
||||||
|
dU = dUNew ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// se precedente minore del successivo faccio la media
|
||||||
|
if ( Icci1.IciB[kj].dU < Icci2.IciB[ki].dU)
|
||||||
|
dU = ( Icci2.IciB[ki].dU + Icci1.IciB[kj].dU) / 2 ;
|
||||||
|
// altrimenti guardi tra lo start e il successivo
|
||||||
|
else {
|
||||||
|
bPrevIsBefore = false ;
|
||||||
|
dU = ( Icci2.IciB[0].dU + 0.) / 2 ;
|
||||||
|
if ( dU < EPS_SMALL) {
|
||||||
|
double dStart, dEnd ;
|
||||||
|
pThisCrv->GetDomain( dStart, dEnd) ;
|
||||||
|
double dUNew = dEnd - Icci1.IciB[kj].dU / 2 ;
|
||||||
|
if ( dUNew > dU)
|
||||||
|
dU = dUNew ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Point3d ptTest ; pThisCrv->GetPointD1D2( dU, ICurve::FROM_MINUS, ptTest) ;
|
||||||
|
DistPointCurve dpc( ptTest, *pOtherCrv) ;
|
||||||
|
dpc.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ;
|
||||||
|
if ( nType == MDS_LEFT)
|
||||||
|
nType = ICCT_IN ;
|
||||||
|
else if ( nType == MDS_RIGHT)
|
||||||
|
nType = ICCT_OUT ;
|
||||||
|
// se lo trovo sulla curva controllo se posso definire un tratto overlap
|
||||||
|
if ( nType == MDS_ON) {
|
||||||
|
double dFactor = 1./3. ;
|
||||||
|
DBLVECTOR vdU(2) ;
|
||||||
|
bool bIsOn = false ;
|
||||||
|
if ( bCrvAOrB) {
|
||||||
|
if ( bPrevIsBefore) {
|
||||||
|
vdU[0] = ( 1 - dFactor) * Icci2.IciA[ki].dU + dFactor * Icci1.IciA[kj].dU ;
|
||||||
|
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciA[ki].dU + 2 * dFactor * Icci1.IciA[kj].dU ;
|
||||||
|
}
|
||||||
|
else if ( Icci2.IciA[ki].dU > 2 * EPS_SMALL){
|
||||||
|
vdU[0] = ( Icci2.IciA[ki].dU + 0.) * dFactor ;
|
||||||
|
vdU[1] = ( Icci2.IciA[ki].dU + 0.) * 2 * dFactor ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bIsOn = true ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( bPrevIsBefore) {
|
||||||
|
vdU[0] = ( 1 - dFactor) * Icci2.IciB[ki].dU + dFactor * Icci1.IciB[kj].dU ;
|
||||||
|
vdU[1] = ( 1 - 2 * dFactor) * Icci2.IciB[ki].dU + 2 * dFactor * Icci1.IciB[kj].dU ;
|
||||||
|
}
|
||||||
|
else if ( Icci2.IciB[ki].dU > 2 * EPS_SMALL) {
|
||||||
|
vdU[0] = ( Icci2.IciB[ki].dU + 0.) * dFactor ;
|
||||||
|
vdU[1] = ( Icci2.IciB[ki].dU + 0.) * 2 * dFactor ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bIsOn = true ;
|
||||||
|
}
|
||||||
|
if ( ! bIsOn) {
|
||||||
|
bIsOn = true ;
|
||||||
|
for ( int k = 0 ; k < ssize(vdU) && bIsOn ; ++k) {
|
||||||
|
Point3d ptTest2 ; pThisCrv->GetPointD1D2( vdU[k], ICurve::FROM_MINUS, ptTest2) ;
|
||||||
|
DistPointCurve dpc2( ptTest2, *pOtherCrv) ;
|
||||||
|
dpc2.GetSideAtMinDistPoint( 0, Z_AX, nType, EPS_ZERO) ;
|
||||||
|
if ( nType != MDS_ON)
|
||||||
|
bIsOn = false ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bIsOn) {
|
||||||
|
m_Info[i].bOverlap = true ;
|
||||||
|
Vector3d vtDirThis, vtDirOther ;
|
||||||
|
Point3d ptCommon ;
|
||||||
|
double dUThis = 0 ;
|
||||||
|
if ( bCrvAOrB)
|
||||||
|
dUThis = m_Info[i].IciA[0].dU ;
|
||||||
|
else
|
||||||
|
dUThis = m_Info[i].IciB[0].dU ;
|
||||||
|
pThisCrv->GetPointD1D2( dUThis, ICurve::Side::FROM_MINUS, ptCommon, &vtDirThis) ;
|
||||||
|
double dUOther = 0 ; pOtherCrv->GetParamAtPoint( ptCommon, dUOther) ;
|
||||||
|
pOtherCrv->GetPointD1D2( dUOther, ICurve::Side::FROM_MINUS, ptCommon, &vtDirOther) ;
|
||||||
|
m_Info[i].bCBOverEq = vtDirThis * vtDirOther > 0 ;
|
||||||
|
if ( m_Info[i].bCBOverEq) {
|
||||||
|
m_Info[i].IciA[1] = m_Info[i].IciA[0] ;
|
||||||
|
m_Info[i].IciB[1] = m_Info[i].IciB[0] ;
|
||||||
|
m_Info[i].IciA[0] = m_Info[j].IciA[kj] ;
|
||||||
|
m_Info[i].IciB[0] = m_Info[j].IciB[kj] ;
|
||||||
|
m_Info[i].IciA[1].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciB[1].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciA[0].nNextTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciB[0].nNextTy = ICCT_ON ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( bCrvAOrB) {
|
||||||
|
m_Info[i].IciA[1] = m_Info[i].IciA[0] ;
|
||||||
|
m_Info[i].IciA[0] = m_Info[j].IciA[kj] ;
|
||||||
|
m_Info[i].IciA[1].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciA[0].nNextTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciB[1] = m_Info[j].IciB[kj] ;
|
||||||
|
m_Info[i].IciB[0].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciB[1].nNextTy = ICCT_ON ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_Info[i].IciB[1] = m_Info[i].IciB[0] ;
|
||||||
|
m_Info[i].IciB[0] = m_Info[j].IciB[kj] ;
|
||||||
|
m_Info[i].IciB[1].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciB[0].nNextTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciA[1] = m_Info[j].IciA[kj] ;
|
||||||
|
m_Info[i].IciA[0].nPrevTy = ICCT_ON ;
|
||||||
|
m_Info[i].IciA[1].nNextTy = ICCT_ON ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nType = ICCT_ON ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCrvCompoCrvCompo::MergeNewOverlap( int i, bool bCrvAOrB)
|
||||||
|
{
|
||||||
|
if ( i >= ssize(m_Info))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// faccio il merge col precedente
|
||||||
|
int j = ( i == 0 ? m_nNumInters - 1 : i - 1) ;
|
||||||
|
if ( m_Info[j].bOverlap) {
|
||||||
|
m_Info[i].IciA[0] = m_Info[j].IciA[0] ;
|
||||||
|
m_Info[i].IciB[0] = m_Info[j].IciB[0] ;
|
||||||
|
}
|
||||||
|
m_Info.erase( m_Info.begin() + j) ;
|
||||||
|
-- j ;
|
||||||
|
-- m_nNumInters ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB,
|
IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB,
|
||||||
@@ -806,13 +1142,27 @@ bool
|
|||||||
IntersCrvCompoCrvCompo::EraseOtherInfo( int& nIndCurr, int& nIndOther)
|
IntersCrvCompoCrvCompo::EraseOtherInfo( int& nIndCurr, int& nIndOther)
|
||||||
{
|
{
|
||||||
m_Info.erase( m_Info.begin() + nIndOther) ;
|
m_Info.erase( m_Info.begin() + nIndOther) ;
|
||||||
if ( nIndOther < nIndCurr)
|
|
||||||
-- nIndCurr ;
|
-- nIndCurr ;
|
||||||
-- nIndOther ;
|
-- nIndOther ;
|
||||||
-- m_nNumInters ;
|
-- m_nNumInters ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
IntersCrvCompoCrvCompo::EraseBothInfo( int& nIndCurr, int& nIndOther)
|
||||||
|
{
|
||||||
|
m_Info.erase( m_Info.begin() + nIndOther) ;
|
||||||
|
-- nIndCurr ;
|
||||||
|
-- nIndOther ;
|
||||||
|
-- m_nNumInters ;
|
||||||
|
m_Info.erase( m_Info.begin() + nIndCurr) ;
|
||||||
|
if ( nIndCurr != -1)
|
||||||
|
-- nIndCurr ;
|
||||||
|
-- m_nNumInters ;
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Global functions
|
// Global functions
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -855,21 +1205,25 @@ SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
|
|||||||
dU1 = aInfo1.IciB[0].dU ;
|
dU1 = aInfo1.IciB[0].dU ;
|
||||||
if ( aInfo1.bOverlap) {
|
if ( aInfo1.bOverlap) {
|
||||||
// caso normale
|
// caso normale
|
||||||
if ( aInfo1.IciB[0].dU < aInfo1.IciB[1].dU)
|
if ( ( aInfo1.bCBOverEq && aInfo1.IciB[0].dU < aInfo1.IciB[1].dU) || ( ! aInfo1.bCBOverEq && aInfo1.IciB[0].dU > aInfo1.IciB[1].dU))
|
||||||
dU1 = 0.5 * ( aInfo1.IciB[0].dU + aInfo1.IciB[1].dU) ;
|
dU1 = 0.5 * ( aInfo1.IciB[0].dU + aInfo1.IciB[1].dU) ;
|
||||||
// a cavallo di fine / inizio
|
// a cavallo di fine / inizio
|
||||||
else
|
else if ( aInfo1.bCBOverEq)
|
||||||
dU1 = aInfo1.IciB[0].dU + SPAN_PARAM ;
|
dU1 = aInfo1.IciB[0].dU + SPAN_PARAM ;
|
||||||
|
else
|
||||||
|
dU1 = aInfo1.IciB[1].dU + SPAN_PARAM ;
|
||||||
}
|
}
|
||||||
// determino il secondo termine del confronto
|
// determino il secondo termine del confronto
|
||||||
dU2 = aInfo2.IciB[0].dU ;
|
dU2 = aInfo2.IciB[0].dU ;
|
||||||
if ( aInfo2.bOverlap) {
|
if ( aInfo2.bOverlap) {
|
||||||
// caso normale
|
// caso normale
|
||||||
if ( aInfo2.IciB[0].dU < aInfo2.IciB[1].dU)
|
if ( ( aInfo2.bCBOverEq && aInfo2.IciB[0].dU < aInfo2.IciB[1].dU) || ( ! aInfo2.bCBOverEq && aInfo2.IciB[0].dU > aInfo2.IciB[1].dU))
|
||||||
dU2 = 0.5 * ( aInfo2.IciB[0].dU + aInfo2.IciB[1].dU) ;
|
dU2 = 0.5 * ( aInfo2.IciB[0].dU + aInfo2.IciB[1].dU) ;
|
||||||
// a cavallo di fine / inizio
|
// a cavallo di fine / inizio
|
||||||
else
|
else if ( aInfo2.bCBOverEq)
|
||||||
dU2 = aInfo2.IciB[0].dU + SPAN_PARAM ;
|
dU2 = aInfo2.IciB[0].dU + SPAN_PARAM ;
|
||||||
|
else
|
||||||
|
dU2 = aInfo2.IciB[1].dU + SPAN_PARAM ;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ( dU2 > dU1 + EPS_PARAM) ;
|
return ( dU2 > dU1 + EPS_PARAM) ;
|
||||||
@@ -879,7 +1233,7 @@ SortGreaterB( const IntCrvCrvInfo& aInfo1, const IntCrvCrvInfo& aInfo2)
|
|||||||
bool
|
bool
|
||||||
OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& CurveB)
|
OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& CurveB)
|
||||||
{
|
{
|
||||||
// questi controlli sono validi solo se la curva B è chiusa
|
// questi controlli sono validi solo se la curva B è chiusa
|
||||||
if ( ! CurveB.IsClosed())
|
if ( ! CurveB.IsClosed())
|
||||||
return false ;
|
return false ;
|
||||||
|
|
||||||
@@ -908,7 +1262,7 @@ OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& Cu
|
|||||||
// se prima curva aperta, salto alla prossima
|
// se prima curva aperta, salto alla prossima
|
||||||
if ( ! CurveA.IsClosed())
|
if ( ! CurveA.IsClosed())
|
||||||
continue ;
|
continue ;
|
||||||
// è chiusa quindi prendo l'ultima
|
// è chiusa quindi prendo l'ultima
|
||||||
j = nNumInters - 1 ;
|
j = nNumInters - 1 ;
|
||||||
}
|
}
|
||||||
// se i due indici coincidono, salto
|
// se i due indici coincidono, salto
|
||||||
@@ -960,11 +1314,20 @@ OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& Cu
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static bool
|
static bool
|
||||||
CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||||
bool bCrvAClosed, double dCrvASpan)
|
bool bCrvAClosed, double dCrvASpan, bool bOrderedOnB)
|
||||||
{
|
{
|
||||||
int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
int ki = 0 ;
|
||||||
if ( abs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) > 0.1 * SPAN_PARAM &&
|
int kj = 0 ;
|
||||||
( ! bCrvAClosed || abs( abs( Icci1.IciA[k].dU - Icci2.IciA[0].dU) - dCrvASpan) > 0.1 * SPAN_PARAM))
|
if ( ! bOrderedOnB) {
|
||||||
|
ki = 0 ;
|
||||||
|
kj = Icci1.bOverlap ? 1 : 0 ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ki = Icci2.bOverlap && ! Icci2.bCBOverEq ? 1 : 0 ;
|
||||||
|
kj = Icci1.bOverlap && Icci1.bCBOverEq ? 1 : 0 ;
|
||||||
|
}
|
||||||
|
if ( abs( Icci1.IciA[kj].dU - Icci2.IciA[ki].dU) > 0.1 * SPAN_PARAM &&
|
||||||
|
( ! bCrvAClosed || abs( abs( Icci1.IciA[kj].dU - Icci2.IciA[ki].dU) - dCrvASpan) > 0.1 * SPAN_PARAM))
|
||||||
return false ;
|
return false ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -972,11 +1335,21 @@ CompatibleParamA( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
static bool
|
static bool
|
||||||
CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
CompatibleParamB( const IntCrvCrvInfo& Icci1, const IntCrvCrvInfo& Icci2,
|
||||||
bool bCrvBClosed, double dCrvBSpan)
|
bool bCrvBClosed, double dCrvBSpan, bool bOrderedOnB)
|
||||||
{
|
{
|
||||||
int k = ( Icci1.bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
|
int ki = 0 ;
|
||||||
if ( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) > 0.1 * SPAN_PARAM &&
|
int kj = 0 ;
|
||||||
( ! bCrvBClosed || abs( abs( Icci1.IciB[k].dU - Icci2.IciB[0].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM))
|
if ( ! bOrderedOnB) {
|
||||||
|
ki = 0 ;
|
||||||
|
kj = Icci1.bOverlap ? 1 : 0 ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ki = Icci2.bOverlap && ! Icci2.bCBOverEq ? 1 : 0 ;
|
||||||
|
kj = Icci1.bOverlap && Icci1.bCBOverEq ? 1 : 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( abs( Icci1.IciB[kj].dU - Icci2.IciB[ki].dU) > 0.1 * SPAN_PARAM &&
|
||||||
|
( ! bCrvBClosed || abs( abs( Icci1.IciB[kj].dU - Icci2.IciB[ki].dU) - dCrvBSpan) > 0.1 * SPAN_PARAM))
|
||||||
return false ;
|
return false ;
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -998,7 +1371,7 @@ MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crv
|
|||||||
//Point3d ptMed ;
|
//Point3d ptMed ;
|
||||||
//if ( ! crvCompo.GetPointD1D2( dUmed, ICurve::FROM_MINUS, ptMed))
|
//if ( ! crvCompo.GetPointD1D2( dUmed, ICurve::FROM_MINUS, ptMed))
|
||||||
// return ;
|
// return ;
|
||||||
// verifico che non sia più lontano dei punti originali dal loro medio
|
// verifico che non sia più lontano dei punti originali dal loro medio
|
||||||
//if ( SqDist( Ici1.ptI, ptMed) > dSqDist / 4)
|
//if ( SqDist( Ici1.ptI, ptMed) > dSqDist / 4)
|
||||||
// return ;
|
// return ;
|
||||||
// medio i parametri
|
// medio i parametri
|
||||||
@@ -1012,13 +1385,13 @@ MediaParamPoints( IntCrvInfo& Ici1, IntCrvInfo& Ici2, const ICurveComposite& crv
|
|||||||
static int
|
static int
|
||||||
GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
||||||
{
|
{
|
||||||
// non è overlap, è il prev del primo punto
|
// non è overlap, è il prev del primo punto
|
||||||
if ( ! Icci.bOverlap)
|
if ( ! Icci.bOverlap)
|
||||||
return Icci.IciB[0].nPrevTy ;
|
return Icci.IciB[0].nPrevTy ;
|
||||||
// è overlap equiverso, è il prev del primo punto
|
// è overlap equiverso, è il prev del primo punto
|
||||||
if ( Icci.bCBOverEq)
|
if ( Icci.bCBOverEq)
|
||||||
return Icci.IciB[0].nPrevTy ;
|
return Icci.IciB[0].nPrevTy ;
|
||||||
// è overlap controverso, è il next del primo punto
|
// è overlap controverso, è il next del primo punto
|
||||||
return Icci.IciB[0].nNextTy ;
|
return Icci.IciB[0].nNextTy ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,13 +1401,13 @@ GetCrvBDirAPrev( IntCrvCrvInfo& Icci)
|
|||||||
static int
|
static int
|
||||||
GetCrvBDirANext( IntCrvCrvInfo& Icci)
|
GetCrvBDirANext( IntCrvCrvInfo& Icci)
|
||||||
{
|
{
|
||||||
// non è overlap, è il next del primo punto
|
// non è overlap, è il next del primo punto
|
||||||
if ( ! Icci.bOverlap)
|
if ( ! Icci.bOverlap)
|
||||||
return Icci.IciB[0].nNextTy ;
|
return Icci.IciB[0].nNextTy ;
|
||||||
// è overlap equiverso, è il next del secondo punto
|
// è overlap equiverso, è il next del secondo punto
|
||||||
if ( Icci.bCBOverEq)
|
if ( Icci.bCBOverEq)
|
||||||
return Icci.IciB[1].nNextTy ;
|
return Icci.IciB[1].nNextTy ;
|
||||||
// è overlap controverso, è il prev del secondo punto
|
// è overlap controverso, è il prev del secondo punto
|
||||||
return Icci.IciB[1].nPrevTy ;
|
return Icci.IciB[1].nPrevTy ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,7 +1451,7 @@ CalcATypeFromDisk( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
|||||||
return false ;
|
return false ;
|
||||||
if ( dAngBpDeg < 0)
|
if ( dAngBpDeg < 0)
|
||||||
dAngBpDeg += ANG_FULL ;
|
dAngBpDeg += ANG_FULL ;
|
||||||
// se l'angolo di DirA è compreso tra DirBn e DirBp (muovendosi in senso CCW) allora è IN, altrimenti OUT
|
// se l'angolo di DirA è compreso tra DirBn e DirBp (muovendosi in senso CCW) allora è IN, altrimenti OUT
|
||||||
if ( dAngADeg > 0 && dAngADeg < dAngBpDeg)
|
if ( dAngADeg > 0 && dAngADeg < dAngBpDeg)
|
||||||
nType = ICCT_IN ;
|
nType = ICCT_IN ;
|
||||||
else
|
else
|
||||||
@@ -1151,12 +1524,12 @@ CalcATypeFromDisk2( const ICurve& CurveA, double dUA, ICurve::Side nSideA,
|
|||||||
// li ordino in senso crescente
|
// li ordino in senso crescente
|
||||||
if ( dAngB1pDeg > dAngB2pDeg)
|
if ( dAngB1pDeg > dAngB2pDeg)
|
||||||
swap( dAngB1pDeg, dAngB2pDeg) ;
|
swap( dAngB1pDeg, dAngB2pDeg) ;
|
||||||
// se non ci sono variazioni angolari significative, non posso decidere alcunché
|
// se non ci sono variazioni angolari significative, non posso decidere alcunché
|
||||||
const double MIN_DEV_ANG = 2 ;
|
const double MIN_DEV_ANG = 2 ;
|
||||||
if ( abs( DiffAngle( dAngB1pDeg + ANG_STRAIGHT, 0)) < MIN_DEV_ANG &&
|
if ( abs( DiffAngle( dAngB1pDeg + ANG_STRAIGHT, 0)) < MIN_DEV_ANG &&
|
||||||
abs( DiffAngle( dAngB2pDeg + ANG_STRAIGHT, dAngB2nDeg)) < MIN_DEV_ANG)
|
abs( DiffAngle( dAngB2pDeg + ANG_STRAIGHT, dAngB2nDeg)) < MIN_DEV_ANG)
|
||||||
return false ;
|
return false ;
|
||||||
// IN è tra 0 e dAngB1pDeg e tra dAngB2nDeg e dAngB2pDeg
|
// IN è tra 0 e dAngB1pDeg e tra dAngB2nDeg e dAngB2pDeg
|
||||||
if ( ( dAngADeg > 0 && dAngADeg < dAngB1pDeg) ||
|
if ( ( dAngADeg > 0 && dAngADeg < dAngB1pDeg) ||
|
||||||
( dAngADeg > dAngB2nDeg && dAngADeg < dAngB2pDeg))
|
( dAngADeg > dAngB2nDeg && dAngADeg < dAngB2pDeg))
|
||||||
nType = ICCT_IN ;
|
nType = ICCT_IN ;
|
||||||
|
|||||||
@@ -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 ;
|
||||||
|
|||||||
+102
-16
@@ -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 ;
|
||||||
@@ -535,8 +577,24 @@ 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 ;
|
||||||
|
// se sono in un caso di spike devo trattare l'overlap in modo diverso
|
||||||
|
if ( ! bSpike)
|
||||||
nLastTy = InfoCorr[i].IciA[1].nNextTy ;
|
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 ;
|
||||||
|
}
|
||||||
+13
-1
@@ -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,7 +144,13 @@ 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 {
|
||||||
|
if ( dU1 < - EPS_SMALL)
|
||||||
|
vInters.emplace_back( ILBT_TG_INSIDE, 0.) ;
|
||||||
|
else
|
||||||
vInters.emplace_back( ILBT_TG_INI, Clamp( dU1, 0., dLen)) ;
|
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)) ;
|
vInters.emplace_back( ILBT_TG_FIN, Clamp( dU2, 0., dLen)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +168,13 @@ 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 {
|
||||||
|
if ( dU1 < - EPS_SMALL)
|
||||||
|
vInters.emplace_back( ILBT_INSIDE, 0.) ;
|
||||||
|
else
|
||||||
vInters.emplace_back( ILBT_IN, Clamp( dU1, 0., dLen)) ;
|
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)) ;
|
vInters.emplace_back( ILBT_OUT, Clamp( dU2, 0., dLen)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+143
-25
@@ -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,59 +26,80 @@ 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)
|
|
||||||
{
|
{
|
||||||
|
dU1 = NAN ;
|
||||||
|
dU2 = NAN ;
|
||||||
|
|
||||||
// Verifico il versore
|
// Verifico il versore
|
||||||
if ( vtL.IsSmall())
|
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) ;
|
||||||
|
swap( ptInt1, ptInt2) ;
|
||||||
|
swap( vtN1, vtN2) ;
|
||||||
|
}
|
||||||
|
if ( bInvertNormals) {
|
||||||
|
vtN1 *= - 1 ;
|
||||||
|
vtN2 *= - 1 ;
|
||||||
|
}
|
||||||
// Trovate intersezioni
|
// 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) ;
|
||||||
|
|
||||||
|
// 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
|
// 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 ;
|
||||||
@@ -86,10 +108,25 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
|
|
||||||
// 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) ;
|
||||||
|
swap( ptInt1, ptInt2) ;
|
||||||
|
swap( vtN1, vtN2) ;
|
||||||
|
}
|
||||||
|
if ( bInvertNormals) {
|
||||||
|
vtN1 *= - 1 ;
|
||||||
|
vtN2 *= - 1 ;
|
||||||
|
}
|
||||||
// Trovate intersezioni
|
// Trovate intersezioni
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -98,17 +135,34 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
else if ( nRoot == 1) {
|
else if ( nRoot == 1) {
|
||||||
// Se piano superiore
|
// Se piano superiore
|
||||||
if ( nBasInt == 2) {
|
if ( nBasInt == 2) {
|
||||||
|
// Punto di intersezione
|
||||||
dU1 = vdRoots[0] ;
|
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
|
// altrimenti piano inferiore
|
||||||
else if ( nBasInt == 1) {
|
else if ( nBasInt == 1) {
|
||||||
|
// Punto di intersezione
|
||||||
dU2 = vdRoots[0] ;
|
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
|
// altrimenti niente
|
||||||
else
|
else
|
||||||
return false ;
|
return false ;
|
||||||
if ( dU1 > dU2)
|
if ( dU1 > dU2) {
|
||||||
swap( dU1, dU2) ;
|
swap( dU1, dU2) ;
|
||||||
|
swap( ptInt1, ptInt2) ;
|
||||||
|
swap( vtN1, vtN2) ;
|
||||||
|
}
|
||||||
|
if ( bInvertNormals) {
|
||||||
|
vtN1 *= - 1 ;
|
||||||
|
vtN2 *= - 1 ;
|
||||||
|
}
|
||||||
// Trovate intersezioni
|
// Trovate intersezioni
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -118,6 +172,30 @@ IntersLineCyl( const Point3d& ptL, const Vector3d& vtL,
|
|||||||
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) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -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
|
||||||
|
|||||||
+622
-27
@@ -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) ; }) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@@ -142,11 +159,11 @@ IntersLineSurfBz( const Point3d& ptL, const Vector3d& vtL, double dLen, const IS
|
|||||||
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 ;
|
||||||
|
}
|
||||||
|
|||||||
+100
-15
@@ -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) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
|
// ( in questo caso la superficie è unica, quindi ho solo due elementi)
|
||||||
|
m_vBaseInd = { 0, m_vpSTm[0]->GetTriangleCount()} ;
|
||||||
|
|
||||||
|
// creo HashGrid 2d ed eventualmente attivo la griglia
|
||||||
const int LIM_HG_TRIA = 127 ;
|
const int LIM_HG_TRIA = 127 ;
|
||||||
m_HGrids.SetActivationGrid( m_pSTm->GetTriangleCount() > LIM_HG_TRIA) ;
|
m_HGrids.SetActivationGrid( m_vBaseInd.back() > LIM_HG_TRIA) ;
|
||||||
|
|
||||||
// riempio HashGrid
|
// 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 ;
|
||||||
|
|
||||||
@@ -178,11 +227,18 @@ IntersParLinesSurfTm::GetInters( const Point3d& ptL, double dLen, ILSIVECTOR& vI
|
|||||||
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)
|
||||||
|
|||||||
@@ -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) ;
|
||||||
|
}
|
||||||
+62
-73
@@ -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,11 +51,13 @@ 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 ;
|
||||||
|
|||||||
+63
-85
@@ -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,34 +75,25 @@ 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 ;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( m_OutTxtFile != nullptr) {
|
|
||||||
bool bOk = ( gzclose( m_OutTxtFile) == Z_OK) ;
|
|
||||||
m_OutTxtFile = nullptr ;
|
|
||||||
return bOk ;
|
return bOk ;
|
||||||
}
|
}
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
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)) ;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-8
@@ -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) ;
|
||||||
@@ -45,8 +44,5 @@ class NgeWriter
|
|||||||
|
|
||||||
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 ;
|
|
||||||
} ;
|
} ;
|
||||||
|
|||||||
+145
-21
@@ -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 ;
|
||||||
|
|
||||||
|
// suddivido le curve di offset individuando i fillet e isolandoli dagli altri tratti
|
||||||
|
ICRVCOMPOPVECTOR vCrvs ;
|
||||||
|
for ( int i = 0 ; i < int( vOffset.size()) ; i ++) {
|
||||||
|
CurveComposite* pCompo = GetBasicCurveComposite( vOffset[i]) ;
|
||||||
|
if ( pCompo == nullptr)
|
||||||
|
return false ;
|
||||||
|
bool bNewCrv = true ;
|
||||||
|
PtrOwner<ICurve> pCrv( pCompo->RemoveFirstOrLastCurve(false)) ;
|
||||||
while ( ! IsNull( pCrv)) {
|
while ( ! IsNull( pCrv)) {
|
||||||
// se identificato come fillet lo trasformo in smusso o estensione
|
|
||||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
||||||
CurveComposite ccTemp ;
|
// se fillet calcolo il nuovo raccordo
|
||||||
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
CurveComposite* ccTemp = CreateBasicCurveComposite() ;
|
||||||
// metto in lista le curve risultanti
|
ModifyFillet( pCrv, dDist, nType, *ccTemp) ;
|
||||||
if ( ccTemp.GetCurveCount() > 0) {
|
// assegno temp param per identificarlo nei conti successivi
|
||||||
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
ccTemp->SetTempParam( 1) ;
|
||||||
while ( ! IsNull( pCrv2)) {
|
vCrvs.push_back( ccTemp) ;
|
||||||
CrvLst.push_back( Release( pCrv2)) ;
|
bNewCrv = true ;
|
||||||
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// aggiungo la curva
|
||||||
|
if ( bNewCrv) {
|
||||||
|
bNewCrv = false ;
|
||||||
|
CurveComposite* pCompo = ConvertCurveToBasicComposite( Release( pCrv)) ;
|
||||||
|
if ( pCompo == nullptr)
|
||||||
|
return false ;
|
||||||
|
vCrvs.push_back( pCompo) ;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// altrimenti salvo in lista
|
|
||||||
else
|
else
|
||||||
CrvLst.push_back( Release( pCrv)) ;
|
vCrvs.back()->AddCurve( Release( pCrv)) ;
|
||||||
|
}
|
||||||
// passo alla curva successiva
|
// passo alla curva successiva
|
||||||
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
pCrv.Set( pCompo->RemoveFirstOrLastCurve( false)) ;
|
||||||
}
|
}
|
||||||
// rimetto le curve nella composita
|
|
||||||
for ( auto pCrv : CrvLst) {
|
|
||||||
pCrvCo->AddCurve( pCrv) ;
|
|
||||||
}
|
}
|
||||||
// unisco tratti allineati
|
vOffset.clear() ;
|
||||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
|
||||||
|
// 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)) ;
|
||||||
|
}
|
||||||
|
|
||||||
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) ;
|
|
||||||
+16
-8
@@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+324
-7
@@ -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() ;
|
||||||
}
|
}
|
||||||
@@ -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() ;
|
||||||
@@ -1613,7 +1619,8 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
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 ;
|
||||||
@@ -1693,6 +1700,316 @@ AssociatePolyLinesMinDistPoints( const PolyLine& PL1, const PolyLine& PL2, PNTIV
|
|||||||
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) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|||||||
+15
-2
@@ -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) {
|
||||||
@@ -171,7 +177,6 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
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() ;
|
||||||
@@ -206,6 +211,13 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
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) ;
|
||||||
|
if ( intLL.GetIntersCount() == 0) {
|
||||||
|
Point3d ptM = Media( vEdges[i].first, vEdges[i].second) ;
|
||||||
|
ptM.z = 0 ;
|
||||||
|
if ( IsPointInsidePolyLine( ptM, PL, -EPS_SMALL))
|
||||||
|
dElev = max( dElev, max( vEdges[i].first.z, vEdges[i].second.z)) ;
|
||||||
|
}
|
||||||
|
else {
|
||||||
IntCrvCrvInfo aInfo ;
|
IntCrvCrvInfo aInfo ;
|
||||||
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
for ( int j = 0 ; intLL.GetIntCrvCrvInfo( j, aInfo) ; ++ j) {
|
||||||
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
dElev = max( dElev, aInfo.IciA[0].ptI.z) ;
|
||||||
@@ -219,6 +231,7 @@ PolygonElevationInClosedSurfTm( const Polygon3d& pgFacet, const ISurfTriMesh& Cl
|
|||||||
dElev = max( dElev, vEdges[i].second.z) ;
|
dElev = max( dElev, vEdges[i].second.z) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|||||||
+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)
|
||||||
|
|||||||
+603
-254
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
|
||||||
|
|||||||
+80
-643
@@ -98,52 +98,13 @@ GetSurfBezierByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
|
|||||||
// verifica parametri
|
// verifica parametri
|
||||||
if ( pCurve == nullptr || &vtExtr == nullptr)
|
if ( pCurve == nullptr || &vtExtr == nullptr)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
// calcolo la polilinea che approssima la curva
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
||||||
return nullptr ;
|
|
||||||
//// se richiesta chiusura agli estremi
|
|
||||||
//bool bDoCapEnds = false ;
|
|
||||||
//if ( bCapEnds) {
|
|
||||||
// // verifico che la curva sia chiusa e piatta
|
|
||||||
// Plane3d plPlane ;
|
|
||||||
// double dArea ;
|
|
||||||
// if ( PL.IsClosedAndFlat( plPlane, dArea, 50 * EPS_SMALL)) {
|
|
||||||
// // componente dell'estrusione perpendicolare al piano della curva
|
|
||||||
// double dOrthoExtr = plPlane.GetVersN() * vtExtr ;
|
|
||||||
// if ( ( abs( dOrthoExtr) > EPS_SMALL)) {
|
|
||||||
// bDoCapEnds = true ;
|
|
||||||
// // se negativa, inverto il senso del contorno
|
|
||||||
// if ( dOrthoExtr < 0)
|
|
||||||
// PL.Invert() ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
PtrOwner<const ICurve> pBezierForm( CurveToBezierCurve( pCurve)) ;
|
PtrOwner<const ICurve> pBezierForm( CurveToBezierCurve( pCurve)) ;
|
||||||
// creo e setto la superficie trimesh
|
// creo e setto la superficie di Bezier
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
|
if ( IsNull( pSbz) || ! pSbz->CreateByExtrusion( pBezierForm, vtExtr))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
|
|
||||||
//// se da fare, metto i tappi sulle estremità
|
|
||||||
//if ( bDoCapEnds) {
|
|
||||||
// // creo la prima superficie di estremità
|
|
||||||
// SurfTriMesh STM1 ;
|
|
||||||
// if ( ! STM1.CreateByFlatContour( PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // la copio
|
|
||||||
// SurfTriMesh STM2 = STM1 ;
|
|
||||||
// // inverto la prima superficie
|
|
||||||
// STM1.Invert() ;
|
|
||||||
// // traslo la seconda
|
|
||||||
// STM2.Translate( vtExtr) ;
|
|
||||||
|
|
||||||
// ////// SurfCompo?
|
|
||||||
// //// le unisco alla superficie del fianco
|
|
||||||
// //if ( ! pSbz->DoSewing( STM1) || ! pSTM->DoSewing( STM2))
|
|
||||||
// // return nullptr ;
|
|
||||||
//}
|
|
||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSbz) ;
|
return Release( pSbz) ;
|
||||||
}
|
}
|
||||||
@@ -201,45 +162,6 @@ GetSurfBezierByRevolve( const ICurve* pCurve, const Point3d& ptAx, const Vector3
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
// limite minimo su tolleranza
|
// limite minimo su tolleranza
|
||||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||||
//// calcolo la polilinea che approssima la curva
|
|
||||||
//PolyLine PL ;
|
|
||||||
//if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
||||||
// return nullptr ;
|
|
||||||
|
|
||||||
//// se richiesta chiusura degli estremi
|
|
||||||
//if ( bCapEnds && ! PL.IsClosed()) { // serve la SURFCOMPO
|
|
||||||
// Vector3d vtAxN = vtAx ;
|
|
||||||
// vtAxN.Normalize() ;
|
|
||||||
// double dPosIni = 0, dPosFin = 0 ;
|
|
||||||
// Point3d ptP ;
|
|
||||||
// // proietto l'ultimo punto sull'asse di rotazione
|
|
||||||
// if ( PL.GetLastPoint( ptP)) {
|
|
||||||
// dPosFin = ( ptP - ptAx) * vtAxN ;
|
|
||||||
// Point3d ptPOnAx = ptAx + dPosFin * vtAxN ;
|
|
||||||
// // se non giace sull'asse, aggiungo il punto proiettato
|
|
||||||
// if ( ! AreSamePointApprox( ptP, ptPOnAx)) {
|
|
||||||
// double dU ;
|
|
||||||
// PL.GetLastU( dU) ;
|
|
||||||
// PL.AddUPoint( ( dU + 1), ptPOnAx) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // inverto la polilinea
|
|
||||||
// PL.Invert() ;
|
|
||||||
// // proietto l'ultimo punto (era il primo) sull'asse di rotazione
|
|
||||||
// if ( PL.GetLastPoint( ptP)) {
|
|
||||||
// dPosIni = ( ptP - ptAx) * vtAxN ;
|
|
||||||
// Point3d ptPOnAx = ptAx + dPosIni * vtAxN ;
|
|
||||||
// // se non giace sull'asse, aggiungo il punto proiettato
|
|
||||||
// if ( ! AreSamePointApprox( ptP, ptPOnAx)) {
|
|
||||||
// double dU ;
|
|
||||||
// PL.GetLastU( dU) ;
|
|
||||||
// PL.AddUPoint( ( dU + 1), ptPOnAx) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // decido se reinvertire la polilinea
|
|
||||||
// if ( dPosFin > dPosIni)
|
|
||||||
// PL.Invert() ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
// creo e setto la superficie trimesh
|
// creo e setto la superficie trimesh
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
@@ -264,42 +186,12 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
// limite minimo su tolleranza
|
// limite minimo su tolleranza
|
||||||
dLinTol = max( dLinTol, EPS_SMALL) ;
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
||||||
// calcolo la polilinea che approssima la curva
|
|
||||||
PolyLine PL ;
|
|
||||||
if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
||||||
return nullptr ;
|
|
||||||
|
|
||||||
// creo e setto la superficie bezier
|
// creo e setto la superficie bezier
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove))
|
if ( IsNull( pSbz) || ! pSbz->CreateByScrewing( pCurve, ptAx, vtAx, dAngRotDeg, dMove))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
//// se richiesti caps /// richiede la SurfCompo
|
|
||||||
//if ( bCapEnds) {
|
|
||||||
// // determino se la sezione è chiusa e piatta
|
|
||||||
// Plane3d plPlane ; double dArea ;
|
|
||||||
// bool bSectClosedFlat = PL.IsClosedAndFlat( plPlane, dArea, 10 * EPS_SMALL) ;
|
|
||||||
// // determino non sia una semplice rivoluzione
|
|
||||||
// bool bRevolved = ( abs( abs( dAngRotDeg) - ANG_FULL) < EPS_ANG_SMALL && abs( dMove) < EPS_SMALL) ;
|
|
||||||
// // se sezione chiusa e piatta e non rivoluzione, posso aggiungere i tappi
|
|
||||||
// if ( bSectClosedFlat && ! bRevolved) {
|
|
||||||
// // aggiungo il cap sull'inizio
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSTM->DoSewing( *pSci) ;
|
|
||||||
// // aggiungo il cap sulla fine
|
|
||||||
// Vector3d vtMove = vtAx ;
|
|
||||||
// vtMove.Normalize() ;
|
|
||||||
// vtMove *= dMove ;
|
|
||||||
// PL.Translate( vtMove) ;
|
|
||||||
// PL.Rotate( ptAx, vtAx, dAngRotDeg) ;
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// pSTM->DoSewing( *pSce) ;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
// se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
||||||
double dVol ;
|
double dVol ;
|
||||||
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
if ( pSbz->GetVolume( dVol) && dVol < 0)
|
||||||
@@ -308,342 +200,11 @@ GetSurfBezierByScrewing( const ICurve* pCurve, const Point3d& ptAx, const Vector
|
|||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSbz) ;
|
return Release( pSbz) ;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//static ISurfBezier*
|
|
||||||
//GetSurfBezierSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // verifico che la linea guida sia piana
|
|
||||||
// Plane3d plGuide ;
|
|
||||||
// if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// Vector3d vtNorm = plGuide.GetVersN() ;
|
|
||||||
// // determino se la guida è chiusa
|
|
||||||
// bool bGuideClosed = pGuide->IsClosed() ;
|
|
||||||
// // curve di offset
|
|
||||||
// OffsetCurve OffsCrvR ;
|
|
||||||
// if ( ! OffsCrvR.Make( pGuide, dDimH / 2, ICurve::OFF_FILLET) || OffsCrvR.GetCurveCount() == 0)
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurve> pCrvR( OffsCrvR.GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvR))
|
|
||||||
// return nullptr ;
|
|
||||||
// OffsetCurve OffsCrvL ;
|
|
||||||
// if ( ! OffsCrvL.Make( pGuide, -dDimH / 2, ICurve::OFF_FILLET) || OffsCrvL.GetCurveCount() == 0)
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurve> pCrvL( OffsCrvL.GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // costruisco le parti di superficie
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfTop))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
|
||||||
// if ( IsNull( pSrfBot))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfBot->Translate( -dDimV * vtNorm) ;
|
|
||||||
// pSrfBot->Invert() ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvR, -dDimV * vtNorm, false, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfRgt))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfRgt->Invert() ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfLft( GetSurfTriMeshByExtrusion( pCrvL, -dDimV * vtNorm, false, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfLft))
|
|
||||||
// return nullptr ;
|
|
||||||
// // unisco le parti
|
|
||||||
// PtrOwner<ISurfTriMesh> pSTM( Release( pSrfTop)) ;
|
|
||||||
// pSTM->DoSewing( *pSrfRgt) ;
|
|
||||||
// pSTM->DoSewing( *pSrfLft) ;
|
|
||||||
// pSTM->DoSewing( *pSrfBot) ;
|
|
||||||
// // salvo tolleranza lineare usata e imposto angolo per smooth
|
|
||||||
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
||||||
// pSTM->SetSmoothAngle( 20) ;
|
|
||||||
// // se guida aperta e tappi piatti
|
|
||||||
// if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
|
||||||
// // verifico che le due estremità siano chiuse e piatte
|
|
||||||
// POLYLINEVECTOR vPL ;
|
|
||||||
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
|
||||||
// return nullptr ;
|
|
||||||
// Plane3d plEnds ; double dArea ;
|
|
||||||
// if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // aggiungo il cap sull'inizio
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->Invert() ;
|
|
||||||
// pSTM->DoSewing( *pSci) ;
|
|
||||||
// // aggiungo il cap sulla fine
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// pSTM->DoSewing( *pSce) ;
|
|
||||||
// }
|
|
||||||
// // se altrimenti guida aperta e tappi arrotondati
|
|
||||||
// if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
|
||||||
// // step di rotazione per rispettare la tolleranza
|
|
||||||
// double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
|
||||||
// // aggiungo il cap sull'inizio
|
|
||||||
// Point3d ptStart ;
|
|
||||||
// pGuide->GetStartPoint( ptStart) ;
|
|
||||||
// Vector3d vtStart ;
|
|
||||||
// pGuide->GetStartDir( vtStart) ;
|
|
||||||
// vtStart.Rotate( vtNorm, 0, 1) ;
|
|
||||||
// PolyLine PLStart ;
|
|
||||||
// PLStart.AddUPoint( 0, ptStart) ;
|
|
||||||
// PLStart.AddUPoint( 1, ptStart + dDimH / 2 * vtStart) ;
|
|
||||||
// PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dDimV * vtNorm) ;
|
|
||||||
// PLStart.AddUPoint( 3, ptStart - dDimV * vtNorm) ;
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->Invert() ;
|
|
||||||
// pSTM->DoSewing( *pSci) ;
|
|
||||||
// // aggiungo il cap sulla fine
|
|
||||||
// Point3d ptEnd ;
|
|
||||||
// pGuide->GetEndPoint( ptEnd) ;
|
|
||||||
// Vector3d vtEnd ;
|
|
||||||
// pGuide->GetEndDir( vtEnd) ;
|
|
||||||
// vtEnd.Rotate( vtNorm, 0, -1) ;
|
|
||||||
// PolyLine PLEnd ;
|
|
||||||
// PLEnd.AddUPoint( 0, ptEnd) ;
|
|
||||||
// PLEnd.AddUPoint( 1, ptEnd + dDimH / 2 * vtEnd) ;
|
|
||||||
// PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dDimV * vtNorm) ;
|
|
||||||
// PLEnd.AddUPoint( 3, ptEnd - dDimV * vtNorm) ;
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// pSTM->DoSewing( *pSce) ;
|
|
||||||
// }
|
|
||||||
// // restituisco la superficie
|
|
||||||
// return Release( pSTM) ;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//static ISurfBezier*
|
|
||||||
//GetSurfBezierBeveledRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // metodo di calcolo impostato da USE_VORONOI
|
|
||||||
//
|
|
||||||
// // verifico che la linea guida sia piana
|
|
||||||
// Plane3d plGuide ;
|
|
||||||
// if ( ! pGuide->IsFlat( plGuide, false, 10 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // assegno la normale del piano
|
|
||||||
// Vector3d vtNorm = plGuide.GetVersN() ;
|
|
||||||
// // determino il punto centrale della sezione
|
|
||||||
// Point3d ptCen ;
|
|
||||||
// pGuide->GetStartPoint( ptCen) ;
|
|
||||||
// ptCen -= dDimV / 2 * vtNorm ;
|
|
||||||
// // determino se la guida è chiusa
|
|
||||||
// bool bGuideClosed = pGuide->IsClosed() ;
|
|
||||||
// // curve di offset
|
|
||||||
// const int NUM_OFFS = 4 ;
|
|
||||||
// OffsetCurve vOffsCrv[NUM_OFFS] ;
|
|
||||||
// double vDist[NUM_OFFS] = { dDimH / 2 - dBevelH, -dDimH / 2 + dBevelH, dDimH / 2, -dDimH / 2} ;
|
|
||||||
// bool bOk = true ;
|
|
||||||
// if ( ! USE_VORONOI) {
|
|
||||||
// future<bool> vRes[NUM_OFFS] ;
|
|
||||||
// for ( int i = 0 ; i < NUM_OFFS ; ++ i)
|
|
||||||
// vRes[i] = async( launch::async, &OffsetCurve::Make, &vOffsCrv[i], pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
|
||||||
// bool bOk = true ;
|
|
||||||
// int nFin = 0 ;
|
|
||||||
// while ( nFin < NUM_OFFS) {
|
|
||||||
// for ( int i = 0 ; i < NUM_OFFS ; ++ i) {
|
|
||||||
// if ( vRes[i].valid() && vRes[i].wait_for( chrono::nanoseconds{ 1}) == future_status::ready) {
|
|
||||||
// bOk = vRes[i].get() && bOk ;
|
|
||||||
// ++ nFin ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // se Voronoi non è possibile calcolare gli offset di una stessa curva in parallelo
|
|
||||||
// for ( int i = 0 ; i < NUM_OFFS && bOk ; ++ i)
|
|
||||||
// bOk = vOffsCrv[i].Make( pGuide, vDist[i], ICurve::OFF_FILLET) ;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if ( ! bOk ||
|
|
||||||
// vOffsCrv[0].GetCurveCount() == 0 || vOffsCrv[1].GetCurveCount() == 0 ||
|
|
||||||
// vOffsCrv[2].GetCurveCount() == 0 || vOffsCrv[3].GetCurveCount() == 0)
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurve> pCrvR( vOffsCrv[0].GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvR))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurve> pCrvL( vOffsCrv[1].GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvL))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ICurve> pCrvRb( vOffsCrv[2].GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvRb))
|
|
||||||
// return nullptr ;
|
|
||||||
// pCrvRb->Translate( - dBevelV * vtNorm) ;
|
|
||||||
// PtrOwner<ICurve> pCrvLb( vOffsCrv[3].GetLongerCurve()) ;
|
|
||||||
// if ( IsNull( pCrvLb))
|
|
||||||
// return nullptr ;
|
|
||||||
// pCrvLb->Translate( - dBevelV * vtNorm) ;
|
|
||||||
// // costruisco le parti di superficie
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfTop( GetSurfTriMeshRuled( pCrvR, pCrvL, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfTop))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfBot( pSrfTop->Clone()) ;
|
|
||||||
// if ( IsNull( pSrfBot))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfBot->Translate( -dDimV * vtNorm) ;
|
|
||||||
// pSrfBot->Invert() ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfTopR( GetSurfTriMeshRuled( pCrvRb, pCrvR, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfTopR))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfBotR( pSrfTopR->Clone()) ;
|
|
||||||
// if ( IsNull( pSrfBotR))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfBotR->Mirror( ptCen, vtNorm) ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfTopL( GetSurfTriMeshRuled( pCrvL, pCrvLb, ISurfTriMesh::RLT_MINDIST, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfTopL))
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfBotL( pSrfTopL->Clone()) ;
|
|
||||||
// if ( IsNull( pSrfBotL))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfBotL->Mirror( ptCen, vtNorm) ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfRgt( GetSurfTriMeshByExtrusion( pCrvRb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfRgt))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSrfRgt->Invert() ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSrfLft( GetSurfTriMeshByExtrusion( pCrvLb, ( -dDimV + 2 * dBevelV) * vtNorm, false, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSrfLft))
|
|
||||||
// return nullptr ;
|
|
||||||
// // unisco le parti
|
|
||||||
// int nBuckets = max( 4 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ;
|
|
||||||
// StmFromTriangleSoup stmSoup ;
|
|
||||||
// if ( ! stmSoup.Start( nBuckets))
|
|
||||||
// return nullptr ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfTop) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfTopR) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfTopL) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfRgt) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfLft) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfBotR) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfBotL) ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSrfBot) ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pSTM ;
|
|
||||||
// // se guida aperta e tappi piatti
|
|
||||||
// if ( ! bGuideClosed && nCapType == RSCAP_FLAT) {
|
|
||||||
// // completo unione e recupero la superficie risultante
|
|
||||||
// if ( ! stmSoup.End())
|
|
||||||
// return nullptr ;
|
|
||||||
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
||||||
// // preparo seconda zuppa di triangoli per inserire i tappi
|
|
||||||
// StmFromTriangleSoup stmCapSoup ;
|
|
||||||
// if ( ! stmCapSoup.Start( nBuckets))
|
|
||||||
// return nullptr ;
|
|
||||||
// // verifico che le due estremità siano chiuse e piatte
|
|
||||||
// POLYLINEVECTOR vPL ;
|
|
||||||
// if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2)
|
|
||||||
// return nullptr ;
|
|
||||||
// Plane3d plEnds ; double dArea ;
|
|
||||||
// if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL))
|
|
||||||
// return nullptr ;
|
|
||||||
// // calcolo il cap sull'inizio
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0]))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->Invert() ;
|
|
||||||
// // calcolo il cap sulla fine
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1]))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// // cucio i tappi all'estrusione
|
|
||||||
// if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce))
|
|
||||||
// return nullptr ;
|
|
||||||
// }
|
|
||||||
// // se altrimenti guida aperta e tappi arrotondati
|
|
||||||
// else if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) {
|
|
||||||
// // step di rotazione per rispettare il tipo o la tolleranza
|
|
||||||
// double dStepRotDeg = ( nCapType == RSCAP_BEVEL ? ANG_STRAIGHT / 4 : sqrt( 8 * dLinTol / dDimH) * RADTODEG) ;
|
|
||||||
// // aggiungo il cap sull'inizio
|
|
||||||
// Point3d ptStart ;
|
|
||||||
// pGuide->GetStartPoint( ptStart) ;
|
|
||||||
// Vector3d vtStart ;
|
|
||||||
// pGuide->GetStartDir( vtStart) ;
|
|
||||||
// vtStart.Rotate( vtNorm, 0, 1) ;
|
|
||||||
// PolyLine PLStart ;
|
|
||||||
// PLStart.AddUPoint( 0, ptStart) ;
|
|
||||||
// PLStart.AddUPoint( 1, ptStart + ( dDimH / 2 - dBevelH) * vtStart) ;
|
|
||||||
// PLStart.AddUPoint( 2, ptStart + dDimH / 2 * vtStart - dBevelV * vtNorm) ;
|
|
||||||
// PLStart.AddUPoint( 3, ptStart + dDimH / 2 * vtStart - ( dDimV - dBevelV) * vtNorm) ;
|
|
||||||
// PLStart.AddUPoint( 4, ptStart + ( dDimH / 2 - dBevelH) * vtStart - dDimV * vtNorm) ;
|
|
||||||
// PLStart.AddUPoint( 5, ptStart - dDimV * vtNorm) ;
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->Invert() ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSci) ;
|
|
||||||
// // aggiungo il cap sulla fine
|
|
||||||
// Point3d ptEnd ;
|
|
||||||
// pGuide->GetEndPoint( ptEnd) ;
|
|
||||||
// Vector3d vtEnd ;
|
|
||||||
// pGuide->GetEndDir( vtEnd) ;
|
|
||||||
// vtEnd.Rotate( vtNorm, 0, -1) ;
|
|
||||||
// PolyLine PLEnd ;
|
|
||||||
// PLEnd.AddUPoint( 0, ptEnd) ;
|
|
||||||
// PLEnd.AddUPoint( 1, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd) ;
|
|
||||||
// PLEnd.AddUPoint( 2, ptEnd + dDimH / 2 * vtEnd - dBevelV * vtNorm) ;
|
|
||||||
// PLEnd.AddUPoint( 3, ptEnd + dDimH / 2 * vtEnd - ( dDimV - dBevelV) * vtNorm) ;
|
|
||||||
// PLEnd.AddUPoint( 4, ptEnd + ( dDimH / 2 - dBevelH) * vtEnd - dDimV * vtNorm) ;
|
|
||||||
// PLEnd.AddUPoint( 5, ptEnd - dDimV * vtNorm) ;
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// stmSoup.AddSurfTriMesh( *pSce) ;
|
|
||||||
// // completo unione e recupero la superficie risultante
|
|
||||||
// if ( ! stmSoup.End())
|
|
||||||
// return nullptr ;
|
|
||||||
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
// // completo unione e recupero la superficie risultante
|
|
||||||
// if ( ! stmSoup.End())
|
|
||||||
// return nullptr ;
|
|
||||||
// pSTM.Set( stmSoup.GetSurf()) ;
|
|
||||||
// }
|
|
||||||
// // salvo tolleranza lineare usata e imposto angolo per smooth
|
|
||||||
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
||||||
// pSTM->SetSmoothAngle( 20) ;
|
|
||||||
// // restituisco la superficie
|
|
||||||
// return Release( pSTM) ;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfBezier*
|
|
||||||
//GetSurfBezierRectSwept( double dDimH, double dDimV, double dBevelH, double dBevelV, const ICurve* pGuide, int nCapType, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // verifica parametri
|
|
||||||
// if ( pGuide == nullptr || dBevelH > 0.4 * dDimH || dBevelV > 0.4 * dDimV)
|
|
||||||
// return nullptr ;
|
|
||||||
// // determino se sezione squadrata o con smusso
|
|
||||||
// bool bSharp = ( dBevelH < 100 * EPS_SMALL || dBevelV < 100 * EPS_SMALL) ;
|
|
||||||
// // eseguo
|
|
||||||
// if ( bSharp)
|
|
||||||
// return GetSurfBezierSharpRectSwept( dDimH, dDimV, pGuide, nCapType, dLinTol) ;
|
|
||||||
// else
|
|
||||||
// return GetSurfBezierBeveledRectSwept( dDimH, dDimV, dBevelH, dBevelV, pGuide, nCapType, dLinTol) ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfBezier*
|
ISurfBezier*
|
||||||
GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
|
GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtNorm, bool bCapEnds, double dLinTol)
|
||||||
{
|
{
|
||||||
//// determino se la sezione è chiusa
|
|
||||||
//bool bSectClosed = pSect->IsClosed() ;
|
|
||||||
//// determino se la guida è chiusa
|
|
||||||
//bool bGuideClosed = pGuide->IsClosed() ;
|
|
||||||
|
|
||||||
// riferimento all'inizio della linea guida
|
// riferimento all'inizio della linea guida
|
||||||
Frame3d frStart ;
|
Frame3d frStart ;
|
||||||
Point3d ptStart ;
|
Point3d ptStart ;
|
||||||
@@ -925,10 +486,6 @@ GetSurfBezierSweptInPlane( const ICurve* pSect, const ICurve* pGuide, const Vect
|
|||||||
ISurfBezier*
|
ISurfBezier*
|
||||||
GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
||||||
{
|
{
|
||||||
//// determino se la sezione è chiusa
|
|
||||||
//bool bSectClosed = pSect->IsClosed() ;
|
|
||||||
//// determino se la guida è chiusa
|
|
||||||
//bool bGuideClosed = pGuide->IsClosed() ;
|
|
||||||
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
|
// determino algoritmo da usare per calcolare i riferimenti lungo la curva
|
||||||
bool bRMF = vtAx.IsSmall() ;
|
bool bRMF = vtAx.IsSmall() ;
|
||||||
|
|
||||||
@@ -1052,11 +609,9 @@ GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//// per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
|
// per ogni Frame calcolato, la sezione va roto-traslata lungo la guida
|
||||||
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
int nSpanU = int( pCrvU->GetCurveCount()) ;
|
||||||
int nDegU = 9 ; // debug
|
int nDegU = 9 ; // debug
|
||||||
|
|
||||||
|
|
||||||
int nDegV = 3 ;
|
int nDegV = 3 ;
|
||||||
if ( bGuideIsPolyLine){
|
if ( bGuideIsPolyLine){
|
||||||
nDegV = 1 ;
|
nDegV = 1 ;
|
||||||
@@ -1125,191 +680,6 @@ GetSurfBezierSwept3d( const ICurve* pSect, const ICurve* pGuide, const Vector3d&
|
|||||||
return nullptr ;
|
return nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfBezier*
|
|
||||||
//GetSurfTriMeshSwept( const ICurve* pSect, const ICurve* pGuide, const Vector3d& vtAx,
|
|
||||||
// bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // verifica parametri
|
|
||||||
// if ( pSect == nullptr || pGuide == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
//
|
|
||||||
// bool bIsLine = false ;
|
|
||||||
// if ( pGuide->GetType() == CRV_LINE)
|
|
||||||
// bIsLine = true ;
|
|
||||||
// else {
|
|
||||||
// const CurveComposite* pCompo = GetBasicCurveComposite( pGuide) ;
|
|
||||||
// Point3d ptStart, ptEnd ;
|
|
||||||
// if ( pCompo != nullptr && pCompo->IsALine( 10 * EPS_SMALL, ptStart, ptEnd))
|
|
||||||
// bIsLine = true ;
|
|
||||||
// }
|
|
||||||
// // se la guida è piana
|
|
||||||
// Plane3d plGuide ;
|
|
||||||
// if ( pGuide->IsFlat( plGuide, bIsLine, 10 * EPS_SMALL))
|
|
||||||
// return GetSurfBezierSweptInPlane( pSect, pGuide, plGuide.GetVersN(), bCapEnds, dLinTol) ;
|
|
||||||
//
|
|
||||||
// // altrimenti swept 3d
|
|
||||||
// return GetSurfBezierSwept3d( pSect, pGuide, vtAx, bCapEnds, dLinTol) ;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfBezier*
|
|
||||||
//GetSurfBezierSwept( const ISurfFlatRegion* pSfrSect, const ICurve* pGuide, const Vector3d& vtAx,
|
|
||||||
// bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // verifica dei parametri
|
|
||||||
// if ( pSfrSect == nullptr || pGuide == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
//
|
|
||||||
// // predispongo collettore superfici componenti
|
|
||||||
// StmFromTriangleSoup StmSoup ;
|
|
||||||
// StmSoup.Start() ;
|
|
||||||
//
|
|
||||||
// // per ogni loop della superficie, creo una Swept
|
|
||||||
// for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
|
|
||||||
// for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
|
|
||||||
// // recupero il loop
|
|
||||||
// PtrOwner<ICurve> pCrvLoop( pSfrSect->GetLoop( nC, nL)) ;
|
|
||||||
// if ( IsNull( pCrvLoop) || ! pCrvLoop->IsValid())
|
|
||||||
// return nullptr ;
|
|
||||||
// // creo la Trimesh Swept
|
|
||||||
// PtrOwner<ISurfTriMesh> pStmLoopSwept( GetSurfTriMeshSwept( pCrvLoop, pGuide, vtAx, false, dLinTol)) ;
|
|
||||||
// if ( IsNull( pStmLoopSwept) || ! pStmLoopSwept->IsValid())
|
|
||||||
// return nullptr ;
|
|
||||||
// // aggiungo la Swept ricavata al risultato finale ( come triangoli )
|
|
||||||
// StmSoup.AddSurfTriMesh( *pStmLoopSwept) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // Recupero la superficie
|
|
||||||
// if ( ! StmSoup.End())
|
|
||||||
// return nullptr ;
|
|
||||||
// PtrOwner<ISurfTriMesh> pStmSwept( StmSoup.GetSurf()) ;
|
|
||||||
// if ( IsNull( pStmSwept))
|
|
||||||
// return nullptr ;
|
|
||||||
//
|
|
||||||
// // se rischiesta chiusura...
|
|
||||||
// // Controllo solo che la guida non sia chiusa, la sezione derivando da una Flatregion è sempre chiusa
|
|
||||||
// if ( bCapEnds && ! pGuide->IsClosed()) {
|
|
||||||
// // recupero i loop all'inizio (dalla regione e apportunamente approssimati)
|
|
||||||
// POLYLINEVECTOR vPLi ;
|
|
||||||
// for ( int nC = 0 ; nC < pSfrSect->GetChunkCount() ; ++ nC) {
|
|
||||||
// for ( int nL = 0 ; nL < pSfrSect->GetLoopCount( nC) ; ++ nL) {
|
|
||||||
// vPLi.emplace_back() ;
|
|
||||||
// if ( ! pSfrSect->ApproxLoopWithLines( nC, nL, dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, vPLi.back()))
|
|
||||||
// return nullptr ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // creo il cap sull'inizio e lo attacco alla swept ( è già in posizione giusta)
|
|
||||||
// PtrOwner<ISurfTriMesh> pSci( CreateSurfTriMesh()) ;
|
|
||||||
// if ( ! pSci->CreateByRegion( vPLi))
|
|
||||||
// return nullptr ;
|
|
||||||
// pStmSwept->DoSewing( *pSci) ;
|
|
||||||
// // recupero i loops alla fine
|
|
||||||
// POLYLINEVECTOR vPLe ;
|
|
||||||
// if ( ! pStmSwept->GetLoops( vPLe))
|
|
||||||
// return nullptr ;
|
|
||||||
// // creo la superficie alla fine e la attacco
|
|
||||||
// PtrOwner<ISurfTriMesh> pSce( CreateSurfTriMesh()) ;
|
|
||||||
// if ( ! pSce->CreateByRegion( vPLe))
|
|
||||||
// return nullptr ;
|
|
||||||
// // attacco la superficie finale alla swept
|
|
||||||
// pSce->Invert() ;
|
|
||||||
// pStmSwept->DoSewing( *pSce) ;
|
|
||||||
// }
|
|
||||||
// // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
||||||
// double dVol ;
|
|
||||||
// if ( pStmSwept->GetVolume( dVol) && dVol < 0)
|
|
||||||
// pStmSwept->Invert() ;
|
|
||||||
//
|
|
||||||
// return Release( pStmSwept) ;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
////-------------------------------------------------------------------------------
|
|
||||||
//ISurfBezier*
|
|
||||||
//GetSurfBezierTransSwept( const ICurve* pSect, const ICurve* pGuide, bool bCapEnds, double dLinTol) // DA SISTEMARE - ancora copia della versione stm, cambia solo il nome della funzione//////////////////////
|
|
||||||
//{
|
|
||||||
// // verifica parametri
|
|
||||||
// if ( pSect == nullptr || pGuide == nullptr)
|
|
||||||
// return nullptr ;
|
|
||||||
// // determino se la sezione è chiusa
|
|
||||||
// bool bSectClosed = pSect->IsClosed() ;
|
|
||||||
// // punto iniziale della sezione e vettore a inizio guida
|
|
||||||
// Point3d ptStart ;
|
|
||||||
// if ( ! pSect->GetStartPoint( ptStart))
|
|
||||||
// return nullptr ;
|
|
||||||
// Point3d ptGuide ;
|
|
||||||
// if ( ! pGuide->GetStartPoint( ptGuide))
|
|
||||||
// return nullptr ;
|
|
||||||
// Vector3d vtDelta = ptStart - ptGuide ;
|
|
||||||
// // calcolo la polilinea che approssima la guida
|
|
||||||
// PolyLine PLG ;
|
|
||||||
// if ( ! pGuide->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLG))
|
|
||||||
// return nullptr ;
|
|
||||||
// // determino se la guida è chiusa
|
|
||||||
// bool bGuideClosed = PLG.IsClosed() ;
|
|
||||||
// // calcolo la superficie
|
|
||||||
// PtrOwner<SurfTriMesh> pSTM( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSTM))
|
|
||||||
// return nullptr ;
|
|
||||||
// // salvo tolleranza lineare usata
|
|
||||||
// pSTM->SetLinearTolerance( dLinTol) ;
|
|
||||||
// // superficie swept
|
|
||||||
// PtrOwner<ICurve> pPrevCrv ;
|
|
||||||
// Point3d ptP ;
|
|
||||||
// bool bPoint = PLG.GetFirstPoint( ptP) ;
|
|
||||||
// while ( bPoint) {
|
|
||||||
// // nuova curva
|
|
||||||
// PtrOwner<ICurve> pCurrCrv( pSect->Clone()) ;
|
|
||||||
// if ( IsNull( pCurrCrv))
|
|
||||||
// return nullptr ;
|
|
||||||
// pCurrCrv->Translate( ptP - ptStart + vtDelta) ;
|
|
||||||
// // se esiste la curva precedente, costruisco la rigata (di tipo minima distanza)
|
|
||||||
// if ( ! IsNull( pPrevCrv)) {
|
|
||||||
// PtrOwner<ISurfTriMesh> pSr( GetSurfTriMeshRuled( pPrevCrv, pCurrCrv, ISurfTriMesh::RLT_ISOPAR, dLinTol)) ;
|
|
||||||
// if ( IsNull( pSr))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSTM->DoSewing( *pSr) ;
|
|
||||||
// }
|
|
||||||
// // salvo la curva come prossima precedente
|
|
||||||
// pPrevCrv.Set( pCurrCrv) ;
|
|
||||||
// // prossimo punto
|
|
||||||
// bPoint = PLG.GetNextPoint( ptP) ;
|
|
||||||
// }
|
|
||||||
// // se richiesti caps e sezione chiusa e guida aperta
|
|
||||||
// if ( bCapEnds && bSectClosed && ! bGuideClosed) {
|
|
||||||
// // calcolo la polilinea che approssima la sezione
|
|
||||||
// PolyLine PLS ;
|
|
||||||
// if ( ! pSect->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PLS))
|
|
||||||
// return nullptr ;
|
|
||||||
// // verifico che la sezione sia chiusa e piatta
|
|
||||||
// Plane3d plSect ; double dArea ;
|
|
||||||
// if ( PLS.IsClosedAndFlat( plSect, dArea, 100 * EPS_SMALL)) {
|
|
||||||
// // aggiungo il cap sull'inizio
|
|
||||||
// PtrOwner<SurfTriMesh> pSci( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSci) || ! pSci->CreateByFlatContour( PLS))
|
|
||||||
// return nullptr ;
|
|
||||||
// pSci->Invert() ;
|
|
||||||
// Point3d ptGi ; PLG.GetFirstPoint( ptGi) ;
|
|
||||||
// pSci->Translate( ptGi - ptStart + vtDelta) ;
|
|
||||||
// pSTM->DoSewing( *pSci) ;
|
|
||||||
// // aggiungo il cap sulla fine
|
|
||||||
// PtrOwner<SurfTriMesh> pSce( CreateBasicSurfTriMesh()) ;
|
|
||||||
// if ( IsNull( pSce) || ! pSce->CreateByFlatContour( PLS))
|
|
||||||
// return nullptr ;
|
|
||||||
// Point3d ptGe ; PLG.GetLastPoint( ptGe) ;
|
|
||||||
// pSce->Translate( ptGe - ptStart + vtDelta) ;
|
|
||||||
// pSTM->DoSewing( *pSce) ;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // se superficie risultante chiusa, verifico che la normale sia verso l'esterno
|
|
||||||
// double dVol ;
|
|
||||||
// if ( pSTM->GetVolume( dVol) && dVol < 0)
|
|
||||||
// pSTM->Invert() ;
|
|
||||||
// // restituisco la superficie
|
|
||||||
// return Release( pSTM) ;
|
|
||||||
//}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
ISurfBezier*
|
ISurfBezier*
|
||||||
GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
||||||
@@ -1317,16 +687,12 @@ GetSurfBezierRuled( const Point3d& ptP, const ICurve* pCurve, double dLinTol)
|
|||||||
// verifica parametri
|
// verifica parametri
|
||||||
if ( &ptP == nullptr || pCurve == nullptr)
|
if ( &ptP == nullptr || pCurve == nullptr)
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
//// calcolo la polilinea che approssima la curva
|
|
||||||
//PolyLine PL ;
|
|
||||||
//if ( ! pCurve->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, ICurve::APL_SPECIAL, PL))
|
|
||||||
// return nullptr ;
|
|
||||||
// creo e setto la superficie trimesh
|
// creo e setto la superficie trimesh
|
||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve))
|
if ( IsNull( pSbz) || ! pSbz->CreateByPointCurve( ptP, pCurve))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
//// salvo tolleranza lineare usata
|
|
||||||
//pSbz->SetLinearTolerance( dLinTol) ;
|
|
||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSbz) ;
|
return Release( pSbz) ;
|
||||||
}
|
}
|
||||||
@@ -1343,7 +709,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
|
|||||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||||
if ( pCurve1->GetType() != CRV_BEZIER)
|
if ( pCurve1->GetType() != CRV_BEZIER)
|
||||||
pCC1->AddCurve( CurveToBezierCurve( pCurve1, true, false)) ;
|
pCC1->AddCurve( CurveToBezierCurve( pCurve1, 3, false)) ;
|
||||||
else
|
else
|
||||||
pCC1->AddCurve( pCurve1->Clone()) ;
|
pCC1->AddCurve( pCurve1->Clone()) ;
|
||||||
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
||||||
@@ -1352,7 +718,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
|
|||||||
// se la curva è già una bezier singola la tengo, sennò la converto
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||||
if ( pCurve2->GetType() != CRV_BEZIER)
|
if ( pCurve2->GetType() != CRV_BEZIER)
|
||||||
pCC2->AddCurve( CurveToBezierCurve( pCurve2, true, false)) ;
|
pCC2->AddCurve( CurveToBezierCurve( pCurve2, 3, false)) ;
|
||||||
else
|
else
|
||||||
pCC2->AddCurve( pCurve2->Clone()) ;
|
pCC2->AddCurve( pCurve2->Clone()) ;
|
||||||
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
||||||
@@ -1362,8 +728,79 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
|
|||||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType))
|
if ( IsNull( pSbz) || ! pSbz->CreateByTwoCurves( pCC1, pCC2, nType))
|
||||||
return nullptr ;
|
return nullptr ;
|
||||||
//// salvo tolleranza lineare usata
|
|
||||||
//pSbz->SetLinearTolerance( dLinTol) ;
|
// restituisco la superficie
|
||||||
|
return Release( pSbz) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
ISurfBezier*
|
||||||
|
GetSurfBezierRuledSmooth( const ICurve* pCurve1, const ICurve* pCurve2, BIPNTVECTOR& vSyncLines, double dSampleLen)
|
||||||
|
{
|
||||||
|
// verifica parametri
|
||||||
|
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
||||||
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
|
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||||
|
if ( pCurve1->GetType() != CRV_BEZIER)
|
||||||
|
pCC1->AddCurve( CurveToBezierCurve( pCurve1, 3, false)) ;
|
||||||
|
else
|
||||||
|
pCC1->AddCurve( pCurve1->Clone()) ;
|
||||||
|
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
|
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||||
|
if ( pCurve2->GetType() != CRV_BEZIER)
|
||||||
|
pCC2->AddCurve( CurveToBezierCurve( pCurve2, 3, false)) ;
|
||||||
|
else
|
||||||
|
pCC2->AddCurve( pCurve2->Clone()) ;
|
||||||
|
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creo e setto la superficie trimesh
|
||||||
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
|
if ( IsNull( pSbz) || ! pSbz->CreateSmoothRuledByTwoCurves( pCC1, pCC2, dSampleLen, vSyncLines))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// restituisco la superficie
|
||||||
|
return Release( pSbz) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------
|
||||||
|
ISurfBezier*
|
||||||
|
GetSurfBezierRuledGuided( const ICurve* pCurve1, const ICurve* pCurve2, const BIPNTVECTOR& vCrv, double dLinTol)
|
||||||
|
{
|
||||||
|
// verifica parametri
|
||||||
|
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// dLinTol servirà quando ci sarà la funzione ApproxWithCurveBezier
|
||||||
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
|
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||||
|
if ( pCurve1->GetType() != CRV_BEZIER)
|
||||||
|
pCC1->AddCurve( CurveToBezierCurve( pCurve1, 3, false)) ;
|
||||||
|
else
|
||||||
|
pCC1->AddCurve( pCurve1->Clone()) ;
|
||||||
|
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// se la curva è già una bezier singola la tengo, sennò la converto
|
||||||
|
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||||
|
if ( pCurve2->GetType() != CRV_BEZIER)
|
||||||
|
pCC2->AddCurve( CurveToBezierCurve( pCurve2, 3, false)) ;
|
||||||
|
else
|
||||||
|
pCC2->AddCurve( pCurve2->Clone()) ;
|
||||||
|
if ( IsNull( pCC2) || ! pCC2->IsValid())
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
|
// creo e setto la superficie trimesh
|
||||||
|
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||||
|
if ( IsNull( pSbz) || ! pSbz->CreateByIsoParamSet( pCC1, pCC2, vCrv))
|
||||||
|
return nullptr ;
|
||||||
|
|
||||||
// restituisco la superficie
|
// restituisco la superficie
|
||||||
return Release( pSbz) ;
|
return Release( pSbz) ;
|
||||||
}
|
}
|
||||||
|
|||||||
+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
|
||||||
|
|||||||
+1114
-535
File diff suppressed because it is too large
Load Diff
+13
-6
@@ -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
|
|
||||||
cCol.Set( vnVal[0], vnVal[1], vnVal[2], vnVal[3]) ;
|
|
||||||
return true ;
|
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 ;
|
||||||
|
}
|
||||||
|
|||||||
+311
-65
@@ -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,7 +45,7 @@ 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) ;
|
||||||
@@ -69,9 +77,13 @@ NurbsSurfaceCanonicalize( SNurbsSurfData& snData)
|
|||||||
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,13 +92,13 @@ 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) ;
|
||||||
@@ -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
|
||||||
if ( nDir == 0)
|
//debug
|
||||||
pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
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
|
else
|
||||||
pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
dLastParam1 = vICCI[j].IciB[k].dU ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int c = 0 ;
|
||||||
|
while ( c < ssize( vMaskClass) - 1 && abs( vMaskClass[c].dParS - dLastParam1) > EPS_PARAM)
|
||||||
|
++c ;
|
||||||
|
|
||||||
// prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
|
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)
|
||||||
|
dCoeffX = SBZ_TREG_COEFF / dLenStrip ;
|
||||||
|
else
|
||||||
|
dCoeffY = SBZ_TREG_COEFF / dLenStrip ;
|
||||||
|
for( int i = 0 ; i < ssize( vCrvStrip); ++i) {
|
||||||
|
if( ! IsNull( vCrvStrip[i]))
|
||||||
|
vCrvStrip[i]->Scale( GLOB_FRM, dCoeffX, dCoeffY, 1) ;
|
||||||
|
else
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 ;
|
Point3d pt ;
|
||||||
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 ;
|
Vector3d vtJoin ;
|
||||||
if ( nDir == 0)
|
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) ;
|
vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
|
||||||
else
|
}
|
||||||
|
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) ;
|
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 ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
else
|
||||||
pRescaledSfr.Set( pSfr_copy) ;
|
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 ( ! vUniformedCurves.empty()) {
|
||||||
|
#if SAVEMKUNIF_CRVS
|
||||||
|
//debug
|
||||||
|
vector<IGeoObj*> vGeo ;
|
||||||
|
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()) {
|
if ( ! IsNull( pRescaledSfr) && pRescaledSfr->IsValid()) {
|
||||||
if ( bRetry)
|
|
||||||
pRescaledSfr->Offset( -10 * EPS_SMALL, ICurve::OFF_CHAMFER) ; // contro OFFSET
|
|
||||||
delete pSfr ;
|
delete pSfr ;
|
||||||
pSfr = Release( pRescaledSfr) ;
|
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) ;
|
||||||
|
|||||||
+2917
-590
File diff suppressed because it is too large
Load Diff
+23
-27
@@ -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,8 +67,7 @@ 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)
|
||||||
@@ -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 ;
|
||||||
@@ -231,15 +227,15 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
|||||||
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 ;
|
||||||
|
|||||||
+173
-19
@@ -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,7 +369,6 @@ 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) ;
|
||||||
@@ -367,10 +382,6 @@ SurfFlatRegion::MyAddIntLoop( ICurve* pCrv, int nChunk)
|
|||||||
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 ;
|
||||||
@@ -1552,6 +1572,140 @@ SurfFlatRegion::GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion&
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
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 ;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
SurfFlatRegion::CalcVoronoiObject() const
|
SurfFlatRegion::CalcVoronoiObject() const
|
||||||
|
|||||||
@@ -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) ;
|
||||||
|
|||||||
+329
-39
@@ -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,13 +1203,17 @@ 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.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
vPL.emplace_back( PL) ;
|
vPL.emplace_back( PL) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1220,7 +1257,7 @@ 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)
|
||||||
@@ -1228,8 +1265,11 @@ SurfTriMesh::GetSilhouette( const Plane3d& plPlane, 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 ;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1242,13 +1282,17 @@ 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.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
vPL.emplace_back( PL) ;
|
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 ( AdjustVert) {
|
||||||
if ( ! AdjustVertices())
|
if ( ! AdjustVertices())
|
||||||
return false ;
|
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) {
|
||||||
@@ -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)
|
||||||
@@ -3101,14 +3150,50 @@ SurfTriMesh::DoCompacting( double dTol)
|
|||||||
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]) {
|
||||||
|
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) ;
|
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) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DoCompacting() ;
|
// rimuovo i triangoli resi invalidi dalla scalatura
|
||||||
|
bool bOk = 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 ;
|
||||||
|
}
|
||||||
|
|||||||
+23
-4
@@ -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,6 +322,8 @@ 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 ;
|
||||||
@@ -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
|
||||||
|
|||||||
+30
-71
@@ -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,8 +502,6 @@ 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
|
||||||
@@ -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
|
||||||
@@ -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 ;
|
||||||
@@ -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
|
||||||
@@ -1383,6 +1338,10 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
|||||||
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 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
|
// Se i triangoli sono sovrapposti
|
||||||
TRIA3DVECTOR vTriaAB ;
|
TRIA3DVECTOR vTriaAB ;
|
||||||
Point3d ptTempA, ptTempB ;
|
Point3d ptTempA, ptTempB ;
|
||||||
|
|||||||
+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) ;
|
||||||
|
}
|
||||||
+191
-18
@@ -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 ;
|
||||||
@@ -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 ||
|
|
||||||
dPos2 < EPS_SMALL || dPos2 > ( ptVertB - ptVertA).Len() - EPS_SMALL)
|
|
||||||
return false ;
|
return false ;
|
||||||
|
if ( dPos1 < - EPS_SMALL || dPos1 > ( ptSegEn - ptSegSt).Len() + EPS_SMALL ||
|
||||||
|
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,12 +188,15 @@ 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]) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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())
|
||||||
@@ -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 ;
|
||||||
@@ -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,7 +23,8 @@
|
|||||||
#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
|
||||||
@@ -33,14 +34,20 @@ struct PairHashInt64 {
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
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 ;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
|
||||||
// riordino le intersezioni per lato in senso antiorario dal top
|
// 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
|
// 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)
|
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} ;
|
||||||
@@ -75,7 +82,8 @@ 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
|
||||||
@@ -135,18 +143,18 @@ struct Inters {
|
|||||||
( 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,39 +261,41 @@ 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, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
|
bool BuildTree( double dLinTol = LIN_TOL_STD,
|
||||||
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
|
double dSideMin = 1, // è la minima lunghezza del lato di una cella
|
||||||
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
|
double dSideMax = INFINITO) ; // è la massima dimensione di un triangolo della trimesh
|
||||||
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops) ;
|
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, std::vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops, bool bUpdateEdges) ;
|
||||||
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) const ; // restituisce le celle foglie che sono adiacenti al lato top
|
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 GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
||||||
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
||||||
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right
|
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs, DBLDBL ddInt = DBLDBL(0,0)) 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
|
||||||
@@ -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.
|
||||||
} ;
|
} ;
|
||||||
+51
-32
@@ -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 {
|
else {
|
||||||
// elimino gli ultimi due triangoli che sono appena stati flippati e ricalcolo adiacenza del triangolo
|
vChain.emplace_back( nTCurr) ;
|
||||||
// precedente
|
vChainEdges.emplace_back( nECurr) ;
|
||||||
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) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// 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
|
||||||
|
|||||||
@@ -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
+532
-136
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,6 +227,15 @@ 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) ;
|
||||||
@@ -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) ;
|
||||||
|
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) ;
|
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)
|
||||||
|
|||||||
+19
-138
@@ -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.
|
||||||
@@ -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,15 +2982,15 @@ 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) {
|
||||||
@@ -3123,8 +3003,8 @@ 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) {
|
||||||
@@ -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
|
||||||
|
|||||||
+211
-35
@@ -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>
|
||||||
@@ -27,7 +28,7 @@ using namespace std ;
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
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)
|
||||||
@@ -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
|
||||||
@@ -115,6 +128,7 @@ VolZmap::Create( const Point3d& ptO, double dDimX, double dDimY, double dDimZ, d
|
|||||||
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 ;
|
||||||
@@ -705,14 +848,17 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
BBox3d SurfBBox ;
|
BBox3d SurfBBox ;
|
||||||
Surf.GetLocalBBox( SurfBBox) ;
|
Surf.GetLocalBBox( SurfBBox) ;
|
||||||
|
|
||||||
|
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
|
||||||
|
// quindi espandiamo il bounding box per ovviare al problema.
|
||||||
|
if ( dExtraBox > EPS_ZERO)
|
||||||
|
SurfBBox.Expand( dExtraBox) ;
|
||||||
|
else
|
||||||
|
dExtraBox = 0 ;
|
||||||
|
|
||||||
// Determino i punti estremi del bounding box
|
// Determino i punti estremi del bounding box
|
||||||
Point3d ptMapOrig, ptMapEnd ;
|
Point3d ptMapOrig, ptMapEnd ;
|
||||||
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
|
SurfBBox.GetMinMax( ptMapOrig, ptMapEnd) ;
|
||||||
|
|
||||||
// Il dexel se parte da un triangolo della trimesh può non trovare l'intersezione,
|
|
||||||
// quindi espandiamo il bounding box per ovviare al problema.
|
|
||||||
SurfBBox.Expand( 100 * EPS_SMALL, 100 * EPS_SMALL, 100 * EPS_SMALL) ;
|
|
||||||
|
|
||||||
// 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,46 +925,50 @@ 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) ;
|
||||||
|
|
||||||
|
// Standarda è multithread
|
||||||
|
constexpr bool MULTITHREAD = true ;
|
||||||
|
if ( MULTITHREAD) {
|
||||||
|
|
||||||
// Numero massimo di thread
|
// Numero massimo di thread
|
||||||
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
|
int nThreadMax = max( 1, int( thread::hardware_concurrency()) - 1) ;
|
||||||
vector< future<bool>> vRes ;
|
vector< future<bool>> vRes ;
|
||||||
vRes.resize( nThreadMax) ;
|
vRes.resize( nThreadMax) ;
|
||||||
if ( m_nNx[g] > m_nNy[g]) {
|
if ( m_nNx[nG] > m_nNy[nG]) {
|
||||||
int nDexNum = m_nNx[g] / nThreadMax ;
|
int nDexNum = m_nNx[nG] / nThreadMax ;
|
||||||
int nRemainder = m_nNx[g] % nThreadMax ;
|
int nRemainder = m_nNx[nG] % nThreadMax ;
|
||||||
int nInfI = 0 ;
|
int nInfI = 0 ;
|
||||||
int nSupI = 0 ;
|
int nSupI = 0 ;
|
||||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||||
nInfI = nSupI ;
|
nInfI = nSupI ;
|
||||||
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
nSupI = nInfI + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||||
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, g,
|
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
|
||||||
nInfI, nSupI, 0, m_nNy[g], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
|
nInfI, nSupI, 0, m_nNy[nG], ref( vtLen), ref( ptMapOrig), ref( Surf), ref( intPLSTM)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int nDexNum = m_nNy[g] / nThreadMax ;
|
int nDexNum = m_nNy[nG] / nThreadMax ;
|
||||||
int nRemainder = m_nNy[g] % nThreadMax ;
|
int nRemainder = m_nNy[nG] % nThreadMax ;
|
||||||
int nInfJ = 0 ;
|
int nInfJ = 0 ;
|
||||||
int nSupJ = 0 ;
|
int nSupJ = 0 ;
|
||||||
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
for ( int nThread = 0 ; nThread < nThreadMax ; ++ nThread) {
|
||||||
nInfJ = nSupJ ;
|
nInfJ = nSupJ ;
|
||||||
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
nSupJ = nInfJ + ( nThread < nRemainder ? nDexNum + 1 : nDexNum) ;
|
||||||
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, g,
|
vRes[nThread] = async( launch::async, &VolZmap::CreateMapPart, this, nG,
|
||||||
0, m_nNx[g], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
|
0, m_nNx[nG], nInfJ, nSupJ, ref( vtLen), ref( ptMapOrig), ref( Surf),ref( intPLSTM)) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -816,16 +985,23 @@ VolZmap::CreateFromTriMesh( const ISurfTriMesh& Surf, double dStep, bool bTriDex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !!!! 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 ;
|
||||||
|
|||||||
+72
-13
@@ -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,6 +951,10 @@ VolZmap::UpdateTripleMapGraphics( void) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Standard è multithread
|
||||||
|
constexpr bool MULTITHREAD = true ;
|
||||||
|
if ( MULTITHREAD) {
|
||||||
|
|
||||||
// Calcolo i triangoli sui blocchi
|
// Calcolo i triangoli sui blocchi
|
||||||
int nBlockUpdated = 0 ;
|
int nBlockUpdated = 0 ;
|
||||||
vector< future<bool>> vRes ;
|
vector< future<bool>> vRes ;
|
||||||
@@ -942,6 +977,18 @@ VolZmap::UpdateTripleMapGraphics( void) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Calcolo i triangoli sui blocchi
|
||||||
|
bool bOk = true ;
|
||||||
|
for ( int i = 0 ; i < m_nNumBlock ; ++ i) {
|
||||||
|
// Se il blocco deve essere processato
|
||||||
|
if ( m_BlockToUpdate[i]) {
|
||||||
|
// processo ...
|
||||||
|
bOk = ExtMarchingCubes( i, vVoxContainerVec[i]) && bOk ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Regolarizzo la catena
|
// Regolarizzo la catena
|
||||||
RegulateFeaturesChain( vVoxContainerVec) ;
|
RegulateFeaturesChain( vVoxContainerVec) ;
|
||||||
@@ -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
+2064
-310
File diff suppressed because it is too large
Load Diff
+49
-15
@@ -21,6 +21,7 @@
|
|||||||
#include "Voronoi.h"
|
#include "Voronoi.h"
|
||||||
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
||||||
#include "/EgtDev/Include/EGkChainCurves.h"
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
|
#include "/EgtDev/Extern/vroni/Include/vroni_object.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
@@ -625,14 +626,10 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
|
|||||||
if ( vResult[i]->IsClosed())
|
if ( vResult[i]->IsClosed())
|
||||||
AdjustOffsetStart( vResult[i]) ;
|
AdjustOffsetStart( vResult[i]) ;
|
||||||
|
|
||||||
// sistemo i raccordi
|
// identifico i raccordi
|
||||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0)
|
||||||
IdentifyFillets( vResult[i], dOffs) ;
|
IdentifyFillets( vResult[i], dOffs) ;
|
||||||
AdjustCurveFillets( vResult[i], dOffs, nType) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// porto nel frame globale
|
|
||||||
vResult[i]->ToGlob( m_Frame) ;
|
|
||||||
// unisco le parti allineate
|
// unisco le parti allineate
|
||||||
vResult[i]->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
vResult[i]->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
||||||
// aggiungo al vettore finale
|
// aggiungo al vettore finale
|
||||||
@@ -642,6 +639,17 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
|
|||||||
delete( pCrv) ;
|
delete( pCrv) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aggiusto i raccordi
|
||||||
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0)
|
||||||
|
if ( ! AdjustCurveFillets( vOffs, dOffs, nType)) {
|
||||||
|
vOffs.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// porto nel frame globale
|
||||||
|
for ( int i = 0 ; i < int( vOffs.size()) ; i++)
|
||||||
|
vOffs[i]->ToGlob( m_Frame) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,9 +828,18 @@ Voronoi::CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs)
|
|||||||
Point3d ptTemp ;
|
Point3d ptTemp ;
|
||||||
Vector3d vtDir ;
|
Vector3d vtDir ;
|
||||||
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
|
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
|
||||||
return false ;
|
continue ;
|
||||||
vtDir.Normalize() ;
|
vtDir.Normalize() ;
|
||||||
|
|
||||||
|
// verifico che il punto non sia già stato trovato
|
||||||
|
bool bAdd = true ;
|
||||||
|
for ( int j = 0 ; j < ssize( vResult) ; j ++) {
|
||||||
|
if ( AreSamePointApprox( vResult[j].first, pt)) {
|
||||||
|
bAdd = false ;
|
||||||
|
break ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( bAdd)
|
||||||
vResult.emplace_back( pt, vtDir) ;
|
vResult.emplace_back( pt, vtDir) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -840,7 +857,8 @@ Voronoi::CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bool bSquareMids)
|
Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bool bSquareMids,
|
||||||
|
bool bMergeOnlySameProps)
|
||||||
{
|
{
|
||||||
vCrvs.clear() ;
|
vCrvs.clear() ;
|
||||||
|
|
||||||
@@ -863,11 +881,10 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
|
|||||||
if ( dOffs > EPS_SMALL)
|
if ( dOffs > EPS_SMALL)
|
||||||
pCrvOffs->Invert() ;
|
pCrvOffs->Invert() ;
|
||||||
|
|
||||||
// sistemo i raccordi
|
// identifico i raccordi da modificare
|
||||||
if ( bClosed && bSquareMids) {
|
if ( bClosed && bSquareMids) {
|
||||||
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
||||||
IdentifyFillets( pCrvOffs, dOffs) ;
|
IdentifyFillets( pCrvOffs, dOffs) ;
|
||||||
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
|
||||||
}
|
}
|
||||||
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
||||||
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
||||||
@@ -880,17 +897,25 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
|
|||||||
else
|
else
|
||||||
pCrvOffs->SetCurveTempParam( j, 0) ;
|
pCrvOffs->SetCurveTempParam( j, 0) ;
|
||||||
}
|
}
|
||||||
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// porto nel frame globale
|
|
||||||
pCrvOffs->ToGlob( m_Frame) ;
|
|
||||||
// unisco le parti allineate
|
// unisco le parti allineate
|
||||||
pCrvOffs->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
pCrvOffs->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, bMergeOnlySameProps) ;
|
||||||
// aggiungo al vettore finale
|
// aggiungo al vettore finale
|
||||||
vCrvs.emplace_back( pCrvOffs) ;
|
vCrvs.emplace_back( pCrvOffs) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sistemo i raccordi
|
||||||
|
if ( bSquareMids || bSquareEnds)
|
||||||
|
if ( ! AdjustCurveFillets( vCrvs, dOffs, ICurve::OFF_EXTEND)) {
|
||||||
|
vCrvs.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// porto nel frame globale
|
||||||
|
for ( int i = 0 ; i < int( vCrvs.size()) ; i++)
|
||||||
|
vCrvs[i]->ToGlob( m_Frame) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -998,9 +1023,18 @@ Voronoi::CalcVroniOffset( ICRVCOMPOPLIST& OffsList, double dOffs)
|
|||||||
RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ;
|
RemoveCurveSmallParts( pCrvOffs, 5 * EPS_SMALL) ;
|
||||||
|
|
||||||
// aggiungo la curva alla lista degli offset
|
// aggiungo la curva alla lista degli offset
|
||||||
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid() && pCrvOffs->GetCurveCount() > 0)
|
if ( ! IsNull( pCrvOffs) && pCrvOffs->IsValid() && pCrvOffs->GetCurveCount() > 0) {
|
||||||
|
// forzo chiusura
|
||||||
|
if ( ! pCrvOffs->IsClosed()) {
|
||||||
|
Point3d ptS ; pCrvOffs->GetStartPoint( ptS) ;
|
||||||
|
Point3d ptE ; pCrvOffs->GetEndPoint( ptE) ;
|
||||||
|
if ( SqDist( ptS, ptE) > 100. * SQ_EPS_SMALL)
|
||||||
|
return false ;
|
||||||
|
pCrvOffs->Close() ;
|
||||||
|
}
|
||||||
OffsList.push_back( Release( pCrvOffs)) ;
|
OffsList.push_back( Release( pCrvOffs)) ;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// libero la memoria di vroni dedicata agli offset
|
// libero la memoria di vroni dedicata agli offset
|
||||||
m_vroni->apiFreeOffsetData() ;
|
m_vroni->apiFreeOffsetData() ;
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user