From 971a76e4738e7c00492e8210f56e9d0d5d4a3269 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Tue, 7 May 2024 11:23:49 +0200 Subject: [PATCH] EgtGeomKernel : - in CAvToolSurfTm corretto segno parametro spostamento della posizione - migliorata RemoveAlignedPoints di PolyLine con controllo punto iniziale di percorsi chiusi - modificate GetSurfTriMeshSharpRectSwept e GetSurfTriMeshBeveledRectSwept per generare superfici chiuse. --- CAvToolSurfTm.cpp | 5 +- PolyLine.cpp | 8 +++ StmFromCurves.cpp | 146 +++++++++++++++++++++++++++++++++++++++------- 3 files changed, 136 insertions(+), 23 deletions(-) diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index baea710..5383a11 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -212,8 +212,9 @@ CAvToolSurfTm::TestSubPath( int nId, PNTULIST& lPntM, const Vector3d& vtDir, dou while ( itPntMCurr != lPntM.end()) { // verifico il punto ptCurr = itPntMCurr->first ; - itPntMCurr->second = MyTestPositionHG( itPntMCurr->first, vtDir) ; - if ( itPntMCurr->second < - EPS_SMALL) + double dMove = MyTestPositionHG( itPntMCurr->first, vtDir) ; + itPntMCurr->second = - dMove ; + if ( dMove < - EPS_SMALL) return false ; // se esiste il punto precedente devo verificare il medio if ( itPntMPrev != lPntM.end()) { diff --git a/PolyLine.cpp b/PolyLine.cpp index 83400c9..7d2d747 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -812,6 +812,14 @@ PolyLine::RemoveAlignedPoints( double dToler) // ordino in senso crescente sort( vInd.begin(), vInd.end()) ; + // se chiusa e almeno 4 punti rimasti, controllo allineamento dell'inizio con precedente e successivo rimasti + if ( IsClosed() && vInd.size() >= 4) { + if ( DistPointLine( vPtU[vInd[0]].first, vPtU[vInd[1]].first, vPtU[vInd[vInd.size()-2]].first).IsEpsilon( dToler)) { + vInd.erase( vInd.begin()) ; + vInd.back() = vInd.front() ; + } + } + // rimetto in lista i soli punti rimasti m_lUPoints.clear() ; for ( auto Ind : vInd) diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index 156dcca..2d6d14e 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -365,36 +365,43 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, if ( IsNull( pSrfLft)) return nullptr ; // unisco le parti - PtrOwner pSTM( Release( pSrfTop)) ; - pSTM->DoSewing( *pSrfRgt) ; - pSTM->DoSewing( *pSrfLft) ; - pSTM->DoSewing( *pSrfBot) ; - // salvo tolleranza lineare usata e imposto angolo per smooth - pSTM->SetLinearTolerance( dLinTol) ; - pSTM->SetSmoothAngle( 20) ; + int nBuckets = max( 2 * ( pSrfRgt->GetVertexSize() + pSrfLft->GetVertexSize()), 1000) ; + StmFromTriangleSoup stmSoup ; + if ( ! stmSoup.Start( nBuckets)) + return nullptr ; + stmSoup.AddSurfTriMesh( *pSrfTop) ; + stmSoup.AddSurfTriMesh( *pSrfRgt) ; + stmSoup.AddSurfTriMesh( *pSrfLft) ; + stmSoup.AddSurfTriMesh( *pSrfBot) ; + PtrOwner pSTM ; // se guida aperta e tappi piatti if ( ! bGuideClosed && nCapType == RSCAP_FLAT) { + // completo unione e recupero la superficie risultante + if ( ! stmSoup.End()) + return nullptr ; + pSTM.Set( stmSoup.GetSurf()) ; // verifico che le due estremità siano chiuse e piatte POLYLINEVECTOR vPL ; if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2) return nullptr ; Plane3d plEnds ; double dArea ; - if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) + if ( ! vPL[0].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL)) return nullptr ; - if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 100 * EPS_SMALL)) + if ( ! vPL[1].IsClosedAndFlat( plEnds, dArea, 50 * EPS_SMALL)) return nullptr ; - // aggiungo il cap sull'inizio + // calcolo il cap sull'inizio PtrOwner pSci( CreateBasicSurfTriMesh()) ; if ( IsNull( pSci) || ! pSci->CreateByFlatContour( vPL[0])) return nullptr ; pSci->Invert() ; - pSTM->DoSewing( *pSci) ; - // aggiungo il cap sulla fine + // calcolo il cap sulla fine PtrOwner pSce( CreateBasicSurfTriMesh()) ; if ( IsNull( pSce) || ! pSce->CreateByFlatContour( vPL[1])) return nullptr ; pSce->Invert() ; - pSTM->DoSewing( *pSce) ; + // cucio i tappi all'estrusione + if ( ! pSTM->DoSewing( *pSci) || ! pSTM->DoSewing( *pSce)) + return nullptr ; } // se altrimenti guida aperta e tappi arrotondati if ( ! bGuideClosed && ( nCapType == RSCAP_ROUND || nCapType == RSCAP_BEVEL)) { @@ -415,7 +422,29 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) return nullptr ; pSci->Invert() ; - pSTM->DoSewing( *pSci) ; + // per le facce con normale parallela a vtNorm, evito di creare giunzioni a T sull'asse di rotazione + for ( int i = 0 ; i < pSci->GetFacetCount() ; ++ i) { + Vector3d vtN ; + // se la faccia ha normale parallela a vtNorm... + if ( pSci->GetFacetNormal( i, vtN) && + AreSameOrOppositeVectorEpsilon( vtN, vtNorm, 5 * EPS_SMALL)) { + // ... ricavo il loop + POLYLINEVECTOR vLoops ; + if ( ! pSci->GetFacetLoops( i, vLoops) || vLoops.empty()) + return nullptr ; + // lo semplifico + vLoops[0].RemoveAlignedPoints( 5 * EPS_SMALL) ; + // eseguo triangolazione e aggiungo la faccia alla Soup + PtrOwner pStmNewFace( CreateSurfTriMesh()) ; + if ( IsNull( pStmNewFace) || + ! pStmNewFace->CreateByFlatContour( vLoops[0])) + return nullptr ; + stmSoup.AddSurfTriMesh( *pStmNewFace) ; + } + // altrimenti faccia con normale non parallela a vtNorm, aggiungo tutti i triangoli + else + stmSoup.AddSurfTriMesh( *pSci->CloneFacet( i)) ; + } // aggiungo il cap sulla fine Point3d ptEnd ; pGuide->GetEndPoint( ptEnd) ; @@ -431,8 +460,43 @@ GetSurfTriMeshSharpRectSwept( double dDimH, double dDimV, const ICurve* pGuide, if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) return nullptr ; pSce->Invert() ; - pSTM->DoSewing( *pSce) ; + // per le facce con normale parallela a vtNorm, evito di creare giunzioni a T sull'asse di rotazione + for ( int i = 0 ; i < pSce->GetFacetCount() ; ++ i) { + Vector3d vtN ; + // se la faccia ha normale parallela a vtNorm... + if ( pSce->GetFacetNormal( i, vtN) && + AreSameOrOppositeVectorEpsilon( vtN, vtNorm, 5 * EPS_SMALL)) { + // ... ricavo il loop + POLYLINEVECTOR vLoops ; + if ( ! pSce->GetFacetLoops( i, vLoops) || vLoops.empty()) + return nullptr ; + // lo semplifico + vLoops[0].RemoveAlignedPoints( 5 * EPS_SMALL) ; + // eseguo triangolazione e aggiungo la faccia alla Soup + PtrOwner pStmNewFace( CreateSurfTriMesh()) ; + if ( IsNull( pStmNewFace) || + ! pStmNewFace->CreateByFlatContour( vLoops[0])) + return nullptr ; + stmSoup.AddSurfTriMesh( *pStmNewFace) ; + } + // altrimenti faccia con normale non parallela a vtNorm, aggiungo tutti i triangoli + else + stmSoup.AddSurfTriMesh( *pSce->CloneFacet( i)) ; + } + // completo unione e recupero la superficie risultante + if ( ! stmSoup.End()) + return nullptr ; + pSTM.Set( stmSoup.GetSurf()) ; } + else { + // completo unione e recupero la superficie risultante + if ( ! stmSoup.End()) + return nullptr ; + pSTM.Set( stmSoup.GetSurf()) ; + } + // salvo tolleranza lineare usata e imposto angolo per smooth + pSTM->SetLinearTolerance( dLinTol) ; + pSTM->SetSmoothAngle( 20) ; // restituisco la superficie return Release( pSTM) ; } @@ -549,10 +613,6 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub if ( ! stmSoup.End()) return nullptr ; pSTM.Set( stmSoup.GetSurf()) ; - // preparo seconda zuppa di triangoli per inserire i tappi - StmFromTriangleSoup stmCapSoup ; - if ( ! stmCapSoup.Start( nBuckets)) - return nullptr ; // verifico che le due estremità siano chiuse e piatte POLYLINEVECTOR vPL ; if ( ! pSTM->GetLoops( vPL) || vPL.size() != 2) @@ -597,7 +657,29 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub if ( IsNull( pSci) || ! pSci->CreateByScrewing( PLStart, ptStart, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) return nullptr ; pSci->Invert() ; - stmSoup.AddSurfTriMesh( *pSci) ; + // per le facce con normale parallela a vtNorm, evito di creare giunzioni a T sull'asse di rotazione + for ( int i = 0 ; i < pSci->GetFacetCount() ; ++ i) { + Vector3d vtN ; + // se la faccia ha normale parallela a vtNorm... + if ( pSci->GetFacetNormal( i, vtN) && + AreSameOrOppositeVectorEpsilon( vtN, vtNorm, 5 * EPS_SMALL)) { + // ... ricavo il loop + POLYLINEVECTOR vLoops ; + if ( ! pSci->GetFacetLoops( i, vLoops) || vLoops.empty()) + return nullptr ; + // lo semplifico + vLoops[0].RemoveAlignedPoints( 5 * EPS_SMALL) ; + // eseguo triangolazione e aggiungo la faccia alla Soup + PtrOwner pStmNewFace( CreateSurfTriMesh()) ; + if ( IsNull( pStmNewFace) || + ! pStmNewFace->CreateByFlatContour( vLoops[0])) + return nullptr ; + stmSoup.AddSurfTriMesh( *pStmNewFace) ; + } + // altrimenti faccia con normale non parallela a vtNorm, aggiungo tutti i triangoli + else + stmSoup.AddSurfTriMesh( *pSci->CloneFacet( i)) ; + } // aggiungo il cap sulla fine Point3d ptEnd ; pGuide->GetEndPoint( ptEnd) ; @@ -615,7 +697,29 @@ GetSurfTriMeshBeveledRectSwept( double dDimH, double dDimV, double dBevelH, doub if ( IsNull( pSce) || ! pSce->CreateByScrewing( PLEnd, ptEnd, vtNorm, ANG_STRAIGHT, dStepRotDeg, 0)) return nullptr ; pSce->Invert() ; - stmSoup.AddSurfTriMesh( *pSce) ; + // per le facce con normale parallela a vtNorm, evito di creare giunzioni a T sull'asse di rotazione + for ( int i = 0 ; i < pSce->GetFacetCount() ; ++ i) { + Vector3d vtN ; + // se la faccia ha normale parallela a vtNorm... + if ( pSce->GetFacetNormal( i, vtN) && + AreSameOrOppositeVectorEpsilon( vtN, vtNorm, 5 * EPS_SMALL)) { + // ... ricavo il loop + POLYLINEVECTOR vLoops ; + if ( ! pSce->GetFacetLoops( i, vLoops) || vLoops.empty()) + return nullptr ; + // lo semplifico + vLoops[0].RemoveAlignedPoints( 5 * EPS_SMALL) ; + // eseguo triangolazione e aggiungo la faccia alla Soup + PtrOwner pStmNewFace( CreateSurfTriMesh()) ; + if ( IsNull( pStmNewFace) || + ! pStmNewFace->CreateByFlatContour( vLoops[0])) + return nullptr ; + stmSoup.AddSurfTriMesh( *pStmNewFace) ; + } + // altrimenti faccia con normale non parallela a vtNorm, aggiungo tutti i triangoli + else + stmSoup.AddSurfTriMesh( *pSce->CloneFacet( i)) ; + } // completo unione e recupero la superficie risultante if ( ! stmSoup.End()) return nullptr ;