EgtGeomKernel :

- nella get Edges3D per sup di Bezier gestito il caso di sup trimmate.
This commit is contained in:
Daniele Bariletti
2024-03-13 15:59:55 +01:00
parent 469d1c3445
commit 67c03daa42
4 changed files with 320 additions and 166 deletions
+162 -87
View File
@@ -1395,6 +1395,12 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
else {
POLYLINEVECTOR vPolygonsBasic ;
GetPolygonsBasic( vPolygonsBasic) ;
// aggiungo 4 elementi al vettore che contiene ciò che resta degli edge dopo il trim
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
@@ -1808,6 +1814,40 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
return nCells ;
}
//----------------------------------------------------------------------------
bool
Tree::UpdateSplitLoop( PolyLine& pl, int& nCount, Point3d& pt)
{
Point3d ptLast ;
pl.GetLastPoint( ptLast) ;
if ( pl.AddUPoint( nCount, pt))
++ nCount ;
if ( pl.GetPointNbr() != 1 ) {
Vector3d vtDir = pt - ptLast ;
if ( ! vtDir.Normalize())
return false ;
// se sono allineato con gli edge della cella ROOT
int nEdge = -1 ;
if ( abs( vtDir.x) > 1 - EPS_SMALL) {
if ( pt.y < EPS_SMALL)
nEdge = 2 ;
else if ( m_nSpanV * SBZ_TREG_COEFF - pt.y < EPS_SMALL)
nEdge = 0 ;
}
else if ( abs( vtDir.y) > 1 - EPS_SMALL) {
if ( pt.x < EPS_SMALL )
nEdge = 1 ;
else if ( m_nSpanU * SBZ_TREG_COEFF - pt.x < EPS_SMALL )
nEdge = 3 ;
}
if ( nEdge != -1) {
m_vCEdge2D[nEdge].second.AddCurve( m_vCEdge2D[nEdge].first.size() + 1, ptLast, vtDir, pt, vtDir) ;
m_vCEdge2D[nEdge].first.emplace_back( BIPOINT( ptLast, pt)) ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
@@ -1820,6 +1860,9 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// percorro i loop trovando le interezioni con le celle e riempiendo i vettori m_vInters delle varie celle
for ( int i = 0 ; i < (int) m_vPlApprox.size() ; ++ i) {
PolyLine plLoop = get<0>( m_vPlApprox[i]) ;
// creo la polyline che aggiunge alla polyline originale degli split dove interseca le celle ( serve per ricostruire gli edge aperti della superficie)
PolyLine plLoopSplit ;
int nPtLoopSplit = 0 ;
// controllo se il loop è CCW o CW
bool bCCW = get<1>( m_vPlApprox[i]) ;
// trovo in quale cella è il ptStart
@@ -1831,6 +1874,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
advance( ptSecond, 1) ;
CurveLine clFirst ;
clFirst.Set( ptFirst->first, ptSecond->first) ;
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptFirst->first) ;
// individuo la cella da cui parte il loop
INTVECTOR nCells = FindCell( ptStart, clFirst) ;
int nId ;
@@ -1895,9 +1940,13 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
m_mTree[nId].m_vInters.back().bCCW = bCCW ;
// salvo il chunk del loop
m_mTree[nId].m_vInters.back().nChunk = m_mChunk[i] ;
// 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) ;
}
if ( nId == nFirstCell)
vptInters.pop_back() ;
@@ -1946,6 +1995,8 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
m_mTree[nId].m_vInters[nPass].nOut = nOut ;
}
}
// salvo la polyline splittata
m_vPlLoop2D.emplace_back( plLoopSplit) ;
}
// riordino i vettori di intersezione per ogni cella e setto il flag RightEdgeIn
@@ -3556,106 +3607,130 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
//----------------------------------------------------------------------------
bool
Tree::GetEdge3D( POLYLINEVECTOR& vPLEdges)
{
INTMATRIX vEdges ; // le righe sono gli edge a partire dallo 0, le colonne sono le celle che compongono quell'edge
// recupero le celle sui quattro bordi
vEdges.emplace_back() ;
GetRootNeigh( 0, vEdges[0]) ;
// le celle sui bordi orizzontali sono ordinate per x o y crescente, ma i io voglio costruire gli edge in senso antiorario a partire dal ptTR,
// quindi devo invertire gli Edge 0 e 1
reverse( vEdges[0].begin(), vEdges[0].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 1, vEdges[1]) ;
reverse( vEdges[1].begin(), vEdges[1].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 2, vEdges[2]) ;
vEdges.emplace_back() ;
GetRootNeigh( 3, vEdges[3]) ;
Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
{
// se la superficie non è trimmata ricostruisco dalle celle al bordo
if ( ! m_bTrimmed) {
INTMATRIX vEdges ; // le righe sono gli edge a partire dallo 0, le colonne sono le celle che compongono quell'edge
// recupero le celle sui quattro bordi
vEdges.emplace_back() ;
GetRootNeigh( 0, vEdges[0]) ;
// le celle sui bordi orizzontali sono ordinate per x o y crescente, ma i io voglio costruire gli edge in senso antiorario a partire dal ptTR,
// quindi devo invertire gli Edge 0 e 1
reverse( vEdges[0].begin(), vEdges[0].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 1, vEdges[1]) ;
reverse( vEdges[1].begin(), vEdges[1].end()) ;
vEdges.emplace_back() ;
GetRootNeigh( 2, vEdges[2]) ;
vEdges.emplace_back() ;
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]) ;
// 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]) ;
// scorro sui gruppi di polyline che rappresentano i poligoni delle celle lungo un lato
for ( int i = 0 ; i < int( mPL.size()) ; ++i) {
vPLEdges.emplace_back() ;
int nPtCount = 0 ;
// 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) ;
Point3d pt3d ;
// a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato
if ( i == 0) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopRight()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[2]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
vPLEdges.back().AddUPoint( nPtCount, pt3d) ;
// 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 ;
// 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) ;
Point3d pt3d ;
// a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato
if ( i == 0) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopRight()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[2]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[3]) ;
++ nPtCount ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[0][c])[3]) ;
++ nPtCount ;
}
else if ( i == 1 ) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetTopLeft()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[3]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
vPLEdges.back().AddUPoint( nPtCount, pt3d) ;
else if ( i == 1 ) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetTopLeft()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[3]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[0]) ;
++ nPtCount ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[1][c])[0]) ;
++ nPtCount ;
}
else if ( i == 2) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomLeft()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[0]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
vPLEdges.back().AddUPoint( nPtCount, pt3d) ;
else if ( i == 2) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomLeft()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[0]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[1]) ;
++ nPtCount ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[2][c])[1]) ;
++ nPtCount ;
}
else if ( i == 3) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetBottomRight()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[1]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
vPLEdges.back().AddUPoint( nPtCount, pt3d) ;
else if ( i == 3) {
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetBottomRight()) && mPL[i][c].GetNextPoint( pt)) {
continue ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[1]) ;
++ nPtCount ;
// scorro fino alla fine di quel lato
while ( mPL[i][c].GetNextPoint( pt) && ! AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight())) {
m_pSrfBz->GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3d) ;
mPLEdges.back().back().AddUPoint( nPtCount, pt3d) ;
++ nPtCount ;
}
mPLEdges.back().back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[2]) ;
++ nPtCount ;
}
vPLEdges.back().AddUPoint( nPtCount, m_mVert.at(vEdges[3][c])[2]) ;
++ nPtCount ;
}
}
}
// se la superficie è trimmata ricostruisco dai loop splittati ricostruiti durante il TraceLoop
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) {
INTVECTOR vId ;
Point3d ptNear = m_mTree.at(-1).GetBottomLeft() ;
while( m_vCEdge2D[i].second.GetChainFromNear(ptNear, false, vId) ) {
PolyLine pl2D ;
int nInd = abs( vId[0]) - 1 ;
pl2D.AddUPoint( 0, m_vCEdge2D[i].first[nInd].first) ;
int nCount = 1 ;
for ( int j = 1 ; j < int( vId.size()) ; ++j) {
nInd = abs( vId[j]) - 1 ;
if ( pl2D.AddUPoint( nCount, m_vCEdge2D[i].first[nInd].second))
++ nCount ;
}
// qui devo fare dei controlli prima di aggiungere questa polyline?
mPLEdges[i].emplace_back( pl2D) ;
}
}
}
return true ;
}