EgtGeomKernel :
- correzione bug nelle rigate con le Bezier.
This commit is contained in:
+75
-21
@@ -46,6 +46,8 @@ using namespace std ;
|
||||
//----------------------------------------------------------------------------
|
||||
GEOOBJ_REGISTER( SRF_BEZIER, NGE_S_BEZ, SurfBezier) ;
|
||||
|
||||
static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
SurfBezier::SurfBezier( void)
|
||||
: m_pSTM( nullptr), m_nStatus( TO_VERIFY), m_nDegU(), m_nDegV(), m_nSpanU(), m_nSpanV(), m_bRat( false),
|
||||
@@ -3846,7 +3848,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
for ( int i = 0 ; i < nDegU + 1 ; ++i ) {
|
||||
if( i != nDegU && !( i == 0 && k == 0))
|
||||
continue ;
|
||||
Point3d ptCtrl = pSubCrv0->GetControlPoint( i) ; // il caso razionale come è da gestire????? devo usare i punti omogenei per il calcolo delle distanze??
|
||||
Point3d ptCtrl = pSubCrv0->GetControlPoint( i) ;
|
||||
if ( bRat0)
|
||||
vdW0.push_back( pSubCrv0->GetControlWeight( i)) ;
|
||||
// aggiungo alla polyline solo gli estremi delle sottocurve ( senza ripetizioni)
|
||||
@@ -3883,27 +3885,31 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
bool bRat = bRat0 && bRat1 ;
|
||||
int nSecondRowInd = nDegU * nSpanU + 1 ;
|
||||
|
||||
// se sono chiuse devo controllare che gli start siano il più allineati possibile, se non lo sono cambio gli start
|
||||
ChangeStartForClosed( plU0, plU1, pCrvU0, pCrvU1) ;
|
||||
|
||||
// se sto usando la ISOPARM o la MINDIST semplice allora collego più span di una curva allo stesso punto
|
||||
// ( aggiungo delle span alla curva che localmente ne ha di meno, semplicemente riprendo più volte lo stesso punto)
|
||||
if ( nRuledType == RLT_B_MINDIST) {
|
||||
// creo le liste di punti per le isoparametriche in U
|
||||
PNTIVECTOR vPnt0Match, vPnt1Match ;
|
||||
bool bCommonPoint = false ;
|
||||
AssociatePolyLinesMinDistPoints( plU0, plU1, vPnt0Match, vPnt1Match, bCommonPoint) ;
|
||||
|
||||
AssociatePolyLinesMinDistPoints( plU0, plU1, vPnt0Match, vPnt1Match, bCommonPoint) ;
|
||||
// devo contare il numero di ripetizioni dei match nel mezzo delle curve, perché aumentano il numero di span della superficie!!
|
||||
int nRep0 = 0 ;
|
||||
int nIndMatch = 0 ;
|
||||
int nIndMatchNext = 0 ;
|
||||
int nRep1 = int( vPnt1Match.size() - 1) - vPnt0Match.back().second ;
|
||||
for ( int i = 0 ; i < int( vPnt0Match.size() - 1) ; ++i) {
|
||||
nIndMatch = vPnt0Match[i].second ;
|
||||
nIndMatchNext = vPnt0Match[i+1].second ;
|
||||
if ( nIndMatch != nIndMatchNext)
|
||||
nRep0 += nIndMatchNext - nIndMatch - 1;
|
||||
nRep1 += nIndMatchNext - nIndMatch - 1 ;
|
||||
if ( nIndMatch == nIndMatchNext)
|
||||
++nRep0 ;
|
||||
}
|
||||
int nRep1 = int( vPnt1Match.size() - 1) - vPnt0Match.back().second ;
|
||||
// reinizializzo la superficie con il nuovo numero di span in U
|
||||
nSpanU = nSpanU0 + nRep0 + nRep1 ;
|
||||
nSpanU = nSpanU0 + nRep1 ;
|
||||
if ( nSpanU < max(nSpanU0, nSpanU1))
|
||||
nSpanU = max(nSpanU0, nSpanU1) ;
|
||||
nSecondRowInd = nDegU * nSpanU + 1 ;
|
||||
@@ -3913,7 +3919,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
nCount0 = 0 ;
|
||||
nCount1 = 0 ;
|
||||
|
||||
// scorro gli estremi delle sottocurve della curva 1
|
||||
// scorro gli estremi delle sottocurve della curva U0
|
||||
for ( int i = 0 ; i < int( vPnt0Match.size() - 1) ; ++i) {
|
||||
nIndMatch = vPnt0Match[i].second ;
|
||||
nIndMatchNext = vPnt0Match[i+1].second ;
|
||||
@@ -3927,8 +3933,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
SetControlPoint( nCount0 * nDegU + j, pSubCrv0->GetControlPoint( j), pSubCrv0->GetControlWeight( j)) ;
|
||||
}
|
||||
++ nCount0 ;
|
||||
// ripeto l'ultimo punto aggiunto alla riga 2
|
||||
int nInd = nIndMatch - 1 ;
|
||||
// ripeto l'ultimo punto aggiunto alla riga U1 della superificie
|
||||
int nInd = nIndMatch > 0 ? nIndMatch - 1 : 0 ;
|
||||
const ICurveBezier* pSubCrv0 = GetCurveBezier( pCrvU1->GetCurve( nInd)) ;
|
||||
for ( int j = nCount1 == 0 ? 0 : 1 ; j < nLastPoint ; ++j) {
|
||||
int nPoint = nCount1 == 0 ? 0 : nDegU ;
|
||||
@@ -3938,7 +3944,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
SetControlPoint( nSecondRowInd + nCount1 * nDegU + j, pSubCrv0->GetControlPoint( nPoint), pSubCrv0->GetControlWeight( nPoint)) ;
|
||||
}
|
||||
++nCount1 ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// qui devo capire se aggiungere la nuova sottocurva prima o dopo la ripetizione dei punti
|
||||
// se il match del punto della U1 è uguale al punto a cui ero arrivato sulla U0 allora prima aggiungo la ripetizione di punti
|
||||
@@ -4146,7 +4152,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
}
|
||||
}
|
||||
// spezzo le curve di bezier dove è necessario aggiungere dei punti
|
||||
else if ( nRuledType == RLT_B_MINDIST_PLUS ) { // probabilmente se questo funziona bene non serve la modilità ISOPARM_SMOOTH
|
||||
else if ( nRuledType == RLT_B_MINDIST_PLUS ) {
|
||||
// scorro la prima curva e per ogni punto di fine sottocurva cerco il minDistPoint sull'altra curva
|
||||
// in quel punto la curva verrà spezzata, a meno che non si trovi una joint già sufficientemente vicina
|
||||
|
||||
@@ -4333,7 +4339,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
switch( vnAddedOrNextIsRep0[z]) {
|
||||
case 0 : if( vbRep1[nSplit])
|
||||
++ nRep1 ;
|
||||
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
vbRep1.insert( vbRep1.begin() + nSplit, vbRep1[nSplit]) ; break ;
|
||||
case 1 : vbRep1.insert( vbRep1.begin() + nSplit, true) ; break ;
|
||||
case 2 : if ( vbRep1[nSplit])
|
||||
--nRep1 ;
|
||||
@@ -4357,7 +4364,8 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
switch( vnAddedOrNextIsRep1[z]) {
|
||||
case 0 : if( vbRep0[nSplit])
|
||||
++ nRep0 ;
|
||||
vbRep0.insert( vbRep0.begin() + nSplit, vbRep0[nSplit]) ; break ; // di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
// di default aggiungerei false, ma se il successivo è già un Rep allora anche questo deve esserlo
|
||||
vbRep0.insert( vbRep0.begin() + nSplit, vbRep0[nSplit]) ; break ;
|
||||
case 1 : vbRep0.insert( vbRep0.begin() + nSplit, true) ; break ;
|
||||
case 2 : if( vbRep0[nSplit])
|
||||
-- nRep0 ;
|
||||
@@ -4388,21 +4396,23 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int
|
||||
-- nRep0 ;
|
||||
-- nRep1 ;
|
||||
}
|
||||
if ( ! bRep0)
|
||||
if ( ! bRep0 || nCrv1 == nSpanU1 - 1)
|
||||
++ nCrv1 ;
|
||||
if ( ! bRep1)
|
||||
if ( ! bRep1 || nCrv0 == nSpanU0 - 1)
|
||||
++ nCrv0 ;
|
||||
++nAddedSpan ;
|
||||
}
|
||||
// se non sono arrivato all'ultima curva su U0 o U1 vuol dire che ho creato delle ripetizioni che non ho contato prima
|
||||
if( nCrv1 < nSpanU1)
|
||||
if( nCrv1 < nSpanU1) {
|
||||
nRep1 += nSpanU1 - nCrv1 ;
|
||||
for ( int z = int( vbRep1.size() - 1) ; z >= nCrv1 ; --z)
|
||||
vbRep1[z] = true ;
|
||||
if( nCrv0 < nSpanU0)
|
||||
for ( int z = int( vbRep1.size() - 1) ; z >= nCrv1 ; --z)
|
||||
vbRep1[z] = true ;
|
||||
}
|
||||
if( nCrv0 < nSpanU0) {
|
||||
nRep0 += nSpanU0 - nCrv0 ;
|
||||
for ( int z = int( vbRep0.size() - 1) ; z >= nCrv0 ; --z)
|
||||
vbRep0[z] = true ;
|
||||
for ( int z = int( vbRep0.size() - 1) ; z >= nCrv0 ; --z)
|
||||
vbRep0[z] = true ;
|
||||
}
|
||||
|
||||
// trovo il numero di span che dovrà avere la superficie
|
||||
// ( numero di sottocurve che compongono la U0 + tutte le ripetizioni dei match di punti della curva U1 con i punti di U0)
|
||||
@@ -4557,3 +4567,47 @@ SurfBezier::ParametrizeByLen( const ICurveComposite* pCurve0, const ICurveCompos
|
||||
// }
|
||||
// return true ;
|
||||
//}
|
||||
|
||||
static bool ChangeStartForClosed( PolyLine& plU0, PolyLine& plU1, ICurveComposite* pCrvU0, ICurveComposite* pCrvU1) {
|
||||
// se sono chiuse devo controllare che gli start siano il più allineati possibile, se non lo sono cambio gli start
|
||||
if ( plU0.IsClosed() && plU1.IsClosed()) {
|
||||
vector<tuple<double,int,Point3d,int,Point3d>> vDistVert ;
|
||||
tuple<double,int,Point3d,int,Point3d> tMatch ;
|
||||
Point3d pt0 ;
|
||||
bool bOk0 = plU0.GetFirstPoint( pt0) ;
|
||||
int c0 = 0 ;
|
||||
double dMinDist = INFINITO ;
|
||||
while ( bOk0) {
|
||||
Point3d pt1 ;
|
||||
bool bOk1 = plU1.GetFirstPoint( pt1) ;
|
||||
int c1 = 0 ;
|
||||
while ( bOk1) {
|
||||
double dDist = Dist( pt0, pt1) ;
|
||||
if ( dDist < dMinDist) {
|
||||
tMatch = make_tuple( dDist, c0, pt0, c1, pt1) ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
++c1 ;
|
||||
bOk1 = plU1.GetNextPoint( pt1) ;
|
||||
}
|
||||
vDistVert.push_back( tMatch) ;
|
||||
dMinDist = INFINITO ;
|
||||
c1 = 0 ;
|
||||
++c0 ;
|
||||
bOk0 = plU0.GetNextPoint( pt0) ;
|
||||
}
|
||||
int nMin = 0 ;
|
||||
dMinDist = INFINITO ;
|
||||
for ( int i = 0 ; i < int( vDistVert.size()) ; ++i) {
|
||||
if( get<0>(vDistVert[i]) < dMinDist) {
|
||||
dMinDist = get<0>(vDistVert[i]) ;
|
||||
nMin = i ;
|
||||
}
|
||||
}
|
||||
ChangePolyLineStart(plU0, get<2>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
ChangePolyLineStart(plU1, get<4>(vDistVert[nMin]), EPS_SMALL) ;
|
||||
pCrvU0->ChangeStartPoint( double( get<1>(vDistVert[nMin]))) ;
|
||||
pCrvU1->ChangeStartPoint( double( get<3>(vDistVert[nMin]))) ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user