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:
@@ -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
@@ -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
@@ -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) ; }
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user