EgtGeomKernel :
- migliorie a RemoveTJunctions di SurfTriMesh.
This commit is contained in:
@@ -19,6 +19,141 @@
|
||||
|
||||
using namespace std ;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunctions(void)
|
||||
{
|
||||
// Vettore di indici dei vertici sui lati del triangolo corrente
|
||||
unordered_map< int, INTVECTOR> TriaMap ;
|
||||
|
||||
// Ciclo sui triangoli della superficie per determinare gli altri vertici sul loro perimetro
|
||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Vettore degli altri vertici sul contorno del triangolo
|
||||
INTVECTOR vVertOtl ;
|
||||
// Box del triangolo
|
||||
BBox3d b3Tria ;
|
||||
trTria.GetLocalBBox( b3Tria) ;
|
||||
INTVECTOR vNearTria ;
|
||||
GetAllTriaOverlapBox( b3Tria, vNearTria) ;
|
||||
// Ciclo sui lati del triangolo
|
||||
for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) {
|
||||
// aggiungo al vettore il vertice iniziale del lato
|
||||
vVertOtl.emplace_back( m_vTria[nT].nIdVert[nSeg]) ;
|
||||
// Se in questo lato il triangolo è adiacente a un altro, lo salto.
|
||||
if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL && m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL)
|
||||
continue ;
|
||||
int nPrevSize = int( vVertOtl.size()) ;
|
||||
// recupero la geometria del lato
|
||||
Point3d ptSegSt = trTria.GetP( nSeg) ;
|
||||
Point3d ptSegEn = trTria.GetP( ( nSeg + 1) % 3) ;
|
||||
Vector3d vtSeg = ptSegEn - ptSegSt ;
|
||||
double dSegLen = vtSeg.Len() ;
|
||||
if ( dSegLen < EPS_SMALL)
|
||||
continue ;
|
||||
vtSeg /= dSegLen ;
|
||||
// Ciclo sui triangoli vicini
|
||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||
// Salto il triangolo se è quello di riferimento
|
||||
if ( vNearTria[nI] == nT)
|
||||
continue ;
|
||||
// Cerco i vertici che stanno sul lato del triangolo
|
||||
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
|
||||
Point3d ptVert ;
|
||||
if ( ! GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], ptVert))
|
||||
continue ;
|
||||
double dProj = ( ptVert - ptSegSt) * vtSeg ;
|
||||
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
|
||||
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < SQ_EPS_TRIA_H)
|
||||
vVertOtl.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||
}
|
||||
}
|
||||
// Riordino i vertici sul segmento
|
||||
auto SortVerteces = [ 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) ;
|
||||
}
|
||||
// Se ci sono più di 3 vertici
|
||||
if ( vVertOtl.size() > 3) {
|
||||
// Elimino i vertici ripetuti
|
||||
vVertOtl.erase( unique( vVertOtl.begin(), vVertOtl.end()), vVertOtl.end()) ;
|
||||
// Se ci sono ancora più di 3 vertici, inserisco nel Map
|
||||
if ( vVertOtl.size() > 3)
|
||||
TriaMap.emplace( nT, vVertOtl) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Ciclo sui triangoli da sistemare
|
||||
for ( auto itT = TriaMap.begin() ; itT != TriaMap.end() ; ++ itT) {
|
||||
// Indice del triangolo
|
||||
int nT = itT->first ;
|
||||
// Vettore degli altri vertici sul perimetro
|
||||
const INTVECTOR& vVertOtl = itT->second ;
|
||||
// Se il triangolo non è valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
// Salvo eventuale indice di faccetta
|
||||
int nFacet = m_vTria[nT].nIdFacet ;
|
||||
if ( nFacet > int( m_vFacet.size()) || m_vFacet[nFacet] != nT)
|
||||
nFacet = SVT_NULL ;
|
||||
// Rimuovo il triangolo
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
// Aggiungo i nuovi triangoli
|
||||
int nLastNewTria = SVT_NULL ;
|
||||
// Se ci sono 4 vertici, inserisco due triangoli
|
||||
if ( vVertOtl.size() == 4) {
|
||||
// se 1-2-3 è triangolo (e quindi 0-1-3)
|
||||
int nNew1Id[3] = { vVertOtl[1], vVertOtl[2], vVertOtl[3]} ;
|
||||
int nNew1Tria = AddTriangle( nNew1Id, nTFlag) ;
|
||||
if ( nNew1Tria != SVT_NULL && nNew1Tria != SVT_DEL) {
|
||||
nLastNewTria = nNew1Tria ;
|
||||
int nNew2Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[3]} ;
|
||||
int nNew2Tria = AddTriangle( nNew2Id, nTFlag) ;
|
||||
if ( nNew2Tria != SVT_NULL && nNew2Tria != SVT_DEL)
|
||||
nLastNewTria = nNew2Tria ;
|
||||
}
|
||||
// altrimenti 0-1-2 e 2-3-0
|
||||
else {
|
||||
int nNew3Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[2]} ;
|
||||
int nNew3Tria = AddTriangle( nNew3Id, nTFlag) ;
|
||||
if ( nNew3Tria != SVT_NULL && nNew3Tria != SVT_DEL)
|
||||
nLastNewTria = nNew3Tria ;
|
||||
int nNew4Id[3] = { vVertOtl[2], vVertOtl[3], vVertOtl[0]} ;
|
||||
int nNew4Tria = AddTriangle( nNew4Id, nTFlag) ;
|
||||
if ( nNew4Tria != SVT_NULL && nNew4Tria != SVT_DEL)
|
||||
nLastNewTria = nNew4Tria ;
|
||||
}
|
||||
}
|
||||
// altrimenti inserisco un ventaglio di triangoli dal centro ai vertici
|
||||
else {
|
||||
Point3d ptTriaCen = trTria.GetCentroid() ;
|
||||
int nCenIndex = AddVertex( ptTriaCen) ;
|
||||
int nVertNum = int( vVertOtl.size()) ;
|
||||
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
|
||||
int nEnV = ( nStV + 1) % nVertNum ;
|
||||
int nNewId[3] = { nCenIndex, vVertOtl[nStV], vVertOtl[nEnV]} ;
|
||||
int nNewTria = AddTriangle( nNewId, nTFlag) ;
|
||||
if ( nNewTria != SVT_NULL && nNewTria != SVT_DEL)
|
||||
nLastNewTria = nNewTria ;
|
||||
}
|
||||
}
|
||||
// Eventuale aggiustamento per indice di faccetta
|
||||
if ( nFacet != SVT_NULL && nLastNewTria != SVT_NULL)
|
||||
m_vFacet[nFacet] = nLastNewTria ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool
|
||||
IsVertex( PNTULIST& PointList, PNTULIST::const_iterator itCurr)
|
||||
|
||||
Reference in New Issue
Block a user