diff --git a/CurveCompositeOffset.cpp b/CurveCompositeOffset.cpp
index 57badfc..ebed9f3 100644
--- a/CurveCompositeOffset.cpp
+++ b/CurveCompositeOffset.cpp
@@ -18,7 +18,7 @@
#include "CurveArc.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgkCurve.h"
-#include "/EgtDev/Include/EgkIntersCurveCurve.h"
+#include "/EgtDev/Include/EgkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc
index 0683286..65d5d8a 100644
Binary files a/EgtGeomKernel.rc and b/EgtGeomKernel.rc differ
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index d42f500..3f42458 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -318,6 +318,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
@@ -378,7 +379,7 @@ copy $(TargetPath) \EgtProg\Dll64
-
+
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index b8d7b28..f90fe6f 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -291,6 +291,9 @@
File di origine\Base
+
+ File di origine\GeoInters
+
@@ -479,9 +482,6 @@
File di intestazione\Include
-
- File di intestazione\Include
-
File di intestazione\Include
@@ -680,6 +680,9 @@
File di intestazione
+
+ File di intestazione\Include
+
diff --git a/FilletChamfer.cpp b/FilletChamfer.cpp
index 334b79d..4412d65 100644
--- a/FilletChamfer.cpp
+++ b/FilletChamfer.cpp
@@ -17,7 +17,7 @@
#include "CurveLine.h"
#include "/EgtDev/Include/EgkFilletChamfer.h"
#include "/EgtDev/Include/EgkDistPointCurve.h"
-#include "/EgtDev/Include/EgkIntersCurveCurve.h"
+#include "/EgtDev/Include/EgkIntersCurves.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
diff --git a/GdbExecutor.cpp b/GdbExecutor.cpp
index 5a86ef8..60c275c 100644
--- a/GdbExecutor.cpp
+++ b/GdbExecutor.cpp
@@ -35,7 +35,7 @@
#include "/EgtDev/Include/EGkCurveBezier.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EGkBiArcs.h"
#include "/EgtDev/Include/EGkCurveByInterp.h"
diff --git a/GeomDB.cpp b/GeomDB.cpp
index 3987588..8ddd794 100644
--- a/GeomDB.cpp
+++ b/GeomDB.cpp
@@ -1161,6 +1161,13 @@ GeomDB::GroupSwap( int nId1, int nId2, bool bSwapRef, bool bMark)
return true ;
}
+//----------------------------------------------------------------------------
+int
+GeomDB::GetNewId( void) const
+{
+ return m_IdManager.GetNewId() ;
+}
+
//----------------------------------------------------------------------------
bool
GeomDB::ChangeId( int nId, int nNewId)
diff --git a/GeomDB.h b/GeomDB.h
index c5ee41d..ab0d6db 100644
--- a/GeomDB.h
+++ b/GeomDB.h
@@ -77,6 +77,7 @@ class GeomDB : public IGeomDB
virtual bool RelocateGlob( int nId, int nRefId, int nSonBeforeAfter = GDB_LAST_SON)
{ return Relocate( nId, nRefId, nSonBeforeAfter, true) ; }
virtual bool GroupSwap( int nId1, int nId2, bool bSwapRef, bool bMark = false) ;
+ virtual int GetNewId( void) const ;
virtual bool ChangeId( int nId, int nNewId) ;
virtual bool Erase( int nId) ;
virtual bool EmptyGroup( int nId) ;
diff --git a/HashGrids2d.cpp b/HashGrids2d.cpp
index 3dd992b..af003ab 100644
--- a/HashGrids2d.cpp
+++ b/HashGrids2d.cpp
@@ -639,7 +639,7 @@ HashGrids2d::Find( const BBox3d& b3Test, INTVECTOR& vnIds)
// ordino il risultato ed elimino gli indici ripetuti
sort( vnIds.begin(), vnIds.end()) ;
- vnIds.erase( unique( vnIds.begin(), vnIds.end() ), vnIds.end()) ;
+ vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
return ( vnIds.size() > 0) ;
}
diff --git a/HashGrids3d.cpp b/HashGrids3d.cpp
index b805d84..06cd524 100644
--- a/HashGrids3d.cpp
+++ b/HashGrids3d.cpp
@@ -681,7 +681,7 @@ HashGrids3d::Find( const BBox3d& b3Test, INTVECTOR& vnIds)
// ordino il risultato ed elimino gli indici ripetuti
sort( vnIds.begin(), vnIds.end()) ;
- vnIds.erase( unique( vnIds.begin(), vnIds.end() ), vnIds.end()) ;
+ vnIds.erase( unique( vnIds.begin(), vnIds.end()), vnIds.end()) ;
return ( vnIds.size() > 0) ;
}
diff --git a/IdManager.h b/IdManager.h
index 6465db5..2391dce 100644
--- a/IdManager.h
+++ b/IdManager.h
@@ -47,7 +47,7 @@ class IdManager
if ( nId == m_nMaxId && m_nMaxId > 0)
-- m_nMaxId ;
return true ; }
- int GetNewId( void)
+ int GetNewId( void) const
{ return ( m_nMaxId + 1) ; }
int GetMaxId( void) const
{ return m_nMaxId ; }
diff --git a/IntersArcArc.h b/IntersArcArc.h
index 4a1d731..3fb407e 100644
--- a/IntersArcArc.h
+++ b/IntersArcArc.h
@@ -13,7 +13,7 @@
#pragma once
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "CurveArc.h"
diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp
index e7b4089..00c01bc 100644
--- a/IntersCrvCompoCrvCompo.cpp
+++ b/IntersCrvCompoCrvCompo.cpp
@@ -44,16 +44,19 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
m_nNumInters = 0 ;
m_Info.clear() ;
+ // determino se auto-intersezione
+ bool bAutoInters = ( &CCompoA == &CCompoB) ;
+
// dati generali delle curve
- m_bCrvAClosed = CCompoA.IsClosed() ;
- m_bCrvBClosed = CCompoB.IsClosed() ;
+ bool bCrvAClosed = CCompoA.IsClosed() ;
+ bool bCrvBClosed = CCompoB.IsClosed() ;
double dStart, dEnd ;
if ( ! CCompoA.GetDomain( dStart, dEnd))
return ;
- m_dCrvASpan = dEnd - dStart ;
+ double dCrvASpan = dEnd - dStart ;
if ( ! CCompoB.GetDomain( dStart, dEnd))
return ;
- m_dCrvBSpan = dEnd - dStart ;
+ double dCrvBSpan = dEnd - dStart ;
// creo HashGrids2d per curva con maggior numero di elementi
const int LIM_CRVNBRSQUARED = 4095 ;
@@ -81,7 +84,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
int nA = vnIds[i] ;
const ICurve* pCrvA = CCompoA.GetCurve( nA) ;
// eseguo l'intersezione di queste curve semplici
- IntersSimpleCurves( *pCrvA, nA, *pCrvB, nB) ;
+ IntersSimpleCurves( *pCrvA, nA, *pCrvB, nB, bAutoInters, bCrvAClosed, nCrvNbrA) ;
}
}
}
@@ -108,7 +111,7 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
int nB = vnIds[i] ;
const ICurve* pCrvB = CCompoB.GetCurve( nB) ;
// eseguo l'intersezione di queste curve semplici
- IntersSimpleCurves( *pCrvA, nA, *pCrvB, nB) ;
+ IntersSimpleCurves( *pCrvA, nA, *pCrvB, nB, bAutoInters, bCrvAClosed, nCrvNbrA) ;
}
}
}
@@ -117,6 +120,56 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
// ordino le intersezioni secondo l'ordine crescente del parametro della prima curva
stable_sort( m_Info.begin(), m_Info.end(), SortGreater) ;
+ // se auto-intersezione, elimino le seconde copie di una stessa intersezione
+ if ( bAutoInters) {
+ for ( int i = 0 ; i < m_nNumInters ; ++ i) {
+ for ( int j = i + 1 ; j < m_nNumInters ; ++ j) {
+ // se intersezioni puntuali
+ if ( ! m_Info[i].bOverlap && ! m_Info[j].bOverlap) {
+ // se coincidono U e ptInt tra A e B
+ if ( fabs( m_Info[i].IciA[0].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
+ AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL)) {
+ // se non è alla fine di curva chiusa
+ if ( ! bCrvAClosed || fabs( m_Info[j].IciA[0].dU - dCrvBSpan) > EPS_SMALL)
+ // elimino la seconda
+ EraseOtherInfo( i, j) ;
+ else
+ // elimino la prima
+ EraseCurrentInfo( i, j) ;
+ break ;
+ }
+ }
+ // se intersezioni sovrapposte
+ else if ( m_Info[i].bOverlap && m_Info[j].bOverlap) {
+ // se equiverse
+ if ( m_Info[i].bCBOverEq && m_Info[j].bCBOverEq) {
+ // se coincidono U e ptInt tra A e B
+ if ( fabs( m_Info[i].IciA[0].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
+ fabs( m_Info[i].IciA[1].dU - m_Info[j].IciB[1].dU) < EPS_SMALL &&
+ AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL) &&
+ AreSamePointXYEpsilon( m_Info[i].IciA[1].ptI, m_Info[j].IciB[1].ptI, 10 * EPS_SMALL)) {
+ // elimino la seconda
+ EraseOtherInfo( i, j) ;
+ break ;
+ }
+ }
+ // se controverse
+ else if ( ! m_Info[i].bCBOverEq && ! m_Info[j].bCBOverEq) {
+ // se coincidono U e ptInt tra A e B invertiti
+ if ( fabs( m_Info[i].IciA[0].dU - m_Info[j].IciB[1].dU) < EPS_SMALL &&
+ fabs( m_Info[i].IciA[1].dU - m_Info[j].IciB[0].dU) < EPS_SMALL &&
+ AreSamePointXYEpsilon( m_Info[i].IciA[0].ptI, m_Info[j].IciB[1].ptI, 10 * EPS_SMALL) &&
+ AreSamePointXYEpsilon( m_Info[i].IciA[1].ptI, m_Info[j].IciB[0].ptI, 10 * EPS_SMALL)) {
+ // elimino la seconda
+ EraseOtherInfo( i, j) ;
+ break ;
+ }
+ }
+ }
+ }
+ }
+ }
+
// sistemazione di intersezioni coincidenti
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
for ( int j = 0 ; j < m_nNumInters ; ++ j) {
@@ -127,10 +180,10 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
int ki = 0 ; // del successivo si prende sempre il primo
int kj = ( m_Info[j].bOverlap ? 1 : 0) ; // del precedente si prende il secondo se overlap
// verifico se precedente e corrente si riferiscono alla stessa intersezione (10 * EPS_SMALL)
- if ( SqDistXY( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI) < ( 100 * EPS_SMALL * EPS_SMALL) &&
- SqDistXY( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI) < ( 100 * EPS_SMALL * EPS_SMALL) &&
- CompatibleParamA( m_Info[j], m_Info[i], m_bCrvAClosed, m_dCrvASpan) &&
- CompatibleParamB( m_Info[j], m_Info[i], m_bCrvBClosed, m_dCrvBSpan)) {
+ if ( AreSamePointXYEpsilon( m_Info[j].IciA[kj].ptI, m_Info[i].IciA[ki].ptI, 10 * EPS_SMALL) &&
+ AreSamePointXYEpsilon( m_Info[j].IciB[kj].ptI, m_Info[i].IciB[ki].ptI, 10 * EPS_SMALL) &&
+ CompatibleParamA( m_Info[j], m_Info[i], bCrvAClosed, dCrvASpan) &&
+ CompatibleParamB( m_Info[j], m_Info[i], bCrvBClosed, dCrvBSpan)) {
// caso DET-NULL -> NULL-DET per prima curva
if ( m_Info[j].IciA[kj].nPrevTy != ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL &&
m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy != ICCT_NULL) {
@@ -463,16 +516,20 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
//----------------------------------------------------------------------------
bool
-IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB)
+IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB,
+ bool bAutoInters, bool bClosed, int nCurvesNbr)
{
+ // se autointersezione, verifico non sia la stessa curva
+ if ( bAutoInters && nA == nB)
+ return true ;
// eseguo l'intersezione di queste curve semplici
IntersCurveCurve intCC( CurveA, CurveB) ;
// ne recupero i risultati
int nCurrInters = intCC.GetNumInters() ;
if ( nCurrInters > 0) {
- m_nNumInters += nCurrInters ;
m_bOverlaps = ( intCC.GetOverlaps() ? true : m_bOverlaps) ;
for ( int j = 0 ; j < nCurrInters ; ++ j) {
+ // recupero e aggiusto i dati dell'intersezione
IntCrvCrvInfo aInfo ;
intCC.GetIntCrvCrvInfo( j, aInfo) ;
aInfo.IciA[0].dU += nA ;
@@ -481,7 +538,26 @@ IntersCrvCompoCrvCompo::IntersSimpleCurves( const ICurve& CurveA, int nA, const
aInfo.IciA[1].dU += nA ;
aInfo.IciB[1].dU += nB ;
}
+ // se autointersezione, escludo le intersezioni puntuali agli estremi comuni di curve consecutive
+ if ( bAutoInters) {
+ // estremo iniziale
+ if ( ( nB == nA - 1 || ( bClosed && nA == 0 && nB == nCurvesNbr - 1)) && ! aInfo.bOverlap) {
+ Point3d ptStart ;
+ if ( CurveA.GetStartPoint( ptStart) &&
+ AreSamePointApprox( ptStart, aInfo.IciA[0].ptI))
+ continue ;
+ }
+ // estremo finale
+ if ( ( nB == nA + 1 || ( bClosed && nA == nCurvesNbr - 1 && nB == 0)) && ! aInfo.bOverlap) {
+ Point3d ptEnd ;
+ if ( CurveA.GetEndPoint( ptEnd) &&
+ AreSamePointApprox( ptEnd, aInfo.IciA[0].ptI))
+ continue ;
+ }
+ }
+ // aggiungo all'elenco delle intersezioni
m_Info.push_back( aInfo) ;
+ ++ m_nNumInters ;
}
}
return true ;
@@ -591,7 +667,7 @@ OrderNonManifoldInters( ICCIVECTOR& Info, const ICurve& CurveA, const ICurve& Cu
// coincidenza dei punti della curva B
if ( CompatibleParamA( Info[j], Info[i], bCrvAClosed, dCrvASpan) &&
! CompatibleParamB( Info[j], Info[i], bCrvBClosed, dCrvBSpan) &&
- SqDistXY( Info[j].IciB[kj].ptI, Info[i].IciB[ki].ptI) < ( 100 * EPS_SMALL * EPS_SMALL)) {
+ AreSamePointXYEpsilon( Info[j].IciB[kj].ptI, Info[i].IciB[ki].ptI, 10 * EPS_SMALL)) {
// se sono diversi i precedenti
if ( Info[j].IciA[kj].nPrevTy != Info[i].IciA[ki].nPrevTy) {
// studio la topologia del disco non-manifold
diff --git a/IntersCrvCompoCrvCompo.h b/IntersCrvCompoCrvCompo.h
index 6f38627..6a98f41 100644
--- a/IntersCrvCompoCrvCompo.h
+++ b/IntersCrvCompoCrvCompo.h
@@ -13,7 +13,7 @@
#pragma once
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkCurveComposite.h"
@@ -21,6 +21,7 @@
class IntersCrvCompoCrvCompo
{
friend class IntersCurveCurve ;
+ friend class SelfIntersCurve ;
public :
IntersCrvCompoCrvCompo( const ICurveComposite& CCompo1, const ICurveComposite& CCompo2) ;
@@ -38,15 +39,12 @@ class IntersCrvCompoCrvCompo
private :
IntersCrvCompoCrvCompo( void) ;
- bool IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB) ;
+ bool IntersSimpleCurves( const ICurve& CurveA, int nA, const ICurve& CurveB, int nB,
+ bool bAutoInters, bool bClosed, int nCurvesNbr) ;
bool EraseCurrentInfo( int& nIndCurr, int& nIndOther) ;
bool EraseOtherInfo( int& nIndCurr, int& nIndOther) ;
private :
- bool m_bCrvAClosed ;
- bool m_bCrvBClosed ;
- double m_dCrvASpan ;
- double m_dCrvBSpan ;
bool m_bOverlaps ;
int m_nNumInters ;
ICCIVECTOR m_Info ;
diff --git a/IntersCurveCurve.cpp b/IntersCurveCurve.cpp
index cf4e933..0c2fb8c 100644
--- a/IntersCurveCurve.cpp
+++ b/IntersCurveCurve.cpp
@@ -2,7 +2,7 @@
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : IntersCurveCurve.cpp Data : 20.06.14 Versione : 1.5f6
-// Contenuto : Implementazione della classe intersezione linea/linea.
+// Contenuto : Implementazione della classe intersezione curva/curva.
//
//
//
@@ -14,13 +14,13 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "GeoConst.h"
+#include "CurveLine.h"
+#include "CurveComposite.h"
#include "IntersLineLine.h"
#include "IntersLineArc.h"
#include "IntersArcArc.h"
#include "IntersCrvCompoCrvCompo.h"
-#include "CurveLine.h"
-#include "CurveComposite.h"
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkPlane3d.h"
#include "/EgtDev/Include/EGtPointerOwner.h"
@@ -112,7 +112,7 @@ IntersCurveCurve::IsArcToApprox( const ICurve& Curve)
const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
if ( pArc == nullptr)
return false ;
- // verifico se non è nel piano XY e ha più di un giro al centro
+ // verifico se non è nel piano XY o ha più di un giro al centro
return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
fabs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
}
diff --git a/IntersLineArc.h b/IntersLineArc.h
index a112ead..8913f9e 100644
--- a/IntersLineArc.h
+++ b/IntersLineArc.h
@@ -13,7 +13,7 @@
#pragma once
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "CurveLine.h"
#include "CurveArc.h"
diff --git a/IntersLineLine.h b/IntersLineLine.h
index 52540a1..6f1a802 100644
--- a/IntersLineLine.h
+++ b/IntersLineLine.h
@@ -13,7 +13,7 @@
#pragma once
-#include "/EgtDev/Include/EGkIntersCurveCurve.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
#include "/EgtDev/Include/EGkCurveLine.h"
diff --git a/SelfIntersCurve.cpp b/SelfIntersCurve.cpp
new file mode 100644
index 0000000..014a0d9
--- /dev/null
+++ b/SelfIntersCurve.cpp
@@ -0,0 +1,169 @@
+//----------------------------------------------------------------------------
+// EgalTech 2015-2015
+//----------------------------------------------------------------------------
+// File : SelfIntersCurve.cpp Data : 06.07.15 Versione : 1.6g2
+// Contenuto : Implementazione della classe auto-intersezione di curva.
+//
+//
+//
+// Modifiche : 06.07.15 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "GeoConst.h"
+#include "CurveArc.h"
+#include "CurveComposite.h"
+#include "IntersCrvCompoCrvCompo.h"
+#include "/EgtDev/Include/EGkIntersCurves.h"
+#include "/EgtDev/Include/EGkDistPointCurve.h"
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+SelfIntersCurve::SelfIntersCurve( const ICurve& Curve)
+{
+ // Le auto-intersezioni sono calcolate nel piano XY locale.
+
+ // inizializzazioni
+ m_bOverlaps = false ;
+ m_nNumInters = 0 ;
+ m_pOriCrv = &Curve ;
+
+ // se curva è arco da approssimare oppure è curva di Bezier
+ if ( ( m_pOriCrv->GetType() == CRV_ARC && IsArcToApprox( *m_pOriCrv)) ||
+ m_pOriCrv->GetType() == CRV_BEZ) {
+ // approssimo con rette
+ PolyLine PL ;
+ if ( ! m_pOriCrv->ApproxWithLines( EPS_SMALL, ANG_TOL_STD_DEG, ICurve::APL_STD, PL))
+ return ;
+ m_pTmpCrv.Set( CreateBasicCurveComposite()) ;
+ if ( IsNull( m_pTmpCrv))
+ return ;
+ if ( ! GetBasicCurveComposite( Get( m_pTmpCrv))->FromPolyLine( PL))
+ return ;
+ m_pCurve = Get( m_pTmpCrv) ;
+ }
+ // altrimenti uso la curva originale
+ else
+ m_pCurve = m_pOriCrv ;
+
+ // chiamo calcolatore opportuno
+ switch ( m_pCurve->GetType()) {
+ case CRV_LINE :
+ // un segmento non può autointersecarsi (non considero auto-intersezione un segmento perpendicolare a XY)
+ break ;
+ case CRV_ARC :
+ // un arco nel piano XY con angolo al centro non superiore al giro non può autointersecarsi
+ break ;
+ case CRV_COMPO : {
+ IntersCrvCompoCrvCompo intCcCc( *GetCurveComposite( &Curve), *GetCurveComposite( &Curve)) ;
+ if ( intCcCc.m_nNumInters > 0) {
+ m_bOverlaps = intCcCc.m_bOverlaps ;
+ m_nNumInters = intCcCc.m_nNumInters ;
+ for ( int i = 0 ; i < m_nNumInters ; ++ i)
+ m_Info.push_back( intCcCc.m_Info[i]) ;
+ }
+ }
+ break ;
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+SelfIntersCurve::IsArcToApprox( const ICurve& Curve)
+{
+ // recupero l'arco
+ const CurveArc* pArc = GetBasicCurveArc( &Curve) ;
+ if ( pArc == nullptr)
+ return false ;
+ // verifico se non è nel piano XY o ha più di un giro al centro
+ return ( ( ! pArc->GetNormVersor().IsZplus() && ! pArc->GetNormVersor().IsZminus()) ||
+ fabs( pArc->GetAngCenter()) > ANG_FULL + EPS_ANG_ZERO) ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SelfIntersCurve::GetOverlaps( void)
+{
+ return m_bOverlaps ;
+}
+
+//----------------------------------------------------------------------------
+int
+SelfIntersCurve::GetNumInters( void)
+{
+ return m_nNumInters ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SelfIntersCurve::GetIntCrvCrvInfo( int nInd, IntCrvCrvInfo& aInfo)
+{
+ if ( nInd < 0 || nInd >= m_nNumInters)
+ return false ;
+ aInfo = m_Info[nInd] ;
+ // se curva originale approssimata, devo ricalcolare i parametri dei punti di intersezione
+ if ( m_pCurve != m_pOriCrv) {
+ if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[0].ptI, aInfo.IciA[0].dU, 10 * EPS_SMALL))
+ return false ;
+ if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciA[1].ptI, aInfo.IciA[1].dU, 10 * EPS_SMALL))
+ return false ;
+ if ( ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[0].ptI, aInfo.IciB[0].dU, 10 * EPS_SMALL))
+ return false ;
+ if ( aInfo.bOverlap && ! m_pOriCrv->GetParamAtPoint( aInfo.IciB[1].ptI, aInfo.IciB[1].dU, 10 * EPS_SMALL))
+ return false ;
+ }
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+SelfIntersCurve::GetIntersPointNearTo( const Point3d& ptNear, Point3d& ptI)
+{
+ if ( m_nNumInters == 0)
+ return false ;
+
+ // ricerca del punto più vicino tra le intersezioni singole
+ bool bFound = false ;
+ double dMinSqDist = INFINITO * INFINITO ;
+ for ( int i = 0 ; i < m_nNumInters ; ++ i) {
+ // se è un'intersezione singola
+ if ( ! m_Info[i].bOverlap) {
+ // faccio la verifica sul punto
+ Point3d ptP = m_Info[i].IciA[0].ptI ;
+ double dSqDist = SqDist( ptNear, ptP) ;
+ if ( dSqDist < dMinSqDist) {
+ dMinSqDist = dSqDist ;
+ ptI = ptP ;
+ bFound = true ;
+ }
+ }
+ // altrimenti
+ else {
+ // recupero il tratto di sovrapposizione
+ double dUStartTrim, dUEndTrim ;
+ dUStartTrim = m_Info[i].IciA[0].dU ;
+ dUEndTrim = m_Info[i].IciA[1].dU ;
+ PtrOwner pCrv( m_pCurve->CopyParamRange( dUStartTrim, dUEndTrim)) ;
+ if ( IsNull( pCrv))
+ continue ;
+ // cerco il punto
+ int nFlag ;
+ Point3d ptP ;
+ if ( DistPointCurve( ptNear, *pCrv).GetMinDistPoint( 0.5, ptP, nFlag)) {
+ // faccio la verifica
+ double dSqDist = SqDist( ptNear, ptP) ;
+ if ( dSqDist < dMinSqDist) {
+ dMinSqDist = dSqDist ;
+ ptI = ptP ;
+ bFound = true ;
+ }
+ }
+ }
+ }
+
+ return bFound ;
+}