EgtMachKernel :
- aggiunta gestione archi su piani diversi da XY - disposizione rimette sempre anche i sottopezzi al loro posto - aggiunti attacchi e uscite a fresature - aggiunta prima versione calcolo collegamenti tra lavorazioni evitando collisioni - modifiche a simulazione per tavole mobili con sottopezzi e pezzi.
This commit is contained in:
+636
-4
@@ -18,7 +18,9 @@
|
||||
#include "Milling.h"
|
||||
#include "MachiningConst.h"
|
||||
#include "/EgtDev/Include/EGkCurveLine.h"
|
||||
#include "/EgtDev/Include/EGkCurveArc.h"
|
||||
#include "/EgtDev/Include/EGkCurveComposite.h"
|
||||
#include "/EgtDev/Include/EgkArcSpecial.h"
|
||||
#include "/EgtDev/Include/EgkChainCurves.h"
|
||||
#include "/EgtDev/Include/EGkUserObjFactory.h"
|
||||
#include "/EgtDev/Include/EGnStringKeyVal.h"
|
||||
@@ -187,6 +189,11 @@ Milling::Prepare( const string& sMillName)
|
||||
bool
|
||||
Milling::SetParam( int nType, bool bVal)
|
||||
{
|
||||
switch ( nType) {
|
||||
case MPA_INVERT :
|
||||
m_Params.m_bInvert = bVal ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -194,6 +201,28 @@ Milling::SetParam( int nType, bool bVal)
|
||||
bool
|
||||
Milling::SetParam( int nType, int nVal)
|
||||
{
|
||||
switch ( nType) {
|
||||
case MPA_WORKSIDE :
|
||||
if ( ! m_Params.VerifyWorkSide( nVal))
|
||||
return false ;
|
||||
m_Params.m_nWorkSide = nVal ;
|
||||
return true ;
|
||||
case MPA_STEPTYPE :
|
||||
if ( ! m_Params.VerifyStepType( nVal))
|
||||
return false ;
|
||||
m_Params.m_nStepType = nVal ;
|
||||
return true ;
|
||||
case MPA_LEADINTYPE :
|
||||
if ( ! m_Params.VerifyLeadInType( nVal))
|
||||
return false ;
|
||||
m_Params.m_nLeadInType = nVal ;
|
||||
return true ;
|
||||
case MPA_LEADOUTTYPE :
|
||||
if ( ! m_Params.VerifyLeadOutType( nVal))
|
||||
return false ;
|
||||
m_Params.m_nLeadOutType = nVal ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
|
||||
@@ -246,6 +275,30 @@ Milling::SetParam( int nType, double dVal)
|
||||
else
|
||||
m_Params.m_dOffsL = dVal ;
|
||||
return true ;
|
||||
case MPA_DEPTH :
|
||||
m_Params.m_sDepth = ToString( dVal) ;
|
||||
return true ;
|
||||
case MPA_STARTPOS :
|
||||
m_Params.m_dStartPos = dVal ;
|
||||
return true ;
|
||||
case MPA_OVERLAP :
|
||||
m_Params.m_dOverlap = dVal ;
|
||||
return true ;
|
||||
case MPA_STEP :
|
||||
m_Params.m_dStep = dVal ;
|
||||
return true ;
|
||||
case MPA_LITANG :
|
||||
m_Params.m_dLiTang = dVal ;
|
||||
return true ;
|
||||
case MPA_LIPERP :
|
||||
m_Params.m_dLiPerp = dVal ;
|
||||
return true ;
|
||||
case MPA_LIELEV :
|
||||
m_Params.m_dLiElev = dVal ;
|
||||
return true ;
|
||||
case MPA_LICOMPLEN :
|
||||
m_Params.m_dLoCompLen = dVal ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
@@ -263,6 +316,9 @@ Milling::SetParam( int nType, const string& sVal)
|
||||
m_Params.m_ToolUuid = pTdata->m_Uuid ;
|
||||
m_TParams = *pTdata ;
|
||||
} break ;
|
||||
case MPA_DEPTH_STR :
|
||||
m_Params.m_sDepth = sVal ;
|
||||
return true ;
|
||||
case MPA_SYSNOTES :
|
||||
m_Params.m_sSysNotes = sVal ;
|
||||
break ;
|
||||
@@ -279,7 +335,29 @@ Milling::SetParam( int nType, const string& sVal)
|
||||
bool
|
||||
Milling::SetGeometry( const SELVECTOR& vIds)
|
||||
{
|
||||
return false ;
|
||||
// verifico validità gestore DB geometrico
|
||||
if ( m_pGeomDB == nullptr)
|
||||
return false ;
|
||||
// reset della geometria corrente
|
||||
m_vId.clear() ;
|
||||
// verifico che gli identificativi rappresentino delle entità ammissibili
|
||||
for ( const auto& Id : vIds) {
|
||||
// test sull'entità
|
||||
int nSubs ;
|
||||
if ( ! VerifyGeometry( Id, nSubs)) {
|
||||
string sOut = "Entity " + ToString( Id) + " skipped by Milling" ;
|
||||
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) ;
|
||||
}
|
||||
}
|
||||
return ( ! m_vId.empty()) ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -299,7 +377,72 @@ Milling::Apply( bool bRecalc)
|
||||
// reset numero percorsi di lavoro generati
|
||||
m_nMills = 0 ;
|
||||
|
||||
return false ;
|
||||
// verifico validità gestore DB geometrico e Id del gruppo
|
||||
if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId))
|
||||
return false ;
|
||||
|
||||
// recupero gruppo per geometria ausiliaria
|
||||
int nAuxId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_AUX) ;
|
||||
bool bChain = false ;
|
||||
// se non c'è, lo aggiungo
|
||||
if ( nAuxId == GDB_ID_NULL) {
|
||||
nAuxId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
|
||||
if ( nAuxId == GDB_ID_NULL)
|
||||
return false ;
|
||||
m_pGeomDB->SetName( nAuxId, MCH_AUX) ;
|
||||
m_pGeomDB->SetStatus( nAuxId, GDB_ST_OFF) ;
|
||||
bChain = true ;
|
||||
}
|
||||
// altrimenti, se chiesto ricalcolo, lo svuoto
|
||||
else if ( bRecalc) {
|
||||
m_pGeomDB->EmptyGroup( nAuxId) ;
|
||||
bChain = true ;
|
||||
}
|
||||
|
||||
// aggiorno dati geometrici dell'utensile
|
||||
if ( ! UpdateToolData()) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Sawing : UpdateToolData failed") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria
|
||||
if ( bChain && ! Chain( nAuxId))
|
||||
return false ;
|
||||
|
||||
// recupero gruppo per geometria di lavorazione (Cutter Location)
|
||||
int nClId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_CL) ;
|
||||
// se non c'è, lo aggiungo
|
||||
if ( nClId == GDB_ID_NULL) {
|
||||
nClId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
|
||||
if ( nClId == GDB_ID_NULL)
|
||||
return false ;
|
||||
m_pGeomDB->SetName( nClId, MCH_CL) ;
|
||||
}
|
||||
// altrimenti lo svuoto
|
||||
else
|
||||
m_pGeomDB->EmptyGroup( nClId) ;
|
||||
|
||||
// lavoro ogni singola catena
|
||||
int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ;
|
||||
while ( nPathId != GDB_ID_NULL) {
|
||||
if ( ! ProcessPath( nPathId, GDB_ID_NULL, nClId))
|
||||
return false ;
|
||||
nPathId = m_pGeomDB->GetNextGroup( nPathId) ;
|
||||
}
|
||||
|
||||
// se lavorazione vuota, esco
|
||||
if ( m_nMills == 0)
|
||||
return true ;
|
||||
|
||||
// calcolo gli assi macchina
|
||||
if ( ! CalculateAxesValues())
|
||||
return false ;
|
||||
|
||||
// gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine della lavorazione
|
||||
if ( ! AdjustStartEndMovements())
|
||||
return false ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
@@ -317,6 +460,18 @@ Milling::GetParam( int nType, int& nVal) const
|
||||
case MPA_TYPE :
|
||||
nVal = MT_MILLING ;
|
||||
return true ;
|
||||
case MPA_WORKSIDE :
|
||||
nVal = m_Params.m_nWorkSide ;
|
||||
return true ;
|
||||
case MPA_STEPTYPE :
|
||||
nVal = m_Params.m_nStepType ;
|
||||
return true ;
|
||||
case MPA_LEADINTYPE :
|
||||
nVal = m_Params.m_nLeadInType ;
|
||||
return true ;
|
||||
case MPA_LEADOUTTYPE :
|
||||
nVal = m_Params.m_nLeadOutType ;
|
||||
return true ;
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
@@ -350,9 +505,25 @@ Milling::GetParam( int nType, double& dVal) const
|
||||
case MPA_STARTPOS :
|
||||
dVal = m_Params.m_dStartPos ;
|
||||
return true ;
|
||||
case MPA_SIDEANGLE :
|
||||
dVal = m_Params.m_dSideAngle ;
|
||||
case MPA_OVERLAP :
|
||||
dVal = m_Params.m_dOverlap ;
|
||||
return true ;
|
||||
case MPA_STEP :
|
||||
dVal = m_Params.m_dStep ;
|
||||
return true ;
|
||||
case MPA_LITANG :
|
||||
dVal = m_Params.m_dLiTang ;
|
||||
return true ;
|
||||
case MPA_LIPERP :
|
||||
dVal = m_Params.m_dLiPerp ;
|
||||
return true ;
|
||||
case MPA_LIELEV :
|
||||
dVal = m_Params.m_dLiElev ;
|
||||
return true ;
|
||||
case MPA_LICOMPLEN :
|
||||
dVal = m_Params.m_dLoCompLen ;
|
||||
return true ;
|
||||
|
||||
}
|
||||
return false ;
|
||||
}
|
||||
@@ -607,3 +778,464 @@ Milling::AdjustEndPointForAxesCalc( const CamData* pCamData, Point3d& ptP)
|
||||
// non devo fare alcunché
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::ProcessPath( int nPathId, int nPvId, int nClId)
|
||||
{
|
||||
// recupero gruppo per geometria temporanea
|
||||
const string GRP_TEMP = "Temp" ;
|
||||
int nTempId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, GRP_TEMP) ;
|
||||
// se non c'è, lo aggiungo
|
||||
if ( nTempId == GDB_ID_NULL) {
|
||||
nTempId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
|
||||
if ( nTempId == GDB_ID_NULL)
|
||||
return false ;
|
||||
m_pGeomDB->SetName( nTempId, GRP_TEMP) ;
|
||||
}
|
||||
// altrimenti lo svuoto
|
||||
else
|
||||
m_pGeomDB->EmptyGroup( nTempId) ;
|
||||
// in ogni caso lo dichiaro temporaneo e non visibile
|
||||
m_pGeomDB->SetLevel( nTempId, GDB_LV_TEMP) ;
|
||||
m_pGeomDB->SetStatus( nTempId, GDB_ST_OFF) ;
|
||||
|
||||
// copio la curva composita da elaborare
|
||||
int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ;
|
||||
if ( m_pGeomDB->GetGeoType( nCrvId) != CRV_COMPO)
|
||||
return false ;
|
||||
int nCopyId = m_pGeomDB->CopyGlob( nCrvId, GDB_ID_NULL, nTempId) ;
|
||||
if ( nCopyId == GDB_ID_NULL)
|
||||
return false ;
|
||||
ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( nCopyId)) ;
|
||||
|
||||
// unisco le parti allineate
|
||||
//if ( ! pCompo->MergeCurves( 10 * EPS_SMALL, 10 * EPS_ANG_SMALL))
|
||||
// return false ;
|
||||
|
||||
// eventuale inversione percorso
|
||||
if ( m_Params.m_bInvert)
|
||||
pCompo->Invert() ;
|
||||
|
||||
// se utensile non centrato, eseguo correzione raggio utensile ed eventuale offset
|
||||
double dOffs = 0.5 * m_TParams.m_dTDiam + GetOffsR() ;
|
||||
if ( m_Params.m_nWorkSide != MILL_WS_CENTER && abs( dOffs) > EPS_SMALL) {
|
||||
double dSignOffs = ( m_Params.m_nWorkSide == MILL_WS_RIGHT) ? dOffs : - dOffs ;
|
||||
if ( ! pCompo->SimpleOffset( dSignOffs, ICurve::OFF_EXTEND)){
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : SimpleOffset not computable") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// recupero estrusione e spessore
|
||||
Vector3d vtExtr ;
|
||||
pCompo->GetExtrusion( vtExtr) ;
|
||||
double dThick ;
|
||||
pCompo->GetThickness( dThick) ;
|
||||
|
||||
// recupero il box del grezzo in globale
|
||||
BBox3d b3Raw ;
|
||||
if ( ! GetRawGlobBox( m_nPhase, nPathId, b3Raw) || b3Raw.IsEmpty()) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in SawFinishing : Empty RawBox") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// recupero distanza da fondo dei grezzi interessati dal percorso
|
||||
double dRbDist ;
|
||||
if ( ! GetDistanceFromRawBottom( m_nPhase, nCopyId, 2 * m_TParams.m_dThick, dRbDist))
|
||||
return false ;
|
||||
|
||||
// valuto l'espressione dell'affondamento
|
||||
ExeLuaSetGlobNumVar( "TH", (( dThick * vtExtr.z < 0) ? fabs( dThick) : 0)) ;
|
||||
ExeLuaSetGlobNumVar( "RB", dRbDist) ;
|
||||
double dDepth ;
|
||||
if ( ! ExeLuaEvalNumExpr( m_Params.m_sDepth, &dDepth)) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : Depth not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// verifico di non superare il massimo materiale
|
||||
if ( dDepth > m_TParams.m_dMaxMat) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : Depth bigger than MaxMaterial") ;
|
||||
return false ;
|
||||
}
|
||||
|
||||
// recupero nome del path
|
||||
string sPathName ;
|
||||
m_pGeomDB->GetName( nPathId, sPathName) ;
|
||||
|
||||
// verifiche sull'ampiezza dell'angolo al centro degli eventuali archi
|
||||
const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ;
|
||||
int nMaxInd = pCompo->GetCurveCount() - 1 ;
|
||||
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
|
||||
// se arco con angolo al centro oltre il limite, lo divido a metà
|
||||
const ICurveArc* pArc = GetCurveArc( pCompo->GetCurve( i)) ;
|
||||
if ( pArc != nullptr && abs( pArc->GetAngCenter()) > MAX_ANG_CEN) {
|
||||
pCompo->AddJoint( i + 0.5) ;
|
||||
++ i ;
|
||||
++ nMaxInd ;
|
||||
}
|
||||
}
|
||||
|
||||
// creo gruppo per geometria di lavorazione del percorso
|
||||
int nPxId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
|
||||
if ( nPxId == GDB_ID_NULL)
|
||||
return false ;
|
||||
m_pGeomDB->SetName( nPxId, sPathName) ;
|
||||
m_pGeomDB->SetMaterial( nPxId, BLUE) ;
|
||||
|
||||
// calcolo il versore fresa
|
||||
Vector3d vtTool = Z_AX ;
|
||||
if ( ! vtExtr.IsSmall())
|
||||
vtTool = vtExtr ;
|
||||
|
||||
// Imposto dati comuni
|
||||
SetPathId( nPxId) ;
|
||||
SetToolDir( vtTool) ;
|
||||
// recupero distanza di sicurezza
|
||||
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
|
||||
// lunghezza di approccio/retrazione
|
||||
double dAppr = m_Params.m_dStartPos ;
|
||||
|
||||
// ciclo sulle curve elementari
|
||||
bool bClosed = pCompo->IsClosed() ;
|
||||
nMaxInd = pCompo->GetCurveCount() - 1 ;
|
||||
for ( int i = 0 ; i <= nMaxInd ; ++ i) {
|
||||
// curva corrente
|
||||
const ICurve* pCrvC = pCompo->GetCurve( i) ;
|
||||
// copio la curva
|
||||
PtrOwner<ICurve> pCurve( ::GetCurve( pCrvC->Clone())) ;
|
||||
if ( IsNull( pCurve))
|
||||
return false ;
|
||||
// aggiungo affondamento
|
||||
pCurve->Translate( - vtTool * dDepth) ;
|
||||
// calcolo elevazione
|
||||
double dElev ;
|
||||
Point3d ptStart, ptMid, ptEnd ;
|
||||
pCurve->GetStartPoint( ptStart) ;
|
||||
pCurve->GetMidPoint( ptMid) ;
|
||||
pCurve->GetEndPoint( ptEnd) ;
|
||||
if ( ! GetElevation( m_nPhase, ptStart, ptMid, ptEnd, vtTool, dElev)) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : Entity GetElevation") ;
|
||||
return false ;
|
||||
}
|
||||
if ( dElev < EPS_SMALL) {
|
||||
BBox3d b3Crv ;
|
||||
pCurve->GetLocalBBox( b3Crv) ;
|
||||
dElev = max( 0., b3Raw.GetMax().z - b3Crv.GetMin().z) ;
|
||||
}
|
||||
// se prima entità, approccio e affondo
|
||||
if ( i == 0) {
|
||||
// dati inizio entità
|
||||
Point3d ptStart ;
|
||||
pCurve->GetStartPoint( ptStart) ;
|
||||
Vector3d vtStart ;
|
||||
pCurve->GetStartDir( vtStart) ;
|
||||
// determino inizio attacco
|
||||
Point3d ptP1 ;
|
||||
if ( ! CalcLeadInStart( ptStart, vtStart, vtExtr, ptP1))
|
||||
return false ;
|
||||
// aggiungo approccio
|
||||
if ( ! AddApproach( ptP1, vtTool, dSafeZ, dElev, dAppr))
|
||||
return false ;
|
||||
// affondo al punto iniziale
|
||||
SetFlag( 0) ;
|
||||
SetFeed( GetTipFeed()) ;
|
||||
if ( AddLinearMove( ptP1) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// aggiungo attacco
|
||||
SetFeed( GetStartFeed()) ;
|
||||
if ( ! AddLeadIn( ptP1, ptStart, vtStart, vtExtr)) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : LeadIn not computable") ;
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
// elaborazioni sulla curva corrente
|
||||
if ( pCurve->GetType() == CRV_LINE) {
|
||||
ICurveLine* pLine = GetCurveLine( pCurve) ;
|
||||
Point3d ptP3 = pLine->GetEnd() ;
|
||||
SetFeed( GetFeed()) ;
|
||||
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
else if ( pCurve->GetType() == CRV_ARC) {
|
||||
ICurveArc* pArc = GetCurveArc( pCurve) ;
|
||||
Point3d ptCen = pArc->GetCenter() ;
|
||||
double dAngCen = pArc->GetAngCenter() ;
|
||||
Vector3d vtN = pArc->GetNormVersor() ;
|
||||
Point3d ptP3 ;
|
||||
pArc->GetEndPoint( ptP3) ;
|
||||
SetFeed( GetFeed()) ;
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen, vtN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
// se ultima entità, uscita e retrazione
|
||||
if ( i == nMaxInd) {
|
||||
// dati fine entità
|
||||
Point3d ptEnd ;
|
||||
pCurve->GetEndPoint( ptEnd) ;
|
||||
Vector3d vtEnd ;
|
||||
pCurve->GetEndDir( vtEnd) ;
|
||||
// aggiungo uscita
|
||||
Point3d ptP1 ;
|
||||
SetFeed( GetStartFeed()) ;
|
||||
if ( ! AddLeadOut( ptEnd, vtEnd, vtExtr, ptP1)) {
|
||||
LOG_INFO( GetEMkLogger(), "Error in Milling : LeadOut not computable") ;
|
||||
return false ;
|
||||
}
|
||||
// aggiungo retrazione
|
||||
if ( ! AddRetract( ptP1, vtTool, dSafeZ, dElev, dAppr))
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
// incremento numero di fresate
|
||||
++ m_nMills ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::AddApproach( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr)
|
||||
{
|
||||
// se distanza di sicurezza minore di distanza di inizio
|
||||
if ( dSafeZ < m_Params.m_dStartPos + 10 * EPS_SMALL) {
|
||||
// 1 -> punto sopra inizio
|
||||
SetFlag( 1) ;
|
||||
Point3d ptP1 = ptP + vtTool * ( dElev + dAppr) ;
|
||||
if ( AddRapidStart( ptP1) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
// 1a -> punto sopra inizio
|
||||
SetFlag( 1) ;
|
||||
Point3d ptP1b = ptP + vtTool * ( dElev + dAppr) ;
|
||||
Point3d ptP1a = ptP1b + vtTool * ( dSafeZ - m_Params.m_dStartPos) ;
|
||||
if ( AddRapidStart( ptP1a) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// 1b -> punto appena sopra inizio
|
||||
SetFlag( 0) ;
|
||||
if ( AddRapidMove( ptP1b) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::AddRetract( const Point3d& ptP, const Vector3d& vtTool, double dSafeZ, double dElev, double dAppr)
|
||||
{
|
||||
if ( dSafeZ < m_Params.m_dStartPos + 10 * EPS_SMALL) {
|
||||
// 4 -> movimento di risalita sopra il punto finale
|
||||
SetFeed( GetEndFeed()) ;
|
||||
Point3d ptP4 = ptP + vtTool * ( dElev + dAppr) ;
|
||||
if ( AddLinearMove( ptP4) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
else {
|
||||
// 4a -> movimento di risalita appena sopra il punto finale
|
||||
SetFeed( GetEndFeed()) ;
|
||||
Point3d ptP4a = ptP + vtTool * ( dElev + dAppr) ;
|
||||
if ( AddLinearMove( ptP4a) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// 4b -> movimento di risalita sopra il punto finale
|
||||
Point3d ptP4b = ptP4a + vtTool * ( dSafeZ - m_Params.m_dStartPos) ;
|
||||
if ( AddRapidMove( ptP4b) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::CalcLeadInStart( const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN, Point3d& ptP1)
|
||||
{
|
||||
switch ( m_Params.m_nLeadInType) {
|
||||
case MILL_LI_NONE :
|
||||
ptP1 = ptStart ;
|
||||
return true ;
|
||||
case MILL_LI_LINEAR :
|
||||
case MILL_LI_TANGENT : {
|
||||
if ( m_Params.m_dLiTang < 10 * EPS_SMALL && abs( m_Params.m_dLiPerp) < EPS_SMALL)
|
||||
return false ;
|
||||
Vector3d vtPerp = vtStart ;
|
||||
vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ;
|
||||
ptP1 = ptStart - vtStart * m_Params.m_dLiTang + vtPerp * m_Params.m_dLiPerp ;
|
||||
return true ;
|
||||
}
|
||||
case MILL_LI_GLIDE :
|
||||
// !!! DA FARE !!!
|
||||
return false ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::AddLeadIn( const Point3d& ptP1, const Point3d& ptStart, const Vector3d& vtStart, const Vector3d& vtN)
|
||||
{
|
||||
switch ( m_Params.m_nLeadInType) {
|
||||
case MILL_LI_NONE :
|
||||
return true ;
|
||||
case MILL_LI_LINEAR :
|
||||
return ( AddLinearMove( ptStart, MCH_CL_LEADIN) != GDB_ID_NULL) ;
|
||||
case MILL_LI_TANGENT :
|
||||
{
|
||||
PtrOwner<ICurve> pCrv( GetArc2PVN( ptStart, ptP1, - vtStart, vtN)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
pCrv->Invert() ;
|
||||
if ( pCrv->GetType() == CRV_LINE) {
|
||||
ICurveLine* pLine = GetCurveLine( pCrv) ;
|
||||
Point3d ptP3 = pLine->GetEnd() ;
|
||||
return ( AddLinearMove( ptP3, MCH_CL_LEADIN) != GDB_ID_NULL) ;
|
||||
}
|
||||
else if ( pCrv->GetType() == CRV_ARC) {
|
||||
ICurveArc* pArc = GetCurveArc( pCrv) ;
|
||||
Point3d ptCen = pArc->GetCenter() ;
|
||||
double dAngCen = pArc->GetAngCenter() ;
|
||||
Vector3d vtN = pArc->GetNormVersor() ;
|
||||
Point3d ptP3 ;
|
||||
pArc->GetEndPoint( ptP3) ;
|
||||
// se angolo al centro minore del limite, un solo arco
|
||||
const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ;
|
||||
if ( abs( dAngCen) < MAX_ANG_CEN) {
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti due archi
|
||||
else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){
|
||||
Point3d ptMid ;
|
||||
pArc->GetMidPoint( ptMid) ;
|
||||
// prima metà arco
|
||||
if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// seconda metà arco
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
// oppure tre archi
|
||||
else {
|
||||
Point3d ptTmp ;
|
||||
// primo terzo
|
||||
pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ;
|
||||
if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// secondo terzo
|
||||
ptCen.z = ptTmp.z ;
|
||||
pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ;
|
||||
if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// ultimo terzo
|
||||
ptCen.z = ptTmp.z ;
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADIN) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
case MILL_LI_GLIDE :
|
||||
// !!! DA FARE !!!
|
||||
return false ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
Milling::AddLeadOut( const Point3d& ptEnd, const Vector3d& vtEnd, const Vector3d& vtN, Point3d& ptP1)
|
||||
{
|
||||
// assegno i parametri
|
||||
int nType = m_Params.m_nLeadOutType ;
|
||||
double dTang = m_Params.m_dLoTang ;
|
||||
double dPerp = m_Params.m_dLoPerp ;
|
||||
if ( nType == MILL_LO_AS_LI) {
|
||||
nType = m_Params.m_nLeadInType ;
|
||||
dTang = m_Params.m_dLiTang ;
|
||||
dPerp = m_Params.m_dLiPerp ;
|
||||
}
|
||||
// eseguo a seconda del tipo
|
||||
switch ( nType) {
|
||||
case MILL_LO_NONE :
|
||||
ptP1 = ptEnd ;
|
||||
return true ;
|
||||
case MILL_LO_LINEAR :
|
||||
{
|
||||
if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL)
|
||||
return false ;
|
||||
Vector3d vtPerp = vtEnd ;
|
||||
vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ;
|
||||
ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp ;
|
||||
return ( AddLinearMove( ptP1, MCH_CL_LEADOUT) != GDB_ID_NULL) ;
|
||||
}
|
||||
case MILL_LO_TANGENT :
|
||||
{
|
||||
// calcolo punto finale dell'uscita
|
||||
if ( dTang < 10 * EPS_SMALL && abs( dPerp) < EPS_SMALL)
|
||||
return false ;
|
||||
Vector3d vtPerp = vtEnd ;
|
||||
vtPerp.Rotate( vtN, ( ( m_Params.m_nWorkSide == MILL_WS_LEFT) ? 90 : - 90)) ;
|
||||
ptP1 = ptEnd + vtEnd * dTang + vtPerp * dPerp ;
|
||||
// inserisco uscita
|
||||
PtrOwner<ICurve> pCrv( GetArc2PVN( ptEnd, ptP1, vtEnd, vtN)) ;
|
||||
if ( IsNull( pCrv))
|
||||
return false ;
|
||||
if ( pCrv->GetType() == CRV_LINE) {
|
||||
ICurveLine* pLine = GetCurveLine( pCrv) ;
|
||||
Point3d ptP3 = pLine->GetEnd() ;
|
||||
return ( AddLinearMove( ptP3, MCH_CL_LEADOUT) != GDB_ID_NULL) ;
|
||||
}
|
||||
else if ( pCrv->GetType() == CRV_ARC) {
|
||||
ICurveArc* pArc = GetCurveArc( pCrv) ;
|
||||
Point3d ptCen = pArc->GetCenter() ;
|
||||
double dAngCen = pArc->GetAngCenter() ;
|
||||
Vector3d vtN = pArc->GetNormVersor() ;
|
||||
Point3d ptP3 ;
|
||||
pArc->GetEndPoint( ptP3) ;
|
||||
// se angolo al centro minore del limite, un solo arco
|
||||
const double MAX_ANG_CEN = 150 + EPS_ANG_SMALL ;
|
||||
if ( abs( dAngCen) < MAX_ANG_CEN) {
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
// altrimenti due archi
|
||||
else if ( abs( dAngCen) < 2 * MAX_ANG_CEN){
|
||||
Point3d ptMid ;
|
||||
pArc->GetMidPoint( ptMid) ;
|
||||
// prima metà arco
|
||||
if ( AddArcMove( ptMid, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// seconda metà arco
|
||||
ptCen.z = ptMid.z ;
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen / 2, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
// oppure tre archi
|
||||
else {
|
||||
Point3d ptTmp ;
|
||||
// primo terzo
|
||||
pArc->GetPointD1D2( 1. / 3, ICurve::FROM_MINUS, ptTmp) ;
|
||||
if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// secondo terzo
|
||||
ptCen.z = ptTmp.z ;
|
||||
pArc->GetPointD1D2( 2. / 3, ICurve::FROM_MINUS, ptTmp) ;
|
||||
if ( AddArcMove( ptTmp, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
// ultimo terzo
|
||||
ptCen.z = ptTmp.z ;
|
||||
if ( AddArcMove( ptP3, ptCen, dAngCen / 3, vtN, MCH_CL_LEADOUT) == GDB_ID_NULL)
|
||||
return false ;
|
||||
}
|
||||
return true ;
|
||||
}
|
||||
}
|
||||
case MILL_LO_GLIDE :
|
||||
// !!! DA FARE !!!
|
||||
return false ;
|
||||
default :
|
||||
return false ;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user