4f22c9c578
- migliorati messaggi di log su Apply lavorazioni.
1786 lines
64 KiB
C++
1786 lines
64 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2015-2015
|
|
//----------------------------------------------------------------------------
|
|
// File : Drilling.cpp Data : 21.05.15 Versione : 1.6e7
|
|
// Contenuto : Implementazione gestione forature.
|
|
//
|
|
// Note : Questa lavorazione è sempre espressa nel riferimento globale.
|
|
//
|
|
// Modifiche : 21.05.15 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "MachMgr.h"
|
|
#include "DllMain.h"
|
|
#include "Drilling.h"
|
|
#include "OperationConst.h"
|
|
#include "/EgtDev/Include/EXeCmdLogOff.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkChainCurves.h"
|
|
#include "/EgtDev/Include/EGkSfrCreate.h"
|
|
#include "/EgtDev/Include/EGkUserObjFactory.h"
|
|
#include "/EgtDev/Include/EGnStringKeyVal.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//------------------------------ Errors --------------------------------------
|
|
// 2101 = "Error in Drilling : UpdateToolData failed"
|
|
// 2102 = "Error in Drilling : Offset not computable"
|
|
// 2103 = "Error in Drilling : Overlap not computable"
|
|
// 2104 = "Error in Drilling : Depth not computable"
|
|
// 2105 = "Error in Drilling : Drill with zero depth"
|
|
// 2106 = "Error in Drilling : Entity xx skipped because missing aggregate from bottom"
|
|
// 2107 = "Error in Drilling : Entity xx skipped because too far from part sides"
|
|
// 2108 = "Error in Drilling : Chaining failed"
|
|
// 2109 = "Error in Drilling : axes values not calculable"
|
|
// 2110 = "Error in Drilling : outstroke xx"
|
|
// 2111 = "Error in Drilling : link movements not calculable"
|
|
// 2112 = "Error in Drilling : link outstroke xx"
|
|
// 2113 = "Error in Drilling : post apply not calculable"
|
|
// 2114 = "Error in Drilling : blind hole not reversible"
|
|
// 2151 = "Warning in Drilling : Skipped entity (xx)"
|
|
// 2152 = "Warning in Drilling : No machinable path"
|
|
// 2153 = "Warning in Drilling : Tool name changed (xx)"
|
|
// 2154 = "Warning in Drilling : Tool data changed (xx)"
|
|
// 2155 = "Warning in Drilling : Drill bit too short for Hole "
|
|
// 2156 = "Warning in Drilling : Skipped by Standard Drilling "
|
|
// 2157 = "Warning in Drilling : Skipped by Peck Drilling "
|
|
|
|
//----------------------------------------------------------------------------
|
|
struct Hole
|
|
{
|
|
int nOriId ; // identificativo della geometria di origine
|
|
Point3d ptIni ; // punto iniziale
|
|
Vector3d vtDir ; // direzione di riferimento (dal fondo verso l'inizio)
|
|
double dDiam ; // diametro
|
|
double dThick ; // lunghezza della geometria originale
|
|
double dLen ; // lunghezza dell'asse
|
|
bool bBlind ; // flag per cieco/passante
|
|
// eventuale tipo ( standard, ribassato, svasato) ?
|
|
Hole( void)
|
|
: nOriId( GDB_ID_NULL), ptIni(), vtDir(), dDiam( 0), dThick( 0), dLen( 0), bBlind( true) {}
|
|
} ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
USEROBJ_REGISTER( GetOperationClass( OPER_DRILLING), Drilling) ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
const string&
|
|
Drilling::GetClassName( void) const
|
|
{
|
|
return USEROBJ_GETNAME( Drilling) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
Drilling*
|
|
Drilling::Clone( void) const
|
|
{
|
|
// alloco oggetto
|
|
Drilling* pDri = new(nothrow) Drilling ;
|
|
// eseguo copia dei dati
|
|
if ( pDri != nullptr) {
|
|
try {
|
|
pDri->m_vId = m_vId ;
|
|
pDri->m_pMchMgr = m_pMchMgr ;
|
|
pDri->m_nPhase = m_nPhase ;
|
|
pDri->m_Params = m_Params ;
|
|
pDri->m_TParams = m_TParams ;
|
|
pDri->m_nStatus = m_nStatus ;
|
|
pDri->m_nDrillings = m_nDrillings ;
|
|
pDri->m_bTiltingTab = m_bTiltingTab ;
|
|
pDri->m_bAboveHead = m_bAboveHead ;
|
|
pDri->m_bAggrBottom = m_bAggrBottom ;
|
|
}
|
|
catch( ...) {
|
|
delete pDri ;
|
|
return nullptr ;
|
|
}
|
|
}
|
|
// ritorno l'oggetto
|
|
return pDri ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Dump( string& sOut, bool bMM, const char* szNewLine) const
|
|
{
|
|
sOut += GetClassName() + "[mm]" + szNewLine ;
|
|
sOut += KEY_PHASE + EQUAL + ToString( m_nPhase) + szNewLine ;
|
|
sOut += KEY_IDS + EQUAL + ToString( m_vId) + szNewLine ;
|
|
for ( int i = 0 ; i < m_Params.GetSize() ; ++ i)
|
|
sOut += m_Params.ToString( i) + szNewLine ;
|
|
for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i)
|
|
sOut += m_TParams.ToString( i) + szNewLine ;
|
|
sOut += KEY_NUM + EQUAL + ToString( m_nDrillings) + szNewLine ;
|
|
sOut += KEY_STAT + EQUAL + ToString( m_nStatus) + szNewLine ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Save( int nBaseId, STRVECTOR& vString) const
|
|
{
|
|
try {
|
|
int nSize = 1 + m_Params.GetSize() + m_TParams.GetSize() + 3 ;
|
|
vString.insert( vString.begin(), nSize, "") ;
|
|
int k = - 1 ;
|
|
if ( ! SetVal( KEY_IDS, m_vId, vString[++k]))
|
|
return false ;
|
|
for ( int i = 0 ; i < m_Params.GetSize() ; ++ i)
|
|
vString[++k] = m_Params.ToString( i) ;
|
|
for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i)
|
|
vString[++k] = m_TParams.ToString( i) ;
|
|
if ( ! SetVal( KEY_PHASE, m_nPhase, vString[++k]))
|
|
return false ;
|
|
if ( ! SetVal( KEY_NUM, m_nDrillings, vString[++k]))
|
|
return false ;
|
|
if ( ! SetVal( KEY_STAT, m_nStatus, vString[++k]))
|
|
return false ;
|
|
}
|
|
catch( ...) {
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Load( const STRVECTOR& vString, int nBaseGdbId)
|
|
{
|
|
int nSize = int( vString.size()) ;
|
|
// lista identificativi geometrie da lavorare
|
|
int k = - 1 ;
|
|
if ( k >= nSize - 1 || ! GetVal( vString[++k], KEY_IDS, m_vId))
|
|
return false ;
|
|
for ( auto& Sel : m_vId)
|
|
Sel.nId += nBaseGdbId ;
|
|
// parametri lavorazione
|
|
for ( int i = 0 ; i < m_Params.GetSize() ; ++ i) {
|
|
int nKey ;
|
|
if ( k >= nSize - 1 || ! m_Params.FromString( vString[++k], nKey) || nKey != i) {
|
|
if ( m_Params.IsOptional( i))
|
|
-- k ;
|
|
else
|
|
return false ;
|
|
}
|
|
}
|
|
// parametri utensile
|
|
for ( int i = 0 ; i < m_TParams.GetSize() ; ++ i) {
|
|
int nKey ;
|
|
if ( k >= nSize - 1 || ! m_TParams.FromString( vString[++k], nKey) || nKey != i)
|
|
return false ;
|
|
}
|
|
// parametri di stato
|
|
while ( k < nSize - 1) {
|
|
// separo chiave da valore
|
|
string sKey, sVal ;
|
|
SplitFirst( vString[++k], "=", sKey, sVal) ;
|
|
// leggo
|
|
if ( sKey == KEY_PHASE) {
|
|
if ( ! FromString( sVal, m_nPhase))
|
|
return false ;
|
|
}
|
|
else if ( sKey == KEY_NUM) {
|
|
if ( ! FromString( sVal, m_nDrillings))
|
|
return false ;
|
|
}
|
|
else if ( sKey == KEY_STAT) {
|
|
if ( ! FromString( sVal, m_nStatus))
|
|
return false ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
//----------------------------------------------------------------------------
|
|
Drilling::Drilling( void)
|
|
{
|
|
m_Params.m_sName = "*" ;
|
|
m_Params.m_sToolName = "*" ;
|
|
m_TParams.m_sName = "*" ;
|
|
m_TParams.m_sHead = "*" ;
|
|
m_nStatus = MCH_ST_TO_VERIFY ;
|
|
m_nDrillings = 0 ;
|
|
m_bTiltingTab = false ;
|
|
m_bAboveHead = true ;
|
|
m_bAggrBottom = false ;
|
|
m_dDistBottom = 0 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Prepare( const string& sDriName)
|
|
{
|
|
// verifico il gestore lavorazioni
|
|
if ( m_pMchMgr == nullptr)
|
|
return false ;
|
|
// recupero il gestore DB utensili della macchina corrente
|
|
ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ;
|
|
if ( pTMgr == nullptr)
|
|
return false ;
|
|
// recupero il gestore DB lavorazioni della macchina corrente
|
|
MachiningsMgr* pMMgr = m_pMchMgr->GetCurrMachiningsMgr() ;
|
|
if ( pMMgr == nullptr)
|
|
return false ;
|
|
// ricerca della lavorazione di libreria con il nome indicato
|
|
const DrillingData* pDdata = GetDrillingData( pMMgr->GetMachining( sDriName)) ;
|
|
if ( pDdata == nullptr)
|
|
return false ;
|
|
m_Params = *pDdata ;
|
|
// ricerca dell'utensile usato dalla lavorazione
|
|
const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ;
|
|
if ( pTdata == nullptr)
|
|
return false ;
|
|
m_TParams = *pTdata ;
|
|
m_Params.m_sToolName = m_TParams.m_sName ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::SetParam( int nType, bool bVal)
|
|
{
|
|
switch ( nType) {
|
|
case MPA_INVERT :
|
|
if ( bVal != m_Params.m_bInvert)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_bInvert = bVal ;
|
|
return true ;
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::SetParam( int nType, int nVal)
|
|
{
|
|
switch ( nType) {
|
|
case MPA_SUBTYPE :
|
|
if ( nVal != m_Params.m_nSubType)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_nSubType = nVal ;
|
|
return true ;
|
|
case MPA_SCC :
|
|
if ( ! m_Params.VerifySolCh( nVal))
|
|
return false ;
|
|
if ( nVal != m_Params.m_nSolCh)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_nSolCh = nVal ;
|
|
return true ;
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::SetParam( int nType, double dVal)
|
|
{
|
|
switch ( nType) {
|
|
case MPA_SPEED :
|
|
if ( ! m_TParams.VerifySpeed( dVal))
|
|
return false ;
|
|
if ( abs( m_TParams.m_dSpeed - dVal) < EPS_MACH_ANG_PAR)
|
|
dVal = 0 ;
|
|
if ( abs( dVal - m_Params.m_dSpeed) > EPS_MACH_ANG_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dSpeed = dVal ;
|
|
return true ;
|
|
case MPA_FEED :
|
|
if ( abs( m_TParams.m_dFeed - dVal) < EPS_MACH_LEN_PAR)
|
|
dVal = 0 ;
|
|
if ( abs( dVal - m_Params.m_dFeed) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dFeed = dVal ;
|
|
return true ;
|
|
case MPA_STARTFEED :
|
|
if ( abs( m_TParams.m_dStartFeed - dVal) < EPS_MACH_LEN_PAR)
|
|
dVal = 0 ;
|
|
if ( abs( dVal - m_Params.m_dStartFeed) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dStartFeed = dVal ;
|
|
return true ;
|
|
case MPA_ENDFEED :
|
|
if ( abs( m_TParams.m_dEndFeed - dVal) < EPS_MACH_LEN_PAR)
|
|
dVal = 0 ;
|
|
if ( abs( dVal - m_Params.m_dEndFeed) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dEndFeed = dVal ;
|
|
return true ;
|
|
case MPA_TIPFEED :
|
|
if ( abs( m_TParams.m_dTipFeed - dVal) < EPS_MACH_LEN_PAR)
|
|
dVal = 0 ;
|
|
if ( abs( dVal - m_Params.m_dTipFeed) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dTipFeed = dVal ;
|
|
return true ;
|
|
case MPA_DEPTH : {
|
|
string sVal = ToString( dVal) ;
|
|
if ( sVal != m_Params.m_sDepth)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sDepth = sVal ;
|
|
} return true ;
|
|
case MPA_STARTPOS :
|
|
if ( abs( dVal - m_Params.m_dStartPos) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dStartPos = dVal ;
|
|
return true ;
|
|
case MPA_STARTSLOWLEN :
|
|
if ( abs( dVal - m_Params.m_dStartSlowLen) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dStartSlowLen = dVal ;
|
|
return true ;
|
|
case MPA_ENDSLOWLEN :
|
|
if ( abs( dVal - m_Params.m_dEndSlowLen) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dEndSlowLen = dVal ;
|
|
return true ;
|
|
case MPA_THROUADDLEN :
|
|
if ( abs( dVal - m_Params.m_dThroughAddLen) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dThroughAddLen = dVal ;
|
|
return true ;
|
|
case MPA_STEP :
|
|
if ( abs( dVal - m_Params.m_dStep) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dStep = dVal ;
|
|
return true ;
|
|
case MPA_RETURNPOS :
|
|
if ( abs( dVal - m_Params.m_dReturnPos) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dReturnPos = dVal ;
|
|
return true ;
|
|
case MPA_OVERLAP : {
|
|
string sVal = ToString( dVal) ;
|
|
if ( sVal != m_Params.m_sOverlap)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sOverlap = sVal ;
|
|
} return true ;
|
|
case MPA_STARTADDLEN :
|
|
if ( abs( dVal - m_Params.m_dStartAddLen) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dStartAddLen = dVal ;
|
|
return true ;
|
|
case MPA_ENDADDLEN :
|
|
if ( abs( dVal - m_Params.m_dEndAddLen) > EPS_MACH_LEN_PAR)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_dEndAddLen = dVal ;
|
|
return true ;
|
|
case MPA_OFFSET : {
|
|
string sVal = ToString( dVal) ;
|
|
if ( sVal != m_Params.m_sOverlap)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sOffset = sVal ;
|
|
} return true ;
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::SetParam( int nType, const string& sVal)
|
|
{
|
|
switch ( nType) {
|
|
case MPA_TOOL : {
|
|
const ToolData* pTdata ;
|
|
if ( ! m_Params.VerifyTool( m_pMchMgr->GetCurrToolsMgr(), sVal, pTdata))
|
|
return false ;
|
|
if ( ! SameTool( m_TParams, *pTdata))
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sToolName = sVal ;
|
|
m_Params.m_ToolUuid = pTdata->m_Uuid ;
|
|
m_TParams = *pTdata ;
|
|
} return true ;
|
|
case MPA_DEPTH_STR :
|
|
if ( sVal != m_Params.m_sDepth)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sDepth = sVal ;
|
|
return true ;
|
|
case MPA_SYSNOTES :
|
|
if ( sVal != m_Params.m_sSysNotes)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sSysNotes = sVal ;
|
|
return true ;
|
|
case MPA_USERNOTES :
|
|
if ( sVal != m_Params.m_sUserNotes)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sUserNotes = sVal ;
|
|
return true ;
|
|
case MPA_OVERLAP_STR :
|
|
if ( sVal != m_Params.m_sOverlap)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sOverlap = sVal ;
|
|
return true ;
|
|
case MPA_OFFSET_STR :
|
|
if ( sVal != m_Params.m_sOffset)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sOffset = sVal ;
|
|
return true ;
|
|
case MPA_INITANGS :
|
|
if ( sVal != m_Params.m_sInitAngs)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sInitAngs = sVal ;
|
|
return true ;
|
|
case MPA_BLOCKEDAXIS :
|
|
if ( sVal != m_Params.m_sBlockedAxis)
|
|
m_nStatus |= MCH_ST_PARAM_MODIF ;
|
|
m_Params.m_sBlockedAxis = sVal ;
|
|
return true ;
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::SetGeometry( const SELVECTOR& vIds)
|
|
{
|
|
// verifico validità gestore generale e gestore DB geometrico
|
|
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
|
|
return false ;
|
|
// reset della geometria corrente
|
|
m_vId.clear() ;
|
|
// se lavorazione standard
|
|
if ( m_Params.m_nSubType == DRI_SUB_STD) {
|
|
// recupero il valore di tolleranza sul diametro
|
|
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
|
|
// verifico che gli identificativi rappresentino dei fori con il corretto diametro
|
|
for ( int i = 0 ; i < int( vIds.size()) ; ++ i) {
|
|
// recupero i dati del foro
|
|
Hole hole ;
|
|
if ( ! GetHoleData( vIds[i], hole) || ! VerifyDiameter( hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
|
|
string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
|
|
m_pMchMgr->SetWarning( 2151, sInfo) ;
|
|
continue ;
|
|
}
|
|
// posso aggiungere alla lista
|
|
m_vId.push_back( vIds[i]) ;
|
|
}
|
|
}
|
|
// altrimenti se lavorazione lungo curve
|
|
else if ( m_Params.m_nSubType == DRI_SUB_ALONG_CURVE) {
|
|
// verifico che gli identificativi rappresentino delle curve
|
|
for ( int i = 0 ; i < int( vIds.size()) ; ++ i) {
|
|
if ( ( m_pGeomDB->GetGeoType( vIds[i].nId) & GEO_CURVE) == 0) {
|
|
string sInfo = "Warning in Drilling : Skipped entity " + ToString( vIds[i].nId) ;
|
|
m_pMchMgr->SetWarning( 2151, sInfo) ;
|
|
continue ;
|
|
}
|
|
// posso aggiungere alla lista
|
|
m_vId.push_back( vIds[i]) ;
|
|
}
|
|
}
|
|
// aggiorno lo stato
|
|
m_nStatus |= MCH_ST_GEO_MODIF ;
|
|
// restituisco presenza geometria da lavorare
|
|
return ( ! m_vId.empty()) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Preview( bool bRecalc)
|
|
{
|
|
// reset numero forature nella lavorazione
|
|
m_nDrillings = 0 ;
|
|
// verifico validità gestore DB geometrico e Id del gruppo
|
|
if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId))
|
|
return false ;
|
|
// recupero gruppo per geometria di Preview
|
|
int nPvId = m_pGeomDB->GetFirstNameInGroup( m_nOwnerId, MCH_PV) ;
|
|
// se non c'è, lo aggiungo
|
|
if ( nPvId == GDB_ID_NULL) {
|
|
nPvId = m_pGeomDB->AddGroup( GDB_ID_NULL, m_nOwnerId, Frame3d()) ;
|
|
if ( nPvId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nPvId, MCH_PV) ;
|
|
}
|
|
// altrimenti lo svuoto
|
|
else
|
|
m_pGeomDB->EmptyGroup( nPvId) ;
|
|
|
|
// aggiorno dati geometrici dell'utensile
|
|
if ( ! UpdateToolData()) {
|
|
m_pMchMgr->SetLastError( 2101, "Error in Drilling : UpdateToolData failed") ;
|
|
return false ;
|
|
}
|
|
|
|
// se lavorazione standard
|
|
if ( m_Params.m_nSubType == DRI_SUB_STD)
|
|
return StdandardProcess( bRecalc, nPvId, GDB_ID_NULL) ;
|
|
// se altrimenti lavorazione lungo curve
|
|
else if ( m_Params.m_nSubType == DRI_SUB_ALONG_CURVE)
|
|
return AlongCurveProcess( bRecalc, nPvId, GDB_ID_NULL) ;
|
|
// altrimenti errore
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Apply( bool bRecalc, bool bPostApply)
|
|
{
|
|
// reset numero forature nella lavorazione
|
|
int nCurrDrillings = m_nDrillings ;
|
|
m_nDrillings = 0 ;
|
|
|
|
// verifico validità gestore DB geometrico e Id del gruppo
|
|
if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId))
|
|
return false ;
|
|
|
|
// aggiorno dati geometrici dell'utensile
|
|
bool bToolChanged = true ;
|
|
if ( ! UpdateToolData( &bToolChanged)) {
|
|
m_pMchMgr->SetLastError( 2101, "Error in Drilling : UpdateToolData failed") ;
|
|
return false ;
|
|
}
|
|
|
|
// verifico se necessario continuare nell'aggiornamento
|
|
if ( ! bRecalc && ! bToolChanged &&
|
|
( m_nStatus == MCH_ST_OK || ( ! bPostApply && m_nStatus == MCH_ST_NO_POSTAPPL))) {
|
|
// confermo i percorsi di lavorazione
|
|
m_nDrillings = nCurrDrillings ;
|
|
LOG_DBG_INFO( GetEMkLogger(), "Drilling apply skipped : status already ok") ;
|
|
// eseguo aggiornamento assi macchina e collegamento con operazione precedente
|
|
if ( ! Update( bPostApply))
|
|
return false ;
|
|
LOG_DBG_INFO( GetEMkLogger(), "Update done") ;
|
|
// esco con successo
|
|
return true ;
|
|
}
|
|
m_nStatus = MCH_ST_TO_VERIFY ;
|
|
|
|
// 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) ;
|
|
|
|
// se lavorazione standard
|
|
if ( m_Params.m_nSubType == DRI_SUB_STD) {
|
|
if ( ! StdandardProcess( bRecalc, GDB_ID_NULL, nClId))
|
|
return false ;
|
|
}
|
|
// se altrimenti lavorazione lungo curve
|
|
else if ( m_Params.m_nSubType == DRI_SUB_ALONG_CURVE) {
|
|
if ( ! AlongCurveProcess( bRecalc, GDB_ID_NULL, nClId))
|
|
return false ;
|
|
}
|
|
// altrimenti errore
|
|
else
|
|
return false ;
|
|
|
|
// assegno ingombri dei vari percorsi di lavorazione e della lavorazione nel suo complesso
|
|
CalcAndSetBBox( nClId) ;
|
|
|
|
// eseguo aggiornamento assi macchina e collegamento con operazione precedente
|
|
if ( ! Update( bPostApply))
|
|
return false ;
|
|
|
|
// aggiorno stato della lavorazione
|
|
m_nStatus = ( bPostApply ? MCH_ST_OK : MCH_ST_NO_POSTAPPL) ;
|
|
// dichiaro successiva da aggiornare
|
|
UpdateFollowingOperationsStatus( MCH_ST_OTH_MODIF) ;
|
|
|
|
LOG_DBG_INFO( GetEMkLogger(), "Drilling apply done") ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Update( bool bPostApply)
|
|
{
|
|
// verifico validità gestore DB geometrico e Id del gruppo
|
|
if ( m_pGeomDB == nullptr || ! m_pGeomDB->ExistsObj( m_nOwnerId))
|
|
return false ;
|
|
|
|
// se lavorazione vuota, esco
|
|
if ( m_nDrillings == 0) {
|
|
m_pMchMgr->SetWarning( 2152, "Warning in Drilling : No machinable hole") ;
|
|
return true ;
|
|
}
|
|
|
|
// imposto eventuale asse bloccato da lavorazione
|
|
SetBlockedRotAxis( m_Params.m_sBlockedAxis) ;
|
|
|
|
// calcolo gli assi macchina
|
|
string sHint = ExtractHint( m_Params.m_sUserNotes) ;
|
|
if ( ! m_Params.m_sInitAngs.empty())
|
|
sHint = m_Params.m_sInitAngs ;
|
|
if ( ! CalculateAxesValues( sHint)) {
|
|
string sInfo = m_pMchMgr->GetOutstrokeInfo() ;
|
|
if ( sInfo.empty())
|
|
m_pMchMgr->SetLastError( 2109, "Error in Drilling : axes values not calculable") ;
|
|
else
|
|
m_pMchMgr->SetLastError( 2110, "Error in Drilling : outstroke ") ;
|
|
return false ;
|
|
}
|
|
|
|
// gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine della lavorazione
|
|
if ( ! AdjustStartEndMovements()) {
|
|
string sInfo = m_pMchMgr->GetOutstrokeInfo() ;
|
|
if ( sInfo.empty())
|
|
m_pMchMgr->SetLastError( 2111, "Error in Drilling : link movements not calculable") ;
|
|
else
|
|
m_pMchMgr->SetLastError( 2112, "Error in Drilling : link outstroke ") ;
|
|
return false ;
|
|
}
|
|
|
|
// assegno estremi degli assi dei vari percorsi di lavorazione e della lavorazione nel suo complesso
|
|
CalcAndSetAxesBBox() ;
|
|
|
|
// esecuzione eventuali personalizzazioni
|
|
string sErr ;
|
|
if ( bPostApply && ! PostApply( sErr)) {
|
|
if ( ! IsEmptyOrSpaces( sErr))
|
|
m_pMchMgr->SetLastError( 2113, sErr) ;
|
|
else
|
|
m_pMchMgr->SetLastError( 2113, "Error in Drilling : post apply not calculable") ;
|
|
return false ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::StdandardProcess( bool bRecalc, int nPvId, int nClId)
|
|
{
|
|
|
|
// elaboro i singoli fori
|
|
int i = 0 ;
|
|
for ( const auto& vId : m_vId) {
|
|
// se richiesto preview
|
|
if ( nPvId != GDB_ID_NULL) {
|
|
if ( ! GenerateHolePv( i, vId, MCH_PATH, nPvId))
|
|
return false ;
|
|
// creo la regione di ingombro del foro
|
|
int nDriId = m_pGeomDB->GetFirstInGroup( m_pGeomDB->GetLastGroupInGroup( nPvId)) ;
|
|
GenerateHoleRegionPv( nDriId, 1, nPvId) ;
|
|
}
|
|
// se richiesta lavorazione
|
|
if ( nClId != GDB_ID_NULL) {
|
|
if ( ! GenerateHoleCl( i, vId, MCH_PATH, nClId))
|
|
return false ;
|
|
}
|
|
// incremento indice
|
|
++ i ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::AlongCurveProcess( bool bRecalc, int nPvId, int nClId)
|
|
{
|
|
// 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 ;
|
|
}
|
|
|
|
// se necessario, eseguo concatenamento ed inserisco i percorsi sotto la geometria ausiliaria
|
|
if ( bChain && ! Chain( nAuxId)) {
|
|
m_pMchMgr->SetLastError( 2108, "Error in Drilling : Chaining failed") ;
|
|
return false ;
|
|
}
|
|
|
|
// calcolo ogni singola catena
|
|
int nPathId = m_pGeomDB->GetFirstGroupInGroup( nAuxId) ;
|
|
while ( nPathId != GDB_ID_NULL) {
|
|
if ( ! ProcessPath( nPathId, nPvId, nClId))
|
|
return false ;
|
|
nPathId = m_pGeomDB->GetNextGroup( nPathId) ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::Chain( int nGrpDestId)
|
|
{
|
|
// vettore puntatori alle curve
|
|
ICURVEPOVECTOR vpCrvs ;
|
|
vpCrvs.reserve( m_vId.size()) ;
|
|
// recupero tutte le curve e le porto in globale
|
|
for ( const auto& Id : m_vId) {
|
|
// prendo curva
|
|
vpCrvs.emplace_back( GetCurve( Id)) ;
|
|
// ne verifico la validità
|
|
if ( IsNull( vpCrvs.back())) {
|
|
string sInfo = "Warning in Drilling : Skipped entity " + ToString( Id) ;
|
|
m_pMchMgr->SetWarning( 2151, sInfo) ;
|
|
vpCrvs.back().Reset() ;
|
|
}
|
|
}
|
|
// preparo i dati per il concatenamento
|
|
bool bFirst = true ;
|
|
Point3d ptNear = ORIG ;
|
|
double dToler = 10 * EPS_SMALL ;
|
|
ChainCurves chainC ;
|
|
chainC.Init( true, dToler, int( vpCrvs.size())) ;
|
|
for ( size_t i = 0 ; i < vpCrvs.size() ; ++ i) {
|
|
// recupero la curva e il suo riferimento
|
|
ICurve* pCrv = vpCrvs[i] ;
|
|
if ( pCrv == nullptr)
|
|
continue ;
|
|
// recupero i dati della curva necessari al concatenamento e li assegno
|
|
Point3d ptStart, ptEnd ;
|
|
Vector3d vtStart, vtEnd ;
|
|
if ( ! pCrv->GetStartPoint( ptStart) || ! pCrv->GetStartDir( vtStart) ||
|
|
! pCrv->GetEndPoint( ptEnd) || ! pCrv->GetEndDir( vtEnd))
|
|
return false ;
|
|
if ( ! chainC.AddCurve( int( i + 1), ptStart, vtStart, ptEnd, vtEnd))
|
|
return false ;
|
|
// se prima curva, assegno inizio della ricerca
|
|
if ( bFirst) {
|
|
ptNear = ptStart + 10 * EPS_SMALL * vtStart ;
|
|
bFirst = false ;
|
|
}
|
|
}
|
|
// recupero i percorsi concatenati
|
|
int nCount = 0 ;
|
|
INTVECTOR vnId2 ;
|
|
while ( chainC.GetChainFromNear( ptNear, false, vnId2)) {
|
|
// creo una curva composita
|
|
PtrOwner<ICurveComposite> pCrvCompo( CreateCurveComposite()) ;
|
|
if ( IsNull( pCrvCompo))
|
|
return false ;
|
|
// estrusione e spessore
|
|
Vector3d vtExtr = Z_AX ;
|
|
double dThick = 0 ;
|
|
// vettore Id originali
|
|
SELVECTOR vId2 ;
|
|
vId2.reserve( vnId2.size()) ;
|
|
// recupero le curve semplici e le inserisco nella curva composita
|
|
for ( size_t i = 0 ; i < vnId2.size() ; ++ i) {
|
|
int nId = abs( vnId2[i]) - 1 ;
|
|
bool bInvert = ( vnId2[i] < 0) ;
|
|
vId2.emplace_back( m_vId[nId]) ;
|
|
// recupero la curva
|
|
ICurve* pCrv = vpCrvs[nId] ;
|
|
// se necessario, la inverto
|
|
if ( bInvert)
|
|
pCrv->Invert() ;
|
|
// recupero eventuali estrusione e spessore
|
|
Vector3d vtTemp ;
|
|
if ( pCrv->GetExtrusion( vtTemp)) {
|
|
vtExtr = vtTemp ;
|
|
double dTemp ;
|
|
if ( pCrv->GetThickness( dTemp) && abs( dTemp) > abs( dThick))
|
|
dThick = dTemp ;
|
|
}
|
|
// la aggiungo alla curva composta
|
|
if ( ! pCrvCompo->AddCurve( ::Release( vpCrvs[nId]), true, dToler))
|
|
return false ;
|
|
}
|
|
// se non sono state inserite curve, vado oltre
|
|
if ( pCrvCompo->GetCurveCount() == 0)
|
|
continue ;
|
|
// imposto estrusione e spessore
|
|
pCrvCompo->SetExtrusion( vtExtr) ;
|
|
pCrvCompo->SetThickness( dThick) ;
|
|
// aggiorno il nuovo punto vicino
|
|
pCrvCompo->GetEndPoint( ptNear) ;
|
|
// creo nuovo gruppo
|
|
int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nGrpDestId, Frame3d()) ;
|
|
if ( nPathId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nPathId, MCH_PATH + ToString( ++ nCount)) ;
|
|
m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( vId2)) ;
|
|
// inserisco la curva composita nel gruppo destinazione
|
|
int nNewId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, ::Release( pCrvCompo)) ;
|
|
if ( nNewId == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
ICurve*
|
|
Drilling::GetCurve( SelData Id)
|
|
{
|
|
// 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))
|
|
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
|
|
Drilling::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) ;
|
|
|
|
// recupero la curva composita
|
|
int nCrvId = m_pGeomDB->GetFirstInGroup( nPathId) ;
|
|
// recupero nome del path
|
|
string sPName ;
|
|
m_pGeomDB->GetName( nPathId, sPName) ;
|
|
|
|
// valuto l'espressione dell'offset e della sovrapposizione
|
|
ExeLuaSetGlobNumVar( "D", m_TParams.m_dDiam) ;
|
|
double dOffset ;
|
|
if ( ! ExeLuaEvalNumExpr( m_Params.m_sOffset, &dOffset)) {
|
|
m_pMchMgr->SetLastError( 2102, "Error in Drilling : Offset not computable") ;
|
|
return false ;
|
|
}
|
|
double dOverlap ;
|
|
if ( ! ExeLuaEvalNumExpr( m_Params.m_sOverlap, &dOverlap)) {
|
|
m_pMchMgr->SetLastError( 2103, "Error in Drilling : Overlap not computable") ;
|
|
return false ;
|
|
}
|
|
|
|
// disabilito eventuale registrazione comandi EXE (riabilitazione automatica)
|
|
CmdLogOff cmdLogOff ;
|
|
|
|
// genero le circonferenze
|
|
int nCount = 0 ;
|
|
int nFirstId = ExeCreateCirclesAlongCurve( nTempId, nCrvId, dOffset, dOverlap, m_Params.m_dStartAddLen,
|
|
m_Params.m_dEndAddLen, m_TParams.m_dDiam, &nCount) ;
|
|
|
|
// se richiesta anteprima
|
|
if ( nPvId != GDB_ID_NULL) {
|
|
// creo l'anteprima dei fori
|
|
for ( int i = 0 ; i < nCount ; ++ i) {
|
|
// identificativo circonferenza
|
|
int nId = nFirstId + i ;
|
|
// calcolo il preview del foro
|
|
if ( ! GenerateHolePv( i, nId, sPName + "_", nPvId))
|
|
return false ;
|
|
}
|
|
// creo la regione di ingombro dei fori
|
|
GenerateHoleRegionPv( nFirstId, nCount, nPvId) ;
|
|
}
|
|
|
|
// se richiesta lavorazione
|
|
if ( nClId != GDB_ID_NULL) {
|
|
// creo lavorazione dei fori
|
|
for ( int i = 0 ; i < nCount ; ++ i) {
|
|
// identificativo circonferenza
|
|
int nId = nFirstId + i ;
|
|
// calcolo la lavorazione del foro
|
|
if ( ! GenerateHoleCl( i, nId, sPName + "_", nClId))
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GenerateHolePv( int nInd, const SelData& nCircId, const string& sPName, int nPvId)
|
|
{
|
|
// creo gruppo per geometria di lavorazione del foro
|
|
int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nPvId, Frame3d()) ;
|
|
if ( nPathId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nPathId, sPName + ToString( nInd + 1)) ;
|
|
m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( nCircId)) ;
|
|
m_pGeomDB->SetMaterial( nPathId, GREEN) ;
|
|
// recupero il valore di tolleranza sul diametro
|
|
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
|
|
// recupero i dati del foro
|
|
Hole hole ;
|
|
if ( ! GetHoleData( nCircId, hole) || ! VerifyDiameter( hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
|
|
m_pGeomDB->Erase( nPathId) ;
|
|
string sInfo = "Warning in Drilling : Skipped entity " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2151, sInfo) ;
|
|
return true ;
|
|
}
|
|
// limito lunghezza foro a massima lavorazione della punta
|
|
if ( hole.dLen > m_TParams.m_dMaxMat + EPS_SMALL) {
|
|
hole.dLen = m_TParams.m_dMaxMat ;
|
|
string sInfo = "Warning in Drilling : Drill bit too short for Hole " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2155, sInfo) ;
|
|
}
|
|
// inserisco circonferenza che rappresenta il foro
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc) || ! pCrvArc->Set( hole.ptIni, hole.vtDir, 0.5 * m_TParams.m_dDiam))
|
|
return false ;
|
|
// assegno il versore estrusione e lo spessore
|
|
pCrvArc->SetExtrusion( hole.vtDir) ;
|
|
pCrvArc->SetThickness( - hole.dLen) ;
|
|
// inserisco nel DB
|
|
int nDriId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nPathId, Release( pCrvArc)) ;
|
|
// assegno nome e colore
|
|
m_pGeomDB->SetName( nDriId, MCH_PV_CUT) ;
|
|
m_pGeomDB->SetMaterial( nDriId, LIME) ;
|
|
// aggiorno numero forature
|
|
++ m_nDrillings ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GenerateHoleCl( int nInd, const SelData& nCircId, const string& sPName, int nClId)
|
|
{
|
|
// creo gruppo per geometria di lavorazione del foro
|
|
int nPathId = m_pGeomDB->AddGroup( GDB_ID_NULL, nClId, Frame3d()) ;
|
|
if ( nPathId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nPathId, sPName + ToString( nInd + 1)) ;
|
|
m_pGeomDB->SetInfo( nPathId, KEY_IDS, ToString( nCircId)) ;
|
|
m_pGeomDB->SetMaterial( nPathId, GREEN) ;
|
|
// recupero il valore di tolleranza sul diametro
|
|
double dDiamTol = m_pMchMgr->GetCurrMachiningsMgr()->GetHoleDiamToler() ;
|
|
// recupero i dati del foro
|
|
Hole hole ;
|
|
if ( ! GetHoleData( nCircId, hole) || ! VerifyDiameter( hole.dDiam, m_TParams.m_dDiam, dDiamTol)) {
|
|
m_pGeomDB->Erase( nPathId) ;
|
|
string sInfo = "Warning in Drilling : Skipped entity " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2151, sInfo) ;
|
|
return true ;
|
|
}
|
|
// se richiesta inversione e foro passante, provvedo
|
|
if ( m_Params.m_bInvert) {
|
|
if ( hole.bBlind) {
|
|
m_pMchMgr->SetLastError( 2114, "Error in Drilling : blind hole not reversible") ;
|
|
return false ;
|
|
}
|
|
else {
|
|
hole.ptIni -= hole.vtDir * hole.dThick ;
|
|
hole.vtDir.Invert() ;
|
|
}
|
|
}
|
|
// se lavorazione del foro non arriva al suo fondo, lo considero cieco
|
|
if ( hole.dLen < hole.dThick - 10 * EPS_SMALL)
|
|
hole.bBlind = true ;
|
|
// imposto elevazione da lunghezza foro con possibilità di sovrascrittura da info
|
|
double dElev = hole.dLen ;
|
|
double dMaxElev ;
|
|
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "MaxElev="), dMaxElev) && dElev > dMaxElev) {
|
|
dElev = dMaxElev ;
|
|
hole.ptIni += hole.vtDir * ( dElev - hole.dLen) ;
|
|
hole.dLen = dElev ;
|
|
}
|
|
// limito lunghezza foro a massima lavorazione della punta
|
|
double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ;
|
|
if ( ( dElev + dAddLen) > m_TParams.m_dMaxMat + EPS_SMALL) {
|
|
hole.dLen = m_TParams.m_dMaxMat + max( hole.dLen - dElev, 0.) ;
|
|
hole.bBlind = true ;
|
|
string sInfo = "Warning in Drilling : Drill bit too short for Hole " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2155, sInfo) ;
|
|
}
|
|
// verifico se tavola basculante
|
|
bool bTiltTab = false ;
|
|
m_bTiltingTab = ( m_pMchMgr->GetCurrMachine()->GetCurrTableIsTilting( bTiltTab) && bTiltTab) ;
|
|
// verifico se testa da sopra (Z+)
|
|
m_bAboveHead = m_pMchMgr->GetHeadAbove( m_TParams.m_sHead) ;
|
|
// verifiche per foro verso il basso
|
|
m_bAggrBottom = false ;
|
|
if ( ! VerifyHoleFromBottom( hole, nCircId))
|
|
return false ;
|
|
// assegno il vettore estrazione al gruppo del percorso
|
|
m_pGeomDB->SetInfo( nPathId, KEY_EXTR, hole.vtDir) ;
|
|
// assegno i punti di inizio e fine al gruppo del percorso
|
|
m_pGeomDB->SetInfo( nPathId, KEY_START, hole.ptIni) ;
|
|
m_pGeomDB->SetInfo( nPathId, KEY_END, hole.ptIni) ;
|
|
// assegno l'elevazione massima
|
|
m_pGeomDB->SetInfo( nPathId, KEY_ELEV, hole.dLen) ;
|
|
// foro normale
|
|
if ( m_Params.m_dStep < EPS_SMALL ||
|
|
m_Params.m_dStep > hole.dLen - EPS_SMALL) {
|
|
if ( DoStandardDrilling( hole, nCircId, nPathId)) {
|
|
// aggiorno numero forature
|
|
++ m_nDrillings ;
|
|
}
|
|
else {
|
|
m_pGeomDB->Erase( nPathId) ;
|
|
string sInfo = "Warning in Drilling : Skipped by Standard Drilling " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2156, sInfo) ;
|
|
}
|
|
}
|
|
else {
|
|
if ( DoPeckDrilling( hole, nCircId, nPathId)) {
|
|
// aggiorno numero forature
|
|
++ m_nDrillings ;
|
|
}
|
|
else {
|
|
m_pGeomDB->Erase( nPathId) ;
|
|
string sInfo = "Warning in Drilling : Skipped by Peck Drilling " + ToString( nCircId) ;
|
|
m_pMchMgr->SetWarning( 2157, sInfo) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GenerateHoleRegionPv( int nFirstId, int nCount, int nPvId)
|
|
{
|
|
// raggio dei fori
|
|
double dRad = m_TParams.m_dDiam / 2 ;
|
|
// extra raggio
|
|
double dExtraR = m_pMchMgr->GetCurrMachiningsMgr()->GetExtraROnDrillRegion() ;
|
|
|
|
// gruppo di inserimento
|
|
int nGroupId = m_pGeomDB->GetLastGroupInGroup( nPvId) ;
|
|
|
|
// creo polyline che unisce i centri
|
|
PolyLine PL ;
|
|
for ( int i = 0 ; i < nCount ; ++ i) {
|
|
int nId = nFirstId + i ;
|
|
const ICurveArc* pArc = GetCurveArc( m_pGeomDB->GetGeoObj( nId)) ;
|
|
if ( pArc == nullptr)
|
|
return false ;
|
|
PL.AddUPoint( i, pArc->GetCenter()) ;
|
|
}
|
|
|
|
// calcolo la regione
|
|
ISurfFlatRegion* pSfr = nullptr ;
|
|
|
|
// se polilinea con almeno due punti
|
|
if ( PL.GetPointNbr() > 1) {
|
|
// ne derivo una curva composita
|
|
PtrOwner<ICurveComposite> pCompo1( CreateCurveComposite()) ;
|
|
if ( IsNull( pCompo1) || ! pCompo1->FromPolyLine( PL))
|
|
return false ;
|
|
// calcolo la regione
|
|
pSfr = GetSurfFlatRegionFromFatCurve( Release( pCompo1), dRad + dExtraR, false, true) ;
|
|
if ( pSfr == nullptr)
|
|
return false ;
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// approssimo l'unico foro
|
|
pSfr = GetSurfFlatRegionDisk( dRad + dExtraR) ;
|
|
if ( pSfr == nullptr)
|
|
return false ;
|
|
Point3d ptCen ;
|
|
PL.GetFirstPoint( ptCen) ;
|
|
pSfr->Translate( ptCen - ORIG) ;
|
|
}
|
|
|
|
// inserisco la regione nel DB
|
|
int nRId = m_pGeomDB->AddGeoObj( GDB_ID_NULL, nGroupId, pSfr) ;
|
|
if ( nRId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nRId, MCH_PV_RCUT) ;
|
|
m_pGeomDB->SetMaterial( nRId, INVISIBLE) ;
|
|
// la copio anche come regione ridotta
|
|
int nRrId = m_pGeomDB->Copy( nRId, GDB_ID_NULL, nGroupId) ;
|
|
if ( nRrId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGeomDB->SetName( nRrId, MCH_PV_RRCUT) ;
|
|
m_pGeomDB->SetMaterial( nRrId, INVISIBLE) ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::VerifyDiameter( double dHdiam, double dTdiam, double dDiamTol)
|
|
{
|
|
// imposto minima tolleranza
|
|
if ( abs( dDiamTol) < 10 * EPS_SMALL)
|
|
dDiamTol = 10 * EPS_SMALL ;
|
|
// se tolleranza in più o in meno
|
|
if ( dDiamTol > 0)
|
|
return ( abs( dHdiam - dTdiam) < dDiamTol) ;
|
|
// altrimenti tolleranza solo in meno
|
|
return ( dTdiam < dHdiam + 10 * EPS_SMALL && dTdiam > dHdiam + dDiamTol - 10 * EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetParam( int nType, bool& bVal) const
|
|
{
|
|
switch ( nType) {
|
|
case MPA_INVERT :
|
|
bVal = m_Params.m_bInvert ;
|
|
return true ;
|
|
}
|
|
bVal = false ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetParam( int nType, int& nVal) const
|
|
{
|
|
switch ( nType) {
|
|
case MPA_TYPE :
|
|
nVal = MT_DRILLING ;
|
|
return true ;
|
|
case MPA_SUBTYPE :
|
|
nVal = m_Params.m_nSubType ;
|
|
return true ;
|
|
case MPA_SCC :
|
|
nVal = m_Params.m_nSolCh ;
|
|
return true ;
|
|
}
|
|
nVal = 0 ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetParam( int nType, double& dVal) const
|
|
{
|
|
switch ( nType) {
|
|
case MPA_SPEED :
|
|
dVal = GetSpeed() ;
|
|
return true ;
|
|
case MPA_FEED :
|
|
dVal = GetFeed() ;
|
|
return true ;
|
|
case MPA_STARTFEED :
|
|
dVal = GetStartFeed() ;
|
|
return true ;
|
|
case MPA_ENDFEED :
|
|
dVal = GetEndFeed() ;
|
|
return true ;
|
|
case MPA_TIPFEED :
|
|
dVal = GetTipFeed() ;
|
|
return true ;
|
|
case MPA_STARTPOS :
|
|
dVal = m_Params.m_dStartPos ;
|
|
return true ;
|
|
case MPA_STARTSLOWLEN :
|
|
dVal = m_Params.m_dStartSlowLen ;
|
|
return true ;
|
|
case MPA_ENDSLOWLEN :
|
|
dVal = m_Params.m_dEndSlowLen ;
|
|
return true ;
|
|
case MPA_THROUADDLEN :
|
|
dVal = m_Params.m_dThroughAddLen ;
|
|
return true ;
|
|
case MPA_STEP :
|
|
dVal = m_Params.m_dStep ;
|
|
return true ;
|
|
case MPA_RETURNPOS :
|
|
dVal = m_Params.m_dReturnPos ;
|
|
return true ;
|
|
case MPA_STARTADDLEN :
|
|
dVal = m_Params.m_dStartAddLen ;
|
|
return true ;
|
|
case MPA_ENDADDLEN :
|
|
dVal = m_Params.m_dEndAddLen ;
|
|
return true ;
|
|
}
|
|
dVal = 0 ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetParam( int nType, string& sVal) const
|
|
{
|
|
switch ( nType) {
|
|
case MPA_NAME :
|
|
sVal = m_Params.m_sName ;
|
|
return true ;
|
|
case MPA_TOOL :
|
|
sVal = m_Params.m_sToolName ;
|
|
return true ;
|
|
case MPA_DEPTH_STR :
|
|
sVal = m_Params.m_sDepth ;
|
|
return true ;
|
|
case MPA_TUUID :
|
|
sVal = ToString( m_Params.m_ToolUuid) ;
|
|
return true ;
|
|
case MPA_UUID :
|
|
sVal = ToString( m_Params.m_Uuid) ;
|
|
return true ;
|
|
case MPA_SYSNOTES :
|
|
sVal = m_Params.m_sSysNotes ;
|
|
return true ;
|
|
case MPA_USERNOTES :
|
|
sVal = m_Params.m_sUserNotes ;
|
|
return true ;
|
|
case MPA_OVERLAP_STR :
|
|
sVal = m_Params.m_sOverlap ;
|
|
return true ;
|
|
case MPA_OFFSET_STR :
|
|
sVal = m_Params.m_sOffset ;
|
|
return true ;
|
|
case MPA_INITANGS :
|
|
sVal = m_Params.m_sInitAngs ;
|
|
return true ;
|
|
case MPA_BLOCKEDAXIS :
|
|
sVal = m_Params.m_sBlockedAxis ;
|
|
return true ;
|
|
}
|
|
sVal = "" ;
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
const ToolData&
|
|
Drilling::GetToolData( void) const
|
|
{
|
|
return m_TParams ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::UpdateToolData( bool* pbChanged)
|
|
{
|
|
// recupero il gestore DB utensili della macchina corrente
|
|
ToolsMgr* pTMgr = m_pMchMgr->GetCurrToolsMgr() ;
|
|
if ( pTMgr == nullptr)
|
|
return false ;
|
|
// recupero l'utensile nel DB utensili
|
|
const ToolData* pTdata = pTMgr->GetTool( m_Params.m_ToolUuid) ;
|
|
if ( pTdata == nullptr)
|
|
return false ;
|
|
// verifico se sono diversi (ad esclusione del nome)
|
|
m_TParams.m_sName = pTdata->m_sName ;
|
|
bool bChanged = ! SameTool( m_TParams, *pTdata) ;
|
|
// aggiorno comunque i parametri
|
|
m_TParams = *pTdata ;
|
|
// eventuali segnalazioni
|
|
if ( ! EqualNoCase( m_Params.m_sToolName, m_TParams.m_sName)) {
|
|
string sInfo = "Warning in Drilling : tool name changed (" +
|
|
m_Params.m_sToolName + "->" + m_TParams.m_sName + ")" ;
|
|
m_pMchMgr->SetWarning( 2153, sInfo) ;
|
|
m_Params.m_sToolName = m_TParams.m_sName ;
|
|
}
|
|
if ( bChanged) {
|
|
string sInfo = "Warning in Drilling : tool data changed (" +
|
|
m_Params.m_sToolName + ")" ;
|
|
m_pMchMgr->SetWarning( 2154, sInfo) ;
|
|
}
|
|
// se definito parametro di ritorno, lo assegno
|
|
if ( pbChanged != nullptr)
|
|
*pbChanged = bChanged ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetGeometry( SELVECTOR& vIds) const
|
|
{
|
|
// restituisco l'elenco delle entità
|
|
vIds = m_vId ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::GetHoleData( SelData Id, Hole& hole)
|
|
{
|
|
PtrOwner<ICurveArc> pMyArc ;
|
|
// deve essere un arco o una composita formata da un arco
|
|
const ICurveArc* pArc = GetCurveArc( m_pGeomDB->GetGeoObj( Id.nId)) ;
|
|
if ( pArc == nullptr) {
|
|
const ICurveComposite* pCompo = GetCurveComposite( m_pGeomDB->GetGeoObj( Id.nId)) ;
|
|
Point3d ptCen ;
|
|
Vector3d vtN ;
|
|
double dRad ;
|
|
bool bCCW ;
|
|
if ( pCompo == nullptr || ! pCompo->IsACircle( 100 * EPS_SMALL, ptCen, vtN, dRad, bCCW))
|
|
return false ;
|
|
pMyArc.Set( CreateCurveArc()) ;
|
|
if ( IsNull( pMyArc) || ! pMyArc->Set( ptCen, vtN, dRad))
|
|
return false ;
|
|
Vector3d vtExtr ; pCompo->GetExtrusion( vtExtr) ;
|
|
pMyArc->SetExtrusion( vtExtr) ;
|
|
double dThick = 0 ; pCompo->GetThickness( dThick) ;
|
|
pMyArc->SetThickness( dThick) ;
|
|
pArc = pMyArc ;
|
|
}
|
|
// ne recupero il riferimento globale
|
|
Frame3d frGlob ;
|
|
if ( ! m_pGeomDB->GetGlobFrame( Id.nId, frGlob))
|
|
return false ;
|
|
// deve avere estrusione
|
|
Vector3d vtExtr ;
|
|
if ( ! pArc->GetExtrusion( vtExtr))
|
|
return false ;
|
|
if ( vtExtr.IsSmall())
|
|
vtExtr = pArc->GetNormVersor() ;
|
|
// recupero spessore
|
|
double dThick = 0 ;
|
|
pArc->GetThickness( dThick) ;
|
|
// se diretto come asse Z, recupero distanza da fondo dei grezzi interessati dal foro
|
|
double dRbDist = 0 ;
|
|
Vector3d vtExtrG = vtExtr ;
|
|
vtExtrG.ToGlob( frGlob) ;
|
|
if ( vtExtrG.IsZplus())
|
|
GetDistanceFromRawBottom( m_nPhase, Id.nId, EPS_SMALL, dRbDist) ;
|
|
// valuto l'espressione dell'affondamento
|
|
ExeLuaSetGlobNumVar( "TH", abs( dThick)) ;
|
|
ExeLuaSetGlobNumVar( "RB", dRbDist) ;
|
|
double dDepth ;
|
|
string sMyDepth = m_Params.m_sDepth ;
|
|
if ( ! ExeLuaEvalNumExpr( ToUpper( sMyDepth), &dDepth)) {
|
|
m_pMchMgr->SetLastError( 2104, "Error in Drilling : Depth not computable") ;
|
|
return false ;
|
|
}
|
|
if ( abs( dDepth) < EPS_SMALL) {
|
|
m_pMchMgr->SetLastError( 2105, "Error in Drilling : Drill with zero depth") ;
|
|
return false ;
|
|
}
|
|
// assegno Id
|
|
hole.nOriId = Id.nId ;
|
|
// ne recupero il diametro
|
|
hole.dDiam = 2 * pArc->GetRadius() ;
|
|
// ne recupero il centro
|
|
hole.ptIni = pArc->GetCenter() + ( dThick > 0 ? vtExtr * dThick : V_NULL) ;
|
|
hole.ptIni.ToGlob( frGlob) ;
|
|
// ne recupero versore direzione e lunghezze
|
|
hole.vtDir = vtExtr ;
|
|
hole.vtDir.ToGlob( frGlob) ;
|
|
hole.vtDir.Normalize() ;
|
|
hole.dThick = abs( dThick) ;
|
|
hole.dLen = abs( dDepth) ;
|
|
// per default è cieco
|
|
hole.bBlind = true ;
|
|
// se dichiarato passante o no (1/0)
|
|
int nOpen ;
|
|
if ( FromString( ExtractInfo( m_Params.m_sUserNotes, "Open="), nOpen))
|
|
hole.bBlind = ( nOpen == 0) ;
|
|
// se verticale ed arriva fino al fondo grezzo, allora passante
|
|
else if ( hole.vtDir.IsZplus() && hole.dThick > dRbDist - EPS_SMALL)
|
|
hole.bBlind = false ;
|
|
// altrimenti determino la distanza del fondo del foro dal bordo opposto del grezzo
|
|
else {
|
|
const double BLIND_TOL = 10 ;
|
|
double dBackElev ;
|
|
if ( GetElevation( m_nPhase, hole.ptIni, - hole.vtDir, dBackElev) && ( dBackElev - hole.dThick) <= BLIND_TOL)
|
|
hole.bBlind = false ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::VerifyHoleFromBottom( const Hole& hole, SelData Id)
|
|
{
|
|
// se non è foro dal basso in alto, esco
|
|
if ( hole.vtDir.z > MIN_ZDIR_TOP_TOOL)
|
|
return true ;
|
|
// se c'è testa non dall'alto o tavola basculante, esco
|
|
if ( ! m_bAboveHead || m_bTiltingTab)
|
|
return true ;
|
|
// recupero dati di eventuale rinvio da sotto
|
|
if ( ! GetAggrBottomData( m_TParams.m_sHead, m_AggrBottom) || m_AggrBottom.nType == 0) {
|
|
string sOut = "Error in Drilling : Entity " + ToString( Id) + " skipped because missing aggregate from bottom" ;
|
|
m_pMchMgr->SetLastError( 2106, sOut) ;
|
|
return false ;
|
|
}
|
|
// calcolo la distanza minima del punto dal contorno del grezzo
|
|
double dDist ;
|
|
Vector3d vtDir ;
|
|
if ( ! GetMinDistanceFromRawSide( m_nPhase, hole.ptIni, 0, m_AggrBottom.vtMDir, MCH_AGB_DELTAMAX_MDIR, dDist, vtDir) || dDist > m_AggrBottom.dDMax) {
|
|
string sOut = "Error in Drilling : Entity " + ToString( Id) + " skipped because too far from part sides" ;
|
|
m_pMchMgr->SetLastError( 2107, sOut) ;
|
|
return false ;
|
|
}
|
|
// assegno direzione di accesso e segnalazione di utilizzo aggregato da sotto
|
|
m_vtAggrBottom = vtDir ;
|
|
m_bAggrBottom = true ;
|
|
m_dDistBottom = dDist ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::DoStandardDrilling( const Hole& hole, SelData Id, int nPathId)
|
|
{
|
|
// aggiusto alcuni parametri del ciclo di foratura
|
|
double dStartSlowLen = abs( m_Params.m_dStartSlowLen) ;
|
|
if ( abs( m_TParams.m_dStartFeed - m_TParams.m_dFeed) < EPS_SMALL)
|
|
dStartSlowLen = 0 ;
|
|
double dEndSlowLen = ( hole.bBlind ? 0 : abs( m_Params.m_dEndSlowLen)) ;
|
|
if ( abs( m_TParams.m_dTipFeed - m_TParams.m_dFeed) < EPS_SMALL)
|
|
dEndSlowLen = 0 ;
|
|
if ( ( dStartSlowLen + dEndSlowLen) > hole.dLen) {
|
|
dStartSlowLen = dStartSlowLen / ( dStartSlowLen + dEndSlowLen) * hole.dLen ;
|
|
dEndSlowLen = hole.dLen - dStartSlowLen ;
|
|
}
|
|
double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ;
|
|
bool bStartSlow = ( dStartSlowLen > EPS_SMALL) ;
|
|
bool bStd = ( ( hole.dLen - dStartSlowLen - dEndSlowLen) > EPS_SMALL) ;
|
|
bool bEndSlow = ( dEndSlowLen > EPS_SMALL) ;
|
|
// determino l'elevazione
|
|
double dElev = 0 ;
|
|
GetElevation( m_nPhase, hole.ptIni, hole.vtDir, m_TParams.m_dDiam / 2, hole.vtDir, dElev) ;
|
|
// determino alcune caratteristiche dell'utensile
|
|
double dTExtrLen = max( 0.0, m_TParams.m_dTLen - m_TParams.m_dLen) ;
|
|
// imposto dati comuni
|
|
SetPathId( nPathId) ;
|
|
SetToolDir( hole.vtDir) ;
|
|
// 1 -> punto approccio (se con aggregato da sotto è una sequenza di approccio)
|
|
SetFlag( 1) ;
|
|
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
|
|
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
|
|
double dAppr = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ;
|
|
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen) ;
|
|
if ( m_bAggrBottom) {
|
|
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
|
|
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
|
|
// se rinvio da sotto che richiede speciale rotazione
|
|
if ( m_AggrBottom.nType == 1) {
|
|
Vector3d vtAux = m_vtAggrBottom ;
|
|
vtAux.Rotate( Z_AX, 0, 1) ;
|
|
SetAuxDir( vtAux) ;
|
|
if ( AddRapidStart( ptP00, MCH_CL_AGB_DWN) == GDB_ID_NULL)
|
|
return false ;
|
|
SetAuxDir( m_vtAggrBottom) ;
|
|
SetFlag( 0) ;
|
|
if ( AddRapidMove( ptP0, MCH_CL_AGB_IN) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// altrimenti rinvio normale
|
|
else {
|
|
SetAuxDir( m_vtAggrBottom) ;
|
|
if ( AddRapidStart( ptP0, MCH_CL_AGB_IN) == GDB_ID_NULL)
|
|
return false ;
|
|
SetFlag( 0) ;
|
|
}
|
|
if ( AddRapidMove( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
else {
|
|
if ( AddRapidStart( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
SetFlag( 0) ;
|
|
// 2 -> punto fuori (se diverso dal precedente)
|
|
if ( m_Params.m_dStartPos < dAppr) {
|
|
Point3d ptP2 = hole.ptIni + hole.vtDir * ( m_Params.m_dStartPos + dTExtrLen) ;
|
|
if ( AddRapidMove( ptP2) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// 3 -> punto termine velocità ridotta iniziale (se previsto)
|
|
if ( bStartSlow) {
|
|
SetFeed( GetStartFeed()) ;
|
|
if ( ! bStd && ! bEndSlow)
|
|
SetFlag( 101) ; // fondo del foro
|
|
Point3d ptP3 = hole.ptIni - hole.vtDir * dStartSlowLen ;
|
|
if ( ! bStd && ! bEndSlow)
|
|
ptP3 -= hole.vtDir * dAddLen ;
|
|
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// 4 -> punto termine velocità standard (se risulta)
|
|
if ( bStd) {
|
|
SetFeed( GetFeed()) ;
|
|
if ( ! bEndSlow)
|
|
SetFlag( 101) ; // fondo del foro
|
|
Point3d ptP4 = hole.ptIni - hole.vtDir * ( hole.dLen - dEndSlowLen) ;
|
|
if ( ! bEndSlow)
|
|
ptP4 -= hole.vtDir * dAddLen ;
|
|
if ( AddLinearMove( ptP4) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// 5 -> punto termine velocità finale ridotta (se previsto)
|
|
if ( bEndSlow) {
|
|
SetFeed( GetTipFeed()) ;
|
|
SetFlag( 101) ; // fondo del foro
|
|
Point3d ptP5 = hole.ptIni - hole.vtDir * ( hole.dLen + dAddLen) ;
|
|
if ( AddLinearMove( ptP5) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// 6 -> ritorno all'approccio del foro
|
|
SetFeed( GetEndFeed()) ;
|
|
SetFlag( 104) ; // risalita sopra il foro
|
|
if ( AddLinearMove( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
// 7 -> punto fuori (se uso aggregato da sotto)
|
|
if ( m_bAggrBottom) {
|
|
SetFlag( 0) ;
|
|
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
|
|
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
|
|
if ( AddRapidMove( ptP0, MCH_CL_AGB_OUT) == GDB_ID_NULL)
|
|
return false ;
|
|
// se rinvio da sotto che richiede speciale rotazione
|
|
if ( m_AggrBottom.nType == 1) {
|
|
Vector3d vtAux = m_vtAggrBottom ;
|
|
vtAux.Rotate( Z_AX, 0, 1) ;
|
|
SetAuxDir( vtAux) ;
|
|
if ( AddRapidMove( ptP00, MCH_CL_AGB_UP) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
// reset dati di movimento
|
|
ResetMoveData() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Drilling::DoPeckDrilling( const Hole& hole, SelData Id, int nPathId)
|
|
{
|
|
// aggiusto alcuni parametri del ciclo di foratura
|
|
double dStartSlowLen = abs( m_Params.m_dStartSlowLen) ;
|
|
if ( abs( m_TParams.m_dStartFeed - m_TParams.m_dFeed) < EPS_SMALL)
|
|
dStartSlowLen = 0 ;
|
|
double dEndSlowLen = ( hole.bBlind ? 0 : abs( m_Params.m_dEndSlowLen)) ;
|
|
if ( abs( m_TParams.m_dTipFeed - m_TParams.m_dFeed) < EPS_SMALL)
|
|
dEndSlowLen = 0 ;
|
|
if ( ( dStartSlowLen + dEndSlowLen) > hole.dLen) {
|
|
dStartSlowLen = dStartSlowLen / ( dStartSlowLen + dEndSlowLen) * hole.dLen ;
|
|
dEndSlowLen = hole.dLen - dStartSlowLen ;
|
|
}
|
|
double dStdLen = hole.dLen - dStartSlowLen - dEndSlowLen ;
|
|
double dAddLen = ( hole.bBlind ? 0 : m_Params.m_dThroughAddLen) ;
|
|
double dReturnPos = m_Params.m_dReturnPos ;
|
|
bool bStartSlow = ( dStartSlowLen > EPS_SMALL) ;
|
|
bool bStd = ( dStdLen > EPS_SMALL) ;
|
|
bool bEndSlow = ( dEndSlowLen > EPS_SMALL) ;
|
|
// determino l'elevazione
|
|
double dElev = 0 ;
|
|
GetElevation( m_nPhase, hole.ptIni, hole.vtDir, m_TParams.m_dDiam / 2, hole.vtDir, dElev) ;
|
|
// determino alcune caratteristiche dell'utensile
|
|
double dTExtrLen = max( 0.0, m_TParams.m_dTLen - m_TParams.m_dLen) ;
|
|
// imposto dati comuni
|
|
SetPathId( nPathId) ;
|
|
SetToolDir( hole.vtDir) ;
|
|
// 1 -> punto approccio
|
|
SetFlag( 1) ;
|
|
double dSafeZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeZ() ;
|
|
double dSafeAggrBottZ = m_pMchMgr->GetCurrMachiningsMgr()->GetSafeAggrBottZ() ;
|
|
double dAppr = ( m_bAggrBottom ? dSafeAggrBottZ : dSafeZ) ;
|
|
Point3d ptP1 = hole.ptIni + hole.vtDir * ( dAppr + dElev + dTExtrLen) ;
|
|
if ( m_bAggrBottom) {
|
|
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
|
|
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
|
|
// se rinvio da sotto che richiede speciale rotazione
|
|
if ( m_AggrBottom.nType == 1) {
|
|
Vector3d vtAux = m_vtAggrBottom ;
|
|
vtAux.Rotate( Z_AX, 0, 1) ;
|
|
SetAuxDir( vtAux) ;
|
|
if ( AddRapidStart( ptP00, MCH_CL_AGB_DWN) == GDB_ID_NULL)
|
|
return false ;
|
|
SetFlag( 0) ;
|
|
SetAuxDir( m_vtAggrBottom) ;
|
|
if ( AddRapidMove( ptP0, MCH_CL_AGB_IN) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// altrimenti rinvio normale
|
|
else {
|
|
SetAuxDir( m_vtAggrBottom) ;
|
|
if ( AddRapidStart( ptP0, MCH_CL_AGB_IN) == GDB_ID_NULL)
|
|
return false ;
|
|
SetFlag( 0) ;
|
|
}
|
|
if ( AddRapidMove( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
else {
|
|
if ( AddRapidStart( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
SetFlag( 0) ;
|
|
// 2 -> punto fuori (se diverso dal precedente)
|
|
if ( m_Params.m_dStartPos < dAppr) {
|
|
Point3d ptP2 = hole.ptIni + hole.vtDir * ( m_Params.m_dStartPos + dTExtrLen) ;
|
|
if ( AddRapidMove( ptP2) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// ciclo di affondamento a step
|
|
const double MIN_STEP = 5 ;
|
|
const double APPR_STEP = 1 ;
|
|
const double MIN_MOVE = 1 ;
|
|
double dStep = max( m_Params.m_dStep, MIN_STEP) ;
|
|
int nStep = int( ceil( hole.dLen / dStep)) ;
|
|
dStep = hole.dLen / nStep ;
|
|
if ( dReturnPos < - dStep + APPR_STEP + MIN_MOVE)
|
|
dReturnPos = - dStep + APPR_STEP + MIN_MOVE ;
|
|
double dCurrLen = 0 ;
|
|
for ( int i = 1 ; i <= nStep ; ++ i) {
|
|
// se non è primo step faccio retrazione e riaffondo
|
|
if ( i != 1) {
|
|
// retrazione
|
|
SetFeed( GetEndFeed()) ;
|
|
SetFlag( 103) ; // punto di scarico truciolo
|
|
Point3d ptPr = hole.ptIni + hole.vtDir * dReturnPos ;
|
|
if ( AddLinearMove( ptPr) == GDB_ID_NULL)
|
|
return false ;
|
|
// riaffondo
|
|
SetFeed( GetEndFeed()) ;
|
|
SetFlag( 0) ;
|
|
Point3d ptPa = hole.ptIni - hole.vtDir * ( dCurrLen - APPR_STEP) ;
|
|
if ( AddLinearMove( ptPa) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
// lunghezza di fine step
|
|
double dEndLen = dCurrLen + dStep ;
|
|
// 3 -> punto termine velocità ridotta iniziale (se previsto)
|
|
if ( bStartSlow && ( i == 1 || dCurrLen < dStartSlowLen + EPS_SMALL)) {
|
|
// lunghezza di esecuzione
|
|
double dLen = min( dStartSlowLen, dEndLen) ;
|
|
// determino se arrivo in fondo al foro
|
|
bool bHoleEnd = ( ! bStd && ! bEndSlow && dLen > hole.dLen - EPS_SMALL) ;
|
|
// determino se arrivo in fondo allo step
|
|
bool bStepEnd = ( dLen > dEndLen - EPS_SMALL) ;
|
|
// assegno parametri
|
|
SetFeed( GetStartFeed()) ;
|
|
if ( bHoleEnd)
|
|
SetFlag( 101) ; // fondo del foro
|
|
else if ( bStepEnd)
|
|
SetFlag( 102) ; // fondo dello step
|
|
// movimento
|
|
Point3d ptP3 = hole.ptIni - hole.vtDir * dLen ;
|
|
if ( bHoleEnd)
|
|
ptP3 -= hole.vtDir * dAddLen ;
|
|
if ( AddLinearMove( ptP3) == GDB_ID_NULL)
|
|
return false ;
|
|
// aggiorno posizione e verifico se step completato
|
|
dCurrLen = dLen ;
|
|
if ( bHoleEnd || bStepEnd)
|
|
continue ;
|
|
}
|
|
// 4 -> punto termine velocità standard (se risulta)
|
|
if ( bStd && dCurrLen < dStartSlowLen + dStdLen + EPS_SMALL) {
|
|
// lunghezza di esecuzione
|
|
double dLen = min( hole.dLen - dEndSlowLen, dEndLen) ;
|
|
// determino se arrivo in fondo al foro
|
|
bool bHoleEnd = ( ! bEndSlow && dLen > hole.dLen - EPS_SMALL) ;
|
|
// determino se arrivo in fondo allo step
|
|
bool bStepEnd = ( dLen > dEndLen - EPS_SMALL) ;
|
|
// assegno parametri
|
|
SetFeed( GetFeed()) ;
|
|
if ( bHoleEnd)
|
|
SetFlag( 101) ; // fondo del foro
|
|
else if ( bStepEnd)
|
|
SetFlag( 102) ; // fondo dello step
|
|
// movimento
|
|
Point3d ptP4 = hole.ptIni - hole.vtDir * dLen ;
|
|
if ( bHoleEnd)
|
|
ptP4 -= hole.vtDir * dAddLen ;
|
|
if ( AddLinearMove( ptP4) == GDB_ID_NULL)
|
|
return false ;
|
|
// aggiorno posizione e verifico se step completato
|
|
dCurrLen = dLen ;
|
|
if ( bHoleEnd || bStepEnd)
|
|
continue ;
|
|
}
|
|
// 5 -> punto termine velocità finale ridotta (se previsto)
|
|
if ( bEndSlow) {
|
|
// lunghezza di esecuzione
|
|
double dLen = dEndLen ;
|
|
// determino se arrivo in fondo al foro
|
|
bool bHoleEnd = ( dLen > hole.dLen - EPS_SMALL) ;
|
|
// sono sempre in fondo allo step
|
|
// assegno parametri
|
|
SetFeed( GetTipFeed()) ;
|
|
if ( bHoleEnd)
|
|
SetFlag( 101) ; // fondo del foro
|
|
else
|
|
SetFlag( 102) ; // fondo dello step
|
|
// movimento
|
|
Point3d ptP5 = hole.ptIni - hole.vtDir * dLen ;
|
|
if ( bHoleEnd)
|
|
ptP5 -= hole.vtDir * dAddLen ;
|
|
if ( AddLinearMove( ptP5) == GDB_ID_NULL)
|
|
return false ;
|
|
// aggiorno posizione
|
|
dCurrLen = dLen ;
|
|
}
|
|
}
|
|
|
|
// 6 -> ritorno all'approccio del foro
|
|
SetFeed( GetEndFeed()) ;
|
|
SetFlag( 104) ; // risalita sopra il foro
|
|
if ( AddLinearMove( ptP1) == GDB_ID_NULL)
|
|
return false ;
|
|
|
|
// 7 -> punto fuori (se uso aggregato da sotto)
|
|
if ( m_bAggrBottom) {
|
|
SetFlag( 0) ;
|
|
Point3d ptP0 = ptP1 + m_vtAggrBottom * ( m_dDistBottom + m_AggrBottom.dEncH + dSafeZ) ;
|
|
Point3d ptP00 = ptP0 + Z_AX * ( m_AggrBottom.dEncV + m_TParams.m_dLen + dAppr + dTExtrLen) ;
|
|
if ( AddRapidMove( ptP0, MCH_CL_AGB_OUT) == GDB_ID_NULL)
|
|
return false ;
|
|
// se rinvio da sotto che richiede speciale rotazione
|
|
if ( m_AggrBottom.nType == 1) {
|
|
Vector3d vtAux = m_vtAggrBottom ;
|
|
vtAux.Rotate( Z_AX, 0, 1) ;
|
|
SetAuxDir( vtAux) ;
|
|
if ( AddRapidMove( ptP00, MCH_CL_AGB_UP) == GDB_ID_NULL)
|
|
return false ;
|
|
}
|
|
}
|
|
|
|
// reset dati di movimento
|
|
ResetMoveData() ;
|
|
|
|
return true ;
|
|
}
|