Files
EgtMachKernel/Disposition.cpp
T
Dario Sassi d682572702 EgtMachKernel 1.6v7 :
- modifiche per bloccaggi su più fasi
2016-10-15 10:06:51 +00:00

1051 lines
38 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2016
//----------------------------------------------------------------------------
// File : Drilling.cpp Data : 29.04.16 Versione : 1.6p4
// Contenuto : Implementazione gestione disposizione.
//
//
//
// Modifiche : 21.05.15 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "MachMgr.h"
#include "DllMain.h"
#include "Disposition.h"
#include "/EgtDev/Include/EMkDispositionConst.h"
#include "/EgtDev/Include/EGkAngle.h"
#include "/EgtDev/Include/EGkStringUtils3d.h"
#include "/EgtDev/Include/EGkUserObjFactory.h"
#include "/EgtDev/Include/EGnStringKeyVal.h"
#include "/EgtDev/Include/EGnFileUtils.h"
using namespace std ;
//----------------------------------------------------------------------------
static std::string DIS_TABLE = "Tab" ;
static std::string DIS_PHASE = "Ph" ;
static std::string DIS_REF1 = "Ref1" ;
static std::string DIS_AREA1 = "Area1" ;
static std::string DIS_FXD_TOT = "FxT" ;
static std::string DIS_FXD_NAME = "FxN" ;
static std::string DIS_FXD_POS = "FxP" ;
static std::string DIS_FXD_ANG = "FxA" ;
static std::string DIS_FXD_MOV = "FxM" ;
static std::string DIS_MVD_TOT = "MvT" ;
static std::string DIS_MVD_ID = "MvI" ;
static std::string DIS_MVD_TYPE = "MvT" ;
static std::string DIS_MVD_PNT = "MvP" ;
static std::string DIS_MVD_ANG = "MvA" ;
static std::string DIS_MVD_FLAG = "MvF" ;
static std::string DIS_NUM = "NUM" ;
static std::string DIS_HEAD = "Head" ;
static std::string DIS_EXIT = "Exit" ;
static std::string DIS_SOMEBYHAND = "Sbh" ;
//----------------------------------------------------------------------------
USEROBJ_REGISTER( "EMkDisposition", Disposition) ;
//----------------------------------------------------------------------------
const string&
Disposition::GetClassName( void) const
{
return USEROBJ_GETNAME( Disposition) ;
}
//----------------------------------------------------------------------------
Disposition*
Disposition::Clone( void) const
{
// alloco oggetto
Disposition* pDisp = new(nothrow) Disposition ;
// eseguo copia dei dati
if ( pDisp != nullptr) {
try { pDisp->m_sTabName = m_sTabName ;
pDisp->m_ptRef1 = m_ptRef1 ;
pDisp->m_b3Area1 = m_b3Area1 ;
pDisp->m_bTabOk = m_bTabOk ;
pDisp->m_vFixData = m_vFixData ;
pDisp->m_vMvrData = m_vMvrData ;
pDisp->m_sHead = m_sHead ;
pDisp->m_nExit = m_nExit ;
pDisp->m_nShifts = m_nShifts ;
pDisp->m_bSomeByHand = m_bSomeByHand ;
}
catch( ...) {
delete pDisp ;
return nullptr ;
}
}
// ritorno l'oggetto
return pDisp ;
}
//----------------------------------------------------------------------------
bool
Disposition::Dump( string& sOut, bool bMM, const char* szNewLine) const
{
sOut += GetClassName() + "[mm]" + szNewLine ;
sOut += "Tab=" + m_sTabName + ( m_bTabOk ? " (ok)" : " (to verify)") + szNewLine ;
sOut += "Phase=" + ToString( m_nPhase) + szNewLine ;
sOut += "Ref1=(" + ToString( m_ptRef1, 3) + ")" + szNewLine ;
sOut += "Area1=(" + ToString( m_b3Area1, 3) + ")" + szNewLine ;
for ( const auto& FixData : m_vFixData) {
sOut += "FxD=" + FixData.sName + "," +
ToString( FixData.nId) + ",(" +
ToString( FixData.ptPos) + ")," +
ToString( FixData.dAng) + "," +
ToString( FixData.dMov) + szNewLine ;
}
for ( const auto& MvrData : m_vMvrData) {
sOut += "MvD=" + ToString( MvrData.nRawId) + "," ;
switch ( MvrData.nType) {
case MoveRawData::NONE :
sOut += string( " NONE") + szNewLine ;
break ;
case MoveRawData::COR :
sOut += " COR,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ;
break ;
case MoveRawData::CEN :
sOut += " CEN,(" + ToString( MvrData.ptP) + ")," + ToString( MvrData.nFlag) + szNewLine ;
break ;
case MoveRawData::ROT :
sOut += " ROT,(" + ToString( MvrData.ptP) + ")" + szNewLine ;
break ;
}
}
sOut += "Num=" + ToString( m_nShifts) + szNewLine ;
sOut += "Head=" + m_sHead + szNewLine ;
sOut += "Exit=" + ToString( m_nExit) + szNewLine ;
sOut += "ByHand=" + ToString( m_bSomeByHand) + szNewLine ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::Save( STRVECTOR& vString) const
{
try {
int k = - 1 ;
int nFxdTot = int( m_vFixData.size()) ;
int nFxdLines = 1 + 4 * nFxdTot ;
int nMvdTot = int( m_vMvrData.size()) ;
int nMvdLines = 1 + 4 * nMvdTot ;
int nOther = 4 ;
vString.insert( vString.begin(), 4 + nFxdLines + nMvdLines + nOther, "") ;
// Nome
if ( ! SetVal( DIS_TABLE, m_sTabName, vString[++k]))
return false ;
// Fase
if ( ! SetVal( DIS_PHASE, m_nPhase, vString[++k]))
return false ;
// Primo riferimento
if ( ! SetVal( DIS_REF1, m_ptRef1, vString[++k]))
return false ;
// Prima area
if ( ! SetVal( DIS_AREA1, m_b3Area1, vString[++k]))
return false ;
// Dati sottopezzi
if ( ! SetVal( DIS_FXD_TOT, nFxdTot, vString[++k]))
return false ;
for ( const auto& FixData : m_vFixData) {
if ( ! SetVal( DIS_FXD_NAME, FixData.sName, vString[++k]) ||
! SetVal( DIS_FXD_POS, FixData.ptPos, vString[++k]) ||
! SetVal( DIS_FXD_ANG, FixData.dAng, vString[++k]) ||
! SetVal( DIS_FXD_MOV, FixData.dMov, vString[++k]))
return false ;
}
// Dati posizionamento grezzi
if ( ! SetVal( DIS_MVD_TOT, nMvdTot, vString[++k]))
return false ;
for ( const auto& MvrData : m_vMvrData) {
if ( ! SetVal( DIS_MVD_ID, MvrData.nRawId, vString[++k]) ||
! SetVal( DIS_MVD_TYPE, MvrData.nType, vString[++k]) ||
! SetVal( DIS_MVD_PNT, MvrData.ptP, vString[++k]) ||
! SetVal( DIS_MVD_FLAG, MvrData.nFlag, vString[++k]))
return false ;
}
// altri dati
if ( ! SetVal( DIS_NUM, m_nShifts, vString[++k]))
return false ;
if ( ! SetVal( DIS_HEAD, m_sHead, vString[++k]))
return false ;
if ( ! SetVal( DIS_EXIT, m_nExit, vString[++k]))
return false ;
if ( ! SetVal( DIS_SOMEBYHAND, m_bSomeByHand, vString[++k]))
return false ;
}
catch( ...) { return false ; }
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::Load( const STRVECTOR& vString, int nBaseGdbId)
{
if ( vString.size() < 5)
return false ;
int k = - 1 ;
// nome della tavola
m_bTabOk = false ;
if ( ! GetVal( vString[++k], DIS_TABLE, m_sTabName))
return false ;
// fase opzionale
if ( ! GetVal( vString[++k], DIS_PHASE, m_nPhase))
-- k ;
// primo riferimento
if ( ! GetVal( vString[++k], DIS_REF1, m_ptRef1))
return false ;
// prima area
if ( ! GetVal( vString[++k], DIS_AREA1, m_b3Area1))
return false ;
// dati sottopezzi
int nFxdTot ;
if ( ! GetVal( vString[++k], DIS_FXD_TOT, nFxdTot))
return false ;
int nFxdLines = 1 + 3 * nFxdTot ;
if ( int( vString.size()) < 3 + nFxdLines + 1)
return false ;
m_vFixData.insert( m_vFixData.begin(), nFxdTot, FixtureData()) ;
for ( auto& FixData : m_vFixData) {
// dati obbligatori
if ( ! GetVal( vString[++k], DIS_FXD_NAME, FixData.sName) ||
! GetVal( vString[++k], DIS_FXD_POS, FixData.ptPos) ||
! GetVal( vString[++k], DIS_FXD_ANG, FixData.dAng))
return false ;
// dati facoltativi
if ( k + 1 < int( vString.size())) {
if ( ! GetVal( vString[++k], DIS_FXD_MOV, FixData.dMov))
-- k ;
}
}
// dati posizionamento grezzi
int nMvdTot ;
if ( ! GetVal( vString[++k], DIS_MVD_TOT, nMvdTot))
return false ;
int nMvdLines = 1 + 4 * nMvdTot ;
if ( int( vString.size()) < 3 + nFxdLines + nMvdLines)
return false ;
m_vMvrData.insert( m_vMvrData.begin(), nMvdTot, MoveRawData()) ;
for ( auto& MvrData : m_vMvrData) {
if ( ! GetVal( vString[++k], DIS_MVD_ID, MvrData.nRawId) ||
! GetVal( vString[++k], DIS_MVD_TYPE, MvrData.nType) ||
! GetVal( vString[++k], DIS_MVD_PNT, MvrData.ptP) ||
! GetVal( vString[++k], DIS_MVD_FLAG, MvrData.nFlag))
return false ;
MvrData.nRawId += nBaseGdbId ;
}
// altri dati aggiuntivi
if ( k + 1 < int( vString.size())) {
if ( ! GetVal( vString[++k], DIS_NUM, m_nShifts))
return false ;
}
if ( k + 1 < int( vString.size())) {
if ( ! GetVal( vString[++k], DIS_HEAD, m_sHead))
return false ;
}
if ( k + 1 < int( vString.size())) {
if ( ! GetVal( vString[++k], DIS_EXIT, m_nExit))
return false ;
}
if ( k + 1 < int( vString.size())) {
if ( ! GetVal( vString[++k], DIS_SOMEBYHAND, m_bSomeByHand))
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
Disposition::Disposition( void)
: m_bTabOk( false), m_nExit( 0), m_nShifts( 0), m_bSomeByHand( false)
{
}
//----------------------------------------------------------------------------
bool
Disposition::SetTable( const string& sTable)
{
// dichiaro tavola non verificata
m_bTabOk = false ;
// verifico il gestore lavorazioni
if ( m_pMchMgr == nullptr)
return false ;
// recupero la macchina corrente
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
// imposta questa tavola come corrente
if ( ! pMch->SetCurrTable( sTable))
return false ;
// recupero il primo riferimento e l'area utile della tavola
Point3d ptPrevRef1 = m_ptRef1 ;
if ( ! pMch->GetCurrTableRef1( m_ptRef1) ||
! pMch->GetCurrTableArea1( m_b3Area1))
return false ;
if ( ! m_sTabName.empty() && EqualNoCase( m_sTabName, sTable) &&
! AreSamePointApprox( ptPrevRef1, m_ptRef1)) {
string sOut = "Table Ref1 changed : (" + ToString( ptPrevRef1) + ") -> (" + ToString( m_ptRef1) +")" ;
LOG_INFO( GetEMkLogger(), sOut.c_str()) ;
}
// salvo il nome e dichiaro tavola verificata
m_sTabName = sTable ;
m_bTabOk = true ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetTable( string& sTable) const
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// verifico tavola
if ( ! m_bTabOk && ! const_cast<Disposition*>(this)->SetTable( m_sTabName))
return false ;
// recupero il nome della tavola
sTable = m_sTabName ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetTableRef1( Point3d& ptRef1) const
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// verifico tavola
if ( ! m_bTabOk && ! const_cast<Disposition*>(this)->SetTable( m_sTabName))
return false ;
// recupero il primo riferimento della tavola
ptRef1 = m_ptRef1 ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetTableArea1( BBox3d& b3Area1) const
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// verifico tavola
if ( ! m_bTabOk && ! const_cast<Disposition*>(this)->SetTable( m_sTabName))
return false ;
// recupero la prima area utile della tavola
b3Area1 = m_b3Area1 ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::Apply( bool bVerifyTab)
{
// verifico tavola
if ( ( ! m_bTabOk || bVerifyTab) && ! SetTable( m_sTabName))
return false ;
// aggiornamento sottopezzi
for ( auto& FixData : m_vFixData) {
// se sottopezzo da caricare
if ( FixData.nId == GDB_ID_NULL) {
int nId = AddFixture( FixData.sName, FixData.ptPos, FixData.dAng, FixData.dMov, false) ;
if ( nId == GDB_ID_NULL) {
string sOut = "Error adding fixture " + FixData.sName ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
}
else
FixData.nId = nId ;
}
// altrimenti sottopezzo da rimettere in posizione
else {
if ( ! PlaceFixture( FixData.nId, FixData.ptPos, FixData.dAng, FixData.dMov)) {
string sOut = "Error placing fixture " + ToString( FixData.nId) ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
}
}
}
// annullo movimento grezzi
int nRawId = m_pMchMgr->GetFirstRawPart() ;
while ( nRawId != GDB_ID_NULL) {
if ( m_pMchMgr->VerifyRawPartPhase( nRawId, m_nPhase)) {
// recupero riferimento del grezzo
Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ;
// lo trasformo nel riferimento globale
pfrRaw->Reset() ;
}
nRawId = m_pMchMgr->GetNextRawPart( nRawId) ;
}
// aggiornamento movimento grezzi
for ( const auto& vMvrData : m_vMvrData) {
switch ( vMvrData.nType) {
case MoveRawData::COR :
if ( ! MoveToCornerRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) {
string sOut = "Error in MoveToCornerRawPart " + ToString( vMvrData.nRawId) ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
}
break ;
case MoveRawData::CEN :
if ( ! MoveToCenterRawPart( vMvrData.nRawId, vMvrData.ptP, vMvrData.nFlag, false)) {
string sOut = "Error in MoveToCenterRawPart " + ToString( vMvrData.nRawId) ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
}
break ;
case MoveRawData::ROT :
if ( ! ApplyRotationToRawPart( vMvrData.nRawId, vMvrData.ptP.x, vMvrData.ptP.y, vMvrData.ptP.z)) {
string sOut = "Error in ApplyRotationToRawPart " + ToString( vMvrData.nRawId) ;
LOG_ERROR( GetEMkLogger(), sOut.c_str()) ;
}
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
int
Disposition::AddFixture( const string& sName, const Point3d& ptPos, double dAngDeg,
double dMov, bool bAddToList)
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return GDB_ID_NULL ;
// verifico tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return GDB_ID_NULL ;
// verifico che la posizione sia nell'area della tavola
if ( ! m_b3Area1.EnclosesXY( m_ptRef1 + ptPos))
return GDB_ID_NULL ;
// Nome tutto maiuscolo
string sMyName = sName ;
ToUpper( sMyName) ;
// Se recuperabile dal gruppo dei bloccaggi
int nFixtId = m_pMchMgr->GetUnusedFixture( sMyName, m_nPhase) ;
if ( nFixtId != GDB_ID_NULL) {
// aggiungo la fase al bloccaggio
INTVECTOR vPhase ;
m_pMchMgr->GetFixturePhases( nFixtId, vPhase) ;
vPhase.push_back( m_nPhase) ;
m_pGeomDB->SetInfo( nFixtId, MACH_FXT_PHASE, vPhase) ;
// aggiorno visualizzazione
m_pGeomDB->SetStatus( nFixtId, GDB_ST_ON) ;
}
// altrimenti lo carico da file
else {
// recupero il gruppo delle fixtures nella macchinata corrente
int nFixtGrpId = m_pMchMgr->GetCurrFixtGroupId() ;
if ( nFixtGrpId == GDB_ID_NULL)
return GDB_ID_NULL ;
// verifico esistenza file sottopezzo
string sFixtFile = m_pMchMgr->GetCurrFixtDir() + "\\" + sName + ".Nge" ;
if ( ! ExistsFile( sFixtFile))
return GDB_ID_NULL ;
// inserisco il sottopezzo nel gruppo
if ( ! m_pGeomDB->Load( sFixtFile, nFixtGrpId))
return GDB_ID_NULL ;
nFixtId = m_pGeomDB->GetLastGroupInGroup( nFixtGrpId) ;
if ( nFixtId == GDB_ID_NULL)
return GDB_ID_NULL ;
// assegno il nome
m_pGeomDB->SetName( nFixtId, sMyName) ;
// imposto il livello a temporaneo
m_pGeomDB->SetLevel( nFixtId, GDB_LV_TEMP) ;
// aggiungo la fase al bloccaggio
m_pGeomDB->SetInfo( nFixtId, MACH_FXT_PHASE, m_nPhase) ;
}
// resetto il riferimento del gruppo
Frame3d* pfrFixt = m_pGeomDB->GetGroupFrame( nFixtId) ;
pfrFixt->Reset() ;
// la muovo nella posizione voluta
Vector3d vtMove = ( m_ptRef1 + ptPos) - ORIG ;
m_pGeomDB->TranslateGlob( nFixtId, vtMove) ;
// la ruoto
if ( fabs( dAngDeg) > EPS_ANG_SMALL)
m_pGeomDB->RotateGroup( nFixtId, ORIG, Z_AX, dAngDeg) ;
// muovo eventuale parte mobile
int nMobId = m_pGeomDB->GetFirstNameInGroup( nFixtId, FXT_MOBILE) ;
if ( nMobId != GDB_ID_NULL) {
double dCurrVal = 0 ;
m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ;
if ( abs( dMov - dCurrVal) > EPS_SMALL) {
m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dMov - dCurrVal)) ;
m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, dMov) ;
}
}
// se da aggiungere alla lista
if ( bAddToList)
m_vFixData.emplace_back( sName, nFixtId, ptPos, dAngDeg, dMov) ;
return nFixtId ;
}
//----------------------------------------------------------------------------
int
Disposition::GetFirstFixture( void)
{
// verifico se ci sono bloccaggi
if ( m_vFixData.empty())
return GDB_ID_NULL ;
// recupero il primo
int nId = m_vFixData.front().nId ;
// ne verifico la validit
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return GDB_ID_NULL ;
return nId ;
}
//----------------------------------------------------------------------------
int
Disposition::GetNextFixture( int nId)
{
// ciclo sui bloccaggi
int nFxtTot = int( m_vFixData.size()) ;
for ( int i = 0 ; i < nFxtTot ; ++ i) {
// se trovato
if ( m_vFixData[i].nId == nId) {
// se esiste successivo e valido
int j = i + 1 ;
if ( j < nFxtTot &&
m_pMchMgr != nullptr && m_pMchMgr->VerifyFixture( m_vFixData[j].nId, false))
return m_vFixData[j].nId ;
else
return GDB_ID_NULL ;
}
}
return GDB_ID_NULL ;
}
//----------------------------------------------------------------------------
bool
Disposition::MoveFixture( int nId, const Vector3d& vtMove)
{
// verifica validit sottopezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return false ;
// verifico aggiornamento tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// verifico che la posizione finale sia nell'area della tavola
Frame3d frFixt ;
if ( ! m_pGeomDB->GetGroupFrame( nId, frFixt) ||
! m_b3Area1.EnclosesXY( frFixt.Orig() + vtMove))
return false ;
// muovo l'oggetto
m_pGeomDB->TranslateGlob( nId, vtMove) ;
// aggiorno la posizione dell'oggetto nel vettore dei comandi
for ( auto& FixData : m_vFixData) {
if ( FixData.nId == nId) {
FixData.ptPos += vtMove ;
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::RotateFixture( int nId, double dDeltaAngDeg)
{
// verifica validit sottopezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return false ;
// verifico aggiornamento tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// ruoto l'oggetto
m_pGeomDB->RotateGroup( nId, ORIG, Z_AX, dDeltaAngDeg) ;
// aggiorno la posizione dell'oggetto nel vettore dei comandi
for ( auto& FixData : m_vFixData) {
if ( FixData.nId == nId) {
FixData.dAng += dDeltaAngDeg ;
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::MoveFixtureMobile( int nId, double dDeltaMov)
{
// verifica validit sottopezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return false ;
// verifico aggiornamento tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// muovo eventuale parte mobile
int nMobId = m_pGeomDB->GetFirstNameInGroup( nId, FXT_MOBILE) ;
if ( nMobId != GDB_ID_NULL) {
double dCurrVal = 0 ;
m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ;
if ( abs( dDeltaMov) > EPS_SMALL) {
m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dDeltaMov)) ;
m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, ( dCurrVal + dDeltaMov)) ;
}
}
// aggiorno la posizione dell'oggetto nel vettore dei comandi
for ( auto& FixData : m_vFixData) {
if ( FixData.nId == nId) {
FixData.dMov += dDeltaMov ;
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::PlaceFixture( int nId, const Point3d& ptPos, double dAngDeg, double dMov)
{
// verifica validit sottopezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return false ;
// verifico aggiornamento tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// verifico che la posizione sia nell'area della tavola
if ( ! m_b3Area1.EnclosesXY( m_ptRef1 + ptPos))
return false ;
// aggiorno visualizzazione
m_pGeomDB->SetStatus( nId, GDB_ST_ON) ;
// resetto il riferimento del gruppo
Frame3d* pfrFixt = m_pGeomDB->GetGroupFrame( nId) ;
pfrFixt->Reset() ;
// lo muovo nella posizione voluta
Vector3d vtMove = ( m_ptRef1 + ptPos) - ORIG ;
m_pGeomDB->TranslateGlob( nId, vtMove) ;
// lo ruoto
if ( fabs( dAngDeg) > EPS_ANG_SMALL)
m_pGeomDB->RotateGroup( nId, ORIG, Z_AX, dAngDeg) ;
// muovo eventuale parte mobile
int nMobId = m_pGeomDB->GetFirstNameInGroup( nId, FXT_MOBILE) ;
if ( nMobId != GDB_ID_NULL) {
double dCurrVal = 0 ;
m_pGeomDB->GetInfo( nMobId, FXT_MOB_CPOS, dCurrVal) ;
if ( abs( dMov - dCurrVal) > EPS_SMALL) {
m_pGeomDB->TranslateGroup( nMobId, Vector3d( 0, 0, dMov - dCurrVal)) ;
m_pGeomDB->SetInfo( nMobId, FXT_MOB_CPOS, dMov) ;
}
}
// aggiorno la posizione dell'oggetto nel vettore dei comandi
for ( auto& FixData : m_vFixData) {
if ( FixData.nId == nId) {
FixData.ptPos = ptPos ;
FixData.dAng = dAngDeg ;
FixData.dMov = dMov ;
break ;
}
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::RemoveFixture( int nId)
{
// verifica validit sottopezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyFixture( nId, false))
return false ;
// verifico aggiornamento tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// dichiaro l'oggetto non pi usato dalla fase
INTVECTOR vPhase ;
if ( ! m_pMchMgr->GetFixturePhases( nId, vPhase))
return false ;
auto iIter = find( vPhase.begin(), vPhase.end(), m_nPhase) ;
if ( iIter != vPhase.end()) {
vPhase.erase( iIter) ;
m_pGeomDB->SetInfo( nId, MACH_FXT_PHASE, vPhase) ;
}
// rimuovo l'oggetto dal vettore dei comandi
while ( true) {
auto iIter = find_if( m_vFixData.begin(), m_vFixData.end(),
[ nId]( const FixtureData& Fxt)
{ return ( Fxt.nId == nId) ; }) ;
if ( iIter == m_vFixData.end())
break ;
else
m_vFixData.erase( iIter) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::MoveToCornerRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// recupero il solido
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
// determino il box del grezzo (solo il solido ovviamente)
BBox3d b3Raw ;
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw))
return false ;
// calcolo il movimento necessario
Vector3d vtMove ;
switch ( nFlag) {
case MCH_CR_TL :
vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ;
break ;
case MCH_CR_TR :
vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMax().y, b3Raw.GetMin().z) ;
break ;
default : // RPCP_BL
vtMove = ( m_ptRef1 + ptP) - b3Raw.GetMin() ;
break ;
case MCH_CR_BR :
vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, b3Raw.GetMin().y, b3Raw.GetMin().z) ;
break ;
}
// verifico se il grezzo nella posizione finale sar nella tavola
b3Raw.Translate( vtMove) ;
if ( ! m_b3Area1.EnclosesXY( b3Raw))
return false ;
// recupero eventuale spostamento corrente della tavola
Vector3d vtDelta1 ;
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1))
return false ;
// eseguo traslazione in globale
Vector3d vtTotMove = vtMove + vtDelta1 ;
if ( ! vtTotMove.IsSmall())
m_pGeomDB->TranslateGlob( nRawId, vtTotMove) ;
// se da aggiungere alla lista
if ( bAddToList) {
auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(),
[ nRawId]( const MoveRawData& Mrv)
{ return ( Mrv.nRawId == nRawId &&
( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ;
if ( iIter == m_vMvrData.end())
m_vMvrData.emplace_back( nRawId, MoveRawData::COR, ptP, nFlag) ;
else
*iIter = MoveRawData( nRawId, MoveRawData::COR, ptP, nFlag) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::MoveToCenterRawPart( int nRawId, const Point3d& ptP, int nFlag, bool bAddToList)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// recupero il solido
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
// determino il box del grezzo (solo il solido ovviamente)
BBox3d b3Raw ;
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw))
return false ;
// ricavo il centro dal box (in generale non il centro geometrico)
Point3d ptCen ;
b3Raw.GetCenter( ptCen) ;
// calcolo il movimento necessario
Vector3d vtMove ;
switch ( nFlag) {
case MCH_CE_TC :
vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMax().y, ptCen.z) ;
break ;
default : // RPCE_ML
vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMin().x, ptCen.y, ptCen.z) ;
break ;
case MCH_CE_MR :
vtMove = ( m_ptRef1 + ptP) - Point3d( b3Raw.GetMax().x, ptCen.y, ptCen.z) ;
break ;
case MCH_CE_BC :
vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, b3Raw.GetMin().y, ptCen.z) ;
break ;
case MCH_CE_MC :
vtMove = ( m_ptRef1 + ptP) - Point3d( ptCen.x, ptCen.y, b3Raw.GetMin().z) ;
break ;
}
// verifico se il grezzo nella posizione finale sar nella tavola
b3Raw.Translate( vtMove) ;
if ( ! m_b3Area1.EnclosesXY( b3Raw))
return false ;
// eseguo traslazione in globale
if ( ! vtMove.IsSmall())
m_pGeomDB->TranslateGlob( nRawId, vtMove) ;
// se da aggiungere alla lista
if ( bAddToList) {
auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(),
[ nRawId]( const MoveRawData& Mrv)
{ return ( Mrv.nRawId == nRawId &&
( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ;
if ( iIter == m_vMvrData.end())
m_vMvrData.emplace_back( nRawId, MoveRawData::CEN, ptP, nFlag) ;
else
*iIter = MoveRawData( nRawId, MoveRawData::CEN, ptP, nFlag) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::MoveRawPart( int nRawId, const Vector3d& vtMove)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// se movimento nullo, non devo fare alcunch
if ( vtMove.IsSmall())
return true ;
// verifico ci sia gi un movimento assoluto di questo grezzo
auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(),
[ nRawId]( const MoveRawData& Mrv)
{ return ( Mrv.nRawId == nRawId &&
( Mrv.nType == MoveRawData::COR || Mrv.nType == MoveRawData::CEN)) ; }) ;
if ( iIter == m_vMvrData.end())
return false ;
// recupero il solido
int nRawSolId = m_pGeomDB->GetFirstNameInGroup( nRawId, MACH_RAW_SOLID) ;
// determino il box del grezzo (solo il solido ovviamente)
BBox3d b3Raw ;
if ( ! m_pGeomDB->GetGlobalBBox( nRawSolId, b3Raw))
return false ;
// recupero eventuale spostamento corrente della tavola
Vector3d vtDelta1 ;
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr || ! pMch->GetCurrTableDeltaRef1( vtDelta1))
return false ;
// verifico se il grezzo nella posizione finale sar nella tavola
b3Raw.Translate( vtMove - vtDelta1) ;
if ( ! m_b3Area1.EnclosesXY( b3Raw))
return false ;
// eseguo traslazione in globale
m_pGeomDB->TranslateGlob( nRawId, vtMove) ;
// aggiorno comando di movimento
iIter->ptP += vtMove ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::RotateRawPart( int nRawId, const Vector3d& vtAx, double dAngRotDeg)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// recupero centro del grezzo
Point3d ptAx ;
if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptAx))
return false ;
// eseguo rotazione in globale attorno al centro del grezzo
if ( ! m_pGeomDB->RotateGlob( nRawId, ptAx, vtAx, dAngRotDeg))
return false ;
// recupero riferimento globale del grezzo
Frame3d frRaw ;
m_pGeomDB->GetGroupGlobFrame( nRawId, frRaw) ;
// ne calcolo gli angoli di Eulero
double dAngCDeg, dAngADeg, dAngC1Deg ;
frRaw.GetRotationsCAC1( dAngCDeg, dAngADeg, dAngC1Deg) ;
// aggiungo o modifico nella lista
auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(),
[ nRawId]( const MoveRawData& Mrv)
{ return ( Mrv.nRawId == nRawId && Mrv.nType == MoveRawData::ROT) ; }) ;
if ( iIter == m_vMvrData.end())
m_vMvrData.emplace_back( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ;
else
*iIter = MoveRawData( nRawId, MoveRawData::ROT, Point3d( dAngCDeg, dAngADeg, dAngC1Deg), 0) ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::ApplyRotationToRawPart( int nRawId, double dAngCDeg, double dAngADeg, double dAngC1Deg)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// recupero centro del grezzo
Point3d ptCen ;
if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptCen))
return false ;
// recupero riferimento del grezzo (coincide con quello globale)
Frame3d* pfrRaw = m_pGeomDB->GetGroupFrame( nRawId) ;
// lo trasformo nel nuovo riferimento
Point3d ptOrig = pfrRaw->Orig() ; // necessario copiarlo
pfrRaw->Set( ptOrig, dAngCDeg, dAngADeg, dAngC1Deg) ;
// recupero nuovo centro del grezzo
Point3d ptNewCen ;
if ( ! m_pMchMgr->GetRawPartCenter( nRawId, ptNewCen))
return false ;
// eseguo spostamento per riportare il centro nella posizione originale
pfrRaw->Translate( ptCen - ptNewCen) ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::RemoveRawPart( int nRawId)
{
// verifica validit grezzo
if ( m_pMchMgr == nullptr || ! m_pMchMgr->VerifyRawPart( nRawId, false))
return false ;
// elimino i movimenti registrati per questo grezzo
while ( true) {
auto iIter = find_if( m_vMvrData.begin(), m_vMvrData.end(),
[ nRawId]( const MoveRawData& Mrv)
{ return ( Mrv.nRawId == nRawId) ; }) ;
if ( iIter == m_vMvrData.end())
break ;
else
m_vMvrData.erase( iIter) ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetFixtureData( int nInd, string& sName, int& nId, Point3d& ptPos, double& dAngDeg) const
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// verifico l'indice
if ( nInd < 0 || nInd >= int( m_vFixData.size()))
return false ;
// recupero i dati
sName = m_vFixData[nInd].sName ;
nId = m_vFixData[nInd].nId ;
ptPos = m_vFixData[nInd].ptPos ;
dAngDeg = m_vFixData[nInd].dAng ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetMoveRawData( int nInd, int& nRawId, int& nType, Point3d& ptPos, int& nFlag) const
{
// verifico MachMgr e GeomDB
if ( m_pMchMgr == nullptr || m_pGeomDB == nullptr)
return false ;
// verifico l'indice
if ( nInd < 0 || nInd >= int( m_vMvrData.size()))
return false ;
// recupero i dati
nRawId = m_vMvrData[nInd].nRawId ;
nType = m_vMvrData[nInd].nType ;
ptPos = m_vMvrData[nInd].ptP ;
nFlag = m_vMvrData[nInd].nFlag ;
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::SpecialApply( bool bRecalc)
{
// reset
m_sHead.empty() ;
m_nExit = 0 ;
m_nShifts = 0 ;
// verifico tavola
if ( ! m_bTabOk && ! SetTable( m_sTabName))
return false ;
// recupero la macchina corrente
Machine* pMch = m_pMchMgr->GetCurrMachine() ;
if ( pMch == nullptr)
return false ;
// costanti
static const string EMC_VAR = "EMC" ; // tabella variabili locali per calcolo
static const string EVAR_TABNAME = ".TABNAME" ; // IN (string) nome della tavola macchina
static const string EVAR_DISPID = ".DISPID" ; // IN (int) identificativo della disposizione
static const string EVAR_ERROR = ".ERR" ; // OUT (int) codice di errore ( 0 = ok)
static const string EVAR_HEAD = ".HEAD" ; // OUT (string) nome della testa
static const string EVAR_EXIT = ".EXIT" ; // OUT (int) indice dell'uscita
static const string EVAR_SHIFTS = ".SHIFTS" ; // OUT (int) numero di movimenti eseguiti
static const string EVAR_SBH = ".SBH" ; // OUT (bool) flag presenza operazioni manuali
static const string ON_SPECIAL_APPLY = "OnSpecialApplyDisposition" ;
// eseguo l'azione
if ( pMch->LuaExistsFunction( ON_SPECIAL_APPLY)) {
bool bOk = true ;
int nErr = 99 ;
// imposto valori parametri
bOk = bOk && pMch->LuaCreateGlobTable( EMC_VAR) ;
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_TABNAME, m_sTabName) ;
bOk = bOk && pMch->LuaSetGlobVar( EMC_VAR + EVAR_DISPID, m_nOwnerId) ;
// eseguo
bOk = bOk && pMch->LuaCallFunction( ON_SPECIAL_APPLY) ;
// recupero valori parametri
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_ERROR, nErr) ;
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_HEAD, m_sHead) ;
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_EXIT, m_nExit) ;
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_SHIFTS, m_nShifts) ;
bOk = bOk && pMch->LuaGetGlobVar( EMC_VAR + EVAR_SBH, m_bSomeByHand) ;
bOk = bOk && pMch->LuaResetGlobVar( EMC_VAR) ;
// segnalo errori
if ( nErr != 0) {
bOk = false ;
string sOut = " Error in " + ON_SPECIAL_APPLY + " (" + ToString( nErr) + ")" ;
LOG_INFO( GetEMkLogger(), sOut.c_str())
}
// se disposizione vuota, esco
if ( m_nShifts == 0)
return bOk ;
// calcolo assi macchina
string sHint = "" ;
bOk = bOk && CalculateAxesValues( sHint) ;
// gestione movimenti all'inizio di ogni singolo percorso di lavorazione e alla fine di tutti
bOk = bOk && AdjustStartEndMovements() ;
return bOk ;
}
else
return true ;
}
//----------------------------------------------------------------------------
bool
Disposition::GetToolData( string& sName, string& sHead, int& nExit) const
{
sName = "" ;
sHead = m_sHead ;
nExit = m_nExit ;
return true ;
}
//----------------------------------------------------------------------------
const string&
Disposition::GetToolName( void) const
{
static string sDummy = "" ;
return sDummy ;
}
//----------------------------------------------------------------------------
const string&
Disposition::GetHeadName( void) const
{
return m_sHead ;
}
//----------------------------------------------------------------------------
int
Disposition::GetExitNbr( void) const
{
return m_nExit ;
}
//----------------------------------------------------------------------------
const string&
Disposition::GetToolTcPos( void) const
{
static string sDummy = "" ;
return sDummy ;
}
//----------------------------------------------------------------------------
bool
Disposition:: NeedPrevHome( void) const
{
return ( IsEmpty() || m_bSomeByHand) ;
}