EgtGeomKernel :

- correzioni e migliorie alla triangolazione con le bezier.
This commit is contained in:
Daniele Bariletti
2024-07-25 16:25:05 +02:00
parent c3e7d3d8c7
commit 9b87de9fa2
3 changed files with 178 additions and 304 deletions
+127 -291
View File
@@ -68,43 +68,6 @@ Tree::Tree( const Point3d ptBl, const Point3d ptTr)
bool
Tree::LimitLoop( PolyLine& pl, POLYLINEVECTOR& vPl, BOOLVECTOR& vbOrientation) const
{
// //questo metodo NON VA BENE perchè tiene anche parte dei loop che stanno fuori dal parametrico e quindi il FINDCELL può fallire
//
//// creo la flat region di trim, quella del parametrico e li interseco
//PtrOwner<ISurfFlatRegion> pSfrTrim( GetSurfFlatRegionFromPolyLine( pl)) ;
//bool bInverted = false ;
//if ( ! pSfrTrim->GetNormVersor().IsZplus()) {
// pSfrTrim->Invert() ;
// bInverted = true ;
//}
//PtrOwner<ISurfFlatRegion> pParamTrim( GetSurfFlatRegionRectangle( SBZ_TREG_COEFF * m_nSpanU, SBZ_TREG_COEFF * m_nSpanV)) ;
//if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid()) {
// if ( ! pParamTrim->Offset( 10 * EPS_SMALL, ICurve::OFF_EXTEND))
// return false ;
// if ( ! pParamTrim->Intersect( *pSfrTrim) || ! pParamTrim->IsValid())
// return false ;
// if ( ! pParamTrim->Offset( -10 * EPS_SMALL, ICurve::OFF_EXTEND))
// return false ;
//}
//// ricostruisco la curva tenendo solo le parti dentro lo spazio parametrico
//// devo recuperare la polyline dei bordi dei vari chunk creati
//for ( int c = 0 ; c < int( pParamTrim->GetChunkCount()) ; ++c) {
// for ( int l = 0 ; l < pParamTrim->GetLoopCount(c) ; ++l) {
// PtrOwner<ICurve> pCrv ( pParamTrim->GetLoop( c, l)) ;
// if ( bInverted)
// pCrv->Invert() ;
// PolyLine plApprox ;
// double dLinTol = 10 * EPS_SMALL, dAngTolDeg = 5 ;
// int nType = 0 ;
// pCrv->ApproxWithLines( dLinTol, dAngTolDeg, nType, plApprox) ;
// // aggiungo la polyline del chunk
// vPl.push_back( plApprox) ;
// }
//}
//// CON LE CURVE ( INTERSEZIONI CON BORDO PARAMETRICO)
PtrOwner<ICurveComposite> pCCEdge( CreateCurveComposite()) ;
pCCEdge->AddPoint( m_mTree.at(-1).GetTopRight()) ;
@@ -321,121 +284,124 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_mVert.insert( pair<int, PNTVECTOR>( -1, vVert)) ;
// se richiesto divido preliminarmente le patches
m_vnParents.clear() ;
if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) {
int nId = -1 ;
// se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo
if ( AreSamePointApprox(ptP00, ptP10) && AreSamePointApprox(ptP01, ptP11) ) {
m_mTree[-1].m_nLeft = -1 ;
m_mTree[-1].m_nRight = -1 ;
m_bClosedU = true ;
}
// se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo
if ( ( AreSamePointApprox(ptP00, ptP01) && AreSamePointApprox(ptP10, ptP11) ) ) {
m_mTree[-1].m_nTop = -1 ;
m_mTree[-1].m_nBottom = -1 ;
m_bClosedV = true ;
}
for ( int i = 1 ; i < nSpanU ; ++i) {
// chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000)
if ( i * SBZ_TREG_COEFF > ptMin.x + 5 && i * SBZ_TREG_COEFF < ptTop.x - 5){
m_mTree[nId].SetSplitDirVert( true) ;
if ( Split( nId, i * SBZ_TREG_COEFF)) {
++ nId ;
++ nId ;
}
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
if( ! bIsPlanar) {
if ( m_bSplitPatches && ( nSpanU > 1 || nSpanV > 1)) {
int nId = -1 ;
// se la superficie è chiusa lungo il parametro U, sistemo le adiacenze al bordo
if ( AreSamePointApprox(ptP00, ptP10) && AreSamePointApprox(ptP01, ptP11) ) {
m_mTree[-1].m_nLeft = -1 ;
m_mTree[-1].m_nRight = -1 ;
m_bClosedU = true ;
}
}
INTVECTOR vLeaves ;
GetHeightLeaves( -1, vLeaves) ;
for ( int nId : vLeaves) {
for ( int j = nSpanV - 1 ; j > 0 ; --j) {
// chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000)
if ( j * SBZ_TREG_COEFF > ptMin.y + 5 && j * SBZ_TREG_COEFF < ptTop.y - 5){
m_mTree[nId].SetSplitDirVert( false) ;
if ( Split( nId, j * SBZ_TREG_COEFF))
nId = m_mTree[nId].m_nChild2 ;
}
}
}
vLeaves.clear() ;
}
// controllo se la superficie è chiusa.
// se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa
// e sistemo le adiacenze
if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) ||
( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11))) {
// m_bClosed = true ;
if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) && (int) m_mTree.size() == 1) {
if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) {
// se la superficie è chiusa lungo il parametro V, sistemo le adiacenze al bordo
if ( ( AreSamePointApprox(ptP00, ptP01) && AreSamePointApprox(ptP10, ptP11) ) ) {
m_mTree[-1].m_nTop = -1 ;
m_mTree[-1].m_nBottom = -1 ;
m_bClosedV = true ;
}
m_mTree[-1].SetSplitDirVert( false) ;
Split( -1) ;
// qui devo fare il controllo capped ( chiusura a semisfera)
// devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti
// in caso devo fare uno split nell'altra direzione
bool bOk = false ;
bool bPole0 = true, bPole1 = true ;
Point3d ptU0, ptU1 ;
// controllo se tutti i punti di controllo sull'isoparametrica sono uguali
for ( int i = 1 ; i < nDegV * nSpanV + 1 ; ++ i) {
ptU0 = m_pSrfBz->GetControlPoint( i * ( nDegU * nSpanU + 1), &bOk) ;
bPole0 = bPole0 && AreSamePointApprox( ptP00, ptU0) ;
ptU1 = m_pSrfBz->GetControlPoint( ( i + 1) * ( nDegU * nSpanU + 1) - 1, &bOk) ;
bPole1 = bPole1 && AreSamePointApprox( ptP10, ptU1) ;
}
m_vbPole[1] = bPole0 ;
m_vbPole[3] = bPole1 ;
if ( bPole0 && bPole1) {
m_mTree[0].SetSplitDirVert( true) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( true) ;
Split( 1) ;
}
}
// nella condizione di questo if non controllo eventuali divisioni preliminari, perché ne tengo conto dopo
if ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11)) {
if ( m_mTree.size() == 1) {
if ( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11)) {
m_mTree[-1].m_nLeft = -1 ;
m_mTree[-1].m_nRight = -1 ;
m_bClosedU = true ;
for ( int i = 1 ; i < nSpanU ; ++i) {
// chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000)
if ( i * SBZ_TREG_COEFF > ptMin.x + 5 && i * SBZ_TREG_COEFF < ptTop.x - 5){
m_mTree[nId].SetSplitDirVert( true) ;
if ( Split( nId, i * SBZ_TREG_COEFF)) {
++ nId ;
++ nId ;
}
}
m_mTree[-1].SetSplitDirVert( true) ;
}
INTVECTOR vLeaves ;
GetHeightLeaves( -1, vLeaves) ;
for ( int nId : vLeaves) {
for ( int j = nSpanV - 1 ; j > 0 ; --j) {
// chiedo che il taglio disti dal bordo almeno il 2% della singola patch (1000 x 1000)
if ( j * SBZ_TREG_COEFF > ptMin.y + 5 && j * SBZ_TREG_COEFF < ptTop.y - 5){
m_mTree[nId].SetSplitDirVert( false) ;
if ( Split( nId, j * SBZ_TREG_COEFF))
nId = m_mTree[nId].m_nChild2 ;
}
}
}
vLeaves.clear() ;
}
// controllo se la superficie è chiusa.
// se è chiusa e non ho già fatto split preliminare, splitto sul parametro su cui è chiusa
// e sistemo le adiacenze
if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) ||
( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11))) {
// m_bClosed = true ;
if ( ( AreSamePointApprox( ptP00, ptP01) || AreSamePointApprox( ptP10, ptP11)) && (int) m_mTree.size() == 1) {
if ( AreSamePointApprox( ptP00, ptP01) && AreSamePointApprox( ptP10, ptP11)) {
m_mTree[-1].m_nTop = -1 ;
m_mTree[-1].m_nBottom = -1 ;
m_bClosedV = true ;
}
m_mTree[-1].SetSplitDirVert( false) ;
Split( -1) ;
// devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti
// qui devo fare il controllo capped ( chiusura a semisfera)
// devo controllare se i punti ai parametri U=0 e U=1 sono tutti coincidenti
// in caso devo fare uno split nell'altra direzione
bool bOk = false ;
bool bPole0 = true, bPole1 = true ;
Point3d ptV0, ptV1 ;
// controllo se tutti i punti sull'isoparametrica sono uguali
for ( int i = 1 ; i < nDegU * nSpanU + 1 ; ++ i) {
ptV0 = m_pSrfBz->GetControlPoint( i, &bOk) ;
bPole0 = bPole0 && AreSamePointApprox( ptP00, ptV0) ;
ptV1 = m_pSrfBz->GetControlPoint( i + ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ;
bPole1 = bPole1 && AreSamePointApprox( ptP01, ptV1) ;
Point3d ptU0, ptU1 ;
// controllo se tutti i punti di controllo sull'isoparametrica sono uguali
for ( int i = 1 ; i < nDegV * nSpanV + 1 ; ++ i) {
ptU0 = m_pSrfBz->GetControlPoint( i * ( nDegU * nSpanU + 1), &bOk) ;
bPole0 = bPole0 && AreSamePointApprox( ptP00, ptU0) ;
ptU1 = m_pSrfBz->GetControlPoint( ( i + 1) * ( nDegU * nSpanU + 1) - 1, &bOk) ;
bPole1 = bPole1 && AreSamePointApprox( ptP10, ptU1) ;
}
m_vbPole[0] = bPole0 ;
m_vbPole[2] = bPole1 ;
m_vbPole[1] = bPole0 ;
m_vbPole[3] = bPole1 ;
if ( bPole0 && bPole1) {
m_mTree[0].SetSplitDirVert( false) ;
m_mTree[0].SetSplitDirVert( true) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( false) ;
m_mTree[1].SetSplitDirVert( true) ;
Split( 1) ;
}
}
// se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1
else if ( (int) m_mTree.size() > 1 && (int) m_mTree.size() < 4 && ! m_mTree.at(-1).IsSplitVert()) { // si può mettere anche < 5
m_mTree[0].m_nLeft = -1 ;
m_mTree[0].m_nRight = -1 ;
m_mTree[1].m_nLeft = -1 ;
m_mTree[1].m_nRight = -1 ;
m_mTree[0].SetSplitDirVert( true) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( true) ;
Split( 1) ;
// nella condizione di questo if non controllo eventuali divisioni preliminari, perché ne tengo conto dopo
if ( AreSamePointApprox( ptP00, ptP10) || AreSamePointApprox( ptP01, ptP11)) {
if ( m_mTree.size() == 1) {
if ( AreSamePointApprox( ptP00, ptP10) && AreSamePointApprox( ptP01, ptP11)) {
m_mTree[-1].m_nLeft = -1 ;
m_mTree[-1].m_nRight = -1 ;
m_bClosedU = true ;
}
m_mTree[-1].SetSplitDirVert( true) ;
Split( -1) ;
// devo controllare se i punti ai parametri V=0 e V=1 sono tutti coincidenti
// in caso devo fare uno split nell'altra direzione
bool bOk = false ;
bool bPole0 = true, bPole1 = true ;
Point3d ptV0, ptV1 ;
// controllo se tutti i punti sull'isoparametrica sono uguali
for ( int i = 1 ; i < nDegU * nSpanU + 1 ; ++ i) {
ptV0 = m_pSrfBz->GetControlPoint( i, &bOk) ;
bPole0 = bPole0 && AreSamePointApprox( ptP00, ptV0) ;
ptV1 = m_pSrfBz->GetControlPoint( i + ( nDegU * nSpanU + 1) * ( nDegV * nSpanV), &bOk) ;
bPole1 = bPole1 && AreSamePointApprox( ptP01, ptV1) ;
}
m_vbPole[0] = bPole0 ;
m_vbPole[2] = bPole1 ;
if ( bPole0 && bPole1) {
m_mTree[0].SetSplitDirVert( false) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( false) ;
Split( 1) ;
}
}
// se ho fatto solo 1 split orizzontale e ho due celle foglie nId = 0 e nId = 1
else if ( (int) m_mTree.size() > 1 && (int) m_mTree.size() < 4 && ! m_mTree.at(-1).IsSplitVert()) { // si può mettere anche < 5
m_mTree[0].m_nLeft = -1 ;
m_mTree[0].m_nRight = -1 ;
m_mTree[1].m_nLeft = -1 ;
m_mTree[1].m_nRight = -1 ;
m_mTree[0].SetSplitDirVert( true) ;
Split( 0) ;
m_mTree[1].SetSplitDirVert( true) ;
Split( 1) ;
}
}
}
}
@@ -1003,6 +969,8 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
}
// bilineare
else {
bool bIsPlanar = m_pSrfBz->IsPlanar() ;
while ( nCToSplit != -2 && m_mTree[nCToSplit].IsProcessed() == false) {
if ( m_mTree[nCToSplit].IsLeaf()) {
// vertici della cella
@@ -1079,7 +1047,7 @@ Tree::BuildTree( double dLinTol, double dSideMin, double dSideMax)
}
}
}
else {
else if ( ! bIsPlanar){
dErr = 1. / 4. * ( ( ptP00 - ptP01) + ( ptP11 - ptP10)).Len() ;
//int dErr2 = 1. / 4. * ( ( ptP10 - ptP01) + ( ptP11 - ptP00)).Len() ; //correzione che mi verrebbe intuitiva, ma che fa dividere la superficie molto di più ( probabilmente troppo)!! quindi probabilmente sbagliata
}
@@ -1557,16 +1525,6 @@ Tree::GetDepth( int nId, int nRef = -2) const
return i ;
}
////----------------------------------------------------------------------------
//struct generator
//{
// int value ;
// generator( void)
// { value = -1 ; }
// int operator() ()
// { return ++value ; }
//} ;
//----------------------------------------------------------------------------
bool
Tree::GetPolygons( POLYLINEMATRIX& vvPolygons)
@@ -1792,7 +1750,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1){
// se la superficie è chiusa lungo il parametro U e le celle vicine right sono sul lato Left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
vnVert.push_back( int(vVertices.size() - 1)) ;
if ( m_bClosedU && m_mTree.at( vNeigh[0]).m_bOnLeftEdge ) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( nId).GetTopRight().x, m_mTree.at(j).GetBottomLeft().y) ;
@@ -1825,7 +1783,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
if ( ! vNeigh.empty() && vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro V e la cella è sul lato top
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
vnVert.push_back( int(vVertices.size() - 1)) ;
if ( m_bClosedV && m_mTree.at( nId).m_bOnTopEdge) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( j).GetBottomLeft().x, m_mTree.at( nId).GetTopRight().y) ;
@@ -1851,7 +1809,7 @@ Tree::GetPolygonsBasic( POLYLINEVECTOR& vPolygonsBasic, POLYLINEVECTOR& vPolygon
if ( (int) vNeigh.size() != 0 && (int) vNeigh.size() != 1) {
// se la superficie è chiusa lungo il parametro U e la cella è sul lato left
// devo aggiungere i vertici tenendo conto della periodicità dello spazio parametrico.
vnVert.push_back( int(vVertices.size())) ;
vnVert.push_back( int(vVertices.size() - 1)) ;
if ( m_bClosedU && m_mTree.at( nId).m_bOnLeftEdge) {
for ( int j : vNeigh) {
Point3d pt( m_mTree.at( nId).GetBottomLeft().x, m_mTree.at(j).GetTopRight().y) ;
@@ -2236,40 +2194,6 @@ Tree::FindCell( const Point3d& ptToAssign, const CurveLine& cl, INTVECTOR vCells
}
// rilancio la rigida ricerca
nCells = FindCell( ptIntersPlus, cl, vCells, true) ;
/////////////////////////// questa versione funziona, ma forse potrebbe fallire in alcuni casi///
// for ( int nCell : vCells) {
// if ( ptToAssign.x > m_mTree.at( nCell).GetBottomLeft().x - EPS_SMALL && ptToAssign.x < m_mTree.at( nCell).GetTopRight().x + EPS_SMALL &&
// ptToAssign.y > m_mTree.at( nCell).GetBottomLeft().y - EPS_SMALL && ptToAssign.y < m_mTree.at( nCell).GetTopRight().y + EPS_SMALL) {
// nId = nCell ;
// nCells.push_back( nId) ;
// }
// }
// if ( (int)nCells.size() == 1)
// return nCells ;
// // sono su vertice o un lato, quindi avanzo con il parametro lungo la curva
// else if ( (int)nCells.size() > 1 ) {
// // la CurveLine è il segmento di trim su cui giace ptToAssign
// Point3d ptIntersPlus ;
// Vector3d vtDir ;
// cl.GetStartDir( vtDir) ;
// // mi sposto appena più avanti di ptToAssign
// // se la curva è orientata come l'asse x o y mi sto muovendo su un lato e sarò ancora sul lato, quindi dovrei ruotare il vettore a destra prima di spostarmi
// if ( abs( vtDir.x) >= 1 - EPS_SMALL || abs( vtDir.y) >= 1 - EPS_SMALL)
// vtDir.Rotate( Z_AX, -45) ;
// ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
// // se sono finito fuori dallo spazio parametrico giro invece a sinistra
// if ( ptIntersPlus.x < m_mTree.at( -1).GetBottomLeft().x - EPS_SMALL || ptIntersPlus.x > m_mTree.at( -1).GetTopRight().x + EPS_SMALL||
// ptIntersPlus.y < m_mTree.at( -1).GetBottomLeft().y - EPS_SMALL || ptIntersPlus.y > m_mTree.at( -1).GetTopRight().y + EPS_SMALL) {
// vtDir.Rotate( Z_AX, 90) ;
// ptIntersPlus = ptToAssign + vtDir * EPS_SMALL ;
// }
// nCells = FindCell( ptIntersPlus, cl, vCells) ;
// }
//// se vuoto allora il punto non è in nessuna delle celle passate in input
// else
// return nCells ;
//////////////////////////////////////////////////////////////////////////
}
return nCells ;
@@ -2405,19 +2329,13 @@ Tree::TraceLoopLabelCell( const POLYLINEVECTOR& vplPolygons)
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, vptInters.back()) ;
}
// VERSIONE NUOVA
// controllo di aggiungere un punto abbastanza distante dal precedente
if( ! AreSamePointEpsilon( vptInters.back(), ptCurr, 2 * EPS_SMALL)) {
if( ! AreSamePointEpsilon( vptInters.back(), ptCurr, 10 * EPS_SMALL)) {
// aggiungo la fine del segmento nel vettore delle intersezioni
vptInters.push_back( ptCurr) ;
// aggiorno la polyline splittata
UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptCurr) ;
}
////VECCHIA VERSIONE
//// aggiungo la fine del segmento nel vettore delle intersezioni
//vptInters.push_back( ptCurr) ;
//// aggiorno la polyline splittata
//UpdateSplitLoop( plLoopSplit, nPtLoopSplit, ptCurr) ;
}
if ( nId == nFirstCell)
vptInters.pop_back() ;
@@ -2626,91 +2544,6 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon,
int nEdge ; // flag che indica il lato su cui ho l'intersezione a partire dal lato top in senso antiorario
Point3d ptInters ;
//CurveLine clEdge , clEdge2 ;
//Point3d ptStart , ptEnd ;
//clTrim.GetStartPoint( ptStart) ;
//clTrim.GetEndPoint( ptEnd) ;
//// trovo da quale lato sto uscendo
////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
////int nEdge2 ;
//if ( ptEnd.y >= ptTR.y && ptEnd.x <= ptTR.x) {
// //nEdge = 0 ;
// // lato sopra
// clEdge.Set( ptTR, ptTl) ;
// // lato sinistro
// if ( ptEnd.x < ptBL.x) {
// //nEdge2 = 1 ;
// clEdge2.Set( ptTl, ptBL) ;
// }
//}
//else if ( ptEnd.x <= ptBL.x && ptEnd.y <= ptTR.y) {
// nEdge = 1 ;
// // lato sinistro
// clEdge.Set( ptTl, ptBL) ;
// // lato sotto
// if ( ptEnd.y < ptBL.y) {
// //nEdge2 = 2 ;
// clEdge2.Set( ptBL, ptBr) ;
// }
//}
//else if ( ptEnd.y <= ptBL.y && ptEnd.x >= ptBL.x) {
// nEdge = 2 ;
// // lato sotto
// clEdge.Set( ptBL, ptBr) ;
// // lato destro
// if ( ptEnd.x > ptTR.x) {
// //nEdge2 = 3 ;
// clEdge2.Set( ptBr, ptTR) ;
// }
//}
//else if ( ptEnd.x >= ptTR.x && ptEnd.y >= ptBL.y) {
// nEdge = 3 ;
// // lato desto
// clEdge.Set( ptBr, ptTR) ;
// // lato sopra
// if ( ptEnd.y > ptTR.y) {
// //nEdge2 = 0 ;
// clEdge2.Set( ptTR, ptTl) ;
// }
//}
//else
// return false ;
//bool bIntersFound = false ;
//// intersezione e controlli
//IntersLineLine illExit( clTrim, clEdge, true) ;
//IntCrvCrvInfo aInfo, aInfo2 ;
//if ( ! illExit.GetIntCrvCrvInfo( aInfo)) {
// bIntersFound = false ;
// if ( ! clEdge2.IsValid())
// return false ;
//}
//else {
// bIntersFound = true ;
// if ( aInfo.bOverlap)
// ptInters = aInfo.IciA[1].ptI ;
// else
// ptInters = aInfo.IciA[0].ptI ;
//}
//if ( clEdge2.IsValid() && ! bIntersFound){
// IntersLineLine illExit2( clTrim, clEdge2, true) ;
// // verifico su quale dei due lati ho l'intersezione
// if ( ! illExit2.GetIntCrvCrvInfo( aInfo2))
// bIntersFound = false ;
// else {
// bIntersFound = true ;
// //// solo intersezione sul lato 2
// if ( aInfo2.bOverlap)
// ptInters = aInfo2.IciA[1].ptI ;
// else
// ptInters = aInfo2.IciA[0].ptI ;
// }
//}
//if ( ! bIntersFound)
// return false ;
PtrOwner<ICurveComposite> pCC( CreateCurveComposite()) ;
PolyLine plSimplePolygon ;
plSimplePolygon = plPolygon ;
@@ -2765,7 +2598,7 @@ Tree::FindInters( int& nId, const CurveLine& clTrim, const PolyLine& plPolygon,
else if ( nEdge == 7)
ptInters = ptTR ;
// aggiungo il nuovo punto al vettore delle intersezioni
if ( (int)vptInters.size() == 0 || ! AreSamePointEpsilon( ptInters , vptInters.back(), 2 * EPS_SMALL))
if ( (int)vptInters.size() == 0 || ! AreSamePointEpsilon( ptInters , vptInters.back(), 10 * EPS_SMALL))
vptInters.push_back( ptInters) ;
else {
// se l'ultimo punto del vettore delle intersezioni è quasi uguale al punto che devo aggiungere allora lo sostituisco con quest'ultimo
@@ -3140,15 +2973,13 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
}
else {
double dPar = 0 ;
bool bAdvanced = false ;
while ( plCell.GetNextUPoint( &dPar, &ptToAdd) && ! AreSamePointExact( ptToAdd, ptNextVert)) {
vEdgeVertex[j].push_back( ptToAdd) ;
if ( dPar > 0)
plCell3d.GetNextPoint( pt3d) ;
vEdgeVertex3d[j].push_back( pt3d) ;
bAdvanced = true ;
}
if ( ! bAdvanced && dPar > 0)
if ( dPar > 0)
plCell3d.GetNextPoint( pt3d) ;
}
}
@@ -3198,7 +3029,9 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
Vector3d vEdge ;
// estendo: se l'ultimo tratto è sovrapposto e controverso allora elimino l'ultimo punto
bool bNotEquiverseOverlap = false ;
if ( nEdge == 0 || nEdge == 7 ) {
int nEdgeLast = -1 ;
OnWhichEdge(nId,ptLast, nEdgeLast) ;
if ( (nEdge == 0 || nEdge == 7) && nEdge == nEdgeLast) {
vEdge.Set( 1,0,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
@@ -3207,7 +3040,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
bNotEquiverseOverlap = true ;
}
}
else if ( nEdge == 1 || nEdge == 4 ) {
else if ( ( nEdge == 1 || nEdge == 4 ) && nEdge == nEdgeLast) {
vEdge.Set( 0,-1,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
@@ -3216,7 +3049,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
bNotEquiverseOverlap = true ;
}
}
else if ( nEdge == 2 || nEdge == 5 ) {
else if ( ( nEdge == 2 || nEdge == 5) && nEdge == nEdgeLast) {
vEdge.Set( -1,0,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
@@ -3225,7 +3058,7 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
bNotEquiverseOverlap = true ;
}
}
else if ( nEdge == 3 || nEdge == 6 ) {
else if ( ( nEdge == 3 || nEdge == 6) && nEdge == nEdgeLast) {
vEdge.Set( 0,1,0) ;
if ( AreOppositeVectorApprox( vLast, vEdge)) {
plTrimmedPoly.EraseLastUPoint() ;
@@ -3313,8 +3146,9 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
else if ( ! bNotCameBack){
Point3d ptStart ;
plTrimmedPoly.GetFirstPoint( ptStart) ;
Point3d ptLast ; plTrimmedPoly.GetLastPoint( ptLast) ;
for ( int p = 1 ; p < (int) vEdgeVertex[nEdge].size() ; ++ p) {
if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], ptStart)) {
if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], ptStart) && CheckIfBefore( nEdge, ptLast, vEdgeVertex[nEdge][p])) {
plTrimmedPoly.AddUPoint( c, vEdgeVertex[nEdge][p]) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[nEdge][p]) ;
++ c ;
@@ -3348,8 +3182,9 @@ Tree::CreateCellPolygons( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATRIX
// aggiorno le condizioni per il while
bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ;
}
Point3d ptLast ; plTrimmedPoly.GetLastPoint( ptLast) ;
for ( int p = 1 ; p < (int) vEdgeVertex[nEdge].size() ; ++ p) {
if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], ptStart)) {
if ( CheckIfBefore( nEdge, vEdgeVertex[nEdge][p], ptStart) && CheckIfBefore( nEdge, ptLast, vEdgeVertex[nEdge][p])) {
plTrimmedPoly.AddUPoint( c, vEdgeVertex[nEdge][p]) ;
plTrimmedPoly3d.AddUPoint( c, vEdgeVertex3d[nEdge][p]) ;
++ c ;
@@ -3458,10 +3293,11 @@ Tree::CreateIslandAndHoles( int nLeafId, POLYLINEMATRIX& vPolygons, POLYLINEMATR
vPolygons.push_back( vCellPolygons) ;
++ nPoly ;
if ( bForTriangulation) {
plInLoop3d.AddUPoint( 0, m_mVert[nId][2]);
plInLoop3d.AddUPoint( 1, m_mVert[nId][3]);
plInLoop3d.AddUPoint( 2, m_mVert[nId][0]);
plInLoop3d.AddUPoint( 3, m_mVert[nId][1]);
plInLoop3d.AddUPoint( 0, m_mVert[nId][2]) ;
plInLoop3d.AddUPoint( 1, m_mVert[nId][3]) ;
plInLoop3d.AddUPoint( 2, m_mVert[nId][0]) ;
plInLoop3d.AddUPoint( 3, m_mVert[nId][1]) ;
plInLoop3d.Close() ;
vCellPolygons3d.push_back( plInLoop3d) ;
vPolygons3d.push_back( vCellPolygons3d) ;
vCellPolygons3d.clear() ;
@@ -3884,7 +3720,7 @@ Tree::AddVertex( int nId, const PNTMATRIX& vEdgeVertex, const PNTMATRIX& vEdgeVe
bool
Tree::SetRightEdgeIn( int nId)
{
// categorizzo la cella in base a quanta parte del lato destro è conenuta all'interno delle curve di trim
// categorizzo la cella in base a quanta parte del lato destro è contenuta all'interno delle curve di trim
// RightEdgeIn -> 0 non contenuto ; 1 contenuto ; 2 in parte contenuto
int nPass = (int) m_mTree[nId].m_vInters.size() ;
if ( nPass == 0) {