opennurbs_object.h
1 /* $NoKeywords: $ */
2 /*
3 //
4 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
5 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
6 // McNeel & Associates.
7 //
8 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
9 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
10 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
11 //
12 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
13 //
14 ////////////////////////////////////////////////////////////////
15 */
16 
17 ////////////////////////////////////////////////////////////////
18 //
19 // virtual base class for all openNURBS objects
20 //
21 ////////////////////////////////////////////////////////////////
22 
23 #if !defined(OPENNURBS_OBJECT_INC_)
24 #define OPENNURBS_OBJECT_INC_
25 
26 
27 class ON_ClassId; // used for runtime class identification
28 
29 ////////////////////////////////////////////////////////////////
30 //
31 //
32 /*
33  Description:
34  OpenNURBS classes derived from ON_Object use ON_ClassId to
35  store run-time type information
36 
37  The ON_OBJECT_DECLARE and ON_OBJECT_IMPLEMENT macros generate
38  the code that creates and initializes the ON_ClassId for each
39  class.
40 
41  The ON_Object::IsKindOf() and ON_Object::Cast() functions
42  use this run-time type information.
43 */
44 class ON_CLASS ON_ClassId
45 {
46 public:
47 
48  // Description:
49  // This constructor is called to initialize each class id.
50  // The call is generated by the ON_OBJECT_IMPLEMENT macro.
51  //
52  // Parameters:
53  // sClassName - [in] name of the class (like ON_Geometry)
54  // sBaseClassName - [in] name of baseclass (like ON_Object)
55  // create - [in] function to create a new object(like CreateNewON_Geometry())
56  // sUUID - [in] UUID in registry format from Windows guidgen.exe
57  ON_ClassId(
58  const char* sClassName,
59  const char* sBaseClassName,
60  class ON_Object* (*create)(),
61  const char* sUUID
62  );
63 
64  ~ON_ClassId();
65 
66  // Description:
67  // Gets a class's ON_ClassId from the class's name.
68  // Parameters:
69  // sClassName - [in] name of class
70  // Returns:
71  // Pointer to the class's ON_ClassId.
72  // Example:
73  // const ON_ClassId* brep_id = ON_CLassId::ClassId("ON_Brep");
74  static const ON_ClassId* ClassId(
75  const char* sClassName
76  );
77 
78  // Description:
79  // Gets a class's ON_ClassId from the class's uuid.
80  // Parameters:
81  // class_uuid - [in] uuid for the class
82  // Returns:
83  // Pointer to the class's ON_ClassId.
84  // Example:
85  // ON_UUID brep_uuid = ON_UuidFromString("60B5DBC5-E660-11d3-BFE4-0010830122F0");
86  // const ON_ClassId* brep_id = ON_ClassId::ClassId(brep_uuid);
87  static const ON_ClassId* ClassId(
88  ON_UUID class_uuid
89  );
90 
91  // Description:
92  // Each class derived from ON_Object has a corresponding ON_ClassId
93  // stored in a linked list and the class is marked with an integer
94  // value. ON_ClassId::IncrementMark() increments the value used to
95  // mark new classes and returns the new marking value.
96  // Returns:
97  // Value that will be used to mark all future ON_ClassIds.
98  static int IncrementMark();
99  static int CurrentMark();
100  static const ON_ClassId* LastClassId();
101 
102  // Description:
103  // Each class derived from ON_Object has a corresponding
104  // ON_ClassId stored in a linked list. If a class definition
105  // is going to disappear (which happens when the derived object
106  // definition is in a DLL that uses openNURBS as a DLL and the
107  // DLL containing the derived object's definition is unloaded),
108  // then the class's ON_ClassId needs to be removed from the class
109  // list. ON_ClassId::Purge( mark ) removes all ON_ClassIds with a
110  // a prescribed mark and returns the number of classes that
111  // were purged.
112  // Parameters:
113  // mark - [in] All ON_ClassIds with this mark will be purged.
114  // Returns:
115  // Number of classes that were purged.
116  // Example:
117  // // Call ON_ClassId::IncrementMark() BEFORE loading MY.DLL.
118  // int my_dll_classid_mark = ON_ClassId::IncrementMark();
119  // load MY.DLL with classes derived from ON_Object
120  // ...
121  // // Call ON_ClassId::Purge() BEFORE unloading MY.DLL.
122  // ON_ClassId::Purge( my_dll_classid_mark );
123  // unload MY.DLL
124  static int Purge(int mark);
125  static bool PurgeAfter(const ON_ClassId* pClassId);
126 
127  // Description:
128  // Dumps the ON_ClassId list
129  // Parameters:
130  // dump - [in] destination for the text dump.
131  static void Dump(
132  ON_TextLog& dump
133  );
134 
135  // Returns:
136  // class name
137  const char* ClassName() const;
138 
139  // Returns:
140  // base class name
141  const char* BaseClassName() const;
142 
143  // Returns:
144  // base class id
145  const ON_ClassId* BaseClass() const;
146 
147  // Description:
148  // Determine if the class associated with this ON_ClassId
149  // is derived from another class.
150  // Parameters:
151  // potential_parent - [in] Class to test as parent.
152  // Returns:
153  // true if this is derived from potential_parent.
154  bool IsDerivedFrom(
155  const ON_ClassId* potential_parent
156  ) const;
157 
158  // Descrption:
159  // Use the default constructor to create an instance of the
160  // class on the heap.
161  // Returns:
162  // Null or a pointer to an instance of the class created
163  // using new and the class's default constructor.
164  ON_Object* Create() const;
165 
166  // Returns:
167  // class uuid
168  ON_UUID Uuid() const;
169 
170  /*
171  Description:
172  Opennurbs classes have a mark value of 0. Core Rhino
173  classes have a mark value of 1. Rhino plug-in classes
174  have a mark value of > 1.
175  Returns:
176  Class mark value
177  */
178  int Mark() const;
179 
180  unsigned int ClassIdVersion() const;
181 
182 private:
183  static ON_ClassId* m_p0; // first id in the linked list of class ids
184  static ON_ClassId* m_p1; // last id in the linked list of class ids
185  static int m_mark0; // current mark value
186  ON_ClassId* m_pNext; // next in the linked list of class ids
187  const ON_ClassId* m_pBaseClassId; // base class id
188  char m_sClassName[80];
189  char m_sBaseClassName[80];
190  // m_create points to a function that calls the default constuctor.
191  // m_create() is used to create classes from uuids when reading files.
192  ON_Object* (*m_create)();
193  ON_UUID m_uuid;
194  int m_mark; // bit 0x80000000 is used to indicate new extensions
195 
196 private:
197  // There are no implementaions of the default constructor, copy constructor
198  // or operator=() to prohibit use.
199  ON_ClassId();
200  ON_ClassId( const ON_ClassId&);
201  ON_ClassId& operator=( const ON_ClassId&);
202 
203 private:
204  void ConstructorHelper(
205  const char* sClassName,
206  const char* sBaseClassName,
207  const char* sUUID
208  );
209 
210  // The m_f[] pointers provide a way add a "virtual" function to
211  // a class derived from ON_Object without breaking the SDK.
212  // At each SDK breaking relase, any functions that use this
213  // mechanism are made into C++ virtual functions on the appropriate
214  // classes. Currently, none of these are in use.
215  unsigned int m_class_id_version;
216  void* m_f1;
217  void* m_f2;
218  void* m_f3;
219  void* m_f4;
220  void* m_f5;
221  void* m_f6;
222  void* m_f7;
223  void* m_f8;
224 };
225 
226 /*
227 Description:
228  ON_CLASS_RTTI is a macro to get the class's run-time type
229  information from class name.
230 Example:
231  // Get the ON_Brep class's run-time type information.
232  const ON_ClassId& brep_rtti = ON_CLASS_RTTI(ON_Brep);
233 */
234 #define ON_CLASS_RTTI( cls ) cls::m_##cls##_class_rtti
235 
236 /*
237 Description:
238  ON_CLASS_ID is a macro to get the class's uuid from
239  a class name.
240 Example:
241  // Get the class id for ON_Brep.
242  ON_UUID brep_class_id = ON_CLASS_ID(ON_Brep);
243 */
244 #define ON_CLASS_ID( cls ) ON_CLASS_RTTI( cls ).Uuid()
245 
246 /*
247 Description:
248  Expert user function to get the value of ON_ClassId::m_uuid
249  of the last instance of ON_ClassId to call ON_ClassId::Create().
250  This function was created to support Rhino's .NET SDK.
251  This function returns the value of a static id in
252  opennurbs_object.cpp and is NOT thread safe.
253 Returns:
254  Value of ON_ClassId::m_uuid of the instance of ON_ClassId that
255  most recently called ON_ClassId::Create().
256 */
257 ON_DECL
258 ON_UUID ON_GetMostRecentClassIdCreateUuid();
259 
260 
261 #define ON_OBJECT_DECLARE_VIRTUAL
262 #define ON_OBJECT_DECLARE_OVERRIDE override
263 
264 /*
265 All classes derived from ON_Object must have the declaration macro
266  ON_OBJECT_DECLARE( <classname> );
267 as the first line in their class definition, must have a robust
268 operator=(), should have a robust copy constructory, and must
269 have exactly one of the following implementation macros in
270 a .cpp file.
271  Classes with a pure virtual function:
272  ON_VIRTUAL_OBJECT_IMPLEMENT( <classname>, <basclassname>, <classuuid> )
273  Classes with an operator= and copy constructor.
274  ON_OBJECT_IMPLEMENT( <classname>, <basclassname>, <classuuid> )
275  Classes with an operator=, but no copy constructor.
276  ON_OBJECT_IMPLEMENT_NO_COPYCTOR( <classname>, <basclassname>, <classuuid> )
277 */
278 #define ON_OBJECT_DECLARE( cls ) \
279  protected: \
280  static void* m_s_##cls##_ptr; \
281  \
282  public: \
283  /* OpenNURBS class run-time type information */ \
284  static const ON_ClassId m_##cls##_class_rtti; \
285  \
286  /*OpenNURBS platfrom independent dynamic cast*/ \
287  static cls * Cast( ON_Object* ); \
288  \
289  /*OpenNURBS platfrom independent dynamic cast*/ \
290  static const cls * Cast( const ON_Object* ); \
291  \
292  /*Returns: OpenNURBS run-time type information.*/ \
293  ON_OBJECT_DECLARE_VIRTUAL const ON_ClassId* ClassId() const ON_OBJECT_DECLARE_OVERRIDE; \
294  \
295  public: \
296  /*Description: */ \
297  /* Uses a virtual function to create a deep copy. */ \
298  /*Returns: */ \
299  /* null or a deep copy with type this->ClassId(). */ \
300  /*See Also: */ \
301  /* ON_Curve::DuplicateCurve() */ \
302  /* ON_Surface::DuplicateSurface() */ \
303  /* CRhinoObject::DuplicateRhinoObject() */ \
304  cls * Duplicate() const; \
305  \
306  /*Description: */ \
307  /* Uses operator= to copy src to this. */ \
308  /*Returns: */ \
309  /* True if successful. */ \
310  /* False if src is null or an incompatible type. */ \
311  ON_OBJECT_DECLARE_VIRTUAL bool CopyFrom(const ON_Object*) ON_OBJECT_DECLARE_OVERRIDE; \
312  \
313  private: \
314  /* Duplicate() uses this virtual helper function. */ \
315  ON_OBJECT_DECLARE_VIRTUAL ON_Object* Internal_DeepCopy() const ON_OBJECT_DECLARE_OVERRIDE \
316 
317 
318 /*
319 Classes derived from ON_Object that are pure virtual classes,
320 or do not have a valid default constructor, valid operator new
321 or valid operator= must use ON_VIRTUAL_OBJECT_IMPLEMENT in their
322 implementation. Classes implemented with ON_VIRTUAL_OBJECT_IMPLEMENT
323 cannot be serialized using ON_BinaryArchive::ReadObject()/WriteObject()
324 or duplicated using ON_Object::Duplicate().
325 The Cast() and ClassId() members work on classes implemented with
326 ON_VIRTUAL_OBJECT_IMPLEMENT, ON_OBJECT_IMPLEMENT or
327 ON_OBJECT_IMPLEMENT_NO_COPYCTOR
328 */
329 #define ON_VIRTUAL_OBJECT_IMPLEMENT( cls, basecls, uuid ) \
330  void* cls::m_s_##cls##_ptr = nullptr; \
331  const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,0,uuid);\
332  cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
333  const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
334  const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
335  bool cls::CopyFrom(const ON_Object*) {return false;} \
336  cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
337  ON_Object* cls::Internal_DeepCopy() const {return nullptr;}
338 
339 /*
340 Classes derived from ON_Object that have a valid default constructor,
341 valid copy constructor, operator new and operator= can use
342 ON_OBJECT_IMPLEMENT in their implementation. Classes implemented
343 with ON_OBJECT_IMPLEMENT can be created from their run-time type
344 information id and their Duplicate() function will use the class's
345 copy constructor to create a deep copy.
346 */
347 #define ON_OBJECT_IMPLEMENT( cls, basecls, uuid ) \
348  void* cls::m_s_##cls##_ptr = nullptr; \
349  static ON_Object* CreateNew##cls() {return new cls();} \
350  const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
351  cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
352  const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
353  const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
354  bool cls::CopyFrom( const ON_Object* src){const cls * s=cls::Cast(src); if ( nullptr != this && nullptr != s) {*this = *s; return true;}return false;} \
355  cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
356  ON_Object* cls::Internal_DeepCopy() const {return new cls (*this);}
357 
358 /*
359 Classes derived from ON_Object that have a valid default constructor,
360 operator new and operator=, but do not have a valid copy constructor,
361 can use ON_OBJECT_IMPLEMENT_NO_COPYCTOR in their implementation.
362 Classes implemented with ON_OBJECT_IMPLEMENT_NO_COPYCTOR can be created
363 from their run-time type information id and their Duplicate() function
364 will use the class's default constructor and operator= to create a
365 deep copy.
366 */
367 #define ON_OBJECT_IMPLEMENT_NO_COPYCTOR( cls, basecls, uuid ) \
368  void* cls::m_s_##cls##_ptr = nullptr; \
369  static ON_Object* CreateNew##cls() {return new cls();} \
370  const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
371  cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
372  const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
373  const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
374  bool cls::CopyFrom( const ON_Object* src){const cls* s=cls::Cast(src); if ( 0 != this && 0 != s) {*this = *s; return true;}return false;} \
375  cls * cls::Duplicate() const {return static_cast< cls *>(this->Internal_DeepCopy());} \
376  ON_Object* cls::Internal_DeepCopy() const { cls* p = new cls();if (p) {*p = *this; return p;}return nullptr;}
377 
378 /*
379 Classes derived from ON_Object that have a valid default constructor,
380 operator new and operator=, but do not have a valid copy constructor or assignment operator,
381 can use ON_OBJECT_IMPLEMENT_NO_COPY in their implementation.
382 Classes implemented with ON_OBJECT_IMPLEMENT_NO_COPY can be created
383 from their run-time type information id and their Duplicate() function
384 will silently return a nullptr. CopyFrom will return false.
385 */
386 #define ON_OBJECT_IMPLEMENT_NO_COPY( cls, basecls, uuid ) \
387  void* cls::m_s_##cls##_ptr = nullptr; \
388  static ON_Object* CreateNew##cls() {return new cls();} \
389  const ON_ClassId cls::m_##cls##_class_rtti(#cls,#basecls,CreateNew##cls,uuid);\
390  cls * cls::Cast( ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast< cls *>(p):nullptr;} \
391  const cls * cls::Cast( const ON_Object* p) {return(p&&p->IsKindOf(&cls::m_##cls##_class_rtti))?static_cast<const cls *>(p):nullptr;} \
392  const ON_ClassId* cls::ClassId() const {return &cls::m_##cls##_class_rtti;} \
393  bool cls::CopyFrom( const ON_Object* src){return false;} \
394  cls * cls::Duplicate() const {return nullptr;} \
395  ON_Object* cls::Internal_DeepCopy() const { return nullptr;}
396 
397 #define ON__SET__THIS__PTR(ptr) if (ptr) *((void**)this) = ptr
398 
399 class ON_CLASS ON_UserString
400 {
401 public:
402  ON_UserString();
403  ~ON_UserString();
404  ON_wString m_key;
405  ON_wString m_string_value;
406 
407  void Dump(ON_TextLog& text_log) const;
408  bool Write(ON_BinaryArchive&) const;
409  bool Read(ON_BinaryArchive&);
410 };
411 
412 #if defined(ON_DLL_TEMPLATE)
413 ON_DLL_TEMPLATE template class ON_CLASS ON_ClassArray<ON_UserString>;
414 #endif
415 
416 /*
417 Description:
418  When ON_Object::IsValid() fails and returns false, ON_IsNotValid()
419  is called. This way, a developer can put a breakpoint in
420  ON_IsNotValid() and stop execution at the exact place IsValid()
421  fails.
422 Returns:
423  false;
424 */
425 ON_DECL
426 bool ON_IsNotValid();
427 
428 ////////////////////////////////////////////////////////////////
429 
430 // Description:
431 // Pure virtual base class for all classes that must provide
432 // runtime class id or support object level 3DM serialization
433 class ON_CLASS ON_Object
434 {
435 #undef ON_OBJECT_DECLARE_VIRTUAL
436 #undef ON_OBJECT_DECLARE_OVERRIDE
437 #define ON_OBJECT_DECLARE_VIRTUAL virtual
438 #define ON_OBJECT_DECLARE_OVERRIDE
439  // This is the base class
440  ON_OBJECT_DECLARE(ON_Object);
441  // Every other use of ON_OBJECT_DECLARE() is in derived class
442 #undef ON_OBJECT_DECLARE_VIRTUAL
443 #undef ON_OBJECT_DECLARE_OVERRIDE
444 #define ON_OBJECT_DECLARE_VIRTUAL
445 #define ON_OBJECT_DECLARE_OVERRIDE override
446 
447 public:
448  ON_Object() ON_NOEXCEPT;
449  virtual ~ON_Object();
450  ON_Object( const ON_Object& );
451  ON_Object& operator=( const ON_Object& );
452 
453 #if defined(ON_HAS_RVALUEREF)
454  // rvalue copy constructor
455  ON_Object( ON_Object&& ) ON_NOEXCEPT;
456 
457  // The rvalue assignment operator calls this->PurgeUserData()
458  // which calls unknown destructors that could throw exceptions.
459  ON_Object& operator=( ON_Object&& );
460 #endif
461 
462 public:
463 
464 
465 
466 
467  /*
468  Description:
469  Sets m_user_data_list = 0.
470  */
471  void EmergencyDestroy();
472 
473  /*
474  Description:
475  The MemoryRelocate() function is called when an
476  object's location in memory is changed. For
477  example, if an object resides in a chunk of
478  memory that is grown by calling a realloc
479  that has to allocate a new chunk and
480  copy the contents of the old chunk to the
481  new chunk, then the location of the object's
482  memory changes. In practice this happens when
483  classes derived from ON_Object are stored
484  in dynamic arrays, like the default implementation
485  of ON_ObjectArray<>'s that use realloc to grow
486  the dynamic array.
487  */
488  virtual
489  void MemoryRelocate();
490 
491  /*
492  Description:
493  Low level tool to test if an object is derived
494  from a specified class.
495  Parameters:
496  pClassId - [in] use classname::ClassId()
497  Returns:
498  true if the instantiated object is derived from the
499  class whose id is passed as the argument.
500  Example:
501 
502  ON_Object* p = ....;
503  if ( p->IsKindOf( ON_NurbsCurve::ClassId() ) )
504  {
505  it's a NURBS curve
506  }
507 
508  Remarks:
509  The primary reason for IsKindOf() is to support the
510  static Cast() members declared in the ON_OBJECT_DECLARE
511  macro. If we determine that dynamic_cast is properly
512  supported and implemented by all supported compilers,
513  then IsKindOf() may dissappear. If an application needs
514  to determine if a pointer points to a class derived from
515  ON_SomeClassName, then call
516  ON_SomeClassName::Cast(mystery pointer) and check for
517  a non-null return.
518  */
519  bool IsKindOf(
520  const ON_ClassId* pClassId
521  ) const;
522 
523  /*
524  Description:
525  Tests an object to see if its data members are correctly
526  initialized.
527  Parameters:
528  text_log - [in] if the object is not valid and text_log
529  is not nullptr, then a brief englis description of the
530  reason the object is not valid is appened to the log.
531  The information appended to text_log is suitable for
532  low-level debugging purposes by programmers and is
533  not intended to be useful as a high level user
534  interface tool.
535  Returns:
536  @untitled table
537  true object is valid
538  false object is invalid, uninitialized, etc.
539  */
540  virtual bool IsValid( class ON_TextLog* text_log = nullptr ) const;
541 
542  /*
543  Description:
544  Creates a text dump of the object.
545  Remarks:
546  Dump() is intended for debugging and is not suitable
547  for creating high quality text descriptions of an
548  object.
549 
550  The default implementations of this virtual function
551  prints the class's name.
552  */
553  virtual
554  void Dump( ON_TextLog& ) const;
555 
556  /*
557  Returns:
558  An estimate of the amount of memory the class uses in bytes.
559  */
560  virtual
561  unsigned int SizeOf() const;
562 
563  /*
564  Description:
565  Returns a CRC calculated from the information that defines
566  the object. This CRC can be used as a quick way to see
567  if two objects are not identical.
568  Parameters:
569  current_remainder - [in];
570  Returns:
571  CRC of the information the defines the object.
572  */
573  virtual
574  ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
575 
576  /*
577  Description:
578  Low level archive writing tool used by ON_BinaryArchive::WriteObject().
579  Parameters:
580  binary_archive - archive to write to
581  Returns:
582  Returns true if the write is successful.
583  Remarks:
584  Use ON_BinaryArchive::WriteObject() to write objects.
585  This Write() function should just write the specific definition of
586  this object. It should not write and any chunk typecode or length
587  information.
588 
589  The default implementation of this virtual function returns
590  false and does nothing.
591  */
592  virtual
593  bool Write(
594  ON_BinaryArchive& binary_archive
595  ) const;
596 
597  /*
598  Description:
599  Low level archive writing tool used by ON_BinaryArchive::ReadObject().
600  Parameters:
601  binary_archive - archive to read from
602  Returns:
603  Returns true if the read is successful.
604  Remarks:
605  Use ON_BinaryArchive::ReadObject() to read objects.
606  This Read() function should read the objects definition back into
607  its data members.
608 
609  The default implementation of this virtual function returns
610  false and does nothing.
611  */
612  virtual
613  bool Read(
614  ON_BinaryArchive& binary_archive
615  );
616 
617  /*
618  Description:
619  Useful for switch statements that need to differentiate
620  between basic object types like points, curves, surfaces,
621  and so on.
622 
623  Returns:
624  ON::object_type enum value.
625 
626  Remarks:
627  The default implementation of this virtual function returns
628  ON::unknown_object_type
629  */
630  virtual
631  ON::object_type ObjectType() const;
632 
633 
634 
635  /*
636  Description:
637  All objects in an opennurbs model have an id
638  ( ON_Layer.m_layer_id, ON_Font.m_font_id,
639  ON_Material.m_material_id, ON_3dmObjectAttributes.m_uuid
640  ).
641  Returns:
642  The id used to identify the object in the openurbs model.
643  */
644  virtual
645  ON_UUID ModelObjectId() const;
646 
647  //////////////////////////////////////////////////////////////////
648  //
649  // BEGIN: User string support
650  //
651 
652  /*
653  Description:
654  Attach a user string to the object. This information will
655  perisist through copy construction, operator=, and file IO.
656  Parameters:
657  key - [in] id used to retrieve this string.
658  string_value - [in]
659  If nullptr, the string with this id will be removed.
660  Returns:
661  True if successful.
662  */
663  bool SetUserString(
664  const wchar_t* key,
665  const wchar_t* string_value
666  );
667 
668  /*
669  Description:
670  Append entries to the user string list
671  Parameters:
672  count - [in]
673  number of element in us[] array
674  user_strings - [in]
675  entries to append.
676  bReplace - [in]
677  If bReplace is true, then existing entries with the same key are
678  updated with the new entry's value. If bReplace is false, then
679  existing entries are not updated.
680  Returns:
681  Number of entries added, deleted, or modified.
682  */
683  int SetUserStrings( int count, const ON_UserString* user_strings, bool bReplace );
684 
685  /*
686  Description:
687  Get user string from the object.
688  Parameters:
689  key - [in] id used to retrieve the string.
690  string_value - [out]
691  Returns:
692  True if a string with id was found.
693  */
694  bool GetUserString(
695  const wchar_t* key,
696  ON_wString& string_value
697  ) const;
698 
699  /*
700  Description:
701  Get a list of all user strings on the object.
702  Parameters:
703  user_strings - [out]
704  user strings are appended to this list.
705  Returns:
706  Number of elements appended to the user_strings list.
707  */
708  int GetUserStrings(
709  ON_ClassArray<ON_UserString>& user_strings
710  ) const;
711 
712  /*
713  Description:
714  Get a list of all user string keys on the object.
715  Parameters:
716  user_string_keys - [out]
717  user string keys are appended to this list.
718  Returns:
719  Number of elements appended to the user_strings list.
720  */
721  int GetUserStringKeys(
722  ON_ClassArray<ON_wString>& user_string_keys
723  ) const;
724 
725  /*
726  Returns:
727  Number of user strings on the object.
728  */
729  int UserStringCount() const;
730 
731  //
732  // END: User string support
733  //
734  //////////////////////////////////////////////////////////////////
735 
736  /////////////////////////////////////////////////////////////////
737  //
738  // User data provides a standard way for extra information to
739  // be attached to any class derived from ON_Object. The attached
740  // information can persist and be transformed. If you use user
741  // data, please carefully read all the comments from here to the
742  // end of the file.
743  //
744 
745  /*
746  Description:
747  Attach user data to an object.
748  Parameters:
749  pUserData - [in] user data to attach to object.
750  The ON_UserData pointer passed to AttachUserData()
751  must be created with new.
752  Returns:
753  If true is returned, then ON_Object will delete the user
754  data when appropriate. If false is returned, then data
755  could not be attached and caller must delete.
756  Remarks:
757  AttachUserData() will fail if the user data's m_userdata_uuid
758  field is nil or not unique.
759  */
760  bool AttachUserData(
761  class ON_UserData* pUserData
762  );
763 
764  /*
765  Description:
766  Remove user data from an object.
767  Parameters:
768  pUserData - [in] user data to attach to object.
769  The ON_UserData pointer passed to DetachUserData()
770  must have been previously attached using
771  AttachUserData().
772  Returns:
773  If true is returned, then the user data was
774  attached to this object and it was detached. If false
775  is returned, then the user data was not attached to this
776  object to begin with. In all cases, you can be assured
777  that the user data is no longer attached to "this".
778  Remarks:
779  Call delete pUserData if you want to destroy the user data.
780  */
781  bool DetachUserData(
782  class ON_UserData* pUserData
783  );
784 
785 
786  /*
787  Description:
788  Get a pointer to user data.
789  Parameters:
790  userdata_uuid - [in] value of the user data's
791  m_userdata_uuid field.
792  Remarks:
793  The returned user data is still attached to the object.
794  Deleting the returned user data will automatically remove
795  the user data from the object.
796  */
797  class ON_UserData* GetUserData(
798  const ON_UUID& userdata_uuid
799  ) const;
800 
801  /*
802  Description:
803  PurgeUserData() removes all user data from object.
804  Remarks:
805  Use delete GetUserData(...) to destroy a single piece
806  of user data.
807  */
808  void PurgeUserData();
809 
810  /*
811  Description:
812  User data is stored as a linked list of ON_UserData
813  classes. FirstUserData gets the first item in the
814  linked list. This is the most recent item attached
815  using AttachUserData().
816  Remark:
817  To iterate through all the user data on an object,
818  call FirstUserData() and then use ON_UserData::Next()
819  to traverse the list.
820  */
821  class ON_UserData* FirstUserData() const;
822 
823  /*
824  Description:
825  Objects derived from ON_Geometry must call
826  TransformUserData() in their Transform() member function.
827  Parameters:
828  xform - [in] transformation to apply to user data
829  */
830  void TransformUserData(
831  const class ON_Xform& xform
832  );
833 
834  /*
835  Description:
836  When a userdata item is copied or moved from a source object to
837  a destination object, the ON_Object::UserDataConflictResolution
838  enum values specify how conficts are resolved.
839  Remark:
840  A userdata item "conflict" occurs when both the destination
841  and source object have a user data item with the same
842  value of ON_UserData::m_userdata_uuid.
843  */
844  enum class UserDataConflictResolution : unsigned char
845  {
846  destination_object = 0, // use destination item
847  source_object = 1, // use source item
848  source_copycount_gt = 2, // use source item if source copycount > destination copy count
849  source_copycount_ge = 3, // use source item if source copycount >= destination copy count
850  destination_copycount_gt = 4, // use destination item if destination copycount > source copy count
851  destination_copycount_ge = 5, // use destination item if destination copycount >= source copy count
852  delete_item = 6 // delete item from the destination object
853  };
854 
855  /*
856  Description:
857  Expert user tool that copies user data items with positive values of
858  ON_UserData.m_userdata_copycount from source_object to "this.
859  Parameters:
860  source_object - [in]
861  source of user data to copy
862  source_userdata_item_id - [in]
863  If source_userdata_item_id is not nil, then only the user data item
864  with a matching ON_UserData.m_userdata_uuid value will be copied.
865  userdata_conflict_resolution - [in]
866  method to resolve userdata item conficts.
867  Remarks:
868  Generally speaking you don't need to use CopyUserData().
869  Simply rely on ON_Object::operator=() or the copy constructor
870  to do the right thing.
871  Returns:
872  Number of user data items that were copied.
873  */
874  unsigned int CopyUserData(
875  const ON_Object& source_object,
876  ON_UUID source_userdata_item_id,
877  ON_Object::UserDataConflictResolution userdata_conflict_resolution
878  );
879 
880  /*
881  Description:
882  Expert user tool that moves user data items from source_object to "this.
883  Parameters:
884  source_object - [in]
885  source of user data to copy
886  source_userdata_item_id - [in]
887  If source_userdata_item_id is not nil, then only the user data item
888  with a matching ON_UserData.m_userdata_uuid value will be moved.
889  userdata_conflict_resolution - [in]
890  method to resolve userdata item conficts.
891  bDeleteAllSourceItems - [in]
892  If bDeleteAllSourceItems is true, then any userdata items
893  that are not copied from source_object are deleted.
894  Remarks:
895  Generally speaking you don't need to use MoveUserData().
896  Simply rely on ON_Object::operator=() or the copy constructor
897  to do the right thing.
898  Returns:
899  Number of user data items that were moved.
900  */
901  unsigned int MoveUserData(
902  ON_Object& source_object,
903  ON_UUID source_userdata_item_id,
904  ON_Object::UserDataConflictResolution userdata_conflict_resolution,
905  bool bDeleteAllSourceItems
906  );
907 
908  /*
909  Description:
910  Calls CopyUserData(source_object,ON_Object::UserDataConflictResolution::source_object).
911  Parameters:
912  source_object - [in]
913  */
914  void CopyUserData(
915  const ON_Object& source_object
916  );
917 
918  /*
919  Description:
920  Calls MoveUserData(source_object,ON_Object::UserDataConflictResolution::source_object,true).
921  Parameters:
922  source_object - [in]
923  */
924  void MoveUserData(
925  ON_Object& source_object
926  );
927 
928  /*
929  Description:
930  Uses the destination_manifest to update references to other components.
931  This is typically done when a component's references came from a "source"
932  context and are being updated to the "destination" context. For example,
933  inserting one model into another when index, id, and name conflicts
934  need to be resolved at the time of insertion.
935  Parameters:
936  source_manifest - [in]
937  A manifest of the source context with indices and ids
938  corresponding to the current component references.
939  If this manifest is not available, pass ON_ComponentManifest::Empty.
940  destination_manifest - [in]
941  A manifest of the destination context with indices and ids
942  corresponding to the desired component references.
943  If this manifest is not available, pass ON_ComponentManifest::Empty.
944  manifest_map - [in]
945  A map from the source (current) referenced component index/id values
946  to the destination (desired) component index/id values.
947  Returns:
948  True if successful.
949  False indicates a referenced component was not found in the manifest
950  and the reference was changed to a default value.
951  Example:
952  If this object is an ON_Layer, the line pattern and render material references
953  are updated.
954  If this object is an ON_DimStyle, the text style reference is updated.
955  If this object is an ON_3dmObjectAttributes, the layer,
956  material, line pattern, and group references are updated.
957  */
958  virtual bool UpdateReferencedComponents(
959  const class ON_ComponentManifest& source_manifest,
960  const class ON_ComponentManifest& destination_manifest,
961  const class ON_ManifestMap& manifest_map
962  );
963 
964  /////////////////////////////////////////////////////////////////
965  //
966  // Component status interface
967  //
968  // Currently implemnented on ON_SubD and ON_Brep
969  //
970 
971  /*
972  Description:
973  Set all active level component states to ON_ComponentStatus::NoneSet.
974  Returns:
975  Number of components where a state setting chanaged.
976  */
977  unsigned int ClearAllComponentStates() const;
978 
979  /*
980  Description:
981  Clear the specified states on every component.
982  Parameters:
983  states_to_clear - [in]
984  States to clear.
985  Returns:
986  Number of components where a state setting chanaged.
987  */
988  virtual
989  unsigned int ClearComponentStates(
990  ON_ComponentStatus states_to_clear
991  ) const;
992 
993  /*
994  Parameters:
995  states_filter - [in]
996 
997  bAllEqualStates - [in]
998  If a state is set in states_filter, all active level components
999  with the same state set will be included in the
1000  components_with_set_states[] array.
1001 
1002  If bAllEqualStates is true, then ON_ComponentStatus::AllEqualStates()
1003  is used to test for inclusion.
1004 
1005  If bAllEqualStates is false, then ON_ComponentStatus::SomeEqualStates()
1006  is used to test for inclusion.
1007 
1008  components_with_set_states - [out]
1009  Returns:
1010  Number of returned components.
1011  */
1012  virtual
1013  unsigned int GetComponentsWithSetStates(
1014  ON_ComponentStatus states_filter,
1015  bool bAllEqualStates,
1017  ) const;
1018 
1019  /*
1020  Description:
1021  Set states on an individual component.
1022  Parameters:
1023  component_index - [in]
1024  The states will be set on this component.
1025  states_to_set - [in]
1026  If a state is set in the states_to_set parameter, the same
1027  state will be set on the component.
1028  Returns:
1029  0: no state settings changed on the component.
1030  1: some state setting changed on the component.
1031  */
1032  virtual
1033  unsigned int SetComponentStates(
1034  ON_COMPONENT_INDEX component_index,
1035  ON_ComponentStatus states_to_set
1036  ) const;
1037 
1038  /*
1039  Description:
1040  Clear states on an individual component.
1041  Parameters:
1042  component_index - [in]
1043  The states will be cleared on this component.
1044  states_to_clear - [in]
1045  If a state is set in the states_to_clear parameter, the same
1046  state will be cleared on the component.
1047  Returns:
1048  0: no state settings changed on the component.
1049  1: some state setting changed on the component.
1050  */
1051  virtual
1052  unsigned int ClearComponentStates(
1053  ON_COMPONENT_INDEX component_index,
1054  ON_ComponentStatus states_to_clear
1055  ) const;
1056 
1057  /*
1058  Description:
1059  Copy status settings to an individual component.
1060  Parameters:
1061  component_index - [in]
1062  The states will be copied to this component.
1063  status_to_copy - [in]
1064  Returns:
1065  0: no state settings changed on the component.
1066  1: some state setting changed on the component.
1067  */
1068  virtual
1069  unsigned int SetComponentStatus(
1070  ON_COMPONENT_INDEX component_index,
1071  ON_ComponentStatus status_to_copy
1072  ) const;
1073 
1074  /*
1075  Description:
1076  Call whenever a component status setting is modifed
1077  by directly changing it on a component in a way that
1078  will result in any saved information about the parent
1079  object's aggretate component status becoming invalid.
1080 
1081  Returns:
1082  Aggregate information about the object's component states.
1083  */
1084  virtual
1085  ON_AggregateComponentStatus AggregateComponentStatus() const;
1086 
1087  /*
1088  Description:
1089  Call whenever a component status setting is modifed
1090  by directly changing it on a component in a way that
1091  will result in any saved information about the parent
1092  object's aggretate component status becoming invalid.
1093 
1094  Remarks:
1095  The implementations of this function are nearly instant.
1096  and this function may be called as frequently as needed.
1097  The next time AggregateComponentStatus()
1098  is called the information used to return the value
1099  will be updated.
1100  */
1101  virtual
1102  void MarkAggregateComponentStatusAsNotCurrent() const;
1103 
1104  /*
1105  Description:
1106  Delete the portions of the object identified in ci_list[].
1107  Parameters:
1108  ci_list - [in]
1109  List of components to delete.
1110  ci_list_count - [in]
1111  Number of elements in the ci_list[] array.
1112  Returns:
1113  True: succesful
1114  False: failure - no changes.
1115  */
1116  virtual
1117  bool DeleteComponents(
1118  const ON_COMPONENT_INDEX* ci_list,
1119  size_t ci_count
1120  );
1121 
1122  /////////////////////////////////////////////////////////////////
1123  //
1124  // Expert interface
1125  //
1126 
1127  /*
1128  Description:
1129  Expert user function. If you are using openNURBS in its
1130  default configuration to read and write 3dm archives,
1131  you never need to call this function.
1132  Many objects employ lazy creation of (runtime) caches
1133  that save information to help speed geometric calculations.
1134  This function will destroy all runtime information.
1135  Parameters:
1136  bDelete - [in] if true, any cached information is properly
1137  deleted. If false, any cached information
1138  is simply discarded. This is useful when
1139  the cached information may be in alternate
1140  memory pools that are managed in nonstandard
1141  ways.
1142  */
1143  virtual void DestroyRuntimeCache( bool bDelete = true );
1144 
1145 private:
1146  class ON_UserData* m_userdata_list;
1147  class ON_UserData* TransferUserDataItem(
1148  const class ON_UserData* source_ud_copy_this,
1149  class ON_UserData* source_ud_move_this,
1150  bool bPerformConflictCheck,
1151  ON_Object::UserDataConflictResolution userdata_conflict_resolution
1152  );
1153 };
1154 
1155 #endif
1156 
ON_UUID is a 16 byte universally unique identifier.
Definition: opennurbs_uuid.h:32
ON_ManifestIdentificationMap is used to record a map from a source manifest to a destination manifest...
Definition: opennurbs_archive.h:1464
Definition: opennurbs_array.h:36
Definition: opennurbs_string.h:2020
UserDataConflictResolution
When a userdata item is copied or moved from a source object to a destination object, the ON_Object::UserDataConflictResolution enum values specify how conficts are resolved. Remark: A userdata item "conflict" occurs when both the destination and source object have a user data item with the same value of ON_UserData::m_userdata_uuid.
Definition: opennurbs_object.h:861
Definition: opennurbs_compstat.h:396
OpenNURBS classes derived from ON_Object use ON_ClassId to store run-time type information ...
Definition: opennurbs_object.h:43
Definition: opennurbs_xform.h:28
Definition: opennurbs_archive.h:478
Definition: opennurbs_compstat.h:88
Pure virtual base class for all classes that must provide runtime class id or support object level 3D...
Definition: opennurbs_object.h:460
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
Definition: opennurbs_userdata.h:20