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:
+100
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user