EgtGeomKernel :

- ottimizzata la funzione per restituire gli edge 3D di una Bezier.
MANCA:
- debug
- debug su closedV
- debug closedU + ClosedV.
This commit is contained in:
Daniele Bariletti
2024-03-20 17:55:24 +01:00
parent 3f02119ef7
commit 718f5ce716
+363 -374
View File
@@ -1475,26 +1475,27 @@ SurfBezier::UpdateEdgesFromTree( Tree& tr) const
tr.GetSplitLoops( vPl) ;
//// per split nel parametrico
//for( int i = 0 ; i < int( vPl.size()); ++i) {
// m_vCCLoop2D.emplace_back(CreateBasicCurveComposite()) ;
// m_vCCLoop2D.back()->FromPolyLine(vPl[i]) ;
//}
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) ;
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 ;
@@ -2794,374 +2795,362 @@ SurfBezier::GetOpenEdges3D( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdg
}
// se la superficie è trimmata devo recuperare i loop dello spazio parametrico
else {
//per split nel parametrico
//
//// devo ricostruire i bordi aperti in caso di superficie chiusa
//// costruisco gli edge
//ICurveLine* pCLU0( CreateCurveLine()) ;
//ICurveLine* pCLU1( CreateCurveLine()) ;
//ICurveLine* pCLV0( CreateCurveLine()) ;
//ICurveLine* pCLV1( CreateCurveLine()) ;
//if ( m_bClosedU ) {
// pCLU0->Set( Point3d( 0, m_nSpanV * SBZ_TREG_COEFF, 0), ORIG) ;
// pCLU1->Set( Point3d( m_nSpanU * SBZ_TREG_COEFF, 0, 0), Point3d( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF, 0)) ;
//}
//if ( m_bClosedV ) {
// pCLV0->Set( ORIG, Point3d( m_nSpanU * SBZ_TREG_COEFF, 0, 0)) ;
// pCLV1->Set( Point3d( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF, 0), Point3d( 0, m_nSpanV * SBZ_TREG_COEFF, 0)) ;
//}
//ICRVLINEPOVECTOR vEdge ;
//// li metto con l'ordine degli edge
//vEdge.emplace_back( pCLV1) ;
//vEdge.emplace_back( pCLU0) ;
//vEdge.emplace_back( pCLV0) ;
//vEdge.emplace_back( pCLU1) ;
//// costruisco la mappa delle intersezioni, trovando tutte le intersezioni tra i trim e il loop esterno dello spazio parametrico
//// i 4 elementi fanno riferimento ai 4 edge. per ogni loop viene salvato il vettore delle intersezioni con tale edege
//vector<unordered_map<int,ICCIVECTOR>> vmInters(4) ;
//unordered_map<int,int> mAdded ; // salvo per ogni loop il gruppo di mLoopTo3D in cui è finito
//for ( int l = 0 ; l < int( m_vCCLoop2D.size()) ; ++ l) {
// // devo controllare se i loop si appoggiano a bordi chiusi
// // se ne ho più di uno che si appoggia allora devo vedere se trovo dei gruppi di loop che in realtà in 3d sono un edge unico, ma nel 2d risultano a cavallo dell'edge di chiusura
// PtrOwner<ICurveComposite> pLoop( m_vCCLoop2D[l]->Clone()) ;
// //int nInters = 0 ;
// for ( int j = 0 ; j < 4 ; ++j) {
// // il primo è un loop di trim, il secondo è un edge dello spazio parametrico
// IntersCurveCurve icc( *pLoop, *vEdge[j]) ;
// ICCIVECTOR vICC ;
// for ( int i = 0 ; i < int(icc.GetIntersCount()) ; ++i ) {
// IntCrvCrvInfo iccInfo ;
// icc.GetIntCrvCrvInfo( i, iccInfo) ;
// vICC.push_back( iccInfo) ;
// }
// if ( int(vICC.size()) > 0) {
// vmInters[j].insert(pair<int, ICCIVECTOR>(l, vICC)) ;
// //++ nInters ;
// }
// }
// //if ( nInters > 0)
// // li aggiungo tutti, tanto devo costruire anche quelli che non fanno intersezioni con gli edge
// mAdded.insert( pair<int,int>( l, -1)) ;
//}
//INTMATRIX mLoopTo3D ;
//// se ho delle intersezioni devo capire se ci sono loop che vanno abbinati e metterli nell'ordine giusto
//// per ogni intersezione controllo se ptStart o ptEnd corrispondono a quelli di qualche altro loop passando attraverso un edge chiuso
//if ( m_bClosedV) {
// // scorro i loop che fanno intersezioni con l'edge 0 ( V=1)
// for ( pair<int, ICCIVECTOR> vInters0 : vmInters[0]) {
// // se il loop corrente è già stato aggiunto lo salto
// if ( mAdded[vInters0.first] != -1)
// continue ;
// INTVECTOR vPairing ;
// // scorro le intersezioni del loop
// for ( IntCrvCrvInfo inters0 : vInters0.second) {
// Point3d ptStart = inters0.IciA[0].ptI ;
// Point3d ptEnd = inters0.IciA[1].ptI ;
// // voglio che il punto start sia quello con la x minore
// if ( ptStart.x > ptEnd.x)
// swap( ptStart, ptEnd) ;
// // cerco sui loop (non ancora aggiunti) che fanno intersezioni con l'edge opposto ( edge 2, V=0) se ho una corrispondenza
// // se trovo un abbinamento con un loop che fa già parte di un gruppo mi salvo il numero del gruppo
// int nGroup = -1 ;
// for ( pair<int, ICCIVECTOR> vInters2 : vmInters[2] ) {
// //if ( mAdded[vInters2.first] != -1)
// // continue ; ////// non è vero!!!!! dovrei semplicemente aggiungere il loop corrente al gruppo a cui appartiene questo loop///////////////////////////
//
//
// // scorro le intersezioni di questo loop
// for ( IntCrvCrvInfo inters2 : vInters2.second) {
// // se lo start e end del loop corrente sono compresi tra lo start e l'end di un loop che fa intesezione sull'edge opposto ( o viceversa) allora devo accoppairli
// // il loop che fa intersezione sull'edge opposto potrebbe essere il corrente stesso
// Point3d ptStart2 = inters2.IciA[0].ptI ;
// Point3d ptEnd2 = inters2.IciA[1].ptI ;
// // come ptStart2 prendo quello con la x minore
// if ( ptStart2.x > ptEnd.x)
// swap( ptStart2, ptEnd2) ;
// if ( ((ptStart.x - 1 < ptStart2.x && ptStart2.x < ptEnd.x + 1) && (ptStart.x - 1 < ptEnd2.x && ptEnd2.x < ptEnd.x + 1)) ||
// ((ptStart2.x - 1 < ptStart.x && ptStart.x < ptEnd2.x + 1) && (ptStart2.x - 1 < ptEnd.x && ptEnd.x < ptEnd2.x + 1))) {
// // aggiungo il loop alla lista degli accoppiati e salvo l'indice del gruppo a cui è stato aggiunto
// if ( mAdded[vInters2.first] == -1) {
// vPairing.push_back( vInters2.first) ;
// mAdded[vInters2.first] == int(mLoopTo3D.size()) ;
// }
// else if ( mAdded[vInters2.first] != -1){
// nGroup = mAdded[vInters2.first] ;
// }
// // qui dovrei anche decidere come trimmare le curve e quante curve 3D devono uscire da questo loop che fa intersezione con gli edge
// asasdasa
//// con split nel parametrico////////////////////////////////////////////////////////
// devo ricostruire i bordi aperti in caso di superficie chiusa
// costruisco gli edge
ICurveLine* pCLU0( CreateCurveLine()) ;
ICurveLine* pCLU1( CreateCurveLine()) ;
ICurveLine* pCLV0( CreateCurveLine()) ;
ICurveLine* pCLV1( CreateCurveLine()) ;
if ( m_bClosedU ) {
pCLU0->Set( Point3d( 0, m_nSpanV * SBZ_TREG_COEFF, 0), ORIG) ;
pCLU1->Set( Point3d( m_nSpanU * SBZ_TREG_COEFF, 0, 0), Point3d( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF, 0)) ;
}
if ( m_bClosedV ) {
pCLV0->Set( ORIG, Point3d( m_nSpanU * SBZ_TREG_COEFF, 0, 0)) ;
pCLV1->Set( Point3d( m_nSpanU * SBZ_TREG_COEFF, m_nSpanV * SBZ_TREG_COEFF, 0), Point3d( 0, m_nSpanV * SBZ_TREG_COEFF, 0)) ;
}
ICRVLINEPOVECTOR vEdge ;
// li metto con l'ordine degli edge
vEdge.emplace_back( pCLV1) ;
vEdge.emplace_back( pCLU0) ;
vEdge.emplace_back( pCLV0) ;
vEdge.emplace_back( pCLU1) ;
// costruisco la mappa delle intersezioni, trovando tutte le intersezioni tra i trim e il loop esterno dello spazio parametrico
// i 4 elementi fanno riferimento ai 4 edge. per ogni loop viene salvato il vettore delle intersezioni con tale edege
vector<unordered_map<int,ICCIVECTOR>> vmInters(4) ;
// comincio anche a creare il vettore di vettori associati ad ogni loop che fa almeno un'intersezione con un edge.
// in ogni vettore verranno salvati l'indice del loop all'interno del vettore dei loop e gli indici di tutti i loop che deriveranno da sue divisioni in più curve
unordered_map<int,INTVECTOR> mSplitLoop ;
int nOriginalLoops = int( m_vCCLoop.size()) ;
for ( int l = 0 ; l < nOriginalLoops ; ++ l) {
bool bInters = false ;
// devo controllare se i loop si appoggiano a bordi chiusi
// se ne ho più di uno che si appoggia allora devo vedere se trovo dei gruppi di loop che in realtà in 3d sono un edge unico, ma nel 2d risultano a cavallo dell'edge di chiusura
PtrOwner<ICurveComposite> pLoop( m_vCCLoop[l]->Clone()) ;
for ( int j = 0 ; j < 4 ; ++j) {
// il primo è un loop di trim, il secondo è un edge dello spazio parametrico
IntersCurveCurve icc( *pLoop, *vEdge[j]) ;
ICCIVECTOR vICC ;
for ( int i = 0 ; i < int(icc.GetIntersCount()) ; ++i ) {
IntCrvCrvInfo iccInfo ;
icc.GetIntCrvCrvInfo( i, iccInfo) ;
vICC.push_back( iccInfo) ;
}
if ( int(vICC.size()) > 0) {
vmInters[j].insert(pair<int, ICCIVECTOR>(l, vICC)) ;
bInters = true ;
}
}
if ( bInters)
mSplitLoop.insert( pair<int,INTVECTOR>( l, INTVECTOR({l}))) ;
}
// break ;
// }
// }
// }
// // aggiungo il loop corrente
// vPairing.push_back( vInters0.first) ;
// if ( nGroup == -1 ) {
// mAdded[vInters0.first] == int( mLoopTo3D.size()) ;
// if ( int( mLoopTo3D.size()) > 0 && int(mLoopTo3D.back().size()) > 0)
// mLoopTo3D.emplace_back(vPairing) ;
// else
// mLoopTo3D.back() = vPairing ;
// }
// else {
// mAdded[vInters0.first] = nGroup ;
// mLoopTo3D[nGroup].emplace_back( vPairing) ;
// }
// }
// }
// // qua devo ciclare di nuovo sui loop che fanno intersezione con l'edge 2 per verificare se li ho aggiunti tutti
//}
//if ( m_bClosedU ) {
// for ( int i = 0 ; i < int( vmInters[1].size()) ; ++i ) {
// Point3d ptStart, ptEnd ;
// }
//}
if ( m_bClosedV) {
// scorro i loop che fanno intersezioni con l'edge 0 ( V=1) e le riporto sull'edge opposto
for ( pair<int, ICCIVECTOR> vInters0 : vmInters[0]) {
// scorro le intersezioni del loop
for ( IntCrvCrvInfo inters0 : vInters0.second) {
Point3d ptStart0 = inters0.IciA[0].ptI ;
Point3d ptEnd0 = inters0.IciA[1].ptI ;
// porto i punti sull'edge opposto
ptStart0.y = 0 ;
ptEnd0.y = 0 ;
// scorro le intersezioni sull'edge opposto e quando trovo un loop che tra le sue intersezioni contiene uno dei punti che ho appena portato
// su qusto edge allora cancello la parte comune
for ( pair<int, ICCIVECTOR> vInters2 : vmInters[2] ) {
// scorro le intersezioni di questo loop
for ( IntCrvCrvInfo inters2 : vInters2.second) {
// se lo start o end del loop corrente è compreso tra lo start e l'end di un loop che fa intesezione sull'edge opposto allora
// 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)
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))) {
PtrOwner<ICurveLine> pCL( CreateBasicCurveLine()) ;
pCL->Set( ptStart0, ptEnd0) ;
// devo scorrere su tutte le curve che sono state ottenute dallo split del loop originale
for ( int w = 0 ; w < int( mSplitLoop[vInters2.first].size()) ; ++w) {
int nIndex2 = mSplitLoop[vInters2.first][w] ;
IntersCurveCurve icc( *m_vCCLoop[nIndex2], *pCL) ;
IntCrvCrvInfo iccInfo ; icc.GetIntCrvCrvInfo( 0, iccInfo) ;
if ( ! iccInfo.bOverlap)
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
if ( m_vCCLoop[nIndex2]->IsClosed()) {
ICurveComposite* pCC2( GetCurveComposite( m_vCCLoop[nIndex2]->CopyParamRange( iccInfo.IciA[1].dU, iccInfo.IciA[0].dU))) ;
m_vCCLoop[nIndex2].Set( pCC2) ;
}
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) ;
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) ;
}
// per togliere la parte comune al loop corrente devo riportare i punti di intersezione sull'edge di partenza
Point3d ptOverlapS = iccInfo.IciB[0].ptI ;
Point3d ptOverlapE = iccInfo.IciB[1].ptI ;
ptOverlapS.y = m_nSpanV * SBZ_TREG_COEFF ;
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 ) {
int nIndex0 = mSplitLoop[vInters0.first][j] ;
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))) ;
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) ;
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) ;
}
break ;
}
break ;
}
break ;
}
}
}
}
}
}
//// qui portei estrarre una funzione che proietta curve dal parametrico al 3D
//// scorro i gruppi di loop 2D formati da loop che partecipano alla formazione dello stesso loop nel 3D
//for( int i = 0 ; i < int( mLoopTo3D.size()); ++i) {
// vCC.emplace_back(CreateBasicCurveComposite()) ;
// PolyLine pl3D ;
// // scorro i loop 2D all'interno del gruppo
// for ( int j = 0 ; j < int( mLoopTo3D[i].size()) ; ++j) {
// // la composita è una spezzata composta da linee, quindi la ricostruisco come polyline in 3D
// Point3d pt ; m_vCCLoop2D[mLoopTo3D[i][j]]->GetStartPoint( 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 ;
// // scorro le curve singole della composita
// for ( int k = 0 ; k < m_vCCLoop2D[mLoopTo3D[i][j]]->GetCurveCount() ; ++k){
// // recupero l'end point della curva e lo porto in 3D
// m_vCCLoop2D[mLoopTo3D[i][j]]->GetCurve( k)->GetEndPoint( pt) ;
// GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
// pl3D.AddUPoint( nCount, pt3D) ;
// ++ nCount ;
// }
// }
// vCC.back()->FromPolyLine(pl3D) ;
//}
if ( m_bClosedU) {
// scorro i loop che fanno intersezioni con l'edge 1 ( U=0) e le riporto sull'edge opposto
for ( pair<int, ICCIVECTOR> vInters1 : vmInters[1]) {
// scorro le intersezioni del loop
for ( IntCrvCrvInfo inters1 : vInters1.second) {
Point3d ptStart1 = inters1.IciA[0].ptI ;
Point3d ptEnd1 = inters1.IciA[1].ptI ;
// porto i punti sull'edge opposto
ptStart1.x = m_nSpanU * SBZ_TREG_COEFF ;
ptEnd1.x = m_nSpanU * SBZ_TREG_COEFF ;
// scorro le intersezioni sull'edge opposto e quando trovo un loop che tra le sue intersezioni contiene uno dei punti che ho appena portato
// su qusto edge allora cancello la parte comune
for ( pair<int, ICCIVECTOR> vInters3 : vmInters[3] ) {
// scorro le intersezioni di questo loop
for ( IntCrvCrvInfo inters3 : vInters3.second) {
// se lo start o end del loop corrente è compreso tra lo start e l'end di un loop che fa intesezione sull'edge opposto allora
// devo cancellare la parte comune
Point3d ptStart3 = inters3.IciA[0].ptI ;
Point3d ptEnd3 = inters3.IciA[1].ptI ;
// come ptStart3 prendo quello con la y maggiore
if ( ptStart3.y < ptEnd3.y)
swap( ptStart3, ptEnd3) ;
if ( (( ptEnd1.y - EPS_SMALL< ptStart3.y && ptStart3.y < ptStart1.y + EPS_SMALL) && ( ptEnd1.y - EPS_SMALL < ptEnd3.y && ptEnd3.y < ptStart1.y + EPS_SMALL)) ||
(( ptEnd3.y - EPS_SMALL < ptStart1.y && ptStart1.y < ptStart3.y + EPS_SMALL) && ( ptEnd3.y - EPS_SMALL < ptEnd1.y && ptEnd1.y < ptStart3.y + EPS_SMALL))) {
PtrOwner<ICurveLine> pCL( CreateBasicCurveLine()) ;
pCL->Set( ptStart1, ptEnd1) ;
// devo scorrere su tutte le curve che sono state ottenute dallo split del loop originale
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) ;
if ( ! iccInfo.bOverlap)
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
if ( m_vCCLoop[nIndex3]->IsClosed()) {
ICurveComposite* pCC3( GetCurveComposite( m_vCCLoop[nIndex3]->CopyParamRange( iccInfo.IciA[1].dU, iccInfo.IciA[0].dU))) ;
m_vCCLoop[nIndex3].Set( pCC3) ;
}
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) ;
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) ;
}
// per togliere la parte comune al loop corrente devo riportare i punti di intersezione sull'edge di partenza
Point3d ptOverlapS = iccInfo.IciB[0].ptI ;
Point3d ptOverlapE = iccInfo.IciB[1].ptI ;
ptOverlapS.x = 0 ;
ptOverlapE.x = 0 ;
double dStart1, dEnd1 ;
// scorro tutte le curve in cui è stato splittato il loop iniziale
for ( int j = 0 ; int( mSplitLoop[vInters1.first].size()) ; ++j ) {
int nIndex1 = mSplitLoop[vInters1.first][j] ;
if ( ! m_vCCLoop[nIndex1]->GetParamAtPoint( ptOverlapS, dStart1) || ! m_vCCLoop[nIndex1]->GetParamAtPoint( ptOverlapE, dEnd1))
continue ;
// se parto da una curva chiusa semplicemente tolgo un pezzo
if ( m_vCCLoop[nIndex1]->IsClosed()) {
ICurveComposite* pCC1( GetCurveComposite( m_vCCLoop[nIndex1]->CopyParamRange( dStart1, dEnd1))) ;
m_vCCLoop[nIndex1].Set( pCC1) ;
}
else {
// se la curva era già aperta allora otterrò due curve separate
ICurveComposite* pCC1a( GetCurveComposite( m_vCCLoop[nIndex1]->Clone())) ;
pCC1a->TrimEndAtParam( dEnd1) ;
ICurveComposite* pCC1b( GetCurveComposite( m_vCCLoop[nIndex1]->Clone())) ;
pCC1b->TrimStartAtParam( dStart1) ;
m_vCCLoop[nIndex1].Set( pCC1a) ;
m_vCCLoop.emplace_back( pCC1b) ;
mSplitLoop[vInters1.first].push_back( m_vCCLoop.size() - 1) ;
}
break ;
}
break ;
}
break ;
}
}
}
}
}
}
// qui portei estrarre una funzione che proietta curve dal parametrico al 3D
// scorro i gruppi di loop 2D formati da loop che partecipano alla formazione dello stesso loop nel 3D
ICRVCOMPOPOVECTOR vpCCOpen ;
for( int i = 0 ; i < int( m_vCCLoop.size()); ++i) {
vpCCOpen.emplace_back(CreateBasicCurveComposite()) ;
PolyLine pl3D ;
// la composita è una spezzata composta da linee, quindi la ricostruisco come polyline in 3D
Point3d pt ; m_vCCLoop[i]->GetStartPoint( 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 ;
// scorro le curve singole della composita
for ( int k = 0 ; k < m_vCCLoop[i]->GetCurveCount() ; ++k){
// recupero l'end point della curva e lo porto in 3D
m_vCCLoop[i]->GetCurve( k)->GetEndPoint( pt) ;
GetPointD1D2( pt.x / SBZ_TREG_COEFF, pt.y / SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, pt3D) ;
pl3D.AddUPoint( nCount, pt3D) ;
++ nCount ;
}
vpCCOpen.back()->FromPolyLine(pl3D) ;
}
// 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 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
//// se il lato di chiusura è orientato come Z allora cambio sistema di riferimento per trovare le intersezioni XY
//bool bMod = false ;
//Frame3d frRot ;
//if ( m_bClosedU) {
// Point3d ptP00 ; GetPointD1D2( 0 , 0, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ;
// Point3d ptP01 ; GetPointD1D2( 0 , m_nSpanV * SBZ_TREG_COEFF, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP01) ;
// Point3d ptP0001 ; GetPointD1D2( 0 , m_nSpanV * SBZ_TREG_COEFF / 2, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP0001) ;
// Vector3d vtDir01 = ptP01 - ptP00 ;
// Vector3d vtDir0001 = ptP0001 - ptP00 ;
// if ( ! vtDir01.Normalize() || ! vtDir0001.Normalize())
// return false ;
// if ( AreSameVectorApprox( vtDir01, vtDir0001) && AreSameOrOppositeVectorApprox( vtDir01, Z_AX)) {
// // il lato di chiusura è parallelo all'asse Z, quindi prima di calcolare le autointersezioni devo cambiare sistema di riferimento
// bMod = true ;
// frRot.Set( ORIG, X_AX /*+ Y_AX*/) ;
// //for ( int j = 0 ; j < int(m_vCCLoop.size()) ; ++j )
// // m_vCCLoop[j]->ToLoc( frRot) ;
// // 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)) ;
// }
//}
//if ( m_bClosedV) {
// Point3d ptP00 ; GetPointD1D2( 0 , 0, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP00) ;
// Point3d ptP10 ; GetPointD1D2( m_nSpanU * SBZ_TREG_COEFF , 0, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP10) ;
// Point3d ptP0010 ; GetPointD1D2( m_nSpanU * SBZ_TREG_COEFF / 2, 0, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptP0010) ;
// Vector3d vtDir10 = ptP10 - ptP00 ;
// Vector3d vtDir0010 = ptP0010 - ptP00 ;
// if ( ! vtDir10.Normalize() || ! vtDir0010.Normalize())
// return false ;
// if ( AreSameVectorApprox( vtDir10, vtDir0010) && AreSameOrOppositeVectorApprox( vtDir10, Z_AX)) {
// // il lato di chiusura è parallelo all'asse Z, quindi prima di calcolare le autointersezioni devo cambiare sistema di riferimento
// bMod = true ;
// frRot.Set( ORIG, X_AX + Y_AX) ;
// //for ( int j = 0 ; j < int(m_vCCLoop.size()) ; ++j )
// // m_vCCLoop[j]->ToLoc( frRot) ;
// }
//}
// con le inters in 3D
for ( int i = 0 ; i < int( m_vCCLoop.size()) ; ++i) {
//if ( bMod)
// m_vCCLoop[i]->ToLoc( frRot) ;
//// debug
////disegno le curve nel nuovo riferimento
//vCC.emplace_back( Release(m_vCCLoop[i])) ;
// continue ;
////debug
// le autotintersezioni in 3D fanno casino!!!!!!!!!
//// calcolo le autointersezioni per capire quali tratti sono sul lato di chiusura
//SelfIntersCurve sic( *m_vCCLoop[i]) ;
//PNTVECTOR vPnt ;
//DBLVECTOR vdU ;
//IntCrvCrvInfo iccInfo0 ;
//for ( int j = 0 ; sic.GetIntCrvCrvInfo( j, iccInfo0) ; ++ j) {
// if ( ! iccInfo0.bOverlap) {
// Point3d ptA = iccInfo0.IciA[0].ptI ;
// Point3d ptB = iccInfo0.IciB[0].ptI ;
// if ( AreSamePointApprox( ptA, ptB)) {
// vPnt.push_back( ptA) ;
// vPnt.push_back( ptB) ;
// vdU.push_back(iccInfo0.IciA[0].dU) ;
// vdU.push_back(iccInfo0.IciB[0].dU) ;
// }
// }
// else {
// Point3d ptA0 = iccInfo0.IciA[0].ptI ;
// Point3d ptB0 = iccInfo0.IciB[0].ptI ;
// if ( AreSamePointApprox( ptA0, ptB0) ) {
// vPnt.push_back( ptA0) ;
// vPnt.push_back( ptB0) ;
// vdU.push_back(iccInfo0.IciA[0].dU) ;
// vdU.push_back(iccInfo0.IciB[0].dU) ;
// }
// Point3d ptA1 = iccInfo0.IciA[1].ptI ;
// Point3d ptB1 = iccInfo0.IciB[1].ptI ;
// if ( AreSamePointApprox( ptA1, ptB1) ) {
// vPnt.push_back( ptA1) ;
// vPnt.push_back( ptB1) ;
// vdU.push_back(iccInfo0.IciA[1].dU) ;
// vdU.push_back(iccInfo0.IciB[1].dU) ;
// }
// }
//}
//sort( vdU.begin(), vdU.end()) ;
//if ( bMod)
// m_vCCLoop[i]->ToGlob( frRot) ;
// 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) ;
//if ( ( AreSamePointApprox( ptStartA, ptEndB) && AreSamePointApprox( ptEndA, ptStartB)) ||
// ( AreSamePointApprox( ptStartA, ptStartB) && AreSamePointApprox( ptEndA, ptEndB))) {
// vbErased[k] = true ;
// //inDomain.Subtract(k, k+1) ;
// vbErased[w] = true ;
// //inDomain.Subtract(w, w+1) ;
// break ;
//}
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
}
//double dStart, dEnd ; m_vCCLoop[i]->GetDomain( dStart, dEnd) ;
//if ( vbErased[0])
// vdU.emplace_back( dStart) ;
//for ( int w = 1 ; w < int( vbErased.size()) ; ++w) {
// if ( (vbErased[w] && ! vbErased[w - 1]) || (! vbErased[w] && vbErased[w - 1]))
// vdU.emplace_back( w) ;
//}
//if ( vbErased.back())
// vdU.emplace_back( dEnd) ;
ICRVCOMPOPOVECTOR vpCCOpen ;
//double dStartA, dEndA ; inDomain.GetFirst( dStartA, dEndA) ;
//double dStartB, dEndB ; inDomain.GetLast( dStartB, dEndB) ;
//Point3d ptTest0 ; m_vCCLoop[i]->GetPointD1D2( dStartA + EPS_SMALL, ICurve::FROM_MINUS, ptTest0) ;
//Point3d ptTest1 ; m_vCCLoop[i]->GetPointD1D2( dEndB - EPS_SMALL, ICurve::FROM_MINUS, ptTest1) ;
////questo pezzo in teoria non serve perché gli intervalli segnalati sono quelli da cancellare( con dU)
//// con Intervals, quello che resta è quello da tenere
//Point3d ptTest0 ; m_vCCLoop[i]->GetPointD1D2( vdU[0] + EPS_SMALL, ICurve::FROM_MINUS, ptTest0) ;
//Point3d ptTest1 ; m_vCCLoop[i]->GetPointD1D2( vdU.back() - EPS_SMALL, ICurve::FROM_MINUS, ptTest1) ;
//// scopro quali sono gli intervalli da tenere e quali da cancellare
//int nFirst = 0 ;
//if ( AreSamePointApprox( ptTest0, ptTest1)) {
// nFirst = 1 ;
// if ( vdU[0] > EPS_SMALL )
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( 0, vdU[0]))) ;
//}
//// ricostruisco la curva finale prendendo tutto tranne i tratti sovrapposti
//
//// con vdU
//if ( vdU[0] > EPS_SMALL)
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( 0, vdU[0]))) ;
//for ( int j = 0 ; j < int(vdU.size() / 2) - 1 ; ++j)
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU[j*2 + 1], vdU[(j+ 1)*2]))) ;
//
//// se dopo l'ultimo dU ho ancora un pezzo di curva allora lo aggiungo
//if ( dEnd - vdU.back() > EPS_SMALL) {
// vpCCOpen.emplace_back( GetCurveComposite( m_vCCLoop[i]->CopyParamRange( vdU.end()[-2], vdU.back()))) ;
//}
// 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 ;
}