EgtGeomKernel 1.8c2 :

- Validate e DoCompacting di SurfTrimesh eliminano i triangoli degeneri (punto o segmento di retta)
- a SurfTrimesh aggiunta Cut (taglio con un piano).
This commit is contained in:
Dario Sassi
2017-03-14 12:04:30 +00:00
parent 876e310289
commit 0b50dc348c
11 changed files with 243 additions and 19 deletions
+1 -1
View File
@@ -347,7 +347,7 @@ CurveBezier::GetType( void) const
const string&
CurveBezier::GetTitle( void) const
{
static const string sTitle = "CBezier" ;
static const string sTitle = "CurveBezier" ;
return sTitle ;
}
+1 -1
View File
@@ -575,7 +575,7 @@ CurveComposite::GetType( void) const
const string&
CurveComposite::GetTitle( void) const
{
static const string sTitle = "CComposite" ;
static const string sTitle = "CurveCompo" ;
return sTitle ;
}
BIN
View File
Binary file not shown.
+5
View File
@@ -58,9 +58,14 @@ PolyArc::AddUPoint( double dPar, const Point3d& ptP, double dBulge)
{
// se il punto è uguale al precedente (ignoro parametro e bulge), non lo inserisco ma ok
if ( m_lUPointBs.size() > 0 && AreSamePointApprox( ptP, m_lUPointBs.back().ptP)) {
// assegno parametro e bulge
m_lUPointBs.back().dU = dPar ;
m_lUPointBs.back().dB = dBulge ;
// incremento contatore rifiutati ed esco
++ m_nRejected ;
return true ;
}
// aggiungo il punto
try {
m_lUPointBs.emplace_back( dPar, ptP, dBulge) ;
}
+2 -2
View File
@@ -136,7 +136,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<ICurveComposite> pCompo2( GetCurveComposite( pCompo1->Clone())) ;
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// per creare la regione
@@ -168,7 +168,7 @@ GetSurfFlatRegionFromFatCurve( ICurve* pCrv, double dRadius, bool bSquareEnds, b
// fondo le curve allineate
pCompo1->MergeCurves( LIN_TOL_FINE, ANG_TOL_STD_DEG) ;
// ne faccio una copia e la inverto
PtrOwner<ICurveComposite> pCompo2( GetCurveComposite( pCompo1->Clone())) ;
PtrOwner<CurveComposite> pCompo2( pCompo1->Clone()) ;
if ( IsNull( pCompo2) || ! pCompo2->Invert())
return nullptr ;
// offset della prima curva a destra del raggio
+2 -2
View File
@@ -107,7 +107,7 @@ GetSurfTriMeshByExtrusion( const ICurve* pCurve, const Vector3d& vtExtr,
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
return nullptr ;
// la copio
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMesh( pSTM1->Clone())) ;
PtrOwner<ISurfTriMesh> pSTM2( pSTM1->Clone()) ;
if ( IsNull( pSTM2))
return nullptr ;
// inverto la prima superficie
@@ -154,7 +154,7 @@ GetSurfTriMeshByRegionExtrusion( const CICURVEPVECTOR& vpCurve, const Vector3d&
return nullptr ;
// creo la seconda superficie e la unisco alla prima
{ // copio la prima superficie
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMesh( pSTM->Clone())) ;
PtrOwner<ISurfTriMesh> pSTM2( pSTM->Clone()) ;
if ( IsNull( pSTM2))
return nullptr ;
// inverto la prima superficie
+1 -1
View File
@@ -47,7 +47,7 @@ GetSurfTriMeshBox( double dDimX, double dDimY, double dHeight)
if ( IsNull( pSTM1) || ! pSTM1->CreateByFlatContour( PL))
return nullptr ;
// la copio
PtrOwner<ISurfTriMesh> pSTM2( GetSurfTriMesh( pSTM1->Clone())) ;
PtrOwner<ISurfTriMesh> pSTM2( pSTM1->Clone()) ;
if ( IsNull( pSTM2))
return nullptr ;
// inverto la prima superficie
+1 -1
View File
@@ -375,7 +375,7 @@ SurfFlatRegion::GetType( void) const
const string&
SurfFlatRegion::GetTitle( void) const
{
static const string sTitle = "FlatRegion" ;
static const string sTitle = "SurfFr" ;
return sTitle ;
}
+224 -7
View File
@@ -35,7 +35,8 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ;
//----------------------------------------------------------------------------
SurfTriMesh::SurfTriMesh( void)
: m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dBoundaryAng( STM_STD_BOUNDARY_ANG),
m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false), m_nTimeStamp(), m_nTempProp()
m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bOriented( false), m_bClosed( false), m_bFaceted( false),
m_nTimeStamp( 0), m_nTempProp( 0)
{
m_dCosBndAng = cos( m_dBoundaryAng * DEGTORAD) ;
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
@@ -925,7 +926,7 @@ SurfTriMesh::GetType( void) const
const string&
SurfTriMesh::GetTitle( void) const
{
static const string sTitle = "TriMesh" ;
static const string sTitle = "SurfTm" ;
return sTitle ;
}
@@ -1146,8 +1147,10 @@ SurfTriMesh::Validate( void)
m_nStatus = ERR ;
}
// calcolo eventuale normale mancante
if ( m_nStatus == OK && m_vTria[i].vtN.IsSmall())
CalcTriangleNormal( i) ;
if ( m_nStatus == OK && m_vTria[i].vtN.IsSmall()) {
if ( ! CalcTriangleNormal( i))
RemoveTriangle( i) ;
}
}
}
@@ -2216,6 +2219,11 @@ SurfTriMesh::DoCompacting( void)
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
// se due vertici coincidono, cancello il triangolo
if ( m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[1] ||
m_vTria[nId].nIdVert[0] == m_vTria[nId].nIdVert[2] ||
m_vTria[nId].nIdVert[1] == m_vTria[nId].nIdVert[2])
RemoveTriangle( nId) ;
}
// ricalcolo le adiacenze
@@ -2295,9 +2303,11 @@ SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther)
vId[0] = vVId[vOId[0]] ;
vId[1] = vVId[vOId[1]] ;
vId[2] = vVId[vOId[2]] ;
// inserisco il triangolo
if ( AddTriangle( vId) == SVT_NULL)
return false ;
// se triangolo ancora valido, lo inserisco
if ( vId[0] != vId[1] && vId[0] != vId[2] && vId[1] != vId[2]) {
if ( AddTriangle( vId) == SVT_NULL)
return false ;
}
}
// ricalcolo le adiacenze
@@ -2673,3 +2683,210 @@ SurfTriMesh::Invert( void)
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::Cut( const Plane3d& plPlane, bool bSaveOnEq)
{
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// classifico i vertici rispetto al piano
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
double dDist = DistPointPlane( m_vVert[i].ptP, plPlane) ;
if ( abs( dDist) < EPS_SMALL)
m_vVert[i].nTemp = 0 ;
else if ( dDist > 0)
m_vVert[i].nTemp = +1 ;
else
m_vVert[i].nTemp = -1 ;
}
// aggiorno timestamp dei triangoli
for ( auto& Tria : m_vTria)
Tria.nTemp = m_nTimeStamp ;
++ m_nTimeStamp ;
// sistemo i triangoli (eventualmente li elimino)
bool bModif = false ;
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
// salto i triangoli cancellati e quelli aggiunti
if ( m_vTria[i].nIdVert[0] == SVT_DEL || m_vTria[i].nTemp == m_nTimeStamp)
continue ;
// se flag abilita e giace sul piano ed equiverso, lo salvo
if ( bSaveOnEq &&
m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0 &&
m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0 &&
m_vVert[ m_vTria[i].nIdVert[2]].nTemp == 0 &&
AreSameVectorApprox( m_vTria[i].vtN, plPlane.vtN))
;
// se giace sul piano o dalla parte esterna del piano, lo cancello
else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != -1 &&
m_vVert[ m_vTria[i].nIdVert[1]].nTemp != -1 &&
m_vVert[ m_vTria[i].nIdVert[2]].nTemp != -1) {
bModif = true ;
RemoveTriangle( i) ;
}
// se giace dalla parte interna con al massimo un lato sul piano, lo conservo
else if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp != 1 &&
m_vVert[ m_vTria[i].nIdVert[1]].nTemp != 1 &&
m_vVert[ m_vTria[i].nIdVert[2]].nTemp != 1)
;
// altrimenti attraversa il piano, devo modificarlo
else {
bModif = true ;
int nDisc = m_vVert[ m_vTria[i].nIdVert[0]].nTemp +
m_vVert[ m_vTria[i].nIdVert[1]].nTemp +
m_vVert[ m_vTria[i].nIdVert[2]].nTemp ;
// se ha un vertice all'interno e uno sul piano -> 1 nuovo vertice e 1 nuovo triangolo
if ( nDisc == 0) {
// classifico i vertici
int nVertOn, nVertIn, nVertOut ;
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 0) {
nVertOn = 0 ;
nVertIn = 1 ;
nVertOut = 2 ;
if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp > 0)
swap( nVertIn, nVertOut) ;
}
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 0) {
nVertOn = 1 ;
nVertIn = 2 ;
nVertOut = 0 ;
if ( m_vVert[ m_vTria[i].nIdVert[2]].nTemp > 0)
swap( nVertIn, nVertOut) ;
}
else {
nVertOn = 2 ;
nVertIn = 0 ;
nVertOut = 1 ;
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp > 0)
swap( nVertIn, nVertOut) ;
}
// calcolo il punto di intersezione del lato che attraversa il piano
double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ;
double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ;
Point3d ptInt = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
dDistIn / ( dDistIn + dDistOut)) ;
// inserisco il nuovo vertice
int nNewV = AddVertex( ptInt) ;
// inserisco il nuovo triangolo
int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
nIdVert[nVertOut] = nNewV ;
int nIdTria = AddTriangle( nIdVert) ;
if ( ! IsValidSvt( nIdTria))
return false ;
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
// cancello il vecchio triangolo
RemoveTriangle( i) ;
}
// se ha un vertice all'interno e due all'esterno -> 2 nuovi vertici e 1 nuovo triangolo
else if ( nDisc == 1) {
// classifico i vertici
int nVertIn, nVertOut1, nVertOut2 ;
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == -1) {
nVertIn = 0 ;
nVertOut1 = 1 ;
nVertOut2 = 2 ;
}
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == -1) {
nVertIn = 1 ;
nVertOut1 = 2 ;
nVertOut2 = 0 ;
}
else {
nVertIn = 2 ;
nVertOut1 = 0 ;
nVertOut2 = 1 ;
}
// calcolo i punti di intersezione dei lati che attraversano il piano
double dDistIn = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP, plPlane) ;
double dDistOut1 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP, plPlane) ;
double dDistOut2 = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP, plPlane) ;
Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
m_vVert[m_vTria[i].nIdVert[nVertOut1]].ptP,
dDistIn / ( dDistIn + dDistOut1)) ;
Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn]].ptP,
m_vVert[m_vTria[i].nIdVert[nVertOut2]].ptP,
dDistIn / ( dDistIn + dDistOut2)) ;
// inserisco i nuovi vertici
int nNewV1 = AddVertex( ptInt1) ;
int nNewV2 = AddVertex( ptInt2) ;
// inserisco il nuovo triangolo
int nIdVert[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
nIdVert[nVertOut1] = nNewV1 ;
nIdVert[nVertOut2] = nNewV2 ;
int nIdTria = AddTriangle( nIdVert) ;
if ( ! IsValidSvt( nIdTria))
return false ;
m_vTria[nIdTria].nTemp = m_nTimeStamp ;
// cancello il vecchio triangolo
RemoveTriangle( i) ;
}
// altrimenti ha due vertici allinterno e uno all'esterno -> 2 nuovi vertici e 2 nuovi triangoli
else {
// classifico i vertici
int nVertIn1, nVertIn2, nVertOut ;
if ( m_vVert[ m_vTria[i].nIdVert[0]].nTemp == 1) {
nVertOut = 0 ;
nVertIn1 = 1 ;
nVertIn2 = 2 ;
}
else if ( m_vVert[ m_vTria[i].nIdVert[1]].nTemp == 1) {
nVertOut = 1 ;
nVertIn1 = 2 ;
nVertIn2 = 0 ;
}
else {
nVertOut = 2 ;
nVertIn1 = 0 ;
nVertIn2 = 1 ;
}
// calcolo i punti di intersezione dei lati che attraversano il piano
double dDistIn1 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, plPlane) ;
double dDistIn2 = - DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, plPlane) ;
double dDistOut = DistPointPlane( m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP, plPlane) ;
Point3d ptInt1 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP,
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
dDistIn1 / ( dDistIn1 + dDistOut)) ;
Point3d ptInt2 = Media( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP,
m_vVert[m_vTria[i].nIdVert[nVertOut]].ptP,
dDistIn2 / ( dDistIn2 + dDistOut)) ;
// inserisco i nuovi vertici
int nNewV1 = AddVertex( ptInt1) ;
int nNewV2 = AddVertex( ptInt2) ;
// inserisco i nuovi triangoli
int nIdVert1[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
int nIdVert2[3] = { m_vTria[i].nIdVert[0], m_vTria[i].nIdVert[1], m_vTria[i].nIdVert[2]} ;
double dSqDist1 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn1]].ptP, ptInt2) ;
double dSqDist2 = SqDist( m_vVert[m_vTria[i].nIdVert[nVertIn2]].ptP, ptInt1) ;
if ( dSqDist1 <= dSqDist2) {
nIdVert1[nVertOut] = nNewV1 ;
nIdVert1[nVertIn2] = nNewV2 ;
nIdVert2[nVertOut] = nNewV2 ;
}
else {
nIdVert1[nVertOut] = nNewV1 ;
nIdVert2[nVertOut] = nNewV2 ;
nIdVert2[nVertIn1] = nNewV1 ;
}
int nIdTria1 = AddTriangle( nIdVert1) ;
int nIdTria2 = AddTriangle( nIdVert2) ;
if ( ! IsValidSvt( nIdTria1) || ! IsValidSvt( nIdTria2))
return false ;
m_vTria[nIdTria1].nTemp = m_nTimeStamp ;
m_vTria[nIdTria2].nTemp = m_nTimeStamp ;
// cancello il vecchio triangolo
RemoveTriangle( i) ;
}
}
}
// se necessario, aggiorno tutto
if ( bModif)
return DoCompacting() ;
return true ;
}
+5 -3
View File
@@ -25,13 +25,14 @@
class StmVert
{
public :
StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0) {}
StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0) {}
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF) {}
StmVert( void) : ptP(), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
StmVert( const Point3d& ptQ) : ptP( ptQ), nIdTria( SVT_NULL), nFlag( 0), nTemp( 0) {}
StmVert( const Point3d& ptQ, int nIdT, int nF) : ptP( ptQ), nIdTria( nIdT), nFlag( nF), nTemp( 0) {}
public :
Point3d ptP ;
int nIdTria ;
int nFlag ;
mutable int nTemp ;
} ;
//----------------------------------------------------------------------------
@@ -177,6 +178,7 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
bool GetFacetNormal( int nF, Vector3d& vtN) const override ;
bool GetFacetArea( int nF, double& dArea) const override ;
SurfTriMesh* CloneFacet( int nF) const override ;
bool Cut( const Plane3d& plPlane, bool bSaveOnEq) override ;
public : // IGeoObjRW
int GetNgeId( void) const override ;
+1 -1
View File
@@ -142,7 +142,7 @@ VolZmap::GetType( void) const
const string&
VolZmap::GetTitle( void) const
{
static const string sTitle = "Zmap" ;
static const string sTitle = "VolZm" ;
return sTitle ;
}