- pulizia del codice.

This commit is contained in:
Daniele Bariletti
2025-03-25 12:37:13 +01:00
parent 71276a8de3
commit 851c053f7c
4 changed files with 390 additions and 463 deletions
+387 -441
View File
@@ -104,12 +104,6 @@ Tree::AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation)
bool
Tree::GetPoint( double dU, double dV, Point3d& pt) const
{
//INTINT key ( int( dU * pow(2,15)), int( dV * pow(2,15))) ;
//INTINT key ( int( dU * 100), int( dV * 100)) ;
//if (dU > 100000 || dV > 100000)
// int a = 0 ;
//double dDecimal = 5 ;
//DBLDBL key( trunc(dU * dDecimal) / dDecimal, trunc(dV * dDecimal) / dDecimal) ;
pair<int64_t, int64_t> key (static_cast<int64_t>(dU * pow(2,15)), static_cast<int64_t>(dV * pow(2,15))) ;
bool bOk = true ;
if ( m_mPt3d.find( key) == m_mPt3d.end()) {
@@ -124,12 +118,6 @@ Tree::GetPoint( double dU, double dV, Point3d& pt) const
bool
Tree::SavePoint( double dU, double dV, Point3d& pt)
{
//INTINT key ( int( dU * pow(2,15)), int( dV * pow(2,15))) ;
//INTINT key ( int( dU * 100), int( dV * 100)) ;
//if (dU > 100000 || dV > 100000)
// int a = 0 ;
//double dDecimal = 5 ;
//DBLDBL key( trunc(dU * dDecimal) / dDecimal, trunc(dV * dDecimal) / dDecimal) ;
pair<int64_t, int64_t> key (static_cast<int64_t>(dU * pow(2,15)), static_cast<int64_t>(dV * pow(2,15))) ;
if ( m_mPt3d.find( key) == m_mPt3d.end())
m_mPt3d[key] = pt ;
@@ -149,8 +137,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_mPt3d.clear() ;
m_mChunk.clear() ;
m_vPlApprox.clear() ;
//m_vPolygons.clear() ;
//m_vPolygonsCorr.clear() ;
m_vCCLoop2D.clear() ;
m_pSrfBz = pSrfBz ;
@@ -217,7 +203,6 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
for ( int k = 0 ; k < int( vPlAdjusted.size()) ; ++k )
m_vPlApprox.push_back( tuple<PolyLine,bool>(vPlAdjusted[k], vbOrientation[k])) ;
// aggiorno la mappa del chunk di appartenenza per tutti i loop aggiunti // do per scontato che siano tutti dello stesso chunk anche se li ho separati
//m_vLoop.emplace_back( Release( pLoop)) ;
for ( int k = nLoop ; k < int( m_vPlApprox.size()); ++k)
m_mChunk[k] = i ;
}
@@ -798,11 +783,6 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
bVert = true ;
}
pcToSplit->SetSplitDirVert( bVert) ;
//Point3d ptP00, ptP10, ptP11, ptP01 ;
//ptP00 = m_mVert[nCToSplit][0] ;
//ptP10 = m_mVert[nCToSplit][1] ;
//ptP11 = m_mVert[nCToSplit][2] ;
//ptP01 = m_mVert[nCToSplit][3] ;
// distanza reale tra i vertici della cella
double dLen0 = Dist( ptP00, ptP10) ;
double dLen1 = Dist( ptP10, ptP11) ;
@@ -1520,83 +1500,76 @@ Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, vec
POLYLINEVECTOR vPolygonsBasic ;
POLYLINEVECTOR vPolygonsCorrected ;
POLYLINEVECTOR vPolygonsBasic3d ;
//if ( m_vPolygons.empty()) {
if ( ! m_bTrimmed) {
vvPolygons.clear() ;
if ( ! m_bTrimmed) {
vvPolygons.clear() ;
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
if (vPolygonsBasic.empty())
return false ;
int c = 0;
for ( PolyLine& pl : vPolygonsCorrected) {
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
if (vPolygonsBasic.empty())
return false ;
int c = 0;
for ( PolyLine& pl : vPolygonsCorrected) {
vvPolygons.emplace_back() ;
vvPolygons.back().emplace_back(std::move(pl)) ;
vvPolygons3d.emplace_back() ;
vvPolygons3d.back().emplace_back(std::move(vPolygonsBasic3d[c])) ;
++c ;
}
}
// trimmata
else {
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
if (vPolygonsBasic.empty())
return false ;
// aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim
m_vCEdge2D.clear() ;
for ( int i = 0 ; i < 4 ; ++i) {
m_vCEdge2D.emplace_back() ;
m_vCEdge2D.back().second.Init( false, EPS_SMALL, 1) ;
}
// percorro i loop, trovo le intersezioni con le celle e le categorizzo
if ( ! TraceLoopLabelCell( vPolygonsBasic))
return false ;
// scorro sulle celle e costruisco i poligoni
int nCells = int( vPolygonsBasic.size()) ;
for ( int i = 0 ; i < nCells ; ++ i) {
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
if ( m_mTree[nId].m_nFlag == 4) {
// vettore dei poligoni ( loop) della cella nId
vvPolygons.emplace_back() ;
vvPolygons.back().emplace_back(std::move(pl)) ;
vvPolygons.back().push_back(std::move(vPolygonsCorrected[i])) ;
vvPolygons3d.emplace_back() ;
vvPolygons3d.back().emplace_back(std::move(vPolygonsBasic3d[c])) ;
++c ;
}
}
// trimmata
else {
GetPolygonsBasic( vPolygonsBasic, vPolygonsCorrected, vPolygonsBasic3d) ;
if (vPolygonsBasic.empty())
return false ;
// aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim
m_vCEdge2D.clear() ;
for ( int i = 0 ; i < 4 ; ++i) {
m_vCEdge2D.emplace_back() ;
m_vCEdge2D.back().second.Init( false, EPS_SMALL, 1) ;
}
// percorro i loop, trovo le intersezioni con le celle e le categorizzo
if ( ! TraceLoopLabelCell( vPolygonsBasic))
return false ;
// scorro sulle celle e costruisco i poligoni
int nCells = int( vPolygonsBasic.size()) ;
for ( int i = 0 ; i < nCells ; ++ i) {
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
if ( m_mTree[nId].m_nFlag == 4) {
// vettore dei poligoni ( loop) della cella nId
vvPolygons.emplace_back() ;
vvPolygons.back().push_back(std::move(vPolygonsCorrected[i])) ;
vvPolygons3d.emplace_back() ;
vvPolygons3d.back().push_back(std::move(vPolygonsBasic3d[i])) ;
}
else if ( m_mTree[nId].m_nFlag == 0)
continue ;
else {
// vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella
INTVECTOR vnParentChunk ;
// vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo
INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ;
//generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ;
iota( vToCheck.begin(), vToCheck.end(), 0) ;
// numero di poligoni aggiunti
int nPoly = 0 ;
// scorro sui vettori intersezione della cella nId e sui suoi vertici
// in questo for analizzo solo i loop che tagliano la cella
while ( ! vToCheck.empty()) {
int nPolyBefore = nPoly ;
PolyLine pl3d ;
CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
if ( nPolyBefore == nPoly)
break ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
}
vvPolygons3d.back().push_back(std::move(vPolygonsBasic3d[i])) ;
}
else if ( m_mTree[nId].m_nFlag == 0)
continue ;
else {
// vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella
INTVECTOR vnParentChunk ;
// vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo
INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ;
iota( vToCheck.begin(), vToCheck.end(), 0) ;
// numero di poligoni aggiunti
int nPoly = 0 ;
// scorro sui vettori intersezione della cella nId e sui suoi vertici
// in questo for analizzo solo i loop che tagliano la cella
while ( ! vToCheck.empty()) {
int nPolyBefore = nPoly ;
PolyLine pl3d ;
CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
if ( nPolyBefore == nPoly)
break ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk, vPolygonsCorrected[i], vPolygonsBasic3d[i]) ;
}
}
}
// aggiorno gli edge 3d e i loop della superficie
GetEdges3D( vvCCEdges3D, vPolygonsCorrected) ;
GetSplitLoops( vCCLoops) ;
return true ;
/*}
else {
vvPolygons = m_vPolygons ;
return true ;
}*/
}
//----------------------------------------------------------------------------
@@ -1607,366 +1580,342 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
PNTVECTOR vVertices ;
PNTVECTOR vVerticesCorr ;
PNTVECTOR vVertices3d ;
//if ( m_vPolygons.empty() || // se non li ho mai calcolati
// ( ! m_vPolygons.empty() && ! vCells.empty()) || // se ho già calcolato dei poligoni ma ne sto chiedendo di un altro gruppo di celle
// ( vCells.empty() && m_vPolygons.size() != m_vnLeaves.size()) || // se sto chiedendo i poligoni di tutte le celle, ma i poligoni già calcolati sono meno delle celle
// bForTriangulation) { // oppure se sto chiedendo i poligoni per la triangolazione ( devo fare considerazioni particolari se ho dei poli sui lati del parametrico)
//m_vPolygons.clear() ;
//m_vPolygons3d.clear() ;
//// se non ho dato un elenco di celle in input do per scontato che la chiamata sia per calcolare i poligoni di tutte le foglie
//if ( vCells.empty())
// vCells = m_vnLeaves ;
INTVECTOR vNeigh ;
// setto le celle che sono sul LeftEdge e sul TopEdge
if ( m_bClosedU) {
GetRootNeigh( 1, vNeigh) ;
for ( int k : vNeigh) {
m_mTree[k].m_bOnLeftEdge = true ;
}
vNeigh.clear() ;
INTVECTOR vNeigh ;
// setto le celle che sono sul LeftEdge e sul TopEdge
if ( m_bClosedU) {
GetRootNeigh( 1, vNeigh) ;
for ( int k : vNeigh) {
m_mTree[k].m_bOnLeftEdge = true ;
}
if ( m_bClosedV) {
GetRootNeigh( 0, vNeigh) ;
for ( int k : vNeigh) {
m_mTree[k].m_bOnTopEdge = true ;
vNeigh.clear() ;
}
if ( m_bClosedV) {
GetRootNeigh( 0, vNeigh) ;
for ( int k : vNeigh) {
m_mTree[k].m_bOnTopEdge = true ;
}
}
bool bBottomRight , bTopLeft ;
// scorro lungo tutte le celle leaves e oltre agli angoli della cella aggiungo alla polyline della cella anche i vertici, delle celle adiacenti,
// che sono sui lati della cella corrente
// N.B. :i poligoni sono costruiti a partire dal ptBL !!!
int c = 0 ;
for ( int nId : m_vnLeaves) {
Cell& cell = m_mTree.at( nId) ;
vVertices.clear() ;
vVertices3d.clear() ;
vNeigh.clear() ;
vVertices.push_back( cell.GetBottomLeft()) ;
Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
INTVECTOR vnVert ;
BOOLVECTOR vbBonusVert(4) ;
std::fill( vbBonusVert.begin(), vbBonusVert.end(), false) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetBottomNeigh( nId, vNeigh) ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, ptP00) ;
GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, ptP10) ;
GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, ptP11) ;
GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, ptP01) ;
// aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom
if ( vNeigh.size() > 1){
// se la superficie è chiusa lungo il parametro V e le celle vicine bottom sono sul lato Top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
if ( m_bClosedV && m_mTree.at(vNeigh[0]).m_bOnTopEdge) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cNeigh.GetTopRight().x, cell.GetBottomLeft().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetTopRight()) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
bBottomRight = true ;
vbBonusVert[2] = true ;
}
else
bBottomRight = false ;
vNeigh.clear() ;
GetRightNeigh ( nId, vNeigh) ;
// aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right
if ( vNeigh.size() > 1){
// se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cell.GetTopRight().x, cNeigh.GetBottomLeft().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetBottomLeft()) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
vbBonusVert[3] = true ;
}
// se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right
else if ( ! bBottomRight) {
Point3d ptBr( cell.GetTopRight().x, cell.GetBottomLeft().y) ;
vVertices.push_back( ptBr) ;
Point3d pt3d ; GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( cell.GetTopRight()) ;
pt3d = ORIG ; GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetTopNeigh ( nId, vNeigh) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
if ( ! vNeigh.empty() && vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro V e la cella è sul lato top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedV && cell.m_bOnTopEdge) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetBottomLeft().x, cell.GetTopRight().y) ;
vVertices.push_back( pt) ;
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ;
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
bTopLeft = true ;
vbBonusVert[0] = true ;
}
else
bTopLeft = false ;
vNeigh.clear() ;
GetLeftNeigh ( nId, vNeigh) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left
if ( vNeigh.size() > 1) {
// se la superficie è chiusa lungo il parametro U e la cella è sul lato left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedU && cell.m_bOnLeftEdge) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cell.GetBottomLeft().x, cNeigh.GetTopRight().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetTopRight()) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
vbBonusVert[1] = true ;
}
// se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left
else if ( ! bTopLeft) {
Point3d ptTl( cell.GetBottomLeft().x, cell.GetTopRight().y) ;
vVertices.push_back( ptTl) ;
Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( cell.GetBottomLeft()) ;
pt3d = ORIG ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
BOOLVECTOR vbKeepPoint( vVertices.size()) ;
std::fill( vbKeepPoint.begin(), vbKeepPoint.end(), true) ;
// se non è trimmata aggiusto subito il vettore dei vertici, sennò i salvo le informazioni per quando creerò i poligoni trimmato
vVerticesCorr = vVertices ;
// ora devo controllare se uno dei lati della cella è collassato in un punto.
// se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra
// se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato
if ( AreSamePointApprox(ptP00, ptP10)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
else if ( ! vbBonusVert[1] && vbBonusVert[3] ) {
if ( ! m_bTrimmed) {
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVerticesCorr.pop_back() ;
vVerticesCorr[0] = vVerticesCorr.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
vbKeepPoint[0] = false ;
vbKeepPoint.back() = false ;
cell.m_nVertToErase = 0 ; // ptBL
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
}
if ( AreSamePointApprox(ptP10, ptP11)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
else if ( ! vbBonusVert[0] && vbBonusVert[2] ){
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
}
if ( AreSamePointApprox(ptP11, ptP01)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
else if ( ! vbBonusVert[1] && vbBonusVert[3]) {
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
}
if ( AreSamePointApprox(ptP01, ptP00)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVerticesCorr.pop_back() ;
vVerticesCorr[0] = vVerticesCorr.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
vbKeepPoint[0] = false ;
vbKeepPoint.back() = false ;
cell.m_nVertToErase = 0 ; // ptBL
}
else if ( ! vbBonusVert[0] && vbBonusVert[2]) {
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
}
bool bBottomRight , bTopLeft ;
// scorro lungo tutte le celle leaves e oltre agli angoli della cella aggiungo alla polyline della cella anche i vertici, delle celle adiacenti,
// che sono sui lati della cella corrente
// N.B. :i poligoni sono costruiti a partire dal ptBL !!!
int c = 0 ;
for ( int nId : m_vnLeaves) {
Cell& cell = m_mTree.at( nId) ;
vVertices.clear() ;
vVertices3d.clear() ;
vNeigh.clear() ;
vVertices.push_back( cell.GetBottomLeft()) ;
Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
INTVECTOR vnVert ;
BOOLVECTOR vbBonusVert(4) ;
std::fill( vbBonusVert.begin(), vbBonusVert.end(), false) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetBottomNeigh( nId, vNeigh) ;
Point3d ptP00, ptP10, ptP11, ptP01 ;
GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, ptP00) ;
GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, ptP10) ;
GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, ptP11) ;
GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, ptP01) ;
// aggiungo i vertici che sono sul lato bottom, solo se ho più di un vicino bottom
if ( vNeigh.size() > 1){
// se la superficie è chiusa lungo il parametro V e le celle vicine bottom sono sul lato Top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
if ( m_bClosedV && m_mTree.at(vNeigh[0]).m_bOnTopEdge) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cNeigh.GetTopRight().x, cell.GetBottomLeft().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetTopRight()) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
bBottomRight = true ;
vbBonusVert[2] = true ;
}
else
bBottomRight = false ;
vNeigh.clear() ;
GetRightNeigh ( nId, vNeigh) ;
// aggiungo i vertici che sono sul lato right, solo se ho più di un vicino right
if ( vNeigh.size() > 1){
// se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cell.GetTopRight().x, cNeigh.GetBottomLeft().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetBottomLeft()) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
vbBonusVert[3] = true ;
}
// se non l'ho già aggiunto tramite i vicini bottom aggiungo il punto bottom right
else if ( ! bBottomRight) {
Point3d ptBr( cell.GetTopRight().x, cell.GetBottomLeft().y) ;
vVertices.push_back( ptBr) ;
Point3d pt3d ; GetPoint( cell.GetTopRight().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( cell.GetTopRight()) ;
pt3d = ORIG ; GetPoint( cell.GetTopRight().x, cell.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetTopNeigh ( nId, vNeigh) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato top, solo se ho più di un vicino top
if ( ! vNeigh.empty() && vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro V e la cella è sul lato top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedV && cell.m_bOnTopEdge) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetBottomLeft().x, cell.GetTopRight().y) ;
vVertices.push_back( pt) ;
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ;
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
bTopLeft = true ;
vbBonusVert[0] = true ;
}
else
bTopLeft = false ;
vNeigh.clear() ;
GetLeftNeigh ( nId, vNeigh) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
// aggiungo i vertici che sono sul lato left, solo se ho più di un vicino left
if ( vNeigh.size() > 1) {
// se la superficie è chiusa lungo il parametro U e la cella è sul lato left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
if ( m_bClosedU && cell.m_bOnLeftEdge) {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
Point3d pt( cell.GetBottomLeft().x, cNeigh.GetTopRight().y) ;
vVertices.push_back( pt) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
else {
for ( int j : vNeigh) {
Cell& cNeigh = m_mTree.at(j) ;
vVertices.push_back( cNeigh.GetTopRight()) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
}
}
vbBonusVert[1] = true ;
}
// se non l'ho già aggiunto tramite i vicini top aggiungo il punto top left
else if ( ! bTopLeft) {
Point3d ptTl( cell.GetBottomLeft().x, cell.GetTopRight().y) ;
vVertices.push_back( ptTl) ;
Point3d pt3d ; GetPoint( cell.GetBottomLeft().x, cell.GetTopRight().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( cell.GetBottomLeft()) ;
pt3d = ORIG ; GetPoint( cell.GetBottomLeft().x, cell.GetBottomLeft().y, pt3d) ;
vVertices3d.push_back( pt3d) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
BOOLVECTOR vbKeepPoint( vVertices.size()) ;
std::fill( vbKeepPoint.begin(), vbKeepPoint.end(), true) ;
// se non è trimmata aggiusto subito il vettore dei vertici, sennò i salvo le informazioni per quando creerò i poligoni trimmato
vVerticesCorr = vVertices ;
// ora devo controllare se uno dei lati della cella è collassato in un punto.
// se così, devo guardare se sui due lati adiacenti a quello di polo ho messo dei punti extra
// se ne ho messi solo su uno dei due allora devo togliere il vertice dell'altro lato
if ( AreSamePointApprox(ptP00, ptP10)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]) {// lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
else if ( ! vbBonusVert[1] && vbBonusVert[3] ) {
if ( ! m_bTrimmed) {
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVerticesCorr.pop_back() ;
vVerticesCorr[0] = vVerticesCorr.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
vbKeepPoint[0] = false ;
vbKeepPoint.back() = false ;
cell.m_nVertToErase = 0 ; // ptBL
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
}
if ( AreSamePointApprox(ptP10, ptP11)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
vbKeepPoint[vnVert[1]] = false ;
cell.m_nVertToErase = 1 ; // ptBr
}
else if ( ! vbBonusVert[0] && vbBonusVert[2] ){
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
}
if ( AreSamePointApprox(ptP11, ptP01)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] && ! vbBonusVert[3]){ // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
vbKeepPoint[vnVert[2]] = false ;
cell.m_nVertToErase = 2 ; // ptTR
}
else if ( ! vbBonusVert[1] && vbBonusVert[3]) {
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
}
if ( AreSamePointApprox(ptP01, ptP00)) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] && ! vbBonusVert[2]) { // lati contati a partire da quello sopra in senso CCW
if ( ! m_bTrimmed) {
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVerticesCorr.pop_back() ;
vVerticesCorr[0] = vVerticesCorr.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
vbKeepPoint[0] = false ;
vbKeepPoint.back() = false ;
cell.m_nVertToErase = 0 ; // ptBL
}
else if ( ! vbBonusVert[0] && vbBonusVert[2]) {
if ( ! m_bTrimmed) {
vVerticesCorr.erase(vVerticesCorr.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
// se non ho bonus su nessuno dei due
else {
// ne scelgo uno dei due da togliere
vbKeepPoint[vnVert[3]] = false ;
cell.m_nVertToErase = 3 ; // ptTl
}
}
if ( ! m_bTrimmed) {
// se ho una cella con vicino dello stesso grado ( quindi il poligono ha solo 5 punti) 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 ;
double dU, dV ;
dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ;
dV = ( cell.GetBottomLeft().y + cell.GetTopRight().y) / 2 / SBZ_TREG_COEFF ;
GetPoint( dU, dV, ptPSrf) ;
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) + EPS_SMALL > Dist( ptP10P01, ptPSrf)) {
rotate( vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ;
vVertices.back() = vVertices.at( 0) ;
rotate( vVertices3d.begin(), vVertices3d.begin() + 1,vVertices3d.end()) ;
vVertices3d.back() = vVertices3d.at( 0) ;
rotate( vbKeepPoint.begin(), vbKeepPoint.begin() + 1,vbKeepPoint.end()) ;
vbKeepPoint.back() = vbKeepPoint.at( 0) ;
rotate( vVerticesCorr.begin(), vVerticesCorr.begin() + 1,vVerticesCorr.end()) ;
vVerticesCorr.back() = vVerticesCorr.at( 0) ;
}
}
}
cell.AddPoly( c) ;
// aggiorno il contatore dei poligoni
c += 1 ;
vPolygonsBasic.emplace_back() ;
//m_vPolygons.back().emplace_back() ;
vPolygonsCorrected.emplace_back() ;
//m_vPolygonsCorr.back().emplace_back() ;
vPolygons3d.emplace_back() ;
//m_vPolygons3d.back().emplace_back() ;
int nVertCorr = int(vVerticesCorr.size());
for ( int i = 0 ; i < (int) vVertices.size() ; ++i) {
int dPar = i ;
if( ! vbKeepPoint[i])
dPar = -1 ;
vPolygonsBasic.back().AddUPoint( dPar, vVertices.at( i)) ;
if( i < nVertCorr){
vPolygonsCorrected.back().AddUPoint( dPar, vVerticesCorr.at( i)) ;
vPolygons3d.back().AddUPoint( dPar, vVertices3d.at( i)) ;
if ( ! m_bTrimmed) {
// se ho una cella con vicino dello stesso grado ( quindi il poligono ha solo 5 punti) 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 ;
double dU, dV ;
dU = ( cell.GetBottomLeft().x + cell.GetTopRight().x) / 2 / SBZ_TREG_COEFF ;
dV = ( cell.GetBottomLeft().y + cell.GetTopRight().y) / 2 / SBZ_TREG_COEFF ;
GetPoint( dU, dV, ptPSrf) ;
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) + EPS_SMALL > Dist( ptP10P01, ptPSrf)) {
rotate( vVertices.begin(), vVertices.begin() + 1,vVertices.end()) ;
vVertices.back() = vVertices.at( 0) ;
rotate( vVertices3d.begin(), vVertices3d.begin() + 1,vVertices3d.end()) ;
vVertices3d.back() = vVertices3d.at( 0) ;
rotate( vbKeepPoint.begin(), vbKeepPoint.begin() + 1,vbKeepPoint.end()) ;
vbKeepPoint.back() = vbKeepPoint.at( 0) ;
rotate( vVerticesCorr.begin(), vVerticesCorr.begin() + 1,vVerticesCorr.end()) ;
vVerticesCorr.back() = vVerticesCorr.at( 0) ;
}
}
}
//}
//// restituisco i poligoni delle celle del tree nello spazio parametrico
//for ( int t = 0 ; t < (int)m_vPolygons.size() ; ++ t) {
// for ( int z = 0 ; z < (int)m_vPolygons[t].size() ; ++z) {
// vPolygonsBasic.push_back( std::move(m_vPolygons[t][z])) ;
// if( bForTriangulation) {
// vPolygonsCorrected.push_back( std::move(m_vPolygonsCorr[t][z])) ;
// vPolygons3d.push_back( std::move(m_vPolygons3d[t][z])) ;
// }
// }
//}
cell.AddPoly( c) ;
// aggiorno il contatore dei poligoni
c += 1 ;
vPolygonsBasic.emplace_back() ;
vPolygonsCorrected.emplace_back() ;
vPolygons3d.emplace_back() ;
int nVertCorr = int(vVerticesCorr.size());
for ( int i = 0 ; i < (int) vVertices.size() ; ++i) {
int dPar = i ;
if( ! vbKeepPoint[i])
dPar = -1 ;
vPolygonsBasic.back().AddUPoint( dPar, vVertices.at( i)) ;
if( i < nVertCorr){
vPolygonsCorrected.back().AddUPoint( dPar, vVerticesCorr.at( i)) ;
vPolygons3d.back().AddUPoint( dPar, vVertices3d.at( i)) ;
}
}
}
return true ;
}
@@ -3536,8 +3485,6 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
ptLast.Set( ptToAdd.x, ptToAdd.y, 0) ;
return true ;
}
//Point3d ptLast ;
//plTrimmedPoly.GetLastPoint( ptLast) ;
// verifico di essere allineato con un lato, sennò aggiungo e basta
Vector3d vDir ;
@@ -4380,7 +4327,6 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons)
// preparo tutto per poter chiamare la createCellPolygon
m_vnLeaves.push_back( nRoot) ;
INTVECTOR vToCheck( (int) m_mTree.at(nRoot).m_vInters.size()) ;
//generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ;
iota( vToCheck.begin(), vToCheck.end(), 0) ;
int nPoly = 0 ;
INTVECTOR vnParentChunk ;