From a706c667aa5c5c1464e6fdd396f561e256056df7 Mon Sep 17 00:00:00 2001 From: Dario Sassi Date: Fri, 9 Dec 2016 17:02:58 +0000 Subject: [PATCH] EgtMachKernel : - prima versione di milling su facce piane. --- Milling.cpp | 246 +++++++++++++++++++++++++++++++++++++++------------- Milling.h | 3 +- 2 files changed, 190 insertions(+), 59 deletions(-) diff --git a/Milling.cpp b/Milling.cpp index 65cdf25..3e2edbb 100644 --- a/Milling.cpp +++ b/Milling.cpp @@ -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 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 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 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 ; } //---------------------------------------------------------------------------- diff --git a/Milling.h b/Milling.h index f1be6f2..1da9131 100644 --- a/Milling.h +++ b/Milling.h @@ -62,8 +62,9 @@ class Milling : public Machining private : bool UpdateToolData( void) ; - bool VerifyGeometry( SelData Id, int& nSubs) ; + bool VerifyGeometry( SelData Id, int& nSubs, int& nType) ; ICurve* GetCurve( SelData Id) ; + bool AdjustCurveFromSurf( ICurveComposite* pCrvCompo) ; bool Chain( int nGrpDestId) ; bool ProcessPath( int nPathId, int nPvId, int nClId) ; bool CalcPathElevation( const ICurveComposite* pCompo, const Vector3d& vtTool, double dDepth, double dRad, double& dElev) ;