EgtGeomKernel :

- sistemati vari bug nella creazione della superficie trimesh trimmata
si una superficie di bezier
Problemi noti :
- sui casi con un tree reale entro in un loop infinito o seleziono oppure
seleziono un elemento inesistente di un vettore
This commit is contained in:
Daniele Bariletti
2023-06-06 16:36:09 +02:00
parent 579bc5492c
commit f3346fd1f1
2 changed files with 118 additions and 127 deletions
+115 -125
View File
@@ -1393,6 +1393,12 @@ Tree::FindCell( const Point3d& ptToAssign, CurveLine& clTrim) const
//nCells.push_back( - 2) ;
return nCells ;
}
// se lo spazio parametrico non è stato suddiviso ( ho un piano), restituisco la cella root
if ( m_mTree.at(nId).IsLeaf() ) {
nCells.push_back( nId) ;
return nCells ;
}
while ( ! m_mTree.at(nId).IsLeaf()) {
if ( m_mTree.at(nId).IsSplitVert()) {
@@ -2164,23 +2170,24 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
// in questo for analizzo solo i loop che tagliano la cella
int nEdgeIn = -1 ;
int nFirstLoopInPoly = -1 ;
INTVECTOR vAddedLoops ;
for ( int w = 0 ; w < (int)vToCheckNow.size() ; ++ w) {
// primo loop di questo poligono
// indice del loop in m_vInters
int j = vToCheckNow[w] ;
Inters inA = m_mTree[nId].m_vInters[j] ;
if ( inA.nIn != -1 ) {
int nEdge ;
if ( nEdgeIn == -1 )
if ( nEdgeIn == -1 ) {
// salvo il lato di ingresso del primo lato del poligono che sto costruendo
nEdgeIn = inA.nIn ;
nFirstLoopInPoly = j ;
}
for ( Point3d ptInt : inA.vpt ) {
AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptInt) ;
//plTrimmedPoly.AddUPoint(c, ptInt) ;
//++c ;
}
vAddedLoops.push_back( j) ;
nEdge = inA.nOut ;
// se la curva è CW devo verifica di non essere uscito in un vertice, con un tratto sovrapposto al lato che ripercorrerò tra poco
// qui ho tolto l'if e esteso anche ai casi CCW perché anche lì devo controllare!!!!!////////////////////////////////////////////////////////////
// devo verificare di non essere uscito in un vertice, con un tratto sovrapposto al lato che ripercorrerò tra poco
Point3d ptLast, ptSecondToLast;
plTrimmedPoly.GetLastPoint(ptLast) ;
plTrimmedPoly.GetPrevPoint(ptSecondToLast) ;
@@ -2240,7 +2247,7 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
bool bNotCameBack = true ;
bool bValidNextStart = false ;
bool bAtNextStart = false ;
if ( j < nPassToCheck - 1) {
if ( w < nPassToCheck - 1) { // ho messo w al posto di j ////////////////////////////////////////////////////////////////////////////////////////
int nSecondCheck = 0 ;
int nNext ;
// ciclo sui loop successivi per vedere se ne ho uno con un valid start
@@ -2253,39 +2260,12 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
}
else {
++ nSecondCheck ;
vToCheck.push_back( t) ;
vToCheck.push_back( vToCheckNow[t]) ;
}
}
//// ciclo sui loop successivi per vedere se ne ho uno su questo lato con un valid start
//for ( int t = w ; t < nPassToCheck -1 ; ++ t) {
// if ( AreSameEdge( nEdge, m_mTree[nId].m_vInters[j].nIn) ) {
// if ( m_mTree[nId].m_vInters[j].bCCW) {
// bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && // loop successivo inizia su questo lato
// ! CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; // in posizione giusta da essere concatenato
// }
// else {
// // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline
// bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) &&
// CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ;
// }
// }
// else
// bValidNextStart = CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ;
// if ( ! AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) || bValidNextStart)
// //if ( bValidNextStart)
// break ;
// // se ho trovato un loop successivo che devo saltare, lo salvo e considero i loop più avanti.
// if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) && ! bValidNextStart){
// //else {
// ++ nSecondCheck ;
// vToCheck.push_back( t + 1) ;
// }
//}
bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ;
//while ( ! bValidNextStart && bNotCameBack) {
while ( ! ( bValidNextStart && bAtNextStart) && bNotCameBack) {
Point3d ptVert ;
if ( nEdge == 0)
@@ -2297,8 +2277,6 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
else if ( nEdge == 3)
ptVert = m_mTree[nId].GetTopRight() ;
AddVertex( nId, vEdgeVertex, plTrimmedPoly, c, ptVert) ;
//plTrimmedPoly.AddUPoint( c, ptVert) ;
//++c ;
if ( nEdge > 3 && nEdge != 7)
nEdge = nEdge - 4 ;
else if ( nEdge < 3 )
@@ -2311,50 +2289,10 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
bAtNextStart = AreSameEdge( nEdge, m_mTree[nId].m_vInters[vToCheckNow[nNext]].nIn) ;
bNotCameBack = ! ( AreSameEdge( nEdge, nEdgeIn) && CheckIfBefore( plTrimmedPoly, nEdge)) ;
/*for ( int t = w + 1 ; t < nPassToCheck -1 ; ++ t) {
bValidNextStart = CheckIfBetween( m_mTree[nId].m_vInters[j], m_mTree[nId].m_vInters[vToCheckNow[t]]) ;
if ( bValidNextStart) {
bAtNextStart = AreSameEdge( m_mTree[nId].m_vInters[j].nOut, m_mTree[nId].m_vInters[vToCheckNow[t]].nIn) ;
break ;
}
else {
++ nSecondCheck ;
vToCheck.push_back( t) ;
}
}*/
// ciclo sui loop successivi per vedere se ne ho uno su questo lato con un valid start
//for ( int t = w ; t < nPassToCheck -1 ; ++ t) {
// if ( AreSameEdge( nEdge, m_mTree[nId].m_vInters[j].nIn) ) {
// if ( m_mTree[nId].m_vInters[j].bCCW) {
// bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) && // loop successivo inizia su questo lato
// ! CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ; // in posizione giusta da essere concatenato
// }
// else {
// // se il loop è CW e sono tornato sul lato di partenza allora controllo se sono prima del primo punto della polyline
// bValidNextStart = ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge)) &&
// CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ;
// }
// }
// else
// bValidNextStart = CheckIfAfter( plTrimmedPoly, m_mTree[nId].m_vInters[vToCheckNow[t + 1]].vpt[0], nEdge) ;
// if ( ! AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) || bValidNextStart)
// //if ( bValidNextStart)
// break ;
// // se ho trovato un loop successivo che devo saltare, lo salvo e considero i loop più avanti.
// if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[t + 1]].nIn, nEdge) && ! bValidNextStart){
// //else {
// ++ nSecondCheck ;
// vToCheck.push_back( t + 1) ;
// }
//}
}
// se ho trovato un altro loop salto all'inizio del for
//
//if ( AreSameEdge( m_mTree[nId].m_vInters[vToCheckNow[w + 1 + nSecondCheck]].nIn, nEdge) && bValidNextStart) { // qui ho aggiunto bValidNextStart/////////////////////////
if ( bValidNextStart) { ///////////////////////////////
w = w + nSecondCheck ;
if ( bValidNextStart) {
w = w + nSecondCheck ;
continue ;
}
}
@@ -2398,6 +2336,14 @@ Tree::CreateCellPolygons( int nLeafId, std::vector<POLYLINEVECTOR>& vPolygons, I
c = 0 ;
plTrimmedPoly.Clear() ;
nEdgeIn = -1 ;
// devo verificare se tra i loop che sono finiti in vToCheck in realtà qualcuno l'ho usato per fare un poligono/////////////////////////////////////
for ( int k = 0 ; k < (int)vToCheck.size() ; ++ k) {
for ( int i = 0 ; i < (int)vAddedLoops.size() ; ++ i) {
if ( vToCheck[k] == vAddedLoops[i] ) {
vToCheck.erase(vToCheck.begin() + k) ;
}
}
}
}
else
continue ;
@@ -2551,7 +2497,7 @@ bool
Tree::CheckIfBefore( int& nEdge1, Point3d& ptP1, int& nEdge2, Point3d& ptP2) const
{
INTVECTOR vEdges = { 7, 0, 4, 1, 5, 2, 6} ;
// controllo se nEdge1 viene prima di nEdge2. la partenza è da ptTR e l'arrivo è ptBr
// controllo se ptP1, che è su nEdge1, viene prima di ptP2, che è su nEdge2. la partenza è da ptTR e l'arrivo è ptBr
INTVECTOR :: iterator iter1 = find( vEdges.begin(), vEdges.end(), nEdge1) ;
int nPos1 = std::distance( vEdges.begin(), iter1) ;
INTVECTOR :: iterator iter2 = find( vEdges.begin(), vEdges.end(), nEdge2) ;
@@ -2574,53 +2520,58 @@ Tree::CheckIfBefore( int& nEdge1, Point3d& ptP1, int& nEdge2, Point3d& ptP2) con
//----------------------------------------------------------------------------
bool
Tree::CheckIfAfter( PolyLine& pl, Point3d& ptNextStart, int nEdge, bool bSameEdge) const
Tree::CheckIfBefore( int& nEdge, Point3d& ptP1, Point3d& ptP2) const
{
// sul lato nEdge controllo se ptP1 viene prima di ptP2.
// i lati vengono percorsi in senso antiorario
if ( nEdge == 0 ) {
return ptP1.x > ptP2.x ;
}
else if ( nEdge == 1 ) {
return ptP1.y > ptP2.y ;
}
else if ( nEdge == 2 ) {
return ptP1.x < ptP2.x ;
}
else if ( nEdge == 3 ) {
return ptP1.y < ptP2.y ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
Tree::CheckIfAfter( PolyLine& pl, Point3d& ptNextStart, int nEdge) const
{
// controllo se ptNextStart è più avanti rispetto a ptEnd in senso antiorario
// ATTENZIONE i due punti devono essere sullo stesso lato!
// se i punti non sono sullo stesso lato ritorno false ( con bSameEdge == true)
// se i punti non sono sullo stesso lato ritorno false
Point3d ptEnd ;
pl.GetLastPoint( ptEnd) ;
if ( nEdge == 0 ) {
if ( bSameEdge) {
if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL)
return ptEnd.x > ptNextStart.x ;
else
return false ;
}
else
if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL)
return ptEnd.x > ptNextStart.x ;
else
return false ;
}
else if ( nEdge == 1 ) {
if ( bSameEdge) {
if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL)
return ptEnd.y > ptNextStart.y ;
else
return false ;
}
else
if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL)
return ptEnd.y > ptNextStart.y ;
else
return false ;
}
else if ( nEdge == 2 ) {
if ( bSameEdge) {
if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL)
return ptEnd.x < ptNextStart.x ;
else
return false ;
}
else
if ( ptNextStart.y > ptEnd.y - EPS_SMALL && ptNextStart.y < ptEnd.y + EPS_SMALL)
return ptEnd.x < ptNextStart.x ;
else
return false ;
}
else if ( nEdge == 3 ) {
if ( bSameEdge) {
if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL)
return ptEnd.y < ptNextStart.y ;
else
return false ;
}
else
if ( ptNextStart.x > ptEnd.x - EPS_SMALL && ptNextStart.x < ptEnd.x + EPS_SMALL)
return ptEnd.y < ptNextStart.y ;
else
return false ;
}
return false ;
}
@@ -2992,33 +2943,72 @@ Tree::CategorizeCell( int& nId)
//----------------------------------------------------------------------------
bool
Tree::CheckIfBetween( Inters& intA, Inters& intB) const
Tree::CheckIfBetween( Inters& inA, Inters& inB) const
{
// controllo se intB è compreso tra l'end e lo start di intA
// controllo se inB è compreso tra l'end e lo start di inA
// ( dall'end di A percorro i bordi della cella fino a tornare allo start e devo incontrare In e Out di B)
INTVECTOR vEdges ;
int nEdge = intA.nOut ;
vEdges.push_back( nEdge) ;
if ( nEdge == 3)
nEdge = 0 ;
else
++ nEdge ;
while ( nEdge != intA.nIn ) {
int nEdge = inA.nOut ;
//vEdges.push_back( nEdge) ;
//if ( nEdge == 3)
// nEdge = 0 ;
//else
// ++ nEdge ;
while ( nEdge != inA.nIn || (int) vEdges.size() == 0) {
vEdges.push_back( nEdge) ;
if ( nEdge == 3)
nEdge = 0 ;
else
++ nEdge ;
}
if ( inA.nIn != inA.nOut)
vEdges.push_back( nEdge) ;
bool bFound = false ;
for ( int i : vEdges) {
if ( intB.nIn == i) {
PolyLine pl ;
pl.AddUPoint( 0, intA.vpt[0]) ;
pl.AddUPoint( 1, intA.vpt.back()) ;
if ( CheckIfAfter( pl, intB.vpt[0], i, false))
bFound = true ;
if ( inB.nIn == i) {
if ( inB.nIn == inA.nIn && inA.nIn == inA.nOut ) {
nEdge = inA.nIn ;
//se l'inizio di A è prima della fine, allora devo controllare che B sia compreso tra Out e In (esterno)
if ( CheckIfBefore( nEdge, inA.vpt[0], inA.vpt.back()) ) {
if ( CheckIfBefore( nEdge, inA.vpt.back(), inB.vpt[0]) || CheckIfBefore( nEdge, inB.vpt[0], inA.vpt[0]))
bFound = true ;
}
// se l'inizio di A è dopo la fine, allora devo controllare che B sia compreso tra In e Out ( interno)
else {
if ( CheckIfBefore( nEdge, inA.vpt.back(), inB.vpt[0]) && CheckIfBefore( nEdge, inB.vpt[0], inA.vpt[0]))
bFound = true ;
}
// alternativa
// percorrendo il lato in modo ciclico ( con condizioni al contorno che dalla fine mi riportano all'inizio)
// partendo da OutA devo incontrare InB e poi InA
//if ( CheckIfBefore( nEdge, inA.vpt.back(), nEdge, inB.vpt[0]) && CheckIfBefore( nEdge, inA.vpt.back(), nEdge, inB.vpt[0])) {
// bFound = true ;
//}
// mancano gli altri due casi da aggiungere alla ( condizione) || ( ) || ( )
}
else if ( inB.nIn == inA.nOut) {
PolyLine pl ;
pl.AddUPoint( 0, inA.vpt[0]) ;
pl.AddUPoint( 1, inA.vpt.back()) ;
if ( CheckIfAfter( pl, inB.vpt[0], i))
bFound = true ;
}
else if ( inB.nIn == inA.nIn ) {
//devo controllare il loop b sia prima dell'inizio di A
if ( CheckIfBefore(inA.nIn, inB.vpt[0], inA.nIn, inA.vpt[0]))
bFound = true ;
}
else
// devo controllare che inB sia prima di OutB
if ( inB.nOut == inB.nIn && CheckIfBefore( inB.nOut, inB.vpt[0], inB.vpt.back())) {
bFound = true ;
}
else if ( inB.nOut != inB.nIn)
bFound = true ;
}
if ( inB.nOut == i && ! bFound)
break ;
}
return bFound ;
}