From 2a4d3b7947b2c6ae68178cf824a027fa5376fbcd Mon Sep 17 00:00:00 2001 From: SaraP Date: Wed, 3 Nov 2021 15:10:49 +0100 Subject: [PATCH] EgtExchange : - in export 3MF aggiunta esportazione texture - in export 3MF migliorie varie. --- Export3MF.cpp | 212 ++++++++++++++++++++++++++++++++++++++------------ Export3MF.h | 20 +++-- stdafx.h | 1 + 3 files changed, 177 insertions(+), 56 deletions(-) diff --git a/Export3MF.cpp b/Export3MF.cpp index cfa8705..bd0bbb8 100644 --- a/Export3MF.cpp +++ b/Export3MF.cpp @@ -26,6 +26,8 @@ #include "/EgtDev/Include/EgtKeyCodes.h" #include "/EgtDev/Include/EgtStringConverter.h" #include "/EgtDev/Include/EgtPointerOwner.h" +#include "/EgtDev/Include/EXeExecutor.h" +#include "/EgtDev/Include/EGnFileUtils.h" using namespace std ; using namespace Lib3MF ; @@ -58,6 +60,7 @@ Export3MF::Export( IGeomDB* pGDB, int nId, const string& sFile) LOG_ERROR( GetEExLogger(), "Export3MF : Error on GeomDB") return false ; } + m_pGDB = pGDB ; // verifico l'Id dell'oggetto da esportare if ( ! pGDB->ExistsObj( nId)) { @@ -65,45 +68,54 @@ Export3MF::Export( IGeomDB* pGDB, int nId, const string& sFile) return false ; } + try { + if ( ! DoExport( nId, sFile)) + return false ; + } + catch ( ELib3MFException &exception) { + LOG_ERROR( GetEExLogger(), exception.what()) ; + return false ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +bool +Export3MF::DoExport( const int& nId, const string& sFile) +{ // libreria 3MF m_wrapper = CWrapper::loadLibrary() ; if ( ! m_wrapper) { LOG_ERROR( GetEExLogger(), "Export3MF : Error on lib3mf Wrapper") return false ; } + // creo model per 3MF m_model = m_wrapper->CreateModel() ; if ( ! m_model) { LOG_ERROR( GetEExLogger(), "Export3MF : Error on lib3mf Model") - return false ; + return false ; } + if ( ! m_model->AddColorGroup()) { LOG_ERROR( GetEExLogger(), "Export3MF : Error on lib3mf Color Group") - return false ; - } - + return false ; + } // creo un iteratore - PtrOwner pIter( CreateGdbIterator( pGDB)) ; + PtrOwner pIter( CreateGdbIterator( m_pGDB)) ; if ( IsNull( pIter)) return false ; pIter->GoTo( nId) ; // esporto l'oggetto e i suoi eventuali figli if ( ! ExportObject( *pIter)) return false ; - - // scrivo il file - try { - PWriter writer = m_model->QueryWriter( "3mf") ; - writer->WriteToFile( sFile) ; - } - catch ( ELib3MFException &e) { - LOG_ERROR( GetEExLogger(), "Export3MF : Error on writing") - string s = e.what() ; - LOG_ERROR( GetEExLogger(), ( " " + s).c_str()) ; - return false ; - } + // scrivo il file + PWriter writer = m_model->QueryWriter( "3mf") ; + writer->WriteToFile( sFile) ; + return true ; } @@ -120,11 +132,7 @@ Export3MF::ExportObject( const IGdbIterator& iIter) return true ; // se non è una superficie esco if ( pGeoObj->GetType() != SRF_TRIMESH && pGeoObj->GetType() != SRF_FLATRGN) - return true ; - // recupero il riferimento globale dell'oggetto - Frame3d frFrame ; - if ( ! iIter.GetGlobFrame( frFrame)) - return false ; + return true ; // recupero il livello dell'oggetto int nLev = GDB_LV_USER ; iIter.GetCalcLevel( nLev) ; @@ -135,22 +143,15 @@ Export3MF::ExportObject( const IGdbIterator& iIter) int nStat = GDB_ST_ON ; iIter.GetCalcStatus( nStat) ; // se il filtro lo abilita - if ( TestFilter( nLev, nMode, nStat)) { - // recupero eventuale nome - string sName ; - if ( ! iIter.GetName( sName)) - sName = ToString( iIter.GetId()) ; - // recupero il colore - Color cCol ; - bool bCol = GetColor( cCol, iIter.GetGDB(), iIter.GetId()) ; + if ( TestFilter( nLev, nMode, nStat)) { // emetto l'oggetto switch ( pGeoObj->GetType()) { case SRF_TRIMESH : - if ( ! ExportSTM( sName, pGeoObj, frFrame, bCol ? &cCol : nullptr)) + if ( ! ExportSTM( iIter.GetId(), GetSurfTriMesh( pGeoObj))) return false ; break ; case SRF_FLATRGN : - if ( ! ExportSFR( sName, pGeoObj, frFrame, bCol ? &cCol : nullptr)) + if ( ! ExportSFR( iIter.GetId(), GetSurfFlatRegion( pGeoObj))) return false ; break ; default : @@ -189,25 +190,33 @@ Export3MF::TestFilter( int nLev, int nMode, int nStat) //---------------------------------------------------------------------------- bool -Export3MF::ExportSFR( const string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, const Color* pCol) +Export3MF::ExportSFR( const int& nId, const ISurfFlatRegion* pSFR) { // verifico oggetto - const ISurfFlatRegion* pSFR = GetSurfFlatRegion( pGeoObj) ; - if ( pSFR == nullptr) + if ( pSFR == nullptr || nId == GDB_ID_NULL) return false ; // ricavo la trimesh equivalente const ISurfTriMesh* pStm = pSFR->GetAuxSurf() ; - return ExportSTM( sName, pStm, frFrame, pCol) ; + return ExportSTM( nId, pStm) ; } //---------------------------------------------------------------------------- bool -Export3MF::ExportSTM( const std::string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, const Color* pCol) +Export3MF::ExportSTM( const int& nId, const ISurfTriMesh* pSTM) { // verifico oggetto - const ISurfTriMesh* pSTM = GetSurfTriMesh( pGeoObj) ; - if ( pSTM == nullptr) + if ( pSTM == nullptr || nId == GDB_ID_NULL) return false ; + + // recupero il riferimento globale dell'oggetto + Frame3d frFrame ; + if ( ! m_pGDB->GetGlobFrame( nId, frFrame)) + return false ; + + // recupero eventuale nome + string sName ; + if ( ! m_pGDB->GetName( nId, sName)) + sName = ToString( nId) ; // ciclo sui vertici della trimesh vector vVertices( pSTM->GetVertexSize()) ; @@ -231,7 +240,7 @@ Export3MF::ExportSTM( const std::string& sName, const IGeoObj* pGeoObj, const Fr vTriangles[k].m_Indices[0] = nIdVert[0] ; vTriangles[k].m_Indices[1] = nIdVert[1] ; vTriangles[k].m_Indices[2] = nIdVert[2] ; - k ++ ; + k ++ ; } if ( vVertices.size() == 0 || vTriangles.size() == 0) { @@ -248,16 +257,21 @@ Export3MF::ExportSTM( const std::string& sName, const IGeoObj* pGeoObj, const Fr meshObject->SetName( sName) ; meshObject->SetGeometry( vVertices, vTriangles) ; - // assegno il colore - if ( pCol != nullptr) { - Lib3MF_uint32 nColId = ColorHandler3MF( pCol) ; + // texture + if ( ! ExportTexture( nId, pSTM, meshObject)) + return false ; + + // assegno il colore + Color cCol ; + if ( GetColor( nId, cCol)) { + Lib3MF_uint32 nColId = ColorHandler3MF( cCol) ; meshObject->SetObjectLevelProperty( 1, nColId) ; } m_model->AddBuildItem( meshObject.get(), m_wrapper->GetIdentityTransform()) ; return true ; } - + //---------------------------------------------------------------------------- bool Export3MF::ScanGroup( const IGdbIterator& iIter) @@ -280,26 +294,26 @@ Export3MF::ScanGroup( const IGdbIterator& iIter) //---------------------------------------------------------------------------- bool -Export3MF::GetColor( Color& pCol, const IGeomDB * pGDB, const int& nId) +Export3MF::GetColor( const int& nId, Color& cCol) { if ( nId == GDB_ID_NULL) return false ; - if ( ! pGDB->GetMaterial( nId, pCol)) + if ( ! m_pGDB->GetMaterial( nId, cCol)) // se fallisce cerco il colore del parent - return GetColor( pCol, pGDB, pGDB->GetParentId( nId)) ; + return GetColor( m_pGDB->GetParentId( nId), cCol) ; return true ; } //---------------------------------------------------------------------------- Lib3MF_uint32 -Export3MF::ColorHandler3MF( const Color* pCol) +Export3MF::ColorHandler3MF( const Color& cCol) { PColorGroup pColorGrp = m_model->GetColorGroupByID( 1) ; // converto il colore nel formato usato da 3MF - Lib3MF_uint8 nAlpha = ( int)( pCol->GetIntAlpha() * 2.55 + 0.5) ; - sColor cCol3mf = m_wrapper->RGBAToColor( pCol->GetIntRed(), pCol->GetIntGreen(), pCol->GetIntBlue(), nAlpha) ; + Lib3MF_uint8 nAlpha = ( int)( cCol.GetIntAlpha() * 2.55 + 0.5) ; + sColor cCol3mf = m_wrapper->RGBAToColor( cCol.GetIntRed(), cCol.GetIntGreen(), cCol.GetIntBlue(), nAlpha) ; // verifico se il colore è già presente nel colorgroup UINTVECTOR vColorIdx ; pColorGrp->GetAllPropertyIDs( vColorIdx) ; @@ -311,4 +325,102 @@ Export3MF::ColorHandler3MF( const Color* pCol) } // se non fosse presente, lo aggiungo return pColorGrp->AddColor( cCol3mf) ; +} + +//---------------------------------------------------------------------------- +bool +Export3MF::ExportTexture( const int& nObjId, const ISurfTriMesh* pSTM, PMeshObject& meshObject) +{ + // verifico esistenza texture + string sTxrName ; + if ( ! m_pGDB->GetTextureName( nObjId, sTxrName)) + return true ; + + // cerco id della texture nel GeomDB + int nGrpId = m_pGDB->GetFirstNameInGroup( GDB_ID_ROOT, "Photos") ; + if ( nGrpId == GDB_ID_NULL) + return false ; + int nTxrId = m_pGDB->GetFirstNameInGroup( nGrpId, sTxrName) ; + if ( nTxrId == GDB_ID_NULL) + return false ; + + double dDimX, dDimY ; + if ( ! ExeGetPhotoDimensions( nTxrId, dDimX, dDimY)) + return false ; + + // frame per gestire la texture + Frame3d frSrf ; + if ( ! m_pGDB->GetTextureFrame( nObjId, frSrf)) + return false ; + + Lib3MF_uint32 nTxrGrpId = TextureGroupHandler( nTxrId) ; + PTexture2DGroup textureGroup = m_model->GetTexture2DGroupByID( nTxrGrpId) ; + + // creo coordinate ( u, v) della texture per ogni vertice di pSTM + for ( int i = 0 ; i < pSTM->GetVertexSize() ; i ++) { + Point3d pt( 0, 0, 0) ; + pSTM->GetVertex( i, pt) ; + pt.ToLoc( frSrf) ; + textureGroup->AddTex2Coord( sLib3MFTex2Coord({ pt.x / dDimX, pt.y / dDimY})) ; + } + + // indice in textureGroup corrispondente al primo vertice di questa superficie + int nOffs = textureGroup->GetCount() - pSTM->GetVertexSize() + 1 ; + + // assegno ai triangoli + int k = 0 ; + for ( int i = 0 ; i < pSTM->GetTriangleSize() ; i++) { + + sLib3MFTriangleProperties property ; + property.m_ResourceID = nTxrGrpId ; + + int nIdVert[3] ; + if ( ! pSTM->GetTriangle( i, nIdVert)) + continue ; + + property.m_PropertyIDs[0] = nIdVert[0] + nOffs ; + property.m_PropertyIDs[1] = nIdVert[1] + nOffs ; + property.m_PropertyIDs[2] = nIdVert[2] + nOffs ; + + meshObject->SetTriangleProperties( k, property) ; + k ++ ; + } + + return true ; +} + +//---------------------------------------------------------------------------- +Lib3MF_uint32 +Export3MF::TextureGroupHandler( const int& nTxrId) +{ + auto it = m_TexturesMap.find( nTxrId) ; + // se la texture è già presente nel modello 3MF restituisco il suo id + if ( it != m_TexturesMap.end()) + return it->second ; + + // se non è presente l'aggiungo + string sTxrPath ; + string sInfo ; + m_pGDB->GetInfo( nTxrId, "Path", sInfo) ; + + ExeGetPhotoPath( nTxrId, sTxrPath) ; + string sTxrExtension = GetFileExtension( sTxrPath) ; + + string sTxrRelationshipType = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture" ; + string sOPCPath = "/3D/Texture/texture_" + to_string( m_TexturesMap.size()) + "." + sTxrExtension ; + PAttachment attachment = m_model->AddAttachment( sOPCPath, sTxrRelationshipType) ; + attachment->ReadFromFile( sTxrPath) ; + + PTexture2D texture2D = m_model->AddTexture2DFromAttachment( attachment.get()) ; + if ( sTxrExtension == "jpg" || sTxrExtension == "jpeg") + texture2D->SetContentType( eTextureType::JPEG) ; + else if ( sTxrExtension == "png") + texture2D->SetContentType( eTextureType::PNG) ; + texture2D->SetTileStyleUV( eTextureTileStyle::NoTileStyle, eTextureTileStyle::NoTileStyle) ; + + PTexture2DGroup textureGroup = m_model->AddTexture2DGroup( texture2D.get()) ; + Lib3MF_uint32 nTxrGrpId = textureGroup->GetResourceID() ; + m_TexturesMap.emplace( nTxrId, nTxrGrpId) ; + + return nTxrGrpId ; } \ No newline at end of file diff --git a/Export3MF.h b/Export3MF.h index b554f06..15b7d74 100644 --- a/Export3MF.h +++ b/Export3MF.h @@ -16,8 +16,11 @@ #define NOMINMAX #include "/EgtDev/Extern/Lib3MF/Include/lib3mf_implicit.hpp" #include "/EgtDev/Include/EExExport3MF.h" +#include class IGdbIterator ; +class ISurfTriMesh ; +class ISurfFlatRegion ; //---------------------------------------------------------------------------- class Export3MF : public IExport3MF @@ -30,16 +33,21 @@ class Export3MF : public IExport3MF Export3MF( void) : m_nFilter( EEXFLT_DEFAULT) {} private : + bool DoExport( const int& nId, const std::string& sFile) ; bool ExportObject( const IGdbIterator& iIter) ; bool ScanGroup( const IGdbIterator& iIter) ; - bool TestFilter( int nLev, int nMode, int nStat) ; - bool ExportSFR( const std::string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, const Color* pCol) ; - bool ExportSTM( const std::string& sName, const IGeoObj* pGeoObj, const Frame3d& frFrame, const Color* pCol) ; - Lib3MF_uint32 ColorHandler3MF( const Color* pCol) ; - bool GetColor( Color& pCol, const IGeomDB * pGBD, const int& nId) ; + bool TestFilter( int nLev, int nMode, int nStat) ; + bool ExportSFR( const int& nId, const ISurfFlatRegion* pSFR) ; + bool ExportSTM( const int& nId, const ISurfTriMesh* pSTM) ; + Lib3MF_uint32 ColorHandler3MF( const Color& cCol) ; + bool GetColor( const int& nId, Color& cCol) ; + bool ExportTexture( const int& nObjId, const ISurfTriMesh* pSTM, Lib3MF::PMeshObject& meshObject) ; + Lib3MF_uint32 TextureGroupHandler( const int& nTxrId) ; - private : + private : + IGeomDB* m_pGDB ; int m_nFilter ; // filtro su livello, modo e stato Lib3MF::PWrapper m_wrapper ; // lib3mf wrapper Lib3MF::PModel m_model ; // lib3mf model + std::map< int, Lib3MF_uint32> m_TexturesMap ; } ; \ No newline at end of file diff --git a/stdafx.h b/stdafx.h index d49ee15..6e39cf4 100644 --- a/stdafx.h +++ b/stdafx.h @@ -31,6 +31,7 @@ #pragma comment(lib, EGTLIBDIR "EgtGeneral" EGTLIBVER ".lib") #pragma comment(lib, EGTLIBDIR "EgtNumKernel" EGTLIBVER ".lib") #pragma comment(lib, EGTLIBDIR "EgtGeomKernel" EGTLIBVER ".lib") +#pragma comment(lib, EGTLIBDIR "EgtExecutor" EGTLIBVER ".lib") #pragma comment(lib, EGTLIBDIR "SEgtLock" EGTLIBVER ".lib") #pragma comment(lib, EGTEXTDIR "/libzip/Lib/zip" EGTLIBVER ".lib") #pragma comment(lib, EGTEXTDIR "/lib3mf/Lib/lib3mf" EGTLIBVER ".lib")