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 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
18 
ON_COMPONENT_INDEX()19 ON_COMPONENT_INDEX::ON_COMPONENT_INDEX()
20                    : m_type(ON_COMPONENT_INDEX::invalid_type),
21                      m_index(-1)
22 {
23 }
24 
ON_COMPONENT_INDEX(ON_COMPONENT_INDEX::TYPE type,int index)25 ON_COMPONENT_INDEX::ON_COMPONENT_INDEX(
26                                        ON_COMPONENT_INDEX::TYPE type,
27                                        int index
28                                        )
29                    : m_type(type),
30                      m_index(index)
31 {
32 }
33 
Type(int i)34 ON_COMPONENT_INDEX::TYPE ON_COMPONENT_INDEX::Type(int i)
35 {
36   TYPE t = invalid_type;
37   switch((unsigned int)i)
38   {
39   case no_type:            t = no_type;            break;
40   case brep_vertex:        t = brep_vertex;        break;
41   case brep_edge:          t = brep_edge;          break;
42   case brep_face:          t = brep_face;          break;
43   case brep_trim:          t = brep_trim;          break;
44   case brep_loop:          t = brep_loop;          break;
45   case mesh_vertex:        t = mesh_vertex;        break;
46   case meshtop_vertex:     t = meshtop_vertex;     break;
47   case meshtop_edge:       t = meshtop_edge;       break;
48   case mesh_face:          t = mesh_face;          break;
49   case idef_part:          t = idef_part;          break;
50   case polycurve_segment:  t = polycurve_segment;  break;
51   case pointcloud_point:   t = pointcloud_point;   break;
52   case group_member:       t = group_member;       break;
53 
54   case extrusion_bottom_profile: t = extrusion_bottom_profile; break;
55   case extrusion_top_profile:    t = extrusion_top_profile;    break;
56   case extrusion_wall_edge:      t = extrusion_wall_edge;      break;
57   case extrusion_wall_surface:   t = extrusion_wall_surface;   break;
58   case extrusion_cap_surface:    t = extrusion_cap_surface;    break;
59   case extrusion_path:           t = extrusion_path;           break;
60 
61   case dim_linear_point:   t = dim_linear_point;   break;
62   case dim_radial_point:   t = dim_radial_point;   break;
63   case dim_angular_point:  t = dim_angular_point;  break;
64   case dim_ordinate_point: t = dim_ordinate_point; break;
65   case dim_text_point:     t = dim_text_point;     break;
66   }
67   return t;
68 }
69 
70 
Set(ON_COMPONENT_INDEX::TYPE type,int index)71 void ON_COMPONENT_INDEX::Set(
72                                        ON_COMPONENT_INDEX::TYPE type,
73                                        int index
74                                        )
75 {
76   m_type = type;
77   m_index = index;
78 }
79 
UnSet()80 void ON_COMPONENT_INDEX::UnSet()
81 {
82   m_type = ON_COMPONENT_INDEX::invalid_type;
83   m_index = -1;
84 }
85 
IsMeshComponentIndex() const86 bool ON_COMPONENT_INDEX::IsMeshComponentIndex() const
87 {
88   bool rc = false;
89   switch(m_type)
90   {
91   case ON_COMPONENT_INDEX::mesh_vertex:
92   case ON_COMPONENT_INDEX::meshtop_vertex:
93   case ON_COMPONENT_INDEX::meshtop_edge:
94   case ON_COMPONENT_INDEX::mesh_face:
95     if ( m_index >= 0 )
96     {
97       rc = true;
98     }
99     break;
100   default:
101     // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
102     break;
103   }
104   return rc;
105 }
106 
IsAnnotationComponentIndex() const107 bool ON_COMPONENT_INDEX::IsAnnotationComponentIndex() const
108 {
109   bool rc = false;
110   switch(m_type)
111   {
112   case ON_COMPONENT_INDEX::dim_linear_point:
113   case ON_COMPONENT_INDEX::dim_radial_point:
114   case ON_COMPONENT_INDEX::dim_angular_point:
115   case ON_COMPONENT_INDEX::dim_ordinate_point:
116   case ON_COMPONENT_INDEX::dim_text_point:
117     if ( m_index >= 0 )
118     {
119       rc = true;
120     }
121     break;
122   default:
123     // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
124     break;
125   }
126   return rc;
127 }
128 
IsBrepComponentIndex() const129 bool ON_COMPONENT_INDEX::IsBrepComponentIndex() const
130 {
131   bool rc = false;
132   switch(m_type)
133   {
134   case ON_COMPONENT_INDEX::brep_vertex:
135   case ON_COMPONENT_INDEX::brep_trim:
136   case ON_COMPONENT_INDEX::brep_loop:
137   case ON_COMPONENT_INDEX::brep_edge:
138   case ON_COMPONENT_INDEX::brep_face:
139     if ( m_index >= 0 )
140     {
141       rc = true;
142     }
143     break;
144   default:
145     // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
146     break;
147   }
148   return rc;
149 }
150 
IsIDefComponentIndex() const151 bool  ON_COMPONENT_INDEX::IsIDefComponentIndex() const
152 {
153   return ( ON_COMPONENT_INDEX::idef_part == m_type && m_index >= 0 );
154 }
155 
IsPolyCurveComponentIndex() const156 bool  ON_COMPONENT_INDEX::IsPolyCurveComponentIndex() const
157 {
158   return ( ON_COMPONENT_INDEX::polycurve_segment == m_type && m_index >= 0 );
159 }
160 
IsGroupMemberComponentIndex() const161 bool  ON_COMPONENT_INDEX::IsGroupMemberComponentIndex() const
162 {
163   return ( ON_COMPONENT_INDEX::group_member == m_type && m_index >= 0 );
164 }
165 
IsExtrusionProfileComponentIndex() const166 bool  ON_COMPONENT_INDEX::IsExtrusionProfileComponentIndex() const
167 {
168   return ( (   ON_COMPONENT_INDEX::extrusion_bottom_profile  == m_type
169             || ON_COMPONENT_INDEX::extrusion_top_profile     == m_type
170             )
171             && m_index >= 0
172          );
173 }
174 
IsExtrusionPathComponentIndex() const175 bool  ON_COMPONENT_INDEX::IsExtrusionPathComponentIndex() const
176 {
177   return ( ON_COMPONENT_INDEX::extrusion_path  == m_type
178            && m_index >= -1
179            && m_index <= 1
180          );
181 }
182 
IsExtrusionWallEdgeComponentIndex() const183 bool  ON_COMPONENT_INDEX::IsExtrusionWallEdgeComponentIndex() const
184 {
185   return ( ON_COMPONENT_INDEX::extrusion_wall_edge  == m_type
186            && m_index >= 0
187          );
188 }
189 
IsExtrusionWallSurfaceComponentIndex() const190 bool  ON_COMPONENT_INDEX::IsExtrusionWallSurfaceComponentIndex() const
191 {
192   return ( ON_COMPONENT_INDEX::extrusion_wall_surface  == m_type
193            && m_index >= 0
194          );
195 }
196 
IsExtrusionWallComponentIndex() const197 bool  ON_COMPONENT_INDEX::IsExtrusionWallComponentIndex() const
198 {
199   return ( (   ON_COMPONENT_INDEX::extrusion_wall_edge == m_type
200              || ON_COMPONENT_INDEX::extrusion_wall_surface == m_type
201            )
202            && m_index >= 0
203          );
204 }
205 
IsExtrusionComponentIndex() const206 bool  ON_COMPONENT_INDEX::IsExtrusionComponentIndex() const
207 {
208   return ( (   ON_COMPONENT_INDEX::extrusion_bottom_profile  == m_type
209             || ON_COMPONENT_INDEX::extrusion_top_profile     == m_type
210             || ON_COMPONENT_INDEX::extrusion_wall_edge       == m_type
211             || ON_COMPONENT_INDEX::extrusion_wall_surface    == m_type
212             || ON_COMPONENT_INDEX::extrusion_cap_surface     == m_type
213             || ON_COMPONENT_INDEX::extrusion_path            == m_type
214             )
215             &&
216             (  m_index >= 0
217               || (-1 == m_index && ON_COMPONENT_INDEX::extrusion_path == m_type)
218             )
219          );
220 }
221 
IsPointCloudComponentIndex() const222 bool  ON_COMPONENT_INDEX::IsPointCloudComponentIndex() const
223 {
224   return ( ON_COMPONENT_INDEX::pointcloud_point == m_type && m_index >= 0 );
225 }
226 
IsSet() const227 bool ON_COMPONENT_INDEX::IsSet() const
228 {
229   bool rc = false;
230   switch(m_type)
231   {
232   case invalid_type:
233     rc = false;
234     break;
235 
236   case no_type:
237     rc = false;
238     break;
239 
240   case brep_vertex:
241   case brep_edge:
242   case brep_face:
243   case brep_trim:
244   case brep_loop:
245   case mesh_vertex:
246   case meshtop_vertex:
247   case meshtop_edge:
248   case mesh_face:
249   case idef_part:
250   case polycurve_segment:
251   case pointcloud_point:
252   case group_member:
253     rc = (m_index != -1);
254     break;
255 
256   default:
257     rc = false;
258     break;
259   }
260   return rc;
261 }
262 
263 
Compare(const ON_COMPONENT_INDEX * a,const ON_COMPONENT_INDEX * b)264 int ON_COMPONENT_INDEX::Compare( const ON_COMPONENT_INDEX* a, const ON_COMPONENT_INDEX* b )
265 {
266   int i = ((int)a->m_type) - ((int)b->m_type);
267   if ( 0 == i )
268   {
269     i = a->m_index - b->m_index;
270   }
271   return i;
272 }
273 
operator ==(const ON_COMPONENT_INDEX & other) const274 bool ON_COMPONENT_INDEX::operator==(const ON_COMPONENT_INDEX& other) const
275 {
276   return (m_type == other.m_type && m_index == other.m_index);
277 }
278 
operator !=(const ON_COMPONENT_INDEX & other) const279 bool ON_COMPONENT_INDEX::operator!=(const ON_COMPONENT_INDEX& other) const
280 {
281   return (m_type != other.m_type || m_index != other.m_index);
282 }
283 
operator <(const ON_COMPONENT_INDEX & other) const284 bool ON_COMPONENT_INDEX::operator<(const ON_COMPONENT_INDEX& other) const
285 {
286   return (ON_COMPONENT_INDEX::Compare(this,&other) < 0);
287 }
288 
operator <=(const ON_COMPONENT_INDEX & other) const289 bool ON_COMPONENT_INDEX::operator<=(const ON_COMPONENT_INDEX& other) const
290 {
291   return (ON_COMPONENT_INDEX::Compare(this,&other) <= 0);
292 }
293 
operator >(const ON_COMPONENT_INDEX & other) const294 bool ON_COMPONENT_INDEX::operator>(const ON_COMPONENT_INDEX& other) const
295 {
296   return (ON_COMPONENT_INDEX::Compare(this,&other) > 0);
297 }
298 
operator >=(const ON_COMPONENT_INDEX & other) const299 bool ON_COMPONENT_INDEX::operator>=(const ON_COMPONENT_INDEX& other) const
300 {
301   return (ON_COMPONENT_INDEX::Compare(this,&other) >= 0);
302 }
303 
ON_ObjRefEvaluationParameter()304 ON_ObjRefEvaluationParameter::ON_ObjRefEvaluationParameter()
305 : m_t_type(0)
306 , m_reserved(0)
307 {
308   m_t[0] = ON_UNSET_VALUE;
309   m_t[1] = ON_UNSET_VALUE;
310   m_t[2] = ON_UNSET_VALUE;
311   m_t[3] = ON_UNSET_VALUE;
312 }
313 
Default()314 void ON_ObjRefEvaluationParameter::Default()
315 {
316   ON_ObjRefEvaluationParameter d;
317   *this = d;
318 }
319 
~ON_ObjRefEvaluationParameter()320 ON_ObjRefEvaluationParameter::~ON_ObjRefEvaluationParameter()
321 {
322 }
323 
Write(ON_BinaryArchive & archive) const324 bool ON_ObjRefEvaluationParameter::Write( ON_BinaryArchive& archive ) const
325 {
326   bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
327   if (!rc)
328     return rc;
329 
330   for(;;)
331   {
332     rc = archive.WriteInt(m_t_type);
333     if (!rc) break;
334 
335     rc = archive.WriteComponentIndex(m_t_ci);
336     if (!rc) break;
337 
338     rc = archive.WriteDouble(4,m_t);
339     if (!rc) break;
340 
341     rc = archive.WriteInterval(m_s[0]);
342     if (!rc) break;
343 
344     rc = archive.WriteInterval(m_s[1]);
345     if (!rc) break;
346 
347     rc = archive.WriteInterval(m_s[2]);
348     if (!rc) break;
349 
350     break;
351   }
352 
353   if ( !archive.EndWrite3dmChunk() )
354     rc = false;
355 
356   return rc;
357 }
358 
Read(ON_BinaryArchive & archive)359 bool ON_ObjRefEvaluationParameter::Read( ON_BinaryArchive& archive )
360 {
361   Default();
362 
363   int major_version = 0;
364   int minor_version = 0;
365   bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
366   if (!rc)
367     return rc;
368 
369   for(;;)
370   {
371     rc = (1 == major_version);
372     if (!rc) break;
373 
374     rc = archive.ReadInt(&m_t_type);
375     if (!rc) break;
376 
377     rc = archive.ReadComponentIndex(m_t_ci);
378     if (!rc) break;
379 
380     rc = archive.ReadDouble(4,m_t);
381     if (!rc) break;
382 
383     rc = archive.ReadInterval(m_s[0]);
384     if (!rc) break;
385 
386     rc = archive.ReadInterval(m_s[1]);
387     if (!rc) break;
388 
389     rc = archive.ReadInterval(m_s[2]);
390     if (!rc) break;
391 
392     break;
393   }
394 
395   if ( !archive.EndRead3dmChunk() )
396     rc = false;
397 
398   return rc;
399 }
400 
ON_ObjRef()401 ON_ObjRef::ON_ObjRef()
402           : m_uuid(ON_nil_uuid),
403             m_geometry(0),
404             m_parent_geometry(0),
405             m_geometry_type(ON::unknown_object_type),
406             m_runtime_sn(0),
407             m_point(ON_UNSET_POINT),
408             m_osnap_mode(ON::os_none),
409             m__proxy1(0),
410             m__proxy2(0),
411             m__proxy_ref_count(0)
412 {
413 }
414 
Destroy()415 void ON_ObjRef::Destroy()
416 {
417   DecrementProxyReferenceCount();
418   m_uuid = ON_nil_uuid;
419   m_geometry = 0;
420   m_parent_geometry = 0;
421   m_geometry_type = ON::unknown_object_type;
422   m_runtime_sn = 0;
423   m_point = ON_UNSET_POINT;
424   m_osnap_mode = ON::os_none;
425   m__proxy1 = 0;
426   m__proxy2 = 0;
427   m__proxy_ref_count = 0;
428 }
429 
430 
ON_ObjRef(const ON_ObjRef & src)431 ON_ObjRef::ON_ObjRef( const ON_ObjRef& src )
432           : m_uuid(src.m_uuid),
433             m_geometry(src.m_geometry),
434             m_parent_geometry(src.m_parent_geometry),
435             m_component_index(src.m_component_index),
436             m_geometry_type(src.m_geometry_type),
437             m_runtime_sn(src.m_runtime_sn),
438             m_point(src.m_point),
439             m_osnap_mode(src.m_osnap_mode),
440             m_evp(src.m_evp),
441             m__iref(src.m__iref),
442             m__proxy1(src.m__proxy1),
443             m__proxy2(src.m__proxy2),
444             m__proxy_ref_count(src.m__proxy_ref_count)
445 {
446   if ( m__proxy_ref_count && *m__proxy_ref_count > 0 )
447   {
448     *m__proxy_ref_count = *m__proxy_ref_count + 1;
449   }
450 }
451 
operator =(const ON_ObjRef & src)452 ON_ObjRef& ON_ObjRef::operator=( const ON_ObjRef& src )
453 {
454   if ( this != &src )
455   {
456     // Remove any reference this ON_ObjRef class
457     // may currently have.
458     DecrementProxyReferenceCount();
459 
460     // copy the values from src
461     m_uuid = src.m_uuid;
462     m_geometry = src.m_geometry;
463     m_parent_geometry = src.m_parent_geometry;
464     m_component_index = src.m_component_index;
465     m_geometry_type = src.m_geometry_type;
466     m_runtime_sn = src.m_runtime_sn;
467     m_point = src.m_point;
468     m_osnap_mode = src.m_osnap_mode;
469     m_evp = src.m_evp;
470     m__iref = src.m__iref;
471     m__proxy1 = src.m__proxy1;
472     m__proxy2 = src.m__proxy2;
473     m__proxy_ref_count = src.m__proxy_ref_count;
474 
475     if ( m__proxy_ref_count && *m__proxy_ref_count > 0 )
476     {
477       *m__proxy_ref_count = *m__proxy_ref_count + 1;
478     }
479   }
480 
481   return *this;
482 }
483 
Write(ON_BinaryArchive & archive) const484 bool ON_ObjRef_IRefID::Write( ON_BinaryArchive& archive ) const
485 {
486   bool rc = archive.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 1 );
487   if ( !rc )
488     return false;
489 
490   for(;;)
491   {
492     rc = archive.WriteUuid(m_iref_uuid);
493     if (!rc) break;
494 
495     rc = archive.WriteXform(m_iref_xform);
496     if (!rc) break;
497 
498     rc = archive.WriteUuid(m_idef_uuid);
499     if (!rc) break;
500 
501     rc = archive.WriteInt(m_idef_geometry_index);
502     if (!rc) break;
503 
504     // 13 July 2006 - 1.1 - added m_component_index and m_evp
505     rc = archive.WriteComponentIndex(m_component_index);
506     if (!rc) break;
507 
508     rc = m_evp.Write(archive);
509     if (!rc) break;
510 
511     break;
512   }
513 
514   if ( !archive.EndWrite3dmChunk() )
515     rc = false;
516   return rc;
517 }
518 
Read(ON_BinaryArchive & archive)519 bool ON_ObjRef_IRefID::Read( ON_BinaryArchive& archive )
520 {
521   Default();
522 
523   int major_version = 0;
524   int minor_version = 0;
525   bool rc = archive.BeginRead3dmChunk(
526                           TCODE_ANONYMOUS_CHUNK,
527                           &major_version,
528                           &minor_version );
529   if ( !rc )
530     return false;
531 
532   for(;;)
533   {
534     rc = (1 == major_version);
535     if (!rc) break;
536 
537     rc = archive.ReadUuid(m_iref_uuid);
538     if (!rc) break;
539 
540     rc = archive.ReadXform(m_iref_xform);
541     if (!rc) break;
542 
543     rc = archive.ReadUuid(m_idef_uuid);
544     if (!rc) break;
545 
546     rc = archive.ReadInt(&m_idef_geometry_index);
547     if (!rc) break;
548 
549     if ( minor_version >= 1 )
550     {
551       // 13 July 2006 - 1.1 - added m_component_index and m_evp
552       rc = archive.ReadComponentIndex(m_component_index);
553       if (!rc) break;
554 
555       rc = m_evp.Read(archive);
556       if (!rc) break;
557     }
558 
559     break;
560   }
561 
562   if ( !archive.EndRead3dmChunk() )
563     rc = false;
564   return rc;
565 }
566 
567 
Write(ON_BinaryArchive & archive) const568 bool ON_ObjRef::Write( ON_BinaryArchive& archive ) const
569 {
570   bool rc = archive.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 2 );
571   if ( !rc )
572     return false;
573 
574   for(;;)
575   {
576     rc = archive.WriteUuid(m_uuid);
577     if (!rc) break;
578 
579     rc = archive.WriteComponentIndex(m_component_index);
580     if (!rc) break;
581 
582     rc = archive.WriteInt(m_geometry_type);
583     if (!rc) break;
584 
585     // Do not save the value of m_runtime_sn in the
586     // archive.  When the file is read in, the object
587     // will have a different value of m_runtime_sn.
588 
589     rc = archive.WritePoint(m_point);
590     if (!rc) break;
591 
592     // Prior to 13 July 2006, the evaluation parameters
593     // m_evp were members of ON_ObjRef.  That's why the
594     // m_evp fields are written directly rather than
595     // using m_evp.Write().
596     rc = archive.WriteInt(m_evp.m_t_type);
597     if (!rc) break;
598 
599     rc = archive.WriteComponentIndex(m_evp.m_t_ci);
600     if (!rc) break;
601 
602     rc = archive.WriteDouble(4,m_evp.m_t);
603     if (!rc) break;
604 
605     rc = archive.WriteArray(m__iref);
606     if (!rc) break;
607 
608     // 1.1 IO fields
609     rc = archive.WriteInterval(m_evp.m_s[0]);
610     if (!rc) break;
611 
612     rc = archive.WriteInterval(m_evp.m_s[1]);
613     if (!rc) break;
614 
615     // 1.2 IO fields
616     rc = archive.WriteInterval(m_evp.m_s[2]);
617     if (!rc) break;
618 
619     break;
620   }
621 
622   if ( !archive.EndWrite3dmChunk() )
623     rc = false;
624   return rc;
625 }
626 
Read(ON_BinaryArchive & archive)627 bool ON_ObjRef::Read( ON_BinaryArchive& archive )
628 {
629   int major_version = 0;
630   int minor_version = 0;
631   bool rc = archive.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version );
632   if ( !rc )
633     return false;
634 
635   for(;;)
636   {
637     rc = (1 == major_version);
638     if (!rc) break;
639 
640     rc = archive.ReadUuid(m_uuid);
641     if (!rc) break;
642 
643     rc = archive.ReadComponentIndex(m_component_index);
644     if (!rc) break;
645 
646     rc = archive.ReadInt(&m_geometry_type);
647     if (!rc) break;
648 
649     rc = archive.ReadPoint(m_point);
650     if (!rc) break;
651 
652     // Prior to 13 July 2006, the evaluation parameters
653     // m_evp were members of ON_ObjRef.  That's why the
654     // m_evp fields are read directly rather than
655     // using m_evp.Read().
656     rc = archive.ReadInt(&m_evp.m_t_type);
657     if (!rc) break;
658 
659     rc = archive.ReadComponentIndex(m_evp.m_t_ci);
660     if (!rc) break;
661 
662     rc = archive.ReadDouble(4,m_evp.m_t);
663     if (!rc) break;
664 
665     rc = archive.ReadArray(m__iref);
666     if (!rc) break;
667 
668     if ( minor_version >= 1 )
669     {
670       // 1.1 IO fields
671       rc = archive.ReadInterval(m_evp.m_s[0]);
672       if (!rc) break;
673       rc = archive.ReadInterval(m_evp.m_s[1]);
674       if (!rc) break;
675       if ( minor_version >= 2 )
676       {
677         rc = archive.ReadInterval(m_evp.m_s[2]);
678         if (!rc) break;
679       }
680     }
681 
682     break;
683   }
684 
685   if ( !archive.EndRead3dmChunk() )
686     rc = false;
687   return rc;
688 }
689 
690 
~ON_ObjRef()691 ON_ObjRef::~ON_ObjRef()
692 {
693   DecrementProxyReferenceCount();
694 }
695 
696 
RemapObjectId(const ON_SimpleArray<ON_UuidPair> & id_remap)697 void ON_ObjRef::RemapObjectId( const ON_SimpleArray<ON_UuidPair>& id_remap )
698 {
699   // The cast is a lie but it works because ON_UuidPair::CompareFirstUuid
700   // looks for an id in the first 16 bytes of the ON_UuidPair.
701   int i = id_remap.BinarySearch((const ON_UuidPair*)&m_uuid,ON_UuidPair::CompareFirstUuid);
702   if ( i >= 0 )
703     m_uuid = id_remap[i].m_uuid[1];
704 }
705 
ProxyReferenceCount() const706 int ON_ObjRef::ProxyReferenceCount() const
707 {
708   return m__proxy_ref_count ? *m__proxy_ref_count : 0;
709 }
710 
ON_BrepParent(const ON_Geometry * geo)711 const ON_Brep* ON_BrepParent( const ON_Geometry* geo )
712 {
713   const ON_Brep* brep = 0;
714 
715   if ( geo == NULL )
716     return NULL;
717 
718   if  ( ON::brep_object == geo->ObjectType() )
719   {
720     brep = ON_Brep::Cast(geo);
721   }
722   else
723   {
724     // ComponentIndex() is the fastest way
725     switch( geo->ComponentIndex().m_type )
726     {
727     case ON_COMPONENT_INDEX::brep_edge:
728       {
729         const ON_BrepEdge* edge = ON_BrepEdge::Cast(geo);
730         if ( edge )
731           brep = edge->Brep();
732       }
733       break;
734 
735     case ON_COMPONENT_INDEX::brep_face:
736       {
737         const ON_BrepFace* face = ON_BrepFace::Cast(geo);
738         if ( face )
739           brep = face->Brep();
740       }
741       break;
742 
743     case ON_COMPONENT_INDEX::brep_trim:
744       {
745         const ON_BrepTrim* trim = ON_BrepTrim::Cast(geo);
746         if ( trim )
747           brep = trim->Brep();
748       }
749       break;
750 
751     case ON_COMPONENT_INDEX::brep_loop:
752       {
753         const ON_BrepLoop* loop = ON_BrepLoop::Cast(geo);
754         if ( loop )
755           brep = loop->Brep();
756       }
757       break;
758 
759     default:
760       // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
761       break;
762     }
763   }
764 
765   return brep;
766 }
767 
768 
ON_MeshParent(const ON_Geometry * geo)769 const ON_Mesh* ON_MeshParent( const ON_Geometry* geo )
770 {
771   const ON_Mesh* mesh = 0;
772 
773   if ( geo == NULL )
774     return NULL;
775 
776   if  ( ON::mesh_object == geo->ObjectType() )
777   {
778     mesh = ON_Mesh::Cast(geo);
779   }
780   else
781   {
782     // ComponentIndex() is the fastest way
783     switch( geo->ComponentIndex().m_type )
784     {
785     case ON_COMPONENT_INDEX::mesh_vertex:
786     case ON_COMPONENT_INDEX::meshtop_vertex:
787       {
788         const ON_MeshVertexRef* vref = ON_MeshVertexRef::Cast(geo);
789         if ( vref )
790           mesh = vref->m_mesh;
791       }
792       break;
793 
794     case ON_COMPONENT_INDEX::meshtop_edge:
795       {
796         const ON_MeshEdgeRef* eref = ON_MeshEdgeRef::Cast(geo);
797         if ( eref )
798           mesh = eref->m_mesh;
799       }
800       break;
801 
802     case ON_COMPONENT_INDEX::mesh_face:
803       {
804         const ON_MeshFaceRef* fref = ON_MeshFaceRef::Cast(geo);
805         if ( fref )
806           mesh = fref->m_mesh;
807       }
808       break;
809 
810     default:
811       // intentionally skipping other ON_COMPONENT_INDEX::TYPE enum values
812       break;
813     }
814   }
815 
816   return mesh;
817 }
818 
SetParentIRef(const ON_InstanceRef & iref,ON_UUID iref_id,int idef_geometry_index)819 bool ON_ObjRef::SetParentIRef( const ON_InstanceRef& iref,
820                                ON_UUID iref_id,
821                                int idef_geometry_index
822                                )
823 {
824   bool rc = false;
825 
826   if ( m__iref.Count() > 0 )
827   {
828     // nested irefs
829     if (    0 == m__proxy2
830          || 0 == m__proxy_ref_count
831          || *m__proxy_ref_count <= 0 )
832     {
833       return false;
834     }
835     ON_Geometry* proxy_geo = ON_Geometry::Cast(m__proxy2);
836     if ( !proxy_geo )
837       return false;
838     if ( !proxy_geo->Transform(iref.m_xform) )
839       return false;
840     rc = true;
841   }
842   else if ( ON_COMPONENT_INDEX::invalid_type == m_component_index.m_type )
843   {
844     // handle top level objects
845     while ( m__proxy1 || m__proxy2 || m__proxy_ref_count )
846     {
847       // It it's an brep proxy for an extrusion object, then keep going.
848       if (    0 != m__proxy1
849            && 0 == m__proxy2
850            && 0 != m__proxy_ref_count
851            && 1 == *m__proxy_ref_count
852            && m__proxy1 != m_geometry
853            && 0 != ON_Brep::Cast(m_geometry)
854            )
855       {
856         // 13 July 2011 - Part of the fix for bug 87827
857         // is to break here instead of returning false
858         // because we have something like a brep proxy
859         // of an extrusion.
860         break;
861       }
862       return false;
863     }
864 
865     if ( !m_geometry )
866     {
867       return false;
868     }
869     if ( m_geometry->ComponentIndex().m_type != ON_COMPONENT_INDEX::invalid_type )
870     {
871       return false;
872     }
873     if ( m_parent_geometry && m_geometry != m_parent_geometry )
874     {
875       return false;
876     }
877     ON_Geometry* proxy_geo = m_geometry->Duplicate();
878     if ( !proxy_geo->Transform(iref.m_xform) )
879     {
880       delete proxy_geo;
881       return false;
882     }
883 
884     // 13 July 2011 - Part of the fix for bug 87827
885     // was to put the m_geometry and m_parent_geometry
886     // assignments after the call to SetProxy() which
887     // was zeroing m_geometry and m_parent_geometry.
888     SetProxy(0,proxy_geo,true);
889     m_geometry = proxy_geo;
890     m_parent_geometry = proxy_geo;
891     rc = true;
892   }
893   else
894   {
895     // handle brep and mesh subobjects
896     // create proxy object
897     if ( m__proxy2 )
898       return false;
899 
900     const ON_Brep* parent_brep = ON_BrepParent(m_parent_geometry);
901     if ( !parent_brep)
902       parent_brep = ON_BrepParent(m_geometry);
903     if ( parent_brep )
904     {
905       // handle breps and their parts
906       if ( m__proxy1 || m__proxy_ref_count )
907       {
908         return false;
909       }
910       if ( m_parent_geometry != parent_brep && 0 != m_parent_geometry )
911       {
912         return false;
913       }
914       if ( m_geometry != parent_brep->BrepComponent(m_component_index) )
915       {
916         return false;
917       }
918       ON_Brep* proxy_brep = parent_brep->Duplicate();
919       if ( !proxy_brep->Transform(iref.m_xform) )
920       {
921         delete proxy_brep;
922         return false;
923       }
924       const ON_Geometry* brep_component = proxy_brep->BrepComponent(m_component_index);
925       if ( !brep_component )
926       {
927         delete brep_component;
928         return false;
929       }
930       SetProxy(0,proxy_brep,true);
931       m_geometry        = brep_component;
932       m_parent_geometry = proxy_brep;
933       rc = true;
934     }
935     else
936     {
937       const ON_Mesh* parent_mesh = ON_MeshParent(m_parent_geometry);
938       if ( !parent_mesh)
939         parent_mesh = ON_MeshParent(m_geometry);
940       if ( parent_mesh  )
941       {
942         // handle meshes and their parts
943         switch(m_component_index.m_type)
944         {
945         case ON_COMPONENT_INDEX::mesh_vertex:
946         case ON_COMPONENT_INDEX::meshtop_vertex:
947         case ON_COMPONENT_INDEX::meshtop_edge:
948         case ON_COMPONENT_INDEX::mesh_face:
949           {
950             if ( m_geometry->ComponentIndex() != m_component_index )
951               return false;
952             ON_Mesh* proxy_mesh = parent_mesh->Duplicate();
953             if ( !proxy_mesh->Transform(iref.m_xform) )
954             {
955               delete proxy_mesh;
956               return false;
957             }
958             ON_Geometry* proxy_component = proxy_mesh->MeshComponent(m_component_index);
959             if( !proxy_component )
960             {
961               delete proxy_mesh;
962               return false;
963             }
964             m_geometry = proxy_component;
965             m_parent_geometry = proxy_mesh;
966             SetProxy(proxy_component,proxy_mesh,true);
967             rc = true;
968           }
969           break;
970         default:
971           return false;
972           break;
973         }
974       }
975     }
976   }
977 
978   if ( rc )
979   {
980     // This is a valid reference to a piece of geometry
981     // in an instance definition.
982 
983     ON_Xform geometry_xform(1.0);
984     if ( m__iref.Count() > 0 )
985       geometry_xform = m__iref.Last()->m_geometry_xform;
986 
987     ON_ObjRef_IRefID& this_ref     = m__iref.AppendNew();
988     this_ref.m_iref_uuid           = iref_id;
989     this_ref.m_iref_xform          = iref.m_xform;
990     this_ref.m_idef_uuid           = iref.m_instance_definition_uuid;
991     this_ref.m_idef_geometry_index = idef_geometry_index;
992     this_ref.m_geometry_xform      = iref.m_xform*geometry_xform;
993 
994     m_uuid = this_ref.m_iref_uuid;
995   }
996 
997   return rc;
998 }
999 
ProxyObject(int proxy_object_index) const1000 const ON_Object* ON_ObjRef::ProxyObject(int proxy_object_index) const
1001 {
1002   return ( (1 == proxy_object_index)
1003            ? m__proxy1
1004            : ((2==proxy_object_index) ? m__proxy2 : 0)
1005          );
1006 }
1007 
SetProxy(ON_Object * proxy1,ON_Object * proxy2,bool bCountReferences)1008 void ON_ObjRef::SetProxy(
1009           ON_Object* proxy1,
1010           ON_Object* proxy2,
1011           bool bCountReferences
1012           )
1013 {
1014   if ( m__proxy1 || m__proxy2 || m__proxy_ref_count )
1015   {
1016     // Remove any reference this ON_ObjRef class
1017     // may currently have.
1018     DecrementProxyReferenceCount();
1019   }
1020 
1021   m__proxy1 = proxy1;
1022   m__proxy2 = proxy2;
1023   if ( bCountReferences && (m__proxy1 || m__proxy2) )
1024   {
1025     m__proxy_ref_count = (int*)onmalloc_from_pool(
1026           ON_MainMemoryPool(),
1027           sizeof(*m__proxy_ref_count)
1028           );
1029     *m__proxy_ref_count = 1;
1030   }
1031 }
1032 
DecrementProxyReferenceCount()1033 void ON_ObjRef::DecrementProxyReferenceCount()
1034 {
1035   if ( 0 != m__proxy_ref_count )
1036   {
1037     if (*m__proxy_ref_count > 1)
1038     {
1039       // Including this class, there are *m__proxy_ref_count
1040       // ON_ObjRef classes using m__proxy and m_geometry.
1041       // Decrement the reference counter and set the
1042       // pointers to zero.
1043       *m__proxy_ref_count = *m__proxy_ref_count - 1;
1044     }
1045     else if ( 1 == *m__proxy_ref_count )
1046     {
1047       // This is the only ON_ObjRef class using
1048       // m__proxy and m_geometry.  Set *m__proxy_ref_count
1049       // to zero (in case some rogue reference still exists),
1050       // delete m__proxy and m__proxy_ref_count, and
1051       // set m_geometry (which points to some part of m__proxy)
1052       // to NULL.
1053 
1054       // Setting *m__proxy_ref_count to zero, prevents crashes
1055       // if somebody incorrectly uses memcpy() instead of the
1056       // copy constructor or operator= to duplicate this class.
1057       *m__proxy_ref_count = 0;
1058       if ( m__proxy1 )
1059       {
1060         // delete proxy geometry
1061         delete m__proxy1;
1062       }
1063       if ( m__proxy2 )
1064       {
1065         // delete proxy geometry
1066         delete m__proxy2;
1067       }
1068       onfree(m__proxy_ref_count);
1069     }
1070     else
1071     {
1072       // Somebody did something along the lines of using
1073       // memcpy() instead of the copy constructor or operator=
1074       // to duplicate this class.
1075       ON_ERROR("ON_ObjRef::DecrementReferenceCount() *m__proxy_ref_count <= 0");
1076     }
1077   }
1078 
1079   // In all cases, setting these pointers to zero indicates this
1080   // ON_ObjRef is no longer referencing any runtime geometry.
1081   m__proxy_ref_count = 0;
1082   m__proxy1 = 0;
1083   m__proxy2 = 0;
1084   m_geometry = 0;
1085 }
1086 
ON_ObjRef_IRefID()1087 ON_ObjRef_IRefID::ON_ObjRef_IRefID()
1088           : m_iref_uuid(ON_nil_uuid),
1089             m_iref_xform(0.0),
1090             m_idef_uuid(ON_nil_uuid),
1091             m_idef_geometry_index(0),
1092             m_geometry_xform(0.0)
1093 {
1094 }
1095 
Default()1096 void ON_ObjRef_IRefID::Default()
1097 {
1098   ON_ObjRef_IRefID d;
1099   *this = d;
1100 }
1101 
~ON_ObjRef_IRefID()1102 ON_ObjRef_IRefID::~ON_ObjRef_IRefID()
1103 {
1104 }
1105 
1106 
1107