- riduzione del numero di copie di polyline nel tree di una bezier.

This commit is contained in:
Daniele Bariletti
2025-03-24 10:09:39 +01:00
parent 0b9c9f375c
commit eb9aaef53a
3 changed files with 86 additions and 76 deletions
+23 -14
View File
@@ -1611,19 +1611,18 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
bool
SurfBezier::UpdateEdgesFromTree( Tree& tr) const
{
POLYLINEMATRIX mPlEdges ;
tr.GetEdges3D( mPlEdges) ;
for ( int i= 0 ; i < int( mPlEdges.size()); ++i) {
for ( int j = 0 ; j < int ( mPlEdges[i].size()) ; ++j) {
m_mCCEdge[i].emplace_back(CreateBasicCurveComposite()) ;
if ( ! m_mCCEdge[i].back()->FromPolyLine(mPlEdges[i][j]) ) {
Point3d ptStart ;
if ( ! mPlEdges[i][j].GetFirstPoint( ptStart))
continue ;
m_mCCEdge[i].back()->FromPoint( ptStart) ;
}
}
}
tr.GetEdges3D( m_mCCEdge) ;
//for ( int i= 0 ; i < int( mPlEdges.size()); ++i) {
// for ( int j = 0 ; j < int ( mPlEdges[i].size()) ; ++j) {
// m_mCCEdge[i].emplace_back(CreateBasicCurveComposite()) ;
// if ( ! m_mCCEdge[i].back()->FromPolyLine(mPlEdges[i][j]) ) {
// Point3d ptStart ;
// if ( ! mPlEdges[i][j].GetFirstPoint( ptStart))
// continue ;
// m_mCCEdge[i].back()->FromPoint( ptStart) ;
// }
// }
//}
if ( m_bTrimmed) {
POLYLINEVECTOR vPl ;
@@ -1636,6 +1635,17 @@ SurfBezier::UpdateEdgesFromTree( Tree& tr) const
}
}
// if ( m_bTrimmed) {
// //POLYLINEVECTOR vPl ;
// tr.GetSplitLoops( m_vCCLoop) ;
// //// recupero i loop nel parametrico
// //for( int i = 0 ; i < int( vPl.size()); ++i) {
// // m_vCCLoop.emplace_back(CreateBasicCurveComposite()) ;
// // m_vCCLoop.back()->FromPolyLine(vPl[i]) ;
// //}
// }
return true ;
}
@@ -1681,7 +1691,6 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin) const
bool bTest = false ; // per debug
// resetto il vettore degli edge
m_mCCEdge.clear() ;
m_mCCEdge = vector<ICRVCOMPOPOVECTOR>(4) ;
m_vCCLoop.clear() ;
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
Point3d ptMin = get<0>( vTrees[i]) ;
+53 -59
View File
@@ -2075,6 +2075,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
}
}
cell.AddPoly( m_vPolygons.size()) ;
m_vPolygons.emplace_back() ;
m_vPolygons.back().emplace_back() ;
m_vPolygonsCorr.emplace_back() ;
@@ -4288,7 +4289,7 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
//----------------------------------------------------------------------------
bool
Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
Tree::GetEdges3D( vector<ICRVCOMPOPOVECTOR>& mCCEdges)
{
// se la superficie non è trimmata ricostruisco dalle celle al bordo
if ( ! m_bTrimmed) {
@@ -4308,97 +4309,90 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
GetRootNeigh( 3, vEdges[3]) ;
// recupero i poligoni base delle celle sui bordi
POLYLINEMATRIX mPL ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[0], vEdges[0]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[1], vEdges[1]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[2], vEdges[2]) ;
mPL.emplace_back() ;
GetPolygonsBasic( mPL[3], vEdges[3]) ;
//POLYLINEMATRIX mPL ;
//mPL.emplace_back() ;
//GetPolygonsBasic( mPL[0], vEdges[0]) ;
//mPL.emplace_back() ;
//GetPolygonsBasic( mPL[1], vEdges[1]) ;
//mPL.emplace_back() ;
//GetPolygonsBasic( mPL[2], vEdges[2]) ;
//mPL.emplace_back() ;
//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) {
mPLEdges.emplace_back() ;
mPLEdges.back().emplace_back() ;
int nPtCount = 0 ;
for ( int i = 0 ; i < int( vEdges.size()) ; ++i) {
mCCEdges.emplace_back() ;
mCCEdges.back().emplace_back(CreateBasicCurveComposite()) ;
// scorro sui poligoni delle celle di un lato
for ( int c = 0 ; c < int( mPL[i].size()) ; ++c) {
Point3d pt ; mPL[i][c].GetFirstPoint( pt) ;
for ( int c = 0 ; c < int( vEdges[i].size()) ; ++c) {
Cell& cNeigh = m_mTree.at(vEdges[i][c]) ;
PolyLine& plCell = m_vPolygons[cNeigh.m_vnPolyId[0]][0] ;
Point3d pt ; plCell.GetFirstPoint( pt) ;
Point3d pt3d ;
// a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato
if ( i == 0) {
while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[0][c]).GetTopRight()) && mPL[i][c].GetNextPoint( pt)) {
while ( ! AreSamePointXYApprox(pt, cNeigh.GetTopRight()) && plCell.GetNextPoint(pt) ) {
continue ;
}
Cell& cNeigh = m_mTree.at(vEdges[0][c]) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddPoint( pt3d) ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft())) {
while ( plCell.GetNextPoint( pt) && ! AreSamePointXYApprox(pt, cNeigh.GetTopLeft())) {
GetPoint( pt.x, pt.y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
}
pt3d = ORIG ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetTopRight().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
if ( ! mCCEdges.back().back()->IsValid())
mCCEdges.back().back()->FromPoint( pt3d) ;
}
else if ( i == 1 ) {
while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[1][c]).GetTopLeft()) && mPL[i][c].GetNextPoint( pt)) {
while ( ! AreSamePointXYApprox(pt, cNeigh.GetTopLeft()) && plCell.GetNextPoint( pt)) {
continue ;
}
Cell& cNeigh = m_mTree.at(vEdges[1][c]) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetTopRight().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddPoint( pt3d) ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft())) {
while ( plCell.GetNextPoint( pt) && ! AreSamePointXYApprox(pt, cNeigh.GetBottomLeft())) {
GetPoint( pt.x, pt.y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
}
pt3d = ORIG ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
if ( ! mCCEdges.back().back()->IsValid())
mCCEdges.back().back()->FromPoint( pt3d) ;
}
else if ( i == 2) {
while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomLeft()) && mPL[i][c].GetNextPoint( pt)) {
while ( ! AreSamePointXYApprox(pt, cNeigh.GetBottomLeft()) && plCell.GetNextPoint( pt)) {
continue ;
}
Cell& cNeigh = m_mTree.at(vEdges[2][c]) ;
Point3d pt3d ; GetPoint( cNeigh.GetBottomLeft().x, cNeigh.GetBottomLeft().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddPoint( pt3d) ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight())) {
while ( plCell.GetNextPoint( pt) && ! AreSamePointXYApprox(pt, cNeigh.GetBottomRight())) {
GetPoint( pt.x, pt.y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
}
pt3d = ORIG ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetBottomLeft().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
if ( ! mCCEdges.back().back()->IsValid())
mCCEdges.back().back()->FromPoint( pt3d) ;
}
else if ( i == 3) {
while ( ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[3][c]).GetBottomRight()) && mPL[i][c].GetNextPoint( pt)) {
while ( ! AreSamePointXYApprox(pt, cNeigh.GetBottomRight()) && plCell.GetNextPoint( pt)) {
continue ;
}
Cell& cNeigh = m_mTree.at(vEdges[3][c]) ;
Point3d pt3d ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetBottomLeft().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddPoint( pt3d) ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointXYApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight())) {
while ( plCell.GetNextPoint( pt) && ! AreSamePointXYApprox(pt, cNeigh.GetTopRight())) {
GetPoint( pt.x, pt.y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
}
pt3d = ORIG ; GetPoint( cNeigh.GetTopRight().x, cNeigh.GetTopRight().y, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
mCCEdges.back().back()->AddLine( pt3d) ;
if ( ! mCCEdges.back().back()->IsValid())
mCCEdges.back().back()->FromPoint( pt3d) ;
}
}
}
@@ -4407,25 +4401,25 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
else {
// per ogni edge creo le compo che compongono l'edge dopo i trim ( possono essere più compo separate tra loro)
for ( int i = 0 ; i < 4 ; ++i) {
mPLEdges.emplace_back() ;
mCCEdges.emplace_back() ;
INTVECTOR vId ;
Point3d ptNear = m_mTree.at(-1).GetBottomLeft() ;
while( m_vCEdge2D[i].second.GetChainFromNear(ptNear, false, vId) ) {
PolyLine pl3D ;
PtrOwner<ICurveComposite> pCC3D( CreateCurveComposite()) ;
int nInd = abs( vId[0]) - 1 ;
Point3d pt2D = m_vCEdge2D[i].first[nInd].first ;
Point3d pt3D ; GetPoint( pt2D.x, pt2D.y, pt3D) ;
pl3D.AddUPoint( 0, pt3D) ;
int nCount = 1 ;
pCC3D->AddPoint( pt3D) ;
for ( int j = 1 ; j < int( vId.size()) ; ++j) {
nInd = abs( vId[j]) - 1 ;
pt2D = m_vCEdge2D[i].first[nInd].second ;
GetPoint( pt2D.x, pt2D.y, pt3D) ;
if ( pl3D.AddUPoint( nCount, pt3D))
++ nCount ;
pCC3D->AddLine( pt3D) ;
}
if ( ! pCC3D->IsValid())
pCC3D->FromPoint( pt3D) ;
// qui devo fare dei controlli prima di aggiungere questa polyline?
mPLEdges[i].emplace_back( pl3D) ;
mCCEdges[i].emplace_back( Release(pCC3D)) ;
}
}
}
+10 -3
View File
@@ -203,9 +203,11 @@ class Cell
void SetProcessed( bool bProcessed = true)
{ m_bProcessed = bProcessed ; }
static bool minorX( const Cell& c1, const Cell& c2)
{ return c1.m_ptPbl.x < c2.m_ptPbl.x ; }
{ return c1.m_ptPbl.x < c2.m_ptPbl.x ; }
static bool minorY( const Cell& c1, const Cell& c2)
{ return c1.m_ptPbl.y < c2.m_ptPbl.y ; }
{ return c1.m_ptPbl.y < c2.m_ptPbl.y ; }
void AddPoly( int nPolyId)
{ m_vnPolyId.push_back( nPolyId) ;}
public :
int m_nId ; // Id della cella
@@ -228,6 +230,7 @@ class Cell
// ogni elemento del vettore è l'insieme dei punti che caratterizza un attraversamento della cella
int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo
// contati in senso CCW a partire dal bottom left
INTVECTOR m_vnPolyId ; // indici dei poligoni associati a questa cella nel vettore m_vPolygons del Tree
private :
Point3d m_ptPbl ; // punto bottom left
@@ -258,9 +261,11 @@ class Tree
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, 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 GetEdges3D ( vector<ICRVCOMPOPOVECTOR>& mCCEdge) ; // restituisce gli edge 3D come polyline
bool GetSplitLoops( POLYLINEVECTOR& vPl) const // funzione che restituisce i loop splitatti ai confini delle celle
{ for ( int i = 0 ; i < int( m_vPlLoop2D.size()); ++i) vPl.emplace_back( m_vPlLoop2D[i]) ; return true ; };
// bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // funzione che restituisce i loop splitatti ai confini delle celle
// { for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i) vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ; return true ; };
void SetTestMode( void) { m_bTestMode = true ;} ; // attivando la test mode, per la costruzione dell'albero viene usata la funzione BuiltTree_test e viene corretta di conseguenza la FindCell
// funzioni da usare per ricostruire tagli che vanno aggiunti allo spazio parametrico
bool AddCutsToRoot( POLYLINEVECTOR& vCuts) ; // aggiunge i tagli al tree
@@ -304,6 +309,7 @@ class Tree
bool OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const ; // indica a quale edge o vertice il punto è vicino entro EPS_SMALL
bool AdjustCuts( void) ;
bool UpdateSplitLoop( PolyLine& pl, int& nCount, Point3d& pt) ;
//bool UpdateSplitLoop( ICurveComposite* pCC, Point3d& pt) ;
bool CloseOpenCuts( void) ;
bool CloseOpenCuts( POLYLINEVECTOR& vPL, PolyLine& pl) const ;
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
@@ -339,5 +345,6 @@ class Tree
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
bool m_bTestMode ; // bool che indica se la test mode è attiva
POLYLINEVECTOR m_vPlLoop2D ; // vettore che contiene le polyline che rappresentano i loop di trim tenendo conto della divisione in celle
//ICRVCOMPOPOVECTOR m_vCCLoop2D ; // vettore che contiene le CurveCompo che rappresentano i loop di trim tenendo conto della divisione in celle
vector<pair<BIPNTVECTOR, ChainCurves>> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim.
} ;