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:
+6
-1
@@ -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) ;
|
||||
|
||||
|
||||
Binary file not shown.
+232
-83
@@ -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 ;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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} ;
|
||||
|
||||
Reference in New Issue
Block a user