Files
EgtGeomKernel/Tree.h
T
Daniele Bariletti e4243a2df3 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
2023-05-29 09:02:51 +02:00

143 lines
9.7 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2023
//----------------------------------------------------------------------------
// File : Tree.h Data : 21.04.23 Versione :
// Contenuto : Implementazione della classe Cell di un albero binario Tree.
//
//
//
// Modifiche : 21.04.23 DB Creazione modulo.
//
//
//----------------------------------------------------------------------------
#pragma once
//--------------------------- Include ----------------------------------------
#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
{
public :
~Cell( void) ;
Cell( void) ;
Cell( Point3d& ptBL, Point3d& ptTR) ;
inline bool IsSame( const Cell& cOtherCell) const ;
void SetBottomLeft( Point3d ptBL) { m_ptPbl = ptBL ; }
void SetTopRight( Point3d ptTR) { m_ptPtr = ptTR ; }
void SetSplitDirVert( bool bVert) { m_bSplitVert = bVert ; }
void SetParent( int nParent) { m_nParent = nParent ; }
Point3d GetBottomLeft( void) const { return m_ptPbl ; }
Point3d GetTopRight( void) const { return m_ptPtr ; }
double GetSplitValue( void) const { return m_dSplit ; }
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 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_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
Point3d m_ptPtr ; // punto top right
bool m_bProcessed ; // flag che indica se la cella è stata processata
bool m_bSplitVert ; // flag che indica in quale direzione è stata divisa la cella
} ;
//----------------------------------------------------------------------------
class Tree
{
public :
~Tree( void) ;
Tree( void) ;
Tree ( const SurfBezier* pSrfBz, bool bSplitPatches = false) ;
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( 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
void Balance () ; // creo rami in modo che tutte tutte le foglie abbiano come adiacenti foglie ad una profonditù di +- 1
int GetHeightLeaves ( int nId, INTVECTOR& vnLeaves, int d = 0) const ; // altezza del subtree a partire dal nodo nId
int GetDepth ( int nId, int nRef) const ; // livello del nodo nId
void GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const ; // restituisce le celle foglie che sono adiacenti al lato top
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 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
} ;