zjf
2023-03-06 392b76515f40376b6d36f40a114850ef63650384
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
/////////////////////////////////////////////////////////////////////////////// 
// 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__