EgtGeomKernel 1.5e1 :

- in TriMesh migliorato lo smooth delle normali
- in TriMesh aggiunta generazione per rivoluzione
- migliorati gestione e aggiornamento materiali.
This commit is contained in:
Dario Sassi
2014-05-02 06:57:24 +00:00
parent e080543b97
commit 1b767fe58e
12 changed files with 621 additions and 110 deletions
+6 -1
View File
@@ -34,7 +34,12 @@ class DistPointLine
public :
bool GetSqDist( double& dSqDist) ;
bool GetDist( double& dDist) ;
int GetNbrMinDist( void) { return (( m_dSqDist < 0) ? 0 : 1) ; }
bool IsSmall( void)
{ double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < EPS_SMALL * EPS_SMALL) ; }
bool IsZero( void)
{ double dSqDist ; return ( GetSqDist( dSqDist) && dSqDist < EPS_ZERO * EPS_ZERO) ; }
int GetNbrMinDist( void)
{ return (( m_dSqDist < 0) ? 0 : 1) ; }
bool GetMinDistPoint( Point3d& ptMinDist) ;
bool GetParamAtMinDistPoint( double& dParam) ;
BIN
View File
Binary file not shown.
+232 -83
View File
@@ -16,6 +16,7 @@
#include "stdafx.h"
#include "GdbExecutor.h"
#include "GdbIterator.h"
#include "GeoConst.h"
#include "GeomDB.h"
#include "DllMain.h"
#include "/EgtDev/Include/EgnStringUtils.h"
@@ -589,6 +590,24 @@ GdbExecutor::ExecuteCurveBez( const string& sCmd2, const STRVECTOR& vsParams)
//----------------------------------------------------------------------------
bool
GdbExecutor::ExecuteCurveCompo( const string& sCmd2, const STRVECTOR& vsParams)
{
// creazione generica
if ( sCmd2 == "" || sCmd2 == "MAKE")
return CurveCompoMake( vsParams) ;
// creazione da split di curva semplice
else if ( sCmd2 == "S" || sCmd2 == "FROMSPLIT")
return CurveCompoFromSplit( vsParams) ;
// modifica per aggiunta di una curva
else if ( sCmd2 == "ADD" || sCmd2 == "ADDCURVE")
return CurveCompoAddCurve( vsParams) ;
// altrimenti errore
else
return false ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::CurveCompoMake( const STRVECTOR& vsParams)
{
// creo la curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
@@ -599,92 +618,50 @@ GdbExecutor::ExecuteCurveCompo( const string& sCmd2, const STRVECTOR& vsParams)
INTVECTOR vnNames ;
INTVECTOR::iterator Iter ;
// curva composita generica
if ( sCmd2 == "" || sCmd2 == "MAKE") {
// 3 o 4 parametri
switch ( vsParams.size()) {
case 3 : bErase = false ; break ;
case 4 : bErase = ( vsParams[3] != "0") ; break ;
default : return false ; break ;
}
// recupero lista nomi
if ( ! GetNamesParam( vsParams[2], vnNames))
return false ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// esecuzione
for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) {
// recupero la curva
int nIdCrv = *Iter ;
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
if ( pCrv == nullptr)
return false ;
// recupero il riferimento della curva
Frame3d frSou ;
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frSou))
return false ;
// se i riferimenti sono uguali
if ( AreSameFrame( frSou, frDest)) {
// aggiungo direttamente questa curva
if ( ! pCrvCompo->AddCurve( *pCrv))
return false ;
}
// altrimenti devo prima trasformare la curva
else {
// creo una copia della curva (da buttare alla fine)
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
if ( ! IsValid( pModCrv))
return false ;
// eseguo la trasformazione
pModCrv->ToGlob( frSou) ;
pModCrv->ToLoc( frDest) ;
// aggiungo la curva modificata
if ( ! pCrvCompo->AddCurve( *pModCrv))
return false ;
}
}
// 3 o 4 parametri
switch ( vsParams.size()) {
case 3 : bErase = false ; break ;
case 4 : bErase = ( vsParams[3] != "0") ; break ;
default : return false ; break ;
}
// da split di curva semplice
else if ( sCmd2 == "S" || sCmd2 == "FROMSPLIT") {
// 4 o 5 parametri
switch ( vsParams.size()) {
case 4 : bErase = false ; break ;
case 5 : bErase = ( vsParams[4] != "0") ; break ;
default : return false ; break ;
}
// salvo nome curva originale per eventuale cancellazione
int nIdCrv = GetIdParam( vsParams[2]) ;
vnNames.push_back( nIdCrv) ;
// recupero lista nomi
if ( ! GetNamesParam( vsParams[2], vnNames))
return false ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// esecuzione
for ( Iter = vnNames.begin() ; Iter != vnNames.end() ; ++Iter) {
// recupero la curva
int nIdCrv = *Iter ;
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
if ( pCrv == nullptr)
return false ;
// recupero il numero delle parti in cui spezzare
int nParts ;
if ( ! FromString( vsParams[3], nParts))
return false ;
// ne deduco la curva composita
if ( ! pCrvCompo->FromSplit( *pCrv, nParts))
return false ;
// recupero il riferimento della curva
Frame3d frSou ;
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frSou))
return false ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// porto la curva composita dal riferimento della sorgente a quello di inserimento
if ( ! AreSameFrame( frSou, frDest)) {
pCrvCompo->ToGlob( frSou) ;
pCrvCompo->ToLoc( frDest) ;
// se i riferimenti sono uguali
if ( AreSameFrame( frSou, frDest)) {
// aggiungo direttamente questa curva
if ( ! pCrvCompo->AddCurve( *pCrv))
return false ;
}
// altrimenti devo prima trasformare la curva
else {
// creo una copia della curva (da buttare alla fine)
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
if ( ! IsValid( pModCrv))
return false ;
// eseguo la trasformazione
pModCrv->ToGlob( frSou) ;
pModCrv->ToLoc( frDest) ;
// aggiungo la curva modificata
if ( ! pCrvCompo->AddCurve( *pModCrv))
return false ;
}
}
// altrimenti errore
else
return false ;
// inserisco la curva composita nel DB
if ( AddGeoObj( vsParams[0], vsParams[1], Release( pCrvCompo))) {
@@ -701,6 +678,99 @@ GdbExecutor::ExecuteCurveCompo( const string& sCmd2, const STRVECTOR& vsParams)
return false ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::CurveCompoFromSplit( const STRVECTOR& vsParams)
{
// per eventuale cancellazione curva di origine
bool bErase ;
// 4 o 5 parametri
switch ( vsParams.size()) {
case 4 : bErase = false ; break ;
case 5 : bErase = ( vsParams[4] != "0") ; break ;
default : return false ; break ;
}
// creo la curva composita
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
if ( ! IsValid( pCrvCompo))
return false ;
// salvo nome curva originale per eventuale cancellazione
int nIdCrv = GetIdParam( vsParams[2]) ;
// recupero la curva
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
if ( pCrv == nullptr)
return false ;
// recupero il numero delle parti in cui spezzare
int nParts ;
if ( ! FromString( vsParams[3], nParts))
return false ;
// ne deduco la curva composita
if ( ! pCrvCompo->FromSplit( *pCrv, nParts))
return false ;
// recupero il riferimento della curva
Frame3d frSou ;
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frSou))
return false ;
// recupero il riferimento del gruppo destinazione
Frame3d frDest ;
if ( ! m_pGDB->GetGroupGlobFrame( GetIdParam( vsParams[1]), frDest))
return false ;
// porto la curva composita dal riferimento della sorgente a quello di inserimento
if ( ! AreSameFrame( frSou, frDest)) {
pCrvCompo->ToGlob( frSou) ;
pCrvCompo->ToLoc( frDest) ;
}
// inserisco la curva composita nel DB
if ( AddGeoObj( vsParams[0], vsParams[1], Release( pCrvCompo))) {
// se richiesto, cancello la curva originale
if ( bErase) {
if ( ! m_pGDB->Erase( nIdCrv))
return false ;
}
return true ;
}
else
return false ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::CurveCompoAddCurve( const STRVECTOR& vsParams)
{
// per eventuale cancellazione curva da accodare
bool bErase ;
// 2 o 3 parametri ( IdCurveCompo, IdCurveToAdd[, bEraseCurveToAdd])
switch ( vsParams.size()) {
case 2 : bErase = false ; break ;
case 3 : bErase = ( vsParams[2] != "0") ; break ;
default : return false ; break ;
}
// recupero la curva composita
ICurveComposite* pCrvComp = GetCurveComposite( m_pGDB->GetGeoObj( GetIdParam( vsParams[0]))) ;
if ( pCrvComp == nullptr)
return false ;
// salvo nome curva da accodare per eventuale cancellazione
int nIdCrv = GetIdParam( vsParams[1]) ;
// recupero la curva
const ICurve* pCrvToAdd = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
if ( pCrvToAdd == nullptr)
return false ;
// eseguo l'accodamento
if ( ! pCrvComp->AddCurve( *pCrvToAdd))
return false ;
// se richiesto, elimino la curva accodata
if ( bErase) {
if ( ! m_pGDB->Erase( nIdCrv))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
@@ -780,9 +850,13 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
}
// se creazione per triangolazione di un contorno chiuso e piano
else if ( sCmd2 == "CONT" || sCmd2 == "BYCONTOUR") {
// 3 parametri : Id, ParentId, IdCurve
if ( vsParams.size() != 3)
// 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() == 5)
FromString( vsParams[3], dLinTol) ;
// recupero la curva
int nIdCrv = GetIdParam( vsParams[2]) ;
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
@@ -801,7 +875,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
// se i riferimenti sono uguali
if ( AreSameFrame( frCrv, frDest)) {
// ricavo l'approssimazione
if ( ! pCrv->ApproxWithLines( 0.01, 15, PL))
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// altrimenti devo prima trasformare la curva
@@ -814,7 +888,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
pModCrv->ToGlob( frCrv) ;
pModCrv->ToLoc( frDest) ;
// ricavo l'approssimazione
if ( ! pModCrv->ApproxWithLines( 0.01, 15, PL))
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// creo la superficie
@@ -829,9 +903,13 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
}
// se creazione per estrusione
else if ( sCmd2 == "EXTR" || sCmd2 == "BYEXTRUSION") {
// 4 parametri : Id, ParentId, IdCurve, vtExtr
if ( vsParams.size() != 4)
// 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]) ;
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
@@ -850,7 +928,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
// se i riferimenti sono uguali
if ( AreSameFrame( frCrv, frDest)) {
// ricavo l'approssimazione
if ( ! pCrv->ApproxWithLines( 0.01, 15, PL))
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// altrimenti devo prima trasformare la curva
@@ -863,7 +941,7 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
pModCrv->ToGlob( frCrv) ;
pModCrv->ToLoc( frDest) ;
// ricavo l'approssimazione
if ( ! pModCrv->ApproxWithLines( 0.01, 15, PL))
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// recupero il vettore di estrusione
@@ -880,6 +958,77 @@ GdbExecutor::ExecuteSurfTriMesh( const string& sCmd2, const STRVECTOR& vsParams)
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
}
// se creazione per rivoluzione
else if ( sCmd2 == "REV" || sCmd2 == "BYREVOLUTION") {
// 6 o 7 parametri : Id, ParentId, IdCurve, ptRev, vtRev, dAngRot[, dLinTol]
if ( vsParams.size() != 6 && vsParams.size() != 7)
return false ;
// recupero la tolleranza lineare
double dLinTol = LIN_TOL_STD ;
if ( vsParams.size() == 7)
FromString( vsParams[6], dLinTol) ;
// recupero la curva
int nIdCrv = GetIdParam( vsParams[2]) ;
const ICurve* pCrv = GetCurve( m_pGDB->GetGeoObj( nIdCrv)) ;
if ( pCrv == nullptr)
return false ;
// recupero il riferimento della curva
Frame3d frCrv ;
if ( ! m_pGDB->GetGlobFrame( nIdCrv, frCrv))
return false ;
// 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 ;
// se i riferimenti sono uguali
if ( AreSameFrame( frCrv, frDest)) {
// ricavo l'approssimazione
if ( ! pCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// altrimenti devo prima trasformare la curva
else {
// creo una copia della curva (da buttare alla fine)
PtrOwner<ICurve> pModCrv( GetCurve( pCrv->Clone())) ;
if ( ! IsValid( pModCrv))
return false ;
// eseguo la trasformazione
pModCrv->ToGlob( frCrv) ;
pModCrv->ToLoc( frDest) ;
// ricavo l'approssimazione
if ( ! pModCrv->ApproxWithLines( dLinTol, ANG_TOL_STD_DEG, PL))
return false ;
}
// recupero il punto dell'asse di rivoluzione
Point3d ptAx ;
if ( ! GetPointParam( vsParams[3], ptAx))
return false ;
// recupero il vettore dell'asse di rivoluzione
Vector3d vtAx ;
if ( ! GetVectorParam( vsParams[4], vtAx))
return false ;
// recupero l'angolo di rotazione
double dAngRotDeg ;
if ( ! FromString( vsParams[5], dAngRotDeg))
return false ;
// calcolo lo step di rotazione
double dMaxRad = 0 ;
PL.GetMaxDistanceFromLine( dMaxRad, ptAx, vtAx, 1, false) ;
if ( dMaxRad < EPS_SMALL)
return false ;
double dStepRotDeg = sqrt( 8 * dLinTol / dMaxRad) * RADTODEG ;
// creo la superficie
PtrOwner<ISurfTriMesh> pSTM( CreateSurfTriMesh()) ;
if ( ! IsValid( pSTM))
return false ;
// costruisco la rivoluzione
if ( ! pSTM->CreateByRevolution( PL, ptAx, vtAx, dAngRotDeg, dStepRotDeg))
return false ;
// inserisco la superficie trimesh nel DB
return AddGeoObj( vsParams[0], vsParams[1], Release( pSTM)) ;
}
else
return false ;
}
+3
View File
@@ -51,6 +51,9 @@ class GdbExecutor : public IGdbExecutor
bool ExecuteCurveArc( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteCurveBez( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteCurveCompo( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool CurveCompoMake( const STRVECTOR& vsParams) ;
bool CurveCompoFromSplit( const STRVECTOR& vsParams) ;
bool CurveCompoAddCurve( const STRVECTOR& vsParams) ;
bool ExecuteSurfTriMesh( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteLevel( const std::string& sCmd2, const STRVECTOR& vsParams) ;
bool ExecuteMode( const std::string& sCmd2, const STRVECTOR& vsParams) ;
+2 -2
View File
@@ -202,7 +202,7 @@ GdbMaterialMgr::FindMaterial( const string& sName) const
//----------------------------------------------------------------------------
bool
GdbMaterialMgr::GetMaterial( int nId, Material& matM) const
GdbMaterialMgr::GetMaterialData( int nId, Material& matM) const
{
if ( ! ExistsMaterial( nId))
return false ;
@@ -235,7 +235,7 @@ GdbMaterialMgr::IsCustomMaterial( int nId, bool& bCustom) const
//----------------------------------------------------------------------------
bool
GdbMaterialMgr::ModifyMaterial( int nId, const Material& matM)
GdbMaterialMgr::ModifyMaterialData( int nId, const Material& matM)
{
if ( ! ExistsMaterial( nId))
return false ;
+2 -2
View File
@@ -35,10 +35,10 @@ class GdbMaterialMgr
{ return int( m_GdbMats.size()) ; }
bool ExistsMaterial( int nId) const
{ return ( nId > GDB_MT_NULL && nId <= int( m_GdbMats.size()) && ! m_GdbMats[nId-1].sName.empty()) ; }
bool GetMaterial( int nId, Material& matM) const ;
bool GetMaterialData( int nId, Material& matM) const ;
bool GetMaterialName( int nId, std::string& sName) const ;
bool IsCustomMaterial( int nId, bool& bCustom) const ;
bool ModifyMaterial( int nId, const Material& matM) ;
bool ModifyMaterialData( int nId, const Material& matM) ;
bool ModifyMaterialName( int nId, const std::string& sName) ;
private :
+7 -3
View File
@@ -19,15 +19,19 @@
//----------------- Costanti per approssimazioni con polilinee ---------------
// tolleranza lineare minima in approssimazioni lineari
const double LIN_TOL_MIN = 0.01 ;
const double LIN_TOL_MIN = 0.001 ;
// deviazione angolare minima (in gradi) in approssimazioni lineari
const double ANG_TOL_MIN_DEG = 0.1 ;
// deviazione angolare massima (in gradi) in approssimazioni lineari esterne
const double ANG_TOL_EXT_MAX_DEG = 90 ;
// tolleranza lineare standard in approssimazioni lineari
// tolleranza lineare comune in approssimazioni lineari
static const double LIN_TOL_APPROX = 1 ;
// deviazione angolare standard (in gradi) in approssimazioni lineari
// deviazione angolare comune (in gradi) in approssimazioni lineari
static const double ANG_TOL_APPROX_DEG = 45 ;
// tolleranza lineare standard
static const double LIN_TOL_STD = 0.1 ;
// deviazione angolare standard (in gradi)
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
+17 -7
View File
@@ -1408,7 +1408,7 @@ GeomDB::SetMaterial( GdbObj* pGdbObj, const string& sMatName)
// recupero il materiale per assegnare anche il colore
Material mMat ;
GetMaterial( nIdMat, mMat) ;
GetMaterialData( nIdMat, mMat) ;
// assegno il materiale tramite indice
return ( pGdbObj->SetMaterial( mMat.GetDiffuse()) &&
@@ -1580,7 +1580,7 @@ GeomDB::UsedMaterialInGroup( int nMat, const GdbGroup* pGdbGroup) const
//----------------------------------------------------------------------------
bool
GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, bool bByParent, GdbGroup* pGdbGroup)
GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, Color cCol, bool bByParent, GdbGroup* pGdbGroup)
{
// verifico se il gruppo utilizza direttamente il materiale
int nObjMat ;
@@ -1589,6 +1589,11 @@ GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, bool bByParent, GdbGroup* pG
nObjMat = GDB_MT_PARENT ;
// se il materiale è usato dal gruppo
bByParent = ( nObjMat == nMat || ( nObjMat == GDB_MT_PARENT && bByParent)) ;
// eventuale aggiornamento del colore
if ( nObjMat == nMat) {
pGdbGroup->SetMaterial( cCol) ;
pGdbGroup->SetMaterial( nMat) ;
}
// scandisco il gruppo
bool bOk = true ;
for ( GdbObj* pGdbObj = pGdbGroup->GetFirstObj() ;
@@ -1597,7 +1602,7 @@ GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, bool bByParent, GdbGroup* pG
// se sottogruppo, devo cercare nei suoi figli
GdbGroup* pGdbSubGrp ;
if ( ( pGdbSubGrp = ::GetGdbGroup( pGdbObj)) != nullptr) {
if ( ! NotifyObjectsWithMaterialInGroup( nMat, bByParent, pGdbSubGrp))
if ( ! NotifyObjectsWithMaterialInGroup( nMat, cCol, bByParent, pGdbSubGrp))
bOk = false ;
}
// altrimenti oggetto
@@ -1611,6 +1616,11 @@ GeomDB::NotifyObjectsWithMaterialInGroup( int nMat, bool bByParent, GdbGroup* pG
if ( ! pGdbObj->OnSetMaterial())
bOk = false ;
}
// eventuale aggiornamento del colore
if ( nObjMat == nMat) {
pGdbObj->SetMaterial( cCol) ;
pGdbObj->SetMaterial( nMat) ;
}
}
}
@@ -1739,7 +1749,7 @@ GeomDB::EraseMaterial( int nMat, bool& bInUse)
bool
GeomDB::GetMaterialData( int nMat, Material& matM) const
{
return m_MatManager.GetMaterial( nMat, matM) ;
return m_MatManager.GetMaterialData( nMat, matM) ;
}
//----------------------------------------------------------------------------
@@ -1774,10 +1784,10 @@ GeomDB::IsCustomMaterial( int nMat, bool& bCustom) const
bool
GeomDB::ModifyMaterialData( int nMat, const Material& matM)
{
if ( ! m_MatManager.ModifyMaterial( nMat, matM))
if ( ! m_MatManager.ModifyMaterialData( nMat, matM))
return false ;
// notifico gli oggetti che usano questo materiale
NotifyObjectsWithMaterialInGroup( nMat, false, &m_GrpRadix) ;
// notifico gli oggetti che usano questo materiale (e gli aggiorno il colore)
NotifyObjectsWithMaterialInGroup( nMat, matM.GetDiffuse(), false, &m_GrpRadix) ;
return true ;
}
+1 -1
View File
@@ -160,7 +160,7 @@ class GeomDB : public IGeomDB
bool GetMaterial( const GdbObj* pGdbObj, Material& mMat) const ;
bool GetCalcMaterial( const GdbObj* pGdbObj, Material& mMat) const ;
bool UsedMaterialInGroup( int nMat, const GdbGroup* pGdbGroup) const ;
bool NotifyObjectsWithMaterialInGroup( int nMat, bool bByParent, GdbGroup* pGdbGroup) ;
bool NotifyObjectsWithMaterialInGroup( int nMat, Color cCol, bool bByParent, GdbGroup* pGdbGroup) ;
bool AddGdbIteratorToList( GdbIterator* pIter)
{ return m_IterManager.AddGdbIterator( pIter) ; }
bool RemoveGdbIteratorFromList( GdbIterator* pIter)
+22
View File
@@ -13,6 +13,7 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DistPointLine.h"
#include "\EgtDev\Include\EGkPolyLine.h"
#include "\EgtDev\Include\EGkPlane3d.h"
@@ -289,3 +290,24 @@ PolyLine::IsPlanar( Plane3d& plPlane, double dToler) const
// All points passed distance test, so polygon is considered planar
return true ;
}
//----------------------------------------------------------------------------
bool
PolyLine::GetMaxDistanceFromLine( double& dMaxDist, const Point3d& ptAx,
const Vector3d& vtAx, double dLen, bool bIsSegment) const
{
// Verifico che la polilinea esista
if ( GetPointNbr() < 1)
return false ;
// Calcolo la distanza di ogni punto dalla linea
dMaxDist = 0 ;
Point3d ptP ;
for ( bool bFound = GetFirstPoint( ptP) ; bFound ; bFound = GetNextPoint( ptP)) {
DistPointLine dstPL( ptP, ptAx, vtAx, dLen, bIsSegment) ;
double dDist ;
if ( dstPL.GetDist( dDist) && dDist > dMaxDist)
dMaxDist = dDist ;
}
return true ;
}
+322 -10
View File
@@ -17,6 +17,7 @@
#include "GeoObjFactory.h"
#include "NgeWriter.h"
#include "NgeReader.h"
#include "DistPointLine.h"
#include "Triangulate.h"
#include "\EgtDev\Include\EGkStringUtils3d.h"
#include "\EgtDev\Include\EGkPolyLine.h"
@@ -225,8 +226,9 @@ bool
SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
{
// recupero tutti i triangoli attorno al vertice
bool bCirc ;
INTVECTOR vT ;
int nTria = GetAllTriaAroundVertex( m_vTria[nT].nIdVert[nV], vT) ;
int nTria = GetAllTriaAroundVertex( m_vTria[nT].nIdVert[nV], vT, bCirc) ;
if ( nTria < 1)
return false ;
@@ -241,23 +243,44 @@ SurfTriMesh::GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const
if ( nPos == -1)
return false ;
// medio le normali, finché non incontro degli spigoli
// medio le normali, finché non incontro degli spigoli
vtN = m_vTria[nT].vtN ;
const double COS_DEV_LIM = cos( 18 * DEGTORAD) ;
const double COS_DEV_LIM = cos( 22.5 * DEGTORAD) ;
// parto dal triangolo e vado in direzione positiva
for ( int i = nPos + 1 ; i < int( vT.size()) ; ++ i) {
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)
vtN += m_vTria[vT[i]].vtN ;
else
break ;
nLim = i ;
}
// parto dal triangolo e vado in direzione negativa
for ( int i = nPos - 1 ; i >= 0 ; -- i) {
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)
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 ;
@@ -486,7 +509,7 @@ SurfTriMesh::FindVertexInTria( int nV, int nT, int& nK) const
//----------------------------------------------------------------------------
int
SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT) const
SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT, bool& bCirc) const
{
const int MAX_VT_SIZE = 512 ;
@@ -516,8 +539,10 @@ SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT) const
} while ( nTa != nT && nTa != SVT_NULL && vT.size() < MAX_VT_SIZE) ;
// se sono ritornato al triangolo di partenza ho fatto un giro e concluso la ricerca
if ( nTa == nT)
if ( nTa == nT) {
bCirc = true ;
return int( vT.size()) ;
}
// altrimenti, devo cercare i triangoli adiacenti con lo stesso vertice in CW
nTa = nT ;
@@ -534,9 +559,30 @@ SurfTriMesh::GetAllTriaAroundVertex( int nV, INTVECTOR& vT) const
vT.insert( vT.begin(), nTa) ;
} while ( nTa != nT && nTa != SVT_NULL && vT.size() < MAX_VT_SIZE) ;
bCirc = ( nTa == nT) ;
return int( vT.size()) ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::NextIndAroundVertex( int nInd, int nSize, bool bCirc) const
{
nInd = nInd + 1 ;
if ( bCirc && nInd >= nSize)
nInd = nInd % nSize ;
return nInd ;
}
//----------------------------------------------------------------------------
int
SurfTriMesh::PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const
{
nInd = nInd - 1 ;
if ( bCirc && nInd < 0)
nInd = ( nInd + nSize) % nSize ;
return nInd ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::AdjustAdjacencies( void)
@@ -567,10 +613,11 @@ SurfTriMesh::AdjustAdjacencies( void)
int nVf = m_vTria[i].nIdVert[Next(j)] ;
// indice altro vertice in altro triangolo
int k ;
int nN ;
int nN ;
bool bCirc ;
INTVECTOR vT ;
// triangoli con il vertice all'inizio dello half-edge
nN = GetAllTriaAroundVertex( nVi, vT) ;
nN = GetAllTriaAroundVertex( nVi, vT, bCirc) ;
for ( int l = 0 ; l < nN ; ++ l) {
int nTi = vT[l] ;
if ( nTi != i) {
@@ -589,7 +636,7 @@ SurfTriMesh::AdjustAdjacencies( void)
}
}
// triangoli con il vertice alla fine dello half-edge
nN = GetAllTriaAroundVertex( nVf, vT) ;
nN = GetAllTriaAroundVertex( nVf, vT, bCirc) ;
for ( int l = 0 ; l < nN ; ++ l) {
int nTf = vT[l] ;
if ( nTf != i) {
@@ -801,6 +848,271 @@ SurfTriMesh::CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr)
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
double dAngRot, double dStepRot)
{
// verifico che l'asse di rotazione sia non nullo
if ( vtAx.IsSmall())
return false ;
// verifico che l'angolo di rotazione sia significativo e non superi un giro
if ( fabs( dAngRot) < EPS_ANG_SMALL)
return false ;
if ( fabs( dAngRot) > ANG_FULL)
dAngRot = _copysign( ANG_FULL, dAngRot) ;
// verifico se rotazione completa
bool bFullRev = ( fabs( fabs( dAngRot) - ANG_FULL) < EPS_ANG_SMALL) ;
// aggiusto il valore dell'angolo di step
const double MIN_STEP_ROT = 1 ;
const double MAX_STEP_ROT = 90 ;
if ( fabs( dStepRot) < MIN_STEP_ROT)
dStepRot = _copysign( MIN_STEP_ROT, dAngRot) ;
else if ( fabs( dStepRot) > MAX_STEP_ROT)
dStepRot = _copysign( MAX_STEP_ROT, dAngRot) ;
else
dStepRot = _copysign( dStepRot, dAngRot) ;
// calcolo il numero di step
int nStep = int( dAngRot / dStepRot) ;
nStep = max( nStep, 1) ;
dStepRot = dAngRot / nStep ;
if ( bFullRev)
-- nStep ;
// verifico che la polilinea non attraversi l'asse di rivoluzione o lo tocchi in punti interni
if ( ! VeryfyPolylineForRevolution( PL, ptAx, vtAx)) {
LOG_ERROR( GetEGkLogger(), "StmCreateByRevolution : polyline inside meets axis")
return false ;
}
// verifico se la polilinea è chiusa
bool bClosed = PL.IsClosed() ;
// costruisco la mesh
int nPointNbr = PL.GetPointNbr() ;
if ( ! Init( ( 1 + nStep) * nPointNbr, ( 1 + nStep) * nPointNbr))
return false ;
// inserisco il primo punto della polilinea e i suoi ruotati
int nP = 0 ;
int nV = -1 ;
Point3d ptP ;
// recupero il punto
if ( ! PL.GetFirstPoint( ptP))
return false ;
++ nP ;
// inserisco il primo vertice
if ( AddVertex( ptP) == SVT_NULL)
return false ;
++ nV ;
// verifico se il punto giace sull'asse
bool bPrevOnAx = DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
int nVPrevOnAx = nV ;
// se non è sull'asse, inserisco le copie ruotate
if ( ! bPrevOnAx) {
for ( int i = 1 ; i <= nStep ; ++i) {
ptP.Rotate( ptAx, vtAx, dStepRot * DEGTORAD) ;
if ( AddVertex( ptP) == SVT_NULL)
return false ;
++ nV ;
}
}
// ciclo sui punti della polilinea (per inserire vertice e suoi ruotati + 2 triangoli per ogni punto)
int nIdV[4] ;
while ( PL.GetNextPoint( ptP)) {
// incremento numero punto
++ nP ;
// se polilinea aperta o non è l'ultimo punto
if ( ! bClosed || nP < nPointNbr) {
// aggiungo il primo vertice
if ( AddVertex( ptP) == SVT_NULL)
return false ;
++ nV ;
// verifico se il punto giace sull'asse
bool bOnAx = DistPointLine( ptP, ptAx, vtAx, 1, false).IsSmall() ;
// ciclo sugli step
for ( int i = 1 ; i <= nStep ; ++i) {
// se non è sull'asse, inserisco le copie ruotate
if ( ! bOnAx) {
ptP.Rotate( ptAx, vtAx, dStepRot * DEGTORAD) ;
if ( AddVertex( ptP) == SVT_NULL)
return false ;
++ nV ;
}
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
// se il precedente è sull'asse, aggiungo un solo triangolo
if ( bPrevOnAx) {
nIdV[0] = nVPrevOnAx ;
nIdV[1] = nV ;
nIdV[2] = nV - 1 ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// se il corrente è sull'asse, aggiungo un solo triangolo
else if ( bOnAx) {
nIdV[0] = nV - ( nStep + 2) + i ;
nIdV[1] = nIdV[0] + 1 ;
nIdV[2] = nV ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// altrimenti aggiungo due triangoli
else {
nIdV[0] = nV - ( nStep + 2) ;
nIdV[1] = nIdV[0] + 1 ;
nIdV[2] = nV ;
nIdV[3] = nV - 1 ;
if ( ! AddBiTriangle( nIdV))
return false ;
}
}
// se rivoluzione completa, aggiungo i due triangoli di chiusura
if ( bFullRev) {
// per i controlli già fatti non è possibile avere contemp. prec e corr su asse
// se il precedente è sull'asse, aggiungo un solo triangolo
if ( bPrevOnAx) {
nIdV[0] = nVPrevOnAx ;
nIdV[1] = nV - nStep ;
nIdV[2] = nV ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// se il corrente è sull'asse, aggiungo un solo triangolo
else if ( bOnAx) {
nIdV[0] = nV - 1 ;
nIdV[1] = nV - ( nStep + 1) ;
nIdV[2] = nV ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// altrimenti aggiungo due triangoli
else {
nIdV[0] = nV - ( nStep + 1) ;
nIdV[1] = nV - ( 2 * nStep + 1) ;
nIdV[2] = nV - nStep ;
nIdV[3] = nV ;
if ( ! AddBiTriangle( nIdV))
return false ;
}
}
bPrevOnAx = false ;
}
// altrimenti ultimo punto di polilinea chiusa
else {
for ( int i = 1 ; i <= nStep ; ++i) {
// non devo aggiungere i vertici, perchè coincidono con quelli iniziali
// aggiungo triangolo in basso a sinistra
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = nV - nStep + i ; nIdV[2] = i ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
// aggiungo triangolo in alto a destra
nIdV[0] = nV - nStep + i - 1 ; nIdV[1] = i ; nIdV[2] = i - 1 ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// se rivoluzione completa, aggiungo i due triangoli di chiusura
if ( bFullRev) {
// aggiungo triangolo in basso a sinistra
nIdV[0] = nV ; nIdV[1] = nV - nStep ; nIdV[2] = 0 ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
// aggiungo triangolo in alto a destra
nIdV[0] = nV ; nIdV[1] = 0 ; nIdV[2] = nStep ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
}
}
// sistemo la topologia
return AdjustTopology() ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::VeryfyPolylineForRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx) const
{
// calcolo un riferimento con origine ptAx e asseZ vtAx
Frame3d frAx ;
if ( ! frAx.Set( ptAx, vtAx))
return false ;
// numero di segmenti della polilinea
int nTotSeg = PL.GetLineNbr() ;
// flag di chiusa
bool bClosed = PL.IsClosed() ;
// recupero il primo punto e lo porto nel riferimento Ax e quindi lo proietto su XY
Point3d ptPp ;
if ( ! PL.GetFirstPoint( ptPp))
return false ;
ptPp.ToLoc( frAx) ;
ptPp.z = 0 ;
// calcolo la distanza tra i segmenti della polilinea portati nel piano XY del rif Ax e l'origine
int nSeg = 0 ;
Point3d ptPc ;
while ( PL.GetNextPoint( ptPc)) {
// punto corrente
ptPc.ToLoc( frAx) ;
ptPc.z = 0 ;
++ nSeg ;
// verifico distanza
if ( DistPointLine( ORIG, ptPp, ptPc).IsSmall()) {
if ( bClosed ||
( ! ( nSeg == 1 && AreSamePointNear( ORIG, ptPp)) &&
! ( nSeg == nTotSeg && AreSamePointNear( ORIG, ptPc))))
return false ;
}
// salvo punto
ptPp = ptPc ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::AddBiTriangle( const int nIdVert[4])
{
// 0 <- 3
// | |
// 1 -> 2
int nIdV[3] ;
// se la diagonale 0->2 è più corta della 1->3
if ( SqDist( m_vVert[nIdVert[0]].ptP, m_vVert[nIdVert[2]].ptP) <=
SqDist( m_vVert[nIdVert[1]].ptP, m_vVert[nIdVert[3]].ptP)) {
// triangolo 0->1->2
nIdV[0] = nIdVert[0] ;
nIdV[1] = nIdVert[1] ;
nIdV[2] = nIdVert[2] ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
// triangolo 0->2->3
nIdV[0] = nIdVert[0] ;
nIdV[1] = nIdVert[2] ;
nIdV[2] = nIdVert[3] ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
// altrimenti uso la 1->3
else {
// triangolo 0->1->3
nIdV[0] = nIdVert[0] ;
nIdV[1] = nIdVert[1] ;
nIdV[2] = nIdVert[3] ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
// triangolo 1->2->3
nIdV[0] = nIdVert[1] ;
nIdV[1] = nIdVert[2] ;
nIdV[2] = nIdVert[3] ;
if ( AddTriangle( nIdV) == SVT_NULL)
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
SurfTriMesh::GetLocalBBox( BBox3d& b3Loc) const
+7 -1
View File
@@ -97,6 +97,8 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
virtual bool AdjustTopology( void) ;
virtual bool CreateByTriangulation( const PolyLine& PL) ;
virtual bool CreateByExtrusion( const PolyLine& PL, const Vector3d& vtExtr) ;
virtual bool CreateByRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx,
double dAngRot, double dStepRot) ;
virtual int GetVertexNum( void) const
{ return int( m_vVert.size()) ; }
virtual int GetTriangleNum( void) const
@@ -134,8 +136,12 @@ class SurfTriMesh : public ISurfTriMesh, public IGeoObjRW
int Prev( int i) const
{ return (( i + 2) % 3) ; }
bool FindVertexInTria( int nV, int nT, int& nK) const ;
int GetAllTriaAroundVertex( int nV, INTVECTOR& vT) const ;
int GetAllTriaAroundVertex( int nV, INTVECTOR& vT, bool& bCirc) const ;
int NextIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
int PrevIndAroundVertex( int nInd, int nSize, bool bCirc) const ;
bool GetTriangleSmoothNormal( int nT, int nV, Vector3d& vtN) const ;
bool VeryfyPolylineForRevolution( const PolyLine& PL, const Point3d& ptAx, const Vector3d& vtAx) const ;
bool AddBiTriangle( const int nIdVert[4]) ;
private :
enum Status { ERR = 0, OK = 1, TO_VERIFY = 2} ;