Migliorie operazioni booleane e intersezione triangoli

This commit is contained in:
LorenzoM
2021-12-07 09:43:59 +01:00
parent 2d70d27d85
commit 009328b31b
2 changed files with 129 additions and 31 deletions
+100 -29
View File
@@ -27,6 +27,7 @@
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLineBox.h"
#include "/EgtDev/Include/EGkIntersPlanePlane.h"
#include "/EgtDev/Include/EGkIntersPlaneTria.h"
#include "/EgtDev/Include/EGkIntersTriaTria.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkChainCurves.h"
@@ -125,7 +126,7 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
nCvSecond = nLine ;
}
}
if ( nCvFirst != nCvSecond && nCvSecond != - 1) {
// li ordino in senso crescente
if ( nCvFirst > nCvSecond)
@@ -444,6 +445,57 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
}
}
// Gestione tagli piccoli
if ( int( cvOpenChain.size()) == 1 && int( cvOpenChain[0].size()) == 1 && int( cvClosedChain.size()) == 0) {
if ( AreSamePointEpsilon( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].ptEn, EPS_SMALL)) {
Plane3d plPlane ;
plPlane.Set( cvOpenChain[0][0].ptSt, cvOpenChain[0][0].vtOuter) ;
Point3d ptIntSt, ptIntEn ;
int nPlaneTriaInt = IntersPlaneTria( plPlane, trTria, ptIntEn, ptIntSt) ;
if ( nPlaneTriaInt == IPTT_YES) {
int nOldTriaCol = Surf.m_vTria[it->first].nTFlag ;
Surf.RemoveTriangle( it->first) ;
int nDist[3] ;
for ( int nV = 0 ; nV < 3 ; ++ nV) {
double dD = - DistPointPlane( trTria.GetP( nV), plPlane) ;
nDist[nV] = ( abs( dD) < EPS_SMALL ? 0 : ( dD > 0 ? 1 : - 1)) ;
}
int nAloneVert = ( nDist[0] == nDist[1] ? 2 : ( nDist[0] == nDist[2] ? 1 : 0)) ;
if ( nDist[nAloneVert] == - 1) {
swap( ptIntSt, ptIntEn) ;
}
int nNewAloneId[3] = { Surf.AddVertex( trTria.GetP( nAloneVert)), Surf.AddVertex( ptIntSt), Surf.AddVertex( ptIntEn) } ;
int nNewAloneTriaNum = Surf.AddTriangle( nNewAloneId, nOldTriaCol) ;
if ( IsValidSvt( nNewAloneTriaNum)) {
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[0] = 0 ;
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[1] = 0 ;
Surf.m_vTria[nNewAloneTriaNum].nETempFlag[2] = 0 ;
Surf.m_vTria[nNewAloneTriaNum].nTempPart = nDist[nAloneVert] ;
bModif = true ;
}
int nNewCoupleId1[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 1) % 3)), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)) } ;
int nNewCoupleTriaNum1 = Surf.AddTriangle( nNewCoupleId1, nOldTriaCol) ;
if ( IsValidSvt( nNewCoupleTriaNum1)) {
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[0] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[1] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum1].nETempFlag[2] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum1].nTempPart = - nDist[nAloneVert] ;
bModif = true ;
}
int nNewCoupleId2[3] = { Surf.AddVertex( ptIntSt), Surf.AddVertex( trTria.GetP( ( nAloneVert + 2) % 3)), Surf.AddVertex( ptIntEn) } ;
int nNewCoupleTriaNum2 = Surf.AddTriangle( nNewCoupleId2, nOldTriaCol) ;
if ( IsValidSvt( nNewCoupleTriaNum2)) {
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[0] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[1] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum2].nETempFlag[2] = 0 ;
Surf.m_vTria[nNewCoupleTriaNum2].nTempPart = - nDist[nAloneVert] ;
bModif = true ;
}
continue ;
}
}
}
// 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
@@ -1339,9 +1391,12 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
Point3d ptTempA, ptTempB ;
int nIntTypeAB = IntersTriaTria( trTriaA, trTriaB, ptTempA, ptTempB, vTriaAB) ;
if ( nIntTypeAB == ITTT_OVERLAPS) {
bool bInvertB = trTriaA.GetN() * trTriaB.GetN() < 0. ;
m_vTria[nTA].nTempPart = ( bInvertB ? -2 : 2) ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = ( bInvertB ? - 2 : 2) ;
m_vTria[nTA].nTempPart = 2 ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = 2 ;
}
else if ( nIntTypeAB == ITTT_COUNTER_OVERLAPS) {
m_vTria[nTA].nTempPart = - 2 ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = - 2 ;
}
}
}
@@ -1409,6 +1464,9 @@ SurfTriMesh::RemoveTJunctions(void)
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.
if ( m_vTria[nT].nIdAdjac[nSeg] != SVT_DEL && m_vTria[nT].nIdAdjac[nSeg] != SVT_NULL)
continue ;
int nPrevSize = int( vIndexRow.size()) ;
// recupero la geometria del lato
Point3d ptSegSt = trTria.GetP( nSeg) ;
@@ -1426,10 +1484,11 @@ SurfTriMesh::RemoveTJunctions(void)
// Cerco i vertici che stanno sul lato del triangolo
for ( int nVert = 0 ; nVert < 3 ; ++ nVert) {
Point3d ptVert ;
GetVertex( m_vTria[vNearTria[nI]].nIdVert[nVert], 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) {
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL && dOrt < /*10 * BOOLEAN_SCALE **/ SQ_EPS_TRIA_H) {
vIndexRow.emplace_back( m_vTria[vNearTria[nI]].nIdVert[nVert]) ;
}
}
@@ -1446,34 +1505,38 @@ SurfTriMesh::RemoveTJunctions(void)
}
//double dTime1 = Counter.Stop() ; Counter.Start() ;
for ( int nT = 0 ; nT < int( vvIndexMatrix.size()) ; ++ nT) {
if ( vvIndexMatrix[nT].size() > 3) {
PolyLine Polygon ;
for ( int nV = 0 ; nV < int( vvIndexMatrix[nT].size()) ; ++ nV) {
Point3d ptPt;
GetVertex( vvIndexMatrix[nT][nV], ptPt) ;
Polygon.AddUPoint( 0., ptPt) ;
}
Polygon.Close() ;
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( Polygon, vPt, vTr)) {
// Rimuovo il triangolo originale e salvo il suo flag
int nTFlag = m_vTria[nT].nTFlag ;
RemoveTriangle( nT) ;
// Inserisco i nuovi triangoli che lo sostituiscono e asegno loro lo stesso flag
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
int nNewTriaVertId[3] = { vTr[n], vTr[n + 1], vTr[n + 2]} ;
int nNewId[3] = { AddVertex( vPt[nNewTriaVertId[0]]),
AddVertex( vPt[nNewTriaVertId[1]]),
AddVertex( vPt[nNewTriaVertId[2]])} ;
AddTriangle( nNewId, nTFlag) ;
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) ;
}
// 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) ;
Point3d ptTriaCen = trTria.GetCentroid() ;
int nCenIndex = AddVertex( ptTriaCen) ;
int nVertNum = int( vvIndexMatrix[nT].size()) ;
for ( int nStV = 0 ; nStV < nVertNum ; ++ nStV) {
int nEnV = ( nStV + 1) % nVertNum ;
int nNewId[3] = { nCenIndex, vvIndexMatrix[nT][nStV], vvIndexMatrix[nT][nEnV] } ;
AddTriangle( nNewId, nTFlag) ;
}
}
}
return true ;
}
@@ -3662,10 +3725,18 @@ SurfTriMesh::IntersectTriMeshFacets( SurfTriMesh& Other)
IsPointInsideTriangle( ptIntTriaCentroid, trTriaB, TriangleType::EXACT) ;
}
// Se l'intersezeione è corretta e i triangoli sono sovrapposti aggiorno gli indici.
if ( nIntTypeAB == ITTT_OVERLAPS && bSuccesfullInters) {
/*if ( nIntTypeAB == ITTT_OVERLAPS && bSuccesfullInters) {
bool bInvertB = trTriaA.GetN() * trTriaB.GetN() < 0. ;
m_vTria[nTA].nTempPart = ( bInvertB ? -2 : 2) ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = ( bInvertB ? - 2 : 2) ;
}*/
if ( nIntTypeAB == ITTT_OVERLAPS && bSuccesfullInters) {
m_vTria[nTA].nTempPart = 2 ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = 2 ;
}
else if ( nIntTypeAB == ITTT_COUNTER_OVERLAPS && bSuccesfullInters) {
m_vTria[nTA].nTempPart = - 2 ;
SurfB.m_vTria[vNearTria[nTB]].nTempPart = - 2 ;
}
}
}