EgtGeomKernel :
- aggiunte tutte le funzionalità per la gestione delle superfici di bezier con spazio parametrico trimmato Manca : - debug.
This commit is contained in:
@@ -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 ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user