//---------------------------------------------------------------------------- // EgalTech 2015-2015 //---------------------------------------------------------------------------- // File : ImportBtl.cpp Data : 22.08.15 Versione : 1.6h5 // Contenuto : Implementazione della classe per l'importazione BTL. // // // // Modifiche : 22.08.15 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ImportBtl.h" #include "DllMain.h" #include "/EgtDev/Include/EExDllMain.h" #include "/EgtDev/Include/EGkStmStandard.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/EgtPointerOwner.h" using namespace std ; //---------------------------------------------------------------------------- // Sezioni static const std::string SEC_GENERAL = "[GENERAL]" ; static const std::string SEC_RAWPART = "[RAWPART]" ; static const std::string SEC_PART = "[PART]" ; static const std::string SEC_COMPOSITE = "[COMPOSITE]" ; // Chiavi static const std::string KEY_BUILD = "BUILD" ; static const std::string KEY_SCALEUNIT = "SCALEUNIT" ; static const std::string KEY_SINGLEMEMBERNUMBER = "SINGLEMEMBERNUMBER" ; static const std::string KEY_DESIGNATION = "DESIGNATION" ; static const std::string KEY_COUNT = "COUNT" ; static const std::string KEY_LENGTH = "LENGTH" ; static const std::string KEY_HEIGHT = "HEIGHT" ; static const std::string KEY_WIDTH = "WIDTH" ; static const std::string KEY_UID = "UID" ; static const std::string KEY_TRANSFORMATION = "TRANSFORMATION" ; static const std::string KEY_OUTLINE = "OUTLINE" ; static const std::string KEY_APERTURE = "APERTURE" ; static const std::string KEY_PROCESSKEY = "PROCESSKEY" ; static const std::string KEY_REFERENCEPLANE = "REFERENCEPLANE" ; static const std::string KEY_PROCESSPARAMETERS = "PROCESSPARAMETERS" ; static const std::string KEY_PROCESSIDENT = "PROCESSIDENT" ; // Parametri static const std::string PAR_OX = "OX" ; static const std::string PAR_OY = "OY" ; static const std::string PAR_OZ = "OZ" ; static const std::string PAR_XX = "XX" ; static const std::string PAR_XY = "XY" ; static const std::string PAR_XZ = "XZ" ; static const std::string PAR_YX = "YX" ; static const std::string PAR_YY = "YY" ; static const std::string PAR_YZ = "YZ" ; static const std::string PAR_SIDE = "SIDE" ; static const std::string PAR_P = "P" ; //---------------------------------------------------------------------------- IImportBtl* CreateImportBtl( void) { // verifico la chiave e le opzioni if ( ! TestKeyForEEx( GetEExKey(), KEYOPT_EEX_INPADV, GetEExLogger())) return false ; // creo l'oggetto return static_cast ( new(nothrow) ImportBtl) ; } //---------------------------------------------------------------------------- ImportBtl::ImportBtl( void) { m_nBuild = 10000 ; m_dScale = 1 ; } //---------------------------------------------------------------------------- bool ImportBtl::Import( const string& sFile, IGeomDB* pGDB, bool bFlatPos, bool bSpecialTrim) { // log di informazioni LOG_INFO( GetEExLogger(), ( "ImportBtl : " + sFile).c_str()) // inizializzo lo scanner if ( ! m_theScanner.Init( sFile, ";")) { LOG_ERROR( GetEExLogger(), " Error on Init") return false ; } // inizializzo il gestore geometria pezzi Btl if ( ! m_BtlGeom.Init( pGDB, bFlatPos, bSpecialTrim)) { LOG_ERROR( GetEExLogger(), " Error on BtlGeom.Init") return false ; } // lettura intestazione if ( ! ReadHeader()) { string sOut = " Error (ReadHeader) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } // lettura generalità if ( ! ReadGeneral()) { string sOut = " Error (ReadGeneral) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) return false ; } // ciclo sui grezzi bool bOk = true ; for ( bool bEnd = false ; ! bEnd ;) { if ( ! ReadRawPart( bEnd)) { string sOut = " Error (ReadRawPart) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) bOk = false ; } } // ciclo sui pezzi for ( bool bEnd = false ; ! bEnd ;) { if ( ! ReadPart( bEnd)) { // i log di errore sono già gestiti nella funzione chiamata bOk = false ; } } // ciclo sui compositi for ( bool bEnd = false ; ! bEnd ;) { if ( ! ReadComposite( bEnd)) { string sOut = " Error on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) bOk = false ; } } return bOk ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadHeader( void) { // conteggio campi utili letti int nRead = 0 ; // ciclo sulle linee string sLine ; while ( m_theScanner.GetLine( sLine)) { // se cambio sezione if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; return ( nRead == 1) ; } // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // se numero di versione if ( sKey == KEY_BUILD) { Trim( sVal, " \t\r\n\"") ; if ( FromString( sVal, m_nBuild)) ++ nRead ; } } return false ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadGeneral( void) { // conteggio campi utili letti int nRead = 0 ; // leggo la prossima linea e verifico sia la sezione GENERAL string sLine ; if ( ! m_theScanner.GetLine( sLine) || sLine != SEC_GENERAL) return false ; // ciclo sulle linee while ( m_theScanner.GetLine( sLine)) { // se cambio sezione if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; return ( nRead == 1) ; } // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // se numero di decimali if ( sKey == KEY_SCALEUNIT) { int nUnit ; if ( FromString( sVal, nUnit)) { m_dScale = pow( 10, - nUnit) ; ++ nRead ; } } } return false ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadRawPart( bool& bEnd) { string sLine ; // leggo la prossima linea e verifico sia la sezione RAWPART if ( ! m_theScanner.GetLine( sLine)) { bEnd = true ; return true ; } // verifico sia la sezione RAWPART if ( sLine != SEC_RAWPART) { m_theScanner.UngetLine( sLine) ; bEnd = true ; return true ; } // ciclo sulle linee while ( m_theScanner.GetLine( sLine)) { // se cambio sezione if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; bEnd = false ; return true ; } // ignoro tutto } bEnd = true ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadPart( bool& bEnd) { string sLine ; // leggo la prossima linea if ( ! m_theScanner.GetLine( sLine)) { bEnd = true ; return true ; } // verifico sia la sezione PART if ( sLine != SEC_PART) { m_theScanner.UngetLine( sLine) ; bEnd = true ; return true ; } // creo il pezzo if ( ! m_BtlGeom.CreatePart()) { string sOut = " Error (CreatePart) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrSection() ; bEnd = false ; return false ; } // ciclo sulle linee con i dati generali del pezzo double dLength = 0, dHeight = 0, dWidth = 0 ; bool bLength = false, bHeight = false, bWidth = false, bBox = false ; bool bOutline = false ; int nUID = 0 ; while ( m_theScanner.GetLine( sLine)) { // se cambio sezione if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; bEnd = false ; return true ; } // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // identificativo di produzione if ( sKey == KEY_SINGLEMEMBERNUMBER) { int nProdNbr = 0 ; if ( FromString( sVal, nProdNbr)) m_BtlGeom.SetPartProdNbr( nProdNbr) ; } // nome else if ( sKey == KEY_DESIGNATION) { Trim( sVal, " \t\r\n\"") ; m_BtlGeom.SetPartName( sVal) ; } // numero di pezzi da produrre else if ( sKey == KEY_COUNT) { int nCount = 0 ; if ( FromString( sVal, nCount)) m_BtlGeom.SetPartCount( nCount) ; } // lunghezza (dimensione in X) else if ( sKey == KEY_LENGTH) { if ( FromString( sVal, dLength)) { dLength *= m_dScale ; bLength = true ; } if ( bLength && bHeight && bWidth) { if ( m_BtlGeom.AddPartBox( dLength, dHeight, dWidth)) bBox = true ; } } // altezza (dimensione in Y) else if ( sKey == KEY_HEIGHT) { if ( FromString( sVal, dHeight)) { dHeight *= m_dScale ; bHeight = true ; } if ( bLength && bHeight && bWidth) { if ( m_BtlGeom.AddPartBox( dLength, dHeight, dWidth)) bBox = true ; } } // larghezza (dimensione in Z) else if ( sKey == KEY_WIDTH) { if ( FromString( sVal, dWidth)) { dWidth *= m_dScale ; bWidth = true ; } if ( bLength && bHeight && bWidth) { if ( m_BtlGeom.AddPartBox( dLength, dHeight, dWidth)) bBox = true ; } } // UID istanza pezzo nella struttura else if ( sKey == KEY_UID) { FromString( sVal, nUID) ; } // matrice di trasformazione istanza pezzo nella struttura else if ( sKey == KEY_TRANSFORMATION) { Frame3d frRef ; if ( ReadTransformation( sVal, frRef)) m_BtlGeom.AddPartTransformation( nUID, frRef) ; } // contorno else if ( sKey == KEY_OUTLINE) { // interpreto l'outline m_theScanner.UngetLine( sLine) ; if ( ! ReadOutline()) { string sOut = " Error (ReadOutline) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrSection() ; m_BtlGeom.ErasePart() ; bEnd = false ; return false ; } bOutline = true ; } // apertura else if ( sKey == KEY_APERTURE) { // interpreto l'apertura m_theScanner.UngetLine( sLine) ; if ( ! ReadAperture()) { string sOut = " Error (ReadAperture) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrSection() ; m_BtlGeom.ErasePart() ; bEnd = false ; return false ; } } // lavorazione else if ( sKey == KEY_PROCESSKEY) { m_theScanner.UngetLine( sLine) ; break ; } } // verifico sia stato definito il contorno del pezzo if ( ! bBox) { string sOut = " Error (AddPartBox) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrSection() ; m_BtlGeom.ErasePart() ; bEnd = false ; return false ; } // se non trovato l'outline lo aggiungo if ( ! bOutline) { if ( ! m_BtlGeom.AddPartStdOutline()) { string sOut = " Error (AddPartStdOutline) on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrSection() ; m_BtlGeom.ErasePart() ; bEnd = false ; return false ; } } // interpreto le lavorazioni (processing) bool bOk = true ; for ( bool bProcEnd = false ; ! bProcEnd ;) { if ( ! ReadProcess( bProcEnd)) { // i log di errore sono già gestiti nella funzione chiamata bOk = false ; } } bEnd = false ; return bOk ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadComposite( bool& bEnd) { string sLine ; // leggo la prossima linea if ( ! m_theScanner.GetLine( sLine)) { bEnd = true ; return true ; } // verifico sia la sezione COMPOSITE if ( sLine != SEC_COMPOSITE) { bEnd = true ; return true ; } // ciclo sulle linee while ( m_theScanner.GetLine( sLine)) { // se cambio sezione if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; bEnd = false ; return true ; } // ignoro tutto } bEnd = true ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadTransformation( const string& sVal, Frame3d& frRef) { // leggo i valori Point3d ptO ; GetParam( sVal, PAR_OX, ptO.x) ; GetParam( sVal, PAR_OY, ptO.y) ; GetParam( sVal, PAR_OZ, ptO.z) ; Vector3d vtX ; GetParam( sVal, PAR_XX, vtX.x) ; GetParam( sVal, PAR_XY, vtX.y) ; GetParam( sVal, PAR_XZ, vtX.z) ; Vector3d vtY ; GetParam( sVal, PAR_YX, vtY.x) ; GetParam( sVal, PAR_YY, vtY.y) ; GetParam( sVal, PAR_YZ, vtY.z) ; // calcolo il riferimento return frRef.Set( ptO, ptO + vtX, ptO + vtY) ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadOutline( void) { int nSide = BTL_SIDE_NONE ; FCEDEQUE dqFce ; // ciclo sulle linee string sLine ; while ( m_theScanner.GetLine( sLine)) { // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // se cambio tipologia, concludo if ( sKey != KEY_OUTLINE) { m_theScanner.UngetLine( sLine) ; break ; } // leggo i dati // tipo int nFlag ; GetParamP( sVal, 8, nFlag) ; // se non ancora assegnata, leggo faccia di riferimento if ( nSide == BTL_SIDE_NONE) GetInfo( sVal, PAR_SIDE, nSide) ; // punto principale Point3d ptP ; GetParamP( sVal, 1, ptP.x) ; GetParamP( sVal, 2, ptP.y) ; GetParamP( sVal, 3, ptP.z) ; // se arco leggo il punto intermedio Point3d ptM ; if ( nFlag == FreeContourEnt::ARC) { GetParamP( sVal, 10, ptM.x) ; GetParamP( sVal, 11, ptM.y) ; GetParamP( sVal, 12, ptM.z) ; } // aggiungo i dati alla deque dqFce.emplace_back( nFlag, ptP, ptM, 0, 0, 0) ; } // inserimento del contorno nel pezzo return m_BtlGeom.AddPartOutline( nSide, dqFce) ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadAperture( void) { int nSide = BTL_SIDE_NONE ; FCEDEQUE dqFce ; // ciclo sulle linee string sLine ; while ( m_theScanner.GetLine( sLine)) { // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // se cambio tipologia, concludo if ( sKey != KEY_APERTURE) { m_theScanner.UngetLine( sLine) ; break ; } // leggo i dati // tipo int nFlag ; GetParamP( sVal, 8, nFlag) ; // se tipo start ed esistono precedenti entità, ne derivo una apertura if ( nFlag == FreeContourEnt::START && dqFce.size() > 0) { if ( ! m_BtlGeom.AddPartAperture( nSide, dqFce)) return false ; nSide = BTL_SIDE_NONE ; dqFce.clear() ; } // se non ancora assegnata, leggo faccia di riferimento if ( nSide == BTL_SIDE_NONE) GetInfo( sVal, PAR_SIDE, nSide) ; // punto principale Point3d ptP ; GetParamP( sVal, 1, ptP.x) ; GetParamP( sVal, 2, ptP.y) ; GetParamP( sVal, 3, ptP.z) ; // se arco leggo il punto intermedio Point3d ptM ; if ( nFlag == FreeContourEnt::ARC) { GetParamP( sVal, 10, ptM.x) ; GetParamP( sVal, 11, ptM.y) ; GetParamP( sVal, 12, ptM.z) ; } // aggiungo i dati alla deque dqFce.emplace_back( nFlag, ptP, ptM, 0, 0, 0) ; } // inserimento dell'ultima apertura nel pezzo return m_BtlGeom.AddPartAperture( nSide, dqFce) ; } //---------------------------------------------------------------------------- bool ImportBtl::ReadProcess( bool& bProcEnd) { bProcEnd = false ; string sLine ; // leggo la prossima linea if ( ! m_theScanner.GetLine( sLine)) { bProcEnd = true ; return true ; } // verifico sia l'istruzione PROCESSKEY if ( sLine.find( KEY_PROCESSKEY) == string::npos) { m_theScanner.UngetLine( sLine) ; bProcEnd = true ; return true ; } // recupero i parametri string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; TrimLeft( sVal) ; string sType, sDes ; SplitFirst( sVal, " ", sType, sDes) ; Trim( sDes) ; STRVECTOR vsItem ; Tokenize( sType, "-", vsItem) ; if ( vsItem.size() < 3) { string sOut = " Error in ProcessType(" + sType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrProcess() ; bProcEnd = false ; return false ; } int nGroup = 0 ; FromString( vsItem[0], nGroup) ; int nProc = 0 ; FromString( vsItem[1], nProc) ; int nSide = 0 ; FromString( vsItem[2], nSide) ; bool bParams = false ; INTVECTOR vnDPar ; int nSPar ; DBLVECTOR vdPar ; string sPar ; int nProcId = 0 ; Frame3d frRef ; // ciclo sulle linee while ( true) { // se fine file, concludo if ( ! m_theScanner.GetLine( sLine)) { bProcEnd = true ; break ; } // se cambio sezione, concludo if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; bProcEnd = true ; break ; } // se nuova lavorazione, concludo if ( sLine.find( KEY_PROCESSKEY) != string::npos) { m_theScanner.UngetLine( sLine) ; bProcEnd = false ; break ; } // spezzo la linea string sKey, sVal ; SplitFirst( sLine, ":", sKey, sVal) ; // se riferimento if ( sKey == KEY_REFERENCEPLANE) { if ( ! ReadTransformation( sVal, frRef)) { string sOut = " Error : unable to read ReferencePlane (" + sType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrProcess() ; bProcEnd = false ; return false ; } } // se parametri else if ( sKey == KEY_PROCESSPARAMETERS) { if ( ! m_BtlGeom.GetProcessParamInfos( nGroup, nProc, nSide, vnDPar, nSPar, vdPar, sPar)) { string sOut = " Error : Unknown Process (" + sType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrProcess() ; bProcEnd = false ; return true ; } else if ( ! GetProcessParams( sVal, sType, vnDPar, nSPar, vdPar, sPar)) { string sOut = " Error in GetProcessParams (" + sType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) SkipCurrProcess() ; bProcEnd = false ; return false ; } bParams = true ; } // se identificativo else if ( sKey == KEY_PROCESSIDENT) { FromString( sVal, nProcId) ; } } // inserimento della lavorazione nel pezzo if ( ! bParams || ! m_BtlGeom.AddProcess( nGroup, nProc, nSide, sDes, nProcId, frRef, vnDPar, nSPar, vdPar, sPar, m_theScanner.GetCurrLineNbr())) { string sOut = " Error in AddProcess (" + sType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_ERROR( GetEExLogger(), sOut.c_str()) bProcEnd = false ; return false ; } bProcEnd = false ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::SkipCurrSection( void) { // ciclo sulle linee string sLine ; while ( true) { // se fine file, concludo if ( ! m_theScanner.GetLine( sLine)) { break ; } // se cambio sezione, concludo if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; break ; } } return true ; } //---------------------------------------------------------------------------- bool ImportBtl::SkipCurrProcess( void) { // ciclo sulle linee string sLine ; while ( true) { // se fine file, concludo if ( ! m_theScanner.GetLine( sLine)) { break ; } // se cambio sezione, concludo if ( sLine[0] == '[') { m_theScanner.UngetLine( sLine) ; break ; } // se nuova lavorazione, concludo if ( sLine.find( KEY_PROCESSKEY) != string::npos) { m_theScanner.UngetLine( sLine) ; break ; } } return true ; } //---------------------------------------------------------------------------- bool ImportBtl::GetProcessParams( const string& sText, const string& sProcType, const INTVECTOR& vnDPar, int nSPar, DBLVECTOR& vdPar, string& sPar) { // verifico corrispondenza numero definizioni - numero parametri numerici if ( vnDPar.size() != vdPar.size()) return false ; // leggo i parametri numerici for ( int i = 0 ; i < int( vnDPar.size()) ; ++ i) { if ( ! GetParamP( sText, vnDPar[i], vdPar[i])) { string sOut = " Info : P" + ToString( vnDPar[i], 2) + " missing in Process (" + sProcType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_INFO( GetEExLogger(), sOut.c_str()) } } // leggo l'eventuale parametro stringa if ( nSPar != 0) { if ( ! GetParamP( sText, nSPar, sPar)) { string sOut = " Info : P" + ToString( nSPar, 2) + " missing in Process (" + sProcType + ") on line " + ToString( m_theScanner.GetCurrLineNbr()) ; LOG_INFO( GetEExLogger(), sOut.c_str()) } } return true ; } //---------------------------------------------------------------------------- bool ImportBtl::GetInfo( const string& sText, const string& sPar, int& nVal) { // cerco l'identificativo del parametro size_t nPos = sText.find( sPar + ":") ; if ( nPos == string::npos) return false ; // recupero la stringa successiva const int SVAL_LEN = 14 ; string sVal = sText.substr( nPos + sPar.length() + 1, SVAL_LEN) ; TrimLeft( sVal, " \t\r\n0") ; nVal = 0 ; FromString( sVal, nVal) ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::GetParam( const string& sText, const string& sPar, double& dVal) { // cerco l'identificativo del parametro size_t nPos = sText.find( sPar + ":") ; if ( nPos == string::npos) return false ; // recupero la stringa successiva const int SVAL_LEN = 14 ; string sVal = sText.substr( nPos + sPar.length() + 1, SVAL_LEN) ; TrimLeft( sVal, " \t\r\n0") ; dVal = 0 ; FromString( sVal, dVal) ; dVal *= m_dScale ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::GetParam( const string& sText, const string& sPar, string& sVal) { // cerco l'identificativo del parametro size_t nPos = sText.find( sPar + ":") ; if ( nPos == string::npos) return false ; // cerco i delimitatori della stringa " size_t nPosI = sText.find( "\"", nPos + sPar.length() + 1) ; if ( nPosI == string::npos) return false ; size_t nPosF = sText.find( "\"", nPosI + 1) ; if ( nPosF == string::npos) return false ; // estraggo la stringa sVal = sText.substr( nPosI + 1, nPosF - nPosI - 1) ; return true ; } //---------------------------------------------------------------------------- bool ImportBtl::GetParamP( const string& sText, int nInd, int& nVal) { // creo l'identificativo string sPar = PAR_P + ToString( nInd, 2) ; // leggo il parametro double dVal ; bool bOk = GetParam( sText, sPar, dVal) ; nVal = lround( dVal) ; return bOk ; } //---------------------------------------------------------------------------- bool ImportBtl::GetParamP( const string& sText, int nInd, double& dVal) { // creo l'identificativo string sPar = PAR_P + ToString( nInd, 2) ; // leggo il parametro return GetParam( sText, sPar, dVal) ; } //---------------------------------------------------------------------------- bool ImportBtl::GetParamP( const string& sText, int nInd, string& sVal) { // creo l'identificativo string sPar = PAR_P + ToString( nInd, 2) ; // leggo il parametro return GetParam( sText, sPar, sVal) ; }