EgtGeomKernel :
- negli offset gestite autointersezioni per raccordi chamfer ed extend.
This commit is contained in:
+149
-25
@@ -16,9 +16,17 @@
|
|||||||
#include "CurveArc.h"
|
#include "CurveArc.h"
|
||||||
#include "CurveLine.h"
|
#include "CurveLine.h"
|
||||||
#include "GeoConst.h"
|
#include "GeoConst.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntervals.h"
|
||||||
|
#include "/EgtDev/Include/EGkIntersCurves.h"
|
||||||
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
||||||
|
|
||||||
using namespace std ;
|
using namespace std ;
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
static bool IsFillet( const ICurve* pCrv, double dDist) ;
|
||||||
|
static bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
||||||
|
static bool AdjustIntersections( ICRVCOMPOPVECTOR& CrvList) ;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
IdentifyFillets( ICurveComposite* pCrvCo, double dDist)
|
||||||
@@ -52,36 +60,76 @@ IsFillet( const ICurve* pCrv, double dDist)
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool
|
bool
|
||||||
AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType)
|
AdjustCurveFillets( ICURVEPOVECTOR& vOffset, double dDist, int nType)
|
||||||
{
|
{
|
||||||
ICURVEPLIST CrvLst ;
|
if ( vOffset.empty())
|
||||||
PtrOwner<ICurve> pCrv( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
return true ;
|
||||||
while ( ! IsNull( pCrv)) {
|
|
||||||
// se identificato come fillet lo trasformo in smusso o estensione
|
// suddivido le curve di offset individuando i fillet e isolandoli dagli altri tratti
|
||||||
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
ICRVCOMPOPVECTOR vCrvs ;
|
||||||
CurveComposite ccTemp ;
|
for ( int i = 0 ; i < int( vOffset.size()) ; i ++) {
|
||||||
ModifyFillet( pCrv, dDist, nType, ccTemp) ;
|
CurveComposite* pCompo = GetBasicCurveComposite( vOffset[i]) ;
|
||||||
// metto in lista le curve risultanti
|
if ( pCompo == nullptr)
|
||||||
if ( ccTemp.GetCurveCount() > 0) {
|
return false ;
|
||||||
PtrOwner<ICurve> pCrv2( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
bool bNewCrv = true ;
|
||||||
while ( ! IsNull( pCrv2)) {
|
PtrOwner<ICurve> pCrv( pCompo->RemoveFirstOrLastCurve(false)) ;
|
||||||
CrvLst.push_back( Release( pCrv2)) ;
|
while ( ! IsNull( pCrv)) {
|
||||||
pCrv2.Set( ccTemp.RemoveFirstOrLastCurve( false)) ;
|
if ( pCrv->GetTempParam() > EPS_SMALL) {
|
||||||
}
|
// se fillet calcolo il nuovo raccordo
|
||||||
|
CurveComposite* ccTemp = CreateBasicCurveComposite() ;
|
||||||
|
ModifyFillet( pCrv, dDist, nType, *ccTemp) ;
|
||||||
|
// assegno temp param per identificarlo nei conti successivi
|
||||||
|
ccTemp->SetTempParam( 1) ;
|
||||||
|
vCrvs.push_back( ccTemp) ;
|
||||||
|
bNewCrv = true ;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
// aggiungo la curva
|
||||||
|
if ( bNewCrv) {
|
||||||
|
bNewCrv = false ;
|
||||||
|
CurveComposite* pCompo = ConvertCurveToBasicComposite( Release( pCrv)) ;
|
||||||
|
if ( pCompo == nullptr)
|
||||||
|
return false ;
|
||||||
|
vCrvs.push_back( pCompo) ;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
vCrvs.back()->AddCurve( Release( pCrv)) ;
|
||||||
|
}
|
||||||
|
// passo alla curva successiva
|
||||||
|
pCrv.Set( pCompo->RemoveFirstOrLastCurve( false)) ;
|
||||||
}
|
}
|
||||||
// altrimenti salvo in lista
|
|
||||||
else
|
|
||||||
CrvLst.push_back( Release( pCrv)) ;
|
|
||||||
// passo alla curva successiva
|
|
||||||
pCrv.Set( pCrvCo->RemoveFirstOrLastCurve( false)) ;
|
|
||||||
}
|
}
|
||||||
// rimetto le curve nella composita
|
vOffset.clear() ;
|
||||||
for ( auto pCrv : CrvLst) {
|
|
||||||
pCrvCo->AddCurve( pCrv) ;
|
// gestione delle intersezioni
|
||||||
|
if ( ! AdjustIntersections( vCrvs))
|
||||||
|
return false ;
|
||||||
|
|
||||||
|
// concateno i tratti ottenuti
|
||||||
|
ChainCurves ChainCrv ;
|
||||||
|
ChainCrv.Init( false, 2 * EPS_SMALL, vCrvs.size()) ;
|
||||||
|
for ( int i = 0 ; i < int( vCrvs.size()); ++ i) {
|
||||||
|
Point3d ptS, ptE ;
|
||||||
|
Vector3d vtS, vtE ;
|
||||||
|
vCrvs[i]->GetStartPoint( ptS) ;
|
||||||
|
vCrvs[i]->GetEndPoint( ptE) ;
|
||||||
|
vCrvs[i]->GetStartDir( vtS) ;
|
||||||
|
vCrvs[i]->GetEndDir( vtE) ;
|
||||||
|
ChainCrv.AddCurve( i + 1, ptS, vtS, ptE, vtE) ;
|
||||||
|
}
|
||||||
|
// recupero i concatenamenti
|
||||||
|
Point3d ptRef ; vCrvs[0]->GetStartPoint( ptRef) ;
|
||||||
|
INTVECTOR vIds ;
|
||||||
|
while ( ChainCrv.GetChainFromNear( ptRef, false, vIds)) {
|
||||||
|
PtrOwner<CurveComposite> pCompo( CreateBasicCurveComposite()) ;
|
||||||
|
if ( IsNull( pCompo))
|
||||||
|
return false ;
|
||||||
|
for ( auto i : vIds)
|
||||||
|
pCompo->AddCurve( vCrvs[i-1]) ;
|
||||||
|
pCompo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
||||||
|
pCompo->GetEndPoint( ptRef) ;
|
||||||
|
vOffset.emplace_back( Release( pCompo)) ;
|
||||||
}
|
}
|
||||||
// unisco tratti allineati
|
|
||||||
pCrvCo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
|
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
@@ -175,3 +223,79 @@ ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux)
|
|||||||
}
|
}
|
||||||
return false ;
|
return false ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool
|
||||||
|
AdjustIntersections( ICRVCOMPOPVECTOR& vCrvs)
|
||||||
|
{
|
||||||
|
// sistema le curve nel vettore vCrvs eliminando le parti coinvolte nelle intersezioni
|
||||||
|
|
||||||
|
vector<Intervals> vIntervals( vCrvs.size()) ;
|
||||||
|
INTVECTOR vFillets ;
|
||||||
|
for ( int i = 0 ; i < int( vCrvs.size()) ; i ++) {
|
||||||
|
// salvo i parametri della curva
|
||||||
|
double dParS, dParE ;
|
||||||
|
vCrvs[i]->GetDomain( dParS, dParE) ;
|
||||||
|
vIntervals[i].Set( dParS, dParE) ;
|
||||||
|
// verifico se raccordo
|
||||||
|
if ( vCrvs[i]->GetTempParam() > EPS_SMALL)
|
||||||
|
vFillets.emplace_back( i) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// verifico se i raccordi intersecano le altre curve
|
||||||
|
bool bInters = false ;
|
||||||
|
for ( int i = 0 ; i < int( vFillets.size()) ; i ++) {
|
||||||
|
int nIdx = vFillets[i] ;
|
||||||
|
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++) {
|
||||||
|
if ( j == nIdx)
|
||||||
|
continue ;
|
||||||
|
|
||||||
|
IntersCurveCurve intCC( *vCrvs[nIdx], *vCrvs[j]) ;
|
||||||
|
int nCnt = intCC.GetIntersCount() ;
|
||||||
|
if ( nCnt > 1) {
|
||||||
|
// aggiorno gli intervalli della curva sottraendo la parte coinvolta dall'intersezione
|
||||||
|
for ( int k = 0 ; k < nCnt - 1 ; k = k+2) {
|
||||||
|
IntCrvCrvInfo iccInfo1, iccInfo2 ;
|
||||||
|
intCC.GetIntCrvCrvInfo( k, iccInfo1) ;
|
||||||
|
// verifico non sia intersezione nell'estremo iniziale o sovrapposizione
|
||||||
|
if ( iccInfo1.IciA[0].dU < EPS_SMALL || iccInfo1.bOverlap) {
|
||||||
|
k-- ;
|
||||||
|
continue ;
|
||||||
|
}
|
||||||
|
intCC.GetIntCrvCrvInfo( k+1, iccInfo2) ;
|
||||||
|
|
||||||
|
vIntervals[nIdx].Subtract( iccInfo1.IciA[0].dU, iccInfo2.IciA[0].dU) ;
|
||||||
|
vIntervals[j].Subtract( iccInfo1.IciB[0].dU, iccInfo2.IciB[0].dU) ;
|
||||||
|
bInters = true ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! bInters)
|
||||||
|
return true ;
|
||||||
|
|
||||||
|
// aggiorno le curve eliminando i tratti coinvolti nelle intersezioni
|
||||||
|
for ( int i = 0 ; i < int( vIntervals.size()) ; i++) {
|
||||||
|
if ( vIntervals[i].GetCount() > 1) {
|
||||||
|
PtrOwner<CurveComposite> pCompo( CloneBasicCurveComposite( vCrvs[i])) ;
|
||||||
|
if ( IsNull( pCompo))
|
||||||
|
return false ;
|
||||||
|
double dParS, dParE ;
|
||||||
|
vIntervals[i].GetFirst( dParS, dParE) ;
|
||||||
|
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
||||||
|
while ( vIntervals[i].GetNext( dParS, dParE)) {
|
||||||
|
CurveComposite* pCrv = ConvertCurveToBasicComposite( pCompo->CopyParamRange( dParS, dParE)) ;
|
||||||
|
if ( pCrv == nullptr)
|
||||||
|
return false ;
|
||||||
|
vCrvs.emplace_back( pCrv) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
double dParS, dParE ;
|
||||||
|
vIntervals[i].GetFirst( dParS, dParE) ;
|
||||||
|
vCrvs[i]->TrimStartEndAtParam( dParS, dParE) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true ;
|
||||||
|
}
|
||||||
|
|||||||
+1
-3
@@ -16,6 +16,4 @@
|
|||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
bool IdentifyFillets( ICurveComposite* pCrvCo, double dDist) ;
|
||||||
bool IsFillet( const ICurve* pCrv, double dDist) ;
|
bool AdjustCurveFillets( ICURVEPOVECTOR& vCrvs, double dDist, int nType) ;
|
||||||
bool AdjustCurveFillets( ICurveComposite* pCrvCo, double dDist, int nType) ;
|
|
||||||
bool ModifyFillet( ICurve* pCrv, double dDist, int nType, ICurveComposite& ccAux) ;
|
|
||||||
+13
-5
@@ -674,12 +674,20 @@ OffsetCurve::Make( const ICurve* pCrv, double dDist, int nType)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
// nono passo : se con smusso o estensione, sostituisco i fillet con questi
|
||||||
|
// NB questa parte non è gestita in modo efficiente perchè dovrebbe essere sempre disabilitata.
|
||||||
|
// Le funzioni sono state ottimizzate per lavorare con voronoi
|
||||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
||||||
for ( auto iIter = m_CrvLst.begin() ; iIter != m_CrvLst.end() ; ++ iIter) {
|
ICURVEPOVECTOR vCrvs ;
|
||||||
CurveComposite* pCrvCo = GetBasicCurveComposite( *iIter) ;
|
vCrvs.reserve( m_CrvLst.size()) ;
|
||||||
IdentifyFillets( pCrvCo, dDist) ;
|
for ( auto pCrv : m_CrvLst) {
|
||||||
AdjustCurveFillets( pCrvCo, dDist, nType) ;
|
IdentifyFillets( GetCurveComposite( pCrv), dDist) ;
|
||||||
}
|
vCrvs.emplace_back( pCrv) ;
|
||||||
|
}
|
||||||
|
if ( ! AdjustCurveFillets( vCrvs, dDist, nType))
|
||||||
|
return false ;
|
||||||
|
m_CrvLst.clear() ;
|
||||||
|
for ( int j = 0 ; j < int( vCrvs.size()) ; j ++)
|
||||||
|
m_CrvLst.emplace_back( Release( vCrvs[j])) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+30
-16
@@ -625,16 +625,12 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
|
|||||||
if ( vResult[i]->IsClosed())
|
if ( vResult[i]->IsClosed())
|
||||||
AdjustOffsetStart( vResult[i]) ;
|
AdjustOffsetStart( vResult[i]) ;
|
||||||
|
|
||||||
// sistemo i raccordi
|
// identifico i raccordi
|
||||||
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0) {
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0)
|
||||||
IdentifyFillets( vResult[i], dOffs) ;
|
IdentifyFillets( vResult[i], dOffs) ;
|
||||||
AdjustCurveFillets( vResult[i], dOffs, nType) ;
|
|
||||||
}
|
|
||||||
|
|
||||||
// porto nel frame globale
|
|
||||||
vResult[i]->ToGlob( m_Frame) ;
|
|
||||||
// unisco le parti allineate
|
// unisco le parti allineate
|
||||||
vResult[i]->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
vResult[i]->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
||||||
// aggiungo al vettore finale
|
// aggiungo al vettore finale
|
||||||
vOffs.emplace_back( Release( vResult[i])) ;
|
vOffs.emplace_back( Release( vResult[i])) ;
|
||||||
}
|
}
|
||||||
@@ -642,6 +638,17 @@ Voronoi::CalcOffset( ICURVEPOVECTOR& vOffs, double dOffs, int nType)
|
|||||||
delete( pCrv) ;
|
delete( pCrv) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aggiusto i raccordi
|
||||||
|
if ( ( nType & ICurve::OFF_CHAMFER) != 0 || ( nType & ICurve::OFF_EXTEND) != 0)
|
||||||
|
if ( ! AdjustCurveFillets( vOffs, dOffs, nType)) {
|
||||||
|
vOffs.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// porto nel frame globale
|
||||||
|
for ( int i = 0 ; i < int( vOffs.size()) ; i++)
|
||||||
|
vOffs[i]->ToGlob( m_Frame) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +827,7 @@ Voronoi::CalcSpecialPointOffset( PNTVECTVECTOR& vResult, double dOffs)
|
|||||||
Point3d ptTemp ;
|
Point3d ptTemp ;
|
||||||
Vector3d vtDir ;
|
Vector3d vtDir ;
|
||||||
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
|
if ( ! pCrv->GetParamAtPoint( pt, dPar, 100 * EPS_SMALL) || ! pCrv->GetPointD1D2( dPar, ICurve::FROM_MINUS, ptTemp, &vtDir))
|
||||||
return false ;
|
return false ;
|
||||||
vtDir.Normalize() ;
|
vtDir.Normalize() ;
|
||||||
|
|
||||||
vResult.emplace_back( pt, vtDir) ;
|
vResult.emplace_back( pt, vtDir) ;
|
||||||
@@ -863,11 +870,10 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
|
|||||||
if ( dOffs > EPS_SMALL)
|
if ( dOffs > EPS_SMALL)
|
||||||
pCrvOffs->Invert() ;
|
pCrvOffs->Invert() ;
|
||||||
|
|
||||||
// sistemo i raccordi
|
// identifico i raccordi da modificare
|
||||||
if ( bClosed && bSquareMids) {
|
if ( bClosed && bSquareMids) {
|
||||||
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
// se curva è chiusa tutti i raccordi rispondono a bSquareMids
|
||||||
IdentifyFillets( pCrvOffs, dOffs) ;
|
IdentifyFillets( pCrvOffs, dOffs) ;
|
||||||
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
|
||||||
}
|
}
|
||||||
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
else if ( ! bClosed && ( bSquareMids || bSquareEnds)) {
|
||||||
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
// se curva è aperta devo distinguere i raccordi interni da quelli relativi agli estremi e
|
||||||
@@ -880,17 +886,25 @@ Voronoi::CalcFatCurve( ICURVEPOVECTOR& vCrvs, double dOffs, bool bSquareEnds, bo
|
|||||||
else
|
else
|
||||||
pCrvOffs->SetCurveTempParam( j, 0) ;
|
pCrvOffs->SetCurveTempParam( j, 0) ;
|
||||||
}
|
}
|
||||||
AdjustCurveFillets( pCrvOffs, dOffs, ICurve::OFF_EXTEND) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// porto nel frame globale
|
|
||||||
pCrvOffs->ToGlob( m_Frame) ;
|
|
||||||
// unisco le parti allineate
|
// unisco le parti allineate
|
||||||
pCrvOffs->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
pCrvOffs->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG, true, true) ;
|
||||||
// aggiungo al vettore finale
|
// aggiungo al vettore finale
|
||||||
vCrvs.emplace_back( pCrvOffs) ;
|
vCrvs.emplace_back( pCrvOffs) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sistemo i raccordi
|
||||||
|
if ( bSquareMids || bSquareEnds)
|
||||||
|
if ( ! AdjustCurveFillets( vCrvs, dOffs, ICurve::OFF_EXTEND)) {
|
||||||
|
vCrvs.clear() ;
|
||||||
|
return false ;
|
||||||
|
}
|
||||||
|
|
||||||
|
// porto nel frame globale
|
||||||
|
for ( int i = 0 ; i < int( vCrvs.size()) ; i++)
|
||||||
|
vCrvs[i]->ToGlob( m_Frame) ;
|
||||||
|
|
||||||
return true ;
|
return true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user