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
/////////////////////////////////////////////////////////////////////////////// 
// 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
 
    <group OdGs_Classes> 
*/
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
 
    <group OdGs_Classes> 
*/
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 <OdGiContext::FadingType fadingType> 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 <OdGiContext::FadingType fadingType>
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_