EgtGeomKernel :

- nuova versione regolarize.
This commit is contained in:
Daniele Bariletti
2026-04-17 13:34:17 +02:00
parent 02cb8a0d3c
commit 37e9a05347
2 changed files with 106 additions and 84 deletions
+2 -4
View File
@@ -1670,11 +1670,9 @@ ApproxCurveWithBezier( const ICurve* pCrv , double dTol, const Vector3d& vtStart
VCT3DVECTOR vPrevDer ;
VCT3DVECTOR vNextDer ;
ComputeAkimaTangents( false, vParam, vPnt, vPrevDer, vNextDer) ;
vPrevDer[0] = vtStart ;
vNextDer.back() = vtEnd ;
if ( ! AreSameVectorExact(vtStart, V_NULL)) {
vPrevDer[1] = vtStart ;
vNextDer.end()[-2] = vtEnd ;
vNextDer[0] = vtStart ;
vPrevDer.back() = vtEnd ;
}
int nOverSampling = ssize( vPntOverSampling) ;
+104 -80
View File
@@ -62,7 +62,7 @@
#define DEBUG_EDGES 0
#define DEBUG_SHAPE_STM 0
#define DEBUG_HOLES 0
#define DEBUG_SMOOTH_CURVATURE 0
#define DEBUG_SMOOTH_CURVATURE 1
#if DEBUG_BASIC_BORDERS || DEBUG_CHAIN_CURVES || DEBUG_ANG_APPROX || DEBUG_BEZIER_INTERP || \
DEBUG_FACE_SEARCH || DEBUG_FACE_SEARCH_TRIA_MODIF || DEBUG_BRK_POINTS || DEBUG_BRK_THICK || \
DEBUG_BRK || DEBUG_BORDERS_BY_NORMALS || DEBUG_SYNC_POINTS || DEBUG_SYNC_INTERPOLATION || \
@@ -83,8 +83,6 @@
using namespace std ;
bool RegolarizeBorders( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, double dTol) ;
// Vettori e Matrici di Curve Composite
typedef vector<CurveComposite> COMPOVECTOR ;
typedef vector<COMPOVECTOR> COMPOMATRIX ;
@@ -4293,6 +4291,10 @@ GetTrimmingRuledBezier( const CISURFPVECTOR& vSurf, const ICurve* pCrvEdge1,
}
}
//////debug
//RegolarizeBordersLocally(pCrvEdge1,pCrvEdge2, pSurfBz, 0.2) ;
//return nullptr ;
return ( IsNull( pSurfBz) || ! pSurfBz->IsValid() ? nullptr : Release( pSurfBz)) ;
}
@@ -4969,94 +4971,116 @@ typedef vector<PntInfo> PNTINFOVECTOR ;
//------------------------------------------------------------------------------
// Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim
// Le curve vengono modificate entro una data tolleranza, in modo che
static bool
RegolarizeBorders( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, double dTol)
bool
RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol)
{
#if DEBUG_SMOOTH_CURVATURE
VT.clear() ;
#endif
#if DEBUG_SMOOTH_CURVATURE
VT.push_back( pCrv1->Clone()) ;
#endif
// le due curve sono compo di bezier, e tutte le sottocurve sono dello stesso grado (3)
PNTINFOVECTOR vPntInfo ;
const ICurveComposite* pCC1 = GetCurveComposite( pCrv1) ;
for ( int i = 0 ; i < pCC1->GetCurveCount() ; ++i) {
const ICurveBezier* pSubCrv = GetCurveBezier( pCC1->GetCurve( i)) ;
int nDeg = pSubCrv->GetDegree() ;
for ( int j = i == 0 ? 0 : 1 ; j <= nDeg ; ++j) {
bool bOk = false ;
Point3d pt = pSubCrv->GetControlPoint( j, &bOk) ;
DistPointSurfBz dpsb( pt, *pSurfBz) ;
double dDist = 0 ; dpsb.GetDist( dDist) ;
Point3d ptMinDist ; dpsb.GetMinDistPoint( ptMinDist) ;
Vector3d vtN ; dpsb.GetNorm( vtN) ;
Vector3d vtPos = pt - ptMinDist ;
double dSide = vtPos * vtN ;
int nSide = 0 ;
if ( abs( dSide) > EPS_SMALL) {
if ( dSide > 0)
nSide = 1 ;
else
nSide = - 1 ;
}
vPntInfo.emplace_back( pt, i, j, dDist, vtN, nSide) ;
// prendo per buone le isocurve di inizio e fine tratto e devo identificare tra loro le isocurve che creano troppo twist e che sono da raddrizzare
int nUS1 = - 1, nUS2 = -1 ;
const Point3d& ptS1 = bpIsoStart.first ;
const Point3d& ptS2 = bpIsoEnd.first ;
int nDegU, nDegV, nSpanU, nSpanV ;
bool bRat, bTrimmed ;
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
if ( nDegU != 3)
return false ;
// individuo quali isocurve sono state indicate come inizio e fine
for ( int i = 0 ; i < nDegU * nSpanU + 1 ; ++i) {
bool bOk = false ;
Point3d pt = pSurfBz->GetControlPoint( i, 0, &bOk) ;
if ( nUS1 == -1 && AreSamePointExact(pt, ptS1))
nUS1 = i ;
else if ( AreSamePointExact( pt, ptS2)) {
nUS2 = i ;
break ;
}
}
// se trovo tre punti di fila che sono dallo stesso lato, opposto a quello degli altri punti attorno, allora cerco di spostarli lungo la
// normale alla superficie in modo da evitare cambi di concavità
int nCurrSide = vPntInfo[0].nSide ;
int c = 0 ;
CurveComposite CC ;
for ( int i = 0 ; i < ssize( vPntInfo) ; ++i) {
if ( nCurrSide == 0)
nCurrSide = vPntInfo[i].nSide ;
int nFirst = i ;
int nSecond = nFirst == ssize( vPntInfo) ? 0 : nFirst + 1 ;
int nThird = nSecond == ssize( vPntInfo) ? 0 : nSecond + 1 ;
int nFourth = nThird == ssize( vPntInfo) ? 0 : nThird + 1 ;
if ( i > 2 && vPntInfo[nFirst].nSide != nCurrSide && vPntInfo[nFirst].nSide != 0) {
// devo verificare anche che sia uguale ai due successivi
if ( ( vPntInfo[nFirst].nSide == vPntInfo[nSecond].nSide || vPntInfo[nSecond].nSide == 0) &&
( vPntInfo[nFirst].nSide == vPntInfo[nThird].nSide || vPntInfo[nThird].nSide == 0)) {
// se il successivo al terzetto è diverso ho un terzetto anomalo da aggiustare
// altrimenti ho un cambio naturale di concavità
if ( vPntInfo[nFirst].nSide != vPntInfo[nFourth].nSide) {
// modifico due curve
CurveComposite CCToApprox ;
int nCurrSub = nFirst / 3 ;
if ( nFirst % 3 == 0)
--nCurrSub ;
CCToApprox.AddCurve( pCC1->CopyParamRange( nCurrSub, nCurrSub + 2)) ;
Vector3d vtStart ; pCC1->GetStartDir( vtStart) ;
Vector3d vtEnd ; pCC1->GetEndDir( vtEnd) ;
PtrOwner<ICurve> pCrvApprox( ApproxCurveWithBezier( &CCToApprox, dTol, vtStart, vtEnd)) ;
if ( ! IsNull( pCrvApprox))
CC.AddCurve( Release( pCrvApprox)) ;
else
return false ;
// scorro le isocurve a partire dallo start e dell'end della zona indicata
// controllo il twist rispetto alla isocurva precedente
int nMid = ( nUS2 + nUS1) / 2 ;
Point3d ptPrevS = ptS1 ;
Point3d ptPrevE = bpIsoStart.second ;
Vector3d vtIsoPrev = ptPrevE - ptPrevS ; vtIsoPrev.Normalize() ;
Point3d ptBez ; Vector3d vtNPrev ;
pSurfBz->GetPointNrmD1D2( nUS1, 0.5, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez, vtNPrev) ;
int nPoints = ( nUS2 - nUS1) * nDegU + 1 ;
PNTVECTOR vPnt0 ; vPnt0.reserve( nPoints) ; vPnt0.push_back( ptPrevS) ;
PNTVECTOR vPnt1 ; vPnt1.reserve( nPoints) ;vPnt1.push_back( ptPrevE) ;
// salvo il secondo punto di controllo della patch
bool bOk = false ;
Point3d ptSecond1Curr = pSurfBz->GetControlPoint( nUS1 + 1, 0, &bOk) ;
vPnt0.push_back( ptSecond1Curr) ;
Point3d ptSecond2Curr = pSurfBz->GetControlPoint( nUS1 + 1, 1, &bOk) ;
vPnt1.push_back( ptSecond2Curr) ;
// scorro le isocurve di separazione tra patch
for ( int i = nUS1 + 3 ; i < nUS2 ; i +=3) { /////////////////// scorro fino in fondo??
// recupero precedente e successivo
Point3d ptThird1Curr = pSurfBz->GetControlPoint( i - 1, 0, &bOk) ;
Point3d ptThird2Curr = pSurfBz->GetControlPoint( i - 1, 1, &bOk) ;
Point3d ptSecond1Next = pSurfBz->GetControlPoint( i + 1, 0, &bOk) ;
Point3d ptSecond2Next = pSurfBz->GetControlPoint( i + 1, 1, &bOk) ;
// recupero corrente e verifico la torsione
Point3d ptCurrS = pSurfBz->GetControlPoint( i, 0, &bOk) ;
Point3d ptCurrE = pSurfBz->GetControlPoint( i, 1, &bOk) ;
Vector3d vtIsoCurr = ptCurrE - ptCurrS ;
double dDist = vtIsoCurr.Len() ;
vtIsoCurr.Normalize() ;
Vector3d vtDirPrev = vtIsoPrev ^ vtNPrev ;
Vector3d vtCurrInPlane = OrthoCompo( vtIsoCurr, vtDirPrev) ;
bool bDet = false ;
double dAng = 0 ; vtIsoPrev.GetRotation( vtCurrInPlane, vtDirPrev, dAng, bDet) ;
if ( abs( dAng) > 0) {
// se l'isocurva di separazione dalla patch successiva è torta rispetto alla precedente
// allora prendo il penultimo punto della curva corrente, l'ultimo e il secondo della prossima e li sposto lungo la normale della superficie
dDist *= dAng * DEGTORAD ;
ptThird1Curr += vtNPrev * dDist ;
ptCurrS += vtNPrev * dDist ;
ptSecond1Next += vtNPrev * dDist ;
ptThird2Curr -= vtNPrev * dDist ;
ptCurrE -= vtNPrev * dDist ;
ptSecond2Next -= vtNPrev * dDist ;
}
vPnt0.push_back( ptThird1Curr) ;
vPnt0.push_back( ptCurrS) ;
vPnt0.push_back( ptSecond1Next) ;
// scavalco i punti delle curve che ho appena modificato
i += 6 ;
}
c = 0 ;
nCurrSide = vPntInfo[i].nSide ;
}
else
++c ;
}
else {
++c ;
if ( i != 0 && i % 3 == 0)
CC.AddCurve( pCC1->GetCurve( i / 3 - 1)->Clone()) ;
}
vPnt1.push_back( ptThird2Curr) ;
vPnt1.push_back( ptCurrE) ;
vPnt1.push_back( ptSecond2Next) ;
vtIsoPrev = ptCurrE - ptCurrS ; vtIsoPrev.Normalize() ;
vtNPrev = ( ptSecond1Next - ptCurrS) ^ vtIsoPrev ; vtNPrev.Normalize() ;
}
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) {
PtrOwner<ICurveBezier> cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ;
cb1->SetControlPoint( 0, vPnt0[i]) ;
cb1->SetControlPoint( 1, vPnt0[i+1]) ;
cb1->SetControlPoint( 2, vPnt0[i+2]) ;
cb1->SetControlPoint( 3, vPnt0[i+3]) ;
pCC1->AddCurve( Release( cb1)) ;
PtrOwner<ICurveBezier> cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ;
cb2->SetControlPoint( 0, vPnt1[i]) ;
cb2->SetControlPoint( 1, vPnt1[i+1]) ;
cb2->SetControlPoint( 2, vPnt1[i+2]) ;
cb2->SetControlPoint( 3, vPnt1[i+3]) ;
pCC2->AddCurve( Release( cb2)) ;
}
//PtrOwner<ISurfBezier> pSB( CreateSurfBezier()) ;
//pSB->CreateSmoothRuledByTwoCurves( pCrv1, pCrv2, 10) ;
#if DEBUG_SMOOTH_CURVATURE
VT.push_back( CC.Clone()) ;
VT.push_back( pSurfBz->Clone()) ;
SaveGeoObj( VT, "D:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
VT.push_back( Release(pCC1)) ;
VT.push_back( Release(pCC2)) ;
SaveGeoObj( VT, "D:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
#endif
return true ;