//---------------------------------------------------------------------------- // EgalTech 2020-2023 //---------------------------------------------------------------------------- // File : EgtConverter.cpp Data : 03.05.23 Versione : 2.5e1 // Contenuto : Importatore da formati avanzati tramite C3d. // // // // Modifiche : 12.09.20 DS Creazione modulo. // 20.11.20 SP Trasformazione diretta in nge. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #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/mb_placement.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/point_frame.h" #include "/EgtDev/Extern/C3d/Include/wire_frame.h" #include "/EgtDev/Extern/C3d/Include/space_instance.h" #include "/EgtDev/Extern/C3d/Include/plane_instance.h" #include "/EgtDev/Extern/C3d/Include/point3d.h" #include "/EgtDev/Extern/C3d/Include/cur_polyline3d.h" #include "/EgtDev/Extern/C3d/Include/cur_polyline.h" #include "/EgtDev/Extern/C3d/Include/cur_line_segment3d.h" #include "/EgtDev/Extern/C3d/Include/cur_line_segment.h" #include "/EgtDev/Extern/C3d/Include/cur_arc3d.h" #include "/EgtDev/Extern/C3d/Include/cur_arc.h" #include "/EgtDev/Extern/C3d/Include/cur_nurbs3d.h" #include "/EgtDev/Extern/C3d/Include/cur_nurbs.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 "/EgtDev/Extern/C3d/Include/mip_solid_area_volume.h" #include "/EgtDev/Include/EGkDllMain.h" #include "/EgtDev/Include/EGkGeomDB.h" #include "/EgtDev/Include/EGkColor.h" #include "/EgtDev/Include/EGkGeoPoint3d.h" #include "/EgtDev/Include/EGkCurveLine.h" #include "/EgtDev/Include/EGkCurveArc.h" #include "/EgtDev/Include/EGkCurveComposite.h" #include "/EgtDev/Include/EGkCurveAux.h" #include "/EgtDev/Include/EGkCurveBezier.h" #include "/EgtDev/Include/EGkStmFromTriangleSoup.h" #include "/EgtDev/Include/EGnDllMain.h" #include "/EgtDev/Include/EGnGetModuleVer.h" #include "/EgtDev/Include/EGnStringUtils.h" #include "/EgtDev/Include/EGnFileUtils.h" #include "/EgtDev/Include/EGnGetKeyData.h" #include "/EgtDev/Include/EgtStringConverter.h" #include "/EgtDev/Include/EgtLogger.h" #include "/EgtDev/Include/EgtPointerOwner.h" #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/SELkLockId.h" #include "/EgtDev/Include/SELkKeyProc.h" using namespace std ; using namespace c3d ; using namespace egtlogger ; //--------------------------- Costanti ---------------------------------------- #if defined( _WIN64) #if defined( _DEBUG) const string EXE_NAME = "EgtConverterD64.exe" ; #else const string EXE_NAME = "EgtConverterR64.exe" ; #endif #elif defined( _WIN32) #if defined( _DEBUG) const string EXE_NAME = "EgtConverterD32.exe" ; #else const string EXE_NAME = "EgtConverterR32.exe" ; #endif #endif const double dTol = 2 * EPS_SMALL ; const double TOL_LIM_S = 0.101 ; const double TOL_LIM_B = 1.001 ; //------------------------- Prototipi locali --------------------------------- bool PrepareExit( Logger* pLog = nullptr, const char* szOut = nullptr) ; uint32 GetSolidColor( MbSolid* pSolid) ; bool CreateMeshData( MbStepData& stepData, MbFormNote& note) ; bool point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color) ; bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool nurbs3D_handler( const MbNurbs3D* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, bool bColor = true) ; bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool pointframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool spaceinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) ; bool planeinstance_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) ; // Settimo parametro della linea di comando : LockId wstring swLockId = ( argc >= 7 ? argv[6] : L"") ; string sLockId = wstringtoA( swLockId) ; // Creo il logger PtrOwner pGenLog( new( nothrow) Logger( ( nDebugLev > 0 ? LL_DEBUG : LL_INFO), "EgtConverter")) ; if ( IsNull( pGenLog)) { cout << "Error creating logger" ; return 4 ; } // assegno il file string sLogFile = ChangeFileExtension( sExpName, "txt") ; pGenLog->AddOutputStream( new( nothrow) ofstream( sLogFile), true) ; // Imposto livello di debug alle librerie di base SetEGkDebugLev( nDebugLev) ; // Imposto logger SetEGkLogger( pGenLog) ; SetEGnLogger( pGenLog) ; // Imposto il tipo di chiave SetLockType( KEY_LOCK_TYPE_HW) ; SetEGkKeyType( KEY_LOCK_TYPE_HW) ; SetEGnKeyType( KEY_LOCK_TYPE_HW) ; if ( ! sLockId.empty()) { int nKeyType = KEY_LOCK_TYPE_HW ; bool bNetHwKey = false ; int nUserId = 0 ; if ( GetLockIdStringInfo( sLockId, nKeyType, bNetHwKey, nUserId)) { string sAddrPort = "" ; if ( nKeyType == KEY_LOCK_TYPE_HW) GetLockIdStringNetData( sLockId, sAddrPort) ; SetNetHwKey( bNetHwKey, nUserId, sAddrPort) ; SetEGkNetHwKey( bNetHwKey) ; SetEGnNetHwKey( bNetHwKey) ; } } // Verifico la chiave int nKLev, nKeyExpDays ; int nLevRet = GetKeyLevel( sKeyCode, KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nKLev, nKeyExpDays) ; SetEGnKeyLevel( nLevRet, nKLev, nKeyExpDays) ; unsigned int nOpt1, nOpt2 ; int nKeyOptExpDays ; int nOptRet = GetKeyOptions( sKeyCode, KEY_BASELIB_PROD, KEY_BASELIB_VER, KEY_BASELIB_LEV, nOpt1, nOpt2, nKeyOptExpDays) ; SetEGnKeyOptions( nOptRet, nOpt1, nOpt2, nKeyOptExpDays) ; // Imposto la chiave di protezione alle librerie di base SetEGkKey( sKeyCode) ; SetEGnKey( sKeyCode) ; // Dichiaro inizio programma LOG_DATETIME( pGenLog, " Init") // messaggio dall'applicazione string sExeVer ; GetModuleVersion( NULL, sExeVer) ; string sAppMsg = EXE_NAME + " ver." + sExeVer ; LOG_INFO( pGenLog, sAppMsg.c_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. // chiavi licenza dalla versione 117955 di c3d string str0( "Egalware..[C3D][cnv][mdl]") ; string str1( "1RM6ZehiyVYJeIbiHEWppkPKTE0Qfw+EGGDNQjAtvEFueEjOCSSvdx9dmZzoHTpu9ugDha+cR3qIAUYXcjvMfB6pHhvXX8f2DwIcbxzf9pMk/7umVH/1fUk485Z/7y+wj7TdscCmJ4sgooAc1CLn++0BXvukeXPhGXNFuS4YUSE=") ; // chiavi licenza per vecchie versioni // 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) { PrepareExit( pGenLog, "Error activating Modeler or Converter") ; return 10 ; } // 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) PrepareExit( pGenLog, "Error opening input file") ; else if ( nReadRes == cnv_UnknownExtension) PrepareExit( pGenLog, "Unkwown input file type") ; else if ( nReadRes == cnv_NotEnoughMemory) PrepareExit( pGenLog, "Not enough memory") ; else PrepareExit( pGenLog, "Internal error during read") ; return 11 ; } // Creo GeomDB PtrOwner pGeomDB( CreateGeomDB()) ; if ( IsNull( pGeomDB)){ PrepareExit( 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()) ; // scorro il 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) ; else if ( ( *it)->IsA() == st_PointFrame) bSolOk = pointframe_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_WireFrame) bSolOk = wireframe_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_SpaceInstance) bSolOk = spaceinstance_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_Mesh) bSolOk = mesh_handler(*it, nLayId, pGeomDB, pGenLog) ; else if ( ( *it)->IsA() == st_PlaneInstance) bSolOk = planeinstance_handler(*it, nLayId, pGeomDB, pGenLog) ; if ( ! bSolOk) { PrepareExit( pGenLog, "Error on model") ; return 14 ; } } // Salvo il progetto bool bOk = pGeomDB->Save( GDB_ID_ROOT, sExpName, GDB_SV_BIN) ; if ( ! bOk) { PrepareExit( pGenLog, "Error saving GeomDB") ; return 13 ; } else LOG_INFO( pGenLog, "Conversion finished with success") PrepareExit() ; LOG_DATETIME( pGenLog, " Exit") return 0 ; } //---------------------------------------------------------------------------- bool PrepareExit( Logger* pLog, const char* szOut) { // Free of the geometric kernel C3D FreeMathModulesChecker() ; // Close NetKey if necessary CloseNetHwKey() ; // Log if requested if ( pLog != nullptr && szOut != nullptr) LOG_ERROR( pLog, szOut) ; return true ; } //---------------------------------------------------------------------------- bool mesh_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, bool bColor) { MbMesh * pMesh = static_cast( pIt) ; if ( pMesh == nullptr) { LOG_ERROR( pGenLog, "Error : Mesh pointer null") ; return false ; } PtrOwner pStm( CreateSurfTriMesh()) ; if ( IsNull( pStm) || ! pStm->Init( 3, 1)) return false ; // scorro le grids int nVertexNbr = 0 ; for ( size_t i = 0 ; i < pMesh->GridsCount() ; i++) { const MbGrid* pGrid = pMesh->GetGrid( i) ; // scorro i punti for ( size_t j = 0 ; j < pGrid->PointsCount() ; j ++) { MbCartPoint3D pt ; pGrid->GetPoint ( j, pt) ; pStm->AddVertex( Point3d( pt.x, pt.y, pt.z)) ; } // scorro i triangoli for ( size_t j = 0 ; j < pGrid->TrianglesCount() ; j++) { uint idx0, idx1, idx2 ; pGrid->GetTriangleIndex( j, idx0, idx1, idx2) ; int nIdV[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx1), int( nVertexNbr + idx2)} ; pStm->AddTriangle( nIdV) ; } // scorro i quadrilateri for ( size_t j = 0 ; j < pGrid->QuadranglesCount() ; j++) { uint idx0, idx1, idx2, idx3 ; pGrid->GetQuadrangleIndex( j, idx0, idx1, idx2, idx3) ; int nIdV[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx2), int( nVertexNbr + idx3)} ; pStm->AddTriangle( nIdV) ; int nIdV2[3] = { int( nVertexNbr + idx0), int( nVertexNbr + idx1), int( nVertexNbr + idx2)} ; pStm->AddTriangle( nIdV2) ; } nVertexNbr += ( int)pGrid->PointsCount() ; } pStm->DoCompacting() ; int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, Release( pStm)) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } if ( bColor) { uint32 MeshColor = pMesh->GetColor() ; if ( MeshColor == 16744192) // colore "nullo" return true ; float r, g, b ; uint322RGB( MeshColor, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } return true ; } //---------------------------------------------------------------------------- uint32 GetSolidColor( MbSolid* pSolid) { unordered_map < uint32, double> color_map ; uint32 color = 16744192 ; //colore "nullo" RGB (0,127,255) double max_area = 0.0 ; FacesVector faces ; pSolid -> GetFaces( faces) ; // cerco il colore che occupa l'area maggiore su tutte le facce del solido for ( size_t i = 0 ; i < faces.size() ; i++){ uint32 colFace = faces[i]->GetColor() ; if ( color_map.find( colFace) == color_map.end()) color_map.insert( make_pair( colFace, CalculateArea( *faces[i], 1))) ; else color_map[colFace]=color_map[colFace] + CalculateArea( *faces[i], 1) ; if ( color_map[colFace] > max_area) { color = colFace ; max_area = color_map[colFace] ; } } if ( color == 16744192) return pSolid->GetColor() ; return color ; } //---------------------------------------------------------------------------- bool solid_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbSolid* pSolid = static_cast( pIt) ; if ( pSolid == nullptr) { LOG_ERROR( pGenLog, "Error : Solid pointer null") ; return false ; } // Creazione mesh MbStepData stepdata ; MbFormNote note ; CreateMeshData( stepdata, note) ; MbMesh mesh ; pSolid->CalculateMesh( stepdata, note, mesh) ; if ( ! mesh_handler( & mesh, nLayId, pGeomDB, pGenLog, false)) return false ; int nId = pGeomDB->GetLastInGroup( nLayId) ; // recupero id dell'oggetto appena aggiunto dal mesh_handler // 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( 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())) ; } } // Gestione colori uint32 col=GetSolidColor( pSolid) ; // verifico non sia il colore "nullo" if ( col != 16744192) { float r, g, b = 0 ; uint322RGB( col, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } return true ; } //---------------------------------------------------------------------------- bool pointframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbPointFrame* pPointFr = static_cast( pIt) ; if ( pPointFr == nullptr) { LOG_ERROR( pGenLog, "Error : Point Frame pointer null") ; return false ; } // scorro i punti del PointFrame for ( size_t i = 0 ; i < pPointFr->GetVerticesCount() ; i++) { MbCartPoint3D pt ; pPointFr->GetCartPoint( i, pt) ; MbPoint3D ptP( pt) ; bool bPointOk = point_handler( &ptP, nLayId, pGeomDB, pGenLog) ; if ( ! bPointOk) return false ; } return true; } //---------------------------------------------------------------------------- bool wireframe_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbWireFrame* pWireFr = static_cast( pIt) ; if ( pWireFr == nullptr) { LOG_ERROR( pGenLog, "Error : Point Frame pointer null") ; return false ; } vector curves ; pWireFr->GetCurves(curves) ; for ( size_t i =0 ; i < curves.size() ; i++) { // scorro tutte le curve del WireFrame bool bCurveOk = curve_handler( curves[i], nLayId, pGeomDB, pGenLog) ; if ( ! bCurveOk) return false ; } return true ; } //---------------------------------------------------------------------------- bool assembly_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbAssembly* pAss = static_cast( pIt) ; if ( pAss == nullptr) return false ; // analizzo gl elementi dell'assembly RPArray assItems ; pAss->GetItems( assItems) ; for ( MbItem** it = assItems.begin() ; it != assItems.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) ; else if ( (*it)->IsA() == st_PointFrame) bSolOk = pointframe_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_WireFrame) bSolOk = wireframe_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_SpaceInstance) bSolOk = spaceinstance_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_Mesh) bSolOk = mesh_handler( *it, nLayId, pGeomDB, pGenLog) ; else if ( (*it)->IsA() == st_PlaneInstance) bSolOk = planeinstance_handler( *it, nLayId, pGeomDB, pGenLog) ; if ( ! bSolOk) return false ; } return true; } //---------------------------------------------------------------------------- bool instance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbInstance* pInst = static_cast( pIt) ; if ( pInst == nullptr) return false ; const MbItem* pInstItem = pInst->GetItem() ; if ( pInstItem == nullptr) return false ; MbItem* pItem = static_cast( &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) ; else if ( (pInstItem)->IsA() == st_PointFrame) return pointframe_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_WireFrame) return wireframe_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_SpaceInstance) return spaceinstance_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_Mesh) return mesh_handler( pItem, nLayId, pGeomDB, pGenLog) ; else if ( (pInstItem)->IsA() == st_PlaneInstance) return planeinstance_handler( pItem, nLayId, pGeomDB, pGenLog) ; return false ; } //---------------------------------------------------------------------------- bool planeinstance_handler( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbPlaneInstance * pPlaneInstance = static_cast (pIt) ; if ( pPlaneInstance == nullptr) { LOG_ERROR( pGenLog, "Error : Plane Instance pointer null") ; return false ; } vector pConstPlaneItems ; pPlaneInstance->GetItems ( pConstPlaneItems) ; const MbPlacement3D placement = pPlaneInstance->GetPlacement() ; // matrice di trasformazione dalle coord locali a quelle assolute MbCartPoint placement2D_origin( placement.GetOrigin().x, placement.GetOrigin().y) ; MbVector placement2D_xaxis( placement.GetAxisX().x, placement.GetAxisX().y) ; MbVector placement2D_yaxis( placement.GetAxisY().x, placement.GetAxisY().y) ; MbPlacement placement2D( placement2D_origin, placement2D_xaxis, placement2D_yaxis) ; MbMatrix matrix( placement2D) ; // scorro tutti i PlaneItems contenuti in PlaneInstance for ( size_t i = 0 ; i < pConstPlaneItems.size() ; i++) { MbPlaneItem * pPlaneIt = &pConstPlaneItems[i]->Duplicate() ; if ( pPlaneIt == nullptr) return false ; // trasformo in coordinate assolute pPlaneIt->Transform( matrix) ; // Plane Polyline if ( pPlaneIt->IsA() == pt_Polyline) { MbPolyline * pPolyline = static_cast ( pPlaneIt) ; if ( pPlaneInstance == nullptr) { LOG_ERROR( pGenLog, "Error : Polyline pointer null") ; return false ; } vector points ; pPolyline->GetPoints( points) ; // elimino punti coincidenti rispetto alla tol fissata for ( vector::iterator it = points.begin() + 1 ; it != points.end() ; it++) if ( abs( it->x - ( it-1)->x) < dTol && abs( it->y - ( it-1)->y) < dTol) { points.erase( it) ; it-- ; } // se dopo la rimozione è rimasto un solo punto, la curva è degenerata in un GeoPoint if ( points.size() == 1) { LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; const MbPoint3D point( MbCartPoint3D( points[0].x, points[0].y, 0)) ; return point_handler( &point, nLayId, pGeomDB, pGenLog) ; } ICurveComposite* pCurveCompo = CreateCurveComposite() ; if ( pCurveCompo == nullptr){ LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } bool bStartPointOk = pCurveCompo->AddPoint( Point3d( points[0].x, points[0].y)) ; //starting point if ( ! bStartPointOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } for ( size_t i = 1 ; i < points.size() - 1 ; i++){ //mid points bool bAddLineOk = pCurveCompo->AddLine( Point3d( points[i].x, points[i].y), false) ; if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } } bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x, points.back().y), false) ; //end point if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveCompo) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Plane LineSegment else if ( pPlaneIt->IsA() == pt_LineSegment) { MbLineSegment * pSegment = static_cast( pPlaneIt) ; if ( pSegment == nullptr) { LOG_ERROR( pGenLog, "Error : Segment pointer null") ; return false ; } MbCartPoint start = pSegment->GetLimitPoint( 1) ; MbCartPoint end = pSegment->GetLimitPoint( 2) ; // se i due punti sono coincidenti per la toll fissata, la curva è degenerata in un GeoPoint if ( abs( start.x - end.x) < dTol && abs( start.y - end.y) < dTol ) { LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; const MbPoint3D point( MbCartPoint3D( start.x, start.y, 0)) ; return point_handler( &point, nLayId, pGeomDB, pGenLog) ; } ICurveLine* pLine = CreateCurveLine() ; if ( pLine == nullptr) { LOG_ERROR( pGenLog, "Error : creating CurveLine") ; return false ; } bool bLineOk = pLine->Set( Point3d( start.x, start.y), Point3d( end.x, end.y)) ; if ( ! bLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveLine") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Plane Nurbs else if ( pPlaneIt->IsA() == pt_Nurbs) { MbNurbs * pNurbs= static_cast( pPlaneIt) ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : Nurbs pointer null") ; return false ; } bool bNurbsOk = nurbs2D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; if ( ! bNurbsOk) return false ; } // Plane Generic Curve else if ( pPlaneIt->Family() == pt_Curve) { MbCurve * pCurve= static_cast( pPlaneIt) ; if ( pCurve == nullptr) { LOG_ERROR( pGenLog, "Error : Curve pointer null") ; return false ; } // Approssimo la curva con Nurbs MbNurbs* pNurbs = pCurve->NurbsCurve() ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : converting the curve to a NURBS") ; return false ; } bool bNurbsOk = nurbs2D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; if ( ! bNurbsOk) return false ; } } // ciclo sui planeitems return true ; } //---------------------------------------------------------------------------- bool nurbs2D_handler( MbNurbs* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { // se la Nurbs è periodica non la considero e passo all'item successivo if ( pNurbs->IsPeriodic()) { LOG_ERROR( pGenLog, "Warning : periodic NURBS is ignored") ; return true ; } vector ctrlPoints ; DBLVECTOR knots, weights ; pNurbs->GetPoints( ctrlPoints) ; pNurbs->GetKnots( knots) ; pNurbs->GetWeights( weights) ; PNTVECTOR ctrlPoints_vector( ctrlPoints.size()) ; for ( size_t i = 0 ; i < ctrlPoints.size() ; i++) ctrlPoints_vector[i] = Point3d( ctrlPoints[i].x, ctrlPoints[i].y) ; // creo la struct NurbsData CNurbsData NurbsData; NurbsData.nDeg = int( pNurbs->GetDegree()) - 1 ; // la funzione GetDegree di c3d restituisce l'ordine NurbsData.bRat = pNurbs->IsRational() ; NurbsData.bClosed = pNurbs->IsClosed() ; NurbsData.bPeriodic = pNurbs->IsPeriodic() ; NurbsData.bExtraKnotes = false ; if ( knots.size() == ctrlPoints.size() + NurbsData.nDeg + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere NurbsData.vU = vector( knots.begin() + 1, knots.end() - 1) ; else NurbsData.vU = knots ; NurbsData.vCP = ctrlPoints_vector ; NurbsData.vW = weights ; ICurve* pBezierCurve = NurbsToBezierCurve( NurbsData) ; if ( pBezierCurve == nullptr) { LOG_ERROR( pGenLog, "Error : cannot create Bezier Curve from given Nurbs") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pBezierCurve) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- bool spaceinstance_handler ( MbItem* pIt, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbSpaceInstance* pSpaceInst = static_cast( pIt) ; if ( pSpaceInst == nullptr) { LOG_ERROR( pGenLog, "Error : Space Instance pointer null") ; return false ; } uint32 color = pSpaceInst->GetColor() ; // ricavo l'oggetto contenuto nello space instance const MbSpaceItem * pSpaceIt = pSpaceInst->GetSpaceItem() ; if ( pSpaceIt == nullptr) { LOG_ERROR( pGenLog, "Error : null space item") ; return false ; } // point if ( pSpaceIt->IsA() == st_Point3D) { const MbPoint3D* pPoint = static_cast( pSpaceIt) ; if ( pPoint == nullptr) { LOG_ERROR( pGenLog, "Error : Point pointer null") ; return false ; } return point_handler( pPoint, nLayId, pGeomDB, pGenLog) ; } // curve else if ( pSpaceIt->Family() == st_Curve3D) { const MbCurve3D* pCurve = static_cast( pSpaceIt) ; if ( pCurve == nullptr) { LOG_ERROR( pGenLog, "Error : Curve pointer null") ; return false ; } return curve_handler( pCurve, nLayId, pGeomDB, pGenLog) ; } // surface else if ( pSpaceIt->Family() == st_Surface) { const MbSurface* pSurface = static_cast( pSpaceIt) ; if ( pSurface == nullptr) { LOG_ERROR( pGenLog, "Error : Surface pointer null") ; return false ; } return surface_handler( pSurface, nLayId, pGeomDB, pGenLog, color) ; } return true ; } //---------------------------------------------------------------------------- bool point_handler( const MbPoint3D* pPoint, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { MbCartPoint3D pt = pPoint->GetCartPoint() ; IGeoPoint3d* pGeoPoint = CreateGeoPoint3d() ; if ( pGeoPoint == nullptr) { LOG_ERROR( pGenLog, "Error : creating GeoPoint") ; return false ; } bool bPointOk = pGeoPoint->Set( Point3d( pt.x, pt.y, pt.z)) ; if ( ! bPointOk) { LOG_ERROR( pGenLog, "Error : creating GeoPoint") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pGeoPoint) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- bool curve_handler( const MbCurve3D* pCurve, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { // Polyline if ( pCurve->IsA() == st_Polyline3D) { const MbPolyline3D * pPolyline = static_cast( pCurve) ; if ( pPolyline == nullptr) { LOG_ERROR( pGenLog, "Error : Polyline pointer null") ; return false ; } vector< MbCartPoint3D > points ; pPolyline->GetPoints( points) ; // elimino punti coincidenti rispetto alla tol fissata for ( vector::iterator it = points.begin() + 1 ; it != points.end() ; it++) if ( abs( it->x - ( it-1)->x) < dTol && abs( it->y - ( it-1)->y) < dTol && abs( it->z - ( it-1)->z) < dTol) { points.erase( it) ; it-- ; } // se dopo la rimozione è rimasto un solo punto, la curva è degenerata in un GeoPoint if ( points.size() == 1) { LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; MbPoint3D ptP( points[0]) ; return point_handler( &ptP, nLayId, pGeomDB, pGenLog) ; } ICurveComposite* pCurveCompo = CreateCurveComposite() ; if ( pCurveCompo == nullptr) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } bool bStartPointOk = pCurveCompo->AddPoint( Point3d( points[0].x, points[0].y, points[0].z)) ; // starting point if ( ! bStartPointOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } for ( size_t i = 1 ; i < points.size() - 1 ; i++){ // mid points bool bAddLineOk = pCurveCompo->AddLine( Point3d( points[i].x, points[i].y, points[i].z), false) ; if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } } bool bAddLineOk = pCurveCompo->AddLine( Point3d( points.back().x, points.back().y, points.back().z), false) ; // end point if ( ! bAddLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveComposite") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveCompo) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // LineSegment else if ( pCurve->IsA() == st_LineSegment3D ){ const MbLineSegment3D * pSegment = static_cast( pCurve) ; if ( pSegment == nullptr) { LOG_ERROR( pGenLog, "Error : Segment pointer null") ; return false ; } MbCartPoint3D start = pSegment->GetLimitPoint( 1) ; MbCartPoint3D end = pSegment->GetLimitPoint( 2) ; // Se i due punti sono coincidenti per la toll fissata, la curva è degenerata in un GeoPoint if ( abs( start.x - end.x) < dTol && abs( start.y - end.y) < dTol && abs( start.z - end.z) < dTol) { LOG_ERROR( pGenLog, "Warining : curve degenerated in one point") ; MbPoint3D ptP( start) ; return point_handler( &ptP, nLayId, pGeomDB, pGenLog) ; } ICurveLine* pLine = CreateCurveLine() ; if ( pLine == nullptr) { LOG_ERROR( pGenLog, "Error : creating CurveLine") ; return false ; } bool bLineOk = pLine->Set( Point3d( start.x, start.y, start.z), Point3d( end.x, end.y, end.z)) ; if ( ! bLineOk) { LOG_ERROR( pGenLog, "Error : creating CurveLine") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pLine) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Arc else if ( pCurve->IsA() == st_Arc3D ) { const MbArc3D * pArc = static_cast( pCurve) ; if ( pArc == nullptr) { LOG_ERROR( pGenLog, "Error : Arc pointer null") ; return false ; } MbCartPoint3D start = pArc->GetLimitPoint( 1) ; MbCartPoint3D end = pArc->GetLimitPoint( 2) ; MbCartPoint3D mid ; double t = pArc->GetTMid() ; pArc->PointOn( t, mid) ; double radius = pArc->GetRadius() ; ICurveArc* pCurveArc = CreateCurveArc() ; if ( pCurveArc == nullptr) { LOG_ERROR( pGenLog, "Error : creating CurveArc") ; return false ; } bool bArcOk = false ; if ( abs( start.x - end.x) < dTol && abs( start.y - end.y) < dTol && abs( start.z - end.z) < dTol && radius != 0) { //circonferenza MbAxis3D axis ; bool bAxisOk = pArc->GetCircleAxis( axis) ; if ( ! bAxisOk ) { LOG_ERROR( pGenLog, "Error : no circle axis") ; return false ; } bArcOk = pCurveArc->Set( Point3d( axis.GetOrigin().x, axis.GetOrigin().y, axis.GetOrigin().z), Vector3d( axis.GetAxisZ().x, axis.GetAxisZ().y, axis.GetAxisZ().z), radius) ; } else // arco generico bArcOk = pCurveArc->Set3P( Point3d( start.x, start.y, start.z), Point3d( mid.x, mid.y, mid.z), Point3d( end.x, end.y, end.z)) ; if ( ! bArcOk) { LOG_ERROR( pGenLog, "Error : creating CurveArc") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pCurveArc) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; } // Nurbs else if ( pCurve->IsA() == st_Nurbs3D) { const MbNurbs3D * pNurbs= static_cast( pCurve) ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : Nurbs pointer null") ; return false ; } return nurbs3D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; } // Generic curve else { // Approssimo la curva con Nurbs const MbNurbs3D* pNurbs = pCurve->NurbsCurve() ; if ( pNurbs == nullptr) { LOG_ERROR( pGenLog, "Error : converting the curve to a NURBS") ; return false ; } return nurbs3D_handler( pNurbs, nLayId, pGeomDB, pGenLog) ; } return true ; } //---------------------------------------------------------------------------- bool nurbs3D_handler( const MbNurbs3D* pNurbs, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog) { // se la Nurbs è periodica non la considero e passo all'item successivo if ( pNurbs->IsPeriodic()) { LOG_ERROR( pGenLog, "Warning : periodic NURBS is ignored") ; return true ; } vector ctrlPoints ; DBLVECTOR knots, weights ; pNurbs->GetPoints( ctrlPoints) ; pNurbs->GetKnots( knots) ; pNurbs->GetWeights( weights) ; PNTVECTOR ctrlPoints_vector( ctrlPoints.size()) ; for ( size_t i = 0 ; i < ctrlPoints.size() ; i++) ctrlPoints_vector[i] = Point3d( ctrlPoints[i].x, ctrlPoints[i].y, ctrlPoints[i].z) ; // creo la struct NurbsData CNurbsData NurbsData; NurbsData.nDeg = int( pNurbs->GetDegree()) - 1 ; // la funzione GetDegree di c3d restituisce l'ordine NurbsData.bRat = pNurbs->IsRational() ; NurbsData.bClosed = pNurbs->IsClosed() ; NurbsData.bPeriodic = pNurbs->IsPeriodic() ; NurbsData.bExtraKnotes = false ; if ( knots.size() == ctrlPoints.size() + NurbsData.nDeg + 1) // significa che ci sono due nodi extra, uno all'inizio e uno alla fine, da togliere NurbsData.vU = vector( knots.begin() + 1, knots.end() - 1) ; else NurbsData.vU = knots ; NurbsData.vCP = ctrlPoints_vector ; NurbsData.vW = weights ; ICurve* pBezierCurve = NurbsToBezierCurve( NurbsData) ; if ( pBezierCurve == nullptr) { LOG_ERROR( pGenLog, "Error : cannot create Bezier Curve from given Nurbs") ; return false ; } int nId = pGeomDB->AddGeoObj( GDB_ID_NULL, nLayId, pBezierCurve) ; if ( nId == GDB_ID_NULL) { LOG_ERROR( pGenLog, "Error : adding object to GeomDB") ; return false ; } pGeomDB->SetMaterial( nId, Color( 0, 0, 0)) ; return true ; } //---------------------------------------------------------------------------- bool surface_handler( const MbSurface* pSurface, int nLayId, IGeomDB* pGeomDB, Logger* pGenLog, uint32 color) { // Creazione mesh MbStepData stepdata ; MbFormNote note ; CreateMeshData( stepdata, note) ; MbMesh mesh ; pSurface->CalculateMesh( stepdata, note, mesh) ; bool bMeshOk = mesh_handler( & mesh, nLayId, pGeomDB, pGenLog, false) ; if ( ! bMeshOk) return false ; int nId = pGeomDB->GetLastInGroup( nLayId) ; // recupero id dell'oggetto appena aggiunto dal mesh_handler if ( color != 16744192) { float r, g, b ; uint322RGB( color, r, g, b) ; pGeomDB->SetMaterial( nId, Color( r, g, b)) ; } return true ; } //--------------------------------------------------- bool CreateMeshData( MbStepData& stepData, MbFormNote& note) { stepData.Init( ist_SpaceStep, s_dLinToler, M_PI / 12, ( s_dLinToler > TOL_LIM_S ? 1000 : 100)) ; stepData.SetStepType( ist_DeviationStep) ; if ( s_dLinToler < TOL_LIM_B) stepData.SetStepType( ist_MetricStep) ; note.SetWire( true) ; note.SetGrid( true) ; note.SetSeam( true) ; note.SetExact( true) ; note.SetQuad( false) ; note.SetFair( true) ; note.SetMere( true) ; return true ; }