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 ; +}