diff --git a/CurveComposite.cpp b/CurveComposite.cpp index c9d6239..2c34eab 100644 --- a/CurveComposite.cpp +++ b/CurveComposite.cpp @@ -3134,7 +3134,7 @@ CurveComposite::RemoveUndercutOnY( double dLinTol, double dAngTolDeg) pSfrCut->Translate( b3Box.GetMin() - Point3d( 10 * EPS_SMALL, dLen, 0)) ; // calcolo la classificazione della curva rispetto alla regione CRVCVECTOR ccClass ; - if ( ! pSfrCut->GetCurveClassification( *pOutLoop, ccClass)) + if ( ! pSfrCut->GetCurveClassification( *pOutLoop, EPS_SMALL, ccClass)) return false ; // determino gli intervalli di curva da conservare Intervals inOk ; diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp index 2762cc5..fde9548 100644 --- a/GdbExecutor.cpp +++ b/GdbExecutor.cpp @@ -7647,7 +7647,7 @@ GdbExecutor::CurveCopyBySplitClass( const STRVECTOR& vsParams) IntersCurveCurve intCC( *pCrv, *pCloCrv, true) ; // recupero la classificazione della prima curva CRVCVECTOR ccClass ; - if ( ! intCC.GetCurveClassification( 0, ccClass)) + if ( ! intCC.GetCurveClassification( 0, EPS_SMALL, ccClass)) return false ; // recupero gli indici dei gruppi destinazione e i loro riferimenti const int N_GRP = 4 ; diff --git a/IntersCurveCurve.cpp b/IntersCurveCurve.cpp index 794fb97..1390683 100644 --- a/IntersCurveCurve.cpp +++ b/IntersCurveCurve.cpp @@ -391,7 +391,7 @@ IntersCurveCurve::GetIntersPointNearTo( int nCrv, const Point3d& ptNear, Point3d //---------------------------------------------------------------------------- bool -IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass) +IntersCurveCurve::GetCurveClassification( int nCrv, double dLenMin, CRVCVECTOR& ccClass) { // pulisco vettore classificazioni ccClass.clear() ; @@ -407,7 +407,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass) return false ; // se esiste almeno una intersezione if ( m_nIntersCount >= 1) - return CalcCurveClassification( m_pCurve[0], m_Info, ccClass) ; + return CalcCurveClassification( m_pCurve[0], m_Info, dLenMin, ccClass) ; // altrimenti la curva è completamente interna oppure completamente esterna else return CalcCurveInOrOut( m_pCurve[0], m_pCurve[1], ccClass) ; @@ -424,7 +424,7 @@ IntersCurveCurve::GetCurveClassification( int nCrv, CRVCVECTOR& ccClass) SwapInfoAB( InfoTmp, 1) ; // se esiste almeno una intersezione if ( m_nIntersCount >= 1) - return CalcCurveClassification( m_pCurve[1], InfoTmp, ccClass) ; + return CalcCurveClassification( m_pCurve[1], InfoTmp, dLenMin, ccClass) ; // altrimenti la curva è completamente interna oppure completamente esterna else return CalcCurveInOrOut( m_pCurve[1], m_pCurve[0], ccClass) ; @@ -461,7 +461,7 @@ IntersCurveCurve::SwapInfoAB( ICCIVECTOR& Info, int IndCrvOrd) //---------------------------------------------------------------------------- bool -IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, CRVCVECTOR& ccClass) +IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTOR& Info, double dLenMin, CRVCVECTOR& ccClass) { // numero intersezioni int nNumInters = int( Info.size()) ; @@ -471,6 +471,8 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO 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 ICCIVECTOR InfoCorr ; InfoCorr.reserve( Info.size()) ; @@ -527,7 +529,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO for ( int i = 0 ; i < nNumInters ; ++ i) { // se è definito un tratto precedente double dLenU ; pCurve->GetLengthAtParam( InfoCorr[i].IciA[0].dU, dLenU) ; - if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > EPS_SMALL) { + if ( InfoCorr[i].IciA[0].dU > dCurrPar + EPS_PARAM && dLenU - dCurrLen > dLenMin) { // verifico che la definizione sul tratto sia omogenea e valida int nPrevTy = InfoCorr[i].IciA[0].nPrevTy ; if ( ( nLastTy != ICCT_NULL && nPrevTy != nLastTy) || @@ -562,7 +564,7 @@ IntersCurveCurve::CalcCurveClassification( const ICurve* pCurve, const ICCIVECTO } } // eventuale tratto finale rimasto - if ( dCurrPar < dEndPar - EPS_PARAM && dEndLen - dCurrLen > EPS_SMALL) { + 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 ; @@ -673,7 +675,7 @@ IntersCurveCurve::GetRegionCurveClassification( void) { // classifico la prima curva rispetto alla seconda CRVCVECTOR ccClass ; - if ( ! GetCurveClassification( 0, ccClass)) + if ( ! GetCurveClassification( 0, EPS_SMALL, ccClass)) return CCREGC_NULL ; // derivo la classificazione delle curve come regioni bool bIn = false ; @@ -710,7 +712,7 @@ IntersCurveCurve::GetRegionCurveClassification( void) if ( bOnP) return CCREGC_IN2 ; CRVCVECTOR ccClass2 ; - if ( ! GetCurveClassification( 1, ccClass2) || ccClass2.empty()) + if ( ! GetCurveClassification( 1, EPS_SMALL, ccClass2) || ccClass2.empty()) return CCREGC_NULL ; if ( ccClass2[0].nClass == CRVC_OUT) return CCREGC_OUT ; diff --git a/OffsetCurve.cpp b/OffsetCurve.cpp index a0b0684..ca43e19 100644 --- a/OffsetCurve.cpp +++ b/OffsetCurve.cpp @@ -449,7 +449,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) inOk.Set( dStart, dEnd) ; IntersCurveCurve ccInt( *pCrv, *pCircS) ; CRVCVECTOR ccPart ; - if ( ! ccInt.GetCurveClassification( 0, ccPart)) + if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart)) return false ; for ( auto& ccOne : ccPart) { switch ( ccOne.nClass) { @@ -498,7 +498,7 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType) inOk.Set( dStart, dEnd) ; IntersCurveCurve ccInt( *pCrv, *pCircE) ; CRVCVECTOR ccPart ; - if ( ! ccInt.GetCurveClassification( 0, ccPart)) + if ( ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccPart)) return false ; for ( auto& ccOne : ccPart) { switch ( ccOne.nClass) { diff --git a/SurfFlatRegion.cpp b/SurfFlatRegion.cpp index b5ef968..286c9fc 100644 --- a/SurfFlatRegion.cpp +++ b/SurfFlatRegion.cpp @@ -165,7 +165,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv) for ( auto i : m_vExtInd) { IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ; if ( ccInt.GetCrossOrOverlapIntersCount() > 0 || - ! ccInt.GetCurveClassification( 0, ccClass) || + ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) || ccClass.empty() || ccClass[0].nClass != CRVC_OUT) { bOk = false ; break ; @@ -178,7 +178,7 @@ SurfFlatRegion::AddSimpleExtLoop( ICurve* pCrv) continue ; IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[i]) ; if ( ccInt.GetCrossOrOverlapIntersCount() == 0 && - ccInt.GetCurveClassification( 0, ccClass) && + ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) && ! ccClass.empty() && ccClass[0].nClass == CRVC_OUT) { bOk = true ; break ; @@ -298,7 +298,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv) IntersCurveCurve ccInt( *pMyCrv, *m_vpLoop[m_vExtInd[i]]) ; CRVCVECTOR ccClass ; if ( ccInt.GetCrossOrOverlapIntersCount() > 0 || - ! ccInt.GetCurveClassification( 0, ccClass) || + ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) || ccClass.empty() || ccClass[0].nClass != CRVC_IN) continue ; // verifica rispetto ai loop interni @@ -309,7 +309,7 @@ SurfFlatRegion::AddSimpleIntLoop( ICurve* pCrv) IntersCurveCurve ccInt2( *pMyCrv, *m_vpLoop[k]) ; CRVCVECTOR ccClass2 ; if ( ccInt2.GetCrossOrOverlapIntersCount() > 0 || - ! ccInt2.GetCurveClassification( 0, ccClass2) || + ! ccInt2.GetCurveClassification( 0, EPS_SMALL, ccClass2) || ccClass2.empty() || ccClass2[0].nClass != CRVC_IN) { bOk = false ; break ; @@ -1150,7 +1150,7 @@ SurfFlatRegion::CloneChunk( int nChunk) const //---------------------------------------------------------------------------- bool -SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const +SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const { // la curva deve già essere nel riferimento intrinseco della regione // verifico lo stato @@ -1179,7 +1179,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass IntersCurveCurve ccInt( Crv, *pLoop) ; // classificazione CRVCVECTOR ccPart ; - if ( ! ccInt.GetCurveClassification( 0, ccPart)) + if ( ! ccInt.GetCurveClassification( 0, dLenMin, ccPart)) return false ; for ( auto& ccOne : ccPart) { switch ( ccOne.nClass) { @@ -1272,7 +1272,7 @@ SurfFlatRegion::MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass //---------------------------------------------------------------------------- bool -SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const +SurfFlatRegion::GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const { // verifico lo stato if ( m_nStatus != OK || m_vpLoop.empty()) @@ -1293,7 +1293,7 @@ SurfFlatRegion::GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) pCrvLoc = pCopyCrv ; } // esecuzione classificazione nel riferimento intrinseco - return MyGetCurveClassification( *pCrvLoc, ccClass) ; + return MyGetCurveClassification( *pCrvLoc, dLenMin, ccClass) ; } //---------------------------------------------------------------------------- diff --git a/SurfFlatRegion.h b/SurfFlatRegion.h index 3ace4b1..88a9700 100644 --- a/SurfFlatRegion.h +++ b/SurfFlatRegion.h @@ -92,7 +92,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW const SurfTriMesh* GetAuxSurf( void) const override ; SurfFlatRegion* CloneChunk( int nChunk) const override ; bool GetChunkCentroid( int nChunk, Point3d& ptCen) const override ; - bool GetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const override ; + bool GetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const override ; int GetChunkSimpleClassification( int nChunk, const ISurfFlatRegion& Other, int nOthChunk) const override ; // compare only outsides public : // IGeoObjRW @@ -131,7 +131,7 @@ class SurfFlatRegion : public ISurfFlatRegion, public IGeoObjRW ICurve* GetMyLoop( int nChunk, int nLoop) const ; // nChunk 0-based, nLoop 0-based (1°esterno, successivi interni) void ResetAuxSurf( void) const ; bool ConvertArcsToBezierCurves( void) ; - bool MyGetCurveClassification( const ICurve& Crv, CRVCVECTOR& ccClass) const ; + bool MyGetCurveClassification( const ICurve& Crv, double dLenMin, CRVCVECTOR& ccClass) const ; static bool MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion& Other, int nType1, bool bInvert1, int nType2, bool bInvert2, PCRV_DEQUE& vpCurve) ; static bool MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop) ; diff --git a/SurfFlatRegionBooleans.cpp b/SurfFlatRegionBooleans.cpp index b763d96..f2b7f5e 100644 --- a/SurfFlatRegionBooleans.cpp +++ b/SurfFlatRegionBooleans.cpp @@ -289,7 +289,7 @@ SurfFlatRegion::MySelectCurves( const PCRV_DEQUE& vpLoop, const SurfFlatRegion& for ( auto& pLoop : vpLoop) { // eseguo classificazione CRVCVECTOR ccClass ; - if ( ! Other.MyGetCurveClassification( *pLoop, ccClass)) + if ( ! Other.MyGetCurveClassification( *pLoop, EPS_SMALL, ccClass)) return false ; // creo intervalli validi, tenendo classificazioni ricevute Intervals inOk1( EPS_PARAM), inOk2( EPS_PARAM) ; @@ -441,7 +441,7 @@ SurfFlatRegion::MyNewSurfFromLoops( PCRV_DEQUE& vpLoop) CRVCVECTOR ccClass ; IntersCurveCurve ccInt( *vpLoop[l], *pExtLoop) ; if ( ccInt.GetCrossOrOverlapIntersCount() > 0 || - ! ccInt.GetCurveClassification( 0, ccClass) || + ! ccInt.GetCurveClassification( 0, EPS_SMALL, ccClass) || ccClass.empty() || ccClass[0].nClass != CRVC_IN) continue ; // lo inserisco diff --git a/SurfTriMesh.cpp b/SurfTriMesh.cpp index db53337..88b6ca6 100644 --- a/SurfTriMesh.cpp +++ b/SurfTriMesh.cpp @@ -3401,11 +3401,9 @@ SurfTriMesh::Invert( void) //---------------------------------------------------------------------------- bool -SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) +SurfTriMesh::CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) { -#define UseTria 1 -#if UseTria - // la superficie deve essere validata + // la superficie deve essere validata if ( m_nStatus != OK) return false ; @@ -3430,7 +3428,6 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) ++ m_nTimeStamp ; // sistemo i triangoli (eventualmente li elimino) - bool bModif = false ; for ( int i = 0 ; i < GetTriangleSize() ; ++ i) { // salto i triangoli cancellati e quelli aggiunti if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp) @@ -3609,43 +3606,40 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) } } - // se effettuate modifiche - if ( bModif) { - // aggiorno tutto - if ( ! AdjustVertices() || ! DoCompacting()) - return false ; - } - return true ; +} -#else - - bool bModif = false ; - - // Setto i triangoli come né fuori né dentro. - int nTriaNum = GetTriangleSize() ; - for ( int nT = 0 ; nT < nTriaNum ; ++ nT) { +//---------------------------------------------------------------------------- +bool +SurfTriMesh::CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) +{ + // Setto posizione triangoli non definita + for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) m_vTria[nT].nTempPart = 0 ; - } INTERSCHAINMAP IntersLineMap ; // Ciclo su tutte le facce. - int nFacetNum = GetFacetCount() ; - for ( int nF = 0 ; nF < nFacetNum ; ++ nF) { + for ( int nF = 0 ; nF < GetFacetCount() ; ++ nF) { // Dati della faccia POLYLINEVECTOR vLoopVec ; GetFacetLoops( nF, vLoopVec) ; if ( vLoopVec.empty()) continue ; - PtrOwner pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ; - if ( IsNull( pReg)) - return false ; + // Verifico la posizione del loop esterno + int nIntType = VerifyLoopPlane( vLoopVec[0], plPlane) ; + // Se interseca il piano di taglio, calcolo la divisione della faccia LineFacetClassVector IntersLinePart ; - int nIntType = IntersFacetPlane( *pReg, vLoopVec[0], plPlane, IntersLinePart) ; - if ( nIntType == FacetPlaneIntersType::FPI_CUT) { + if ( nIntType == FPI_CUT) { + PtrOwner pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ; + if ( IsNull( pReg) || ! pReg->IsValid()) + return false ; + nIntType = IntersFacetPlane( *pReg, plPlane, IntersLinePart) ; + } + // Gestione dei risultati + if ( nIntType == FPI_CUT) { for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) { - // Salvo intersezione per la faccia. + // Salvo intersezione per la faccia. auto it = IntersLineMap.find( nF) ; if ( it != IntersLineMap.end()) { it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ; @@ -3655,26 +3649,28 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) } } } - else if ( nIntType == FacetPlaneIntersType::FPI_ON) { + else if ( nIntType == FPI_ON) { INTVECTOR vT ; GetAllTriaInFacet( nF, vT) ; + Vector3d vtNf ; + GetFacetNormal( nF, vtNf) ; for ( auto& nT : vT) - m_vTria[nT].nTempPart = pReg->GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ; + m_vTria[nT].nTempPart = ( vtNf * plPlane.GetVersN() > 0 ? 2 : -2) ; } - else if ( nIntType == FacetPlaneIntersType::FPI_INN) { + else if ( nIntType == FPI_IN) { INTVECTOR vT ; GetAllTriaInFacet( nF, vT) ; for ( auto& nT : vT) m_vTria[nT].nTempPart = 1 ; } - else if ( nIntType == FacetPlaneIntersType::FPI_OUT) { + else if ( nIntType == FPI_OUT) { INTVECTOR vT ; GetAllTriaInFacet( nF, vT) ; for ( auto& nT : vT) - m_vTria[nT].nTempPart = - 1 ; + m_vTria[nT].nTempPart = -1 ; } else - ; + return false ; } // Divido le facce. @@ -3683,13 +3679,44 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) INTERSEDGEMAP EdgeInterLineMap, EdgeEdgeLineMap ; RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ; - int nNumTria = GetTriangleSize() ; - for ( int nT = 0 ; nT < nNumTria ; ++ nT) - if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) + // Elimino i triangoli superflui + for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) { + if ( m_vTria[nT].nTempPart == 0 || + m_vTria[nT].nTempPart == -1 || + m_vTria[nT].nTempPart == -2 || + ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2)) { RemoveTriangle( nT) ; + bModif = true ; + } + } - return AdjustVertices() && DoCompacting() ; -#endif + return true ; +} + +//---------------------------------------------------------------------------- +bool +SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq) +{ + // la superficie deve essere validata + if ( m_nStatus != OK) + return false ; + + // eseguo il taglio con il metodo delle faccette + bool bModif = false ; + if ( true || ! CutByFacets( plPlane, bSaveOnEq, bModif)) { + bModif = false ; + if ( ! CutByTriangles( plPlane, bSaveOnEq, bModif)) + return false ; + } + + // se effettuate modifiche + if ( bModif) { + // aggiorno tutto + if ( ! AdjustVertices() || ! DoCompacting()) + return false ; + } + + return true ; } //---------------------------------------------------------------------------- diff --git a/SurfTriMesh.h b/SurfTriMesh.h index 303e6c7..1b15035 100644 --- a/SurfTriMesh.h +++ b/SurfTriMesh.h @@ -121,7 +121,7 @@ struct LineFacetClass { nTypeA = 0 ; nTypeB = 0 ; } - LineFacetClass( const Point3d& ptS, const Point3d ptE, int nTpA, int nTpB) { + LineFacetClass( const Point3d& ptS, const Point3d& ptE, int nTpA, int nTpB) { ptSt = ptS ; ptEn = ptE ; nTypeA = nTpA ; @@ -131,7 +131,7 @@ struct LineFacetClass { typedef std::vector LineFacetClassVector ; //---------------------------------------------------------------------------- -enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_INN = 2, FPI_OUT = 3, FPI_ON = 4 } ; +enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_IN = 2, FPI_OUT = 3, FPI_ON = 4 } ; //---------------------------------------------------------------------------- // Definizione strutture e contenitori @@ -381,16 +381,19 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW void ResetHashGrids3d( void) const ; bool VerifyHashGrids3d( void) const ; bool VerifyConnection( void) const ; + bool CutByTriangles( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ; + bool CutByFacets( const Plane3d& plPlane, bool bSaveOnEq, bool& bModif) ; bool DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut) ; bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ; bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ; bool IntersectTriMeshTriangle( SurfTriMesh& Other) ; - int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane, - LineFacetClassVector& IntersLinePart) ; + int VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) ; + int IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane, + LineFacetClassVector& IntersLinePart) ; bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA, const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB, LineFacetClassVector& IntersLinePart) ; - bool ItersectTriMeshFacets( SurfTriMesh& Other) ; + bool IntersectTriMeshFacets( SurfTriMesh& Other) ; bool RetriangulateFacetPieces( const PieceMap& NewFacet, const INTERSEDGEMAP& EdgeInterLineMap, const INTERSEDGEMAP& EdgeEdgeLineMap) ; diff --git a/SurfTriMeshBooleans.cpp b/SurfTriMeshBooleans.cpp index 0377b79..808a372 100644 --- a/SurfTriMeshBooleans.cpp +++ b/SurfTriMeshBooleans.cpp @@ -2573,23 +2573,14 @@ SurfTriMesh::CutWithOtherSurf( const ISurfTriMesh& CutterSurf, bool bInVsOut, bo //---------------------------------------------------------------------------- int -SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane, - LineFacetClassVector& IntersLinePart) +SurfTriMesh::VerifyLoopPlane( const PolyLine& ExtLoop, const Plane3d& plCutPlane) { - // Se la regione o il piano non sono validi, non è possibile proseguire. - if ( ! ( Region.IsValid() && plCutPlane.IsValid())) + // Verifico il loop e il piano di taglio + if ( ExtLoop.GetPointNbr() == 0 || ! plCutPlane.IsValid()) return FPI_ERROR ; - // Determino il piano della regione. - Plane3d plFacetPlane ; - plFacetPlane.Set( Region.GetPlanePoint(), Region.GetNormVersor()) ; - // Se il piano della regione non è valido, non è possibile proseguire. - if ( ! plCutPlane.IsValid()) - return FPI_ERROR ; - // Pulisco il vettore delle intersezioni risultanti. - IntersLinePart.resize( 0) ; - // Calcolo le distanze dei vertici della faccia dal piano. + // Calcolo le distanze dei vertici della faccia dal piano int nExtLoopPointNum = int( ExtLoop.GetPointNbr()) ; - vector vDist ; + DBLVECTOR vDist ; vDist.reserve( nExtLoopPointNum) ; Point3d ptP ; bool bContinue = ExtLoop.GetFirstPoint( ptP) ; @@ -2597,7 +2588,7 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext vDist.emplace_back( DistPointPlane( ptP, plCutPlane)) ; bContinue = ExtLoop.GetNextPoint( ptP) ; } - // Verifico posizione della faccia rispetto al piano. + // Verifico posizione della faccia rispetto al piano. int nVertPos = 0 ; int nVertNeg = 0 ; for ( const auto& dDist : vDist) { if ( dDist > 0.5 * EPS_SMALL) @@ -2611,36 +2602,58 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext return FPI_ON ; // Tutto dentro else if ( nVertPos == 0) - return FPI_INN ; + return FPI_IN ; // Tutto fuori else if ( nVertNeg == 0) return FPI_OUT ; + // Si intersecano + else + return FPI_CUT ; +} + +//---------------------------------------------------------------------------- +int +SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const Plane3d& plCutPlane, + LineFacetClassVector& IntersLinePart) +{ + // Verifico la regione e il piano di taglio + if ( ! Region.IsValid() || ! plCutPlane.IsValid()) + return FPI_ERROR ; + + // Recupero il piano della regione. + Plane3d plFacetPlane ; + plFacetPlane.Set( Region.GetPlanePoint(), Region.GetNormVersor()) ; + if ( ! plFacetPlane.IsValid()) + return FPI_ERROR ; + + // Pulisco il vettore delle intersezioni + IntersLinePart.resize( 0) ; // Intersezione tra i piani delle due facce Point3d ptL ; Vector3d vtL ; int nResPP = IntersPlanePlane( plFacetPlane, plCutPlane, ptL, vtL) ; - // Non essendo complanari, se non trovo la retta d'intersezione c'è un errore. + // Sono considerate non complanari, se c'è la retta d'intersezione è errore if ( nResPP == IPPT_NO || nResPP == IPPT_OVERLAPS) return FPI_ERROR ; - // Box contenente entrambe le regioni + // Box della regione BBox3d b3Box ; Region.GetLocalBBox( b3Box) ; b3Box.Expand( 10) ; - // Limito la retta nel box contenente le regioni + // Limito la retta nel box contenente la regione INTDBLVECTOR vInters ; if ( ! IntersLineBox( ptL, vtL, 100., b3Box, vInters, false) || int( vInters.size()) < 2) return FPI_ERROR ; - double dLen = vInters.back().second - vInters[0].second ; - Point3d ptIntLineSt = ptL + vInters[0].second * vtL ; + double dLen = vInters.back().second - vInters.front().second ; + Point3d ptIntLineSt = ptL + vInters.front().second * vtL ; Point3d ptIntLineEn = ptL + vInters.back().second * vtL ; CurveLine cvPlaneIntersLine ; cvPlaneIntersLine.Set( ptIntLineSt, ptIntLineEn) ; - // Limito la linea di intersezione con la faccia. + // Classifico la linea di intersezione con la faccia CRVCVECTOR IntersectionResults ; - bool bClassificationOk = Region.GetCurveClassification( cvPlaneIntersLine, IntersectionResults) ; + bool bClassificationOk = Region.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResults) ; // Se non trovo le intersezioni, c'è un errore. if ( ! bClassificationOk) return FPI_ERROR ; @@ -2655,8 +2668,17 @@ SurfTriMesh::IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& Ext IntersLinePart.emplace_back( LineFacetClass( ptIntLineSt + dParS * vtL, ptIntLineSt + dParE * vtL, nType, nType)) ; } } + if ( ! IntersLinePart.empty()) + return FPI_CUT ; - return int( IntersLinePart.size()) > 0 ; + // La linea si è ridotta ad un punto, la regione è tutta dentro o tutta fuori + Point3d ptCen ; + if ( ! Region.GetChunkCentroid( 0, ptCen)) + return FPI_ERROR ; + if ( DistPointPlane( ptCen, plCutPlane) > 0) + return FPI_OUT ; + else + return FPI_IN ; } //---------------------------------------------------------------------------- @@ -2744,11 +2766,11 @@ SurfTriMesh::IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& Ex // Limito la linea di intersezione con la faccia A CRVCVECTOR IntersectionResultsA ; - bool bClassificationOk = RegionA.GetCurveClassification( cvPlaneIntersLine, IntersectionResultsA) ; + bool bClassificationOk = RegionA.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResultsA) ; // Limito la linea di intersezione con la faccia B CRVCVECTOR IntersectionResultsB ; - bClassificationOk = bClassificationOk && RegionB.GetCurveClassification( cvPlaneIntersLine, IntersectionResultsB) ; + bClassificationOk = bClassificationOk && RegionB.GetCurveClassification( cvPlaneIntersLine, 0.1 * EPS_SMALL, IntersectionResultsB) ; if ( ! bClassificationOk) return false ; @@ -2830,7 +2852,7 @@ ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) } } // Se il punto non sta sul loop, errore - if ( dMinSqDist > 100 * SQ_EPS_SMALL) + if ( dMinSqDist > 4 * SQ_EPS_SMALL) return false ; // Se il punto non sta su un vertice del segmento, lo aggiungo. Altrimenti non devo fare nulla. auto itNewPointSt = LoopList.begin() ; @@ -2896,7 +2918,7 @@ PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& } } // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) + if ( dMinSqDist > 4 * SQ_EPS_SMALL) return false ; // Calcolo il parametro lungo il segmento. Vector3d vtSeg = itMinDistEn->first - itMinDistSt->first ; @@ -3114,7 +3136,7 @@ SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine } } // Se il punto non sta sul loop, lo segnalo. - if ( dMinSqDist > 100 * SQ_EPS_SMALL) + if ( dMinSqDist > 4 * SQ_EPS_SMALL) return false ; // Se il punto di stop sta su un vertice non devo aggiungerlo e il // punto di stop sarà uno degli estremi del segmento su cui giace. @@ -3185,13 +3207,13 @@ bool SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet) { for ( auto it = IntersLineMap.begin() ; it != IntersLineMap.end() ; ++ it) { - // Normale alla faccia + // Normale alla faccia Vector3d vtFacetNorm ; GetFacetNormal( it->first, vtFacetNorm) ; - // Creo i loop + // Creo i loop ChainCurves LoopCreator ; LoopCreator.Init( false, 10 * EPS_SMALL, int( it->second.size()), 10) ; - // Carico le curve per concatenarle + // Carico le curve per concatenarle for ( int nCv = 0 ; nCv < int( it->second.size()); ++ nCv) { Point3d ptSt = it->second[nCv].ptSt ; Point3d ptEn = it->second[nCv].ptEn ; @@ -3199,31 +3221,31 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet vtDir.Normalize() ; LoopCreator.AddCurve( nCv + 1, ptSt, vtDir, ptEn, vtDir) ; } - // Recupero i concatenamenti e li divido fra chiusi e aperti. - INTVECTOR vIds ; - Point3d ptNearStart = ( it->second.size() > 0 ? it->second[0].ptSt : ORIG) ; + // Recupero i concatenamenti e li divido fra chiusi e aperti. INNCHAINVECTOR cvClosedChain ; INNCHAINVECTOR cvOpenChain ; + INTVECTOR vIds ; + Point3d ptNearStart = ( it->second.size() > 0 ? it->second[0].ptSt : ORIG) ; while ( LoopCreator.GetChainFromNear( ptNearStart, false, vIds)) { IntersInnChain chTemp ; - for ( auto i : vIds) { - // Aggiungo la linea alla curva composta. + // Aggiungo la linea alla curva composta. + for ( auto i : vIds) chTemp.emplace_back( it->second[i - 1]) ; - } - int nCurLoopLast = max( int( chTemp.size()) - 1, 0) ; - if ( AreSamePointEpsilon( chTemp[0].ptSt, chTemp[nCurLoopLast].ptEn, 10 * EPS_SMALL) && nCurLoopLast > 0) + // Inserisco opportunamente negli aperti o chiusi + int nCurLoopLast = int( chTemp.size()) - 1 ; + if ( nCurLoopLast > 0 && AreSamePointEpsilon( chTemp[0].ptSt, chTemp[nCurLoopLast].ptEn, 10 * EPS_SMALL)) cvClosedChain.emplace_back( chTemp) ; else cvOpenChain.emplace_back( chTemp) ; } - // Elimino la seconda copia di catene aperte doppie + // Elimino la seconda copia di catene aperte doppie for ( int nI = 0 ; nI < int( cvOpenChain.size()) - 1 ; ++ nI) { for ( int nJ = nI + 1 ; nJ < int( cvOpenChain.size()) ; ++ nJ) { if ( cvOpenChain[nI].size() == cvOpenChain[nJ].size()) { bool bSame = true ; for ( int nK = 0 ; nK < int( cvOpenChain[nI].size()) ; ++ nK) { - if ( ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptSt, cvOpenChain[nJ][nK].ptSt, 10 * EPS_SMALL) || - ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptEn, cvOpenChain[nJ][nK].ptEn, 10 * EPS_SMALL)) { + if ( ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptSt, cvOpenChain[nJ][nK].ptSt, EPS_SMALL) || + ! AreSamePointEpsilon( cvOpenChain[nI][nK].ptEn, cvOpenChain[nJ][nK].ptEn, EPS_SMALL)) { bSame = false ; break ; } @@ -3235,14 +3257,14 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Elimino la seconda copia di catene chiuse doppie + // Elimino la seconda copia di catene chiuse doppie for ( int nI = 0 ; nI < int( cvClosedChain.size()) - 1 ; ++ nI) { for ( int nJ = nI + 1 ; nJ < int( cvClosedChain.size()) ; ++ nJ) { if ( cvClosedChain[nI].size() == cvClosedChain[nJ].size()) { bool bSame = true ; for ( int nK = 0 ; nK < int( cvClosedChain[nI].size()) ; ++ nK) { - if ( ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptSt, cvClosedChain[nJ][nK].ptSt, 10 * EPS_SMALL) || - ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptEn, cvClosedChain[nJ][nK].ptEn, 10 * EPS_SMALL)) { + if ( ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptSt, cvClosedChain[nJ][nK].ptSt, EPS_SMALL) || + ! AreSamePointEpsilon( cvClosedChain[nI][nK].ptEn, cvClosedChain[nJ][nK].ptEn, EPS_SMALL)) { bSame = false ; break ; } @@ -3254,13 +3276,13 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Recupero i loop della faccia da dividere + // Recupero i loop della faccia da dividere vector& vNewPieces = ( NewFacet.emplace( it->first, vector()).first)->second ; vNewPieces.emplace_back(); vNewPieces.back().nPiecePart = 1 ; GetFacetLoops( it->first, vNewPieces.back().vPieceLoop) ; - // Divido la faccia in parti. - // Ciclo sulle catene finché non esauriscono. + // Divido la faccia in parti. + // Ciclo sulle catene finché non esauriscono. int nIterNumber = 0 ; int nPrevLastChainNum = int( cvOpenChain.size()) ; while ( int( cvOpenChain.size()) > 0) { @@ -3281,12 +3303,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } if ( int( cvOpenChain.size()) == 0) break ; - // Ciclo su tutte le parti della faccia. + // Ciclo su tutte le parti della faccia. int nPartLoopNum = int( vNewPieces.size()) ; for ( int nPart = 0 ; nPart < nPartLoopNum ; ++ nPart) { - // Cerco i loop su cui la catena corrente inizia e finisce. + // Cerco i loop su cui la catena corrente inizia e finisce. INTVECTOR vLoopIndexes ; - // Ciclo sui loop della faccia. + // Ciclo sui loop della faccia. for ( int nLoop = 0 ; nLoop < int( vNewPieces[nPart].vPieceLoop.size()) && int( vLoopIndexes.size()) < 2 ; ++ nLoop) { int nSegNum ; double dParOnSeg ; @@ -3301,47 +3323,47 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet vLoopIndexes.emplace_back( nLoop) ; } } - // Se non ho trovato almeno un taglio completo, vado al prossimo. + // Se non ho trovato almeno un taglio completo, vado al prossimo. if ( int( vLoopIndexes.size()) < 2) continue ; - // La catena finisce sul loop ove inizia. Divido la nuova parte. + // La catena finisce sul loop ove inizia. Divido la nuova parte. if ( vLoopIndexes[0] == vLoopIndexes[1]) { - // Cambio inizio al loop iniziale. + // Cambio inizio al loop iniziale. ChangePolyLineStart( cvOpenChain[nLastChainNum].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ; - // Divido il loop della parte - // Loop1 + // Divido il loop della parte + // Loop1 PolyLine NewLoop1 ; - // Inserisco i punti della catena nella PolyLine del nuovo loop. + // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = 0 ; m < int( cvOpenChain[nLastChainNum].size()) ; ++ m) { NewLoop1.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptSt) ; if ( m == int( cvOpenChain[nLastChainNum].size()) - 1) NewLoop1.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ; } - // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. + // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. PolyLine SplitLoop1, SplitLoop2 ; SplitPolyLineAtPoint( cvOpenChain[nLastChainNum][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]], SplitLoop1, SplitLoop2) ; - // Aggiungo i punti precedenti il punto di frattura nella in NewLoop1. + // Aggiungo i punti precedenti il punto di frattura nella in NewLoop1. AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ; - // Loop2 + // Loop2 PolyLine NewLoop2 ; AddPolyLineToPolyLine( NewLoop2, SplitLoop2) ; - // Inserisco i punti della catena nella PolyLine del nuovo loop. + // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[nLastChainNum].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptEn) ; if ( m == 0) NewLoop2.AddUPoint( 0., cvOpenChain[nLastChainNum][m].ptSt) ; } - // Loop esterno coinvolto + // Loop esterno coinvolto if ( vLoopIndexes[0] == 0) { - // Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti. + // Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti. FacetPiece PieceInn, PieceOut ; PieceInn.vPieceLoop.emplace_back( NewLoop1) ; PieceInn.nPiecePart = 1 ; PieceOut.vPieceLoop.emplace_back( NewLoop2) ; PieceOut.nPiecePart = - 1 ; - // Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi. + // Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi. for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) { if ( nIL == vLoopIndexes[0]) continue ; @@ -3368,7 +3390,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet vNewPieces.emplace_back( PieceInn) ; vNewPieces.emplace_back( PieceOut) ; } - // Loop esterno non coinvolto + // Loop esterno non coinvolto else { Plane3d plLoopPlane1, plLoopPlane2, plContLoopPlane; double dArea1, dArea2, dAreaCont; @@ -3387,11 +3409,11 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet NewLoopCCW = NewLoop2; NewLoopCW = NewLoop1; } - // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. + // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. FacetPiece DetachedPiece; DetachedPiece.vPieceLoop.emplace_back(NewLoopCCW); DetachedPiece.nPiecePart = bFirstLoopIsCounter ? 1 : -1; - // Al pezzo pezzo staccato assegno i loop interni del vecchio pezzo non tagliati da catene. + // Al pezzo pezzo staccato assegno i loop interni del vecchio pezzo non tagliati da catene. for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) { if ( nIL == vLoopIndexes[0]) continue ; @@ -3400,7 +3422,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) { DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ; - // Cambio il numero dei loop talgiati + // Cambio il numero dei loop tagliati for ( int nIntersLoop = 0 ; nIntersLoop < int( vLoopIndexes.size()) ; ++ nIntersLoop) { if ( vLoopIndexes[nIntersLoop] > nIL) -- vLoopIndexes[nIntersLoop] ; @@ -3408,26 +3430,26 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet -- nIL ; } } - // Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca. + // Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca. /*if ( ! bFirstLoopIsCounter)*/ vNewPieces[nPart].vPieceLoop.erase(vNewPieces[nPart].vPieceLoop.begin() + vLoopIndexes[0]); vNewPieces[nPart].vPieceLoop.emplace_back( NewLoopCW) ; vNewPieces[nPart].nPiecePart = bFirstLoopIsCounter ? - 1 : 1 ; vNewPieces.emplace_back( DetachedPiece) ; } - // Elimino la catena usata. + // Elimino la catena usata. cvOpenChain.erase( cvOpenChain.begin() + nLastChainNum) ; - // Interrompo il ciclo sulle parti. + // Interrompo il ciclo sulle parti. break ; } - // Cerco le catene per dividere la nuova parte. + // Cerco le catene per dividere la nuova parte. else { INTVECTOR vChainIndex ; vChainIndex.emplace_back( nLastChainNum) ; while ( vLoopIndexes.back() != vLoopIndexes[0]) { - // Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata. + // Cambio inizio del loop corrente in modo che il punto di inizio sia il punto finale dell'ultima catena trovata. ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes.back()]) ; - // Cerco catene che iniziano sul loop coorente + // Cerco catene che iniziano sul loop coorente vector vChainStartingOnLoop ; for ( int nCh = 0 ; nCh < nLastChainNum ; ++ nCh) { int nSegNum ; @@ -3436,7 +3458,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet vChainStartingOnLoop.emplace_back( PositionOnPolyLine(nCh, nSegNum, dParOnSeg)) ; } } - // Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso. + // Ordino le catene secondo la vicinanza lungo il loop del loro punto d'inizio al punto d'inizio del loop stesso. sort( vChainStartingOnLoop.begin(), vChainStartingOnLoop.end(), [] ( PositionOnPolyLine Ch1, PositionOnPolyLine Ch2) { if ( Ch1.nSegNum/*nIndexInVec*/ < Ch2.nSegNum/*nIndexInVec*/) return true ; @@ -3444,81 +3466,81 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet return Ch1.dParOnSeg < Ch2.dParOnSeg ; else return false ; } ) ; - // Cerco la prima catena che non termina sul loop corrente. + // Cerco la prima catena che non termina sul loop corrente. for ( int n = 0 ; n < int( vChainStartingOnLoop.size()) ; ++ n) { - // Indice della catena e indice del segmento finale + // Indice della catena e indice del segmento finale int nCh = vChainStartingOnLoop[n].nIndexInVec ; int nLastLineIndex = int( cvOpenChain[nCh].size()) - 1 ; - // Ciclo sui loop + // Ciclo sui loop int nLoopNum = int( vNewPieces[nPart].vPieceLoop.size()) ; - int nLoop ; - for ( nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { - // Salto il loop corrente + bool bFound = false ; + for ( int nLoop = 0 ; nLoop < nLoopNum ; ++ nLoop) { + // Salto il loop corrente if ( nLoop == vLoopIndexes.back()) continue ; int nSegNum ; double dParOnSeg ; - // La catena termina su questo loop diverso da quello corrente. - if ( nLoop != vLoopIndexes.back() && - PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) { - // Salvo l'indice della catena e quello del loop. + // La catena termina su questo loop diverso da quello corrente. + if ( PointPositionOnPolyLine( cvOpenChain[nCh][nLastLineIndex].ptEn, vNewPieces[nPart].vPieceLoop[nLoop], nSegNum, dParOnSeg)) { + // Salvo l'indice della catena e quello del loop. vChainIndex.emplace_back( nCh) ; vLoopIndexes.emplace_back( nLoop) ; + bFound = true ; break ; } } - if ( nLoop == nLoopNum) + if ( bFound) break ; } } - // Cambio inizio al loop iniziale. + // Cambio inizio al loop iniziale. ChangePolyLineStart( cvOpenChain[vChainIndex.back()].back().ptEn, vNewPieces[nPart].vPieceLoop[vLoopIndexes[0]]) ; - // Divido i loop della parte. + // Divido i loop della parte. POLYLINEVECTOR vPolySecondPartVec ; PolyLine NewLoop1 ; for ( int n = 0 ; n < int( vChainIndex.size()) ; ++ n) { - // Inserisco i punti della catena nella PolyLine del nuovo loop. + // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = 0 ; m < int( cvOpenChain[vChainIndex[n]].size()) ; ++ m) { NewLoop1.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptSt) ; if ( m == int( cvOpenChain[vChainIndex[n]].size()) - 1) NewLoop1.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ; } - // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. + // Spezzo il loop successivo alla catena nel punto in cui comincia la catena successiva. PolyLine SplitLoop1, SplitLoop2 ; SplitPolyLineAtPoint( cvOpenChain[vChainIndex[( n + 1) % int( vChainIndex.size())]][0].ptSt, vNewPieces[nPart].vPieceLoop[vLoopIndexes[n + 1]], SplitLoop1, SplitLoop2) ; - // Aggiungo i punti precedenti il punto di frattura in NewLoop1. + // Aggiungo i punti precedenti il punto di frattura in NewLoop1. AddPolyLineToPolyLine( NewLoop1, SplitLoop1) ; - // Salvo la parte dopo il punto di frattura in un apposito vettore. + // Salvo la parte dopo il punto di frattura in un apposito vettore. vPolySecondPartVec.emplace_back( SplitLoop2) ; } PolyLine NewLoop2 ; for ( int n = int( vChainIndex.size()) - 1 ; n >= 0 ; -- n) { - // Aggiungo i punti successivi il punto di frattura in NewLoop2. + // Aggiungo i punti successivi il punto di frattura in NewLoop2. AddPolyLineToPolyLine( NewLoop2, vPolySecondPartVec[n]) ; - // Inserisco i punti della catena nella PolyLine del nuovo loop. + // Inserisco i punti della catena nella PolyLine del nuovo loop. for ( int m = int( cvOpenChain[vChainIndex[n]].size()) - 1 ; m >= 0 ; -- m) { NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptEn) ; if ( m == 0) NewLoop2.AddUPoint( 0., cvOpenChain[vChainIndex[n]][m].ptSt) ; } } - // Controllo che il loop esterno sia interessato. + // Controllo che il loop esterno sia interessato. bool bExtCutted = false ; for ( int n = 0 ; n < int( vLoopIndexes.size()) && ! bExtCutted ; ++ n) { if ( vLoopIndexes[n] == 0) bExtCutted = true ; } - // Loop esterno interessato + // Loop esterno interessato if ( bExtCutted) { - // Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti. + // Creo i pezzi nuovi, i cui loop esterni sono quelli appena definiti. FacetPiece PieceInn, PieceOut ; PieceInn.vPieceLoop.emplace_back( NewLoop1) ; PieceInn.nPiecePart = 1 ; PieceOut.vPieceLoop.emplace_back( NewLoop2) ; PieceOut.nPiecePart = - 1 ; - // Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi. + // Assegno i loop interni del vecchio pezzo non tagliati da catene ai nuovi. for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) { bool bUsed = false ; for ( int nU = 0 ; nU < int( vLoopIndexes.size()) - 1 ; ++ nU) { @@ -3548,12 +3570,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Aggiungo i due nuovi pezzi ed elimino quello da cui sono nati. + // Aggiungo i due nuovi pezzi ed elimino quello da cui sono nati. vNewPieces.erase( vNewPieces.begin() + nPart) ; vNewPieces.emplace_back( PieceInn) ; vNewPieces.emplace_back( PieceOut) ; } - // Loop esterno non interessato + // Loop esterno non interessato else { Plane3d plLoopPlane1, plLoopPlane2, plContLoopPlane ; double dArea1, dArea2, dAreaCont ; @@ -3572,7 +3594,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet NewLoopCCW = NewLoop2 ; NewLoopCW = NewLoop1 ; } - // // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. + // // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. // FacetPiece PieceInn ; // PieceInn.vPieceLoop.emplace_back( NewLoop1) ; // PieceInn.nPiecePart = 1 ; @@ -3599,11 +3621,11 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet // vNewPieces[nPart].vPieceLoop.emplace_back( NewLoop2) ; // vNewPieces[nPart].nPiecePart = - 1 ; // vNewPieces.emplace_back( PieceInn) ; - // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. + // Creo il pezzo nuovo, il cui loop esterno è stato appena definito. FacetPiece DetachedPiece ; DetachedPiece.vPieceLoop.emplace_back( NewLoopCCW) ; DetachedPiece.nPiecePart = bFirstLoopIsCounter ? 1 : - 1 ; - // Al pezzo che si stacca assegno i loop interni del vecchio pezzo non tagliati da catene. + // Al pezzo che si stacca assegno i loop interni del vecchio pezzo non tagliati da catene. for ( int nIL = 1 ; nIL < int( vNewPieces[nPart].vPieceLoop.size()) ; ++ nIL) { bool bUsed = false ; for ( int nU = 1 ; nU < int( vLoopIndexes.size()) - 1 ; ++ nU) { @@ -3619,7 +3641,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet if ( IsPointInsidePolyLine( ptPointInnerLoop, DetachedPiece.vPieceLoop[0])) { DetachedPiece.vPieceLoop.emplace_back( vNewPieces[nPart].vPieceLoop[nIL]) ; vNewPieces[nPart].vPieceLoop.erase( vNewPieces[nPart].vPieceLoop.begin() + nIL) ; - // Cambio il numero dei loop talgiati + // Cambio il numero dei loop talgiati for ( int nIntersLoop = 0 ; nIntersLoop < int( vLoopIndexes.size()) ; ++ nIntersLoop) { if ( vLoopIndexes[nIntersLoop] > nIL) -- vLoopIndexes[nIntersLoop] ; @@ -3627,7 +3649,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet -- nIL ; } } - // Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca. + // Aggiungo al pezzo, da cui si stacca quello appena creato, il loop complementare a quello che appartiene al pezzo che si stacca. vLoopIndexes.resize(int(vLoopIndexes.size()) - 1); sort( vLoopIndexes.begin(), vLoopIndexes.end(), [] ( int nIndex1, int nIndex2) { return nIndex1 > nIndex2 ; }) ; for (int nLoopInd = 0; nLoopInd < int(vLoopIndexes.size()); ++nLoopInd) { @@ -3637,23 +3659,23 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet vNewPieces[nPart].nPiecePart = bFirstLoopIsCounter ? - 1 : 1 ; vNewPieces.emplace_back( DetachedPiece) ; } - // Elimino catene usate. + // Elimino catene usate. sort( vChainIndex.begin(), vChainIndex.end(), [] ( int nIndex1, int nIndex2) { return nIndex1 > nIndex2 ; }) ; for ( int nChInd = 0 ; nChInd < int( vChainIndex.size()) ; ++ nChInd) { cvOpenChain.erase( cvOpenChain.begin() + vChainIndex[nChInd]) ; } - // Interrompo il ciclo sulle parti. + // Interrompo il ciclo sulle parti. break ; } } } - // Assegno i loop chiusi interni alle rispettive parti di faccia. - // Ciclo sui pezzi di facet. + // 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 + // Ciclo sui loop interni for ( int nInnL = 0 ; nInnL < int( cvClosedChain.size()) ; ++ nInnL) { - // Trasformo il loop interno in PolyLine. + // 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) { @@ -3663,7 +3685,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet double dArea ; if ( ! CurInnerLoop.IsClosedAndFlat( plPlane, dArea) || dArea < EPS_SMALL) continue ; - // Ciclo sui punti del loop interno. + // Ciclo sui punti del loop interno. PNTULIST& LoopList = CurInnerLoop.GetUPointList() ; for ( auto itInn = LoopList.begin() ; itInn != LoopList.end() ; ++ itInn) { Point3d ptInnP = itInn->first ; @@ -3678,15 +3700,15 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet AuxPolygon.FromPolyLine( CurInnerLoop) ; Vector3d vtInnLoopNorm = AuxPolygon.GetVersN() ; if ( vtFacetNorm * vtInnLoopNorm < 0.) { - // Aggiungo loop al pezzo. + // Aggiungo loop al pezzo. vNewPieces[nPieceN].nPiecePart = 1 ; vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ; - // Aggiungo nuovo pezzo. + // 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 + // 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() ; @@ -3698,7 +3720,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. + // 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) @@ -3706,15 +3728,15 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet break ; } else { - // Aggiungo loop al pezzo. + // Aggiungo loop al pezzo. vNewPieces[nPieceN].nPiecePart = - 1 ; vNewPieces[nPieceN].vPieceLoop.emplace_back( CurInnerLoop) ; vNewPieces[nPieceN].vPieceLoop.back().Invert() ; - // Aggiungo nuovo pezzo. + // Aggiungo nuovo pezzo. vNewPieces.emplace_back() ; vNewPieces.back().vPieceLoop.emplace_back( CurInnerLoop) ; vNewPieces.back().nPiecePart = 1 ; - // Cerco loop interni a quello appena aggiunto + // 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() ; @@ -3726,7 +3748,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Aggiungo i loop al nuovo pezzo e li tolgo dal precedente. + // 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) @@ -3737,10 +3759,10 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Aggiungo al loop esterno i punti dei loop interni che lo toccano. - // Ciclo sui pezzi della faccia. + // Aggiungo al loop esterno i punti dei loop interni che lo toccano. + // Ciclo sui pezzi della faccia. for ( int nPieceN = 0 ; nPieceN < nPieceNum ; ++ nPieceN) { - // Ciclo sui segmenti del loop esterno. + // Ciclo sui segmenti del loop esterno. PNTULIST& ExtLoopList = vNewPieces[nPieceN].vPieceLoop[0].GetUPointList() ; auto itSt = ExtLoopList.begin() ; auto itEn = itSt ; ++ itEn ; for ( ; itEn != ExtLoopList.end(); ++itSt, ++itEn) { @@ -3749,12 +3771,12 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet Vector3d vtSeg = ptEn - ptSt ; double dSegLen = vtSeg.Len() ; vtSeg /= dSegLen ; - // Vettore dei punti dei loop interni che stanno sul segmento del loop esterno + // Vettore dei punti dei loop interni che stanno sul segmento del loop esterno PNTUVECTOR vPointWithOrder ; - // Ciclo sui loop interni del pezzo + // Ciclo sui loop interni del pezzo int nInnerLoopNum = int( vNewPieces[nPieceN].vPieceLoop.size()) ; for ( int nInnLoop = 1 ; nInnLoop < nInnerLoopNum ; ++ nInnLoop) { - // Ciclo sui punti del loop interno. + // Ciclo sui punti del loop interno. Point3d ptInnPoint ; bool bIsFirst = true ; bool bContinue = vNewPieces[nPieceN].vPieceLoop[nInnLoop].GetFirstPoint( ptInnPoint) ; @@ -3774,7 +3796,7 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet bContinue = vNewPieces[nPieceN].vPieceLoop[nInnLoop].GetNextPoint( ptInnPoint) ; } } - // Riordino i punti interni sul segmento esterno in funzione della distanza dall'origine di esso + // 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) { @@ -3782,13 +3804,13 @@ SurfTriMesh::SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet } } } - // Aggiungo i punti al loop esterno + // Aggiungo i punti al loop esterno for ( int nPi = 0 ; nPi < int( vPointWithOrder.size()) ; ++ nPi) { itSt = ExtLoopList.emplace( itEn, vPointWithOrder[nPi]) ; } } } - // Se non ho diviso la faccia, la elimino + // Se non ho diviso la faccia, la elimino if ( int( vNewPieces.size()) == 1) NewFacet.erase( it->first) ; } @@ -4168,7 +4190,7 @@ SurfTriMesh::RetriangulateFacetPieces( const PieceMap& NewFacet, //---------------------------------------------------------------------------- bool -SurfTriMesh::ItersectTriMeshFacets( SurfTriMesh& Other) +SurfTriMesh::IntersectTriMeshFacets( SurfTriMesh& Other) { //////////////////////////////////////////////////////////////////////////////////////////////////////// static int nTime = 0 ; diff --git a/VolZmapCreation.cpp b/VolZmapCreation.cpp index 583df4c..681bf34 100644 --- a/VolZmapCreation.cpp +++ b/VolZmapCreation.cpp @@ -220,7 +220,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, IntersectionResults) ; + Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ; // Analizzo le parti in cui la retta è stata divisa int nPart = int( IntersectionResults.size()) ; @@ -327,7 +327,7 @@ VolZmap::CreateFromFlatRegion( const ISurfFlatRegion& Surf, double dDimZ, double // Determino le intersezioni della retta con la regione CRVCVECTOR IntersectionResults ; - Surf.GetCurveClassification( GridLine, IntersectionResults) ; + Surf.GetCurveClassification( GridLine, EPS_SMALL, IntersectionResults) ; // Analizzo le parti int nPart = int( IntersectionResults.size()) ;