EgtGeomKernel :

- migliormaneto della velocità di calcolo per la triangolazione di superfici di Bezier.
- irrobustimento della stessa triangolazione.
This commit is contained in:
Daniele Bariletti
2024-06-19 10:07:03 +02:00
parent 09220bfd68
commit 9d845179a4
3 changed files with 306 additions and 88 deletions
+39 -9
View File
@@ -1518,6 +1518,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
// costruttore della superficie
POLYLINEMATRIX vvPL ;
POLYLINEMATRIX vvPL3d ;
//POLYLINEVECTOR vPL ; // per usare i polygon basic
Tree Tree ;
if ( ! Tree.SetSurf( this, true))
@@ -1543,7 +1544,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
Tree.BuildTree( dTol, dSideMin) ;
//Tree.BuildTree( 1, 5) ; //debug
}
if ( ! Tree.GetPolygons( vvPL))
if ( ! Tree.GetPolygons( vvPL, vvPL3d))
continue ;
//Tree.GetPolygonsBasic( vPL, true) ; // per usare i polygon basic
@@ -1569,6 +1570,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
return nullptr ;
// prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d
int c = 0 ;
for ( POLYLINEVECTOR vPL : vvPL) {
PNTVECTOR vPnt ;
INTVECTOR vTria ;
@@ -1576,17 +1578,44 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
if ( ! Tri.Make( vPL, vPnt, vTria))
return nullptr ;
//vedo se la polyline 3d che passo io corrisponde a quella che usavo prima
POLYLINEVECTOR vPL3d = vvPL3d[c] ;
// porto i punti in 3d
PNTVECTOR vPnt3d ;
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
Point3d pt3d ;
//// NOTA PER MIGLIORAMENTO
// i punti nello spazio 3D che calcolo qui in realtà li ho già calcolati durante la costruzione dell'albero!!!
// devo trovare il modo di passarli fino a qui, tenendo conto anche che potrebbero esserci più alberi!!
if ( ! GetPointD1D2( vPnt[i].x / SBZ_TREG_COEFF, vPnt[i].y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d))
return nullptr ;
vPnt3d.push_back( pt3d) ;
for( int i = 0 ; i < int( vPL3d.size()) ; ++i) {
PolyLine pl3d = vPL3d[i] ;
Point3d pt3d ; pl3d.GetFirstPoint( pt3d) ;
//vPnt3d.push_back( pt3d) ;
while ( pl3d.GetNextPoint( pt3d)) {
vPnt3d.push_back( pt3d) ;
}
}
// controllo per ogni polyline se è stato invertito il vettore dei punti
int nCurrPoint = 0 ;
for( int i = 0 ; i < int( vPL.size()) ; ++i) {
Point3d pt3d ; vPL[i].GetFirstPoint( pt3d) ;
vPL[i].GetNextPoint( pt3d) ;
int nPoints = vPL[i].GetPointNbr() - 2 ;
if ( ! AreSamePointApprox( vPnt[nCurrPoint], pt3d))
reverse( vPnt3d.begin() + nCurrPoint, vPnt3d.begin() + nCurrPoint + nPoints) ;
nCurrPoint += nPoints ;
}
//controllo che i due vettori vPnt e vPnt3d abbiano la stessa lunghezza, sennò vuol dire che nel vettore vPnt3d ho avuto dei Rejected e devo ricalcolarli
// i punti in eccesso verranno poi scartati dalla trimesh
if( vPnt.size() != vPnt3d.size()) {
vPnt3d.clear() ;
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
Point3d pt3d ;
if ( ! GetPointD1D2( vPnt[i].x / SBZ_TREG_COEFF, vPnt[i].y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d))
return nullptr ;
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]],
@@ -1595,6 +1624,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
vPnt[vTria[3*i+2]].x, vPnt[vTria[3*i+2]].y))
return nullptr ;
}
++c ;
}
// termino
+255 -72
View File
@@ -1567,24 +1567,54 @@ Tree::GetDepth( int nId, int nRef = -2) const
//----------------------------------------------------------------------------
bool
Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
Tree::GetPolygons( POLYLINEMATRIX& vvPolygons)
{
POLYLINEMATRIX vvPolygonsBasic3d ;
return GetPolygons( vvPolygons, false, vvPolygonsBasic3d) ;
}
//----------------------------------------------------------------------------
bool
Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vPolygonsBasic3d)
{
return GetPolygons( vvPolygons, true, vPolygonsBasic3d) ;
}
//----------------------------------------------------------------------------
bool
Tree::GetPolygons( POLYLINEMATRIX& vvPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d)
{
if ( (int) m_vPolygons.size() == 0) {
if ( ! m_bTrimmed) {
vPolygons.clear() ;
vvPolygons.clear() ;
POLYLINEVECTOR vPolygonsBasic ;
GetPolygonsBasic( vPolygonsBasic, true) ;
POLYLINEVECTOR vPolygonsBasic3d ;
if ( bForTriangulation)
GetPolygonsBasic( vPolygonsBasic, vPolygonsBasic3d) ;
else
GetPolygonsBasic( vPolygonsBasic) ;
int c = 0;
for ( PolyLine pl : vPolygonsBasic) {
POLYLINEVECTOR vSinglePolygon ;
vSinglePolygon.push_back( pl) ;
vPolygons.push_back( vSinglePolygon) ;
vvPolygons.push_back( vSinglePolygon) ;
if ( bForTriangulation) {
POLYLINEVECTOR vSinglePolygon3d ;
vSinglePolygon3d.push_back( vPolygonsBasic3d[c]) ;
vvPolygons3d.push_back( vSinglePolygon3d) ;
}
++c ;
}
return true ;
}
// trimmata
else {
POLYLINEVECTOR vPolygonsBasic ;
GetPolygonsBasic( vPolygonsBasic) ;
POLYLINEVECTOR vPolygonsBasic3d ;
if ( bForTriangulation)
GetPolygonsBasic( vPolygonsBasic, vPolygonsBasic3d) ;
else
GetPolygonsBasic( vPolygonsBasic) ;
// 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) {
@@ -1603,7 +1633,17 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
// vettore dei poligoni ( loop) della cella nId
POLYLINEVECTOR vCellPolygons ;
vCellPolygons.push_back( vPolygonsBasic[i]) ;
vPolygons.push_back( vCellPolygons) ;
vvPolygons.push_back( vCellPolygons) ;
if ( bForTriangulation ) {
POLYLINEVECTOR vCellPolygons3d ;
PolyLine plPolygon3d ;
plPolygon3d.AddUPoint( 0, m_mVert[nId][0]) ;
plPolygon3d.AddUPoint( 1, m_mVert[nId][1]) ;
plPolygon3d.AddUPoint( 2, m_mVert[nId][2]) ;
plPolygon3d.AddUPoint( 3, m_mVert[nId][3]) ;
vCellPolygons3d.push_back( plPolygon3d) ;
vvPolygons3d.push_back( vCellPolygons3d) ;
}
}
else if ( m_mTree[nId].m_nFlag == 0)
continue ;
@@ -1620,26 +1660,41 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
// in questo for analizzo solo i loop che tagliano la cella
while( (int)vToCheck.size() != 0) {
int nPolyBefore = nPoly ;
CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i]) ;
CreateCellPolygons( i, vvPolygons, vvPolygons3d, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i], vPolygonsBasic3d[i]) ;
if ( nPolyBefore == nPoly)
break ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vPolygons, nPoly, vnParentChunk) ;
CreateIslandAndHoles( i, vvPolygons, vvPolygons3d, nPoly, vnParentChunk) ;
}
}
return true ;
}
}
else {
vPolygons = m_vPolygons ;
vvPolygons = m_vPolygons ;
return true ;
}
}
//----------------------------------------------------------------------------
bool
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVECTOR vCells)
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygons3d)
{
return GetPolygonsBasic( vPolygons, true, vPolygons3d) ;
}
//----------------------------------------------------------------------------
bool
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells)
{
POLYLINEVECTOR vPolygons3d ;
return GetPolygonsBasic( vPolygons, false, vPolygons3d, vCells) ;
}
//----------------------------------------------------------------------------
bool
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells)
{
// condizioni per il calcolo dei poligoni di base
if ( m_vPolygons.empty() || // se non li ho mai calcolati
@@ -1647,11 +1702,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
( 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 ;
PNTVECTOR vVertices ;
PNTVECTOR vVertices3d ;
INTVECTOR vNeigh ;
// setto le celle che sono sul LeftEdge e sul TopEdge
if ( m_bClosedU) {
@@ -1673,8 +1730,10 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
// N.B. :i poligoni sono costruiti a partire dal ptBL !!!
for ( int nId : vCells) {
vVertices.clear() ;
vVertices3d.clear() ;
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ;
vVertices3d.push_back( m_mVert.at( nId)[0]) ;
INTVECTOR vnVert ;
BOOLVECTOR vbBonusVert(4) ;
fill( vbBonusVert.begin(), vbBonusVert.end(), false) ;
@@ -1688,11 +1747,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ;
vVertices.push_back( pt) ;
vVertices3d.push_back( m_mVert[j][1]) ;
}
}
else {
for ( int j : vNeigh)
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetTopRight()) ;
vVertices3d.push_back( m_mVert[j][2]) ;
}
}
bBottomRight = true ;
vbBonusVert[2] = true ;
@@ -1710,11 +1772,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( nId).GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ;
vVertices.push_back( pt) ;
vVertices3d.push_back( m_mVert[j][1]) ;
}
}
else {
for ( int j : vNeigh)
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ;
vVertices3d.push_back( m_mVert[j][0]) ;
}
}
vbBonusVert[3] = true ;
}
@@ -1722,10 +1787,12 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
else if ( ! bBottomRight) {
Point3d ptBr( m_mTree.at( nId).GetTopRight().x, m_mTree.at( nId).GetBottomLeft().y) ;
vVertices.push_back( ptBr) ;
vVertices3d.push_back( m_mVert[nId][1]) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetTopRight()) ;
vVertices3d.push_back( m_mVert[nId][2]) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
GetTopNeigh ( nId, vNeigh) ;
std::reverse( vNeigh.begin(), vNeigh.end()) ;
@@ -1738,11 +1805,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ;
vVertices.push_back( pt) ;
vVertices3d.push_back( m_mVert[j][3]) ;
}
}
else {
for ( int j : vNeigh)
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetBottomLeft()) ;
vVertices3d.push_back( m_mVert[j][0]) ;
}
}
bTopLeft = true ;
vbBonusVert[0] = true ;
@@ -1761,11 +1831,14 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ;
vVertices.push_back( pt) ;
vVertices3d.push_back( m_mVert[j][3]) ;
}
}
else {
for ( int j : vNeigh)
for ( int j : vNeigh) {
vVertices.push_back( m_mTree.at( j).GetTopRight()) ;
vVertices3d.push_back( m_mVert[j][2]) ;
}
}
vbBonusVert[1] = true ;
}
@@ -1773,10 +1846,12 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
else if ( ! bTopLeft) {
Point3d ptTl( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ;
vVertices.push_back( ptTl) ;
vVertices3d.push_back( m_mVert[nId][3]) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
}
vNeigh.clear() ;
vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ;
vVertices3d.push_back( m_mVert[nId][0]) ;
vnVert.push_back( int(vVertices.size()) - 1) ;
if ( bForTriangulation){
@@ -1787,12 +1862,16 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
// se ho punti bonus su entrambi i lati non devo fare nulla
if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] ) // lati contati a partire da quello sopra in senso CCW
if ( vbBonusVert[1] ) {// lati contati a partire da quello sopra in senso CCW
vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
else if ( vbBonusVert[3] ) {
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVertices.pop_back() ;
vVertices[0] = vVertices.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
}
}
@@ -1800,20 +1879,28 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
// se ho punti bonus su entrambi i lati non devo fare nulla
if ( !( vbBonusVert[0] && vbBonusVert[2] ) ) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[0] ) // lati contati a partire da quello sopra in senso CCW
if ( vbBonusVert[0] ){ // lati contati a partire da quello sopra in senso CCW
vVertices.erase(vVertices.begin() + vnVert[1]) ; // vertici della cella contati a partire da ptBL in senso CCW
else if ( vbBonusVert[2] )
vVertices3d.erase(vVertices3d.begin() + vnVert[1]) ;
}
else if ( vbBonusVert[2] ){
vVertices.erase(vVertices.begin() + vnVert[2]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
}
}
if ( AreSamePointApprox(m_mVert.at(nId).at(2), m_mVert.at(nId).at(3)) && ( vbBonusVert[1] || vbBonusVert[3] ) ) {
// se ho punti bonus su entrambi i lati non devo fare nulla
if ( !( vbBonusVert[1] && vbBonusVert[3] ) ) {
// sennò devo togliere l'estremo del lato su cui NON ho punti bonus
if ( vbBonusVert[1] ) // lati contati a partire da quello sopra in senso CCW
if ( vbBonusVert[1] ){ // lati contati a partire da quello sopra in senso CCW
vVertices.erase(vVertices.begin() + vnVert[2]) ; // vertici della cella contati a partire da ptBL in senso CCW
else if ( vbBonusVert[3] )
vVertices3d.erase(vVertices3d.begin() + vnVert[2]) ;
}
else if ( vbBonusVert[3] ) {
vVertices.erase(vVertices.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
}
}
if ( AreSamePointApprox(m_mVert.at(nId).at(3), m_mVert.at(nId).at(0)) && ( vbBonusVert[0] || vbBonusVert[2] ) ) {
@@ -1824,9 +1911,13 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
// dovrei eliminare ptBL, quindi devo eliminare il primo e l'ultimo punto della polyline e poi chiuderla con quello che era il penultimo punto
vVertices.pop_back() ;
vVertices[0] = vVertices.end()[-1] ;
vVertices3d.pop_back() ;
vVertices3d[0] = vVertices3d.end()[-1] ;
}
else if ( vbBonusVert[2] )
else if ( vbBonusVert[2] ) {
vVertices.erase(vVertices.begin() + vnVert[3]) ;
vVertices3d.erase(vVertices3d.begin() + vnVert[3]) ;
}
}
}
}
@@ -1850,14 +1941,19 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
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) ;
}
}
}
m_vPolygons.emplace_back() ;
m_vPolygons.back().emplace_back() ;
m_vPolygons3d.emplace_back() ;
m_vPolygons3d.back().emplace_back() ;
for ( int i = 0 ; i < (int) vVertices.size() ; ++i) {
m_vPolygons.back().back().AddUPoint( i, vVertices.at( i)) ;
m_vPolygons3d.back().back().AddUPoint( i, vVertices3d.at( i)) ;
}
}
@@ -1867,6 +1963,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, INTVE
for ( int t = 0 ; t < (int)m_vPolygons.size() ; ++ t) {
for ( int z = 0 ; z < (int)m_vPolygons[t].size() ; ++z) {
vPolygons.push_back( m_vPolygons[t][z]) ;
vPolygons3d.push_back( m_vPolygons3d[t][z]) ;
}
}
return true ;
@@ -2172,7 +2269,7 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// qui devo mettere una tolleranza negativa per poter tener conto anche dei punti che sono SULLA curva
while ( ! IsPointInsidePolyLine( ptCurr, vplPolygons[nIdPolygon], dLinTol)) {
// sto uscendo dalla cella, quindi cerco l'intersezione
if ( bEraseNextPoint) {
if ( bEraseNextPoint && vptInters.size() != 0) {
vptInters.pop_back() ;
bEraseNextPoint = false ;
}
@@ -2182,7 +2279,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// al precedente FindInters avrei dovuto passare di cella
if ( ! FindInters( nId, clTrim, vptInters, true)) {
// scarterò il punto molto vicino al lato e tengo solo l'intersezione del trim col lato
vptInters.pop_back() ;
if( vptInters.size() != 0)
vptInters.pop_back() ;
plLoop.GetPrevPoint( ptTEnd) ;
plLoop.GetPrevPoint( ptTStart) ;
plLoop.GetNextPoint( ptCurr) ;
@@ -2203,10 +2301,19 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, vptInters.back()) ;
}
// aggiungo la fine del segmento nel vettore delle intersezioni
vptInters.push_back( ptCurr) ;
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptCurr) ;
// VERSIONE NUOVA
// controllo di aggiungere un punto abbastanza distante dal precedente
if( ! AreSamePointEpsilon( vptInters.back(), ptCurr, 2 * EPS_SMALL)) {
// aggiungo la fine del segmento nel vettore delle intersezioni
vptInters.push_back( ptCurr) ;
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptCurr) ;
}
////VECCHIA VERSIONE
//// aggiungo la fine del segmento nel vettore delle intersezioni
//vptInters.push_back( ptCurr) ;
//// aggiorno la polyline splittata
//UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptCurr) ;
}
if ( nId == nFirstCell)
vptInters.pop_back() ;
@@ -2519,7 +2626,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
else if ( nEdge == 7)
ptInters = ptTR ;
// aggiungo il nuovo punto al vettore delle intersezioni
if ( (int)vptInters.size() == 0 || ! AreSamePointApprox( ptInters , vptInters.back()))
if ( (int)vptInters.size() == 0 || ! AreSamePointEpsilon( ptInters , vptInters.back(), 2 * EPS_SMALL))
vptInters.push_back( ptInters) ;
else {
// se l'ultimo punto del vettore delle intersezioni è quasi uguale al punto che devo aggiungere allora lo sostituisco con quest'ultimo
@@ -2834,21 +2941,20 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool
//----------------------------------------------------------------------------
bool
Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell)
Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d)
{
// conto quanti vertici in più ho per lato e creo un vettore dei vertici per lato
int nId = m_vnLeaves[nLeafId] ;
PNTMATRIX vEdgeVertex ;
Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ;
Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ;
vEdgeVertex.emplace_back() ;
vEdgeVertex.back().push_back( m_mTree[nId].GetTopRight()) ;
vEdgeVertex.emplace_back() ;
vEdgeVertex.back().push_back( ptTl) ;
vEdgeVertex.emplace_back() ;
vEdgeVertex.back().push_back( m_mTree[nId].GetBottomLeft()) ;
vEdgeVertex.emplace_back() ;
vEdgeVertex.back().push_back( ptBr) ;
PNTMATRIX vEdgeVertex(4) ;
PNTMATRIX vEdgeVertex3d(4) ;
vEdgeVertex[0].push_back( m_mTree[nId].GetTopRight()) ;
vEdgeVertex[1].push_back( m_mTree[nId].GetTopLeft()) ;
vEdgeVertex[2].push_back( m_mTree[nId].GetBottomLeft()) ;
vEdgeVertex[3].push_back( m_mTree[nId].GetBottomRight()) ;
vEdgeVertex3d[0].push_back( m_mVert[nId][2]) ;
vEdgeVertex3d[1].push_back( m_mVert[nId][3]) ;
vEdgeVertex3d[2].push_back( m_mVert[nId][0]) ;
vEdgeVertex3d[3].push_back( m_mVert[nId][1]) ;
// la PolyLine è riempita a partire dal lato bottom
Point3d ptStart ;
plCell.GetFirstPoint( ptStart) ;
@@ -2868,8 +2974,10 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
INTVECTOR vToCheckNow = vToCheck ;
// vettore dei poligoni ( loop) della cella nId
POLYLINEVECTOR vCellPolygons ;
POLYLINEVECTOR vCellPolygons3d ;
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
PolyLine plTrimmedPoly ;
PolyLine plTrimmedPoly3d ;
// numero di volte che la cella è stata attraversata da una curva di trim
int nPassToCheck = (int) vToCheckNow.size() ;
// numero di vertici aggiunti al nuovo poligono
@@ -2894,7 +3002,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
nFirstLoopInPoly = j ;
}
for ( Point3d ptInt : inA.vpt) {
AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptInt) ;
AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptInt, plTrimmedPoly3d) ;
}
vAddedLoops.push_back( j) ;
nEdge = inA.nOut ;
@@ -2948,6 +3056,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
vEdge.Set( 1,0,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
plTrimmedPoly3d.EraseLastUPoint() ;
nEdge = 0 ;
}
}
@@ -2956,6 +3065,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
vEdge.Set( 0,-1,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
plTrimmedPoly3d.EraseLastUPoint() ;
nEdge = 1 ;
}
}
@@ -2964,6 +3074,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
vEdge.Set( -1,0,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
plTrimmedPoly3d.EraseLastUPoint() ;
nEdge = 2 ;
}
}
@@ -2972,6 +3083,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
vEdge.Set( 0,1,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
plTrimmedPoly3d.EraseLastUPoint() ;
nEdge = 3 ;
}
}
@@ -2980,6 +3092,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
// quindi salto al prossimo loop
if ( plTrimmedPoly.GetPointNbr() == 1) {
plTrimmedPoly.Clear() ;
plTrimmedPoly3d.Clear() ;
if ( j == nFirstLoopInPoly)
nEdgeIn = -1 ;
continue ;
@@ -3015,14 +3128,14 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
while ( ! ( bValidNextStart && bAtNextStart) && bNotCameBack) {
Point3d ptVert ;
if ( nEdge == 0)
ptVert = ptTl ;
ptVert = vEdgeVertex[1][0] ;
else if ( nEdge == 1)
ptVert = m_mTree[nId].GetBottomLeft() ;
ptVert = vEdgeVertex[2][0] ;
else if ( nEdge == 2)
ptVert = ptBr ;
ptVert = vEdgeVertex[3][0] ;
else if ( nEdge == 3)
ptVert = m_mTree[nId].GetTopRight() ;
AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptVert) ;
ptVert = vEdgeVertex[0][0] ;
AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d) ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3)
@@ -3069,14 +3182,14 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
while ( bNotCameBack) {
Point3d ptVert ;
if ( nEdge == 0)
ptVert = ptTl ;
ptVert = vEdgeVertex[1][0] ;
else if ( nEdge == 1)
ptVert = m_mTree[nId].GetBottomLeft() ;
ptVert = vEdgeVertex[2][0] ;
else if ( nEdge == 2)
ptVert = ptBr ;
ptVert = vEdgeVertex[3][0] ;
else if ( nEdge == 3)
ptVert = m_mTree[nId].GetTopRight() ;
AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptVert) ;
ptVert = vEdgeVertex[0][0] ;
AddVertex( nId, vEdgeVertex, vEdgeVertex3d, plTrimmedPoly, c, ptVert, plTrimmedPoly3d) ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3)
@@ -3095,6 +3208,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
}
plTrimmedPoly.Close() ;
plTrimmedPoly3d.Close() ;
// controllo sull'area del poligono, se è 0 ( quindi un segmento), non lo aggiungo
double dArea ;
plTrimmedPoly.GetAreaXY( dArea) ;
@@ -3102,13 +3216,17 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
if ( dArea > 0) {
vCellPolygons.push_back( plTrimmedPoly) ;
vPolygons.push_back( vCellPolygons) ;
vCellPolygons3d.push_back( plTrimmedPoly3d) ;
vPolygons3d.push_back( vCellPolygons3d) ;
++ nPoly ;
vnParentChunk.push_back( inA.nChunk) ;
vCellPolygons.clear() ;
vCellPolygons3d.clear() ;
}
c = 0 ;
plTrimmedPoly.Clear() ;
plTrimmedPoly3d.Clear() ;
nEdgeIn = -1 ;
// devo verificare se tra i loop che sono finiti in vToCheck in realtà qualcuno l'ho usato per fare un poligono
for ( int k = 0 ; k < (int)vToCheck.size() ; ++ k) {
@@ -3127,18 +3245,21 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vTo
//----------------------------------------------------------------------------
bool
Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk)
Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, int& nPoly, INTVECTOR& vnParentChunk)
{
// vettore dei poligoni ( loop) della cella nId
POLYLINEVECTOR vCellPolygons ;
POLYLINEVECTOR vCellPolygons3d ;
// costruisco i poligoni partendo dal vettore delle intersezioni
int nId = m_vnLeaves[nLeafId] ;
PolyLine plTrimmedPoly ;
//PolyLine plTrimmedPoly ;
//PolyLine plTrimmedPoly3d ;
// loop interni in una cella intersecata
int nChunkBiggestCW = -1 ;
if ( m_mTree[nId].m_nFlag == 3 || m_mTree[nId].m_nFlag == 2) {
PolyLine plInLoop ;
PolyLine plInLoop3d ;
Inters inA ;
// se ho almeno un loop CW che non è contenuto in un altro poligono o in un loop interno CCW devo aggiungere il bordo
bool bAllContained = true ;
@@ -3175,18 +3296,24 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly,
// i loop esterni sono CW, quindi prima dei loop di trim aggiungo il bordo cella
Point3d ptVert = m_mTree[nId].GetTopRight() ;
plInLoop.AddUPoint( 0, ptVert) ;
ptVert.x = m_mTree[nId].GetBottomLeft().x ;
ptVert.y = m_mTree[nId].GetTopRight().y ;
ptVert = m_mTree[nId].GetTopLeft() ;
plInLoop.AddUPoint( 1, ptVert) ;
ptVert = m_mTree[nId].GetBottomLeft() ;
plInLoop.AddUPoint( 2, ptVert) ;
ptVert.x = m_mTree[nId].GetTopRight().x ;
ptVert.y = m_mTree[nId].GetBottomLeft().y ;
ptVert = m_mTree[nId].GetBottomRight() ;
plInLoop.AddUPoint( 3, ptVert) ;
plInLoop.Close() ;
vCellPolygons.push_back( plInLoop) ;
vPolygons.push_back( vCellPolygons) ;
++ nPoly ;
plInLoop3d.AddUPoint( 0, m_mVert[nId][2]);
plInLoop3d.AddUPoint( 1, m_mVert[nId][3]);
plInLoop3d.AddUPoint( 2, m_mVert[nId][0]);
plInLoop3d.AddUPoint( 3, m_mVert[nId][1]);
vCellPolygons3d.push_back( plInLoop3d) ;
vPolygons3d.push_back( vCellPolygons3d) ;
vCellPolygons3d.clear() ;
plInLoop3d.Clear() ;
// imposto il chunk del loop CW più grande ( il primo che ho incontrato)
vnParentChunk.push_back( nChunkBiggestCW) ;
vCellPolygons.clear() ;
@@ -3199,9 +3326,12 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly,
int k = 0 ;
for ( Point3d ptInt : inA.vpt) {
plInLoop.AddUPoint( k, ptInt) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptInt.x / SBZ_TREG_COEFF, ptInt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plInLoop3d.AddUPoint( k, pt3d) ;
++ k ;
}
plInLoop.Close() ;
plInLoop3d.Close() ;
bool bAdded = false ;
// se il loop è CW devo controllare in quale altro dei poligoni che ho già aggiunto è contenuto
if ( ! inA.bCCW) {
@@ -3211,7 +3341,9 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly,
for ( int r = 0 ; r < nPoly ; ++r) {
if ( IsPointInsidePolyLine( ptStart, vPolygons[nOtherPoly - r - 1][0], -0.01) && vnParentChunk[nPoly - r - 1] == inA.nChunk) {
vPolygons[nOtherPoly - r - 1].push_back( plInLoop) ;
vPolygons3d[nOtherPoly - r - 1].push_back( plInLoop3d) ;
plInLoop.Clear() ;
plInLoop3d.Clear() ;
bAdded = true ;
break ;
}
@@ -3220,12 +3352,17 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly,
if ( ! bAdded) {
vCellPolygons.push_back( plInLoop) ;
vPolygons.push_back( vCellPolygons) ;
vCellPolygons3d.push_back( plInLoop3d) ;
vPolygons3d.push_back( vCellPolygons3d) ;
++ nPoly ;
vnParentChunk.push_back( inA.nChunk) ;
plInLoop.Clear() ;
vCellPolygons.clear() ;
plInLoop3d.Clear() ;
vCellPolygons3d.clear() ;
}
plInLoop.Clear() ;
plInLoop3d.Clear() ;
}
else
continue ;
@@ -3384,11 +3521,14 @@ Tree::AreSameEdge( int nEdge1, int nEdge2) const
//----------------------------------------------------------------------------
bool
Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const
Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d) const
{
// se è il primo punto della PolyLine lo aggiungo
if ( plTrimmedPoly.GetPointNbr() == 0) {
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ;
m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
return true ;
}
@@ -3403,20 +3543,37 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly,
if ( ! AreSamePointApprox( ptToAdd, ptLast))
vDir = ptToAdd - ptLast ;
else
return true ;
return false ;
// se non riesco a normalizzare perché sono troppo vicino ad un vertice allora aggiungo direttamente il vertice
if ( ! vDir.Normalize()) {
plTrimmedPoly.EraseLastUPoint() ;
if ( AreSamePointApprox( ptToAdd, ptBr))
plTrimmedPoly.AddUPoint( c, ptBr) ;
else if ( AreSamePointApprox( ptToAdd, ptTR))
plTrimmedPoly.AddUPoint( c, ptTR) ;
else if ( AreSamePointApprox( ptToAdd, ptTl))
plTrimmedPoly.AddUPoint( c, ptTl) ;
else if ( AreSamePointApprox( ptToAdd, ptBL))
plTrimmedPoly.AddUPoint( c, ptBL) ;
Point3d ptVert ;
int nVert = -1 ;
if ( AreSamePointApprox( ptToAdd, ptBr)){
ptVert = ptBr ;
nVert = 1 ;
}
else if ( AreSamePointApprox( ptToAdd, ptTR)) {
ptVert = ptTR ;
nVert = 2 ;
}
else if ( AreSamePointApprox( ptToAdd, ptTl)) {
ptVert = ptTl ;
nVert = 3 ;
}
else if ( AreSamePointApprox( ptToAdd, ptBL)) {
ptVert = ptBL ;
nVert = 0 ;
}
else
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
ptVert = ptToAdd ;
plTrimmedPoly.AddUPoint( c, ptVert) ;
Point3d pt3d ;
if ( nVert != -1)
pt3d = m_mVert.at(nId)[nVert] ;
else
m_pSrfBz->GetPointD1D2( ptVert.x, ptVert.y, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
return true ;
}
@@ -3428,10 +3585,13 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly,
Point3d ptIntermed = vEdgeVertex[0][t] ;
if ( ptIntermed.x > ptToAdd.x && ptIntermed.x < ptLast.x) {
plTrimmedPoly.AddUPoint( c, ptIntermed) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[0][t]) ;
++ c ;
}
}
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
// edge 1
@@ -3440,10 +3600,13 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly,
Point3d ptIntermed = vEdgeVertex[1][t] ;
if ( ptIntermed.y > ptToAdd.y && ptIntermed.y < ptLast.y) {
plTrimmedPoly.AddUPoint( c, ptIntermed) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[1][t]) ;
++ c ;
}
}
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
// edge 2
@@ -3452,10 +3615,13 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly,
Point3d ptIntermed = vEdgeVertex[2][t] ;
if ( ptIntermed.x < ptToAdd.x && ptIntermed.x > ptLast.x) {
plTrimmedPoly.AddUPoint( c, ptIntermed) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[2][t]) ;
++ c ;
}
}
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
// edge 3
@@ -3464,22 +3630,29 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly,
Point3d ptIntermed = vEdgeVertex[3][t] ;
if ( ptIntermed.y < ptToAdd.y && ptIntermed.y > ptLast.y) {
plTrimmedPoly.AddUPoint( c, ptIntermed) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[3][t]) ;
++ c ;
}
}
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
// sono allineato con un lato, ma NON sono su un lato
// aggiungo e basta
else {
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
}
// non su un edge, quindi aggiungo e basta
else {
plTrimmedPoly.AddUPoint( c, ptToAdd) ;
Point3d pt3d ; m_pSrfBz->GetPointD1D2( ptToAdd.x / SBZ_TREG_COEFF, ptToAdd.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
plTrimmedPoly3d.AddUPoint( c, pt3d) ;
++ c ;
}
return true ;
@@ -3899,13 +4072,13 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
// recupero i poligoni base delle celle sui bordi
POLYLINEMATRIX mPL ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[0], false, vEdges[0]) ;
GetPolygonsBasic( mPL[0], vEdges[0]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[1], false, vEdges[1]) ;
GetPolygonsBasic( mPL[1], vEdges[1]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[2], false, vEdges[2]) ;
GetPolygonsBasic( mPL[2], vEdges[2]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[3], false, vEdges[3]) ;
GetPolygonsBasic( mPL[3], vEdges[3]) ;
// scorro sui gruppi di polyline che rappresentano i poligoni delle celle lungo un lato
for ( int i = 0 ; i < int( mPL.size()) ; ++i) {
@@ -4097,6 +4270,7 @@ Tree::AddCutsToRoot( POLYLINEVECTOR& vCuts)
bool
Tree::AdjustCuts( void)
{
// correzione del verso dei tagli aperti
if ( int( m_mTree.at( -1).m_vInters.size()) == 1)
return true ;
// li riordino per ordine di quali taglio incontrerei percorrendo il bordo della cella a partire da ptTR
@@ -4138,10 +4312,19 @@ Tree::CreateCellContour( POLYLINEMATRIX& vPolygons)
pl.AddUPoint(2, m_mTree.at(nRoot).GetBottomLeft()) ;
pl.AddUPoint(3, m_mTree.at(nRoot).GetBottomRight()) ;
pl.Close() ;
PolyLine pl3d ;
pl3d.AddUPoint(0, m_mVert.at(nRoot)[2]) ;
pl3d.AddUPoint(1, m_mVert.at(nRoot)[3]) ;
pl3d.AddUPoint(2, m_mVert.at(nRoot)[0]) ;
pl3d.AddUPoint(3, m_mVert.at(nRoot)[1]) ;
pl3d.Close() ;
// ora posso creare il poligono della cella con i tagli
POLYLINEMATRIX vPolygons3d ;
while( (int)vToCheck.size() != 0) {
int nPolyBefore = nPoly ;
CreateCellPolygons( 0, vPolygons, vToCheck, nPoly, vnParentChunk, pl) ;
CreateCellPolygons( 0, vPolygons, vPolygons3d, vToCheck, nPoly, vnParentChunk, pl, pl3d) ; // l'aggiunta di vPolygons3d forse è un problema in questo punto.
// sarà da valutare quando si aggiungerà la funzione per aggiungere tagli aperti
// e se si vuole usare la funzione su uno spazio 2D ideale non collegato ad una sup di Bezier
if ( nPolyBefore == nPoly)
break ;
}
+12 -7
View File
@@ -238,10 +238,14 @@ class Tree
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ; // dSideMax è il massimo per la dimensione maggiore di un triangolo della trimesh
// dSideMin è lunghezza minima del lato di una cella nello spazio reale
bool BuildTree_test( double dLinTol = LIN_TOL_STD, double dSideMin = 1, double dSideMax = INFINITO) ;
bool GetPolygons( POLYLINEMATRIX& vPolygons) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bFroTriangulation = false, INTVECTOR vCells = {}) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
// se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
bool GetPolygons( POLYLINEMATRIX& vvPolygons) ;
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d) ;
bool GetPolygons( POLYLINEMATRIX& vPolygons, bool bForTriangulation, POLYLINEMATRIX& vvPolygons3d) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, bool bForTriangulation, POLYLINEVECTOR& vPolygons3d, INTVECTOR vCells = {}) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
// ad ogni poligono sono stati aggiunti tutti i vertici dei vicini posizionati sui suoi lati
// se richiesti per la triangolazione ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygons3d) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR vCells = {}) ;
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
bool GetEdges3D ( POLYLINEMATRIX& mPLEdges) ; // restituisce gli edge 3D come polyline
bool GetSplitLoops( POLYLINEVECTOR& vPl) const // funzione che restituisce i loop splitatti ai confini delle celle
@@ -272,14 +276,14 @@ class Tree
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
bool FindInters( int& nId, const CurveLine& clTrim, PNTVECTOR& vptInters, bool bFirstInters = true) ; // trova le intersezioni tra una cella e una linea di trim
// resituisce l'id della cella verso cui la curva di trim esce e il vettore delle intersezioni per la cella successiva con il primo punto
bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni.
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, int& nPoly, INTVECTOR& vnParentChunk) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
bool CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni.
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario
bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR.
bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3)
bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2.
bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c, const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag
bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata)
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW)
@@ -311,6 +315,7 @@ class Tree
int m_nSpanU ; // numero di span lungo il parametro U
int m_nSpanV ; // numero di span lungo il parametro V
POLYLINEMATRIX m_vPolygons ; // matrice dei poligoni del tree
POLYLINEMATRIX m_vPolygons3d ; // matrice dei poligoni3d del tree
std::map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
std::map<int,PNTVECTOR> m_mVert ; // mappa che contiene tutti i vertici 3d delle celle del tree. L'Id è lo stesso che la cella ha in m_mTree. I punti sono nell'ordine P00, P10, P11, P01
INTVECTOR m_vnLeaves ; // vettore delle foglie