EgtGeomKernel :

- correzioni e migliorie all'offset3d e SurfExtend.
This commit is contained in:
Daniele Bariletti
2026-07-01 14:33:58 +02:00
parent 01342aebe5
commit 063322e528
3 changed files with 79 additions and 119 deletions
+67 -115
View File
@@ -83,35 +83,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
return false ;
}
// identifico le zone circostanti un angolo interno
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) {
// scorro indietro e avanti flaggando i tratti da controllare
int nPrev = i - 1 ;
if ( nPrev < 0)
nPrev = ssize( vPnt5Ax) - 1;
int nNext = i + 1 ;
if ( nNext >= ssize( vPnt5Ax))
nNext = 0 ;
double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) ;
double dDistAngConc = dOffDist * tan( dAng / 2) ;
int c = nPrev ;
while ( c > 0 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
--c ;
}
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
// scorro in avanti
c = nNext ;
while ( c < ssize( vPnt5Ax) && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
++c ;
}
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
i = c ;
}
}
PtrOwner<CurveComposite> pCrv( CreateBasicCurveComposite()) ;
if ( ! pCrv->FromPolyLine( PL))
return false ;
@@ -158,6 +129,47 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
bool bClosed = pCrv->IsClosed() ;
// identifico le zone circostanti un angolo interno
for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) {
if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CONC) {
// scorro indietro e avanti flaggando i tratti da controllare
int nPrev = i - 1 ;
if ( nPrev < 0)
nPrev = ssize( vPnt5Ax) - 1;
int nNext = i + 1 ;
if ( nNext >= ssize( vPnt5Ax))
nNext = 0 ;
double dAng = acos( vPnt5Ax[nPrev].vtDir1 * vPnt5Ax[nNext].vtDir1) * RADTODEG ;
double dDistAngConc = dOffDist * tan( ( dAng / 2) * DEGTORAD) ;
int c = nPrev ;
while ( Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
--c ;
if ( c < 0) {
if ( bClosed)
c = ssize( vPnt5Ax) - 1 ;
else
break ;
}
}
vFlag[c] = OffsetCurve3d::AngType::ANG_BEFORE_CONC ;
// scorro in avanti
c = nNext ;
while ( c < ssize( vPnt5Ax) - 1 && Dist( vPnt5Ax[i].ptP, vPnt5Ax[c].ptP) < dDistAngConc) {
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
++c ;
if ( c == ssize( vPnt5Ax) - 1) {
if ( bClosed)
c = 0 ;
else
break ;
}
}
vFlag[c] = OffsetCurve3d::AngType::ANG_AFTER_CONC ;
i = c ;
}
}
for ( int i = 1 ; i < ssize( vFlag) - 1 ; ++i) {
if ( vFlag[i-1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC &&
vFlag[i+1] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC &&
@@ -218,10 +230,10 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
vtTang.Normalize() ;
Vector3d vtCorr = vtOffDir ;
double dCorrK = 1 ;
if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) {
double dHalfAlfa = acos( vtTang * vtTangPrev) ;
dCorrK = 1 / sin( 90 - dHalfAlfa) ;
}
//if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CONC) {
// double dHalfAlfa = acos( vtTang * vtTangPrev) * RADTODEG ;
// dCorrK = 1 / sin( ( 90 - dHalfAlfa) * DEGTORAD) ;
//}
Point3d ptP ;
if ( pCrvCurr != nullptr)
@@ -250,30 +262,6 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
if ( ! vtAng.IsSmall() && vtAng.Normalize())
bPlanarConcCvex = abs( vtAng * vOffDir[nCurr]) < COS_ANG_MAX_PLANAR ;
//// se punto di angolo interno di fianco, elimino eventuali movimenti precedenti invertiti
//if ( vFlag[nCurr] == OffsetCurve3d::AngType::ANG_CVEX == 3) {
// local nLastId = EgtGetLastInGroup( nClPathId)
// while nLastId do
// local vtMlast = ptP - EgtEP( nLastId, GDB_ID.ROOT) ; vtMlast:normalize()
// if vtMlast * vtGpre < 0.5 then
// ptPpre = EgtSP( nLastId, GDB_ID.ROOT)
// EgtErase( nLastId)
// else
// break
// end
// nLastId = EgtGetLastInGroup( nClPathId)
// end
//}
//// se appena dopo angolo interno di fianco, verifico se da aggiungere
//bool bToAdd = true
//if ( nFlpre == 3 and abs( dSideAng) > GEO.EPS_ANG_SMALL) {
// local vtMove = ptP - ptPpre ; vtMove:normalize()
// if vtMove * vtTang < 0.5 then
// bToAdd = false
// end
//}
if ( ! bCheckingClosure) {
Vector3d vtDirCurrOff = ptP - ptPrev ; vtDirCurrOff.Normalize() ;
double dProj = 1 ;
@@ -376,21 +364,8 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType)
return true ;
// raccordi
// angoli interni
// angoli esterni
// auto intersezioni
//// sesto passo : se curva aperta, elimino i tratti che stanno nella circonferenza di offset dei punti estremi
//// ottavo passo : concateno i percorsi risultanti (senza cambiare verso)
//// nono passo : se con smusso o estensione, sostituisco i fillet con questi
//// ordino le curve in ordine decrescente di lunghezza
//if ( m_CrvLst.size() > 1) {
// for ( auto pCrv : m_CrvLst) {
@@ -467,18 +442,11 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
const double dLinTol = 10 * EPS_SMALL ;
for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) {
int nFlag = vOffsetCrvs[i].nFlag ;
if ( nFlag == OffsetCurve3d::AngType::ANG_SMOOTH_CONC || nFlag == OffsetCurve3d::AngType::ANG_BEFORE_CONC) {
// considero tutt le zone concave
if ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
// scorro i prossimi finchè trovo la fine della zona concava
INTVECTOR vLines ;
while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
vLines.push_back( i) ;
++i ;
if ( i < ssize( vOffsetCrvs))
nFlag = vOffsetCrvs[i].nFlag ;
else
nFlag = OffsetCurve3d::AngType::ANG_STR ;
}
// controllo se devo considerare anche tratti prima dello start
INTVECTOR vLines ;
if ( i == 0) {
INTVECTOR vLinesAdd ;
int c = ssize( vOffsetCrvs) - 1 ;
@@ -489,9 +457,24 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
if ( c > 0)
nFlag = vOffsetCrvs[c].nFlag ;
}
vLinesAdd.insert( vLinesAdd.end(), vLines.begin(), vLines.end()) ;
swap( vLinesAdd, vLines) ;
// inserisco il vettore al contrario, in modo che sia in ordine crescente
vLines.insert( vLines.end(), vLinesAdd.rbegin(), vLinesAdd.rend()) ;
}
bool bDone = false ;
nFlag = vOffsetCrvs[i].nFlag ;
while ( nFlag >= OffsetCurve3d::AngType::ANG_CONC) {
vLines.push_back( i) ;
++i ;
if ( i < ssize( vOffsetCrvs))
nFlag = vOffsetCrvs[i].nFlag ;
else {
bDone = true ;
break ;
}
}
// se sto ricominciando, esco dal for ( il tratto finale è già stato considerato insieme al tratto iniziale)
if ( bDone)
break ;
CYLVECT vCyl ;
// creo un cilindro della dimensione del raggio
for ( int j = 0 ; j < ssize( vLines) ; ++j) {
@@ -501,7 +484,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
Point3d ptStart, ptEnd ;
pSubCrv->GetStartPoint( ptStart) ;
pSubCrv->GetEndPoint( ptEnd) ;
////////// cilindri con asse sul parent
// cilindri con asse sul parent
Vector3d vtHeight = ptEnd - ptStart ;
double dHeight = vtHeight.Len() ;
vtHeight.Normalize() ;
@@ -512,23 +495,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
vGeo.push_back( pSurfTm) ;
vCol.push_back( LGRAY) ;
#endif
// //// cilindri con la direz offset
// Point3d ptOffEnd ; vOffsetCrvs[vLines[j]].pCrv->GetEndPoint( ptOffEnd) ;
// Vector3d vtOff = ptOffEnd - ptEnd ; vtOff.Normalize() ;
// Vector3d vtHeight = ptEnd - ptStart ;
// double dHeight = vtHeight.Len() ;
// Vector3d vtNewAxis = OrthoCompo( vtHeight, vtOff) ;
// vtHeight.Normalize() ;
// vtNewAxis.Normalize() ;
// Point3d ptStartCyl = ptEnd -vtNewAxis * dHeight ;
// vCyl.emplace_back( ptStartCyl, vtNewAxis, dHeight, dRad, dLinTol) ;
//#if SAVECYL
// CurveArc ca ; ca.Set( vCyl.back().frCyl.Orig(), vCyl.back().frCyl.VersZ(), dRad) ;
// ISurfTriMesh* pSurfTm = GetSurfTriMeshByExtrusion( &ca, vCyl.back().frCyl.VersZ() * dHeight, false, 2 * EPS_SMALL) ;
// vGeo.push_back( pSurfTm) ;
// vCol.push_back( LGRAY) ;
//#endif
}
// controllo l'end di ogni linea per verificare se sta nel cilindro definito da uno degli altri tratti
@@ -558,16 +524,7 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
bErasedSomePart = true ;
if ( ! bStartInsideCyl)
bCheckStart = true ;
//// se avevo un'interruzione nella zona da modificare, la colmo
//if ( ! vInters.empty() && vInters.back().first != vLines[j-1]) {
// // aggiungo tutti i precedenti che mancano
// int z = vInters.back().second ;
// for ( int h = vInters.back().first + 1 ; h < vLines[j] ; ++h) {
// vInters.emplace_back( h, z) ;
// vEditInfo.pop_back() ;
// ++z ;
// }
//}
if ( vEditZones.empty() || vEditZones.back().back().first != vLines[j-1])
vEditZones.emplace_back() ;
vEditZones.back().emplace_back( vLines[j], j) ;
@@ -584,11 +541,6 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v
}
}
if ( bErasedSomePart) {
//// controllo che effettivamente tutti i tratti cancellati siano consecutivi
//for ( int j = 1 ; j < ssize( vInters) ; ++j) {
// if ( vInters[j].first != vInters[j-1].first + 1)
// return false ;
//}
// calcolo le intersezioni effettive del primo e ultimo tratto cancellati con i cilindri che li hanno cancellati
for ( int z = 0 ; z < ssize( vEditZones) ; ++z) {
INTINTVECTOR& vInters = vEditZones[z] ;
+11 -3
View File
@@ -13,6 +13,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include <cmath>
#include "SurfTriMesh.h"
#include "SurfBezier.h"
#include "GeoConst.h"
@@ -1292,17 +1293,24 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
Vector3d vtNormPrev = V_INVALID ;
Point3d ptPrev ;
bool bFirst = true ;
const ICurveComposite* pCC = GetCurveComposite( &crCrv) ;
while ( bFound) {
// se trovo proiezione, la salvo
Point5ax Pt5ax ;
Pt5ax.ptP = ptP ;
Pt5ax.dPar = dPar ;
int nTria = int( crCrv.GetTempParam( dPar)) ;
double dDecimal ;
int nCrv = int( modf( dPar, &dDecimal) == 0.0 ? 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 ;
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) ;*/
@@ -1356,9 +1364,9 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf,
vtDir = vtDirPrev ;
// in caso sia stato superato l'angolo limite dò priorità alla direzione precedente
if ( vtDirPrev.IsValid() && (! bFirst || ( bFirst && bClosed))) {
double dProj = vtDir * vtDirPrev ;
double dProj = vtDirNext * vtDirPrev ;
if ( dProj > COS_ANG_MAX_CORNER)
vtDir = Media( vtDir, vtDirPrev) ;
vtDir = Media( vtDirNext, vtDirPrev) ;
}
vtDirPrev = vtDirNext ;
Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ;
+1 -1
View File
@@ -2171,7 +2171,7 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu
PL.GetFirstUPoint( &dPar, &pt) ;
for ( int i = 0 ; i < pLoop->GetCurveCount() ; ++i) {
PL.GetNextUPoint( &dPar, &pt) ;
pLoop->SetTempProp( i, dPar) ;
pLoop->SetCurveTempProp( i, int( dPar)) ;
}
// ricavo il tratto di bordo da estendere, con le tangenti della superficie