EgtGeomKernel 2.1k4 :
- correzioni alle operazioni booleane tra superfici trimesh.
This commit is contained in:
+746
-31
@@ -28,7 +28,6 @@
|
||||
#include "/EgtDev/Include/EGkGeoCollection.h"
|
||||
#include "/EgtDev/Include/EGkPolygon3d.h"
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
using namespace std ;
|
||||
|
||||
@@ -64,7 +63,7 @@ IntersRectangleTriangle( const Point3d& ptP, const Vector3d& vtL1, const Vector3
|
||||
if ( FromSpecialToNormal( nIntTypeB) == ITTT_PNT || FromSpecialToNormal( nIntTypeB) == ITTT_VERT)
|
||||
nIntB = 1 ;
|
||||
else if ( FromSpecialToNormal( nIntTypeB) == ITTT_YES || FromSpecialToNormal( nIntTypeB) == ITTT_EDGE) {
|
||||
nIntB = 2 ;
|
||||
nIntB = 2 ;
|
||||
}
|
||||
// Unisco le due intersezioni
|
||||
int nIntTot = nIntA + nIntB ;
|
||||
@@ -544,7 +543,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
|
||||
vector<PNTVECTOR> cvBoundClosedLoopVec ;
|
||||
cvBoundClosedLoopVec.emplace_back(cvFirstLoop);
|
||||
vector<bool> vbInOut ;
|
||||
BOOLVECTOR vbInOut ;
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop di partenza in sotto-loop
|
||||
while ( cvOpenChain.size() > 0) {
|
||||
@@ -742,10 +741,12 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, vector<PNTVECTOR>& cvBoundClosedLoopVec, vector<bool>& vbInOut)
|
||||
SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, vector<PNTVECTOR>& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut)
|
||||
{
|
||||
// Divido il loop di partenza in sotto-loop
|
||||
while ( cvOpenChain.size() > 0) {
|
||||
// Divido il loop di partenza in sotto-loop
|
||||
int nIterationCount = 0 ;
|
||||
while ( cvOpenChain.size() > 0) {
|
||||
bool bLoopSplitted = false ;
|
||||
int nLastOpenLoopN = int( cvOpenChain.size()) - 1 ;
|
||||
if ( vnDegVec[nLastOpenLoopN] == 1) {
|
||||
for ( int nLoop = 0 ; nLoop < int( cvBoundClosedLoopVec.size()) ; ++ nLoop) {
|
||||
@@ -757,7 +758,8 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, vecto
|
||||
bool bChangedStart = ChangeStart( ptOpenLoopStP, cvBoundClosedLoopVec[nLoop]) ;
|
||||
bool bSplitted = SplitAtPoint( ptOpenLoopEnP, cvBoundClosedLoopVec[nLoop], Loop1, Loop2) ;
|
||||
if ( ! ( bChangedStart && bSplitted))
|
||||
continue ;
|
||||
continue ;
|
||||
bLoopSplitted = true ;
|
||||
Chain cvCounterChain ;
|
||||
for ( int nPt = int( cvOpenChain[nLastOpenLoopN].size()) - 1 ; nPt >= 0 ; -- nPt) {
|
||||
IntSegment CurSeg ;
|
||||
@@ -892,11 +894,32 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, vecto
|
||||
bool bC21 = ( ( ptM21 - ptProva) * vtVecProva < 0) ;
|
||||
vbInOut[nLoop] = bC21 ;
|
||||
}
|
||||
}
|
||||
bLoopSplitted = true ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! bLoopSplitted) {
|
||||
int nCurDeg = vnDegVec[nLastOpenLoopN] ;
|
||||
vnDegVec.emplace( vnDegVec.begin(), nCurDeg) ;
|
||||
Chain CurChain ;
|
||||
for ( int nCrChSeg = 0 ; nCrChSeg < int( cvOpenChain[nLastOpenLoopN].size()) ; ++ nCrChSeg) {
|
||||
IntSegment CurChainSeg ;
|
||||
CurChainSeg.ptSt = cvOpenChain[nLastOpenLoopN][nCrChSeg].ptSt ;
|
||||
CurChainSeg.ptEn = cvOpenChain[nLastOpenLoopN][nCrChSeg].ptEn ;
|
||||
CurChainSeg.vtOuter = cvOpenChain[nLastOpenLoopN][nCrChSeg].vtOuter ;
|
||||
CurChainSeg.bDegenerate = cvOpenChain[nLastOpenLoopN][nCrChSeg].bDegenerate ;
|
||||
CurChain.emplace_back( CurChainSeg) ;
|
||||
}
|
||||
cvOpenChain.emplace( cvOpenChain.begin(), CurChain) ;
|
||||
++ nLastOpenLoopN ;
|
||||
++ nIterationCount ;
|
||||
}
|
||||
else
|
||||
nIterationCount = 0 ;
|
||||
vnDegVec.resize( nLastOpenLoopN) ;
|
||||
cvOpenChain.resize( nLastOpenLoopN) ;
|
||||
if ( nIterationCount > int( cvOpenChain.size()) + 2)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
@@ -911,8 +934,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
if ( m_nStatus != OK || ! SurfB.IsValid())
|
||||
return false ;
|
||||
// Unordered map dei segmenti di intersezione
|
||||
unordered_map <int, Chain> LineMapA ;
|
||||
unordered_map <int, Chain> LineMapB ;
|
||||
std::unordered_map <int, Chain> LineMapA ;
|
||||
std::unordered_map <int, Chain> LineMapB ;
|
||||
// Unordered map dei triangoli ambigui (intersezione edge-edge)
|
||||
std::unordered_map <int, std::vector <Triangle3d>> AmbiguosA ;
|
||||
std::unordered_map <int, std::vector <Triangle3d>> AmbiguosB ;
|
||||
// Ciclo sui triangoli delle mesh
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
int nTriaNumB = SurfB.GetTriangleSize() ;
|
||||
@@ -925,7 +951,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Se il triangolo A non è valido, continuo
|
||||
Triangle3d trTriaA ;
|
||||
if ( ! ( GetTriangle( nTA, trTriaA) && trTriaA.Validate( true)))
|
||||
continue ;
|
||||
continue ;
|
||||
// Box del triangolo A
|
||||
BBox3d b3dTriaA ;
|
||||
trTriaA.GetLocalBBox( b3dTriaA) ;
|
||||
@@ -934,7 +960,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
// Se il triangolo B non è valido, continuo
|
||||
Triangle3d trTriaB ;
|
||||
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate( true)))
|
||||
continue ;
|
||||
continue ;
|
||||
// Box del triangolo B
|
||||
BBox3d b3dTriaB ;
|
||||
trTriaB.GetLocalBBox( b3dTriaB) ;
|
||||
@@ -999,7 +1025,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
else
|
||||
bIntOnEndgeB = true ;
|
||||
|
||||
// Intersezione edge-interno
|
||||
if ( bIntOnEndgeA && ! bIntOnEndgeB) {
|
||||
double dMaxDist = 0. ;
|
||||
int nSegMaxDist = - 1 ;
|
||||
@@ -1014,6 +1040,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
m_vTria[nTA].nTempPart = ( ( trTriaA.GetP( nSegMaxDist) - trTriaB.GetP( 0)) * trTriaB.GetN() < - EPS_SMALL ? 1 : - 1) ;
|
||||
}
|
||||
}
|
||||
// Intersezione interno-edge
|
||||
else if ( ! bIntOnEndgeA && bIntOnEndgeB) {
|
||||
double dMaxDist = 0. ;
|
||||
int nSegMaxDist = - 1 ;
|
||||
@@ -1028,6 +1055,27 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
SurfB.m_vTria[nTB].nTempPart = ( ( trTriaB.GetP( nSegMaxDist) - trTriaA.GetP( 0)) * trTriaA.GetN() < - EPS_SMALL ? 1 : - 1) ;
|
||||
}
|
||||
}
|
||||
// Intersezione edge-edge
|
||||
else if ( bIntOnEndgeA && bIntOnEndgeB) {
|
||||
auto itA = AmbiguosA.find( nTA) ;
|
||||
if ( itA == AmbiguosA.end()) {
|
||||
std::vector <Triangle3d> vVecTriaB ;
|
||||
vVecTriaB.emplace_back( trTriaB) ;
|
||||
AmbiguosA.emplace( nTA, vVecTriaB) ;
|
||||
}
|
||||
else {
|
||||
itA->second.emplace_back( trTriaB) ;
|
||||
}
|
||||
auto itB = AmbiguosB.find( nTB) ;
|
||||
if ( itB == AmbiguosB.end()) {
|
||||
std::vector <Triangle3d> vVecTriaA ;
|
||||
vVecTriaA.emplace_back( trTriaA) ;
|
||||
AmbiguosB.emplace( nTB, vVecTriaA) ;
|
||||
}
|
||||
else {
|
||||
itB->second.emplace_back( trTriaA) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
;
|
||||
@@ -1035,7 +1083,7 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Ritriangolarizzo i triangoli della superficie A
|
||||
for ( auto it = LineMapA.begin() ; it != LineMapA.end() ; ++ it) {
|
||||
for ( int nS1 = 0 ; nS1 < int( it->second.size()) - 1 ; ++ nS1) {
|
||||
@@ -1052,6 +1100,14 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
if ( int( it->second.size()) == 0)
|
||||
continue ;
|
||||
// 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 itA = AmbiguosA.find( it->first) ;
|
||||
if ( itA != AmbiguosA.end()) {
|
||||
AmbiguosA.erase( itA) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Recupero il triangolo
|
||||
Triangle3d trTriaA ;
|
||||
@@ -1150,8 +1206,33 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
else
|
||||
vnDegVec.emplace_back( 1) ;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
for ( int nCh1 = 0 ; nCh1 < int( cvOpenChain.size()) - 1 ; ++ nCh1) {
|
||||
for ( int nCh2 = nCh1 + 1 ; nCh2 < int( cvOpenChain.size()) ; ++ nCh2) {
|
||||
int nChainSize1 = int( cvOpenChain[nCh1].size()) ;
|
||||
int nChainSize2 = int( cvOpenChain[nCh2].size()) ;
|
||||
int nSameSeg = 0 ;
|
||||
for ( int nSeg1 = 0 ; nSeg1 < nChainSize1 ; ++ nSeg1) {
|
||||
for ( int nSeg2 = 0 ; nSeg2 < nChainSize2 ; ++ nSeg2) {
|
||||
if ( AreSamePointExact( cvOpenChain[nCh1][nSeg1].ptSt, cvOpenChain[nCh2][nSeg2].ptSt) &&
|
||||
AreSamePointExact( cvOpenChain[nCh1][nSeg1].ptEn, cvOpenChain[nCh2][nSeg2].ptEn) &&
|
||||
AreSameVectorExact( cvOpenChain[nCh1][nSeg1].vtOuter, cvOpenChain[nCh2][nSeg2].vtOuter)) {
|
||||
++ nSameSeg ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nChainSize1 == nSameSeg) {
|
||||
cvOpenChain.erase( cvOpenChain.begin() + nCh1) ;
|
||||
vnDegVec.erase( vnDegVec.begin() + nCh1) ;
|
||||
-- nCh1 ;
|
||||
}
|
||||
else if ( nChainSize2 == nSameSeg) {
|
||||
cvOpenChain.erase( cvOpenChain.begin() + nCh2) ;
|
||||
vnDegVec.erase( vnDegVec.begin() + nCh2) ;
|
||||
-- nCh2 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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
|
||||
@@ -1160,14 +1241,14 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
cvFirstLoop.emplace_back( trTriaA.GetP( 0)) ;
|
||||
cvFirstLoop.emplace_back( trTriaA.GetP( 1)) ;
|
||||
cvFirstLoop.emplace_back( trTriaA.GetP( 2)) ;
|
||||
|
||||
|
||||
vector<PNTVECTOR> cvBoundClosedLoopVec ;
|
||||
cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ;
|
||||
vector<bool> vbInOut ;
|
||||
BOOLVECTOR vbInOut ;
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop usando le catene
|
||||
DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut) ;
|
||||
|
||||
|
||||
// Divido il loop usando le catene
|
||||
bool bDecomposed = DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut) ;
|
||||
// Rimuovo il triangolo corrente
|
||||
RemoveTriangle( it->first) ;
|
||||
// Trasformo i loop compositi in loop polyline
|
||||
@@ -1412,8 +1493,17 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( int( it->second.size()) == 0)
|
||||
continue ;
|
||||
// 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 itB = AmbiguosB.find( it->first) ;
|
||||
if ( itB != AmbiguosB.end()) {
|
||||
AmbiguosB.erase( itB) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Recupero il triangolo
|
||||
Triangle3d trTriaB ;
|
||||
@@ -1513,6 +1603,31 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
vnDegVec.emplace_back( 1) ;
|
||||
}
|
||||
}
|
||||
|
||||
for ( int nCh1 = 0 ; nCh1 < int( cvOpenChain.size()) - 1 ; ++ nCh1) {
|
||||
for ( int nCh2 = nCh1 + 1 ; nCh2 < int( cvOpenChain.size()) ; ++ nCh2) {
|
||||
int nChainSize1 = int( cvOpenChain[nCh1].size()) ;
|
||||
int nChainSize2 = int( cvOpenChain[nCh2].size()) ;
|
||||
int nSameSeg = 0 ;
|
||||
for ( int nSeg1 = 0 ; nSeg1 < nChainSize1 ; ++ nSeg1) {
|
||||
for ( int nSeg2 = 0 ; nSeg2 < nChainSize2 ; ++ nSeg2) {
|
||||
if ( AreSamePointExact( cvOpenChain[nCh1][nSeg1].ptSt, cvOpenChain[nCh2][nSeg2].ptSt) &&
|
||||
AreSamePointExact( cvOpenChain[nCh1][nSeg1].ptEn, cvOpenChain[nCh2][nSeg2].ptEn) &&
|
||||
AreSameVectorExact( cvOpenChain[nCh1][nSeg1].vtOuter, cvOpenChain[nCh2][nSeg2].vtOuter)) {
|
||||
++ nSameSeg ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nChainSize1 == nSameSeg) {
|
||||
cvOpenChain.erase( cvOpenChain.begin() + nCh1) ;
|
||||
vnDegVec.erase( vnDegVec.begin() + nCh1) ;
|
||||
}
|
||||
else if ( nChainSize2 == nSameSeg) {
|
||||
cvOpenChain.erase( cvOpenChain.begin() + nCh2) ;
|
||||
vnDegVec.erase( vnDegVec.begin() + nCh2) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Creo il loop chiuso padre di tutti, il perimetro del triangolo.
|
||||
// Questo viene diviso in sotto-loop chiusi mediante quelli aperti.
|
||||
@@ -1525,10 +1640,10 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
|
||||
vector<PNTVECTOR> cvBoundClosedLoopVec ;
|
||||
cvBoundClosedLoopVec.emplace_back( cvFirstLoop) ;
|
||||
vector<bool> vbInOut ;
|
||||
BOOLVECTOR vbInOut ;
|
||||
vbInOut.push_back( true) ;
|
||||
// Divido il loop usando le catene
|
||||
DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut) ;
|
||||
bool bDecomposed = DecomposeLoop( cvOpenChain, vnDegVec, cvBoundClosedLoopVec, vbInOut) ;
|
||||
// Rimuovo il triangolo corrente
|
||||
SurfB.RemoveTriangle( it->first) ;
|
||||
// Trasformo i loop compositi in loop polyline
|
||||
@@ -1761,9 +1876,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
vInnerLoop.resize( 0) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Se i triangoli delle superfici non si intersecano, una delle due è totalmente interna o esterna all'altra.
|
||||
bool bRetriangulated = true ;
|
||||
if ( ! bModif) {
|
||||
bRetriangulated = false ;
|
||||
int nVertNum = 0 ;
|
||||
Point3d ptFirstV ;
|
||||
int nCurVert = GetFirstVertex( ptFirstV) ;
|
||||
@@ -1843,12 +1960,67 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
SurfB.m_vTria[nTB].nTempPart = nInOutNum ;
|
||||
}
|
||||
}
|
||||
// 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) {
|
||||
for ( auto it = AmbiguosA.begin() ; it != AmbiguosA.end() ; ++ it) {
|
||||
Triangle3d trTriaA ;
|
||||
GetTriangle( it->first, trTriaA) ;
|
||||
trTriaA.Validate() ;
|
||||
Point3d ptBarA = ( trTriaA.GetP( 0) + trTriaA.GetP( 1) + trTriaA.GetP( 2)) / 3 ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
int nTriaIndex = - 1 ;
|
||||
for ( int nTB = 0 ; nTB < int( it->second.size()) ; ++ nTB) {
|
||||
Triangle3d trTriaB = it->second[nTB] ;
|
||||
double dDot = ( ptBarA - trTriaB.GetP( 0)) * trTriaB.GetN() ;
|
||||
if ( abs( dDot) > EPS_SMALL) {
|
||||
DistPointTriangle DistCalc( ptBarA, trTriaB) ;
|
||||
double dDist ;
|
||||
DistCalc.GetDist( dDist) ;
|
||||
if ( dDist < dMinDist) {
|
||||
nTriaIndex = nTB ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nTriaIndex != - 1) {
|
||||
Triangle3d trTriaB = it->second[nTriaIndex] ;
|
||||
trTriaB.Validate() ;
|
||||
double dDot = ( ptBarA - trTriaB.GetP( 0)) * trTriaB.GetN() ;
|
||||
m_vTria[it->first].nTempPart = ( dDot < 0 ? 1 : - 1) ;
|
||||
}
|
||||
}
|
||||
for ( auto it = AmbiguosB.begin() ; it != AmbiguosB.end() ; ++ it) {
|
||||
Triangle3d trTriaB ;
|
||||
SurfB.GetTriangle( it->first, trTriaB) ;
|
||||
Point3d ptBarB = ( trTriaB.GetP( 0) + trTriaB.GetP( 1) + trTriaB.GetP( 2)) / 3 ;
|
||||
double dMinDist = DBL_MAX ;
|
||||
int nTriaIndex = - 1 ;
|
||||
for ( int nTA = 0 ; nTA < int( it->second.size()) ; ++ nTA) {
|
||||
Triangle3d trTriaA = it->second[nTA] ;
|
||||
double dDot = ( ptBarB - trTriaA.GetP( 0)) * trTriaA.GetN() ;
|
||||
if ( abs(dDot) > EPS_SMALL) {
|
||||
DistPointTriangle DistCalc( ptBarB, trTriaA);
|
||||
double dDist ;
|
||||
DistCalc.GetDist( dDist) ;
|
||||
if ( dDist < dMinDist) {
|
||||
nTriaIndex = nTA ;
|
||||
dMinDist = dDist ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( nTriaIndex != - 1) {
|
||||
Triangle3d trTriaA = it->second[nTriaIndex] ;
|
||||
double dDot = ( ptBarB - trTriaA.GetP( 0)) * trTriaA.GetN() ;
|
||||
SurfB.m_vTria[it->first].nTempPart = ( dDot < 0 ? 1 : -1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bContinue = true ;
|
||||
// Se avvenuta modifica, aggiorno tutto
|
||||
if ( bModif)
|
||||
bContinue = ( AdjustVertices() && DoCompacting() && SurfB.AdjustVertices() && SurfB.DoCompacting()) ;
|
||||
|
||||
// Triangoli sovrapposti
|
||||
if ( bContinue) {
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
@@ -1879,8 +2051,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
|
||||
int nIntTypeAB = IntersTriaTria( trTriaA, trTriaB, ptTempA, ptTempB, vTriaAB) ;
|
||||
if ( nIntTypeAB == ITTTS_OVERLAPS) {
|
||||
bool bInvertB = trTriaA.GetN() * trTriaB.GetN() < 0. ;
|
||||
//m_vTria[nTA].nTempPart = ( m_vTria[nTA].nTempPart == 1 ? ( bInvertB ? -2 : 2) : m_vTria[nTA].nTempPart) ;
|
||||
//SurfB.m_vTria[nTB].nTempPart = ( SurfB.m_vTria[nTB].nTempPart == 1 ? ( bInvertB ? - 2 : 2) : SurfB.m_vTria[nTB].nTempPart) ;
|
||||
m_vTria[nTA].nTempPart = ( bInvertB ? -2 : 2) ;
|
||||
SurfB.m_vTria[nTB].nTempPart = ( bInvertB ? - 2 : 2) ;
|
||||
}
|
||||
@@ -1923,6 +2093,464 @@ SurfTriMesh::IdentifyParts( void) const
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::RemoveTJunction( void)
|
||||
{
|
||||
// Verifico lo stato
|
||||
if ( m_nStatus != OK)
|
||||
return false ;
|
||||
// Aggiorno timestamp dei triangoli
|
||||
++ m_nTimeStamp ;
|
||||
for ( auto& Tria : m_vTria)
|
||||
Tria.nTemp = m_nTimeStamp ;
|
||||
// Incremento time stamp
|
||||
++ m_nTimeStamp ;
|
||||
// Vettore di loop di T-Junction
|
||||
TJuncLoopVec TJLVec ;
|
||||
// Ciclo sui triangoli
|
||||
for ( int nT = 0 ; nT < int( m_vTria.size()) ; ++ nT) {
|
||||
// Se triangolo valido e non ancora visitato
|
||||
if ( m_vTria[nT].nIdVert[0] != SVT_DEL && m_vTria[nT].nTemp != m_nTimeStamp) {
|
||||
// Determino i triangoli adiacenti
|
||||
int nAdjT[3] ;
|
||||
for ( int j = 0 ; j < 3 ; ++ j)
|
||||
nAdjT[j] = m_vTria[nT].nIdAdjac[j] ;
|
||||
// Tre lati di contorno
|
||||
if ( nAdjT[0] == SVT_NULL && nAdjT[1] == SVT_NULL && nAdjT[2] == SVT_NULL) {
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
}
|
||||
// Lati 0 e 1 di contorno
|
||||
else if ( nAdjT[0] == SVT_NULL && nAdjT[1] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 0 ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 1 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 2, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
// Lati 1 e 2 di contorno
|
||||
else if ( nAdjT[1] == SVT_NULL && nAdjT[2] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 1 ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 2 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 0, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
// Lati 2 e 0 di contorno
|
||||
else if ( nAdjT[2] == SVT_NULL && nAdjT[0] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 2 ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 0 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 1, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
//Lato 0 di contorno
|
||||
else if ( nAdjT[0] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 0 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 1, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
// Lato 1 di contorno
|
||||
else if ( nAdjT[1] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 1 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 2, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
// Lato 2 di contorno
|
||||
else if ( nAdjT[2] == SVT_NULL) {
|
||||
// Ho trovato l'inizio di un loop
|
||||
TJLVec.emplace_back() ;
|
||||
TJLVec.back().emplace_back() ;
|
||||
TJLVec.back().back().nTriaId = nT ;
|
||||
TJLVec.back().back().nEdge = 2 ;
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
// Cammino lungo il loop fino a chiuderlo
|
||||
if ( ! MarchAlongFacetLoopForTJunc( nT, 0, m_nTimeStamp, TJLVec.back()))
|
||||
return false ;
|
||||
}
|
||||
// Altrimenti non c'è contorno
|
||||
else {
|
||||
// Marco il triangolo come verificato
|
||||
m_vTria[nT].nTemp = m_nTimeStamp ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::vector<TJEdgeSet>> vvIndexesSet ;
|
||||
// Cerco delle T-Junction nei loop trovati
|
||||
for ( int nL = 0 ; nL < int( TJLVec.size()) ; ++ nL) {
|
||||
// Ciclo suigli edges per raggrupparli
|
||||
for ( int nPos1 = 0 ; nPos1 < int( TJLVec[nL].size()) ; ++ nPos1) {
|
||||
bool bNew = true ;
|
||||
for ( int nPos2 = 0 ; nPos2 < int( TJLVec[nL].size()) ; ++ nPos2) {
|
||||
if ( nPos1 == nPos2)
|
||||
continue ;
|
||||
// Punti estremi dei due edge correnti
|
||||
Point3d ptS1, ptE1, ptS2, ptE2 ;
|
||||
GetVertex( m_vTria[TJLVec[nL][nPos1].nTriaId].nIdVert[TJLVec[nL][nPos1].nEdge], ptS1) ;
|
||||
GetVertex( m_vTria[TJLVec[nL][nPos1].nTriaId].nIdVert[( TJLVec[nL][nPos1].nEdge + 1) % 3], ptE1) ;
|
||||
GetVertex( m_vTria[TJLVec[nL][nPos2].nTriaId].nIdVert[TJLVec[nL][nPos2].nEdge], ptS2) ;
|
||||
GetVertex( m_vTria[TJLVec[nL][nPos2].nTriaId].nIdVert[( TJLVec[nL][nPos2].nEdge + 1) % 3], ptE2) ;
|
||||
Vector3d vtV = ptE1 - ptS1 ;
|
||||
double dLen = vtV.Len() ;
|
||||
vtV.Normalize() ;
|
||||
double dProjSt = ( ptS2 - ptS1) * vtV ;
|
||||
double dProjEn = ( ptE2 - ptS1) * vtV ;
|
||||
double dOrtSt = ( ( ptS2 - ptS1) - dProjSt * vtV).Len() ;
|
||||
double dOrtEn = ( ( ptE2 - ptS1) - dProjEn * vtV).Len() ;
|
||||
// Edge di posizione 2 forma una T-Junction su edge di posizione 1
|
||||
if ( ( dProjSt > EPS_SMALL && dProjSt < dLen - EPS_SMALL && dOrtSt < EPS_SMALL) ||
|
||||
( dProjEn > EPS_SMALL && dProjEn < dLen - EPS_SMALL && dOrtEn < EPS_SMALL)) {
|
||||
// Edge di pos 1 non aveva ancora T-Junction con edge di pos 2
|
||||
if ( bNew) {
|
||||
// Aggiungo il vettore di tutti i gruppi di edge che formano T-Junction con endge di pos 1,
|
||||
// aggiungo il gruppo con la normale di edge di pos 2 e aggiungo edge di pos due a tale gruppo.
|
||||
vvIndexesSet.emplace_back() ;
|
||||
vvIndexesSet[vvIndexesSet.size() - 1].emplace_back() ;
|
||||
vvIndexesSet[vvIndexesSet.size() - 1][vvIndexesSet[vvIndexesSet.size() - 1].size() - 1].emplace( TJLVec[nL][nPos2]) ;
|
||||
bNew = false ;
|
||||
}
|
||||
// Edge di pos 1 aveva già T-Junction con edge di pos 2
|
||||
else {
|
||||
// Cerco nei triangoli degli edge di pos 2 già trovati alcuni con la normale uguale al nuovo trovato
|
||||
int nNorm ;
|
||||
for ( nNorm = 0 ; nNorm < int( vvIndexesSet[vvIndexesSet.size() - 1].size()) ; ++ nNorm) {
|
||||
auto TEdgePtr = vvIndexesSet[vvIndexesSet.size() - 1][nNorm].begin() ;
|
||||
if ( AreSameVectorExact( m_vTria[TEdgePtr->nTriaId].vtN, m_vTria[TJLVec[nL][nPos2].nTriaId].vtN)) {
|
||||
break ;
|
||||
}
|
||||
}
|
||||
// Se non ho trovato tali triangoli aggiungo un nuovo gruppo
|
||||
if ( nNorm == int( vvIndexesSet[vvIndexesSet.size() - 1].size())) {
|
||||
vvIndexesSet[vvIndexesSet.size() - 1].emplace_back() ;
|
||||
}
|
||||
// Aggiungo il nuovo edge al suo gruppo
|
||||
vvIndexesSet[vvIndexesSet.size() - 1][nNorm].emplace( TJLVec[nL][nPos2]) ;
|
||||
}
|
||||
// Fra i triangoli adiacenti al triangolo con l'edge di pos 2
|
||||
// ne cerco altri con un vertice nella T-Junction
|
||||
for ( int m = 0 ; m < 3 ; ++ m) {
|
||||
// Triangolo adiacente e suo indice
|
||||
int nAdjTriaIndex = m_vTria[TJLVec[nL][nPos2].nTriaId].nIdAdjac[m] ;
|
||||
Triangle3d trAdjTria ;
|
||||
if ( GetTriangle( nAdjTriaIndex, trAdjTria)) {
|
||||
// Ciclo sugli edge del triangolo adiacente
|
||||
for ( int nVrt = 0 ; nVrt < 3 ; ++ nVrt) {
|
||||
double dAdjProjVrt = ( trAdjTria.GetP( nVrt) - ptS1) * vtV ;
|
||||
double dAdjOrtVrt = ( ( trAdjTria.GetP( nVrt) - ptS1) - dAdjProjVrt * vtV).Len() ;
|
||||
double dAdjProjNxt1 = ( trAdjTria.GetP( ( nVrt + 1) % 3) - ptS1) * vtV ;
|
||||
double dAdjOrtNxt1 = ( ( trAdjTria.GetP( ( nVrt + 1) % 3) - ptS1) - dAdjProjNxt1 * vtV).Len() ;
|
||||
double dAdjProjNxt2 = ( trAdjTria.GetP( ( nVrt + 2) % 3) - ptS1) * vtV ;
|
||||
double dAdjOrtNxt2 = ( ( trAdjTria.GetP( ( nVrt + 2) % 3) - ptS1) - dAdjProjNxt2 * vtV).Len() ;
|
||||
// Triangolo adiacente forma una T-Junction con l'edge di pos 1
|
||||
if ( dAdjProjVrt > EPS_SMALL && dAdjProjVrt < dLen - EPS_SMALL && dAdjOrtVrt < EPS_SMALL &&
|
||||
dAdjOrtNxt1 > EPS_SMALL && dAdjOrtNxt2 > EPS_SMALL) {
|
||||
// Lo aggiungo nel gruppo con i triangoli aventi la sua normale.
|
||||
// Se tale gruppo non esiste, lo aggiungo preventivamente
|
||||
int nNorm ;
|
||||
for ( nNorm = 0 ; nNorm < int( vvIndexesSet[vvIndexesSet.size() - 1].size()) ; ++ nNorm) {
|
||||
auto TEdgePtr = vvIndexesSet[vvIndexesSet.size() - 1][nNorm].begin() ;
|
||||
if ( AreSameVectorExact( m_vTria[TEdgePtr->nTriaId].vtN, m_vTria[nAdjTriaIndex].vtN)) {
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( nNorm == int( vvIndexesSet[vvIndexesSet.size() - 1].size())) {
|
||||
vvIndexesSet[vvIndexesSet.size() - 1].emplace_back() ;
|
||||
}
|
||||
// Cerco adiacenti dell'adiacente
|
||||
TEdgeId TJAdjTria ;
|
||||
TJAdjTria.nTriaId = nAdjTriaIndex ;
|
||||
TJAdjTria.nEdge = nVrt ;
|
||||
vvIndexesSet[vvIndexesSet.size() - 1][nNorm].emplace( TJAdjTria) ;
|
||||
TEdgeId TJTurnTria ;
|
||||
TJTurnTria.nTriaId = TJAdjTria.nTriaId ;
|
||||
TJTurnTria.nEdge = TJAdjTria.nEdge ;
|
||||
while ( GetForwardAdjTriaSharingVertex( TJTurnTria.nTriaId, TJTurnTria.nEdge) &&
|
||||
TJTurnTria.nTriaId != TJAdjTria.nTriaId) {
|
||||
if ( AreSameVectorExact( m_vTria[TJTurnTria.nTriaId].vtN, m_vTria[TJAdjTria.nTriaId].vtN)) {
|
||||
vvIndexesSet[vvIndexesSet.size() - 1][nNorm].emplace( TJTurnTria) ;
|
||||
}
|
||||
}
|
||||
TJTurnTria.nTriaId = TJAdjTria.nTriaId ;
|
||||
TJTurnTria.nEdge = TJAdjTria.nEdge ;
|
||||
while ( GetBackwardAdjTriaSharingVertex( TJTurnTria.nTriaId, TJTurnTria.nEdge) &&
|
||||
TJTurnTria.nTriaId != TJAdjTria.nTriaId) {
|
||||
if ( AreSameVectorExact( m_vTria[TJTurnTria.nTriaId].vtN, m_vTria[TJAdjTria.nTriaId].vtN)) {
|
||||
vvIndexesSet[vvIndexesSet.size() - 1][nNorm].emplace( TJTurnTria) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fra Loop diversi cerco se un medesimo gruppo appartiene a più edge dello stesso loop
|
||||
// o edge di loop diversi. In entrambi i casi fondo i gruppi.
|
||||
for ( int nL1 = 0 ; nL1 < int( vvIndexesSet.size()) ; ++ nL1) {
|
||||
for ( int nL2 = nL1 + 1 ; nL2 < int( vvIndexesSet.size()) ; ++ nL2) {
|
||||
for ( int nN1 = 0 ; nN1 < int( vvIndexesSet[nL1].size()) ; ++ nN1) {
|
||||
for ( int nN2 = 0 ; nN2 < int( vvIndexesSet[nL2].size()) ; ++ nN2) {
|
||||
bool bFoundCouple = false ;
|
||||
for ( auto it1 = vvIndexesSet[nL1][nN1].begin() ; it1 != vvIndexesSet[nL1][nN1].end() ; ++ it1) {
|
||||
for ( auto it2 = vvIndexesSet[nL2][nN2].begin() ; it2 != vvIndexesSet[nL2][nN2].end() ; ++ it2) {
|
||||
if ( it1->nTriaId == it2->nTriaId) {
|
||||
bFoundCouple = true ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( bFoundCouple)
|
||||
break ;
|
||||
}
|
||||
if ( bFoundCouple) {
|
||||
if ( vvIndexesSet[nL1][nN1].size() < vvIndexesSet[nL2][nN2].size()) {
|
||||
for ( auto it1 = vvIndexesSet[nL1][nN1].begin() ; it1 != vvIndexesSet[nL1][nN1].end() ; ++ it1) {
|
||||
vvIndexesSet[nL2][nN2].emplace( *it1) ;
|
||||
}
|
||||
vvIndexesSet[nL1][nN1].clear() ;
|
||||
}
|
||||
else {
|
||||
for ( auto it2 = vvIndexesSet[nL2][nN2].begin() ; it2 != vvIndexesSet[nL2][nN2].end(); ++ it2) {
|
||||
vvIndexesSet[nL1][nN1].emplace( *it2) ;
|
||||
}
|
||||
vvIndexesSet[nL2][nN2].clear() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Retriangolarizzo i poligoni
|
||||
for ( int nP = 0 ; nP < int( vvIndexesSet.size()) ; ++ nP) {
|
||||
for ( int nPP = 0 ; nPP < int( vvIndexesSet[nP].size()) ; ++ nPP) {
|
||||
auto it = vvIndexesSet[nP][nPP].begin() ;
|
||||
if ( it == vvIndexesSet[nP][nPP].end())
|
||||
continue ;
|
||||
Point3d ptP0, ptP1, ptP2 ;
|
||||
GetVertex( m_vTria[it->nTriaId].nIdVert[0], ptP0) ;
|
||||
GetVertex( m_vTria[it->nTriaId].nIdVert[1], ptP1) ;
|
||||
GetVertex( m_vTria[it->nTriaId].nIdVert[2], ptP2) ;
|
||||
CurveLine cvLine0 ;
|
||||
cvLine0.Set( ptP0, ptP1) ;
|
||||
CurveLine cvLine1 ;
|
||||
cvLine1.Set( ptP1, ptP2) ;
|
||||
CurveLine cvLine2 ;
|
||||
cvLine2.Set( ptP2, ptP0) ;
|
||||
CurveComposite cvLoop ;
|
||||
cvLoop.AddCurve( cvLine0) ;
|
||||
cvLoop.AddCurve( cvLine1) ;
|
||||
cvLoop.AddCurve( cvLine2) ;
|
||||
SurfFlatRegion Facet ;
|
||||
Facet.AddExtLoop( cvLoop) ;
|
||||
RemoveTriangle( it->nTriaId) ;
|
||||
++ it ;
|
||||
for ( ; it != vvIndexesSet[nP][nPP].end() ; ) {
|
||||
Point3d ptAddP0, ptAddP1, ptAddP2;
|
||||
if ( ! ( GetVertex( m_vTria[it->nTriaId].nIdVert[0], ptAddP0) &&
|
||||
GetVertex( m_vTria[it->nTriaId].nIdVert[1], ptAddP1) &&
|
||||
GetVertex( m_vTria[it->nTriaId].nIdVert[2], ptAddP2))) {
|
||||
++ it ;
|
||||
continue ;
|
||||
}
|
||||
CurveLine cvAddLine0 ;
|
||||
cvAddLine0.Set( ptAddP0, ptAddP1) ;
|
||||
CurveLine cvAddLine1 ;
|
||||
cvAddLine1.Set( ptAddP1, ptAddP2) ;
|
||||
CurveLine cvAddLine2 ;
|
||||
cvAddLine2.Set( ptAddP2, ptAddP0) ;
|
||||
CurveComposite cvAddLoop ;
|
||||
cvAddLoop.AddCurve( cvAddLine0) ;
|
||||
cvAddLoop.AddCurve( cvAddLine1) ;
|
||||
cvAddLoop.AddCurve( cvAddLine2) ;
|
||||
SurfFlatRegion AddFacet ;
|
||||
AddFacet.AddExtLoop( cvAddLoop) ;
|
||||
Facet.Add( AddFacet) ;
|
||||
RemoveTriangle( it->nTriaId) ;
|
||||
++it ;
|
||||
}
|
||||
int nChunkNum = Facet.GetChunkCount() ;
|
||||
for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) {
|
||||
ICurve* pOutline = Facet.GetLoop( nChunk, 0) ;
|
||||
PolyLine PolyOutline ;
|
||||
pOutline->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PolyOutline) ;
|
||||
PNTVECTOR vPt ;
|
||||
INTVECTOR vTr ;
|
||||
if ( Triangulate().Make( PolyOutline, vPt, vTr)) {
|
||||
// Inserisco i nuovi triangoli
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::MarchAlongFacetLoopForTJunc( int nT, int nV, int nTimeStamp, TJuncLoop& TJLoop) const
|
||||
{
|
||||
// Mi muovo lungo il loop, un triangolo alla volta
|
||||
bool bEnd = false ;
|
||||
while ( ! bEnd) {
|
||||
if ( ! MarchOneFacetTriaForTJunc( nT, nV, nTimeStamp, TJLoop, bEnd))
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::MarchOneFacetTriaForTJunc( int& nT, int& nV, int nTimeStamp, TJuncLoop& TJLoop, bool& bEnd) const
|
||||
{
|
||||
// Verifico esistenza triangolo adiacente, sul lato dopo il vertice
|
||||
if ( m_vTria[nT].nIdAdjac[nV] == SVT_NULL)
|
||||
return false ;
|
||||
// Indice del triangolo adiacente
|
||||
int nAdjT = m_vTria[nT].nIdAdjac[nV] ;
|
||||
// Recupero il suo lato di adiacenza
|
||||
int nAdjS = SVT_NULL ;
|
||||
for ( int i = 0 ; i < 3 ; ++ i) {
|
||||
if ( m_vTria[nAdjT].nIdAdjac[i] == nT) {
|
||||
nAdjS = i ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
if ( nAdjS == SVT_NULL)
|
||||
return false ;
|
||||
// Vertice di fine adiacenza e indice del successivo lato
|
||||
int nAdjV = Next( nAdjS) ;
|
||||
// Verifico se il lato successivo è un bordo
|
||||
int nNextT = m_vTria[nAdjT].nIdAdjac[nAdjV] ;
|
||||
if ( nNextT == SVT_NULL) {
|
||||
// Se già recuperato
|
||||
if ( m_vTria[nAdjT].nTemp == nTimeStamp) {
|
||||
bEnd = true ;
|
||||
return true ;
|
||||
}
|
||||
// Dichiaro triangolo analizzato
|
||||
m_vTria[nAdjT].nTemp = nTimeStamp ;
|
||||
// Aggiungo il lato al loop
|
||||
TJLoop.emplace_back() ;
|
||||
TJLoop.back().nTriaId = nAdjT ;
|
||||
TJLoop.back().nEdge = nAdjV ;
|
||||
// Verifico anche il successivo
|
||||
nAdjV = Next( nAdjV) ;
|
||||
nNextT = m_vTria[nAdjT].nIdAdjac[nAdjV] ;
|
||||
if ( nNextT == SVT_NULL) {
|
||||
// Aggiungo il lato al loop
|
||||
TJLoop.emplace_back() ;
|
||||
TJLoop.back().nTriaId = nAdjT ;
|
||||
TJLoop.back().nEdge = nAdjV ;
|
||||
nAdjV = Next(nAdjV);
|
||||
}
|
||||
}
|
||||
// Devo passare al triangolo adiacente
|
||||
nT = nAdjT ;
|
||||
nV = nAdjV ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetForwardAdjTriaSharingVertex( int& nTria, int& nVertInTria) const
|
||||
{
|
||||
// Verifico validità della posizione del vertice nel triangolo
|
||||
if ( nVertInTria < 0 || nVertInTria > 2)
|
||||
return false ;
|
||||
int nVert = m_vTria[nTria].nIdVert[nVertInTria] ;
|
||||
// Verifico esistenza del vertice
|
||||
if ( nVert < 0 || nVert >= GetVertexSize() || m_vVert[nVert].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// Verifico esistenza del triangolo
|
||||
if ( nTria < 0 || nTria >= GetTriangleSize() || m_vTria[nTria].nIdVert[0] == SVT_DEL)
|
||||
return false ;
|
||||
// Trovo triangolo adiacente che condivide il vertice
|
||||
nTria = m_vTria[nTria].nIdAdjac[nVertInTria] ;
|
||||
if ( nTria < 0 || nTria >= GetTriangleSize())
|
||||
return false ;
|
||||
// Trovo posizione del vertice nel triangolo adiacente
|
||||
nVertInTria = - 1 ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( m_vTria[nTria].nIdVert[n] == nVert)
|
||||
nVertInTria = n ;
|
||||
}
|
||||
return ( nVertInTria != - 1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::GetBackwardAdjTriaSharingVertex( int& nTria, int& nVertInTria) const
|
||||
{
|
||||
// Verifico validità della posizione del vertice nel triangolo
|
||||
if ( nVertInTria < 0 || nVertInTria > 2)
|
||||
return false ;
|
||||
int nVert = m_vTria[nTria].nIdVert[nVertInTria] ;
|
||||
// Verifico esistenza del vertice
|
||||
if ( nVert < 0 || nVert >= GetVertexSize() || m_vVert[nVert].nIdTria == SVT_DEL)
|
||||
return false ;
|
||||
// Verifico esistenza del triangolo
|
||||
if ( nTria < 0 || nTria >= GetTriangleSize() || m_vTria[nTria].nIdVert[0] == SVT_DEL)
|
||||
return false ;
|
||||
// Trovo triangolo adiacente che condivide il vertice
|
||||
nTria = m_vTria[nTria].nIdAdjac[( nVertInTria + 2) % 3] ;
|
||||
if ( nTria < 0 || nTria >= GetTriangleSize())
|
||||
return false ;
|
||||
// Trovo posizione del vertice nel triangolo adiacente
|
||||
nVertInTria = -1 ;
|
||||
for ( int n = 0 ; n < 3 ; ++ n) {
|
||||
if ( m_vTria[nTria].nIdVert[n] == nVert)
|
||||
nVertInTria = n ;
|
||||
}
|
||||
return ( nVertInTria != - 1) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
@@ -1947,7 +2575,11 @@ SurfTriMesh::Add( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bContinue = ( AdjustVertices() && DoCompacting()) ;
|
||||
if ( bContinue)
|
||||
RemoveTJunction() ;
|
||||
else
|
||||
return false ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
}
|
||||
|
||||
@@ -1975,7 +2607,11 @@ SurfTriMesh::Intersect( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bContinue = ( AdjustVertices() && DoCompacting()) ;
|
||||
if ( bContinue)
|
||||
RemoveTJunction() ;
|
||||
else
|
||||
return false ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
}
|
||||
|
||||
@@ -1989,7 +2625,7 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
IdentifyParts() ;
|
||||
SurfB.IdentifyParts() ;
|
||||
int nTriaNumA = GetTriangleSize() ;
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
for ( int nTA = 0 ; nTA < nTriaNumA ; ++ nTA) {
|
||||
if ( m_vTria[nTA].nTempPart == 1 || m_vTria[nTA].nTempPart == 2)
|
||||
RemoveTriangle( nTA) ;
|
||||
}
|
||||
@@ -2004,6 +2640,85 @@ SurfTriMesh::Subtract( const ISurfTriMesh& Other)
|
||||
AddTriangle( nNewVert) ;
|
||||
}
|
||||
}
|
||||
|
||||
bool bContinue = ( AdjustVertices() && DoCompacting()) ;
|
||||
if ( bContinue)
|
||||
RemoveTJunction() ;
|
||||
else
|
||||
return false ;
|
||||
return ( AdjustVertices() && DoCompacting()) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////// DEBUG /////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//if ( ( AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 30))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 30))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 30)))) {
|
||||
// int a = 0 ;
|
||||
//}
|
||||
//
|
||||
//if ( ( AreSamePointApprox(trTriaB.GetP(0), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(1), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(2), Point3d(20, 40, 30))) ||
|
||||
// ( AreSamePointApprox(trTriaB.GetP(2), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(0), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(1), Point3d(20, 40, 30))) ||
|
||||
// ( AreSamePointApprox(trTriaB.GetP(1), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(2), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(0), Point3d(20, 40, 30)))) {
|
||||
// int b = 0 ;
|
||||
//}
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//if ((AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 30))) ||
|
||||
// (AreSamePointApprox(trTriaA.GetP(2), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 30))) ||
|
||||
// (AreSamePointApprox(trTriaA.GetP(1), Point3d(20, 40, 46)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d(100, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d(20, 40, 30)))) {
|
||||
//
|
||||
// if ((AreSamePointApprox(trTriaB.GetP(0), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(1), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(2), Point3d(20, 40, 30))) ||
|
||||
// (AreSamePointApprox(trTriaB.GetP(2), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(0), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(1), Point3d(20, 40, 30))) ||
|
||||
// (AreSamePointApprox(trTriaB.GetP(1), Point3d(76, 40, 30)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(2), Point3d(60, 40, 50)) &&
|
||||
// AreSamePointApprox(trTriaB.GetP(0), Point3d(20, 40, 30)))) {
|
||||
// int b = 0;
|
||||
// }
|
||||
//}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//bool
|
||||
//FacesRetriangulation()
|
||||
//{
|
||||
// // Mi assicuro che la trimesh sia ok
|
||||
// // Assicurarsi che la trimesh sia ok ......
|
||||
// // Pongo tutti i triangoli come non visitati
|
||||
// for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) {
|
||||
// m_vTria[nT].nTemp = 0 ;
|
||||
// }
|
||||
// // Ciclo sui triangoli
|
||||
// for ( int nT = 0 ; nT < GetTriangleSize() ; ++ nT) {
|
||||
// // Se triangolo non visitato
|
||||
// if ( m_vTria[nT].nTemp == 0) {
|
||||
// m_vTria[nT].nTemp = 1 ;
|
||||
// std::unordered_set<int> TriaIndexSet ;// devi usare stack
|
||||
// TriaIndexSet.emplace( nT) ;
|
||||
// while ( ! TriaIndexSet.empty()) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return true ;
|
||||
//}
|
||||
|
||||
Reference in New Issue
Block a user