ec6eb3e645
- modifica a Trimming - sistemazioni estetiche varie.
349 lines
23 KiB
C++
349 lines
23 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 "SurfBezier.h"
|
|
#include "GeoConst.h"
|
|
#include "CurveLine.h"
|
|
#include "/EgtDev/Include/EGkPolyLine.h"
|
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
|
#include <map>
|
|
#include <utility>
|
|
|
|
struct PairHashInt64 {
|
|
size_t
|
|
operator()( const std::pair<int64_t, int64_t>& key) const {
|
|
size_t h1 = std::hash<int64_t>{}(key.first) ;
|
|
size_t h2 = std::hash<int64_t>{}(key.second) ;
|
|
return h1 ^ (h2 << 1); // Combine hashes
|
|
}
|
|
} ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
struct Inters {
|
|
int nIn ;
|
|
int nOut ;
|
|
PNTVECTOR vpt ;
|
|
bool bCCW ;
|
|
int nChunk ;
|
|
bool bSortedbyStart ;
|
|
|
|
// 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
|
|
|
|
// 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)
|
|
{
|
|
// trovo in che ordine stanno i due start, tenendo conto anche della possibilità che siano vertici
|
|
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
|
const auto iter1 = find( vEdges.begin(), vEdges.end(), nIn) ;
|
|
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
|
const auto iter2 = find( vEdges.begin(), vEdges.end(), b.nIn) ;
|
|
int nPos2 = std::distance( vEdges.begin(), iter2) ;
|
|
// se sono loop interni li ordino in modo decrescente rispetto all'area
|
|
bool bEqIn = ( nIn == b.nIn) ;
|
|
double dAreaA = 0 , dAreaB = 0 ;
|
|
if ( bEqIn && nIn == -1) {
|
|
PolyLine pl ;
|
|
for ( int k = 0 ; k < (int)vpt.size(); ++ k)
|
|
pl.AddUPoint( k, vpt[k]) ;
|
|
pl.Close() ;
|
|
pl.GetAreaXY( dAreaA) ;
|
|
pl.Clear() ;
|
|
for ( int k = 0 ; k < (int)b.vpt.size(); ++ k)
|
|
pl.AddUPoint( k, b.vpt[k]) ;
|
|
pl.Close() ;
|
|
pl.GetAreaXY( dAreaB) ;
|
|
}
|
|
// se nIn è un vertice sistemo il valore
|
|
int nEdgeIn = nIn ;
|
|
if ( nIn > 3)
|
|
nEdgeIn = nIn - 4 ;
|
|
return ( nPos1 < nPos2 ||
|
|
( bEqIn && nEdgeIn == -1 && abs( dAreaA) > abs( dAreaB)) ||
|
|
( bEqIn && nEdgeIn == 0 && vpt[0].x > b.vpt[0].x) ||
|
|
( bEqIn && nEdgeIn == 1 && vpt[0].y > b.vpt[0].y) ||
|
|
( bEqIn && nEdgeIn == 2 && vpt[0].x < b.vpt[0].x) ||
|
|
( bEqIn && nEdgeIn == 3 && vpt[0].y < b.vpt[0].y)) ;
|
|
}
|
|
|
|
static bool
|
|
FirstEncounter( Inters& a, Inters& b)
|
|
{
|
|
// riordino in base al lato toccato, o dall'uscita o dall'ingresso, che viene prima.
|
|
// ottengo l'ordine che avrei percorrendo il bordo da ptTR e considerando i loop che incontro, indipendentemente se li incontro nel punto di uscita o ingresso
|
|
// nell'intersezione salvo se il taglio è stato ordinato guardando l'ingresso o l'uscita
|
|
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6, 3} ;
|
|
// trovo i lati di ingresso e uscita
|
|
const auto iter1 = find( vEdges.begin(), vEdges.end(), a.nIn) ;
|
|
int nPos1 = std::distance( vEdges.begin(), iter1) ;
|
|
const auto iter2 = find( vEdges.begin(), vEdges.end(), a.nOut) ;
|
|
int nPos2 = std::distance( vEdges.begin(), iter2) ;
|
|
const auto iter3 = find( vEdges.begin(), vEdges.end(), b.nIn) ;
|
|
int nPos3 = std::distance( vEdges.begin(), iter3) ;
|
|
const auto iter4 = find( vEdges.begin(), vEdges.end(), b.nOut) ;
|
|
int nPos4 = std::distance( vEdges.begin(), iter4) ;
|
|
int nFirstA = 0 ;
|
|
int nFirstB = 0 ;
|
|
// salvo l'indice del primo punto dell'intersezione che ho incontrato scorrendo il bordo da ptTR
|
|
// salvo il lato che viene prima confrontando ingresso e uscita
|
|
if ( nPos2 < nPos1) {
|
|
nPos1 = nPos2 ;
|
|
nFirstA = int( a.vpt.size()) - 1 ;
|
|
}
|
|
// se ingresso e uscita sono sullo stesso lato allora confronto le coordinate per capire se viene prima l'ingresso o l'uscita
|
|
else if ( nPos2 == nPos1 ) {
|
|
if ( nPos1 == 0 )
|
|
nFirstA = a.vpt[0].x > a.vpt.back().x ? 0 : ( int( a.vpt.size()) - 1) ;
|
|
else if ( nPos1 == 1 )
|
|
nFirstA = a.vpt[0].y > a.vpt.back().y ? 0 : ( int( a.vpt.size()) - 1) ;
|
|
else if ( nPos1 == 2 )
|
|
nFirstA = a.vpt[0].x < a.vpt.back().x ? 0 : ( int( a.vpt.size()) - 1) ;
|
|
else if ( nPos1 == 3 )
|
|
nFirstA = a.vpt[0].y < a.vpt.back().y ? 0 : ( int( a.vpt.size()) - 1) ;
|
|
}
|
|
if ( nPos4 < nPos3) {
|
|
nPos3 = nPos4 ;
|
|
nFirstB = int( b.vpt.size()) - 1 ;
|
|
}
|
|
else if ( nPos4 == nPos3 ) {
|
|
if ( nPos3 == 0 )
|
|
nFirstB = b.vpt[0].x > b.vpt.back().x ? 0 : ( int( b.vpt.size()) - 1) ;
|
|
else if ( nPos3 == 1 )
|
|
nFirstB = b.vpt[0].y > b.vpt.back().y ? 0 : ( int( b.vpt.size()) - 1) ;
|
|
else if ( nPos3 == 2 )
|
|
nFirstB = b.vpt[0].x < b.vpt.back().x ? 0 : ( int( b.vpt.size()) - 1) ;
|
|
else if ( nPos3 == 3 )
|
|
nFirstB = b.vpt[0].y < b.vpt.back().y ? 0 : ( int( b.vpt.size()) - 1) ;
|
|
}
|
|
a.bSortedbyStart = nFirstA == 0 ;
|
|
b.bSortedbyStart = nFirstB == 0 ;
|
|
// se sono diversi ritorno il confronto
|
|
if ( nPos1 != nPos3)
|
|
return nPos1 < nPos3 ;
|
|
// se sono uguali devo valutare il punto di intersezione
|
|
return ( nPos1 == 0 && a.vpt[nFirstA].x > b.vpt[nFirstB].x) ||
|
|
( nPos1 == 1 && a.vpt[nFirstA].y > b.vpt[nFirstB].y) ||
|
|
( nPos1 == 2 && a.vpt[nFirstA].x < b.vpt[nFirstB].x) ||
|
|
( nPos1 == 3 && a.vpt[nFirstA].y < b.vpt[nFirstB].y) ;
|
|
}
|
|
|
|
bool
|
|
operator == ( Inters& b)
|
|
{
|
|
return AreSamePointExact( vpt[0], b.vpt[0]) ;
|
|
}
|
|
|
|
bool
|
|
operator != ( Inters& b)
|
|
{
|
|
return ! AreSamePointExact( vpt[0], b.vpt[0]) ;
|
|
}
|
|
} ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
class Cell
|
|
{
|
|
// Edge 0 ( Top)
|
|
// Edge 4 ( NW) __________________ Edge 7 ( NE)
|
|
// | |
|
|
// | |
|
|
// Edge 1 ( Left) | | Edge 3 ( Right)
|
|
// | |
|
|
// | |
|
|
// |_________________|
|
|
// Edge 5 ( SW) Edge 2 (Bottom) Edge 6 ( SE)
|
|
|
|
public :
|
|
enum Collapsed { TO_VERIFY = -1, // da verificare
|
|
NO_COLLAPSE = 0, // non ho coppie di lati collassati
|
|
VERT_EDGES = 1, // coppia di lati verticali(1-3) sono collassati
|
|
HORIZ_EDGES = 2} ; // coppia di lati verticali(0-2) sono collassati
|
|
|
|
public :
|
|
~Cell( void) {}
|
|
Cell( void)
|
|
: m_nId( -1), m_nTop( -2), m_nBottom( -2), m_nLeft( -2), m_nRight( -2), m_nParent( -2), m_nDepth( 0),
|
|
m_dSplit( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( false), m_nRightEdgeIn( -1),
|
|
m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1), m_nCollapsed( -1), m_ptPbl( ORIG),
|
|
m_ptPtr( SBZ_TREG_COEFF, SBZ_TREG_COEFF, 0), m_bProcessed( false), m_bSplitVert( true) {}
|
|
Cell( const Point3d& ptBL, const Point3d& ptTR)
|
|
: m_nId( -1), m_nTop( -2), m_nBottom( -2), m_nLeft( -2), m_nRight( -2), m_nParent( -2), m_nDepth( 0),
|
|
m_dSplit( 0), m_nChild1( -2), m_nChild2( -2), m_nFlag( -1), m_bLabelled( 0), m_nRightEdgeIn( -1),
|
|
m_bOnLeftEdge( false), m_bOnTopEdge( false), m_nVertToErase( -1), m_nCollapsed( -1), m_ptPbl( ptBL),
|
|
m_ptPtr( ptTR), m_bProcessed( false), m_bSplitVert( true) {}
|
|
bool IsSame( const Cell& cOtherCell) const
|
|
{ return ( m_nId == cOtherCell.m_nId) ; }
|
|
void SetBottomLeft( const Point3d& ptBL)
|
|
{ m_ptPbl = ptBL ; }
|
|
void SetTopRight( const 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 ; }
|
|
Point3d GetTopLeft( void) const
|
|
{ return Point3d( m_ptPbl.x, m_ptPtr.y) ; }
|
|
Point3d GetBottomRight( void) const
|
|
{ return Point3d( m_ptPtr.x, m_ptPbl.y); }
|
|
Point3d GetCenter( void) const
|
|
{ return ( m_ptPbl + m_ptPtr) / 2 ; }
|
|
double GetSplitValue( void) const
|
|
{ return m_dSplit ; }
|
|
bool IsSplitVert( void) const // se true la cella verrebbe splittata verticalmente, altrimenti orizzontalmente
|
|
{ return m_bSplitVert ; }
|
|
bool IsLeaf( void) const // flag che indica se la cella ha figli o se è una foglia
|
|
{ return ( m_nChild1 == -2 && m_nChild2 == -2) ; }
|
|
bool IsProcessed( void) const // flag che indica se tutti i figli della cella, se ce ne sono, sono stati processati
|
|
{ return m_bProcessed ; }
|
|
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 ; }
|
|
void AddPoly( int nPolyId)
|
|
{ m_vnPolyId.push_back( nPolyId) ;}
|
|
|
|
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 ; // flag che indica la caratterizzazione della cella rispetto ai loop di trim
|
|
// 0 esterna, 1 intersecata, 2 contiene un loop, 3 intersecata e contenente un loop, 4 contenuta in un loop
|
|
bool m_bLabelled ; // flag che indica se la cella è stata attraversata durante l'ultima fase del labelling
|
|
int m_nRightEdgeIn ; // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
|
|
bool m_bOnLeftEdge ; // flag che indica se la cella è sul lato sinistro ( per superfici chiuse sul parametro U)
|
|
bool m_bOnTopEdge ; // flag che indica se la cella è sul lato top ( per superfici chiuse sul parametro V)
|
|
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 attraversamento della cella
|
|
int m_nVertToErase ; // vertice da eliminare dal poligono della cella, in caso di lato sovrapposto ad un lato di polo
|
|
// contati in senso CCW a partire dal bottom left
|
|
INTVECTOR m_vnPolyId ; // indici dei poligoni associati a questa cella nel vettore m_vPolygons del Tree
|
|
int m_nCollapsed ; // flag che indica se la coppia di lati verticali (1) o orizzontali(2) sono collassati
|
|
|
|
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 Point3d ptBl, const Point3d ptTr) ; // da usare solo nel caso in cui si voglia aggiungere tagli ad un'unica cella e del risultato ottenere il contorno
|
|
bool SetSurf( const SurfBezier* pSrfBz, const Point3d& ptMin = ORIG, const Point3d& ptMax = ORIG) ;
|
|
bool GetIndependentTrees( BIPNTVECTOR& vTrees) ; // calcolo la suddivisione della superficie solo sulle singole bbox dei loop di trim ( unendo quelli vicini)
|
|
bool BuildTree( double dLinTol = LIN_TOL_STD,
|
|
double dSideMin = 1, // è la minima lunghezza del lato di una cella
|
|
double dSideMax = INFINITO) ; // è la massima dimensione di un triangolo della trimesh
|
|
bool GetPolygons( POLYLINEMATRIX& vvPolygons, POLYLINEMATRIX& vvPolygons3d, std::vector<ICRVCOMPOPOVECTOR>& vCCEdges3D, ICRVCOMPOPOVECTOR& vCCLoops, bool bUpdateEdges) ;
|
|
bool GetPolygonsBasic( POLYLINEVECTOR& vPolygons, POLYLINEVECTOR& vPolygonsCorrected, POLYLINEVECTOR& vPolygons3d) ; // 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
|
|
// ad alcuni poligoni potrebbero venire tolti dei punti per evitare errori dovuti ad eventuali poli sui bordi del parametrico
|
|
bool GetLeaves( std::vector<Cell>& vLeaves) const ; // restituisce gli indici delle foglie nell'albero
|
|
bool GetEdges3D( std::vector<ICRVCOMPOPOVECTOR>& mCCEdge, POLYLINEVECTOR& vPolygons) ; // restituisce gli edge 3D come polyline
|
|
bool GetSplitLoops( ICRVCOMPOPOVECTOR& vCCLoopSplit) const // restituisce i loop splitatti ai confini delle celle
|
|
{ for ( int i = 0 ; i < int( m_vCCLoop2D.size()); ++i)
|
|
vCCLoopSplit.emplace_back( m_vCCLoop2D[i]->Clone()) ;
|
|
return true ; }
|
|
// 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) const // restituisce flag di chiusara in U
|
|
{ return m_bClosedU ; }
|
|
bool IsClosedV( void) const // restituisce flag di chiusara in V
|
|
{ return m_bClosedV ; }
|
|
BOOLVECTOR GetPoles( void) // restituisce i flag che indicano se i lati sono collassati in dei poli
|
|
{ return m_vbPole ; }
|
|
|
|
private :
|
|
bool Split( int nId, double dSplitValue) ; // funzione di split di una cella al parametro indicato nella direzione data da bVert
|
|
bool Split( int nId) ; // funzione di split di una cella dell'albero a metà nella direzione data da bVert
|
|
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, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato top ( la coppia di double è per dare un intervallo diverso su cui limitare i vicini)
|
|
void GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato bottom
|
|
void GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs, DBLDBL ddInt = DBLDBL(0,0)) const ; // restituisce le celle foglie che sono adiacenti al lato left
|
|
void GetRightNeigh( int nId, INTVECTOR& vRightNeighs, DBLDBL ddInt = DBLDBL(0,0)) 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
|
|
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
|
INTVECTOR FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells, bool bRecurs = false) const ; // dato un punto, trova la cella foglia a cui appartiene
|
|
bool TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons) ; // tracing dei loop e labelling delle celle
|
|
bool FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon, PNTVECTOR& vptInters, bool bFirstInters = true) ; // 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 CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vPolygons3d, INTVECTOR& vToCheck, int& nPoly, INTVECTOR& vnParentChunk, const PolyLine& plCell, const PolyLine& plCell3d) ; // crea i poligoni della cella passata. richiede anche la funzione CreateIslandAndHoles per completare i poligoni.
|
|
bool CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX& vvPolygons3d, int& nPoly, INTVECTOR& vnParentChunk,
|
|
const PolyLine& plPolygonsBasic, const PolyLine& plPolygonsBasic3d) ; // ai poligoni generati da CreatePolygonsCell aggiunge i loop che creano isole o buchi all'interno della singola cella
|
|
bool CheckIfBefore( const PolyLine& pl, int nEdge) const ; // controllo se ptEnd è prima di ptStart sul lato nEdge rispetto al senso antiorario
|
|
bool CheckIfBefore( const Inters& inA) const ; // controlla se l'ingresso è prima dell'uscita in senso antiorario a partire da ptTR.
|
|
bool CheckIfBefore( int nEdge1, const Point3d& ptP1, int nEdge2, const Point3d& ptP2) const ; // verifico quale punto viene prima tra pt1 e pt2 a partire da ptTR girando in senso CCW (punto 1 su edge 1 e punto 2 su edge 2, rispetto al lato 3)
|
|
bool CheckIfBefore( int nEdge, const Point3d& ptP1, const Point3d& ptP2, int nEdge2 = -1) const ; // sul lato nEdge controllo se ptP1 viene prima di ptP2.
|
|
bool AreSameEdge( int nEdge1, int nEdge2) const ; // indica se i due edge sono lo stesso. Un vertice adiacente ad un edge viene considerato uguale a questo edge
|
|
bool CheckIfBefore( int nEdgeA, int nEdgeB) const ; // per due edge uguali per la funzione AreSameEdge chiedo se EdgeA viene prima di EdgeB
|
|
bool AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVertex3d, PolyLine& plTrimmedPoly, int& c,
|
|
const Point3d& ptToAdd, PolyLine& plTrimmedPoly3d, bool ForTriangulation, Point3d& ptLast) const ; // aggiunge un punto ad un poligono in una cella, premurandosi di aggiungere eventualmente vertici o punti di celle vicine di cui tenere conto
|
|
bool SetRightEdgeIn( int nId) ; // categorizza la cella in base all'edge destro per poter poi definire m_nFlag
|
|
bool CategorizeCell( int nId) ; // categorizza la cella in base al flag m_nFlag (dentro, fuori, intersecata)
|
|
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( ICurveComposite* pCC, Point3d& pt) ;
|
|
bool VerifyLoopOrientation( ICURVEPLIST& vpCrv, BOOLVECTOR& vbOrientation) const ; // verifico l'orientazione ( CCW o CW) delle polyline in base a come sono contenute le une nelle altre
|
|
bool AdjustLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const ;
|
|
bool GetPoint(double dU, double dV, Point3d& ptP) const ;
|
|
bool SavePoint( double dU, double dV, const Point3d& ptP) ;
|
|
|
|
private :
|
|
const SurfBezier* m_pSrfBz ; // superficie di bezier
|
|
bool m_bTrimmed ; // superficie trimmata
|
|
std::unordered_map<int,int> m_mChunk ; // mappa in cui vengono salvati chunk di appartenza per ogni loop di trim
|
|
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
|
|
bool m_bClosedV ; // superficie chiusa lungo il parametro V
|
|
BOOLVECTOR m_vbPole ; // vettore che indica se i vari lati sono collassati in poli ( indici riferiti all'ordine degli edge)
|
|
int m_nDegU ; // grado della superficie nel parametro U
|
|
int m_nDegV ; // grado della superficie nel parametro V
|
|
int m_nSpanU ; // numero di span lungo il parametro U
|
|
int m_nSpanV ; // numero di span lungo il parametro V
|
|
std::unordered_map<int,Cell> m_mTree ; // mappa che contiene tutti i nodi e le foglie dell'albero. -2 è puntatore Null e -1 è root
|
|
mutable std::unordered_map<std::pair<int64_t,int64_t>,Point3d,PairHashInt64> m_mPt3d ; // mappa che contiene tutti i punti 3d della superficie calcolati (la chiave sono le coordinate, moltiplicate per 2^24 e trasformate in int)
|
|
INTVECTOR m_vnLeaves ; // vettore delle foglie
|
|
INTVECTOR m_vnParents ; // vettore delle celle ottenute dalla divisione preliminare in singole patch
|
|
ICRVCOMPOPOVECTOR m_vCCLoop2D ; // vettore che contiene le CurveCompo 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.
|
|
} ;
|