Migliorato algoritmo di divisione delle facce

This commit is contained in:
LorenzoM
2021-04-29 15:02:39 +02:00
parent ec51c51c54
commit 43233528f2
+82 -73
View File
@@ -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() ;