From 8c79bbb2b619ff1a6f85f85311cf2c4217bbccc4 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Wed, 10 May 2023 15:35:42 +0200 Subject: [PATCH] =?UTF-8?q?EgtGeomKernel=20:=20-=20completata=20l'implemen?= =?UTF-8?q?tazione=20della=20tassellazione=20adattiva=20per=20una=20superf?= =?UTF-8?q?icie=20di=20bezier=20(=20si=20pu=C3=B2=20migliorare=20il=20cost?= =?UTF-8?q?o=20di=20memoria=20e=20computazionale)=20-=20manca=20la=20gesti?= =?UTF-8?q?one=20del=20trim=20dello=20spazio=20parametrico.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- SurfBezier.cpp | 131 ++++++++++++++-------- Tree.cpp | 292 +++++++++++++++++++++++++++++++++---------------- Tree.h | 6 +- 3 files changed, 288 insertions(+), 141 deletions(-) diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 7106029..a5f7245 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -1534,62 +1534,101 @@ SurfBezier::GetAuxSurf( void) const POLYLINEVECTOR vPL ; Tree.GetPolygons( vPL) ; PtrOwner pSrfTm( CreateBasicSurfTriMesh()) ; + StmFromTriangleSoup stmSoup ; + if ( ! stmSoup.Start()) + return nullptr ; - //srfTm.CreateByRegion( vPL) ; // prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d for ( PolyLine i : vPL) { - PtrOwner srfTmCell( CreateBasicSurfTriMesh()) ; PNTVECTOR vPnt ; INTVECTOR vTria ; Triangulate Tri ; if ( ! Tri.Make( i, vPnt, vTria)) return false ; - - // inizializzo la superficie - int nVert = int( vPnt.size()) ; - int nTria = int( vTria.size()) / 3 ; - if ( ! srfTmCell->Init( nVert, nTria)) - return false ; - - // porti i vertici dallo spazio parametrico allo spazio 3d e li inserisco nella superficie - for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { - Point3d pt3d; - GetPointD1D2( vPnt[i].x, vPnt[i].y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; - if ( srfTmCell->AddVertex( pt3d) == SVT_NULL) - //if ( srfTmCell->AddVertex( vPnt[i]) == SVT_NULL ) - return false ; - } - - // recupero i triangoli e li inserisco nella superficie - int vV[3] ; - for ( int i = 0 ; i < nTria ; ++i) { - vV[0] = vTria[3*i] ; - vV[1] = vTria[3*i+1] ; - vV[2] = vTria[3*i+2] ; - if ( srfTmCell->AddTriangle( vV) == SVT_NULL) - return false ; - } - - // sistemo la topologia - if ( ! srfTmCell->AdjustTopology()) - return false ; - //if ( ! pSrfTm->Add( srfTmCell)) - // return false ; - - if ( ! pSrfTm->IsValid() ) { - //pSrfTm.Set( CloneBasicSurfTriMesh(srfTmCell)) ; - pSrfTm.Set( Release(srfTmCell)) ; - } - else { - //if ( ! pSrfTm->Add( *srfTmCell)) - if ( ! pSrfTm->DoSewing( *srfTmCell)) - return false ; - } - - } + // porto i punti in 3d + PNTVECTOR vPnt3d ; + for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { + Point3d pt3d ; + if ( ! GetPointD1D2( vPnt[i].x, vPnt[i].y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d)) + return false ; + vPnt3d.push_back( pt3d) ; + } + int nTria = int( vTria.size()) / 3 ; + for ( int i = 0 ; i < nTria ; ++i) { + if ( ! stmSoup.AddTriangle( vPnt3d[vTria[3*i]], vPnt3d[vTria[3*i+1]], vPnt3d[vTria[3*i+2]])) + return false ; + } + + + // if ( pSrfTm->GetVertexCount() == 0) { + // // inizializzo la superficie + // int nVert = int( vPnt.size()) ; + // int nTria = int( vTria.size()) / 3 ; + // if ( ! pSrfTm->Init( nVert, nTria)) + // return false ; + + // // porti i vertici dallo spazio parametrico allo spazio 3d e li inserisco nella superficie + // for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { + // Point3d pt3d; + // GetPointD1D2( vPnt[i].x, vPnt[i].y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + // if ( pSrfTm->AddVertex( pt3d) == SVT_NULL) + // //if ( srfTmCell->AddVertex( vPnt[i]) == SVT_NULL ) + // return false ; + // } + + // // recupero i triangoli e li inserisco nella superficie + // int vV[3] ; + // for ( int i = 0 ; i < nTria ; ++i) { + // vV[0] = vTria[3*i] ; + // vV[1] = vTria[3*i+1] ; + // vV[2] = vTria[3*i+2] ; + // if ( pSrfTm->AddTriangle( vV) == SVT_NULL) + // return false ; + // } + + // // sistemo la topologia + // if ( ! pSrfTm->AdjustTopology()) + // return false ; + + // //pSrfTm.Set( Release(srfTmCell)) ; + // } + // else { + // // inizializzo la superficie + // int nVert = int( vPnt.size()) ; + // int nTria = int( vTria.size()) / 3 ; + + // // porti i vertici dallo spazio parametrico allo spazio 3d e li inserisco nella superficie + // for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) { + // Point3d pt3d; + // GetPointD1D2( vPnt[i].x, vPnt[i].y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ; + // if ( pSrfTm->AddVertex( pt3d) == SVT_NULL) + // return false ; + // } + + // // recupero i triangoli e li inserisco nella superficie + // int vV[3] ; + // int nVertCount = int ( pSrfTm->GetVertexCount()) - 4 ; + // for ( int i = 0 ; i < nTria ; ++i) { + // vV[0] = vTria[3*i] + nVertCount ; + // vV[1] = vTria[3*i+1] + nVertCount ; + // vV[2] = vTria[3*i+2] + nVertCount ; + // if ( pSrfTm->AddTriangle( vV) == SVT_NULL) + // return false ; + // } + // } + } + // if ( ! pSrfTm->AdjustTopology()) + // return false ; + //// la salvo + // m_pSTM = Release( pSrfTm) ; + + + // la salvo - m_pSTM = Release(pSrfTm) ; + if ( ! stmSoup.End()) + return nullptr ; + m_pSTM = GetBasicSurfTriMesh( stmSoup.GetSurf()) ; } return m_pSTM ; } diff --git a/Tree.cpp b/Tree.cpp index 3d6f8e3..5304f3f 100644 --- a/Tree.cpp +++ b/Tree.cpp @@ -1,4 +1,4 @@ -//---------------------------------------------------------------------------- +//---------------------------------------------------------------------------- // EgalTech 2023 //---------------------------------------------------------------------------- // File : Tree.cpp Data : 21.04.23 Versione : @@ -17,6 +17,9 @@ #include "Tree.h" #include "SurfBezier.h" #include "GeoConst.h" +#include "CurveLine.h" +#include "/EgtDev/Include/EGkPolyLine.h" +#include "/EgtDev/Include/EGkDistPointCurve.h" using namespace std ; @@ -68,7 +71,7 @@ Cell::IsLeaf ( void) //---------------------------------------------------------------------------- Tree::Tree( void) - : m_dLinTol(LIN_TOL_FINE), m_pSrfBz(nullptr), m_nRoot( -1) + : m_dLinTol(LIN_TOL_FINE), m_pSrfBz(nullptr), m_nRoot( -1), m_bTrimmed( false) { Point3d ptBl( 0, 0), ptTr ( 1, 1) ; Cell cRoot( ptBl, ptTr) ; @@ -83,6 +86,7 @@ Tree::Tree( const SurfBezier* pSrfBz) int nDegU, nDegV, nSpanU, nSpanV ; bool bIsRat, bTrimmed ; m_pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ; + m_bTrimmed = bTrimmed ; Point3d ptTop( nSpanU, nSpanV) ; Cell cRoot( ORIG, ptTop) ; m_mTree.insert( pair< int, Cell>( m_nRoot, cRoot)) ; @@ -101,6 +105,7 @@ void Tree::SetSurf( const SurfBezier* pSrfBz) int nDegU, nDegV, nSpanU, nSpanV ; bool bIsRat, bTrimmed ; m_pSrfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bIsRat, bTrimmed) ; + m_bTrimmed = bTrimmed ; Point3d ptTop( nSpanU, nSpanV) ; Cell cRoot( ORIG, ptTop) ; m_mTree.insert( pair< int, Cell>( -1, cRoot)) ; @@ -122,7 +127,7 @@ Tree::Split( int nId) m_mTree.insert( pair( nNodes, cChild2)) ; if ( ! m_mTree[nId].IsSplitVert()) { - // la cella figlio 1 è quella sopra + // la cella figlio 1 è quella sopra Point3d ptBL( m_mTree[nId].GetBottomLeft().x, ( m_mTree[nId].GetBottomLeft().y + m_mTree[nId].GetTopRight().y) / 2) ; m_mTree[m_mTree[nId].m_nChild1].SetBottomLeft( ptBL) ; m_mTree[m_mTree[nId].m_nChild1].SetTopRight( m_mTree[nId].GetTopRight()) ; @@ -139,7 +144,7 @@ Tree::Split( int nId) m_mTree[m_mTree[nId].m_nChild2].m_nRight = m_mTree[nId].m_nRight ; } else { - // la cella figlio 1 è quella di sinistra + // la cella figlio 1 è quella di sinistra Point3d ptTR( ( m_mTree[nId].GetBottomLeft().x + m_mTree[nId].GetTopRight().x) / 2, m_mTree[nId].GetTopRight().y) ; m_mTree[m_mTree[nId].m_nChild1].SetBottomLeft( m_mTree[nId].GetBottomLeft()) ; m_mTree[m_mTree[nId].m_nChild1].SetTopRight( ptTR) ; @@ -163,7 +168,7 @@ Tree::Split( int nId) ////---------------------------------------------------------------------------- //bool Tree::BuildTree(void) //{ -// // di default SplitVert è true ! +// // di default SplitVert è true ! // int ToSplit = -1; // m_mTree[ToSplit].SetSplitDirVert( true) ; // Split( ToSplit) ; @@ -207,24 +212,40 @@ Tree::Split( int nId) // return true ; //} +////---------------------------------------------------------------------------- +//bool Tree::BuildTree( void) +//{ +// int ToSplit = -1 ; +// m_mTree[ToSplit].SetSplitDirVert( true) ; +// Split( ToSplit) ; +// // celle 2 e 3 +// ToSplit = m_mTree[-1].m_nChild1 ; +// m_mTree[ToSplit].SetSplitDirVert( false) ; +// Split( ToSplit) ; +// +// return true ; +//} //---------------------------------------------------------------------------- -bool Tree::BuildTree( void) +bool Tree::BuildTree( double dLinTol, double dSideMax) { // trovo dove splittare la cella e creo i puntatori ai figli // comincio a suddividere la superficie usando un kd-tree - // approssimo con una bilineare e se l'errore di approssimazione è troppo grande cerco una direzione + // approssimo con una bilineare e se l'errore di approssimazione è troppo grande cerco una direzione // in cui dividere la superficie double dErr ; // errore calcolato double dDist; // distanza tra punti selezionati sulla isoparametrica - double dSide ; // lunghezza del lato della eventuale cella figlio - double dSplit = 0.5 ; // effettuo sempre split a metà - //double dSidemin = 0.05 ; // lunghezza minima del lato di una cella - double dSidemin = 0.1 ; // lunghezza minima del lato di una cella + double dSideMinVal, dSideMaxVal ; // lunghezza del lato della eventuale cella figlio + double dSplit = 0.5 ; // effettuo sempre split a metà + double dSideMin = 0.05 ; // lunghezza minima del lato di una cella + //double dSidemin = 0.1 ; // lunghezza minima del lato di una cella + //m_dLinTol = dLinTol ; + m_dLinTol = 0.2 ; int nSteps = 51 ; // numero di Step mentre scorro lungo un'isoparametrica - double dU, dV , dIter, dIterLoc, dULoc, dVLoc ; + double dU, dV , dULoc, dVLoc ; + //double dIter, dIterLoc ; bool bVert ; Point3d ptBz, ptBl ; // cerco lo scostamento massimo tra la sup di Bezier e la sua approssimazione bilineare @@ -234,59 +255,123 @@ bool Tree::BuildTree( void) int c = 1 ; while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) { dErr = 0 ; - // verifico se l'approsimazione bilineare è ancora troppo distante dalla superficie reale - // calcolo la bilineare per gli estremi della cella - SurfBezier pSrfBl ; - pSrfBl.Init(1, 1, 1, 1, false) ; - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; - pSrfBl.SetControlPoint( 0, ptBz) ; // P00 - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; - pSrfBl.SetControlPoint( 1, ptBz) ; // P01 - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; - pSrfBl.SetControlPoint( 2, ptBz) ; // P10 - m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; - pSrfBl.SetControlPoint( 3, ptBz) ; // P11 - // scorro lungo le isoparametriche a questi valori di U e V per trovare dov'è il punto di maggior discostamento - dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; - dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; - dULoc = dU - m_mTree[nCToSplit].GetBottomLeft().x / ( m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x) ; - dVLoc = dV - m_mTree[nCToSplit].GetBottomLeft().y / ( m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y) ; - double dErrUmax, dErrVmax ; - for ( int i = 0 ; i < nSteps ; ++ i){ - dIter = double ( i) / double ( nSteps - 1) ; - dIterLoc = ( 1 - dIter) * m_mTree[nCToSplit].GetBottomLeft().y + dIter * m_mTree[nCToSplit].GetTopRight().y ; - if ( ! m_pSrfBz->GetPointD1D2( dU, dIterLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) || - ! pSrfBl.GetPointD1D2( dU, dIter, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBl)) /// dU è riferito alla Bz totale, quant'è sulla Bl?? + // calcolo l'errore di approssimazione + + //// calcolo l'errore di approssimazione confrontando con la bilineare corrispondente + //SurfBezier pSrfBl ; + //pSrfBl.Init(1, 1, 1, 1, false) ; + //m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; + //pSrfBl.SetControlPoint( 0, ptBz) ; // P00 + //m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; + //pSrfBl.SetControlPoint( 1, ptBz) ; // P10 + //m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; + //pSrfBl.SetControlPoint( 2, ptBz) ; // P01 + //m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) ; + //pSrfBl.SetControlPoint( 3, ptBz) ; // P11 + //// scorro lungo le isoparametriche a questi valori di U e V per trovare dov'è il punto di maggior discostamento + //dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; + //dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; + //dULoc = ( dU - m_mTree[nCToSplit].GetBottomLeft().x) / ( m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x) ; + //dVLoc = ( dV - m_mTree[nCToSplit].GetBottomLeft().y) / ( m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y) ; + //double dErrUmax = 0, dErrVmax = 0 ; + //for ( int i = 0 ; i < nSteps ; ++ i){ + // dIter = double ( i) / double ( nSteps - 1) ; + // dIterLoc = ( 1 - dIter) * m_mTree[nCToSplit].GetBottomLeft().y + dIter * m_mTree[nCToSplit].GetTopRight().y ; + // if ( ! m_pSrfBz->GetPointD1D2( dU, dIterLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) || + // ! pSrfBl.GetPointD1D2( dULoc, dIter, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBl)) + // return false ; + // dDist = Dist( ptBz, ptBl) ; + // dErrVmax = max ( dErrVmax, dDist) ; + // if ( dDist > dErr) { + // dErr = dDist ; + // //bVert = true ; + // } + // dIterLoc = ( 1 - dIter) * m_mTree[nCToSplit].GetBottomLeft().x + dIter * m_mTree[nCToSplit].GetTopRight().x ; + // if ( ! m_pSrfBz->GetPointD1D2( dIterLoc, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) || + // ! pSrfBl.GetPointD1D2( dIter, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBl)) + // return false ; + // dDist = Dist( ptBz, ptBl) ; + // dErrUmax = max ( dErrUmax, dDist) ; + // if ( dDist > dErr) { + // dErr = dDist ; + // //bVert = false ; + // } + //} + + Point3d ptP00, ptP10, ptP11, ptP01 ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ; + CurveLine cl0010, cl0001, cl1011, cl0111 ; + // U=0 + cl0010.Set( ptP00, ptP10) ; + //// V=0 + //cl0001.Set( ptP00, ptP01) ; + // U=1 + cl0111.Set( ptP01, ptP11) ; + //// V=1 + //cl0111.Set( ptP01, ptP11) ; + Point3d pt0010, pt0111, ptBz0, ptBz1, ptBzV ; + int nFlag ; + CurveLine clV ; + for ( int u = 0 ; u < nSteps ; ++ u){ + dU = double ( u) / double ( nSteps - 1) ; + dULoc = ( 1 - dU) * m_mTree[nCToSplit].GetBottomLeft().x + dU * m_mTree[nCToSplit].GetTopRight().x ; + if ( ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz0) || + ! m_pSrfBz->GetPointD1D2( dULoc, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz1)) return false ; - dDist = Dist( ptBz, ptBl) ; - if ( dDist > dErr) { - dErr = dDist ; - bVert = true ; - dErrVmax = dErr ; - } - dIterLoc = ( 1 - dIter) * m_mTree[nCToSplit].GetBottomLeft().x + dIter * m_mTree[nCToSplit].GetTopRight().x ; - if ( ! m_pSrfBz->GetPointD1D2( dIterLoc, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBz) || - ! pSrfBl.GetPointD1D2( dIter, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBl)) /// dV è riferito alla Bz totale, quant'è sulla Bl?? - return false ; - dDist = Dist( ptBz, ptBl) ; - if ( dDist > dErr) { - dErr = dDist ; - bVert = false ; - dErrUmax = dErr ; + DistPointCurve dpc0010( ptBz0, cl0010) ; + DistPointCurve dpc0111( ptBz1, cl0111) ; + dpc0010.GetMinDistPoint( 0, pt0010, nFlag) ; + dpc0111.GetMinDistPoint( 0, pt0111, nFlag) ; + clV.Set( pt0010, pt0111) ; + for ( int v = 0 ; v < nSteps ; ++ v){ + dV = double ( v) / double ( nSteps - 1) ; + dVLoc = ( 1 - dV) * m_mTree[nCToSplit].GetBottomLeft().y + dV * m_mTree[nCToSplit].GetTopRight().y ; + if ( ! m_pSrfBz->GetPointD1D2( dULoc, dVLoc, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBzV)) + return false ; + DistPointCurve dpc( ptBzV, clV) ; + dpc.GetDist( dDist) ; + if ( dDist > dErr) + dErr = dDist ; } } + + // calcolo in quale direzione ho più curvatura + // devo trovare i punti sui lati corrispondenti a dUmax e dVmax, unendo queste coppie trovo le due direzioni di possibile split + // punti medi del lato successivo in senso antiorario rispetto al relativo vertice della patch + dU = ( m_mTree[nCToSplit].GetTopRight().x + m_mTree[nCToSplit].GetBottomLeft().x) / 2 ; + dV = ( m_mTree[nCToSplit].GetTopRight().y + m_mTree[nCToSplit].GetBottomLeft().y) / 2 ; + dULoc = dVLoc = 0.5 ; + Point3d ptPSrf ; //ptP00, ptP10, ptP11, ptP01; + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetTopRight().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ; + m_pSrfBz->GetPointD1D2( dU, m_mTree[nCToSplit].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ; + m_pSrfBz->GetPointD1D2( m_mTree[nCToSplit].GetBottomLeft().x, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ; + Point3d ptP00P11 = ( 1 - dULoc) * ptP00 + dULoc * ptP11 ; + Point3d ptP10P01 = ( 1 - dVLoc) * ptP10 + dVLoc * ptP01 ; + // per lo split scelgo la direzione che è più vicina alla superficie originale nel punto di maggior distanza + // effettuo lo split e configuro le celle figlie + if ( Dist(ptP00P11, ptPSrf) > Dist(ptP10P01, ptPSrf)) + // lungo la direzione U ho una curvatura maggiore + bVert = false ; + else + // lungo la direzione V ho una curvatura maggiore + bVert = true ; + // verifico che la cella sia da splittare e che eventualmente sia abbastanza grande da poterlo fare if ( bVert) - dSide = m_mTree[nCToSplit].GetTopRight().x - m_mTree[nCToSplit].GetBottomLeft().x ; + dSideMinVal = min( Dist( ptP00, ptP10), Dist( ptP01, ptP11)) ; else - dSide = m_mTree[nCToSplit].GetTopRight().y - m_mTree[nCToSplit].GetBottomLeft().y ; - if ( dErr > m_dLinTol && dSide >= dSidemin) { + dSideMinVal = min( Dist( ptP00, ptP01), Dist( ptP10, ptP11)) ; + dSideMaxVal = max( Dist( ptP00, ptP11), Dist( ptP10, ptP01)) ; + if ( ( dErr > m_dLinTol && dSideMinVal >= dSideMin) || dSideMaxVal > dSideMax) { m_mTree[nCToSplit].SetSplitDirVert( bVert) ; // effettuo lo split Split( nCToSplit) ; - // qui faccio i check per capire quali celle devo inserire in vBalanceCheck /////////////////////////////////////////////////////// - // procedo con lo split del Child1 nCToSplit = m_mTree[nCToSplit].m_nChild1 ; } @@ -294,7 +379,7 @@ bool Tree::BuildTree( void) // sono arrivato ad una cella Leaf, quindi salvo la cella m_vnLeaves.push_back( nCToSplit) ; m_mTree[nCToSplit].Processed() ; - // risalgo i parent finché non trovo il primo Child2 da processare + // risalgo i parent finché non trovo il primo Child2 da processare nCToSplit = m_mTree[nCToSplit].m_nParent ; if ( m_mTree[m_mTree[nCToSplit].m_nChild1].IsProcessed() && m_mTree[m_mTree[nCToSplit].m_nChild2].IsProcessed()) m_mTree[nCToSplit].Processed() ; @@ -318,7 +403,8 @@ bool Tree::BuildTree( void) void Tree::Balance( INTVECTOR vCheck) { for ( int i : vCheck ) { - + // non ancora implementato + // rendolo il tree balanced : ogni foglia deve avere una profondità di +- 1 rispetto ai suoi vicini. } } @@ -332,13 +418,13 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) vTopNeighs.push_back( m_mTree[nId].m_nTop) ; else { if ( m_mTree[m_mTree[nId].m_nTop].IsSplitVert()) { - // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[m_mTree[nId].m_nTop].GetTopRight().x - m_mTree[m_mTree[nId].m_nTop].GetBottomLeft().x <= m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild1) ; vTopNeighs.push_back( m_mTree[m_mTree[nId].m_nTop].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else{ if ( m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || m_mTree[m_mTree[m_mTree[nId].m_nTop].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) @@ -357,7 +443,7 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) bAllLeaves = false ; } if ( ! bAllLeaves ) - // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child + // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child GetTopNeigh( nId, vTopNeighs) ; } else { @@ -366,17 +452,17 @@ void Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) if ( m_mTree[i].IsLeaf()) continue; else { - // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child + // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vTopNeighs.erase( remove( vTopNeighs.begin(),vTopNeighs.end(),i)) ; -- j ; if ( m_mTree[i].IsSplitVert() ) { - // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <= m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { vTopNeighs.push_back( m_mTree[i].m_nChild1) ; vTopNeighs.push_back( m_mTree[i].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else { if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) @@ -410,13 +496,13 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) vBottomNeighs.push_back( m_mTree[nId].m_nBottom) ; else { if ( m_mTree[m_mTree[nId].m_nBottom].IsSplitVert()) { - // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[m_mTree[nId].m_nBottom].GetTopRight().x - m_mTree[m_mTree[nId].m_nBottom].GetBottomLeft().x <= m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild1) ; vBottomNeighs.push_back( m_mTree[m_mTree[nId].m_nBottom].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else{ if ( m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || m_mTree[m_mTree[m_mTree[nId].m_nBottom].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) @@ -435,7 +521,7 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) bAllLeaves = false ; } if ( ! bAllLeaves ) - // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child + // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child GetBottomNeigh( nId, vBottomNeighs) ; } else { @@ -444,17 +530,17 @@ void Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) if ( m_mTree[i].IsLeaf()) continue; else { - // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child + // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vBottomNeighs.erase( remove( vBottomNeighs.begin(),vBottomNeighs.end(),i)) ; -- j ; if ( m_mTree[i].IsSplitVert()) { - // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[i].GetTopRight().x - m_mTree[i].GetBottomLeft().x <= m_mTree[nId].GetTopRight().x - m_mTree[nId].GetBottomLeft().x) { vBottomNeighs.push_back( m_mTree[i].m_nChild1) ; vBottomNeighs.push_back( m_mTree[i].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else { if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().x <= m_mTree[nId].GetBottomLeft().x || m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().x >= m_mTree[nId].GetTopRight().x ) @@ -489,13 +575,13 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) vLeftNeighs.push_back( m_mTree[nId].m_nLeft) ; else { if ( ! m_mTree[m_mTree[nId].m_nLeft].IsSplitVert()) { - // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[m_mTree[nId].m_nLeft].GetTopRight().y - m_mTree[m_mTree[nId].m_nLeft].GetBottomLeft().y <= m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild1) ; vLeftNeighs.push_back( m_mTree[m_mTree[nId].m_nLeft].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else{ if ( m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || m_mTree[m_mTree[m_mTree[nId].m_nLeft].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y ) @@ -514,7 +600,7 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) bAllLeaves = false ; } if ( ! bAllLeaves ) - // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child + // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child GetLeftNeigh( nId, vLeftNeighs) ; } else { @@ -523,17 +609,17 @@ void Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) if ( m_mTree[i].IsLeaf()) continue; else { - // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child + // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vLeftNeighs.erase( remove( vLeftNeighs.begin(),vLeftNeighs.end(),i)) ; -- j ; if ( ! m_mTree[i].IsSplitVert()) { - // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <= m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { vLeftNeighs.push_back( m_mTree[i].m_nChild1) ; vLeftNeighs.push_back( m_mTree[i].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else { if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y ) @@ -567,13 +653,13 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) vRightNeighs.push_back( m_mTree[nId].m_nRight) ; else { if ( ! m_mTree[m_mTree[nId].m_nRight].IsSplitVert()) { - // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella vicina è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[m_mTree[nId].m_nRight].GetTopRight().y - m_mTree[m_mTree[nId].m_nRight].GetBottomLeft().y <= m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild1) ; vRightNeighs.push_back( m_mTree[m_mTree[nId].m_nRight].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else{ if ( m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || m_mTree[m_mTree[m_mTree[nId].m_nRight].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y ) @@ -592,7 +678,7 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) bAllLeaves = false ; } if ( ! bAllLeaves ) - // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child + // almeno una cella tra i vicini trovati non è leaf quindi devo richiamare ricorsivamente questa funzione per trovare i suoi child GetRightNeigh( nId, vRightNeighs) ; } else { @@ -601,17 +687,17 @@ void Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) if ( m_mTree[i].IsLeaf()) continue; else { - // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child + // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vRightNeighs.erase( remove( vRightNeighs.begin(),vRightNeighs.end(), i)) ; -- j ; if ( ! m_mTree[i].IsSplitVert()) { - // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima + // se la cella è più piccola della cella indagata, allora entrambi i figli saranno vicini di quest'ultima if ( m_mTree[i].GetTopRight().y - m_mTree[i].GetBottomLeft().y <= m_mTree[nId].GetTopRight().y - m_mTree[nId].GetBottomLeft().y) { vRightNeighs.push_back( m_mTree[i].m_nChild1) ; vRightNeighs.push_back( m_mTree[i].m_nChild2) ; } - // altrimenti solo uno dei figli lo sarà + // altrimenti solo uno dei figli lo sarà else { if ( m_mTree[m_mTree[i].m_nChild1].GetTopRight().y <= m_mTree[nId].GetBottomLeft().y || m_mTree[m_mTree[i].m_nChild1].GetBottomLeft().y >= m_mTree[nId].GetTopRight().y ) @@ -645,7 +731,7 @@ int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) vnLeaves.push_back( m_mTree[nId].m_nChild1) ; vnLeaves.push_back( m_mTree[nId].m_nChild2) ; if ( ! m_mTree[m_mTree[nId].m_nChild1].IsLeaf() || ! m_mTree[m_mTree[nId].m_nChild2].IsLeaf()) - // almeno un child non è leaf quindi devo richiamare ricorsivamente questa funzione sui child in questione + // almeno un child non è leaf quindi devo richiamare ricorsivamente questa funzione sui child in questione d = GetHeightLeaves( nId, vnLeaves, m_mTree[m_mTree[nId].m_nChild1].m_nDepth) ; } } @@ -656,7 +742,7 @@ int Tree::GetHeightLeaves( int nId, INTVECTOR& vnLeaves, int d) continue ; } else { - // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child + // se la cella non è leaf la tolgo dal vettore delle foglie e aggiungo invece i suoi child vnLeaves.erase( remove( vnLeaves.begin(),vnLeaves.end(),i)) ; -- j ; vnLeaves.push_back( m_mTree[i].m_nChild1) ; @@ -689,13 +775,11 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) bool bBottomRight , bTopLeft ; // scorro lungo tutte le celle leaves ( dell'albero bilanciato) e oltre agli angoli della cella aggiungo alla polyline anche i vertici sui lati for ( int nId : m_vnLeaves) { - //Point3d ptPbr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; - //Point3d ptPtl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; vVertices.clear() ; vNeigh.clear() ; vVertices.push_back( m_mTree[nId].GetBottomLeft()) ; GetBottomNeigh( nId, vNeigh) ; - // aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom + // aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ for ( int j : vNeigh ) vVertices.push_back( m_mTree[j].GetTopRight()) ; @@ -705,12 +789,12 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) bBottomRight = false ; vNeigh.clear() ; GetRightNeigh ( nId, vNeigh) ; - // aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right + // aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){ for ( int j : vNeigh ) vVertices.push_back( m_mTree[j].GetBottomLeft()) ; } - // se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right + // se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right else if ( ! bBottomRight ) { Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ; vVertices.push_back( ptBr) ; @@ -719,7 +803,7 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) vVertices.push_back( m_mTree[nId].GetTopRight()) ; GetTopNeigh ( nId, vNeigh) ; reverse( vNeigh.begin(), vNeigh.end()) ; - // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top + // aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { for ( int j : vNeigh) vVertices.push_back( m_mTree[j].GetBottomLeft()) ; @@ -730,26 +814,48 @@ bool Tree::GetPolygons( POLYLINEVECTOR& vPolygons) vNeigh.clear() ; GetLeftNeigh ( nId, vNeigh) ; reverse( vNeigh.begin(), vNeigh.end()) ; - // aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left + // aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) { for ( int j : vNeigh) vVertices.push_back( m_mTree[j].GetTopRight()) ; } - // se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left + // se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left else if ( ! bTopLeft) { Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ; vVertices.push_back( ptTl) ; } vNeigh.clear() ; vVertices.push_back( m_mTree[nId].GetBottomLeft()) ; - double k = 0 ; + // se hop una cella con vicino dello stesso grado controllo la curvatura nella cella e + // se necessario cambio l'ordine dei vertici per scegliere la diagonale di split migliore + if ( vVertices.size() == 5) { + Point3d ptPSrf, ptP00, ptP10, ptP11, ptP01; + double dU, dV ; + dU = ( m_mTree[nId].GetBottomLeft().x + m_mTree[nId].GetTopRight().x) / 2 ; + dV = ( m_mTree[nId].GetBottomLeft().y + m_mTree[nId].GetTopRight().y) / 2 ; + m_pSrfBz->GetPointD1D2( dU, dV, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptPSrf) ; + m_pSrfBz->GetPointD1D2( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ; + m_pSrfBz->GetPointD1D2( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ; + m_pSrfBz->GetPointD1D2( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP11) ; + m_pSrfBz->GetPointD1D2( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ; + Point3d ptP00P11 = ( ptP00 + ptP11) / 2 ; + Point3d ptP10P01 = ( ptP10 + ptP01) / 2 ; + // ho la curvatura maggiore sulla diagonale tra P10 e P01, ruoto l'ordine dei vertici, in modo che triangulate prenda la diagonale giusta + if ( Dist(ptP00P11, ptPSrf) > Dist(ptP10P01, ptPSrf)) { + rotate(vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ; + vVertices.back() = vVertices[0] ; + } + } + + //double k = 0 ; m_vPolygons.emplace_back() ; for ( int i = 0 ; i < (int) vVertices.size() ; ++i ) { - k = double( i) / double( vVertices.size()) ; + //k = double( i) / double( vVertices.size()) ; m_vPolygons.back().AddUPoint( i, vVertices[i]) ; } } } + // restituisco i poligoni delle celle del tree nello spazio parametrico vPolygons = m_vPolygons ; return true ; diff --git a/Tree.h b/Tree.h index aab0ac1..4df9a50 100644 --- a/Tree.h +++ b/Tree.h @@ -17,6 +17,7 @@ #include #include "tree.h" #include "SurfBezier.h" +#include "GeoConst.h" //---------------------------------------------------------------------------- class Cell @@ -68,7 +69,7 @@ public : Tree( void) ; Tree ( const SurfBezier* pSrfBz) ; void SetSurf( const SurfBezier* pSrfBz) ; - bool BuildTree() ; + bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMax = INFINITO) ; // dSidemax è il massimo per la dimensione maggiore di un triangolo della trimesh bool GetPolygons( POLYLINEVECTOR& vPolygons) ; private : @@ -86,7 +87,8 @@ private : double m_dLinTol ; // errore dell'approssimazione int m_nRoot ; // cella base const SurfBezier* m_pSrfBz ; // root + bool m_bTrimmed ; // superficie trimmata POLYLINEVECTOR m_vPolygons ; // vettore dei poligoni del kd-tree std::map m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root - INTVECTOR m_vnLeaves ; // vettore delle foglie + INTVECTOR m_vnLeaves ; // vettore delle foglie } ; \ No newline at end of file