EgtGeomKernel 2.1i2 :

- correzione offset di percorsi aperti con tratti estremi piccoli e perpendicolari ai successivi.
This commit is contained in:
Dario Sassi
2019-09-25 18:29:44 +00:00
parent d63e2bf884
commit 345dc7e896
2 changed files with 65 additions and 30 deletions
BIN
View File
Binary file not shown.
+65 -30
View File
@@ -389,15 +389,56 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
PtrOwner<CurveArc> pCircS( CreateBasicCurveArc()) ;
if ( IsNull( pCircS) || ! pCircS->Set( ptStart, Z_AX, abs( dDist)))
return false ;
// elimino le parti di offset interne a questa circonferenza
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
// recupero la curva e il suo dominio
ICurve* pCrv = *iIter ;
double dStart, dEnd ;
if ( ! pCrv->GetDomain( dStart, dEnd))
return false ;
// determino gli intervalli da conservare (inizializzo come tutta la curva per poi rimuovere la parte finale)
Intervals inOk( EPS_PARAM) ;
inOk.Set( dStart, dEnd) ;
IntersCurveCurve ccInt( *pCrv, *pCircS) ;
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
case CRVC_IN :
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM)
inOk.Subtract( ccOne.dParS, ccOne.dParE) ;
// intervallo che attraversa punto di chiusura della curva
else {
inOk.Subtract( ccOne.dParS, dEnd) ;
inOk.Subtract( dStart, ccOne.dParE) ;
}
break ;
case CRVC_NULL :
return false ;
}
}
// eseguo trim (solo della parte iniziale)
double dMin, dMax ;
if ( inOk.GetLast( dMin, dMax)) {
if ( dMin > dStart + 100 * EPS_PARAM)
pCrv->TrimStartAtParam( dMin) ;
}
else {
delete pCrv ;
iIter = m_CrvLst.erase( iIter) ;
continue ;
}
// passo alla successiva
++ iIter ;
}
// circonferenza sull'estremità finale
Point3d ptEnd ; ccCopy.GetEndPoint( ptEnd) ;
PtrOwner<CurveArc> pCircE( CreateBasicCurveArc()) ;
if ( IsNull( pCircE) || ! pCircE->Set( ptEnd, Z_AX, abs( dDist)))
return false ;
ICURVEPOVECTOR vpCirc ;
vpCirc.emplace_back( Release( pCircS)) ;
vpCirc.emplace_back( Release( pCircE)) ;
// elimino le parti di offset interne a queste circonferenze
// elimino le parti di offset interna a questa circonferenza
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ;) {
// recupero la curva e il suo dominio
ICurve* pCrv = *iIter ;
@@ -407,36 +448,30 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
// determino gli intervalli da conservare (inizializzo come tutta la curva per poi poter rimuovere parti)
Intervals inOk( EPS_PARAM) ;
inOk.Set( dStart, dEnd) ;
for ( const auto& pCirc : vpCirc) {
IntersCurveCurve ccInt( *pCrv, *pCirc) ;
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
case CRVC_IN :
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM)
inOk.Subtract( ccOne.dParS, ccOne.dParE) ;
// intervallo che attraversa punto di chiusura della curva
else {
inOk.Subtract( ccOne.dParS, dEnd) ;
inOk.Subtract( dStart, ccOne.dParE) ;
}
break ;
case CRVC_NULL :
return false ;
IntersCurveCurve ccInt( *pCrv, *pCircE) ;
CRVCVECTOR ccPart ;
if ( ! ccInt.GetCurveClassification( 0, ccPart))
return false ;
for ( auto& ccOne : ccPart) {
switch ( ccOne.nClass) {
case CRVC_IN :
// intervallo standard
if ( ccOne.dParS < ccOne.dParE - EPS_PARAM)
inOk.Subtract( ccOne.dParS, ccOne.dParE) ;
// intervallo che attraversa punto di chiusura della curva
else {
inOk.Subtract( ccOne.dParS, dEnd) ;
inOk.Subtract( dStart, ccOne.dParE) ;
}
break ;
case CRVC_NULL :
return false ;
}
}
// eseguo trim (solo della parte iniziale e/o finale)
// eseguo trim (solo della parte finale)
double dMin, dMax ;
if ( inOk.GetMinMax( dMin, dMax)) {
if ( dMin > dStart + 100 * EPS_PARAM && dMax < dEnd - 100 * EPS_PARAM)
pCrv->TrimStartEndAtParam( dMin, dMax) ;
else if ( dMin > dStart + 100 * EPS_PARAM)
pCrv->TrimStartAtParam( dMin) ;
else if ( dMax < dEnd - 100 * EPS_PARAM)
if ( inOk.GetFirst( dMin, dMax)) {
if ( dMax < dEnd - 100 * EPS_PARAM)
pCrv->TrimEndAtParam( dMax) ;
}
else {