Migliorie operazioni booleane e intersezione triangoli
This commit is contained in:
+29
-2
@@ -83,8 +83,35 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
|
||||
// se i triangoli sono complanari
|
||||
if ( nResPP == IPPT_OVERLAPS ||
|
||||
((( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) &&
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL))
|
||||
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
|
||||
( trTria1.GetN() ^ trTria2.GetN()).SqLen() < 25 * SIN_EPS_ANG_SMALL * SIN_EPS_ANG_SMALL)) {
|
||||
bool bCounter = false ;
|
||||
Triangle3d trMyTria2 = trTria2 ;
|
||||
if ( trTria1.GetN() * trTria2.GetN() < 0) {
|
||||
Point3d ptV0 = trMyTria2.GetP( 0) ;
|
||||
trMyTria2.SetP( 0, trMyTria2.GetP( 1)) ;
|
||||
trMyTria2.SetP( 1, ptV0) ;
|
||||
trMyTria2.Validate() ;
|
||||
bCounter = true ;
|
||||
}
|
||||
bool bAreSameTria = ( ( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 2))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 1)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 0))) ||
|
||||
( AreSamePointExact( trTria1.GetP( 0), trMyTria2.GetP( 2)) &&
|
||||
AreSamePointExact( trTria1.GetP( 1), trMyTria2.GetP( 0)) &&
|
||||
AreSamePointExact( trTria1.GetP( 2), trMyTria2.GetP( 1)))) &&
|
||||
( AreSameVectorExact( trTria1.GetN(), trMyTria2.GetN())) ;
|
||||
if ( bAreSameTria) {
|
||||
vTria.emplace_back( trTria1) ;
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
if ( ITTT_OVERLAPS == IntersCoplanarTriaTria( trTria1, trMyTria2, vTria)) {
|
||||
return ( bCounter ? ITTT_COUNTER_OVERLAPS : ITTT_OVERLAPS) ;
|
||||
}
|
||||
return ITTT_NO ;
|
||||
}
|
||||
|
||||
// limito la linea di intersezione con il primo triangolo
|
||||
Point3d ptSt1, ptEn1 ;
|
||||
|
||||
+100
-29
@@ -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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user