From c1a291297075b566fc7aa63450464e5c22713e85 Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Thu, 25 Jun 2026 15:26:00 +0200 Subject: [PATCH] EgtGeomKernel : - correzioni e migliorie a offset3d e surfextend. --- OffsetCurve3d.cpp | 2 +- ProjectCurveSurf.cpp | 34 +++++++++++++++++++++++++++++----- StmFromCurves.cpp | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 65 insertions(+), 10 deletions(-) diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index 54f78da..ed7801e 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -231,7 +231,7 @@ OffsetCurve3d::Make( const PNT5AXVECTOR& vPnt5Ax, double dOffDist, int nType) if ( vtDirPrevOff.IsValid()) dProj = vtDirCurrOff * vtDirPrevOff ; // prima di inserirlo controllo che il tratto non torni indietro - if ( dProj > - 0.5 || vFlag[i] == OffsetCurve3d::AngType::ANG_SMOOTH_CONC) { + if ( vFlag[i] != ANG_STR || dProj > - 0.5) { // aggiungo tratto ICurveLine* pCL = CreateBasicCurveLine() ; pCL->Set( ptPrev, ptP) ; diff --git a/ProjectCurveSurf.cpp b/ProjectCurveSurf.cpp index f767a8c..7383155 100644 --- a/ProjectCurveSurf.cpp +++ b/ProjectCurveSurf.cpp @@ -405,27 +405,51 @@ ProjectCurveOnSurf( const ICurve& crCrv, const CISURFPVECTOR& vpSurf, vtDirPrev = pt2 - pt1 ; } bool bFound = PL.GetFirstULine( &dPar, &ptP, &dParNext, &ptPNext) ; - Vector3d vtFirst = ptPNext - ptP ; + Vector3d vtFirst = ptPNext - ptP ; vtFirst.Normalize() ; bool bClosed = PL.IsClosed() ; bool bLast = false ; + Vector3d vtNormPrev = V_INVALID ; 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) { + 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) { + vPt5ax.back().vtDir1 = vtNormPrev ; + vPt5ax.back().vtDir2 = vtNormPrev ; + } + } + } + vtNormPrev = vPt5ax.back().vtDir1 ; // se richiesta la tangente anziché la normale allora modifico il vettore associato al punto Vector3d vtDir ; if ( ! bNormOrTang) { Vector3d vtNorm = vPt5ax.back().vtDir1 ; - if ( ! bLast) + if ( ! bLast) { vtDir = ptPNext - ptP ; + vtDir.Normalize() ; + } else if ( bClosed) vtDir = vtFirst ; else vtDir = vtDirPrev ; - vtDirPrev = vtDir ; - if ( vtDirPrev.IsValid()) - vtDir = Media( vtDir, vtDirPrev) ; + Vector3d vtDirTemp = vtDir ; + if ( vtDirPrev.IsValid()) { + double dProj = vtDir * vtDirPrev ; + if ( dProj > COS_ANG_MAX_CORNER) + vtDir = Media( vtDir, vtDirPrev) ; + } + vtDirPrev = vtDirTemp ; Vector3d vtTang = vtDir ^ vtNorm ; vtTang.Normalize() ; vPt5ax.back().vtDir1 = vtTang ; vPt5ax.back().vtDir2 = vtTang ; diff --git a/StmFromCurves.cpp b/StmFromCurves.cpp index ccad9ef..d07e736 100644 --- a/StmFromCurves.cpp +++ b/StmFromCurves.cpp @@ -2168,8 +2168,39 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu PtrOwner pEdge ; if ( nSubCrv == - 1) pEdge.Set( pLoop) ; - else - pEdge.Set( pLoop->GetCurve( nSubCrv)->Clone()) ; + else { + // prendo tutti i lati adiacenti a quello selezionato e che non formano angoli superiori al limite + double dCosMin = 0.866 ; // 30 gradi + // scorro in avanti + int nNextCrv = nSubCrv ; + double dProj = 1 ; + while ( nNextCrv < pLoop->GetCurveCount() - 1) { + const ICurve* pCurr = pLoop->GetCurve( nNextCrv) ; + const ICurve* pNext = pLoop->GetCurve( nNextCrv + 1) ; + Vector3d vtCurr ; pCurr->GetEndDir( vtCurr) ; + Vector3d vtNext ; pNext->GetStartDir( vtNext) ; + dProj = vtCurr * vtNext ; + if ( dProj > dCosMin) + ++ nNextCrv ; + else + break ; + } + // scorro indietro + int nPrevCrv = nSubCrv ; + dProj = 1 ; + while ( nPrevCrv > 1) { + const ICurve* pCurr = pLoop->GetCurve( nPrevCrv) ; + const ICurve* pPrev = pLoop->GetCurve( nPrevCrv - 1) ; + Vector3d vtCurr ; pCurr->GetStartDir( vtCurr) ; + Vector3d vtPrev ; pPrev->GetEndDir( vtPrev) ; + dProj = vtCurr * vtPrev ; + if ( dProj > dCosMin) + -- nPrevCrv ; + else + break ; + } + pEdge.Set( pLoop->CopyParamRange( nPrevCrv, nNextCrv + 1)) ; + } double dMaxLen = 2.5 ; PNT5AXVECTOR vPnt5Ax ; @@ -2219,9 +2250,9 @@ GetSurfExtension( const ISurfTriMesh* pSrfTM, double dExtLen, int nLoop, int nSu vvGeo.back().push_back( pOffEdge->Clone()) ; vCol.push_back( AQUA) ; vvGeo.emplace_back() ; - for ( int i = 0 ; i < ssize( vOffDir) ; ++i) { + for ( int i = 0 ; i < ssize( vPnt5Ax) ; ++i) { IGeoVector3d* pGV = CreateGeoVector3d() ; - pGV->Set( vOffDir[i] * dExtLen, vPnt5Ax[i].ptP) ; + pGV->Set( vPnt5Ax[i].vtDir1 * dExtLen, vPnt5Ax[i].ptP) ; vvGeo.back().push_back( pGV) ; } vCol.push_back( LIME) ;