From dc46c92c954dd1ca800a276eccb82c04aebdd84d Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Tue, 7 Jul 2026 09:13:18 +0200 Subject: [PATCH] EgtGeomKernel : - aggiunta funzione per gestione spigoli in SurfExtend - correzioni a SurfExtend. --- OffsetCurve3d.cpp | 139 +++++++++++++++++++++++++++++++++---------- ProjectCurveSurf.cpp | 16 +++-- 2 files changed, 119 insertions(+), 36 deletions(-) diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index f8a5a05..21e0ad4 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -20,6 +20,7 @@ #include "/EgtDev/Include/EGkPoint3d.h" #include "/EgtDev/Include/EGkPolyLine.h" #include "/EgtDev/Include/EGkOffsetCurve3d.h" +#include "/EgtDev/Include/EGkIntersLinePlane.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include @@ -304,7 +305,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) return false ; if ( nType == OFFTYPE::PLANECUT) { - if ( ! CalcAdjustConcavePartsPlaneCut( pCrv, vPnt5Ax, vOffsetCrvs, vFlag, dOffDist, vEditInfo)) + if ( ! CalcAdjustConcavePartsPlaneCut( pCrv, vPnt5Ax, vOffsetCrvs, dOffDist, vEditInfo)) return false ; } @@ -651,34 +652,108 @@ CalcAdjustConcavePartsInPath( const ICurveComposite* pCrv, const OFFSETSEGVEC& v return true ; } -////---------------------------------------------------------------------------- -//bool -//CalcAdjustConcavePartsPlaneCut( const ICurveComposite* pCrv, const PNT5AXVECTOR& vPnt5Ax, const OFFSETSEGVEC& vOffsetCrvs, const INTVECTOR& vFlag, double dRad, EDITCRVINFOVEC& vEditInfo) -//{ -// // calcolo come tagliare il percorso negli angoli misti concavo/convesso -// // il taglio al percorso lo faccio usando il piano definito dalla direzione di offset -// // se una delle due direzioni è perpendicolare al piano formato dai due tratti, la cui joint è il punto corrente, allora non faccio nulla -// for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { -// if ( vFlag[i] == OffsetCurve3d::AngType::ANG_CVEX) { -// // trovo i due piani e taglio i tratti prima e dopo lo spigolo -// Point3d pt ; vOffsetCrvs[i].pCrv->GetStartPoint( pt) ; -// int nParent = vOffsetCrvs[i].nParent ; -// Vector3d vtDirCurr ; -// Vector3d vtDirPrev ; -// Vector3d vtN1 = vPnt5Ax[nParent].vtDir1 ^ vtDirCurr ; -// Vector3d vtN2 = vPnt5Ax[nParent].vtDir1 ^ vtDirPrev ; -// Plane3d plNext ; plNext.Set( pt, vtN1) ; -// Plane3d plPrev ; plPrev.Set( pt, vtN2) ; -// while( ) { -// // interseco con il piano precedente prendendo i tratti successivi -// } -// // salvo la modifica nel vettore edit -// while( ) { -// // interseco con il piano successivo prendendo i tratti precedenti -// } -// // salvo la modifica nel vettore edit -// } -// } -// -// return true ; -//} \ No newline at end of file +//---------------------------------------------------------------------------- +bool +CalcAdjustConcavePartsPlaneCut( const ICurveComposite* pCrv, const PNT5AXVECTOR& vPnt5Ax, const OFFSETSEGVEC& vOffsetCrvs, + double dRad, EDITCRVINFOVEC& vEditInfo) +{ + // calcolo come tagliare il percorso negli angoli misti concavo/convesso + // il taglio al percorso lo faccio usando il piano definito dalla direzione di offset + // se una delle due direzioni è perpendicolare al piano formato dai due tratti, la cui joint è il punto corrente, allora non faccio nulla + for ( int i = 0 ; i < ssize( vOffsetCrvs) ; ++i) { + if ( vOffsetCrvs[i].nFlag == OffsetCurve3d::AngType::ANG_CVEX) { + // se ho 2 tratti convex di fila, ho un convex non planar e se ho anche un angolo importante tra i due lati, devo correggere + // se ho 4 tratti convex di fila, ho un convex planar e non devo fare nulla + int c = 1 ; + while ( i + c < ssize( vOffsetCrvs) && vOffsetCrvs[i + c].nFlag == OffsetCurve3d::AngType::ANG_CVEX) + ++c ; + if ( c == 4) { + i += 3 ; + continue ; + } + + // trovo i due piani e taglio i tratti prima e dopo lo spigolo + int nParent = vOffsetCrvs[i].nParent ; // sottocurva di pCrv che ha generato il tratto di offset + Point3d pt ; pCrv->GetCurve( nParent)->GetEndPoint( pt) ; + Vector3d vtDirNext ; pCrv->GetCurve( nParent + 1)-> GetStartDir( vtDirNext) ; + Vector3d vtDirPrev ; pCrv->GetCurve( nParent)-> GetEndDir( vtDirPrev) ; + // punti che rappresentano la pCrv ( quindi pCrv->GetCurveCount() == ssize( vPnt5Ax) - 1) + Vector3d vtNNext = vPnt5Ax[nParent+1].vtDir2 ^ vtDirNext ; + Vector3d vtNPrev = vPnt5Ax[nParent+1].vtDir1 ^ vtDirPrev ; + Plane3d plNext ; plNext.Set( pt, vtNNext) ; + Plane3d plPrev ; plPrev.Set( pt, vtNPrev) ; + Point3d ptPrev ; + Point3d ptNext ; + // interseco con il piano precedente prendendo i tratti successivi + bool bFound = false ; + // parto a confrontare i segmenti successivi a quelli identificati come concavi + c = i + 2 ; + while ( ! bFound && c > 0) { + Point3d ptInt ; + Point3d ptStart, ptEnd ; + vOffsetCrvs[c].pCrv->GetStartPoint( ptStart) ; + vOffsetCrvs[c].pCrv->GetEndPoint( ptEnd) ; + IntersLinePlane( ptStart, ptEnd, plPrev, ptInt, false) ; + Vector3d vtDir ; vOffsetCrvs[c].pCrv->GetStartDir( vtDir) ; + double dLen ; vOffsetCrvs[c].pCrv->GetLength( dLen) ; + double dU = ( ptInt - ptStart).Len() / dLen ; + if ( vtDir * ( ptInt - ptStart) < 0) + dU *= -1 ; + if ( dU < 1) { + ptNext = ptInt ; + bFound = true ; + } + else + ++c ; + } + // salvo la modifica nel vettore edit + int nNext = c ; + vEditInfo[c].nFlag = EditCrvInfo::EditFlag::EDIT ; + vEditInfo[c].ptStart = ptNext ; + + // interseco con il piano successivo prendendo i tratti precedenti + bFound = false ; + c = i - 1 ; + while ( ! bFound && c < ssize( vOffsetCrvs)) { + Point3d ptInt ; + Point3d ptStart, ptEnd ; + vOffsetCrvs[c].pCrv->GetStartPoint( ptStart) ; + vOffsetCrvs[c].pCrv->GetEndPoint( ptEnd) ; + IntersLinePlane( ptStart, ptEnd, plNext, ptInt, false) ; + Vector3d vtDir ; vOffsetCrvs[c].pCrv->GetStartDir( vtDir) ; + double dLen ; vOffsetCrvs[c].pCrv->GetLength( dLen) ; + double dU = ( ptInt - ptStart).Len() / dLen ; + if ( vtDir * ( ptInt - ptStart) < 0) + dU *= -1 ; + if ( dU > 0) { + ptPrev = ptInt ; + bFound = true ; + } + else + --c ; + } + // salvo la modifica nel vettore edit + int nPrev = c ; + vEditInfo[c].nFlag = EditCrvInfo::EditFlag::EDIT ; + vEditInfo[c].ptEnd = ptPrev ; + + // tengo solo il punto più esterno + double dLen1 = Dist( ptPrev, pt) ; + double dLen2 = Dist( ptNext, pt) ; + if ( dLen1 > dLen2) + vEditInfo[nNext].ptStart = ptPrev ; + else + vEditInfo[nPrev].ptStart = ptNext ; + + // setto come da cancellare tutti i tratti nel mezzo + c = nPrev + 1 ; + while ( c < nNext) { + vEditInfo[c].nFlag = EditCrvInfo::EditFlag::DEL ; + ++c ; + } + i = nNext ; + } + } + + return true ; +} \ No newline at end of file diff --git a/ProjectCurveSurf.cpp b/ProjectCurveSurf.cpp index 8d4a416..b39727d 100644 --- a/ProjectCurveSurf.cpp +++ b/ProjectCurveSurf.cpp @@ -1325,6 +1325,8 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, Point3d ptPrev ; bool bFirst = true ; const ICurveComposite* pCC = GetCurveComposite( &crCrv) ; + int nTria = -1 ; + Triangle3dEx trTria ; while ( bFound) { // se trovo proiezione, la salvo Point5ax Pt5ax ; @@ -1335,13 +1337,19 @@ GetCurveOnSurfInfo( const ICurve& crCrv, const ISurfTriMesh& pSurf, 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() ; + int nTriaCurr ; pCC->GetCurveTempProp( nCrv, nTriaCurr, 0) ; + if ( nTriaCurr != nTria) + pSurf.GetTriangle( nTriaCurr, trTria) ; + if ( ! CalcNormal( ptP, trTria, Pt5ax.vtDir1)) + Pt5ax.vtDir1 = trTria.GetN() ; + nTria = nTriaCurr ; if ( bJoint) { int nTria2 ; pCC->GetCurveTempProp( int( dPar), nTria2, 0) ; Triangle3d trTria2 ; pSurf.GetTriangle( nTria2, trTria2) ; - Pt5ax.vtDir2 = trTria2.GetN() ; + if ( ! CalcNormal( ptP, trTria2, Pt5ax.vtDir2)) + Pt5ax.vtDir2 = trTria2.GetN() ; + nTria = nTria2 ; + trTria = trTria2 ; } else Pt5ax.vtDir2 = Pt5ax.vtDir1 ;