diff --git a/ChainCurves.cpp b/ChainCurves.cpp
index 2fd1499..1b702d5 100644
--- a/ChainCurves.cpp
+++ b/ChainCurves.cpp
@@ -52,10 +52,6 @@ ChainCurves::AddCurve( int nId, const Point3d& ptStart, const Vector3d& vtStart,
// li inserisco nel PointGrid3d
m_PointGrid.InsertPoint( ptStart, nV) ;
m_PointGrid.InsertPoint( ptEnd, - nV) ;
- // verifico il valore di tolleranza rispetto alla distanza tra gli estremi dell'entità (ignoro curve chiuse)
- double dDist = Dist( ptStart, ptEnd) ;
- if ( dDist > EPS_SMALL && m_dToler > dDist / 2)
- m_dToler = max( dDist / 2, EPS_SMALL) ;
return true ;
}
diff --git a/DistPointTria.cpp b/DistPointTria.cpp
new file mode 100644
index 0000000..34e8a09
--- /dev/null
+++ b/DistPointTria.cpp
@@ -0,0 +1,95 @@
+//----------------------------------------------------------------------------
+// EgalTech 2017-2017
+//----------------------------------------------------------------------------
+// File : DistPointTria.cpp Data : 19.10.17 Versione : 1.8j4
+// Contenuto : Implementazione della classe distanza punto da triangolo.
+//
+//
+//
+// Modifiche : 19.10.17 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "ProjPlane.h"
+#include "DistPointLine.h"
+#include "/EgtDev/Include/EGkDistPointTria.h"
+
+
+//----------------------------------------------------------------------------
+DistPointTriangle::DistPointTriangle( const Point3d& ptP, const Triangle3d& Tria)
+{
+ if ( &Tria == nullptr || ! Tria.IsValid()) {
+ // distanza non calcolabile
+ m_dSqDist = - 1 ;
+ return ;
+ }
+
+ // eseguo calcoli e determino il quadrato della distanza
+ Calculate( ptP, Tria) ;
+
+ // dichiaro distanza non ancora calcolata
+ m_dDist = - 1 ;
+}
+
+//----------------------------------------------------------------------------
+void
+DistPointTriangle::Calculate( const Point3d& ptP, const Triangle3d& Tria)
+{
+ // Proiezione del punto sul piano del triangolo
+ Point3d ptQ = ptP - (( ptP - Tria.GetP( 0)) * Tria.GetN()) * Tria.GetN() ;
+
+ // Verifico se il punto proiettato sta nel triangolo
+ if ( PointInTria( ptQ, Tria) != PTT_OUT) {
+ m_dSqDist = SqDist( ptP, ptQ) ;
+ m_ptMinDist = ptQ ;
+ return ;
+ }
+
+ // Determino la minima distanza dai tre lati
+ for ( int i = 0 ; i < 3 ; ++ i) {
+ DistPointLine dstPL( ptQ, Tria.GetP( i), Tria.GetP( ( i + 1) % 3)) ;
+ double dSqDist ;
+ if ( dstPL.GetSqDist( dSqDist) && ( m_dSqDist < 0 || dSqDist < m_dSqDist)) {
+ m_dSqDist = dSqDist ;
+ dstPL.GetMinDistPoint( m_ptMinDist) ;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+bool
+DistPointTriangle::GetSqDist( double& dSqDist)
+{
+ if ( m_dSqDist < 0)
+ return false ;
+
+ dSqDist = m_dSqDist ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+DistPointTriangle::GetDist( double& dDist)
+{
+ if ( m_dSqDist < 0)
+ return false ;
+
+ if ( m_dDist < 0)
+ m_dDist = sqrt( m_dSqDist) ;
+ dDist = m_dDist ;
+ return true ;
+}
+
+//----------------------------------------------------------------------------
+bool
+DistPointTriangle::GetMinDistPoint( Point3d& ptMinDist)
+{
+ if ( m_dSqDist < 0)
+ return false ;
+
+ ptMinDist = m_ptMinDist ;
+ return true ;
+}
diff --git a/EgtGeomKernel.vcxproj b/EgtGeomKernel.vcxproj
index df3a9af..03332ff 100644
--- a/EgtGeomKernel.vcxproj
+++ b/EgtGeomKernel.vcxproj
@@ -267,7 +267,10 @@ copy $(TargetPath) \EgtProg\Dll64
+
+
+
@@ -388,6 +391,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
@@ -408,6 +412,7 @@ copy $(TargetPath) \EgtProg\Dll64
+
diff --git a/EgtGeomKernel.vcxproj.filters b/EgtGeomKernel.vcxproj.filters
index 0f1ed74..a6f8f4a 100644
--- a/EgtGeomKernel.vcxproj.filters
+++ b/EgtGeomKernel.vcxproj.filters
@@ -363,6 +363,15 @@
File di origine\GeoInters
+
+ File di origine\GeoInters
+
+
+ File di origine\GeoInters
+
+
+ File di origine\GeoDist
+
@@ -791,6 +800,12 @@
File di intestazione\Include
+
+ File di intestazione\Include
+
+
+ File di intestazione\Include
+
diff --git a/IntersCrvCompoCrvCompo.cpp b/IntersCrvCompoCrvCompo.cpp
index dac0154..cce1610 100644
--- a/IntersCrvCompoCrvCompo.cpp
+++ b/IntersCrvCompoCrvCompo.cpp
@@ -170,213 +170,249 @@ IntersCrvCompoCrvCompo::IntersCrvCompoCrvCompo( const ICurveComposite& CCompoA,
}
}
- // sistemazione di intersezioni coincidenti
+ // sistemazione di intersezioni coincidenti con ordinamento su prima curva A
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
- for ( int j = 0 ; j < m_nNumInters ; ++ j) {
- // se i due indici coincidono, passo oltre
- if ( i == j)
- continue ;
- // calcolo sottoindici
- 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 ( 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) {
- // per la prima curva tengo i determinati
- m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
- m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
- // se overlap equiverso
- if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
- // per la seconda curva ogni sottotipo è il duale di quello della prima
- m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
- m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
- // per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
- m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
- m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
- }
- // se overlap equiverso
- if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
- m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
- m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
- m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
- m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
- }
- // medio parametri e punti separatamente per le due curve
- MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
- MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
- // se entrambi overlap non cancello
- if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
- continue ;
- // cancello un singolo
- if ( m_Info[i].bOverlap) {
- EraseOtherInfo( i, j) ;
- }
- else {
- EraseCurrentInfo( i, j) ;
- break ;
- }
+ // precedente
+ int j = i - 1 ;
+ if ( j < 0) {
+ if ( bCrvAClosed && m_nNumInters > 1)
+ j = m_nNumInters - 1 ;
+ else
+ continue ;
+ }
+ // calcolo sottoindici
+ 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 ( 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) {
+ // per la prima curva tengo i determinati
+ m_Info[i].IciA[ki].nPrevTy = m_Info[j].IciA[kj].nPrevTy ;
+ m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
+ // se overlap equiverso
+ if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è il duale di quello della prima
+ m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
+ m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
}
- // caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa)
- else 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) {
- // per la prima curva tengo i determinati
- m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
- m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
- // se overlap equiverso
- if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
- // per la seconda curva ogni sottotipo è il duale di quello della prima
- m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
- m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
- // per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
- m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
- m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
- }
- // se overlap equiverso
- if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
- // per la seconda curva ogni sottotipo è il duale di quello della prima
- m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
- m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
- // per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
- m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
- m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
- }
- // medio parametri e punti separatamente per le due curve
- MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
- MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
- // se entrambi overlap non cancello
- if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
- continue ;
- // cancello un singolo
- if ( m_Info[i].bOverlap) {
- EraseOtherInfo( i, j) ;
- }
- else {
- EraseCurrentInfo( i, j) ;
- break ;
- }
+ // se altrimenti overlap controverso
+ else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è come quello della prima ma in posizione invertita
+ m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
+ m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
}
- // caso DET-NULL -> NULL-DET per seconda curva
- else if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
- m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
- // per la seconda curva tengo i determinati
- m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
- m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
- // se overlap equiverso
- if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
- // per la prima curva ogni sottotipo è il duale di quello della seconda
- m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
- m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
- // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
- m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
- m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
- }
- // se overlap equiverso
- if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
- // per la prima curva ogni sottotipo è il duale di quello della seconda
- m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
- m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
- // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
- m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
- m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
- }
- // medio parametri e punti separatamente per le due curve
- MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
- MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
- // se entrambi overlap non cancello
- if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
- continue ;
- // cancello un singolo
- if ( m_Info[i].bOverlap) {
- EraseOtherInfo( i, j) ;
- }
- else {
- EraseCurrentInfo( i, j) ;
- break ;
- }
+ // se overlap equiverso
+ if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
+ m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
+ m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
}
- // caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa)
- else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
- m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
- // per la seconda curva tengo i determinati
- m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
- m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
- // se overlap equiverso
- if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
- // per la prima curva ogni sottotipo è il duale di quello della seconda
- m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
- m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
- // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
- m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
- m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
- }
- // se overlap equiverso
- if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
- // per la prima curva ogni sottotipo è il duale di quello della seconda
- m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
- m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
- }
- // se altrimenti overlap controverso
- else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
- // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
- m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
- m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
- }
- // medio parametri e punti separatamente per le due curve
- MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
- MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
- // se entrambi overlap non cancello
- if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
- continue ;
- // cancello un singolo
- if ( m_Info[i].bOverlap) {
- EraseOtherInfo( i, j) ;
- }
- else {
- EraseCurrentInfo( i, j) ;
- break ;
- }
+ // se altrimenti overlap controverso
+ else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
+ m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
+ m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
}
- // caso NULL-NULL per corrente di prima curva
- else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
- // cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
- EraseCurrentInfo( i, j) ;
- break ;
- }
- // caso NULL-NULL per precedente di prima curva
- else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
- // cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
+ // medio parametri e punti separatamente per le due curve
+ MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
+ MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
+ // se entrambi overlap non cancello
+ if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
+ continue ;
+ // cancello un singolo
+ if ( m_Info[i].bOverlap) {
EraseOtherInfo( i, j) ;
}
+ else {
+ EraseCurrentInfo( i, j) ;
+ }
+ }
+ // caso NULL-DET -> DET-NULL per prima curva (possibile su inizio/fine di curva chiusa)
+ else 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) {
+ // per la prima curva tengo i determinati
+ m_Info[i].IciA[ki].nNextTy = m_Info[j].IciA[kj].nNextTy ;
+ m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciA[ki].nPrevTy ;
+ // se overlap equiverso
+ if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è il duale di quello della prima
+ m_Info[i].IciB[ki].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
+ m_Info[i].IciB[ki].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
+ m_Info[i].IciB[ki].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
+ m_Info[i].IciB[ki].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
+ }
+ // se overlap equiverso
+ if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è il duale di quello della prima
+ m_Info[j].IciB[kj].nPrevTy = GetDualIcct( m_Info[i].IciA[ki].nPrevTy) ;
+ m_Info[j].IciB[kj].nNextTy = GetDualIcct( m_Info[i].IciA[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
+ // per la seconda curva ogni sottotipo è come quello della prima ma in posizione scambiata
+ m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciA[ki].nNextTy ;
+ m_Info[j].IciB[kj].nNextTy = m_Info[i].IciA[ki].nPrevTy ;
+ }
+ // medio parametri e punti separatamente per le due curve
+ MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
+ MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
+ // se entrambi overlap non cancello
+ if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
+ continue ;
+ // cancello un singolo
+ if ( m_Info[i].bOverlap) {
+ EraseOtherInfo( i, j) ;
+ }
+ else {
+ EraseCurrentInfo( i, j) ;
+ }
+ }
+ // caso NULL-NULL per corrente di prima curva
+ else if ( m_Info[i].IciA[ki].nPrevTy == ICCT_NULL && m_Info[i].IciA[ki].nNextTy == ICCT_NULL) {
+ m_Info[j].IciA[kj].nNextTy = m_Info[i].IciA[ki].nNextTy ;
+ // cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
+ EraseCurrentInfo( i, j) ;
+ }
+ // caso NULL-NULL per precedente di prima curva
+ else if ( m_Info[j].IciA[kj].nPrevTy == ICCT_NULL && m_Info[j].IciA[kj].nNextTy == ICCT_NULL) {
+ m_Info[i].IciA[0].nPrevTy = m_Info[j].IciA[0].nPrevTy ;
+ // cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
+ EraseOtherInfo( i, j) ;
}
}
}
+ // sistemazione di intersezioni coincidenti con ordinamento su seconda curva B
+ stable_sort( m_Info.begin(), m_Info.end(), SortGreaterB) ;
+ for ( int i = 0 ; i < m_nNumInters ; ++ i) {
+ // precedente
+ int j = i - 1 ;
+ if ( j < 0) {
+ if ( bCrvAClosed && m_nNumInters > 1)
+ j = m_nNumInters - 1 ;
+ else
+ continue ;
+ }
+ // calcolo sottoindici
+ 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 ( 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 seconda curva
+ if ( m_Info[j].IciB[kj].nPrevTy != ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL &&
+ m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy != ICCT_NULL) {
+ // per la seconda curva tengo i determinati
+ m_Info[i].IciB[ki].nPrevTy = m_Info[j].IciB[kj].nPrevTy ;
+ m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
+ // se overlap equiverso
+ if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
+ // per la prima curva ogni sottotipo è il duale di quello della seconda
+ m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
+ m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
+ // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
+ m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
+ m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
+ }
+ // se overlap equiverso
+ if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
+ // per la prima curva ogni sottotipo è il duale di quello della seconda
+ m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
+ m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
+ // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
+ m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
+ m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
+ }
+ // medio parametri e punti separatamente per le due curve
+ MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
+ MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
+ // se entrambi overlap non cancello
+ if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
+ continue ;
+ // cancello un singolo
+ if ( m_Info[i].bOverlap) {
+ EraseOtherInfo( i, j) ;
+ }
+ else {
+ EraseCurrentInfo( i, j) ;
+ }
+ }
+ // caso NULL-DET -> DET-NULL per seconda curva (possibile su inizio/fine di curva chiusa)
+ else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy != ICCT_NULL &&
+ m_Info[i].IciB[ki].nPrevTy != ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
+ // per la seconda curva tengo i determinati
+ m_Info[i].IciB[ki].nNextTy = m_Info[j].IciB[kj].nNextTy ;
+ m_Info[j].IciB[kj].nPrevTy = m_Info[i].IciB[ki].nPrevTy ;
+ // se overlap equiverso
+ if ( m_Info[i].bOverlap && m_Info[i].bCBOverEq) {
+ // per la prima curva ogni sottotipo è il duale di quello della seconda
+ m_Info[i].IciA[ki].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
+ m_Info[i].IciA[ki].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[i].bOverlap && ! m_Info[i].bCBOverEq) {
+ // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
+ m_Info[i].IciA[ki].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
+ m_Info[i].IciA[ki].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
+ }
+ // se overlap equiverso
+ if ( m_Info[j].bOverlap && m_Info[j].bCBOverEq) {
+ // per la prima curva ogni sottotipo è il duale di quello della seconda
+ m_Info[j].IciA[kj].nPrevTy = GetDualIcct( m_Info[i].IciB[ki].nPrevTy) ;
+ m_Info[j].IciA[kj].nNextTy = GetDualIcct( m_Info[i].IciB[ki].nNextTy) ;
+ }
+ // se altrimenti overlap controverso
+ else if ( m_Info[j].bOverlap && ! m_Info[j].bCBOverEq) {
+ // per la prima curva ogni sottotipo è come quello della seconda ma in posizione scambiata
+ m_Info[j].IciA[kj].nPrevTy = m_Info[i].IciB[ki].nNextTy ;
+ m_Info[j].IciA[kj].nNextTy = m_Info[i].IciB[ki].nPrevTy ;
+ }
+ // medio parametri e punti separatamente per le due curve
+ MediaParamPoints( m_Info[i].IciA[ki], m_Info[j].IciA[kj]) ;
+ MediaParamPoints( m_Info[i].IciB[ki], m_Info[j].IciB[kj]) ;
+ // se entrambi overlap non cancello
+ if ( m_Info[j].bOverlap && m_Info[i].bOverlap)
+ continue ;
+ // cancello un singolo
+ if ( m_Info[i].bOverlap) {
+ EraseOtherInfo( i, j) ;
+ }
+ else {
+ EraseCurrentInfo( i, j) ;
+ }
+ }
+ // caso NULL-NULL per corrente di seconda curva
+ else if ( m_Info[i].IciB[ki].nPrevTy == ICCT_NULL && m_Info[i].IciB[ki].nNextTy == ICCT_NULL) {
+ m_Info[j].IciB[kj].nNextTy = m_Info[i].IciB[ki].nNextTy ;
+ // cancello l'intersezione corrente (non aggiunge nulla rispetto alla precedente)
+ EraseCurrentInfo( i, j) ;
+ }
+ // caso NULL-NULL per precedente di seconda curva
+ else if ( m_Info[j].IciB[kj].nPrevTy == ICCT_NULL && m_Info[j].IciB[kj].nNextTy == ICCT_NULL) {
+ m_Info[i].IciB[0].nPrevTy = m_Info[j].IciB[0].nPrevTy ;
+ // cancello l'intersezione precedente (non aggiunge nulla rispetto alla corrente)
+ EraseOtherInfo( i, j) ;
+ }
+ }
+ }
+ // ripristino ordinamento su prima curva
+ stable_sort( m_Info.begin(), m_Info.end(), SortGreaterA) ;
+
// verifico se sono rimaste delle intersezioni di tipo non definito sulla curva A e cerco di risolverle per continuità
for ( int i = 0 ; i < m_nNumInters ; ++ i) {
// se il tipo di accostamento per la curva A non è definito
diff --git a/IntersLineLine.cpp b/IntersLineLine.cpp
index b7437b6..de58ef5 100644
--- a/IntersLineLine.cpp
+++ b/IntersLineLine.cpp
@@ -162,17 +162,17 @@ IntersLineLine::IntersFiniteLines( const ICurveLine& Line1, const ICurveLine& Li
m_Info.IciB[0].dU = CrossXY( ( ptS2 - ptS1), vtDir1) / dCrossXY ;
// verifica posizione intersezione su prima linea
int nPos1 = ICurve::PP_NULL ; // fuori
- if ( ( m_Info.IciA[0].dU * vtDir1).IsSmall())
+ if ( abs( m_Info.IciA[0].dU * dLen1XY) < EPS_SMALL)
nPos1 = ICurve::PP_START ; // vicino a inizio
- else if ( (( 1 - m_Info.IciA[0].dU) * vtDir1).IsSmall())
+ else if ( abs(( 1 - m_Info.IciA[0].dU) * dLen1XY) < EPS_SMALL)
nPos1 = ICurve::PP_END ; // vicino a fine
else if ( m_Info.IciA[0].dU > 0 && m_Info.IciA[0].dU < 1)
nPos1 = ICurve::PP_MID ; // nell'interno
// verifica posizione intersezione su seconda linea
int nPos2 = ICurve::PP_NULL ; // fuori
- if ( ( m_Info.IciB[0].dU * vtDir2).IsSmall())
+ if ( abs( m_Info.IciB[0].dU * dLen2XY) < EPS_SMALL)
nPos2 = ICurve::PP_START ; // vicino a inizio
- else if ( (( 1 - m_Info.IciB[0].dU) * vtDir2).IsSmall())
+ else if ( abs(( 1 - m_Info.IciB[0].dU) * dLen2XY) < EPS_SMALL)
nPos2 = ICurve::PP_END ; // vicino a fine
else if ( m_Info.IciB[0].dU > 0 && m_Info.IciB[0].dU < 1)
nPos2 = ICurve::PP_MID ; // nell'interno
diff --git a/IntersLineTria.cpp b/IntersLineTria.cpp
index 6fa89ab..100565b 100644
--- a/IntersLineTria.cpp
+++ b/IntersLineTria.cpp
@@ -1,7 +1,7 @@
//----------------------------------------------------------------------------
-// EgalTech 2015-2015
+// EgalTech 2015-2017
//----------------------------------------------------------------------------
-// File : IntersLinePlane.cpp Data : 18.02.15 Versione : 1.6b7
+// File : IntersLineTria.cpp Data : 16.10.17 Versione : 1.8j4
// Contenuto : Implementazione della intersezione linea/triangolo.
//
//
@@ -16,19 +16,17 @@
#include "ProjPlane.h"
#include "CurveLine.h"
#include "IntersLineLine.h"
+#include "IntersLineTria.h"
#include "/EgtDev/Include/EGkFrame3d.h"
-#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
+#include
-
-//----------------------------------------------------------------------------
-static int IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
- Point3d& ptInt, Point3d& ptInt2) ;
+using namespace std ;
//----------------------------------------------------------------------------
int
IntersLineTria( const Point3d& ptL1, const Point3d& ptL2, const Triangle3d& trTria,
- Point3d& ptInt, Point3d& ptInt2)
+ Point3d& ptInt, Point3d& ptInt2, bool bFinite)
{
Vector3d vtL = ptL2 - ptL1 ;
double dLen = vtL.Len() ;
@@ -36,19 +34,19 @@ IntersLineTria( const Point3d& ptL1, const Point3d& ptL2, const Triangle3d& trTr
vtL /= dLen ;
else
vtL = V_NULL ;
- return IntersLineTria( ptL1, vtL, dLen, trTria, ptInt, ptInt2) ;
+ return IntersLineTria( ptL1, vtL, dLen, trTria, ptInt, ptInt2, bFinite) ;
}
//----------------------------------------------------------------------------
int
IntersLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
- Point3d& ptInt, Point3d& ptInt2)
+ Point3d& ptInt, Point3d& ptInt2, bool bFinite)
{
// determino il piano del triangolo
Plane3d plPlane ;
plPlane.Set( trTria.GetP( 0), trTria.GetN()) ;
// calcolo l'intersezione tra il segmento di linea e il piano del triangolo
- int nRes = IntersLinePlane( ptL, vtL, dLen, plPlane, ptInt) ;
+ int nRes = IntersLinePlane( ptL, vtL, dLen, plPlane, ptInt, bFinite) ;
// se non c'è intersezione
if ( nRes == ILPT_NO)
return ILTT_NO ;
@@ -68,134 +66,253 @@ IntersLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Tria
}
// se la linea giace nel piano del triangolo
else {
- return IntersCoplanarLineTria( ptL, vtL, dLen, trTria, ptInt, ptInt2) ;
+ return IntersCoplanarLineTria( ptL, vtL, dLen, trTria, ptInt, ptInt2, bFinite) ;
}
}
//----------------------------------------------------------------------------
int
IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
- Point3d& ptInt, Point3d& ptInt2)
+ Point3d& ptInt, Point3d& ptInt2, bool bFinite)
{
- // verifico se il segmento è completamente contenuto nel triangolo
- ptInt = ptL ;
- ptInt2 = ptL + vtL * dLen ;
- int nPTT = PointInTria( ptInt, trTria) ;
- int nPTT2 = PointInTria( ptInt2, trTria) ;
- if ( ( nPTT == PTT_IN && nPTT2 != PTT_OUT) || ( nPTT != PTT_OUT && nPTT2 == PTT_IN))
- return ILTT_SEGM ;
- if ( nPTT == PTT_VERT && nPTT2 == PTT_VERT)
- return ILTT_SEGM_ON_EDGE ;
- if ( ( nPTT == PTT_VERT || nPTT == PTT_EDGE) && ( nPTT2 == PTT_VERT || nPTT2 == PTT_EDGE)) {
- Point3d ptMed = Media( ptInt, ptInt2, 0.5) ;
- if ( PointInTria( ptMed, trTria) == PTT_IN)
- return ILTT_SEGM ;
- else
+ // Normale alla linea giacente nel piano
+ Vector3d vtN = vtL ^ trTria.GetN() ;
+ vtN.Normalize() ;
+ // calcolo le distanze dei vertici del triangolo dalla retta
+ array< double, 3> vDist ;
+ for ( int i = 0 ; i < 3 ; ++i)
+ vDist[i] = ( trTria.GetP( i) - ptL) * vtN ;
+ // verifico posizione del triangolo rispetto alla retta
+ array vPos = { 0, 0, 0} ;
+ int nVertPos = 0 ; int nVertNeg = 0 ;
+ for ( int i = 0 ; i < 3 ; ++i) {
+ if ( vDist[i] > EPS_SMALL) {
+ vPos[i] = 1 ;
+ ++ nVertPos ;
+ }
+ else if ( vDist[i] < -EPS_SMALL) {
+ vPos[i] = -1 ;
+ ++ nVertNeg ;
+ }
+ }
+ // Se il triangolo giace tutto da una parte della retta, nessuna intersezione
+ if ( nVertPos == 3 || nVertNeg == 3) {
+ return ILTT_NO ;
+ }
+ // Se altrimenti il triangolo giace sulla retta (triangolo schiacciato), sovrapposizione
+ else if ( nVertPos == 0 && nVertNeg == 0) {
+ // Determino i vertici estremi sulla retta
+ double dUmin = ( trTria.GetP( 0) - ptL) * vtL ;
+ double dUmax = ( trTria.GetP( 1) - ptL) * vtL ;
+ ptInt = trTria.GetP( 0) ;
+ ptInt2 = trTria.GetP( 1) ;
+ if ( dUmin > dUmax) {
+ swap( dUmin, dUmax) ;
+ swap( ptInt, ptInt2) ;
+ }
+ double dU2 = ( trTria.GetP( 2) - ptL) * vtL ;
+ if ( dU2 < dUmin)
+ ptInt = trTria.GetP( 2) ;
+ else if ( dU2 > dUmax)
+ ptInt2 = trTria.GetP( 2) ;
+ // Se linea infinita
+ if ( ! bFinite) {
return ILTT_SEGM_ON_EDGE ;
- }
- // se segmento nullo, basta verificare la posizione del punto iniziale
- if ( dLen < EPS_SMALL || vtL.IsSmall()) {
- switch ( nPTT) {
- case PTT_OUT :
- return ILTT_NO ;
- case PTT_VERT :
- return ILTT_VERT ;
- case PTT_EDGE :
- return ILTT_EDGE ;
- default :
- return ILTT_IN ;
}
- }
- // definisco un riferimento coincidente con il piano del triangolo
- Frame3d frRef ;
- if ( ! frRef.Set( trTria.GetP( 0), trTria.GetN(), ( trTria.GetP( 1) - trTria.GetP( 0))))
- return ILTT_NO ;
- // esprimo il triangolo e il segmento in questo riferimento
- Triangle3d trTriaL = trTria ;
- trTriaL.ToLoc( frRef) ;
- Point3d ptLL = ptL ;
- ptLL.ToLoc( frRef) ;
- Vector3d vtLL = vtL ;
- vtLL.ToLoc( frRef) ;
- // calcolo le intersezioni tra i lati del triangolo e il segmento
- CurveLine LineLL ;
- LineLL.Set( ptLL, ptLL + vtLL * dLen) ;
- int nNumInt = 0 ;
- IntCrvCrvInfo IntCCI[3] ;
- for ( int i = 0 ; i < 3 ; ++ i) {
- CurveLine LineTL ;
- LineTL.Set( trTriaL.GetP( i), trTriaL.GetP( ( i + 1) % 3)) ;
- IntersLineLine IntLL( LineLL, LineTL) ;
- if ( IntLL.GetIntCrvCrvInfo( IntCCI[nNumInt]))
- ++ nNumInt ;
- }
- // se nessuna intersezione
- if ( nNumInt == 0)
- return ILTT_NO ;
- // se una sola intersezione
- else if ( nNumInt == 1) {
- // punto di intersezione
- Point3d ptIntL = IntCCI[0].IciA[0].ptI ;
- ptInt = ptIntL ;
- ptInt.ToGlob( frRef) ;
- // se è l'inizio del segmento ( e il resto del segmento deve essere per forza esterno)
- if ( AreSamePointApprox( ptIntL, LineLL.GetStart()))
- return ( ( nPTT == PTT_VERT) ? ILTT_VERT : ILTT_EDGE) ;
- // se è la fine del segmento ( e il resto del segmento deve essere per forza esterno)
- else if ( AreSamePointApprox( ptIntL, LineLL.GetEnd()))
- return ( ( nPTT2 == PTT_VERT) ? ILTT_VERT : ILTT_EDGE) ;
- // altrimenti è un punto intermedio
+ // Altrimenti linea finita
else {
- // se l'inizio è nel triangolo
- if ( nPTT == PTT_IN) {
- ptInt = ptL ;
- ptInt2 = ptInt ;
- return ILTT_SEGM ;
- }
- // se altrimenti è la fine nel triangolo
- else if ( nPTT2 == PTT_IN) {
- ptInt2 = ptL + vtL * dLen ;
- return ILTT_SEGM ;
- }
- // altrimenti entrambi esterni, è un vertice
- else
+ // se massimo coincide con inizio segmento di retta
+ if ( abs( dUmax) < EPS_SMALL) {
+ ptInt = ptInt2 ;
return ILTT_VERT ;
- }
- }
- // se 2 intersezioni
- else if ( nNumInt == 2) {
- // punti di intersezione
- Point3d ptIntL = IntCCI[0].IciA[0].ptI ;
- ptInt = ptIntL ;
- ptInt.ToGlob( frRef) ;
- Point3d ptInt2L = IntCCI[1].IciA[0].ptI ;
- ptInt2 = ptInt2L ;
- ptInt2.ToGlob( frRef) ;
- // se coincidono, deve essere un vertice
- if ( AreSamePointApprox( ptIntL, ptInt2L))
- return ILTT_VERT ;
- // altrimenti è un tratto
- else {
- // le ordino secondo il verso positivo della linea
- if ( ( ptInt - ptL) * vtL > ( ptInt2 - ptL) * vtL)
- std::swap( ptInt, ptInt2) ;
- return ILTT_SEGM ;
- }
- }
- // altrimenti 3 intersezioni, una deve coincidere con un lato le altre due sono i suoi vertici
- else {
- for ( int i = 0 ; i < 3 ; ++ i) {
- if ( IntCCI[i].bOverlap) {
- // punti di intersezione
- Point3d ptIntL = IntCCI[i].IciA[0].ptI ;
- ptInt = ptIntL ;
- ptInt.ToGlob( frRef) ;
- Point3d ptInt2L = IntCCI[i].IciA[1].ptI ;
- ptInt2 = ptInt2L ;
- ptInt2.ToGlob( frRef) ;
+ }
+ // se minimo coincide con fine segmento di retta
+ else if ( abs ( dUmin - dLen) < EPS_SMALL) {
+ return ILTT_VERT ;
+ }
+ // se segmento non si sovrappone
+ else if ( dUmax < 0 || dUmin > dLen) {
+ return ILTT_NO ;
+ }
+ // altrimenti sovrapposizione parziale
+ else {
+ if ( dUmin < 0)
+ ptInt = ptL ;
+ if ( dUmax > dLen)
+ ptInt2 = ptL + vtL * dLen ;
return ILTT_SEGM_ON_EDGE ;
}
}
}
- return ILTT_NO ;
-}
\ No newline at end of file
+ // se altrimenti due vertici del triangolo giacciono sulla linea
+ else if ( nVertPos + nVertNeg == 1) {
+ // Determino i vertici sulla linea
+ int nCount = 0 ;
+ for ( int i = 0 ; i < 3 ; ++i) {
+ if ( vPos[i] == 0) {
+ if ( nCount == 0)
+ ptInt = trTria.GetP( i) ;
+ else
+ ptInt2 = trTria.GetP( i) ;
+ nCount ++ ;
+ }
+ }
+ // Ordino i vertici sulla linea
+ double dUmin = ( ptInt - ptL) * vtL ;
+ double dUmax = ( ptInt2 - ptL) * vtL ;
+ if ( dUmin > dUmax) {
+ swap( dUmin, dUmax) ;
+ swap( ptInt, ptInt2) ;
+ }
+ // Se linea infinita
+ if ( ! bFinite) {
+ return ILTT_SEGM_ON_EDGE ;
+ }
+ // Altrimenti linea finita
+ else {
+ // se massimo coincide con inizio segmento di retta
+ if ( abs( dUmax) < EPS_SMALL) {
+ ptInt = ptInt2 ;
+ return ILTT_VERT ;
+ }
+ // se minimo coincide con fine segmento di retta
+ else if ( abs ( dUmin - dLen) < EPS_SMALL) {
+ return ILTT_VERT ;
+ }
+ // se segmento non si sovrappone
+ else if ( dUmax < 0 || dUmin > dLen) {
+ return ILTT_NO ;
+ }
+ // altrimenti sovrapposizione parziale
+ else {
+ if ( dUmin < 0)
+ ptInt = ptL ;
+ if ( dUmax > dLen)
+ ptInt2 = ptL + vtL * dLen ;
+ return ILTT_SEGM_ON_EDGE ;
+ }
+ }
+ }
+ // se altrimenti un vertice del triangolo giace sulla retta e gli altri due sono dalla stessa parte
+ else if ( ( nVertPos == 2 && nVertNeg == 0) || ( nVertPos == 0 && nVertNeg == 2)) {
+ // Determino quale è il vertice sulla linea
+ for ( int i = 0 ; i < 3 ; ++i) {
+ if ( vPos[i] == 0) {
+ ptInt = trTria.GetP( i) ;
+ break ;
+ }
+ }
+ // Se linea infinita
+ if ( ! bFinite) {
+ return ILTT_VERT ;
+ }
+ // Altrimenti linea finita
+ else {
+ // devo verificare che il vertice stia sul segmento
+ double dU = ( ptInt - ptL) * vtL ;
+ if ( dU < -EPS_SMALL || dU > dLen + EPS_SMALL)
+ return ILTT_NO ;
+ else
+ return ILTT_VERT ;
+ }
+ }
+ // se altrimenti un vertice del triangolo giace sulla retta e gli altri due sono da parti opposte
+ else if ( nVertPos == 1 && nVertNeg == 1) {
+ // Determino il vertice sulla linea e gli altri due da interpolare
+ int nP, nM ;
+ for ( int i = 0 ; i < 3 ; ++i) {
+ if ( vPos[i] == 0)
+ ptInt = trTria.GetP( i) ;
+ else if ( vPos[i] > 0)
+ nP = i ;
+ else
+ nM = i ;
+ }
+ // Calcolo l'intersezione con la linea
+ double dCoeff = abs( vDist[nP]) / ( abs( vDist[nP]) + abs( vDist[nM])) ;
+ ptInt2 = Media( trTria.GetP( nP), trTria.GetP( nM), dCoeff) ;
+ // Ordino i vertici sulla linea
+ double dUmin = ( ptInt - ptL) * vtL ;
+ double dUmax = ( ptInt2 - ptL) * vtL ;
+ if ( dUmin > dUmax) {
+ swap( dUmin, dUmax) ;
+ swap( ptInt, ptInt2) ;
+ }
+ // Se linea infinita
+ if ( ! bFinite) {
+ return ILTT_SEGM ;
+ }
+ // Altrimenti linea finita
+ else {
+ // se massimo coincide con inizio segmento di retta
+ if ( abs( dUmax) < EPS_SMALL) {
+ ptInt = ptInt2 ;
+ return ILTT_EDGE ;
+ }
+ // se minimo coincide con fine segmento di retta
+ else if ( abs ( dUmin - dLen) < EPS_SMALL) {
+ return ILTT_EDGE ;
+ }
+ // se segmento non si sovrappone
+ else if ( dUmax < 0 || dUmin > dLen) {
+ return ILTT_NO ;
+ }
+ // altrimenti sovrapposizione parziale
+ else {
+ if ( dUmin < 0)
+ ptInt = ptL ;
+ if ( dUmax > dLen)
+ ptInt2 = ptL + vtL * dLen ;
+ return ILTT_SEGM ;
+ }
+ }
+ }
+ // altrimenti due vertici giaccio da una parte e uno da quella opposta
+ else {
+ // Determino le intersezioni
+ int nCount = 0 ;
+ for ( int i = 0 ; i < 3 ; ++ i) {
+ int j = ( i + 1) % 3 ;
+ if ( vPos[i] != vPos[j]) {
+ double dCoeff = abs( vDist[i]) / ( abs( vDist[i]) + abs( vDist[j])) ;
+ ( nCount == 0 ? ptInt : ptInt2) = Media( trTria.GetP( i), trTria.GetP( j), dCoeff) ;
+ ++ nCount ;
+ }
+ }
+ // Ordino i vertici sulla linea
+ double dUmin = ( ptInt - ptL) * vtL ;
+ double dUmax = ( ptInt2 - ptL) * vtL ;
+ if ( dUmin > dUmax) {
+ swap( dUmin, dUmax) ;
+ swap( ptInt, ptInt2) ;
+ }
+ // Se linea infinita
+ if ( ! bFinite) {
+ return ILTT_SEGM ;
+ }
+ // Altrimenti linea finita
+ else {
+ // se massimo coincide con inizio segmento di retta
+ if ( abs( dUmax) < EPS_SMALL) {
+ ptInt = ptInt2 ;
+ return ILTT_EDGE ;
+ }
+ // se minimo coincide con fine segmento di retta
+ else if ( abs ( dUmin - dLen) < EPS_SMALL) {
+ return ILTT_EDGE ;
+ }
+ // se segmento non si sovrappone
+ else if ( dUmax < 0 || dUmin > dLen) {
+ return ILTT_NO ;
+ }
+ // altrimenti sovrapposizione parziale
+ else {
+ if ( dUmin < 0)
+ ptInt = ptL ;
+ if ( dUmax > dLen)
+ ptInt2 = ptL + vtL * dLen ;
+ return ILTT_SEGM ;
+ }
+ }
+ }
+}
diff --git a/IntersLineTria.h b/IntersLineTria.h
new file mode 100644
index 0000000..2c598dc
--- /dev/null
+++ b/IntersLineTria.h
@@ -0,0 +1,21 @@
+//----------------------------------------------------------------------------
+// EgalTech 2017-2017
+//----------------------------------------------------------------------------
+// File : IntersLineTria.cpp Data : 16.10.17 Versione : 1.8j4
+// Contenuto : Dichiarazione di funzioni intersezione linea/triangolo.
+//
+//
+//
+// Modifiche : 16.10.17 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+#pragma once
+
+#include "/EgtDev/Include/EGkIntersLineTria.h"
+
+//----------------------------------------------------------------------------
+int IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, const Triangle3d& trTria,
+ Point3d& ptInt, Point3d& ptInt2, bool bFinite = true) ;
+
diff --git a/IntersPlanePlane.cpp b/IntersPlanePlane.cpp
index 48e5539..1791d82 100644
--- a/IntersPlanePlane.cpp
+++ b/IntersPlanePlane.cpp
@@ -6,15 +6,15 @@
//
//
//
-// Modifiche : 15.12.17 DS Creazione modulo.
+// Modifiche : 15.10.17 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
-#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
+#include "/EgtDev/Include/EGkIntersLinePlane.h"
//----------------------------------------------------------------------------
int
diff --git a/IntersPlaneSurfTm.cpp b/IntersPlaneSurfTm.cpp
new file mode 100644
index 0000000..08ddebc
--- /dev/null
+++ b/IntersPlaneSurfTm.cpp
@@ -0,0 +1,206 @@
+//----------------------------------------------------------------------------
+// EgalTech 2017-2017
+//----------------------------------------------------------------------------
+// File : IntersPlaneSurfTm.cpp Data : 16.10.17 Versione : 1.8j4
+// Contenuto : Implementazione della intersezione piano/superficie trimesh.
+//
+//
+//
+// Modifiche : 16.10.17 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "ProjPlane.h"
+#include "IntersLineSurfTm.h"
+#include "CurveLine.h"
+#include "DistPointLine.h"
+#include "HashGrids3d.h"
+#include "/EgtDev/Include/EGkIntersPlaneSurfTm.h"
+#include "/EgtDev/Include/EGkIntersPlaneTria.h"
+#include "/EgtDev/Include/EGkPointGrid3d.h"
+#include "/EgtDev/Include/EGkDistPointTria.h"
+#include
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+// Intersezione di un piano con una superficie TriMesh
+//----------------------------------------------------------------------------
+bool
+IntersPlaneSurfTm( const Plane3d& plPlane, const ISurfTriMesh& Stm,
+ PNTVECTOR& vPnt, BIPNTVECTOR& vBpt, TRIA3DVECTOR& vTria)
+{
+ // verifico piano
+ if ( &plPlane == nullptr || plPlane.GetVersN().IsSmall())
+ return false ;
+ // verifico superficie
+ if ( &Stm == nullptr || ! Stm.IsValid())
+ return false ;
+ // verifico parametri di ritorno
+ if ( &vPnt == nullptr || &vBpt == nullptr || &vTria == nullptr)
+ return false ;
+ vPnt.clear() ;
+ vBpt.clear() ;
+ vTria.clear() ;
+
+ // per ricerca veloce di punti ripetuti
+ PointGrid3d PtGrid ;
+ PtGrid.Init( 100) ;
+
+ // per ricerca veloce di linee ripetute
+ HashGrids3d LnGrid ;
+ LnGrid.SetActivationGrid( true) ;
+
+ // per ricerca veloce di triangoli ripetuti
+ HashGrids3d TrGrid ;
+ TrGrid.SetActivationGrid( true) ;
+
+ // cerco i triangoli intersecati dal piano
+ Triangle3d Tria ;
+ int nT = Stm.GetFirstTriangle( Tria) ;
+ while ( nT != SVT_NULL) {
+ // intersezione tra il piano e il triangolo
+ Point3d ptInt, ptInt2 ;
+ int nRes = IntersPlaneTria( plPlane, Tria, ptInt, ptInt2) ;
+ // se vertice
+ if ( nRes == IPTT_VERT) {
+ // verifico se punto già inserito
+ int nId ;
+ if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
+ vPnt.emplace_back( ptInt) ;
+ PtGrid.InsertPoint( ptInt, int( vPnt.size()) - 1) ;
+ }
+ }
+ // se altrimenti segmento
+ else if ( nRes == IPTT_EDGE || nRes == IPTT_YES) {
+ // se abbastanza lungo
+ if ( ! AreSamePointApprox( ptInt, ptInt2)) {
+ // verifico se già inserito
+ bool bFound = false ;
+ BBox3d b3Line( ptInt, ptInt2) ;
+ INTVECTOR vnIds ;
+ if ( LnGrid.Find( b3Line, vnIds)) {
+ for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
+ int nA = vnIds[i] ;
+ const Point3d& ptOth = vBpt[nA].first ;
+ const Point3d& ptOth2 = vBpt[nA].second ;
+ if ( ( AreSamePointEpsilon( ptInt, ptOth, 10 * EPS_SMALL) &&
+ AreSamePointEpsilon( ptInt2, ptOth2, 10 * EPS_SMALL)) ||
+ ( AreSamePointEpsilon( ptInt, ptOth2, 10 * EPS_SMALL) &&
+ AreSamePointEpsilon( ptInt2, ptOth, 10 * EPS_SMALL))) {
+ bFound = true ;
+ break ;
+ }
+ }
+ }
+ // se non inserito, procedo
+ if ( ! bFound) {
+ vBpt.emplace_back( ptInt, ptInt2) ;
+ LnGrid.Add( int( vBpt.size()) - 1, b3Line) ;
+ LnGrid.Update() ;
+ }
+ }
+ }
+ // se altrimenti l'intero triangolo
+ else if ( nRes == IPTT_OVERLAPS) {
+ // verifico se triangolo già inserito
+ bool bFound = false ;
+ BBox3d b3Tria( Tria.GetP( 0), Tria.GetP( 1)) ;
+ b3Tria.Add( Tria.GetP( 2)) ;
+ INTVECTOR vnIds ;
+ if ( TrGrid.Find( b3Tria, vnIds)) {
+ for ( int i = 0 ; i < int( vnIds.size()) ; ++ i) {
+ int nA = vnIds[i] ;
+ const Triangle3d& trOth = vTria[nA] ;
+ array< bool, 3> bOth = { false, false, false} ;
+ for ( int j = 0 ; j < 3 ; ++ j) {
+ for ( int k = 0 ; k < 3 ; ++ k) {
+ if ( ! bOth[k])
+ bOth[k] = AreSamePointEpsilon( Tria.GetP( j), trOth.GetP( k), 10 * EPS_SMALL) ;
+ }
+ }
+ if ( bOth[0] && bOth[1] && bOth[2]) {
+ bFound = true ;
+ break ;
+ }
+ }
+ }
+ // se non inserito, procedo
+ if ( ! bFound) {
+ vTria.emplace_back( Tria) ;
+ TrGrid.Add( int( vTria.size()) - 1, b3Tria) ;
+ TrGrid.Update() ;
+ }
+ }
+ // passo al prossimo triangolo
+ nT = Stm.GetNextTriangle( nT, Tria) ;
+ }
+
+ // rimuovo i punti che stanno sui segmenti
+ for ( int i = int( vPnt.size()) - 1 ; i >= 0 ; -- i) {
+ bool bFound = false ;
+ BBox3d b3Pnt( vPnt[i]) ;
+ b3Pnt.Expand( 10 * EPS_SMALL) ;
+ INTVECTOR vnIds ;
+ if ( LnGrid.Find( b3Pnt, vnIds)) {
+ for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
+ int nA = vnIds[j] ;
+ double dSqDist ;
+ if ( DistPointLine( vPnt[i], vBpt[nA].first, vBpt[nA].second).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
+ bFound = true ;
+ break ;
+ }
+ }
+ }
+ if ( bFound)
+ vPnt.erase( vPnt.begin() + i) ;
+ }
+
+ // rimuovo i punti che stanno sui triangoli
+ for ( int i = int( vPnt.size()) - 1 ; i >= 0 ; -- i) {
+ bool bFound = false ;
+ BBox3d b3Pnt( vPnt[i]) ;
+ b3Pnt.Expand( 10 * EPS_SMALL) ;
+ INTVECTOR vnIds ;
+ if ( TrGrid.Find( b3Pnt, vnIds)) {
+ for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
+ int nA = vnIds[j] ;
+ const Triangle3d& trOth = vTria[nA] ;
+ double dSqDist ;
+ if ( DistPointTriangle( vPnt[i], trOth).GetSqDist( dSqDist) && dSqDist < 100 * SQ_EPS_SMALL) {
+ bFound = true ;
+ break ;
+ }
+ }
+ }
+ if ( bFound)
+ vPnt.erase( vPnt.begin() + i) ;
+ }
+
+ // rimuovo i segmenti che stanno sui triangoli
+ for ( int i = int( vBpt.size()) - 1 ; i >= 0 ; -- i) {
+ bool bFound = false ;
+ Point3d ptStart = vBpt[i].first ;
+ Point3d ptEnd = vBpt[i].second ;
+ BBox3d b3Line( ptStart, ptEnd) ;
+ INTVECTOR vnIds ;
+ if ( TrGrid.Find( b3Line, vnIds)) {
+ for ( int j = 0 ; j < int( vnIds.size()) ; ++ j) {
+ int nA = vnIds[j] ;
+ const Triangle3d& trOth = vTria[nA] ;
+ Point3d ptInt, ptInt2 ;
+ if ( IntersLineTria( ptStart, ptEnd, trOth, ptInt, ptInt2) == ILTT_SEGM_ON_EDGE) {
+ bFound = true ;
+ break ;
+ }
+ }
+ }
+ if ( bFound)
+ vBpt.erase( vBpt.begin() + i) ;
+ }
+
+ return true ;
+}
diff --git a/IntersPlaneTria.cpp b/IntersPlaneTria.cpp
new file mode 100644
index 0000000..52a4cab
--- /dev/null
+++ b/IntersPlaneTria.cpp
@@ -0,0 +1,63 @@
+//----------------------------------------------------------------------------
+// EgalTech 2017-2017
+//----------------------------------------------------------------------------
+// File : IntersPlaneTria.cpp Data : 16.10.17 Versione : 1.8j3
+// Contenuto : Implementazione della intersezione piano/triangolo.
+//
+//
+//
+// Modifiche : 16.10.17 DS Creazione modulo.
+//
+//
+//----------------------------------------------------------------------------
+
+//--------------------------- Include ----------------------------------------
+#include "stdafx.h"
+#include "IntersLineTria.h"
+#include "/EgtDev/Include/EGkIntersPlaneTria.h"
+#include "/EgtDev/Include/EGkIntersPlanePlane.h"
+#include
+
+using namespace std ;
+
+//----------------------------------------------------------------------------
+int
+IntersPlaneTria( const Plane3d& plPlane, const Triangle3d& trTria, Point3d& ptInt, Point3d& ptInt2)
+{
+ // calcolo le distanze dei vertici del triangolo dal piano
+ array< double, 3> vDist ;
+ for ( int i = 0 ; i < 3 ; ++i)
+ vDist[i] = ( ( trTria.GetP( i) - ORIG) * plPlane.GetVersN() - plPlane.GetDist()) ;
+ // verifico posizione del triangolo rispetto al piano
+ int nVertPos = 0 ; int nVertNeg = 0 ;
+ for ( auto& dDist : vDist) {
+ if ( dDist > EPS_SMALL)
+ ++ nVertPos ;
+ else if ( dDist < -EPS_SMALL)
+ ++ nVertNeg ;
+ }
+ // se il triangolo giace nel piano, sovrapposizione
+ if ( nVertPos == 0 && nVertNeg == 0)
+ return IPTT_OVERLAPS ;
+ // se altrimenti il triangolo giace tutto da una parte del piano, nessuna intersezione
+ else if ( nVertPos == 3 || nVertNeg == 3)
+ return IPTT_NO ;
+
+ // intersezione tra il piano e il piano del triangolo
+ Plane3d plTria ;
+ plTria.Set( trTria.GetP( 0), trTria.GetN()) ;
+ Point3d ptL ; Vector3d vtL ;
+ if ( IntersPlanePlane( plPlane, plTria, ptL, vtL) != IPPT_YES)
+ return IPTT_NO ;
+
+ // interseco la linea con il triangolo (giace nel suo piano)
+ int nRes = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria, ptInt, ptInt2, false) ;
+ switch( nRes) {
+ case ILTT_NO : return IPTT_NO ;
+ case ILTT_SEGM : return IPTT_YES ;
+ case ILTT_SEGM_ON_EDGE : return IPTT_EDGE ;
+ case ILTT_VERT : return IPTT_VERT ;
+ case ILTT_EDGE : return IPTT_NO ;
+ default : return IPTT_NO ;
+ }
+}
diff --git a/MC_Tables.h b/MC_Tables.h
index 27803ec..7106ee3 100644
--- a/MC_Tables.h
+++ b/MC_Tables.h
@@ -1747,7 +1747,7 @@ static int nIndexVsIndex10[6][2] = { { 60 , 5 },
static int Cases10Plus[6][2][12] = {
-/* 195: 0, 1, 6, 7, */ {{ 7, 5, 9, 9, 8, 7, 1, 0, 11, 11, 3, 1 },// 0
+/* 195: 0, 1, 6, 7, */ {{ 7, 5, 9, 9, 8, 7, 1, 10, 11, 11, 3, 1 },// 0
{ 2, 4, 4, 7, 5, 9, 8, 1, 10, 11, 3, -1}},
/* 85: 0, 2, 4, 6, */ {{ 0, 4, 1, 4, 5, 1, 3, 2, 6, 3, 6, 7 },// 1
diff --git a/PolyLine.cpp b/PolyLine.cpp
index 5d155c0..f94795c 100644
--- a/PolyLine.cpp
+++ b/PolyLine.cpp
@@ -845,17 +845,18 @@ PolyLine::MyApproxOnSide( const Vector3d& vtN, bool bLeftSide, double dToler)
( ! bLeftSide && dCrossXY > 0 && dCros2XY > 0)) {
// calcolo del punto di intersezione tra i segmenti precP-currP e nextP-next2P, allungati al centro
CurveLine Line1, Line2 ;
- if ( Line1.Set( precP->first, currP->first) && Line1.ExtendEndByLen( 1000) &&
- Line2.Set( nextP->first, nex2P->first) && Line2.ExtendStartByLen( 1000)) {
+ if ( Line1.Set( precP->first, currP->first) &&
+ Line2.Set( nextP->first, nex2P->first)) {
// se la normale non coincide con l'asse Z, devo portare le linee nel riferimento OCS di questa
Frame3d frNorm ;
if ( ! vtN.IsZplus() && ! vtN.IsZminus())
frNorm.Set( ORIG, vtN) ;
Line1.ToLoc( frNorm) ;
Line2.ToLoc( frNorm) ;
- IntersLineLine IntLL( Line1, Line2) ;
+ IntersLineLine IntLL( Line1, Line2, false) ;
IntCrvCrvInfo IntInfo ;
- if ( IntLL.GetIntCrvCrvInfo( IntInfo) && ! IntInfo.bOverlap) {
+ if ( IntLL.GetIntCrvCrvInfo( IntInfo) &&
+ ! IntInfo.bOverlap && IntInfo.IciA[0].dU > 1 && IntInfo.IciB[0].dU < 0) {
Point3d ptInt = 0.5 * ( IntInfo.IciA[0].ptI + IntInfo.IciB[0].ptI) ;
ptInt.ToGlob( frNorm) ;
// verifico che distanza dell'intersezione dal segmento currP-nextP sia inferiore a tolleranza corrente
diff --git a/SurfFlatRegionBooleans.cpp b/SurfFlatRegionBooleans.cpp
index 868d208..af13c4c 100644
--- a/SurfFlatRegionBooleans.cpp
+++ b/SurfFlatRegionBooleans.cpp
@@ -319,8 +319,9 @@ bool
SurfFlatRegion::MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop)
{
// concateno le curve
+ double dToler = 5 * EPS_SMALL ;
ChainCurves chainC ;
- chainC.Init( false, 5 * EPS_SMALL, int( vpCurve.size())) ;
+ chainC.Init( false, dToler, int( vpCurve.size())) ;
for ( int i = 0 ; i < int( vpCurve.size()) ; ++i) {
// recupero i dati della curva necessari al concatenamento e li assegno
Point3d ptStart, ptEnd ;
@@ -342,13 +343,26 @@ SurfFlatRegion::MyChainCurves( PCRV_DEQUE& vpCurve, PCRV_DEQUE& vpLoop)
// recupero le curve e le inserisco nella nuova curva composita
for ( auto i : vIds) {
// la aggiungo alla curva composta
- if ( ! pCrvCompo->AddCurve( vpCurve[i-1], true, 5 * EPS_SMALL))
+ if ( ! pCrvCompo->AddCurve( vpCurve[i-1], true, dToler))
return false ;
vpCurve[i-1] = nullptr ;
}
// aggiorno il nuovo punto vicino
if ( pCrvCompo->GetCurveCount() > 0)
pCrvCompo->GetEndPoint( ptNearStart) ;
+ // se lunghezza curva inferiore a 2 volte la tolleranza, la salto
+ double dCrvLen ;
+ if ( ! pCrvCompo->GetLength( dCrvLen) || dCrvLen < 2. * dToler)
+ continue ;
+ // se curva chiusa entro 2 volte la tolleranza ma considerata aperta, la chiudo bene
+ Point3d ptStart, ptEnd ;
+ if ( pCrvCompo->GetStartPoint( ptStart) &&
+ pCrvCompo->GetEndPoint( ptEnd) &&
+ AreSamePointEpsilon( ptStart, ptEnd, 2. * dToler) &&
+ ! AreSamePointApprox( ptStart, ptEnd)) {
+ // porto il punto finale a coincidere esattamente con l'inizio
+ pCrvCompo->ModifyEnd( ptStart) ;
+ }
// compatto la nuova curva
pCrvCompo->MergeCurves( LIN_TOL_MIN, ANG_TOL_STD_DEG) ;
// inserisco la curva composita nel gruppo destinazione