EgtGeomKernel 1.5d2 :

- creazione di superfici trimesh da piani contornati e per estrusione
- migliorie a PolyLine
- migliorie a FromString
- modifiche a Vector3d e Point3d.
This commit is contained in:
Dario Sassi
2014-04-09 13:00:17 +00:00
parent d509417136
commit 9b564445cd
15 changed files with 771 additions and 119 deletions
+212 -28
View File
@@ -13,15 +13,11 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DllMain.h"
#include "SurfTriMesh.h"
#include "GeoConst.h"
#include "DistPointLine.h"
#include "GeoObjFactory.h"
#include "PolynomialPoint3d.h"
#include "\EgtDev\Include\EGkCurveArc.h"
#include "\EgtDev\Include\ENkPolynomial.h"
#include "Triangulate.h"
#include "\EgtDev\Include\EGkStringUtils3d.h"
#include "\EgtDev\Include\EGkPolyLine.h"
#include <new>
using namespace std ;
@@ -73,7 +69,7 @@ SurfTriMesh::AddVertex( const Point3d& ptVert)
m_OGrMgr.Reset() ;
// inserisco il vertice
try { m_vVert.push_back( StmVert( ptVert)) ;}
catch(...) { return - 1 ;}
catch(...) { return VT_NULL ;}
// ne determino l'indice
return int( m_vVert.size() - 1) ;
}
@@ -95,9 +91,11 @@ SurfTriMesh::SetVertex( int nInd, const StmVert& vV)
try { m_vVert.resize( nNewSize) ; }
catch (...) { return false ; }
// inizializzo a cancellati gli eventuali vertici intermedi
StmVert vEmpty( Point3d(), VT_DEL, 0) ;
for ( int i = nPrevSize ; i < nNewSize ; ++ i)
m_vVert[i] = vEmpty ;
if ( ( nNewSize - nPrevSize) > 1) {
StmVert vEmpty( Point3d(), VT_DEL, 0) ;
for ( int i = nPrevSize ; i < nNewSize ; ++ i)
m_vVert[i] = vEmpty ;
}
}
// inserisco il vertice
m_vVert[nInd] = vV ;
@@ -112,7 +110,8 @@ SurfTriMesh::AddTriangle( const int nIdVert[3])
m_nStatus = TO_VERIFY ;
m_OGrMgr.Reset() ;
// inserisco il triangolo
m_vTria.push_back( StmTria( nIdVert)) ;
try { m_vTria.push_back( StmTria( nIdVert)) ;}
catch(...) { return VT_NULL ;}
// ne determino l'indice
return int( m_vTria.size() - 1) ;
}
@@ -134,10 +133,12 @@ SurfTriMesh::SetTriangle( int nInd, const StmTria& tT)
try { m_vTria.resize( nNewSize) ; }
catch (...) { return false ; }
// inizializzo a cancellati gli eventuali triangoli intermedi
StmTria tEmpty ;
tEmpty.nIdVert[0] = VT_DEL ;
for ( int i = nPrevSize ; i < nNewSize ; ++ i)
m_vTria[i] = tEmpty ;
if ( ( nNewSize - nPrevSize) > 1) {
StmTria tEmpty ;
tEmpty.nIdVert[0] = VT_DEL ;
for ( int i = nPrevSize ; i < nNewSize ; ++ i)
m_vTria[i] = tEmpty ;
}
}
// inserisco il vertice
m_vTria[nInd] = tT ;
@@ -148,7 +149,7 @@ SurfTriMesh::SetTriangle( int nInd, const StmTria& tT)
int
SurfTriMesh::GetFirstVertex( Point3d& ptP) const
{
return GetNextVertex( -1, ptP) ;
return GetNextVertex( VT_NULL, ptP) ;
}
//----------------------------------------------------------------------------
@@ -161,7 +162,7 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
} while ( nId < GetVertexNum() && m_vVert[nId].nIdTria == VT_DEL) ;
// se oltrepassata fine
if ( nId >= GetVertexNum())
return -1 ;
return VT_NULL ;
// recupero i dati
ptP = m_vVert[nId].ptP ;
// ritorno indice triangolo corrente
@@ -172,7 +173,7 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
int
SurfTriMesh::GetFirstTriangle( Triangle3d& Tria) const
{
return GetNextTriangle( -1, Tria) ;
return GetNextTriangle( VT_NULL, Tria) ;
}
//----------------------------------------------------------------------------
@@ -185,7 +186,7 @@ SurfTriMesh::GetNextTriangle( int nId, Triangle3d& Tria) const
} while ( nId < GetTriangleNum() && m_vTria[nId].nIdVert[0] == VT_DEL) ;
// se oltrepassata fine
if ( nId >= GetTriangleNum())
return -1 ;
return VT_NULL ;
// recupero i dati
Tria.Set( m_vVert[m_vTria[nId].nIdVert[0]].ptP,
m_vVert[m_vTria[nId].nIdVert[1]].ptP,
@@ -195,6 +196,66 @@ SurfTriMesh::GetNextTriangle( int nId, Triangle3d& Tria) const
return nId ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetTriangleSmoothNormals( int nId, TriNormals3d& TNrms) const
{
// verifico esistenza del triangolo
if ( nId >= GetTriangleNum() || m_vTria[nId].nIdVert[0] == VT_DEL)
return false ;
// recupero le normali di ciascun vertice
for ( int i = 0 ; i < 3 ; ++ i) {
if ( ! GetTriangleSmoothNormal( nId, i, TNrms.vtN[i]))
TNrms.vtN[i] = m_vTria[nId].vtN ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
{
// recupero tutti i triangoli attorno al vertice
INTVECTOR vT ;
int nTria = GetAllTriaAroundVertex( m_vTria[nT].nIdVert[nV], vT) ;
if ( nTria < 1)
return false ;
// cerco indice del triangolo corrente
int nPos = - 1 ;
for ( int i = 0 ; i < int( vT.size()) ; ++ i) {
if ( vT[i] == nT) {
nPos = i ;
break ;
}
}
if ( nPos == -1)
return false ;
// medio le normali, finché non incontro degli spigoli
vtN = m_vTria[nT].vtN ;
const double COS_DEV_LIM = cos( 18 * DEGTORAD) ;
// parto dal triangolo e vado in direzione positiva
for ( int i = nPos + 1 ; i < int( vT.size()) ; ++ i) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= COS_DEV_LIM)
vtN += m_vTria[vT[i]].vtN ;
else
break ;
}
// parto dal triangolo e vado in direzione negativa
for ( int i = nPos - 1 ; i >= 0 ; -- i) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= COS_DEV_LIM)
vtN += m_vTria[vT[i]].vtN ;
else
break ;
}
vtN.Normalize() ;
return true ;
}
//----------------------------------------------------------------------------
SurfTriMesh*
SurfTriMesh::Clone( void) const
@@ -359,7 +420,7 @@ SurfTriMesh::Load( Scanner& TheScanner)
return false ;
// la divido in parametri
Tokenize( sLine, ";", vsParams) ;
// 6 parametri : Indice, Punto, IdTria, Flag
// 6 parametri : Indice, IdVertici, IdAdiacenze, Normale, TFlag, EFlag
if ( vsParams.size() != 6)
return false ;
// la interpreto e imposto il vertice
@@ -414,7 +475,7 @@ SurfTriMesh::Validate( void)
//----------------------------------------------------------------------------
bool
SurfTriMesh::FindVertexInTria( int nV, int nT, int& nK)
SurfTriMesh::FindVertexInTria( int nV, int nT, int& nK) const
{
nK = - 1 ;
for ( int k = 0 ; k < 3 ; k ++) {
@@ -428,7 +489,7 @@ SurfTriMesh::FindVertexInTria( int nV, int nT, int& nK)
//----------------------------------------------------------------------------
int
SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT)
SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT) const
{
const int MAX_VT_SIZE = 512 ;
@@ -642,6 +703,107 @@ SurfTriMesh::AdjustTopology( void)
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByTriangulation( const PolyLine& PL)
{
// eseguo la triangolazione
PNTVECTOR vPnt ;
INTVECTOR vTria ;
Triangulate Tri ;
if ( ! Tri.Make( PL, vPnt, vTria))
return false ;
// inizializzo la superficie
int nVert = int( vPnt.size()) ;
int nTria = int( vTria.size()) / 3 ;
if ( ! Init( nVert, nTria))
return false ;
// inserisco i vertici nella superficie
for ( int i = 0 ; i < int( vPnt.size()) ; ++ i) {
if ( AddVertex( vPnt[i]) == VT_NULL)
return false ;
}
// recupero i triangoli e li inserisco nella superficie
int vV[3] ;
for ( int i = 0 ; i < nTria ; ++i) {
vV[0] = vTria[3*i] ;
vV[1] = vTria[3*i+1] ;
vV[2] = vTria[3*i+2] ;
if ( AddTriangle( vV) == VT_NULL)
return false ;
}
// sistemo la topologia
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
{
// verifico che il vettore di estrusione sia non nullo
if ( vtExtr.IsSmall())
return false ;
// verifico se la polilinea è chiusa
bool bClosed = PL.IsClosed() ;
// costruisco la mesh
int nPointNbr = PL.GetPointNbr() ;
if ( ! Init( 2 * nPointNbr, 2 * nPointNbr))
return false ;
// inserisco il primo vertice della polilinea e il suo estruso
int nP = 0 ;
int nV = -1 ;
Point3d ptP ;
if ( ! PL.GetFirstPoint( ptP))
return false ;
++ nP ;
if ( AddVertex( ptP) == VT_NULL || AddVertex( ptP + vtExtr) == VT_NULL)
return false ;
nV += 2 ;
// ciclo sui punti della polilinea (per inserire vertice e suo estruso + 2 triangoli per ogni punto)
int nIdV[3] ;
while ( PL.GetNextPoint( ptP)) {
// incremento numero punto
++ nP ;
// se polilinea aperta o non è l'ultimo punto
if ( ! bClosed || nP < nPointNbr) {
// aggiungo due nuovi vertici
if ( AddVertex( ptP) == VT_NULL || AddVertex( ptP + vtExtr) == VT_NULL)
return false ;
nV += 2 ;
// aggiungo triangolo in basso a sinistra
nIdV[0] = nV - 3 ; nIdV[1] = nV - 1 ; nIdV[2] = nV - 2 ;
if ( AddTriangle( nIdV) == VT_NULL)
return false ;
// aggiungo triangolo in alto a destra
nIdV[0] = nV - 2 ; nIdV[1] = nV - 1 ; nIdV[2] = nV ;
if ( AddTriangle( nIdV) == VT_NULL)
return false ;
}
// altrimenti ultimo punto di polilinea chiusa
else {
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
// aggiungo triangolo in basso a sinistra
nIdV[0] = nV - 1 ; nIdV[1] = 0 ; nIdV[2] = nV ;
if ( AddTriangle( nIdV) == VT_NULL)
return false ;
// aggiungo triangolo in alto a destra
nIdV[0] = nV ; nIdV[1] = 0 ; nIdV[2] = 1 ;
if ( AddTriangle( nIdV) == VT_NULL)
return false ;
}
}
// sistemo la topologia
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetLocalBBox( BBox3d& b3Loc) const
@@ -852,7 +1014,7 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
bool
SurfTriMesh::ToGlob( const Frame3d& frRef)
{
// la curva deve essere validata
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
@@ -861,8 +1023,10 @@ SurfTriMesh::ToGlob( const Frame3d& frRef)
return false ;
// trasformo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i)
m_vVert[i].ptP.ToGlob( frRef) ;
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
if ( m_vVert[i].nIdTria != VT_DEL)
m_vVert[i].ptP.ToGlob( frRef) ;
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
@@ -874,7 +1038,7 @@ SurfTriMesh::ToGlob( const Frame3d& frRef)
bool
SurfTriMesh::ToLoc( const Frame3d& frRef)
{
// la curva deve essere validata
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
@@ -883,8 +1047,28 @@ SurfTriMesh::ToLoc( const Frame3d& frRef)
return false ;
// trasformo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i)
m_vVert[i].ptP.ToLoc( frRef) ;
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
if ( m_vVert[i].nIdTria != VT_DEL)
m_vVert[i].ptP.ToLoc( frRef) ;
}
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::Invert( void)
{
// la superficie deve essere validata
if ( m_nStatus != OK)
return false ;
// inverto i triangoli
for ( int i = 0 ; i < GetTriangleNum() ; ++ i)
InvertTriangle( i) ;
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;