EgtGeomKernel 2.4a1 :

- migliorie alle booleane delle superfici trimesh.
This commit is contained in:
DarioS
2022-01-04 08:03:15 +01:00
parent d2b77833fd
commit 41d76f0c3f
5 changed files with 166 additions and 90 deletions
BIN
View File
Binary file not shown.
+1 -1
View File
@@ -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
View File
@@ -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 ;
}
+1
View File
@@ -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
View File
@@ -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) ;
}