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
+6 -4
View File
@@ -75,10 +75,10 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
// intersezione tra i triangoli
Point3d ptInt, ptInt2 ;
TRIA3DVECTOR vIttTria ;
int nResEx = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
int nRes = FromSpecialToNormal( nResEx) ;
int nRes = IntersTriaTria( TriaA, TriaB, ptInt, ptInt2, vIttTria) ;
// se punto
if ( nRes == ITTT_VERT || nRes == ITTT_PNT) {
if ( nRes == ITTT_VERT_VERT || nRes == ITTT_VERT_EDGE || nRes == ITTT_VERT_INT ||
nRes == ITTT_EDGE_VERT || nRes == ITTT_EDGE_EDGE_PNT || nRes == ITTT_INT_VERT) {
// verifico se punto già inserito
int nId ;
if ( ! PtGrid.Find( ptInt, 10 * EPS_SMALL, nId)) {
@@ -87,7 +87,8 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
}
}
// se altrimenti segmento
else if ( nRes == ITTT_EDGE || nRes == ITTT_YES) {
else if ( nRes == ITTT_EDGE_EDGE_SEG || nRes == ITTT_EDGE_INT ||
nRes == ITTT_INT_EDGE || nRes == ITTT_INT_INT_SEG ) {
// se abbastanza lungo
if ( ! AreSamePointApprox( ptInt, ptInt2)) {
// verifico se già inserito
@@ -217,3 +218,4 @@ IntersSurfTmSurfTm( const ISurfTriMesh& Stm1, const ISurfTriMesh& Stm2,
return true ;
}
+337 -51
View File
@@ -25,20 +25,16 @@
using namespace std ;
//----------------------------------------------------------------------------
int nTriaTriaIntersCases[6][6] = { { ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_NO },
{ ITTTS_NO, ITTTS_INT_INT_SEG, ITTTS_INT_EDGE, ITTTS_NO, ITTTS_NO, ITTTS_NO },
{ ITTTS_NO, ITTTS_EDGE_INT, ITTTS_EDGE_EDGE_SEG, ITTTS_NO, ITTTS_NO, ITTTS_NO },
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_VERT_VERT, ITTTS_VERT_EDGE, ITTTS_VERT_INT },
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_EDGE_VERT, ITTTS_EDGE_EDGE_PNT, ITTTS_NO },
{ ITTTS_NO, ITTTS_NO, ITTTS_NO, ITTTS_INT_VERT, ITTTS_NO, ITTTS_NO } } ;
//----------------------------------------------------------------------------
static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TRIA3DVECTOR& vTria) ;
//----------------------------------------------------------------------------
static int FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU) ;
//----------------------------------------------------------------------------
int
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria)
IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, TRIA3DVECTOR& vTria, bool bSpecial)
{
// piano del secondo triangolo
Plane3d plTria2 ;
@@ -79,8 +75,8 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
return ITTT_NO ;
// intersezione tra i piani dei due triangoli
Point3d ptL1 ; Vector3d vtL1 ;
int nResPP = IntersPlanePlane( plTria1, plTria2, ptL1, vtL1) ;
Point3d ptL ; Vector3d vtL ;
int nResPP = IntersPlanePlane( plTria1, plTria2, ptL, vtL) ;
if ( nResPP == IPPT_NO)
return ITTT_NO ;
@@ -91,47 +87,22 @@ IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& p
return IntersCoplanarTriaTria( trTria1, trTria2, vTria) ;
// limito la linea di intersezione con il primo triangolo
int nRes1 = IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria1, ptInt, ptInt2, false) ;
if ( nRes1 == ILTT_NO)
return ITTT_NO ;
// il segmento calcolato va limitato col secondo triangolo
Point3d ptL2 = ptInt ;
Vector3d vtL2 = vtL1 ;
double dLen = 0 ;
if ( nRes1 != ILTT_VERT) {
vtL2 = ptInt2 - ptInt ;
dLen = vtL2.Len() ;
vtL2 /= dLen ;
}
Point3d ptI1 = ptInt ;
Point3d ptI12 = ptInt2 ;
int nRes2 = IntersCoplanarLineTria( ptL2, vtL2, dLen, trTria2, ptInt, ptInt2, true) ;
// gestione casi speciali apparentemente incongruenti
if ( ( nRes1 == ILTT_SEGM && nRes2 == ILTT_EDGE) || ( nRes1 == ILTT_EDGE && nRes2 == ILTT_SEGM)) {
if ( nRes1 == ILTT_SEGM) {
if ( PointInTria( ptI1, trTria2) != PTT_OUT && PointInTria( ptI12, trTria2) != PTT_OUT) {
ptInt = ( ptI1 + ptI12) / 2 ;
ptInt2 = ( ptI1 + ptI12) / 2 ;
return ITTTS_EDGE_EDGE_PNT ;
}
else
return ITTTS_NO ;
}
else {
Point3d ptI3, ptI32 ;
IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria2, ptI3, ptI32, false) ;
if ( PointInTria( ptI3, trTria1) != PTT_OUT && PointInTria( ptI32, trTria1) != PTT_OUT) {
ptInt = ( ptI3 + ptI32) / 2 ;
ptInt2 = ( ptI3 + ptI32) / 2 ;
return ITTTS_EDGE_EDGE_PNT ;
}
else
return ITTTS_NO ;
}
Point3d ptSt1, ptEn1 ;
int nRes1 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria1, ptSt1, ptEn1, false) ;
// limito la liena di intersezione con il secondo triangolo
Point3d ptSt2, ptEn2 ;
int nRes2 = IntersCoplanarLineTria( ptL, vtL, 100.0, trTria2, ptSt2, ptEn2, false) ;
double dIntStU, dIntEnU;
int nIntType = FindTriaTriaIntersType( trTria1, trTria2, ptL, vtL,
( ptSt1 - ptL) * vtL, ( ptEn1 - ptL) * vtL,
( ptSt2 - ptL) * vtL, ( ptEn2 - ptL) * vtL,
nRes1, nRes2, dIntStU, dIntEnU) ;
if ( nIntType != ITTT_NO) {
ptInt = ptL + dIntStU * vtL ;
ptInt2 = ptL + dIntEnU * vtL ;
return nIntType ;
}
return nTriaTriaIntersCases[nRes1][nRes2] ;
return ITTT_NO;
}
//----------------------------------------------------------------------------
@@ -225,3 +196,318 @@ IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, TR
return ITTT_OVERLAPS ;
}
//----------------------------------------------------------------------------
int
FindTriaTriaIntersType( const Triangle3d& trTria1, const Triangle3d& trTria2, const Point3d& ptLineSt, const Vector3d& vtLineDir,
double dStU1, double dEnU1, double dStU2, double dEnU2, int nRes1, int nRes2, double& dIntStU, double& dIntEnU)
{
// Controllo su validità input
if ( ! ( trTria1.IsValid() && trTria2.IsValid() && vtLineDir.IsNormalized()))
return ITTT_NO ;
// Casi
if ( nRes1 == ILTT_SEGM) {
if ( nRes2 == ILTT_SEGM) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false ;
bool bOnVert2 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert1) {
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else if ( bOnVert2)
return ITTT_EDGE_VERT ;
else
return ITTT_EDGE_EDGE_PNT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_INT_INT_SEG ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false;
bool bOnVert2 = false;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert1) {
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else if ( bOnVert2)
return ITTT_EDGE_VERT ;
else
return ITTT_EDGE_EDGE_PNT ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
}
if ( bOnVert1)
return ITTT_VERT_VERT ;
else
return ITTT_EDGE_VERT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_INT_EDGE ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
}
if ( bOnVert1)
return ITTT_VERT_VERT ;
else
return ITTT_EDGE_VERT ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_VERT) {
dEnU2 = dStU2 ;
if ( dStU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dStU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dStU2) ;
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
}
if ( bOnVert1)
return ITTT_VERT_VERT ;
else
return ITTT_EDGE_VERT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_INT_VERT ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert1 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria1.GetP( n), ptInt))
bOnVert1 = true ;
}
if ( bOnVert1)
return ITTT_VERT_VERT ;
else
return ITTT_EDGE_VERT ;
}
else
return ITTT_NO ;
}
else
return ITTT_NO ;
}
else if ( nRes1 == ILTT_SEGM_ON_EDGE) {
if ( nRes2 == ILTT_SEGM) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert2 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_EDGE_INT ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert2 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
return ITTT_VERT_VERT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_EDGE_EDGE_SEG ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
return ITTT_VERT_VERT ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_VERT) {
dEnU2 = dStU2 ;
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
return ITTT_VERT_VERT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_EDGE_VERT ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
return ITTT_VERT_VERT ;
}
else
return ITTT_NO ;
}
else
return ITTT_NO ;
}
else if ( nRes1 == ILTT_VERT) {
dEnU1 = dStU1 ;
if ( nRes2 == ILTT_SEGM) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert2 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_VERT_INT ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU2 + dEnU1) ;
dIntEnU = 0.5 * ( dStU2 + dEnU1) ;
Point3d ptInt = ptLineSt + dIntStU * vtLineDir ;
bool bOnVert2 = false ;
for ( int n = 0 ; n < 3 ; ++ n) {
if ( AreSamePointApprox( trTria2.GetP( n), ptInt))
bOnVert2 = true ;
}
if ( bOnVert2)
return ITTT_VERT_VERT ;
else
return ITTT_VERT_EDGE ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_SEGM_ON_EDGE) {
if ( dEnU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dEnU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dEnU2) ;
dIntEnU = 0.5 * ( dStU1 + dEnU2) ;
return ITTT_VERT_VERT ;
}
else if ( dStU2 < dEnU1 - EPS_SMALL) {
dIntStU = max( dStU1, dStU2) ;
dIntEnU = min( dEnU1, dEnU2) ;
return ITTT_VERT_EDGE ;
}
else if ( dStU2 < dEnU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dStU2) ;
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
return ITTT_VERT_VERT ;
}
else
return ITTT_NO ;
}
else if ( nRes2 == ILTT_VERT) {
if ( dStU2 < dStU1 - EPS_SMALL)
return ITTT_NO ;
else if ( dStU2 < dStU1 + EPS_SMALL) {
dIntStU = 0.5 * ( dStU1 + dStU2) ;
dIntEnU = 0.5 * ( dStU1 + dStU2) ;
return ITTT_VERT_VERT ;
}
else
return ITTT_NO ;
}
else
return ITTT_NO ;
}
else
return ITTT_NO ;
}
+63
View File
@@ -18,6 +18,7 @@
#include "CurveComposite.h"
#include "SurfFlatRegion.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EgkPolyLine.h"
#include "/EgtDev/Include/EgkBiArcs.h"
#include "/EgtDev/Include/EgkOffsetCurve.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
@@ -275,6 +276,68 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
}
}
//----------------------------------------------------------------------------
ISurfFlatRegion*
GetSurfFlatRegionFromPolyLine( const PolyLine& ContourPolyLine)
{
// Creo la regione.
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
if ( IsNull( pSfr))
return nullptr ;
// Creo curva composita.
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
if ( IsNull( pLoop))
return nullptr ;
Point3d ptSt, ptEn ;
bool bContinue = ContourPolyLine.GetFirstPoint( ptSt) &&
ContourPolyLine.GetNextPoint( ptEn) ;
while ( bContinue) {
CurveLine cvLine ;
cvLine.Set( ptSt, ptEn) ;
pLoop->AddCurve( cvLine) ;
ptSt = ptEn ;
bContinue = ContourPolyLine.GetNextPoint( ptEn) ;
}
pSfr->AddExtLoop( Release( pLoop)) ;
return Release( pSfr) ;
}
//----------------------------------------------------------------------------
ISurfFlatRegion*
GetSurfFlatRegionFromPolyLineVector( const POLYLINEVECTOR& vContoursPolyLineVec)
{
// Creo la regione.
PtrOwner<SurfFlatRegion> pSfr( CreateBasicSurfFlatRegion()) ;
if ( IsNull( pSfr))
return nullptr ;
// Ciclo sulle PolyLine.
for ( int nL = 0 ; nL < int( vContoursPolyLineVec.size()) ; ++ nL) {
// Creo curva composita.
PtrOwner<CurveComposite> pLoop( CreateBasicCurveComposite()) ;
if ( IsNull( pLoop))
return nullptr ;
Point3d ptSt, ptEn ;
bool bContinue = vContoursPolyLineVec[nL].GetFirstPoint( ptSt) &&
vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
while ( bContinue) {
CurveLine cvLine ;
cvLine.Set( ptSt, ptEn) ;
pLoop->AddCurve( cvLine) ;
ptSt = ptEn ;
bContinue = vContoursPolyLineVec[nL].GetNextPoint( ptEn) ;
}
// Loop esterno
if ( nL == 0) {
pSfr->AddExtLoop( Release( pLoop)) ;
}
// Loop interno
else {
pSfr->AddIntLoop( Release( pLoop)) ;
}
}
return Release( pSfr) ;
}
//-------------------------------------------------------------------------------
// Classe SurfFlatRegionByContours
//-------------------------------------------------------------------------------
+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
}
//----------------------------------------------------------------------------
+90
View File
@@ -21,6 +21,8 @@
#include <deque>
#include <set>
class SurfFlatRegion ;
//----------------------------------------------------------------------------
// Classe Vertice
class StmVert
@@ -110,6 +112,70 @@ typedef std::vector<TJuncLoop> TJuncLoopVec ;
// Set di TEdgeId
typedef std::set<TEdgeId> TJEdgeSet ;
// Definizione strutture intersezione linea-faccia
//----------------------------------------------------------------------------
struct LineFacetClass {
Point3d ptSt, ptEn ;
int nTypeA, nTypeB ;
LineFacetClass() {
nTypeA = 0 ;
nTypeB = 0 ;
}
LineFacetClass( const Point3d& ptS, const Point3d ptE, int nTpA, int nTpB) {
ptSt = ptS ;
ptEn = ptE ;
nTypeA = nTpA ;
nTypeB = nTpB ;
}
} ;
typedef std::vector<LineFacetClass> LineFacetClassVector ;
//----------------------------------------------------------------------------
enum FacetPlaneIntersType { FPI_ERROR = 0, FPI_CUT = 1, FPI_INN = 2, FPI_OUT = 3, FPI_ON = 4 } ;
//----------------------------------------------------------------------------
// Definizione strutture e contenitori
// Contatti interno-interno
struct IntersInnSeg {
Point3d ptSt ;
Point3d ptEn ;
Vector3d vtOuter ;
IntersInnSeg(void) {
;
}
IntersInnSeg(const Point3d& ptS, const Point3d& ptE) {
ptSt = ptS;
ptEn = ptE;
}
IntersInnSeg(const Point3d& ptS, const Point3d& ptE, const Vector3d& vtO) {
ptSt = ptS;
ptEn = ptE;
vtOuter = vtO;
}
};
typedef std::vector<IntersInnSeg> IntersInnChain ;
typedef std::vector<IntersInnChain> INNCHAINVECTOR ;
typedef std::unordered_map<int, IntersInnChain> INTERSCHAINMAP ;
// Contatti con spigolo
struct IntersEdge {
Point3d ptSt ;
Point3d ptEn ;
INTVECTOR vOthFacetIndex ;
IntersEdge( const Point3d& ptS, const Point3d& ptE, const INTVECTOR& vOFI) {
ptSt = ptS;
ptEn = ptE;
vOthFacetIndex = vOFI;
}
} ;
typedef std::vector<IntersEdge> IntersEdgeVec ;
typedef std::unordered_map<int, IntersEdgeVec> INTERSEDGEMAP ;
// Parte di faccia
struct FacetPiece {
POLYLINEVECTOR vPieceLoop ;
int nPiecePart ;
} ;
typedef std::unordered_map<int, std::vector<FacetPiece>> PieceMap ;
//----------------------------------------------------------------------------
class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
{
@@ -318,6 +384,22 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool RetriangulationForBooleanOperation( CHAINMAP& LoopLines, TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf, bool& bModif) ;
bool AmbiguosTriangleManager( TRIA3DVECTORMAP& Ambiguos, SurfTriMesh& Surf) ;
bool IntersectTriMeshTriangle( SurfTriMesh& Other) ;
int IntersFacetPlane( const SurfFlatRegion& Region, const PolyLine& ExtLoop, const Plane3d& plCutPlane,
LineFacetClassVector& IntersLinePart) ;
bool IntersFacetFacet( const SurfFlatRegion& RegionA, const PolyLine& ExtLoopA,
const SurfFlatRegion& RegionB, const PolyLine& ExtLoopB,
LineFacetClassVector& IntersLinePart) ;
bool ItersectTriMeshFacets( SurfTriMesh& Other) ;
bool RetriangulateFacetPieces( const PieceMap& NewFacet,
const INTERSEDGEMAP& EdgeInterLineMap,
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
bool EdgeInteriorContactManager( const SurfTriMesh& OthSurf,
const INTERSCHAINMAP& InterInterLineMap,
const INTERSEDGEMAP& EdgeInterLineMap) ;
bool EdgeEdgeContactManager( const SurfTriMesh& OthSurf,
const INTERSCHAINMAP& InterInterLineMap,
const INTERSEDGEMAP& EdgeEdgeLineMap) ;
bool SplitFacet( const INTERSCHAINMAP& IntersLineMap, PieceMap& NewFacet);
bool IdentifyParts( void) const ;
bool RemoveTJunctions( void) ;
bool RemoveCaps( void) ;
@@ -347,6 +429,14 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
mutable BBox3d m_b3HGrd3d ; // Box3d collegato a Hash Grid 3d
} ;
//----------------------------------------------------------------------------
static bool ChangePolyLineStart( const Point3d& ptNewStart, PolyLine& Loop) ;
// nSegNum 0-based
static bool PointPositionOnPolyLine( const Point3d& ptPoint, /*const*/ PolyLine& Loop, int& nSegNum, double& dParOnSeg) ;
static bool IsPointInsidePolyLine( const Point3d& ptP, /*const*/ PolyLine& plPoly) ;
static bool SplitPolyLineAtPoint( const Point3d& ptPoint, /*const*/ PolyLine& Loop, PolyLine& Loop1, PolyLine& Loop2) ;
static bool AddPolyLineToPolyLine(PolyLine& Poly, PolyLine& PolyToAdd) ;
//-----------------------------------------------------------------------------
inline SurfTriMesh* CreateBasicSurfTriMesh( void)
{ return ( static_cast<SurfTriMesh*>( CreateGeoObj( SRF_TRIMESH))) ; }
+2198 -39
View File
File diff suppressed because it is too large Load Diff