EgtGeomKernel :
- tolta da ChainCurves riduzione tolleranza con dimensione pezzi - aggiunte DistPointTriangle, IntersPlaneTria, IntersPlaneSurfTm - correzioni a IntersCrvCompoCrvCompo per topologia intersezioni - completamente riscritta IntersCoplanarLineTria per robustezza topologica.
This commit is contained in:
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
@@ -267,7 +267,10 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClCompile Include="CurveByApprox.cpp" />
|
||||
<ClCompile Include="CurveByInterp.cpp" />
|
||||
<ClCompile Include="CurveCompositeOffset.cpp" />
|
||||
<ClCompile Include="DistPointTria.cpp" />
|
||||
<ClCompile Include="IntersPlanePlane.cpp" />
|
||||
<ClCompile Include="IntersPlaneSurfTm.cpp" />
|
||||
<ClCompile Include="IntersPlaneTria.cpp" />
|
||||
<ClCompile Include="OffsetCurve.cpp" />
|
||||
<ClCompile Include="DistPointArc.cpp" />
|
||||
<ClCompile Include="DistPointCrvAux.cpp" />
|
||||
@@ -388,6 +391,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EgkCurveLine.h" />
|
||||
<ClInclude Include="..\Include\EGkCurvePointDiffGeom.h" />
|
||||
<ClInclude Include="..\Include\EGkDistPointCurve.h" />
|
||||
<ClInclude Include="..\Include\EGkDistPointTria.h" />
|
||||
<ClInclude Include="..\Include\EGkDllMain.h" />
|
||||
<ClInclude Include="..\Include\EGkExtText.h" />
|
||||
<ClInclude Include="..\Include\EGkFilletChamfer.h" />
|
||||
@@ -408,6 +412,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
|
||||
<ClInclude Include="..\Include\EGkIntersLineSurfTm.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersLineTria.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlanePlane.h" />
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneTria.h" />
|
||||
<ClInclude Include="..\Include\EGkLinePerpTwoCurves.h" />
|
||||
<ClInclude Include="..\Include\EGkLinePntMinDistCurve.h" />
|
||||
<ClInclude Include="..\Include\EGkLinePntPerpCurve.h" />
|
||||
|
||||
@@ -363,6 +363,15 @@
|
||||
<ClCompile Include="IntersPlanePlane.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersPlaneTria.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="IntersPlaneSurfTm.cpp">
|
||||
<Filter>File di origine\GeoInters</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DistPointTria.cpp">
|
||||
<Filter>File di origine\GeoDist</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
@@ -791,6 +800,12 @@
|
||||
<ClInclude Include="..\Include\EGkIntersPlanePlane.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkIntersPlaneTria.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\Include\EGkDistPointTria.h">
|
||||
<Filter>File di intestazione\Include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="EgtGeomKernel.rc">
|
||||
|
||||
+232
-196
@@ -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
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
+244
-127
@@ -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 <array>
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
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<int, 3> 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 ;
|
||||
}
|
||||
// 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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) ;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 <array>
|
||||
|
||||
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 ;
|
||||
}
|
||||
@@ -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 <array>
|
||||
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user