9577795c73
- per BTL aggiunta possibilità di gestione geometrica del PARTOFFSET (controllata da flag).
1441 lines
44 KiB
C++
1441 lines
44 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2017
|
|
//----------------------------------------------------------------------------
|
|
// File : ImportCnc.cpp Data : 26.03.17 Versione : 1.8c4
|
|
// Contenuto : Implementazione della classe per l'importazione di CNC.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 15.09.14 DS Creazione modulo.
|
|
// 26/03/17 DS Gestione punto come solo cambio assi rotanti.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "ImportCnc.h"
|
|
#include "DllMain.h"
|
|
#include "/EgtDev/Include/EExDllMain.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkGdbIterator.h"
|
|
#include "/EgtDev/Include/EGkStringUtils3d.h"
|
|
#include "/EgtDev/Include/EGkGeoPoint3d.h"
|
|
#include "/EgtDev/Include/EGkCurveLine.h"
|
|
#include "/EgtDev/Include/EGkCurveArc.h"
|
|
#include "/EgtDev/Include/EGkCurveComposite.h"
|
|
#include "/EgtDev/Include/EGkArcSpecial.h"
|
|
#include "/EgtDEv/Include/EGnScanner.h"
|
|
#include "/EgtDev/Include/EgtStringConverter.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
static const string NAME_ERROR = "Error" ;
|
|
static const Color COL_RAPID( 0, 192, 192, 50) ;
|
|
static const Color COL_ERROR( 255, 0, 0, 100) ;
|
|
static const string KEY_TCS = "TCS" ;
|
|
static const string KEY_TCOMP = "TCOMP" ;
|
|
static const string KEY_TNAME = "TNAME" ;
|
|
static const string KEY_EXIT = "EXIT" ;
|
|
static const string KEY_TPOS = "TPOS" ;
|
|
static const string KEY_TPOS2 = "TPOS2" ;
|
|
static const string KEY_SPEED = "SPEED" ;
|
|
static const string KEY_ROTAX_A = "A" ;
|
|
static const string KEY_ROTAX_B = "B" ;
|
|
static const string KEY_ROTAX_C = "C" ;
|
|
static const string KEY_INFO = "INFO" ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
IImportCnc*
|
|
CreateImportCnc( void)
|
|
{
|
|
// verifico la chiave e le opzioni
|
|
if ( ! VerifyKey( KEYOPT_EEX_INPBASE))
|
|
return nullptr ;
|
|
// creo l'oggetto
|
|
return static_cast<IImportCnc*> ( new(nothrow) ImportCnc) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::Import( const string& sFile, IGeomDB* pGDB, int nIdGroup, int nFlag)
|
|
{
|
|
// verifico il DB geometrico
|
|
if ( pGDB == nullptr) {
|
|
LOG_ERROR( GetEExLogger(), "ImportCnc : Error on GeomDB")
|
|
return false ;
|
|
}
|
|
m_pGDB = pGDB ;
|
|
|
|
// verifico l'Id di gruppo
|
|
if ( ! m_pGDB->ExistsObj( nIdGroup)) {
|
|
LOG_ERROR( GetEExLogger(), "ImportCnc : Error on IdGroup")
|
|
return false ;
|
|
}
|
|
m_nIdGroup = nIdGroup ;
|
|
// ricavo il riferimento del gruppo
|
|
if ( ! m_pGDB->GetGroupGlobFrame( m_nIdGroup, m_frGroup)) {
|
|
LOG_ERROR( GetEExLogger(), "ImportCnc : Error on Group Frame3d")
|
|
return false ;
|
|
}
|
|
|
|
// imposto le opzioni di importazione
|
|
m_nFlag = nFlag ;
|
|
|
|
// inizializzo lo scanner
|
|
Scanner TheScanner ;
|
|
if ( ! TheScanner.Init( sFile, "")) {
|
|
LOG_ERROR( GetEExLogger(), "ImportCnc : Error on Init")
|
|
return false ;
|
|
}
|
|
|
|
// inizializzo lo stato
|
|
m_nLine = 0 ;
|
|
m_nCNC = CNC_STD ;
|
|
m_bToMove = false ;
|
|
m_bLoadTool = false ;
|
|
m_nTool = 0 ;
|
|
m_nNextTool = 0 ;
|
|
m_nFirstGroup = GDB_ID_NULL ;
|
|
m_nMoveType = RAPID ;
|
|
m_nCharsOn = 0 ;
|
|
m_bZeroMach = false ;
|
|
m_bAbsCoord = true ;
|
|
m_nInterpPl = XY ;
|
|
m_nArcType = NO_ARCTYPE ;
|
|
m_nComp = 0 ;
|
|
m_nCompSide = NO_COMP ;
|
|
m_ptHome = ORIG ;
|
|
m_ptLast = ORIG ;
|
|
m_ptNext = ORIG ;
|
|
m_ptCen = ORIG ;
|
|
m_vtOffs = V_NULL ;
|
|
m_dLinCoeff = ONEMM ;
|
|
m_dRadius = 0 ;
|
|
m_dRotAxA = NAN ;
|
|
m_dRotAxB = NAN ;
|
|
m_dRotAxC = NAN ;
|
|
SaveRotAxes() ;
|
|
m_dOffsAxA = 0 ;
|
|
m_dOffsAxB = 0 ;
|
|
m_dOffsAxC = 0 ;
|
|
m_colCurr = BLACK ;
|
|
m_sToolName.clear() ;
|
|
m_nExit = 1 ;
|
|
|
|
// se estensione xpi è NUM
|
|
string sFileTitle, sFileExt ;
|
|
SplitLast( sFile, ".", sFileTitle, sFileExt) ;
|
|
ToUpper( sFileExt) ;
|
|
if ( sFileExt == "XPI")
|
|
m_nCNC = CNC_NUM ;
|
|
else if ( sFileExt == "MPF")
|
|
m_nCNC = CNC_SIEMENS ;
|
|
else if ( sFileExt == "ISO")
|
|
m_nCNC = CNC_TPA ;
|
|
else if ( sFileExt == "CNC")
|
|
m_nCNC = CNC_OSAI ;
|
|
else if ( sFileExt == "EIA")
|
|
m_nCNC = CNC_MAZAK ;
|
|
else if ( sFileExt == "PIM")
|
|
m_nCNC = CNC_FAGOR ;
|
|
|
|
// ciclo di lettura delle linee
|
|
bool bOk = true ;
|
|
string sLine ;
|
|
while ( TheScanner.GetLine( sLine)) {
|
|
m_nLine = TheScanner.GetCurrLineNbr() ;
|
|
if ( ! ProcessLine( sLine)) {
|
|
bOk = false ;
|
|
string sErr = "ImportCnc : Error on line " + ToString( m_nLine) ;
|
|
LOG_ERROR( GetEExLogger(), sErr.c_str())
|
|
}
|
|
}
|
|
|
|
// se importazione riuscita eseguo elaborazione finale
|
|
if ( bOk)
|
|
bOk = PostProcess() ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ProcessLine( const string& sLine)
|
|
{
|
|
// eventuale gestione linea di commento o con etichetta
|
|
if ( sLine[0] == '(' || sLine[0] == ';' || sLine[0] == '\"')
|
|
return ParseRemark( sLine) ;
|
|
|
|
// altre linee da saltare
|
|
if ( sLine[0] == '$' || sLine[0] == '!' || ( sLine[0] == 'M' && sLine[1] == 'S' && sLine[2] == 'G'))
|
|
return true ;
|
|
|
|
// eliminazione di commenti intermedi o finali
|
|
string sMyLine = sLine ;
|
|
// se controllo OSAI elimino le parti dopo ;
|
|
if ( m_nCNC == CNC_OSAI) {
|
|
size_t nStart = sMyLine.find( ';') ;
|
|
if ( nStart == string::npos)
|
|
nStart = sMyLine.find( "@") ;
|
|
if ( nStart != string::npos)
|
|
sMyLine.erase( nStart) ;
|
|
}
|
|
// se controllo NUM elimino le parti tra parentesi tonde
|
|
else if ( m_nCNC == CNC_NUM) {
|
|
size_t nStart = sMyLine.find( '(') ;
|
|
if ( nStart != string::npos) {
|
|
size_t nEnd = sMyLine.find( ')', nStart) ;
|
|
if ( nEnd != string::npos)
|
|
sMyLine.erase( nStart, nEnd - nStart + 1) ;
|
|
else
|
|
sMyLine.erase( nStart) ;
|
|
}
|
|
}
|
|
// se controllo SIEMENS elimino alcuni comandi speciali ed effettuo conversioni
|
|
else if ( m_nCNC == CNC_SIEMENS) {
|
|
size_t nStart = sMyLine.find( "CYCLE800") ;
|
|
if ( nStart == string::npos)
|
|
nStart = sMyLine.find( "CYCLE832") ;
|
|
if ( nStart == string::npos)
|
|
nStart = sMyLine.find( "DYNROUGH") ;
|
|
if ( nStart == string::npos)
|
|
nStart = sMyLine.find( "/WHEN") ;
|
|
if ( nStart != string::npos)
|
|
sMyLine.erase( nStart) ;
|
|
ReplaceString( sMyLine, "SUPA", "G79") ;
|
|
ReplaceString( sMyLine, "AC(", "") ;
|
|
}
|
|
|
|
// divido la linea in parti
|
|
STRVECTOR vsTokens ;
|
|
TokenizePlus( sMyLine, "NGXYZIJKPQRUVWABCFTMHhDEL", vsTokens) ;
|
|
|
|
// analizzo ogni singola parte
|
|
for ( int i = 0 ; i < ssize( vsTokens) ; ++ i) {
|
|
// analizzo per categorie determinate dal primo carattere del token
|
|
switch ( vsTokens[i][0]) {
|
|
case 'G' :
|
|
ParseG( vsTokens[i]) ;
|
|
break ;
|
|
case 'X' :
|
|
ParseX( vsTokens[i]) ;
|
|
break ;
|
|
case 'Y' :
|
|
ParseY( vsTokens[i]) ;
|
|
break ;
|
|
case 'Z' :
|
|
ParseZ( vsTokens[i]) ;
|
|
break ;
|
|
case 'I' :
|
|
ParseI( vsTokens[i]) ;
|
|
break ;
|
|
case 'J' :
|
|
ParseJ( vsTokens[i]) ;
|
|
break ;
|
|
case 'K' :
|
|
ParseK( vsTokens[i]) ;
|
|
break ;
|
|
case 'P' :
|
|
ParseR( vsTokens[i]) ;
|
|
break ;
|
|
case 'Q' :
|
|
ParseR( vsTokens[i]) ;
|
|
break ;
|
|
case 'R' :
|
|
ParseR( vsTokens[i]) ;
|
|
break ;
|
|
case 'A' :
|
|
ParseA( vsTokens[i]) ;
|
|
break ;
|
|
case 'B' :
|
|
ParseB( vsTokens[i]) ;
|
|
break ;
|
|
case 'C' :
|
|
ParseC( vsTokens[i]) ;
|
|
break ;
|
|
case 'T' :
|
|
ParseT( vsTokens[i]) ;
|
|
break ;
|
|
case 'M' :
|
|
ParseM( vsTokens[i]) ;
|
|
break ;
|
|
case 'H' :
|
|
if ( m_nCNC == CNC_FANUC)
|
|
ParseH( vsTokens[i]) ;
|
|
break ;
|
|
case 'h' :
|
|
if ( m_nCNC == CNC_OSAI)
|
|
ParseH( vsTokens[i]) ;
|
|
break ;
|
|
case 'D' :
|
|
if ( m_nCNC != CNC_FANUC && m_nCNC != CNC_OSAI)
|
|
ParseH( vsTokens[i]) ;
|
|
break ;
|
|
}
|
|
}
|
|
|
|
bool bOk = true ;
|
|
// se utensile da caricare
|
|
if ( m_bLoadTool)
|
|
m_nTool = m_nNextTool ;
|
|
// se comando di movimento o riconosciuto movimento, lo eseguo
|
|
if ( m_nCommand == MOVE || m_bToMove)
|
|
bOk = ExecMovement() ;
|
|
// se comando di impostazione piano di interpolazione
|
|
else if ( m_nCommand == IPL)
|
|
bOk = ExecSetIPL() ;
|
|
|
|
// reset stato comandi
|
|
m_nCommand = NO_CMD ;
|
|
m_nCharsOn = 0 ;
|
|
m_bToMove = false ;
|
|
m_bZeroMach = false ;
|
|
m_bLoadTool = false ;
|
|
m_nArcType = NO_ARCTYPE ;
|
|
m_nCompSide = NO_COMP ;
|
|
// centro archi non modale
|
|
m_ptCen = ORIG ;
|
|
|
|
return bOk ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseRemark( const string& sLine)
|
|
{
|
|
// verifico se commento tra parentesi
|
|
bool bBrackets = ( sLine[0] == '(') ;
|
|
// cerco indicazione tipo controllo numerico
|
|
string::size_type iCnc = sLine.find( "CNC/") ;
|
|
if ( iCnc == string::npos)
|
|
iCnc = sLine.find( "CNC=") ;
|
|
if ( iCnc != string::npos) {
|
|
string sCNC = sLine.substr( iCnc + 4) ;
|
|
TrimRight( sCNC, " )") ;
|
|
sCNC = ToUpper( sCNC) ;
|
|
if ( sCNC == "OSAI")
|
|
m_nCNC = CNC_OSAI ;
|
|
else if ( sCNC == "FANUC")
|
|
m_nCNC = CNC_FANUC ;
|
|
else if ( sCNC == "NUM")
|
|
m_nCNC = CNC_NUM ;
|
|
else if ( sCNC == "SIEMENS")
|
|
m_nCNC = CNC_SIEMENS ;
|
|
else if ( sCNC == "TPA")
|
|
m_nCNC = CNC_TPA ;
|
|
else if ( sCNC == "MAZAK")
|
|
m_nCNC = CNC_MAZAK ;
|
|
else if ( sCNC == "FAGOR")
|
|
m_nCNC = CNC_FAGOR ;
|
|
}
|
|
// cerco indicazione di posizione Home
|
|
string::size_type iFrom = sLine.find( "FROM/") ;
|
|
if ( iFrom == string::npos)
|
|
iFrom = sLine.find( "FROM=") ;
|
|
if ( iFrom != string::npos) {
|
|
Point3d ptHome ;
|
|
if ( FromString( sLine.substr( iFrom + 5), ptHome)) {
|
|
m_ptHome = ptHome ;
|
|
m_ptLast = m_ptHome ;
|
|
m_ptNext = m_ptLast ;
|
|
}
|
|
return true ;
|
|
}
|
|
// cerco indicazione di colore
|
|
string::size_type iCol = sLine.find( "COLOR/") ;
|
|
if ( iCol == string::npos)
|
|
iCol = sLine.find( "COLOR=") ;
|
|
if ( iCol != string::npos) {
|
|
int vnVal[3] ;
|
|
if ( FromString( sLine.substr( iCol + 6), vnVal)) {
|
|
m_colCurr.Set( vnVal[0], vnVal[1], vnVal[2]) ;
|
|
}
|
|
return true ;
|
|
}
|
|
// cerco indicazione nome utensile
|
|
string::size_type iTool = sLine.find( "TOOL/") ;
|
|
if ( iTool == string::npos)
|
|
iTool = sLine.find( "TOOL=") ;
|
|
if ( iTool != string::npos) {
|
|
m_sToolName = sLine.substr( iTool + 5) ;
|
|
if ( bBrackets)
|
|
TrimRight( m_sToolName, " )") ;
|
|
return true ;
|
|
}
|
|
// cerco indicazione uscita in uso
|
|
string::size_type iExit = sLine.find( "EXIT/") ;
|
|
if ( iExit == string::npos)
|
|
iExit = sLine.find( "EXIT=") ;
|
|
if ( iExit != string::npos) {
|
|
if ( ! FromString( sLine.substr( iExit + 5), m_nExit))
|
|
m_nExit = 0 ;
|
|
return true ;
|
|
}
|
|
// cerco indicazione posizione nel TC
|
|
string::size_type iTpos = sLine.find( "TPOS/") ;
|
|
if ( iTpos == string::npos)
|
|
iTpos = sLine.find( "TPOS=") ;
|
|
if ( iTpos != string::npos) {
|
|
m_sToolPos = sLine.substr( iTpos + 5) ;
|
|
if ( bBrackets)
|
|
TrimRight( m_sToolPos, " )") ;
|
|
return true ;
|
|
}
|
|
// cerco indicazione seconda posizione nel TC
|
|
string::size_type iTpos2 = sLine.find( "TPOS2/") ;
|
|
if ( iTpos2 == string::npos)
|
|
iTpos2 = sLine.find( "TPOS2=") ;
|
|
if ( iTpos2 != string::npos) {
|
|
m_sToolPos2 = sLine.substr( iTpos2 + 6) ;
|
|
if ( bBrackets)
|
|
TrimRight( m_sToolPos2, " )") ;
|
|
return true ;
|
|
}
|
|
// cerco indicazione Speed
|
|
string::size_type iSpeed = sLine.find( "SPEED/") ;
|
|
if ( iSpeed == string::npos)
|
|
iSpeed = sLine.find( "SPEED=") ;
|
|
if ( iSpeed != string::npos) {
|
|
m_sSpeed = sLine.substr( iSpeed + 6) ;
|
|
if ( bBrackets)
|
|
TrimRight( m_sSpeed, " )") ;
|
|
return true ;
|
|
}
|
|
// cerco informazione da inserire nella prossima entità
|
|
string::size_type iInfo = sLine.find( "INFO/") ;
|
|
if ( iInfo == string::npos)
|
|
iInfo = sLine.find( "INFO=") ;
|
|
if ( iInfo != string::npos) {
|
|
m_vInfos.push_back( sLine.substr( iInfo + 5)) ;
|
|
if ( bBrackets)
|
|
TrimRight( m_vInfos.back(), " )") ;
|
|
return true ;
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseG( const string& sToken)
|
|
{
|
|
int nVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), nVal))
|
|
nVal = 0 ;
|
|
switch ( nVal) {
|
|
case 0 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = RAPID ;
|
|
break ;
|
|
case 1 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = LINE ;
|
|
break ;
|
|
case 2 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = ARC_CW ;
|
|
break ;
|
|
case 3 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = ARC_CCW ;
|
|
break ;
|
|
case 14 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = ARC_MID_3D ;
|
|
break ;
|
|
case 23 :
|
|
m_nCommand = MOVE ;
|
|
m_nMoveType = ARC_MID_2D ;
|
|
break ;
|
|
case 16 :
|
|
m_nCommand = IPL ;
|
|
break ;
|
|
case 17 :
|
|
m_nInterpPl = XY ;
|
|
break ;
|
|
case 18 :
|
|
m_nInterpPl = ZX ;
|
|
break ;
|
|
case 19 :
|
|
m_nInterpPl = YZ ;
|
|
break ;
|
|
case 20 :
|
|
m_dLinCoeff = ONEINCH ;
|
|
break ;
|
|
case 21 :
|
|
m_dLinCoeff = ONEMM ;
|
|
break ;
|
|
case 40 :
|
|
m_nCompSide = G40 ;
|
|
break ;
|
|
case 41 :
|
|
m_nCompSide = G41 ;
|
|
break ;
|
|
case 42 :
|
|
m_nCompSide = G42 ;
|
|
break ;
|
|
case 54 :
|
|
case 55 :
|
|
case 56 :
|
|
case 57 :
|
|
m_vtOffs = V_NULL ;
|
|
m_dOffsAxA = 0 ; m_dOffsAxB = 0 ; m_dOffsAxC = 0 ;
|
|
break ;
|
|
case 58 :
|
|
case 59 :
|
|
m_nCommand = OFFS ;
|
|
m_vtOffs = V_NULL ;
|
|
m_dOffsAxA = 0 ; m_dOffsAxB = 0 ; m_dOffsAxC = 0 ;
|
|
break ;
|
|
case 70 :
|
|
m_dLinCoeff = ONEINCH ;
|
|
break ;
|
|
case 71 :
|
|
m_dLinCoeff = ONEMM ;
|
|
break ;
|
|
case 79 :
|
|
m_bZeroMach = true ;
|
|
break ;
|
|
case 90 :
|
|
m_bAbsCoord = true ;
|
|
break ;
|
|
case 91 :
|
|
m_bAbsCoord = false ;
|
|
break ;
|
|
}
|
|
// per saltare le macro custom su NUM (tipo G101... di S3)
|
|
if ( m_nCNC == CNC_NUM && nVal > 99) {
|
|
m_nCommand = NO_CMD ;
|
|
m_nMoveType = RAPID ;
|
|
m_bZeroMach = true ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseX( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
switch ( m_nCommand) {
|
|
case IPL :
|
|
break ;
|
|
case OFFS :
|
|
m_vtOffs.x = dVal ;
|
|
break ;
|
|
default :
|
|
if ( m_bZeroMach)
|
|
m_ptNext.x = m_ptHome.x + dVal ;
|
|
else
|
|
m_ptNext.x = ( m_bAbsCoord ? m_vtOffs.x + dVal : m_ptLast.x + dVal) ;
|
|
m_bToMove = true ;
|
|
break ;
|
|
}
|
|
m_nCharsOn |= X_ON ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseY( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
switch ( m_nCommand) {
|
|
case IPL :
|
|
break ;
|
|
case OFFS :
|
|
m_vtOffs.y = dVal ;
|
|
break ;
|
|
default :
|
|
if ( m_bZeroMach)
|
|
m_ptNext.y = m_ptHome.y + dVal ;
|
|
else
|
|
m_ptNext.y = ( m_bAbsCoord ? m_vtOffs.y + dVal : m_ptLast.y + dVal) ;
|
|
m_bToMove = true ;
|
|
break ;
|
|
}
|
|
m_nCharsOn |= Y_ON ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseZ( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
switch ( m_nCommand) {
|
|
case IPL :
|
|
break ;
|
|
case OFFS :
|
|
m_vtOffs.z = dVal ;
|
|
break ;
|
|
default :
|
|
if ( m_bZeroMach)
|
|
m_ptNext.z = m_ptHome.z + dVal ;
|
|
else
|
|
m_ptNext.z = ( m_bAbsCoord ? m_vtOffs.z + dVal : m_ptLast.z + dVal) ;
|
|
m_bToMove = true ;
|
|
break ;
|
|
}
|
|
m_nCharsOn |= Z_ON ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseI( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
if ( m_nCNC != CNC_OSAI)
|
|
m_ptCen.x = dVal ;
|
|
else {
|
|
switch ( m_nInterpPl) {
|
|
case XY : m_ptCen.x = dVal ; break ;
|
|
case YZ : m_ptCen.y = dVal ; break ;
|
|
case ZX : m_ptCen.z = dVal ; break ;
|
|
}
|
|
}
|
|
m_nArcType = CENTER ;
|
|
m_bToMove = true ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseJ( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
if ( m_nCNC != CNC_OSAI)
|
|
m_ptCen.y = dVal ;
|
|
else {
|
|
switch ( m_nInterpPl) {
|
|
case XY : m_ptCen.y = dVal ; break ;
|
|
case YZ : m_ptCen.z = dVal ; break ;
|
|
case ZX : m_ptCen.x = dVal ; break ;
|
|
}
|
|
}
|
|
|
|
m_nArcType = CENTER ;
|
|
m_bToMove = true ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseK( const string& sToken)
|
|
{
|
|
if ( m_nCNC == CNC_OSAI)
|
|
return true ;
|
|
// Z del centro dell'arco
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
m_ptCen.z = dVal ;
|
|
m_nArcType = CENTER ;
|
|
m_bToMove = true ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseP( const string& sToken)
|
|
{
|
|
// se direzione utensile NUM (G16) salto e resetto comando
|
|
if ( m_nCommand == IPL) {
|
|
m_nCommand = NO_CMD ;
|
|
return true ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseQ( const string& sToken)
|
|
{
|
|
// se direzione utensile NUM (G16) salto e resetto comando
|
|
if ( m_nCommand == IPL) {
|
|
m_nCommand = NO_CMD ;
|
|
return true ;
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseR( const string& sToken)
|
|
{
|
|
// se direzione utensile NUM (G16) salto e resetto comando
|
|
if ( m_nCommand == IPL) {
|
|
m_nCommand = NO_CMD ;
|
|
return true ;
|
|
}
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
dVal *= m_dLinCoeff ;
|
|
m_dRadius = dVal ;
|
|
m_nArcType = RADIUS ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseA( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( FromString( sToken.substr( nStart), dVal)) {
|
|
if ( m_nCommand == OFFS)
|
|
m_dOffsAxA = dVal ;
|
|
else {
|
|
m_dRotAxA = ( m_bAbsCoord ? m_dOffsAxA + dVal : m_dRotAxA + dVal) ;
|
|
m_bToMove = true ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseB( const string& sToken)
|
|
{
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( FromString( sToken.substr( nStart), dVal)) {
|
|
if ( m_nCommand == OFFS)
|
|
m_dOffsAxB = dVal ;
|
|
else {
|
|
m_dRotAxB = ( m_bAbsCoord ? m_dOffsAxB + dVal : m_dRotAxB + dVal) ;
|
|
m_bToMove = true ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseC( const string& sToken)
|
|
{
|
|
// cerco l'impostazione del raggio con CR= (Siemens)
|
|
if ( sToken.find( "CR=") == 0) {
|
|
double dVal ;
|
|
int nStart = 3 ;
|
|
if ( ! FromString( sToken.substr( nStart), dVal))
|
|
dVal = 0 ;
|
|
m_dRadius = dVal ;
|
|
m_nArcType = RADIUS ;
|
|
return true ;
|
|
}
|
|
// altrimenti può essere l'asse rotante C
|
|
double dVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( FromString( sToken.substr( nStart), dVal)) {
|
|
if ( m_nCommand == OFFS)
|
|
m_dOffsAxC = dVal ;
|
|
else {
|
|
m_dRotAxC = ( m_bAbsCoord ? m_dOffsAxC + dVal : m_dRotAxC + dVal) ;
|
|
m_bToMove = true ;
|
|
}
|
|
}
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseT( const string& sToken)
|
|
{
|
|
int nVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), nVal))
|
|
nVal = 0 ;
|
|
m_nNextTool = nVal ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseM( const string& sToken)
|
|
{
|
|
int nVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), nVal))
|
|
nVal = 0 ;
|
|
if ( nVal == 6)
|
|
m_bLoadTool = true ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ParseH( const string& sToken)
|
|
{
|
|
int nVal ;
|
|
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
|
|
if ( ! FromString( sToken.substr( nStart), nVal))
|
|
nVal = 0 ;
|
|
m_nComp = nVal ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ExecSetIPL( void)
|
|
{
|
|
if ( ( m_nCharsOn & X_ON) != 0 && ( m_nCharsOn & Y_ON)) {
|
|
m_nInterpPl = XY ;
|
|
return true ;
|
|
}
|
|
else if ( ( m_nCharsOn & Y_ON) != 0 && ( m_nCharsOn & Z_ON)) {
|
|
m_nInterpPl = YZ ;
|
|
return true ;
|
|
}
|
|
else if ( ( m_nCharsOn & Z_ON) != 0 && ( m_nCharsOn & X_ON)) {
|
|
m_nInterpPl = ZX ;
|
|
return true ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::ExecMovement( void)
|
|
{
|
|
// se richiesto di ignorare i movimenti in Zero Macchina
|
|
if ( ( m_nFlag & EICFLAG_SKIP_ZEROMACH) != 0 && m_bZeroMach)
|
|
return true ;
|
|
// eseguo movimento
|
|
switch ( m_nMoveType) {
|
|
case RAPID :
|
|
if ( AreSamePointApprox( m_ptLast, m_ptNext))
|
|
return ( RotAxesChanged() ? AddPoint( P_RAPID) : true) ;
|
|
else
|
|
return AddLine( L_RAPID) ;
|
|
case LINE :
|
|
if ( AreSamePointApprox( m_ptLast, m_ptNext))
|
|
return ( RotAxesChanged() ? AddPoint( P_PNT) : true) ;
|
|
else
|
|
return AddLine( L_LINE) ;
|
|
case ARC_CW :
|
|
case ARC_CCW :
|
|
if ( AddArc( m_nMoveType == ARC_CCW))
|
|
return true ;
|
|
if ( AreSamePointApprox( m_ptLast, m_ptNext))
|
|
AddPoint( P_ERROR) ;
|
|
else
|
|
AddLine( L_ERROR) ;
|
|
return false ;
|
|
case ARC_MID_2D :
|
|
case ARC_MID_3D :
|
|
if ( AddArc3P( m_nMoveType == ARC_MID_2D))
|
|
return true ;
|
|
if ( AreSamePointApprox( m_ptLast, m_ptNext))
|
|
AddPoint( P_ERROR) ;
|
|
else
|
|
AddLine( L_ERROR) ;
|
|
return false ;
|
|
}
|
|
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::AddPoint( int nPntType)
|
|
{
|
|
// creo il punto
|
|
PtrOwner<IGeoPoint3d> pGeoPnt( CreateGeoPoint3d()) ;
|
|
if ( IsNull( pGeoPnt))
|
|
return false ;
|
|
// setto il punto
|
|
if ( ! pGeoPnt->Set( 0.5 * ( m_ptLast + m_ptNext)))
|
|
return false ;
|
|
// porto il punto nel riferimento del gruppo
|
|
pGeoPnt->ToLoc( m_frGroup) ;
|
|
// inserisco il punto nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetToolGroup(), Release( pGeoPnt)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// attributi
|
|
switch ( nPntType) {
|
|
case P_RAPID :
|
|
m_pGDB->SetMaterial( nId, COL_RAPID) ;
|
|
break ;
|
|
case P_PNT :
|
|
m_pGDB->SetMaterial( nId, m_colCurr) ;
|
|
break ;
|
|
case P_ERROR :
|
|
m_pGDB->SetMaterial( nId, COL_ERROR) ;
|
|
m_pGDB->SetName( nId, NAME_ERROR) ;
|
|
break ;
|
|
}
|
|
// assegnazione numero di linea
|
|
m_pGDB->SetName( nId, ToString( m_nLine)) ;
|
|
// assegnazione eventuale uscita
|
|
if ( m_nExit != 0) {
|
|
m_pGDB->SetInfo( nId, KEY_EXIT, m_nExit) ;
|
|
m_nExit = 0 ;
|
|
}
|
|
// assegnazione eventuali assi rotanti
|
|
if ( ! isnan( m_dRotAxA))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_A, m_dRotAxA) ;
|
|
if ( ! isnan( m_dRotAxB))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_B, m_dRotAxB) ;
|
|
if ( ! isnan( m_dRotAxC))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_C, m_dRotAxC) ;
|
|
// assegnazione eventuali info
|
|
SetInfos( nId) ;
|
|
m_vInfos.clear() ;
|
|
// movimento effettuato
|
|
m_ptLast = m_ptNext ;
|
|
SaveRotAxes() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::AddLine( int nLineType)
|
|
{
|
|
// creo la linea
|
|
PtrOwner<ICurveLine> pCrvLine( CreateCurveLine()) ;
|
|
if ( IsNull( pCrvLine))
|
|
return false ;
|
|
// setto la linea
|
|
if ( ! pCrvLine->Set( m_ptLast, m_ptNext))
|
|
return false ;
|
|
// porto la linea nel riferimento del gruppo
|
|
pCrvLine->ToLoc( m_frGroup) ;
|
|
// inserisco la linea nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetToolGroup(), Release( pCrvLine)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// attributi
|
|
switch ( nLineType) {
|
|
case L_RAPID :
|
|
m_pGDB->SetMaterial( nId, COL_RAPID) ;
|
|
break ;
|
|
case L_LINE :
|
|
m_pGDB->SetMaterial( nId, m_colCurr) ;
|
|
break ;
|
|
case L_ERROR :
|
|
m_pGDB->SetMaterial( nId, COL_ERROR) ;
|
|
m_pGDB->SetName( nId, NAME_ERROR) ;
|
|
break ;
|
|
}
|
|
// eventuale info sul correttore (se non è riferito a zero macchina)
|
|
if ( m_nComp != 0 && ! m_bZeroMach)
|
|
m_pGDB->SetInfo( nId, KEY_TCOMP, m_nComp) ;
|
|
// eventuale info su lato di correzione
|
|
if ( m_nCompSide != NO_COMP)
|
|
m_pGDB->SetInfo( nId, KEY_TCS, m_nCompSide) ;
|
|
// assegnazione numero di linea
|
|
m_pGDB->SetName( nId, ToString( m_nLine)) ;
|
|
// assegnazione eventuale uscita
|
|
if ( m_nExit != 0) {
|
|
m_pGDB->SetInfo( nId, KEY_EXIT, m_nExit) ;
|
|
m_nExit = 0 ;
|
|
}
|
|
// assegnazione eventuali assi rotanti
|
|
if ( ! isnan( m_dRotAxA))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_A, m_dRotAxA) ;
|
|
if ( ! isnan( m_dRotAxB))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_B, m_dRotAxB) ;
|
|
if ( ! isnan( m_dRotAxC))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_C, m_dRotAxC) ;
|
|
// assegnazione eventuali info
|
|
SetInfos( nId) ;
|
|
m_vInfos.clear() ;
|
|
// movimento effettuato
|
|
m_ptLast = m_ptNext ;
|
|
SaveRotAxes() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::AddArc( bool bCCW)
|
|
{
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc))
|
|
return false ;
|
|
// determino la normale al piano di interpolazione
|
|
Vector3d vtN = Z_AX ;
|
|
if ( m_nInterpPl == ZX)
|
|
vtN = Y_AX ;
|
|
else if ( m_nInterpPl == YZ)
|
|
vtN = X_AX ;
|
|
// se arco definito con raggio
|
|
if ( m_nArcType == RADIUS) {
|
|
// punti estremi, raggio e senso di rotazione
|
|
if ( ! pCrvArc->Set2PNRS( m_ptLast, m_ptNext, vtN, abs( m_dRadius), bCCW))
|
|
return false ;
|
|
// se raggio negativo, si deve prendere la soluzione con AngCen > 180deg
|
|
if ( m_dRadius < 0) {
|
|
if ( ! pCrvArc->Flip() || ! pCrvArc->ToExplementary())
|
|
return false ;
|
|
}
|
|
}
|
|
// se arco definito con centro
|
|
else if ( m_nArcType == CENTER) {
|
|
// determino se valido
|
|
switch ( VerifyArcCenter( vtN)) {
|
|
case A_ARC :
|
|
// punti estremi e centro
|
|
pCrvArc.Set( GetArc2PCN( m_ptLast, m_ptNext, m_ptCen, vtN)) ;
|
|
if ( IsNull( pCrvArc))
|
|
return false ;
|
|
// verifico senso di rotazione
|
|
if ( ( bCCW && pCrvArc->GetAngCenter() < 0) ||
|
|
( ! bCCW && pCrvArc->GetAngCenter() > 0)) {
|
|
if ( ! pCrvArc->ToExplementary())
|
|
return false ;
|
|
}
|
|
break ;
|
|
case A_CIRC :
|
|
// calcolo standard
|
|
if ( ! SetCircC2PN( m_ptCen, m_ptLast, m_ptNext, vtN, pCrvArc))
|
|
return false ;
|
|
// verifico senso di rotazione
|
|
if ( ( bCCW && pCrvArc->GetAngCenter() < 0) ||
|
|
( ! bCCW && pCrvArc->GetAngCenter() > 0)) {
|
|
if ( ! pCrvArc->Invert())
|
|
return false ;
|
|
}
|
|
break ;
|
|
default :
|
|
return false ;
|
|
}
|
|
}
|
|
// altrimenti errore
|
|
else
|
|
return false ;
|
|
// porto l'arco nel riferimento del gruppo
|
|
pCrvArc->ToLoc( m_frGroup) ;
|
|
// inserisco l'arco nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetToolGroup(), Release( pCrvArc)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// assegnazione del colore
|
|
if ( ! m_pGDB->SetMaterial( nId, m_colCurr))
|
|
return false ;
|
|
// assegnazione numero di linea
|
|
m_pGDB->SetName( nId, ToString( m_nLine)) ;
|
|
// assegnazione eventuale uscita
|
|
if ( m_nExit != 0) {
|
|
m_pGDB->SetInfo( nId, KEY_EXIT, m_nExit) ;
|
|
m_nExit = 0 ;
|
|
}
|
|
// assegnazione eventuali assi rotanti
|
|
if ( ! isnan( m_dRotAxA))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_A, m_dRotAxA) ;
|
|
if ( ! isnan( m_dRotAxB))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_B, m_dRotAxB) ;
|
|
if ( ! isnan( m_dRotAxC))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_C, m_dRotAxC) ;
|
|
// assegnazione eventuali info
|
|
SetInfos( nId) ;
|
|
m_vInfos.clear() ;
|
|
// movimento effettuato
|
|
m_ptLast = m_ptNext ;
|
|
SaveRotAxes() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::AddArc3P( bool bIs2D)
|
|
{
|
|
// creo l'arco
|
|
PtrOwner<ICurveArc> pCrvArc( CreateCurveArc()) ;
|
|
if ( IsNull( pCrvArc))
|
|
return false ;
|
|
// se arco definito in 2D
|
|
if ( bIs2D) {
|
|
// determino la normale al piano di interpolazione
|
|
Vector3d vtN = Z_AX ;
|
|
if ( m_nInterpPl == ZX)
|
|
vtN = Y_AX ;
|
|
else if ( m_nInterpPl == YZ)
|
|
vtN = X_AX ;
|
|
// calcolo le proiezioni dei punti intermedio e finale nel piano del punto iniziale
|
|
Point3d ptCen2D = m_ptCen - ( m_ptCen - m_ptLast) * vtN * vtN ;
|
|
Point3d ptNext2D = m_ptNext - ( m_ptNext - m_ptLast) * vtN * vtN ;
|
|
// punto iniziale, intermedio e finale in 2D
|
|
if ( ! pCrvArc->Set3P( m_ptLast, ptCen2D, ptNext2D))
|
|
return false ;
|
|
// se normale arco opposta a normale piano interpolazione, sistemo
|
|
if ( ! AreSameVectorApprox( vtN, pCrvArc->GetNormVersor()))
|
|
pCrvArc->InvertN() ;
|
|
// aggiusto per il punto finale
|
|
pCrvArc->ChangeDeltaN( ( m_ptNext - ptNext2D) * vtN) ;
|
|
}
|
|
// altrimenti è in 3D
|
|
else {
|
|
// punto iniziale, intermedio e finale
|
|
if ( ! pCrvArc->Set3P( m_ptLast, m_ptCen, m_ptNext))
|
|
return false ;
|
|
}
|
|
// porto l'arco nel riferimento del gruppo
|
|
pCrvArc->ToLoc( m_frGroup) ;
|
|
// inserisco l'arco nel DB
|
|
int nId = m_pGDB->AddGeoObj( GDB_ID_NULL, GetToolGroup(), Release( pCrvArc)) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return false ;
|
|
// assegnazione del colore
|
|
if ( ! m_pGDB->SetMaterial( nId, m_colCurr))
|
|
return false ;
|
|
// assegnazione numero di linea
|
|
m_pGDB->SetName( nId, ToString( m_nLine)) ;
|
|
// assegnazione eventuale uscita
|
|
if ( m_nExit != 0) {
|
|
m_pGDB->SetInfo( nId, KEY_EXIT, m_nExit) ;
|
|
m_nExit = 0 ;
|
|
}
|
|
// assegnazione eventuali assi rotanti
|
|
if ( ! isnan( m_dRotAxA))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_A, m_dRotAxA) ;
|
|
if ( ! isnan( m_dRotAxB))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_B, m_dRotAxB) ;
|
|
if ( ! isnan( m_dRotAxC))
|
|
m_pGDB->SetInfo( nId, KEY_ROTAX_C, m_dRotAxC) ;
|
|
// assegnazione eventuali info
|
|
SetInfos( nId) ;
|
|
m_vInfos.clear() ;
|
|
// movimento effettuato
|
|
m_ptLast = m_ptNext ;
|
|
SaveRotAxes() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ImportCnc::VerifyArcCenter( const Vector3d& vtN)
|
|
{
|
|
// calcolo il riferimento OCS derivato da vtN
|
|
Frame3d frOcs ;
|
|
if ( ! frOcs.Set( ORIG, vtN))
|
|
return A_ERROR ;
|
|
// porto i punti in questo riferimento
|
|
Point3d ptLloc = GetToLoc( m_ptLast, frOcs) ;
|
|
Point3d ptNloc = GetToLoc( m_ptNext, frOcs) ;
|
|
Point3d ptCloc = GetToLoc( m_ptCen, frOcs) ;
|
|
Vector3d vtOloc = GetToLoc( m_vtOffs, frOcs) ;
|
|
// verifico se circonferenza
|
|
int nRet = ( SqDistXY( ptLloc, ptNloc) > EPS_SMALL * EPS_SMALL) ? A_ARC : A_CIRC ;
|
|
// se controllo Fanuc o Fagor, centro è sempre in relativo
|
|
if ( m_nCNC == CNC_FANUC || m_nCNC == CNC_FAGOR) {
|
|
// centro in relativo
|
|
Point3d ptCrl = ptCloc + ptLloc ;
|
|
double dRadLast = DistXY( ptLloc, ptCrl) ;
|
|
double dRadNext = DistXY( ptNloc, ptCrl) ;
|
|
if ( abs( dRadNext - dRadLast) < 100 * EPS_SMALL) {
|
|
m_ptCen = GetToGlob( ptCrl, frOcs) ;
|
|
return nRet ;
|
|
}
|
|
}
|
|
// se coordinate in assoluto prima verifico in assoluto
|
|
else if ( m_bAbsCoord) {
|
|
// centro in assoluto
|
|
Point3d ptCas = ptCloc + vtOloc ;
|
|
double dRadCasLast = DistXY( ptLloc, ptCas) ;
|
|
double dRadCasNext = DistXY( ptNloc, ptCas) ;
|
|
// centro in relativo
|
|
Point3d ptCrl = ptCloc + ptLloc ;
|
|
double dRadCrlLast = DistXY( ptLloc, ptCrl) ;
|
|
double dRadCrlNext = DistXY( ptNloc, ptCrl) ;
|
|
// controlli con precisione più elevata
|
|
if ( abs( dRadCasNext - dRadCasLast) < 10 * EPS_SMALL) {
|
|
m_ptCen += m_vtOffs ;
|
|
return nRet ;
|
|
}
|
|
if ( abs( dRadCrlNext - dRadCrlLast) < 10 * EPS_SMALL) {
|
|
m_ptCen = GetToGlob( ptCrl, frOcs) ;
|
|
return nRet ;
|
|
}
|
|
// controlli con precisione più bassa
|
|
if ( abs( dRadCasNext - dRadCasLast) < 100 * EPS_SMALL) {
|
|
m_ptCen += m_vtOffs ;
|
|
return nRet ;
|
|
}
|
|
if ( abs( dRadCrlNext - dRadCrlLast) < 100 * EPS_SMALL) {
|
|
m_ptCen = GetToGlob( ptCrl, frOcs) ;
|
|
return nRet ;
|
|
}
|
|
}
|
|
// altrimenti coordinate in relativo e prima provo queste
|
|
else {
|
|
// centro in relativo
|
|
Point3d ptCrl = ptCloc + ptLloc ;
|
|
double dRadCrlLast = DistXY( ptLloc, ptCrl) ;
|
|
double dRadCrlNext = DistXY( ptNloc, ptCrl) ;
|
|
// centro in assoluto
|
|
Point3d ptCas = ptCloc + vtOloc ;
|
|
double dRadCasLast = DistXY( ptLloc, ptCas) ;
|
|
double dRadCasNext = DistXY( ptNloc, ptCas) ;
|
|
// controlli con precisione più elevata
|
|
if ( abs( dRadCrlNext - dRadCrlLast) < 10 * EPS_SMALL) {
|
|
m_ptCen = GetToGlob( ptCrl, frOcs) ;
|
|
return nRet ;
|
|
}
|
|
if ( abs( dRadCasNext - dRadCasLast) < 10 * EPS_SMALL) {
|
|
m_ptCen += m_vtOffs ;
|
|
return nRet ;
|
|
}
|
|
// controlli con precisione più bassa
|
|
if ( abs( dRadCrlNext - dRadCrlLast) < 100 * EPS_SMALL) {
|
|
m_ptCen = GetToGlob( ptCrl, frOcs) ;
|
|
return nRet ;
|
|
}
|
|
if ( abs( dRadCasNext - dRadCasLast) < 100 * EPS_SMALL) {
|
|
m_ptCen += m_vtOffs ;
|
|
return nRet ;
|
|
}
|
|
}
|
|
|
|
return A_ERROR ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::SetCircC2PN( const Point3d& ptCen, const Point3d& ptStart, const Point3d& ptNearEnd, const Vector3d& vtN,
|
|
ICurveArc* pCrvArc)
|
|
{
|
|
// calcolo il riferimento OCS derivato da vtN
|
|
Frame3d frOcs ;
|
|
if ( ! frOcs.Set( ORIG, vtN))
|
|
return false ;
|
|
// porto i punti in questo riferimento
|
|
Point3d ptCloc = GetToLoc( ptCen, frOcs) ;
|
|
Point3d ptSloc = GetToLoc( ptStart, frOcs) ;
|
|
Point3d ptNEloc = GetToLoc( ptNearEnd, frOcs) ;
|
|
// calcolo il cerchio in questo piano
|
|
double dRad = 0.5 * ( DistXY( ptCloc, ptSloc) + DistXY( ptCloc, ptNEloc)) ;
|
|
ptCloc.z = ptSloc.z ;
|
|
Vector3d vtS = ptSloc - ptCloc ;
|
|
if ( ! pCrvArc->Set( ptCloc, Z_AX, dRad, vtS, ANG_FULL, ptNEloc.z - ptSloc.z))
|
|
return false ;
|
|
// riporto l'arco nel riferimento naturale
|
|
return pCrvArc->ToGlob( frOcs) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
ImportCnc::GetToolGroup( void)
|
|
{
|
|
// assegno il nome dell'utensile
|
|
string sTool = "T" + ToString( m_nTool, 2) ;
|
|
|
|
// se trovo un gruppo con il nome dell'utensile, ne restituisco l'Id
|
|
if ( m_nFirstGroup != GDB_ID_NULL) {
|
|
string sName ;
|
|
if ( m_pGDB->GetName( m_nFirstGroup, sName) && sName == sTool)
|
|
return m_nFirstGroup ;
|
|
int nId = m_pGDB->GetNextName( m_nFirstGroup, sTool) ;
|
|
if ( nId != GDB_ID_NULL)
|
|
return nId ;
|
|
}
|
|
|
|
// inserisco un nuovo layer nel DB geometrico
|
|
int nId = m_pGDB->AddGroup( GDB_ID_NULL, m_nIdGroup, GLOB_FRM) ;
|
|
if ( nId == GDB_ID_NULL)
|
|
return GDB_ID_NULL ;
|
|
// assegnazione nome
|
|
if ( ! m_pGDB->SetName( nId, sTool))
|
|
return GDB_ID_NULL ;
|
|
// se definito nome utensile, assegno info relativa
|
|
if ( ! m_sToolName.empty())
|
|
m_pGDB->SetInfo( nId, KEY_TNAME, m_sToolName) ;
|
|
m_sToolName.clear() ;
|
|
// se definita posizione utensile, assegno info relativa
|
|
if ( ! m_sToolPos.empty())
|
|
m_pGDB->SetInfo( nId, KEY_TPOS, m_sToolPos) ;
|
|
m_sToolPos.clear() ;
|
|
// se definita seconda posizione utensile, assegno info relativa
|
|
if ( ! m_sToolPos2.empty())
|
|
m_pGDB->SetInfo( nId, KEY_TPOS2, m_sToolPos2) ;
|
|
m_sToolPos2.clear() ;
|
|
// se definita speed utensile, assegno info relativa
|
|
if ( ! m_sSpeed.empty())
|
|
m_pGDB->SetInfo( nId, KEY_SPEED, m_sSpeed) ;
|
|
m_sSpeed.clear() ;
|
|
// se è il primo, lo salvo
|
|
if ( m_nFirstGroup == GDB_ID_NULL)
|
|
m_nFirstGroup = nId ;
|
|
|
|
return nId ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::PostProcess( void)
|
|
{
|
|
// se richiesto concatenamento dei percorsi
|
|
if ( ( m_nFlag & EICFLAG_CHAIN) != 0) {
|
|
// gestore di curva composita
|
|
PtrOwner<ICurveComposite> pCompo ;
|
|
// ciclo sui gruppi
|
|
int nGroupId = m_nFirstGroup ;
|
|
while ( nGroupId != GDB_ID_NULL) {
|
|
// ciclo sulle entità del gruppo
|
|
Color cCol ;
|
|
int nComp = 0 ;
|
|
int nCompSide = 0 ;
|
|
int nId = m_pGDB->GetFirstInGroup( nGroupId) ;
|
|
while ( nId != GDB_ID_NULL) {
|
|
// leggo eventuali info correttore utensile
|
|
int nTcomp = 0 ; m_pGDB->GetInfo( nId, KEY_TCOMP, nTcomp) ;
|
|
// leggo eventuali info di correzione raggio utensile
|
|
int nTcs = 0 ; m_pGDB->GetInfo( nId, KEY_TCS, nTcs) ;
|
|
// se curva e G40/G41/G42 o non rapido, la aggiungo alla composita
|
|
if ( ( m_pGDB->GetGeoType( nId) & GEO_CURVE) != 0 &&
|
|
( nTcs == 40 || nTcs == 41 || nTcs == 42 || ! IsRapid( nId))) {
|
|
// se G41 o G42 termino eventuale precedente composita
|
|
if ( ( nTcs == 41 || nTcs == 42) && ! IsNull( pCompo) && pCompo->GetCurveCount() > 0) {
|
|
if ( ! InsertCurveComposite( Release( pCompo), cCol, nComp, nCompSide, nId, GDB_BEFORE))
|
|
return false ;
|
|
}
|
|
// se non c'è la composita, la creo ed assegno colore e lato di lavoro
|
|
if ( IsNull( pCompo)) {
|
|
pCompo.Set( CreateCurveComposite()) ;
|
|
if ( IsNull( pCompo))
|
|
return false ;
|
|
m_pGDB->GetMaterial( nId, cCol) ;
|
|
// considero inserimento correttore sempre in feed
|
|
if ( ( nTcs == 41 || nTcs == 42) && cCol == COL_RAPID)
|
|
cCol = BLACK ;
|
|
nComp = nTcomp ;
|
|
nCompSide = nTcs ;
|
|
}
|
|
// calcolo prossimo Id
|
|
int nNextId = m_pGDB->GetNext( nId) ;
|
|
// estraggo la curva e la accodo alla composita
|
|
ICurve* pCrv = GetCurve( m_pGDB->RemoveGeoObjAndErase( nId)) ;
|
|
if ( ! pCompo->AddCurve( pCrv, true, 10 * EPS_SMALL))
|
|
return false ;
|
|
// passo alla successiva
|
|
nId = nNextId ;
|
|
// se G40 termino la composita
|
|
if ( nTcs == 40) {
|
|
if ( nId != GDB_ID_NULL) {
|
|
if ( ! InsertCurveComposite( Release( pCompo), cCol, nComp, nCompSide, nId, GDB_BEFORE))
|
|
return false ;
|
|
}
|
|
else {
|
|
if ( ! InsertCurveComposite( Release( pCompo), cCol, nComp, nCompSide, nGroupId, GDB_LAST_SON))
|
|
return false ;
|
|
}
|
|
}
|
|
}
|
|
// altrimenti
|
|
else {
|
|
// se c'è curva in costruzione con qualcosa, la salvo
|
|
if ( ! IsNull( pCompo) && pCompo->GetCurveCount() > 0) {
|
|
if ( ! InsertCurveComposite( Release( pCompo), cCol, nComp, nCompSide, nId, GDB_BEFORE))
|
|
return false ;
|
|
}
|
|
// passo alla successiva
|
|
nId = m_pGDB->GetNext( nId) ;
|
|
}
|
|
}
|
|
// se c'è curva in costruzione con qualcosa, la salvo
|
|
if ( ! IsNull( pCompo) && pCompo->GetCurveCount() > 0) {
|
|
if ( ! InsertCurveComposite( Release( pCompo), cCol, nComp, nCompSide, nGroupId, GDB_LAST_SON))
|
|
return false ;
|
|
}
|
|
// passo al gruppo successivo
|
|
nGroupId = m_pGDB->GetNextGroup( nGroupId) ;
|
|
}
|
|
}
|
|
|
|
// se richiesta eliminazione dei movimenti in rapido
|
|
if ( ( m_nFlag & EICFLAG_SKIP_RAPID) != 0) {
|
|
// ciclo sui gruppi
|
|
int nGroupId = m_nFirstGroup ;
|
|
while ( nGroupId != GDB_ID_NULL) {
|
|
// ciclo sulle entità del gruppo
|
|
int nId = m_pGDB->GetFirstInGroup( nGroupId) ;
|
|
while ( nId != GDB_ID_NULL) {
|
|
// se movimento in rapido, lo cancello
|
|
if ( IsRapid( nId)) {
|
|
int nNextId = m_pGDB->GetNext( nId) ;
|
|
m_pGDB->Erase( nId) ;
|
|
nId = nNextId ;
|
|
}
|
|
// altrimenti passo oltre
|
|
else
|
|
nId = m_pGDB->GetNext( nId) ;
|
|
}
|
|
// passo al gruppo successivo
|
|
nGroupId = m_pGDB->GetNextGroup( nGroupId) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::IsRapid( int nId)
|
|
{
|
|
Color cCol ;
|
|
return ( m_pGDB != nullptr && m_pGDB->GetMaterial( nId, cCol) && cCol == COL_RAPID) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::InsertCurveComposite( ICurveComposite* pCompo, Color cCol, int nComp, int nSide, int nRefId, int nSonBeforeAfter)
|
|
{
|
|
int nCmpId = m_pGDB->InsertGeoObj( GDB_ID_NULL, nRefId, nSonBeforeAfter, pCompo) ;
|
|
if ( nCmpId == GDB_ID_NULL)
|
|
return false ;
|
|
m_pGDB->SetMaterial( nCmpId, cCol) ;
|
|
if ( nComp != 0)
|
|
m_pGDB->SetInfo( nCmpId, KEY_TCOMP, nComp) ;
|
|
if ( nSide != 0)
|
|
m_pGDB->SetInfo( nCmpId, KEY_TCS, nSide) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
ImportCnc::SetInfos( int nId)
|
|
{
|
|
for ( int i = 0, j = 1 ; i < int( m_vInfos.size()) ; ++ i) {
|
|
string sKey, sVal ;
|
|
SplitFirst( m_vInfos[i], "=", sKey, sVal) ;
|
|
if ( ! sKey.empty() && ! sVal.empty())
|
|
m_pGDB->SetInfo( nId, sKey, sVal) ;
|
|
else
|
|
m_pGDB->SetInfo( nId, KEY_INFO + ToString( j ++), m_vInfos[i]) ;
|
|
}
|
|
return true ;
|
|
}
|