EgtGeomKernel :
- funzioni MakeUniform e OnWhichEdge per Bezier spostate da converter e exch3dm a metodi della classe Bezier.
This commit is contained in:
+172
@@ -3176,4 +3176,176 @@ SurfBezier::GetSingleEdge3D( bool bLineOrBezier, int nEdge) const
|
||||
}
|
||||
}
|
||||
return pCrvCompo ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::MakeUniform( ISurfFlatRegion** sfr, DBLVECTOR& vU0, DBLVECTOR& vV0, double dScaleU, double dScaleV, bool& bRescaled, bool bRetry) const
|
||||
{
|
||||
// la superficie in input arriva già scalata
|
||||
bool bRescaledU = false ;
|
||||
bool bRescaledV = false ;
|
||||
int nSpanU = 1, nSpanV = 1 ;
|
||||
PtrOwner<ISurfFlatRegion> sfr_rescaled( CreateSurfFlatRegion()) ;
|
||||
for ( int nDir = 0 ; nDir <= 1 ; ++ nDir) {
|
||||
// vettore dei nodi
|
||||
DBLVECTOR vU ;
|
||||
int nExtraKnots = 0 ;
|
||||
|
||||
if ( nDir == 0) {
|
||||
if ( m_nDegU > 1) {
|
||||
nExtraKnots = m_nDegU - 1 ;
|
||||
}
|
||||
for ( int i = nExtraKnots ; i < int( vU0.size()) - nExtraKnots ; ++i ) {
|
||||
double dKnot = vU0[i] * SBZ_TREG_COEFF ;
|
||||
// lo aggiungo solo se è diverso dal precedente
|
||||
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
|
||||
vU.push_back( dKnot) ;
|
||||
}
|
||||
}
|
||||
else if ( nDir == 1 ) {
|
||||
if ( m_nDegV > 1) {
|
||||
nExtraKnots = m_nDegV - 1 ;
|
||||
}
|
||||
for ( int i = nExtraKnots ; i < int( vV0.size()) - nExtraKnots ; ++i ) {
|
||||
double dKnot = vV0[i] * SBZ_TREG_COEFF ;
|
||||
// lo aggiungo solo se è diverso dal precedente
|
||||
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL || dKnot < vU.back() - EPS_SMALL)
|
||||
vU.push_back( dKnot) ;
|
||||
}
|
||||
}
|
||||
|
||||
nDir == 0 ? nSpanU = (int)vU.size() - 1 : nSpanV = (int)vU.size() - 1 ;
|
||||
// controllo se il vettore dei nodi è uniforme
|
||||
int a = 0, b = 1 ;
|
||||
double d0 = abs( vU[b] - vU[a]), d1 = d0 ;
|
||||
// il vettore è uniforme quando la distanza tra nodi consecutivi è sempre zero o un valore costante
|
||||
while ( b < (int)vU.size() && ( ( d1 < d0 + EPS_SMALL && d1 > d0 - EPS_SMALL) || d1 < EPS_SMALL)) {
|
||||
a = b ;
|
||||
++b ;
|
||||
if ( b < (int)vU.size())
|
||||
d1 = abs( vU[b] - vU[a]) ;
|
||||
}
|
||||
if ( b != (int)vU.size()) {
|
||||
nDir == 0 ? bRescaledU = true : bRescaledV = true ;
|
||||
sfr_rescaled.Set( CreateSurfFlatRegion()) ;
|
||||
if ( IsNull( sfr_rescaled))
|
||||
return false ;
|
||||
for ( int p = 0 ; p < (int)vU.size() - 1 ; ++p) {
|
||||
PtrOwner<ISurfFlatRegion> pSfr_copy( (*sfr)->Clone()) ;
|
||||
if ( IsNull( pSfr_copy))
|
||||
return false ;
|
||||
double dLenStrip = abs( vU[p+1] - vU[p]) ;
|
||||
if ( dLenStrip < EPS_SMALL)
|
||||
continue ;
|
||||
// creo la maschera per tagliare la superficie originale e ottenere una striscia
|
||||
PtrOwner<ISurfFlatRegion> pSfrTrim( CreateSurfFlatRegion()) ;
|
||||
|
||||
// ricavo la maschera del trim, con cui poi farò l'intersezione con la sfr iniziale
|
||||
Vector3d vtTrim ;
|
||||
if ( nDir == 0) {
|
||||
pSfrTrim.Set( GetSurfFlatRegionRectangle( dLenStrip, dScaleV + 2)) ;
|
||||
vtTrim.Set( abs(vU[p] - vU.front()), - 1, 0) ;
|
||||
}
|
||||
else{
|
||||
pSfrTrim.Set( GetSurfFlatRegionRectangle( dScaleU + 2, dLenStrip)) ;
|
||||
vtTrim.Set( - 1, abs(vU[p] - vU.front()), 0) ;
|
||||
}
|
||||
pSfrTrim->Translate( vtTrim) ;
|
||||
|
||||
if ( ! pSfr_copy->Intersect( *pSfrTrim))
|
||||
return false ;
|
||||
|
||||
// aggiungo la nuova striscia solo se è valida
|
||||
if ( pSfr_copy->IsValid() ) {
|
||||
if ( nDir == 0)
|
||||
pSfr_copy->Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
||||
else
|
||||
pSfr_copy->Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
||||
|
||||
// prima di riunire la striscia al resto devo traslarla sul bordo destro della superificie che sto ricostruendo
|
||||
|
||||
Point3d pt ;
|
||||
nDir == 0 ? pt.Set( abs(vU[p] - vU.front()), 0, 0) : pt.Set( 0,abs(vU[p] - vU.front()), 0) ;
|
||||
if ( nDir == 0)
|
||||
pt.Scale( GLOB_FRM, SBZ_TREG_COEFF / dLenStrip, 1, 1) ;
|
||||
else
|
||||
pt.Scale( GLOB_FRM, 1, SBZ_TREG_COEFF / dLenStrip, 1) ;
|
||||
|
||||
Vector3d vtJoin ;
|
||||
if ( nDir == 0)
|
||||
vtJoin.Set( p * SBZ_TREG_COEFF - pt.x, 0, 0) ;
|
||||
else
|
||||
vtJoin.Set( 0, p * SBZ_TREG_COEFF - pt.y, 0) ;
|
||||
pSfr_copy->Translate( vtJoin) ;
|
||||
// se sto ritentando MakeUniform, allora faccio anche OFFSET e controOFFSET
|
||||
if ( bRetry)
|
||||
pSfr_copy->Offset( 10*EPS_SMALL,ICurve::OFF_FILLET) ; // OFFSET
|
||||
if ( sfr_rescaled->IsValid()) {
|
||||
if ( ! sfr_rescaled->Add( *pSfr_copy))
|
||||
return false ;
|
||||
}
|
||||
else
|
||||
sfr_rescaled.Set( pSfr_copy) ;
|
||||
}
|
||||
}
|
||||
if ( nDir == 0) {
|
||||
dScaleU = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
||||
if ( sfr_rescaled->IsValid()) {
|
||||
if ( bRetry)
|
||||
sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; //contro OFFSET
|
||||
*sfr = Release( sfr_rescaled) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
dScaleV = ((int)vU.size() - 1) * SBZ_TREG_COEFF ;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! IsNull( sfr_rescaled) && sfr_rescaled->IsValid()) {
|
||||
if ( bRetry)
|
||||
sfr_rescaled->Offset( -10*EPS_SMALL,ICurve::OFF_FILLET) ; // contro OFFSET
|
||||
*sfr = Release( sfr_rescaled) ;
|
||||
}
|
||||
|
||||
if ( ! bRescaledU && ! bRescaledV)
|
||||
( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
|
||||
else if ( bRescaledU && ! bRescaledV)
|
||||
( *sfr)->Scale( GLOB_FRM, 1, nSpanV / dScaleV * SBZ_TREG_COEFF, 1) ;
|
||||
else if ( ! bRescaledU && bRescaledV)
|
||||
( *sfr)->Scale( GLOB_FRM, nSpanU / dScaleU * SBZ_TREG_COEFF, 1, 1) ;
|
||||
|
||||
bRescaled = bRescaledU || bRescaledV ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::OnWhichEdge( double u0, double u1, double v0, double v1, int& nEdge, Point3d ptToAssign) const
|
||||
{
|
||||
Point3d ptTR( u1, v1) ;
|
||||
Point3d ptTl( u0, v1) ;
|
||||
Point3d ptBL( u0, v0) ;
|
||||
Point3d ptBr( u1, v0) ;
|
||||
|
||||
double dEps = 0.1 ;
|
||||
if ( AreSamePointEpsilon( ptToAssign, ptTR, dEps))
|
||||
nEdge = 7 ;
|
||||
else if ( AreSamePointEpsilon( ptToAssign, ptTl, dEps))
|
||||
nEdge = 4 ;
|
||||
else if ( AreSamePointEpsilon( ptToAssign, ptBL, dEps))
|
||||
nEdge = 5 ;
|
||||
else if ( AreSamePointEpsilon( ptToAssign, ptBr, dEps))
|
||||
nEdge = 6 ;
|
||||
else if ( ptToAssign.x > ptBL.x - dEps && ptToAssign.x < ptTR.x + dEps && abs( ptToAssign.y - ptTR.y) < dEps)
|
||||
nEdge = 0 ;
|
||||
else if ( ptToAssign.y > ptBL.y - dEps && ptToAssign.y < ptTR.y + dEps && abs( ptToAssign.x - ptBL.x) < dEps)
|
||||
nEdge = 1 ;
|
||||
else if ( ptToAssign.x > ptBL.x - dEps && ptToAssign.x < ptTR.x + dEps && abs( ptToAssign.y - ptBL.y) < dEps)
|
||||
nEdge = 2 ;
|
||||
else if ( ptToAssign.y > ptBL.y - dEps && ptToAssign.y < ptTR.y + dEps && abs( ptToAssign.x - ptTR.x) < dEps)
|
||||
nEdge = 3 ;
|
||||
else
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
@@ -138,6 +138,8 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
// funzione che restituisce gli edge della superficie o in forma di linea spezzata o in forma di curva di Bezier
|
||||
// se la superficie è trimmata restituisce i loop dello spazio parametrico in forma di linee spezzate
|
||||
bool GetLoops( ICRVCOMPOPOVECTOR& vCC, bool bLineOrBezier, int nEdge = -1) const override ;
|
||||
bool MakeUniform( ISurfFlatRegion** sfr, DBLVECTOR& vU, DBLVECTOR& vV, double dScaleU, double dScaleV, bool& bRescaled, bool bRetry) const override ;
|
||||
bool OnWhichEdge( double u0, double u1, double v0, double v1, int& nEdge, Point3d ptToAssign) const override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
|
||||
Reference in New Issue
Block a user