EgtGeomKernel 3.1e2 :
- piccola modifica - cambio versione.
This commit is contained in:
Binary file not shown.
+66
-91
@@ -6402,7 +6402,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
#endif
|
||||
|
||||
// Verifico che la distanza di campionamento sia ammissibile
|
||||
double dSampleDist = Clamp( dSampleLen, 2., 30.) ; // 20.0 sembra un passo di campionamento ideale
|
||||
double dMyDist = Clamp( dSampleLen, 2., 30.) ; // 20.0 sembra un passo di campionamento ideale
|
||||
// Recupero parametri iniziali
|
||||
double dLen1 ; pCrvEdge1->GetLength( dLen1) ;
|
||||
double dLen2 ; pCrvEdge2->GetLength( dLen2) ;
|
||||
@@ -6415,26 +6415,22 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
Point3d ptPrev1, ptCurr1 ; pCrvEdge1->GetStartPoint( ptPrev1) ;
|
||||
Point3d ptPrev2, ptCurr2 ; pCrvEdge2->GetStartPoint( ptPrev2) ;
|
||||
Vector3d vtCurr1 = V_NULL, vtCurr2 = V_NULL ;
|
||||
while ( dLenPrev1 + dSampleDist < dLen1 - EPS_ZERO) {
|
||||
// Recupero dU, Point3d e dLen corrente sul primo bordo, per un incremento del passo di campionamento
|
||||
dLenCurr1 = Clamp( dLenPrev1 + dSampleDist, 0., dLen1) ;
|
||||
|
||||
while ( dLenPrev1 + dMyDist < dLen1 - EPS_ZERO) {
|
||||
// Recupero dU, Point3d e dLen corrente sul primo bordo, per un incremento del passo di campionamento
|
||||
dLenCurr1 = Clamp( dLenPrev1 + dMyDist, 0., dLen1) ;
|
||||
pCrvEdge1->GetParamAtLength( dLenCurr1, dUCurr1) ;
|
||||
// se sono abbastanza vicino ad una joint allora prendo quel punto
|
||||
double dUClosestJoint1 = round( dUCurr1) ;
|
||||
double dLenAlt1 = 0 ; pCrvEdge1->GetLengthAtParam( dUClosestJoint1, dLenAlt1) ;
|
||||
if ( abs( dLenCurr1 - dLenAlt1) < 1)
|
||||
dUCurr1 = dUClosestJoint1 ;
|
||||
pCrvEdge1->GetPointD1D2( dUCurr1, ICurve::FROM_MINUS, ptCurr1, &vtCurr1) ;
|
||||
vtCurr1.Normalize() ;
|
||||
|
||||
#if DEBUG_SYNCLINES
|
||||
PtrOwner<IGeoPoint3d> ptGeo1( CreateGeoPoint3d()) ; ptGeo1->Set( ptCurr1) ;
|
||||
PtrOwner<IGeoVector3d> vtGeo1( CreateGeoVector3d()) ; vtGeo1->Set( 5. * vtCurr1, ptCurr1) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( ptGeo1)) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( vtGeo1)) ;
|
||||
#endif
|
||||
#if DEBUG_SYNCLINES
|
||||
PtrOwner<IGeoPoint3d> ptGeo1( CreateGeoPoint3d()) ; ptGeo1->Set( ptCurr1) ;
|
||||
PtrOwner<IGeoVector3d> vtGeo1( CreateGeoVector3d()) ; vtGeo1->Set( 5. * vtCurr1, ptCurr1) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( ptGeo1)) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay1, Release( vtGeo1)) ;
|
||||
#endif
|
||||
|
||||
// --- Piano di taglio per punto a minima distanza
|
||||
// --- Piano di taglio per punto a minima distanza
|
||||
IntersCurvePlane ICP( *pCrvEdge2, ptCurr1, vtCurr1) ;
|
||||
int nIndParCloser = - 1, nIndPointCloser = -1 ;
|
||||
double dSqMinDist = INFINITO ;
|
||||
@@ -6452,67 +6448,67 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
}
|
||||
bool bOkPlane = ( nIndParCloser != -1 && nIndPointCloser != -1) ;
|
||||
if ( bOkPlane) {
|
||||
// Se gli indici sono tra loro coerenti allora ho individuato il punto
|
||||
// Se gli indici sono tra loro coerenti allora ho individuato il punto
|
||||
if ( nIndParCloser == nIndPointCloser) {
|
||||
IntCrvPlnInfo aInfo ;
|
||||
ICP.GetIntCrvPlnInfo( nIndParCloser, aInfo) ;
|
||||
dUCurr2 = aInfo.Ici[0].dU ;
|
||||
}
|
||||
// Se gli indici sono discordi, devo scegliere quale dei due punti tenere
|
||||
// Se gli indici sono discordi, devo scegliere quale dei due punti tenere
|
||||
else {
|
||||
// scelgo il punto più vicino al corrente
|
||||
// scelgo il punto più vicino al corrente
|
||||
IntCrvPlnInfo aInfoPt, aInfoPar ;
|
||||
ICP.GetIntCrvPlnInfo( nIndPointCloser, aInfoPt) ;
|
||||
ICP.GetIntCrvPlnInfo( nIndParCloser, aInfoPar) ;
|
||||
dUCurr2 = ( SqDist( ptCurr1, aInfoPt.Ici[0].ptI) < SqDist( ptCurr1, aInfoPar.Ici[0].ptI) ?
|
||||
aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ;
|
||||
#if DEBUG_SYNCLINES && 0
|
||||
VT.clear() ; VC.clear() ;
|
||||
VT.emplace_back( pCrvEdge1->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ;
|
||||
VT.emplace_back( pCrvEdge2->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ;
|
||||
PtrOwner<IGeoPoint3d> ptCurr1Geo( CreateGeoPoint3d()) ; ptCurr1Geo->Set( ptCurr1) ;
|
||||
VT.emplace_back( Release( ptCurr1Geo)) ; VC.emplace_back( BLUE) ;
|
||||
PtrOwner<IGeoPoint3d> ptPar( CreateGeoPoint3d()) ; ptPar->Set( aInfoPar.Ici[0].ptI) ;
|
||||
PtrOwner<IGeoPoint3d> ptPt( CreateGeoPoint3d()) ; ptPt->Set( aInfoPt.Ici[0].ptI) ;
|
||||
VT.emplace_back( Release( ptPar)) ; VC.emplace_back( LIME) ;
|
||||
VT.emplace_back( Release( ptPt)) ; VC.emplace_back( FUCHSIA) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\TestTrimmingPlane.nge") ;
|
||||
#endif
|
||||
aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ;
|
||||
#if DEBUG_SYNCLINES && 0
|
||||
VT.clear() ; VC.clear() ;
|
||||
VT.emplace_back( pCrvEdge1->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ;
|
||||
VT.emplace_back( pCrvEdge2->Clone()) ; VC.emplace_back( Color( 0, 128, 255)) ;
|
||||
PtrOwner<IGeoPoint3d> ptCurr1Geo( CreateGeoPoint3d()) ; ptCurr1Geo->Set( ptCurr1) ;
|
||||
VT.emplace_back( Release( ptCurr1Geo)) ; VC.emplace_back( BLUE) ;
|
||||
PtrOwner<IGeoPoint3d> ptPar( CreateGeoPoint3d()) ; ptPar->Set( aInfoPar.Ici[0].ptI) ;
|
||||
PtrOwner<IGeoPoint3d> ptPt( CreateGeoPoint3d()) ; ptPt->Set( aInfoPt.Ici[0].ptI) ;
|
||||
VT.emplace_back( Release( ptPar)) ; VC.emplace_back( LIME) ;
|
||||
VT.emplace_back( Release( ptPt)) ; VC.emplace_back( FUCHSIA) ;
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\TestTrimmingPlane.nge") ;
|
||||
#endif
|
||||
}
|
||||
// Verifico di non essermi allontanato troppo
|
||||
// Verifico di non essermi allontanato troppo
|
||||
double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ;
|
||||
bOkPlane = ( dLen < dLenPrev2 + 2. * dSampleDist) ;
|
||||
bOkPlane = ( dLen < dLenPrev2 + 2. * dMyDist) ;
|
||||
}
|
||||
if ( ! bOkPlane) {
|
||||
// --- Altrimenti, cerco il punto a minima distanza
|
||||
// --- Altrimenti, cerco il punto a minima distanza
|
||||
DistPointCurve DPC( ptCurr1, *pCrvEdge2) ;
|
||||
int nFlag ;
|
||||
bool bOkMinDist = ( DPC.GetParamAtMinDistPoint( dUPrev2, dUCurr2, nFlag) && dUCurr2 > dUPrev2) ;
|
||||
// Verifico di non essermi allontanato troppo
|
||||
// Verifico di non essermi allontanato troppo
|
||||
if ( bOkMinDist) {
|
||||
double dLen ; pCrvEdge2->GetLengthAtParam( dUCurr2, dLen) ;
|
||||
bOkMinDist = ( dLen < dLenPrev2 + 2. * dSampleDist) ;
|
||||
bOkMinDist = ( dLen < dLenPrev2 + 2. * dMyDist) ;
|
||||
}
|
||||
if ( ! bOkMinDist) {
|
||||
// --- Aumento la distanza corrente del passo di campionamento
|
||||
double dLen = Clamp( dLenPrev2 + dSampleDist, 0., dLen2) ;
|
||||
// --- Aumento la distanza corrente del passo di campionamento
|
||||
double dLen = Clamp( dLenPrev2 + dMyDist, 0., dLen2) ;
|
||||
pCrvEdge2->GetParamAtLength( dLen, dUCurr2) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Recupero il punto corrente e la direzione tangente sul secondo bordo
|
||||
// Recupero il punto corrente e la direzione tangente sul secondo bordo
|
||||
pCrvEdge2->GetLengthAtParam( dUCurr2, dLenCurr2) ;
|
||||
pCrvEdge2->GetPointD1D2( dUCurr2, ICurve::FROM_MINUS, ptCurr2, &vtCurr2) ;
|
||||
vtCurr2.Normalize() ;
|
||||
|
||||
// Verifico se le direzioni tangenti sono tra di loro circa parallele
|
||||
// Verifico se le direzioni tangenti sono tra di loro circa parallele
|
||||
const double COS_ANG_TOL = cos( 15. * DEGTORAD) ;
|
||||
if ( vtCurr1 * vtCurr2 < COS_ANG_TOL) {
|
||||
// Se fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 2. * dMyDist)
|
||||
// Se fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 2. * dMyDist)
|
||||
pCrvEdge2->GetLengthAtPoint( ptCurr2, dLenCurr2) ;
|
||||
double dLimInfLen2 = Clamp( dLenCurr2 - dSampleDist, dLenPrev2, dLen2) ;
|
||||
double dLimSupLen2 = Clamp( dLenCurr2 + dSampleDist, dLenPrev2, dLen2) ;
|
||||
// [Controllo migliorabile, magari mendiante metodo di bisezione (?)]
|
||||
double dLimInfLen2 = Clamp( dLenCurr2 - dMyDist, dLenPrev2, dLen2) ;
|
||||
double dLimSupLen2 = Clamp( dLenCurr2 + dMyDist, dLenPrev2, dLen2) ;
|
||||
// [Controllo migliorabile, magari mendiante metodo di bisezione (?)]
|
||||
const int NUM_STEP = 20 ;
|
||||
double dMinCos = - 1. - EPS_ZERO ;
|
||||
const double DEGTOL = 5. ;
|
||||
@@ -6523,7 +6519,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
pCrvEdge2->GetPointD1D2( dUStep2, ICurve::FROM_MINUS, ptStep2, &vtStep2) ; vtStep2.Normalize() ;
|
||||
double dStepCos2 = vtCurr1 * vtStep2 ;
|
||||
double dAngTol = ( i < NUM_STEP / 2 ? ( 2. * DEGTOL) / NUM_STEP * i :
|
||||
( - 2. * DEGTOL) / NUM_STEP * ( i - NUM_STEP)) ;
|
||||
( - 2. * DEGTOL) / NUM_STEP * ( i - NUM_STEP)) ;
|
||||
double dCosTol = 1. - cos( dAngTol * DEGTORAD) ;
|
||||
if ( dStepCos2 + dCosTol > dMinCos) {
|
||||
ptCurr2 = ptStep2 ;
|
||||
@@ -6534,49 +6530,35 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
}
|
||||
}
|
||||
|
||||
// verifico se sono vicino ad una joint esistente allora modifico la curva 2
|
||||
double dUClosestJoint2 = round( dUCurr2) ;
|
||||
double dLenAlt2 = 0 ; pCrvEdge2->GetLengthAtParam( dUClosestJoint2, dLenAlt2) ;
|
||||
if ( abs( dLenCurr1 - dLenAlt2) < 1) {
|
||||
Point3d ptNewJoint ; pCrvEdge2->GetPointD1D2( dUClosestJoint2, ICurve::FROM_MINUS, ptNewJoint) ;
|
||||
pCrvEdge2->ModifyJoint( int( dUClosestJoint2), ptNewJoint) ;
|
||||
dUCurr2 = dUClosestJoint2 ;
|
||||
}
|
||||
|
||||
#if DEBUG_SYNCLINES
|
||||
PtrOwner<IGeoPoint3d> ptGeo2( CreateGeoPoint3d()) ; ptGeo2->Set( ptCurr2) ;
|
||||
PtrOwner<IGeoVector3d> vtGeo2( CreateGeoVector3d()) ; vtGeo2->Set( 5. * vtCurr2, ptCurr2) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( ptGeo2)) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( vtGeo2)) ;
|
||||
#endif
|
||||
|
||||
#if SAVEPACEDISO
|
||||
// Inserisco le curve di sincronizzazione nel Layer di destinazine
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( ptCurr1, ptCurr2) ;
|
||||
vGeo.push_back( Release( pLine)) ;
|
||||
vCol.push_back( LIME) ;
|
||||
#if DEBUG_SYNCLINES
|
||||
PtrOwner<IGeoPoint3d> ptGeo2( CreateGeoPoint3d()) ; ptGeo2->Set( ptCurr2) ;
|
||||
PtrOwner<IGeoVector3d> vtGeo2( CreateGeoVector3d()) ; vtGeo2->Set( 5. * vtCurr2, ptCurr2) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( ptGeo2)) ;
|
||||
pGeomDB->AddGeoObj( GDB_ID_NULL, nLay2, Release( vtGeo2)) ;
|
||||
#endif
|
||||
vSyncLines.emplace_back( ptCurr1, ptCurr2) ;
|
||||
|
||||
// --- Analisi degli spigoli all'interno della Quadrangolazione corrente ---
|
||||
// NB. Non è sempre detto che uno spigolo di una curva sia sincronizzato con lo spigolo di un'altra ( se questi esistono)...
|
||||
// Pertanto la Bezier Ruled ricavata non è detto che sia in grado di approssimare lo spigolo correttamente, potrebbe sdondarlo
|
||||
//// Inserisco le curve di sincronizzazione nel Layer di destinazine
|
||||
//PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( ptCurr1, ptCurr2) ;
|
||||
//pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrp, Release( pLine)) ;
|
||||
|
||||
// --- Analisi degli spigoli all'interno della Quadrangolazione corrente ---
|
||||
// NB. Non è sempre detto che uno spigolo di una curva sia sincronizzato con lo spigolo di un'altra ( se questi esistono)...
|
||||
// Pertanto la Bezier Ruled ricavata non è detto che sia in grado di approssimare lo spigolo correttamente, potrebbe sdondarlo
|
||||
PtrOwner<ICurveComposite> pCrvQuad1( ConvertCurveToComposite( pCrvEdge1->CopyParamRange( dUPrev1, dUCurr1))) ;
|
||||
PtrOwner<ICurveComposite> pCrvQuad2( ConvertCurveToComposite( pCrvEdge2->CopyParamRange( dUPrev2, dUCurr2))) ;
|
||||
BIPNTVECTOR vEdgeSyncLines ;
|
||||
ManageEdgesInQuadrangulation( pCrvQuad1, pCrvQuad2, vEdgeSyncLines) ;
|
||||
#if SAVEPACEDISO
|
||||
for ( int i = 0 ; i < ssize( vEdgeSyncLines) ; ++ i) {
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( vEdgeSyncLines[i].first, vEdgeSyncLines[i].second) ;
|
||||
vGeo.push_back( Release( pLine)) ;
|
||||
vCol.push_back( GREEN) ;
|
||||
}
|
||||
#endif
|
||||
//for ( int i = 0 ; i < ssize( vEdgeSyncLines) ; ++ i) {
|
||||
// PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( vEdgeSyncLines[i].first, vEdgeSyncLines[i].second) ;
|
||||
// int nNewId = pGeomDB->AddGeoObj( GDB_ID_NULL, nDestGrp, Release( pLine)) ;
|
||||
// pGeomDB->SetMaterial( nNewId, GREEN) ;
|
||||
//}
|
||||
|
||||
// --- Aggiunta di Linee di Sync all'interno della Quandrangolazione corrente ---
|
||||
// Perchè parametrizzando per la lunghezza i SottoTratti ricavati, nel caso di elevate variazioni angolari tra l'inizio e la fine
|
||||
// ( tra due curva di Sync) si potrebbero generare delle torsioni non volute
|
||||
// -->! NB. Queste linee vengono create considerando le SubQuadrangolazioni con gli Spigoli. !<--
|
||||
// --- Aggiunta di Linee di Sync all'interno della Quandrangolazione corrente ---
|
||||
// Perchè parametrizzando per la lunghezza i SottoTratti ricavati, nel caso di elevate variazioni angolari tra l'inizio e la fine
|
||||
// ( tra due curva di Sync) si potrebbero generare delle torsioni non volute
|
||||
// -->! NB. Queste linee vengono create considerando le SubQuadrangolazioni con gli Spigoli. !<--
|
||||
BIPNTVECTOR vTwistSyncLines ;
|
||||
if ( vEdgeSyncLines.empty())
|
||||
ManageTwistInQuadrangulation( pCrvQuad1, pCrvQuad2, vTwistSyncLines) ;
|
||||
@@ -6593,7 +6575,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
SyncLineNext.first = vEdgeSyncLines[i].first ;
|
||||
SyncLineNext.second = vEdgeSyncLines[i].second ;
|
||||
}
|
||||
// Recupero i parametri correnti
|
||||
// Recupero i parametri correnti
|
||||
double dUS1, dUE1, dUS2, dUE2 ;
|
||||
pCrvQuad1->GetParamAtPoint( SyncLinePrev.first, dUS1) ;
|
||||
pCrvQuad2->GetParamAtPoint( SyncLinePrev.second, dUS2) ;
|
||||
@@ -6602,22 +6584,15 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
PtrOwner<ICurveComposite> pCrvSubQuad1( ConvertCurveToComposite( pCrvQuad1->CopyParamRange( dUS1, dUE1))) ;
|
||||
PtrOwner<ICurveComposite> pCrvSubQuad2( ConvertCurveToComposite( pCrvQuad2->CopyParamRange( dUE1, dUE2))) ;
|
||||
ManageTwistInQuadrangulation( pCrvSubQuad1, pCrvSubQuad2, vTwistSyncLines) ;
|
||||
// Aggiorno i parametri
|
||||
// Aggiorno i parametri
|
||||
SyncLinePrev = SyncLineNext ;
|
||||
}
|
||||
}
|
||||
// aggiungo le nuove curve ( non importa che siano in ordine di parametro)
|
||||
vSyncLines.insert( vSyncLines.end(), vEdgeSyncLines.begin(), vEdgeSyncLines.end()) ;
|
||||
vSyncLines.insert( vSyncLines.end(), vTwistSyncLines.begin(), vTwistSyncLines.end()) ;
|
||||
#if SAVEPACEDISO
|
||||
for ( int i = 0 ; i < ssize( vTwistSyncLines) ; ++ i) {
|
||||
PtrOwner<ICurveLine> pLine( CreateCurveLine()) ; pLine->Set( vTwistSyncLines[i].first, vTwistSyncLines[i].second) ;
|
||||
vGeo.push_back( Release( pLine)) ;
|
||||
vCol.push_back( OLIVE) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Aggiorno i parametri
|
||||
// Aggiorno i parametri
|
||||
ptPrev1 = ptCurr1 ; dUPrev1 = dUCurr1 ; dLenPrev1 = dLenCurr1 ;
|
||||
ptPrev2 = ptCurr2 ; dUPrev2 = dUCurr2 ; dLenPrev2 = dLenCurr2 ;
|
||||
}
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@
|
||||
#define DEBUG_EDGES 0
|
||||
#define DEBUG_SHAPE_STM 0
|
||||
#define DEBUG_HOLES 0
|
||||
#define DEBUG_SMOOTH_CURVATURE 1
|
||||
#define DEBUG_SMOOTH_CURVATURE 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_SYNC_INTERPOLATION || \
|
||||
|
||||
Reference in New Issue
Block a user