d1cebf628c
- cambiato ordine parametri su linea di comando e aggiunta tolleranza lineare.
368 lines
13 KiB
C++
368 lines
13 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2020-2020
|
|
//----------------------------------------------------------------------------
|
|
// File : EgtConverter.cpp Data : 20.11.20 Versione : 2.2k2
|
|
// Contenuto : Importatore da formati avanzati tramite C3d.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 12.09.20 DS Creazione modulo.
|
|
// 20.11.20 SP Trasformazione diretta in nge.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "/EgtDev/Extern/C3d/Include/tool_enabler.h"
|
|
#include "/EgtDev/Extern/C3d/Include/model.h"
|
|
#include "/EgtDev/Extern/C3d/Include/conv_model_exchange.h"
|
|
#include "/EgtDev/Extern/C3d/Include/conv_exchange_settings.h"
|
|
#include "/EgtDev/Extern/C3d/Include/solid.h"
|
|
#include "/EgtDev/Extern/C3d/Include/assembly.h"
|
|
#include "/EgtDev/Extern/C3d/Include/mesh.h"
|
|
#include "/EgtDev/Extern/C3d/Include/attr_color.h"
|
|
#include "/EgtDev/Extern/C3d/Include/mb_property.h"
|
|
#include "/EgtDev/Extern/C3d/Include/attr_product.h"
|
|
#include "stdafx.h"
|
|
#include "/EgtDev/Include/EGkDllMain.h"
|
|
#include "/EgtDev/Include/EGkGeomDB.h"
|
|
#include "/EgtDev/Include/EGkColor.h"
|
|
#include "/EgtDev/Include/EGkStmFromTriangleSoup.h"
|
|
#include "/EgtDev/Include/EGnStringUtils.h"
|
|
#include "/EgtDev/Include/EGnFileUtils.h"
|
|
#include "/EgtDev/Include/EgtStringConverter.h"
|
|
#include "/EgtDev/Include/EgtLogger.h"
|
|
#include "/EgtDev/Include/EgtPointerOwner.h"
|
|
#include "/EgtDev/Include/SELkLockId.h"
|
|
#include "/EgtDev/Include/SELkKeyProc.h"
|
|
|
|
using namespace c3d ;
|
|
using namespace std ;
|
|
using namespace egtlogger ;
|
|
|
|
//--------------------------- Costanti ----------------------------------------
|
|
#if defined( _WIN64)
|
|
#if defined( _DEBUG)
|
|
const char* EXE_STR = "EgtConverterD64.exe ver 2.2k3" ;
|
|
#else
|
|
const char* EXE_STR = "EgtConverterR64.exe ver 2.2k3" ;
|
|
#endif
|
|
#elif defined( _WIN32)
|
|
#if defined( _DEBUG)
|
|
const char* EXE_STR = "EgtConverterD32.exe ver 2.2k3" ;
|
|
#else
|
|
const char* EXE_STR = "EgtConverterR32.exe ver 2.2k3" ;
|
|
#endif
|
|
#endif
|
|
|
|
//------------------------- Prototipi locali ---------------------------------
|
|
bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
|
|
bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
|
|
bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ;
|
|
|
|
//------------------------- Variabili locali ---------------------------------
|
|
static double s_dLinToler = 0.1 ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
int
|
|
wmain( int argc, wchar_t* argv[])
|
|
{
|
|
// Primo parametro della linea di comando : nome eseguibile
|
|
// Non interessa
|
|
// Secondo parametro della linea di comando : file di input
|
|
wstring swInpName = ( argc >= 2 ? argv[1] : L"") ;
|
|
if ( swInpName.empty()) {
|
|
cout << "Missing input file path" ;
|
|
return 1 ;
|
|
}
|
|
string sInpName = wstringtoA( swInpName) ;
|
|
// Terzo parametro della linea di comando : file di output
|
|
wstring swExpName = ( argc >= 3 ? argv[2] : L"") ;
|
|
if ( swExpName.empty()) {
|
|
cout << "Missing output file path" ;
|
|
return 2 ;
|
|
}
|
|
string sExpName = wstringtoA( swExpName) ;
|
|
// Quarto parametro della linea di comando : errore cordale massimo
|
|
wstring swToler = ( argc >= 4 ? argv[3] : L"0.1") ;
|
|
string sToler = wstringtoA( swToler) ;
|
|
FromString( sToler, s_dLinToler) ;
|
|
// Quinto parametro della linea di comando : livello di debug
|
|
wstring swDebugLev = ( argc >= 5 ? argv[4] : L"0") ;
|
|
string sDebugLev = wstringtoA( swDebugLev) ;
|
|
int nDebugLev = 0 ;
|
|
FromString( sDebugLev, nDebugLev) ;
|
|
// Sesto parametro della linea di comando : licenza
|
|
wstring swKeyCode = ( argc >= 6 ? argv[5] : L"") ;
|
|
if ( swKeyCode.empty()) {
|
|
cout << "Missing key code" ;
|
|
return 3 ;
|
|
}
|
|
string sKeyCode = wstringtoA( swKeyCode) ;
|
|
|
|
// Creo il logger
|
|
Logger* pGenLog = new( nothrow) Logger( ( nDebugLev > 0 ? LL_DEBUG : LL_INFO), "EgtConverter") ;
|
|
if ( pGenLog == nullptr) {
|
|
cout << "Error creating logger" ;
|
|
return 4 ;
|
|
}
|
|
// assegno il file
|
|
string sLogFile = ChangeFileExtension( sExpName, "txt") ;
|
|
pGenLog->AddOutputStream( new( nothrow) ofstream( sLogFile), true) ;
|
|
|
|
// Imposto la chiave di protezione alle librerie di base
|
|
SetEGkKeyType( KEY_LOCK_TYPE_HW) ;
|
|
SetEGkKey( sKeyCode) ;
|
|
|
|
// Imposto livello di debug alle librerie di base
|
|
SetEGkDebugLev( nDebugLev) ;
|
|
// Imposto logger
|
|
SetEGkLogger( pGenLog) ;
|
|
|
|
// Dichiaro inizio programma
|
|
LOG_DATETIME( pGenLog, " Init")
|
|
// messaggio dall'applicazione
|
|
LOG_INFO( pGenLog, EXE_STR)
|
|
// versione dei componenti
|
|
string sVer ;
|
|
sVer += GetEGkVersion() ;
|
|
LOG_INFO( pGenLog, sVer.c_str())
|
|
// tolleranza lineare
|
|
LOG_INFO( pGenLog, ( "Toler=" + sToler).c_str())
|
|
// livello di log
|
|
LOG_INFO( pGenLog, ( "DbgLev=" + sDebugLev).c_str())
|
|
|
|
// Activation of the geometric kernel C3D.
|
|
string str0( "Egaltech..[cnv][mdl]") ;
|
|
string str1( "JW02HxzIKyBIMzDWswgytSRB98wcImMzPTohT44M5EbQK8BpmEHA54hEkogovfCbtMufHIT2HbjX6NSp1+gpEw==") ;
|
|
EnableMathModules( str0.c_str(), (int)str0.length(), str1.c_str(), (int)str1.length()) ;
|
|
|
|
// Verify module activation
|
|
bool bModOk = IsMathModelerEnable() ;
|
|
bool bConvOk = IsMathConverterEnable() ;
|
|
if ( ! bModOk || ! bConvOk) {
|
|
LOG_ERROR( pGenLog, "Error activating Modeler or Converter") ;
|
|
return 9 ;
|
|
}
|
|
|
|
// File import
|
|
LOG_INFO( pGenLog, ( "File to import : " + sInpName).c_str())
|
|
MbModel geomModel ;
|
|
int nReadRes = ImportFromFile( geomModel, C3DToPathstring( swInpName)) ;
|
|
if ( nReadRes != cnv_Success) {
|
|
if ( nReadRes == cnv_FileOpenError)
|
|
LOG_ERROR( pGenLog, "Error opening input file")
|
|
else if ( nReadRes == cnv_UnknownExtension)
|
|
LOG_ERROR( pGenLog, "Unkwown input file type")
|
|
else if ( nReadRes == cnv_NotEnoughMemory)
|
|
LOG_ERROR( pGenLog, "Not enough memory")
|
|
else
|
|
LOG_ERROR( pGenLog, "Internal error during read")
|
|
return 11 ;
|
|
}
|
|
|
|
// Creo GeomDB
|
|
PtrOwner<IGeomDB> pGeomDB( CreateGeomDB()) ;
|
|
if ( IsNull( pGeomDB)){
|
|
LOG_ERROR( pGenLog, "Error creating GeomDB");
|
|
return 12 ;
|
|
}
|
|
|
|
// Inserisco gli oggetti nel GeomDB (sotto pezzo/layer)
|
|
pGeomDB->SetDefaultMaterial( Color( 176, 176, 176)) ;
|
|
int nPartId = pGeomDB->AddGroup( GDB_ID_NULL, GDB_ID_ROOT, Frame3d()) ;
|
|
int nLayId = pGeomDB->AddGroup( GDB_ID_NULL, nPartId, Frame3d()) ;
|
|
// ciclo sul modello importato
|
|
for ( MbModel::ItemIterator it=geomModel.Begin() ; it!=geomModel.End() ; it++ ) {
|
|
|
|
bool bSolOk = true ;
|
|
|
|
if ( ( *it)->IsA() == st_Assembly)
|
|
bSolOk = assembly_handler( *it, nLayId, pGeomDB, pGenLog) ;
|
|
else if ( ( *it)->IsA() == st_Solid)
|
|
bSolOk = solid_handler( *it, nLayId, pGeomDB, pGenLog) ;
|
|
else if ( ( *it)->IsA() == st_Instance)
|
|
bSolOk = instance_handler(*it, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
if ( ! bSolOk)
|
|
return 14 ;
|
|
}
|
|
|
|
// Salvo il progetto
|
|
bool bOk = pGeomDB->Save( GDB_ID_ROOT, sExpName, GDB_SV_BIN) ;
|
|
if ( ! bOk) {
|
|
LOG_ERROR( pGenLog, "Error saving GeomDB") ;
|
|
return 13 ;
|
|
}
|
|
else
|
|
LOG_INFO( pGenLog, "Conversion finished with success")
|
|
|
|
// Free of the geometric kernel C3D
|
|
FreeMathModulesChecker() ;
|
|
|
|
LOG_DATETIME( pGenLog, " Exit")
|
|
|
|
return 0 ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
|
|
{
|
|
MbSolid* pSolid = static_cast<MbSolid*>( pIt) ;
|
|
if ( pSolid == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Solid pointer null") ;
|
|
return false ;
|
|
}
|
|
|
|
// Creazione mesh
|
|
MbStepData stepdata ;
|
|
stepdata.Init( ist_SpaceStep, s_dLinToler, M_PI / 12, 100) ;
|
|
|
|
MbFormNote note( false, true) ;
|
|
MbMesh mesh ;
|
|
pSolid->CalculateMesh( stepdata, note, mesh) ;
|
|
|
|
StmFromTriangleSoup Stm ;
|
|
bool bStmOk = Stm.Start() ;
|
|
if ( ! bStmOk) {
|
|
LOG_ERROR( pGenLog, "stm : Error creating stm") ;
|
|
return false ;
|
|
}
|
|
|
|
// scorro le grids
|
|
for ( size_t i = 0 ; i < mesh.GridsCount() ; i++) {
|
|
|
|
const MbGrid* grid = mesh.GetGrid( i) ;
|
|
|
|
// scorro i triangoli
|
|
for ( size_t j = 0 ; j < grid->TrianglesCount() ; j++) {
|
|
MbCartPoint3D p0, p1, p2 ;
|
|
grid->GetTrianglePoints( j, p0, p1, p2) ;
|
|
|
|
bool bTAddOk = Stm.AddTriangle( Point3d( p0.x, p0.y, p0.z), Point3d( p1.x, p1.y, p1.z), Point3d( p2.x, p2.y, p2.z)) ;
|
|
if ( ! bTAddOk) {
|
|
LOG_ERROR( pGenLog, "Stm : Error adding triangle")
|
|
}
|
|
}
|
|
}
|
|
|
|
bStmOk = Stm.End() ;
|
|
if ( ! bStmOk) {
|
|
LOG_ERROR( pGenLog, "Error : Stm finalizing") ;
|
|
return false ;
|
|
}
|
|
|
|
ISurfTriMesh* pSurf = Stm.GetSurf() ;
|
|
if ( pSurf == nullptr) {
|
|
LOG_ERROR( pGenLog, "Error : Stm getting SurfTriMesh") ;
|
|
return false ;
|
|
}
|
|
|
|
int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pSurf) ;
|
|
if ( nId == GDB_ID_NULL) {
|
|
LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ;
|
|
return false ;
|
|
}
|
|
|
|
// Aggiungo attributes
|
|
AttrVector attributes ;
|
|
pSolid->GetAttributes( attributes, at_Undefined, at_Undefined) ;
|
|
|
|
for ( unsigned int i = 0; i < attributes.size(); i++) {
|
|
|
|
MbAttribute* pAttr = attributes[i] ;
|
|
if ( pAttr == nullptr)
|
|
continue ;
|
|
|
|
if ( pAttr->AttributeType() == at_ProductInfo) {
|
|
MbProductInfo* pInfo = static_cast<MbProductInfo*>( pAttr) ;
|
|
if ( ! pInfo->GetName().empty()) {
|
|
pGeomDB->SetName( nId, ToSTDstring( pInfo->GetName())) ;
|
|
if ( ! pInfo->GetId().empty())
|
|
pGeomDB->SetInfo( nId, "Id", ToSTDstring( pInfo->GetId())) ;
|
|
}
|
|
else if ( ! pInfo->GetId().empty())
|
|
pGeomDB->SetName( nId, ToSTDstring( pInfo->GetName())) ;
|
|
if ( ! pInfo->GetDescription().empty())
|
|
pGeomDB->SetInfo( nId, "Description", ToSTDstring( pInfo->GetDescription())) ;
|
|
}
|
|
|
|
else if ( pAttr->AttributeType() == at_Color) {
|
|
MbColor* pColorAttr = static_cast<MbColor*>( pAttr) ;
|
|
uint32 col = pColorAttr->Color() ;
|
|
float r, g, b = 0 ;
|
|
uint322RGB( col, r, g, b) ;
|
|
pGeomDB->SetMaterial( nId, Color( r, g, b)) ;
|
|
}
|
|
|
|
else {
|
|
uint32 col = pSolid->GetColor() ;
|
|
float r, g, b = 0 ;
|
|
uint322RGB( col, r, g, b) ;
|
|
pGeomDB->SetMaterial( nId, Color( r, g, b)) ;
|
|
}
|
|
}
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
|
|
{
|
|
MbAssembly* pAss = static_cast<MbAssembly*>( pIt) ;
|
|
if ( pAss == nullptr)
|
|
return false ;
|
|
|
|
//Analizzo gl elementi dell'assembly
|
|
RPArray <MbItem> assItems ;
|
|
pAss->GetItems( assItems) ;
|
|
|
|
for ( MbItem** it2 = assItems.begin() ; it2 != assItems.end() ; it2 ++) {
|
|
bool bSolOk = true ;
|
|
|
|
if ( (*it2)->IsA() == st_Assembly)
|
|
bSolOk = assembly_handler( *it2, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
else if ( (*it2)->IsA() == st_Solid)
|
|
bSolOk = solid_handler( *it2, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
else if ( (*it2)->IsA() == st_Instance)
|
|
bSolOk = instance_handler( *it2, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
if ( ! bSolOk)
|
|
return false ;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog)
|
|
{
|
|
MbInstance* pInst = static_cast<MbInstance*>( pIt) ;
|
|
if ( pInst == nullptr)
|
|
return false ;
|
|
const MbItem* pInstItem = pInst->GetItem() ;
|
|
if ( pInstItem == nullptr)
|
|
return false ;
|
|
MbItem* pItem = static_cast<MbItem*>( &pInstItem->Duplicate()) ;
|
|
if ( pItem == nullptr)
|
|
return false ;
|
|
MbPlacement3D InstPlacement = pInst->GetPlacement() ;
|
|
|
|
// Matrice di trasformazione dalle coord locali a quelle assolute
|
|
MbMatrix3D matrix( InstPlacement) ;
|
|
pItem->Transform( matrix) ;
|
|
|
|
// Analizzo l'item dell'instance
|
|
if ( pInstItem->IsA() == st_Solid)
|
|
return solid_handler( pItem, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
else if ( pInstItem->IsA() == st_Assembly)
|
|
return assembly_handler( pItem, nLayId, pGeomDB, pGenLog) ;
|
|
|
|
return false ;
|
|
}
|