///////////////////////////////////////////////////////////////////////////////
|
// 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_BLOCKREFERENCE_NODE__
|
#define __OD_GS_BLOCKREFERENCE_NODE__
|
|
#include "TD_PackPush.h"
|
|
#include "GsEntityNode.h"
|
#include "OdVector.h"
|
|
class OdGsSpQueryContext;
|
|
/** \details
|
|
Library: TD_SpatialIndex
|
|
<group OdSi_Classes>
|
*/
|
class GS_TOOLKIT_EXPORT OdSiRecursiveVisitor : public OdSiVisitor
|
{
|
public:
|
OdSiRecursiveVisitor(): m_pQuery(NULL), m_worldToNode(NULL), m_nodeToWorld(NULL),
|
m_worldToModel(NULL), m_modelToWorld(NULL){}
|
|
const OdSiShape* query() const { return m_pQuery; }
|
void resetQuery(const OdSiShape* pQuery) { m_pQuery = pQuery; }
|
|
const OdGeMatrix3d* worldToNode() const { return m_worldToNode; }
|
void setWorldToNode(const OdGeMatrix3d* tf) { m_worldToNode = tf; }
|
const OdGeMatrix3d* nodeToWorld() const { return m_nodeToWorld; }
|
void setNodeToWorld(const OdGeMatrix3d* tf) { m_nodeToWorld = tf; }
|
const OdGeMatrix3d* worldToModel() const { return m_worldToModel; }
|
void setWorldToModel(const OdGeMatrix3d* tf) { m_worldToModel = tf; }
|
const OdGeMatrix3d* modelToWorld() const { return m_modelToWorld; }
|
void setModelToWorld(const OdGeMatrix3d* tf) { m_modelToWorld = tf; }
|
|
protected:
|
const OdSiShape* m_pQuery;
|
const OdGeMatrix3d* m_worldToNode;
|
const OdGeMatrix3d* m_nodeToWorld;
|
const OdGeMatrix3d* m_worldToModel;
|
const OdGeMatrix3d* m_modelToWorld;
|
};
|
|
typedef OdSiRecursiveVisitor OdSiSelBaseVisitor;
|
|
/** \details
|
|
Library: TD_SpatialIndex
|
|
<group OdSi_Classes>
|
*/
|
class OdSiRecursiveVisitorTf
|
{
|
public:
|
OdSiRecursiveVisitorTf(OdSiRecursiveVisitor& v, const OdGeMatrix3d& mat);
|
~OdSiRecursiveVisitorTf();
|
operator OdSiRecursiveVisitor*() { return &m_visitor; }
|
|
protected:
|
OdSiRecursiveVisitor& m_visitor;
|
private:
|
const OdSiShape* m_prevQuery;
|
std::auto_ptr<OdSiShape> m_transformedQuery;
|
};
|
typedef OdSiRecursiveVisitorTf OdSiSelectVisitorTf;
|
|
/** \details
|
|
Library: TD_SpatialIndex
|
|
<group OdSi_Classes>
|
*/
|
class OdGsSpQueryContextTf: public OdSiRecursiveVisitorTf
|
{
|
public:
|
OdGsSpQueryContextTf(OdSiRecursiveVisitor& v, const OdGeMatrix3d& objectTf, const OdGeMatrix3d& objectTfInv,
|
const OdGeScale3d& scale);
|
~OdGsSpQueryContextTf();
|
|
protected:
|
OdGeMatrix3d m_nodeToWorld;
|
OdGeMatrix3d m_worldToNode;
|
const OdGeMatrix3d* m_prevNodeToWorld;
|
const OdGeMatrix3d* m_prevWorldToNode;
|
OdGeMatrix3d m_modelToWorld;
|
OdGeMatrix3d m_worldToModel;
|
const OdGeMatrix3d* m_prevModelToWorld;
|
const OdGeMatrix3d* m_prevWorldToModel;
|
};
|
|
// forward declarations
|
class OdGsBlockReferenceNodeImpl;
|
class OdGsBlockNode;
|
class WorldDrawBlockRef;
|
class OdGsUpdateState;
|
|
/** \details
|
This class is a service class for handling of viewport aware flags array.
|
|
Library: TD_Gs
|
|
<group OdGs_Classes>
|
*/
|
class GS_TOOLKIT_EXPORT OdGsAwareFlagsArray
|
{
|
public:
|
OdGsAwareFlagsArray(){}
|
enum
|
{
|
kChildrenNotUpToDate = 0x80000000
|
};
|
void setChildrenUpToDate(bool childrenUpToDate, const OdUInt32 nVpID);
|
bool childrenUpToDate(OdUInt32 nVpID) const;
|
OdUInt32 get(OdUInt32 nVpID) const;
|
void set(OdUInt32 nVpID, OdUInt32 flags);
|
void clear() { m_vpAwareFlags.clear(); }
|
bool isEmpty() const { return m_vpAwareFlags.isEmpty(); }
|
OdUInt32 numAwareFlags() const { return m_vpAwareFlags.size(); }
|
bool areInvalid(OdUInt32 nVpID) const;
|
|
protected:
|
bool findFlag(OdUInt32 nVpID) const
|
{ return nVpID < m_vpAwareFlags.size(); }
|
|
private:
|
// viewport aware flags
|
OdUInt32Vector m_vpAwareFlags;
|
};
|
|
/** \details
|
This class is the base class for implementation of GS reference nodes.
|
Derivatives of this class implement different model of storing referenced objects.
|
|
Library: Gs
|
<group OdGs_Classes>
|
*/
|
class GS_TOOLKIT_EXPORT OdGsBlockReferenceNodeImpl
|
{
|
public:
|
OdGsBlockReferenceNodeImpl();
|
void* operator new(size_t);
|
void operator delete(void*);
|
|
void addRef()
|
{
|
++m_nRefCounter;
|
}
|
void release()
|
{
|
ODA_ASSERT((m_nRefCounter > 0));
|
if (!(--m_nRefCounter))
|
delete this;
|
}
|
long numRefs() const { return m_nRefCounter; }
|
|
// Main methods, used for OdGsNode interface implementation
|
|
//pBlock can be NULL.
|
//If is not NULL only when it is passed directly from the function where the drawable is open.
|
//If it is NULL and it is required then use blockNode.underlyingDrawable()
|
virtual void updateSubitems(OdGsUpdateContext& ctx,
|
OdGsBlockNode& blockNode, const OdGiDrawable* pBlock) = 0;
|
virtual void display(OdGsDisplayContext& ctx, bool isHighlightedAll) = 0;
|
|
//NS: following methods return true if operation succeded (invalidation
|
//or destroying leave the object valid). If they return false, it means that
|
//OdGsNode should release the instance and recreate m_pImpl.
|
virtual bool invalidate(OdGsContainerNode* pParent, OdGsViewImpl* pView,
|
OdUInt32 mask) = 0;
|
virtual bool destroy() = 0;
|
virtual bool destroySubitems() = 0;
|
|
virtual bool select(OdGsBaseVectorizer& view, OdSiSelBaseVisitor* pVisitor,
|
bool bHasExtents, OdGsView::SelectionMode mode) = 0;
|
virtual void highlight(bool bDoIt, bool bWholeBranch) = 0;
|
// Methods for traversing internal subitems
|
virtual OdGsEntityNode* firstEntity() = 0;
|
virtual void playAsGeometry(OdGsBaseVectorizer& view, EMetafilePlayMode eMode) = 0;
|
virtual bool isSharedReference() const { return false; }
|
virtual bool isSharedDefinition() const { return false; }
|
virtual bool layersChanged(OdGsViewImpl& view) const;
|
|
virtual void makeStock() = 0;
|
virtual void releaseStock() = 0;
|
virtual void propagateLayerChangesStock() = 0;
|
virtual void doSpatialQuery(OdGsSpQueryContext& ctx) = 0;
|
|
virtual bool saveNodeImplState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer) const = 0;
|
virtual bool loadNodeImplState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer, OdGsBaseModel *pModel) = 0;
|
virtual void postprocessNodeImplLoading(OdGsFiler * /*pFiler*/) { }
|
protected:
|
virtual ~OdGsBlockReferenceNodeImpl();
|
|
protected:
|
OdRefCounter m_nRefCounter;
|
};
|
|
/** \details
|
|
Library: TD_Gs
|
|
<group OdGs_Classes>
|
*/
|
class GS_TOOLKIT_EXPORT OdGsBlockReferenceNode: public OdGsEntityNode,
|
protected OdGsAwareFlagsArray
|
{
|
public:
|
ODRX_DECLARE_MEMBERS(OdGsBlockReferenceNode);
|
|
OdGsBlockReferenceNode(OdGsBaseModel* pModel, const OdGiDrawable* pDrawable, bool bSetGsNode = false);
|
public:
|
~OdGsBlockReferenceNode();
|
|
// additional flags for processing of inserts
|
enum
|
{
|
kValid = OdGsEntityNode::kLastFlag << 1,
|
kBrExcludeFromViewExt = OdGsEntityNode::kLastFlag << 2,
|
kBrClipped = OdGsEntityNode::kLastFlag << 3,
|
kLastFlag = kBrClipped
|
};
|
|
bool isValid() const { return GETBIT(m_flags, kValid); }
|
void setValid(bool bSet) { SETBIT(m_flags, kValid, bSet); }
|
bool excludeFromViewExt() const { return GETBIT(m_flags, kBrExcludeFromViewExt); }
|
void setExcludeFromViewExt(bool bSet) { SETBIT(m_flags, kBrExcludeFromViewExt, bSet); }
|
|
virtual bool isReference() const { return true; }
|
virtual bool layersChanged(OdGsViewImpl& view) const;
|
// implementation of OdGsEntityNode interface:
|
virtual void update(OdGsUpdateContext& ctx, OdGsContainerNode* pParent,
|
OdSiSpatialIndex* pParentIndex);
|
virtual void propagateLayerChanges(OdGsViewImpl& view);
|
|
virtual void invalidate(OdGsContainerNode* pParent, OdGsViewImpl* pView, OdUInt32 mask);
|
virtual void destroy();
|
virtual void destroySubitems();
|
|
virtual bool select(OdGsBaseVectorizer& view, OdSiSelBaseVisitor*,
|
OdGsView::SelectionMode mode);
|
|
/** \details
|
Add/release counter of highlighted children of the node, and set kHLT/kHLT_All flags if necessary
|
\param nSubnodes [in] number of subnodes
|
\param bHighlight [in] if true then highlight else unhighlight
|
\param bAll [in] if true then consider kHLT_All flag
|
Returns true if and only if highlighting of the child caused changing of kHLT flag on the container.
|
*/
|
bool highlightSubnodes(OdUInt32 nSubnodes, bool bHighlight, bool bAll);
|
|
/** \details
|
Returns the Aware flags for the specified Viewport for object.
|
\param viewportId [in] Viewport ID.
|
*/
|
virtual OdUInt32 awareFlags(OdUInt32 viewportId) const;
|
|
/** \details
|
Check Aware flags for the specified Viewport and return true if flags are invalid,
|
i.e. cannot be used for determining awareness of the node about view properties.
|
\param viewportId [in] Viewport ID.
|
*/
|
virtual bool awareFlagsAreInvalid(OdUInt32 viewportId) const;
|
|
/** \details
|
Returns true if the node has no graphical content.
|
*/
|
virtual bool isEmpty();
|
|
virtual OdGsEntityNode* firstEntity();
|
virtual OdGsEntityNode* firstAttrib() { return m_pFirstAttrib; }
|
void updateImpl(OdGsUpdateContext& ctx, const OdGiDrawable* pInsert,
|
OdSiSpatialIndex* pParentIndex);
|
|
OdGsBlockNode* blockNode() const { return m_pBlockNode; }
|
void clearBlockNode();
|
|
virtual void makeStock();
|
virtual void releaseStock();
|
virtual void propagateLayerChangesStock();
|
void updateBlockNode(const OdGiDrawable* pBlockTableRecord);
|
//For testing purposes
|
void* sharedDefinition();
|
virtual bool isMInsert() const { return false; }
|
static OdGsBlockReferenceNode* create(OdGsBaseModel* pModel, const OdGiDrawable* pDrawable);
|
virtual void doDisplay(OdGsDisplayContext& ctx);
|
virtual bool doSelect(OdGsBaseVectorizer& vect, OdGiDrawable* pDrw,
|
OdSiSelBaseVisitor* pVisitor, OdGsView::SelectionMode mode);
|
|
virtual void spatialQuery(const OdGsView& view, OdSiRecursiveVisitor* pVisitor);
|
|
protected:
|
virtual void setChildrenUpToDate(bool childrenUpToDate, const OdUInt32 nVpID);
|
virtual bool childrenUpToDate(OdUInt32 nVpID) const;
|
virtual bool childrenRegenDraw(OdUInt32 nVpID) const;
|
void updateAttribute(OdGsUpdateContext& ctx, OdGsEntityNode* pNode,
|
const OdGiDrawable* pInsert, OdGsMarker marker);
|
// Tool methods
|
void setAwareFlags(OdUInt32 viewportId, OdUInt32 nAwareFlags);
|
virtual void playAsGeometry(OdGsBaseVectorizer& view, EMetafilePlayMode eMode);
|
void initBlockNode(const OdGiDrawable* pBlock);
|
void setMetafile(OdGsUpdateContext& ctx, OdGsEntityNode::Metafile* pMf,
|
OdUInt32 awareFlags, const OdGeExtents3d& ext);
|
bool needRegen(OdUInt32 nVpID) const
|
{
|
if(!childrenUpToDate(nVpID))
|
return true;
|
OdUInt32 nAF = awareFlags(nVpID);
|
if( nAF == 0xFFFFFFFF || (baseModel()->viewChanges(nVpID) & nAF) != 0 )
|
{
|
const_cast<OdGsBlockReferenceNode*>(this)->setChildrenUpToDate(false, nVpID);
|
return true;
|
}
|
return false;
|
}
|
virtual void doUpdateImpl(OdGsUpdateContext& ctx, const OdGiDrawable* pBlockTableRecord, unsigned iInstance);
|
void drawBlock(OdGsUpdateContext& ctx, const OdGiDrawable* pBlockTableRecord,
|
OdGsBlockReferenceNodeImpl* pContainer,
|
bool bEnableSharedGraphics);
|
void postUpdateStep(OdGsUpdateState& state);
|
void addEntPropsFromState(const OdGsUpdateState& state);
|
void checkCancelledSharedRef(OdGsUpdateState& state);
|
static void actionPostUpdateStep(void* pObj, OdGsUpdateState& state);
|
static void actionAddEntPropsFromState(void* pObj, OdGsUpdateState& state);
|
static void actionCheckCancelledSharedRef(void* pObj, OdGsUpdateState& state);
|
static void actionRestartLocked(void* pObj, OdGsUpdateContext& ctx);
|
virtual void doSpatialQuery(OdGsSpQueryContext& ctx);
|
|
bool saveClientNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer) const;
|
bool loadClientNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer);
|
bool postprocessNodeLoading(OdGsFiler *pFiler);
|
private:
|
void createImpl(const OdGsUpdateContext& ctx, bool bTryShared);
|
void drawBlockImpl(OdGsUpdateContext& ctx, const OdGiDrawable* pBlockTableRecord,
|
OdGsBlockReferenceNodeImpl* pContainer,
|
bool bEnableSharedGraphics);
|
|
bool isAProxy(OdGiDrawable *pDrw, const OdGiContext *pCtx = NULL) const;
|
protected:
|
// Pointer to implementation object
|
TPtr<OdGsBlockReferenceNodeImpl> m_pImpl;
|
// Pointer to the node, corresponding to the block table record
|
OdGsBlockNode* m_pBlockNode;
|
// list of attributes
|
OdGsEntityNode* m_pFirstAttrib;
|
|
friend class WorldDrawBlockRef;
|
friend class GsDrawableNested;
|
friend class OdGsSpQueryContext;
|
};
|
|
/** \details
|
|
Library: TD_Gs
|
|
<group OdGs_Classes>
|
*/
|
class GS_TOOLKIT_EXPORT OdGsMInsertBlockNode: public OdGsBlockReferenceNode
|
{
|
public:
|
ODRX_DECLARE_MEMBERS(OdGsMInsertBlockNode);
|
OdGsMInsertBlockNode(OdGsBaseModel* pModel, const OdGiDrawable* pInsert, bool bSetGsNode = false);
|
public:
|
~OdGsMInsertBlockNode();
|
|
virtual void invalidate(OdGsContainerNode* pParent, OdGsViewImpl* pView, OdUInt32 mask);
|
virtual void destroy();
|
virtual void destroySubitems();
|
|
virtual void highlight(bool bDoIt, bool bWholeBranch);
|
|
virtual OdGsEntityNode* firstEntity();
|
virtual OdGsEntityNode* firstAttrib();
|
virtual bool layersChanged(OdGsViewImpl& view) const;
|
virtual void playAsGeometry(OdGsBaseVectorizer& view, EMetafilePlayMode eMode);
|
|
virtual void makeStock();
|
virtual void releaseStock();
|
virtual void propagateLayerChangesStock();
|
virtual bool isMInsert() const { return true; }
|
virtual void doUpdateImpl(OdGsUpdateContext& ctx,
|
const OdGiDrawable* pBlockTableRecord, unsigned iInstance);
|
OdGsEntityNode*& firstAttrib(unsigned iInstance) { return item(iInstance)->m_pFirstAttrib; }
|
void stretchExtents();
|
void setParams(const OdGeMatrix3d& blockTf, int nCols, int nRows, double sx, double sy)
|
{
|
m_blockTf = blockTf;
|
m_nCols = nCols;
|
m_nRows = nRows;
|
m_sx = sx;
|
m_sy = sy;
|
}
|
static void actionStretchExtents(void* pObj, OdGsUpdateState& state);
|
virtual void doDisplay(OdGsDisplayContext& ctx);
|
virtual bool doSelect(OdGsBaseVectorizer& vect, OdGiDrawable* pDrw,
|
OdSiSelBaseVisitor* pVisitor, OdGsView::SelectionMode mode);
|
|
protected:
|
void destroyCollection();
|
|
bool selectSubitems(OdGsBaseVectorizer& view,
|
OdSiSelBaseVisitor* pVisitor, OdGsView::SelectionMode mode);
|
bool selectAttributes(OdGsBaseVectorizer& view);
|
|
protected:
|
class GS_TOOLKIT_EXPORT CollectionItem
|
{
|
public:
|
CollectionItem() : m_nodeImp(0), m_pFirstAttrib(0) { }
|
CollectionItem(const CollectionItem& c):
|
m_nodeImp(c.m_nodeImp), m_pFirstAttrib(c.m_pFirstAttrib){}
|
void copyFrom(const CollectionItem& c);
|
|
OdGsBlockReferenceNodeImpl* imp() { return m_nodeImp; }
|
const OdGsBlockReferenceNodeImpl* imp() const { return m_nodeImp; }
|
OdGsEntityNode* firstAttrib() { return m_pFirstAttrib; }
|
const OdGsEntityNode* firstAttrib() const { return m_pFirstAttrib; }
|
|
public:
|
TPtr<OdGsBlockReferenceNodeImpl> m_nodeImp;
|
OdGsEntityNode* m_pFirstAttrib;
|
|
bool operator ==(const CollectionItem &it2) const
|
{
|
return (m_nodeImp == it2.m_nodeImp) && (m_pFirstAttrib == it2.m_pFirstAttrib);
|
}
|
bool operator !=(const CollectionItem &it2) const
|
{
|
return (m_nodeImp != it2.m_nodeImp) || (m_pFirstAttrib != it2.m_pFirstAttrib);
|
}
|
};
|
class GS_TOOLKIT_EXPORT Collection: public OdArray<CollectionItem>
|
{
|
public:
|
Collection(): OdArray<CollectionItem>(){}
|
Collection(const Collection& c);
|
~Collection();
|
};
|
protected:
|
OdGsBlockReferenceNodeImpl* getImpl(unsigned iInstance) { return item(iInstance)->m_nodeImp; }
|
CollectionItem* item(unsigned iInstance);
|
void clearParams() {m_nCols = m_nRows = 0; m_sx = m_sy = 0.; m_blockTf.setToIdentity(); }
|
|
bool saveClientNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer) const;
|
bool loadClientNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer);
|
bool postprocessNodeLoading(OdGsFiler *pFiler);
|
protected:
|
// Collection of implementation objects, representing clipped MINSERT.
|
// (If MINSERT is not clipped, it's represented by only implementation
|
// object OdGsBlockReferenceNode::m_pImpl)
|
Collection* m_pCollectionImpl;
|
OdGeMatrix3d m_xModelToWorld;
|
OdGeMatrix3d m_blockTf;
|
int m_nCols;
|
int m_nRows;
|
double m_sx;
|
double m_sy;
|
};
|
|
inline void OdGsBlockReferenceNode::clearBlockNode()
|
{
|
m_pBlockNode = 0;
|
}
|
|
#include "TD_PackPop.h"
|
|
#endif // __OD_GS_REFERENCE_NODE__
|