EgtGeomKernel :
- migliorie e correzioni a RuledSmooth.
This commit is contained in:
+60
-19
@@ -2703,6 +2703,18 @@ GetChainedCurves( ICRVCOMPOPOVECTOR& vCrv, double dChainTol, bool bAllowInvert)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
double
|
||||
CalcWeightVal( double dLen, const ICurve* pCrv, const Vector3d vtCurr1, const Point3d& ptCurr1, double dCoeff, double dMyDist, double& dUStep2)
|
||||
{
|
||||
pCrv->GetParamAtLength( dLen, dUStep2) ;
|
||||
Point3d ptStep2 ; Vector3d vtStep2 = V_NULL ;
|
||||
pCrv->GetPointD1D2( dUStep2, ICurve::FROM_MINUS, ptStep2, &vtStep2) ; vtStep2.Normalize() ;
|
||||
double dStepCos2 = vtCurr1 * vtStep2 ;
|
||||
double dDist = Dist( ptCurr1, ptStep2) ;
|
||||
return (1 - dStepCos2) + dCoeff * dDist / dMyDist ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
GetIsoPointOnSecondCurve( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, double dUCurr1, double& dUCurr2, double dMyDist, double dUPrev2,
|
||||
@@ -2711,6 +2723,7 @@ GetIsoPointOnSecondCurve( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, doub
|
||||
Point3d ptCurr1 ;
|
||||
Vector3d vtCurr1 ;
|
||||
pCrvEdge1->GetPointD1D2( dUCurr1, ICurve::FROM_MINUS, ptCurr1, &vtCurr1) ;
|
||||
vtCurr1.Normalize() ;
|
||||
// --- Piano di taglio per punto a minima distanza
|
||||
IntersCurvePlane ICP( *pCrvEdge2, ptCurr1, vtCurr1) ;
|
||||
int nIndParCloser = - 1, nIndPointCloser = -1 ;
|
||||
@@ -2786,31 +2799,59 @@ GetIsoPointOnSecondCurve( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2, doub
|
||||
|
||||
// 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)
|
||||
const double COS_SMALL_ANG_TOL = cos( 4. * DEGTORAD) ;
|
||||
double dSearchLen = dMyDist / 2 ;
|
||||
int NUM_STEP = 10 ;
|
||||
const double dCoeff = 0.1 ;
|
||||
double dCos = vtCurr1 * vtCurr2 ;
|
||||
double dDistCurr = Dist( ptCurr1, ptCurr2) ;
|
||||
double dMin = (1 - dCos) + dCoeff * dDistCurr / dMyDist ;
|
||||
double bUpdated = false ;
|
||||
// se poco fuori tolleranza controllo se ho un punto abbastanza vicino con la stessa tangente
|
||||
if ( vtCurr1 * vtCurr2 < COS_SMALL_ANG_TOL) {
|
||||
// Se tanto fuori dalla tolleranza, recupero il miglior versore tangente sul secondo bordo nell'intervallo successivo di lunghezza ( 2. * dMyDist)
|
||||
if ( vtCurr1 * vtCurr2 < COS_ANG_TOL) {
|
||||
dSearchLen = dMyDist ;
|
||||
NUM_STEP = 20 ;
|
||||
}
|
||||
pCrvEdge2->GetLengthAtPoint( ptCurr2, dLenCurr2) ;
|
||||
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. ;
|
||||
double dLimInfLen2 = Clamp( dLenCurr2 - dSearchLen, dLenPrev2, dLen2) ;
|
||||
double dLimSupLen2 = Clamp( dLenCurr2 + dSearchLen, dLenPrev2, dLen2) ;
|
||||
|
||||
// faccio un campionamento grossolano e poi campiono più finemente in prossimità dei minimi
|
||||
DBLVECTOR vVal ;
|
||||
for ( int i = 0 ; i <= NUM_STEP ; ++ i) {
|
||||
double dLen = dLimInfLen2 + i * ( dLimSupLen2 - dLimInfLen2) / NUM_STEP ;
|
||||
double dUStep2 ; pCrvEdge2->GetParamAtLength( dLen, dUStep2) ;
|
||||
Point3d ptStep2 ; Vector3d vtStep2 = V_NULL ;
|
||||
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)) ;
|
||||
double dCosTol = 1. - cos( dAngTol * DEGTORAD) ;
|
||||
if ( dStepCos2 + dCosTol > dMinCos) {
|
||||
ptCurr2 = ptStep2 ;
|
||||
vtCurr2 = vtStep2 ;
|
||||
double dUStep2 ;
|
||||
vVal.push_back( CalcWeightVal( dLen, pCrvEdge2, vtCurr1, ptCurr1, dCoeff, dMyDist, dUStep2)) ;
|
||||
if ( vVal.back() < dMin) {
|
||||
dMin = vVal.back() ;
|
||||
dUCurr2 = dUStep2 ;
|
||||
dMinCos = dStepCos2 + dCosTol ;
|
||||
}
|
||||
}
|
||||
DBLDBLVECTOR vInterv ;
|
||||
for ( int i = 1 ; i < ssize(vVal) - 1 ; ++i) {
|
||||
if ( vVal[i] < vVal[i-1] && vVal[i] < vVal[i+1])
|
||||
vInterv.emplace_back( dLimInfLen2 + ( i - 1) * ( dLimSupLen2 - dLimInfLen2) / NUM_STEP,
|
||||
dLimInfLen2 + ( i + 1) * ( dLimSupLen2 - dLimInfLen2) / NUM_STEP) ;
|
||||
}
|
||||
if ( ssize( vInterv) != 0) {
|
||||
for ( int j = 0 ; j < ssize( vInterv) ; ++j) {
|
||||
for ( int i = 0 ; i <= NUM_STEP ; ++ i) {
|
||||
double dLen = vInterv[j].first + i * ( vInterv[j].second - vInterv[j].first) / NUM_STEP ;
|
||||
double dUStep2 ;
|
||||
double dVal = CalcWeightVal( dLen, pCrvEdge2, vtCurr1, ptCurr1, dCoeff, dMyDist, dUStep2) ;
|
||||
if ( dVal < dMin) {
|
||||
dUCurr2 = dUStep2 ;
|
||||
dMin = dVal ;
|
||||
bUpdated = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se il parametro è cambiato devo ricalcolare la lunghezza, che viene restituita
|
||||
if ( bUpdated)
|
||||
pCrvEdge2->GetLengthAtParam( dUCurr2, dLenCurr2) ;
|
||||
return true ;
|
||||
}
|
||||
+55
-137
@@ -5976,103 +5976,6 @@ CalcSyncPointFromEdge( const SHARPEDGEVECTOR& vSharpEdge, const ICurveComposite*
|
||||
return true ;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Calcolo della curva di Sync tra un punto di una curva di Bordo (calcolato come il punto a curvatura massima) e il suo
|
||||
// associato sull'altra Curva di Bordo
|
||||
// -> Restituisce la singola Linea di Sincronizzazione
|
||||
static bool
|
||||
CalcSyncPointFromCurvature( const CurvaturePoint& PointK, const ICurveComposite* pCompoSubEdge, BIPOINT& SyncLine)
|
||||
{
|
||||
// Verifico la validità del SubEdge su cui trovare il punto di Sincronizzazione
|
||||
if ( pCompoSubEdge == nullptr || ! pCompoSubEdge->IsValid())
|
||||
return false ;
|
||||
|
||||
// --- Piano di taglio per punto a distanza minima
|
||||
double dUCurrSubEdge = 0. ;
|
||||
IntersCurvePlane ICP( *pCompoSubEdge, PointK.ptCurvature, Media( PointK.vtTanPrev, PointK.vtTanNext)) ;
|
||||
int nIndParCloser = -1, nIndPointCloser = -1 ;
|
||||
double dSqMinDist = INFINITO ;
|
||||
for ( int nInfo = 0 ; nInfo < ICP.GetIntersCount() ; ++ nInfo) {
|
||||
IntCrvPlnInfo aInfo ;
|
||||
if ( ICP.GetIntCrvPlnInfo( nInfo, aInfo)) {
|
||||
if ( nIndParCloser == -1)
|
||||
nIndParCloser = nInfo ;
|
||||
double dSqDist = SqDist( PointK.ptCurvature, aInfo.Ici[0].ptI) ;
|
||||
if ( dSqDist < dSqMinDist) {
|
||||
dSqMinDist = dSqDist ;
|
||||
nIndPointCloser = nInfo ;
|
||||
}
|
||||
}
|
||||
}
|
||||
bool bOkPlane = ( nIndParCloser != -1 && nIndPointCloser != -1) ;
|
||||
if ( bOkPlane) {
|
||||
// Se gli indici sono tra loro coerenti allora ho individuato il punto
|
||||
if ( nIndParCloser == nIndPointCloser) {
|
||||
IntCrvPlnInfo aInfo ;
|
||||
ICP.GetIntCrvPlnInfo( nIndParCloser, aInfo) ;
|
||||
dUCurrSubEdge = aInfo.Ici[0].dU ;
|
||||
}
|
||||
// Se gli indici sono discordi, devo scegliere quale dei due punti tenere
|
||||
else {
|
||||
// scelgo il punto più vicino al corrente
|
||||
IntCrvPlnInfo aInfoPt, aInfoPar ;
|
||||
ICP.GetIntCrvPlnInfo( nIndPointCloser, aInfoPt) ;
|
||||
ICP.GetIntCrvPlnInfo( nIndParCloser, aInfoPar) ;
|
||||
dUCurrSubEdge = ( SqDist( PointK.ptCurvature, aInfoPt.Ici[0].ptI) < SqDist( PointK.ptCurvature, aInfoPar.Ici[0].ptI) ?
|
||||
aInfoPt.Ici[0].dU : aInfoPar.Ici[0].dU) ;
|
||||
}
|
||||
}
|
||||
if ( ! bOkPlane) {
|
||||
// --- Altrimenti, cerco il punto a minima distanza
|
||||
DistPointCurve DPC( PointK.ptCurvature, *pCompoSubEdge) ;
|
||||
int nFlag ;
|
||||
bool bOkMinDist = ( DPC.GetParamAtMinDistPoint( 0., dUCurrSubEdge, nFlag)) ;
|
||||
if ( ! bOkMinDist) {
|
||||
// --- Alla peggio mi posiziono a metà tra la posizione corrente e quella finale
|
||||
double dPrevLen ; pCompoSubEdge->GetLengthAtParam( 0., dPrevLen) ;
|
||||
double dLen ; pCompoSubEdge->GetLength( dLen) ;
|
||||
pCompoSubEdge->GetParamAtLength( ( dPrevLen + dLen) / 2., dUCurrSubEdge) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Definisco il primo estremo della linea di Sincronizzazione corrente
|
||||
SyncLine.first = PointK.ptCurvature ;
|
||||
|
||||
// Verifico se posso muovermi attorno al punto trovato per allinearmi meglio con le normali alla curva
|
||||
// NB. Si cerca di privilgiare i punti più vicini ( in parametro) al punto calcolato sopra, in modo da cercare di
|
||||
// non discostare troppo la Linea di sincronizzazione dal punto trovato.
|
||||
const double MAX_DIST = 2.5 ;
|
||||
const int NUM_SAMPLE_PNT = 20 ;
|
||||
double dLen ; pCompoSubEdge->GetLength( dLen) ;
|
||||
double dSyncLen ; pCompoSubEdge->GetLengthAtParam( dUCurrSubEdge, dSyncLen) ;
|
||||
Vector3d vtSyncTanPrev, vtSyncTanNext ;
|
||||
pCompoSubEdge->GetPointD1D2( dUCurrSubEdge, ICurve::FROM_MINUS, SyncLine.second, &vtSyncTanPrev) ; vtSyncTanPrev.Normalize() ;
|
||||
pCompoSubEdge->GetPointD1D2( dUCurrSubEdge, ICurve::FROM_PLUS, SyncLine.second, &vtSyncTanNext) ; vtSyncTanNext.Normalize() ;
|
||||
double dLimInfLen = Clamp( dSyncLen - MAX_DIST, 0., dLen) ;
|
||||
double dLimSupLen = Clamp( dSyncLen + MAX_DIST, 0., dLen) ;
|
||||
int nSamplePnt = int( ceil( NUM_SAMPLE_PNT / 4.)) ;
|
||||
double dMaxCos = ( Media( PointK.vtTanPrev, PointK.vtTanNext) * Media( vtSyncTanPrev, vtSyncTanNext)) ;
|
||||
double dShiftR = ( dLimSupLen - dSyncLen) / nSamplePnt ;
|
||||
double dShiftL = ( dSyncLen - dLimInfLen) / nSamplePnt ;
|
||||
array<double, 2> vdLens = { dSyncLen, dSyncLen} ;
|
||||
for ( int i = 1 ; i <= nSamplePnt ; ++ i) {
|
||||
vdLens[0] += dShiftR ;
|
||||
vdLens[1] -= dShiftL ;
|
||||
for ( int j = 0 ; j < 2 ; ++ j) {
|
||||
double dU ; pCompoSubEdge->GetParamAtLength( vdLens[j], dU) ;
|
||||
Point3d ptCurr ; Vector3d vtTan ;
|
||||
pCompoSubEdge->GetPointD1D2( dU, ICurve::FROM_MINUS, ptCurr, &vtTan) ; vtTan.Normalize() ;
|
||||
double dCos = ( vtTan * Media( PointK.vtTanPrev, PointK.vtTanNext)) ;
|
||||
if ( dCos > dMaxCos) {
|
||||
dMaxCos = dCos ;
|
||||
SyncLine.second = ptCurr ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Gestione degli spigoli all'interno della Quadrangolazione corrente
|
||||
static bool
|
||||
@@ -6184,7 +6087,7 @@ ManageEdgesInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
// ---------------------------------------------------------------------------
|
||||
// Calcolo delle Curve di Sync per evitare Twist
|
||||
static bool
|
||||
ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComposite* pSubEdge2, BIPNTVECTOR& vSyncLines)
|
||||
ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComposite* pSubEdge2, BIPNTVECTOR& vSyncLines, bool& bEraseLastIso)
|
||||
{
|
||||
// Verifica validità delle curve
|
||||
if ( pSubEdge1 == nullptr || ! pSubEdge1->IsValid() || pSubEdge2 == nullptr || ! pSubEdge2->IsValid())
|
||||
@@ -6192,6 +6095,7 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
|
||||
const double COS_LIMIT = cos( 50. * DEGTORAD) ;
|
||||
const int NUM_SAMPLE_PNT = 20 ;
|
||||
const int nStepSkip = NUM_SAMPLE_PNT / 10 ;
|
||||
#if DEBUG_CURVATURE
|
||||
vector<pair<Point3d, double>> _vPtK1 ;
|
||||
vector<pair<Point3d, double>> _vPtK2 ;
|
||||
@@ -6203,13 +6107,16 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
Vector3d vtS1 ; pSubEdge1->GetStartDir( vtS1) ;
|
||||
Vector3d vtE1 ; pSubEdge1->GetEndDir( vtE1) ;
|
||||
double dLen1 = - EPS_SMALL ;
|
||||
double dLen2 = - EPS_SMALL ;
|
||||
pSubEdge1->GetLength( dLen1) ;
|
||||
pSubEdge2->GetLength( dLen2) ;
|
||||
double dMyDist = min( dLen1, dLen2) * 0.85 ;
|
||||
bool bSplit1 = ( vtS1 * vtE1 < COS_LIMIT) ;
|
||||
if ( bSplit1) {
|
||||
// Individuo il punto a Curvatura Massima
|
||||
pSubEdge1->GetLength( dLen1) ;
|
||||
double dKMax1 = - INFINITO + 1, dUK1Max = - EPS_SMALL ;
|
||||
Point3d ptKMax1 ; Vector3d vtTanKMax1Prev, vtTanKMax1Next ;
|
||||
for ( int i = 0 ; i <= NUM_SAMPLE_PNT ; ++ i) {
|
||||
for ( int i = nStepSkip ; i <= NUM_SAMPLE_PNT - nStepSkip ; ++ i) {
|
||||
// Ricavo la Lunghezza corrente e il parametro dU associato
|
||||
double dCurrLen1 = Clamp( i * ( dLen1 / NUM_SAMPLE_PNT), 0., dLen1) ;
|
||||
double dUCurr1 ; pSubEdge1->GetParamAtLength( dCurrLen1, dUCurr1) ;
|
||||
@@ -6237,22 +6144,21 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
vtTanKMax1Next.Normalize() ;
|
||||
// Calcolo la nuova linea di sincronizzazione
|
||||
CurvaturePoint myCurvaturePoint( dUK1Max, ptKMax1, vtTanKMax1Prev, vtTanKMax1Next) ;
|
||||
BIPOINT SyncLine ;
|
||||
CalcSyncPointFromCurvature( myCurvaturePoint, pSubEdge2, SyncLine) ;
|
||||
vSyncLines.emplace_back( SyncLine) ;
|
||||
double dUOn2 ; double dLenCurr2 ;
|
||||
GetIsoPointOnSecondCurve( pSubEdge1, pSubEdge2, dUK1Max, dUOn2, dMyDist, 0, 0, dLenCurr2, dLen2) ;
|
||||
Point3d ptOn2 ; pSubEdge2->GetPointD1D2( dUOn2, ICurve::FROM_MINUS, ptOn2) ;
|
||||
vSyncLines.emplace_back( ptKMax1, ptOn2) ;
|
||||
}
|
||||
|
||||
// --- Verifico il cambiamento di Deviazione angolare tra Inizio-Fine del tratto per la prima curva di Bordo
|
||||
Vector3d vtS2 ; pSubEdge2->GetStartDir( vtS2) ;
|
||||
Vector3d vtE2 ; pSubEdge2->GetEndDir( vtE2) ;
|
||||
double dLen2 = - EPS_SMALL ;
|
||||
bool bSplit2 = ( vtS2 * vtE2 < COS_LIMIT) ;
|
||||
if ( bSplit2) {
|
||||
// Individuo il punto a Curvatura Massima
|
||||
pSubEdge2->GetLength( dLen2) ;
|
||||
double dKMax2 = - INFINITO + 1, dUK2Max = - EPS_SMALL ;
|
||||
Point3d ptKMax2 ; Vector3d vtTanKMax2Prev, vtTanKMax2Next ;
|
||||
for ( int i = 0 ; i <= NUM_SAMPLE_PNT ; ++ i) {
|
||||
for ( int i = nStepSkip ; i <= NUM_SAMPLE_PNT - nStepSkip ; ++ i) {
|
||||
// Ricavo la Lunghezza corrente e il parametro dU associato
|
||||
double dCurrLen2 = Clamp( i * ( dLen2 / NUM_SAMPLE_PNT), 0., dLen2) ;
|
||||
double dUCurr2 ; pSubEdge2->GetParamAtLength( dCurrLen2, dUCurr2) ;
|
||||
@@ -6280,11 +6186,10 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
vtTanKMax2Next.Normalize() ;
|
||||
// Calcolo la nuova linea di sincronizzazione
|
||||
CurvaturePoint myCurvaturePoint( dUK2Max, ptKMax2, vtTanKMax2Prev, vtTanKMax2Next) ;
|
||||
BIPOINT SyncLine ;
|
||||
CalcSyncPointFromCurvature( myCurvaturePoint, pSubEdge1, SyncLine) ;
|
||||
// !<-- Inverto la curva di Sincronizzaione per coerenza con la prima -->!
|
||||
swap( SyncLine.first, SyncLine.second) ;
|
||||
vSyncLines.emplace_back( SyncLine) ;
|
||||
double dUOn1 ; double dLenCurr1 ;
|
||||
GetIsoPointOnSecondCurve( pSubEdge2, pSubEdge1, dUK2Max, dUOn1, dMyDist, 0, 0, dLenCurr1, dLen1) ;
|
||||
Point3d ptOn1 ; pSubEdge1->GetPointD1D2( dUOn1, ICurve::FROM_MINUS, ptOn1) ;
|
||||
vSyncLines.emplace_back( ptOn1, ptKMax2) ;
|
||||
}
|
||||
|
||||
#if DEBUG_CURVATURE // Curvatura minima -> AQUA | Curvatura massima -> ORANGE
|
||||
@@ -6338,17 +6243,25 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
// NB. Risultano ridondanti, creano SottoQuadrangolazioni molto strette o possono Inclinare eccssivamente l'Utensile
|
||||
// NB. Così facendo evito anche di creare curve di Sync lungo le diagonali della Quadrangolazione
|
||||
const double LEN_TOL = 2. ;
|
||||
const double dParTol = 0.1 ;
|
||||
double dLenPrev1 = - LEN_TOL, dLenPrev2 = - LEN_TOL ;
|
||||
for ( int i = 0 ; i < ssize( vSyncLines) ; ++ i) {
|
||||
double dSyncLen1 ; pSubEdge1->GetLengthAtPoint( vSyncLines[i].first, dSyncLen1, TOL) ;
|
||||
bool bErase = ( dSyncLen1 < max( LEN_TOL, 0.2 * dLen1) || dSyncLen1 > min( dLen1 - LEN_TOL, 0.8 * dLen1)) ;
|
||||
bool bErase = ( dSyncLen1 < max( LEN_TOL, dParTol * dLen1) || dSyncLen1 - dLenPrev1 < LEN_TOL) ;
|
||||
bEraseLastIso = dSyncLen1 > min( dLen1 - LEN_TOL, ( 1 - dParTol) * dLen1) ;
|
||||
if ( ! bErase) {
|
||||
double dSyncLen2 ; pSubEdge2->GetLengthAtPoint( vSyncLines[i].second, dSyncLen2, TOL) ;
|
||||
bErase = ( dSyncLen2 < max( LEN_TOL, 0.2 * dLen2) || dSyncLen2 > min( dLen2 - LEN_TOL, 0.8 * dLen2)) ;
|
||||
bErase = ( dSyncLen2 < max( LEN_TOL, dParTol * dLen2) || dSyncLen2 - dLenPrev2 < LEN_TOL) ;
|
||||
bEraseLastIso = bEraseLastIso || dSyncLen2 > min( dLen2 - LEN_TOL, ( 1 - dParTol) * dLen2) ;
|
||||
dLenPrev2 = dSyncLen2 ;
|
||||
}
|
||||
if ( bErase) {
|
||||
if ( bErase && ! bEraseLastIso) {
|
||||
vSyncLines.erase( vSyncLines.begin() + i) ;
|
||||
-- i ;
|
||||
}
|
||||
dLenPrev1 = dSyncLen1 ;
|
||||
if ( bEraseLastIso)
|
||||
break ;
|
||||
}
|
||||
if ( vSyncLines.empty())
|
||||
return true ;
|
||||
@@ -6374,6 +6287,10 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
vSyncLines.pop_back() ; // lascio solo la prima... ( bisognerebbe scegliere quale lasciare con un criterio migliore ?)
|
||||
}
|
||||
|
||||
// se ne ho due tengo solo la prima
|
||||
if ( ssize( vSyncLines) == 2)
|
||||
vSyncLines.pop_back() ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
@@ -6420,11 +6337,11 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
// 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 ;
|
||||
// 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() ;
|
||||
|
||||
@@ -6437,14 +6354,17 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
|
||||
GetIsoPointOnSecondCurve( pCrvEdge1, pCrvEdge2, dUCurr1, dUCurr2, dMyDist, dUPrev2, dLenPrev2, dLenCurr2, dLen2) ;
|
||||
|
||||
//////////////////////////N.B.: se si aggiunge questo pezzo bisogna anche gestire il fatto che i punti precedentemente aggiunti potrebbero non stare più sulla curva modificata!!!
|
||||
//// 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 ( abs( dLenCurr2 - dLenAlt2) < 1) {
|
||||
// Point3d ptNewJoint ; pCrvEdge2->GetPointD1D2( dUCurr2, ICurve::FROM_MINUS, ptNewJoint) ;
|
||||
// if ( pCrvEdge2->ModifyJoint( int( dUClosestJoint2), ptNewJoint))
|
||||
// dUCurr2 = dUClosestJoint2 ;
|
||||
//}
|
||||
|
||||
|
||||
pCrvEdge2->GetPointD1D2( dUCurr2, ICurve::FROM_MINUS, ptCurr2, &vtCurr2) ;
|
||||
|
||||
#if DEBUG_SYNCLINES
|
||||
@@ -6455,10 +6375,6 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
#endif
|
||||
vSyncLines.emplace_back( ptCurr1, ptCurr2) ;
|
||||
|
||||
//// 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
|
||||
@@ -6466,19 +6382,15 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
PtrOwner<ICurveComposite> pCrvQuad2( ConvertCurveToComposite( pCrvEdge2->CopyParamRange( dUPrev2, dUCurr2))) ;
|
||||
BIPNTVECTOR vEdgeSyncLines ;
|
||||
ManageEdgesInQuadrangulation( pCrvQuad1, pCrvQuad2, vEdgeSyncLines) ;
|
||||
//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. !<--
|
||||
BIPNTVECTOR vTwistSyncLines ;
|
||||
bool bEraseLastIso = false ;
|
||||
if ( vEdgeSyncLines.empty())
|
||||
ManageTwistInQuadrangulation( pCrvQuad1, pCrvQuad2, vTwistSyncLines) ;
|
||||
ManageTwistInQuadrangulation( pCrvQuad1, pCrvQuad2, vTwistSyncLines, bEraseLastIso) ;
|
||||
else {
|
||||
BIPOINT SyncLinePrev, SyncLineNext ;
|
||||
pCrvQuad1->GetStartPoint( SyncLinePrev.first) ;
|
||||
@@ -6500,12 +6412,20 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
pCrvQuad2->GetParamAtPoint( SyncLineNext.second, dUE2) ;
|
||||
PtrOwner<ICurveComposite> pCrvSubQuad1( ConvertCurveToComposite( pCrvQuad1->CopyParamRange( dUS1, dUE1))) ;
|
||||
PtrOwner<ICurveComposite> pCrvSubQuad2( ConvertCurveToComposite( pCrvQuad2->CopyParamRange( dUE1, dUE2))) ;
|
||||
ManageTwistInQuadrangulation( pCrvSubQuad1, pCrvSubQuad2, vTwistSyncLines) ;
|
||||
ManageTwistInQuadrangulation( pCrvSubQuad1, pCrvSubQuad2, vTwistSyncLines, bEraseLastIso) ;
|
||||
// Aggiorno i parametri
|
||||
SyncLinePrev = SyncLineNext ;
|
||||
}
|
||||
bEraseLastIso = false ;
|
||||
}
|
||||
// aggiungo le nuove curve ( non importa che siano in ordine di parametro)
|
||||
if ( bEraseLastIso) {
|
||||
vSyncLines.pop_back() ;
|
||||
double dQuadLen1 ; pCrvQuad1->GetLengthAtPoint( vTwistSyncLines[0].first, dQuadLen1) ;
|
||||
dLenCurr1 = dLenPrev1 + dQuadLen1 ;
|
||||
double dQuadLen2 ; pCrvQuad2->GetLengthAtPoint( vTwistSyncLines[0].second, dQuadLen2) ;
|
||||
dLenCurr2 = dLenPrev2 + dQuadLen2 ;
|
||||
}
|
||||
// aggiungo le nuove curve ( non importa che siano ordinate per parametro)
|
||||
vSyncLines.insert( vSyncLines.end(), vEdgeSyncLines.begin(), vEdgeSyncLines.end()) ;
|
||||
vSyncLines.insert( vSyncLines.end(), vTwistSyncLines.begin(), vTwistSyncLines.end()) ;
|
||||
|
||||
@@ -6518,8 +6438,6 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
SaveGeoObj( vGeo, vCol, "D:\\Temp\\bezier\\ruled\\trimming\\smooth.nge") ;
|
||||
#endif
|
||||
|
||||
|
||||
// devo riempire vSyncLines
|
||||
return CreateByIsoParamSet( pCrvEdge1, pCrvEdge2, vSyncLines) ;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user