From a67a0502fadd295f4b9c0466e567916f8fa9762e Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Tue, 10 Sep 2024 09:19:28 +0200 Subject: [PATCH] EgtGeomKernel : - correzioni alla triangolazione di una surf di bezier (split iniziale). --- Tree.cpp | 76 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/Tree.cpp b/Tree.cpp index 2388616..fdb72cd 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -283,40 +283,51 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_vnParents.clear() ; bool bIsPlanar = m_pSrfBz->IsPlanar() ; if( ! bIsPlanar || m_bMulti) { - if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) { + // se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo + if ( AreSamePointApprox(ptP00, ptP10) && AreSamePointApprox(ptP01, ptP11) ) { + m_mTree[-1].m_nLeft = -1 ; + m_mTree[-1].m_nRight = -1 ; + m_bClosedU = true ; + } + // se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo + if ( ( AreSamePointApprox(ptP00, ptP01) && AreSamePointApprox(ptP10, ptP11) ) ) { + m_mTree[-1].m_nTop = -1 ; + m_mTree[-1].m_nBottom = -1 ; + m_bClosedV = true ; + } + if ( (m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) || m_bClosedU || m_bClosedV) { int nId = -1 ; - // se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo - if ( AreSamePointApprox(ptP00, ptP10) && AreSamePointApprox(ptP01, ptP11) ) { - m_mTree[-1].m_nLeft = -1 ; - m_mTree[-1].m_nRight = -1 ; - m_bClosedU = true ; + int nSplit = nSpanU ; + bool bSplitInHalf = false ; + // se la superficie è chiusa lungo un parametro la splitto lungo quel parametro almeno una volta + if( m_bClosedU && nSpanU == 1) { + nSplit = 2 ; + bSplitInHalf = true ; } - // se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo - if ( ( AreSamePointApprox(ptP00, ptP01) && AreSamePointApprox(ptP10, ptP11) ) ) { - m_mTree[-1].m_nTop = -1 ; - m_mTree[-1].m_nBottom = -1 ; - m_bClosedV = true ; - } - for ( int i = 1 ; i < nSpanU ; ++i) { - // chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000) - if ( i * SBZ_TREG_COEFF > ptMin.x + 5 && i * SBZ_TREG_COEFF < ptTop.x - 5){ - m_mTree[nId].SetSplitDirVert( true) ; - if ( Split( nId, i * SBZ_TREG_COEFF)) { - ++ nId ; - ++ nId ; - } + for ( int i = 1 ; i < nSplit ; ++i) { + m_mTree[nId].SetSplitDirVert( true) ; + double dSplit = bSplitInHalf ? i * SBZ_TREG_COEFF / 2 : i * SBZ_TREG_COEFF ; + if ( Split( nId, dSplit)) { + //++ nId ; + //++ nId ; + nId = m_mTree[nId].m_nChild2 ; } } INTVECTOR vLeaves ; GetHeightLeaves( -1, vLeaves) ; + nSplit = nSpanV - 1 ; + bSplitInHalf = false ; + // se la superficie è chiusa lungo un parametro la splitto lungo quel parametro almeno una volta + if( m_bClosedV && nSpanV == 1) { + nSplit = 1 ; + bSplitInHalf = true ; + } for ( int nId : vLeaves) { - for ( int j = nSpanV - 1 ; j > 0 ; --j) { - // chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000) - if ( j * SBZ_TREG_COEFF > ptMin.y + 5 && j * SBZ_TREG_COEFF < ptTop.y - 5){ - m_mTree[nId].SetSplitDirVert( false) ; - if ( Split( nId, j * SBZ_TREG_COEFF)) - nId = m_mTree[nId].m_nChild2 ; - } + for ( int j = nSplit ; j > 0 ; --j) { + m_mTree[nId].SetSplitDirVert( false) ; + double dSplit = bSplitInHalf ? j * SBZ_TREG_COEFF / 2 : j * SBZ_TREG_COEFF ; + if ( Split( nId, dSplit)) + nId = m_mTree[nId].m_nChild2 ; } } vLeaves.clear() ; @@ -326,9 +337,10 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi // e sistemo le adiacenze if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) || ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11))) { - // m_bClosed = true ; if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11))) { - if( int( m_mTree.size()) == 1) { + + ////questo in teoria non serve più perché lo faccio appena sopra + if( int( m_mTree.size()) == 1) { if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) { m_mTree[-1].m_nTop = -1 ; m_mTree[-1].m_nBottom = -1 ; @@ -337,6 +349,8 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_mTree[-1].SetSplitDirVert( false) ; Split( -1) ; } + //////// + // qui devo fare il controllo capped ( chiusura a semisfera) // devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti // in caso devo fare uno split nell'altra direzione @@ -361,6 +375,8 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi } // nella condizione di questo if non controllo eventuali divisioni preliminari, perché ne tengo conto dopo if ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11)) { + + //// questo in teoria non serve più perché lo faccio sopra if ( m_mTree.size() == 1) { if ( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11)) { m_mTree[-1].m_nLeft = -1 ; @@ -370,6 +386,8 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi m_mTree[-1].SetSplitDirVert( true) ; Split( -1) ; } + //////// + // devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti // in caso devo fare uno split nell'altra direzione bool bOk = false ;