EgtGeomKernel :
- miglioramenti alla regolarize.
This commit is contained in:
+263
-252
@@ -63,7 +63,7 @@
|
||||
#define DEBUG_EDGES 0
|
||||
#define DEBUG_SHAPE_STM 0
|
||||
#define DEBUG_HOLES 0
|
||||
#define DEBUG_SMOOTH_CURVATURE 0
|
||||
#define DEBUG_SMOOTH_CURVATURE 1
|
||||
#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 || \
|
||||
@@ -4943,9 +4943,10 @@ RemoveInflexionPoints( PNTVECTOR& vPnt, PNTINFOVECTOR& vPntInfo, PNTINFOVECTOR&
|
||||
// se trovo tre punti di fila che sono dallo stesso lato, opposto a quello degli altri punti attorno, allora cerco di spostarli lungo la
|
||||
// normale alla superficie in modo da evitare cambi di concavità
|
||||
bool bSameSideAsPrev = true ;
|
||||
double dSmallDist = 5 * EPS_SMALL ;
|
||||
for ( int i = 2 ; i < ssize( vPntInfo) - 2 ; ++i) {
|
||||
// se è un punto di split o sta sulla curva vado avanti
|
||||
if ( vPntInfo[i].dDist < EPS_ZERO)
|
||||
if ( vPntInfo[i].dDist < dSmallDist)
|
||||
continue ;
|
||||
int nPrev = vPntInfo[i-1].dDist < EPS_ZERO ? i - 2 : i - 1 ;
|
||||
double dProj = vPntInfo[i].vtPos * vPntInfo[nPrev].vtPos ;
|
||||
@@ -4972,23 +4973,29 @@ RemoveInflexionPoints( PNTVECTOR& vPnt, PNTINFOVECTOR& vPntInfo, PNTINFOVECTOR&
|
||||
int nNext = bCurrOrPrev ? i + 2 : i + 1 ;
|
||||
// se il successivo è diverso ho un terzetto anomalo da aggiustare
|
||||
// altrimenti ho un cambio naturale di concavità
|
||||
if ( vPntInfo[i].vtPos * vPntInfo[nNext].vtPos < 0) {
|
||||
if ( vPntInfo[i].vtPos * vPntInfo[nNext].vtPos < 0 || vPntInfo[nNext].dDist < dSmallDist) {
|
||||
// ruoto il terzetto fino a matchare la tangente sull'altra curva
|
||||
Vector3d vtCurr = vPntInfo[nNext].pt - vPntInfo[i].pt ;
|
||||
Vector3d vtRef = vPntRefInfo[nNext].pt - vPntRefInfo[i].pt ;
|
||||
Vector3d vtAx = vPntRefInfo[nSecond].pt - vPntInfo[nSecond].pt ;
|
||||
bool bDet = false ;
|
||||
double dAng = 0 ; vtCurr.GetRotation(vtRef, vtAx, dAng, bDet) ;
|
||||
if ( dAng > 170) {
|
||||
dAng = 180 - dAng ;
|
||||
// devo capire quale delle due curve ha i punti di controllo incrociati (come conseguenza della correzione precedente) e rimediare
|
||||
// DA IMPLEMENTARE, eventualmente
|
||||
}
|
||||
// ruoto il punto solo se non stava già esattamente sulla SubCrv ( che suppongo essere un tratto rettilineo)
|
||||
if ( vPntInfo[nFirst].dDist > EPS_ZERO)
|
||||
if ( vPntInfo[nFirst].dDist > dSmallDist) {
|
||||
Vector3d vtCurr = vPntInfo[nSecond].pt - vPntInfo[nFirst].pt ;
|
||||
Vector3d vtRef = vPntRefInfo[nSecond].pt - vPntRefInfo[nFirst].pt ;
|
||||
Vector3d vtAx = vPntRefInfo[nSecond].pt - vPntInfo[nSecond].pt ;
|
||||
bool bDet = false ;
|
||||
double dAng = 0 ; vtCurr.GetRotation(vtRef, vtAx, dAng, bDet) ;
|
||||
if ( abs(dAng) > 170)
|
||||
dAng = 180 - dAng ;
|
||||
vPnt[nFirst].Rotate( vPnt[nSecond], vtAx, dAng) ;
|
||||
if ( vPntInfo[nThird].dDist > EPS_ZERO)
|
||||
}
|
||||
if ( vPntInfo[nThird].dDist > dSmallDist) {
|
||||
Vector3d vtCurr = vPntInfo[nThird].pt - vPntInfo[nSecond].pt ;
|
||||
Vector3d vtRef = vPntRefInfo[nThird].pt - vPntRefInfo[nSecond].pt ;
|
||||
Vector3d vtAx = vPntRefInfo[nSecond].pt - vPntInfo[nSecond].pt ;
|
||||
bool bDet = false ;
|
||||
double dAng = 0 ; vtCurr.GetRotation(vtRef, vtAx, dAng, bDet) ;
|
||||
if ( abs(dAng) > 170)
|
||||
dAng = 180 - dAng ;
|
||||
vPnt[nThird].Rotate( vPnt[nSecond], vtAx, dAng) ;
|
||||
}
|
||||
if ( bCurrOrPrev)
|
||||
i += 2 ;
|
||||
}
|
||||
@@ -4998,235 +5005,14 @@ RemoveInflexionPoints( PNTVECTOR& vPnt, PNTINFOVECTOR& vPntInfo, PNTINFOVECTOR&
|
||||
return true ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim
|
||||
// Le curve vengono modificate entro una data tolleranza, in modo che
|
||||
ISurfBezier*
|
||||
RegolarizeBordersLocally( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol)
|
||||
{
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.clear() ;
|
||||
#endif
|
||||
|
||||
// prendo per buone le isocurve di inizio e fine tratto e devo identificare tra loro le isocurve che creano troppo twist e che sono da raddrizzare
|
||||
Point3d ptS1 = bpIsoStart.first ;
|
||||
Point3d ptS2 = bpIsoEnd.first ;
|
||||
Vector3d vtDir1 = bpIsoStart.second - ptS1 ;
|
||||
Vector3d vtDir2 = bpIsoEnd.second - ptS2 ;
|
||||
double dInterpolateAngTol = 4 ;
|
||||
double dAngInterp = 0 ;
|
||||
vtDir1.GetAngle( vtDir2, dAngInterp) ;
|
||||
bool bInterpolate = dAngInterp > dInterpolateAngTol ;
|
||||
|
||||
int nDegU, nDegV, nSpanU, nSpanV ;
|
||||
bool bRat, bTrimmed ;
|
||||
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
||||
if ( nDegU != 3)
|
||||
return nullptr ;
|
||||
// individuo quali isocurve sono state indicate come inizio e fine
|
||||
PtrOwner<ICurveComposite> pCrv1( pSurfBz->GetSingleEdge3D( false, 2)) ;
|
||||
PtrOwner<ICurveComposite> pCrv2( pSurfBz->GetSingleEdge3D( false, 0)) ;
|
||||
// inverto la curva corrispondente al bordo 2 della bezier per avere le due guide concordi
|
||||
pCrv2->Invert() ;
|
||||
double dParS1 = -1 ; double dParS2 = -1 ;
|
||||
if ( ! pCrv1->GetParamAtPoint( ptS1, dParS1) || ! pCrv1->GetParamAtPoint( ptS2, dParS2))
|
||||
return nullptr ;
|
||||
int nUS1 = int ( dParS1) * nDegU ;
|
||||
int nUS2 = int ( dParS2) * nDegU ;
|
||||
bool bInverted = false ;
|
||||
if ( nUS1 > nUS2) {
|
||||
swap( nUS1, nUS2) ;
|
||||
swap( dParS1, dParS2) ;
|
||||
swap( ptS1, ptS2) ;
|
||||
swap( vtDir1, vtDir2) ;
|
||||
bInverted = true ;
|
||||
}
|
||||
PtrOwner<ICurve> pCrvOrig1( pCrv1->CopyParamRange( dParS1, dParS2)) ;
|
||||
PtrOwner<ICurve> pCrvOrig2( pCrv2->CopyParamRange( dParS1, dParS2)) ;
|
||||
|
||||
///// versione con correzioni a mano
|
||||
Point3d ptPrevS = ptS1 ;
|
||||
Point3d ptPrevE = ! bInverted ? bpIsoStart.second : bpIsoEnd.second ;
|
||||
Vector3d vtIsoPrev = ptPrevE - ptPrevS ; vtIsoPrev.Normalize() ;
|
||||
Point3d ptBez ; Vector3d vtNPrev ;
|
||||
pSurfBz->GetPointNrmD1D2( dParS1, 0.5, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez, vtNPrev) ;
|
||||
int nPoints = ( nUS2 - nUS1) * nDegU + 1 ;
|
||||
PNTVECTOR vPnt0 ; vPnt0.reserve( nPoints) ; vPnt0.push_back( ptPrevS) ;
|
||||
PNTVECTOR vPnt1 ; vPnt1.reserve( nPoints) ; vPnt1.push_back( ptPrevE) ;
|
||||
// salvo il secondo punto di controllo della patch
|
||||
bool bOk = false ;
|
||||
Point3d ptSecond1Curr = pSurfBz->GetControlPoint( nUS1 + 1, 0, &bOk) ;
|
||||
vPnt0.push_back( ptSecond1Curr) ;
|
||||
Point3d ptSecond2Curr = pSurfBz->GetControlPoint( nUS1 + 1, 1, &bOk) ;
|
||||
vPnt1.push_back( ptSecond2Curr) ;
|
||||
// scorro le isocurve di separazione tra patch
|
||||
for ( int i = nUS1 + 3 ; i < nUS2 ; i +=3) {
|
||||
// recupero precedente e successivo
|
||||
Point3d ptThird1Prev = pSurfBz->GetControlPoint( i - 1, 0, &bOk) ;
|
||||
Point3d ptThird2Prev = pSurfBz->GetControlPoint( i - 1, 1, &bOk) ;
|
||||
Point3d ptSecond1Next = pSurfBz->GetControlPoint( i + 1, 0, &bOk) ;
|
||||
Point3d ptSecond2Next = pSurfBz->GetControlPoint( i + 1, 1, &bOk) ;
|
||||
// recupero corrente e verifico la torsione
|
||||
Point3d ptCurr1 = pSurfBz->GetControlPoint( i, 0, &bOk) ;
|
||||
Point3d ptCurr2 = pSurfBz->GetControlPoint( i, 1, &bOk) ;
|
||||
Vector3d vtIsoCurr = ptCurr2 - ptCurr1 ;
|
||||
double dDist = vtIsoCurr.Len() ;
|
||||
vtIsoCurr.Normalize() ;
|
||||
Vector3d vtDirPrev = vtIsoPrev ^ vtNPrev ;
|
||||
Vector3d vtCurrInPlane = OrthoCompo( vtIsoCurr, vtDirPrev) ;
|
||||
bool bDet = false ;
|
||||
double dAng = 0 ; vtIsoPrev.GetRotation( vtCurrInPlane, vtDirPrev, dAng, bDet) ;
|
||||
double dSinAngTol = sin( 5 * DEGTORAD) ;
|
||||
Vector3d vtPrev1 = ptCurr1 - ptThird1Prev ; vtPrev1.Normalize() ;
|
||||
Vector3d vtNext1 = ptSecond1Next - ptCurr1 ; vtNext1.Normalize() ;
|
||||
bool bAngularPoint1 = ! AreSameVectorEpsilon( vtPrev1, vtNext1, dSinAngTol) ;
|
||||
Vector3d vtPrev2 = ptCurr2 - ptThird2Prev ; vtPrev2.Normalize() ;
|
||||
Vector3d vtNext2 = ptSecond2Next - ptCurr2 ; vtNext2.Normalize() ;
|
||||
bool bAngularPoint2 = ! AreSameVectorEpsilon( vtPrev2, vtNext2, dSinAngTol) ;
|
||||
if ( abs( dAng) > 0) {
|
||||
// se l'isocurva di separazione dalla patch successiva è torta rispetto alla precedente
|
||||
// allora prendo il penultimo punto della curva precedente, il punto di joint e il secondo della prossima e li sposto lungo la normale della superficie
|
||||
dDist *= dAng * DEGTORAD / 2 ;
|
||||
if ( ! bAngularPoint1) {
|
||||
// se non ho un punto angoloso muovo tutto il terzetto insieme
|
||||
ptThird1Prev += vtNPrev * dDist ;
|
||||
ptSecond1Next += vtNPrev * dDist ;
|
||||
ptCurr1 += vtNPrev * dDist ;
|
||||
}
|
||||
else {
|
||||
// altrimenti sposto solo il punto corrente verso la congiungente tra il precedente e il successivo
|
||||
DistPointLine dpl( ptCurr1, ptThird1Prev, ptSecond1Next, true) ;
|
||||
Point3d ptMinDist ; dpl.GetMinDistPoint( ptMinDist) ;
|
||||
Vector3d vtCorrDir = ptMinDist - ptCurr1 ; vtCorrDir.Normalize() ;
|
||||
double dProjDir = vtNPrev * vtCorrDir ;
|
||||
if ( dProjDir < 0)
|
||||
LOG_ERROR( GetEGkLogger(), "Error : regolarizing crv0 near an angular point") ;
|
||||
double dDistCorr = min( dDist, Dist( ptMinDist, ptCurr1)) ;
|
||||
ptCurr1 += vtCorrDir * dDistCorr ;
|
||||
}
|
||||
if ( ! bAngularPoint2) {
|
||||
ptThird2Prev -= vtNPrev * dDist ;
|
||||
ptSecond2Next -= vtNPrev * dDist ;
|
||||
ptCurr2 -= vtNPrev * dDist ;
|
||||
}
|
||||
else {
|
||||
// altrimenti sposto solo il punto corrente verso la congiungente tra il precedente e il successivo
|
||||
DistPointLine dpl( ptCurr2, ptThird2Prev, ptSecond2Next, true) ;
|
||||
Point3d ptMinDist ; dpl.GetMinDistPoint( ptMinDist) ;
|
||||
Vector3d vtCorrDir = ptMinDist - ptCurr2 ; vtCorrDir.Normalize() ;
|
||||
double dProjDir = vtNPrev * vtCorrDir ;
|
||||
if ( dProjDir < 0)
|
||||
LOG_ERROR( GetEGkLogger(), "Error : regolarizing crv1 near an angular point") ;
|
||||
double dDistCorr = min( dDist, Dist( ptMinDist, ptCurr2)) ;
|
||||
ptCurr2 -= vtCorrDir * dDistCorr ;
|
||||
}
|
||||
}
|
||||
vPnt0.push_back( ptThird1Prev) ;
|
||||
vPnt0.push_back( ptCurr1) ;
|
||||
vPnt0.push_back( ptSecond1Next) ;
|
||||
|
||||
vPnt1.push_back( ptThird2Prev) ;
|
||||
vPnt1.push_back( ptCurr2) ;
|
||||
vPnt1.push_back( ptSecond2Next) ;
|
||||
|
||||
vtIsoPrev = ptCurr2 - ptCurr1 ; vtIsoPrev.Normalize() ;
|
||||
vtNPrev = ( ptSecond1Next - ptCurr1) ^ vtIsoPrev ; vtNPrev.Normalize() ;
|
||||
}
|
||||
// aggiungo gli ultimi due punti
|
||||
Point3d ptThird1Prev = pSurfBz->GetControlPoint( nUS2 - 1, 0, &bOk) ;
|
||||
vPnt0.push_back( ptThird1Prev) ;
|
||||
Point3d ptFourth1Curr = pSurfBz->GetControlPoint( nUS2, 0, &bOk) ;
|
||||
vPnt0.push_back( ptFourth1Curr) ;
|
||||
Point3d ptThird2Prev = pSurfBz->GetControlPoint( nUS2 - 1, 1, &bOk) ;
|
||||
vPnt1.push_back( ptThird2Prev) ;
|
||||
Point3d ptFourth2Curr = pSurfBz->GetControlPoint( nUS2, 1, &bOk) ;
|
||||
vPnt1.push_back( ptFourth2Curr) ;
|
||||
|
||||
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||
for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) {
|
||||
PtrOwner<ICurveBezier> cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ;
|
||||
cb1->SetControlPoint( 0, vPnt0[i]) ;
|
||||
cb1->SetControlPoint( 1, vPnt0[i+1]) ;
|
||||
cb1->SetControlPoint( 2, vPnt0[i+2]) ;
|
||||
cb1->SetControlPoint( 3, vPnt0[i+3]) ;
|
||||
pCC1->AddCurve( Release( cb1)) ;
|
||||
|
||||
PtrOwner<ICurveBezier> cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ;
|
||||
cb2->SetControlPoint( 0, vPnt1[i]) ;
|
||||
cb2->SetControlPoint( 1, vPnt1[i+1]) ;
|
||||
cb2->SetControlPoint( 2, vPnt1[i+2]) ;
|
||||
cb2->SetControlPoint( 3, vPnt1[i+3]) ;
|
||||
pCC2->AddCurve( Release( cb2)) ;
|
||||
}
|
||||
|
||||
////// N.B.:dovrei tener conto anche della patch PRECEDENTE e SUCCESSIVA a quelle indicate, altrimenti non vedo se ho creato flessi al bordo della zona
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.push_back( pCC1->Clone()) ;
|
||||
VT.push_back( pCC2->Clone()) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized_first_step.nge") ;
|
||||
#endif
|
||||
|
||||
// ora verifico l'eventuale presenza di cambi di concavità non desiderati
|
||||
// se ne trovo su una curva e non sull'altra allora ruoto il terzetto di punti della curva con flesso in modo
|
||||
// da matchare la tangente dell'altra curva
|
||||
PNTINFOVECTOR vPntInfo1, vPntInfo2 ;
|
||||
FillPntInfo( vPnt0, pCC1, vPntInfo1) ;
|
||||
FillPntInfo( vPnt1, pCC2, vPntInfo2) ;
|
||||
|
||||
RemoveInflexionPoints( vPnt0, vPntInfo1, vPntInfo2) ;
|
||||
RemoveInflexionPoints( vPnt1, vPntInfo2, vPntInfo1) ;
|
||||
|
||||
pCC1->Clear() ;
|
||||
pCC2->Clear() ;
|
||||
for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) {
|
||||
PtrOwner<ICurveBezier> cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ;
|
||||
cb1->SetControlPoint( 0, vPnt0[i]) ;
|
||||
cb1->SetControlPoint( 1, vPnt0[i+1]) ;
|
||||
cb1->SetControlPoint( 2, vPnt0[i+2]) ;
|
||||
cb1->SetControlPoint( 3, vPnt0[i+3]) ;
|
||||
pCC1->AddCurve( Release( cb1)) ;
|
||||
|
||||
PtrOwner<ICurveBezier> cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ;
|
||||
cb2->SetControlPoint( 0, vPnt1[i]) ;
|
||||
cb2->SetControlPoint( 1, vPnt1[i+1]) ;
|
||||
cb2->SetControlPoint( 2, vPnt1[i+2]) ;
|
||||
cb2->SetControlPoint( 3, vPnt1[i+3]) ;
|
||||
pCC2->AddCurve( Release( cb2)) ;
|
||||
}
|
||||
|
||||
// controllo di essere rimasto in tolleranza
|
||||
double dErr = 0 ;
|
||||
CalcApproxError( pCrvOrig1, pCC1, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return nullptr ;
|
||||
CalcApproxError( pCrvOrig2, pCC2, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return nullptr ;
|
||||
|
||||
PtrOwner<ISurfBezier> pNewSurf( pSurfBz->Clone()) ;
|
||||
// aggiorno i punti di controllo della superficie di bezier
|
||||
for ( int i = 0 ; i < ssize( vPnt0) ; ++i) {
|
||||
pNewSurf->SetControlPoint( nUS1 + i, 0, vPnt0[i]) ;
|
||||
pNewSurf->SetControlPoint( nUS1 + i, 1, vPnt1[i]) ;
|
||||
}
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.push_back( Release(pCC1)) ;
|
||||
VT.push_back( Release(pCC2)) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
|
||||
#endif
|
||||
|
||||
return Release( pNewSurf) ;
|
||||
}
|
||||
|
||||
// Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim
|
||||
// Le curve vengono modificate entro una data tolleranza, in modo che
|
||||
ISurfBezier*
|
||||
RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol)
|
||||
{
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.clear() ;
|
||||
#endif
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.clear() ;
|
||||
#endif
|
||||
|
||||
// prendo per buone le isocurve di inizio e fine tratto e devo identificare tra loro le isocurve che creano troppo twist e che sono da raddrizzare
|
||||
Point3d ptS1 = bpIsoStart.first ;
|
||||
@@ -5322,19 +5108,19 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta
|
||||
if ( IsNull( pCC1) || ! pCC1->IsValid())
|
||||
return nullptr ;
|
||||
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
for( int i = 0 ; i < ssize( vPnt1) ; ++i) {
|
||||
PtrOwner<IGeoPoint3d> pPT( CreateGeoPoint3d()) ; pPT->Set( vPnt1[i]) ;
|
||||
VT.push_back( Release( pPT)) ;
|
||||
}
|
||||
for( int i = 0 ; i < ssize( vPnt0) ; ++i) {
|
||||
PtrOwner<IGeoPoint3d> pPT( CreateGeoPoint3d()) ; pPT->Set( vPnt0[i]) ;
|
||||
VT.push_back( Release( pPT)) ;
|
||||
}
|
||||
VT.push_back( pCC1->Clone()) ;
|
||||
VT.push_back( pCC2->Clone()) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized_RMF.nge") ;
|
||||
#endif
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
for( int i = 0 ; i < ssize( vPnt1) ; ++i) {
|
||||
PtrOwner<IGeoPoint3d> pPT( CreateGeoPoint3d()) ; pPT->Set( vPnt1[i]) ;
|
||||
VT.push_back( Release( pPT)) ;
|
||||
}
|
||||
for( int i = 0 ; i < ssize( vPnt0) ; ++i) {
|
||||
PtrOwner<IGeoPoint3d> pPT( CreateGeoPoint3d()) ; pPT->Set( vPnt0[i]) ;
|
||||
VT.push_back( Release( pPT)) ;
|
||||
}
|
||||
VT.push_back( pCC1->Clone()) ;
|
||||
VT.push_back( pCC2->Clone()) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized_RMF.nge") ;
|
||||
#endif
|
||||
|
||||
// controllo di essere rimasto in tolleranza
|
||||
double dErr = 0 ;
|
||||
@@ -5347,4 +5133,229 @@ RegolarizeBordersLocallyRMF( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoSta
|
||||
return nullptr ;
|
||||
|
||||
return nullptr ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim
|
||||
// Le curve vengono modificate entro una data tolleranza, in modo che
|
||||
ISurfBezier*
|
||||
RegolarizeBordersLocally( const ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol, int nType)
|
||||
{
|
||||
if ( nType == RegolarizeType::RMF)
|
||||
return RegolarizeBordersLocallyRMF( pSurfBz, bpIsoStart, bpIsoEnd, dTol) ;
|
||||
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.clear() ;
|
||||
#endif
|
||||
|
||||
// prendo per buone le isocurve di inizio e fine tratto e devo identificare tra loro le isocurve che creano troppo twist e che sono da raddrizzare
|
||||
Point3d ptS1 = bpIsoStart.first ;
|
||||
Point3d ptS2 = bpIsoEnd.first ;
|
||||
Vector3d vtDir1 = bpIsoStart.second - ptS1 ;
|
||||
Vector3d vtDir2 = bpIsoEnd.second - ptS2 ;
|
||||
//double dInterpolateAngTol = 4 ;
|
||||
//double dAngInterp = 0 ;
|
||||
//vtDir1.GetAngle( vtDir2, dAngInterp) ;
|
||||
//bool bInterpolate = dAngInterp > dInterpolateAngTol ;
|
||||
|
||||
int nDegU, nDegV, nSpanU, nSpanV ;
|
||||
bool bRat, bTrimmed ;
|
||||
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
||||
if ( nDegU != 3)
|
||||
return nullptr ;
|
||||
// individuo quali isocurve sono state indicate come inizio e fine
|
||||
PtrOwner<ICurveComposite> pCrv1( pSurfBz->GetSingleEdge3D( false, 2)) ;
|
||||
PtrOwner<ICurveComposite> pCrv2( pSurfBz->GetSingleEdge3D( false, 0)) ;
|
||||
// inverto la curva corrispondente al bordo 2 della bezier per avere le due guide concordi
|
||||
pCrv2->Invert() ;
|
||||
double dParS1 = -1 ; double dParS2 = -1 ;
|
||||
if ( ! pCrv1->GetParamAtPoint( ptS1, dParS1) || ! pCrv1->GetParamAtPoint( ptS2, dParS2))
|
||||
return nullptr ;
|
||||
int nUS1 = int ( dParS1) * nDegU ;
|
||||
int nUS2 = int ( dParS2) * nDegU ;
|
||||
bool bInverted = false ;
|
||||
if ( nUS1 > nUS2) {
|
||||
swap( nUS1, nUS2) ;
|
||||
swap( dParS1, dParS2) ;
|
||||
swap( ptS1, ptS2) ;
|
||||
swap( vtDir1, vtDir2) ;
|
||||
bInverted = true ;
|
||||
}
|
||||
PtrOwner<ICurve> pCrvOrig1( pCrv1->CopyParamRange( dParS1, dParS2)) ;
|
||||
PtrOwner<ICurve> pCrvOrig2( pCrv2->CopyParamRange( dParS1, dParS2)) ;
|
||||
double dLen = 0 ; pCrvOrig1->GetLength( dLen) ;
|
||||
|
||||
///// versione con correzioni a mano
|
||||
Point3d ptPrevS = ptS1 ;
|
||||
Point3d ptPrevE = ! bInverted ? bpIsoStart.second : bpIsoEnd.second ;
|
||||
Vector3d vtIsoPrev = ptPrevE - ptPrevS ; vtIsoPrev.Normalize() ;
|
||||
Point3d ptBez ; Vector3d vtNPrev ;
|
||||
pSurfBz->GetPointNrmD1D2( dParS1, 0.5, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez, vtNPrev) ;
|
||||
int nPoints = ( nUS2 - nUS1) * nDegU + 1 ;
|
||||
PNTVECTOR vPnt0 ; vPnt0.reserve( nPoints) ; vPnt0.push_back( ptPrevS) ;
|
||||
PNTVECTOR vPnt1 ; vPnt1.reserve( nPoints) ; vPnt1.push_back( ptPrevE) ;
|
||||
// salvo il secondo punto di controllo della patch
|
||||
bool bOk = false ;
|
||||
Point3d ptSecond1Curr = pSurfBz->GetControlPoint( nUS1 + 1, 0, &bOk) ;
|
||||
vPnt0.push_back( ptSecond1Curr) ;
|
||||
Point3d ptSecond2Curr = pSurfBz->GetControlPoint( nUS1 + 1, 1, &bOk) ;
|
||||
vPnt1.push_back( ptSecond2Curr) ;
|
||||
// scorro le isocurve di separazione tra patch
|
||||
for ( int i = nUS1 + 3 ; i < nUS2 ; i +=3) {
|
||||
// recupero precedente e successivo
|
||||
Point3d ptThird1Prev = pSurfBz->GetControlPoint( i - 1, 0, &bOk) ;
|
||||
Point3d ptThird2Prev = pSurfBz->GetControlPoint( i - 1, 1, &bOk) ;
|
||||
Point3d ptSecond1Next = pSurfBz->GetControlPoint( i + 1, 0, &bOk) ;
|
||||
Point3d ptSecond2Next = pSurfBz->GetControlPoint( i + 1, 1, &bOk) ;
|
||||
// recupero corrente e verifico la torsione
|
||||
Point3d ptCurr1 = pSurfBz->GetControlPoint( i, 0, &bOk) ;
|
||||
Point3d ptCurr2 = pSurfBz->GetControlPoint( i, 1, &bOk) ;
|
||||
Vector3d vtIsoCurr = ptCurr2 - ptCurr1 ;
|
||||
double dDist = vtIsoCurr.Len() ;
|
||||
vtIsoCurr.Normalize() ;
|
||||
Vector3d vtDirPrev = vtIsoPrev ^ vtNPrev ;
|
||||
bool bDet = false ;
|
||||
double dAng = 0 ; vtIsoCurr.GetRotation( vtIsoPrev, vtDirPrev, dAng, bDet) ;
|
||||
double dSinAngTol = sin( 5 * DEGTORAD) ;
|
||||
Vector3d vtPrev1 = ptCurr1 - ptThird1Prev ; vtPrev1.Normalize() ;
|
||||
Vector3d vtNext1 = ptSecond1Next - ptCurr1 ; vtNext1.Normalize() ;
|
||||
bool bAngularPoint1 = ! AreSameVectorEpsilon( vtPrev1, vtNext1, dSinAngTol) ;
|
||||
Vector3d vtPrev2 = ptCurr2 - ptThird2Prev ; vtPrev2.Normalize() ;
|
||||
Vector3d vtNext2 = ptSecond2Next - ptCurr2 ; vtNext2.Normalize() ;
|
||||
bool bAngularPoint2 = ! AreSameVectorEpsilon( vtPrev2, vtNext2, dSinAngTol) ;
|
||||
if ( abs( dAng) > 0) {
|
||||
// se l'isocurva di separazione dalla patch successiva è torta rispetto alla precedente
|
||||
// allora prendo il penultimo punto della curva precedente, il punto di joint e il secondo della prossima e li sposto lungo la normale della superficie
|
||||
dDist *= dAng * DEGTORAD / 2 ;
|
||||
if ( ! bAngularPoint1) {
|
||||
// se non ho un punto angoloso muovo tutto il terzetto insieme
|
||||
ptThird1Prev -= vtNPrev * dDist ;
|
||||
ptSecond1Next -= vtNPrev * dDist ;
|
||||
ptCurr1 -= vtNPrev * dDist ;
|
||||
}
|
||||
else {
|
||||
// altrimenti sposto solo il punto corrente verso la congiungente tra il precedente e il successivo
|
||||
DistPointLine dpl( ptCurr1, ptThird1Prev, ptSecond1Next, true) ;
|
||||
Point3d ptMinDist ; dpl.GetMinDistPoint( ptMinDist) ;
|
||||
Vector3d vtCorrDir = ptMinDist - ptCurr1 ; vtCorrDir.Normalize() ;
|
||||
double dProjDir = vtNPrev * vtCorrDir ;
|
||||
if ( dProjDir < 0)
|
||||
LOG_ERROR( GetEGkLogger(), "Error : regolarizing crv0 near an angular point") ;
|
||||
double dDistCorr = min( dDist, Dist( ptMinDist, ptCurr1)) ;
|
||||
ptCurr1 -= vtCorrDir * dDistCorr ;
|
||||
}
|
||||
if ( ! bAngularPoint2) {
|
||||
ptThird2Prev += vtNPrev * dDist ;
|
||||
ptSecond2Next += vtNPrev * dDist ;
|
||||
ptCurr2 += vtNPrev * dDist ;
|
||||
}
|
||||
else {
|
||||
// altrimenti sposto solo il punto corrente verso la congiungente tra il precedente e il successivo
|
||||
DistPointLine dpl( ptCurr2, ptThird2Prev, ptSecond2Next, true) ;
|
||||
Point3d ptMinDist ; dpl.GetMinDistPoint( ptMinDist) ;
|
||||
Vector3d vtCorrDir = ptMinDist - ptCurr2 ; vtCorrDir.Normalize() ;
|
||||
double dProjDir = vtNPrev * vtCorrDir ;
|
||||
if ( dProjDir < 0)
|
||||
LOG_ERROR( GetEGkLogger(), "Error : regolarizing crv1 near an angular point") ;
|
||||
double dDistCorr = min( dDist, Dist( ptMinDist, ptCurr2)) ;
|
||||
ptCurr2 += vtCorrDir * dDistCorr ;
|
||||
}
|
||||
}
|
||||
vPnt0.push_back( ptThird1Prev) ;
|
||||
vPnt0.push_back( ptCurr1) ;
|
||||
vPnt0.push_back( ptSecond1Next) ;
|
||||
|
||||
vPnt1.push_back( ptThird2Prev) ;
|
||||
vPnt1.push_back( ptCurr2) ;
|
||||
vPnt1.push_back( ptSecond2Next) ;
|
||||
|
||||
vtIsoPrev = ptCurr2 - ptCurr1 ; vtIsoPrev.Normalize() ;
|
||||
vtNPrev = ( ptSecond1Next - ptCurr1) ^ vtIsoPrev ; vtNPrev.Normalize() ;
|
||||
}
|
||||
// aggiungo gli ultimi due punti
|
||||
Point3d ptThird1Prev = pSurfBz->GetControlPoint( nUS2 - 1, 0, &bOk) ;
|
||||
vPnt0.push_back( ptThird1Prev) ;
|
||||
Point3d ptFourth1Curr = pSurfBz->GetControlPoint( nUS2, 0, &bOk) ;
|
||||
vPnt0.push_back( ptFourth1Curr) ;
|
||||
Point3d ptThird2Prev = pSurfBz->GetControlPoint( nUS2 - 1, 1, &bOk) ;
|
||||
vPnt1.push_back( ptThird2Prev) ;
|
||||
Point3d ptFourth2Curr = pSurfBz->GetControlPoint( nUS2, 1, &bOk) ;
|
||||
vPnt1.push_back( ptFourth2Curr) ;
|
||||
|
||||
PtrOwner<ICurveComposite> pCC1( CreateCurveComposite()) ;
|
||||
PtrOwner<ICurveComposite> pCC2( CreateCurveComposite()) ;
|
||||
for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) {
|
||||
PtrOwner<ICurveBezier> cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ;
|
||||
cb1->SetControlPoint( 0, vPnt0[i]) ;
|
||||
cb1->SetControlPoint( 1, vPnt0[i+1]) ;
|
||||
cb1->SetControlPoint( 2, vPnt0[i+2]) ;
|
||||
cb1->SetControlPoint( 3, vPnt0[i+3]) ;
|
||||
pCC1->AddCurve( Release( cb1)) ;
|
||||
|
||||
PtrOwner<ICurveBezier> cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ;
|
||||
cb2->SetControlPoint( 0, vPnt1[i]) ;
|
||||
cb2->SetControlPoint( 1, vPnt1[i+1]) ;
|
||||
cb2->SetControlPoint( 2, vPnt1[i+2]) ;
|
||||
cb2->SetControlPoint( 3, vPnt1[i+3]) ;
|
||||
pCC2->AddCurve( Release( cb2)) ;
|
||||
}
|
||||
|
||||
////// N.B.:dovrei tener conto anche della patch PRECEDENTE e SUCCESSIVA a quelle indicate, altrimenti non vedo se ho creato flessi al bordo della zona
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.push_back( pCC1->Clone()) ;
|
||||
VT.push_back( pCC2->Clone()) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized_first_step.nge") ;
|
||||
#endif
|
||||
|
||||
// ora verifico l'eventuale presenza di cambi di concavità non desiderati
|
||||
// se ne trovo su una curva e non sull'altra allora ruoto il terzetto di punti della curva con flesso in modo
|
||||
// da matchare la tangente dell'altra curva
|
||||
PNTINFOVECTOR vPntInfo1, vPntInfo2 ;
|
||||
FillPntInfo( vPnt0, pCC1, vPntInfo1) ;
|
||||
FillPntInfo( vPnt1, pCC2, vPntInfo2) ;
|
||||
|
||||
RemoveInflexionPoints( vPnt0, vPntInfo1, vPntInfo2) ;
|
||||
RemoveInflexionPoints( vPnt1, vPntInfo2, vPntInfo1) ;
|
||||
|
||||
pCC1->Clear() ;
|
||||
pCC2->Clear() ;
|
||||
for ( int i = 0 ; i < ssize( vPnt0) - 3 ; i+=3) {
|
||||
PtrOwner<ICurveBezier> cb1( CreateCurveBezier()) ; cb1->Init( 3, false) ;
|
||||
cb1->SetControlPoint( 0, vPnt0[i]) ;
|
||||
cb1->SetControlPoint( 1, vPnt0[i+1]) ;
|
||||
cb1->SetControlPoint( 2, vPnt0[i+2]) ;
|
||||
cb1->SetControlPoint( 3, vPnt0[i+3]) ;
|
||||
pCC1->AddCurve( Release( cb1)) ;
|
||||
|
||||
PtrOwner<ICurveBezier> cb2( CreateCurveBezier()) ; cb2->Init( 3, false) ;
|
||||
cb2->SetControlPoint( 0, vPnt1[i]) ;
|
||||
cb2->SetControlPoint( 1, vPnt1[i+1]) ;
|
||||
cb2->SetControlPoint( 2, vPnt1[i+2]) ;
|
||||
cb2->SetControlPoint( 3, vPnt1[i+3]) ;
|
||||
pCC2->AddCurve( Release( cb2)) ;
|
||||
}
|
||||
|
||||
// controllo di essere rimasto in tolleranza
|
||||
double dErr = 0 ;
|
||||
CalcApproxError( pCrvOrig1, pCC1, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return nullptr ;
|
||||
CalcApproxError( pCrvOrig2, pCC2, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return nullptr ;
|
||||
|
||||
PtrOwner<ISurfBezier> pNewSurf( pSurfBz->Clone()) ;
|
||||
// aggiorno i punti di controllo della superficie di bezier
|
||||
for ( int i = 0 ; i < ssize( vPnt0) ; ++i) {
|
||||
pNewSurf->SetControlPoint( nUS1 + i, 0, vPnt0[i]) ;
|
||||
pNewSurf->SetControlPoint( nUS1 + i, 1, vPnt1[i]) ;
|
||||
}
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.clear() ;
|
||||
VT.push_back( Release(pCC1)) ;
|
||||
VT.push_back( Release(pCC2)) ;
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
|
||||
#endif
|
||||
|
||||
return Release( pNewSurf) ;
|
||||
}
|
||||
Reference in New Issue
Block a user