diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 6d6c1e4..278393a 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -271,7 +271,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq) // Approssimo la curva con segmenti CurveComposite cvCompo ; PolyLine PL ; - if ( ! cvCurve.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! cvCompo.FromPolyLine( PL)) + if ( ! cvCurve.ApproxWithLines( LIN_TOL_MIN, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! cvCompo.FromPolyLine( PL)) return false ; // Appiattisco la polilinea nel piano perpendicolare all'estrusione Frame3d frCurve ; @@ -1235,8 +1235,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) // Divido il loop usando le catene bool bDecomposed = DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut) ; - // Rimuovo il triangolo corrente - RemoveTriangle( it->first) ; // Trasformo i loop compositi in loop polyline POLYLINEVECTOR vplPolyVec ; vplPolyVec.resize( cvBoundClosedLoopVec.size()) ; @@ -1356,7 +1354,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( vInnerLoop.size() == 0) { // Eseguo triangolazione - Triangulate CreateTriangulation ; PNTVECTOR vPt ; INTVECTOR vTr ; if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr)) { @@ -1395,20 +1392,20 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) pgPol.FromPolyLine( vPolygons[1]) ; if ( trTriaA.GetN() * pgPol.GetVersN() > 0.) { - for (int nL = 1; nL < int(vPolygons.size()); ++nL) { - vPolygons[nL].Invert(); + for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) { + vPolygons[nL].Invert() ; } - PNTVECTOR vPt; - INTVECTOR vTr; - if (Triangulate().Make(vPolygons, vPt, vTr)) { + PNTVECTOR vPt ; + INTVECTOR vTr ; + if ( Triangulate().Make( vPolygons, vPt, vTr)) { // Inserisco i nuovi triangoli - for (int n = 0; n < int(vTr.size()) - 2; n += 3) { + for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), AddVertex(vPt[nNewTriaVertId[1]]), AddVertex(vPt[nNewTriaVertId[2]])} ; - int nNewTriaNum = AddTriangle(nNewId) ; + int nNewTriaNum = AddTriangle( nNewId) ; if ( IsValidSvt( nNewTriaNum)) { m_vTria[nNewTriaNum].nTempPart = -1 ; bModif = true ; @@ -1416,11 +1413,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) } } - for (int nL = 1; nL < int(vPolygons.size()); ++nL) { - vPolygons[nL].Invert(); - if (Triangulate().Make(vPolygons[nL], vPt, vTr)) { + for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) { + vPolygons[nL].Invert() ; + if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) { // Inserisco i nuovi triangoli - for (int n = 0; n < int(vTr.size()) - 2; n += 3) { + for ( int n = 0 ; n < int(vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), AddVertex(vPt[nNewTriaVertId[1]]), @@ -1435,16 +1432,16 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) } } else { - PNTVECTOR vPt; - INTVECTOR vTr; - if (Triangulate().Make(vPolygons, vPt, vTr)) { + PNTVECTOR vPt ; + INTVECTOR vTr ; + if ( Triangulate().Make( vPolygons, vPt, vTr)) { // Inserisco i nuovi triangoli - for (int n = 0; n < int(vTr.size()) - 2; n += 3) { + for ( int n = 0 ; n < int(vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), AddVertex(vPt[nNewTriaVertId[1]]), AddVertex(vPt[nNewTriaVertId[2]])} ; - int nNewTriaNum = AddTriangle(nNewId) ; + int nNewTriaNum = AddTriangle( nNewId) ; if ( IsValidSvt( nNewTriaNum)) { m_vTria[nNewTriaNum].nTempPart = 1 ; bModif = true ; @@ -1452,11 +1449,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) } } - for (int nL = 1; nL < int(vPolygons.size()); ++nL) { - vPolygons[nL].Invert(); + for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) { + vPolygons[nL].Invert() ; if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) { // Inserisco i nuovi triangoli - for (int n = 0; n < int(vTr.size()) - 2; n += 3) { + for ( int n = 0 ; n < int(vTr.size()) - 2 ; n += 3) { int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ; int nNewId[3] = { AddVertex(vPt[nNewTriaVertId[0]]), AddVertex(vPt[nNewTriaVertId[1]]), @@ -1761,7 +1758,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) if ( vInnerLoop.size() == 0) { // Eseguo triangolazione - Triangulate CreateTriangulation ; PNTVECTOR vPt ; INTVECTOR vTr ; if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr)) { @@ -1844,7 +1840,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) PNTVECTOR vPt ; INTVECTOR vTr ; - if ( Triangulate().Make( vPolygons, vPt, vTr)) { // Inserisco i nuovi triangoli for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) { @@ -1966,6 +1961,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other) SurfB.m_vTria[nTB].nTempPart = nInOutNum ; } } + // Se c'è stata una ritriangolazione di almeno un triangolo, NON siamo nel caso di tutto dentro o tutto fuori. // Studio i triangoli ambigui. if ( bRetriangulated) { @@ -2142,13 +2138,12 @@ SurfTriMesh::RemoveTJunction( void) double dProj = ( ptVert - ptSegSt) * vtSeg ; double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ; if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && - dOrt < EPS_SMALL * EPS_SMALL /*&& - m_vTria[vNearTria[nNT]].nTemp != m_nTimeStamp*/) { + dOrt < EPS_SMALL * EPS_SMALL) { if ( bNewBaseSeg) { IndexesMatrix.emplace_back() ; bNewBaseSeg = false ; } - IndexesMatrix[int( IndexesMatrix.size()) - 1].emplace_back(vNearTria[nNT]) ; + IndexesMatrix.back().emplace_back( vNearTria[nNT]) ; m_vTria[vNearTria[nNT]].nTemp = m_nTimeStamp ; } } @@ -2159,8 +2154,8 @@ SurfTriMesh::RemoveTJunction( void) for ( int nP1 = 0 ; nP1 < int( IndexesMatrix.size()); ++ nP1) { for ( int nP2 = nP1 + 1 ; nP2 < int( IndexesMatrix.size()); ++ nP2) { bool bFoundCouple = false ; - for (int nN1 = 0 ; nN1 < int( IndexesMatrix[nP1].size()); ++ nN1) { - for (int nN2 = 0 ; nN2 < int( IndexesMatrix[nP2].size()); ++ nN2) { + for ( int nN1 = 0 ; nN1 < int( IndexesMatrix[nP1].size()); ++ nN1) { + for ( int nN2 = 0 ; nN2 < int( IndexesMatrix[nP2].size()); ++ nN2) { if ( IndexesMatrix[nP1][nN1] == IndexesMatrix[nP2][nN2]) { bFoundCouple = true ; break ; @@ -2187,54 +2182,42 @@ SurfTriMesh::RemoveTJunction( void) } for ( int nVec = 0 ; nVec < int( IndexesMatrix.size()) ; ++ nVec) { - if ( int( IndexesMatrix[nVec].size()) == 0) + // se non sono almeno due triangoli, passo oltre + if ( IndexesMatrix[nVec].size() < 2) continue ; - Triangle3d trTria ; - if ( ! ( GetTriangle( IndexesMatrix[nVec][0], trTria) && trTria.Validate( true))) - continue ; - CurveLine cvLine0 ; - cvLine0.Set( trTria.GetP( 0), trTria.GetP( 1)) ; - CurveLine cvLine1 ; - cvLine1.Set( trTria.GetP( 1), trTria.GetP( 2)) ; - CurveLine cvLine2 ; - cvLine2.Set( trTria.GetP( 2), trTria.GetP( 0)) ; - CurveComposite cvLoop ; - cvLoop.AddCurve( cvLine0) ; - cvLoop.AddCurve( cvLine1) ; - cvLoop.AddCurve( cvLine2) ; + // creo la regione unione dei triangoli + bool bFacetOk = false ; SurfFlatRegion Facet ; - Facet.AddExtLoop( cvLoop) ; - RemoveTriangle( IndexesMatrix[nVec][0]) ; - for ( int nT = 1 ; nT < int( IndexesMatrix[nVec].size()) ; ++ nT) { + for ( int nT = 0 ; nT < int( IndexesMatrix[nVec].size()) ; ++ nT) { Triangle3d trAddTria ; - if ( ! ( GetTriangle( IndexesMatrix[nVec][nT], trAddTria) && trAddTria.Validate( true))) + if ( ! GetTriangle( IndexesMatrix[nVec][nT], trAddTria) || ! trAddTria.Validate( true)) continue ; - CurveLine cvAddLine0 ; - cvAddLine0.Set( trAddTria.GetP( 0), trAddTria.GetP( 1)) ; - CurveLine cvAddLine1 ; - cvAddLine1.Set( trAddTria.GetP( 1), trAddTria.GetP( 2)) ; - CurveLine cvAddLine2 ; - cvAddLine2.Set( trAddTria.GetP( 2), trAddTria.GetP( 0)) ; - CurveComposite cvAddLoop ; - cvAddLoop.AddCurve( cvAddLine0) ; - cvAddLoop.AddCurve( cvAddLine1) ; - cvAddLoop.AddCurve( cvAddLine2) ; - SurfFlatRegion AddFacet ; - AddFacet.AddExtLoop( cvAddLoop) ; - if ( Facet.Add( AddFacet)) - RemoveTriangle( IndexesMatrix[nVec][nT]) ; + CurveComposite ccLoop ; + ccLoop.AddPoint( trAddTria.GetP( 0)) ; + ccLoop.AddLine( trAddTria.GetP( 1)) ; + ccLoop.AddLine( trAddTria.GetP( 2)) ; + ccLoop.Close() ; + if ( ! bFacetOk) { + if ( Facet.AddExtLoop( ccLoop)) { + bFacetOk = true ; + RemoveTriangle( IndexesMatrix[nVec][nT]) ; + } + } + else { + SurfFlatRegion AddFacet ; + if ( AddFacet.AddExtLoop( ccLoop) && Facet.Add( AddFacet)) + RemoveTriangle( IndexesMatrix[nVec][nT]) ; + } } - int nChunkNum = Facet.GetChunkCount() ; - for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) { + // triangolo la regione e rimetto i triangoli nella superficie + int nChunkCnt = Facet.GetChunkCount() ; + for ( int nChunk = 0 ; nChunk < nChunkCnt ; ++ nChunk) { POLYLINEVECTOR LoopVector ; - int nChunkLoopNum = Facet.GetLoopCount( nChunk) ; - for ( int nChunkLoop = 0 ; nChunkLoop < nChunkLoopNum ; ++ nChunkLoop) { - PtrOwner< ICurve> pOutline( Facet.GetLoop( nChunk, nChunkLoop)) ; - if ( IsNull( pOutline)) - continue ; + int nLoopCnt = Facet.GetLoopCount( nChunk) ; + for ( int nLoop = 0 ; nLoop < nLoopCnt ; ++ nLoop) { PolyLine PolyOutline ; - pOutline->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PolyOutline) ; - LoopVector.emplace_back( PolyOutline) ; + if ( Facet.ApproxLoopWithLines( nChunk, nLoop, LIN_TOL_MIN, ANG_TOL_STD_DEG, ICurve::APL_STD, PolyOutline)) + LoopVector.emplace_back( PolyOutline) ; } PNTVECTOR vPt ; INTVECTOR vTr ; diff --git a/Triangulate.cpp b/Triangulate.cpp index 2b3ca8a..c45fed7 100644 --- a/Triangulate.cpp +++ b/Triangulate.cpp @@ -588,7 +588,7 @@ Triangulate::CalcTriangleAspectRatio( const Point3d& ptPa, const Point3d& ptPb, if ( dTwoArea < SQ_EPS_SMALL) return INFINITO ; else - return ( (std::max)( dSqDistA, (std::max)( dSqDistB, dSqDistC)) / dTwoArea) ; + return ( max( { dSqDistA, dSqDistB, dSqDistC}) / dTwoArea) ; } //----------------------------------------------------------------------------