diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 762b38d..b918274 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -3662,21 +3662,24 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } // Assegno i loop chiusi interni alle rispettive parti di faccia. - // Ciclo sui pezzi di facet. - int nPieceNum = int( vNewPieces.size()) ; - for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) { - // Ciclo sui loop interni - for ( int nInnL = 0 ; nInnL < int( cvClosedChain.size()) ; ++ nInnL) { - // Trasformo il loop interno in PolyLine. - PolyLine CurInnerLoop ; - CurInnerLoop.AddUPoint( 0., cvClosedChain[nInnL][0].ptSt) ; - for ( int nSeg = 0 ; nSeg < int( cvClosedChain[nInnL].size()) ; ++ nSeg) { - CurInnerLoop.AddUPoint( 0., cvClosedChain[nInnL][nSeg].ptEn) ; - } - Plane3d plPlane ; - double dArea ; - if ( ! CurInnerLoop.IsClosedAndFlat( plPlane, dArea) || dArea < EPS_SMALL) - continue ; + // Ciclo sui loop interni + for ( int nInnL = 0 ; nInnL < int( cvClosedChain.size()) ; ++ nInnL) { + // Trasformo il loop interno in PolyLine. + PolyLine CurInnerLoop ; + CurInnerLoop.AddUPoint( 0., cvClosedChain[nInnL][0].ptSt) ; + for ( int nSeg = 0 ; nSeg < int( cvClosedChain[nInnL].size()) ; ++ nSeg) { + CurInnerLoop.AddUPoint( 0., cvClosedChain[nInnL][nSeg].ptEn) ; + } + Plane3d plPlane ; + double dArea ; + if ( ! CurInnerLoop.IsClosedAndFlat( plPlane, dArea) || dArea < EPS_SMALL) + continue ; + int nIncluderPiece = - 1 ; + double dIncluderPieceArea = DBL_MAX ; + bool bNewPieceOut = false ; + // Ciclo sui pezzi di facet. + int nPieceNum = int( vNewPieces.size()) ; + for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) { // Ciclo sui punti del loop interno. PNTULIST& LoopList = CurInnerLoop.GetUPointList() ; for ( auto itInn = LoopList.begin() ; itInn != LoopList.end() ; ++ itInn) { @@ -3688,71 +3691,77 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet ptInnNextP = itInnNext->first ; if ( IsPointInsidePolyLine( ptInnP, vNewPieces[nPieceN].vPieceLoop[0]) || ( itInnNext != LoopList.end() && IsPointInsidePolyLine( 0.5 * ( ptInnP + ptInnNextP), vNewPieces[nPieceN].vPieceLoop[0]))) { - Polygon3d AuxPolygon ; - AuxPolygon.FromPolyLine( CurInnerLoop) ; - Vector3d vtInnLoopNorm = AuxPolygon.GetVersN() ; - if ( vtFacetNorm * vtInnLoopNorm < 0.) { - // Aggiungo loop al pezzo. - vNewPieces[nPieceN].nPiecePart = 1 ; - vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ; - // Aggiungo nuovo pezzo. - vNewPieces.emplace_back() ; - vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ; - vNewPieces.back().vPieceLoop.back().Invert() ; - vNewPieces.back().nPiecePart = - 1 ; - // Cerco loop interni a quello appena aggiunto - INTVECTOR vSecondLevel ; - for ( int nSI = 1 ; nSI < int( vNewPieces[nPieceN].vPieceLoop.size()) ; ++ nSI) { - PNTULIST& SecLevLoopList = vNewPieces[nPieceN].vPieceLoop[nSI].GetUPointList() ; - for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { - Point3d ptPntSL = itSL->first ; - if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { - vSecondLevel.emplace_back( nSI) ; - break ; - } - } - } - // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. - for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) - vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nPieceN].vPieceLoop[vSecondLevel[nSI]]) ; - for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) - vNewPieces[nPieceN].vPieceLoop.erase( vNewPieces[nPieceN].vPieceLoop.begin() + vSecondLevel[nSI]) ; - break ; - } - else { - // Aggiungo loop al pezzo. - vNewPieces[nPieceN].nPiecePart = - 1 ; - vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ; - vNewPieces[nPieceN].vPieceLoop.back().Invert() ; - // Aggiungo nuovo pezzo. - vNewPieces.emplace_back() ; - vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ; - vNewPieces.back().nPiecePart = 1 ; - // Cerco loop interni a quello appena aggiunto - INTVECTOR vSecondLevel ; - for ( int nSI = 1 ; nSI < int( vNewPieces[nPieceN].vPieceLoop.size()) ; ++ nSI) { - PNTULIST& SecLevLoopList = vNewPieces[nPieceN].vPieceLoop[nSI].GetUPointList() ; - for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { - Point3d ptPntSL = itSL->first ; - if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { - vSecondLevel.emplace_back( nSI) ; - break ; - } - } - } - // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. - for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) - vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nPieceN].vPieceLoop[vSecondLevel[nSI]]) ; - for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) - vNewPieces[nPieceN].vPieceLoop.erase( vNewPieces[nPieceN].vPieceLoop.begin() + vSecondLevel[nSI]) ; - break ; + double dPieceArea ; + vNewPieces[nPieceN].vPieceLoop[0].IsClosedAndFlat( Plane3d(), dPieceArea) ; + if ( vNewPieces[nPieceN].vPieceLoop[0].IsClosedAndFlat( Plane3d(), dPieceArea) && dPieceArea < dIncluderPieceArea) { + nIncluderPiece = nPieceN ; + Polygon3d AuxPolygon ; + AuxPolygon.FromPolyLine( CurInnerLoop) ; + Vector3d vtInnLoopNorm = AuxPolygon.GetVersN() ; + bNewPieceOut = vtFacetNorm * vtInnLoopNorm < 0. ; } } } } + + if ( nIncluderPiece != - 1 && bNewPieceOut) { + // Aggiungo loop al pezzo. + vNewPieces[nIncluderPiece].nPiecePart = 1 ; + vNewPieces[nIncluderPiece].vPieceLoop.emplace_back( CurInnerLoop) ; + // Aggiungo nuovo pezzo. + vNewPieces.emplace_back() ; + vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ; + vNewPieces.back().vPieceLoop.back().Invert() ; + vNewPieces.back().nPiecePart = - 1 ; + // Cerco loop interni a quello appena aggiunto + INTVECTOR vSecondLevel ; + for ( int nSI = 1 ; nSI < int( vNewPieces[nIncluderPiece].vPieceLoop.size()) ; ++ nSI) { + PNTULIST& SecLevLoopList = vNewPieces[nIncluderPiece].vPieceLoop[nSI].GetUPointList() ; + for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { + Point3d ptPntSL = itSL->first ; + if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { + vSecondLevel.emplace_back( nSI) ; + break ; + } + } + } + // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. + for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) + vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nIncluderPiece].vPieceLoop[vSecondLevel[nSI]]) ; + for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) + vNewPieces[nIncluderPiece].vPieceLoop.erase( vNewPieces[nIncluderPiece].vPieceLoop.begin() + vSecondLevel[nSI]) ; + } + else { + // Aggiungo loop al pezzo. + vNewPieces[nIncluderPiece].nPiecePart = - 1 ; + vNewPieces[nIncluderPiece].vPieceLoop.emplace_back( CurInnerLoop) ; + vNewPieces[nIncluderPiece].vPieceLoop.back().Invert() ; + // Aggiungo nuovo pezzo. + vNewPieces.emplace_back() ; + vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ; + vNewPieces.back().nPiecePart = 1 ; + // Cerco loop interni a quello appena aggiunto + INTVECTOR vSecondLevel ; + for ( int nSI = 1 ; nSI < int( vNewPieces[nIncluderPiece].vPieceLoop.size()) ; ++ nSI) { + PNTULIST& SecLevLoopList = vNewPieces[nIncluderPiece].vPieceLoop[nSI].GetUPointList() ; + for ( auto itSL = SecLevLoopList.begin() ; itSL != SecLevLoopList.end() ; ++ itSL) { + Point3d ptPntSL = itSL->first ; + if ( IsPointInsidePolyLine( ptPntSL, vNewPieces.back().vPieceLoop.back())) { + vSecondLevel.emplace_back( nSI) ; + break ; + } + } + } + // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. + for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) + vNewPieces.back().vPieceLoop.emplace_back( vNewPieces[nIncluderPiece].vPieceLoop[vSecondLevel[nSI]]) ; + for ( int nSI = 0 ; nSI < int( vSecondLevel.size()) ; ++ nSI) + vNewPieces[nIncluderPiece].vPieceLoop.erase( vNewPieces[nIncluderPiece].vPieceLoop.begin() + vSecondLevel[nSI]) ; + } } // Aggiungo al loop esterno i punti dei loop interni che lo toccano. // Ciclo sui pezzi della faccia. + int nPieceNum = int( vNewPieces.size()) ; for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) { // Ciclo sui segmenti del loop esterno. PNTULIST& ExtLoopList = vNewPieces[nPieceN].vPieceLoop[0].GetUPointList() ;