EgtGeomKernel :

- correzioni e migliorie alla SurfExtend.
This commit is contained in:
Daniele Bariletti
2026-07-03 15:33:10 +02:00
parent 063322e528
commit fca95f609a
2 changed files with 56 additions and 52 deletions
+51 -47
View File
@@ -76,17 +76,30 @@ AddPointsOnCorners( PNT5AXVECTOR& vPt5ax)
double dProjPrev = ( vPt5ax[i].ptP - vPt5ax[j].ptP) * vPt5ax[j].vtDir1 ;
double dProjCurr = ( vPt5ax[j].ptP - vPt5ax[i].ptP) * vPt5ax[i].vtDir1 ;
bool bConvex = ( abs( dProjCurr) > abs( dProjPrev) ? dProjCurr < 0 : dProjPrev < 0) ;
int nPrev = i - 1 ;
if ( i < ssize( vPt5ax) - 2 && ! AreSameVectorExact(vPt5ax[i - 1].vtDir1, vPt5ax[i - 1].vtDir2)) {
int z = nPrev - 1 ;
// se vtDir1 e vtDir2 sono diverse allora sono su uno spigolo
double dProjPrev2 = ( vPt5ax[z].ptP - vPt5ax[nPrev].ptP) * vPt5ax[nPrev].vtDir2 ;
double dProjCurr2 = ( vPt5ax[i].ptP - vPt5ax[nPrev].ptP) * vPt5ax[nPrev].vtDir1 ;
// se uno dei due è convesso allora considero convesso l'angolo
bConvex = dProjPrev2 < EPS_SMALL || dProjCurr2 < EPS_SMALL ;
}
bool bValidIntersAfterJ = true ;
bool bValidIntersBeforeI = true ;
if ( i > 2) {
// verifico che l'intersezione sia tra i e j e non prima di j
int k = i - 2 ;
bValidIntersAfterJ = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[j].ptP - vPt5ax[k].ptP) > 0 ;
bool bBetweenIAndJ = ( ptInt - vPt5ax[j].ptP) * ( vPt5ax[i].ptP - vPt5ax[j].ptP) > 0 ;
bValidIntersAfterJ = bValidIntersAfterJ && bBetweenIAndJ ;
}
if ( i < ssize( vPt5ax) - 1) {
// verifico anche che l'intersezione non sia dopo i
int h = i + 1 ;
bValidIntersBeforeI = ( ptInt - vPt5ax[i].ptP) * ( vPt5ax[h].ptP - vPt5ax[i].ptP) < 0 ;
bool bBetweenIAndJ = ( ptInt - vPt5ax[i].ptP) * ( vPt5ax[i].ptP - vPt5ax[j].ptP) < 0 ;
bValidIntersBeforeI = bValidIntersBeforeI && bBetweenIAndJ ;
}
bool bValidInters = ( bValidIntersAfterJ && bValidIntersBeforeI) ;
// se convesso, metto due punti con direzione appena prima e appena dopo
@@ -487,10 +500,28 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf,
ptAlter = ptP + vtDirNext * 5 * EPS_SMALL ;
Point5ax Pt5axRec ;
if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) {
if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER) {
// aggiorno solo la vtDir1, la vtDir2 la mantengo con la normale successiva allo spigolo
if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER)
vPt5ax.back().vtDir1 = Pt5axRec.vtDir1 ;
vPt5ax.back().vtDir2 = Pt5axRec.vtDir2 ;
}
}
}
else if ( ssize( vPt5ax) > 1 && vPt5ax.back().vtDir1 * vPt5ax.end()[-2].vtDir1 < COS_ANG_MAX_CORNER) {
// se la normale corrente è sufficientemente diversa dalla precedente e i tratti non erano allineati
// controllo se il punto precedente erano su uno spigolo, ricalcolando in un punto appena oltre
Point3d ptAlter = ptPrev + ( ptP - ptPrev) * 5 * EPS_SMALL ;
Point5ax Pt5axRec ;
if ( ProjectPointOnSurf( ptAlter, vpSurf, dPar, Pt5axRec)) {
// aggiorno solo la vtDir1, la vtDir2 la mantengo con la normale successiva allo spigolo
if ( Pt5axRec.vtDir1 * Pt5ax.vtDir1 < COS_ANG_MAX_CORNER)
vPt5ax.end()[-2].vtDir1 = Pt5axRec.vtDir1 ;
}
}
if ( bLast && bClosed) {
// controllo se il punto finale è di spigolo
if ( vPt5ax.back().vtDir1 * vPt5ax.front().vtDir1 < COS_ANG_MAX_CORNER) {
vPt5ax.back().vtDir2 = vPt5ax.front().vtDir1 ;
vPt5ax.front().vtDir2 = vPt5ax.back().vtDir1 ;
}
}
vtNormPrev = vPt5ax.back().vtDir1 ;
@@ -1300,60 +1331,26 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
Pt5ax.ptP = ptP ;
Pt5ax.dPar = dPar ;
double dDecimal ;
int nCrv = int( modf( dPar, &dDecimal) == 0.0 ? dPar - 1 : dPar) ;
bool bJoint = modf( dPar, &dDecimal) == 0.0 ;
int nCrv = int( bJoint ? dPar - 1 : dPar) ;
if ( nCrv < 0)
nCrv = 0 ;
int nTria ; pCC->GetCurveTempProp( nCrv, nTria, 0) ;
Triangle3d trTria ; pSurf.GetTriangle( nTria, trTria) ;
Pt5ax.vtDir1 = trTria.GetN() ;
Pt5ax.vtDir2 = Pt5ax.vtDir1 ;
if ( bJoint) {
int nTria2 ; pCC->GetCurveTempProp( int( dPar), nTria2, 0) ;
Triangle3d trTria2 ; pSurf.GetTriangle( nTria2, trTria2) ;
Pt5ax.vtDir2 = trTria2.GetN() ;
}
else
Pt5ax.vtDir2 = Pt5ax.vtDir1 ;
Pt5ax.vtDirU = V_NULL ;
Pt5ax.vtDirV = V_NULL ;
Pt5ax.nFlag = P5AX_STD ;
vPt5ax.emplace_back( Pt5ax) ;
/*if ( ProjectPointOnSurf( ptP, vpSurf, dPar, Pt5ax))
vPt5ax.emplace_back( Pt5ax) ;*/
///////////////////////////////////////////// questa parte non dovrebbe servire più visto che so già qual'è il triangolo giusto per guardare la normale
//// controllo che la normale trovata sia in linea con la precedente, se i due tratti erano abbastanza allineati
//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] ;
// Vector3d vtDirCurr = pt5Curr.ptP - pt5Prev.ptP ; vtDirCurr.Normalize() ;
// Vector3d vtDirPrev = pt5Prev.ptP - pt5PrevPrev.ptP ; vtDirPrev.Normalize() ;
// double dProjDir = vtDirCurr * vtDirPrev ;
// if ( dProjDir > COS_ANG_MAX_CORNER) {
// double dProjNorm = vPt5ax.back().vtDir1 * 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 ;
// }
// }
//}
//vtNormPrev = vPt5ax.back().vtDir1 ;
// se richiesta la tangente anziché la normale allora modifico il vettore associato al punto
Vector3d vtDir ;
if ( ! bNormOrTang) {
@@ -1369,9 +1366,16 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
vtDir = Media( vtDirNext, vtDirPrev) ;
}
vtDirPrev = vtDirNext ;
bool bEdge = ! AreSameVectorExact( vPt5ax.back().vtDir1, vPt5ax.back().vtDir2) ;
Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ;
vPt5ax.back().vtDir1 = vtTang ;
vPt5ax.back().vtDir2 = vtTang ;
if ( bEdge) {
Vector3d vtTang2 = vtDirNext ^ vPt5ax.back().vtDir2 ;
vtTang2.Normalize() ;
vPt5ax.back().vtDir2 = vtTang2 ;
}
else
vPt5ax.back().vtDir2 = vtTang ;
}
// passo al successivo
ptPrev = ptP ;