EgtGeomKernel :

- miglioria dell'offset3d e del SurfExtend.
This commit is contained in:
Daniele Bariletti
2026-06-30 09:22:32 +02:00
parent c1a2912970
commit ef12fe8bd1
2 changed files with 134 additions and 43 deletions
+74 -13
View File
@@ -161,6 +161,45 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax)
}
}
int i = 0 ;
int j = ssize( vPt5ax) - 1 ;
bool bClosed = AreSamePointApprox( vPt5ax[i].ptP, vPt5ax[j].ptP) ;
// se la curva è chiusa controllo inizio e fine
if ( bClosed) {
// se normali tra corrente e precedente oltre limite
int k = i + 1 ;
int z = j - 1 ;
double dProjPrev = ( vPt5ax[j].ptP - vPt5ax[z].ptP) * vPt5ax[i].vtDir1 ;
double dProjCurr = ( vPt5ax[k].ptP - vPt5ax[i].ptP) * vPt5ax[j].vtDir1 ;
if ( vPt5ax[i].vtDir1 * vPt5ax[j].vtDir1 < COS_ANG_MAX_CORNER) {
bool bConvex = ( abs( dProjCurr) > abs( dProjPrev) ? dProjCurr < 0 : dProjPrev < 0) ;
if ( bConvex) {
vPt5ax[i].nFlag = P5AX_CVEX ;
vPt5ax[j].nFlag = P5AX_CVEX ;
}
else {
vPt5ax[i].nFlag = P5AX_CONC ;
vPt5ax[j].nFlag = P5AX_CONC ;
Vector3d vtDir1 = Media( vPt5ax[i].vtDir1, vPt5ax[j].vtDir1) ; vtDir1.Normalize() ;
Vector3d vtDir2 = Media( vPt5ax[i].vtDir2, vPt5ax[j].vtDir2) ; vtDir2.Normalize() ;
Vector3d vtDirU = Media( vPt5ax[i].vtDirU, vPt5ax[j].vtDirU) ; vtDirU.Normalize() ;
Vector3d vtDirV = Media( vPt5ax[i].vtDirV, vPt5ax[j].vtDirV) ; vtDirV.Normalize() ;
vPt5ax[i].vtDir1 = vtDir1 ;
vPt5ax[j].vtDir1 = vtDir1 ;
vPt5ax[i].vtDir2 = vtDir2 ;
vPt5ax[j].vtDir2 = vtDir2 ;
vPt5ax[i].vtDirU = vtDirU ;
vPt5ax[j].vtDirU = vtDirU ;
vPt5ax[i].vtDirV = vtDirV ;
vPt5ax[j].vtDirV = vtDirV ;
}
}
else if ( abs( dProjPrev) > abs( dProjCurr) ? dProjPrev > dSinSmallAngle : dProjCurr > dSinSmallAngle) {
vPt5ax[i].nFlag = P5AX_SMOOTH_CONC ;
vPt5ax[j].nFlag = P5AX_SMOOTH_CONC ;
}
}
// riscorro tutto il vettore per vedere se ho creato delle zone concave smooth frammentate (separate solo da un tratto non classificato concavo), che quindi uniformo
for ( int i = 1 ; i < ssize( vPt5ax) - 1 ; ++ i) {
if ( vPt5ax[i].nFlag != P5AX_SMOOTH_CONC && vPt5ax[i-1].nFlag == P5AX_SMOOTH_CONC && vPt5ax[i+1].nFlag == P5AX_SMOOTH_CONC)
@@ -404,18 +443,25 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
PL.GetLastLine( pt1, pt2) ;
vtDirPrev = pt2 - pt1 ;
}
Vector3d vtLast ; PL.GetLastULine( &dPar, &ptP, &dParNext, &ptPNext) ;
vtLast = ptPNext - ptP ; vtLast.Normalize() ;
bool bFound = PL.GetFirstULine( &dPar, &ptP, &dParNext, &ptPNext) ;
Vector3d vtFirst = ptPNext - ptP ; vtFirst.Normalize() ;
bool bClosed = PL.IsClosed() ;
bool bLast = false ;
Vector3d vtNormPrev = V_INVALID ;
Point3d ptPrev ;
bool bFirst = true ;
while ( bFound) {
// se trovo proiezione, la salvo
Point5ax Pt5ax ;
if ( ProjectPointOnSurf( ptP, vpSurf, dPar, Pt5ax))
vPt5ax.emplace_back( Pt5ax) ;
// controllo che la normale trovata sia in linea con la precedente, se i due tratti erano abbastanza allineati
if ( ! bClosed && ssize( vPt5ax) > 2) {
bool bRecalc = false ;
if ( bFirst)
bRecalc = true ;
if ( ssize( vPt5ax) > 2) {
Point5ax& pt5Curr = vPt5ax.back() ;
Point5ax& pt5Prev = vPt5ax.end()[-2] ;
Point5ax& pt5PrevPrev = vPt5ax.end()[-3] ;
@@ -424,9 +470,25 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
double dProjDir = vtDirCurr * vtDirPrev ;
if ( dProjDir > COS_ANG_MAX_CORNER) {
double dProjNorm = vPt5ax.back().vtDir1 * vtNormPrev ;
if ( dProjNorm < COS_ANG_MAX_CORNER) {
vPt5ax.back().vtDir1 = vtNormPrev ;
vPt5ax.back().vtDir2 = vtNormPrev ;
if ( dProjNorm < COS_ANG_MAX_CORNER)
bRecalc = true ;
}
}
Vector3d vtDirNext = ptPNext - ptP ; vtDirNext.Normalize() ;
// se sono arrivato ad uno spigolo tengo la normale appena prima dello spigolo
if ( bRecalc) {
Point3d ptAlter ;
if ( ! bFirst) {
Vector3d vtDirPrev = ptP - ptPrev ; vtDirPrev.Normalize() ;
ptAlter = ptP - vtDirPrev * 5 * EPS_SMALL ;
}
else
ptAlter = ptP + vtDirNext * 5 * EPS_SMALL ;
Point5ax Pt5axRec ;
if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) {
if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) {
vPt5ax.back().vtDir1 = Pt5axRec.vtDir1 ;
vPt5ax.back().vtDir2 = Pt5axRec.vtDir2 ;
}
}
}
@@ -435,32 +497,31 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
Vector3d vtDir ;
if ( ! bNormOrTang) {
Vector3d vtNorm = vPt5ax.back().vtDir1 ;
if ( ! bLast) {
vtDir = ptPNext - ptP ;
vtDir.Normalize() ;
}
else if ( bClosed)
vtDir = vtFirst ;
if ( bFirst)
vtDir = vtDirNext ;
else
vtDir = vtDirPrev ;
Vector3d vtDirTemp = vtDir ;
if ( vtDirPrev.IsValid()) {
// in caso sia stato superato l'angolo limite dò priorità alla direzione precedente
if ( vtDirPrev.IsValid() && (! bFirst || ( bFirst && bClosed))) {
double dProj = vtDir * vtDirPrev ;
if ( dProj > COS_ANG_MAX_CORNER)
vtDir = Media( vtDir, vtDirPrev) ;
}
vtDirPrev = vtDirTemp ;
vtDirPrev = vtDirNext ;
Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ;
vPt5ax.back().vtDir1 = vtTang ;
vPt5ax.back().vtDir2 = vtTang ;
}
// passo al successivo
ptPrev = ptP ;
bFound = PL.GetNextULine( &dPar, &ptP, &dParNext, &ptPNext) ;
// se sono arrivato alla fine aggiungo l'ultimo punto
if ( ! bFound && ! bLast) {
bLast = true ;
bFound = true ;
}
if ( bFirst)
bFirst = false ;
}
// se richiesto, inserimento punti intermedi in presenza di spigoli