Files
EgtExchange/ImportCnc.cpp
T
Dario Sassi 716b861006 EgtExchange 1.6x3 :
- in ImportCnc aggiunta opzione per saltare movimenti in Zero Macchina.
2016-12-27 09:05:47 +00:00

967 lines
28 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2014-2014
//----------------------------------------------------------------------------
// File : ImportCnc.cpp Data : 15.09.14 Versione : 1.5i3
// Contenuto : Implementazione della classe per l'importazione di CNC.
//
//
//
// Modifiche : 15.09.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- 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/EGnScanner.h"
#include "/EgtDev/Include/SELkKeyProc.h"
#include "/EgtDev/Include/EgtKeyCodes.h"
#include "/EgtDev/Include/EgtStringConverter.h"
#include "/EgtDev/Include/EgtPointerOwner.h"
using namespace std ;
//----------------------------------------------------------------------------
static const Color COL_RAPID( 0, 192, 192, 50) ;
static const string KEY_TCS = "TCS" ;
static const string KEY_TCOMP = "TCOMP" ;
static const string KEY_TNAME = "TNAME" ;
//----------------------------------------------------------------------------
IImportCnc*
CreateImportCnc( void)
{
// verifico la chiave e le opzioni
if ( ! TestKeyForEEx( GetEExKey(), KEYOPT_EEX_INPBASE, GetEExLogger()))
return false ;
// 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_bToMove = 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_dRadius = 0 ;
m_colCurr = BLACK ;
m_sToolName.clear() ;
// ciclo di lettura delle linee
bool bOk = true ;
string sLine ;
while ( TheScanner.GetLine( sLine)) {
if ( ! ProcessLine( sLine)) {
bOk = false ;
string sErr = "ImportCnc : Error on line " + ToString( TheScanner.GetCurrLineNbr()) ;
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] == '$')
return true ;
// divido la linea in parti
STRVECTOR vsTokens ;
TokenizePlus( sLine, "NGXYZIJKPQRUVWABCFTMHh", vsTokens) ;
// analizzo ogni singola parte
for ( size_t i = 0 ; i < vsTokens.size() ; ++ 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 'C' :
ParseC( vsTokens[i]) ;
break ;
case 'T' :
ParseT( vsTokens[i]) ;
break ;
case 'M' :
ParseM( vsTokens[i]) ;
break ;
case 'h' :
Parseh( vsTokens[i]) ;
break ;
}
}
bool bOk = true ;
// 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_nArcType = NO_ARCTYPE ;
m_nCompSide = NO_COMP ;
return bOk ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::ParseRemark( const string& sLine)
{
// 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) ;
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 16 :
m_nCommand = IPL ;
break ;
case 17 :
m_nInterpPl = XY ;
break ;
case 18 :
m_nInterpPl = ZX ;
break ;
case 19 :
m_nInterpPl = YZ ;
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 ;
break ;
case 58 :
case 59 :
m_nCommand = OFFS ;
m_vtOffs = V_NULL ;
break ;
case 79 :
m_bZeroMach = true ;
break ;
case 90 :
m_bAbsCoord = true ;
break ;
case 91 :
m_bAbsCoord = false ;
break ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::ParseX( const string& sToken)
{
double dVal ;
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
if ( ! FromString( sToken.substr( nStart), dVal))
dVal = 0 ;
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 ;
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 ;
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 ;
m_ptCen.x = dVal ;
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 ;
m_ptCen.y = dVal ;
m_nArcType = CENTER ;
m_bToMove = true ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::ParseK( const string& sToken)
{
double dVal ;
int nStart = ( sToken[1] == '=' ? 2 : 1) ;
if ( ! FromString( sToken.substr( nStart), dVal))
dVal = 0 ;
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 ;
m_dRadius = dVal ;
m_nArcType = RADIUS ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::ParseC( const string& sToken)
{
// cerco l'impostazione del raggio con CR= (Siemens)
if ( sToken.find( "CR=") != 0)
return true ;
double dVal ;
int nStart = 3 ;
if ( ! FromString( sToken.substr( nStart), dVal))
dVal = 0 ;
m_dRadius = dVal ;
m_nArcType = RADIUS ;
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_nTool = m_nNextTool ;
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 :
return AddLine( L_RAPID) ;
case LINE :
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() ;
else
AddLine( L_ERROR) ;
return false ;
}
return false ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::AddPoint( void)
{
// 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
m_pGDB->SetMaterial( nId, RED) ;
m_pGDB->SetName( nId, "Error") ;
// movimento effettuato
m_ptLast = m_ptNext ;
return true ;
}
//----------------------------------------------------------------------------
bool
ImportCnc::AddLine( int nLineType)
{
// se la linea è nulla, non la inserisco ma proseguo senza errore
if ( AreSamePointApprox( m_ptLast, m_ptNext))
return true ;
// 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, RED) ;
m_pGDB->SetName( nId, "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) ;
// movimento effettuato
m_ptLast = m_ptNext ;
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, fabs( 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
if ( ! pCrvArc->SetC2PN( m_ptCen, m_ptLast, m_ptNext, vtN))
return false ;
break ;
case A_CIRC :
// calcolo standard
if ( ! SetCircC2PN( m_ptCen, m_ptLast, m_ptNext, vtN, pCrvArc))
return false ;
break ;
default :
return false ;
}
// verifico senso di rotazione
if ( ( bCCW && pCrvArc->GetAngCenter() < 0) ||
( ! bCCW && pCrvArc->GetAngCenter() > 0)) {
if ( ! pCrvArc->ToExplementary())
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 ;
// movimento effettuato
m_ptLast = m_ptNext ;
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 = m_ptLast ;
ptLloc.ToLoc( frOcs) ;
Point3d ptNloc = m_ptNext ;
ptNloc.ToLoc( frOcs) ;
Point3d ptCloc = m_ptCen ;
ptCloc.ToLoc( frOcs) ;
Vector3d vtOloc = m_vtOffs ;
vtOloc.ToLoc( frOcs) ;
// verifico se circonferenza
int nRet = ( SqDistXY( ptLloc, ptNloc) > EPS_SMALL * EPS_SMALL) ? A_ARC : A_CIRC ;
// se coordinate in assoluto prima verifico in assoluto
if ( m_bAbsCoord) {
// centro in assoluto
Point3d ptCas = ptCloc + vtOloc ;
double dRadLast = DistXY( ptLloc, ptCas) ;
double dRadNext = DistXY( ptNloc, ptCas) ;
if ( fabs ( dRadNext - dRadLast) < 10 * EPS_SMALL) {
m_ptCen += m_vtOffs ;
return nRet ;
}
// centro in relativo
Point3d ptCrl = ptCloc + ptLloc ;
dRadLast = DistXY( ptLloc, ptCrl) ;
dRadNext = DistXY( ptNloc, ptCrl) ;
if ( fabs ( dRadNext - dRadLast) < 10 * EPS_SMALL) {
m_ptCen = ptCrl ;
m_ptCen.ToGlob( frOcs) ;
return nRet ;
}
}
// altrimenti coordinate in relativo e prima provo queste
else {
// centro in relativo
Point3d ptCrl = ptCloc + ptLloc ;
double dRadLast = DistXY( ptLloc, ptCrl) ;
double dRadNext = DistXY( ptNloc, ptCrl) ;
if ( fabs ( dRadNext - dRadLast) < 10 * EPS_SMALL) {
m_ptCen = ptCrl ;
m_ptCen.ToGlob( frOcs) ;
return nRet ;
}
// centro in assoluto
Point3d ptCas = ptCloc + vtOloc ;
dRadLast = DistXY( ptLloc, ptCas) ;
dRadNext = DistXY( ptNloc, ptCas) ;
if ( fabs ( dRadNext - dRadLast) < 10 * 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 = ptCen ;
ptCloc.ToLoc( frOcs) ;
Point3d ptSloc = ptStart ;
ptSloc.ToLoc( frOcs) ;
Point3d ptNEloc = ptNearEnd ;
ptNEloc.ToLoc( 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 è 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) ;
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)) ;
pCompo->AddCurve( pCrv) ;
// 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 ;
}