EgtGeomKernel 2.2j2 :

- nella CurveComposite::MergeTwoCurves vengono eliminate le curve molto corte (minori di 10 volte la tolleranza lineare)
- nell'offset avanzato migliorata gestione angoli interni per curve molto corte.
This commit is contained in:
Dario Sassi
2020-10-12 09:47:46 +00:00
parent b757da0654
commit 20abde05a6
4 changed files with 151 additions and 89 deletions
+103 -74
View File
@@ -2622,54 +2622,34 @@ CurveComposite::ArcsBezierCurvesToArcsPerpExtr( double dLinTol, double dAngTolDe
}
//----------------------------------------------------------------------------
bool
CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd, bool bNeedSameProp)
static int
MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dCosAngTol, bool bNeedSameProp)
{
// se non ci sono almeno 2 curve, esco subito
if ( m_CrvSmplS.size() < 2)
return true ;
// controllo sui limiti di tolleranza
dLinTol = max( dLinTol, EPS_SMALL) ;
dAngTolDeg = max( dAngTolDeg, EPS_ANG_SMALL) ;
// tolleranza lineare corrente
double dCurrLinTol = dLinTol ;
// devo verificare coppie di curve
auto iterP = m_CrvSmplS.begin() ;
auto iterC = next( iterP) ;
// mentre esiste la coppia
while ( iterC != m_CrvSmplS.end()) {
// se curve unite
if ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dAngTolDeg, bNeedSameProp)) {
// cancello l'entità precedente e la tolgo dalla lista
delete (*iterP) ;
iterC = m_CrvSmplS.erase( iterP) ;
}
// altrimenti ripristino la tolleranza
else
dCurrLinTol = dLinTol ;
// avanzo
iterP = iterC ;
iterC = next( iterC) ;
}
// se richiesto e curva chiusa devo confrontare anche ultima e prima curva
if ( bStartEnd && IsClosed()) {
if ( MergeTwoCurves( *iterP, *(m_CrvSmplS.begin()), dCurrLinTol, dAngTolDeg, bNeedSameProp)) {
// cancello l'entità precedente e la tolgo dalla lista
delete (*iterP) ;
iterC = m_CrvSmplS.erase( iterP) ;
// se precedente molto corta
double dLenP ;
if ( pCrvP->GetLength( dLenP) && dLenP < dCurrLinTol) {
// se abbastanza allineata alla successiva
Vector3d vtDirP, vtDirC ;
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
Point3d ptStart ;
return ( pCrvP->GetStartPoint( ptStart) && pCrvC->ModifyStart( ptStart) ? -1 : 0) ;
}
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTol, double dAngTolDeg, bool bNeedSameProp)
{
// se corrente molto corta
double dLenC ;
if ( pCrvC->GetLength( dLenC) && dLenC < dCurrLinTol) {
// se abbastanza allineata alla precedente
Vector3d vtDirP, vtDirC ;
if ( pCrvP->GetEndDir( vtDirP) && pCrvC->GetStartDir( vtDirC) && ( vtDirP * vtDirC) >= dCosAngTol) {
Point3d ptEnd ;
return ( pCrvC->GetEndPoint( ptEnd) && pCrvP->ModifyEnd( ptEnd) ? 1 : 0) ;
}
}
// verifico compatibilità delle proprietà
int nTprP = pCrvP->GetTempProp() ;
int nTprC = pCrvC->GetTempProp() ;
if ( bNeedSameProp && nTprP != nTprC)
return 0 ;
// coefficiente deduzione tolleranza
const double COEFF_TOL = 0.7 ;
// se entrambe rette
@@ -2680,26 +2660,20 @@ CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTo
Vector3d vtDirP, vtDirC ;
if ( pLineP != nullptr && pLineP->GetStartDir( vtDirP) &&
pLineC != nullptr && pLineC->GetStartDir( vtDirC) &&
( vtDirP * vtDirC) >= cos( dAngTolDeg * DEGTORAD)) {
// recupero le proprietà
int nTprP = pLineP->GetTempProp() ;
int nTprC = pLineC->GetTempProp() ;
( vtDirP * vtDirC) >= dCosAngTol) {
// verifico se il punto di giunzione sia eliminabile
DistPointLine dPL( pLineP->GetEnd(), pLineP->GetStart(), pLineC->GetEnd()) ;
double dSqDist ;
if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrLinTol * dCurrLinTol &&
( ! bNeedSameProp || nTprP == nTprC)) {
// se calcolo nuova linea ok, procedo con l'unione
CurveLine NewLine ;
if ( NewLine.Set( pLineP->GetStart(), pLineC->GetEnd())) {
if ( dPL.GetSqDist( dSqDist) && dSqDist < dCurrLinTol * dCurrLinTol) {
// se modifica linea corrente ok, procedo con l'unione
if ( pLineC->ModifyStart( pLineP->GetStart())) {
// diminuisco la tolleranza corrente dell'errore attuale
dCurrLinTol -= COEFF_TOL * sqrt( dSqDist) ;
// se curve originali con la stessa proprietà, la riporto
if ( nTprP == nTprC)
NewLine.SetTempProp( nTprC) ;
// aggiorno la linea corrente e torno flag modifica
*pLineC = NewLine ;
return true ;
// se curve originali con proprietà diversa, la cancello
if ( nTprP != nTprC)
pLineC->SetTempProp( 0) ;
// torno flag modifica
return -1 ;
}
}
}
@@ -2714,20 +2688,20 @@ CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTo
Point3d ptC2Ini = pArcC->GetCenter() ;
// verifico la coincidenza dei centri
if ( ! AreSamePointEpsilon( ptC1Fin, ptC2Ini, dCurrLinTol))
return false ;
return 0 ;
// verifico la coincidenza dei raggi
if ( abs( pArcP->GetRadius() - pArcC->GetRadius()) > dCurrLinTol)
return false ;
return 0 ;
// verifico la collinearità delle normali (tenendo conto del raggio)
if ( ! (( pArcP->GetNormVersor() - pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall() &&
! (( pArcP->GetNormVersor() + pArcC->GetNormVersor()) * pArcP->GetRadius()).IsSmall())
return false ;
return 0 ;
// verifico la coincidenza del senso di rotazione (verso delle normali e segno angoli al centro)
if ( pArcP->GetNormVersor() * pArcC->GetNormVersor() * pArcP->GetAngCenter() * pArcC->GetAngCenter() < 0)
return false ;
return 0 ;
// verifico di non superare l'angolo giro al centro
if ( abs( pArcP->GetAngCenter() + pArcC->GetAngCenter()) > ANG_FULL + EPS_ANG_SMALL)
return false ;
return 0 ;
// se archi piatti
if ( pArcP->IsPlane() && pArcC->IsPlane()) {
// se calcolo nuovo arco ok, procedo con l'unione
@@ -2747,16 +2721,14 @@ CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTo
if ( NewArc.GetNormVersor() * pArcC->GetNormVersor() < 0)
NewArc.InvertN() ;
// se curve originali con la stessa proprietà, la riporto
int nTprP = pArcP->GetTempProp() ;
int nTprC = pArcC->GetTempProp() ;
if ( nTprP == nTprC)
NewArc.SetTempProp( nTprC) ;
// aggiorno l'arco corrente e torno flag modifica
*pArcC = NewArc ;
return true ;
return -1 ;
}
else
return false ;
return 0 ;
}
// verifico coincidenza pendenza sulla normale
double dN = pArcP->GetNormVersor() * pArcC->GetNormVersor() ;
@@ -2772,24 +2744,81 @@ CurveComposite::MergeTwoCurves( ICurve* pCrvP, ICurve* pCrvC, double& dCurrLinTo
CurveArc NewArc ;
if ( NewArc.Set2PVN( ptP1, ptP3, vtDir1, pArcC->GetNormVersor())) {
// se curve originali con la stessa proprietà, la riporto
int nTprP = pArcP->GetTempProp() ;
int nTprC = pArcC->GetTempProp() ;
if ( nTprP == nTprC)
NewArc.SetTempProp( nTprC) ;
// aggiorno l'arco corrente e torno flag modifica
*pArcC = NewArc ;
return true ;
return -1 ;
}
else
return false ;
return 0 ;
}
}
// nessuna fusione
return false ;
return 0 ;
}
//----------------------------------------------------------------------------
bool
CurveComposite::MergeCurves( double dLinTol, double dAngTolDeg, bool bStartEnd, bool bNeedSameProp)
{
// se non ci sono almeno 2 curve, esco subito
if ( m_CrvSmplS.size() < 2)
return true ;
// controllo sui limiti di tolleranza
dLinTol = max( dLinTol, EPS_SMALL) ;
dAngTolDeg = max( dAngTolDeg, EPS_ANG_SMALL) ;
double dCosAngTol = cos( dAngTolDeg * DEGTORAD) ;
// tolleranza lineare corrente
double dCurrLinTol = dLinTol ;
// devo verificare coppie di curve
auto iterP = m_CrvSmplS.begin() ;
auto iterC = next( iterP) ;
// mentre esiste la coppia
while ( iterC != m_CrvSmplS.end()) {
// se curve unite
switch ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dCosAngTol, bNeedSameProp)) {
case -1 : // cancello l'entità precedente e la tolgo dalla lista
delete (*iterP) ;
iterC = m_CrvSmplS.erase( iterP) ;
break ;
case 1 : // cancello l'entità corrente e la tolgo dalla lista
delete (*iterC) ;
iterC = m_CrvSmplS.erase( iterC) ;
iterC = prev( iterC) ;
break ;
default : // ripristino la tolleranza
dCurrLinTol = dLinTol ;
break ;
}
// avanzo
iterP = iterC ;
iterC = next( iterC) ;
}
// se richiesto e curva chiusa devo confrontare anche ultima e prima curva
if ( bStartEnd && m_CrvSmplS.size() >= 2 && IsClosed()) {
iterC = m_CrvSmplS.begin() ;
switch ( MergeTwoCurves( *iterP, *iterC, dCurrLinTol, dCosAngTol, bNeedSameProp)) {
case -1 : // cancello l'entità precedente e la tolgo dalla lista
delete (*iterP) ;
m_CrvSmplS.erase( iterP) ;
break ;
case 1 : // cancello l'entità corrente e la tolgo dalla lista
delete (*iterC) ;
m_CrvSmplS.erase( iterC) ;
break ;
}
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
static bool
SplitTopBottomArcs( CurveComposite& cCompo)
{
int i = 0 ;