/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2016, 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 Teigha(R) software pursuant to a license // agreement with Open Design Alliance. // Teigha(R) Copyright (C) 2002-2016 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_BASE_VECTORIZER_H_ #define __OD_GS_BASE_VECTORIZER_H_ #include "TD_PackPush.h" #include "Gs/GsExport.h" #include "Gs/GiBaseVectorizerImpl.h" #include "Gs/GsExtAccum.h" #include "Gs/GsModel.h" #include "GsMarkerArray.h" #include "Gs/GsHighlightData.h" class OdGsBaseModel; class OdGsLayerNode; class OdGsUpdateContext; class OdGiSelectProc; class OdGsEntityNode; class OdGsBlockReferenceNode; class OdGsBlockReferenceNodeImpl; struct OdGsGeomPortion; class OdGsMaterialNode; class OdGsBaseVectorizer; class OdGsMtContext; class OdGsUpdateState; class OdGiSharedRefDesc; class OdGiHistory; class OdGiSectionGeometry; /** \details Library: TD_Gs */ class GS_TOOLKIT_EXPORT OdGsWriter { public: OdGsWriter(); /** \details Returns the accumulated extents when writing to the object. */ OdGsExtAccum& extentsAccum() { return *m_pExtAccum.get(); } OdGsBaseModel* gsModel() const { return m_pGsModel; } bool isRecordingMetafile() { return m_pGeomPortion != 0; } void beginMetafileRecording(OdGsGeomPortion* pGeomPortion) { m_pGeomPortion = pGeomPortion; } void endMetafileRecording(); void onNestedDrawable(OdDbStub* layerId); bool isLayerFrozen(OdGsLayerNode *pLayerNode) const; private: friend class OdGsBaseVectorizer; void set(OdGsBaseVectorizer* v) { m_vectorizer = v; } void onLayerModified(OdDbStub* layerId); void onLayerModified(OdDbStub* layerId, bool bFrozen); void onFrozenLayerModified(OdDbStub* layerId) const; public: OdGsBaseModel* m_pGsModel; protected: OdGsExtAccumPtr m_pExtAccum; OdGsGeomPortion* m_pGeomPortion; OdGsBaseVectorizer* m_vectorizer; }; class OdGiPointLightTraitsData; class OdGiSpotLightTraitsData; class OdGiDistantLightTraitsData; class OdGiWebLightTraitsData; /** \details Library: TD_Gs */ class GS_TOOLKIT_EXPORT OdGsBaseVectorizer: public OdGiBaseVectorizerImpl { public: OdGsBaseVectorizer(); protected: ODRX_USING_HEAP_OPERATORS(OdGiBaseVectorizer); public: #ifdef SWIG virtual void draw(const OdGiDrawable* pDrawable) {draw(pDrawable);}; #endif /** OdGsBaseVectorizer methods * */ OdGsWriter& gsWriter() { return m_gsWriter; } const OdGsWriter& gsWriter() const { return m_gsWriter; } OdGsExtAccum& gsExtentsAccum() { return gsWriter().extentsAccum(); } /** \details Creates a new GsMetafile (cache) object. \remarks Returns a SmartPointer to the newly created object. GsMetafiles are used to record vectorizations, and rapidly 'redraw' them to a display device. \sa * beginMetafile * endMetafile * playMetafile */ virtual OdRxObjectPtr newGsMetafile(); /** \details Begins vectorization to the specified GsMetafile (cache) object. \param pMetafile [in] Pointer to the GsMetafile. \remarks GsMetafiles are used to record vectorizations, and rapidly 'redraw' them to a display device. \sa * endMetafile * newGsMetafile * playMetafile */ virtual void beginMetafile(OdRxObject* pMetafile); /** \details Ends vectorization to the specified GsMetafile (cache) object. \param pMetafile [in] Pointer to the GsMetafile. \remarks GsMetafiles are used to record vectorizations, and rapidly 'redraw' them to a display device. \sa * beginMetafile * newGsMetafile * playMetafile */ virtual void endMetafile(OdRxObject* pMetafile); /** \details Plays (redraws) the specified Metafile (cache) object. \param pMetafile [in] Pointer to the GsMetafile. \remarks GsMetafiles are used to record vectorizations, and rapidly 'redraw' them to a display device. \sa * beginMetafile * endMetafile * newGsMetafile */ virtual void playMetafile(const OdRxObject* pMetafile); /** \details Stores the specified Metafile (cache) into OdGsFiler object. \param pMetafile [in] Pointer to the GsMetafile. \param pFiler [in] Pointer to the OdGsFiler object. */ virtual bool saveMetafile(const OdRxObject* pMetafile, OdGsFiler *pFiler); /** \details Loads the Metafile (cache) from OdGsFiler object. \param pFiler [in] Pointer to the OdGsFiler object. */ virtual OdRxObjectPtr loadMetafile(OdGsFiler *pFiler); /** \details This method can be called right after endMetafile() to check whether last recorded metafile was empty and optimize stored data. */ bool isMetafileEmpty() const { return m_bMetafileIsEmpty; } /** \details Sets viewport's common data before display() call. */ virtual void loadViewport(); virtual bool forceMetafilesDependence() const; virtual bool isViewRegenerated() const; /** \details Draws the frame for the viewport. */ virtual void drawViewportFrame(); virtual void updateViewport(); // Materials support virtual void processMaterialNode(OdDbStub *materialId, OdGsMaterialNode *pNode); virtual bool saveMaterialCache(const OdGsMaterialNode *pNode, OdGsFiler *pFiler); virtual bool loadMaterialCache(OdGsMaterialNode *pNode, OdGsFiler *pFiler); virtual void addPointLight(const OdGiPointLightTraitsData&) {} virtual void addSpotLight(const OdGiSpotLightTraitsData&) {} virtual void addDistantLight(const OdGiDistantLightTraitsData&) {} virtual void addWebLight(const OdGiWebLightTraitsData&); // default implementation call's addPointLight ~OdGsBaseVectorizer(); /** OdGiGeometry Overrides * */ void pushModelTransform(const OdGeMatrix3d& xfm); void pushModelTransform(const OdGeVector3d& normal); void popModelTransform(); void pushClipBoundary(OdGiClipBoundary* pBoundary); void pushClipBoundary(OdGiClipBoundary* pBoundary, OdGiAbstractClipBoundary* pClipInfo); void popClipBoundary(); /** OdGiBaseVectorizer Overrides * */ virtual void setEntityTraitsDataChanged(); virtual void setEntityTraitsDataChanged(int bit, bool value = true); /** OdGsBaseVectorizer methods * */ bool disableInfiniteGeomExtents() const { return GETBIT(m_flags, kDisableInfiniteGeomExtents); } bool sectionableGeomExtentsOnly() const { return GETBIT(m_flags, kSectionableGeomExtentsOnly); } void setSectionableGeomExtentsOnly(bool bOn) { SETBIT(m_flags, kSectionableGeomExtentsOnly, bOn); } /** \details This method sets internal state flag indicating playing mode and calls playMetafile(). The flag can be accessed via isPlayingMfAsGeometry(), see below. */ void playMetafileMode(const OdRxObject* pMetafile, EMetafilePlayMode eMode); /** \details This method returns internal state indicating metafile playing mode. */ EMetafilePlayMode metafilePlayMode() const { return m_eMfPlayMode; } enum MetafileTransformFlags { kSharedRefTransform = (1 << 0), kSharedRefUpdate = (1 << 1), kSharedRefSelect = (1 << 2) }; virtual void pushMetafileTransform(const OdGeMatrix3d&, OdUInt32 = 0){} virtual void popMetafileTransform(OdUInt32 = 0){} virtual bool useSharedBlockReferences() const { return true; } virtual bool useMetafileAsGeometry() const { return false; } virtual OdGiConveyorOutput& outputForMetafileGeometry(); virtual void setTransformForMetafileGeometry(const OdGeMatrix3d&) {} virtual OdGeMatrix3d getTransformForMetafileGeometry() const { return OdGeMatrix3d::kIdentity; } virtual void reportUpdateError(OdDbStub* /*entityId*/, const OdError& error) { #ifdef ODA_DIAGNOSTICS throw error; #else ODA_ASSERT(error); // prevent arg unused warning #endif } OdGsLayerNode* gsLayerNode(OdDbStub* layerId, OdGsBaseModel* pModel); /** \details This method returns internal state indicating color fading mode. */ inline bool isFaded() const; inline OdUInt32 fadingIntensity() const; inline bool isHighlighted() const; inline bool isSelecting() const; bool isDragging() const; virtual OdGiConveyorOutput& gsExtentsOutput() { return secondaryOutput(); } /** \details Controls analytic linetype support for circles and circular arcs in this VectorizeView object. \param analytic [in] Analytic linetype support. \sa Analytic Linetyping */ virtual void setAnalyticLinetypingCircles(bool analytic); /** \details Returns true if and only if analytic linetype support for circles and circular arcs is enabled in this VectorizeView object. \sa Analytic Linetyping */ virtual bool isAnalyticLinetypingCircles() const; /** \details Controls analytic linetype support for ellipses, elliptical curves, and NURBS curves in this VectorizeView object. \param analytic [in] Analytic linetype support. \sa Analytic Linetyping */ virtual void setAnalyticLinetypingComplexCurves(bool analytic); /** \details Returns true if and only if analytic linetype support for ellipses, elliptical curves, and NURBS curves is enabled in this VectorizeView object. \sa Analytic Linetyping */ virtual bool isAnalyticLinetypingComplexCurves() const; //#ifdef GS_INEXACT_SELECTION void checkSelection(); //#endif virtual bool displayViewportProperties(OdGsPropertiesDirectRenderOutput *pdro = NULL, OdUInt32 incFlags = OdGsProperties::kAll); /** \details Returns the secondary output from this vectorizer object. */ OdGiConveyorOutput& secondaryOutput(); /** OdGiBaseVectorizerImpl methods * */ virtual void setUp(OdGsViewImpl& view); /** OdGiBaseVectorizer methods * */ virtual void beginViewVectorization(); virtual void endViewVectorization(); virtual void onTraitsModified(); virtual bool regenAbort() const; virtual bool doDraw(OdUInt32 drawableFlags, const OdGiDrawable* pDrawable); virtual void setSelectionMarker(OdGsMarker selectionMarker); virtual OdGiConveyorOutput& output(); virtual void setVisualStyle(OdDbStub *visualStyleId); virtual void setVisualStyle(const OdGiVisualStyle& visualStyle); const OdGsMarkerArray* highlightedSubentities() const { return m_pCurHltBr.get() && m_pCurHltBr->markers().size() ? &m_pCurHltBr->markers() : NULL; } OdGsHlBranch* findHighlightedSubnodeBranch(); OdUInt32 threadIndex() const { return m_threadIndex; } void highlight(bool bHighlight); /** \details Returns current highlighting data. */ const OdGsHlBranch* currentHighlightBranch() const { return m_pCurHltBr; } OdGsLayerNode *activeLayerNode(bool bSync = false) const { if (bSync) updateLayerTraits(m_effectiveEntityTraitsData); return m_effectiveLayer; } protected: void doSelect(const OdGePoint2d* aPtDc, int numPoints, OdGsSelectionReactor* pReactor, OdGsView::SelectionMode mode); bool doViewExtents(OdGeBoundBlock3d& extents); /** \details Paints the display with each of the drawable objects associated with this VectorizeView object. \param update [in] If and only if true, the cache is updated before displaying the drawable. \remarks The display is painted for each drawable from one of the following methods in the following order. 1. Model cache. 2. The metafile for the drawable. 3. The drawable itself. */ virtual void display(bool bUpdate); /** \details Recomputes the extents for this VectorizeView object. \param buildCache [in] Builds Metafile (cache) objects if and only if true. */ virtual void updateExtents(bool bBuildCache); /** OdGiBaseVectorizer methods * */ virtual const OdGiLayerTraitsData& effectiveLayerTraits() const; virtual OdDbStub* switchLayer(OdDbStub* layerId) const; void selectionMarkerOnChange(OdGsMarker nSelectionMarker); void checkRenderType(const OdGsModel *pModel); virtual void renderTypeOnChange(OdGsModel::RenderType renderType); void displayWithoutNesting(OdGsEntityNode *pNode); public: void updateExtentsInThreadInit(OdGsMtContext& mtContext); private: void setInitGsState(bool bOn); bool isRecordingHistory(); void deleteHistory(); void setThreadIndex(OdUInt32 idx) { m_threadIndex = idx; } bool drawSectionable(const OdGiDrawable& drawable, bool& bRes); bool drawSectionGeometry(OdGiSectionGeometry& geom, bool bVpModelTfAwareBefore); void setCurrentState(OdGsUpdateState& newState); OdGsUpdateState* currentState() { return m_curState; } const OdGsUpdateState* currentState() const { return m_curState; } void applyState(const OdGsUpdateState& s, const OdGsUpdateState& prev); public: OdGsHlBranchPtr m_pCurHltBr; protected: bool m_bMetafileIsEmpty; OdGsWriter m_gsWriter; OdGiSelectProc* m_pSelectProc; OdGiConveyorGeometry* m_pDetachedOutput; OdGiConveyorGeometry* m_pDetachedSecondaryOutput; EMetafilePlayMode m_eMfPlayMode; OdGsUpdateState* m_curState; OdGsModel::RenderType m_curRenderType; OdIntPtr m_drawableFilterFunction; // Fading support enum FadingFlags { kFfLockedLayer = (1 << 0), kFfXref = (1 << 1), kFfRefEdit = (1 << 2), kFfFlagsMask = kFfLockedLayer | kFfXref | kFfRefEdit, kEFfLockedLayer = (1 << 4), kEFfXref = (1 << 5), kEFfRefEdit = (1 << 6), kEFfFlagsMask = kEFfLockedLayer | kEFfXref | kEFfRefEdit, kEFfFlagsOffset = 4, kFvLockedLayerOffset = 8, kFvLockedLayerMask = (0xFF << kFvLockedLayerOffset), kFvXrefOffset = 16, kFvXrefMask = (0xFF << kFvXrefOffset), kFvRefEditOffset = 24, kFvRefEditMask = (0xFF << kFvRefEditOffset) }; OdUInt32 m_fadingFlags; template friend class OdGsLockFadingFlag; private: mutable const OdGiLayerTraitsData* m_pCachedLayer; OdGsLayerNode* m_effectiveLayer; OdGsExtAccumPtr m_pOutputExtents; OdGiHistory* m_giHistory; OdUInt32 m_threadIndex; bool m_bTraitsDataChanged; bool m_bByBlockTraitsChanged; friend class OdGsUpdateContext; friend class OdGsDisplayContext; friend class OdGsBaseVectorizeView; }; template class OdGsLockFadingFlag { protected: OdUInt32 &m_lockedFlags; bool m_bSavedBit; public: OdGsLockFadingFlag(OdGsBaseVectorizer &vectorizer) : m_lockedFlags(vectorizer.m_fadingFlags) , m_bSavedBit(GETBIT(vectorizer.m_fadingFlags, 1 << fadingType)) {} void set(bool bNewVal) { SETBIT(m_lockedFlags, 1 << fadingType, bNewVal); } OdGsLockFadingFlag(OdGsBaseVectorizer &vectorizer, bool bNewVal) : m_lockedFlags(vectorizer.m_fadingFlags) , m_bSavedBit(GETBIT(vectorizer.m_fadingFlags, 1 << fadingType)) { set(bNewVal); } ~OdGsLockFadingFlag() { set(m_bSavedBit); } }; inline bool OdGsBaseVectorizer::isFaded() const { // Returns true in case if any type of fading is 'true' and fading value is positive return !!((m_fadingFlags & kFfFlagsMask) & ((m_fadingFlags & kEFfFlagsMask) >> kEFfFlagsOffset)); } inline OdUInt32 OdGsBaseVectorizer::fadingIntensity() const { // Returns percentage in [0-100] range OdUInt32 nIntensityMix = 100; if (GETBIT(m_fadingFlags, kFfLockedLayer) && GETBIT(m_fadingFlags, kEFfLockedLayer)) nIntensityMix = nIntensityMix * (100 - ((m_fadingFlags & kFvLockedLayerMask) >> kFvLockedLayerOffset)) / 100; if (GETBIT(m_fadingFlags, kFfXref) && GETBIT(m_fadingFlags, kEFfXref)) nIntensityMix = nIntensityMix * (100 - ((m_fadingFlags & kFvXrefMask) >> kFvXrefOffset)) / 100; if (GETBIT(m_fadingFlags, kFfRefEdit) && GETBIT(m_fadingFlags, kEFfRefEdit)) nIntensityMix = nIntensityMix * (100 - ((m_fadingFlags & kFvRefEditMask) >> kFvRefEditOffset)) / 100; return 100 - nIntensityMix; } inline bool OdGsBaseVectorizer::isSelecting() const { return m_pSelectProc != 0; } inline bool OdGsBaseVectorizer::isHighlighted() const { return GETBIT(m_flags, kHighlighted); } #include "TD_PackPop.h" #endif // __OD_GS_BASE_VECTORIZER_H_