EgtGeomKernel :

- aggiunte tutte le funzionalità per la gestione delle superfici di bezier
con spazio parametrico trimmato
Manca :
- debug.
This commit is contained in:
Daniele Bariletti
2023-06-05 12:12:47 +02:00
parent 56d80f5bdd
commit 71ac2fde82
2 changed files with 200 additions and 66 deletions
+199 -65
View File
@@ -1198,28 +1198,37 @@ Tree::GetPolygons( std::vector<POLYLINEVECTOR>& vPolygons) {
// scorro sui poligoni delle celle non trimmate
int nCells = (int)vPolygonsBasic.size() ;
for ( int i = 0 ; i < nCells ; ++i ) {
// vettore dei poligoni ( loop) della cella nId
POLYLINEVECTOR vCellPolygons ;
// costruisco i poligoni partendo dal vettore delle intersezioni, come spiegato a pag15 di Cripps
int nId = m_vnLeaves[i] ;
// vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella
INTVECTOR vnParentChunk ;
//int nEdgeIn = -1 ;
// vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo
INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ;
std::generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ;
// numero di poligoni aggiunti
int nPoly = 0 ;
// scorro sui vettori intersezione della cella nId e sui suoi vertici
// in questo for analizzo solo i loop che tagliano la cella
while( nPoly == 0 || (int)vToCheck.size() != 0) {
int nPolyBefore = nPoly ;
CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i]) ;
if ( nPolyBefore == nPoly)
break ;
if ( m_mTree[nId].m_nFlag == 4) {
// vettore dei poligoni ( loop) della cella nId
POLYLINEVECTOR vCellPolygons ;
vCellPolygons.push_back( vPolygonsBasic[i]) ;
vPolygons.push_back( vCellPolygons) ;
}
else if ( m_mTree[nId].m_nFlag == 0)
continue ;
else {
// vettore in cui salvo il chunk di appartenenza di ogni loop che attraversa la cella
INTVECTOR vnParentChunk ;
//int nEdgeIn = -1 ;
// vettore in cui salvo i loop che non appartengono al poligono che sto cotruendo nel ciclo attuale e da cui ripasserò dopo
INTVECTOR vToCheck( (int) m_mTree[nId].m_vInters.size()) ;
std::generate_n( vToCheck.begin(), (int) m_mTree[nId].m_vInters.size(), generator()) ;
// numero di poligoni aggiunti
int nPoly = 0 ;
// scorro sui vettori intersezione della cella nId e sui suoi vertici
// in questo for analizzo solo i loop che tagliano la cella
while( nPoly == 0 || (int)vToCheck.size() != 0) {
int nPolyBefore = nPoly ;
CreateCellPolygons( i, vPolygons, vToCheck, nPoly, vnParentChunk, vPolygonsBasic[i]) ;
if ( nPolyBefore == nPoly)
break ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vPolygons, nPoly, vnParentChunk) ;
}
// ora analizzo anche i loop che sono contenuti nella cella
CreateIslandAndHoles( i, vPolygons, nPoly, vnParentChunk) ;
}
return true;
}
@@ -1608,6 +1617,7 @@ Tree::TraceLoopLabelCell( void)
Point3d ptLast = m_mTree[nId].m_vInters.back().vpt.back() ;
Point3d ptTl( m_mTree[nId].GetBottomLeft().x, m_mTree[nId].GetTopRight().y) ;
Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ;
int nLastId ;
if ( AreSamePointApprox( m_mTree[nId].GetTopRight(), ptLast) ||
AreSamePointApprox( ptTl, ptLast) ||
AreSamePointApprox( m_mTree[nId].GetBottomLeft(), ptLast) ||
@@ -1618,12 +1628,14 @@ Tree::TraceLoopLabelCell( void)
CurveLine clTrim ;
clTrim.Set( ptStart, ptEnd) ;
vptInters.clear() ;
nLastId = nId ;
FindInters( nId, clTrim, vptInters, bVertex) ;
m_mTree[nLastId].m_vInters.back().vpt.push_back( vptInters[0]) ;
}
int nOut = m_mTree[nId].m_vInters[nPass].nOut ;
m_mTree[nId].m_vInters.back().vpt.insert( m_mTree[nId].m_vInters.back().vpt.end(),
m_mTree[nId].m_vInters[nPass].vpt.begin(),
m_mTree[nId].m_vInters[nPass].vpt.end()) ;
m_mTree[nId].m_vInters[nPass].vpt.begin(),
m_mTree[nId].m_vInters[nPass].vpt.end()) ;
m_mTree[nId].m_vInters[nPass] = m_mTree[nId].m_vInters.back() ;
m_mTree[nId].m_vInters.pop_back() ;
// sistemo il lato d'uscita
@@ -1668,6 +1680,7 @@ Tree::TraceLoopLabelCell( void)
}
else { //categorizzo la cella///////////////////////////////////////////////////////////
m_mTree[nCell].m_nFlag2 = 1 ;
CategorizeCell( nCell) ;
}
if ( ! m_mTree[nCell].IsProcessed()) {
@@ -1702,6 +1715,7 @@ Tree::TraceLoopLabelCell( void)
if ( nCell == nLastLeft && m_mTree[nCell].IsProcessed() ) {
// categorizzo////////////////////////////////////////////////////////////////////////////
m_mTree[nCell].m_nFlag2 = 1 ;
CategorizeCell( nCell) ;
bAllDone = true ;
break ;
}
@@ -1757,6 +1771,8 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVert
int nEdge ; // flag che indica il lato su cui ho l'intersezione 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
bool bIntersFound = false ;
Point3d ptInters ;
if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) {
nEdge = 0 ;
// lato sopra
@@ -1766,6 +1782,11 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVert
//else //if ( ptEnd.x < ptBL.x)
if ( ptEnd.x < ptBL.x)
clEdge2.Set( ptTl, ptBL) ;
else if ( AreSamePointExact( ptEnd, ptTl)) {
nEdge = 4 ;
ptInters = ptTl ;
bIntersFound = true ;
}
}
else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) {
nEdge = 1 ;
@@ -1777,6 +1798,11 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVert
//else //if ( ptEnd.y < ptBL.y)
if ( ptEnd.y < ptBL.y)
clEdge2.Set( ptBL, ptBr) ;
else if ( AreSamePointExact( ptEnd, ptBL)) {
nEdge = 5 ;
ptInters = ptBL ;
bIntersFound = true ;
}
}
else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) {
nEdge = 2 ;
@@ -1788,6 +1814,11 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVert
//else //if ( ptEnd.x > ptTR.x)
if ( ptEnd.x > ptTR.x)
clEdge2.Set( ptBr, ptTR) ;
else if ( AreSamePointExact( ptEnd, ptBr)) {
nEdge = 6 ;
ptInters = ptBr ;
bIntersFound = true ;
}
}
else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) {
nEdge = 3 ;
@@ -1799,50 +1830,56 @@ Tree::FindInters( int& nId, CurveLine& clTrim, PNTVECTOR& vptInters, bool& bVert
//else //if ( ptEnd.y > ptTR.y)
if ( ptEnd.y > ptTR.y)
clEdge2.Set( ptTR, ptTl) ;
else if ( AreSamePointExact( ptEnd, ptTR)) {
nEdge = 7 ;
ptInters = ptTR ;
bIntersFound = true ;
}
}
else
return false ;
// intersezione e controlli
IntersLineLine illExit( clTrim, clEdge, true) ;
IntCrvCrvInfo aInfo, aInfo2 ;
Point3d ptInters ;
//if ( ! illExit.GetIntCrvCrvInfo( aInfo) )
// return false ;
illExit.GetIntCrvCrvInfo( aInfo) ;
if ( clEdge2.IsValid()){
IntersLineLine illExit2( clTrim, clEdge2, true) ;
//if ( ! illExit2.GetIntCrvCrvInfo( aInfo2) )
if ( ! bIntersFound) {
// intersezione e controlli
IntersLineLine illExit( clTrim, clEdge, true) ;
IntCrvCrvInfo aInfo, aInfo2 ;
//if ( ! illExit.GetIntCrvCrvInfo( aInfo) )
// return false ;
// verifico su quale dei due lati ho l'intersezione
if ( ! illExit2.GetIntCrvCrvInfo( aInfo2))
ptInters = aInfo.IciA[0].ptI ;
else {
// solo intersezione sul lato 2
if ( illExit.GetNumInters() == 0 ) {
ptInters = aInfo2.IciA[0].ptI ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3 )
++ nEdge ;
else
nEdge = 0 ;
}
// intersezione sul vertice della cella
illExit.GetIntCrvCrvInfo( aInfo) ;
if ( clEdge2.IsValid()){
IntersLineLine illExit2( clTrim, clEdge2, true) ;
//if ( ! illExit2.GetIntCrvCrvInfo( aInfo2) )
// return false ;
// verifico su quale dei due lati ho l'intersezione
if ( ! illExit2.GetIntCrvCrvInfo( aInfo2))
ptInters = aInfo.IciA[0].ptI ;
else {
ptInters = aInfo2.IciA[0].ptI ;
bVertex = true ;
// la cella adiacente in diagonale a quel vertice
nEdge = nEdge + 4 ;
// solo intersezione sul lato 2
if ( illExit.GetNumInters() == 0 ) {
ptInters = aInfo2.IciA[0].ptI ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3 )
++ nEdge ;
else
nEdge = 0 ;
}
// intersezione sul vertice della cella
else {
ptInters = aInfo2.IciA[0].ptI ;
bVertex = true ;
// la cella adiacente in diagonale a quel vertice
nEdge = nEdge + 4 ;
}
}
}
else
ptInters = aInfo.IciA[0].ptI ;
}
else
ptInters = aInfo.IciA[0].ptI ;
m_mTree[nId].m_vInters.back().nOut = nEdge ;
vptInters.push_back( ptInters) ;
// salvo il vettore intersezione per la cella e capisco in quale altra cella passare
m_mTree[nId].m_vInters.back().vpt = vptInters ;
m_mTree[nId].m_vInters.back().vpt = vptInters ; // al posto di .vpt = vptInters metto un push_back ////////////////////////////////////////////////
vptInters.clear() ;
// setto la categoria della cella
if ( m_mTree[nId].m_nFlag == -1)
@@ -2356,7 +2393,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
plTrimmedPoly.Close() ;
double dArea ;
plTrimmedPoly.GetAreaXY( dArea) ;
if ( dArea > EPS_SMALL ) {
if ( dArea > SQ_EPS_SMALL) {
vCellPolygons.push_back( plTrimmedPoly) ;
vPolygons.push_back( vCellPolygons) ;
++ nPoly ;
@@ -2481,6 +2518,7 @@ Tree::CheckIfBefore( PolyLine& pl, int nEdge) const
bool
Tree::CheckIfBefore( Inters& inA) const
{
// controllo se l'ingresso è prima dell'uscita
int nEdge1 = inA.nIn ;
int nEdge2 = inA.nOut ;
PolyLine pl ;
@@ -2804,11 +2842,12 @@ Tree::SetRightEdgeIn( int nId)
}
// se non ho inters sul lato destro devo verificare se è tutto dentro o tutto fuori
if ( ! bDone) {
// ciclo sulle inters e cerco se ho dei passaggi con un'uscita più bassa di un'entrata e se eventualmente è la più a destra!
// ciclo sulle inters e cerco quella più a destra, se ha un'uscita più bassa di un'entrata allora il right edge è compreso!
bool bFound = false ;
bool bRightMost = false ;
int nEdgeIn = 6, nEdgeOut = 7, nLoop ;
Point3d ptIn, ptOut ;
ptIn = ptOut = m_mTree[nId].GetBottomLeft() ;
for ( int k = 0 ; k < nPass ; ++ k) {
// trovo il loop che ha l'ingresso o l'uscita più a destra
if ( CheckIfBefore( m_mTree[nId].m_vInters[k].nIn, m_mTree[nId].m_vInters[k].vpt[0], nEdgeIn, ptIn) ||
@@ -2842,16 +2881,111 @@ Tree::SetRightEdgeIn( int nId)
bool
Tree::CategorizeCell( int& nId)
{
//if ( m_mTree[nId].m_nFlag != -1) {
// return true ;
//}
//INTVECTOR vNeigh ;
//GetLeftNeigh( nId, vNeigh) ;
//// mi servono i vicini di sinistra per capire se sono dentro il loop o fuori
//// 0 right edge fuori, 1 right edge dentro, 2 metà e metà
//if ( ) {
if ( m_mTree[nId].m_nFlag != -1) {
return true ;
}
INTVECTOR vNeigh, vNeigh1 ;
GetLeftNeigh( nId, vNeigh) ;
// mi servono i vicini di sinistra per capire se sono dentro il loop o fuori
// nRightEdgeIn // 0 right edge fuori, 1 right edge dentro, 2 metà e metà
// nFlag // 0 fuori, 1 intersecata, 2 contiene loop, 3 = 1 & 2, 4 dentro
if ( (int)vNeigh.size() == 0 ) {
m_mTree[nId].m_nFlag = 0 ;
}
else if ( (int)vNeigh.size() == 1) {
if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 1)
m_mTree[nId].m_nFlag = 4 ;
else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 0)
m_mTree[nId].m_nFlag = 0 ;
// se solo parte del right edge del vicino è compreso, allora devo verificare se la cella è contenuta o no
// guardando nFlag del vicino bottom, che è già categorizzato!
else if ( m_mTree[vNeigh[0]].m_nRightEdgeIn == 2 ) {
// guardo le intersezioni a mano
//
//int nPass = (int) m_mTree[vNeigh[0]].m_vInters.size() ;
//for ( int p = 0 ; p < nPass ; ++p ) {
// // se ho almeno un ingresso o un'uscita
// if ( ) {
// }
// else {
// m_mTree[nId].m_nFlag == 0 ;
// }
//}
GetBottomNeigh( nId, vNeigh1) ;
int nNeigh = vNeigh1[0] ;
if ( m_mTree[nNeigh].m_nFlag == 0 || m_mTree[nNeigh].m_nFlag == 2) {
m_mTree[nId].m_nFlag = 0 ;
}
else if ( m_mTree[nNeigh].m_nFlag == 4) {
m_mTree[nId].m_nFlag = 4 ;
}
else if ( m_mTree[nNeigh].m_nFlag == 1 || m_mTree[nNeigh].m_nFlag == 3) {
if ( m_mTree[nNeigh].m_nRightEdgeIn == 0)
m_mTree[nId].m_nFlag = 0 ;
else if ( m_mTree[nNeigh].m_nRightEdgeIn == 1)
m_mTree[nId].m_nFlag = 4 ;
else if ( m_mTree[nNeigh].m_nRightEdgeIn == 2 ) {
// in questo caso devo verificare le intersezioni sul lato destro del vicino bottom
// scorro e cerco l'intersezione più alta, se è out la cella è dentro, se è in devo verificare l'out se è più a sinistra o a destra.
int nPass = (int) m_mTree[nNeigh].m_vInters.size() ;
bool bTopMost = false ;
bool bFound = false;
Point3d ptInters, ptBr( m_mTree[nNeigh].GetTopRight().x, m_mTree[nNeigh].GetBottomLeft().y) ;
ptInters = ptBr ; // inizializzato a vertice bottom right
int nEdgeIn = 3, nEdgeOut = 3, nLoop ;
for ( int r = 0 ; r < nPass; ++ r ) {
// trovo il loop che ha l'ingresso o l'uscita più in alto sul lato destro
// verifico che o l'ingresso o l'uscita siano sul lato destro e che sia l'intersezione più alta su quel lato
if ( ( AreSameEdge( m_mTree[nNeigh].m_vInters[r].nIn, 3) && ! CheckIfBefore( m_mTree[nNeigh].m_vInters[r].nIn, m_mTree[nNeigh].m_vInters[r].vpt[0], nEdgeIn, ptInters))) {
nLoop = r ;
ptInters = m_mTree[nNeigh].m_vInters[r].vpt[0] ;
bFound = true ;
}
if ( AreSameEdge(m_mTree[nNeigh].m_vInters[r].nOut, 3) && ! CheckIfBefore( m_mTree[nNeigh].m_vInters[r].nOut, m_mTree[nNeigh].m_vInters[r].vpt.back(), nEdgeOut, ptInters)) {
nLoop = r ;
ptInters = m_mTree[nNeigh].m_vInters[r].vpt.back() ;
bFound = true ;
}
}
if ( bFound && CheckIfBefore( m_mTree[nNeigh].m_vInters[nLoop])) {
bTopMost = true ;
}
if ( bFound && bTopMost) {
if ( AreSameEdge(m_mTree[nNeigh].m_vInters[nLoop].nIn, 3) && AreSameEdge(m_mTree[nNeigh].m_vInters[nLoop].nOut, 3) ) {
if ( CheckIfBefore( m_mTree[nNeigh].m_vInters[nLoop]))
m_mTree[nId].m_nFlag = 4 ;
else
m_mTree[nId].m_nFlag = 0 ;
}
else if ( AreSameEdge(m_mTree[nId].m_vInters[nLoop].nOut, 3))
m_mTree[nId].m_nFlag = 4 ;
else if ( AreSameEdge(m_mTree[nNeigh].m_vInters[nLoop].nIn, 3) ) {
// devo verificare se il l'uscita è più a sinistra o più a destra della cella
Point3d ptOut = m_mTree[nNeigh].m_vInters[nLoop].vpt.back() ;
Point3d ptBr( m_mTree[nId].GetTopRight().x, m_mTree[nId].GetBottomLeft().y) ;
if ( ptOut.x >= ptBr.x)
m_mTree[nId].m_nFlag = 4 ;
else
m_mTree[nId].m_nFlag = 0 ;
}
}
}
}
}
}
else {
for ( int r = 0 ; r < (int)vNeigh.size() ; ++ r) {
if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 1) {
m_mTree[nId].m_nFlag = 4 ;
break ;
}
else if ( m_mTree[vNeigh[r]].m_nRightEdgeIn == 0) {
m_mTree[nId].m_nFlag = 0 ;
break ;
}
}
}
//}
// m_mTree[nId].m_nFlag2 = 1 ;
return true ;
}