EgtGeomkernel :
- correzioni a booleane di TriMesh.
This commit is contained in:
+80
-89
@@ -1,7 +1,7 @@
|
||||
//----------------------------------------------------------------------------
|
||||
// EgalTech 2019-2020
|
||||
//----------------------------------------------------------------------------
|
||||
// File : SurfTriMeshBooleans.cpp Data : 13.03.20 Versione : 2.2c1
|
||||
// File : SurfTriMeshBooleans.cpp Data : 04.04.20 Versione : 2.2d1
|
||||
// Contenuto : Implementazione delle funzioni booleane per SurfFTrimesh.
|
||||
//
|
||||
//
|
||||
@@ -128,7 +128,7 @@ ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop)
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int( Loop.size())] ;
|
||||
// Vedo se il punto giace sul segmento del loop
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptNewStart, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
@@ -185,18 +185,18 @@ ChangeStart( const Point3d& ptNewStart, PNTVECTOR& Loop)
|
||||
static bool
|
||||
SplitAtPoint( const Point3d& ptStop, const PNTVECTOR& Loop, PNTVECTOR& Loop1, PNTVECTOR& Loop2)
|
||||
{
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
// Cerco il tratto del loop chiuso più vicino al punto
|
||||
int nMinSeg = -1 ;
|
||||
double dMinSqDinst = DBL_MAX;
|
||||
for (int nPt = 0 ; nPt < int(Loop.size()) ; ++ nPt) {
|
||||
double dMinSqDinst = DBL_MAX ;
|
||||
for ( int nPt = 0 ; nPt < int( Loop.size()) ; ++ nPt) {
|
||||
// Estremi del segmento corrente del loop
|
||||
Point3d ptSegSt = Loop[nPt] ;
|
||||
Point3d ptSegEn = Loop[(nPt + 1) % int(Loop.size())] ;
|
||||
// Vedo se il punto giace sul segmento del loop
|
||||
Point3d ptSegEn = Loop[( nPt + 1) % int(Loop.size())] ;
|
||||
// Distanza del punto dal segmento del loop
|
||||
DistPointLine dDistCalc( ptStop, ptSegSt, ptSegEn) ;
|
||||
double dSqDist ;
|
||||
dDistCalc.GetSqDist( dSqDist) ;
|
||||
if (dSqDist < dMinSqDinst) {
|
||||
if ( dSqDist < dMinSqDinst) {
|
||||
dMinSqDinst = dSqDist ;
|
||||
nMinSeg = nPt ;
|
||||
}
|
||||
@@ -735,6 +735,12 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
|
||||
bool
|
||||
SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMATRIX& cvBoundClosedLoopVec, BOOLVECTOR& vbInOut)
|
||||
{
|
||||
// Valuto se esistono loop non degeneri
|
||||
int nExistNotDeg = 0 ;
|
||||
for ( int nC = 0 ; nC < int( vnDegVec.size()) ; ++ nC) {
|
||||
if ( vnDegVec[nC] > 0)
|
||||
++ nExistNotDeg ;
|
||||
}
|
||||
// Divido il loop di partenza in sotto-loop
|
||||
int nIterationCount = 0 ;
|
||||
while ( cvOpenChain.size() > 0) {
|
||||
@@ -887,7 +893,7 @@ SurfTriMesh::DecomposeLoop( CHAINVECTOR& cvOpenChain, INTVECTOR& vnDegVec, PNTMA
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ! bLoopSplitted) {
|
||||
if ( ! bLoopSplitted && ( vnDegVec[nLastOpenLoopN] == 1 || nExistNotDeg == 0)) {
|
||||
int nCurDeg = vnDegVec[nLastOpenLoopN] ;
|
||||
vnDegVec.emplace( vnDegVec.begin(), nCurDeg) ;
|
||||
Chain CurChain ;
|
||||
@@ -1015,6 +1021,71 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
}
|
||||
|
||||
// Se esistono loop divisi in catene, le unisco
|
||||
Triangle3d trTria ;
|
||||
Surf.GetTriangle( it->first, trTria) ;
|
||||
for ( int nC1 = 0 ; nC1 < nChainCnt - 1 ; ++ nC1) {
|
||||
int nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ;
|
||||
bool bFirstChainInside = nFirstChainLastSegPos >= 0 &&
|
||||
IsPointInsideTriangle( vChain[nC1][0].ptSt, trTria, TriangleType::OPEN) &&
|
||||
IsPointInsideTriangle( vChain[nC1][nFirstChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ;
|
||||
for ( int nC2 = nC1 + 1 ; nC2 < nChainCnt && bFirstChainInside ; ++ nC2) {
|
||||
int nSecondChainLastSegPos = int( vChain[nC2].size()) - 1 ;
|
||||
bool bSecondChainInside = nSecondChainLastSegPos >= 0 &&
|
||||
IsPointInsideTriangle( vChain[nC2][0].ptSt, trTria, TriangleType::OPEN) &&
|
||||
IsPointInsideTriangle( vChain[nC2][nSecondChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ;
|
||||
nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ;
|
||||
bool bFisrtSecond = AreSamePointEpsilon( vChain[nC1][nFirstChainLastSegPos].ptEn, vChain[nC2][0].ptSt, 10 * EPS_SMALL) ;
|
||||
for ( int nSeg = 0 ; nSeg <= nSecondChainLastSegPos && bSecondChainInside && bFisrtSecond ; ++ nSeg) {
|
||||
IntSegment CurSeg ;
|
||||
CurSeg.ptSt = vChain[nC2][nSeg].ptSt ;
|
||||
CurSeg.ptEn = vChain[nC2][nSeg].ptEn ;
|
||||
CurSeg.vtOuter = vChain[nC2][nSeg].vtOuter ;
|
||||
CurSeg.bDegenerate = vChain[nC2][nSeg].bDegenerate ;
|
||||
vChain[nC1].emplace_back( CurSeg) ;
|
||||
}
|
||||
bool bSecondFirst = AreSamePointEpsilon( vChain[nC1][0].ptSt, vChain[nC2][nSecondChainLastSegPos].ptEn, 10 * EPS_SMALL) ;
|
||||
for ( int nSeg = 0 ; nSeg <= nFirstChainLastSegPos && bSecondChainInside && bSecondFirst && ! bFisrtSecond ; ++ nSeg) {
|
||||
IntSegment CurSeg ;
|
||||
CurSeg.ptSt = vChain[nC1][nSeg].ptSt ;
|
||||
CurSeg.ptEn = vChain[nC1][nSeg].ptEn ;
|
||||
CurSeg.vtOuter = vChain[nC1][nSeg].vtOuter ;
|
||||
CurSeg.bDegenerate = vChain[nC1][nSeg].bDegenerate ;
|
||||
vChain[nC2].emplace_back( CurSeg) ;
|
||||
}
|
||||
if ( bSecondChainInside && bFisrtSecond && nSecondChainLastSegPos >= 0) {
|
||||
nFirstChainLastSegPos = int( vChain[nC1].size()) - 1 ;
|
||||
bFirstChainInside = nFirstChainLastSegPos >= 0 &&
|
||||
IsPointInsideTriangle( vChain[nC1][0].ptSt, trTria, TriangleType::OPEN) &&
|
||||
IsPointInsideTriangle( vChain[nC1][nFirstChainLastSegPos].ptEn, trTria, TriangleType::OPEN) ;
|
||||
vChain.erase( vChain.begin() + nC2) ;
|
||||
-- nChainCnt ;
|
||||
-- nC2 ;
|
||||
}
|
||||
if ( bSecondChainInside && bSecondFirst && ! bFisrtSecond && nFirstChainLastSegPos >= 0) {
|
||||
vChain.erase( vChain.begin() + nC1) ;
|
||||
-- nChainCnt ;
|
||||
-- nC2 ;
|
||||
nC2 = nC2 == nC1 ? nC2 + 1 : nC2 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Chiudo i loop costruiti a partire dalle catene
|
||||
for ( int nC = 0 ; nC < nChainCnt ; ++ nC) {
|
||||
int nChainLastSegPos = int( vChain[nC].size()) - 1 ;
|
||||
if ( IsPointInsideTriangle( vChain[nC][0].ptSt, trTria, TriangleType::OPEN) &&
|
||||
IsPointInsideTriangle( vChain[nC][nChainLastSegPos].ptEn, trTria, TriangleType::OPEN) &&
|
||||
AreSamePointEpsilon( vChain[nC][0].ptSt, vChain[nC][nChainLastSegPos].ptEn, 10 * EPS_SMALL)) {
|
||||
IntSegment CurSeg ;
|
||||
CurSeg.ptSt = vChain[nC][nChainLastSegPos].ptEn ;
|
||||
CurSeg.ptEn = vChain[nC][0].ptSt ;
|
||||
CurSeg.vtOuter = ( CurSeg.ptEn - CurSeg.ptSt) ^ trTria.GetN() ;
|
||||
CurSeg.vtOuter.Normalize() ;
|
||||
CurSeg.bDegenerate = ( CurSeg.ptEn - CurSeg.ptSt).Len() > EPS_SMALL ;
|
||||
vChain[nC].emplace_back( CurSeg) ;
|
||||
}
|
||||
}
|
||||
|
||||
// Fra le catene trovate separo le aperte dalle chiuse
|
||||
int nDegenerateChainNum = 0 ;
|
||||
INTVECTOR vnDegVec ;
|
||||
@@ -1071,11 +1142,6 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
// 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.
|
||||
|
||||
// Recupero il triangolo
|
||||
Triangle3d trTria ;
|
||||
Surf.GetTriangle( it->first, trTria) ;
|
||||
|
||||
PNTVECTOR cvFirstLoop ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 0)) ;
|
||||
cvFirstLoop.emplace_back( trTria.GetP( 1)) ;
|
||||
@@ -1137,7 +1203,6 @@ SurfTriMesh::RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECT
|
||||
}
|
||||
else {
|
||||
Surf.m_vTria[it->first].nTempPart = 0 ;
|
||||
/*Surf.m_vTria[it->first].nTempPart *= 10 ;*/
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
@@ -2324,77 +2389,3 @@ SurfTriMesh::GetSurfClassification( const ISurfTriMesh& ClassifierSurf,
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
///////////////////////// DEBUG /////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//if ( nTriaNumB == 76 &&
|
||||
// ( AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 245.89, 190.5))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(2), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 245.89, 190.5))) ||
|
||||
// ( AreSamePointApprox(trTriaA.GetP(1), Point3d( 920.5333, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(2), Point3d( 1150.6666, 0.0000, 190.5)) &&
|
||||
// AreSamePointApprox(trTriaA.GetP(0), Point3d( 920.5333, 245.89, 190.5)))) {
|
||||
// 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 ;
|
||||
// unordered_set<int> TriaIndexSet ;// devi usare stack
|
||||
// TriaIndexSet.emplace( nT) ;
|
||||
// while ( ! TriaIndexSet.empty()) {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return true ;
|
||||
//}
|
||||
|
||||
Reference in New Issue
Block a user