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