EgtMachKernel 1.9c3 :

- tagli di lama ora possono operare su facce di trimesh
- migliorato recupero contorni da facce.
This commit is contained in:
Dario Sassi
2018-03-14 11:00:18 +00:00
parent 1427b57169
commit 47036161c8
13 changed files with 359 additions and 496 deletions
+166 -103
View File
@@ -25,6 +25,7 @@
#include "/EgtDev/Include/EGkChainCurves.h"
#include "/EgtDev/Include/EGkDistPointCurve.h"
#include "/EgtDev/Include/EGkSfrCreate.h"
#include "/EgtDev/Include/EGkSurfTriMesh.h"
#include "/EgtDev/Include/EGkUserObjFactory.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
@@ -402,23 +403,19 @@ Sawing::SetGeometry( const SELVECTOR& vIds)
// reset della geometria corrente
m_vId.clear() ;
// verifico che gli identificativi rappresentino delle entità ammissibili
int nType = GEO_NONE ;
for ( const auto& Id : vIds) {
// test sull'entità
int nSubs ;
if ( ! VerifyGeometry( Id, nSubs)) {
if ( ! VerifyGeometry( Id, nSubs, nType)) {
string sOut = "Warning in Sawing : Skipped entity " + ToString( Id) ;
LOG_INFO( GetEMkLogger(), sOut.c_str()) ;
continue ;
}
// posso aggiungere alla lista
if ( nSubs == 0)
m_vId.emplace_back( Id) ;
else {
for ( int i = 0 ; i < nSubs ; ++ i)
m_vId.emplace_back( Id.nId, i) ;
}
m_vId.emplace_back( Id) ;
}
return ( ! m_vId.empty()) ;
return ( ! m_vId.empty() || vIds.empty()) ;
}
//----------------------------------------------------------------------------
@@ -811,31 +808,58 @@ Sawing::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP) const
//----------------------------------------------------------------------------
bool
Sawing::VerifyGeometry( SelData Id, int& nSubs)
Sawing::VerifyGeometry( SelData Id, int& nSubs, int& nType)
{
// ammessi : curve o facce di polymesh
// per ora accetto solo curve
const ICurve* pCurve = nullptr ;
// ammessi : tutte curve o tutte facce di trimesh
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ;
// se direttamente la curva
if ( Id.nSub == SEL_SUB_ALL) {
pCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pCurve != nullptr) {
if ( pCurve->GetType() == CRV_COMPO)
nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ;
else
nSubs = 0 ;
if ( pGObj == nullptr)
return false ;
// se ammesse curve ed è tale
if ( nType != GEO_SURF && ( pGObj->GetType() & GEO_CURVE) != 0) {
const ICurve* pCurve = nullptr ;
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ;
// se direttamente la curva
if ( Id.nSub == SEL_SUB_ALL) {
pCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pCurve != nullptr) {
if ( pCurve->GetType() == CRV_COMPO)
nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ;
else
nSubs = 0 ;
}
}
// altrimenti sottocurva di composita
else {
const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pCompo != nullptr)
pCurve = pCompo->GetCurve( Id.nSub) ;
nSubs = 0 ;
}
return ( pCurve != nullptr) ;
}
// se altrimenti ammesse superfici trimesh ed è tale
else if ( nType != GEO_CURVE && ( pGObj->GetType() & GEO_SURF) != 0) {
const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ;
if ( pSurf == nullptr)
return false ;
// se direttamente la superficie
if ( Id.nSub == SEL_SUB_ALL) {
nSubs = pSurf->GetFacetCount() ;
return true ;
}
// altrimenti faccia di superficie trimesh
else {
// se faccia non esistente
if ( Id.nSub > pSurf->GetFacetCount())
return false ;
// tutto bene
nSubs = 0 ;
return true ;
}
}
// altrimenti sottocurva di composita
else {
const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pCompo != nullptr)
pCurve = pCompo->GetCurve( Id.nSub) ;
nSubs = 0 ;
}
return ( pCurve != nullptr) ;
// altrimenti errore
else
return false ;
}
//----------------------------------------------------------------------------
@@ -843,91 +867,85 @@ ICurve*
Sawing::GetCurve( SelData Id)
{
// ammessi : curve o facce di polymesh
// nel caso di facce si deve recuperare la linea di base
// per ora accetto solo curve
PtrOwner<ICurve> pCurve ;
// se direttamente curva
if ( Id.nSub == SEL_SUB_ALL) {
// recupero e duplico la curva
const ICurve* pOriCurve = ::GetCurve( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pOriCurve != nullptr)
pCurve.Set( pOriCurve->Clone()) ;
}
// altrimenti sottocurva di composita
else {
// recupero la composita
const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ;
if ( pCompo != nullptr) {
// duplico la curva semplice
const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ;
if ( pOriCurve != nullptr) {
pCurve.Set( pOriCurve->Clone()) ;
// recupero estrusione e spessore
Vector3d vtExtr ;
if ( pCompo->GetExtrusion( vtExtr))
pCurve->SetExtrusion( vtExtr) ;
double dThick ;
if ( pCompo->GetThickness( dThick))
pCurve->SetThickness( dThick) ;
}
}
}
if ( IsNull( pCurve))
const IGeoObj* pGObj = m_pGeomDB->GetGeoObj( Id.nId) ;
if ( pGObj == nullptr)
return nullptr ;
// ne recupero il riferimento globale
Frame3d frGlob ;
if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob))
return nullptr ;
// la porto in globale
pCurve->ToGlob( frGlob) ;
// la restituisco
return Release( pCurve) ;
}
//----------------------------------------------------------------------------
bool
Sawing::VerifySideAngle( void)
{
// verifiche per angolo di sbandamento
if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) {
// non ammesso lato di lavoro in centro
if ( m_Params.m_nWorkSide == SAW_WS_CENTER) {
m_pMchMgr->SetLastError( 2202, "Error in Sawing : Center work not allowed with side angle") ;
return false ;
// se curva
if ( ( pGObj->GetType() & GEO_CURVE) != 0) {
PtrOwner<ICurve> pCurve ;
// se direttamente curva
if ( Id.nSub == SEL_SUB_ALL) {
// recupero e duplico la curva
const ICurve* pOriCurve = ::GetCurve( pGObj) ;
if ( pOriCurve != nullptr)
pCurve.Set( pOriCurve->Clone()) ;
}
// se angolo esterno lato mandrino deve uguagliare lato di lavoro
if ( m_Params.m_dSideAngle > 0) {
if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) {
if ( m_Params.m_nHeadSide == SAW_HS_LEFT) {
m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_RIGHT ;
}
}
if ( m_Params.m_nWorkSide == SAW_WS_LEFT) {
if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) {
m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_LEFT ;
}
}
}
// altrimenti angolo interno, lato mandrino deve essere opposto a lato di lavoro
// altrimenti sottocurva di composita
else {
if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) {
if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) {
m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_LEFT ;
}
}
if ( m_Params.m_nWorkSide == SAW_WS_LEFT) {
if ( m_Params.m_nHeadSide == SAW_HS_LEFT) {
m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_RIGHT ;
// recupero la composita
const ICurveComposite* pCompo = GetCurveComposite( pGObj) ;
if ( pCompo != nullptr) {
// duplico la curva semplice
const ICurve* pOriCurve = ::GetCurve( pCompo->GetCurve( Id.nSub)) ;
if ( pOriCurve != nullptr) {
pCurve.Set( pOriCurve->Clone()) ;
// recupero estrusione e spessore
Vector3d vtExtr ;
if ( pCompo->GetExtrusion( vtExtr))
pCurve->SetExtrusion( vtExtr) ;
double dThick ;
if ( pCompo->GetThickness( dThick))
pCurve->SetThickness( dThick) ;
}
}
}
if ( IsNull( pCurve))
return nullptr ;
// la porto in globale
pCurve->ToGlob( frGlob) ;
// la restituisco
return Release( pCurve) ;
}
return true ;
// se altrimenti superficie
else if ( ( pGObj->GetType() & GEO_SURF) != 0) {
// recupero la trimesh
const ISurfTriMesh* pSurf = ::GetSurfTriMesh( pGObj) ;
if ( pSurf == nullptr)
return nullptr ;
// recupero l'indice della faccia
int nFacet = ( ( Id.nSub == SEL_SUB_ALL) ? 0 : Id.nSub) ;
// recupero i contorni della faccia
POLYLINEVECTOR vPL ;
pSurf->GetFacetLoops( nFacet, vPL) ;
if ( vPL.empty())
return nullptr ;
// recupero la normale esterna della faccia
Vector3d vtN ;
if ( ! pSurf->GetFacetNormal( nFacet, vtN))
return nullptr ;
// creo la curva a partire da quello esterno
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
pCrvCompo->FromPolyLine( vPL[0]) ;
if ( ! pCrvCompo->IsValid())
return nullptr ;
// assegno l'estrusione dalla normale alla faccia
pCrvCompo->SetExtrusion( vtN) ;
// unisco le eventuali parti allineate
pCrvCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL) ;
// la porto in globale
pCrvCompo->ToGlob( frGlob) ;
// sistemazioni varie
AdjustCurveFromSurf( pCrvCompo, TOOL_ORTUP, FACE_DOWN, m_TParams.m_dThick) ;
// la restituisco
return Release( pCrvCompo) ;
}
// altrimenti errore
else
return nullptr ;
}
//----------------------------------------------------------------------------
@@ -1031,6 +1049,51 @@ Sawing::Chain( int nGrpDestId)
return true ;
}
//----------------------------------------------------------------------------
bool
Sawing::VerifySideAngle( void)
{
// verifiche per angolo di sbandamento
if ( abs( m_Params.m_dSideAngle) > EPS_ANG_SMALL) {
// non ammesso lato di lavoro in centro
if ( m_Params.m_nWorkSide == SAW_WS_CENTER) {
m_pMchMgr->SetLastError( 2202, "Error in Sawing : Center work not allowed with side angle") ;
return false ;
}
// se angolo esterno lato mandrino deve uguagliare lato di lavoro
if ( m_Params.m_dSideAngle > 0) {
if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) {
if ( m_Params.m_nHeadSide == SAW_HS_LEFT) {
m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_RIGHT ;
}
}
if ( m_Params.m_nWorkSide == SAW_WS_LEFT) {
if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) {
m_pMchMgr->SetLastError( 2203, "Error in Sawing : External side angle HeadSide must equal WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_LEFT ;
}
}
}
// altrimenti angolo interno, lato mandrino deve essere opposto a lato di lavoro
else {
if ( m_Params.m_nWorkSide == SAW_WS_RIGHT) {
if ( m_Params.m_nHeadSide == SAW_HS_RIGHT) {
m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_LEFT ;
}
}
if ( m_Params.m_nWorkSide == SAW_WS_LEFT) {
if ( m_Params.m_nHeadSide == SAW_HS_LEFT) {
m_pMchMgr->SetLastError( 2204, "Error in Sawing : Internal side angle HeadSide must opposite WorkSide") ;
m_Params.m_nHeadSide = SAW_HS_RIGHT ;
}
}
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Sawing::ProcessPath( int nPathId, int nPvId, int nClId)