/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // // 3dDwfExportImpl.cpp : implementation of the C3dDwfExportImpl class // /////////////////////////////////////////////////////////////////////////////// #include "OdaCommon.h" // workaround for bug in certain versions of HP's aCC compiler #ifdef OD_REDEFINE_STD namespace std {} using namespace std; #endif #define STL_USING_IOSTREAM #define STL_USING_MAP #define STL_USING_VECTOR #include "OdaSTL.h" #include "Ge/GeExtents3d.h" #include "OdTimeStamp.h" #include "ColorMapping.h" #include "DbBaseHostAppServices.h" #include "3dDwfExportImpl.h" #include "3dDwfDrawObject.h" #if defined(_TOOLKIT_IN_DLL_) && defined(WIN32) #include "whiptk/palette.h" #else extern const WT_RGBA32 WD_Old_Default_Palette[256]; extern const WT_RGBA32 WD_New_Default_Palette[256]; #endif #ifdef OD_HAVE_DIRECT_FILE #include #endif #include #include #include "dwfcore/File.h" #include "dwfcore/MIME.h" #include "dwf/Version.h" #include "dwf/package/Constants.h" #include "dwf/package/EPlotSection.h" #include "dwf/package/writer/PackageWriter.h" #include "dwf/package/ContentManager.h" #include "dwf/publisher/model/Model.h" #include "dwf/publisher/impl/DWF6PackagePublisher.h" #include "dwf/publisher/impl/DWFXPackagePublisher.h" #ifdef _DWFCORE_WIN32_SYSTEM #include "dwf/publisher/win32/EmbeddedFontImpl.h" #endif //#define DWF_EXPORT_METADATA_SAMPLE_TEST // better do it via CMakeList.txt using namespace DWFCore; using namespace DWFToolkit; namespace TD_DWF_EXPORT{ /////////////////////////////////////////////////////////////////////////////// // Auxiliary methods /////////////////////////////////////////////////////////////////////////////// DWFUnits::teType getUnitName(OdUInt32 idUnit); //*************************************************************************** // //*************************************************************************** } #ifdef DWF_EXPORT_METADATA_SAMPLE_TEST void DwfMetadataSampleTest(DWFPackagePublisher* pPublisher); #endif namespace TD_DWF_EXPORT{ //*************************************************************************** // C3dDwfExportImpl //*************************************************************************** C3dDwfExportImpl::C3dDwfExportImpl(Dwf3dExportParams& Params) : m_Params(Params) , m_pModel(NULL) , m_pCurrentSegment(NULL) , m_pTKColorRGB(NULL) , m_pPalette(NULL) , m_pPublisher(NULL) { } C3dDwfExportImpl::~C3dDwfExportImpl() { } class C3dDwfExportGsInitializer { public: C3dDwfExportGsInitializer() { ::odgsInitialize(); } ~C3dDwfExportGsInitializer() { ::odgsUninitialize(); } }; OdDbBaseDatabase* C3dDwfExportImpl::database() { return m_Params.database(); } OdDbBaseHostAppServices* C3dDwfExportImpl::getBaseHostAppServices() { OdDbBaseDatabase* pRxDb = database(); OdDbBaseDatabasePEPtr pDbPe = OdDbBaseDatabasePE::cast(pRxDb); ODA_ASSERT_ONCE_X(TDWF, pDbPe.get()); OdDbBaseHostAppServices* pBaseHostAppServ = pDbPe->appServices(pRxDb); return pBaseHostAppServ; } bool C3dDwfExportImpl::addDwf3dPropertyAt(const OdGiDrawable* pParent, const OdGiDrawable* pDrawable, OdUInt32 drawableFlags, OdString& sLabel, OdStringArray& sPropPathNames, OdStringArray& sValues) // out { OdDwf3dPropertyProviderFunc pFunc = m_Params.propertyProviderFunc(); ODA_ASSERT_ONCE_X(TDWF, pFunc && m_pPublisher); // this call should be blocked ealier by NULL of getPublisher() call if (!pFunc || !m_pPublisher) return false; return pFunc(this, pParent, pDrawable, sLabel, sPropPathNames, sValues); } bool C3dDwfExportImpl::run() { bool bRes = true; try { m_pPalette = (m_Params.palette() != NULL) ? m_Params.palette() : odcmAcadPalette(m_Params.background()); // To create DWF device C3dDwfExportGsInitializer gsInitializer; // Wraps Od3dDwfDevice to prevent Gs module unloading before all Gs-related classes release OdGsDevicePtr wr3dDwfDevice = Od3dDwfDevice::createObject(); // To get Model Space OdDbBaseDatabasePEPtr pDbPe(m_Params.database()); OdRxIteratorPtr pLayoutIter = pDbPe->layouts(m_Params.database()); OdString sLayoutNames = OdString::kEmpty; OdDbStub* g_idMsLayout = NULL; for (; !pLayoutIter->done(); pLayoutIter->next()) { OdRxObjectPtr pLayout = pLayoutIter->object(); OdDbBaseLayoutPEPtr pLayoutPE( pLayout ); if( pLayoutPE->isModelLayout(pLayout) ) { sLayoutNames = pLayoutPE->name(pLayout); g_idMsLayout = pDbPe->findLayoutNamed(m_Params.database(), sLayoutNames); // dgn dwf export; break; } } if (sLayoutNames.isEmpty()) { ODA_ASSERT(false); } ((Od3dDwfDevice*)wr3dDwfDevice.get())->setContext(this); // set special context for 3d dwf device // To create & activate own Dwf View OdDbBaseDatabasePEPtr pDbPE(m_Params.database()); OdGiDefaultContextPtr pContex = pDbPE->createGiContext(m_Params.database()); pContex->setPlotGeneration(false); wr3dDwfDevice->setBackgroundColor(m_Params.background()); wr3dDwfDevice->setLogicalPalette(m_pPalette, 256); OdGsDevicePtr pLayoutHelper = pDbPE->setupLayoutView( wr3dDwfDevice, pContex, g_idMsLayout); // dgn dwf export wr3dDwfDevice->onSize( OdGsDCRect( 0, m_Params.ySize(), m_Params.xSize(), 0 ) /*outputRect*/ ); // To create Publisher // DWFCore::DWFFile oDWF( m_Params.dwfFileName().c_str() ); OdString ext = m_Params.dwfFileName().mid(m_Params.dwfFileName().reverseFind(L'.') + 1); std::unique_ptr oPublisher(ext.iCompare(L"dwfx") == 0 ? static_cast(new DWFXPackagePublisher(oDWF)) : static_cast(new DWF6PackagePublisher(oDWF))); m_pPublisher = oPublisher.get(); #ifdef DWF_EXPORT_METADATA_SAMPLE_TEST { DwfMetadataSampleTest(m_pPublisher); m_pPublisher = NULL; return bRes; } #endif // Starts with a new model // DWFModel oModel( (m_Params.title().isEmpty()) // Corresponds to the EModel section title ? m_Params.dwfFileName().c_str() : m_Params.title().c_str() ); DWFContentManager* pContentManager = DWFCORE_ALLOC_OBJECT( DWFContentManager ); DWFContent* pContent = pContentManager->getContent(); OdUInt32 unitId = pDbPE->getUnits(m_Params.database()); oModel.open( pContent, DWFModel::eHandednessLeft, getUnitName( unitId ), // DWFUnits::eCentimeters, NULL, // transform true, // default lights false, // published edges true ); // silhouettes oModel.setViewCubeCompassState(DWFModel::eViewCubeCompassOn); OdGsView* view = wr3dDwfDevice->viewAt(0); double dHeight = view->fieldHeight(); double dWidth = view->fieldWidth(); OdGeVector3d vtUpVector = view->upVector(); OdGePoint3d ptTarget = view->target(); OdGePoint3d ptPosition = view->position(); W3DCamera oDefault; OdGeMatrix3d w3DTransform; // 3D DWF is [Front] -> [Top] transformed (cf. #9714) w3DTransform.setCoordSystem(OdGePoint3d::kOrigin, OdGeVector3d::kXAxis, -OdGeVector3d::kZAxis, OdGeVector3d::kYAxis); OdGeVector3d dir = (ptTarget - ptPosition); vtUpVector.transformBy(w3DTransform); dir.transformBy(w3DTransform); ptPosition = ptTarget - dir; oDefault.setProjection( view->isPerspective() ? W3DCamera::ePerspective : W3DCamera::eOrthographic ); oDefault.setPosition( static_cast(ptPosition.x), static_cast(ptPosition.y), static_cast(ptPosition.z) ); oDefault.setTarget( static_cast(ptTarget.x), static_cast(ptTarget.y), static_cast(ptTarget.z) ); oDefault.setUpVector( static_cast(vtUpVector.x), static_cast(vtUpVector.y), static_cast(vtUpVector.z) ); oDefault.setField( static_cast(dWidth), static_cast(dHeight) ); oModel.createView( "default", oDefault ); // This should be done before any scene graphics are added m_pModel = &oModel; // The first thing to do is create an include segment // that defines a collection of graphics that will be // reused throughout the model // DWFIncludeSegment include = oModel.openIncludeSegment(); // Creates a simple scene // DWFSegment oRootSegment = oModel.openSegment(); m_pCurrentSegment = &oRootSegment; oRootSegment.open( sLayoutNames.c_str() ); { TK_Color_RGB& rColor = oRootSegment.getColorRGBHandler(); m_pTKColorRGB = &rColor; //todo //oRootSegment.addPropertyContainer( pPartProperties ); // Model layout properties // Initiate rendering. // Doing rendering to fill Model and to create the graphics, etc. wr3dDwfDevice->update( 0 ); } oRootSegment.close(); // ADD A THUMBNAIL // if ( !m_Params.thumbnail().sFileName.isEmpty() ) { // open as a streaming binary file // DWFStreamFileDescriptor* pThumbnailFile = new DWFStreamFileDescriptor( DWFString(m_Params.thumbnail().sFileName.c_str()), OD_T("rb") ); pThumbnailFile->open(); // create a stream and attach the file descriptor // DWFFileInputStream* pThumbnailStream = new DWFFileInputStream; pThumbnailStream->attach( pThumbnailFile, false ); // To specify the image file resource's MIME-type DWFString zMimeType; if (SpecifyImageMimeType(zMimeType, m_Params.thumbnail().sFileName)) { // create a thumbnail image and attach the file stream // DWFImage* pThumbnail = DWFCORE_ALLOC_OBJECT( DWFImage( zMimeType, DWFImage::eThumbnail, static_cast(m_Params.thumbnail().ColorDepth), m_Params.thumbnail().Width, m_Params.thumbnail().Height) ); if (pThumbnail) { pThumbnail->attach( pThumbnailStream, true ); // add to the model // oModel.addResource( pThumbnail ); } } } // add some properties that apply to the model as a whole // /* oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Cutting Plane", L"Hide", L"View Modifier")), true ); oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Origin", L"DWFToolkit Sample Applications", L"General")), true ); oModel.addProperty( DWFCORE_ALLOC_OBJECT(DWFProperty(L"Project", L"Bianchi", L"General")), true ); */ // close the model // oModel.close(); oModel.publish( *oPublisher ); // create the DWF // oPublisher->publish(); } catch (DWFException& ex) { OdString msg(OD_T("Dwf exception is thrown during export3dDwf: ")); OdString wsMsg; wsMsg = ex.message(); msg += wsMsg; msg += OdString(ex.function()); wsMsg = ex.file(); //wsMsg += ex.line(); msg += wsMsg; pmStop(); pmRelease(); bRes = false; // return false; } catch (OdError& err) { OdString msg(OD_T("OdError is thrown during export3dDwf: ")); msg += err.description(); getBaseHostAppServices()->warning(msg); pmStop(); pmRelease(); bRes = false; // return false; } catch (...) { OdString msg(OD_T("Unexpected error is happened during exportDwf.")); getBaseHostAppServices()->warning(msg); pmStop(); pmRelease(); bRes = false; // return false; } m_pPublisher = NULL; return bRes; } /////////////////////////////////////////////////////////////////////////////// // Implementation of auxiliary methods /////////////////////////////////////////////////////////////////////////////// DWFUnits::teType getUnitName(OdUInt32 idUnit) { static DWFUnits::teType const Units[] = { DWFUnits::eMillimeters , //"", /* 0 Unspecified (No units) */ DWFUnits::eInches , // "Inches", DWFUnits::eFeet , // "Feet", DWFUnits::eFeet , // "Miles", DWFUnits::eMillimeters , // "Millimeters", DWFUnits::eCentimeters , // "Centimeters", DWFUnits::eMeters , // "Meters", DWFUnits::eMeters , // "Kilometers", DWFUnits::eMillimeters , // "Microinches", DWFUnits::eFeet , // "Mils", DWFUnits::eFeet , // "Yards", DWFUnits::eMillimeters , // "Angstroms", DWFUnits::eMillimeters , // "Nanometers", DWFUnits::eMillimeters , // "Microns", DWFUnits::eMillimeters , // "Decimeters", DWFUnits::eMeters , // "Decameters", DWFUnits::eMeters , // "Hectometers", DWFUnits::eMeters , // "Gigameters", DWFUnits::eMeters , // "Astronomical Units", DWFUnits::eMeters , // "Light Years", DWFUnits::eMeters , // "Parsecs" }; if (idUnit > 20) { idUnit = 0; } return Units[idUnit]; } }