EgtMachKernel :

- prima versione di milling su facce piane.
This commit is contained in:
Dario Sassi
2016-12-09 17:02:58 +00:00
parent 147304df18
commit a706c667aa
2 changed files with 190 additions and 59 deletions
+188 -58
View File
@@ -23,6 +23,7 @@
#include "/EgtDev/Include/EgkArcSpecial.h"
#include "/EgtDev/Include/EgkChainCurves.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"
@@ -367,11 +368,12 @@ Milling::SetGeometry( const SELVECTOR& vIds)
return false ;
// reset della geometria corrente
m_vId.clear() ;
// verifico che gli identificativi rappresentino delle entità ammissibili
// verifico che gli identificativi rappresentino delle entità ammissibili (tutte curve o tutte facce)
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 = "Entity " + ToString( Id) + " skipped by Milling" ;
LOG_INFO( GetEMkLogger(), sOut.c_str()) ;
continue ;
@@ -706,31 +708,57 @@ Milling::GetGeometry( SELVECTOR& vIds) const
//----------------------------------------------------------------------------
bool
Milling::VerifyGeometry( SelData Id, int& nSubs)
Milling::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 ;
// se direttamente la curva
if ( Id.nSub == SEL_SUB_ALL) {
pCurve = ::GetCurve( pGObj) ;
if ( pCurve != nullptr) {
if ( pCurve->GetType() == CRV_COMPO)
nSubs = ::GetCurveComposite( pCurve)->GetCurveCount() ;
else
nSubs = 0 ;
}
}
// altrimenti sottocurva di composita
else {
const ICurveComposite* pCompo = GetCurveComposite( pGObj) ;
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 ;
}
//----------------------------------------------------------------------------
@@ -738,46 +766,148 @@ ICurve*
Milling::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) ;
// 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()) ;
}
// altrimenti sottocurva di composita
else {
// 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) ;
}
// 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) ;
// la porto in globale
pCrvCompo->ToGlob( frGlob) ;
// sistemazioni varie
AdjustCurveFromSurf( pCrvCompo) ;
// la restituisco
return Release( pCrvCompo) ;
}
// altrimenti errore
else
return nullptr ;
}
//----------------------------------------------------------------------------
bool
Milling::AdjustCurveFromSurf( ICurveComposite* pCrvCompo)
{
// con utensile fresa fa il contorno
if ( ( m_TParams.m_nType & TF_SAWBLADE) == 0) {
// cerco l'estremo più alto e lo imposto come inizio
double dU = 0 ;
double dUmax = 0 ;
double dZmax = - INFINITO ;
Point3d ptP ;
while ( pCrvCompo->GetPointD1D2( dU, ICurve::FROM_MINUS, ptP)) {
if ( ptP.z > dZmax + EPS_SMALL) {
dZmax = ptP.z ;
dUmax = dU ;
}
dU += 1 ;
}
if ( dU != 0)
pCrvCompo->ChangeStartPoint( dUmax) ;
}
// con utensile lama tiene solo la parte sotto
else {
// ingombro
BBox3d b3Box ;
pCrvCompo->GetLocalBBox( b3Box) ;
double dZmin = b3Box.GetMin().z ;
double dZtol = min( ( b3Box.GetMax().z - b3Box.GetMin().z) / 2., 20.) ;
// elimino le linee troppo sopra il minimo dall'inizio e poi dalla fine
const ICurve* pCrv = pCrvCompo->GetFirstCurve() ;
while ( pCrv != nullptr) {
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
if ( ptMid.z > dZmin + dZtol) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( false) ;
delete( pErase) ;
pCrv = pCrvCompo->GetFirstCurve() ;
}
else
break ;
}
pCrv = pCrvCompo->GetLastCurve() ;
while ( pCrv != nullptr) {
Point3d ptMid ; pCrv->GetMidPoint( ptMid) ;
Vector3d vtDir ; pCrv->GetMidDir( vtDir) ;
if ( ptMid.z > dZmin + dZtol) {
ICurve* pErase = pCrvCompo->RemoveFirstOrLastCurve( true) ;
delete( pErase) ;
pCrv = pCrvCompo->GetLastCurve() ;
}
else
break ;
}
// verifico il versore estrusione
Vector3d vtN ;
pCrvCompo->GetExtrusion( vtN) ;
if ( vtN.z < - sin( 2 * DEGTORAD)) {
pCrvCompo->Invert() ;
pCrvCompo->Translate( vtN * m_TParams.m_dThick) ;
pCrvCompo->SetExtrusion( - vtN) ;
}
}
return true ;
}
//----------------------------------------------------------------------------