EgtGeomKernel :
- aggiunta la funzione per creare una sfera come superficie bezier - aggiunta la funzione per tagliare una superificie bezier con un piano.
This commit is contained in:
@@ -49,6 +49,14 @@ Tree::~Tree( void)
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
Tree::Tree( const Point3d ptBl, const Point3d ptTr)
|
||||
: m_pSrfBz( nullptr), m_bTrimmed( false), m_bBilinear( false), m_bMulti( false), m_bClosedU( false), m_bClosedV( false), m_bSplitPatches( true), m_bTestMode( false)
|
||||
{
|
||||
Cell cRoot( ptBl, ptTr) ;
|
||||
m_mTree.insert( pair< int, Cell>( -1, cRoot)) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void
|
||||
Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMin, const Point3d& ptMax)
|
||||
@@ -931,6 +939,7 @@ Tree::Balance()
|
||||
void
|
||||
Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
|
||||
{
|
||||
// le celle restituite sono ordinate per x crescente
|
||||
if ( vTopNeighs.empty()) {
|
||||
if ( m_mTree.at( nId).m_nTop == -2)
|
||||
return ;
|
||||
@@ -1000,6 +1009,7 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vTopNeighs)
|
||||
vCells.push_back( m_mTree.at( k)) ;
|
||||
// le celle restituite sono ordinate per x crescente
|
||||
sort( vCells.begin(), vCells.end(), Cell::minorX) ;
|
||||
vTopNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -1011,6 +1021,7 @@ Tree::GetTopNeigh( int nId, INTVECTOR& vTopNeighs) const
|
||||
void
|
||||
Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
|
||||
{
|
||||
// le celle restituite sono ordinate per x crescente
|
||||
if ( vBottomNeighs.empty()) {
|
||||
if ( m_mTree.at( nId).m_nBottom == -2)
|
||||
return ;
|
||||
@@ -1080,6 +1091,7 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vBottomNeighs)
|
||||
vCells.push_back( m_mTree.at( k)) ;
|
||||
// le celle restituite sono ordinate per x crescente
|
||||
sort( vCells.begin(), vCells.end(), Cell::minorX) ;
|
||||
vBottomNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -1090,6 +1102,7 @@ Tree::GetBottomNeigh( int nId, INTVECTOR& vBottomNeighs) const
|
||||
void
|
||||
Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
|
||||
{
|
||||
// le celle restituite sono ordinate per y crescente
|
||||
if ( vLeftNeighs.empty()) {
|
||||
if ( m_mTree.at( nId).m_nLeft == -2)
|
||||
return ;
|
||||
@@ -1159,6 +1172,7 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vLeftNeighs)
|
||||
vCells.push_back( m_mTree.at( k)) ;
|
||||
// le celle restituite sono ordinate per y crescente
|
||||
sort( vCells.begin(), vCells.end(), Cell::minorY) ;
|
||||
vLeftNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -1169,6 +1183,7 @@ Tree::GetLeftNeigh( int nId, INTVECTOR& vLeftNeighs) const
|
||||
void
|
||||
Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
|
||||
{
|
||||
// le celle restituite sono ordinate per y crescente
|
||||
if ( vRightNeighs.empty()) {
|
||||
if ( m_mTree.at( nId).m_nRight == -2)
|
||||
return ;
|
||||
@@ -1238,6 +1253,7 @@ Tree::GetRightNeigh( int nId, INTVECTOR& vRightNeighs) const
|
||||
vector<Cell> vCells ;
|
||||
for ( int k : vRightNeighs)
|
||||
vCells.push_back( m_mTree.at( k)) ;
|
||||
// le celle restituite sono ordinate per y crescente
|
||||
sort( vCells.begin(), vCells.end(), Cell::minorY) ;
|
||||
vRightNeighs.clear() ;
|
||||
for ( Cell c : vCells)
|
||||
@@ -1418,9 +1434,16 @@ Tree::GetPolygons( POLYLINEMATRIX& vPolygons)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons)
|
||||
Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons, INTVECTOR& vCells)
|
||||
{
|
||||
if ( m_vPolygons.empty()) {
|
||||
// condizioni per il calcolo dei poligoni di base
|
||||
if ( m_vPolygons.empty() || // se non li ho mai calcolati
|
||||
( ! m_vPolygons.empty() && ! vCells.empty()) || // se ho già calcolato dei poligoni ma ne sto chiedendo di un altro gruppo di celle
|
||||
( vCells.empty() && m_vPolygons.size() != m_vnLeaves.size())) { // se sto chiedendo i poligoni di tutte le celle, ma i poligoni già calcolati sono meno delle celle
|
||||
// se non ho dato un elenco di celle in input do per scontato che la chiamata sia per calcolare i poligoni di tutte le foglie
|
||||
if ( vCells.empty())
|
||||
vCells = m_vnLeaves ;
|
||||
|
||||
PNTVECTOR vVertices ;
|
||||
INTVECTOR vNeigh ;
|
||||
// setto le celle che sono sul LeftEdge e sul TopEdge
|
||||
@@ -1440,7 +1463,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygons)
|
||||
bool bBottomRight , bTopLeft ;
|
||||
// scorro lungo tutte le celle leaves e oltre agli angoli della cella aggiungo alla polyline della cella anche i vertici, delle celle adiacenti,
|
||||
// che sono sui lati della cella corrente
|
||||
for ( int nId : m_vnLeaves) {
|
||||
for ( int nId : vCells) {
|
||||
vVertices.clear() ;
|
||||
vNeigh.clear() ;
|
||||
vVertices.push_back( m_mTree.at( nId).GetBottomLeft()) ;
|
||||
@@ -3521,3 +3544,153 @@ Tree::OnWhichEdge( int nId, const Point3d& ptToAssign, int& nEdge) const
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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]) ;
|
||||
|
||||
// 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) ;
|
||||
// a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato
|
||||
if ( i == 0 && AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopRight()) ) {
|
||||
// scorro fino alla fine di quel lato
|
||||
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[0][c]).GetTopLeft()) && mPL[i][c].GetNextPoint( pt)) {
|
||||
vPLEdges.back().AddUPoint( nPtCount, pt) ;
|
||||
++ nPtCount ;
|
||||
}
|
||||
}
|
||||
else if ( i == 1 && AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetTopLeft()) ) {
|
||||
// scorro fino alla fine di quel lato
|
||||
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[1][c]).GetBottomLeft()) && mPL[i][c].GetNextPoint( pt)) {
|
||||
vPLEdges.back().AddUPoint( nPtCount, pt) ;
|
||||
++ nPtCount ;
|
||||
}
|
||||
}
|
||||
else if ( i == 2 && AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomLeft()) ) {
|
||||
// scorro fino alla fine di quel lato
|
||||
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[2][c]).GetBottomRight()) && mPL[i][c].GetNextPoint( pt)) {
|
||||
vPLEdges.back().AddUPoint( nPtCount, pt) ;
|
||||
++ nPtCount ;
|
||||
}
|
||||
}
|
||||
else if ( i == 3 && AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetBottomRight()) ) {
|
||||
// scorro fino alla fine di quel lato
|
||||
while ( ! AreSamePointApprox(pt, m_mTree.at(vEdges[3][c]).GetTopRight()) && mPL[i][c].GetNextPoint( pt)) {
|
||||
vPLEdges.back().AddUPoint( nPtCount, pt) ;
|
||||
++ nPtCount ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::AddCutsToRoot( POLYLINEVECTOR& vCuts)
|
||||
{
|
||||
// questa funzione dà per scontato di stare lavorando sulla root di uno spazio parametrico di cui si sta solamente calcolando
|
||||
// il Contour. La funzione da chiamare dopo questa è la CreateCellContour.
|
||||
// i tagli sono sempre delle linee che tagliano da parte a parte la cella, quindi sono curve aperte
|
||||
if ( m_mTree.size() > 1)
|
||||
return false ;
|
||||
int nRoot = -1 ;
|
||||
for ( int i = 0 ; i < int( vCuts.size()); ++i) {
|
||||
PolyLine pl = vCuts.at( i) ;
|
||||
m_mTree.at( nRoot).m_vInters.emplace_back() ;
|
||||
Point3d pt ; pl.GetFirstPoint( pt) ;
|
||||
int nEdgeIn ; OnWhichEdge( nRoot, pt, nEdgeIn) ;
|
||||
m_mTree.at( nRoot).m_vInters.back().nIn = nEdgeIn ;
|
||||
PNTVECTOR vInters ;
|
||||
vInters.emplace_back( pt) ;
|
||||
while ( pl.GetNextPoint( pt))
|
||||
vInters.emplace_back( pt) ;
|
||||
pl.GetLastPoint( pt) ;
|
||||
int nEdgeOut ; OnWhichEdge( nRoot, pt, nEdgeOut) ;
|
||||
m_mTree.at( nRoot).m_vInters.back().nOut = nEdgeOut ;
|
||||
}
|
||||
// chiamo una funzione per renderli coerenti
|
||||
AdjustCuts() ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::AdjustCuts( void)
|
||||
{
|
||||
// li riordino per ordine di quali taglio incontrerei percorrendo il bordo della cella a partire da ptTR
|
||||
sort( m_mTree.at( -1).m_vInters.begin(), m_mTree.at( -1).m_vInters.end(), [](Inters& a, Inters& b){ return Inters::FirstEncounter(a,b) ;}) ;
|
||||
// ora controllo che le intersezioni che trovo siano ingressi alternati ad uscite, sennò inverto l'intersezione
|
||||
bool bPreviousWasStart = m_mTree.at( -1).m_vInters.at(0).bSortedbyStart ;
|
||||
for ( int i = 0 ; i < int( m_mTree.at( -1).m_vInters.size()); ++i) {
|
||||
if ( m_mTree.at( -1).m_vInters.at(i).bSortedbyStart == bPreviousWasStart) {
|
||||
reverse( m_mTree.at( -1).m_vInters.at(i).vpt.begin(), m_mTree.at( -1).m_vInters.at(i).vpt.end()) ;
|
||||
bPreviousWasStart = m_mTree.at( -1).m_vInters.at(i).bSortedbyStart ;
|
||||
}
|
||||
else
|
||||
bPreviousWasStart = ! m_mTree.at( -1).m_vInters.at(i).bSortedbyStart ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Tree::CreateCellContour( POLYLINEMATRIX& vPolygons)
|
||||
{
|
||||
// questa funzione è pensata per essere chiamata dopo la AddCutsToRoot, per creare il poligono di un'unica cella a cui sono stati aggiunti dei tagli
|
||||
if ( m_mTree.size() > 1)
|
||||
return false ;
|
||||
int nRoot = -1 ;
|
||||
// preparo tutto per poter chiamare la createCellPolygon
|
||||
m_vnLeaves.push_back( nRoot) ;
|
||||
INTVECTOR vToCheck( (int) m_mTree.at(nRoot).m_vInters.size()) ;
|
||||
generate_n( vToCheck.begin(), (int) m_mTree.at(nRoot).m_vInters.size(), generator()) ;
|
||||
int nPoly = 0 ;
|
||||
INTVECTOR vnParentChunk ;
|
||||
PolyLine pl ;
|
||||
pl.AddUPoint(0, m_mTree.at(nRoot).GetTopRight()) ;
|
||||
pl.AddUPoint(1, m_mTree.at(nRoot).GetTopLeft()) ;
|
||||
pl.AddUPoint(2, m_mTree.at(nRoot).GetBottomLeft()) ;
|
||||
pl.AddUPoint(3, m_mTree.at(nRoot).GetBottomRight()) ;
|
||||
pl.Close() ;
|
||||
// ora posso creare il poligono della cella con i tagli
|
||||
while( (int)vToCheck.size() != 0) {
|
||||
int nPolyBefore = nPoly ;
|
||||
CreateCellPolygons( 0, vPolygons, vToCheck, nPoly, vnParentChunk, pl) ;
|
||||
if ( nPolyBefore == nPoly)
|
||||
break ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
Reference in New Issue
Block a user