opennurbs_extensions.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 #if !defined(OPENNURBS_EXTENSIONS_INC_)
19 #define OPENNURBS_EXTENSIONS_INC_
20 
21 /*
22 Description:
23  The ONX_ErrorCounter is useful for counting errors that occur in a section of code.
24 */
25 class ON_CLASS ONX_ErrorCounter
26 {
27 public:
28  ONX_ErrorCounter() = default;
29  ~ONX_ErrorCounter() = default;
30  ONX_ErrorCounter(const ONX_ErrorCounter&) = default;
31  ONX_ErrorCounter& operator=(const ONX_ErrorCounter&) = default;
32 
33  const ONX_ErrorCounter operator += (const ONX_ErrorCounter& rhs);
34  const ONX_ErrorCounter operator + (const ONX_ErrorCounter& rhs);
35 
36  static const ONX_ErrorCounter Zero;
37 
38  /*
39  Returns:
40  Number of failures.
41  */
42  unsigned int FailureCount() const;
43 
44  /*
45  Returns:
46  Number of errors.
47  */
48  unsigned int ErrorCount() const;
49 
50  /*
51  Returns:
52  Number of warnings.
53  */
54  unsigned int WarningCount() const;
55 
56  /*
57  Returns:
58  Number of failures, erros, and warnings.
59  */
60  unsigned int TotalCount() const;
61 
62  /*
63  Description:
64  Adds one to the failure count.
65  Returns:
66  Number of failures including this one.
67  */
68  unsigned int IncrementFailureCount();
69 
70  /*
71  Description:
72  Adds one to the error count.
73  Returns:
74  Number of errors including this one.
75  */
76  unsigned int IncrementErrorCount();
77 
78  /*
79  Description:
80  Adds one to the warning count.
81  Returns:
82  Number of warnings including this one.
83  */
84  unsigned int IncrementWarningCount();
85 
86  /*
87  Description:
88  Saves the current value of ON_GetErrorCount()
89  so future calls to ON_ERROR can be counted.
90  */
91  void ClearLibraryErrors();
92 
93  /*
94  Description:
95  Adds the number of calls to ON_ERROR since the last
96  call to ClearLibraryErrors(), AddLibraryErrors(),
97  ClearLibraryErrorsAndWarnings, or AddLibraryErrorsAndWarnings().
98  Returns:
99  The number of errors added.
100  */
101  unsigned int AddLibraryErrors();
102 
103  /*
104  Description:
105  Saves the current value of ON_GetWarningCount()
106  so future calls to ON_WARNING can be counted.
107  */
108  void ClearLibraryWarnings();
109 
110  /*
111  Description:
112  Adds the number of calls to ON_WARNING since the last
113  call to ClearLibraryWarnings(), AddLibraryWarnings(),
114  ClearLibraryErrorsAndWarnings(), or AddLibraryErrorsAndWarnings().
115  Returns:
116  The number of warnings added.
117  */
118  unsigned int AddLibraryWarnings();
119 
120  /*
121  Description:
122  Calls ClearLibraryErrors() and ClearLibraryWarnings().
123  */
124  void ClearLibraryErrorsAndWarnings();
125 
126  /*
127  Description:
128  Calls AddLibraryErrors() and AddLibraryWarnings().
129  Returns:
130  The number of errors and warnings added.
131  */
132  unsigned int AddLibraryErrorsAndWarnings();
133 
134  void Dump(ON_TextLog& text_log) const;
135 
136 private:
137  unsigned int m_failure_count = 0;
138  unsigned int m_error_count = 0;
139  unsigned int m_warning_count = 0;
140 
141  unsigned int m_state_bit_field = 0;
142  unsigned int m_opennurbs_library_error_count = 0;
143  unsigned int m_opennurbs_library_warning_count = 0;
144 };
145 
146 
147 /*
148 Description:
149  Used to store user data information in an ONX_Model.
150 */
151 class ON_CLASS ONX_Model_UserData
152 {
153 public:
154 #if defined(OPENNURBS_EXPORTS) || defined(OPENNURBS_IMPORTS)
155  // See comments at the top of opennurbs_extensions.cpp for details.
156 
157  // new/delete
158  void* operator new(size_t);
159  void operator delete(void*);
160 
161  // array new/delete
162  void* operator new[] (size_t);
163  void operator delete[] (void*);
164 
165  // in place new/delete
166  void* operator new(size_t,void*);
167  void operator delete(void*,void*);
168 #endif
170  ONX_Model_UserData() = default;
171  ~ONX_Model_UserData() = default;
172  ONX_Model_UserData(const ONX_Model_UserData&) = default;
173  ONX_Model_UserData& operator=(const ONX_Model_UserData&) = default;
174 
175  void Dump( ON_TextLog& ) const;
176 
177  ON_UUID m_uuid = ON_nil_uuid;
178  ON_3dmGoo m_goo;
179 
180 public:
181  // 3dm version = 1,2,3,4,5,50,60,...
182  unsigned int m_usertable_3dm_version = 0;
183 
184  // opennurbs_version = old yyyymmddn value or
185  // a value from ON_VersionNumberConstruct().
186  unsigned int m_usertable_opennurbs_version = 0;
187 };
188 
189 #if defined(ON_DLL_TEMPLATE)
190 ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ONX_Model_UserData*>;
191 #endif
192 
193 /*
194 Description:
195  Pedegodgical example of all the things in an OpenNURBS 3dm archive.
196  The openNURBS examples use ONX_Model to store the information
197  read from 3dm archives. Please study example_read.cpp for
198  details.
199 */
200 class ON_CLASS ONX_Model
201 {
202 #if defined(OPENNURBS_EXPORTS) || defined(OPENNURBS_IMPORTS)
203  // See comments at the top of opennurbs_extensions.cpp for details.
204 
205 public:
206 
207  // new/delete
208  void* operator new(size_t);
209  void operator delete(void*);
210 
211  // array new/delete
212  void* operator new[] (size_t);
213  void operator delete[] (void*);
214 
215  // in place new/delete
216  void* operator new(size_t,void*);
217  void operator delete(void*,void*);
218 #endif
219 
220 public:
221  ONX_Model();
222  virtual ~ONX_Model();
223 
224  void Reset();
225 
226 private:
227  // prohibit use of copy construction and operator=
228  ONX_Model(const ONX_Model&) = delete;
229  ONX_Model& operator=(const ONX_Model&) = delete;
230 
231 public:
232  /*
233  Description:
234  Reads an openNURBS archive and saves the information in this model
235  Parameters:
236  archive - [in]
237  archive to read from
238  table_filter - [in]
239  If table_filter is zero, then everything in the archive is read.
240  Otherwise the bits in table_filter identify what tables should
241  be read. The bits are defined by the
242  ON_BInaryArchive::table_type enum.
243  model_object_type_filter - [in]
244  If model_object_type_filter is not zero, then it is a bitfield filter
245  made by bitwise oring ON::object_type values to select which types of
246  objects will be read from the model object table.
247  error_log - [out]
248  any archive reading errors are logged here.
249  Returns:
250  true if archive is read with no error. False if errors occur.
251  Error details are logged in error_log. If crc errors are in
252  the archive, then ONX_Model::m_crc_error_count is set to the
253  number of crc errors.
254  Example:
255 
256  // for ASCII file names
257  const char* sFileName = ....;
258  FILE* fp = ON::OpenFile( sFileName, "rb");
259 
260  // for UNICODE file names
261  const wchar_t* wsFileName = ....;
262  FILE* fp = ON::OpenFile( wsFileName, L"rb");
263 
264  bool bModelRead = false;
265  bool bModelIsValid = false;
266 
267  ON_TextLog error_log;
268  ONX_Model model;
269 
270  if ( 0 != fp )
271  {
272  ON_BinaryFile archive( ON::archive_mode::read3dm, fp );
273  bModelRead = model.Read( archive, error_log );
274  ON::CloseFile( fp );
275  }
276 
277  if ( bModelRead )
278  {
279  bModelIsValid = model.Validate(error_log);
280  }
281 
282  See Also:
283  ONX_Model::IsValid
284  ONX_Model::Write
285  ONX_Model::m_crc_error_count
286  */
287  bool Read(
288  ON_BinaryArchive& archive,
289  unsigned int table_filter,
290  unsigned int model_object_type_filter,
291  ON_TextLog* error_log
292  );
293 
294  bool Read(
295  const char* filename,
296  unsigned int table_filter,
297  unsigned int model_object_type_filter,
298  ON_TextLog* error_log
299  );
300 
301  bool Read(
302  const wchar_t* filename,
303  unsigned int table_filter,
304  unsigned int model_object_type_filter,
305  ON_TextLog* error_log
306  );
307 
308  bool Read(
309  ON_BinaryArchive& archive,
310  ON_TextLog* error_log = nullptr
311  );
312 
313  bool Read(
314  const char* filename,
315  ON_TextLog* error_log = nullptr
316  );
317 
318  bool Read(
319  const wchar_t* filename,
320  ON_TextLog* error_log = nullptr
321  );
322 
323  /*
324  Description:
325  Reads everything up to the object table.
326 
327  Parameters:
328  archive - [in]
329  archive to read from
330  bManageComponents - [in]
331  true:
332  The ONX_Model destructor will delete the model components
333  created by this function.
334  false:
335  The caller must delete the ON_ModelComponent components after
336  the ONX_Model is destroyed.
337  table_filter - [in]
338  If table_filter is zero, then everything in the archive before
339  the model object table is read. Otherwise the bits in
340  table_filter identify what tables should be read. The bits
341  are defined by the ON_BInaryArchive::table_type enum.
342  error_log - [out] any archive reading errors are logged here.
343  pass nullptr if you don't want to log errors
344 
345  Returns:
346  If the input is valid and everything before the model object
347  table is successfully read, then true is returned. Otherwise
348  false is returned.
349 
350  Example:
351 
352  // for ASCII file names
353  const char* sFileName = ....;
354  FILE* fp = ON::OpenFile( sFileName, "rb");
355 
356  // for UNICODE file names
357  const wchar_t* wsFileName = ....;
358  FILE* fp = ON::OpenFile( wsFileName, L"rb");
359 
360  bool bModelRead = false;
361  bool bModelIsValid = false;
362 
363  ON_TextLog error_log;
364 
365  if ( 0 != fp )
366  {
367  ON_BinaryFile archive( ON::archive_mode::read3dm, fp );
368  ONX_Model model;
369 
370  // Read settings, layer information, and other tables
371  // with information that is referenced by model object
372  // attributes.
373  bModelRead = model.IncrementalReadBegin( archive, error_log );
374 
375  if ( bModelRead )
376  {
377  object_filter = ON::mesh_object // read meshes
378  | ON::curve_object // and curves
379  ;
380  for(;;)
381  {
382  // read the next model object
383  ON_ModelGeometryComponent* pModelObject = model.IncrementalReadModelObject(object_filter,0);
384  if ( 0 == pModelObject )
385  break;
386 
387  ... // work with this model object
388 
389  // done with this object.
390  pModelObject = 0;
391  model.m_object_table.Remove();
392  }
393  }
394  ON::CloseFile( fp );
395  }
396  See Also:
397  ONX_Model::IsValid
398  ONX_Model::Write
399  ONX_Model::m_crc_error_count
400  */
401  bool IncrementalReadBegin(
402  ON_BinaryArchive& archive,
403  bool bManageComponents,
404  unsigned int table_filter,
405  ON_TextLog* error_log
406  );
407 
408  /*
409  Description:
410  Reads the next item in the model geometry table.
411 
412  Parameters:
413  archive - [in]
414  bManageModelGeometryComponent - [in]
415  true:
416  The ONX_Model destructor will delete the ON_ModelGeometryComponent components
417  created by this function.
418  false:
419  The caller must delete the ON_ModelGeometryComponent components after
420  the ONX_Model is destroyed.
421  bManageGeometry - [in]
422  true:
423  The ON_ModelGeometryComponent destructor will delete the ON_Geometry
424  classes created by this function.
425  false:
426  The caller must delete the ON_Geometry classes after
427  the ONX_Model and ON_ModelGeometryComponent components are destroyed.
428  bManageAttributes - [in]
429  true:
430  The ON_ModelGeometryComponent destructor will delete the ON_3dmObjectAttributes
431  classes created by this function.
432  false:
433  The caller must delete the ON_3dmObjectAttributes classes after
434  the ONX_Model and ON_ModelGeometryComponent components are destroyed.
435  model_object_type_filter - [in]
436  If model_object_type_filter is not zero, then it is a bitfield filter
437  made by bitwise oring ON::object_type values to select which types of
438  objects will be read from the model object table.
439  model_geometry_reference - [out]
440  A reference to an ON_ModelGeometryComponent. This referenced ON_ModelGeometryComponent
441  component is also added to the ONX_Model.
442  Call ONX_Model.RemoveComponent() if you want to discard it before
443  continuing.
444  Returns:
445  True
446  Succesful. If model_geometry_reference.IsEmpty() is true,
447  then no more geometry objects are available and you should call
448  IncrementalReadFinish().
449  False
450  An error occured and reading should terminate.
451  Remarks:
452  You must call IncrementalReadBegin() before making any calls to
453  IncrementalReadModelObject().
454  */
455  bool IncrementalReadModelGeometry(
456  ON_BinaryArchive& archive,
457  bool bManageModelGeometryComponent,
458  bool bManageGeometry,
459  bool bManageAttributes,
460  unsigned int model_object_type_filter,
461  ON_ModelComponentReference& model_geometry_reference
462  );
463 
464  /*
465  Description:
466  Reads everything up to the object table.
467 
468  Parameters:
469  archive - [in]
470  archive to read from
471  bManageComponents - [in]
472  true:
473  The ONX_Model destructor will delete the model components
474  created by this function.
475  false:
476  The caller must delete the ON_ModelComponent components after
477  the ONX_Model is destroyed.
478  table_filter - [in]
479  If table_filter is zero, then everything in the archive before
480  the model object table is read. Otherwise the bits in
481  table_filter identify what tables should be read. The bits
482  are defined by the ON_BInaryArchive::table_type enum.
483  error_log - [out] any archive reading errors are logged here.
484  pass nullptr if you don't want to log errors
485 
486  Returns:
487  If the input is valid and everything before the model object
488  table is successfully read, then true is returned. Otherwise
489  false is returned.
490 
491  See Also:
492  ONX_Model::IsValid
493  ONX_Model::Write
494  ONX_Model::m_crc_error_count
495  */
496  bool IncrementalReadFinish(
497  ON_BinaryArchive& archive,
498  bool bManageComponents,
499  unsigned int table_filter,
500  ON_TextLog* error_log
501  );
502 
503  /*
504  Description:
505  Writes contents of this model to an openNURBS archive.
506 
507  Parameters:
508  filename - [in]
509 
510  version - [in]
511  Version of the openNURBS archive to write.
512  0 default value and suggested.
513  When 0 is passed in, the value of ON_BinaryArchive::CurrentArchiveVersion()
514  is used.
515  2, 3, 4, 50, 60, ...
516  If you pass in a value < ON_BinaryArchive::CurrentArchiveVersion(), then some
517  information in current data structures will not be saved in the 3dm archive.
518  Rhino 2.x can read version 2 files.
519  Rhino 3.x can read version 2 and 3 files.
520  Rhino 4.x can read version 2, 3, and 4 files.
521  Rhino 5.x can read version 2, 3, 4, 5, and 50 files.
522  Rhino 6.x can read version 2, 3, 4, 5, 50, and 60 files.
523 
524  error_log - [out]
525  any archive writing errors are logged here.
526 
527  Returns:
528  True if archive is written with no error.
529  False if errors occur.
530  Error details are logged in error_log.
531  */
532  bool Write(
533  const char* filename,
534  int version = 0,
535  ON_TextLog* error_log = nullptr
536  ) const;
537 
538  /*
539  Description:
540  Writes contents of this model to an openNURBS archive.
541 
542  Parameters:
543  filename - [in]
544 
545  version - [in]
546  Version of the openNURBS archive to write.
547  0 default value and suggested.
548  When 0 is passed in, the value of ON_BinaryArchive::CurrentArchiveVersion()
549  is used.
550  2, 3, 4, 50, 60, ...
551  If you pass in a value < ON_BinaryArchive::CurrentArchiveVersion(), then some
552  information in current data structures will not be saved in the 3dm archive.
553  Rhino 2.x can read version 2 files.
554  Rhino 3.x can read version 2 and 3 files.
555  Rhino 4.x can read version 2, 3, and 4 files.
556  Rhino 5.x can read version 2, 3, 4, 5, and 50 files.
557  Rhino 6.x can read version 2, 3, 4, 5, 50, and 60 files.
558 
559  error_log - [out]
560  any archive writing errors are logged here.
561 
562  Returns:
563  True if archive is written with no error.
564  False if errors occur.
565  Error details are logged in error_log.
566  */
567  bool Write(
568  const wchar_t* filename,
569  int version = 0,
570  ON_TextLog* error_log = nullptr
571  ) const;
572 
573  /*
574  Description:
575  Writes contents of this model to an openNURBS archive.
576 
577  Parameters:
578  archive - [in]
579  archive to write to
580  You must call archive.SetArchiveFullPath(...) i order for file references to work correctly.
581 
582  version - [in]
583  Version of the openNURBS archive to write.
584  0 default value and suggested.
585  When 0 is passed in, the value of ON_BinaryArchive::CurrentArchiveVersion()
586  is used.
587  2, 3, 4, 50, 60, ...
588  If you pass in a value < ON_BinaryArchive::CurrentArchiveVersion(), then some
589  information in current data structures will not be saved in the 3dm archive.
590  Rhino 2.x can read version 2 files.
591  Rhino 3.x can read version 2 and 3 files.
592  Rhino 4.x can read version 2, 3, and 4 files.
593  Rhino 5.x can read version 2, 3, 4, 5, and 50 files.
594  Rhino 6.x can read version 2, 3, 4, 5, 50, and 60 files.
595 
596  error_log - [out]
597  any archive writing errors are logged here.
598 
599  Returns:
600  True if archive is written with no error.
601  False if errors occur.
602  Error details are logged in error_log.
603 
604  Example:
605 
606  model = ...;
607  if ( model.IsValid( error_log ) )
608  {
609  const wchar_t* wsFileName = ....;
610  FILE* fp = ON::OpenFile( wsFileName, L"wb");
611 
612  bool ok = false;
613  if ( 0 != fp )
614  {
615  const char* sStartSectionComment = "...";
616  int version = 5; // 2, 3, 4 or 5 are valid
617  ON_BinaryFile archive( ON::archive_mode::write3dm, fp );
618  archive.SetArchiveFullPath(wsFileName);
619  ok = model.write( archive,
620  version,
621  sStartSectionComment,
622  error_log );
623  ON::CloseFile( fp );
624  }
625  }
626 
627  */
628  bool Write(
629  ON_BinaryArchive& archive,
630  int version = 0,
631  ON_TextLog* error_log = nullptr
632  ) const;
633 
634  /////////////////////////////////////////////////////////////////////
635  //
636  // BEGIN model definitions
637  //
638 
639  // 3dm archive start section information
640  int m_3dm_file_version = 0;
641  unsigned int m_3dm_opennurbs_version = 0;
642  ON__UINT64 m_3dm_file_byte_count = 0;
643 
645 
646  // Properties include revision history, notes, information about
647  // the applicaton that created the file, and an optional preview image.
649 
650  // Settings include tolerance, and unit system, and defaults used
651  // for creating views and objects.
653 
654  /*
655  Description:
656  A manifest of every model component in this ONX_Model.
657  Remarks:
658  Use the manifest to find model objects from a name, id or index.
659 
660  The manifest Id, Name, and Index values are values used in
661  the model. These are assigned when a component is added to the ONX_Model.
662  When possible the id and name are not changed.
663 
664  The manifest=model and original component values are different when:
665  - The original component Id or Name was not set and a value was automatically
666  assigned.
667  - The original component Id or Name was not unique and was modified when the component
668  was added to the model.
669  - Generally the original component index differs from the manifest=model component
670  index.
671 
672  The OriginalToModelMap() can be used to convert original component index
673  and id to the manifest=model index and id.
674 
675  The ModelToOriginalMap() can be used to manifest=model index and id to
676  the original component index and id.
677  */
678  const ON_ComponentManifest& Manifest() const;
679 
680  /*
681  Returns:
682  A map from original component index and id to manifest=model index and id.
683  Remarks:
684  ON_ManifestMapItem Source = original component index and id.
685  ON_ManifestMapItem Destination = model-manifest index and id.
686  */
687  const ON_ManifestMap& OriginalToModelMap() const;
688 
689  /*
690  Returns:
691  A map from manifest=model index and id to original component index and id.
692  Remarks:
693  ON_ManifestMapItem Source = model-manifest index and id.
694  ON_ManifestMapItem Destination = original component index and id.
695  */
696  const ON_ManifestMap& ModelToOriginalMap() const;
697 
698  /*
699  Description:
700  This number changes every time the content of the ONX_Model is modified.
701  */
702  ON__UINT64 ModelContentVersionNumber() const;
703 
704  /*
705  Description:
706  Add an copy of a model_compoent to this model.
707  model_component - [in]
708  A copy of model_component is added to this model.
709  The index, id, and name of the copied component are
710  set the the model values (Manifest() "Manifest" index, name, and id).
711 
712  bResolveIdAndNameConflicts - [in]
713  If bResolveIdAndNameConflicts is false, then model_component.Id() must be non-nil
714  and not used in this model and model_component.Name() must be correctly set.
715  If bResolveIdAndNameConflicts is true, then id and name will be modified
716  as needed in the model and manifest.
717 
718  Returns:
719  A reference to the added model component.
720  If the reference is empty (ON_ModelComponent::IsEmpty() is true)
721  then the input was not valid.
722  */
723  ON_ModelComponentReference AddModelComponent(
724  const class ON_ModelComponent& model_component,
725  bool bResolveIdAndNameConflicts
726  );
727 
728  ON_ModelComponentReference AddModelComponent(
729  const class ON_ModelComponent& model_component
730  );
731 
732  ON_ModelComponentReference RemoveModelComponent(
733  ON_ModelComponent::Type component_type,
734  ON_UUID component_id
735  );
736 
737  /*
738  Description:
739  Easy way to add a layer to the model.
740  Returns:
741  If layer_name is valid, the layer's index (>=0) is returned. Otherwise,
742  ON_UNSET_INT_INDEX is returned.
743  */
744  int AddLayer(
745  const wchar_t* layer_name,
746  ON_Color layer_color
747  );
748 
749  /*
750  Description:
751  Easy way to add a default layer to the model.
752  Properties:
753  layer_name - [in]
754  can be nullptr or empty.
755  layer_color - [in]
756  can be ON_Color::UnsetColor
757  Returns:
758  The default layer's index (>=0) is returned.
759  */
760  int AddDefaultLayer(
761  const wchar_t* layer_name,
762  ON_Color layer_color
763  );
764 
765  /*
766  Description:
767  Easy way to add a default dimension style to the model.
768  Parameters:
769  dimension_style_name - [in]
770  can be nullptr or empty
771  length_unit_system - [in]
772  If ON::LengthUnitSystem::Unset, then settings length unit system is used.
773  tolerance - [in]
774  If not > 0, then settings tolerance is used.
775  Returns:
776  The default dimension style's index (>=0) is returned.
777  */
778  int AddDefaultDimensionStyle(
779  const wchar_t* dimension_style_name,
780  ON::LengthUnitSystem length_unit_system,
781  double model_tolerance
782  );
783 
784 
785 
786  /*
787  Description:
788  Add a managed model component (ON_Layer, ON_DimStyle, ...) to this model.
789 
790  managed_model_component - [in]
791  managed_model_component must be created by operator new and on the heap.
792  It will be deleted when the model and last ON_ModelComponentReference are
793  destroyed.
794 
795  bResolveIdAndNameConflicts - [in]
796  If bResolveIdAndNameConflicts is false, then model_component.Id() must be non-nil
797  and not used in this model and model_component.Name() must be correctly set.
798  If bResolveIdAndNameConflicts is true, then id and name will be modified
799  as needed in managed_model_component, the model, and the manifest.
800 
801  Returns:
802  A reference to the added model component.
803  If the reference is empty (ON_ModelComponent::IsEmpty() is true)
804  then the input was not valid.
805  */
806  ON_ModelComponentReference AddManagedModelComponent(
807  class ON_ModelComponent* managed_model_component,
808  bool bResolveIdAndNameConflicts
809  );
810 
811  ON_ModelComponentReference AddManagedModelComponent(
812  class ON_ModelComponent* managed_model_component
813  );
814 
815  /*
816  Description:
817  Add a model component to this model and control how the model_component instance
818  is managed.
819 
820  model_component - [in]
821  An ON_ModelComponent created on the heap by calling new X where X is
822  derived from ON_ModelComponent.
823 
824  bManagedComponent - [in]
825  If bManagedComponent is true, then ~ONX_Model will delete the component.
826  If bManagedComponent is false, then you are responsible for insuring
827  the component exists past the desctruction of this ONX_Model.
828 
829  bResolveIdAndNameConflicts - [in]
830  If bResolveIdAndNameConflicts is false, then model_component.Id() must be non-nil
831  and not used in this model and model_component.Name() must be correctly set.
832  If bResolveIdAndNameConflicts is true, then id and name will be modified
833  as needed.
834 
835  bUpdateComponentIdentification - [in]
836  The model_component Index(), Id(), and Name() values are set to match
837  the ones used in the model (Manifest() "Manifest" values.)
838 
839  Returns:
840  A reference to the added model component.
841  If the reference is empty (ON_ModelComponentReference::IsEmpty() is true),
842  then the input was not valid and the model component was not added.
843  */
844  ON_ModelComponentReference AddModelComponentForExperts(
845  class ON_ModelComponent* model_component,
846  bool bManagedComponent,
847  bool bResolveIdAndNameConflicts,
848  bool bUpdateComponentIdentification
849  );
850 
851  /*
852  Description:
853  Add an copy of the model_geometry and attrbutes to this model.
854 
855  Parameters:
856  geometry_object - [in]
857  geometry_object must point to a geometric object (curve, surface, brep, mesh, points, ...),
858  a render light, an annotation object, or a detail object.
859  A copy of geometry_object is added to and managed by this model.
860  attributes - [in]
861  nullptr if not available.
862  A copy of attributes is added to and managed by this model.
863 
864  bResolveIdAndNameConflicts - [in]
865  If bResolveIdAndNameConflicts is false, then attributes must be nullptr
866  or attributes->m_uid must be non-nil and not used in this model.
867  If bResolveIdAndNameConflicts is true, then id will be modified
868  as needed.
869 
870  Returns:
871  A reference to the added model component.
872  If the reference is empty (ON_ModelComponent::IsEmpty() is true)
873  then the input was not valid.
874  */
875  ON_ModelComponentReference AddModelGeometryComponent(
876  const class ON_Object* geometry_object,
877  const class ON_3dmObjectAttributes* attributes,
878  bool bResolveIdAndNameConflicts
879  );
880 
881  ON_ModelComponentReference AddModelGeometryComponent(
882  const class ON_Object* geometry_object,
883  const class ON_3dmObjectAttributes* attributes
884  );
885 
886  /*
887  Description:
888  Add an copy of the model_geometry and attrbutes to this model.
889 
890  Parameters:
891  managed_geometry_object - [in]
892  managed_geometry_object must point to an instance geometric object (curve, surface, brep, mesh, points, ...),
893  a render light, an annotation object, or a detail object created by operator new and on the heap.
894  It will be deleted when the this ONX_Model and the last ON_ModelComponentReference are destroyed.
895 
896  managed_attributes - [in]
897  managed_attributes should be nullptr or point to an instance created by operator new and on the heap.
898  It will be deleted when the this ONX_Model and the last ON_ModelComponentReference are destroyed.
899 
900  bResolveIdAndNameConflicts - [in]
901  If bResolveIdAndNameConflicts is false, then managed_attributes must be nullptr
902  or managed_attributes->m_uuid must be non-nil and not used in this model.
903  If bResolveIdAndNameConflicts is true, then id will be modified
904  as needed.
905 
906  Returns:
907  A reference to the added model component.
908  If the reference is empty (ON_ModelComponent::IsEmpty() is true)
909  then the input was not valid.
910  */
911  ON_ModelComponentReference AddManagedModelGeometryComponent(
912  class ON_Object* managed_geometry_object,
913  class ON_3dmObjectAttributes* managed_attributes,
914  bool bResolveIdAndNameConflicts
915  );
916 
917  ON_ModelComponentReference AddManagedModelGeometryComponent(
918  class ON_Object* managed_geometry_object,
919  class ON_3dmObjectAttributes* managed_attributes
920  );
921 
922  /*
923  Description:
924  Add geometry and attibutes to this model and control how the instances are managed.
925 
926  Parameters:
927  bManageGeometry - [in]
928  If true, geometry_object should point to an instance created by operator new and on the heap.
929  It will be deleted when the this ONX_Model and the last ON_ModelComponentReference are destroyed.
930  If false, the expert caller is carefully managing the instance and memory to insure
931  model_geometry is a valid instance while this ONX_Model and any ON_ModelComponentReference
932  are active.
933 
934  geometry_object - [in]
935  geometry_object should point to a geometric object (curve, surface, brep, mesh, points, ...),
936  a render light, an annotation object, or a detail object.
937 
938  bManageAttributes - [in]
939  If true, attributes should be nullptr or point to an instance created by operator new and on the heap.
940  It will be deleted when the this ONX_Model and the last ON_ModelComponentReference are destroyed.
941  If false, the expert caller is carefully managing the instance and memory to insure
942  attributes is a valid instance while this ONX_Model and and ON_ModelComponentReference
943  are active.
944 
945  attributes - [in]
946  nullptr if not avaiable.
947 
948  bResolveIdAndNameConflicts - [in]
949  If bResolveIdAndNameConflicts is false, then attributes must be nullptr
950  or attributes->m_uid must be non-nil and not used in this model.
951  If bResolveIdAndNameConflicts is true, then id will be modified
952  as needed.
953 
954  Returns:
955  A reference to the added model component.
956  If the reference is empty (ON_ModelComponent::IsEmpty() is true)
957  then the input was not valid.
958  */
959  ON_ModelComponentReference AddModelGeometryComponentForExperts(
960  bool bManageGeometry,
961  class ON_Object* geometry_object,
962  bool bManageAttributes,
963  class ON_3dmObjectAttributes* attributes,
964  bool bResolveIdAndNameConflicts
965  );
966 
967  unsigned int ComponentIndexLimit(
968  ON_ModelComponent::Type component_type
969  ) const;
970 
971  /*
972  Returns:
973  Number of active and deleted components.
974  Count does not include system components.
975  */
976  unsigned int ActiveAndDeletedComponentCount(
977  ON_ModelComponent::Type component_type
978  ) const;
979 
980  /*
981  Returns:
982  Number of active components.
983  Count does not include system components.
984  */
985  unsigned int ActiveComponentCount(
986  ON_ModelComponent::Type component_type
987  ) const;
988 
989  /*
990  Returns:
991  Number of deleted components.
992  */
993  unsigned int DeletedComponentCount(
994  ON_ModelComponent::Type component_type
995  ) const;
996 
997  ON_ModelComponentReference ComponentFromIndex(
998  ON_ModelComponent::Type component_type,
999  int component_model_index
1000  ) const;
1001 
1002  ON_ModelComponentReference ComponentFromUnsignedIndex(
1003  ON_ModelComponent::Type component_type,
1004  unsigned int component_model_index
1005  ) const;
1006 
1007  ON_ModelComponentReference ComponentFromId(
1008  ON_ModelComponent::Type component_type,
1009  ON_UUID component_model_id
1010  ) const;
1011 
1012  ON_ModelComponentReference ComponentFromName(
1013  ON_ModelComponent::Type component_type,
1014  ON_UUID component_parent_id,
1015  const wchar_t* component_model_name
1016  ) const;
1017 
1018  ON_ModelComponentReference ComponentFromNameHash(
1019  ON_ModelComponent::Type component_type,
1020  const ON_NameHash& component_model_name_hash
1021  ) const;
1022 
1023  /*
1024  Description:
1025  Get an image from its model index.
1026  Parameters:
1027  image_model_index - [in]
1028  Returns:
1029  An ON_ModelComponentReference to the image.
1030  Remarks:
1031  Model index and Manifest() manifest item index are the same.
1032  */
1033  ON_ModelComponentReference ImageFromIndex(
1034  int image_model_index
1035  ) const;
1036 
1037  ON_ModelComponentReference ImageFromId(
1038  ON_UUID image_id
1039  ) const;
1040 
1041  ON_ModelComponentReference ImageFromFileFullPath(
1042  const wchar_t* image_file_full_path_name
1043  ) const;
1044 
1045  ON_ModelComponentReference ImageFromFileContent(
1046  const ON_ContentHash& image_file_content_hash
1047  ) const;
1048 
1049  ON_ModelComponentReference ImageFromFileReference(
1050  const ON_FileReference& file_reference
1051  ) const;
1052 
1053  /*
1054  Description:
1055  Get a line pattern from its model index.
1056  Parameters:
1057  line_pattern_model_index - [in]
1058  Returns:
1059  An ON_ModelComponentReference to the line pattern.
1060  Remarks:
1061  Model index and Manifest() manifest item index are the same.
1062  */
1063  ON_ModelComponentReference LinePatternFromIndex(
1064  int line_pattern_model_index
1065  ) const;
1066 
1067  ON_ModelComponentReference LinePatternFromId(
1068  ON_UUID line_pattern_model_id
1069  ) const;
1070 
1071  ON_ModelComponentReference LinePatternFromName(
1072  const wchar_t* line_pattern_name
1073  ) const;
1074 
1075  ON_ModelComponentReference LinePatternFromNameHash(
1076  ON_NameHash line_pattern_model_name_hash
1077  ) const;
1078 
1079  /*
1080  Description:
1081  Get linetype from object attributes.
1082  Parameters:
1083  attributes - [in] object attributes.
1084  line_pattern - [out] linetype
1085  */
1086  ON_ModelComponentReference LinePatternFromAttributes(
1087  const ON_3dmObjectAttributes& attributes
1088  ) const;
1089 
1090  ON_ModelComponentReference LinePatternFromLayerIndex(
1091  int layer_index
1092  ) const;
1093 
1094  /*
1095  Description:
1096  Get render material from object attributes.
1097  Parameters:
1098  attributes - [in] object attributes.
1099  material - [out] render material
1100  */
1101  ON_ModelComponentReference RenderMaterialFromLayerIndex(
1102  int layer_index
1103  ) const;
1104 
1105  ON_ModelComponentReference RenderMaterialFromAttributes(
1106  const ON_3dmObjectAttributes& attributes
1107  ) const;
1108 
1109  ON_ModelComponentReference RenderMaterialFromIndex(
1110  int render_material_index
1111  ) const;
1112 
1113  ON_ModelComponentReference RenderMaterialFromId(
1114  ON_UUID render_material_id
1115  ) const;
1116 
1117  /*
1118  Description:
1119  Get a layer from its model index.
1120  Parameters:
1121  layer_model_index - [in]
1122  Returns:
1123  An ON_ModelComponentReference to the layer.
1124  Remarks:
1125  Model index and Manifest() manifest item index are the same.
1126  */
1127  ON_ModelComponentReference LayerFromIndex(
1128  int layer_model_index
1129  ) const;
1130 
1131  ON_ModelComponentReference LayerFromId(
1132  ON_UUID layer_model_id
1133  ) const;
1134 
1135  ON_ModelComponentReference LayerFromName(
1136  ON_UUID layer_parent_id,
1137  const wchar_t* layer_name
1138  ) const;
1139 
1140  ON_ModelComponentReference LayerFromNameHash(
1141  const ON_NameHash& layer_model_name_hash
1142  ) const;
1143 
1144  ON_ModelComponentReference LayerFromAttributes(
1145  const ON_3dmObjectAttributes& attributes
1146  ) const;
1147 
1148  /*
1149  Description:
1150  Get a dimension style from its model index.
1151  Parameters:
1152  dimension_style_model_index - [in]
1153  Returns:
1154  An ON_ModelComponentReference to the dimension style.
1155  Remarks:
1156  Model index and Manifest() manifest item index are the same.
1157  */
1158  ON_ModelComponentReference DimensionStyleFromIndex(
1159  int dimension_style_index
1160  ) const;
1161  ON_ModelComponentReference DimensionStyleFromId(
1162  ON_UUID dimension_styleid
1163  ) const;
1164  ON_ModelComponentReference DimensionStyleFromName(
1165  const wchar_t* dimension_style_name
1166  ) const;
1167  ON_ModelComponentReference DimensionStyleFromNameHash(
1168  ON_NameHash dimension_style_name_hash
1169  ) const;
1170 
1171  /*
1172  Returns:
1173  Id of the current dimension style or nil if the current style is
1174  not set or not in this model.
1175  */
1176  ON_UUID CurrentDimensionStyleId() const;
1177 
1178  /*
1179  Parameters:
1180  dimension_style_id - [in]
1181  Id of a dimension style in this model, a system dimension style, or ON_nil_uuid.
1182  Returns:
1183  true if dimension_style_id is valid and is set.
1184  */
1185  bool SetCurrentDimensionStyleId(
1186  ON_UUID dimension_style_id
1187  );
1188 
1189  /*
1190  Returns:
1191  Current dimension style
1192  = DimensionStyleFromId(CurrentDimensionStyleId())
1193  */
1194  ON_ModelComponentReference CurrentDimensionStyle() const;
1195 
1196 
1197  /*
1198  Returns:
1199  A system dimension style that is the default for this model
1200  and is used when a referenced dimension style is missing from
1201  this model.
1202  */
1203  ON_ModelComponentReference DefaultDimensionStyle() const;
1204 
1205  /*
1206  Parameters:
1207  font - [in]
1208  model_space_text_scale - [in]
1209  If model_space_text_scale > 0, then the DimScale() must be equal to model_space_text_scale.
1210  bIgnoreSystemDimStyles - [in]
1211  Returns:
1212  The first dimension style with the specified font.
1213  Remarks:
1214  dimension styles with a non-nil parent id are ignored.
1215  */
1216  ON_ModelComponentReference FirstDimensionStyleFromFont(
1217  const ON_Font* font,
1218  double model_space_text_scale,
1219  bool bIgnoreSystemDimStyles
1220  ) const;
1221 
1222  /*
1223  Parameters:
1224  managed_font_serial_number - [in]
1225  model_space_text_scale - [in]
1226  If model_space_text_scale > 0, then the DimScale() must be equal to model_space_text_scale.
1227  bIgnoreSystemDimStyles - [in]
1228  Returns:
1229  The first dimension style with the specified font.
1230  Remarks:
1231  dimension styles with a non-nil parent id are ignored.
1232  */
1233  ON_ModelComponentReference FirstDimensionStyleFromManagedFontSerialNumber(
1234  unsigned int managed_font_serial_number,
1235  double model_space_text_scale,
1236  bool bIgnoreSystemDimStyles
1237  ) const;
1238 
1239  /*
1240  Description:
1241  Find or create a dimension style with the specified font characteristics.
1242  */
1243  ON_ModelComponentReference DimensionStyleWithFontCharacteristics(
1244  const ON_Font& font_characteristics,
1245  double model_space_text_scale
1246  );
1247 
1248 
1249  ON_ModelGeometryComponent ModelGeometryFromIndex(
1250  int model_object_index
1251  );
1252  ON_ModelGeometryComponent ModelGeometryFromUnsignedIndex(
1253  unsigned int model_object_index
1254  );
1255  ON_ModelGeometryComponent ModelGeometryFromId(
1256  unsigned int model_object_index
1257  );
1258 
1259 public:
1260  ON_SimpleArray<ONX_Model_UserData*> m_userdata_table;
1261 
1262 private:
1268 
1269 private:
1270  ON_ModelComponentReference Internal_AddModelComponent(
1271  ON_ModelComponent* model_component,
1272  ON_UUID id,
1273  ON_UUID name_parent_id,
1274  const ON_wString& name,
1275  bool bManagedComponent,
1276  bool bUpdateComponentIdentification
1277  );
1279 private:
1280  // Content version is incremented every time the
1281  // contents of the ONX_Model are modified.
1282  ON__UINT64 m_model_content_version_number = 0;
1283 
1284 private:
1285  void Internal_IncrementModelContentVersionNumber();
1286 
1287 
1288 private:
1289  // A manifest of everything in the model. Use the manifest to find
1290  // objects from a name, id or index.
1291  ON_ComponentManifest m_manifest;
1292  ON_ManifestMap m_original_to_manifest_map;
1293  ON_ManifestMap m_manifest_to_original_map;
1294 
1295 private:
1296  friend class ONX_ModelComponentIterator;
1297  class ONX_ModelComponentReferenceLink* Internal_ModelComponentLinkFromSerialNumber(
1298  ON__UINT64 model_component_runtime_serial_number
1299  ) const;
1300  class ONX_ModelComponentReferenceLink* Internal_AddModelComponentReference(
1302  );
1303  void Internal_RemoveModelComponentReferenceLink(
1304  class ONX_ModelComponentReferenceLink* mcr_link
1305  );
1306  // A map used to lookup by serial number.
1307  ON_SerialNumberMap m_mcr_sn_map;
1308  ON_FixedSizePool m_mcr_link_fsp;
1309 #pragma ON_PRAGMA_WARNING_PUSH
1310 #pragma ON_PRAGMA_WARNING_DISABLE_MSC( 4251 )
1311  // C4251: ... needs to have dll-interface to be used by clients of class ...
1312  // This warning is not correct.
1313  // m_mcr_lists is private and all code that manages m_mcr_lists is explicitly implemented in the DLL.
1314  class ONX_ModelComponentList
1315  {
1316  public:
1318  unsigned int m_count = 0;
1319  class ONX_ModelComponentReferenceLink* m_first_mcr_link = nullptr;
1320  class ONX_ModelComponentReferenceLink* m_last_mcr_link = nullptr;
1321  };
1322  enum : unsigned int
1323  {
1324  ONX_MCR_LIST_COUNT = 16
1325  };
1326  ONX_ModelComponentList m_mcr_lists[ONX_MCR_LIST_COUNT];
1327  const ONX_ModelComponentList& Internal_ComponentListConst(ON_ModelComponent::Type component_type) const;
1328  ONX_ModelComponentList& Internal_ComponentList(ON_ModelComponent::Type component_type);
1329 #pragma ON_PRAGMA_WARNING_POP
1330 
1331 public:
1332  bool ValdateComponentIdAndName(
1333  ON_ModelComponent::Type component_type,
1334  const ON_UUID& candidate_id,
1335  const ON_UUID& component_parent_id,
1336  const wchar_t* candidate_name,
1337  bool bResolveIdConflict,
1338  bool bResolveNameConflict,
1339  ON_UUID& model_id,
1340  ON_wString& model_name
1341  ) const;
1342 
1343  //
1344  // END model definitions
1345  //
1346  /////////////////////////////////////////////////////////////////////
1347 
1348 public:
1349  /*
1350  Returns:
1351  Bounding box of every object in m_object_table[].
1352  */
1353  ON_BoundingBox ModelGeometryBoundingBox() const;
1354 
1355  /*
1356  Returns:
1357  Bounding box of every render light in m_light_table[].
1358  */
1359  ON_BoundingBox RenderLightBoundingBox() const;
1360 
1361 private:
1362  void Internal_ComponentTypeBoundingBox(
1363  const ON_ModelComponent::Type component_type,
1364  ON_BoundingBox& bbox
1365  ) const;
1366 
1367 public:
1368 
1369 
1370  /*
1371  Description:
1372  Get wireframe drawing color from object attributes.
1373  Parameters:
1374  attributes - [in] object attributes.
1375  Returns:
1376  Wireframe drawing color.
1377  */
1378  ON_Color WireframeColorFromAttributes(
1379  const ON_3dmObjectAttributes& attributes
1380  ) const;
1381 
1382  /*
1383  Description:
1384  See if the instance reference iref refers to an instance
1385  definition.
1386  Parameters:
1387  iref - [in]
1388  idef_uuid - [in] id of idef we are looking for
1389  Returns:
1390  @untitled table
1391  0 iref does not use idef
1392  1 iref directly references idef
1393  >1 iref has a nested reference to idef (nesting depth returned)
1394  -1 iref.m_instance_definition_uuid is not valid
1395  -2 invalid idef found
1396  */
1397  int UsesIDef(
1398  const ON_InstanceRef& iref,
1399  ON_UUID idef_uuid
1400  ) const;
1401 
1402  /////////////////////////////////////////////////////////////////////
1403  //
1404  // BEGIN model document level user string tools
1405  //
1406 
1407  /*
1408  Description:
1409  Attach a user string to the document.
1410  Parameters:
1411  key - [in] id used to retrieve this string.
1412  string_value - [in]
1413  If nullptr, the string with this id will be removed.
1414  Returns:
1415  True if successful.
1416  */
1417  bool SetDocumentUserString(
1418  const wchar_t* key,
1419  const wchar_t* string_value
1420  );
1421 
1422  /*
1423  Description:
1424  Get user string from the document.
1425  Parameters:
1426  key - [in] id used to retrieve the string.
1427  string_value - [out]
1428  Returns:
1429  True if a string with id was found.
1430  */
1431  bool GetDocumentUserString(
1432  const wchar_t* key,
1433  ON_wString& string_value
1434  ) const;
1435 
1436  /*
1437  Description:
1438  Get a list of all user strings in the document.
1439  Parameters:
1440  user_strings - [out]
1441  user strings are appended to this list.
1442  Returns:
1443  Number of elements appended to the user_strings list.
1444  */
1445  int GetDocumentUserStrings( ON_ClassArray<ON_UserString>& user_strings ) const;
1446 
1447  //
1448  // END model document level user string tools
1449  //
1450  /////////////////////////////////////////////////////////////////////
1451 
1452 
1453  /////////////////////////////////////////////////////////////////////
1454  //
1455  // BEGIN model text dump tools
1456  //
1457 
1458  // text dump of entire model
1459  void Dump( ON_TextLog& ) const;
1460 
1461  // text dump of model properties and settings
1462  void DumpSummary( ON_TextLog& ) const;
1463 
1464  // text dump of user data table
1465  void DumpUserDataTable( ON_TextLog& ) const;
1466 
1467  void DumpComponentList(
1468  ON_ModelComponent::Type component_type,
1469  ON_TextLog& text_log
1470  ) const;
1471 
1472  /*
1473  Returns:
1474  A text dump of all component lists.
1475  */
1476  void DumpComponentLists(
1477  ON_TextLog& text_log
1478  ) const;
1479 
1480  /*
1481  Returns:
1482  A SHA-1 hash of the model's content. If two models have identical content,
1483  then the have equal ContentHash() values.
1484  */
1485  ON_SHA1_Hash ContentHash() const;
1486 
1487 public:
1488 
1489 
1490 private:
1491  void Internal_DumpSummary(
1492  ON_TextLog& dump,
1493  bool bInvariantContentOnly
1494  ) const;
1495 
1496 public:
1498  //
1499  // END model text dump tools
1500  //
1501  /////////////////////////////////////////////////////////////////////
1502 
1503 
1504  /////////////////////////////////////////////////////////////////////
1505  //
1506  // BEGIN Render Development Toolkit (RDK) information
1507  //
1508  static bool IsRDKDocumentInformation(const ONX_Model_UserData& docud);
1509  static bool GetRDKDocumentInformation(const ONX_Model_UserData& docud,ON_wString& rdk_xml_document_data);
1510 
1511  static bool IsRDKObjectInformation(const ON_UserData& objectud);
1512  static bool GetRDKObjectInformation(const ON_Object& object,ON_wString& rdk_xml_object_data);
1513  //
1514  // END Render Development Toolkit (RDK) information
1515  //
1516  /////////////////////////////////////////////////////////////////////
1517 
1518 private:
1519  mutable ON_BoundingBox m_model_geometry_bbox = ON_BoundingBox::UnsetBoundingBox;
1520  mutable ON_BoundingBox m_render_light_bbox = ON_BoundingBox::UnsetBoundingBox;
1521  class ON_DocumentUserStringList* m_model_user_string_list = nullptr;
1522 };
1523 
1524 class ON_CLASS ONX_ModelComponentIterator
1525 {
1526 public:
1527  ONX_ModelComponentIterator() = default;
1528  ~ONX_ModelComponentIterator() = default;
1530  ONX_ModelComponentIterator& operator=(const ONX_ModelComponentIterator&) = default;
1531 
1533  const ONX_Model& model,
1534  ON_ModelComponent::Type component_type
1535  );
1536 
1537  const ONX_Model* Model() const;
1538 
1539  ON_ModelComponentReference FirstComponentReference();
1540  ON_ModelComponentReference LastComponentReference();
1541  ON_ModelComponentReference CurrentComponentReference() const;
1542  ON_ModelComponentReference NextComponentReference();
1543  ON_ModelComponentReference PreviousComponentReference();
1544 
1545  const ON_ModelComponent* FirstComponent();
1546  const ON_ModelComponent* LastComponent();
1547  const ON_ModelComponent* CurrentComponent() const;
1548  const ON_ModelComponent* NextComponent();
1549  const ON_ModelComponent* PreviousComponent();
1550 
1551  /*
1552  Returns:
1553  Number of active components in the current model.
1554  Remarks:
1555  If the model is modified during iteration, this value will changes.
1556  */
1557  unsigned int ActiveComponentCount() const;
1558 
1559 private:
1560  const class ONX_Model::ONX_ModelComponentList* Internal_List() const;
1561  void Internal_SetLink(const class ONX_ModelComponentReferenceLink* link) const;
1562  void Internal_SetLink(ON__UINT64 model_component_sn) const;
1563  void Internal_IncrementLink() const;
1564  void Internal_DecrementLink() const;
1565 
1567  const class ONX_Model* m_model = nullptr;
1568  mutable ON__UINT64 m_model_content_version = 0;
1569  mutable const class ONX_Model::ONX_ModelComponentList* m_list = nullptr;
1570  mutable const class ONX_ModelComponentReferenceLink* m_link = nullptr;
1571  mutable ON__UINT64 m_current_component_sn = 0;
1572  mutable ON__UINT64 m_next_component_sn = 0;
1573  mutable ON__UINT64 m_prev_component_sn = 0;
1574  mutable ON_ModelComponentReference m_current_component = ON_ModelComponentReference::Empty;
1575 };
1576 
1577 /*
1578 Description:
1579  Tests a string to see if it is valid as a name for a layer,
1580  object, material, linetype, instance definition, etc.
1581 Parameters:
1582  name - [in] string to test
1583 Returns:
1584  True if the string is a valid name.
1585 */
1586 ON_DECL
1587 bool ONX_IsValidName(
1588  const wchar_t* name
1589  );
1590 
1591 class ON_CLASS ONX_ModelTest
1592 {
1593 public:
1594  ONX_ModelTest() = default;
1595  ~ONX_ModelTest() = default;
1596  ONX_ModelTest(const ONX_ModelTest&) = default;
1597  ONX_ModelTest& operator=(const ONX_ModelTest&) = default;
1598 
1599  static const ONX_ModelTest Unset;
1600 
1601 public:
1602 
1603 #pragma region // XXRH_C_SHARED_ENUM // [ONX_ModelTest::Type] [Rhino.Geometry.Something.Type] [nested:byte]
1604  /// <summary>
1605  /// ONX_ModelTest::Type identifies the type of file reading test to perform.
1606  /// </summary>
1607  enum class Type : unsigned char
1608  {
1609  Unset = 0,
1610 
1611  ///<summary>
1612  /// Read the source 3dm file.
1613  ///</summary>
1614  Read = 1,
1615 
1616  ///<summary>
1617  /// Read the source 3dm file and write one or two temporary 3dm files. The original
1618  /// source file is not modified. If the 3dm version of the source file
1619  /// is < ON_BinaryArchive::CurrentArchiveVersion(), then two temporary 3dm
1620  /// files are written, the first with 3dm version = ON_BinaryArchive::CurrentArchiveVersion()-10
1621  /// and the second with 3dm version = ON_BinaryArchive::CurrentArchiveVersion().
1622  /// For example, if Rhino 6 is the current version of Rhino and a file written
1623  /// by Rhino 5 is read, then both a temporary Rhino 5 and a temporary Rhino 6 3dm
1624  /// file are written.
1625  ///</summary>
1626  ReadWrite = 2,
1627 
1628  ///<summary>
1629  /// Perform the ReadWrite test and read the temporary files.
1630  ///</summary>
1631  ReadWriteRead = 3,
1632 
1633  ///<summary>
1634  /// Perform the ReadWriteRead test. If one of the temporary files has the same 3dm version
1635  /// as the original source file, verify that the ONX_Models created by reading the original
1636  /// 3dm file and the temporary 3dm file with the same version have identical values
1637  /// of ONX_Model::ContentHash().
1638  ///</summary>
1639  ReadWriteReadCompare = 4
1640  };
1641 #pragma endregion
1642 
1643  static const char* TestTypeToString(ONX_ModelTest::Type test_type);
1644  static const wchar_t* TestTypeToWideString(ONX_ModelTest::Type test_type);
1645 
1646 #pragma region // XXRH_C_SHARED_ENUM // [ONX_ModelTest::Result] [Rhino.Geometry.Something.Result] [nested:byte]
1647  /// <summary>
1648  /// ONX_ModelTest::Result reports the result of a test.
1649  /// </summary>
1650  enum class Result : unsigned char
1651  {
1652  ///<summary>
1653  /// Test result is not set.
1654  ///</summary>
1655  Unset = 0,
1656 
1657  ///<summary>
1658  /// Test failed to complete.
1659  ///</summary>
1660  Fail = 1,
1661 
1662  ///<summary>
1663  /// Test was performed and completed, but at least one ON_ERROR occured.
1664  ///</summary>
1665  Errors = 2,
1666 
1667  ///<summary>
1668  /// Test was performed and completed, but at least one ON_WARNING occured.
1669  ///</summary>
1670  Warnings = 3,
1671 
1672 
1673  ///<summary>
1674  /// Test was performed and passed.
1675  ///</summary>
1676  Pass = 4,
1677 
1678  ///<summary>
1679  /// Test was not perfomed because the input did not satisfy prerequisites or an
1680  /// earlier test failed.
1681  /// For example, if a ONX_ModelReadTest::TestType::ReadWriteReadCompare
1682  /// test is requested and the source file is a Rhino 1 file, the compare
1683  /// test is skipped.
1684  /// For example, if a ONX_ModelReadTest::TestType::ReadWriteRead
1685  /// test is requested and the Write test failes, the second Read test is skipped.
1686  ///</summary>
1687  Skip = 5,
1688  };
1689 #pragma endregion
1690 
1691  static const char* ResultToString(ONX_ModelTest::Result result);
1692  static const wchar_t* ResultToWideString(ONX_ModelTest::Result result);
1693 
1694  static ONX_ModelTest::Result WorstResult(
1697  );
1698 
1699  /*
1700  Parameters:
1701  error_count - [in]
1702  no_errors_result - [in]
1703  result to return when 0 = error_count.TotalCount().
1704  */
1705  static ONX_ModelTest::Result ResultFromErrorCounter(
1706  ONX_ErrorCounter error_count,
1707  ONX_ModelTest::Result no_errors_result
1708  );
1709 
1710  /*
1711  Description:
1712  Test ONX_Model::Read() and ONX_Model::Write().
1713  Parameters:
1714  file_path - [in]
1715  file path
1716  test_type - [in]
1717  test to perform.
1718  bKeepModels - [in]
1719  If true, then the ONX_Models created by reading 3dm archives are saved
1720  so the can be examined after the tests complete.
1721  text_log - [in]
1722  If text_log is not nullptr, then a summary of the test is sent to text_log.
1723  Returns:
1724  True if every test passed with no warnings or errors.
1725  False if a test failed or warnings or errors occured.
1726  */
1727  bool ReadTest(
1728  const char* file_path,
1729  ONX_ModelTest::Type test_type,
1730  bool bKeepModels,
1731  ON_TextLog* text_log
1732  );
1733 
1734  /*
1735  Description:
1736  ONX_Model::ReadTest() can be used to test reading a specific file.
1737  Parameters:
1738  file_path - [in]
1739  file path
1740  test_type - [in]
1741  test to perform.
1742  bKeepModels - [in]
1743  If true, then the ONX_Models created by reading 3dm archives are saved
1744  so the can be examined after the tests complete.
1745  text_log - [in]
1746  If text_log is not nullptr, then a summary of the test is sent to text_log.
1747  Returns:
1748  True if every test passed with no warnings or errors.
1749  False if a test failed or warnings or errors occured.
1750  */
1751  bool ReadTest(
1752  const wchar_t* file_path,
1753  ONX_ModelTest::Type test_type,
1754  bool bKeepModels,
1755  ON_TextLog* text_log
1756  );
1757 
1758  /*
1759  Description:
1760  ONX_Model::ReadTest() can be used to test reading a specific file.
1761  Parameters:
1762  fp - [in]
1763  fp pointer to a file opened with ON_FileStream::Opent(...,"rb");
1764  test_type - [in]
1765  test to perform.
1766  bKeepModels - [in]
1767  If true, then the ONX_Models created by reading 3dm archives are saved
1768  so the can be examined after the tests complete.
1769  text_log - [in]
1770  If text_log is not nullptr, then a summary of the test is sent to text_log.
1771  Returns:
1772  True if every test passed with no warnings or errors.
1773  False if a test failed or warnings or errors occured.
1774  */
1775  bool ReadTest(
1776  FILE* fp,
1777  ONX_ModelTest::Type test_type,
1778  bool bKeepModels,
1779  ON_TextLog* text_log
1780  );
1781 
1782 
1783  /*
1784  Description:
1785  ONX_Model::Test() can be used to test reading a specific file.
1786  Parameters:
1787  file_path - [in]
1788  file path
1789  test_type - [in]
1790  test to perform.
1791  bKeepModels - [in]
1792  If true, then the ONX_Models created by reading 3dm archives are saved
1793  so the can be examined after the tests complete.
1794  text_log - [in]
1795  If text_log is not nullptr, then a summary of the test is sent to text_log.
1796  Returns:
1797  True if every test passed with no warnings or errors.
1798  False if a test failed or warnings or errors occured.
1799  */
1800  bool ReadTest(
1801  ON_BinaryArchive& archive,
1802  ONX_ModelTest::Type test_type,
1803  bool bKeepModels,
1804  ON_TextLog* text_log
1805  );
1806 
1807  /*
1808  Description:
1809  Prints test results.
1810  */
1811  void Dump(ON_TextLog& text_log) const;
1812 
1813 
1814  /*
1815  Description:
1816  Prints the model context to text_log.
1817  */
1818  static bool DumpModel(const ONX_Model* model, ON_TextLog& text_log);
1819 
1820  /*
1821  Description:
1822  Prints the source model context to text file next to the source file
1823  with the file _ONX_ModelText_original_<PLATFORM>.txt appended to the
1824  source file name.
1825  Remark:
1826  Call after test is completed.
1827  */
1828  bool DumpSourceModel() const;
1829 
1830  /*
1831  Description:
1832  Prints the source model context to text_log.
1833  Remark:
1834  Call after test is completed.
1835  */
1836  bool DumpSourceModel(const wchar_t* text_file_full_path) const;
1837 
1838  /*
1839  Description:
1840  Prints the source model context to text_log.
1841  Remark:
1842  Call after test is completed.
1843  */
1844  bool DumpSourceModel(ON_TextLog& text_log) const;
1845 
1846  /*
1847  Description:
1848  Prints the model obtained from the last read in the read-write-read test to
1849  with the file _ONX_ModelText_copy_<PLATFORM>.txt appended to the
1850  original source file name.
1851  Remark:
1852  Call after test is completed.
1853  */
1854  bool DumpReadWriteReadModel() const;
1855 
1856  /*
1857  Description:
1858  Prints the model obtained from the last read in the read-write-read test to
1859  with the file _ONX_ModelText_copy_<PLATFORM>.txt appended to a text file
1860  with the specified name.
1861  Remark:
1862  Call after test is completed.
1863  */
1864  bool DumpReadWriteReadModel(const wchar_t* text_file_full_path) const;
1865 
1866  /*
1867  Description:
1868  Prints the model obtained from the last read in the read-write-read test to
1869  with the file _ONX_ModelText_copy_<PLATFORM>.txt appended to the text_log.
1870  Remark:
1871  Call after test is completed.
1872  */
1873  bool DumpReadWriteReadModel(ON_TextLog& text_log) const;
1874 
1875 private:
1876  void Internal_BeginTest();
1877 
1878  void Internal_EndCurrentTest();
1879 
1880  void Internal_BeginNextTest(
1881  ONX_ModelTest::Type test_type
1882  );
1883 
1884 
1885  void Internal_ReadTest(
1886  ON_BinaryArchive& archive,
1887  ONX_ModelTest::Type test_type,
1888  bool bKeepModels,
1889  ON_TextLog* text_log
1890  );
1891 
1892  bool Internal_TallyTestResults();
1893 
1894 public:
1895 
1896  // Test that was performed.
1897  ONX_ModelTest::Type TestType() const;
1898 
1899  /*
1900  Returns:
1901  The name of the source 3dm file.
1902  */
1903  const ON_wString Source3dmFilePath() const;
1904 
1905  /*
1906  Returns:
1907  Version of the 3dm fie, 1,2,3,4,5,50,60,...
1908  */
1909  unsigned int Source3dmFileVersion() const;
1910 
1911  /*
1912  Returns:
1913  Worst result for any test that was attempted.
1914  */
1915  ONX_ModelTest::Result TestResult() const;
1916 
1917  /*
1918  Parameters:
1919  test_type - [in]
1920  Returns:
1921  Result of the test identified by the test_type parameter.
1922  */
1923  ONX_ModelTest::Result TestResult(
1924  ONX_ModelTest::Type test_type
1925  );
1926 
1927  static bool SkipCompare(
1928  unsigned int source_3dm_file_version
1929  );
1930 
1931  /*
1932  Returns:
1933  Total number of failures, errors, and warnings for all tests that
1934  were performed.
1935  */
1936  ONX_ErrorCounter ErrorCounter() const;
1937 
1938  /*
1939  Returns:
1940  Total number of failures, errors, and warnings for all tests that
1941  were performed.
1942  */
1943  ONX_ErrorCounter ErrorCounter(
1944  ONX_ModelTest::Type test_type
1945  ) const;
1946 
1947  const ON_SHA1_Hash SourceModelHash();
1948  const ON_SHA1_Hash ReadWriteReadModelHash();
1949 
1950  /*
1951  Returns:
1952  nullptr if the test was run with bKeepModels=false or the
1953  source archive could not be read.
1954  Otherwise, a pointer to the source model.
1955  */
1956  std::shared_ptr<ONX_Model> SourceModel() const;
1957 
1958  /*
1959  Returns:
1960  nullptr if the read write read test was not performed or was run with bKeepModels=false.
1961  Otherwise, a pointer to the result of the read write read test.
1962  */
1963  std::shared_ptr<ONX_Model> ReadWriteReadModel() const;
1964 
1965 
1966  private:
1968 
1969  ON_wString m_source_3dm_file_path;
1970 
1971  unsigned int m_model_3dm_file_version[3];
1972 
1973  unsigned int m_current_test_index = 0;
1974 
1976  ONX_ModelTest::Result m_test_results[7] = {};
1977 
1978  ONX_ErrorCounter m_error_count;
1979  ONX_ErrorCounter m_error_counts[7];
1980 
1981 #pragma ON_PRAGMA_WARNING_PUSH
1982 #pragma ON_PRAGMA_WARNING_DISABLE_MSC( 4251 )
1983  // C4251: ... : class 'std::shared_ptr<ON_MeshThicknessAnalysisImpl>'
1984  // needs to have dll-interface to be used by clients ...
1985  // m_model[] is private and all code that manages m_sp is explicitly implemented in the DLL.
1986 
1987  // m_model[0] = model from source file
1988  // m_model[1] = model[0] -> write to current 3dm version -> read into model[1]
1989  // m_model[2] = model[0] -> write to prev 3dm version -> read into model[2]
1990  std::shared_ptr<ONX_Model> m_model[3];
1991 #pragma ON_PRAGMA_WARNING_POP
1992 
1993  // m_model_hash[i] = m_model[0].Hash()
1994  ON_SHA1_Hash m_model_hash[3];
1995 };
1996 
1997 
1998 #endif
Test result is not set.
static const ON_Linetype Continuous
index = -1, id, name and pattern are set.
Definition: opennurbs_linetype.h:51
ON_SerialNumberMap provides a way to map set of unique serial number - uuid pairs to application defi...
Definition: opennurbs_lookup.h:32
ON_UUID is a 16 byte universally unique identifier.
Definition: opennurbs_uuid.h:32
ON_String m_sStartSectionComments
Definition: opennurbs_extensions.h:644
The ON_ModelComponent class is a base class for all components in a model and manages the index...
Definition: opennurbs_model_component.h:24
Definition: opennurbs_3dm_properties.h:139
ON_3dmProperties m_properties
Definition: opennurbs_extensions.h:648
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
static const ON_Layer Default
Definition: opennurbs_layer.h:32
Definition: opennurbs_3dm_settings.h:1184
ON_3dmSettings m_settings
Definition: opennurbs_extensions.h:652
Definition: opennurbs_sha1.h:19
static const ON_Material Default
Definition: opennurbs_material.h:33
Definition: opennurbs_string.h:2020
static const ON_BoundingBox UnsetBoundingBox
Definition: opennurbs_bounding_box.h:29
The ONX_ErrorCounter is useful for counting errors that occur in a section of code.
Definition: opennurbs_extensions.h:24
Definition: opennurbs_color.h:24
Definition: opennurbs_fsp.h:19
Definition: opennurbs_archive.h:5060
Definition: opennurbs_bounding_box.h:25
Definition: opennurbs_string.h:852
Definition: opennurbs_file_utilities.h:762
An ON_Font is a face in a font family. It corresponds to a Windows LOGFONT, a .NET System...
Definition: opennurbs_font.h:225
Type
The ON_ModelComponent::Type enum has a value for each explicit component type and two special values...
Definition: opennurbs_model_component.h:52
static const ON_TextStyle Default
Definition: opennurbs_text_style.h:25
Type
ONX_ModelTest::Type identifies the type of file reading test to perform.
Definition: opennurbs_extensions.h:1579
An ON_InstanceRef is a reference to an instance definition along with transformation to apply to the ...
Definition: opennurbs_instance.h:613
Definition: opennurbs_extensions.h:1563
Definition: opennurbs_archive.h:478
static const ON_ModelComponentReference Empty
Definition: opennurbs_model_component.h:1625
static const ON_DimStyle Default
Definition: opennurbs_dimensionstyle.h:227
An ON_DocumentUserStringList object is saved in the list of user tables. The Rhino SetDocumentText an...
Definition: opennurbs_userdata.h:568
Top level OpenNURBS objects have geometry and attributes. The geometry is stored in some class derive...
Definition: opennurbs_3dm_attributes.h:41
Used to store geometry table object definition and attributes in an ONX_Model.
Definition: opennurbs_model_geometry.h:22
Pure virtual base class for all classes that must provide runtime class id or support object level 3D...
Definition: opennurbs_object.h:460
Pedegodgical example of all the things in an OpenNURBS 3dm archive. The openNURBS examples use ONX_Mo...
Definition: opennurbs_extensions.h:190
An ON_NameHash is designed to help search for and compare attribute names like the ON_ModelComponent...
Definition: opennurbs_string.h:3434
static ON_ModelComponentReference CreateConstantSystemComponentReference(const class ON_ModelComponent &constant_system_component) ON_NOEXCEPT
Used to store user data information in an ONX_Model.
Definition: opennurbs_extensions.h:142
Definition: opennurbs_textlog.h:20
Definition: opennurbs_archive.h:1783
Definition: opennurbs_userdata.h:20
Definition: opennurbs_extensions.h:1497
Definition: opennurbs_model_component.h:1622
Result
ONX_ModelTest::Result reports the result of a test.
Definition: opennurbs_extensions.h:1622
Definition: opennurbs_file_utilities.h:1125