From 07aee030061a359050dff06699f675faec86719f Mon Sep 17 00:00:00 2001 From: Daniele Bariletti Date: Wed, 26 Aug 2026 09:21:43 +0200 Subject: [PATCH] EgtGeomKernel 3.1h4 : - resa pubblica la funzione per cambiare lo start di una polyline - resa pubblica la MakeByFist della Triangulate - aggiunta di due parametri per l'interpolazione delle linee di sync per il trimming. --- OffsetCurve3d.cpp | 1 + PolyLine.cpp | 12 +++--- SurfBezier.cpp | 97 +++++++++++++++++++++++++++++++++++++---------- Triangulate.cpp | 24 ++++++++---- Triangulate.h | 1 + Trimming.cpp | 31 ++++++++++----- 6 files changed, 124 insertions(+), 42 deletions(-) diff --git a/OffsetCurve3d.cpp b/OffsetCurve3d.cpp index b8d96b7..69c34ff 100644 --- a/OffsetCurve3d.cpp +++ b/OffsetCurve3d.cpp @@ -33,6 +33,7 @@ using namespace std ; #if SAVECRVORIG || SAVEOFFDIR || SAVECYL || SAVEOFFSET #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkGeoVector3d.h" + vector> vvGeo ; vector vGeo ; vector vCol ; #include "CurveArc.h" diff --git a/PolyLine.cpp b/PolyLine.cpp index a1ba656..9bd7c55 100644 --- a/PolyLine.cpp +++ b/PolyLine.cpp @@ -887,19 +887,19 @@ PolyLine::ApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler) // *** polilinea chiusa : devo sistemare a cavallo dell'inizio/fine *** // sposto l'inizio dalla parte opposta - MyChangeStart( int( m_lUPoints.size() / 2)) ; + ChangeStart( int( m_lUPoints.size() / 2)) ; // rifaccio l'approssimazione con 3/4 della tolleranza ammessa if ( ! MyApproxOnSide( vtN, bLeftSide, 0.75 * dToler)) return false ; // risposto l'inizio dalla parte opposta, quindi lo porto vicino all'originale - MyChangeStart( int( m_lUPoints.size() / 2)) ; + ChangeStart( int( m_lUPoints.size() / 2)) ; return true ; } //---------------------------------------------------------------------------- bool -PolyLine::MyChangeStart( int nPos) +PolyLine::ChangeStart( int nPos) { // solo per polilinee chiuse if ( ! IsClosed()) @@ -1037,12 +1037,12 @@ PolyLine::MakeConvex( const Vector3d& vtN, bool bLeftSide) // *** polilinea chiusa : devo sistemare a cavallo dell'inizio/fine *** // sposto l'inizio dalla parte opposta - MyChangeStart( int( m_lUPoints.size() / 2)) ; + ChangeStart( int( m_lUPoints.size() / 2)) ; // rifaccio la modifica if ( ! MyMakeConvex( vtN, bLeftSide)) return false ; // risposto l'inizio dalla parte opposta, quindi lo porto vicino all'originale - MyChangeStart( int( m_lUPoints.size() / 2)) ; + ChangeStart( int( m_lUPoints.size() / 2)) ; return true ; } @@ -1391,7 +1391,7 @@ PolyLine::Trim( const Plane3d& plPlane, bool bInVsOut) // se chiusa, sposto l'inizio su eventuale primo punto di intersezione con il piano if ( IsClosed() && nIntPos != -1) - MyChangeStart( nIntPos) ; + ChangeStart( nIntPos) ; // elimino i punti che non rispettano la posizione rispetto al piano currUP = m_lUPoints.begin() ; diff --git a/SurfBezier.cpp b/SurfBezier.cpp index 39df49d..e446650 100644 --- a/SurfBezier.cpp +++ b/SurfBezier.cpp @@ -46,6 +46,7 @@ #include "/EgtDev/Extern/Eigen/Dense" #define SAVEFAILEDTRIANGULATION 0 +#define SAVEFAILED_RE_TRIANGULATION 0 #define SAVEREBUILTISO 0 #define SAVERULEDISO 0 #define SAVERULEDGUIDEDISO 0 @@ -54,7 +55,7 @@ #define SAVELIMITSURF 0 #define SAVEPACEDISO 0 #if SAVEFAILEDTRIANGULATION || SAVEREBUILTISO || SAVERULEDISO || SAVERULEDGUIDEDISO || SAVEMATCHCURVES \ - || SAVEFAILEDTREE || SAVELIMITSURF || SAVEPACEDISO + || SAVEFAILEDTREE || SAVELIMITSURF || SAVEPACEDISO || SAVEFAILED_RE_TRIANGULATION #include "/EgtDev/Include/EGkGeoObjSave.h" std::vector vGeo ; std::vector vCol ; @@ -884,7 +885,7 @@ SurfBezier::CopyFrom( const SurfBezier& sbSrc) m_bTrimmed = true ; m_pTrimReg = sbSrc.m_pTrimReg->Clone() ; } -#if ! SAVEFAILEDTRIANGULATION && ! SAVEFAILEDTREE +#if ! SAVEFAILEDTRIANGULATION && ! SAVEFAILEDTREE && ! SAVEFAILED_RE_TRIANGULATION if ( sbSrc.GetAuxSurf() != nullptr) m_pSTM = sbSrc.GetAuxSurf()->Clone() ; #endif @@ -1085,7 +1086,7 @@ SurfBezier::Load( NgeReader& ngeIn) vGeo.clear() ; for ( int i = 0 ; i < ssize(vCrv) ; ++i) vGeo.push_back( vCrv[i]->Clone()) ; - SaveGeoObj( vGeo, "D:\\Temp\\bezier\\ruled\\rebuild\\isoCrv.nge") ; + SaveGeoObj( vGeo, "C:\\Temp\\bezier\\ruled\\rebuild\\isoCrv.nge") ; #endif // eseguo validazione @@ -1869,7 +1870,7 @@ SurfBezier::GetAuxSurfRefined( void) const return m_pSTMRefined ; } -#if SAVEFAILEDTRIANGULATION || SAVEFAILEDTREE +#if SAVEFAILEDTRIANGULATION || SAVEFAILEDTREE || SAVEFAILED_RE_TRIANGULATION static int nErr = 0 ; #endif @@ -1909,7 +1910,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons if ( ! Tree.BuildTree( dTol, dSideMin)) { LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface parametric space couldn't be split in cells") ; #if SAVEFAILEDTREE - SaveGeoObj( Clone(),"D:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ; + SaveGeoObj( Clone(),"C:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ; ++nErr ; #endif return nullptr ; @@ -1925,7 +1926,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons if ( vvPL.empty()) { LOG_DBG_ERR( GetEGkLogger(), "ERROR : Bezier Surface couldn't be triangulated") #if SAVEFAILEDTRIANGULATION - SaveGeoObj( Clone(),"D:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ; + SaveGeoObj( Clone(),"C:\\Temp\\bezier\\not_triangulated\\" + ToString( nErr) + ".nge") ; ++nErr ; #endif } @@ -1935,7 +1936,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons return nullptr ; // prendo i punti di ogni polyline dell'albero, li triangolo e li porto in 3d - int c = 0 ; + int p = 0 ; for ( POLYLINEVECTOR& vPL : vvPL) { PNTVECTOR vPnt ; INTVECTOR vTria ; @@ -1945,7 +1946,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons return nullptr ; } - POLYLINEVECTOR vPL3d = vvPL3d[c] ; + POLYLINEVECTOR vPL3d = vvPL3d[p] ; PNTVECTOR vPnt3d ; for ( int i = 0 ; i < int( vPL3d.size()) ; ++i) { @@ -1958,6 +1959,12 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons } } + // calcolo la normale del poligono in 3d + PolyLine& pl3d = vPL3d[0] ; + Plane3d plPlane ; double dArea = 0 ; + pl3d.IsClosedAndFlat( plPlane, dArea) ; + Vector3d vtN = plPlane.GetVersN() ; + // se ho ottenuto meno triangoli di quelli che avrei dovuto avere allora potrei aver avuto un problema in prossimità di un polo // se comunque ho corrispondenza tra vPnt e vPnt3d allora eseguo la trinagolazione in 3d int nTriaNumber = ( vPnt.size() - 2) + (2 * (vPL.size() - 1)) - (vPL.size() > 2 ? vPL.size() - 2 : 0) - (vPL.size() != 1 ? vPL.size() : 0) ; @@ -1980,12 +1987,9 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons if ( bTriangulationSucceded) { bTriangulatedIn3D = true ; // calcolo la normale della polyline per flippare eventualmente i triangoli se hanno la normale sbagliata - PolyLine& pl3d = vPL3d[0] ; - Plane3d plPlane ; double dArea = 0 ; - pl3d.IsClosedAndFlat( plPlane, dArea) ; - Vector3d vtN = plPlane.GetVersN() ; Triangle3d tria ; tria.Set( vPnt[vTria[0]], vPnt[vTria[1]], vPnt[vTria[2]]) ; + tria.Validate( true) ; if ( tria.GetN() * vtN < 0) reverse( vTria.begin(), vTria.end()) ; } @@ -2044,6 +2048,59 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons } } + // controllo che i triangoli calcolati abbiano una normale abbastanza in linea con quella della polyline + INTVECTOR vTriaSave ; + PNTVECTOR vPntSave, vPnt3dSave ; + int nIter = 0 ; + bool bTriangOk = false ; + double dCos = dTol < 0.1 ? 0.866 : 0.707 ; + while ( ! bTriangOk && nIter < 6) { + int c = 0 ; + bool bNormOk = true ; + while ( c < ssize( vTria) && bNormOk) { + Triangle3d tria ; + tria.Set( vPnt3d[vTria[c]], vPnt3d[vTria[c+1]], vPnt3d[vTria[c+2]]) ; + if ( tria.Validate( true)) { + if ( tria.GetN() * vtN < dCos) + bNormOk = false ; + } + c += 3 ; + } + if ( ! bNormOk) { + if ( nIter == 0) { + vTriaSave = vTria ; + vPntSave = vPnt ; + vPnt3dSave = vPnt3d ; + } + switch( nIter) { + case 0 : Tri.MakeByFist( vPL, vPnt, vTria, false, false, true, true) ; + break ; + case 1 : Tri.MakeByFist( vPL, vPnt, vTria, false, false, true, false) ; + break ; + case 2 : Tri.MakeByFist( vPL, vPnt, vTria, true, false, true, false) ; + break ; + default : // ruoto prima di riprovare a triangolare + vPL[0].ChangeStart( 1) ; + vPL3d[0].ChangeStart( 1) ; + rotate( vPnt3d.begin(), vPnt3d.begin() + 1, vPnt3d.end()) ; + Tri.MakeByFist( vPL, vPnt, vTria, false, false, false, false) ; + } + ++ nIter ; + } + else + bTriangOk = true ; + } + if ( ! bTriangOk) { + LOG_DBG_ERR( GetEGkLogger(), "ERROR : Imperfect triangulation of Bezier Surface ( triangle with normal deviating from actual normal)") ; + #if SAVEFAILED_RE_TRIANGULATION + SaveGeoObj( Clone(),"C:\\Temp\\bezier\\not_re_triangulated\\" + ToString( nErr) + "_" + ToString( p) + ".nge") ; + ++nErr ; + #endif + swap( vTriaSave, vTria) ; + swap( vPntSave, vPnt) ; + swap( vPnt3dSave, vPnt3d) ; + } + int nTria = int( vTria.size()) / 3 ; for ( int i = 0 ; i < nTria ; ++i) { if ( ! stmSoup.AddTriangle( vPnt3d[vTria[3*i]], vPnt3d[vTria[3*i+1]], vPnt3d[vTria[3*i+2]], @@ -2052,7 +2109,7 @@ SurfBezier::GetApproxSurf( double dTol, double dSideMin, bool bUpdateEdges) cons vPnt[vTria[3*i+2]].x, vPnt[vTria[3*i+2]].y)) return nullptr ; } - ++c ; + ++p ; } // termino @@ -5137,7 +5194,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int fill( vvCol0[2].begin(), vvCol0[2].end(), Color( 255,128,128)) ; vvCol0[3].resize( ssize(vvGeo0[3])) ; fill( vvCol0[3].begin(), vvCol0[3].end(), Color( 192,128,0)) ; - SaveGeoObj( vvGeo0, vvCol0, "D:\\Temp\\bezier\\ruled\\match.nge") ; + SaveGeoObj( vvGeo0, vvCol0, "C:\\Temp\\bezier\\ruled\\match.nge") ; #endif // salvo le coppie di punti su ogni curva che indicano l'inizio e la fine di regioni di mismatch tra i valori di accoppiamento rilevati @@ -5826,7 +5883,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int } vector vCol( ssize( vCrv)) ; fill( vCol.begin(), vCol.end(), Color( 255,0,128)) ; - SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/isoCurves.nge") ; + SaveGeoObj( vGeo, vCol, "C:/Temp/bezier/ruled/isoCurves.nge") ; //debug vGeo.clear() ; @@ -5835,7 +5892,7 @@ SurfBezier::CreateByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, int vCol.clear() ; vCol.push_back(Color(0,64,128)) ; vCol.push_back(Color(128,64,0)) ; - SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/NewCurves.nge") ; + SaveGeoObj( vGeo, vCol, "C:/Temp/bezier/ruled/NewCurves.nge") ; #endif return bOk ; @@ -6436,7 +6493,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p } #if SAVEPACEDISO - SaveGeoObj( vGeo, vCol, "D:\\Temp\\bezier\\ruled\\trimming\\smooth.nge") ; + SaveGeoObj( vGeo, vCol, "C:\\Temp\\bezier\\ruled\\trimming\\smooth.nge") ; #endif return CreateByIsoParamSet( pCrvEdge1, pCrvEdge2, vSyncLines) ; @@ -7228,7 +7285,7 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c } vector vCol( ssize( vCrvIso)) ; fill( vCol.begin(), vCol.end(), Color( 255,0,128)) ; - SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/isoCurves.nge") ; + SaveGeoObj( vGeo, vCol, "C:/Temp/bezier/ruled/isoCurves.nge") ; //debug vGeo.clear() ; @@ -7237,7 +7294,7 @@ SurfBezier::CreateByIsoParamSet( const ICurve* pCurve0, const ICurve* pCurve1, c vCol.clear() ; vCol.push_back(Color(0,64,128)) ; vCol.push_back(Color(128,64,0)) ; - SaveGeoObj( vGeo, vCol, "D:/Temp/bezier/ruled/NewCurves.nge") ; + SaveGeoObj( vGeo, vCol, "C:/Temp/bezier/ruled/NewCurves.nge") ; #endif return true ; @@ -7598,7 +7655,7 @@ SurfBezier::LimitSurfToTrimmedRegion( void) m_bTrimmed = true ; #if SAVELIMITSURF vGeo.push_back( m_pTrimReg->Clone()) ; - SaveGeoObj( vGeo, "D:\\Temp\\bezier\\edit surf\\trim_reg_before_after.nge") ; + SaveGeoObj( vGeo, "C:\\Temp\\bezier\\edit surf\\trim_reg_before_after.nge") ; vGeo.clear() ; #endif } diff --git a/Triangulate.cpp b/Triangulate.cpp index 4be97fb..b21a9ce 100644 --- a/Triangulate.cpp +++ b/Triangulate.cpp @@ -33,7 +33,7 @@ enum TrgType { TRG_STD = 0, TRG_CAP = 1, TRG_NEEDLE = 2} ; //---------------------------------------------------------------------------- static bool ChangeStartPntVector( int nNewStart, PNTVECTOR& vPi) ; -static bool MakeByFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ; +bool MakeWithFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr, bool bTop = false, bool bRandom = false, bool bSorted = true, bool bFancy = true) ; static bool RemoveFistInvalidTrg( PNTVECTOR& vPt, INTVECTOR& vTr) ; static int CalcTriangleType( const PNTVECTOR& vPt, const INTVECTOR& vTr, int nTrg) ; static bool FindAdjacentOnLongerEdge( PNTVECTOR& vPt, INTVECTOR& vTr, int nTrgA, int&nEdgeA, int& nTrgB, int& nEdgeB) ; @@ -61,7 +61,7 @@ Triangulate::Make( const PolyLine& PL, PNTVECTOR& vPt, INTVECTOR& vTr) // se fist ( e geometria più complessa di un quadrilatero) if ( FORCE_FIST && PL.GetPointNbr() > 5) - return MakeByFist( {PL}, vPt, vTr) ; + return MakeWithFist( {PL}, vPt, vTr) ; // verifico che la polilinea sia chiusa e piana e calcolo il piano medio del poligono double dArea ; @@ -1585,15 +1585,25 @@ RemoveFistInvalidTrg( PNTVECTOR& vPt, INTVECTOR& vTr) //---------------------------------------------------------------------------- bool -MakeByFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) +Triangulate::MakeByFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr, bool bTop, bool bRandom, bool bSorted, bool bFancy) +{ + // pulisco i vettori di ritorno + vPt.clear() ; + vTr.clear() ; + return MakeWithFist( vPL, vPt, vTr, bTop, bRandom, bSorted, bFancy) ; +} + +//---------------------------------------------------------------------------- +bool +MakeWithFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr, bool bTop, bool bRandom, bool bSorted, bool bFancy) { // opzioni di triangolazione rt_options rt_opt ; InitDefaults( &rt_opt) ; - rt_opt.ears_top = false ; - rt_opt.ears_random = false ; - rt_opt.ears_sorted = true ; - rt_opt.ears_fancy = true ; + rt_opt.ears_top = bTop ; + rt_opt.ears_random = bRandom ; + rt_opt.ears_sorted = bSorted ; + rt_opt.ears_fancy = bFancy ; // creo oggetto di fist per triangolazione global_struct fist ; diff --git a/Triangulate.h b/Triangulate.h index b0d9d91..df533df 100644 --- a/Triangulate.h +++ b/Triangulate.h @@ -24,6 +24,7 @@ class Triangulate bool Make( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ; bool MakeAdvanced( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr) ; bool MakeAdvanced( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr, const INTMATRIX& vnPLIndMat) ; + bool MakeByFist( const POLYLINEVECTOR& vPL, PNTVECTOR& vPt, INTVECTOR& vTr, bool bTop = false, bool bRandom = false, bool bSorted = true, bool bFancy = true) ; private : bool MakeByEC_HPP( const PolyLine& PL, bool bCCW, PNTVECTOR& vPt, INTVECTOR& vTr) ; diff --git a/Trimming.cpp b/Trimming.cpp index e008dbb..f48d22f 100644 --- a/Trimming.cpp +++ b/Trimming.cpp @@ -3692,7 +3692,7 @@ InterpolateSyncCurvesOnEndGuidePoints( const ICurveComposite* pGuide, const ICur SaveGeoObj( VT, VC, "C:\\Temp\\trimming\\interpolate\\SyncLinesPlanes.nge") ; #endif } - if ( dMinDiff < 2 * dLinAngTol) + if ( dMinDiff < 5 * dLinAngTol) vBiPts.emplace_back( make_pair( ptCurr, ptBest)) ; } } @@ -4024,7 +4024,7 @@ GetTrimmingSurfBzSyncPoints( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, bool GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, const ICurve* pSync1, const ICurve* pSync2, double dLinTol, - double dAngTol, BIPNTVECTOR& vSyncPoints) + double dAngTol, bool bShorterSide, BIPNTVECTOR& vSyncPoints, GuideBounds& gbGuideBounds) { vSyncPoints.clear() ; @@ -4052,6 +4052,8 @@ GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, if ( ( ! pCrvEdge1->GetParamAtPoint( ptS1, dUA, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptE1, dUB, dMyLinTol)) && ( ! pCrvEdge1->GetParamAtPoint( ptE1, dUA, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptS1, dUB, dMyLinTol))) return false ; + gbGuideBounds.dS1 = dUA ; + gbGuideBounds.dS2 = dUB ; Point3d ptS2 ; pSync2->GetStartPoint( ptS2) ; Point3d ptE2 ; pSync2->GetEndPoint( ptE2) ; if ( AreSamePointEpsilon( ptS2, ptE2, dMyLinTol)) @@ -4059,34 +4061,45 @@ GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, if ( ( ! pCrvEdge1->GetParamAtPoint( ptS2, dUC, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptE2, dUD, dMyLinTol)) && ( ! pCrvEdge1->GetParamAtPoint( ptE2, dUC, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptS2, dUD, dMyLinTol))) return false ; - + gbGuideBounds.dE1 = dUC ; + gbGuideBounds.dE2 = dUD ; // Recupero i due tratti di curva PtrOwner pCompoGuide1( nullptr) ; PtrOwner pCompoGuide2( nullptr) ; // se entrambe chiuse if ( pCrvEdge1->IsClosed() && pCrvEdge2->IsClosed()) { - // Recupero la porzione di curva di Edge1 di lunghezza minima tra il parametro A e C + // Recupero la porzione di curva di Edge1 di lunghezza minima/massima tra il parametro A e C come indicato da bShorterSide PtrOwner pCompoAC( ConvertCurveToBasicComposite( pCrvEdge1->CopyParamRange( dUA, dUC))) ; PtrOwner pCompoCA( ConvertCurveToBasicComposite( pCrvEdge1->CopyParamRange( dUC, dUA))) ; if ( IsNull( pCompoAC) || IsNull( pCompoCA) || ! pCompoAC->IsValid() || ! pCompoCA->IsValid()) return false ; double dLenAC ; pCompoAC->GetLength( dLenAC) ; double dLenCA ; pCompoCA->GetLength( dLenCA) ; - if ( dLenAC < dLenCA) + bool bACIsShorter = dLenAC < dLenCA ; + if ( bACIsShorter == bShorterSide) { pCompoGuide1.Set( Release( pCompoAC)) ; - else + gbGuideBounds.bDirect = true ; + } + else { pCompoGuide1.Set( Release( pCompoCA)) ; - // Recupero la porzione di curva di Edge2 di lunghezza minima tra il parametro B e D + gbGuideBounds.bDirect = false ; + } + // Recupero la porzione di curva di Edge2 di lunghezza minima/massima tra il parametro B e D come indicato da bShorterSide PtrOwner pCompoBD( ConvertCurveToBasicComposite( pCrvEdge2->CopyParamRange( dUB, dUD))) ; PtrOwner pCompoDB( ConvertCurveToBasicComposite( pCrvEdge2->CopyParamRange( dUD, dUB))) ; if ( IsNull( pCompoBD) || IsNull( pCompoBD) || ! pCompoBD->IsValid() || ! pCompoDB->IsValid()) return false ; double dLenBD ; pCompoBD->GetLength( dLenBD) ; double dLenDB ; pCompoDB->GetLength( dLenDB) ; - if ( dLenBD < dLenDB) + bool bBDIsShorter = dLenBD < dLenDB ; + if ( bBDIsShorter == bShorterSide) { pCompoGuide2.Set( Release( pCompoBD)) ; - else + gbGuideBounds.bDirect = true ; + } + else { pCompoGuide2.Set( Release( pCompoDB)) ; + gbGuideBounds.bDirect = false ; + } } // se entrambe aperte else if ( ! pCrvEdge1->IsClosed() && ! pCrvEdge2->IsClosed()) {