EgtGeomKernel 1.5e6 :

- aggiunto PointGrid3d (griglia hash per ricerca spaziale veloce di punti)
- aggiunti Compacting e Sewing a SurfTriMesh
- razionalizzazioni a GdbExecutor.
This commit is contained in:
Dario Sassi
2014-05-18 09:28:31 +00:00
parent 7bcd0813f9
commit ea3099ae74
11 changed files with 731 additions and 234 deletions
+2 -2
View File
@@ -18,7 +18,7 @@
#include <stdlib.h>
//----------------------------------------------------------------------------
BBox3d::BBox3d( const Point3d ptP1, const Point3d ptP2)
BBox3d::BBox3d( const Point3d& ptP1, const Point3d& ptP2)
{
m_ptMin.Set( __min( ptP1.x, ptP2.x), __min( ptP1.y, ptP2.y), __min( ptP1.z, ptP2.z)) ;
m_ptMax.Set( __max( ptP1.x, ptP2.x), __max( ptP1.y, ptP2.y), __max( ptP1.z, ptP2.z)) ;
@@ -33,7 +33,7 @@ BBox3d::BBox3d( double dX1, double dY1, double dZ1, double dX2, double dY2, doub
//----------------------------------------------------------------------------
void
BBox3d::Set( const Point3d ptP1, const Point3d ptP2)
BBox3d::Set( const Point3d& ptP1, const Point3d& ptP2)
{
m_ptMin.Set( __min( ptP1.x, ptP2.x), __min( ptP1.y, ptP2.y), __min( ptP1.z, ptP2.z)) ;
m_ptMax.Set( __max( ptP1.x, ptP2.x), __max( ptP1.y, ptP2.y), __max( ptP1.z, ptP2.z)) ;
BIN
View File
Binary file not shown.
+2
View File
@@ -257,6 +257,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClCompile Include="NgeReader.cpp" />
<ClCompile Include="OutTsc.cpp" />
<ClCompile Include="Point3d.cpp" />
<ClCompile Include="PointGrid3d.cpp" />
<ClCompile Include="PolyLine.cpp" />
<ClCompile Include="PolynomialPoint3d.cpp" />
<ClCompile Include="stdafx.cpp">
@@ -298,6 +299,7 @@ copy $(TargetPath) \EgtProg\Dll64</Command>
<ClInclude Include="..\Include\EgkObjGraphics.h" />
<ClInclude Include="..\Include\EGkPlane3d.h" />
<ClInclude Include="..\Include\EGkPoint3d.h" />
<ClInclude Include="..\Include\EGkPointGrid3d.h" />
<ClInclude Include="..\Include\EGkPolyLine.h" />
<ClInclude Include="..\Include\EGkStringUtils3d.h" />
<ClInclude Include="..\Include\EgkSurfTriMesh.h" />
+6
View File
@@ -153,6 +153,9 @@
<ClCompile Include="GdbMaterialMgr.cpp">
<Filter>File di origine\Gdb</Filter>
</ClCompile>
<ClCompile Include="PointGrid3d.cpp">
<Filter>File di origine\Base</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="stdafx.h">
@@ -395,6 +398,9 @@
<ClInclude Include="Material.h">
<Filter>File di intestazione</Filter>
</ClInclude>
<ClInclude Include="..\Include\EGkPointGrid3d.h">
<Filter>File di intestazione</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="EgtGeomKernel.rc">
+309 -166
View File
@@ -1165,18 +1165,15 @@ GdbExecutor::CurveCompoMake( const STRVECTOR& vsParams)
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( ! IsValid( pCrvCompo))
return false ;
// per eventuale cancellazione curve di origine
bool bErase ;
INTVECTOR vnNames ;
INTVECTOR::iterator Iter ;
// 3 o 4 parametri
bool bErase ;
switch ( vsParams.size()) {
case 3 : bErase = false ; break ;
case 4 : bErase = ( vsParams[3] != "0") ; break ;
default : return false ; break ;
}
// recupero lista nomi
INTVECTOR vnNames ;
if ( ! GetNamesParam( vsParams[2], vnNames))
return false ;
// recupero il riferimento del gruppo destinazione
@@ -1184,6 +1181,7 @@ GdbExecutor::CurveCompoMake( const STRVECTOR& vsParams)
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// esecuzione
INTVECTOR::iterator Iter ;
for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) {
// recupero la curva
int nIdCrv = *Iter ;
@@ -1329,185 +1327,31 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
{
// se inizio creazione con componenti elementari
if ( sCmd2 == "BEGIN") {
// 4 parametri (2 opzionali) : Id, ParentId[, numero vertici e numero triangoli]
if ( vsParams.size() < 2)
return false ;
// recupero Id e ParentId
m_sId = vsParams[0] ;
m_sParentId = vsParams[1] ;
// recupero i parametri opzionali
int nNumVert = 3 ;
if ( vsParams.size() >= 3)
FromString( vsParams[2], nNumVert) ;
int nNumTria = 1 ;
if ( vsParams.size() >= 4)
FromString( vsParams[3], nNumTria) ;
// creo la superficie
ISurfTriMesh* pSTM = CreateSurfTriMesh() ;
if ( pSTM == nullptr)
return false ;
// la inizializzo
if ( ! pSTM->Init( nNumVert, nNumTria))
return false ;
// salvo il puntatore
if ( m_pGeoObj != nullptr)
delete m_pGeoObj ;
m_pGeoObj = pSTM ;
return true ;
return SurfTriMeshBegin( vsParams) ;
}
// se nuovo vertice
else if ( sCmd2 == "VERT" || sCmd2 == "ADDVERTEX") {
// 1 parametro : punto
if ( vsParams.size() != 1)
return false ;
// recupero il riferimento in cui va inserito
Frame3d frRef ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( m_sParentId), frRef))
return false ;
// recupero il punto
Point3d ptP ;
if ( ! GetPointParam( vsParams[0], frRef, ptP))
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// aggiungo il vertice
return ( pSTM->AddVertex( ptP) != -1) ;
return SurfTriMeshAddVertex( vsParams) ;
}
// se nuovo triangolo
else if ( sCmd2 == "TRIA" || sCmd2 == "ADDTRIANGLE") {
// 3 parametri : IdV1, IdV2, IdV3
if ( vsParams.size() != 3)
return false ;
// recupero gli indici dei 3 vertici
int nIdVert[3] ;
if ( ! FromString( vsParams[0], nIdVert[0]) ||
! FromString( vsParams[1], nIdVert[1]) ||
! FromString( vsParams[2], nIdVert[2]))
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// aggiungo il triangolo definito con gli indici dei 3 vertici
return ( pSTM->AddTriangle( nIdVert) != -1) ;
return SurfTriMeshAddTriangle( vsParams) ;
}
// se fine creazione
else if ( sCmd2 == "END") {
// nessun parametro
if ( vsParams.size() != 0)
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// valido la superficie e calcolo le adiacenze
if ( ! pSTM->AdjustTopology())
return false ;
// inserisco la superficie trimesh nel DB
m_pGeoObj = nullptr ;
bool bOk = AddGeoObj( m_sId, m_sParentId, pSTM) ;
m_sId.clear() ;
m_sParentId.clear() ;
return bOk ;
return SurfTriMeshEnd( vsParams) ;
}
// se creazione per triangolazione di un contorno chiuso e piano
else if ( sCmd2 == "CONT" || sCmd2 == "BYCONTOUR") {
// 3 o 4 parametri : Id, ParentId, IdCurve[, dLinTol]
if ( vsParams.size() != 3 && vsParams.size() != 4)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 4)
FromString( vsParams[3], dLinTol) ;
// recupero l'identificativo della curva
int nIdCrv = GetIdParam( vsParams[2]) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco la triangolazione
if ( ! pSTM->CreateByFlatContour( PL))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
return SurfTriMeshByContour( vsParams) ;
}
// se creazione per estrusione
else if ( sCmd2 == "EXTR" || sCmd2 == "BYEXTRUSION") {
// 4 o 5 parametri : Id, ParentId, IdCurve, vtExtr[, dLinTol]
if ( vsParams.size() != 4 && vsParams.size() != 5)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 5)
FromString( vsParams[4], dLinTol) ;
// recupero la curva
int nIdCrv = GetIdParam( vsParams[2]) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
return false ;
// recupero il vettore di estrusione
Vector3d vtExtr ;
if ( ! GetVectorParam( vsParams[3], frDest, vtExtr))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco l'estrusione
if ( ! pSTM->CreateByExtrusion( PL, vtExtr))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
return SurfTriMeshByExtrusion( vsParams) ;
}
// se creazione da 2 percorsi
else if ( sCmd2 == "2P" || sCmd2 == "BY2PATHS") {
// 4 o 5 parametri : Id, ParentId, IdCurve1, IdCurve2[, dLinTol]
if ( vsParams.size() != 4 && vsParams.size() != 5)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 5)
FromString( vsParams[4], dLinTol) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// recupero l'identificativo della prima curva
int nIdCrv1 = GetIdParam( vsParams[2]) ;
// calcolo la polilinea che approssima la prima curva
PolyLine PL1 ;
if ( ! GetPolylineFromCurve( nIdCrv1, frDest, dLinTol, PL1))
return false ;
// recupero l'identificativo della seconda curva
int nIdCrv2 = GetIdParam( vsParams[3]) ;
// calcolo la polilinea che approssima la seconda curva
PolyLine PL2 ;
if ( ! GetPolylineFromCurve( nIdCrv2, frDest, dLinTol, PL2))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco la rigata tra le due curve
if ( ! pSTM->CreateByTwoCurves( PL1, PL2))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
return SurfTriMeshByTwoPaths( vsParams) ;
}
// se creazione per rivoluzione
else if ( sCmd2 == "REV" || sCmd2 == "BYREVOLUTION") {
@@ -1517,10 +1361,225 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
else if ( sCmd2 == "SCR" || sCmd2 == "BYSCREWING") {
return SurfTriMeshByScrewing( true, vsParams) ;
}
// imposto angolo limite per mediare normali in un vertice
else if ( sCmd2 == "SMA" || sCmd2 == "SMOOTHANG") {
return SurfTriMeshChangeSmoothAng( vsParams) ;
}
// compattazione per unione di vertici con posizioni coincidenti
else if ( sCmd2 == "COMP" || sCmd2 == "DOCOMPACTING") {
return SurfTriMeshDoCompacting( vsParams) ;
}
// se unione di due o più superfici per cucitura
else if ( sCmd2 == "SEW" || sCmd2 == "DOSEWING") {
return SurfTriMeshDoSewing( vsParams) ;
}
else
return false ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshBegin( const STRVECTOR& vsParams)
{
// 4 parametri (2 opzionali) : Id, ParentId[, numero vertici e numero triangoli]
if ( vsParams.size() < 2)
return false ;
// recupero Id e ParentId
m_sId = vsParams[0] ;
m_sParentId = vsParams[1] ;
// recupero i parametri opzionali
int nNumVert = 3 ;
if ( vsParams.size() >= 3)
FromString( vsParams[2], nNumVert) ;
int nNumTria = 1 ;
if ( vsParams.size() >= 4)
FromString( vsParams[3], nNumTria) ;
// creo la superficie
ISurfTriMesh* pSTM = CreateSurfTriMesh() ;
if ( pSTM == nullptr)
return false ;
// la inizializzo
if ( ! pSTM->Init( nNumVert, nNumTria))
return false ;
// salvo il puntatore
if ( m_pGeoObj != nullptr)
delete m_pGeoObj ;
m_pGeoObj = pSTM ;
return true ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshAddVertex( const STRVECTOR& vsParams)
{
// 1 parametro : punto
if ( vsParams.size() != 1)
return false ;
// recupero il riferimento in cui va inserito
Frame3d frRef ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( m_sParentId), frRef))
return false ;
// recupero il punto
Point3d ptP ;
if ( ! GetPointParam( vsParams[0], frRef, ptP))
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// aggiungo il vertice
return ( pSTM->AddVertex( ptP) != -1) ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshAddTriangle( const STRVECTOR& vsParams)
{
// 3 parametri : IdV1, IdV2, IdV3
if ( vsParams.size() != 3)
return false ;
// recupero gli indici dei 3 vertici
int nIdVert[3] ;
if ( ! FromString( vsParams[0], nIdVert[0]) ||
! FromString( vsParams[1], nIdVert[1]) ||
! FromString( vsParams[2], nIdVert[2]))
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// aggiungo il triangolo definito con gli indici dei 3 vertici
return ( pSTM->AddTriangle( nIdVert) != -1) ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshEnd( const STRVECTOR& vsParams)
{
// nessun parametro
if ( vsParams.size() != 0)
return false ;
// recupero la superficie
ISurfTriMesh* pSTM = GetSurfTriMesh( m_pGeoObj) ;
if ( pSTM == nullptr)
return false ;
// valido la superficie e calcolo le adiacenze
if ( ! pSTM->AdjustTopology())
return false ;
// inserisco la superficie trimesh nel DB
m_pGeoObj = nullptr ;
bool bOk = AddGeoObj( m_sId, m_sParentId, pSTM) ;
m_sId.clear() ;
m_sParentId.clear() ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshByContour( const STRVECTOR& vsParams)
{
// 3 o 4 parametri : Id, ParentId, IdCurve[, dLinTol]
if ( vsParams.size() != 3 && vsParams.size() != 4)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 4)
FromString( vsParams[3], dLinTol) ;
// recupero l'identificativo della curva
int nIdCrv = GetIdParam( vsParams[2]) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco la triangolazione
if ( ! pSTM->CreateByFlatContour( PL))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshByExtrusion( const STRVECTOR& vsParams)
{
// 4 o 5 parametri : Id, ParentId, IdCurve, vtExtr[, dLinTol]
if ( vsParams.size() != 4 && vsParams.size() != 5)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 5)
FromString( vsParams[4], dLinTol) ;
// recupero la curva
int nIdCrv = GetIdParam( vsParams[2]) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// calcolo la polilinea che approssima la curva
PolyLine PL ;
if ( ! GetPolylineFromCurve( nIdCrv, frDest, dLinTol, PL))
return false ;
// recupero il vettore di estrusione
Vector3d vtExtr ;
if ( ! GetVectorParam( vsParams[3], frDest, vtExtr))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco l'estrusione
if ( ! pSTM->CreateByExtrusion( PL, vtExtr))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshByTwoPaths( const STRVECTOR& vsParams)
{
// 4 o 5 parametri : Id, ParentId, IdCurve1, IdCurve2[, dLinTol]
if ( vsParams.size() != 4 && vsParams.size() != 5)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 5)
FromString( vsParams[4], dLinTol) ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// recupero l'identificativo della prima curva
int nIdCrv1 = GetIdParam( vsParams[2]) ;
// calcolo la polilinea che approssima la prima curva
PolyLine PL1 ;
if ( ! GetPolylineFromCurve( nIdCrv1, frDest, dLinTol, PL1))
return false ;
// recupero l'identificativo della seconda curva
int nIdCrv2 = GetIdParam( vsParams[3]) ;
// calcolo la polilinea che approssima la seconda curva
PolyLine PL2 ;
if ( ! GetPolylineFromCurve( nIdCrv2, frDest, dLinTol, PL2))
return false ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco la rigata tra le due curve
if ( ! pSTM->CreateByTwoCurves( PL1, PL2))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams)
@@ -1624,6 +1683,90 @@ GdbExecutor::GetPolylineFromCurve( int nId, const Frame3d& frDest, double dLinTo
return true ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshChangeSmoothAng( const STRVECTOR& vsParams)
{
// 2 parametri : Id, dSmoothAngDeg
if ( vsParams.size() != 2)
return false ;
// recupero la superficie
ISurfTriMesh* pStm = GetSurfTriMesh( m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) ;
if ( pStm == nullptr)
return false ;
// recupero il valore dell'angolo
double dSmoothAng ;
if ( ! FromString( vsParams[1], dSmoothAng))
return false ;
// imposto l'angolo
pStm->SetSmoothAngle( dSmoothAng) ;
return true ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshDoCompacting( const STRVECTOR& vsParams)
{
// 1 parametro : Id
if ( vsParams.size() != 1)
return false ;
// recupero la superficie
ISurfTriMesh* pStm = GetSurfTriMesh( m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) ;
if ( pStm == nullptr)
return false ;
// eseguo la compattazione
return pStm->DoCompacting() ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::SurfTriMeshDoSewing( const STRVECTOR& vsParams)
{
// 2 o 3 parametri : Id, IdOther[, bErase]
if ( vsParams.size() != 2 && vsParams.size() != 3)
return false ;
// eventuale flag per cancellazione delle superfici cucite alla prima
bool bErase = false ;
if ( vsParams.size() >= 3 && vsParams[2] != "0")
bErase = true ;
// recupero la prima superficie
int nIdStm = GetIdParam( vsParams[0]) ;
ISurfTriMesh* pStm = GetSurfTriMesh( m_pGDB->GetGeoObj( nIdStm)) ;
if ( pStm == nullptr)
return false ;
// ne recupero il riferimento
Frame3d frStm ;
if ( ! m_pGDB->GetGlobFrame( nIdStm, frStm))
return false ;
// recupero lista nomi delle altre superfici
INTVECTOR vnNames ;
if ( ! GetNamesParam( vsParams[1], vnNames))
return false ;
// esecuzione
INTVECTOR::iterator Iter ;
for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) {
// recupero la superficie da cucire
const ISurfTriMesh* pStmS = GetSurfTriMesh( m_pGDB->GetGeoObj( *Iter)) ;
if ( pStmS == nullptr)
return false ;
// recupero il riferimento
Frame3d frStmS ;
if ( ! m_pGDB->GetGlobFrame( *Iter, frStmS))
return false ;
// lo esprimo rispetto a quello della prima superficie
frStmS.ToLoc( frStm) ;
// eseguo la cucitura
if ( ! pStm->DoSewing( *pStmS, frStm))
return false ;
}
// se richiesto, cancello le superfici cucite alla prima
if ( bErase) {
for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter)
m_pGDB->Erase( *Iter) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::AddGeoObj( const string& sId, const string& sIdParent, IGeoObj* pGeoObj)
+10
View File
@@ -77,7 +77,17 @@ class GdbExecutor : public IGdbExecutor
bool CurveCompoFromSplit( const STRVECTOR& vsParams) ;
bool CurveCompoAddCurve( const STRVECTOR& vsParams) ;
bool ExecuteSurfTriMesh( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool SurfTriMeshBegin( const STRVECTOR& vsParams) ;
bool SurfTriMeshAddVertex( const STRVECTOR& vsParams) ;
bool SurfTriMeshAddTriangle( const STRVECTOR& vsParams) ;
bool SurfTriMeshEnd( const STRVECTOR& vsParams) ;
bool SurfTriMeshByContour( const STRVECTOR& vsParams) ;
bool SurfTriMeshByExtrusion( const STRVECTOR& vsParams) ;
bool SurfTriMeshByTwoPaths( const STRVECTOR& vsParams) ;
bool SurfTriMeshByScrewing( bool bMove, const STRVECTOR& vsParams) ;
bool SurfTriMeshChangeSmoothAng( const STRVECTOR& vsParams) ;
bool SurfTriMeshDoCompacting( const STRVECTOR& vsParams) ;
bool SurfTriMeshDoSewing( const STRVECTOR& vsParams) ;
bool ExecuteLevel( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteMode( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteStatus( const std::string& sCmd2, const STRVECTOR& vsParams) ;
+7 -1
View File
@@ -35,4 +35,10 @@ static const double ANG_TOL_STD_DEG = 15 ;
//----------------- Costanti per archi come curve di Bezier ------------------
// massimo angolo al centro di un arco espresso tramite curva di Bezier
static const double BEZARC_ANG_CEN_MAX = 90 ;
static const double BEZARC_ANG_CEN_MAX = 90 ;
//----------------- Costanti per superfici TriMesh ---------------------------
// tolleranza lineare standard
static const double STM_STD_LIN_TOL = 0.1 ;
// angolo limite per mediare le normali in un vertice
static const double STM_STD_SMOOTH_ANG = 25.0 ;
+1 -1
View File
@@ -21,7 +21,7 @@
// versione
const int NGE_MAJOR_VER = 1 ;
const int NGE_MINOR_VER = 5 ;
const int NGE_PATCH_VER = 5 ;
const int NGE_PATCH_VER = 6 ;
// nome GDB
const std::string NGE_GEOMDB = "GeomDB" ;
// indici KeyWord
+111
View File
@@ -0,0 +1,111 @@
//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : PointGrid3d.cpp Data : 15.05.14 Versione : 1.5e5
// Contenuto : Implementazione della classe PointGrid3d.
// Indicizzazione spaziale di Point3d mediante hash grid.
//
//
// Modifiche : 15.05.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "\EgtDev\Include\EGkPointGrid3d.h"
#include <utility>
using namespace std ;
//----------------------------------------------------------------------------
bool
PointGrid3d::Init( int nBuckets, double dCellDim)
{
m_dCellDim = dCellDim ;
m_MMap.rehash( nBuckets) ;
return true ;
}
//----------------------------------------------------------------------------
bool
PointGrid3d::InsertPoint( const Point3d& ptP, int nId)
{
int nKey = PointHash( Get1dCellNbr( ptP.x), Get1dCellNbr( ptP.y), Get1dCellNbr( ptP.z)) ;
m_MMap.insert( make_pair( nKey, make_pair( ptP, nId))) ;
return true ;
}
//----------------------------------------------------------------------------
bool
PointGrid3d::Find( const Point3d& ptTest, double dTol, INTVECTOR& vnIds)
{
// ricavo gli indici sui tre assi degli estremi del box
int nXmin = Get1dCellNbr( ptTest.x - dTol) ;
int nXmax = Get1dCellNbr( ptTest.x + dTol) ;
int nYmin = Get1dCellNbr( ptTest.y - dTol) ;
int nYmax = Get1dCellNbr( ptTest.y + dTol) ;
int nZmin = Get1dCellNbr( ptTest.z - dTol) ;
int nZmax = Get1dCellNbr( ptTest.z + dTol) ;
// pulisco il risultato
vnIds.clear() ;
// ciclo su tutte le celle comprese tra gli estremi
for ( int i = nXmin ; i <= nXmax ; ++ i) {
for ( int j = nYmin ; j <= nYmax ; ++ j) {
for ( int k = nZmin ; k <= nZmax ; ++ k) {
pair<IPNTI_UMMAP::iterator, IPNTI_UMMAP::iterator> MMrange =
m_MMap.equal_range( PointHash( i, j, k)) ;
for ( ; MMrange.first != MMrange.second ; ++ MMrange.first) {
if ( SqDist( (*MMrange.first).second.first, ptTest) < ( dTol * dTol))
vnIds.push_back( (*MMrange.first).second.second) ;
}
}
}
}
return ( vnIds.size() > 0) ;
}
//----------------------------------------------------------------------------
bool
PointGrid3d::Find( const Point3d& ptTest, double dTol, int& nId)
{
// ricavo gli indici sui tre assi degli estremi del box
int nXmin = Get1dCellNbr( ptTest.x - dTol) ;
int nXmax = Get1dCellNbr( ptTest.x + dTol) ;
int nYmin = Get1dCellNbr( ptTest.y - dTol) ;
int nYmax = Get1dCellNbr( ptTest.y + dTol) ;
int nZmin = Get1dCellNbr( ptTest.z - dTol) ;
int nZmax = Get1dCellNbr( ptTest.z + dTol) ;
// ciclo su tutte le celle comprese tra gli estremi
for ( int i = nXmin ; i <= nXmax ; ++ i) {
for ( int j = nYmin ; j <= nYmax ; ++ j) {
for ( int k = nZmin ; k <= nZmax ; ++ k) {
pair<IPNTI_UMMAP::iterator, IPNTI_UMMAP::iterator> MMrange =
m_MMap.equal_range( PointHash( i, j, k)) ;
for ( ; MMrange.first != MMrange.second ; ++ MMrange.first) {
if ( SqDist( (*MMrange.first).second.first, ptTest) < ( dTol * dTol)) {
nId = (*MMrange.first).second.second ;
return true ;
}
}
}
}
}
return false ;
}
//----------------------------------------------------------------------------
int
PointGrid3d::Get1dCellNbr( double dCoord)
{
return static_cast<int>( floor( dCoord / m_dCellDim)) ;
}
//----------------------------------------------------------------------------
int
PointGrid3d::PointHash( int nX, int nY, int nZ)
{
return ( nX * 73856093 ^ nY * 19349663 ^ nZ * 83492791) ;
}
+256 -54
View File
@@ -19,7 +19,9 @@
#include "NgeReader.h"
#include "DistPointLine.h"
#include "Triangulate.h"
#include "GeoConst.h"
#include "\EgtDev\Include\EGkStringUtils3d.h"
#include "\EgtDev\Include\EGkPointGrid3d.h"
#include "\EgtDev\Include\EGkPolyLine.h"
#include <new>
@@ -30,8 +32,9 @@ GEOOBJ_REGISTER( SRF_TRIMESH, NGE_S_TRM, SurfTriMesh) ;
//----------------------------------------------------------------------------
SurfTriMesh::SurfTriMesh( void)
: m_nStatus( TO_VERIFY), m_bClosed( false)
: m_nStatus( TO_VERIFY), m_dLinTol( STM_STD_LIN_TOL), m_dSmoothAng( STM_STD_SMOOTH_ANG), m_bClosed( false)
{
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
}
//----------------------------------------------------------------------------
@@ -169,6 +172,34 @@ SurfTriMesh::SetTriangle( int nInd, const StmTria& tT)
return true ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::GetVertexNum( void) const
{
// calcolo il numero dei vertici cancellati
int nErased = 0 ;
for ( int nId = 0 ; nId < GetVertexSize() ; ++ nId) {
if ( m_vVert[nId].nIdTria == SVT_DEL)
++ nErased ;
}
return ( GetVertexSize() - nErased) ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::GetTriangleNum( void) const
{
// calcolo il numero dei triangoli cancellati
int nErased = 0 ;
for ( int nId = 0 ; nId < GetTriangleSize() ; ++ nId) {
if ( m_vTria[nId].nIdVert[0] == SVT_DEL)
++ nErased ;
}
return ( GetTriangleSize() - nErased) ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::GetFirstVertex( Point3d& ptP) const
@@ -183,9 +214,9 @@ SurfTriMesh::GetNextVertex( int nId, Point3d& ptP) const
// cerco il primo successivo valido
do {
nId ++ ;
} while ( nId < GetVertexNum() && m_vVert[nId].nIdTria == SVT_DEL) ;
} while ( nId < GetVertexSize() && m_vVert[nId].nIdTria == SVT_DEL) ;
// se oltrepassata fine
if ( nId >= GetVertexNum())
if ( nId >= GetVertexSize())
return SVT_NULL ;
// recupero i dati
ptP = m_vVert[nId].ptP ;
@@ -207,9 +238,9 @@ SurfTriMesh::GetNextTriangle( int nId, Triangle3d& Tria) const
// cerco il primo successivo valido
do {
nId ++ ;
} while ( nId < GetTriangleNum() && m_vTria[nId].nIdVert[0] == SVT_DEL) ;
} while ( nId < GetTriangleSize() && m_vTria[nId].nIdVert[0] == SVT_DEL) ;
// se oltrepassata fine
if ( nId >= GetTriangleNum())
if ( nId >= GetTriangleSize())
return SVT_NULL ;
// recupero i dati
Tria.Set( m_vVert[m_vTria[nId].nIdVert[0]].ptP,
@@ -225,7 +256,7 @@ bool
SurfTriMesh::GetTriangleSmoothNormals( int nId, TriNormals3d& TNrms) const
{
// verifico esistenza del triangolo
if ( nId >= GetTriangleNum() || m_vTria[nId].nIdVert[0] == SVT_DEL)
if ( nId >= GetTriangleSize() || m_vTria[nId].nIdVert[0] == SVT_DEL)
return false ;
// recupero le normali di ciascun vertice
@@ -261,13 +292,12 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
// medio le normali, finché non incontro degli spigoli
vtN = m_vTria[nT].vtN ;
const double COS_DEV_LIM = cos( 22.5 * DEGTORAD) ;
// parto dal triangolo e vado in direzione positiva
int nLim = nPos ;
for ( int i = NextIndAroundVertex( nPos, nTria, bCirc) ;
i != nPos && i < int( vT.size()) ;
i = NextIndAroundVertex( i, nTria, bCirc)) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= COS_DEV_LIM)
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
vtN += m_vTria[vT[i]].vtN ;
else
break ;
@@ -277,26 +307,11 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
for ( int i = PrevIndAroundVertex( nPos, nTria, bCirc) ;
i != nLim && i >= 0 ;
i = PrevIndAroundVertex( i, nTria, bCirc)) {
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= COS_DEV_LIM)
if ( m_vTria[vT[nPos]].vtN * m_vTria[vT[i]].vtN >= m_dCosSmAng)
vtN += m_vTria[vT[i]].vtN ;
else
break ;
}
//// 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 ;
@@ -334,11 +349,14 @@ SurfTriMesh::Copy( const SurfTriMesh& stmSrc)
{
if ( &stmSrc == this)
return true ;
if ( ! Init( stmSrc.GetVertexNum(), stmSrc.GetTriangleNum()))
if ( ! Init( stmSrc.GetVertexSize(), stmSrc.GetTriangleSize()))
return false ;
m_vVert = stmSrc.m_vVert ;
m_vTria = stmSrc.m_vTria ;
m_bClosed = stmSrc.m_bClosed ;
m_dLinTol = stmSrc.m_dLinTol ;
m_dSmoothAng = stmSrc.m_dSmoothAng ;
m_dCosSmAng = stmSrc.m_dCosSmAng ;
m_nStatus = stmSrc.m_nStatus ;
return true ;
}
@@ -363,11 +381,13 @@ bool
SurfTriMesh::Dump( string& sOut, const char* szNewLine) const
{
// se superficie aperta o chiusa
sOut += ( m_bClosed ? "Closed" : "Open") ;
sOut += ( m_bClosed ? "Closed" : "Open") + string( szNewLine) ;
// numero di vertici
sOut += " VertNbr=" + ToString( GetVertexNum()) ;
sOut += "Vert : Nbr=" + ToString( GetVertexNum()) +
" Size=" + ToString( GetVertexSize()) + szNewLine ;
// numero di triangoli
sOut += " TriaNbr=" + ToString( GetTriangleNum()) ;
sOut += "Tria : Nbr=" + ToString( GetTriangleNum()) +
" Size=" + ToString( GetTriangleSize()) + szNewLine ;
return true ;
}
@@ -383,12 +403,16 @@ SurfTriMesh::GetNgeId( void) const
bool
SurfTriMesh::Save( NgeWriter& ngeOut) const
{
// tolleranza lineare di costruzione
ngeOut.WriteDouble( m_dLinTol, ";") ;
// angolo limite per mediare le normali
ngeOut.WriteDouble( m_dSmoothAng, ";", true) ;
// flag aperta/chiusa
ngeOut.WriteBool( m_bClosed, ";") ;
// numero di vertici
ngeOut.WriteInt( GetVertexNum(), ";") ;
ngeOut.WriteInt( GetVertexSize(), ";") ;
// numero di triangoli
ngeOut.WriteInt( GetTriangleNum(), ";", true) ;
ngeOut.WriteInt( GetTriangleSize(), ";", true) ;
// ciclo sui vertici
for ( int i = 0 ; i < int( m_vVert.size()) ; ++ i) {
ngeOut.WriteInt( i, ";") ;
@@ -419,6 +443,15 @@ SurfTriMesh::Load( NgeReader& ngeIn)
{
// imposto ricalcolo della grafica
m_OGrMgr.Reset() ;
// leggo la prossima linea ( 2 parametri : dLinTol e dSmoothAng)
// tolleranza lineare di costruzione
double dLinTol ;
if ( ! ngeIn.ReadDouble( dLinTol, ";"))
return false ;
// angolo limite per mediare le normali
double dSmoothAng ;
if ( ! ngeIn.ReadDouble( dSmoothAng, ";", true))
return false ;
// leggo la prossima linea ( 3 parametri : flag chiuso num vertici e num tria)
// recupero il flag
bool bClosed ;
@@ -432,10 +465,13 @@ SurfTriMesh::Load( NgeReader& ngeIn)
int nNumTria ;
if ( ! ngeIn.ReadInt( nNumTria, ";", true))
return false ;
// inizializzo la superficie TriMesh
// preparo la superficie
if ( ! Init( nNumVert, nNumTria))
return false ;
m_bClosed = bClosed ;
m_dLinTol = dLinTol ;
m_dSmoothAng = dSmoothAng ;
m_dCosSmAng = cos( dSmoothAng * DEGTORAD) ;
// lettura dei vertici
int nInd ;
StmVert vV ;
@@ -480,12 +516,12 @@ SurfTriMesh::Validate( void)
// Verifico che i vertici riferiti dai triangoli esistano
m_nStatus = OK ;
for ( int i = 0 ; i < GetTriangleNum() && m_nStatus == OK ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() && m_nStatus == OK ; ++ i) {
// se triangolo non cancellato
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
for ( int j = 0 ; j < 3 && m_nStatus == OK ; ++ j) {
if ( m_vTria[i].nIdVert[j] < 0 ||
m_vTria[i].nIdVert[j] >= GetVertexNum() ||
m_vTria[i].nIdVert[j] >= GetVertexSize() ||
m_vVert[ m_vTria[i].nIdVert[j]].nIdTria == SVT_DEL)
m_nStatus = ERR ;
}
@@ -496,11 +532,11 @@ SurfTriMesh::Validate( void)
}
// Verifico che i triangoli riferiti dai vertici esistano
for ( int i = 0 ; i < GetVertexNum() && m_nStatus == OK ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() && m_nStatus == OK ; ++ i) {
// se vertice non cancellato e con riferimento assegnato
if ( m_vVert[i].nIdTria != SVT_DEL && m_vVert[i].nIdTria != SVT_NULL) {
if ( m_vVert[i].nIdTria < SVT_DEL ||
m_vVert[i].nIdTria >= GetTriangleNum() ||
m_vVert[i].nIdTria >= GetTriangleSize() ||
m_vTria[ m_vVert[i].nIdTria].nIdVert[0] == SVT_DEL)
m_nStatus = ERR ;
}
@@ -604,7 +640,7 @@ bool
SurfTriMesh::AdjustAdjacencies( void)
{
// sistemo i puntatori dai vertici ai triangoli
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
// se triangolo non cancellato
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
for ( int j = 0 ; j < 3 ; ++ j) {
@@ -618,7 +654,7 @@ SurfTriMesh::AdjustAdjacencies( void)
bool bModif ;
do {
bModif = false ;
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
// se triangolo non cancellato
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
for ( int j = 0 ; j < 3 ; ++ j) {
@@ -686,7 +722,7 @@ SurfTriMesh::AdjustOrientations( int nLev, bool& bSomeWrong)
// inizializzo parametro di ritorno
bSomeWrong = false ;
// ciclo sui triangoli
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
// flags
int nNull = 0 ;
int nWrong = 0 ;
@@ -727,7 +763,7 @@ SurfTriMesh::TestClosure( void)
{
// ciclo sui triangoli
bool bClosed = true ;
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
if ( m_vTria[i].nIdAdjac[0] == SVT_NULL ||
m_vTria[i].nIdAdjac[1] == SVT_NULL ||
m_vTria[i].nIdAdjac[2] == SVT_NULL)
@@ -812,6 +848,10 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
if ( PL.GetPointNbr() < 2)
return false ;
// imposto ricalcolo
m_nStatus = ERR ;
m_OGrMgr.Reset() ;
// verifico se la polilinea è chiusa
bool bClosed = PL.IsClosed() ;
@@ -856,6 +896,7 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
}
// sistemo la topologia
m_nStatus = TO_VERIFY ;
return AdjustTopology() ;
}
@@ -866,6 +907,11 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2)
// verifico validità polilinee (devono avere almeno 2 punti e non coincidere se non agli estremi aperti)
if ( ! VerifyPolylinesForTwoCurves( PL1, PL2))
return false ;
// imposto ricalcolo
m_nStatus = ERR ;
m_OGrMgr.Reset() ;
// flag di curve chiuse
bool bClosed = PL1.IsClosed() && PL2.IsClosed() ;
// recupero i parametri delle due polilinee
@@ -1022,6 +1068,7 @@ SurfTriMesh::CreateByTwoCurves( const PolyLine& PL1, const PolyLine& PL2)
}
// sistemo la topologia
m_nStatus = TO_VERIFY ;
return AdjustTopology() ;
}
@@ -1150,6 +1197,10 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
return false ;
}
// imposto ricalcolo
m_nStatus = ERR ;
m_OGrMgr.Reset() ;
// verifico se la polilinea è chiusa
bool bClosed = PL.IsClosed() ;
@@ -1287,6 +1338,7 @@ SurfTriMesh::CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Ve
}
// sistemo la topologia
m_nStatus = TO_VERIFY ;
return AdjustTopology() ;
}
@@ -1375,6 +1427,156 @@ SurfTriMesh::AddBiTriangle( const int nIdVert[4])
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::DoCompacting( void)
{
// imposto ricalcolo
m_nStatus = ERR ;
m_OGrMgr.Reset() ;
// definisco un Grid per i vertici della superficie
PointGrid3d VertGrid ;
int nBuckets = GetVertexSize() ;
VertGrid.Init( nBuckets) ;
// inserisco i vertici della trimesh (evitando ripetizioni coi precedenti),
// salvando in un vettore di reindirizzo i nuovi Id
INTVECTOR vVId ;
vVId.reserve( GetVertexSize()) ;
for ( int nId = 0 ; nId < GetVertexSize() ; ++ nId) {
// salto i vertici cancellati (ma ne occupo il posto nel vettore di reindirizzo)
if ( m_vVert[nId].nIdTria == SVT_DEL) {
vVId.push_back( SVT_DEL) ;
continue ;
}
// recupero la posizione geometrica del vertice
Point3d ptP = m_vVert[nId].ptP ;
// se non c'è già un vertice con la stessa posizione lo inserisco nel grid
int nAliasId ;
if ( ! VertGrid.Find( ptP, 2 * EPS_SMALL, nAliasId)) {
VertGrid.InsertPoint( ptP, nId) ;
// salvo l'Id nel vettore di reindirizzo
vVId.push_back( nId) ;
}
// c'e un vertice coincidente
else {
// salvo l'Id alias nel vettore di reindirizzo
vVId.push_back( nAliasId) ;
// marco il vertice come cancellato
m_vVert[nId].nIdTria = SVT_DEL ;
}
}
int nVIdSize = int( vVId.size()) ;
// sistemo gli indici dei vertici nei triangoli
for ( int nId = 0 ; nId < GetTriangleSize() ; ++ nId) {
// recupero gli indici dei vertici del triangolo
int vOId[3] ;
vOId[0] = m_vTria[nId].nIdVert[0] ;
vOId[1] = m_vTria[nId].nIdVert[1] ;
vOId[2] = m_vTria[nId].nIdVert[2] ;
// salto i triangoli cancellati
if ( vOId[0] == SVT_DEL)
continue ;
// verifico la validità degli indici
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
vOId[2] < 0 || vOId[2] >= nVIdSize)
return false ;
// aggiorno il triangolo
m_vTria[nId].nIdVert[0] = vVId[vOId[0]] ;
m_vTria[nId].nIdVert[1] = vVId[vOId[1]] ;
m_vTria[nId].nIdVert[2] = vVId[vOId[2]] ;
}
// ricalcolo le adiacenze
m_nStatus = TO_VERIFY ;
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther)
{
// recupero l'altra superficie
const SurfTriMesh* pOther = dynamic_cast<const SurfTriMesh*>( &stmOther) ;
if ( pOther == nullptr)
return false ;
// imposto ricalcolo
m_nStatus = ERR ;
m_OGrMgr.Reset() ;
// definisco un Grid per i vertici delle due superfici
PointGrid3d VertGrid ;
int nBuckets = GetVertexSize() + pOther->GetVertexSize() ;
VertGrid.Init( nBuckets) ;
// inserisco i vertici della trimesh corrente (li considero tutti diversi tra loro)
for ( int nId = 0 ; nId < GetVertexSize() ; ++ nId) {
// salto i vertici cancellati
if ( m_vVert[nId].nIdTria == SVT_DEL)
continue ;
// inserisco il vertice nella griglia
VertGrid.InsertPoint( m_vVert[nId].ptP, nId) ;
}
// inserisco i vertici dell'altra trimesh (evitando ripetizioni coi precedenti),
// salvando in un vettore di reindirizzo i nuovi Id
INTVECTOR vVId ;
vVId.reserve( pOther->GetVertexSize()) ;
for ( int nOId = 0 ; nOId < pOther->GetVertexSize() ; ++ nOId) {
// salto i vertici cancellati (ma ne occupo il posto nel vettore di reindirizzo)
if ( pOther->m_vVert[nOId].nIdTria == SVT_DEL) {
vVId.push_back( SVT_DEL) ;
continue ;
}
// recupero la posizione geometrica del vertice
Point3d ptOP = pOther->m_vVert[nOId].ptP ;
// la porto nel riferimento della prima superficie
ptOP.ToGlob( frOther) ;
// se non c'è già un vertice con la stessa posizione lo inserisco
int nNewId ;
if ( ! VertGrid.Find( ptOP, 2 * EPS_SMALL, nNewId)) {
if ( ( nNewId = AddVertex( ptOP)) == SVT_NULL)
return false ;
VertGrid.InsertPoint( ptOP, nNewId) ;
}
// salvo il nuovo Id nel vettore di reindirizzo
vVId.push_back( nNewId) ;
}
int nVIdSize = int( vVId.size()) ;
// inserisco i triangoli dell'altra trimesh
for ( int nOtId = 0 ; nOtId < pOther->GetTriangleSize() ; ++ nOtId) {
// recupero gli indici dei vertici del triangolo
int vOId[3] ;
vOId[0] = pOther->m_vTria[nOtId].nIdVert[0] ;
vOId[1] = pOther->m_vTria[nOtId].nIdVert[1] ;
vOId[2] = pOther->m_vTria[nOtId].nIdVert[2] ;
// salto i triangoli cancellati
if ( vOId[0] == SVT_DEL)
continue ;
// verifico la validità degli indici
if ( vOId[0] < 0 || vOId[0] >= nVIdSize ||
vOId[1] < 0 || vOId[1] >= nVIdSize ||
vOId[2] < 0 || vOId[2] >= nVIdSize)
return false ;
int vId[3] ;
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 ;
}
// ricalcolo le adiacenze
m_nStatus = TO_VERIFY ;
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetLocalBBox( BBox3d& b3Loc) const
@@ -1384,7 +1586,7 @@ SurfTriMesh::GetLocalBBox( BBox3d& b3Loc) const
return false ;
// assegno il box in locale
b3Loc.Reset() ;
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
b3Loc.Add( m_vVert[i].ptP) ;
}
@@ -1403,7 +1605,7 @@ SurfTriMesh::GetBBox( const Frame3d& frRef, BBox3d& b3Ref) const
return false ;
// assegno il box nel riferimento
b3Ref.Reset() ;
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL) {
Point3d ptTemp = m_vVert[i].ptP ;
ptTemp.ToGlob( frRef) ;
@@ -1426,7 +1628,7 @@ SurfTriMesh::Translate( const Vector3d& vtMove)
m_OGrMgr.Reset() ;
// traslo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
m_vVert[i].ptP.Translate( vtMove) ;
}
@@ -1450,13 +1652,13 @@ SurfTriMesh::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng,
m_OGrMgr.Reset() ;
// ruoto i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
m_vVert[i].ptP.Rotate( ptAx, vtAx, dCosAng, dSinAng) ;
}
// ruoto le normali delle facce
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
if ( m_vTria[i].nIdVert[0] != SVT_DEL)
m_vTria[i].vtN.Rotate( vtAx, dCosAng, dSinAng) ;
}
@@ -1485,13 +1687,13 @@ SurfTriMesh::Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double
m_OGrMgr.Reset() ;
// scalo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
m_vVert[i].ptP.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
}
// aggiorno le facce
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
// se c'è mirror, devo invertire la faccia
if ( bMirror && ! InvertTriangle( i))
@@ -1530,13 +1732,13 @@ SurfTriMesh::CalcTriangleNormal( int nT)
return false ;
// controllo validità vertici riferiti dal triangolo
if ( m_vTria[nT].nIdVert[0] < 0 ||
m_vTria[nT].nIdVert[0] >= GetVertexNum() ||
m_vTria[nT].nIdVert[0] >= GetVertexSize() ||
m_vVert[m_vTria[nT].nIdVert[0]].nIdTria == SVT_DEL ||
m_vTria[nT].nIdVert[1] < 0 ||
m_vTria[nT].nIdVert[1] >= GetVertexNum() ||
m_vTria[nT].nIdVert[1] >= GetVertexSize() ||
m_vVert[m_vTria[nT].nIdVert[1]].nIdTria == SVT_DEL ||
m_vTria[nT].nIdVert[2] < 0 ||
m_vTria[nT].nIdVert[2] >= GetVertexNum() ||
m_vTria[nT].nIdVert[2] >= GetVertexSize() ||
m_vVert[m_vTria[nT].nIdVert[2]].nIdTria == SVT_DEL)
return false ;
// calcolo vettori come due lati consecutivi del triangolo
@@ -1566,11 +1768,11 @@ SurfTriMesh::Mirror( const Point3d& ptOn, const Vector3d& vtNorm)
m_OGrMgr.Reset() ;
// specchio i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i)
for ( int i = 0 ; i < GetVertexSize() ; ++ i)
m_vVert[i].ptP.Mirror( ptOn, vtNorm) ;
// inverto le facce
for ( int i = 0 ; i < GetTriangleNum() ; ++ i) {
for ( int i = 0 ; i < GetTriangleSize() ; ++ i) {
if ( m_vTria[i].nIdVert[0] != SVT_DEL) {
// inverto la faccia
if ( ! InvertTriangle( i))
@@ -1597,7 +1799,7 @@ SurfTriMesh::ToGlob( const Frame3d& frRef)
return false ;
// trasformo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
m_vVert[i].ptP.ToGlob( frRef) ;
}
@@ -1621,7 +1823,7 @@ SurfTriMesh::ToLoc( const Frame3d& frRef)
return false ;
// trasformo i vertici
for ( int i = 0 ; i < GetVertexNum() ; ++ i) {
for ( int i = 0 ; i < GetVertexSize() ; ++ i) {
if ( m_vVert[i].nIdTria != SVT_DEL)
m_vVert[i].ptP.ToLoc( frRef) ;
}
@@ -1641,7 +1843,7 @@ SurfTriMesh::Invert( void)
return false ;
// inverto i triangoli
for ( int i = 0 ; i < GetTriangleNum() ; ++ i)
for ( int i = 0 ; i < GetTriangleSize() ; ++ i)
InvertTriangle( i) ;
// imposto ricalcolo della grafica
+27 -10
View File
@@ -92,8 +92,14 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
public : // ISurfTriMesh
virtual bool Copy( const IGeoObj* pGObjSrc) ;
virtual bool Init( int nNumVert, int nNumTria) ;
virtual int AddVertex( const Point3d& ptVert) ;
virtual int AddTriangle( const int nIdVert[3]) ;
virtual void SetLinearTolerance( double dLinTol)
{ m_dLinTol = std::max( dLinTol, EPS_SMALL) ; }
virtual void SetSmoothAngle( double dSmoothAngDeg)
{ m_dSmoothAng = std::max( dSmoothAngDeg, EPS_ANG_SMALL) ;
m_dCosSmAng = cos( m_dSmoothAng * DEGTORAD) ;
m_OGrMgr.Reset() ; }
virtual int AddVertex( const Point3d& ptVert) ;
virtual int AddTriangle( const int nIdVert[3]) ;
virtual bool AdjustTopology( void) ;
virtual bool CreateByFlatContour( const PolyLine& PL) ;
virtual bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) ;
@@ -102,14 +108,22 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
double dAngRot, double dStepRot) ;
virtual bool CreateByScrewing( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
double dAngRot, double dStepRot, double dMove) ;
virtual int GetVertexNum( void) const
{ return int( m_vVert.size()) ; }
virtual int GetTriangleNum( void) const
{ return int( m_vTria.size()) ; }
virtual int GetFirstVertex( Point3d& ptP) const ;
virtual int GetNextVertex( int nId, Point3d& ptP) const ;
virtual int GetFirstTriangle( Triangle3d& Tria) const ;
virtual int GetNextTriangle( int nId, Triangle3d& Tria) const ;
virtual bool DoCompacting( void) ;
virtual bool DoSewing( const ISurfTriMesh& stmOther, const Frame3d& frOther = GLOB_FRM) ;
virtual int GetVertexNum( void) const ;
virtual int GetTriangleNum( void) const ;
virtual int GetVertexSize( void) const
{ return int( m_vVert.size()) ; }
virtual int GetTriangleSize( void) const
{ return int( m_vTria.size()) ; }
virtual double GetLinearTolerance( void)
{ return m_dLinTol ; }
virtual double GetSmoothAngle( void)
{ return m_dSmoothAng ; }
virtual int GetFirstVertex( Point3d& ptP) const ;
virtual int GetNextVertex( int nId, Point3d& ptP) const ;
virtual int GetFirstTriangle( Triangle3d& Tria) const ;
virtual int GetNextTriangle( int nId, Triangle3d& Tria) const ;
virtual bool GetTriangleSmoothNormals( int nId, TriNormals3d& TNrms) const ;
public : // IGeoObjRW
@@ -157,6 +171,9 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
private :
ObjGraphicsMgr m_OGrMgr ; // gestore grafica dell'oggetto
Status m_nStatus ; // stato
double m_dLinTol ; // tolleranza lineare di costruzione
double m_dSmoothAng ; // angolo limite per mediare le normali (in gradi)
double m_dCosSmAng ; // coseno dell'angolo precedente
bool m_bClosed ; // la superficie racchiude un volume
VERTVECTOR m_vVert ; // vettore dei vertici
TRIAVECTOR m_vTria ; // vettore dei triangoli