EgtGeomKernel 2.4c1 :

- migliorato calcolo distanza minima tra due linee
- eliminate da Trimesh parti inutili
- in Trimesh calcolo Loop di una faccia risolto problema di ciclo infinito
- in Trimesh aggiunta funzione per eliminare triangoli esattamente sovrapposti.
This commit is contained in:
DarioS
2022-03-14 09:03:13 +01:00
parent de34cfb7e8
commit f353e65e61
10 changed files with 251 additions and 2241 deletions
+100 -4
View File
@@ -12,17 +12,112 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "Triangulate.h"
#include "SurfTriMesh.h"
#include "CurveLine.h"
#include "Triangulate.h"
#include "DistPointLine.h"
#include "DistLineLine.h"
#include <unordered_map>
using namespace std ;
//----------------------------------------------------------------------------
bool
SurfTriMesh::RemoveTJunctions(void)
SurfTriMesh::RemoveDoubleTriangles( bool& bModified)
{
bModified = false ;
// ciclo sui triangoli
int nTriaNum = GetTriangleSize() ;
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
// se cancellato passo al successivo
if ( m_vTria[nT].nIdVert[0] == SVT_DEL)
continue ;
// recupero i vertici dei triangoli
int nIdV[3] ;
GetTriangle( nT, nIdV) ;
// ciclo sui triangoli adiacenti
for ( int nE = 0 ; nE < 3 ; ++ nE) {
// recupero triangolo adiacente, se non esiste passo al successivo
int nAdjT = m_vTria[nT].nIdAdjac[nE] ;
if ( nAdjT == SVT_NULL || nAdjT == SVT_DEL)
continue ;
// recupero i vertici del triangolo adiacente
int nAdjIdV[3] ;
GetTriangle( nAdjT, nAdjIdV) ;
// verifico se questi vertici coincidono con quelli del triangolo di riferimento
int nCoinc = 0 ;
for ( int i = 0 ; i < 3 ; ++ i) {
for ( int j = 0 ; j < 3 ; ++ j) {
if ( nIdV[i] == nAdjIdV[j])
++ nCoinc ;
}
}
if ( nCoinc == 3) {
RemoveTriangle( nAdjT) ;
bModified = true ;
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::FlipTriangles( int nTA, int nTB)
{
// Verifico esistenza triangoli
if ( ! ExistsTriangle( nTA) || ! ExistsTriangle( nTB))
return false ;
// Verifico adiacenza triangoli
int nEdgeA ;
for ( nEdgeA = 0 ; nEdgeA < 3 ; ++ nEdgeA) {
if ( m_vTria[nTA].nIdAdjac[nEdgeA] == nTB)
break ;
}
int nEdgeB ;
for ( nEdgeB = 0 ; nEdgeB < 3 ; ++ nEdgeB) {
if ( m_vTria[nTB].nIdAdjac[nEdgeB] == nTA)
break ;
}
// Se non sono adiacenti tra loro, impossibile flip
if ( nEdgeA == 3 && nEdgeB == 3)
return false ;
// Recupero i vertici del triangolo A
Point3d ptSegSt, ptSegEn, ptVertA ;
if ( ! GetVertex( m_vTria[nTA].nIdVert[nEdgeA], ptSegSt) ||
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 1) % 3], ptSegEn) ||
! GetVertex( m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3], ptVertA))
return false ;
// Recupero il vertice opposto del triangolo B
Point3d ptVertB ;
if ( ! GetVertex( m_vTria[nTB].nIdVert[( nEdgeB + 2) % 3], ptVertB))
return false ;
// Verifico se possibile il flip (le diagonali del quadrilatero si intersecano internamente)
DistLineLine DiagDist( ptSegSt, ptSegEn, ptVertA, ptVertB) ;
if ( ! DiagDist.IsSmall())
return false ;
double dPos1, dPos2 ;
if ( ! DiagDist.GetPositionsAtMinDistPoints( dPos1, dPos2) ||
dPos1 < EPS_SMALL || dPos1 > ( ptSegEn - ptSegSt).Len() - EPS_SMALL ||
dPos2 < EPS_SMALL || dPos2 > ( ptVertB - ptVertA).Len() - EPS_SMALL)
return false ;
// Eseguo il flipping
m_vTria[nTA].nIdVert[nEdgeA] = m_vTria[nTB].nIdVert[( nEdgeB + 2) % 3] ;
m_vTria[nTB].nIdVert[nEdgeB] = m_vTria[nTA].nIdVert[( nEdgeA + 2) % 3] ;
m_vTria[nTA].nIdAdjac[nEdgeA] = m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] ;
m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] = nTB ;
m_vTria[nTB].nIdAdjac[nEdgeB] = m_vTria[nTA].nIdAdjac[( nEdgeA + 2) % 3] ;
m_vTria[nTB].nIdAdjac[( nEdgeB + 2) % 3] = nTA ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::RemoveTJunctions( bool& bModified)
{
bModified = false ;
// Vettore di indici dei vertici sui lati del triangolo corrente
unordered_map< int, INTVECTOR> TriaMap ;
@@ -72,13 +167,13 @@ SurfTriMesh::RemoveTJunctions(void)
}
}
// Riordino i vertici sul segmento
auto SortVerteces = [ this, &ptSegSt, &vtSeg]( const int nV1, const int nV2)
auto SortVertices = [ this, &ptSegSt, &vtSeg]( const int nV1, const int nV2)
{ Point3d ptV1, ptV2 ;
GetVertex( nV1, ptV1) ;
GetVertex( nV2, ptV2) ;
return ( ( ptV1 - ptSegSt) * vtSeg < ( ptV2 - ptSegSt) * vtSeg) ;
} ;
sort( vVertOtl.begin() + nPrevSize, vVertOtl.end(), SortVerteces) ;
sort( vVertOtl.begin() + nPrevSize, vVertOtl.end(), SortVertices) ;
}
// Se ci sono più di 3 vertici
if ( vVertOtl.size() > 3) {
@@ -107,6 +202,7 @@ SurfTriMesh::RemoveTJunctions(void)
// Rimuovo il triangolo
int nTFlag = m_vTria[nT].nTFlag ;
RemoveTriangle( nT) ;
bModified = true ;
// Aggiungo i nuovi triangoli
int nLastNewTria = SVT_NULL ;
// Se ci sono 4 vertici, inserisco due triangoli