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
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
/////////////////////////////////////////////////////////////////////////////// 
// 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_CONTAINER_NODE__
#define __OD_GS_CONTAINER_NODE__
 
#include "TD_PackPush.h"
 
#include "Gs/GsNode.h"
#include "Si/SiSpatialIndex.h"
#include "OdVector.h"
 
class OdGsEntityNode;
class OdGsLightNode;
class OdGsBlockNode;
 
/** \details
    This class implements OdGsNode descendent objects that
    can serve as containers for OdGsEntityNode objects.
 
    Library: TD_Gs
    <group OdGs_Classes> 
*/
class GS_TOOLKIT_EXPORT OdGsContainerNode : public OdGsNode
{
protected:
  enum
  {
    kEntityListValid  = OdGsNode::kLastFlag << 1,
    kCheckWorkset     = OdGsNode::kLastFlag << 2,
    kHasStockData     = OdGsNode::kLastFlag << 3,
    kVpDepCache       = OdGsNode::kLastFlag << 4,
    kLastFlag         = kVpDepCache
  };
 
  enum
  {
    kChildrenNotUpToDate = 0x80000000 //special flag to use in setChildrenUpToDate/childrenUpToDate
      //per each viewport, flags are stored in m_vpAwareFlags
  };
 
  struct GS_TOOLKIT_EXPORT VpData : public OdRxObject
  {
    OdGsEntityNode*         m_pFirstEntity;
    OdGsEntityNode*         m_pLastEntity;
    OdList<OdGsLightNode*>  m_lightPtrs; // some of the lights are entities (ones that lies in model space)
    OdSiSpatialIndexPtr     m_pSpIndex;
    OdGsEntityNode*         m_pClearSpatialQueryStateFirst;
    int                     m_nChild;
    OdUInt32                m_nChildErased;
    OdUInt32                m_nChildSingleThreaded;
    OdUInt32                m_nChildHighlighted;
    OdGeExtents3d           m_realExtents; //Keeps real extents (for EXTMIN/MAX support)
    OdUInt32                m_maxLw;
    OdUInt32                m_flags;
    OdRxObjectPtr           m_pLightsData; // #21117 : pointer added for future needs. Probably temporary.
 
    enum
    {
      kEntityListValid  = OdGsContainerNode::kEntityListValid,
      kVpDepCache       = OdGsContainerNode::kVpDepCache
    };
 
    VpData();
    static OdSmartPtr<VpData> createObject(bool bShareable = false);
  };
  typedef OdSmartPtr<VpData> VpDataPtr;
  typedef OdVector<VpDataPtr> VpDataArray;
 
  inline VpData *getVpData(OdUInt32 nVpId, bool bCreateIfNotFound = true) const;
  VpData *makeVpData(OdUInt32 nVpId) const;
  inline OdUInt32 vpDataId(const VpData *pVpData) const;
public:
  inline bool hasVpData(OdUInt32 nVpId) const;
  inline OdUInt32 numVpData() const;
  OdUInt32 isAttached(OdGsEntityNode *pNode) const;
  void setEntityListsInvalid();
  OdUInt32 viewportId(const OdGsViewImpl &pView, bool bForceVpId = true) const;
  inline bool isVpDepCache() const;
public:
  /** \details
    Controls the EntityListValid flag for this ContainterNode object.
    \param nVpId [in]  Viewport ID.
    \param entityListValid [in]  Controls flag.
    
    \remarks
    This flag is typically set by update() and cleared by invalidate().     
  */
  void setEntityListValid(OdUInt32 nVpId, bool entityListValid);
  
  /** \details
    Returns true if and only if the ChildrenUpToDate flag is set for this ContainterNode object.
    \param nVpId [in]  Viewport ID.
    \remarks
    This flag is typically set by update() and cleared by addChild() and invalidate().
  */
  bool childrenUpToDate(OdUInt32 nVpId) const;
 
  /** \details
    Returns true if and only if a regen is required for the specified Viewport object for this ContainterNode object.
    \param nVpId [in]  Viewport ID. 
  */
  bool needRegen(OdUInt32 nVpId) const;
 
  void addChildNode(OdUInt32 nVpId, OdGsEntityNode* pEnt);
 
  void turnOnLights(OdGsBaseVectorizer& view);
  virtual ENodeType nodeType() const { return kContainerNode; }
 
  /** \details
    Vectorizes the entities in all of the child nodes of this ContainerNode object.
    \param ctx [in]  Display context.
  */
  virtual void displayEntityList(OdGsDisplayContext& ctx);
 
  /** \details
    Returns pointer to the first entity node inside container.
    \param nVpId [in]  Viewport ID.
  */
  OdGsEntityNode* firstEntityNode(OdUInt32 nVpId);
  /** \details
    Returns pointer to the first entity node inside container.
    \param nVpId [in]  Viewport ID.
  */
  const OdGsEntityNode* firstEntityNode(OdUInt32 nVpId) const;
  /** \details
    Returns pointer to the last entity node inside container.
    \param nVpId [in]  Viewport ID.
  */
  OdGsEntityNode* lastEntityNode(OdUInt32 nVpId);
  /** \details
    Returns pointer to the last entity node inside container.
    \param nVpId [in]  Viewport ID.
  */
  const OdGsEntityNode* lastEntityNode(OdUInt32 nVpId) const;
  /** \details
    Returns light nodes list.
    \param nVpId [in]  Viewport ID.
  */
  OdList<OdGsLightNode*> &lightNodesList(OdUInt32 nVpId);
  /** \details
    Returns light nodes list.
    \param nVpId [in]  Viewport ID.
  */
  const OdList<OdGsLightNode*> &lightNodesList(OdUInt32 nVpId) const;
 
  /** \details
    Returns the Aware flags for the specified Viewport for this ContainerNode object.
    
    \param viewportId [in]  Viewport ID. 
    
    \remarks
    awareFlags() returns a combination of zero or more of the following:
    
    <table>
    Name                            Value
    kVpID                           0x00000001
    kVpRegenType                    0x00000002
    kVpRenderMode                   0x00000004
    kVpWorldToEye                   0x00000008
    kVpPerspective                  0x00000010
    kVpResolution                   0x00000020
    kVpMaxDevForCircle              0x00000040
    kVpMaxDevForCurve               0x00000080
    kVpMaxDevForBoundary            0x00000100
    kVpMaxDevForIsoline             0x00000200
    kVpMaxDevForFacet               0x00000400
    kVpCamLocation                  0x00000800
    kVpCamTarget                    0x00001000
    kVpCamUpVector                  0x00002000
    kVpCamViewDir                   0x00004000
    kVpViewport                     0x00008000
    kVpFrontBack                    0x00010000
    kVpFrozenLayers                 0x00020000
    kVpLtypeScaleMult               0x00040000
    kEntityRegenDraw                0x00080000
    kVpDisableLayoutCache           0x00100000
    kVpModelTf                      0x00200000
    kVpExcludeFromExtMinMax         0x00400000
    kSectionable                    0x00800000
    kVpRenderModule                 0x01000000
    kVpAnnoScale                    0x02000000
    kVpFilterFunction               0x04000000
    kVpVisualStyle                  0x08000000
    </table>
  */
   OdUInt32 awareFlags(OdUInt32 viewportId) const;
 
  /** \details
    Sets the Aware flags for the specified Viewport for this ContainerNode object.
    
    \param viewportId [in]  Viewport ID. 
    \param flags [in]  Aware flags.
    
    \remarks
    awareFlags() returns a combination of zero or more of the following:
    
    <table>
    Name                            Value
    kVpID                           0x00000001
    kVpRegenType                    0x00000002
    kVpRenderMode                   0x00000004
    kVpWorldToEye                   0x00000008
    kVpPerspective                  0x00000010
    kVpResolution                   0x00000020
    kVpMaxDevForCircle              0x00000040
    kVpMaxDevForCurve               0x00000080
    kVpMaxDevForBoundary            0x00000100
    kVpMaxDevForIsoline             0x00000200
    kVpMaxDevForFacet               0x00000400
    kVpCamLocation                  0x00000800
    kVpCamTarget                    0x00001000
    kVpCamUpVector                  0x00002000
    kVpCamViewDir                   0x00004000
    kVpViewport                     0x00008000
    kVpFrontBack                    0x00010000
    kVpFrozenLayers                 0x00020000
    kVpLtypeScaleMult               0x00040000
    kEntityRegenDraw                0x00080000
    kVpDisableLayoutCache           0x00100000
    kVpModelTf                      0x00200000
    kVpExcludeFromExtMinMax         0x00400000
    kSectionable                    0x00800000
    kVpRenderModule                 0x01000000
    kVpAnnoScale                    0x02000000
    kVpFilterFunction               0x04000000
    kVpVisualStyle                  0x08000000
    </table>
  */
   void setAwareFlags(OdUInt32 viewportId, OdUInt32 flags);
 
protected:
  virtual void propagateLayerChanges(OdGsViewImpl& view);
  bool saveVpData(OdGsFiler *pFiler, const VpData *pVpData) const;
  bool loadVpData(OdGsFiler *pFiler, VpData *pVpData);
 
public:
  ODRX_DECLARE_MEMBERS(OdGsContainerNode);
 
  /** \param pModel [in]  Pointer to the BaseModel object.
    \param pUnderlyingDrawable [in]  Pointer to the underlying Drawable object.
    \param bTopLevel [in]  true if container represents layout's block
  */
  OdGsContainerNode(OdGsBaseModel* pModel, const OdGiDrawable* pUnderlyingDrawable, bool bSetGsNode = true);
 
  /** \details
    Returns true if and only if the EntityListValid flag is set for this ContainterNode object.
    \param nVpId [in]  Viewport ID.
    \remarks
    This flag is typically set by update() and cleared by invalidate().     
  */
  bool entityListValid(OdUInt32 nVpId) const;
  bool allEntityListsValid() const;
  bool isEmpty() const;
 
  /** \details
    Controls the ChildrenUpToDate flag for this ContainterNode object.
    \param childrenUpToDate [in]  Controls flag.
    \param nVpID [in]  Viewport ID.
    \remarks
    This flag is typically set by update() and cleared by addChild() and invalidate().
  */
  void setChildrenUpToDate(bool childrenUpToDate, OdUInt32* nVpID = NULL);
  bool childrenRegenDraw(OdUInt32 nVpID) const;
  void setChildrenRegenDraw(bool bVal, OdUInt32 nVpID);
 
  /** \details
    Adds a child node to this ContainerNode object.
    \param pDrawable [in]  Pointer to the Drawable object.
    \param unerased [in]  Added child is unerased.
  */
  virtual void addChild(const OdGiDrawable* pDrawable, OdGsViewImpl *pView, bool unerased = false);
 
  // adds information about the light if the light doesn't have gsNode yet
  virtual void addLight(OdUInt32 nVpId, const OdGiDrawable* pDrawable, const OdGeMatrix3d& model2World);
 
  /** \details
    Removes the specified child node from this ContainerNode object.
    \param pNode [in]  Pointer to the child object. 
  */
  virtual void removeChild(OdGsNode* pNode);
 
  void update(OdGsUpdateContext& ctx, OdGsContainerNode* pParent, OdSiSpatialIndex* pParentIndex);
 
  void display(OdGsDisplayContext& ctx);
 
  /** \details
    Returns a reference to the spatial index for this ContainerNode object.
    \param nVpId [in]  Viewport ID.
  */
  OdSiSpatialIndex& spatialIndex(OdUInt32 nVpId);
  /** \details
    Returns a reference to the spatial index for this ContainerNode object.
    \param nVpId [in]  Viewport ID.
  */
  const OdSiSpatialIndex& spatialIndex(OdUInt32 nVpId) const;
 
  /** \note
    The default implementation of this function ignores the pParent argument.
  */
  void invalidate(OdGsContainerNode* pParent, OdGsViewImpl* pView, OdUInt32 mask);
 
  /** \details
    Returns summ of all aware flags for entire viewports list.
  */
  OdUInt32 currViewChanges() const;
 
  /** \details
    Returns extents of this container node object.
    \param extents [out]  Reference to the OdGeExtents3d object which will receive current container node extents.
  */
  bool extents(OdGeExtents3d& extents) const;
 
  virtual bool extents(const OdGsView* pView, OdGeExtents3d& ext) const;
 
  /** \details
    Updates invalidVp flag for entire entities list.
  */
  void propagateInvalidVpFlag();
 
  bool checkWorkset() const;
  void setCheckWorkset(bool bVal);
  bool updateEntityList(OdGsUpdateContext& ctx);
  void updateEntities(OdGsUpdateContext& ctx);
  bool findCompatibleCache(OdGsViewImpl& view);
  /** \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);
 
  void destroy();
 
  void destroySubitems();
 
  inline OdUInt32 maxLineWeightIndexUsed(OdUInt32 nVpId) const;
 
  /** \details
    Returns real extents of the node
    \param nVpId [in]  Viewport ID.
  */
  inline const OdGeExtents3d& realExtents(OdUInt32 nVpId) const;
 
  /** \details
    Sets real extents of the node and its maximal lineweight
    \param nVpId [in]  Viewport ID.
    \param ext [in]  New real extents for the node.
    \param nMaxLw [in]  New maximal lineweight for the node.
  */
  inline void setRealExtents(OdUInt32 nVpId, const OdGeExtents3d& ext, OdUInt32 nMaxLw);
 
  inline void addViewRef(OdUInt32 nVpId);
  inline void removeViewRef(OdUInt32 nVpId);
  inline const ViewRefs& viewRefs() const;
 
  inline const StockProps& stock() const;
  void makeStock();
  void releaseStock();
  void propagateLayerChangesStock();
 
  bool saveNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer = NULL) const;
  bool loadNodeState(OdGsFiler *pFiler, OdGsBaseVectorizer *pVectorizer = NULL);
  bool postprocessNodeLoading(OdGsFiler *pFiler);
 
  bool safeEntityUpdate(OdGsEntityNode* pEntity, OdGsUpdateContext& ctx, OdSiSpatialIndex* pSpatialIndex);
  void addEntProps(const OdGsUpdateContext& ctx);
  bool doMTUpdate(OdGsUpdateContext& ctx);
  void doSTUpdate(OdGsUpdateContext& ctx);
 
  /** \details
    Removes entities marked as erased.
  */
  void removeErased();
 
  /** \details
    Returns number of child entities
    \param nVpId [in]  Viewport ID.
  */
  inline int numberOfChildren(OdUInt32 nVpId) const;
  inline OdUInt32 numberOfChildrenST(OdUInt32 nVpId) const;
  inline OdUInt32 numberOfChildrenErased(OdUInt32 nVpId) const;
protected:
  mutable VpDataArray m_vpData;
  mutable VpDataPtr m_shareableData;
  OdUInt32Vector m_vpAwareFlags; //this memory is never shared, no need in OdArray with refcounter on buffer
  ViewRefs m_viewRefs;
  StockProps m_stock;
};
 
inline OdGsContainerNode::VpData *OdGsContainerNode::getVpData(OdUInt32 nVpId, bool bCreateIfNotFound) const
{
  if (!GETBIT(m_flags, kVpDepCache))
    return m_shareableData;
  VpData *pVpData = (m_vpData.size() > nVpId) ? m_vpData[nVpId].get() : NULL;
  if (!pVpData && bCreateIfNotFound)
    return makeVpData(nVpId);
  return pVpData;
}
 
inline OdUInt32 OdGsContainerNode::vpDataId(const VpData *pVpData) const
{
  if (GETBIT(m_flags, kVpDepCache))
  {
    const OdUInt32 nVpData = m_vpData.size();
    const VpDataPtr *pVpDataPtr = m_vpData.getPtr();
    for (OdUInt32 nVpId = 0; nVpId < nVpData; nVpId++)
    {
      if (pVpDataPtr[nVpId].get() == pVpData)
        return nVpId;
    }
  }
  return 0;
}
 
inline bool OdGsContainerNode::hasVpData(OdUInt32 nVpId) const
{
  if (!GETBIT(m_flags, kVpDepCache))
    return true;
  return ((m_vpData.size() > nVpId) && !m_vpData.getAt(nVpId).isNull());
}
 
inline OdUInt32 OdGsContainerNode::numVpData() const
{
  if (!GETBIT(m_flags, kVpDepCache))
    return 1;
  return m_vpData.size();
}
 
inline bool OdGsContainerNode::isVpDepCache() const
{
  return GETBIT(m_flags, kVpDepCache);
}
 
inline bool OdGsContainerNode::entityListValid(OdUInt32 nVpId) const
{
  if (!isVpDepCache())
    return GETBIT(m_flags, kEntityListValid);
  const VpData *pVpData = getVpData(nVpId, false);
  if (pVpData)
    return GETBIT(pVpData->m_flags, kEntityListValid);
  return false;
}
 
inline bool OdGsContainerNode::allEntityListsValid() const
{
  return GETBIT(m_flags, kEntityListValid);
}
 
inline bool OdGsContainerNode::isEmpty() const
{
  const OdUInt32 nVpData = numVpData();
  for (OdUInt32 nView = 0; nView < nVpData; nView++)
  {
    const VpData *pVpData = getVpData(nView, false);
    if (pVpData && pVpData->m_pFirstEntity)
      return false;
  }
  return true;
}
 
inline void OdGsContainerNode::setEntityListsInvalid()
{
  for (OdUInt32 nView = 0; nView < numVpData(); nView++)
  {
    if (hasVpData(nView))
      SETBIT_0(getVpData(nView, false)->m_flags, VpData::kEntityListValid);
  }
  SETBIT_0(m_flags, kEntityListValid);
}
 
inline void OdGsContainerNode::setEntityListValid(OdUInt32 nVpId, bool bValid)
{
  SETBIT(getVpData(nVpId)->m_flags, kEntityListValid, bValid);
  if (!bValid || !isVpDepCache())
    SETBIT(m_flags, kEntityListValid, bValid);
  else
  { // Check does all entity lists valid
    const OdUInt32 nViews = numVpData();
    bool bAllListsValid = true;
    for (OdUInt32 nView = 0; nView < nViews; nView++)
    {
      const VpData *pVpData = getVpData(nView, false);
      if (pVpData && !GETBIT(pVpData->m_flags, VpData::kEntityListValid))
      {
        bAllListsValid = false;
        break;
      }
    }
    SETBIT(m_flags, kEntityListValid, bAllListsValid);
  }
}
 
inline OdSiSpatialIndex& OdGsContainerNode::spatialIndex(OdUInt32 nVpId)
{
  return *getVpData(nVpId)->m_pSpIndex.get();
}
 
inline const OdSiSpatialIndex& OdGsContainerNode::spatialIndex(OdUInt32 nVpId) const
{
  return *getVpData(nVpId)->m_pSpIndex.get();
}
 
inline OdGsEntityNode* OdGsContainerNode::firstEntityNode(OdUInt32 nVpId)
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return NULL;
  return pVpData->m_pFirstEntity;
}
 
inline const OdGsEntityNode* OdGsContainerNode::firstEntityNode(OdUInt32 nVpId) const
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return NULL;
  return pVpData->m_pFirstEntity;
}
 
inline OdGsEntityNode* OdGsContainerNode::lastEntityNode(OdUInt32 nVpId)
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return NULL;
  return pVpData->m_pLastEntity;
}
 
inline const OdGsEntityNode* OdGsContainerNode::lastEntityNode(OdUInt32 nVpId) const
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return NULL;
  return pVpData->m_pLastEntity;
}
 
inline OdList<OdGsLightNode*> &OdGsContainerNode::lightNodesList(OdUInt32 nVpId)
{
  return getVpData(nVpId)->m_lightPtrs;
}
 
inline const OdList<OdGsLightNode*> &OdGsContainerNode::lightNodesList(OdUInt32 nVpId) const
{
  return getVpData(nVpId)->m_lightPtrs;
}
 
inline bool OdGsContainerNode::childrenUpToDate(OdUInt32 nVpID) const
{
  if(m_vpAwareFlags.size()>nVpID)
    return !GETBIT(m_vpAwareFlags[nVpID], kChildrenNotUpToDate);
  return false;
}
 
inline void OdGsContainerNode::setChildrenUpToDate(bool bValid, OdUInt32* nVpID)
{
  if(nVpID)
  {
    OdUInt32Array::size_type n = m_vpAwareFlags.size();
    if(n <= *nVpID)
      m_vpAwareFlags.insert(m_vpAwareFlags.end(), (*nVpID)+1-n, 0xFFFFFFFF);
    SETBIT(m_vpAwareFlags[*nVpID], kChildrenNotUpToDate, !bValid);
  }
  else
  {
    ODA_ASSERT(!bValid);
    for(OdUInt32 i = 0; i < m_vpAwareFlags.size(); ++i)
      SETBIT(m_vpAwareFlags[i], kChildrenNotUpToDate, true);
  }
}
 
inline OdUInt32 OdGsContainerNode::awareFlags(OdUInt32 nVpID) const
{
  if(m_vpAwareFlags.size()>nVpID)
    return m_vpAwareFlags[nVpID] & ~kChildrenNotUpToDate;
  return 0xFFFFFFFF;
}
 
inline void OdGsContainerNode::setAwareFlags(OdUInt32 nVpID, OdUInt32 flags)
{
  flags &= ~kChildrenNotUpToDate;
  OdUInt32Array::size_type n = m_vpAwareFlags.size();
  if(n <= nVpID)
  {
    m_vpAwareFlags.insert(m_vpAwareFlags.end(), nVpID+1-n, 0xFFFFFFFF);
    m_vpAwareFlags[nVpID] = flags;
  }
  else
  {
    m_vpAwareFlags[nVpID] = ((m_vpAwareFlags[nVpID] & kChildrenNotUpToDate) | flags);
  }
}
 
inline bool OdGsContainerNode::needRegen(OdUInt32 nVpID) const
{
  if(!childrenUpToDate(nVpID))
    return true;
 
  OdUInt32 nAF = awareFlags(nVpID);
  return ( nAF == 0xFFFFFFFF || ( baseModel()->viewChanges(nVpID) & nAF) != 0 );
}
 
inline bool OdGsContainerNode::checkWorkset() const
{
  return GETBIT(m_flags, kCheckWorkset);
}
 
inline void OdGsContainerNode::setCheckWorkset(bool bVal)
{
  SETBIT(m_flags, kCheckWorkset, bVal);
}
 
inline bool OdGsContainerNode::childrenRegenDraw(OdUInt32 nVpID) const
{
  if(m_vpAwareFlags.size()>nVpID)
    return GETBIT(m_vpAwareFlags[nVpID], kEntityRegenDraw);
  return false;
}
 
inline void OdGsContainerNode::setChildrenRegenDraw(bool bVal, OdUInt32 nVpID)
{
  OdUInt32Array::size_type n = m_vpAwareFlags.size();
  if(n <= nVpID)
    m_vpAwareFlags.insert(m_vpAwareFlags.end(), nVpID+1-n, 0xFFFFFFFF);
  SETBIT(m_vpAwareFlags[nVpID], kEntityRegenDraw, bVal);
}
 
inline OdUInt32 OdGsContainerNode::maxLineWeightIndexUsed(OdUInt32 nVpId) const
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return 0;
  return pVpData->m_maxLw;
}
 
inline const OdGeExtents3d& OdGsContainerNode::realExtents(OdUInt32 nVpId) const
{
  VpData *pVpData = getVpData(nVpId, false);
  if (!pVpData)
    return OdGeExtents3d::kInvalid;
  return getVpData(nVpId)->m_realExtents;
}
 
inline void OdGsContainerNode::setRealExtents(OdUInt32 nVpId, const OdGeExtents3d& ext, OdUInt32 nMaxLw)
{
  VpData *pVpData = getVpData(nVpId);
  pVpData->m_realExtents = ext;
  pVpData->m_maxLw = nMaxLw;
}
 
inline void OdGsContainerNode::addViewRef(OdUInt32 nVpId)
{
  m_viewRefs.add(nVpId);
}
 
inline void OdGsContainerNode::removeViewRef(OdUInt32 nVpId)
{
  m_viewRefs.remove(nVpId);
}
 
inline const ViewRefs& OdGsContainerNode::viewRefs() const
{
  return m_viewRefs;
}
 
inline const StockProps& OdGsContainerNode::stock() const
{
  return m_stock;
}
 
inline int OdGsContainerNode::numberOfChildren(OdUInt32 nVpId) const
{
  return getVpData(nVpId)->m_nChild;
}
 
inline OdUInt32 OdGsContainerNode::numberOfChildrenST(OdUInt32 nVpId) const
{
  return getVpData(nVpId)->m_nChildSingleThreaded;
}
 
inline OdUInt32 OdGsContainerNode::numberOfChildrenErased(OdUInt32 nVpId) const
{
  return getVpData(nVpId)->m_nChildErased;
}
 
#include "TD_PackPop.h"
 
#endif // __OD_GS_CONTAINER_NODE__