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
+137 -73
View File
@@ -162,13 +162,13 @@ SurfBezier::SetTrimRegion( ISurfFlatRegion& sfrTrimReg, bool bIntersectOrSubtrac
}
ResetAuxSurf() ;
// assegno la regione di trim
m_bTrimmed = true ;
if ( m_pTrimReg != nullptr ) {
if ( ! m_pTrimReg->Intersect( *pSfrTrim))
return false ;
}
else
m_pTrimReg = GetBasicSurfFlatRegion( Release( pSfrTrim)) ;
m_bTrimmed = true ;
return true ;
}
@@ -771,7 +771,6 @@ SurfBezier::Load( NgeReader& ngeIn)
}
// se trimmata, lettura della regione
if ( bTrimmed) {
m_bTrimmed = true ;
// creo l'oggetto
ResetTrimRegion() ;
m_pTrimReg = CreateBasicSurfFlatRegion() ;
@@ -781,6 +780,7 @@ SurfBezier::Load( NgeReader& ngeIn)
IGeoObjRW* pGObjRW = dynamic_cast<IGeoObjRW*>( m_pTrimReg) ;
if ( pGObjRW == nullptr || ! pGObjRW->Load( ngeIn))
return false ;
m_bTrimmed = true ;
}
// eseguo validazione
@@ -1439,6 +1439,38 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
return dLen ;
}
//----------------------------------------------------------------------------
bool
SurfBezier::UpdateEdgeFromTree( POLYLINEMATRIX& mPl) const
{
bool bComposed = true ;
m_mCCEdge.clear() ;
for ( int i= 0 ; i < int( mPl.size()); ++i) {
m_mCCEdge.emplace_back() ;
for ( int j = 0 ; j < int ( mPl[i].size()) ; ++j) {
m_mCCEdge.back().emplace_back(CreateBasicCurveComposite()) ;
PolyLine pl3D ;
Point3d pt ; mPl[i][j].GetFirstPoint( pt) ;
Point3d pt3D ; GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
int nCount = 0 ;
pl3D.AddUPoint( nCount, pt3D) ;
++ nCount ;
while( mPl[i][j].GetNextPoint( pt)){
GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
pl3D.AddUPoint( nCount, pt3D) ;
++ nCount ;
}
if ( ! m_mCCEdge.back().back()->FromPolyLine( pl3D))
bComposed = false ;
}
}
// se degli edge hanno delle curve non valide allora salvo anche le polyline
if ( ! bComposed)
m_mPlEdge = mPl ;
return true ;
}
//----------------------------------------------------------------------------
const SurfTriMesh*
SurfBezier::GetAuxSurf( void) const
@@ -1459,6 +1491,7 @@ SurfBezier::GetAuxSurf( void) const
BIPNTVECTOR vTrees ;
Tree.GetIndependentTrees( vTrees) ;
bool bTest = false ; // per debug
POLYLINEMATRIX mPlEdges(4) ;
for ( int i = 0 ; i < (int) vTrees.size() ; ++ i) {
Point3d ptMin = std::get<0>( vTrees[i]) ;
Point3d ptMax = std::get<1>( vTrees[i]) ;
@@ -1472,8 +1505,13 @@ SurfBezier::GetAuxSurf( void) const
Tree.BuildTree( 5 * LIN_TOL_FINE, 0.1) ;
}
Tree.GetPolygons( vvPL) ;
//Tree.GetPolygonsBasic( vPL) ; // per usare i polygon basic
// aggiorno la chiusura della superficie
m_bClosedU = m_bClosedU || Tree.IsClosedU() ;
m_bClosedV = m_bClosedU || Tree.IsClosedV() ;
// salvo i bordi in 3d, che servono in caso si voglia trimmare la superficie DOPO aver costruito la trimesh ausiliaria
Tree.GetEdges3D( mPlEdges) ;
}
//// per usare i polygon basic//////////////////////
//for (int k = 0 ; k < (int)vPL.size(); ++k) {
@@ -1482,28 +1520,35 @@ SurfBezier::GetAuxSurf( void) const
//}
//// per usare i polygon basic///////////////////
UpdateEdgeFromTree( mPlEdges) ;
/////////////////// così facendo sto recuperando gli Edge e la chiusura solo dell'ULTIMO TREE analizzato!!!!! (in caso di trim che creano più chunk analizzo più tree separatamente)///////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// aggiorno la chiusura della superficie
m_bClosedU = Tree.IsClosedU() ;
m_bClosedV = Tree.IsClosedV() ;
//m_vbPole = Tree.GetPoles() ;
/////////////////////da testare/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// bool bComposed = true ;
// m_mCCEdge.clear() ;
// for ( int i= 0 ; i < int( mPlEdges.size()); ++i) {
// m_mCCEdge.emplace_back() ;
// for ( int j = 0 ; j < int ( mPlEdges[i].size()) ; ++j) {
// m_mCCEdge.back().emplace_back(CreateBasicCurveComposite()) ;
// PolyLine pl3D ;
// Point3d pt ; mPlEdges[i][j].GetFirstPoint( pt) ;
// Point3d pt3D ; GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
// int nCount = 0 ;
// pl3D.AddUPoint( nCount, pt3D) ;
// ++ nCount ;
// while( mPlEdges[i][j].GetNextPoint( pt)){
// GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
// pl3D.AddUPoint( nCount, pt3D) ;
// ++ nCount ;
// }
// if ( ! m_mCCEdge.back().back()->FromPolyLine( mPlEdges[i][j]) )
// bComposed = false ;
// }
// }
// salvo i bordi in 3d, che servono in caso si voglia trimmare la superficie DOPO aver costruito la trimesh ausiliaria
POLYLINEVECTOR vPLEdges ;
Tree.GetEdge3D( vPLEdges) ;
bool bComposed = true ;
for ( int i= 0 ; i < int( vPLEdges.size()); ++i) {
m_vCCEdge.emplace_back( CreateBasicCurveComposite()) ;
if ( ! m_vCCEdge.back()->FromPolyLine( vPLEdges[i]))
bComposed = false ;
}
if ( ! bComposed)
m_vPLEdge = vPLEdges ;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// if ( ! bComposed)
// m_mPLEdge = mPlEdges ;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// qui non sarebbe male stampare un messaggio di errore nel log se avevo un'area da disegnare ma non sono usciti dei poligoni
if ( int(vvPL.size()) == 0)
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated, hence wasn't drawn") ;
@@ -2227,7 +2272,7 @@ SurfBezier::Cut( const Plane3d& plPlane, bool bSaveOnEq)
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
@@ -2257,21 +2302,24 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
// se sono in polo e mi hanno passato un punto precedente allora devo prendere il triangolo di quel punto
bool bIsPole = false ;
int nInters = 0 ;
INTVECTOR vInters ;
INTVECTOR vInters(4) ;
fill( vInters.begin(), vInters.end(), 0) ;
// se il vettore dei poli non è stato riempito vuol dire che quando è stata creata la superficie non è stata chiamata la funzione CalcPoles
if ( int( m_vbPole.size()) == 0)
return false ;
if ( m_vbPole[0] || m_vbPole[1] || m_vbPole[2] || m_vbPole[3] || m_bClosedU || m_bClosedV) {
for ( int c = 0 ; c < 4 ; ++c) {
if ( ! m_vCCEdge[c]->IsValid()) {
Point3d pt ;
m_vPLEdge[c].GetFirstPoint( pt) ;
vInters.push_back( AreSamePointApprox( pt, ptI) ? 1 : 0) ;
nInters += vInters.back() ;
}
else {
vInters.push_back( m_vCCEdge[c]->IsPointOn( ptI) ? 1 : 0) ;
nInters += vInters.back() ;
for ( int i = 0 ; i < int( m_mCCEdge[c].size()) ; ++i) {
if ( ! m_mCCEdge[c][i]->IsValid() ) {
Point3d pt ;
m_mPlEdge[c][i].GetFirstPoint(pt) ;
vInters[c] = AreSamePointApprox( pt, ptI) ? 1 : 0 ;
nInters += vInters.back() ;
}
else {
vInters[c] = m_mCCEdge[c][i]->IsPointOn(ptI) ? 1 : 0 ;
nInters += vInters.back() ;
}
}
}
@@ -2333,18 +2381,20 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
int nVertOnPole = -1 ;
for ( int p = 0 ; p < 3; ++p ) {
for ( int ed = 0 ; ed < 4; ++ed) {
if ( ! m_vCCEdge[ed]->IsValid()) {
Point3d pt ;
m_vPLEdge[ed].GetFirstPoint( pt) ;
if ( AreSamePointApprox( pt, vPT[p])) {
vOn[p] = ed ;
// se un vertice sta su un polo me lo segno
nVertOnPole = p ;
for ( int i = 0 ; i < int( m_mCCEdge[ed].size()) ; ++i) {
if ( ! m_mCCEdge[ed][i]->IsValid() ) {
Point3d pt ;
m_mPlEdge[ed][i].GetFirstPoint(pt) ;
if ( AreSamePointApprox( pt, vPT[p])) {
vOn[p] = ed ;
// se un vertice sta su un polo me lo segno
nVertOnPole = p ;
}
}
else {
if (m_mCCEdge[ed][i]->IsPointOn(vPT[p]) && vOn[p] == -1 )
vOn[p] = ed ;
}
}
else {
if (m_vCCEdge[ed]->IsPointOn( vPT[p]) && vOn[p] == -1)
vOn[p] = ed ;
}
}
}
@@ -2380,18 +2430,20 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
int nVertOnPole = -1 ;
for ( int p = 0 ; p < 3; ++p ) {
for (int ed = 0 ; ed < 4 ; ++ed) {
if ( ! m_vCCEdge[ed]->IsValid()) {
Point3d pt ;
m_vPLEdge[ed].GetFirstPoint( pt) ;
if ( AreSamePointApprox( pt, vPT[p])) {
vOn[p] = ed ;
// se un vertice sta su un polo me lo segno
nVertOnPole = p ;
for ( int i = 0 ; i < int( m_mCCEdge[ed].size()) ; ++i) {
if ( ! m_mCCEdge[ed][i]->IsValid()) {
Point3d pt ;
m_mPlEdge[ed][i].GetFirstPoint( pt) ;
if ( AreSamePointApprox( pt, vPT[p])) {
vOn[p] = ed ;
// se un vertice sta su un polo me lo segno
nVertOnPole = p ;
}
}
else {
if( m_mCCEdge[ed][i]->IsPointOn( vPT[p]) && vOn[p] == -1)
vOn[p] = ed ;
}
}
else {
if( m_vCCEdge[ed]->IsPointOn( vPT[p]) && vOn[p] == -1)
vOn[p] = ed ;
}
}
}
@@ -2440,13 +2492,15 @@ SurfBezier::UnprojectPointFromStm( int nT, const Point3d& ptI, Point3d& ptSP, in
std::fill( vbOn.begin(), vbOn.end(), false) ;
for ( int p = 0 ; p < 3; ++p ) {
for ( int c = 0 ; c < 4; ++c) {
if ( ! m_vCCEdge[c]->IsValid()) {
Point3d pt ;
m_vPLEdge[c].GetFirstPoint( pt) ;
vbOn[p] = vbOn[p] || AreSamePointApprox( pt, vPT[p]) ;
for( int i = 0 ; int( m_mCCEdge[c].size()) ; ++i) {
if ( ! m_mCCEdge[c][i]->IsValid()) {
Point3d pt ;
m_mPlEdge[c][i].GetFirstPoint( pt) ;
vbOn[p] = vbOn[p] || AreSamePointApprox( pt, vPT[p]) ;
}
else
vbOn[p] = vbOn[p] || m_mCCEdge[c][i]->IsPointOn( vPT[p]) ;
}
else
vbOn[p] = vbOn[p] || m_vCCEdge[c]->IsPointOn( vPT[p]) ;
}
}
// trovo la coordinata giusta da tenere ( x o y a seconda dell'edge)
@@ -2667,14 +2721,23 @@ SurfBezier::GetEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge) c
if ( m_pSTM == nullptr)
GetAuxSurf() ;
if ( nEdge == -1 ) {
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 0)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 1)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 2)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 3)) ;
// se la superficie non è trimmata mi basta recuperare gli edge della superficie
if ( ! m_bTrimmed) {
// se decidessi di non restituire gli edge chiusi e i poli posso discriminare qui
if ( nEdge == -1 ) {
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 0)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 1)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 2)) ;
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, 3)) ;
}
else
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, nEdge)) ;
}
// se la superficie è trimmata devo recuperare i loop dello spazio parametrico
else {
for ( int i = 0 ; i < int(m_vCCLoop.size()) ; ++i)
vCC.emplace_back( m_vCCLoop[i]->Clone()) ;
}
else
vCC.emplace_back( GetSingleEdge3D( bLineOrBezier, nEdge)) ;
return true ;
}
@@ -2682,14 +2745,15 @@ SurfBezier::GetEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge) c
ICurveComposite*
SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
{
if ( nEdge < 0 || nEdge > 3)
// questa funzione dà per scontato che la superficie NON sia trimmata
if ( nEdge < 0 || nEdge > 3 || m_bTrimmed)
return nullptr ;
ICurveComposite* pCrvCompo( CreateBasicCurveComposite()) ;
switch ( nEdge) {
case 0 : {
// se il bool è true allora restituisco gli edge con la loro approssimazione in forma di linea spezzata 3D
if ( bLineOrBezier)
pCrvCompo = m_vCCEdge[nEdge]->Clone() ;
pCrvCompo = m_mCCEdge[nEdge][0]->Clone() ;
// se il bool è falso restituisco le curve Bezier di edge
else {
//edge 0, scorro sulle patch in U
@@ -2711,7 +2775,7 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
}
case 1 : {
if ( bLineOrBezier)
pCrvCompo = m_vCCEdge[nEdge]->Clone() ;
pCrvCompo = m_mCCEdge[nEdge][0]->Clone() ;
else {
//edge 1, scorro sulle patch in V
for ( int i = 0 ; i < m_nSpanV ; ++i) {
@@ -2732,7 +2796,7 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
}
case 2 : {
if ( bLineOrBezier)
pCrvCompo = m_vCCEdge[nEdge]->Clone() ;
pCrvCompo = m_mCCEdge[nEdge][0]->Clone() ;
else {
// edge 2, scorro sulle patch in U
for ( int i = 0 ; i < m_nSpanU ; ++i) {
@@ -2752,7 +2816,7 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
}
case 3 : {
if ( bLineOrBezier)
pCrvCompo = m_vCCEdge[nEdge]->Clone() ;
pCrvCompo = m_mCCEdge[nEdge][0]->Clone() ;
else {
// edge 3, scorro sulle patch in V
for ( int i = 0 ; i < m_nSpanV ; ++i) {
+11 -2
View File
@@ -19,9 +19,12 @@
#include "CurveComposite.h"
#include "SurfTriMesh.h"
#include "SurfFlatRegion.h"
//#include "Tree.h"
#include "/EgtDev/Include/EGkSurfBezier.h"
#include "/EgtDev/Include/EGkGeoCollection.h"
using namespace std ;
class Tree ;
//----------------------------------------------------------------------------
class SurfBezier : public ISurfBezier, public IGeoObjRW
@@ -132,6 +135,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
// funzioni per incrementare le coordinate restando dentro lo spazio parametrico
bool IncreaseUV( double& dU, double dx, bool bUOrV, double* dUVCopy = nullptr, bool bModifyOrig = true) const override ;
bool IncreaseUV( Point3d& ptUV, Vector3d vtH , Point3d* ptUVCopy, bool bModifyOrig) const override ;
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
bool GetEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
public : // IGeoObjRW
@@ -182,7 +187,9 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
double GetCurveOnVApproxLen( double dU) const ;
// funzione che proietta nello spazio parametrico un trim derivante da un taglio con un piano, categorizzandolo come aperto o chiuso ( nel parametrico)
bool AddCurveCompoToCuts( ICurveComposite* pCrvCompo, ICRVCOMPOPOVECTOR& vpCCOpen, ICRVCOMPOPOVECTOR& vpCCClosed, double dToler = EPS_SMALL, const Plane3d* pPlCut = nullptr) const ;
// restituisce il singolo edge della superficie non trimmata
ICurveComposite* GetSingleEdge3D( bool bLineOrBezier, int nEdge) const ;
bool UpdateEdgeFromTree( POLYLINEMATRIX& mPl) const ;
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
@@ -202,8 +209,10 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
SurfFlatRegion* m_pTrimReg ; // eventuale regione di trim
int m_nTempProp[2] ; // vettore proprietà temporanee
double m_dTempParam[2] ; // vettore parametri temporanei
mutable ICRVCOMPOPVECTOR m_vCCEdge ;// vettore delle curve compo degli edge nello spazio 3D
mutable POLYLINEVECTOR m_vPLEdge ; // vettore delle polyline degli edge nello spazio 3D
mutable vector<ICRVCOMPOPVECTOR> m_mCCEdge ;// vettore dei vettori che contengono le curve compo degli edge della superficie nello spazio 3D
mutable POLYLINEMATRIX m_mPlEdge ; // vettoredei vettori delle polyline degli edge della superficie nello spazio 3D
mutable ICRVCOMPOPOVECTOR m_vCCLoop ; // vettore dei loop della superficie trimmata
mutable POLYLINEVECTOR m_vPLLoop ; // vettore delle polyline dei loop della superficie trimmata
} ;
//-----------------------------------------------------------------------------
+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 ;
}
+10 -4
View File
@@ -18,6 +18,7 @@
#include "GeoConst.h"
#include "CurveLine.h"
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include <map>
//----------------------------------------------------------------------------
@@ -241,13 +242,15 @@ class Tree
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, 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
bool GetLeaves ( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
bool GetEdge3D ( POLYLINEVECTOR& vPLEdges) ; // restituisce gli edge 3D come curve composite
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
{ for ( int i = 0 ; i < int( m_vPlLoop2D.size()); ++i) vPl.emplace_back( m_vPlLoop2D[i]) ; 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
bool CreateCellContour( POLYLINEMATRIX& vPolygons) ; // crea il nuovo contorno esterno, tenendo conto dei tagli
bool IsClosedU( void) { return m_bClosedU ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro U
bool IsClosedV( void) { return m_bClosedV ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro V
bool IsClosedU( void) const { return m_bClosedU ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro U
bool IsClosedV( void) const { return m_bClosedV ;} ; // funzione che riferisce se la superficie è chiusa lungo il parametro V
std::vector<bool> GetPoles( void) { return m_vbPole ;} ; // funzione che restituisce i flag che indicano se i lati sono collassati in dei poli
private :
@@ -280,6 +283,7 @@ class Tree
bool CheckIfBetween( const Inters& inA, const Inters& inB) const ; // / controllo se inB è compreso tra l'end e lo start di inA (in senso CCW)
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) ;
private :
@@ -289,7 +293,7 @@ class Tree
INTMATRIX m_vChunk ; // elenco dei loop divisi per chunk
std::map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
ICURVEPOVECTOR m_vLoop ; // curve di loop
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop
std::vector<std::tuple<PolyLine,bool>> m_vPlApprox ; // vettore contenente le approssimazioni dei loop // il bool indica se la curva è CCW
bool m_bBilinear ; // superficie bilineare
bool m_bMulti ; // superficie multi-patch
bool m_bClosedU ; // superficie chiusa lungo il parametro U
@@ -306,4 +310,6 @@ class Tree
INTVECTOR m_vnLeaves ; // vettore delle foglie
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
std::vector<std::pair<BIPNTVECTOR, ChainCurves>> m_vCEdge2D ; // vettore che le chain che rappresentano ciò che resta degli edge originali, tenendo conto dei trim.
} ;