2ed2a34d55
- modifiche per DistPointLine con interfaccia portata in Include.
207 lines
8.2 KiB
C++
207 lines
8.2 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2017-2022
|
|
//----------------------------------------------------------------------------
|
|
// File : RemoveCurveDefects.cpp Data : 28.11.22 Versione : 2.4k6
|
|
// Contenuto : Implementazione rimozione spikes di curva.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 02.10.17 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "GeoConst.h"
|
|
#include "CurveComposite.h"
|
|
#include "RemoveCurveDefects.h"
|
|
#include "/EgtDev/Include/EGkDistPointLine.h"
|
|
#include "/EgtDev/Include/EGkDistPointCurve.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RemoveCurveSpikes( ICurveComposite* pCurve, double dLinTol)
|
|
{
|
|
// verifico validità curva
|
|
if ( pCurve == nullptr)
|
|
return false ;
|
|
// verifico e sistemo tolleranza lineare
|
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
// recupero il numero di curve semplici componenti la composta
|
|
int nCrvCount = pCurve->GetCurveCount() ;
|
|
if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed()))
|
|
return true ;
|
|
// ciclo sulle curve elementari della composita
|
|
int nStart = pCurve->IsClosed() ? 0 : 1 ;
|
|
for ( int i = nStart ; i < nCrvCount ; ++ i) {
|
|
// recupero due curve consecutive
|
|
const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ;
|
|
const ICurve* pNextCrv = pCurve->GetCurve( i) ;
|
|
// se sono entrambe rette
|
|
if ( pPrevCrv->GetType() == CRV_LINE && pNextCrv->GetType() == CRV_LINE) {
|
|
// recupero i punti estremi
|
|
Point3d ptStart ; pPrevCrv->GetStartPoint( ptStart) ;
|
|
Point3d ptMid ; pPrevCrv->GetEndPoint( ptMid) ;
|
|
Point3d ptEnd ; pNextCrv->GetEndPoint( ptEnd) ;
|
|
// recupero le direzioni negli estremi
|
|
Vector3d vtPrev ; pPrevCrv->GetStartDir( vtPrev) ;
|
|
Vector3d vtNext ; pNextCrv->GetStartDir( vtNext) ;
|
|
// verifico se spike
|
|
double dPrevDist, dNextDist ;
|
|
if ( vtPrev * vtNext < cos( 175 * DEGTORAD) &&
|
|
(( DistPointLine( ptStart, ptMid, ptEnd).GetDist( dPrevDist) && dPrevDist < dLinTol) ||
|
|
( DistPointLine( ptEnd, ptStart, ptMid).GetDist( dNextDist) && dNextDist < dLinTol))) {
|
|
// se spike ha base abbastanza larga, basta togliere uno dei due lati
|
|
if ( SqDist( ptStart, ptEnd) > SQ_EPS_SMALL) {
|
|
pCurve->RemoveJoint( i) ;
|
|
-- nCrvCount ;
|
|
-- i ;
|
|
}
|
|
// altrimenti bisogna togliere entrambi
|
|
else {
|
|
pCurve->RemoveJoint( i - 1) ;
|
|
pCurve->RemoveJoint( i) ;
|
|
nCrvCount -= 2 ;
|
|
i = max( i - 2, nStart - 1) ;
|
|
}
|
|
}
|
|
}
|
|
// !!! Aggiungere la gestione degli altri tipi di curve !!!
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RemoveCurveSmallZs( ICurveComposite* pCurve, double dLinTol)
|
|
{
|
|
// verifico validità curva
|
|
if ( pCurve == nullptr)
|
|
return false ;
|
|
// verifico e sistemo tolleranza lineare
|
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
// recupero il numero di curve semplici componenti la composta
|
|
int nCrvCount = pCurve->GetCurveCount() ;
|
|
if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed()))
|
|
return true ;
|
|
// ciclo sulle curve elementari della composita
|
|
int nStart = pCurve->IsClosed() ? 0 : 1 ;
|
|
int nEnd = pCurve->IsClosed() ? nCrvCount : nCrvCount - 1 ;
|
|
for ( int i = nStart ; i < nEnd ; ++ i) {
|
|
// recupero tre curve consecutive
|
|
const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ;
|
|
const ICurve* pCurrCrv = pCurve->GetCurve( i) ;
|
|
const ICurve* pNextCrv = pCurve->GetCurve( ( i < nCrvCount - 1 ? i + 1 : 0)) ;
|
|
// se la curva corrente è una retta
|
|
if ( pCurrCrv->GetType() == CRV_LINE) {
|
|
// recupero tre punti notevoli della curva
|
|
Point3d ptStart ; pCurrCrv->GetStartPoint( ptStart) ;
|
|
Point3d ptMid ; pCurrCrv->GetMidPoint( ptMid) ;
|
|
Point3d ptEnd ; pCurrCrv->GetEndPoint( ptEnd) ;
|
|
// recupero le direzioni negli estremi
|
|
Vector3d vtPrev ; pPrevCrv->GetEndDir( vtPrev) ;
|
|
Vector3d vtNext ; pNextCrv->GetStartDir( vtNext) ;
|
|
// verifico se Small Z
|
|
double dDistS, dDistM1, dDistM2, dDistE ;
|
|
if ( vtPrev * vtNext > cos( 30 * DEGTORAD) &&
|
|
(( DistPointCurve( ptStart, *pNextCrv).GetDist( dDistS) && dDistS < dLinTol) &&
|
|
( DistPointCurve( ptMid, *pNextCrv).GetDist( dDistM1) && dDistM1 < dLinTol) &&
|
|
( DistPointCurve( ptMid, *pPrevCrv).GetDist( dDistM2) && dDistM2 < dLinTol) &&
|
|
( DistPointCurve( ptEnd, *pPrevCrv).GetDist( dDistE) && dDistE < dLinTol))) {
|
|
// rimuovo il segmento
|
|
if ( pCurve->RemoveJoint( i)) {
|
|
-- nCrvCount ;
|
|
-- nEnd ;
|
|
-- i ;
|
|
// porto il nuovo estremo sul punto medio
|
|
pCurve->ModifyJoint( i + 1, ptMid) ;
|
|
}
|
|
// altrimenti devo rimuovere anche il successivo
|
|
else if ( pCurve->RemoveJoint( i + 1) && pCurve->RemoveJoint( i)) {
|
|
nCrvCount -= 2 ;
|
|
nEnd -= 2 ;
|
|
-- i ;
|
|
// porto il nuovo estremo sul punto medio
|
|
pCurve->ModifyJoint( i + 1, ptMid) ;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
RemoveCurveSmallParts( ICurveComposite* pCurve, double dLinTol)
|
|
{
|
|
// verifico validità curva
|
|
if ( pCurve == nullptr)
|
|
return false ;
|
|
// verifico e sistemo tolleranza lineare
|
|
dLinTol = max( dLinTol, EPS_SMALL) ;
|
|
// recupero il numero di curve semplici componenti la composta
|
|
int nCrvCount = pCurve->GetCurveCount() ;
|
|
if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed()))
|
|
return true ;
|
|
|
|
// se aperta, verifico le due curve agli estremi
|
|
if ( ! pCurve->IsClosed()) {
|
|
// curva iniziale
|
|
const ICurve* pFirstCrv = pCurve->GetFirstCurve() ;
|
|
double dFirstLen ; pFirstCrv->GetLength( dFirstLen) ;
|
|
if ( dFirstLen < dLinTol) {
|
|
Point3d ptStart ; pFirstCrv->GetStartPoint( ptStart) ;
|
|
delete( pCurve->RemoveFirstOrLastCurve( false)) ;
|
|
pCurve->ModifyStart( ptStart) ;
|
|
-- nCrvCount ;
|
|
}
|
|
// curva finale
|
|
const ICurve* pLastCrv = pCurve->GetLastCurve() ;
|
|
double dLastLen ; pLastCrv->GetLength( dLastLen) ;
|
|
if ( dLastLen < dLinTol) {
|
|
Point3d ptEnd ; pLastCrv->GetStartPoint( ptEnd) ;
|
|
delete( pCurve->RemoveFirstOrLastCurve( true)) ;
|
|
pCurve->ModifyEnd( ptEnd) ;
|
|
-- nCrvCount ;
|
|
}
|
|
}
|
|
|
|
// ciclo sulle curve elementari della composita
|
|
int nStart = pCurve->IsClosed() ? 0 : 1 ;
|
|
int nEnd = pCurve->IsClosed() ? nCrvCount : nCrvCount - 1 ;
|
|
for ( int i = nStart ; i < nEnd ; ++ i) {
|
|
// recupero la curva corrente
|
|
const ICurve* pCurrCrv = pCurve->GetCurve( i) ;
|
|
// se la curva corrente è troppo corta
|
|
double dLen ; pCurrCrv->GetLength( dLen) ;
|
|
if ( dLen < dLinTol) {
|
|
// recupero il punto medio della curva
|
|
Point3d ptMid ; pCurrCrv->GetMidPoint( ptMid) ;
|
|
// rimuovo il segmento
|
|
if ( pCurve->RemoveJoint( i)) {
|
|
// porto il nuovo estremo sul punto medio
|
|
pCurve->ModifyJoint( i, ptMid) ;
|
|
// aggiorno valore di i tenendo conto che ModifyJoint potrebbe modificare la curva precedente
|
|
// che quindi va ricontrollata
|
|
i = max( i - 2, nStart - 1) ;
|
|
// aggiorno valore di nEnd ( ModifyJoint potrebbe aver rimosso la curva precedente e la successiva)
|
|
nEnd = pCurve->GetCurveCount() - ( pCurve->IsClosed() ? 0 : 1) ;
|
|
}
|
|
// altrimenti rimuovo anche il successivo
|
|
else if ( pCurve->RemoveJoint( i + 1)) {
|
|
pCurve->RemoveJoint( i) ;
|
|
pCurve->ModifyJoint( i, ptMid) ;
|
|
i = max( i - 2, nStart - 1) ;
|
|
nEnd = pCurve->GetCurveCount() - ( pCurve->IsClosed() ? 0 : 1) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
} |