From 985b69ae339614e5093a83eefc0baf5a4aba9c9a Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 12 Feb 2026 16:17:11 +0100 Subject: [PATCH] EgtGeomKernel : - correzione alla triangolazione delle bezier. - riduzione della dimensione minima dei triangoli nelle surf bezier. --- SurfBezier.cpp | 4 +-- SurfBezier.h | 2 +- Tree.cpp | 87 ++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 88 insertions(+), 5 deletions(-) diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 479eb5c..cb59300 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1820,7 +1820,7 @@ SurfBezier::GetAuxSurf( void) const } } // eseguo calcolo - m_pSTM = GetApproxSurf( s_dAuxSurfTol, 100 * EPS_SMALL, false) ; + m_pSTM = GetApproxSurf( s_dAuxSurfTol, 10 * EPS_SMALL, false) ; ++nSurf ; if ( m_pSTM != nullptr) m_pSTM->SetTempParam( s_dAuxSurfTol) ; @@ -1855,7 +1855,7 @@ SurfBezier::GetAuxSurfRefined( void) const } } // eseguo calcolo - m_pSTMRefined = GetApproxSurf( s_dAuxSurfRefinedTol, 100 * EPS_SMALL, true) ; + m_pSTMRefined = GetApproxSurf( s_dAuxSurfRefinedTol, 10 * EPS_SMALL, true) ; if ( m_pSTMRefined != nullptr) m_pSTMRefined->SetTempParam( s_dAuxSurfRefinedTol) ; return m_pSTMRefined ; diff --git a/SurfBezier.h b/SurfBezier.h index efdec9b..e3c7faf 100644 --- a/SurfBezier.h +++ b/SurfBezier.h @@ -116,7 +116,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW bool GetControlCurveOnV( int nIndU, PolyLine& plCtrlV) const override ; const SurfTriMesh* GetAuxSurf( void) const override ; const SurfTriMesh* GetAuxSurfRefined( void) const override ; - SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 100 * EPS_SMALL, bool bUpdateEdges = false) const override ; + SurfTriMesh* GetApproxSurf( double dTol, double dSideMin = 10 * EPS_SMALL, bool bUpdateEdges = false) const override ; // funzione per ottenere la suddivisione dello spazio parametrico nelle celle utilizzate per la triangolazione. bool GetLeaves( std::vector>& vLeaves) const override ; bool GetTriangles2D( std::vector>& vTria2D) const override ; diff --git a/Tree.cpp b/Tree.cpp index 1150b69..7713ff7 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -664,8 +664,18 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } } + // calcolo se la parte di superficie nella cella è piatta + PolyLine PL ; + PL.AddUPoint( 0, ptP00) ; + PL.AddUPoint( 1, ptP10) ; + PL.AddUPoint( 2, ptP11) ; + PL.AddUPoint( 3, ptP01) ; + PL.AddUPoint( 4, ptCen) ; + Plane3d plPlane ; + bool bIsFlat = PL.IsFlat( plPlane, dLinTol) ; + // su isoparametriche in U e V - if ( dSagU < dLinTol && dSagV < dLinTol) { + if ( dSagU < dLinTol && dSagV < dLinTol && ! bIsFlat) { // step di verifica in U e in V int nStepU = ( dLenParU > 1. / m_nDegU ? m_nDegU + 1 : 2) ; int nStepV = ( dLenParV > 1. / m_nDegV ? m_nDegV + 1 : 2) ; @@ -726,6 +736,73 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) //{ string sLog = " Da Isoparam : FrecciaU=" + ToString( dSagU, 3) + " FrecciaV=" + ToString( dSagV, 3) ; // LOG_DBG_INFO( GetEGkLogger(), sLog.c_str())} } + else if ( dSagU < dLinTol && dSagV < dLinTol && bIsFlat) { + // se la cella è piatta devo verificare che i bordi siano dei tratti retti, altrimenti potrei commettere un errore di approssimazione + + // bordo inferiore e superiore + double dMaxDist = 0 ; + for ( int i = 0 ; i < 2 ; ++i) { + CurveLine clU ; + if ( i == 0) + clU.Set( ptP00, ptP10) ; + else if ( i == 1) + clU.Set( ptP01, ptP11) ; + double dV = 0 ; + if ( i == 0) + dV = pcToSplit->GetBottomLeft().y ; + else if ( i == 1) + dV = pcToSplit->GetTopRight().y ; + + + int nStepU = 4 ; + for ( int j = 1 ; j < nStepU ; ++ j) { + // parametro U + double dCoeffU = double( j) / nStepU ; + double dU = ( 1 - dCoeffU) * pcToSplit->GetBottomLeft().x + dCoeffU * pcToSplit->GetTopRight().x ; + Point3d ptBez ; + GetPoint( dU, dV, ptBez) ; + DistPointCurve dpc( ptBez, clU) ; + double dDist = 0 ; + dpc.GetDist( dDist) ; + if ( dDist > dMaxDist) + dMaxDist = dDist ; + } + } + if ( dMaxDist > dLinTol) + dSagU = dMaxDist ; + + // bordo sinistro e destro + dMaxDist = 0 ; + for ( int i = 0 ; i < 2 ; ++i) { + CurveLine clV ; + if ( i == 0) + clV.Set( ptP00, ptP01) ; + else if ( i == 1) + clV.Set( ptP10, ptP11) ; + double dU = 0 ; + if ( i == 0) + dU = pcToSplit->GetBottomLeft().x ; + else if ( i == 1) + dU = pcToSplit->GetTopRight().x ; + + int nStepV = 4 ; + for ( int j = 1 ; j < nStepV ; ++ j) { + // parametro in V + double dCoeffV = double( j) / nStepV ; + double dV = ( 1 - dCoeffV) * pcToSplit->GetBottomLeft().y + dCoeffV * pcToSplit->GetTopRight().y ; + Point3d ptBez ; + GetPoint( dU, dV, ptBez) ; + DistPointCurve dpc( ptBez, clV) ; + double dDist = 0 ; + dpc.GetDist( dDist) ; + if ( dDist > dMaxDist) + dMaxDist = dDist ; + } + } + if ( dMaxDist > dLinTol) + dSagV = dMaxDist ; + } + // per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza // misura approssimativa della curvatura in una direzione @@ -736,7 +813,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) bVert = false ; else bVert = ( dSagV <= dSagU) ; - pcToSplit->SetSplitDirVert( bVert) ; + bool bFirstTry = true ; + retry : // verifico che la cella sia da splittare e che eventualmente sia abbastanza grande da poterlo fare double dSideMinVal = 0 ; double dLengMinVal = 0 ; @@ -778,6 +856,11 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax) } else if ( dSagV > dLinTol || dSagU > dLinTol) { bSplit = bDimOk ; + if ( ! bSplit && bFirstTry) { + bFirstTry = false ; + bVert = ! bVert ; + goto retry ; + } //if ( bSplit) // LOG_DBG_INFO( GetEGkLogger(), " Split by SagittaUV") }