From b23f738bb9a0bd1df9e9f642e41c2a529ea09f14 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Sun, 5 Apr 2020 17:09:23 +0000 Subject: [PATCH] EgtGeomkernel : - correzioni a booleane di TriMesh. --- SurfTriMeshBooleans.cpp | 169 +++++++++++++++++++--------------------- 1 file changed, 80 insertions(+), 89 deletions(-) diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index d4b4e3d..6135bde 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -1,7 +1,7 @@ //---------------------------------------------------------------------------- // EgalTech 2019-2020 //---------------------------------------------------------------------------- -// File : SurfTriMeshBooleans.cpp Data : 13.03.20 Versione : 2.2c1 +// File : SurfTriMeshBooleans.cpp Data : 04.04.20 Versione : 2.2d1 // Contenuto : Implementazione delle funzioni booleane per SurfFTrimesh. // // @@ -128,7 +128,7 @@ ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) // Estremi del segmento corrente del loop Point3d ptSegSt = Loop[nPt] ; Point3d ptSegEn = Loop[( nPt + 1) % int( Loop.size())] ; - // Vedo se il punto giace sul segmento del loop + // Distanza del punto dal segmento del loop DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ; double dSqDist ; dDistCalc.GetSqDist( dSqDist) ; @@ -185,18 +185,18 @@ ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) static bool SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2) { - // Cerco il tratto del loop chiuso pių vicino al punto + // Cerco il tratto del loop chiuso pių vicino al punto int nMinSeg = -1 ; - double dMinSqDinst = DBL_MAX; - for (int nPt = 0 ; nPt < int(Loop.size()) ; ++ nPt) { + double dMinSqDinst = DBL_MAX ; + for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) { // Estremi del segmento corrente del loop Point3d ptSegSt = Loop[nPt] ; - Point3d ptSegEn = Loop[(nPt + 1) % int(Loop.size())] ; - // Vedo se il punto giace sul segmento del loop + Point3d ptSegEn = Loop[( nPt + 1) % int(Loop.size())] ; + // Distanza del punto dal segmento del loop DistPointLine dDistCalc( ptStop, ptSegSt, ptSegEn) ; double dSqDist ; dDistCalc.GetSqDist( dSqDist) ; - if (dSqDist < dMinSqDinst) { + if ( dSqDist < dMinSqDinst) { dMinSqDinst = dSqDist ; nMinSeg = nPt ; } @@ -735,6 +735,12 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) bool SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) { + // Valuto se esistono loop non degeneri + int nExistNotDeg = 0 ; + for ( int nC = 0 ; nC < int( vnDegVec.size()) ; ++ nC) { + if ( vnDegVec[nC] > 0) + ++ nExistNotDeg ; + } // Divido il loop di partenza in sotto-loop int nIterationCount = 0 ; while ( cvOpenChain.size() > 0) { @@ -887,7 +893,7 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA } } } - if ( ! bLoopSplitted) { + if ( ! bLoopSplitted && ( vnDegVec[nLastOpenLoopN] == 1 || nExistNotDeg == 0)) { int nCurDeg = vnDegVec[nLastOpenLoopN] ; vnDegVec.emplace( vnDegVec.begin(), nCurDeg) ; Chain CurChain ; @@ -1015,6 +1021,71 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT } } + // Se esistono loop divisi in catene, le unisco + Triangle3d trTria ; + Surf.GetTriangle( it->first, trTria) ; + for ( int nC1 = 0 ; nC1 < nChainCnt - 1 ; ++ nC1) { + int nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ; + bool bFirstChainInside = nFirstChainLastSegPos >= 0 && + IsPointInsideTriangle( vChain[nC1][0].ptSt, trTria, TriangleType::OPEN) && + IsPointInsideTriangle( vChain[nC1][nFirstChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ; + for ( int nC2 = nC1 + 1 ; nC2 < nChainCnt && bFirstChainInside ; ++ nC2) { + int nSecondChainLastSegPos = int( vChain[nC2].size()) - 1 ; + bool bSecondChainInside = nSecondChainLastSegPos >= 0 && + IsPointInsideTriangle( vChain[nC2][0].ptSt, trTria, TriangleType::OPEN) && + IsPointInsideTriangle( vChain[nC2][nSecondChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ; + nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ; + bool bFisrtSecond = AreSamePointEpsilon( vChain[nC1][nFirstChainLastSegPos].ptEn, vChain[nC2][0].ptSt, 10 * EPS_SMALL) ; + for ( int nSeg = 0 ; nSeg <= nSecondChainLastSegPos && bSecondChainInside && bFisrtSecond ; ++ nSeg) { + IntSegment CurSeg ; + CurSeg.ptSt = vChain[nC2][nSeg].ptSt ; + CurSeg.ptEn = vChain[nC2][nSeg].ptEn ; + CurSeg.vtOuter = vChain[nC2][nSeg].vtOuter ; + CurSeg.bDegenerate = vChain[nC2][nSeg].bDegenerate ; + vChain[nC1].emplace_back( CurSeg) ; + } + bool bSecondFirst = AreSamePointEpsilon( vChain[nC1][0].ptSt, vChain[nC2][nSecondChainLastSegPos].ptEn, 10 * EPS_SMALL) ; + for ( int nSeg = 0 ; nSeg <= nFirstChainLastSegPos && bSecondChainInside && bSecondFirst && ! bFisrtSecond ; ++ nSeg) { + IntSegment CurSeg ; + CurSeg.ptSt = vChain[nC1][nSeg].ptSt ; + CurSeg.ptEn = vChain[nC1][nSeg].ptEn ; + CurSeg.vtOuter = vChain[nC1][nSeg].vtOuter ; + CurSeg.bDegenerate = vChain[nC1][nSeg].bDegenerate ; + vChain[nC2].emplace_back( CurSeg) ; + } + if ( bSecondChainInside && bFisrtSecond && nSecondChainLastSegPos >= 0) { + nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ; + bFirstChainInside = nFirstChainLastSegPos >= 0 && + IsPointInsideTriangle( vChain[nC1][0].ptSt, trTria, TriangleType::OPEN) && + IsPointInsideTriangle( vChain[nC1][nFirstChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ; + vChain.erase( vChain.begin() + nC2) ; + -- nChainCnt ; + -- nC2 ; + } + if ( bSecondChainInside && bSecondFirst && ! bFisrtSecond && nFirstChainLastSegPos >= 0) { + vChain.erase( vChain.begin() + nC1) ; + -- nChainCnt ; + -- nC2 ; + nC2 = nC2 == nC1 ? nC2 + 1 : nC2 ; + } + } + } + // Chiudo i loop costruiti a partire dalle catene + for ( int nC = 0 ; nC < nChainCnt ; ++ nC) { + int nChainLastSegPos = int( vChain[nC].size()) - 1 ; + if ( IsPointInsideTriangle( vChain[nC][0].ptSt, trTria, TriangleType::OPEN) && + IsPointInsideTriangle( vChain[nC][nChainLastSegPos].ptEn, trTria, TriangleType::OPEN) && + AreSamePointEpsilon( vChain[nC][0].ptSt, vChain[nC][nChainLastSegPos].ptEn, 10 * EPS_SMALL)) { + IntSegment CurSeg ; + CurSeg.ptSt = vChain[nC][nChainLastSegPos].ptEn ; + CurSeg.ptEn = vChain[nC][0].ptSt ; + CurSeg.vtOuter = ( CurSeg.ptEn - CurSeg.ptSt) ^ trTria.GetN() ; + CurSeg.vtOuter.Normalize() ; + CurSeg.bDegenerate = ( CurSeg.ptEn - CurSeg.ptSt).Len() > EPS_SMALL ; + vChain[nC].emplace_back( CurSeg) ; + } + } + // Fra le catene trovate separo le aperte dalle chiuse int nDegenerateChainNum = 0 ; INTVECTOR vnDegVec ; @@ -1071,11 +1142,6 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT // Questo viene diviso in sotto-loop chiusi mediante quelli aperti. // I loop chiusi trovati precedentemente sono interni a uno dei sotto-loop // chiusi di cui č formato il perimetro. - - // Recupero il triangolo - Triangle3d trTria ; - Surf.GetTriangle( it->first, trTria) ; - PNTVECTOR cvFirstLoop ; cvFirstLoop.emplace_back( trTria.GetP( 0)) ; cvFirstLoop.emplace_back( trTria.GetP( 1)) ; @@ -1137,7 +1203,6 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT } else { Surf.m_vTria[it->first].nTempPart = 0 ; - /*Surf.m_vTria[it->first].nTempPart *= 10 ;*/ continue ; } } @@ -2324,77 +2389,3 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf, } return true ; } - -///////////////////////// DEBUG ///////////////////////////////////////////////////////////////////////////////////////////////// -//if ( nTriaNumB == 76 && -// ( AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(1), Point3d( 1150.6666, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 245.89, 190.5))) || -// ( AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(0), Point3d( 1150.6666, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 245.89, 190.5))) || -// ( AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(2), Point3d( 1150.6666, 0.0000, 190.5)) && -// AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 245.89, 190.5)))) { -// int a = 0 ; -//} -// -//if ( ( AreSamePointApprox(trTriaB.GetP(0), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(1), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(2), Point3d(20, 40, 30))) || -// ( AreSamePointApprox(trTriaB.GetP(2), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(0), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(1), Point3d(20, 40, 30))) || -// ( AreSamePointApprox(trTriaB.GetP(1), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(2), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(0), Point3d(20, 40, 30)))) { -// int b = 0 ; -//} -///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -/////////////////////////////////////////////////////////////////////////////////////////////////// -//if ((AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 46)) && -// AreSamePointApprox(trTriaA.GetP(1), Point3d(100, 40, 30)) && -// AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 30))) || -// (AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 46)) && -// AreSamePointApprox(trTriaA.GetP(0), Point3d(100, 40, 30)) && -// AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 30))) || -// (AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 46)) && -// AreSamePointApprox(trTriaA.GetP(2), Point3d(100, 40, 30)) && -// AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 30)))) { -// -// if ((AreSamePointApprox(trTriaB.GetP(0), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(1), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(2), Point3d(20, 40, 30))) || -// (AreSamePointApprox(trTriaB.GetP(2), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(0), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(1), Point3d(20, 40, 30))) || -// (AreSamePointApprox(trTriaB.GetP(1), Point3d(76, 40, 30)) && -// AreSamePointApprox(trTriaB.GetP(2), Point3d(60, 40, 50)) && -// AreSamePointApprox(trTriaB.GetP(0), Point3d(20, 40, 30)))) { -// int b = 0; -// } -//} -/////////////////////////////////////////////////////////////////////////////////////////////////// -//bool -//FacesRetriangulation() -//{ -// // Mi assicuro che la trimesh sia ok -// // Assicurarsi che la trimesh sia ok ...... -// // Pongo tutti i triangoli come non visitati -// for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) { -// m_vTria[nT].nTemp = 0 ; -// } -// // Ciclo sui triangoli -// for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) { -// // Se triangolo non visitato -// if ( m_vTria[nT].nTemp == 0) { -// m_vTria[nT].nTemp = 1 ; -// unordered_set TriaIndexSet ;// devi usare stack -// TriaIndexSet.emplace( nT) ; -// while ( ! TriaIndexSet.empty()) { -// -// } -// } -// } -// return true ; -//}