EgtGeomKernel :

- migliorie e correzioni all'importazione delle bezier.
- tolto limite alle bezier per rivoluzione.
This commit is contained in:
Daniele Bariletti
2026-03-03 17:09:30 +01:00
parent 8f06488b33
commit 5f28258d16
3 changed files with 75 additions and 47 deletions
+6 -12
View File
@@ -575,29 +575,23 @@ MakeUniform( ISurfFlatRegion*& pSfr, bool& bRescaled, const DBLVECTOR& vU0, cons
int nExtraKnots = 0 ;
// controllo in U
if ( nDir == 0) {
if ( nDegU > 1) {
nExtraKnots = nDegU - 1 ;
}
for ( int i = nExtraKnots ; i < int( vU0.size()) - nExtraKnots ; ++i ) {
for ( int i = nExtraKnots ; i < ssize( vU0) - 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)
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL)
vU.push_back( dKnot) ;
}
nSpanU = (int)vU.size() - 1 ;
nSpanU = ssize( vU) - 1 ;
}
// controllo in V
else if ( nDir == 1 ) {
if ( nDegV > 1) {
nExtraKnots = nDegV - 1 ;
}
for ( int i = nExtraKnots ; i < int( vV0.size()) - nExtraKnots ; ++i ) {
for ( int i = nExtraKnots ; i < ssize( vV0) - 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)
if ( i == nExtraKnots || dKnot > vU.back() + EPS_SMALL)
vU.push_back( dKnot) ;
}
nSpanV = (int)vU.size() - 1 ;
nSpanV = ssize( vU) - 1 ;
}
// controllo se il vettore dei nodi è uniforme
+66 -34
View File
@@ -49,7 +49,8 @@
#define SAVERULEDISO 0
#define SAVERULEDGUIDEDISO 0
#define SAVEMATCHCURVES 0
#if SAVEFAILEDTRIANGULATION || SAVEREBUILTISO || SAVERULEDISO || SAVERULEDGUIDEDISO || SAVEMATCHCURVES
#define SAVEFAILEDTREE 0
#if SAVEFAILEDTRIANGULATION || SAVEREBUILTISO || SAVERULEDISO || SAVERULEDGUIDEDISO || SAVEMATCHCURVES || SAVEFAILEDTREE
#include "/EgtDev/Include/EGkGeoObjSave.h"
#endif
@@ -877,7 +878,7 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc)
m_bTrimmed = true ;
m_pTrimReg = sbSrc.m_pTrimReg->Clone() ;
}
#ifndef SAVEFAILEDTRIANGULATION
#if ! SAVEFAILEDTRIANGULATION && ! SAVEFAILEDTREE
if ( sbSrc.GetAuxSurf() != nullptr)
m_pSTM = sbSrc.GetAuxSurf()->Clone() ;
#endif
@@ -1862,7 +1863,7 @@ SurfBezier::GetAuxSurfRefined( void) const
return m_pSTMRefined ;
}
#if SAVEFAILEDTRIANGULATION
#if SAVEFAILEDTRIANGULATION || SAVEFAILEDTREE
static int nErr = 0 ;
#endif
@@ -1901,6 +1902,10 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons
Tree.SetSurf( this, ptMin, ptMax) ;
if ( ! Tree.BuildTree( dTol, dSideMin)) {
LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface parametric space couldn't be split in cells") ;
#if SAVEFAILEDTREE
SaveGeoObj( Clone(),"D:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ;
++nErr ;
#endif
return nullptr ;
}
if ( ! Tree.GetPolygons( vvPL, vvPL3d, m_mCCEdge, m_vCCLoop, bUpdateEdges))
@@ -4226,46 +4231,73 @@ SurfBezier::CreateByScrewing( const ICurve* pCurve, const Point3d& ptAx, const V
if ( bOnlyRev && abs( dAngRotDeg) > ANG_FULL)
dAngRotDeg = _copysign( ANG_FULL, dAngRotDeg) ;
// se sto facendo una rivoluzione e la curva è piana, controllo che la curva non attraversi l'asse
if ( abs( dMove) < EPS_SMALL ) {
Plane3d plPlane ;
if ( pCurve->IsFlat( plPlane, false, 10 * EPS_SMALL)) {
BBox3d b3Crv ;
pCurve->GetLocalBBox( b3Crv) ;
double dAxLen = b3Crv.MaxDistFromPoint( ptAx) ;
CurveLine crvAx ;
crvAx.Set( ptAx - dAxLen * vtAx, ptAx + dAxLen * vtAx) ;
IntersCurveCurve icc( *pCurve, crvAx) ;
Point3d ptStart ; pCurve->GetStartPoint( ptStart) ;
Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ;
for ( int i = 0 ; i < icc.GetIntersCount() ; ++i) {
IntCrvCrvInfo iccInfo ;
icc.GetIntCrvCrvInfo( i, iccInfo) ;
// controllo che sia una vera intersezione in 3D, altrimenti passo alla successiva
if ( ! AreSamePointApprox( iccInfo.IciA[0].ptI, iccInfo.IciB[0].ptI))
continue ;
// se è il punto di inizio o di fine va bene e procedo
if ( AreSamePointApprox( ptStart, iccInfo.IciA[0].ptI) || AreSamePointApprox( ptEnd, iccInfo.IciA[0].ptI))
continue ;
// se la curva oltrepassa l'asse allora mi fermo, se tocca l'asse, ma resta dallo stesso lato, allora vado avanti
if ( iccInfo.IciA->nPrevTy != iccInfo.IciA->nNextTy)
return false ;
}
}
}
//// se sto facendo una rivoluzione e la curva è piana, controllo che la curva non attraversi l'asse
//CurveComposite ccNotTraversing ;
//if ( abs( dMove) < EPS_SMALL ) {
// Plane3d plPlane ;
// if ( pCurve->IsFlat( plPlane, false, 10 * EPS_SMALL)) {
// BBox3d b3Crv ;
// pCurve->GetLocalBBox( b3Crv) ;
// double dAxLen = b3Crv.MaxDistFromPoint( ptAx) ;
// CurveLine crvAx ;
// crvAx.Set( ptAx - dAxLen * vtAx, ptAx + dAxLen * vtAx) ;
// IntersCurveCurve icc( *pCurve, crvAx) ;
// Point3d ptStart ; pCurve->GetStartPoint( ptStart) ;
// Point3d ptEnd ; pCurve->GetEndPoint( ptEnd) ;
// bool bOk = true ;
// double dSplit = 0 ;
// for ( int i = 0 ; i < icc.GetIntersCount() ; ++i) {
// IntCrvCrvInfo iccInfo ;
// icc.GetIntCrvCrvInfo( i, iccInfo) ;
// // controllo che sia una vera intersezione in 3D, altrimenti passo alla successiva
// if ( ! AreSamePointApprox( iccInfo.IciA[0].ptI, iccInfo.IciB[0].ptI))
// continue ;
// // se è il punto di inizio o di fine va bene e procedo
// if ( AreSamePointApprox( ptStart, iccInfo.IciA[0].ptI) || AreSamePointApprox( ptEnd, iccInfo.IciA[0].ptI))
// continue ;
// // se la curva oltrepassa l'asse allora terrò solo la parte prima dell'asse, se tocca l'asse va bene
// if ( iccInfo.IciA->nPrevTy != iccInfo.IciA->nNextTy) {
// bOk = false ;
// dSplit = iccInfo.IciA[0].dU ;
// }
// }
// converto in bezier la curva iniziale
// // tengo solo la parte della curva fino all'intersezione con l'asse
// if ( ! bOk) {
// ccNotTraversing.AddCurve( pCurve->CopyParamRange( 0, dSplit)) ;
// }
// else
// ccNotTraversing.CopyFrom( pCurve) ;
// }
//}
//// converto in bezier la curva iniziale
// CurveComposite CrvU ;
//// se la curva è già una bezier singola la tengo, sennò la converto
// if ( ccNotTraversing.GetType() != CRV_BEZIER)
// CrvU.AddCurve( CurveToBezierCurve( &ccNotTraversing, 3, false)) ;
// else {
// if ( ! GetCurveBezier(&ccNotTraversing)->IsRational())
// CrvU.AddCurve( ccNotTraversing.Clone()) ;
// else {
// ICurveBezier* pCrvCopy = GetCurveBezier( ccNotTraversing.Clone()) ;
// if ( ! CrvU.AddCurve( EditBezierCurve( pCrvCopy, 3, false)))
// return false ;
// }
// }
// converto in bezier la curva iniziale
CurveComposite CrvU ;
// se la curva è già una bezier singola la tengo, sennò la converto
if ( pCurve->GetType() != CRV_BEZIER)
CrvU.AddCurve( CurveToBezierCurve( pCurve, 3, true)) ;
else {
if ( GetCurveBezier(pCurve)->IsRational())
if ( ! GetCurveBezier( pCurve)->IsRational())
CrvU.AddCurve( pCurve->Clone()) ;
else {
ICurveBezier* pCrvCopy = GetCurveBezier( pCurve->Clone()) ;
pCrvCopy->MakeRational() ;
CrvU.AddCurve( pCrvCopy) ;
if ( ! CrvU.AddCurve( EditBezierCurve( pCrvCopy, 3, true)))
return false ;
}
}
if ( ! CrvU.IsValid())
+3 -1
View File
@@ -177,7 +177,7 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const Point3d& ptMin, const Point3d& pt
int nLoop = 0 ;
// recupero la superficie di trim per avere accesso diretto ai loop e mantenendo le informazioni sui chunk
PtrOwner<SurfFlatRegion> pTrimReg( m_pSrfBz->GetTrimRegion()->Clone()) ;
double dLinTol = 0.01 ; // questo è riferito allo spazio parametrico
double dLinTol = 0.005 ; // questo è riferito allo spazio parametrico
double dAngTolDeg = 5 ;
for ( int i = 0 ; i < pTrimReg->GetChunkCount() ; ++ i) {
PtrOwner<SurfFlatRegion> pChunk( pTrimReg->CloneChunk( i)) ;
@@ -185,6 +185,8 @@ Tree::SetSurf( const SurfBezier* pSrfBz, const Point3d& ptMin, const Point3d& pt
// i chunk della falt region sono ancora flat region composte da 1 chunk
// rimuovo i difetti dei loop prima di salvarli
PtrOwner<ICurveComposite> pLoop( GetBasicCurveComposite( pChunk->GetLoop( 0, j))) ;
if ( IsNull( pLoop))
return false ;
pLoop->MergeCurves( dLinTol, dAngTolDeg) ;
pLoop->RemoveSmallDefects( dLinTol, dAngTolDeg, true) ;
pLoop->RemoveSmallParts( dLinTol, dAngTolDeg) ;