Merge branch 'master' into NewRuled
This commit is contained in:
Binary file not shown.
+241
-4
@@ -34,6 +34,7 @@
|
||||
#include "/EgtDev/Include/EGkSbzFromCurves.h"
|
||||
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
||||
#include "/EgtDev/Include/EGkIntersLineBox.h"
|
||||
#include "/EgtDev/Include/EGkIntersCurvePlane.h"
|
||||
#include "/EgtDev/Include/EGkSurfTriMeshAux.h"
|
||||
#include "/EgtDev/Include/EgtNumUtils.h"
|
||||
#include <thread>
|
||||
@@ -53,6 +54,7 @@
|
||||
#define DEBUG_BRK 0
|
||||
#define DEBUG_BORDERS_BY_NORMALS 0
|
||||
#define DEBUG_SYNC_POINTS 0
|
||||
#define DEBUG_SYNC_INTERPOLATION 0
|
||||
#define DEBUG_BEZIER_RULED 0
|
||||
#define DEBUG_CURVATURE 0
|
||||
#define DEBUG_SIMPLE_PATCHES 0
|
||||
@@ -63,9 +65,9 @@
|
||||
#define DEBUG_HOLES 0
|
||||
#if DEBUG_BASIC_BORDERS || DEBUG_CHAIN_CURVES || DEBUG_ANG_APPROX || DEBUG_BEZIER_INTERP || \
|
||||
DEBUG_FACE_SEARCH || DEBUG_FACE_SEARCH_TRIA_MODIF || DEBUG_BRK_POINTS || DEBUG_BRK_THICK || \
|
||||
DEBUG_BRK || DEBUG_BORDERS_BY_NORMALS || DEBUG_SYNC_POINTS || DEBUG_BEZIER_RULED || DEBUG_CURVATURE || \
|
||||
DEBUG_SIMPLE_PATCHES || DEBUG_SURF_PATCHES || DEBUG_RAW_EDGES || DEBUG_EDGES || DEBUG_SHAPE_STM || \
|
||||
DEBUG_HOLES || DEBUG
|
||||
DEBUG_BRK || DEBUG_BORDERS_BY_NORMALS || DEBUG_SYNC_POINTS || DEBUG_SYNC_INTERPOLATION || \
|
||||
DEBUG_BEZIER_RULED || DEBUG_CURVATURE || DEBUG_SIMPLE_PATCHES || DEBUG_SURF_PATCHES || \
|
||||
DEBUG_RAW_EDGES || DEBUG_EDGES || DEBUG_SHAPE_STM || DEBUG_HOLES || DEBUG
|
||||
#include "CurveLine.h"
|
||||
#include "/EgtDev/Include/EGkGeoObjSave.h"
|
||||
#include "/EgtDev/Include/EgtPerfCounter.h"
|
||||
@@ -3577,6 +3579,95 @@ IsBorderAButtonHole( const PolyLine& PL, double dLinTol, double dAngTol, Frame3d
|
||||
return false ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-------------------------------- Interpolazioni -----------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool
|
||||
InterpolateSyncCurvesOnEndGuidePoints( const ICurveComposite* pGuide, const ICurveComposite* pOtherGuide,
|
||||
const Plane3d& plStart, const Plane3d& plEnd, double dLinTol,
|
||||
BIPNTVECTOR& vBiPts)
|
||||
{
|
||||
vBiPts.clear() ;
|
||||
|
||||
// Verifico che le curve siano valide
|
||||
if ( pGuide == nullptr || ! pGuide->IsValid() ||
|
||||
pOtherGuide == nullptr || ! pOtherGuide->IsValid())
|
||||
return false ;
|
||||
|
||||
// Recupero la sua lunghezza
|
||||
double dGuideLen = 0. ;
|
||||
if ( ! pGuide->GetLength( dGuideLen) || dGuideLen < dLinTol)
|
||||
return false ;
|
||||
|
||||
// Scorro le curve da restituire
|
||||
double dProgLen = 0. ;
|
||||
vBiPts.reserve( pGuide->GetCurveCount() - 1) ;
|
||||
for ( int i = 0 ; i < pGuide->GetCurveCount() - 1 ; ++ i) {
|
||||
// Recupero la curva corrente
|
||||
const ICurve* pCrv = pGuide->GetCurve( i) ;
|
||||
if ( pCrv == nullptr || ! pCrv->IsValid())
|
||||
return false ;
|
||||
// Ne recupero la lunghezza e aggiorno la lunghezza progressiva
|
||||
double dLen = 0. ;
|
||||
if ( ! pCrv->GetLength( dLen))
|
||||
return false ;
|
||||
dProgLen += dLen ;
|
||||
// Recupero la percentuale di interpolazione rispetto alla lunghezze
|
||||
double dInterPar = dProgLen / dGuideLen ;
|
||||
// Interpolo le normali dei piani rispetto a tale valore
|
||||
Vector3d vtN = Media( plStart.GetVersN(), plEnd.GetVersN(), dInterPar) ;
|
||||
vtN.Normalize() ;
|
||||
// Definisco il piano di intersezione
|
||||
Point3d ptCurr ;
|
||||
if ( ! pCrv->GetEndPoint( ptCurr))
|
||||
return false ;
|
||||
#if DEBUG_SYNC_INTERPOLATION
|
||||
Frame3d frPl ; frPl.Set( ptCurr, vtN) ;
|
||||
PtrOwner<IGeoFrame3d> frCurr( CreateGeoFrame3d()) ; frCurr->Set( frPl) ;
|
||||
VT.emplace_back( Release( frCurr)) ;
|
||||
VC.emplace_back( WHITE) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ;
|
||||
#endif
|
||||
// Recupero il parametro di intersezione tra la curva e il piano
|
||||
#if 0
|
||||
VT.clear() ; VC.clear() ;
|
||||
PtrOwner<IGeoPoint3d> PT( CreateGeoPoint3d()) ; PT->Set( ptCurr) ;
|
||||
VT.emplace_back( Release( PT)) ;
|
||||
VC.emplace_back( AQUA) ;
|
||||
PtrOwner<IGeoVector3d> VECT( CreateGeoVector3d()) ; VECT->Set( vtN) ;
|
||||
VECT->ChangeBase( ptCurr) ;
|
||||
PtrOwner<ICurveArc> pArc( CreateCurveArc()) ; pArc->Set( ptCurr, vtN, 1000.) ;
|
||||
PtrOwner<ISurfFlatRegion> pSfrPlane( CreateSurfFlatRegion()) ;
|
||||
pSfrPlane->AddExtLoop( Release( pArc)) ;
|
||||
VT.emplace_back( Release( pSfrPlane)) ;
|
||||
VC.emplace_back( Color( 0., 0., 0., .5)) ;
|
||||
VT.emplace_back( Release( VECT)) ;
|
||||
VC.emplace_back( BLUE) ;
|
||||
VT.emplace_back( pOtherGuide->Clone()) ;
|
||||
VC.emplace_back( WHITE) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ;
|
||||
#endif
|
||||
IntersCurvePlane IntCP( *pOtherGuide, ptCurr, vtN) ;
|
||||
if ( IntCP.GetIntersCount() == 0)
|
||||
return false ; // ambiguità
|
||||
// Recupero il punto della prima intersezione trovata
|
||||
Point3d ptInt ;
|
||||
double dPar ;
|
||||
if ( ! IntCP.GetIntersPointNearTo( ptCurr, ptInt, dPar))
|
||||
return false ;
|
||||
#if DEBUG_SYNC_INTERPOLATION
|
||||
PtrOwner<IGeoPoint3d> ptG( CreateGeoPoint3d()) ; ptG->Set( ptInt) ;
|
||||
VT.emplace_back( Release( ptG)) ;
|
||||
VC.emplace_back( WHITE) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ;
|
||||
#endif
|
||||
// Memorizzo tale punto
|
||||
vBiPts.emplace_back( make_pair( ptCurr, ptInt)) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-------------------------------- Funzioni Export ----------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -3847,10 +3938,14 @@ bool
|
||||
GetTrimmingSurfBzSyncPoints( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2,
|
||||
double dLinTol, BIPNTVECTOR& vSyncPoints)
|
||||
{
|
||||
vSyncPoints.clear() ;
|
||||
|
||||
// Verifica validità delle curve per la creazione della Bezier rigata
|
||||
PtrOwner<ICurveComposite> pCompoEdge1( ConvertCurveToComposite( pCrvEdge1->Clone())) ;
|
||||
PtrOwner<ICurveComposite> pCompoEdge2( ConvertCurveToComposite( pCrvEdge2->Clone())) ;
|
||||
vSyncPoints.clear() ;
|
||||
if ( IsNull( pCompoEdge1) || IsNull( pCompoEdge2) ||
|
||||
! pCompoEdge1->IsValid() || ! pCompoEdge2->IsValid())
|
||||
return false ;
|
||||
|
||||
// Controllo sulla tolleranza lineare
|
||||
double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
||||
@@ -3892,6 +3987,148 @@ GetTrimmingSurfBzSyncPoints( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2,
|
||||
return true ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Funzione per interpolare le Curve di Sincronizzazione tra due Curve di Bordo
|
||||
bool
|
||||
GetTrimmingSyncInterpolation( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2,
|
||||
const ICurve* pSync1, const ICurve* pSync2, double dLinTol,
|
||||
double dAngTol, BIPNTVECTOR& vSyncPoints)
|
||||
{
|
||||
vSyncPoints.clear() ;
|
||||
|
||||
// Verifico la validità dei parametri
|
||||
if ( pCrvEdge1 == nullptr || ! pCrvEdge1->IsValid() ||
|
||||
pCrvEdge2 == nullptr || ! pCrvEdge2->IsValid() ||
|
||||
pSync1 == nullptr || ! pSync1->IsValid() ||
|
||||
pSync2 == nullptr || ! pSync2->IsValid())
|
||||
return false ;
|
||||
|
||||
// Le curve di Bordo devono essere entrambe aperte o entrambe chiuse
|
||||
if ( pCrvEdge1->IsClosed() != pCrvEdge2->IsClosed())
|
||||
return false ;
|
||||
|
||||
// Verifico i valori delle tolleranze
|
||||
double dMyLinTol = Clamp( dLinTol, EPS_SMALL, 1e5 * EPS_SMALL) ;
|
||||
double dMyAngTol = Clamp( dAngTol, EPS_ANG_SMALL, 60.) ;
|
||||
|
||||
// Verifico le due curve di sincronizzazione abbiano gli estremi sulle due curve di bordo
|
||||
Point3d ptS1 ; pSync1->GetStartPoint( ptS1) ;
|
||||
Point3d ptE1 ; pSync1->GetEndPoint( ptE1) ;
|
||||
if ( AreSamePointEpsilon( ptS1, ptE1, dMyLinTol))
|
||||
return false ;
|
||||
double dUA, dUB, dUC, dUD ; // [A,C]->Edge1 | [B,D]->Edge2
|
||||
if ( ( ! pCrvEdge1->GetParamAtPoint( ptS1, dUA, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptE1, dUB, dMyLinTol)) &&
|
||||
( ! pCrvEdge1->GetParamAtPoint( ptE1, dUA, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptS1, dUB, dMyLinTol)))
|
||||
return false ;
|
||||
Point3d ptS2 ; pSync2->GetStartPoint( ptS2) ;
|
||||
Point3d ptE2 ; pSync2->GetEndPoint( ptE2) ;
|
||||
if ( AreSamePointEpsilon( ptS2, ptE2, dMyLinTol))
|
||||
return false ;
|
||||
if ( ( ! pCrvEdge1->GetParamAtPoint( ptS2, dUC, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptE2, dUD, dMyLinTol)) &&
|
||||
( ! pCrvEdge1->GetParamAtPoint( ptE2, dUC, dMyLinTol) || ! pCrvEdge2->GetParamAtPoint( ptS2, dUD, dMyLinTol)))
|
||||
return false ;
|
||||
|
||||
// Recupero i due tratti di curva
|
||||
PtrOwner<CurveComposite> pCompoGuide1( ConvertCurveToBasicComposite( pCrvEdge1->CopyParamRange( dUA, dUC))) ;
|
||||
PtrOwner<CurveComposite> pCompoGuide2( ConvertCurveToBasicComposite( pCrvEdge2->CopyParamRange( dUB, dUD))) ;
|
||||
if ( IsNull( pCompoGuide1) || IsNull( pCompoGuide2) ||
|
||||
! pCompoGuide1->IsValid() || ! pCompoGuide2->IsValid())
|
||||
return false ;
|
||||
|
||||
// Determino quale curva è la più lunga, servirà come riferimento per la parametrizzazione e l'interpolazione
|
||||
double dLen1, dLen2 ;
|
||||
if ( ! pCompoGuide1->GetLength( dLen1) || ! pCompoGuide2->GetLength( dLen2) ||
|
||||
dLen1 < dMyLinTol || dLen2 < dMyLinTol)
|
||||
return false ;
|
||||
if ( dLen2 > dLen1) {
|
||||
swap( pCompoGuide1, pCompoGuide2) ;
|
||||
swap( dLen1, dLen2) ;
|
||||
}
|
||||
if ( pCompoGuide2->IsPointOn( ptS1))
|
||||
swap( ptS1, ptE1) ;
|
||||
if ( pCompoGuide2->IsPointOn( ptS2))
|
||||
swap( ptS2, ptE2) ;
|
||||
|
||||
#if DEBUG_SYNC_INTERPOLATION
|
||||
VT.clear() ; VC.clear() ;
|
||||
VT.emplace_back( pCompoGuide1->Clone()) ;
|
||||
VC.emplace_back( AQUA) ;
|
||||
VT.emplace_back( pCompoGuide2->Clone()) ;
|
||||
VC.emplace_back( ORANGE) ;
|
||||
PtrOwner<IGeoPoint3d> ptG( CreateGeoPoint3d()) ; ptG->Set( ptS1) ;
|
||||
VT.emplace_back( ptG->Clone()) ; VC.emplace_back( AQUA) ;
|
||||
ptG->Set( ptE1) ;
|
||||
VT.emplace_back( ptG->Clone()) ; VC.emplace_back( ORANGE) ;
|
||||
ptG->Set( ptS2) ;
|
||||
VT.emplace_back( ptG->Clone()) ; VC.emplace_back( AQUA) ;
|
||||
ptG->Set( ptE2) ;
|
||||
VT.emplace_back( ptG->Clone()) ; VC.emplace_back( ORANGE) ;
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( ptS1, ptE1) ;
|
||||
VT.emplace_back( pLine->Clone()) ; VC.emplace_back( PURPLE) ;
|
||||
pLine->Set( ptS2, ptE2) ;
|
||||
VT.emplace_back( pLine->Clone()) ; VC.emplace_back( PURPLE) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ;
|
||||
#endif
|
||||
|
||||
// Determino le Normali dei piani di taglio agli agli estremi delle due curve
|
||||
Vector3d vtStart1, vtStart2 ;
|
||||
if ( ! pCompoGuide1->GetStartDir( vtStart1) || ! pCompoGuide2->GetStartDir( vtStart2))
|
||||
return false ;
|
||||
Vector3d vtAux = ptE1 - ptS1 ; vtAux.Normalize() ;
|
||||
Vector3d vtMTan = Media( vtStart1, vtStart2) ; vtMTan.Normalize() ;
|
||||
Vector3d vtN = OrthoCompo( vtMTan, vtAux) ; vtN.Normalize() ;
|
||||
Plane3d plStart ;
|
||||
if ( ! plStart.Set( ptS1, vtN))
|
||||
return false ;
|
||||
Vector3d vtEnd1, vtEnd2 ;
|
||||
if ( ! pCompoGuide1->GetEndDir( vtEnd1) || ! pCompoGuide2->GetEndDir( vtEnd2))
|
||||
return false ;
|
||||
vtAux = ptE2 - ptS2 ; vtAux.Normalize() ;
|
||||
vtMTan = Media( vtEnd1, vtEnd2) ; vtMTan.Normalize() ;
|
||||
vtN = OrthoCompo( vtMTan, vtAux) ; vtN.Normalize() ;
|
||||
Plane3d plEnd ;
|
||||
if ( ! plEnd.Set( ptS2, vtN))
|
||||
return false ;
|
||||
|
||||
#if DEBUG_SYNC_INTERPOLATION
|
||||
Frame3d frPlStart ; frPlStart.Set( ptS1, plStart.GetVersN()) ;
|
||||
Frame3d frPlEnd ; frPlEnd.Set( ptS2, plEnd.GetVersN()) ;
|
||||
PtrOwner<IGeoFrame3d> frS( CreateGeoFrame3d()) ; frS->Set( frPlStart) ;
|
||||
PtrOwner<IGeoFrame3d> frE( CreateGeoFrame3d()) ; frE->Set( frPlEnd) ;
|
||||
VT.emplace_back( Release( frS)) ;
|
||||
VC.emplace_back( WHITE) ;
|
||||
VT.emplace_back( Release( frE)) ;
|
||||
VC.emplace_back( WHITE) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\SyncLinesPlanes.nge") ;
|
||||
#endif
|
||||
|
||||
// Curve di Sincronizzazione del Bordo 1 sul Bordo 2
|
||||
BIPNTVECTOR vBiPts1 ;
|
||||
if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide1, pCompoGuide2, plStart, plEnd, dMyLinTol, vBiPts1))
|
||||
return false ;
|
||||
|
||||
// Curve di Sincronizzazione del Bordo 2 sul Bordo 1
|
||||
BIPNTVECTOR vBiPts2 ;
|
||||
if ( ! InterpolateSyncCurvesOnEndGuidePoints( pCompoGuide2, pCompoGuide1, plStart, plEnd, dMyLinTol, vBiPts2))
|
||||
return false ;
|
||||
|
||||
// Restituisco le Curve di Sincronizzazione
|
||||
// [Da Bordo 1 a Bordo 2 originale]
|
||||
vSyncPoints.reserve( ssize( vBiPts1) + ssize( vBiPts2)) ;
|
||||
for ( int i = 0 ; i < ssize( vBiPts1) ; ++ i) {
|
||||
vSyncPoints.emplace_back( vBiPts1[i]) ;
|
||||
if ( pCrvEdge1->IsPointOn( vBiPts1[i].second, dMyLinTol))
|
||||
swap( vSyncPoints.back().first, vSyncPoints.back().second) ;
|
||||
}
|
||||
for ( int i = 0 ; i < ssize( vBiPts2) ; ++ i) {
|
||||
vSyncPoints.emplace_back( vBiPts2[i]) ;
|
||||
if ( pCrvEdge1->IsPointOn( vBiPts2[i].second, dMyLinTol))
|
||||
swap( vSyncPoints.back().first, vSyncPoints.back().second) ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Funzione per il calcolo della superficie di Bezier rigata
|
||||
// NB. Possono essere passati dei parametri opzionali come vIndPriority e vIndVisible :
|
||||
|
||||
Reference in New Issue
Block a user