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.
This commit is contained in:
Daniele Bariletti
2026-08-26 09:21:43 +02:00
parent c64f9f482b
commit 07aee03006
6 changed files with 124 additions and 42 deletions
+1
View File
@@ -33,6 +33,7 @@ using namespace std ;
#if SAVECRVORIG || SAVEOFFDIR || SAVECYL || SAVEOFFSET
#include "/EgtDev/Include/EGkColor.h"
#include "/EgtDev/Include/EGkGeoVector3d.h"
vector<vector<IGeoObj*>> vvGeo ;
vector<IGeoObj*> vGeo ;
vector<Color> vCol ;
#include "CurveArc.h"
+6 -6
View File
@@ -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() ;
+77 -20
View File
@@ -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<IGeoObj*> vGeo ;
std::vector<Color> 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<Color> 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<Color> 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
}
+17 -7
View File
@@ -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 ;
+1
View File
@@ -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) ;
+22 -9
View File
@@ -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<CurveComposite> pCompoGuide1( nullptr) ;
PtrOwner<CurveComposite> 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<CurveComposite> pCompoAC( ConvertCurveToBasicComposite( pCrvEdge1->CopyParamRange( dUA, dUC))) ;
PtrOwner<CurveComposite> 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<CurveComposite> pCompoBD( ConvertCurveToBasicComposite( pCrvEdge2->CopyParamRange( dUB, dUD))) ;
PtrOwner<CurveComposite> 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()) {