EgtGeomKernel :

- corretta e ultimata la funzione edges3D per Bezier. #11
This commit is contained in:
Daniele Bariletti
2024-03-21 12:57:59 +01:00
parent 718f5ce716
commit 535011072d
2 changed files with 81 additions and 148 deletions
+77 -147
View File
@@ -1447,7 +1447,7 @@ SurfBezier::GetCurveOnVApproxLen( double dU) const
bool
SurfBezier::UpdateEdgesFromTree( Tree& tr) const
{
POLYLINEMATRIX mPlEdges(4) ;
POLYLINEMATRIX mPlEdges ;
tr.GetEdges3D( mPlEdges) ;
for ( int i= 0 ; i < int( mPlEdges.size()); ++i) {
for ( int j = 0 ; j < int ( mPlEdges[i].size()) ; ++j) {
@@ -1464,7 +1464,9 @@ SurfBezier::UpdateEdgesFromTree( Tree& tr) const
++ nCount ;
}
if ( ! m_mCCEdge[i].back()->FromPolyLine(pl3D)) {
Point3d ptStart ; pl3D.GetFirstPoint( ptStart) ;
Point3d ptStart ;
if ( ! pl3D.GetFirstPoint( ptStart))
continue ;
m_mCCEdge[i].back()->FromPoint( ptStart) ;
}
}
@@ -1474,28 +1476,11 @@ SurfBezier::UpdateEdgesFromTree( Tree& tr) const
POLYLINEVECTOR vPl ;
tr.GetSplitLoops( vPl) ;
//// per split nel parametrico
// recupero i loop nel parametrico
for( int i = 0 ; i < int( vPl.size()); ++i) {
m_vCCLoop.emplace_back(CreateBasicCurveComposite()) ;
m_vCCLoop.back()->FromPolyLine(vPl[i]) ;
}
//// Loop 3D
//for( int i = 0 ; i < int( vPl.size()); ++i) {
// m_vCCLoop.emplace_back(CreateBasicCurveComposite()) ;
// PolyLine pl3D ;
// Point3d pt ; vPl[i].GetFirstPoint( pt) ;
// Point3d pt3D ; GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
// int nCount = 0 ;
// pl3D.AddUPoint( nCount, pt3D) ;
// ++ nCount ;
// while( vPl[i].GetNextPoint( pt)){
// GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
// pl3D.AddUPoint( nCount, pt3D) ;
// ++ nCount ;
// }
// m_vCCLoop.back()->FromPolyLine(pl3D) ;
//}
}
return true ;
@@ -2795,7 +2780,6 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
}
// se la superficie è trimmata devo recuperare i loop dello spazio parametrico
else {
//// con split nel parametrico////////////////////////////////////////////////////////
// devo ricostruire i bordi aperti in caso di superficie chiusa
// costruisco gli edge
ICurveLine* pCLU0( CreateCurveLine()) ;
@@ -2865,11 +2849,11 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
// devo cancellare la parte comune
Point3d ptStart2 = inters2.IciA[0].ptI ;
Point3d ptEnd2 = inters2.IciA[1].ptI ;
// come ptStart2 prendo quello con la x minore
if ( ptStart2.x > ptEnd2.x)
// come ptStart2 prendo quello con la x maggiore
if ( ptStart2.x < ptEnd2.x)
swap( ptStart2, ptEnd2) ;
if ( (( ptStart0.x - EPS_SMALL< ptStart2.x && ptStart2.x < ptEnd0.x + EPS_SMALL) && ( ptStart0.x - EPS_SMALL < ptEnd2.x && ptEnd2.x < ptEnd0.x + EPS_SMALL)) ||
(( ptStart2.x - EPS_SMALL < ptStart0.x && ptStart0.x < ptEnd2.x + EPS_SMALL) && ( ptStart2.x - EPS_SMALL < ptEnd0.x && ptEnd0.x < ptEnd2.x + EPS_SMALL))) {
if ( (( ptEnd0.x - EPS_SMALL< ptStart2.x && ptStart2.x < ptStart0.x + EPS_SMALL) && ( ptEnd0.x - EPS_SMALL < ptEnd2.x && ptEnd2.x < ptStart0.x + EPS_SMALL)) ||
(( ptEnd2.x - EPS_SMALL < ptStart0.x && ptStart0.x < ptStart2.x + EPS_SMALL) && ( ptEnd2.x - EPS_SMALL < ptEnd0.x && ptEnd0.x < ptStart2.x + EPS_SMALL))) {
PtrOwner<ICurveLine> pCL( CreateBasicCurveLine()) ;
pCL->Set( ptStart0, ptEnd0) ;
// devo scorrere su tutte le curve che sono state ottenute dallo split del loop originale
@@ -2877,6 +2861,11 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
int nIndex2 = mSplitLoop[vInters2.first][w] ;
IntersCurveCurve icc( *m_vCCLoop[nIndex2], *pCL) ;
IntCrvCrvInfo iccInfo ; icc.GetIntCrvCrvInfo( 0, iccInfo) ;
for ( int k = 0 ; k < icc.GetIntersCount() ; ++k) {
icc.GetIntCrvCrvInfo( k, iccInfo) ;
if ( iccInfo.bOverlap)
break ;
}
if ( ! iccInfo.bOverlap)
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
@@ -2887,12 +2876,18 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
else {
// se la curva era già aperta allora otterrò due curve separate
ICurveComposite* pCC2a( GetCurveComposite( m_vCCLoop[nIndex2]->Clone())) ;
pCC2a->TrimEndAtParam( iccInfo.IciA[1].dU) ;
bool bDoneA = pCC2a->TrimEndAtParam( iccInfo.IciA[0].dU) ;
ICurveComposite* pCC2b( GetCurveComposite( m_vCCLoop[nIndex2]->Clone())) ;
pCC2b->TrimStartAtParam( iccInfo.IciA[0].dU) ;
m_vCCLoop[nIndex2].Set( pCC2a) ;
m_vCCLoop.emplace_back( pCC2b) ;
mSplitLoop[vInters2.first].push_back( m_vCCLoop.size() - 1) ;
bool bDoneB = pCC2b->TrimStartAtParam( iccInfo.IciA[1].dU) ;
if ( bDoneA) {
m_vCCLoop[nIndex2].Set( pCC2a) ;
if ( bDoneB) {
m_vCCLoop.emplace_back( pCC2b) ;
mSplitLoop[vInters2.first].push_back( m_vCCLoop.size() - 1) ;
}
}
else if ( bDoneB)
m_vCCLoop[nIndex2].Set( pCC2b) ;
}
// per togliere la parte comune al loop corrente devo riportare i punti di intersezione sull'edge di partenza
@@ -2902,30 +2897,35 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
ptOverlapE.y = m_nSpanV * SBZ_TREG_COEFF ;
double dStart0, dEnd0 ;
// scorro tutte le curve in cui è stato splittato il loop iniziale
for ( int j = 0 ; int( mSplitLoop[vInters0.first].size()) ; ++j ) {
for ( int j = 0 ; j < int( mSplitLoop[vInters0.first].size()) ; ++j ) {
int nIndex0 = mSplitLoop[vInters0.first][j] ;
if ( ! m_vCCLoop[nIndex0]->GetParamAtPoint( ptOverlapS, dStart0) || m_vCCLoop[nIndex0]->GetParamAtPoint( ptOverlapE, dEnd0))
if ( ! m_vCCLoop[nIndex0]->GetParamAtPoint( ptOverlapS, dStart0) || ! m_vCCLoop[nIndex0]->GetParamAtPoint( ptOverlapE, dEnd0))
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
if ( m_vCCLoop[nIndex0]->IsClosed()) {
ICurveComposite* pCC0( GetCurveComposite( m_vCCLoop[nIndex0]->CopyParamRange( dEnd0, dStart0))) ;
ICurveComposite* pCC0( GetCurveComposite( m_vCCLoop[nIndex0]->CopyParamRange( dStart0, dEnd0))) ;
m_vCCLoop[nIndex0].Set( pCC0) ;
}
else {
// se la curva era già aperta allora otterrò due curve separate
ICurveComposite* pCC0a( GetCurveComposite( m_vCCLoop[nIndex0]->Clone())) ;
pCC0a->TrimEndAtParam( dStart0) ;
bool bDoneA = pCC0a->TrimEndAtParam( dEnd0) ;
ICurveComposite* pCC0b( GetCurveComposite( m_vCCLoop[nIndex0]->Clone())) ;
pCC0b->TrimStartAtParam( dEnd0) ;
m_vCCLoop[nIndex0].Set( pCC0a) ;
m_vCCLoop.emplace_back( pCC0b) ;
mSplitLoop[vInters0.first].push_back( m_vCCLoop.size() - 1) ;
bool bDoneB = pCC0b->TrimStartAtParam( dStart0) ;
if ( bDoneA) {
m_vCCLoop[nIndex0].Set( pCC0a) ;
if ( bDoneB) {
m_vCCLoop.emplace_back( pCC0b) ;
mSplitLoop[vInters0.first].push_back( m_vCCLoop.size() - 1) ;
}
}
else if ( bDoneB)
m_vCCLoop[nIndex0].Set( pCC0b) ;
}
break ;
}
break ;
}
break ;
}
}
}
@@ -2963,7 +2963,12 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
for ( int w = 0 ; w < int( mSplitLoop[vInters3.first].size()) ; ++w) {
int nIndex3 = mSplitLoop[vInters3.first][w] ;
IntersCurveCurve icc( *m_vCCLoop[nIndex3], *pCL) ;
IntCrvCrvInfo iccInfo ; icc.GetIntCrvCrvInfo( 0, iccInfo) ;
IntCrvCrvInfo iccInfo ;
for ( int k = 0 ; k < icc.GetIntersCount() ; ++k) {
icc.GetIntCrvCrvInfo( k, iccInfo) ;
if ( iccInfo.bOverlap)
break ;
}
if ( ! iccInfo.bOverlap)
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
@@ -2974,12 +2979,18 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
else {
// se la curva era già aperta allora otterrò due curve separate
ICurveComposite* pCC3a( GetCurveComposite( m_vCCLoop[nIndex3]->Clone())) ;
pCC3a->TrimEndAtParam( iccInfo.IciA[0].dU) ;
bool bDoneA = pCC3a->TrimEndAtParam( iccInfo.IciA[0].dU) ;
ICurveComposite* pCC3b( GetCurveComposite( m_vCCLoop[nIndex3]->Clone())) ;
pCC3b->TrimStartAtParam( iccInfo.IciA[1].dU) ;
m_vCCLoop[nIndex3].Set( pCC3a) ;
m_vCCLoop.emplace_back( pCC3b) ;
mSplitLoop[vInters3.first].push_back( m_vCCLoop.size() - 1) ;
bool bDoneB = pCC3b->TrimStartAtParam( iccInfo.IciA[1].dU) ;
if ( bDoneA) {
m_vCCLoop[nIndex3].Set( pCC3a) ;
if ( bDoneB) {
m_vCCLoop.emplace_back( pCC3b) ;
mSplitLoop[vInters3.first].push_back( m_vCCLoop.size() - 1) ;
}
}
else if ( bDoneB )
m_vCCLoop[nIndex3].Set( pCC3b) ;
}
// per togliere la parte comune al loop corrente devo riportare i punti di intersezione sull'edge di partenza
@@ -3001,18 +3012,23 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
else {
// se la curva era già aperta allora otterrò due curve separate
ICurveComposite* pCC1a( GetCurveComposite( m_vCCLoop[nIndex1]->Clone())) ;
pCC1a->TrimEndAtParam( dEnd1) ;
bool bDoneA = pCC1a->TrimEndAtParam( dEnd1) ;
ICurveComposite* pCC1b( GetCurveComposite( m_vCCLoop[nIndex1]->Clone())) ;
pCC1b->TrimStartAtParam( dStart1) ;
bool bDoneB = pCC1b->TrimStartAtParam( dStart1) ;
if ( bDoneA) {
m_vCCLoop[nIndex1].Set( pCC1a) ;
m_vCCLoop.emplace_back( pCC1b) ;
mSplitLoop[vInters1.first].push_back( m_vCCLoop.size() - 1) ;
if ( bDoneB) {
m_vCCLoop.emplace_back( pCC1b) ;
mSplitLoop[vInters1.first].push_back( m_vCCLoop.size() - 1) ;
}
}
else if ( bDoneB)
m_vCCLoop[nIndex1].Set( pCC1b) ;
}
break ;
}
break ;
}
break ;
}
}
}
@@ -3050,107 +3066,21 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
continue ;
PtrOwner<ICurveComposite> pCC( vpCCOpen[k]->Clone()) ;
vbAdded[k] = true ;
for ( int t = k ; t < int(vpCCOpen.size()); ++t ) {
if ( pCC->AddCurve( vpCCOpen[t]->Clone()))
vbAdded[t] = true ;
bool bAddedOne = true ;
while( bAddedOne) {
bAddedOne = false ;
for ( int t = k ; t < int(vpCCOpen.size()); ++t ) {
if ( vbAdded[t])
continue ;
if ( pCC->AddCurve( vpCCOpen[t]->Clone())) {
vbAdded[t] = true ;
bAddedOne = true ;
}
}
}
// aggiungo la curva agli edge 3d da restituire
vCC.emplace_back( Release( pCC)) ;
}
//// con split nel parametrico////////////////////////////////////////////////////////
//// se volessi restiturie tutto passo i loop del parametrico portati in 3D
//for ( int i = 0 ; i < int(m_vCCLoop2D.size()) ; ++i)
// vCC.emplace_back( m_vCCLoop2D[i]->Clone()) ;
//// con le inters in 3D///////////////////////////////////////////////////
//for ( int i = 0 ; i < int( m_vCCLoop.size()) ; ++i) {
// //// debug
// ////disegno le curve nel nuovo riferimento
// //vCC.emplace_back( Release(m_vCCLoop[i])) ;
// // continue ;
// ////debug
// // calcolo le autointersezioni a mano
// // le premesse sono che le compo è formata da curveLine e che i tratti eventualmente sovrapposti sono linee interamente coincidenti ( start-end e viceversa)
// double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ;
// Intervals inDomain ; inDomain.Set( dStart, dEnd) ;
// //DBLVECTOR vdU ;
// BOOLVECTOR vbErased( m_vCCLoop[i]->GetCurveCount()) ;
// fill( vbErased.begin(), vbErased.end(), false) ;
// // scorro tutte le curve singole della compo
// for ( int k = 0 ; k < int( m_vCCLoop[i]->GetCurveCount()); ++k) {
// const ICurve* pCrvA = m_vCCLoop[i]->GetCurve( k) ;
// if ( vbErased[k])
// continue ;
// Point3d ptStartA ; pCrvA->GetStartPoint( ptStartA) ;
// Point3d ptEndA ; pCrvA->GetEndPoint( ptEndA) ;
// // devo confrontarla con tutte le successive
// for ( int w = k + 1 ; w < int(m_vCCLoop[i]->GetCurveCount()); ++w ) {
// const ICurve* pCrvB = m_vCCLoop[i]->GetCurve( w) ;
// Point3d ptStartB ; pCrvB->GetStartPoint( ptStartB) ;
// Point3d ptEndB ; pCrvB->GetEndPoint( ptEndB) ;
// IntCrvCrvInfo iccInfo ;
// Vector3d vtDirSA ; pCrvA->GetStartDir( vtDirSA) ;
// Vector3d vtDirSB ; pCrvB->GetStartDir( vtDirSB) ;
// if ( AreSameOrOppositeVectorApprox( vtDirSA, Z_AX) || AreSameOrOppositeVectorApprox( vtDirSB, Z_AX)) {
// Frame3d frOptimal ;
// if ( (vtDirSA ^ vtDirSB).Len() > EPS_SMALL)
// frOptimal.Set( ORIG, vtDirSA ^ vtDirSB, vtDirSA) ;
// else
// frOptimal.Set( ORIG, X_AX, vtDirSA) ;
// PtrOwner<ICurve> pCrvNewA( pCrvA->Clone()) ;
// pCrvNewA->ToLoc( frOptimal) ;
// PtrOwner<ICurve> pCrvNewB( pCrvB->Clone()) ;
// pCrvNewB->ToLoc( frOptimal) ;
// IntersCurveCurve icc( *pCrvNewA, *pCrvNewB) ;
// icc.GetIntCrvCrvInfo( 0, iccInfo) ;
// }
// else {
// IntersCurveCurve icc( *pCrvA, *pCrvB) ;
// icc.GetIntCrvCrvInfo( 0, iccInfo) ;
// }
// // se sono sovrapposte allora devo eliminare la parte comune
// if ( iccInfo.bOverlap && ( AreSamePointApprox( ptStartA, ptEndB) || AreSamePointApprox( ptEndA, ptStartB) ||
// AreSamePointApprox( ptStartA, ptStartB) || AreSamePointApprox( ptEndA, ptEndB))) {
// inDomain.Subtract( k + iccInfo.IciA[0].dU, k + iccInfo.IciA[1].dU) ;
// vbErased[k] = true ;
// inDomain.Subtract( w + iccInfo.IciB[0].dU, w + iccInfo.IciB[1].dU) ;
// vbErased[w] = true ;
// break ;
// }
// }
// // quando raggiungo la prima intersezione potrei anche uscire dal for.. però devo salvarmi da qualche parte tra quali sottocurve
// // ci sono intersezioni sennò non posso accorgermene
// }
// ICRVCOMPOPOVECTOR vpCCOpen ;
// // con Intervals
// double dStart0, dEnd0 ; inDomain.GetFirst( dStart0, dEnd0) ;
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( dStart0, dEnd0))) ;
// while ( inDomain.GetNext( dStart0, dEnd0))
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( dStart0, dEnd0))) ;
//
// // creo la chain a mano con le compo
// BOOLVECTOR vbAdded( vpCCOpen.size()) ;
// fill( vbAdded.begin(), vbAdded.end(), false) ;
// for ( int k = 0 ; k < int( vpCCOpen.size()); ++k ) {
// if ( vbAdded[k])
// continue ;
// PtrOwner<ICurveComposite> pCC( vpCCOpen[k]->Clone()) ;
// vbAdded[k] = true ;
// for ( int t = k ; t < int(vpCCOpen.size()); ++t ) {
// if ( pCC->AddCurve( vpCCOpen[t]->Clone()))
// vbAdded[t] = true ;
// }
// // aggiungo la curva agli edge 3d da restituire
// vCC.emplace_back( Release( pCC)) ;
// }
//}
//// con le inters in 3D///////////////////////////////////////////////////
}
return true ;
}
+4 -1
View File
@@ -73,6 +73,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, bool bSplitPatches, const Point3d& ptMi
m_vPlApprox.clear() ;
m_vChunk.clear() ;
m_vPolygons.clear() ;
m_vPlLoop2D.clear() ;
m_pSrfBz = pSrfBz ;
m_bSplitPatches = bSplitPatches ;
@@ -3639,10 +3640,11 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
// scorro sui gruppi di polyline che rappresentano i poligoni delle celle lungo un lato
for ( int i = 0 ; i < int( mPL.size()) ; ++i) {
mPLEdges.back().emplace_back() ;
mPLEdges.emplace_back() ;
int nPtCount = 0 ;
// scorro sui poligoni delle celle di un lato
for ( int c = 0 ; c < int( mPL[i].size()) ; ++c) {
mPLEdges.back().emplace_back() ;
Point3d pt ; mPL[i][c].GetFirstPoint( pt) ;
Point3d pt3d ;
// a seconda del lato controllo di stare scorrendo il poligono prendendo solo i punti su quel lato
@@ -3713,6 +3715,7 @@ Tree::GetEdges3D( POLYLINEMATRIX& mPLEdges)
else {
// per ogni edge creo le compo che compongono l'edge dopo i trim ( possono essere più compo separate tra loro)
for ( int i = 0 ; i < 4 ; ++i) {
mPLEdges.emplace_back() ;
INTVECTOR vId ;
Point3d ptNear = m_mTree.at(-1).GetBottomLeft() ;
while( m_vCEdge2D[i].second.GetChainFromNear(ptNear, false, vId) ) {