EgtGeomKernel 2.4a1 :
- migliorie alle booleane delle superfici trimesh.
This commit is contained in:
Binary file not shown.
+1
-1
@@ -411,7 +411,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
|
||||
bool RemoveTripleTriangles( void) ;
|
||||
bool ScanForTripleTriangles( bool& bModified) ;
|
||||
bool FlipTriangles( int nTA, int nTB) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen) ;
|
||||
bool SimplifyFacets( double dMaxEdgeLen, bool bForced = false) ;
|
||||
bool AddChainToChain( const Chain& ChainToAdd, PNTVECTOR& OrigChain) ;
|
||||
bool DistPointFacet( const Point3d& ptP, const POLYLINEVECTOR& vPolyVec, double& dPointFacetDist) ;
|
||||
bool ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop) ;
|
||||
|
||||
+135
-79
@@ -251,7 +251,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
|
||||
if ( int( it->second.size()) == 0)
|
||||
continue ;
|
||||
// Se il triangolo � stato sottoposto a ritriangolazione, le sue componenti sono classificabili come dentro-fuori.
|
||||
// Se il triangolo è stato sottoposto a ritriangolazione, le sue componenti sono classificabili come dentro-fuori.
|
||||
// Lo tolgo dall'insieme dei triangoli ambigui (intersezione edge-edge)
|
||||
else {
|
||||
auto itS = Ambiguos.find( it->first) ;
|
||||
@@ -499,7 +499,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
// Creo il loop chiuso padre di tutti, il perimetro del triangolo.
|
||||
// Questo viene diviso in sotto-loop chiusi mediante quelli aperti.
|
||||
// I loop chiusi trovati precedentemente sono interni a uno dei sotto-loop
|
||||
// chiusi di cui � formato il perimetro.
|
||||
// chiusi di cui è formato il perimetro.
|
||||
PNTVECTOR cvFirstLoop ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 0)) ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 1)) ;
|
||||
@@ -579,7 +579,7 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
// Assegno ai loop trovati i rispettivi interni
|
||||
// Assumo che i loop interni a uno dei loop creati fino ad'ora siano tutti sullo stesso livello.
|
||||
// Il caso generale si risolve con una struttura ad albero in cui il nodi corrispondente a un
|
||||
// loop � figlio del nodo corrispondente al loop che lo contiene.
|
||||
// loop è figlio del nodo corrispondente al loop che lo contiene.
|
||||
INTVECTOR vInnerLoop ;
|
||||
for ( int nCLI = 0 ; nCLI < int( cvClosedChain.size()) ; ++ nCLI) {
|
||||
for ( int nPtNum = 0 ; nPtNum < int( cvClosedChain[nCLI].size()) ; ++ nPtNum) {
|
||||
@@ -1004,7 +1004,7 @@ SurfTriMesh::AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Su
|
||||
{
|
||||
for ( auto it = Ambiguos.begin() ; it != Ambiguos.end() ; ++ it) {
|
||||
// Se il triangolo ha l'indice diverso da zero vuol dire che oltre a un
|
||||
// contatto edge-edge ha avuto dei contatti che lo hanno gi� classificato.
|
||||
// contatto edge-edge ha avuto dei contatti che lo hanno già classificato.
|
||||
if ( Surf.m_vTria[it->first].nTempPart != 0)
|
||||
continue ;
|
||||
// Recupero il triangolo corrente
|
||||
@@ -1080,7 +1080,7 @@ SurfTriMesh::AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Su
|
||||
if ( j < 3)
|
||||
break ;
|
||||
}
|
||||
// Se la classificazione � coerente segno gli edge di contatto come invalicabili
|
||||
// Se la classificazione è coerente segno gli edge di contatto come invalicabili
|
||||
Surf.m_vTria[it->first].nETempFlag[0] = int( vAdjSegToCurTria[0].size()) > 0 ? 1 : 0 ;
|
||||
Surf.m_vTria[it->first].nETempFlag[1] = int( vAdjSegToCurTria[1].size()) > 0 ? 1 : 0 ;
|
||||
Surf.m_vTria[it->first].nETempFlag[2] = int( vAdjSegToCurTria[2].size()) > 0 ? 1 : 0 ;
|
||||
@@ -1106,7 +1106,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Ciclo sui triangoli delle mesh
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
int nTriaNumB = SurfB.GetTriangleSize() ;
|
||||
// Setto il triangolo come n� fuori n� dentro
|
||||
// Setto il triangolo come né fuori né dentro
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
m_vTria[nTA].nTempPart = 0 ;
|
||||
m_vTria[nTA].nETempFlag[0] = 0 ;
|
||||
@@ -1122,7 +1122,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Resetto e ricalcolo la HashGrid della superficie B
|
||||
SurfB.ResetHashGrids3d() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
// Se il triangolo A non � valido, continuo
|
||||
// Se il triangolo A non è valido, continuo
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! GetTriangle( nTA, trTriaA) || ! trTriaA.Validate( true))
|
||||
continue ;
|
||||
@@ -1133,7 +1133,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
INTVECTOR vNearTria ;
|
||||
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
||||
// Se il triangolo B non � valido, continuo
|
||||
// Se il triangolo B non è valido, continuo
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
||||
continue ;
|
||||
@@ -1209,7 +1209,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
if ( nSegMaxDist >= 0) {
|
||||
// Cerco qual'� il segmento di contatto per dichiararlo come invalicabile
|
||||
// Cerco qual'è il segmento di contatto per dichiararlo come invalicabile
|
||||
int nVA ;
|
||||
for ( nVA = 0 ; nVA < 3 ; ++ nVA) {
|
||||
if ( abs( ( trTriaA.GetP( nVA) - trTriaB.GetP( 0)) * trTriaB.GetN()) < EPS_SMALL &&
|
||||
@@ -1233,7 +1233,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
if ( nSegMaxDist >= 0) {
|
||||
// Cerco qual'� il segmento di contatto per dichiararlo come invalicabile
|
||||
// Cerco qual'è il segmento di contatto per dichiararlo come invalicabile
|
||||
int nVB ;
|
||||
for ( nVB = 0 ; nVB < 3 ; ++ nVB) {
|
||||
if ( abs( ( trTriaB.GetP( nVB) - trTriaA.GetP(0)) * trTriaA.GetN()) < EPS_SMALL &&
|
||||
@@ -1246,8 +1246,8 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
// Intersezione edge-edge: salvo indice e vettore triangoli
|
||||
// Uso i triangoli perch�, se un triangolo fosse cancellato, non potrei accedervi poi usando l'indice.
|
||||
// Salvando i triangoli risolvo il problema perch� ai fini dello studio di questi contatti, triangolo
|
||||
// Uso i triangoli perchè, se un triangolo fosse cancellato, non potrei accedervi poi usando l'indice.
|
||||
// Salvando i triangoli risolvo il problema perchè ai fini dello studio di questi contatti, triangolo
|
||||
// e sua ritriangolazione portano al medesimo risultato.
|
||||
else if ( bIntOnEndgeA && bIntOnEndgeB) {
|
||||
auto itA = AmbiguosA.find( nTA) ;
|
||||
@@ -1277,7 +1277,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
RetriangulationForBooleanOperation( LineMapA, AmbiguosA, *this, bModif) ;
|
||||
RetriangulationForBooleanOperation( LineMapB, AmbiguosB, SurfB, bModif) ;
|
||||
|
||||
// Se i triangoli delle superfici non si intersecano, una delle due � totalmente interna o esterna all'altra.
|
||||
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
|
||||
bool bRetriangulated = true ;
|
||||
if ( ! bModif && ( int( AmbiguosA.size()) == 0 || int( AmbiguosB.size()) == 0)) {
|
||||
bRetriangulated = false ;
|
||||
@@ -1289,7 +1289,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
int nTriaNum = - 1 ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
for ( int nTB = 0 ; nTB < nTriaNumB ; ++ nTB) {
|
||||
// Se il triangolo B non � valido, continuo
|
||||
// Se il triangolo B non è valido, continuo
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! SurfB.GetTriangle( nTB, trTriaB) || ! trTriaB.Validate( true))
|
||||
continue ;
|
||||
@@ -1322,7 +1322,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
int nTriaNum = - 1 ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
// Se il triangolo A non � valido, continuo
|
||||
// Se il triangolo A non è valido, continuo
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( GetTriangle( nTA, trTriaA) && trTriaA.Validate( true)))
|
||||
continue ;
|
||||
@@ -1354,7 +1354,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
|
||||
// Se c'� stata una ritriangolazione di almeno un triangolo, NON siamo nel caso di tutto dentro o tutto fuori.
|
||||
// Se c'è stata una ritriangolazione di almeno un triangolo, NON siamo nel caso di tutto dentro o tutto fuori.
|
||||
// Studio i triangoli ambigui.
|
||||
if ( bRetriangulated) {
|
||||
AmbiguosTriangleManager( AmbiguosA, *this) ;
|
||||
@@ -1371,7 +1371,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Resetto e ricalcolo la HashGrid della superficie B
|
||||
SurfB.ResetHashGrids3d() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNum2A ; ++ nTA) {
|
||||
// Se il triangolo A non � valido, continuo
|
||||
// Se il triangolo A non è valido, continuo
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! GetTriangle( nTA, trTriaA) || ! trTriaA.Validate( true))
|
||||
continue ;
|
||||
@@ -1382,7 +1382,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
INTVECTOR vNearTria ;
|
||||
SurfB.GetAllTriaOverlapBox( b3dTriaA, vNearTria) ;
|
||||
for ( int nTB = 0 ; nTB < int( vNearTria.size()) ; ++ nTB) {
|
||||
// Se il triangolo B non � valido, continuo
|
||||
// Se il triangolo B non è valido, continuo
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! SurfB.GetTriangle( vNearTria[nTB], trTriaB) || ! trTriaB.Validate( true))
|
||||
continue ;
|
||||
@@ -1411,7 +1411,7 @@ bool
|
||||
SurfTriMesh::IdentifyParts( void) const
|
||||
{
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i) {
|
||||
// salto triangoli cancellati o gi� assegnati
|
||||
// salto triangoli cancellati o già assegnati
|
||||
if ( m_vTria[i].nIdVert[0] == SVT_DEL ||
|
||||
abs( m_vTria[i].nTempPart) != 1)
|
||||
continue ;
|
||||
@@ -1443,18 +1443,17 @@ SurfTriMesh::IdentifyParts( void) const
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunctions(void)
|
||||
{
|
||||
//PerformanceCounter Counter ;
|
||||
|
||||
// Vettore di indici dei vertici sui lati del triangolo corrente
|
||||
INTMATRIX vvIndexMatrix( m_vTria.size()) ;
|
||||
// Ciclo sui triangoli della superficie
|
||||
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) {
|
||||
// Riga di matrice per il triangolo
|
||||
INTVECTOR& vIndexRow = vvIndexMatrix[nT] ;
|
||||
// Se il triangolo non � valido, passo al successivo
|
||||
// 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) ;
|
||||
@@ -1462,12 +1461,12 @@ SurfTriMesh::RemoveTJunctions(void)
|
||||
GetAllTriaOverlapBox( b3Tria, vNearTria) ;
|
||||
// Ciclo sui lati del triangolo
|
||||
for ( int nSeg = 0 ; nSeg < 3 ; ++ nSeg) {
|
||||
// aggiungo alla riga della matrice il vertice iniziale del lato
|
||||
vIndexRow.emplace_back( m_vTria[nT].nIdVert[nSeg]) ;
|
||||
// Se in questo lato il triangolo � adiacente a un altro, lo salto.
|
||||
// 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( vIndexRow.size()) ;
|
||||
int nPrevSize = int( vVertOtl.size()) ;
|
||||
// recupero la geometria del lato
|
||||
Point3d ptSegSt = trTria.GetP( nSeg) ;
|
||||
Point3d ptSegEn = trTria.GetP( ( nSeg + 1) % 3) ;
|
||||
@@ -1478,7 +1477,7 @@ SurfTriMesh::RemoveTJunctions(void)
|
||||
vtSeg /= dSegLen ;
|
||||
// Ciclo sui triangoli vicini
|
||||
for ( int nI = 0 ; nI < int( vNearTria.size()) ; ++ nI) {
|
||||
// Salto il triangolo se � quello di riferimento
|
||||
// Salto il triangolo se è quello di riferimento
|
||||
if ( vNearTria[nI] == nT)
|
||||
continue ;
|
||||
// Cerco i vertici che stanno sul lato del triangolo
|
||||
@@ -1488,50 +1487,66 @@ SurfTriMesh::RemoveTJunctions(void)
|
||||
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) {
|
||||
vIndexRow.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
|
||||
}
|
||||
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 nV, const int nVV)
|
||||
{ Point3d ptPV, ptPVV ;
|
||||
GetVertex( nV, ptPV) ;
|
||||
GetVertex( nVV, ptPVV) ;
|
||||
return ( ( ptPV - ptSegSt) * vtSeg < ( ptPVV - ptSegSt) * vtSeg) ;
|
||||
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( vIndexRow.begin() + nPrevSize, vIndexRow.end(), SortVerteces) ;
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
|
||||
//double dTime1 = Counter.Stop() ; Counter.Start() ;
|
||||
|
||||
for ( int nT = 0 ; nT < int( vvIndexMatrix.size()) ; ++ nT) {
|
||||
if ( vvIndexMatrix[nT].size() > 3) {
|
||||
for ( auto itI = vvIndexMatrix[nT].begin() ; itI != vvIndexMatrix[nT].end() ; ) {
|
||||
auto itJ = itI ;
|
||||
++ itJ ;
|
||||
for ( ; itJ != vvIndexMatrix[nT].end() && *itI == *itJ ; ++ itJ) {
|
||||
;
|
||||
}
|
||||
auto itN = itI ;
|
||||
++ itN ;
|
||||
itI = vvIndexMatrix[nT].erase( itN, itJ) ;
|
||||
|
||||
// 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 ;
|
||||
// Rimuovo il triangolo
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
// 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]} ;
|
||||
if ( AddTriangle( nNew1Id, nTFlag) >= 0) {
|
||||
int nNew2Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[3]} ;
|
||||
AddTriangle( nNew2Id, nTFlag) ;
|
||||
}
|
||||
// Se il triangolo non � valido, passo al successivo
|
||||
Triangle3d trTria ;
|
||||
if ( ! GetTriangle( nT, trTria) || ! trTria.Validate( true))
|
||||
continue ;
|
||||
|
||||
int nTFlag = m_vTria[nT].nTFlag ;
|
||||
RemoveTriangle( nT) ;
|
||||
|
||||
// altrimenti 0-1-2 e 2-3-0
|
||||
else {
|
||||
int nNew3Id[3] = { vVertOtl[0], vVertOtl[1], vVertOtl[2]} ;
|
||||
AddTriangle( nNew3Id, nTFlag) ;
|
||||
int nNew4Id[3] = { vVertOtl[2], vVertOtl[3], vVertOtl[0]} ;
|
||||
AddTriangle( nNew4Id, nTFlag) ;
|
||||
}
|
||||
}
|
||||
// altrimenti inserisco un ventaglio di triangoli dal centro ai vertici
|
||||
else {
|
||||
Point3d ptTriaCen = trTria.GetCentroid() ;
|
||||
int nCenIndex = AddVertex( ptTriaCen) ;
|
||||
int nVertNum = int( vvIndexMatrix[nT].size()) ;
|
||||
int nVertNum = int( vVertOtl.size()) ;
|
||||
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
|
||||
int nEnV = ( nStV + 1) % nVertNum ;
|
||||
int nNewId[3] = { nCenIndex, vvIndexMatrix[nT][nStV], vvIndexMatrix[nT][nEnV] } ;
|
||||
int nNewId[3] = { nCenIndex, vVertOtl[nStV], vVertOtl[nEnV]} ;
|
||||
AddTriangle( nNewId, nTFlag) ;
|
||||
}
|
||||
}
|
||||
@@ -1621,7 +1636,7 @@ SurfTriMesh::ScanForTripleTriangles( bool& bModified)
|
||||
bool bCirc ;
|
||||
INTVECTOR vTriaIndex ;
|
||||
int nTriaNum = GetAllTriaAroundVertex( nV, vTriaIndex, bCirc) ;
|
||||
// Se il vertice � condiviso da tre triangoli tutti adiacenti fra loro a due a due
|
||||
// Se il vertice è condiviso da tre triangoli tutti adiacenti fra loro a due a due
|
||||
if ( nTriaNum == 3 && bCirc) {
|
||||
// Valuto parallelismo fra le normali
|
||||
int nParallel = 0 ;
|
||||
@@ -1634,7 +1649,7 @@ SurfTriMesh::ScanForTripleTriangles( bool& bModified)
|
||||
}
|
||||
// Se sono tutte parallele fra loro unisco i tre triangoli in uno
|
||||
if ( nParallel == 3) {
|
||||
// Cerco gli altri triangoli adiacenti a quelli che sostituir� con il triangolo grande.
|
||||
// Cerco gli altri triangoli adiacenti a quelli che sostituirò con il triangolo grande.
|
||||
// Cerco anche quali lati dei tre triangoli che saranno eliminati sono adiacenti a quelli esterni
|
||||
INTVECTOR vVertAndAdjTria ;
|
||||
for ( int nTria = 0 ; nTria < 3 ; ++ nTria) {
|
||||
@@ -1646,7 +1661,7 @@ SurfTriMesh::ScanForTripleTriangles( bool& bModified)
|
||||
}
|
||||
}
|
||||
}
|
||||
// Cerco fra questi altri triangoli esterni sono adiacenti ai triangoli che eliminer�
|
||||
// Cerco fra questi altri triangoli esterni sono adiacenti ai triangoli che eliminerò
|
||||
int nAdjTriaContactEdge[3] ;
|
||||
for ( int nAdjTria = 1 ; nAdjTria < 6 ; nAdjTria += 2) {
|
||||
for ( int nAdjEdge = 0 ; nAdjEdge < 3 ; ++ nAdjEdge) {
|
||||
@@ -1709,19 +1724,19 @@ SurfTriMesh::FlipTriangles( int nTA, int nTB)
|
||||
if ( m_vTria[nTB].nIdAdjac[nEdgeB] == nTA)
|
||||
break ;
|
||||
}
|
||||
// Se uno � adiacente all'altro ma non viceversa, c'� un errore
|
||||
// Se uno è adiacente all'altro ma non viceversa, c'è un errore
|
||||
if ( ( nEdgeA == 3 && nEdgeB < 3) || ( nEdgeA < 3 && nEdgeB == 3))
|
||||
return false ;
|
||||
// Se non sono adiacenti, ho finito
|
||||
else if ( nEdgeA == 3 && nEdgeB == 3)
|
||||
return true ;
|
||||
// Se non trovo i vertici del triangolo A, c'� un errorre
|
||||
// Se non trovo i vertici del triangolo A, c'è un errorre
|
||||
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 ;
|
||||
// Se non trovo i vertici del triangolo B, c'� un errorre
|
||||
// Se non trovo i vertici del triangolo B, c'è un errorre
|
||||
Point3d ptVertB ;
|
||||
if ( ! GetVertex( m_vTria[nTB].nIdVert[( nEdgeB + 2) % 3], ptVertB))
|
||||
return false ;
|
||||
@@ -1749,15 +1764,19 @@ bool
|
||||
SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
{
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
if ( m_vTria[nTA].nTempPart == 1 || m_vTria[nTA].nTempPart == - 2)
|
||||
@@ -1776,12 +1795,21 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTripleTriangles() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTJunctions() ;
|
||||
|
||||
//bOk && RemoveTripleTriangles() ;
|
||||
//bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
bOk = bOk && RemoveTJunctions() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
// cerco di semplificare le facce
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Add")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
@@ -1790,15 +1818,19 @@ bool
|
||||
SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
{
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
if ( m_vTria[nTA].nTempPart == - 1 || m_vTria[nTA].nTempPart == - 2)
|
||||
@@ -1817,12 +1849,20 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTripleTriangles() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTJunctions() ;
|
||||
|
||||
//bOk && RemoveTripleTriangles() ;
|
||||
//bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
bOk = bOk && RemoveTJunctions() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
@@ -1831,15 +1871,19 @@ bool
|
||||
SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
{
|
||||
m_OGrMgr.Clear() ;
|
||||
|
||||
SurfTriMesh SurfB ;
|
||||
SurfB.CopyFrom( &Other) ;
|
||||
|
||||
Frame3d frScalingRef;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
SurfB.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
|
||||
IntersectTriMeshTriangle( SurfB) ;
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
if ( m_vTria[nTA].nTempPart == 1 || m_vTria[nTA].nTempPart == 2)
|
||||
@@ -1859,12 +1903,20 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert, m_nMaxTFlag) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bOk = ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTripleTriangles() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
bOk && RemoveTJunctions() ;
|
||||
|
||||
//bOk && RemoveTripleTriangles() ;
|
||||
//bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
bOk = bOk && RemoveTJunctions() ;
|
||||
bOk = bOk && ( AdjustVertices() && DoCompacting()) ;
|
||||
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
|
||||
if ( ! SimplifyFacets( 5000.0, true))
|
||||
LOG_ERROR( GetEGkLogger(), "Error in SimplifyFacets of Stm::Intersect")
|
||||
|
||||
return bOk ;
|
||||
}
|
||||
|
||||
@@ -1880,12 +1932,15 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
return false ;
|
||||
if ( m_vVert.empty() || m_vTria.empty())
|
||||
return true ;
|
||||
|
||||
SurfTriMesh SurfC ;
|
||||
SurfC.CopyFrom( &ClassifierSurf) ;
|
||||
|
||||
Frame3d frScalingRef ;
|
||||
frScalingRef.Set( m_vVert[0].ptP, X_AX, Y_AX, Z_AX) ;
|
||||
Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
SurfC.Scale( frScalingRef, BOOLEAN_SCALE, BOOLEAN_SCALE, BOOLEAN_SCALE) ;
|
||||
|
||||
IntersectTriMeshTriangle( SurfC) ;
|
||||
IdentifyParts() ;
|
||||
Scale( frScalingRef, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE, 1. / BOOLEAN_SCALE) ;
|
||||
@@ -1912,6 +1967,7 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ SurfTriMesh::UpdateFaceting( void)
|
||||
{
|
||||
// reset faceting
|
||||
m_bFaceted = false ;
|
||||
m_vFacet.clear() ;
|
||||
for ( int i = 0 ; i < int( m_vTria.size()) ; ++ i)
|
||||
m_vTria[i].nIdFacet = SVT_NULL ;
|
||||
|
||||
|
||||
+29
-10
@@ -163,7 +163,7 @@ AdjustLoop( PNTULIST& PointList, double dMaxEdgeLen, bool& bModif)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||
SurfTriMesh::SimplifyFacets( double dMaxEdgeLen, bool bForced)
|
||||
{
|
||||
// La trimesh deve essere valida
|
||||
if ( ! IsValid())
|
||||
@@ -184,7 +184,7 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||
GetFacetLoops( nF, LoopVec) ;
|
||||
|
||||
// Ciclo sui loop della faccia
|
||||
bool bToRetriangulate = false ;
|
||||
bool bToRetriangulate = bForced ;
|
||||
for ( int nL = 0 ; nL < int( LoopVec.size()) ; ++ nL) {
|
||||
|
||||
// Lista dei punti del loop
|
||||
@@ -202,7 +202,24 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
|
||||
// Se da ritriangolare,
|
||||
// Se non richiesta ritriangolazione dai bordi, verifico se ci sono vertici di triangoli interni
|
||||
if ( false && ! bToRetriangulate) {
|
||||
// numero dei triangoli nella faccia
|
||||
INTVECTOR vFacetTria ;
|
||||
GetAllTriaInFacet( nF, vFacetTria) ;
|
||||
int nTriaCnt = int( vFacetTria.size()) ;
|
||||
// numero dei lati di contorno della faccia
|
||||
int nSideCnt = 0 ;
|
||||
for ( int nL = 0 ; nL < int( LoopVec.size()) ; ++ nL)
|
||||
nSideCnt += LoopVec[nL].GetLineNbr() ;
|
||||
// numero dei buchi della faccia
|
||||
int nHoleCnt = int( LoopVec.size()) - 1 ;
|
||||
// dalla formula di Eulero adattata al caso ( nTriaCnt = nSideCnt + 2 * ( nHoleCnt -1))
|
||||
if ( nTriaCnt != nSideCnt + 2 * ( nHoleCnt - 1))
|
||||
bToRetriangulate = true ;
|
||||
}
|
||||
|
||||
// Se da ritriangolare
|
||||
if ( bToRetriangulate) {
|
||||
// Eseguo la ritriangolazione della faccia
|
||||
PNTVECTOR vPt ;
|
||||
@@ -217,28 +234,30 @@ SurfTriMesh::SimplifyFacets( double dMaxEdgeLen)
|
||||
}
|
||||
|
||||
// Ciclo sulle facce da ritriangolare per eliminare i triangoli (nel contempo salvo flag colore)
|
||||
INTVECTOR vDelTria ;
|
||||
unordered_map< int, int> ColorMap ;
|
||||
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||
// Recupero i triangoli della faccia
|
||||
INTVECTOR vFacetTria ;
|
||||
GetAllTriaInFacet( itF->first, vFacetTria) ;
|
||||
vDelTria.insert( vDelTria.end(), vFacetTria.begin(), vFacetTria.end()) ;
|
||||
// Salvo il colore della faccia da flag di un suo triangolo
|
||||
ColorMap.emplace( itF->first, m_vTria[m_vFacet[itF->first]].nTFlag) ;
|
||||
// Cancello i triangoli della faccia.
|
||||
for ( int nT : vFacetTria)
|
||||
RemoveTriangle( nT) ;
|
||||
}
|
||||
// Cancello i triangoli
|
||||
for ( int nT : vDelTria)
|
||||
RemoveTriangle( nT) ;
|
||||
|
||||
// Applico le nuove triangolazioni delle facce
|
||||
for ( auto itFac = FacetMap.begin() ; itFac != FacetMap.end() ; ++ itFac) {
|
||||
const PNTVECTOR& vPt = itFac->second.first ;
|
||||
const INTVECTOR& vTr = itFac->second.second ;
|
||||
for ( auto itF = FacetMap.begin() ; itF != FacetMap.end() ; ++ itF) {
|
||||
const PNTVECTOR& vPt = itF->second.first ;
|
||||
const INTVECTOR& vTr = itF->second.second ;
|
||||
// Inserisco i nuovi triangoli
|
||||
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
|
||||
int nNewId[3] = { AddVertex( vPt[vTr[n]]),
|
||||
AddVertex( vPt[vTr[n + 1]]),
|
||||
AddVertex( vPt[vTr[n + 2]])} ;
|
||||
auto itCol = ColorMap.find( itFac->first) ;
|
||||
auto itCol = ColorMap.find( itF->first) ;
|
||||
int nTFlag = ( itCol != ColorMap.end() ? itCol->second : 0) ;
|
||||
int nNewTriaId = AddTriangle( nNewId, nTFlag) ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user