/////////////////////////////////////////////////////////////////////////////// // 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. /////////////////////////////////////////////////////////////////////////////// #ifndef __OD_GS_VISUALIZE_VECTORIZER__ #define __OD_GS_VISUALIZE_VECTORIZER__ #include "TD_PackPush.h" #include "Gs/GsBaseInclude.h" #include "Gs/GsBaseMaterialView.h" #include "GsVisualizeGeometry.h" #include "TvFactory.h" #include #include #include "RxDispatchImpl.h" #include "RxVariantValue.h" #include "GsVisualizeEntityPool.h" #include "../Kernel/Extensions/ExRender/CommonDeviceProps.h" #include "ThreadsCounter.h" #include "Gs/GsDbRootLinkage.h" #include "RxObject.h" #include "ExVisualizeDeviceExtensions.h" //#include "GsVisualizeClip.h" class OdGiRasterImage; class ExGsVisualizeMetafile; class ExGsVisualizeHierarchyReflector; class ExGsVisualizeDeviceProperties : public OdCommonDeviceProps//public OdRxDispatchImpl<> { protected: enum VisualizeDeviceProperty : OdUInt64 { kDisplayViaGLES2 = 1, kAllowNonPersistent = 1 << 1, kReuseEmptyEntities = 1 << 2, kEnableTiming = 1 << 3, kWriteUserData = 1 << 4, kFullRegenDependentVectorization = 1 << 5, kConvertIndexedColors = 1 << 6, kGenerateEntityNames = 1 << 7, kPerModelViews = 1 << 8, kCompareUnnamedImages = 1 << 9, kDisableEntitiesRemoving = 1 << 10, kUseVisualStyles = 1 << 11, kUseSceneGraph = 1 << 12, kEnableViewDependentEntities = 1 << 13, kLightGlyphDisplay = 1 << 14, kSupportBrepDraw = 1 << 15, kDisableEntityCaching = 1 << 16, kWriteFontFilePath = 1 << 17, kIgnoreColoredShapes = 1 << 18, kCompareMaterialsForUniqueness = 1 << 19, kSupportGeometryInLight = 1 << 20, kDisableNonEntityLineweightTransformation = 1 << 21, kDisableSettingExtents = 1 << 22, kExplodeAnonymousBlocks = 1 <<23, kNeedConvertDgnColorIndexes = 1 << 24, kDisableShellFaceFillPatterns = 1 << 25, kSearchMaterialsInVisDb = 1 << 26, kReflectDatabaseHierarchy = 1 << 27, kAppendBlock = 1 << 28, kWriteDatabaseIDInUserData = 1 << 29, // starting from 32-bit we must specify 1 as OdUInt64 kRestoreRenderMode = (OdUInt64)1 << 30, kUsePolyEdgesWithShadedModes = (OdUInt64)1 << 31, kSupportObjectsClipping = (OdUInt64)1 << 32, kCustomDeviation = (OdUInt64)1 << 33, kCustomDeviationForCurves = (OdUInt64)1 << 34, kSupportDifferentGsModels = (OdUInt64)1 << 35 }; public: ExGsVisualizeDeviceProperties(); virtual ~ExGsVisualizeDeviceProperties(); ODRX_DECLARE_DYNAMIC_PROPERTY_MAP(ExGsVisualizeDeviceProperties); void setHWND(OdIntPtr hWND) { m_hWnd = hWND; } OdIntPtr getHWND() const { return m_hWnd; } void setDisplayViaGLES2( bool d ) { SETBIT( m_deviceProps, kDisplayViaGLES2, d ); } bool getDisplayViaGLES2() const { return GETBIT( m_deviceProps, kDisplayViaGLES2 ); } void setNotifier( OdIntPtr ptr ) { m_pNotifier = (ExGsVisualizeDeviceNotifier*)(ptr); } OdIntPtr getNotifier() const { return (OdIntPtr)(m_pNotifier); } void setAllowNonPersistent( bool b ) { SETBIT( m_deviceProps, kAllowNonPersistent, b ); } bool getAllowNonPersistent() const { return GETBIT( m_deviceProps, kAllowNonPersistent ); } void setReuseEmptyEntities( bool b ) { SETBIT( m_deviceProps, kReuseEmptyEntities, b ); } bool getReuseEmptyEntities() const { return GETBIT( m_deviceProps, kReuseEmptyEntities ); } void setEnableTiming( bool b ) { SETBIT( m_deviceProps, kEnableTiming, b ); timingSet(); } bool getEnableTiming() const { return GETBIT( m_deviceProps, kEnableTiming ); } void setWriteUserData( bool b ) { SETBIT( m_deviceProps, kWriteUserData, b ); } bool getWriteUserData() const { return GETBIT( m_deviceProps, kWriteUserData ); } void setFullRegenDependentVectorization( bool b ) {SETBIT( m_deviceProps, kFullRegenDependentVectorization, b ); } bool getFullRegenDependentVectorization() const { return GETBIT( m_deviceProps, kFullRegenDependentVectorization ); } void setDisableEntityCaching( bool b ) { SETBIT( m_deviceProps, kDisableEntityCaching, b ); } bool getDisableEntityCaching() const { return GETBIT( m_deviceProps, kDisableEntityCaching ); } void setWriteDatabaseIDInUserData(bool b) { SETBIT(m_deviceProps, kWriteDatabaseIDInUserData, b); } bool getWriteDatabaseIDInUserData()const { return GETBIT(m_deviceProps, kWriteDatabaseIDInUserData); } void setCustomDeviation( double d ) { m_dCustomDeviation = d; SETBIT_1(m_deviceProps, kCustomDeviation); } double getCustomDeviation() const { if (!GETBIT(m_deviceProps, kCustomDeviation)) return 0.; return m_dCustomDeviation; } void setCustomDeviationForCurves(double d) { m_dCustomDeviationForCurves = d; SETBIT_1(m_deviceProps, kCustomDeviationForCurves); } double getCustomDeviationForCurves() const { if (!GETBIT(m_deviceProps, kCustomDeviationForCurves)) return 0.; return m_dCustomDeviationForCurves; } void setConvertIndexedColors( bool b ) { SETBIT( m_deviceProps, kConvertIndexedColors, b ); } bool getConvertIndexedColors() const { return GETBIT( m_deviceProps, kConvertIndexedColors ); } void setModelName( const OdString& str ) { m_strModelName = str; } OdString getModelName() const { return m_strModelName; } void setCustomFontFolder(const OdString& str) { m_strCustomFontFolder = str; } OdString getCustomFontFolder() const { return m_strCustomFontFolder; } void setFacetResForBrep(double d) {m_dFacetResForBrep = d;} double getFacetResForBrep() const {return m_dFacetResForBrep; } enum GeometryInterceptionPosition { kAutomatically = 0, kAtConveyorBegin = 1, kAtConveyorEnd = 2 }; void setGeometryInterceptionPosition( OdInt8 pos ) { if( pos == 1 ) m_geomPosition = kAtConveyorBegin; else if( pos == 2 ) m_geomPosition = kAtConveyorEnd; else m_geomPosition = kAutomatically; } OdInt8 getGeometryInterceptionPosition() const { return (OdInt8)( m_geomPosition ); } bool getGenerateEntityNames() const { return GETBIT( m_deviceProps, kGenerateEntityNames ); } void setGenerateEntityNames( bool b ) { SETBIT( m_deviceProps, kGenerateEntityNames, b ); } bool getPerModelViews() const { return GETBIT( m_deviceProps, kPerModelViews ); } void setPerModelViews( bool b ) { SETBIT( m_deviceProps, kPerModelViews, b ); } bool getCompareUnnamedImages() const { return GETBIT( m_deviceProps, kCompareUnnamedImages ); } void setCompareUnnamedImages( bool b ) { SETBIT( m_deviceProps, kCompareUnnamedImages, b ); } bool getDisableEntitiesRemoving() const { return GETBIT( m_deviceProps, kDisableEntitiesRemoving ); } void setDisableEntitiesRemoving( bool b ) { SETBIT( m_deviceProps, kDisableEntitiesRemoving, b ); } bool getUseVisualStyles() const { return GETBIT( m_deviceProps, kUseVisualStyles ); } void setUseVisualStyles( bool b ) { SETBIT( m_deviceProps, kUseVisualStyles, b ); } bool getUseSceneGraph() const { return GETBIT( m_deviceProps, kUseSceneGraph ); } void setUseSceneGraph( bool b ) { SETBIT( m_deviceProps, kUseSceneGraph, b ); } bool getEnableViewDependentEntities() const { return GETBIT( m_deviceProps, kEnableViewDependentEntities ); } void setEnableViewDependentEntities( bool b ) { SETBIT( m_deviceProps, kEnableViewDependentEntities, b ); } void setNamePrefix( const OdString& str ) { m_strPrefix = str; } OdString getNamePrefix() const { return m_strPrefix; } bool ignoreViewInfoFlags() const { return GETBIT( m_ignoreFlags, kIgnoreViewInfoFlags ); } bool ignoreFaceFillPattern() const { return GETBIT( m_ignoreFlags, kIgnoreFaceFillPattern ); } bool ignoreViewBackClipping() const { return GETBIT( m_ignoreFlags, kIgnoreViewBackClipping ); } bool ignoreViewFrontClipping() const { return GETBIT( m_ignoreFlags, kIgnoreViewFrontClipping ); } bool ignoreViewClippingRegion() const { return GETBIT( m_ignoreFlags, kIgnoreViewClippingRegion ); } bool ignoreEdgesColors() const { return GETBIT(m_ignoreFlags, kIgnoreEdgesColors); } bool ignoreEdgesVisibilities() const { return GETBIT(m_ignoreFlags, kIgnoreEdgesVisibilities); } OdUInt16 getIgnoreFlags() const { return m_ignoreFlags; } void setIgnoreFlags( OdUInt16 flg ) { m_ignoreFlags = flg; } void setByBlockLayerName( const OdString& str ) { m_byBlockLayerName = str; } OdString getByBlockLayerName() const { return m_byBlockLayerName; } void setWriteFontFilePath( bool b ) { SETBIT(m_deviceProps, kWriteFontFilePath, b); } bool getWriteFontFilePath() const { return GETBIT(m_deviceProps, kWriteFontFilePath); } bool getLightGlyphDisplay() const { return GETBIT(m_deviceProps, kLightGlyphDisplay); } void setLightGlyphDisplay(bool b) { SETBIT(m_deviceProps, kLightGlyphDisplay, b); } bool getSupportBrepDraw() const { return GETBIT(m_deviceProps, kSupportBrepDraw); } void setSupportBrepDraw(bool b) { SETBIT(m_deviceProps, kSupportBrepDraw, b); } bool getCompareMaterialsForUniqueness() const { return GETBIT(m_deviceProps, kCompareMaterialsForUniqueness); } void setCompareMaterialsForUniqueness(bool b) { SETBIT(m_deviceProps, kCompareMaterialsForUniqueness, b); } bool getIgnoreColoredShape() const { return GETBIT(m_deviceProps, kIgnoreColoredShapes); } void setIgnoreColoredShape(bool b) { SETBIT(m_deviceProps, kIgnoreColoredShapes, b); } bool getSupportGeometryInLight() const { return GETBIT( m_deviceProps, kSupportGeometryInLight ); } void setSupportGeometryInLight( bool b ) { SETBIT( m_deviceProps, kSupportGeometryInLight, b ); } bool getDisableNonEntityLineweightTransformation() const { return GETBIT( m_deviceProps, kDisableNonEntityLineweightTransformation ); } void setDisableNonEntityLineweightTransformation( bool b ) { SETBIT( m_deviceProps, kDisableNonEntityLineweightTransformation, b ); } bool getDisableSettingExtents() const { return GETBIT(m_deviceProps, kDisableSettingExtents); } void setDisableSettingExtents(bool b) { SETBIT(m_deviceProps, kDisableSettingExtents, b); } bool getExplodeAnonymousBlocks() const { return GETBIT( m_deviceProps, kExplodeAnonymousBlocks ); } void setExplodeAnonymousBlocks( bool b ) { SETBIT( m_deviceProps, kExplodeAnonymousBlocks, b ); } bool getNeedConvertDgnColorIndexes() const { return GETBIT(m_deviceProps, kNeedConvertDgnColorIndexes); } void setNeedConvertDgnColorIndexes(bool b) { SETBIT(m_deviceProps, kNeedConvertDgnColorIndexes, b); } bool getDisableShellFaceFillPatterns() const { return GETBIT( m_deviceProps, kDisableShellFaceFillPatterns ); } void setDisableShellFaceFillPatterns( bool b ) { SETBIT( m_deviceProps, kDisableShellFaceFillPatterns, b ); } bool getSearchMaterialsInVisDb() const { return GETBIT(m_deviceProps, kSearchMaterialsInVisDb); } void setSearchMaterialsInVisDb(bool b) { SETBIT(m_deviceProps, kSearchMaterialsInVisDb, b); } bool getReflectHierarchy() const { return GETBIT( m_deviceProps, kReflectDatabaseHierarchy ); } void setReflectHierarchy( bool b ) { SETBIT( m_deviceProps, kReflectDatabaseHierarchy, b ); } void setGeometryNotifier( OdIntPtr ptr ) { m_pGeometryNotifier = (ExGsVisualizeGeomertyNotifier*)( ptr ); } OdIntPtr getGeometryNotifier() const { return (OdIntPtr)( m_pGeometryNotifier ); } bool getAppendBlock() const { return GETBIT(m_deviceProps, kAppendBlock); } void setAppendBlock(bool b) { SETBIT(m_deviceProps, kAppendBlock, b); } bool getRestoreRenderMode() const { return GETBIT( m_deviceProps, kRestoreRenderMode ); } void setRestoreRenderMode( bool b ) { SETBIT( m_deviceProps, kRestoreRenderMode, b ); } bool getUsePolyEdgesWithShadedModes() const { return GETBIT(m_deviceProps, kUsePolyEdgesWithShadedModes); } void setUsePolyEdgesWithShadedModes(bool b) { SETBIT(m_deviceProps, kUsePolyEdgesWithShadedModes, b); } bool getSupportObjectsClipping() const { return GETBIT( m_deviceProps, kSupportObjectsClipping ); } void setSupportObjectsClipping( bool b ) { SETBIT( m_deviceProps, kSupportObjectsClipping, b ); } bool getSupportDifferentGsModels() const { return GETBIT( m_deviceProps, kSupportDifferentGsModels ); } void setSupportDifferentGsModels( bool b ) { SETBIT( m_deviceProps, kSupportDifferentGsModels, b ); } enum class PlineSimplification { kDisabled = 0, kEnabled = 1, kEnabledRespectPlinegen = 2 }; PlineSimplification getPlineSimplification() const { return m_plineSimplification; } void setPlineSimplification( PlineSimplification s ) { m_plineSimplification = s; } OdUInt8 getPlineSimplificationOption() const { return (OdUInt8)( m_plineSimplification ); } void setPlineSimplificationOption( OdUInt8 opt ) { if( opt > 2 ) { ODA_FAIL(); m_plineSimplification = PlineSimplification::kDisabled; } else { m_plineSimplification = (PlineSimplification)( opt ); } } protected: OdIntPtr m_hWnd; ExGsVisualizeDeviceNotifier* m_pNotifier; double m_dCustomDeviation; OdString m_strModelName; OdString m_strCustomFontFolder; OdString m_strPrefix; GeometryInterceptionPosition m_geomPosition; OdUInt64 m_deviceProps; OdUInt16 m_ignoreFlags; double m_dFacetResForBrep; double m_dCustomDeviationForCurves; PlineSimplification m_plineSimplification; OdString m_byBlockLayerName; ExGsVisualizeGeomertyNotifier* m_pGeometryNotifier; virtual void timingSet() {} }; class ExGsVisualizeDevice; class ExGsVisualizeDeviceSelfReference : public OdRxObject { ExGsVisualizeDevice* m_pDevice; public: ExGsVisualizeDeviceSelfReference() { m_pDevice = NULL; }; void setDevice( ExGsVisualizeDevice* device ) { m_pDevice = device; } ExGsVisualizeDevice* device() { return m_pDevice; } }; class OdTvMutexPtr { public: OdTvMutexPtr(); virtual ~OdTvMutexPtr(); OdMutex* get(); void setMutex(OdMutex* pMutex); OdMutex* getMutex() const; private: void create(); void clear(); private: bool m_bGotMutex; static OdMutex s_mt; OdMutex* m_ptr; }; template class ExOptionsKeeper { THolder* m_holder; THolder m_savedValue; public: ExOptionsKeeper( THolder* holder ) { m_holder = holder; m_savedValue = *holder; } ~ExOptionsKeeper() { if( *m_holder != m_savedValue ) { *m_holder = m_savedValue; } } template void setOption( TOption option, TOptionValue value ) { TDataAccessor::set( m_holder, option, value ); } auto getOption( TOption option ) -> decltype( TDataAccessor::get( m_holder, option ) ) { return TDataAccessor::get( m_holder, option ); } }; namespace ExAccessors { template class FlagsAccessor { public: static void set( THolder* holder, TOption option, bool bValue ) { SETBIT( *holder, ( int )option, bValue ); } static bool get( THolder* holder, TOption option ) { return GETBIT( *holder, ( int )option ); } }; class MatrixAccessor { public: static void set( OdTvMatrix* holder, void* option, const OdTvMatrix& value ) { *holder = value; } static const OdTvMatrix& get( OdTvMatrix* holder, void* option ) { return *holder; } }; class MatrixStackAccessor { public: static void set( OdTvMatrix* holder, void* option, const OdTvMatrix& value ) { holder->postMultBy( value ); } static const OdTvMatrix& get( OdTvMatrix* holder, void* option ) { return *holder; } }; }; template using ExFlagsKeeper = ExOptionsKeeper< THolder, TOption, ExAccessors::FlagsAccessor< THolder, TOption > >; using ExMatrixKeeper = ExOptionsKeeper< OdTvMatrix, void*, ExAccessors::MatrixAccessor >; using ExMatrixStackKeeper = ExOptionsKeeper< OdTvMatrix, void*, ExAccessors::MatrixStackAccessor >; /* List of specific device properties: 1)DisplayViaGLES2 - if enabled, TvDevice will be setted up as WinGLES2 device with setted HWND and will perform draw 2)DeviceNotifier - if setted corresponding notified methods will be called 3)AllowNonPersistentObjects - if enabled, non-persistent objects (e.g. grip points) will be vectorized 4)ReuseEmptyEntities - if enabled, instead of removing TvEntities device will clear them and reuse them instead of creating new entities 5)EnableTiming - if enabled, device will measure time for OdTv calls 6)WriteUserData - if enabled, each high-level OdTvEntity will have UserData with corresponding Drawable Handle 7)FullRegenDependentVectorization - if enabled, regen-type dependent entities will be vectorized twice: for wireframe (lines) and render (triangles) 8)TvDatabaseID - if setted, device will use this OdTvdatabase instead of creating new one. Get will return database id 9)TvElapsedTime - set does nothing. Get returns time for OdTv calls or 0. if EnableTiming was disabled 10)CustomDeviation - sets custom deviation 11)ConvertIndexedColor - if enabled, indexed colors will be converted to RGB if palette is set 12)GeometryInterceptionPosition - specify geometry interception position in conveyor: 0 - kAutomatically - vectorizer will start interseption at conveyor begin, but it can move interception position to the end and back if it need 1 - kAtConveyorBegin - vectorizer always will use interseption at conveyor begin 2 - kAtConveyorEnd - vectorizer always will use interseption at conveyor end All other values will be treated as 0 13) GenerateEntityNames - if enabled, resulting TvEntities will have names taken from Drawable description 14) ModelName - if is not empty, device will create model for Model space using specified name 15) DeviceCache - getter write device cache in structure ExGsVisualizeDeviceCache, setter replace device cache by structure content if ExGsVisualizeDeviceCache::m_bApplyCacheData is true, else device only keep structure pointer for getter WARNING: since cache based on object ids, using different databases in devices that share cache data will cause crush NOTE: ExGsVisualizeDeviceCache should be allocated on client side. To read cache from device you must 1) allocate ExGsVisualizeDeviceCache 2) set ExGsVisualizeDeviceCache::m_bApplyCacheData to false 3) set DeviceCache property using this structure 4) read DeviceCache property To set cache to the device: 1) change ExGsVisualizeDeviceCache::m_bApplyCacheData to true 2) set DeviceCache property 16) PerModelViews - if this option enabled each view will show its own model (BIM-specific case) 17) CompareUnnamedImages - if enabled, unnamed image will be compared with cached images to prevent creation copies of single image. If disabled, each unnamed image will create new OdTvRasterImage 18) DisableEntitiesRemoving - if enabled, created TvEntities will not be removed when asociated GS metafiles removing 19) EnableViewDependentEntities - if enabled, device will create view-dependent entities when it need 20) CustomFontFolder - allows to specify custom folder for fonts 21) NamePrefix - allows to specify prefix to generated object names except Model, View and Device 22) TvDeviceDAM - special for Database Agreegated Mode. Allow to specify OdTvGsDevice. If it is not a null, ExGsVisualizeDevice will not create and setup OdTvGsDevice by itself 23) TvViewDAM - special for Database Agreegated Mode. Allow to specify OdTvGsView. If it is not a null, ExGsVisualizeDevice will not create and setup OdTvGsView. It is also will use specified view for all GsViews 24) IgnoreFlags - allow to specify device ignoring flags which can be the combination of the folowing enum DeviceIgnoreFlags { kIgnoreViewInfoFlags = 1 << 0, - if enabled, ViewInfo flags will have no effect on model, so it will be ModelSpace kIgnoreFaceFillPattern = 1 << 1, - if enabled, no OdTvHatchPatternDef will be added to the shells kIgnoreViewBackClipping = 1 << 2, - if enabled, view will ignore back clipping kIgnoreViewFrontClipping = 1 << 3, - if enabled, view will ignore front clipping kIgnoreViewClippingRegion = 1 << 4 - if enabled, view will ignore clipping region kIgnoreEdgesColors = 1 << 5 - if enabled, edge's colors will ignored kIgnoreEdgesVisibilities = 1 << 6 - if enabled, edge's visibilities will be ignored }; 25) ByBlockLayerName - specifies layer, that will be setuped as "ByBlock". "0" by default, can be empty string 26) DisableGsCache - switches device to "No GS Cache" mode 27) LightGlyphDisplay - if true, the glyph for the light should be displayed 28) SupportBrepDraw - if true, the device will support the draw of the BREP 29) DisableEntityCaching - if true, VisualizeGeometry will not cache currently used entity for faster access (unloading case) 30) WriteFontFilePath - if true, Font File Path will be written in text style user data 31) CompareMaterialsForUniqueness - if true, Materials will be checked for uniqueness (currently only for Ifc2Visualize and will return first not null material) 32) IgnoreColoredShapes - if true, the colored shape will not used (shell always will be used instead) 33) SupportGeometryInLight - if true, Light sources also will generate entities to store additional geometry 34) DisableNonEntityLineweightTransformation - if true, non-entity (Layer) lineweight will not be transformed using "lineweight to pixels" 35) DisableSettingExtents - if true, vectorization extents will not be set to the entities 36) ExplodeAnonymousBlocks - if true, anonymous blocks will be exploded during the vectorization 37) NeedConvertDgnColorIndexes - if true, it's need to convert color indexes from DGN palette to DWG palette during the vectorization 38) DisableShellFaceFillPatterns - if true, all shells will be marked as "Disable face fill patterns" 39) AlternativeVisualStyleConflictResolution - REMOVED 40) ClippedByViewportViewList - specifies list of views, that should clip it's content by camera settings. 41) ReflectHierarchy - if enabled, device will create sub-entity each time original database draws sub-drawable. This is required for BIM since we need clipping section flush between different geometries which happens in onTraitsModified and after drawable drawn. We call it "reflect" hierarchy but not "repeat" since 42) AppendBlock - if enabled, device will create block object, instead of new model, This is used for append. VisualizeSDK may require some additional sub-entities compared to the original drawables hierarchy. 43) RestoreRenderMode: during vectorization, device setup render mode using visual style. If this option is enabled, original render mode will be transfered to the result OdTvGsView. 44) UsePolyEdgesWithShadedModes - if enabled, for breps in shaded + edges mode will be drawn polyedges as isolines 45) SupportObjectsClipping - if enabled, clip boundary will be transferred to the graphic conveyor. 46) SupportDifferentGsModels - if enabled, drawables from different Gs models in the same view will be stored in different Tv models. Works only in PerModelViews mode. 47) UniqNumberShareData - if specified, device will use shared OdUInt32 for numbers generation 48) UpdateModifier - if setted, the corresponding modifier will be called. */ class ExGsVisualizeView; class ExGsVisualizeDevice : public OdGsBaseVectorizeDevice, public ExGsVisualizeDeviceProperties { protected: ExGsVisualizeDevice(); virtual ~ExGsVisualizeDevice(); void internalUpdate( OdGsDCRect* pUpdatedRect ); public: // Color map to convert some color index to dwg color. struct OdTvColorIndexDescription { OdUInt8 m_uDwgColorIndex; ODCOLORREF m_clrDwgTrueColor; bool m_bUseTrueColor; }; static OdGsDevicePtr createObject(); void update(OdGsDCRect* pUpdatedRect); OdGsViewPtr createView(const OdGsClientViewInfo* pInfo = 0, bool bEnableLayerVisibilityPerView = false); OdRxDictionaryPtr properties() { return this; } ODRX_DECLARE_DYNAMIC_PROPERTY_MAP(ExGsVisualizeDevice); void setTvDatabaseID( OdIntPtr ptr ); OdIntPtr getTvDatabaseID() const; void setDeviceCache( OdIntPtr ptr ); OdIntPtr getDeviceCache() const; void setOdTvTime( double ) {}; double getOdTvTime() const; void setTvDeviceDAM( OdIntPtr ptr ); OdIntPtr getTvDeviceDAM() const; void setTvViewDAM( OdIntPtr ptr ); OdIntPtr getTvViewDAM() const; void setDatabaseAccessMutex(OdIntPtr ptr); OdIntPtr getDatabaseAccessMutex() const; void setClippedByViewportViewList( OdIntPtr ptr ); OdIntPtr getClippedByViewportViewList(); void setClippedByViewportViewCount( OdUInt32 count ); OdUInt32 getClippedByViewportViewCount(); bool isViewDAMMode( OdTvGsViewId* pViewId = NULL ) const; virtual void onSize(const OdGsDCRect& outputRect); void setUniqNumberShareData( OdIntPtr ptr ); OdIntPtr getUniqNumberShareData(); virtual ExGsVisualizeDeviceNotifier* deviceNotifier() { return m_pNotifier; } void setUpdateModifier( OdIntPtr ptr ); OdIntPtr getUpdateModifier(); protected: OdTvDatabaseId m_dbId; OdTvModelId m_modelId; OdTvBlockId m_appendedBlock; OdTvGsDeviceId m_tvDeviceId; OdTvRegAppId m_appId; OdTvRegAppId m_appId_DbId; OdTvRegAppId m_appId_PlineDataId; void createTvDatabase(); void createTvDevice(); bool m_bTvDeviceInited; void initTvDevice(); void syncTvViews(); void saveTvViewsCache(); void restoreTvViewsCache(); //models OdTvModelId m_modelSpaceModel; OdTvModelId m_paperOnlyModel; typedef std::map< long , OdTvModelId > ModelsMap; ModelsMap m_paperSpaceModels; struct ViewModelPair { OdGsView* pView; OdGsModel* pModel; bool operator<( const ViewModelPair& p ) const { if( pView < p.pView ) return true; if( pView > p.pView ) return false; return pModel < p.pModel; } ViewModelPair( OdGsView* pV, OdGsModel* pM ) : pView( pV ), pModel( pM ) {} ViewModelPair( OdGsView* pV ) : pView( pV ), pModel( nullptr ) {} }; typedef std::map< ViewModelPair, OdTvModelId > ViewModelsMap; ViewModelsMap m_perViewModels; OdTvGsViewId m_tvViewDAM; OdGsView** m_pClippedViewList; OdUInt32 m_nClippedViewCount; ODGSPALETTE m_oldPalette; std::map m_indexedColorToDwgColorMap; // Map for DGN color indexes convertation public: OdTvModelId getTvModelId(); OdTvBlockId getAppendedBlock(); OdTvDatabaseId getTvDatabaseId(); OdTvGsDeviceId getTvDeviceId() const { return m_tvDeviceId; } OdTvRegAppId getTvAppId() const { return m_appId; } OdTvRegAppId getTvAppId_dbId() const { return m_appId_DbId; } OdTvRegAppId getTvAppId_PlineDataId() const { return m_appId_PlineDataId; } void setTvAppId_PlineDataId(const OdTvRegAppId& appId) { m_appId_PlineDataId = appId; } OdTvTextStyleId getTvTextStyleId( const OdGiTextStyle*, double* pObliquingAngle = NULL ); OdTvRasterImageId getTvImageId( const OdGiRasterImage*, const OdGiSubEntityTraitsData* pTraits = NULL ); OdTvBlockId getTvBlockId( OdDbStub* ); OdTvLayerId getTvLayer( OdDbStub*, OdGiLinetypeTraits* pLineTypeTraits = NULL ); void modifyLayer( const OdString& str, OdGiDrawable *pDrawable ); OdTvLayerId findLayer( OdDbStub*, bool findByNameIfFailed = true ); OdTvLinetypeId getTvLineType( OdDbStub*, OdUInt32& flags, OdGiLinetypeTraits* ); OdTvMaterialId getTvMaterial( OdDbStub*, OdUInt32& flags ); OdTvVisualStyleId getTvVisualStyle( OdDbStub* ); OdTvGsViewBackgroundId getTvBackground( OdDbStub* ); template< class T >void setObjectUserData( T pObjectPtr, OdDbStub* id ); void createBlockForAppend(); void setModelForView( OdGsClientViewInfo, OdGsView* ); void getViewModels( OdGsView* pView, OdVector& models ); OdRxObjectPtr getSelfReference() const { return m_pSelfReference;} void deleteTvEntity( OdTvEntityId, bool isInsert, bool isLight = false ); bool reuseEmptyEntity( OdTvModelId modelId, OdTvEntityId& entityId, bool isInsert ); void removeCachedEmptyEntities(); bool isBlockVectoprized( OdDbStub*, bool bMarkAsProcessing = false ); void setBlockVectorized( OdDbStub* ); OdTvExtents3d getBlockExtents( OdDbStub* ); void storeBlockExtents( OdDbStub*, const OdTvExtents3d& ); void setBlockHandle( OdDbStub* id, OdTvBlockId blockId ); void removeBlock( OdTvBlockId blockId ); void syncTvModel( const OdGiDrawable* pDrawable, OdGsView* pGsView ); protected: //names map typedef std::map< OdDbStub*, OdString > NamesMap; NamesMap m_generatedNames; class OdTvUniqNumber { mutable OdTvMutexPtr m_pMutex; OdUInt32* m_pSharedNumber; OdUInt32 m_number; public: OdTvUniqNumber(); ~OdTvUniqNumber(); OdUInt32 get() const; OdUInt32 incAndGet(); void set( OdUInt32 n ); void shareNumber( OdUInt32* pShareNumber, OdTvMutexPtr pMutex ); OdUInt32* sharedData() const { return m_pSharedNumber; } }; OdTvUniqNumber m_uniqNumber; OdString generateUniqName( const OdString& prefix = L"Generated_" ); std::set< OdDbStub* > m_vectorizedBlocks; std::set< OdDbStub* > m_processingBlocks; std::map< OdDbStub*, OdTvExtents3d > m_cachedExtents; OdRxObjectPtr m_pSelfReference; bool supportPartialUpdate() const { return false; } void applyModificationsOnLayer( OdTvLayerId layerId, OdGiLayerTraits* pTraits, OdUInt32 flags, OdGiLinetypeTraits* pLineTypeTraits = NULL ); ExGsVisualizeEntityPool m_emptyEntities; ExGsVisualizeTimer *m_pTimer; double m_dVectorizersTime; virtual void timingSet(); void setupDgn2DwgPaletteConverter(const ODCOLORREF* pPalette, int iPaletteNumColors); void setupDgn2DwgBackgroundColor(ODCOLORREF bgColor); public: void addVectorizerTime( double sec ); bool getDwgColor(OdUInt32 uDgnColorIndex, OdTvColorIndexDescription& retColor) const; protected: OdGiDrawablePtr openDrawable( OdDbStub* ); public: bool isCustomDeviation() const { return GETBIT(m_deviceProps, kCustomDeviation); } bool isCustomDeviationForCurves() const { return GETBIT(m_deviceProps, kCustomDeviationForCurves); } protected: const ODCOLORREF* m_currentPalette; public: const ODCOLORREF* currentPalette() const { return m_currentPalette; } const ODCOLORREF* oldPalette() const { return m_oldPalette.asArrayPtr(); } protected: std::map< OdDbStub*, OdTvLayerId > m_cachedLayers; std::map< OdDbStub*, OdTvLinetypeId > m_cachedLinetypes; std::map< OdDbStub*, OdTvMaterialId > m_cachedMaterials; std::map< OdString, OdTvRasterImageId > m_cachedImages; std::map< ExGsTextStyleCacheData, OdTvTextStyleId > m_cachedTextStyles; std::map< OdDbStub*, OdTvVisualStyleId > m_cachedVisualStyles; std::map< OdDbStub*, OdTvGsViewBackgroundId > m_cachedBackgrounds; std::map< OdDbStub*, OdTvBlockId > m_cachedBlocks; ExGsVisualizeDeviceCache* m_pDeviceCache; class ExGsVisualizeDeviceHelper { protected: ExGsVisualizeDevice* m_pDevice; OdUInt32 m_nAttempts; public: ExGsVisualizeDeviceHelper( ExGsVisualizeDevice*, OdUInt32 ); ~ExGsVisualizeDeviceHelper(); OdTvLayerId createLayer( const OdString&, OdTvDatabasePtr ); OdTvMaterialId createMaterial( const OdString&, OdTvDatabasePtr ); OdTvTextStyleId createTextStyle( const OdString&, OdTvDatabasePtr ); OdTvModelId createModel( const OdString&, OdTvDatabasePtr, OdGsModel* pGsModel = nullptr ); OdTvBlockId createBlock( const OdString&, OdTvDatabasePtr ); OdTvVisualStyleId createVisualStyle( const OdString&, OdTvDatabasePtr, OdTvVisualStyleId ); OdTvGsViewBackgroundId createBackground( const OdString&, OdTvGsViewBackgroundId::BackgroundTypes, OdTvDatabasePtr ); OdTvLinetypeId createLinetype( const OdString&, const OdTvLinetypeElementArray& elements, OdTvDatabasePtr ); static OdTvModel::Type typeByGsModelType( OdGsModel::RenderType tr ); }; ExGsVisualizeDeviceHelper* m_pHelper; OdTvRasterImageId findUnnamedImage( const OdGiRasterImage* ); //MT support OdTvMutexPtr m_databaseAccessMutex; //VS support bool isTheSameVisualStyles( OdTvVisualStyleId tvVS, const OdGiVisualStyle* pVS ); public: OdTvMutexPtr& databaseAccessMutex() { return m_databaseAccessMutex; } OdString fixFilePath(const OdString& file, OdDbBaseHostAppServices::FindFileHint hint = OdDbBaseHostAppServices::kDefault); protected: OdTvColorDef getTvColorDefFromCmEntityColor(const OdCmEntityColor& cmColor); void getOdTvMaterialMapFromOdGiMaterialMap(const OdGiMaterialMap& giMatMap, OdTvMaterialMap& tvMatMap, OdInt16& mapperProj, OdInt16& mapperAutoTrans, bool& isNeedSetUserData); public: //Data replacement void pushZeroLayerReplacement( OdTvLayerId layerId ); void popZeroLayerReplacement(); protected: OdStack m_zeroLayerStack; public: bool getEnableViewportCliping( const OdGsView* pView ) const; //Viewports visibility protected: ExGsVisualizeUpdateModifier* m_pUpdateModifier; }; typedef OdSmartPtr< ExGsVisualizeDevice > ExGsVisualizeDevicePtr; class ExGsVisualizeVectorizer : public OdGsBaseMaterialVectorizer { public: //ODRX_USING_HEAP_OPERATORS(OdGsBaseMaterialVectorizer); ODRX_HEAP_OPERATORS(); public: ExGsVisualizeVectorizer(); virtual ~ExGsVisualizeVectorizer(); virtual void setUp( OdGsViewImpl& view ); protected: virtual void beginViewVectorization(); virtual void endViewVectorization(); virtual void affectTraits(const OdGiSubEntityTraitsData* pSource, OdGiSubEntityTraitsData& destination) const; void setupLinetyper( const OdGiSubEntityTraitsData& traits ) const; class ExGsLinetyperSaver { OdGiLinetyper* m_pLinetyper; OdUInt32* m_pFlags; bool m_bSetContinuousFlag; public: ExGsLinetyperSaver( OdGiLinetyper* pLinetyper, OdUInt32* pFlags ); ~ExGsLinetyperSaver(); }; protected: //Expoloded (Anonimous) data processing inline ExGsVisualizeDevice* getExGsVisualizeDevice(){ return (ExGsVisualizeDevice*)( view().device() ); } void pushLayerZero(); void popLayerZero(); public: void draw(const OdGiDrawable*); virtual bool doDraw(OdUInt32 drawableFlags, const OdGiDrawable* pDrawable); bool regenAbort() const; double deviation(const OdGiDeviationType, const OdGePoint3d&) const; void updateViewport(); void onTraitsModified(); virtual void ownerDrawDc( const OdGePoint3d& origin, const OdGeVector3d& u, const OdGeVector3d& v, const OdGiSelfGdiDrawable* pDrawable, bool dcAligned = true, bool allowClipping = false); //Geometry void pushModelTransform(const OdGeMatrix3d& xfm); void pushModelTransform(const OdGeVector3d& normal); void popModelTransform(); //Clip boundaries void pushClipBoundary(OdGiClipBoundary* pBoundary); void pushClipBoundary(OdGiClipBoundary* pBoundary, OdGiAbstractClipBoundary* pClipInfo); void popClipBoundary(); void polygonEye(OdUInt32 numVertices, const OdGePoint3d* vertexList); virtual void xline(const OdGePoint3d& firstPoint, const OdGePoint3d& secondPoint); virtual void ray(const OdGePoint3d& basePoint, const OdGePoint3d& throughPoint); virtual bool brep(const OdGiBrep& brep); virtual OdGiRegenType regenType() const; OdGiLinetypeTraits* getLineTypeTraits(); protected: ExGsVisualizeGeometryBase* m_pGeom; OdGiRegenType m_regenTypeOverride; bool m_bRegenTypeOverriden; class RegenTypeChanger { public: RegenTypeChanger( ExGsVisualizeVectorizer* pVec , OdGiRegenType type ) { m_oldRT = pVec->m_regenTypeOverride; m_oldRTFlag = pVec->m_bRegenTypeOverriden; m_RTFlag = &(pVec->m_bRegenTypeOverriden); m_RT = &(pVec->m_regenTypeOverride); *m_RTFlag = true; *m_RT = type; } ~RegenTypeChanger() { *m_RTFlag = m_oldRTFlag; *m_RT = m_oldRT; } protected: bool* m_RTFlag; OdGiRegenType* m_RT; OdGiRegenType m_oldRT; bool m_oldRTFlag; }; OdUInt32 m_nNestingLevel; class NLCounter { protected: OdUInt32* m_pLevel; public: NLCounter( ExGsVisualizeVectorizer* pVec ) { m_pLevel = &(pVec->m_nNestingLevel); (*m_pLevel)++; } ~NLCounter() { (*m_pLevel)--; } bool isNested() const { return *m_pLevel != 1; } }; OdTvEntityId createNewTvEntity( const OdString& name = L"" ); OdTvEntityId createNewTvInsert( OdTvBlockId blockId, const OdString& name = L"" ); OdTvBlockId m_curBlockId; OdRxObject* m_pCurMetafile; void createLightEntity( const OdGiDrawable* pDrawable ); public: //Metafiles OdRxObjectPtr newGsMetafile(); void beginMetafile(OdRxObject* pMetafile); void endMetafile(OdRxObject* pMetafile); protected: friend class ExGsVisualizeMetafile; enum EntityType { kTypeEntity = 0, kTypeInsert = 1, kTypeLight = 2 }; void setCurrentMetafileEntity( OdTvEntityId id, EntityType type = kTypeEntity ); OdGiConveyorEmbranchmentPtr m_pConveyorInjection; void createConveyorInjection(); void removeConveyorInjection(); bool m_bVectorizationBegins; bool isIgnore() const; public://attributes void startAttributesSegment(); void processAttributesSegment( bool bFromBlockRef = true ); protected: ExGsVisualizeTimer *m_pTimer; public: void setTiming( bool bEnable ); bool isGeometryNeedTransform() const { return m_bGeomInUse; } protected: bool m_bGeomInUse; void setGeometryNeedTransform( bool b = true ) { m_bGeomInUse = b; } enum GeometryConveyorPosition { kConveyorBegin, kConveyorEnd }; GeometryConveyorPosition m_geometryPosition; OdGiEmptyGeometry m_emptyGeometry; void switchGeometryPosition( GeometryConveyorPosition to = kConveyorBegin ); bool m_bCanSetPositionBegin; public: bool isGeometryInterseptionAtEnd() const { return m_geometryPosition == kConveyorEnd; } bool isGeometryInterseptionAtBegin() const { return m_geometryPosition == kConveyorBegin; } void setDisableEntityCaching( bool b ) { if( m_pGeom ) m_pGeom->setDisableEntityCaching( b ); } protected: struct BlockInsertDescr { OdArray< OdTvEntityId > m_array; OdUInt32 m_processingInsert; BlockInsertDescr() { m_processingInsert = 0; } }; OdStack m_insertStack; bool m_bNeedConvertByBlockColor; struct ClipBoundaryDef { OdGiClipBoundary CB; OdGiAbstractClipBoundary* pAbsCB; BlockInsertDescr* pBlcDescr; ClipBoundaryDef() { pAbsCB = NULL; } ClipBoundaryDef( OdGiClipBoundary cb, OdGiAbstractClipBoundary* absCb, BlockInsertDescr* pBlc ) { CB = cb; if( absCb ) { pAbsCB = absCb->clone(); } else { pAbsCB = NULL; } pBlcDescr = pBlc; } ~ClipBoundaryDef() { if( pAbsCB ) delete pAbsCB; pAbsCB = NULL; } ClipBoundaryDef( const ClipBoundaryDef& def ) { CB = def.CB; if( def.pAbsCB ) { pAbsCB = def.pAbsCB->clone(); } else { pAbsCB = NULL; } pBlcDescr = def.pBlcDescr; } }; OdStack m_clipBoundariesStack; public: OdUInt8 getSpecificFillingMode( const OdGiSubEntityTraitsData& traits ); double getVectorizerTime() const { if( !m_pTimer ) return 0.0; return m_pTimer->time(); } protected: bool isViewportDependentEntity(); void obtainVectorizerExtents( OdGeExtents3d& ); void resetVectorizerExtents( OdGeExtents3d& accumedExtents, const OdGeExtents3d& entExtents = OdGeExtents3d::kInvalid ); OdDbBaseBlockRefPE* m_pCurBlockRefPE; bool m_bProcessedAttributesSegment; bool m_bAlreadyAskedForModes; bool m_bForceInsertViewDependent; bool m_bExplodedBlock; public: bool plineThroughLinetyper( ExGsVisualizeGeometry* pGeom, const OdGiPolyline& lwBuf, const OdGeMatrix3d* pXform, OdUInt32 i, OdUInt32 numSegs ); protected: ExGsVisualizeHierarchyReflector m_reflector; public: ExGsVisualizeHierarchyReflector& reflector() { return m_reflector; } protected: OdGsModel* m_pCurrentGsModel; OdUInt8 m_internalOptions = 0; enum class InternalOption { kInsideAnonymousBlock = 1 << 0, kInsideExplodedInsert = 1 << 1 }; using ExGsVisualizeVectorizerOptionsKeeper = ExFlagsKeeper < OdUInt8, InternalOption >; }; typedef OdSharedPtr ExGsVisualizeVectorizerPtr; #include "TD_PackPop.h" #endif // __OD_GS_BITMAP_VECTORIZER__