Fix Operazioni booleane e taglio trimesh con un piano

This commit is contained in:
LorenzoM
2021-04-21 17:52:35 +02:00
parent f989b402fd
commit 0b37e12df9
6 changed files with 2777 additions and 97 deletions
+83 -3
View File
@@ -21,10 +21,13 @@
#include "DistPointLine.h"
#include "Triangulate.h"
#include "GeoConst.h"
#include "SurfFlatRegion.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
#include "/EgtDev/Include/EGkPointGrid3d.h"
#include "/EgtDev/Include/EGkPolyLine.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUiUnits.h"
#include "/EgtDev/Include/EgkSfrCreate.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
#include <new>
#include <set>
@@ -3298,7 +3301,9 @@ SurfTriMesh::Invert( void)
bool
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
{
// la superficie deve essere validata
#define UseTria 0
#if UseTria
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
@@ -3502,14 +3507,89 @@ SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
}
}
// se effettuate modifiche
// se effettuate modifiche
if ( bModif) {
// aggiorno tutto
// aggiorno tutto
if ( ! AdjustVertices() || ! DoCompacting())
return false ;
}
return true ;
#endif
#if ! UseTria
bool bModif = false ;
// Setto il triangolo come né fuori né dentro.
int nTriaNum = GetTriangleSize();
for ( int nT = 0 ; nT < nTriaNum ; ++ nT) {
m_vTria[nT].nTempPart = 0 ;
}
INTERSCHAINMAP IntersLineMap ;
INTERSEDGEMAP EdgeInterLineMap ;
INTERSEDGEMAP EdgeEdgeLineMap ;
// Ciclo su tutte le facce.
int nFacetNum = GetFacetCount() ;
for ( int nF = 0 ; nF < nFacetNum ; ++ nF) {
// Dati della faccia
POLYLINEVECTOR vLoopVec ;
GetFacetLoops( nF, vLoopVec) ;
if ( vLoopVec.empty())
continue ;
PtrOwner<SurfFlatRegion> pReg( GetBasicSurfFlatRegion( GetSurfFlatRegionFromPolyLineVector( vLoopVec))) ;
if ( pReg == nullptr)
return false ;
SurfFlatRegion Region = *pReg ;
LineFacetClassVector IntersLinePart ;
int nIntType = IntersFacetPlane( Region, vLoopVec[0], plPlane, IntersLinePart) ;
if ( nIntType == FacetPlaneIntersType::FPI_CUT) {
for ( int nPart = 0 ; nPart < int( IntersLinePart.size()) ; ++ nPart) {
// Salvo intersezione per la faccia.
auto it = IntersLineMap.find( nF) ;
if ( it != IntersLineMap.end()) {
it->second.emplace_back( IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn)) ;
}
else {
IntersLineMap.emplace( nF, IntersInnChain( 1, IntersInnSeg( IntersLinePart[nPart].ptSt, IntersLinePart[nPart].ptEn))) ;
}
}
}
else if ( nIntType == FacetPlaneIntersType::FPI_ON) {
INTVECTOR vT ;
GetAllTriaInFacet( nF, vT) ;
for ( auto& nT : vT)
m_vTria[nT].nTempPart = Region.GetNormVersor() * plPlane.GetVersN() > 0. ? 2 : - 2 ;
}
else if ( nIntType == FacetPlaneIntersType::FPI_INN) {
INTVECTOR vT ;
GetAllTriaInFacet( nF, vT) ;
for ( auto& nT : vT)
m_vTria[nT].nTempPart = 1 ;
}
else if ( nIntType == FacetPlaneIntersType::FPI_OUT) {
INTVECTOR vT ;
GetAllTriaInFacet( nF, vT) ;
for ( auto& nT : vT)
m_vTria[nT].nTempPart = - 1 ;
}
else
;
}
// Divido le facce.
PieceMap NewFacet ;
SplitFacet( IntersLineMap, NewFacet) ;
RetriangulateFacetPieces( NewFacet, EdgeInterLineMap, EdgeEdgeLineMap) ;
int nNumTria = GetTriangleSize() ;
for ( int nT = 0 ; nT < nNumTria ; ++ nT)
if ( m_vTria[nT].nTempPart == - 1 || m_vTria[nT].nTempPart == - 2 || ( ! bSaveOnEq && m_vTria[nT].nTempPart == 2))
RemoveTriangle( nT) ;
return AdjustVertices() && DoCompacting() ;
#endif
}
//----------------------------------------------------------------------------