EgtGeomKernel :
- correzioni e migliorie a regolarize dei bordi per trimming.
This commit is contained in:
+2
-2
@@ -735,7 +735,7 @@ GetSurfBezierRuled( const ICurve* pCurve1, const ICurve* pCurve2, int nType, dou
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
ISurfBezier*
|
||||
GetSurfBezierRuledSmooth( const ICurve* pCurve1, const ICurve* pCurve2, double dSampleLen)
|
||||
GetSurfBezierRuledSmooth( const ICurve* pCurve1, const ICurve* pCurve2, BIPNTVECTOR& vSyncLines, double dSampleLen)
|
||||
{
|
||||
// verifica parametri
|
||||
if ( pCurve1 == nullptr || pCurve2 == nullptr)
|
||||
@@ -762,7 +762,7 @@ GetSurfBezierRuledSmooth( const ICurve* pCurve1, const ICurve* pCurve2, double d
|
||||
|
||||
// creo e setto la superficie trimesh
|
||||
PtrOwner<SurfBezier> pSbz( CreateBasicSurfBezier()) ;
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateSmoothRuledByTwoCurves( pCC1, pCC2, dSampleLen))
|
||||
if ( IsNull( pSbz) || ! pSbz->CreateSmoothRuledByTwoCurves( pCC1, pCC2, dSampleLen, vSyncLines))
|
||||
return nullptr ;
|
||||
|
||||
// restituisco la superficie
|
||||
|
||||
+14
-2
@@ -6429,6 +6429,14 @@ ManageTwistInQuadrangulation( const ICurveComposite* pSubEdge1, const ICurveComp
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen)
|
||||
{
|
||||
BIPNTVECTOR vSyncLines ;
|
||||
return CreateSmoothRuledByTwoCurves( pCurve0, pCurve1, dSampleLen, vSyncLines) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen, BIPNTVECTOR& vSyncLines)
|
||||
{
|
||||
// converto in bezier le curve iniziali
|
||||
PtrOwner<ICurve> pCrvEdge1( CurveToBezierCurve( pCurve0, 3, false)) ;
|
||||
@@ -6444,7 +6452,6 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
|
||||
// Verifico che la distanza di campionamento sia ammissibile
|
||||
double dSampleDist = 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) ;
|
||||
@@ -6457,7 +6464,6 @@ 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 ;
|
||||
BIPNTVECTOR vSyncLines ;
|
||||
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) ;
|
||||
@@ -6585,6 +6591,7 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
vGeo.push_back( Release( pLine)) ;
|
||||
vCol.push_back( LIME) ;
|
||||
#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)...
|
||||
@@ -6634,6 +6641,9 @@ SurfBezier::CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* p
|
||||
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) ;
|
||||
@@ -6651,6 +6661,8 @@ 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) ;
|
||||
}
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ class SurfBezier : public ISurfBezier, public IGeoObjRW
|
||||
bool SwapParameters( void) ;
|
||||
bool LimitSurfToTrimmedRegion( void) override ;
|
||||
bool CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen) override ;
|
||||
bool CreateSmoothRuledByTwoCurves( const ICurve* pCurve0, const ICurve* pCurve1, double dSampleLen, BIPNTVECTOR& vSyncLines) override ;
|
||||
|
||||
public : // IGeoObjRW
|
||||
int GetNgeId( void) const override ;
|
||||
|
||||
+63
-88
@@ -284,58 +284,6 @@ GetPointSetByAngTol( const PolyLine& PL, double dAngTol, POLYLINEVECTOR& vPL)
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Funzione per spezzare una curva compo in diversi tratti in corrispondenza
|
||||
// di cambi di direzione maggiori della tolleranza angolare passata
|
||||
static bool
|
||||
SplitCurveCompoByAngTol( const ICurveComposite* pCC, double dAngTol, ICRVCOMPOPOVECTOR& vCC)
|
||||
{
|
||||
int nCurves = pCC->GetCurveCount() ;
|
||||
vCC.emplace_back( CreateCurveComposite()) ;
|
||||
vCC.back()->AddCurve( pCC->GetCurve(0)->Clone()) ;
|
||||
// Cos della tolleranza angolare massima
|
||||
double dCosTol = cos( dAngTol * DEGTORAD) ;
|
||||
|
||||
for ( int nC = 0 ; nC < nCurves - 2; ++ nC) {
|
||||
// Recupero l'angolo tra la fine della curva corrente e l'inizio della successiva
|
||||
const ICurve* pCrvCurr = pCC->GetCurve( nC) ;
|
||||
const ICurve* pCrvNext = pCC->GetCurve( nC + 1) ;
|
||||
Vector3d vtCurrEnd ; pCrvCurr->GetEndDir( vtCurrEnd) ;
|
||||
Vector3d vtNextStart ; pCrvNext->GetStartDir( vtNextStart) ;
|
||||
// Calcolo il Coseno tra i due versori
|
||||
double dCos = vtCurrEnd * vtNextStart ;
|
||||
// Se dentro alla tolleranza, allora i punti apparterranno alla stessa curva
|
||||
if ( dCos > dCosTol) {
|
||||
// Aggiungo la curva
|
||||
vCC.back()->AddCurve( pCrvNext->Clone()) ;
|
||||
}
|
||||
// Se tratto al di fuori della tolleranza, devo definire una nuova curva
|
||||
else {
|
||||
vCC.emplace_back( CreateCurveComposite()) ;
|
||||
vCC.back()->AddCurve( pCrvNext->Clone()) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Se curva originale chiusa
|
||||
if ( pCC->IsClosed() && ssize( vCC) > 1) {
|
||||
// Se ho più tratti, potrei riunire il primo con l'ultimo
|
||||
const ICurve* pCrvFirst = pCC->GetCurve( 0) ;
|
||||
const ICurve* pCrvLast = pCC->GetCurve( nCurves - 1) ;
|
||||
Vector3d vtFirstStart ; pCrvFirst->GetEndDir( vtFirstStart) ;
|
||||
Vector3d vtLastEnd ; pCrvLast->GetStartDir( vtLastEnd) ;
|
||||
// Calcolo il Coseno tra i due versori
|
||||
double dCos = vtFirstStart * vtLastEnd ;
|
||||
// Se dentro alla tolleranza, allora i punti appartengono alla stessa curva
|
||||
if ( dCos > dCosTol) {
|
||||
// Aggiungo la curva
|
||||
vCC.back()->AddCurve( Release( vCC.front())) ;
|
||||
vCC.erase( vCC.begin()) ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
////-----------------------------------------------------------------------------
|
||||
//// Funzione che approssima la curva di bordo per la costruzione della Bezier Ruled mediante
|
||||
//// Patches di curve di Bezier
|
||||
@@ -3959,26 +3907,26 @@ GetTrimmingSurfBzSyncPoints( const ICurve* pCrvEdge1, const ICurve* pCrvEdge2,
|
||||
#endif
|
||||
|
||||
// Definisco la superficie di Bezier rigata
|
||||
PtrOwner<SurfBezier> pSBzRuled( GetBasicSurfBezier( GetSurfBezierRuledSmooth( pCompoEdge1, pCompoEdge2, 10))) ;
|
||||
PtrOwner<SurfBezier> pSBzRuled( GetBasicSurfBezier( GetSurfBezierRuledSmooth( pCompoEdge1, pCompoEdge2, vSyncPoints, 10))) ;
|
||||
if ( IsNull( pSBzRuled) || ! pSBzRuled->IsValid())
|
||||
return false ;
|
||||
|
||||
// Recupero i punti di sincronizzazione e li restituisco
|
||||
ICURVEPOVECTOR vCrv ;
|
||||
pSBzRuled->GetAllPatchesIsocurves( false, vCrv) ;
|
||||
vSyncPoints.reserve( vCrv.size()) ;
|
||||
for ( int i = 0 ; i < ssize( vCrv) ; ++ i) {
|
||||
if ( ! IsNull( vCrv[i]) && vCrv[i]->IsValid()) {
|
||||
#if DEBUG_SYNC_POINTS
|
||||
VT.emplace_back( vCrv[i]->Clone()) ;
|
||||
VC.emplace_back( LIME) ;
|
||||
#endif
|
||||
Point3d ptStart ; vCrv[i]->GetStartPoint( ptStart) ;
|
||||
Point3d ptEnd ; vCrv[i]->GetEndPoint( ptEnd) ;
|
||||
if ( ! AreSamePointApprox( ptStart, ptEnd))
|
||||
vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ;
|
||||
}
|
||||
}
|
||||
//// Recupero i punti di sincronizzazione e li restituisco
|
||||
// ICURVEPOVECTOR vCrv ;
|
||||
// pSBzRuled->GetAllPatchesIsocurves( false, vCrv) ;
|
||||
// vSyncPoints.reserve( vCrv.size()) ;
|
||||
// for ( int i = 0 ; i < ssize( vCrv) ; ++ i) {
|
||||
// if ( ! IsNull( vCrv[i]) && vCrv[i]->IsValid()) {
|
||||
// #if DEBUG_SYNC_POINTS
|
||||
// VT.emplace_back( vCrv[i]->Clone()) ;
|
||||
// VC.emplace_back( LIME) ;
|
||||
// #endif
|
||||
// Point3d ptStart ; vCrv[i]->GetStartPoint( ptStart) ;
|
||||
// Point3d ptEnd ; vCrv[i]->GetEndPoint( ptEnd) ;
|
||||
// if ( ! AreSamePointApprox( ptStart, ptEnd))
|
||||
// vSyncPoints.emplace_back( make_pair( ptStart, ptEnd)) ;
|
||||
// }
|
||||
// }
|
||||
|
||||
#if DEBUG_SYNC_POINTS
|
||||
SaveGeoObj( VT, VC, "C:\\Temp\\BorderSyncPoints.nge") ;
|
||||
@@ -4219,7 +4167,8 @@ GetTrimmingRuledBezier( const CISURFPVECTOR& vSurf, const ICurve* pCrvEdge1,
|
||||
|
||||
// Se non ho punti di controllo forzati
|
||||
if ( vSyncPoints.empty()) {
|
||||
pSurfBz.Set( GetSurfBezierRuledSmooth( pCompoEdge1, pCompoEdge2, 10)) ;
|
||||
BIPNTVECTOR vSyncLines ;
|
||||
pSurfBz.Set( GetSurfBezierRuledSmooth( pCompoEdge1, pCompoEdge2, vSyncLines, 10)) ;
|
||||
if ( IsNull( pSurfBz) || ! pSurfBz->IsValid()) {
|
||||
LOG_ERROR( GetEGkLogger(), "Error in Trimming : Ruled Bezier invalid") ;
|
||||
return nullptr ;
|
||||
@@ -4972,38 +4921,44 @@ typedef vector<PntInfo> PNTINFOVECTOR ;
|
||||
// Funzione per la regolarizzazione delle curve di bordo di una lavorazione di trim
|
||||
// Le curve vengono modificate entro una data tolleranza, in modo che
|
||||
bool
|
||||
RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier* pSurfBz, const BIPOINT& bpIsoStart, const BIPOINT& bpIsoEnd, double dTol)
|
||||
RegolarizeBordersLocally( 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
|
||||
int nUS1 = - 1, nUS2 = -1 ;
|
||||
const Point3d& ptS1 = bpIsoStart.first ;
|
||||
const Point3d& ptS2 = bpIsoEnd.first ;
|
||||
const Point3d& ptE1 = bpIsoStart.second ;
|
||||
const Point3d& ptE2 = bpIsoEnd.second ;
|
||||
int nDegU, nDegV, nSpanU, nSpanV ;
|
||||
bool bRat, bTrimmed ;
|
||||
pSurfBz->GetInfo( nDegU, nDegV, nSpanU, nSpanV, bRat, bTrimmed) ;
|
||||
if ( nDegU != 3)
|
||||
return false ;
|
||||
// individuo quali isocurve sono state indicate come inizio e fine
|
||||
for ( int i = 0 ; i < nDegU * nSpanU + 1 ; ++i) {
|
||||
bool bOk = false ;
|
||||
Point3d pt = pSurfBz->GetControlPoint( i, 0, &bOk) ;
|
||||
if ( nUS1 == -1 && AreSamePointExact(pt, ptS1))
|
||||
nUS1 = i ;
|
||||
else if ( AreSamePointExact( pt, ptS2)) {
|
||||
nUS2 = i ;
|
||||
break ;
|
||||
}
|
||||
PtrOwner<ICurveComposite> pCrv1( pSurfBz->GetSingleEdge3D( false, 2)) ;
|
||||
PtrOwner<ICurveComposite> pCrv2( pSurfBz->GetSingleEdge3D( false, 0)) ;
|
||||
double dParS1 = -1 ; double dParS2 = -1 ;
|
||||
if ( ! pCrv1->GetParamAtPoint( ptS1, dParS1) || ! pCrv1->GetParamAtPoint( ptS2, dParS2))
|
||||
return false ;
|
||||
double dParE1 = -1 ; double dParE2 = -1 ;
|
||||
if ( ! pCrv2->GetParamAtPoint( ptE1, dParE1) || ! pCrv2->GetParamAtPoint( ptE2, dParE2))
|
||||
return false ;
|
||||
int nUS1 = int ( dParS1) ;
|
||||
int nUS2 = int ( dParS2) ;
|
||||
bool bInverted = false ;
|
||||
if ( nUS1 > nUS2) {
|
||||
swap( nUS1, nUS2) ;
|
||||
swap( dParE1, dParE2) ;
|
||||
bInverted = true ;
|
||||
}
|
||||
|
||||
// scorro le isocurve a partire dallo start e dell'end della zona indicata
|
||||
// controllo il twist rispetto alla isocurva precedente
|
||||
int nMid = ( nUS2 + nUS1) / 2 ;
|
||||
Point3d ptPrevS = ptS1 ;
|
||||
Point3d ptPrevE = bpIsoStart.second ;
|
||||
Point3d ptPrevE = ! bInverted ? bpIsoStart.second : bpIsoEnd.second ;
|
||||
Vector3d vtIsoPrev = ptPrevE - ptPrevS ; vtIsoPrev.Normalize() ;
|
||||
Point3d ptBez ; Vector3d vtNPrev ;
|
||||
pSurfBz->GetPointNrmD1D2( nUS1, 0.5, ISurfBezier::FROM_MINUS, ISurfBezier::FROM_MINUS, ptBez, vtNPrev) ;
|
||||
@@ -5017,7 +4972,7 @@ RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier*
|
||||
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) { /////////////////// scorro fino in fondo??
|
||||
for ( int i = nUS1 + 3 ; i < nUS2 ; i +=3) {
|
||||
// recupero precedente e successivo
|
||||
Point3d ptThird1Curr = pSurfBz->GetControlPoint( i - 1, 0, &bOk) ;
|
||||
Point3d ptThird2Curr = pSurfBz->GetControlPoint( i - 1, 1, &bOk) ;
|
||||
@@ -5036,7 +4991,7 @@ RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier*
|
||||
if ( abs( dAng) > 0) {
|
||||
// se l'isocurva di separazione dalla patch successiva è torta rispetto alla precedente
|
||||
// allora prendo il penultimo punto della curva corrente, l'ultimo e il secondo della prossima e li sposto lungo la normale della superficie
|
||||
dDist *= dAng * DEGTORAD ;
|
||||
dDist *= dAng * DEGTORAD / 2 ;
|
||||
ptThird1Curr += vtNPrev * dDist ;
|
||||
ptCurrS += vtNPrev * dDist ;
|
||||
ptSecond1Next += vtNPrev * dDist ;
|
||||
@@ -5074,13 +5029,33 @@ RegolarizeBordersLocally( const ICurve* pCrv1, const ICurve* pCrv2, ISurfBezier*
|
||||
pCC2->AddCurve( Release( cb2)) ;
|
||||
}
|
||||
|
||||
// controllo di essere rimasto in tolleranza
|
||||
PtrOwner<ICurve> pCrvOrig1( pCrv1->CopyParamRange( nUS1, dParE1)) ;
|
||||
PtrOwner<ICurve> pCrvOrig2( pCrv2->CopyParamRange( nUS2, dParE2)) ;
|
||||
double dErr = 0 ;
|
||||
CalcApproxError( pCrvOrig1, pCC1, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return false ;
|
||||
CalcApproxError( pCrvOrig2, pCC2, dErr, 20) ;
|
||||
if ( dErr > dTol)
|
||||
return false ;
|
||||
|
||||
//PtrOwner<ISurfBezier> pSB( CreateSurfBezier()) ;
|
||||
//pSB->CreateSmoothRuledByTwoCurves( pCrv1, pCrv2, 10) ;
|
||||
// controllo di non aver creato dei cambi di concavità
|
||||
// se ne trovo allora ruoto i terzetti attorno alla nuova isocurva
|
||||
////////////////// DA IMPLEMENTARE (prendendo dalla versione precedente della Regolarize)
|
||||
|
||||
// aggiorno i punti di controllo della superficie di bezier
|
||||
for ( int i = 0 ; i < ssize( vPnt0) ; ++i) {
|
||||
pSurfBz->SetControlPoint( nUS1 + i, 0, vPnt0[i]) ;
|
||||
pSurfBz->SetControlPoint( nUS1 + i, 1, vPnt1[i]) ;
|
||||
}
|
||||
#if DEBUG_SMOOTH_CURVATURE
|
||||
VT.push_back( Release(pCC1)) ;
|
||||
VT.push_back( Release(pCC2)) ;
|
||||
SaveGeoObj( VT, "D:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
|
||||
VT.push_back( Release(pCrv1)) ;
|
||||
VT.push_back( Release(pCrv2)) ;
|
||||
VT.push_back(pSurfBz->Clone());
|
||||
SaveGeoObj( VT, "C:\\Temp\\bezier\\ruled\\smoothness\\regolarized.nge") ;
|
||||
#endif
|
||||
|
||||
return true ;
|
||||
|
||||
Reference in New Issue
Block a user