EgtGeomKernel :

- modifiche e migliorie alle booleane delle TriMesh.
This commit is contained in:
Dario Sassi
2019-11-25 08:01:50 +00:00
parent 29694209fa
commit eff21f5df8
2 changed files with 55 additions and 72 deletions
+54 -71
View File
@@ -271,7 +271,7 @@ SurfTriMesh::GeneralizedCut( const ICurve& cvCurve, bool bSaveOnEq)
// Approssimo la curva con segmenti
CurveComposite cvCompo ;
PolyLine PL ;
if ( ! cvCurve.ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! cvCompo.FromPolyLine( PL))
if ( ! cvCurve.ApproxWithLines( LIN_TOL_MIN, ANG_TOL_STD_DEG, ICurve::APL_STD, PL) || ! cvCompo.FromPolyLine( PL))
return false ;
// Appiattisco la polilinea nel piano perpendicolare all'estrusione
Frame3d frCurve ;
@@ -1235,8 +1235,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
// 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
POLYLINEVECTOR vplPolyVec ;
vplPolyVec.resize( cvBoundClosedLoopVec.size()) ;
@@ -1356,7 +1354,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
if ( vInnerLoop.size() == 0) {
// Eseguo triangolazione
Triangulate CreateTriangulation ;
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr)) {
@@ -1395,20 +1392,20 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
pgPol.FromPolyLine( vPolygons[1]) ;
if ( trTriaA.GetN() * pgPol.GetVersN() > 0.) {
for (int nL = 1; nL < int(vPolygons.size()); ++nL) {
vPolygons[nL].Invert();
for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) {
vPolygons[nL].Invert() ;
}
PNTVECTOR vPt;
INTVECTOR vTr;
if (Triangulate().Make(vPolygons, vPt, vTr)) {
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( vPolygons, vPt, vTr)) {
// Inserisco i nuovi triangoli
for (int n = 0; n < int(vTr.size()) - 2; n += 3) {
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]])} ;
int nNewTriaNum = AddTriangle(nNewId) ;
int nNewTriaNum = AddTriangle( nNewId) ;
if ( IsValidSvt( nNewTriaNum)) {
m_vTria[nNewTriaNum].nTempPart = -1 ;
bModif = true ;
@@ -1416,11 +1413,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
}
}
for (int nL = 1; nL < int(vPolygons.size()); ++nL) {
vPolygons[nL].Invert();
if (Triangulate().Make(vPolygons[nL], vPt, vTr)) {
for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) {
vPolygons[nL].Invert() ;
if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) {
// Inserisco i nuovi triangoli
for (int n = 0; n < int(vTr.size()) - 2; n += 3) {
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]]),
@@ -1435,16 +1432,16 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
}
}
else {
PNTVECTOR vPt;
INTVECTOR vTr;
if (Triangulate().Make(vPolygons, vPt, vTr)) {
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( vPolygons, vPt, vTr)) {
// Inserisco i nuovi triangoli
for (int n = 0; n < int(vTr.size()) - 2; n += 3) {
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]])} ;
int nNewTriaNum = AddTriangle(nNewId) ;
int nNewTriaNum = AddTriangle( nNewId) ;
if ( IsValidSvt( nNewTriaNum)) {
m_vTria[nNewTriaNum].nTempPart = 1 ;
bModif = true ;
@@ -1452,11 +1449,11 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
}
}
for (int nL = 1; nL < int(vPolygons.size()); ++nL) {
vPolygons[nL].Invert();
for ( int nL = 1 ; nL < int(vPolygons.size()) ; ++nL) {
vPolygons[nL].Invert() ;
if ( Triangulate().Make( vPolygons[nL], vPt, vTr)) {
// Inserisco i nuovi triangoli
for (int n = 0; n < int(vTr.size()) - 2; n += 3) {
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]]),
@@ -1761,7 +1758,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
if ( vInnerLoop.size() == 0) {
// Eseguo triangolazione
Triangulate CreateTriangulation ;
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( vplPolyVec[nLoop], vPt, vTr)) {
@@ -1844,7 +1840,6 @@ SurfTriMesh::IntersectTriMeshTriangle( SurfTriMesh& Other)
PNTVECTOR vPt ;
INTVECTOR vTr ;
if ( Triangulate().Make( vPolygons, vPt, vTr)) {
// Inserisco i nuovi triangoli
for ( int n = 0 ; n < int( vTr.size()) - 2 ; n += 3) {
@@ -1966,6 +1961,7 @@ 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) {
@@ -2142,13 +2138,12 @@ SurfTriMesh::RemoveTJunction( void)
double dProj = ( ptVert - ptSegSt) * vtSeg ;
double dOrt = ( ( ptVert - ptSegSt) - dProj * vtSeg).SqLen() ;
if ( dProj > EPS_SMALL && dProj < dSegLen - EPS_SMALL &&
dOrt < EPS_SMALL * EPS_SMALL /*&&
m_vTria[vNearTria[nNT]].nTemp != m_nTimeStamp*/) {
dOrt < EPS_SMALL * EPS_SMALL) {
if ( bNewBaseSeg) {
IndexesMatrix.emplace_back() ;
bNewBaseSeg = false ;
}
IndexesMatrix[int( IndexesMatrix.size()) - 1].emplace_back(vNearTria[nNT]) ;
IndexesMatrix.back().emplace_back( vNearTria[nNT]) ;
m_vTria[vNearTria[nNT]].nTemp = m_nTimeStamp ;
}
}
@@ -2159,8 +2154,8 @@ SurfTriMesh::RemoveTJunction( void)
for ( int nP1 = 0 ; nP1 < int( IndexesMatrix.size()); ++ nP1) {
for ( int nP2 = nP1 + 1 ; nP2 < int( IndexesMatrix.size()); ++ nP2) {
bool bFoundCouple = false ;
for (int nN1 = 0 ; nN1 < int( IndexesMatrix[nP1].size()); ++ nN1) {
for (int nN2 = 0 ; nN2 < int( IndexesMatrix[nP2].size()); ++ nN2) {
for ( int nN1 = 0 ; nN1 < int( IndexesMatrix[nP1].size()); ++ nN1) {
for ( int nN2 = 0 ; nN2 < int( IndexesMatrix[nP2].size()); ++ nN2) {
if ( IndexesMatrix[nP1][nN1] == IndexesMatrix[nP2][nN2]) {
bFoundCouple = true ;
break ;
@@ -2187,54 +2182,42 @@ SurfTriMesh::RemoveTJunction( void)
}
for ( int nVec = 0 ; nVec < int( IndexesMatrix.size()) ; ++ nVec) {
if ( int( IndexesMatrix[nVec].size()) == 0)
// se non sono almeno due triangoli, passo oltre
if ( IndexesMatrix[nVec].size() < 2)
continue ;
Triangle3d trTria ;
if ( ! ( GetTriangle( IndexesMatrix[nVec][0], trTria) && trTria.Validate( true)))
continue ;
CurveLine cvLine0 ;
cvLine0.Set( trTria.GetP( 0), trTria.GetP( 1)) ;
CurveLine cvLine1 ;
cvLine1.Set( trTria.GetP( 1), trTria.GetP( 2)) ;
CurveLine cvLine2 ;
cvLine2.Set( trTria.GetP( 2), trTria.GetP( 0)) ;
CurveComposite cvLoop ;
cvLoop.AddCurve( cvLine0) ;
cvLoop.AddCurve( cvLine1) ;
cvLoop.AddCurve( cvLine2) ;
// creo la regione unione dei triangoli
bool bFacetOk = false ;
SurfFlatRegion Facet ;
Facet.AddExtLoop( cvLoop) ;
RemoveTriangle( IndexesMatrix[nVec][0]) ;
for ( int nT = 1 ; nT < int( IndexesMatrix[nVec].size()) ; ++ nT) {
for ( int nT = 0 ; nT < int( IndexesMatrix[nVec].size()) ; ++ nT) {
Triangle3d trAddTria ;
if ( ! ( GetTriangle( IndexesMatrix[nVec][nT], trAddTria) && trAddTria.Validate( true)))
if ( ! GetTriangle( IndexesMatrix[nVec][nT], trAddTria) || ! trAddTria.Validate( true))
continue ;
CurveLine cvAddLine0 ;
cvAddLine0.Set( trAddTria.GetP( 0), trAddTria.GetP( 1)) ;
CurveLine cvAddLine1 ;
cvAddLine1.Set( trAddTria.GetP( 1), trAddTria.GetP( 2)) ;
CurveLine cvAddLine2 ;
cvAddLine2.Set( trAddTria.GetP( 2), trAddTria.GetP( 0)) ;
CurveComposite cvAddLoop ;
cvAddLoop.AddCurve( cvAddLine0) ;
cvAddLoop.AddCurve( cvAddLine1) ;
cvAddLoop.AddCurve( cvAddLine2) ;
SurfFlatRegion AddFacet ;
AddFacet.AddExtLoop( cvAddLoop) ;
if ( Facet.Add( AddFacet))
RemoveTriangle( IndexesMatrix[nVec][nT]) ;
CurveComposite ccLoop ;
ccLoop.AddPoint( trAddTria.GetP( 0)) ;
ccLoop.AddLine( trAddTria.GetP( 1)) ;
ccLoop.AddLine( trAddTria.GetP( 2)) ;
ccLoop.Close() ;
if ( ! bFacetOk) {
if ( Facet.AddExtLoop( ccLoop)) {
bFacetOk = true ;
RemoveTriangle( IndexesMatrix[nVec][nT]) ;
}
}
else {
SurfFlatRegion AddFacet ;
if ( AddFacet.AddExtLoop( ccLoop) && Facet.Add( AddFacet))
RemoveTriangle( IndexesMatrix[nVec][nT]) ;
}
}
int nChunkNum = Facet.GetChunkCount() ;
for ( int nChunk = 0 ; nChunk < nChunkNum ; ++ nChunk) {
// triangolo la regione e rimetto i triangoli nella superficie
int nChunkCnt = Facet.GetChunkCount() ;
for ( int nChunk = 0 ; nChunk < nChunkCnt ; ++ nChunk) {
POLYLINEVECTOR LoopVector ;
int nChunkLoopNum = Facet.GetLoopCount( nChunk) ;
for ( int nChunkLoop = 0 ; nChunkLoop < nChunkLoopNum ; ++ nChunkLoop) {
PtrOwner< ICurve> pOutline( Facet.GetLoop( nChunk, nChunkLoop)) ;
if ( IsNull( pOutline))
continue ;
int nLoopCnt = Facet.GetLoopCount( nChunk) ;
for ( int nLoop = 0 ; nLoop < nLoopCnt ; ++ nLoop) {
PolyLine PolyOutline ;
pOutline->ApproxWithLines( LIN_TOL_FINE, ANG_TOL_STD_DEG, ICurve::APL_STD, PolyOutline) ;
LoopVector.emplace_back( PolyOutline) ;
if ( Facet.ApproxLoopWithLines( nChunk, nLoop, LIN_TOL_MIN, ANG_TOL_STD_DEG, ICurve::APL_STD, PolyOutline))
LoopVector.emplace_back( PolyOutline) ;
}
PNTVECTOR vPt ;
INTVECTOR vTr ;