EgtGeomKernel :

- implementato il trim dello spazio parametrico.
Da aggiungere :
- gestione delle celle non intersecate, interne ai loop
Problematiche :
- gestione di aree di trim nested in una cella
This commit is contained in:
Daniele Bariletti
2023-05-29 09:02:51 +02:00
parent 967f5aa795
commit e4243a2df3
5 changed files with 1444 additions and 372 deletions
+3
View File
@@ -473,6 +473,7 @@
</ClCompile>
<ClCompile Include="Tree.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
<ClCompile Include="IntersLineCyl.cpp">
<Filter>File di origine\GeoInters</Filter>
</ClCompile>
@@ -1112,6 +1113,8 @@
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="Tree.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="IntersLineCyl.h">
<Filter>File di intestazione</Filter>
</ClInclude>
+46 -20
View File
@@ -149,10 +149,12 @@ SurfBezier::SetTrimRegion( const ISurfFlatRegion& sfrTrimReg)
}
//----------------------------------------------------------------------------
bool
SurfBezier::GetTrimRegion( ISurfFlatRegion& sfrTrimReg)
SurfFlatRegion*
SurfBezier::GetTrimRegion( void) const
{
return true ;
if ( ! m_bTrimmed || m_pTrimReg == nullptr )
return nullptr ;
return m_pTrimReg ;
}
//----------------------------------------------------------------------------
@@ -1228,39 +1230,62 @@ SurfBezier::GetCurveOnV( double dU) const
CurveComposite*
SurfBezier::GetLoop( int nLoop) const
{
// Se superficie completa, basta concatenare le 4 isoparametriche di bordo
if ( ! m_bTrimmed) {
// Esiste solo il loop esterno
if ( nLoop != 0)
// Il primo loop sono le 4 isoparametriche di bordo concatenate
if ( ! m_bTrimmed ) {
if ( nLoop != 0 )
return nullptr ;
// Loop
// Loop
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
// prima curva isoparametrica in U con V=0
// prima curva isoparametrica in U con V=0
PtrOwner<CurveComposite> pCrvCoU0( GetCurveOnU( 0)) ;
if ( ! IsNull( pCrvCoU0) && ! pCrvCoU0->IsAPoint())
pLoop->AddCurve( Release( pCrvCoU0)) ;
// seconda curva isoparametrica in V con U=m_nSpanU
// seconda curva isoparametrica in V con U=m_nSpanU
PtrOwner<CurveComposite> pCrvCoV1( GetCurveOnV( m_nSpanU)) ;
if ( ! IsNull( pCrvCoV1) && ! pCrvCoV1->IsAPoint())
pLoop->AddCurve( Release( pCrvCoV1)) ;
// terza curva isoparametrica in U con V=m_nSpanV invertita
// terza curva isoparametrica in U con V=m_nSpanV invertita
PtrOwner<CurveComposite> pCrvCoU1( GetCurveOnU( m_nSpanV)) ;
if ( ! IsNull( pCrvCoU1) && ! pCrvCoU1->IsAPoint()) {
pCrvCoU1->Invert() ;
pLoop->AddCurve( Release( pCrvCoU1)) ;
}
// quarta curva isoparametrica in V con U=0 invertita
// quarta curva isoparametrica in V con U=0 invertita
PtrOwner<CurveComposite> pCrvCoV0( GetCurveOnV( 0)) ;
if ( ! IsNull( pCrvCoV0) && ! pCrvCoV0->IsAPoint()) {
pCrvCoV0->Invert() ;
pLoop->AddCurve( Release( pCrvCoV0)) ;
}
// se loop chiuso lo restituisco, altrimenti errore
// se loop chiuso lo restituisco, altrimenti errore
return ( pLoop->IsClosed() ? Release( pLoop) : nullptr) ;
}
// altrimenti trimmata, per ora non gestita
else
return nullptr ;
// la superficie è trimmata, quindi devo cercare nei vari chunck il loop corrispondente
else {
if ( nLoop > m_pTrimReg->GetChunkCount())
return nullptr ;
else {
int nLoopCount = 0 ;
int nChunck = 0, nLoopLoc = 0;
INTVECTOR nLoopCountPerChunck ;
for ( int i = 0 ; i < m_pTrimReg->GetChunkCount() && nLoopCount != nLoop ; ++ i) {
int nLoopCountLoc = 0 ;
for ( int j = 0 ; j < m_pTrimReg->GetLoopCount( i) ; ++ j) {
++ nLoopCountLoc ;
++ nLoopCount ;
if ( nLoopCount != nLoop ) {
nChunck = i ;
nLoopLoc = j ;
break ;
}
}
nLoopCountPerChunck.push_back( nLoopCountLoc) ;
}
if ( nLoopCount < nLoop )
return nullptr ;
PtrOwner<CurveComposite> pLoop( GetBasicCurveComposite( m_pTrimReg->GetLoop( nChunck, nLoopLoc))) ;
return Release( pLoop) ;
}
}
}
//----------------------------------------------------------------------------
@@ -1473,21 +1498,22 @@ SurfBezier::GetAuxSurf( void) const
return m_pSTM ;
// costruttore della superficie
Tree Tree( this, true) ;
Tree.BuildTree() ;
POLYLINEVECTOR vPL ;
Tree.GetPolygons( vPL) ;
vector<POLYLINEVECTOR> vvPL ;
Tree.GetPolygons( vvPL) ;
PtrOwner<SurfTriMesh> pSrfTm( CreateBasicSurfTriMesh()) ;
StmFromTriangleSoup stmSoup ;
if ( ! stmSoup.Start())
return nullptr ;
// prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d
for ( PolyLine i : vPL) {
for ( POLYLINEVECTOR vPL : vvPL) {
PNTVECTOR vPnt ;
INTVECTOR vTria ;
Triangulate Tri ;
if ( ! Tri.Make( i, vPnt, vTria))
if ( ! Tri.Make( vPL, vPnt, vTria))
return nullptr ;
// porto i punti in 3d
+1 -1
View File
@@ -83,7 +83,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
{ return SetControlPoint( GetInd( nIndU, nIndV), ptCtrl, dW) ; }
bool SetControlPoint( int nInd, const Point3d& ptCtrl, double dW) override ;
bool SetTrimRegion( const ISurfFlatRegion& sfrTrimReg) override ;
bool GetTrimRegion( ISurfFlatRegion& sfrTrimReg) override ;
SurfFlatRegion* GetTrimRegion( void) const override ;
bool GetInfo( int& nDegU, int& nDegV, int& nSpanU, int& nSpanV, bool& bIsRat, bool& bTrimmed) const override ;
const Point3d& GetControlPoint( int nIndU, int nIndV, bool* pbOk) const override
{ return GetControlPoint( GetInd( nIndU, nIndV), pbOk) ; }
+1336 -337
View File
File diff suppressed because it is too large Load Diff
+58 -14
View File
@@ -17,6 +17,28 @@
#include <map>
#include "SurfBezier.h"
#include "GeoConst.h"
#include "CurveLine.h"
struct Inters {
int nIn ;
PNTVECTOR vpt ;
int nOut ;
bool bCCW ;
int nChunk ;
// riordino le intersezioni per lato in senso antiorario dal top
// se ho più intersezioni che entrano in un lato le riordino considerando che percorro i lati in senso antiorario a partire da ptTR
bool operator < ( Inters& b) {
bool bEqIn = ( nIn == b.nIn) ;
return nIn < b.nIn ||
( bEqIn && nIn == 0 && vpt[0].x > b.vpt[0].x) ||
( bEqIn && nIn == 1 && vpt[0].y > b.vpt[0].y) ||
( bEqIn && nIn == 2 && vpt[0].x < b.vpt[0].x) ||
( bEqIn && nIn == 3 && vpt[0].y < b.vpt[0].y)
; }
} ;
// nIn e nOut sono flag che indicano da quale lato ho l'ingresso e l'uscita a partire dal lato top in senso antiorario
// oltre il 3 sono le celle adiacenti in diagonale al vertice-> 4 corrisponde al ptTl e da lì in senso antiorario
// -1 se la curva è sempre dentro la cella
//----------------------------------------------------------------------------
class Cell
@@ -36,21 +58,28 @@ class Cell
bool IsSplitVert( void) const { return m_bSplitVert ; } // se true la cella verrebbe splittata verticalmente, sennò orizzontalmente
bool IsLeaf( void) const ; // flag che indica se la cella ha figli o se è una foglia
bool IsProcessed( void) const { return m_bProcessed ; } // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati
void Processed( void) { m_bProcessed = true ; }
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 ; }
static bool minorY ( const Cell& c1, const Cell& c2) { return c1.m_ptPbl.y < c2.m_ptPbl.y ; }
public :
int m_nId ; // Id della cella
int m_nTop ; // cella adiacente al lato top
int m_nBottom ; // cella adiacente al lato bottom
int m_nLeft ; // cella adiacente al lato left
int m_nRight ; // cella adiacente al lato right
int m_nParent ; // cella genitore
int m_nDepth ; // profondità della cella rispetto a root
double m_dSplit ; // parametro a cui è stata splittata la cella
int m_nChild1 ; // prima cella figlio
int m_nChild2 ; // seconda cella figlio
int m_nId ; // Id della cella
int m_nTop ; // cella adiacente al lato top
int m_nBottom ; // cella adiacente al lato bottom
int m_nLeft ; // cella adiacente al lato left
int m_nRight ; // cella adiacente al lato right
int m_nParent ; // cella genitore
int m_nDepth ; // profondità della cella rispetto a root
double m_dSplit ; // parametro a cui è stata splittata la cella
int m_nChild1 ; // prima cella figlio
int m_nChild2 ; // seconda cella figlio
int m_nFlag ; // falg che indica la caratterizzazaione della cella rispetto ai loop di trim
// -1 non categorizzata
// 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
INTVECTOR m_vnLoop ; // indice dei loop contenuti nella cella
std::vector<Inters> m_vInters ; // vettore delle intersezioni della cella con i loop di trim
// ogni elemento del vettore è l'insieme dei punti che caratterizza un atrtaversamento della cella
private :
Point3d m_ptPbl ; // punto bottom left
@@ -69,9 +98,11 @@ public :
void SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches = true) ;
bool BuildTree( double dLinTol = LIN_TOL_STD, double dSideMin = 5, 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 GetPolygons( POLYLINEVECTOR& vPolygons) ; // restituisce il poligono corrispondente ad ogni cella foglia dell'albero
bool GetPolygons( std::vector<POLYLINEVECTOR>& vPolygons) ;
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons) ; // 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
private :
void Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
void Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
@@ -82,17 +113,30 @@ private :
void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato left
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato right
void GetRootNeigh( int nEdge, INTVECTOR& vNeigh) ; // restituisce le foglie dell'albero che sono adiacenti al lato nEdge, numerato a partire dal top ( 0) in senso antiorario
void ResetTree ( void) ; // resetto m_bProcessed a false per tutti i nodi dell'albero
int FindCell ( const Point3d& ptToAssign) const ; // dato un punto, trova la cella foglia a cui appartiene
bool TraceLoopLabelCell( void) ; // tracing dei loop e labelling delle celle
bool FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters) ; // 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 CheckIfBefore( PolyLine& pl, int nEdge) const ;
bool CheckIfAfter( PolyLine& pl, Point3d& ptNextStart, int nEdge) const ;
private :
const SurfBezier* m_pSrfBz ; // superficie di bezier
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in ordine antiorario a partire da ptP00
DBLVECTOR m_vDim ; // distanze tra i vertici della superficie di bezier in 3d in ordine antiorario a partire da ptP00
bool m_bTrimmed ; // superficie trimmata
std::vector<INTVECTOR> m_vChunk ; // elenco dei loop divisi per chunk
std::map<int,int> m_mChunk ;
//std::vector<ICurve*> m_vLoop ;
ICURVEPOVECTOR m_vLoop ; // curve di loop. la 0 è il bordo dello spazio parametrico, le altre sono i loop interni
bool m_bBilinear ; // superficie bilineare
bool m_bMulti ; // superficie multi-patch
bool m_bClosed ; // superficie chiusa
int m_nDegU ; // grado della superficie nel parametro U
int m_nDegV ; // grado della superficie nel parametro V
POLYLINEVECTOR m_vPolygons ; // vettore dei poligoni del tree
//std::map<int,PolyLine> m_mPolygons ; // mappa dei poligoni
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
INTVECTOR m_vnLeaves ; // vettore delle foglie