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 "opennurbs.h"
18
19 #define ON_BOZO_VACCINE_11EE2C1FF90D4C6AA7CDEC8532E1E32D
20 #define ON_BOZO_VACCINE_F42D967121EB46929B9ABC3507FF28F5
21
22 ON_OBJECT_IMPLEMENT( ON_InstanceDefinition, ON_Geometry, "26F8BFF6-2618-417f-A158-153D64A94989" );
23
ON_InstanceDefinition()24 ON_InstanceDefinition::ON_InstanceDefinition()
25 {
26 m_uuid = ON_nil_uuid;
27 m_idef_update_type = ON_InstanceDefinition::static_def;
28 m_idef_update_depth = 0;
29 m_us.m_unit_system = ON::no_unit_system;
30 m_us.m_custom_unit_scale = 0.0;
31 m_us.m_custom_unit_name.Destroy();
32 m_source_bRelativePath = false;
33 m_reserved1 = 0;
34 m_idef_layer_style = 0;
35 m_reserved2[0] = 0;
36 m_reserved2[1] = 0;
37 }
38
~ON_InstanceDefinition()39 ON_InstanceDefinition::~ON_InstanceDefinition()
40 {
41 }
42
43
Dump(ON_TextLog & text_log) const44 void ON_InstanceDefinition::Dump( ON_TextLog& text_log ) const
45 {
46 const wchar_t* wsIDefName = m_name;
47 if ( 0 == wsIDefName )
48 wsIDefName = L"";
49 text_log.Print("Name: \"%ls\"\n",wsIDefName);
50
51
52 text_log.Print("Type: ");
53 switch(m_idef_update_type)
54 {
55 case ON_InstanceDefinition::static_def:
56 text_log.Print("embedded.");
57 break;
58 case ON_InstanceDefinition::embedded_def:
59 if ( m_source_archive.Length() > 0 )
60 text_log.Print("OBSOLETE embedded_def with non-empty source archive - should be linked_and_embedded_def.");
61 else
62 text_log.Print("OBSOLETE embedded_def with empty source archive - should be static_def.");
63 break;
64 case ON_InstanceDefinition::linked_and_embedded_def:
65 text_log.Print("embedded and linked - definition from source archive.");
66 break;
67 case ON_InstanceDefinition::linked_def:
68 text_log.Print("linked - definition from source archive.");
69 break;
70 default:
71 text_log.Print("not valid");
72 break;
73 }
74 text_log.Print("\n");
75
76
77 text_log.Print("Id: "); text_log.Print(m_uuid); text_log.Print("\n");
78
79 const wchar_t* wsDescription = m_description;
80 if ( 0 != wsDescription && 0 != wsDescription[0])
81 text_log.Print("Description: \"%ls\"\n",wsDescription);
82
83 const wchar_t* wsURL = m_url;
84 if ( 0 != wsURL && 0 != wsURL[0])
85 text_log.Print("URL: \"%ls\"\n",wsURL);
86
87 const wchar_t* wsTag = m_url_tag;
88 if ( 0 != wsTag && 0 != wsTag[0])
89 text_log.Print("URL tag: \"%ls\"\n",wsTag);
90
91 m_us.Dump(text_log);
92
93 const wchar_t* wsSourceArchive = SourceArchive();
94 text_log.Print("Source archive: ");
95 if ( 0 == wsSourceArchive || 0 == wsSourceArchive[0] )
96 {
97 text_log.Print("none.\n");
98 }
99 else
100 {
101 bool bRel = m_source_bRelativePath;
102 text_log.Print("\"%ls\" (%s)\n",wsSourceArchive,bRel?"relative":"absolute");
103
104 text_log.PushIndent();
105 ON_wString str;
106 bRel = false;
107 if ( GetAlternateSourceArchivePath(str,bRel) )
108 {
109 const wchar_t* wsAlternateArchive = str;
110 if ( 0 == wsAlternateArchive || 0 == wsAlternateArchive[0] )
111 wsAlternateArchive = L"";
112 text_log.Print("Alternate archive: \"%ls\" (%s)\n",wsAlternateArchive,bRel?"relative":"absolute");
113 }
114
115 text_log.Print("Update depth: %d\n",m_idef_update_type);
116
117 text_log.Print("Archive ");
118 m_source_archive_checksum.Dump(text_log);
119 text_log.PopIndent();
120 }
121
122 const int id_count = m_object_uuid.Count();
123 text_log.Print("Contains: %d objects\n",id_count);
124
125 if ( id_count > 0 )
126 {
127 text_log.PushIndent();
128
129 text_log.Print(m_object_uuid[0]);
130 text_log.Print("\n");
131
132 if ( id_count > 4 )
133 {
134 text_log.Print("...\n");
135 }
136 else
137 {
138 for ( int i = 1; i < id_count; i++ )
139 {
140 text_log.Print(m_object_uuid[i]);
141 text_log.Print("\n");
142 }
143 }
144
145 text_log.PopIndent();
146 }
147
148 m_bbox.Dump(text_log);
149 }
150
IsValid(ON_TextLog * text_log) const151 ON_BOOL32 ON_InstanceDefinition::IsValid( ON_TextLog* text_log ) const
152 {
153 if ( 0 == ON_UuidCompare( m_uuid, ON_nil_uuid) )
154 {
155 if (text_log)
156 {
157 text_log->Print("ON_InstanceDefinition has nil uuid.\n");
158 }
159 return false;
160 }
161 if ( !m_bbox.IsValid() )
162 {
163 if (text_log)
164 {
165 text_log->Print("ON_InstanceDefinition has invalid bounding box.\n");
166 }
167 return false;
168 }
169
170 switch( m_idef_update_type)
171 {
172 case static_def:
173 // no source archive information should be present
174 if ( m_source_archive.Length() > 0 )
175 {
176 if (text_log)
177 {
178 text_log->Print("ON_InstanceDefinition is static but m_source_archive is not empty.\n");
179 }
180 return false;
181 }
182 if ( m_source_archive_checksum.IsSet() )
183 {
184 if (text_log)
185 {
186 text_log->Print("ON_InstanceDefinition is static but m_source_archive_checksum is set.\n");
187 }
188 return false;
189 }
190
191 if ( 0 != m_idef_layer_style )
192 {
193 if (text_log)
194 {
195 text_log->Print("ON_InstanceDefinition is static but m_idef_layer_style is not zero.\n");
196 }
197 return false;
198 }
199 break;
200
201 case embedded_def: // embedded_def is obsolete -
202 if ( text_log )
203 {
204 text_log->Print("ON_InstanceDefinition.m_idef_update_type = obsolete \"embedded_idef\". Use \"static_def\" or \"linked_and_embedded_def\".\n");
205 }
206 return false;
207 break;
208
209 case linked_and_embedded_def:
210 case linked_def:
211 // source archive information is required
212 if( m_source_archive.IsEmpty())
213 {
214 if (text_log)
215 {
216 text_log->Print("ON_InstanceDefinition is linked or embedded but m_source_archive is empty.\n");
217 }
218 return false;
219 }
220 if( !m_source_archive_checksum.IsSet())
221 {
222 if (text_log)
223 {
224 text_log->Print("ON_InstanceDefinition is linked or embedded but m_source_archive_checksum is zero.\n");
225 }
226 return false;
227 }
228
229 if ( linked_def == m_idef_update_type )
230 {
231 if ( 1 != m_idef_layer_style && 2 != m_idef_layer_style )
232 {
233 if (text_log)
234 {
235 text_log->Print("ON_InstanceDefinition is linked_def but m_idef_layer_style is not 1 or 2.\n");
236 }
237 return false;
238 }
239 }
240 else
241 {
242 if ( 0 != m_idef_layer_style )
243 {
244 if (text_log)
245 {
246 text_log->Print("ON_InstanceDefinition is linked_and_embedded_def but m_idef_layer_style is not zero.\n");
247 }
248 return false;
249 }
250 }
251
252 break;
253
254 default:
255 if ( text_log )
256 {
257 text_log->Print("ON_InstanceDefinition.m_idef_update_type value is invalid.\n");
258 }
259 return false;
260 break;
261 }
262
263 // TODO
264 return true;
265 }
266
267
SizeOf() const268 unsigned int ON_InstanceDefinition::SizeOf() const
269 {
270 unsigned int sz = sizeof(*this) - sizeof(ON_Geometry);
271 sz += ON_Geometry::SizeOf();
272 sz += this->m_object_uuid.SizeOfArray();
273 sz += this->m_name.SizeOf();
274 sz += this->m_description.SizeOf();
275 sz += this->m_url.SizeOf();
276 sz += this->m_url_tag.SizeOf();
277 sz += this->m_source_archive.SizeOf();
278 return sz;
279 }
280
281
Write(ON_BinaryArchive & binary_archive) const282 ON_BOOL32 ON_InstanceDefinition::Write(
283 ON_BinaryArchive& binary_archive
284 ) const
285 {
286 bool rc = binary_archive.Write3dmChunkVersion(1,6);
287
288 // version 1.0 fields
289 if ( rc )
290 rc = binary_archive.WriteUuid( m_uuid );
291 if ( rc )
292 {
293 if ( binary_archive.Archive3dmVersion() >= 4
294 && ON_InstanceDefinition::linked_def == m_idef_update_type )
295 {
296 // linked instance definition geometry is never in the file
297 ON_SimpleArray<ON_UUID> empty_uuid_list;
298 rc = binary_archive.WriteArray( empty_uuid_list );
299 }
300 else
301 {
302 rc = binary_archive.WriteArray( m_object_uuid );
303 }
304 }
305 if ( rc )
306 rc = binary_archive.WriteString( m_name );
307 if ( rc )
308 rc = binary_archive.WriteString( m_description );
309 if ( rc )
310 rc = binary_archive.WriteString( m_url );
311 if ( rc )
312 rc = binary_archive.WriteString( m_url_tag );
313 if ( rc )
314 rc = binary_archive.WriteBoundingBox( m_bbox );
315
316 // m_idef_update_type was an unsigned int and got changed to an enum. Read and write
317 // as an unsigned int to support backwards compatibility
318 const unsigned int idef_update_type = (unsigned int)this->IdefUpdateType();
319 if ( rc )
320 rc = binary_archive.WriteInt( idef_update_type );
321 if ( rc )
322 {
323 // 7 February 2012
324 // Purge source archive information from static_defs
325 if ( ON_InstanceDefinition::static_def == idef_update_type )
326 {
327 ON_wString empty_string;
328 rc = binary_archive.WriteString( empty_string );
329 }
330 else
331 rc = binary_archive.WriteString( m_source_archive );
332 }
333
334 // version 1.1 fields
335 if (rc)
336 {
337 // 7 February 2012
338 // Purge source archive information from static_defs
339 if ( ON_InstanceDefinition::static_def == idef_update_type )
340 ON_CheckSum::UnsetCheckSum.Write(binary_archive);
341 else
342 rc = m_source_archive_checksum.Write( binary_archive );
343 }
344
345 // version 1.2 fields
346 if (rc)
347 rc = binary_archive.WriteInt( m_us.m_unit_system );
348
349 // version 1.3 fields - added 6 March 2006
350 if (rc)
351 rc = binary_archive.WriteDouble( m_us.m_custom_unit_scale );
352
353 if ( rc )
354 {
355 bool b = (ON_InstanceDefinition::static_def == idef_update_type)
356 ? false
357 : m_source_bRelativePath;
358 rc = binary_archive.WriteBool( b );
359 }
360
361 // version 1.4 fields
362 if (rc)
363 rc = m_us.Write(binary_archive);
364
365 // version 1.5 fields
366 if (rc)
367 rc = binary_archive.WriteInt(m_idef_update_depth);
368
369 // version 1.6 fields ( added 14 February 2012 )
370 if (rc)
371 rc = binary_archive.WriteInt( m_idef_layer_style );
372
373 return rc;
374 }
375
IdefUpdateType() const376 ON_InstanceDefinition::IDEF_UPDATE_TYPE ON_InstanceDefinition::IdefUpdateType() const
377 {
378 if ( ON_InstanceDefinition::embedded_def == m_idef_update_type )
379 {
380 ON_ERROR("Using obsolete ON_InstanceDefinition::embedded_def value - fix code.");
381 const_cast< ON_InstanceDefinition* >(this)->m_idef_update_type
382 = ( m_source_archive.Length() > 0 )
383 ? ON_InstanceDefinition::linked_and_embedded_def
384 : ON_InstanceDefinition::static_def;
385 }
386 return m_idef_update_type;
387 }
388
IdefUpdateType(int i)389 ON_InstanceDefinition::IDEF_UPDATE_TYPE ON_InstanceDefinition::IdefUpdateType(int i)
390 {
391 IDEF_UPDATE_TYPE t;
392 switch(i)
393 {
394 case ON_InstanceDefinition::static_def:
395 t = ON_InstanceDefinition::static_def;
396 break;
397 case ON_InstanceDefinition::embedded_def:
398 t = ON_InstanceDefinition::embedded_def;
399 break;
400 case ON_InstanceDefinition::linked_and_embedded_def:
401 t = ON_InstanceDefinition::linked_and_embedded_def;
402 break;
403 case ON_InstanceDefinition::linked_def:
404 t = ON_InstanceDefinition::linked_def;
405 break;
406 default:
407 t = ON_InstanceDefinition::static_def;
408 break;
409 }
410 return t;
411 }
412
413
Read(ON_BinaryArchive & binary_archive)414 ON_BOOL32 ON_InstanceDefinition::Read(
415 ON_BinaryArchive& binary_archive
416 )
417 {
418 int major_version = 0;
419 int minor_version = 0;
420
421 m_idef_layer_style = 0;
422
423 m_us.m_custom_unit_scale = 0.0;
424 m_us.m_custom_unit_name.Destroy();
425 m_us.m_unit_system = ON::no_unit_system;
426 m_source_bRelativePath = false;
427 m_source_archive.Destroy();
428
429 bool rc = binary_archive.Read3dmChunkVersion(&major_version,&minor_version);
430 if ( rc )
431 {
432 if ( major_version != 1 )
433 rc = false;
434 // version 1.0 fields
435 if ( rc )
436 rc = binary_archive.ReadUuid( m_uuid );
437 if ( rc )
438 rc = binary_archive.ReadArray( m_object_uuid );
439 if ( rc )
440 rc = binary_archive.ReadString( m_name );
441 if ( rc )
442 rc = binary_archive.ReadString( m_description );
443 if ( rc )
444 rc = binary_archive.ReadString( m_url );
445 if ( rc )
446 rc = binary_archive.ReadString( m_url_tag );
447 if ( rc )
448 rc = binary_archive.ReadBoundingBox( m_bbox );
449 // m_idef_update_type was an unsigned int and got changed to an enum. Read and write
450 // as an unsigned int to support backwards compatibility
451 unsigned int source = m_idef_update_type;
452 if ( rc )
453 rc = binary_archive.ReadInt( &source );
454 if( rc)
455 m_idef_update_type = ON_InstanceDefinition::IdefUpdateType(source);
456 if ( rc )
457 rc = binary_archive.ReadString( m_source_archive );
458
459 // version 1.1 fields
460 if ( minor_version >= 1 )
461 {
462 if ( rc )
463 rc = m_source_archive_checksum.Read( binary_archive );
464 }
465
466 // version 1.2 fields
467 if ( minor_version >= 2 )
468 {
469 int us = ON::no_unit_system;
470 if ( rc )
471 rc = binary_archive.ReadInt( &us );
472 m_us.m_unit_system = ON::UnitSystem(us);
473 if ( ON::custom_unit_system != m_us.m_unit_system && ON::no_unit_system != m_us.m_unit_system )
474 {
475 m_us.m_custom_unit_scale = ON::UnitScale( m_us.m_unit_system, ON::meters );
476 }
477 else
478 {
479 m_us.m_custom_unit_scale = 0.0;
480 }
481
482 if ( minor_version >= 3 )
483 {
484 // version 1.3 fields - added 6 March 2006
485 //int us = ON::no_unit_system;
486 if ( rc )
487 rc = binary_archive.ReadDouble( &m_us.m_custom_unit_scale );
488 if ( rc )
489 rc = binary_archive.ReadBool( &m_source_bRelativePath );
490 if ( rc && minor_version >= 4 )
491 {
492 rc = m_us.Read(binary_archive);
493 if (rc && minor_version >= 5 )
494 {
495 rc = binary_archive.ReadInt(&m_idef_update_depth);
496
497 if ( rc && minor_version >= 6 )
498 {
499 unsigned int i = 0;
500 rc = binary_archive.ReadInt(&i);
501 if ( i && i > 0 && i < 256 )
502 m_idef_layer_style = (unsigned char)i;
503 }
504 }
505 }
506 }
507 }
508
509 if ( ON_InstanceDefinition::embedded_def == m_idef_update_type )
510 {
511 // 7 February 2012
512 // "embedded_def" is obsolete.
513 if (m_source_archive.Length() > 0 )
514 m_idef_update_type = ON_InstanceDefinition::linked_and_embedded_def;
515 else
516 DestroySourceArchive(); // convert to static
517 }
518
519 if ( ON_InstanceDefinition::linked_def == m_idef_update_type )
520 {
521 if ( m_idef_layer_style < 1 || m_idef_layer_style > 2 )
522 {
523 // The goal of the next if/else clause is for Rhino users
524 // to see what they saw when they created the file.
525 if ( binary_archive.Archive3dmVersion() < 50 )
526 {
527 // V4 linked blocks and early V5 linked blocks treated
528 // layers and materials the way newer "active" idefs work,
529 // so when I read an archive with version < 50, the
530 // default will be 1 for "active".
531 m_idef_layer_style = 1;
532 }
533 else
534 {
535 // The more recent V5 linked blocks treated layers and materials
536 // the way "reference" style idefs work, so when I read an
537 // archive with version >= 50 (meaning recent V5), the default
538 // will be 2 for "reference".
539 m_idef_layer_style = 2;
540 }
541 }
542 }
543 else
544 {
545 m_idef_layer_style= 0;
546 }
547 }
548 return rc;
549 }
550
ObjectType() const551 ON::object_type ON_InstanceDefinition::ObjectType() const
552 {
553 return ON::instance_definition;
554 }
555
556
557 // virtual ON_Geometry overrides
Dimension() const558 int ON_InstanceDefinition::Dimension() const
559 {
560 return 3;
561 }
562
GetBBox(double * boxmin,double * boxmax,ON_BOOL32 bGrowBox) const563 ON_BOOL32 ON_InstanceDefinition::GetBBox(
564 double* boxmin,
565 double* boxmax,
566 ON_BOOL32 bGrowBox
567 ) const
568 {
569 if ( boxmin )
570 {
571 boxmin[0] = m_bbox.m_min.x;
572 boxmin[1] = m_bbox.m_min.y;
573 boxmin[2] = m_bbox.m_min.z;
574 }
575 if ( boxmax )
576 {
577 boxmax[0] = m_bbox.m_max.x;
578 boxmax[1] = m_bbox.m_max.y;
579 boxmax[2] = m_bbox.m_max.z;
580 }
581 return m_bbox.IsValid();
582 }
583
Transform(const ON_Xform & xform)584 ON_BOOL32 ON_InstanceDefinition::Transform(
585 const ON_Xform& xform
586 )
587 {
588 // instance DEFs cannot be transformed
589 return false;
590 }
591
Name() const592 const wchar_t* ON_InstanceDefinition::Name() const
593 {
594 return m_name;
595 }
596
SetName(const wchar_t * name)597 void ON_InstanceDefinition::SetName( const wchar_t* name )
598 {
599 ON_wString s(name);
600 s.TrimLeftAndRight();
601 if ( s.IsEmpty() )
602 m_name.Destroy();
603 else
604 m_name = s;
605 }
606
607
URL() const608 const wchar_t* ON_InstanceDefinition::URL() const
609 {
610 return m_url;
611 }
612
SetURL(const wchar_t * url)613 void ON_InstanceDefinition::SetURL( const wchar_t* url )
614 {
615 ON_wString s(url);
616 s.TrimLeftAndRight();
617 if ( s.IsEmpty() )
618 m_url.Destroy();
619 else
620 m_url = s;
621 }
622
URL_Tag() const623 const wchar_t* ON_InstanceDefinition::URL_Tag() const
624 {
625 return m_url_tag;
626 }
627
SetURL_Tag(const wchar_t * url_tag)628 void ON_InstanceDefinition::SetURL_Tag( const wchar_t* url_tag )
629 {
630 ON_wString s(url_tag);
631 s.TrimLeftAndRight();
632 if ( s.IsEmpty() )
633 m_url_tag.Destroy();
634 else
635 m_url_tag = s;
636 }
637
Uuid() const638 ON_UUID ON_InstanceDefinition::Uuid() const
639 {
640 return m_uuid;
641 }
642
SetUuid(ON_UUID uuid)643 void ON_InstanceDefinition::SetUuid( ON_UUID uuid )
644 {
645 m_uuid = uuid;
646 }
647
Description() const648 const wchar_t* ON_InstanceDefinition::Description() const
649 {
650 return m_description;
651 }
652
SetDescription(const wchar_t * description)653 void ON_InstanceDefinition::SetDescription( const wchar_t* description )
654 {
655 ON_wString s(description);
656 s.TrimLeftAndRight();
657 if ( s.IsEmpty() )
658 m_description.Destroy();
659 else
660 m_description = s;
661 }
662
SetBoundingBox(ON_BoundingBox bbox)663 void ON_InstanceDefinition::SetBoundingBox( ON_BoundingBox bbox )
664 {
665 m_bbox = bbox;
666 }
667
SetSourceArchive(const wchar_t * source_archive,ON_CheckSum checksum,ON_InstanceDefinition::IDEF_UPDATE_TYPE idef_update_type)668 void ON_InstanceDefinition::SetSourceArchive(
669 const wchar_t* source_archive,
670 ON_CheckSum checksum,
671 ON_InstanceDefinition::IDEF_UPDATE_TYPE idef_update_type
672 )
673 {
674 ON_wString s(source_archive);
675 s.TrimLeftAndRight();
676 if ( s.IsEmpty() )
677 {
678 DestroySourceArchive();
679 }
680 else
681 {
682 SetAlternateSourceArchivePath(0,false);
683 m_source_archive = s;
684 m_source_bRelativePath = false;
685 m_source_archive_checksum = checksum;
686 m_idef_update_type = ON_InstanceDefinition::IdefUpdateType(idef_update_type);
687 if ( ON_InstanceDefinition::linked_def != m_idef_update_type )
688 {
689 m_idef_layer_style = 0;
690 }
691 }
692 }
693
DestroySourceArchive()694 void ON_InstanceDefinition::DestroySourceArchive()
695 {
696 m_source_archive.Destroy();
697 m_source_archive_checksum.Zero();
698 m_source_bRelativePath = false;
699 m_idef_update_type = ON_InstanceDefinition::static_def;
700 m_idef_layer_style = 0;
701 m_idef_update_depth = 0;
702 SetAlternateSourceArchivePath(0,false);
703 }
704
SourceArchive() const705 const wchar_t* ON_InstanceDefinition::SourceArchive() const
706 {
707 return m_source_archive;
708 }
709
SourceArchiveCheckSum() const710 ON_CheckSum ON_InstanceDefinition::SourceArchiveCheckSum() const
711 {
712 return m_source_archive_checksum;
713 }
714
UnitSystem() const715 const ON_UnitSystem& ON_InstanceDefinition::UnitSystem() const
716 {
717 return m_us;
718 }
719
SetUnitSystem(ON::unit_system us)720 void ON_InstanceDefinition::SetUnitSystem( ON::unit_system us )
721 {
722 // make sure we are not getting garbage cast as an ON::unit_system
723 if ( us == ON::UnitSystem(us) )
724 {
725 m_us.m_unit_system = us;
726 if ( ON::custom_unit_system != m_us.m_unit_system )
727 {
728 m_us.m_custom_unit_scale = ( ON::no_unit_system == m_us.m_unit_system )
729 ? 0.0
730 : ON::UnitScale(ON::meters,m_us.m_unit_system);
731 }
732 }
733 }
734
SetUnitSystem(const ON_UnitSystem & us)735 void ON_InstanceDefinition::SetUnitSystem( const ON_UnitSystem& us )
736 {
737 // make sure we are not getting garbage cast as an ON::unit_system
738 if ( us.IsValid() )
739 {
740 m_us = us;
741 if ( ON::custom_unit_system != m_us.m_unit_system )
742 {
743 m_us.m_custom_unit_scale = ( ON::no_unit_system == m_us.m_unit_system )
744 ? 0.0
745 : ON::UnitScale(ON::meters,m_us.m_unit_system);
746 }
747 }
748 }
749
750 ON_OBJECT_IMPLEMENT( ON_InstanceRef, ON_Geometry, "F9CFB638-B9D4-4340-87E3-C56E7865D96A" );
751
752 const double ON_InstanceRef::m_singular_xform_tol = 1.0e-6;
753
ON_InstanceRef()754 ON_InstanceRef::ON_InstanceRef()
755 {
756 m_instance_definition_uuid = ON_nil_uuid;
757 m_xform.Identity();
758 }
759
IsValid(ON_TextLog * text_log) const760 ON_BOOL32 ON_InstanceRef::IsValid( ON_TextLog* text_log ) const
761 {
762 if ( 0 == ON_UuidCompare( m_instance_definition_uuid, ON_nil_uuid) )
763 {
764 if ( text_log )
765 text_log->Print("ON_InstanceRef has nil m_instance_definition_uuid.\n");
766 return false;
767 }
768
769 ON_Xform tmp = m_xform.Inverse()*m_xform;
770 if ( !tmp.IsIdentity( ON_InstanceRef::m_singular_xform_tol ) )
771 {
772 if ( text_log )
773 text_log->Print("ON_InstanceRef has singular m_xform.\n");
774 return false;
775 }
776 return true;
777 }
778
Write(ON_BinaryArchive & binary_archive) const779 ON_BOOL32 ON_InstanceRef::Write(
780 ON_BinaryArchive& binary_archive
781 ) const
782 {
783 bool rc = binary_archive.Write3dmChunkVersion(1,0);
784 if ( rc )
785 rc = binary_archive.WriteUuid( m_instance_definition_uuid );
786 if ( rc )
787 rc = binary_archive.WriteXform( m_xform );
788 if ( rc )
789 rc = binary_archive.WriteBoundingBox( m_bbox );
790 return rc;
791 }
792
Read(ON_BinaryArchive & binary_archive)793 ON_BOOL32 ON_InstanceRef::Read(
794 ON_BinaryArchive& binary_archive
795 )
796 {
797 int major_version = 0;
798 int minor_version = 0;
799 bool rc = binary_archive.Read3dmChunkVersion(&major_version,&minor_version);
800 if ( rc )
801 {
802 if ( major_version != 1 )
803 rc = false;
804 if (rc )
805 rc = binary_archive.ReadUuid( m_instance_definition_uuid );
806 if ( rc )
807 rc = binary_archive.ReadXform( m_xform );
808 if ( rc )
809 rc = binary_archive.ReadBoundingBox( m_bbox );
810 }
811 return rc;
812 }
813
ObjectType() const814 ON::object_type ON_InstanceRef::ObjectType() const
815 {
816 return ON::instance_reference;
817 }
818
819
820 // virtual ON_Geometry overrides
Dimension() const821 int ON_InstanceRef::Dimension() const
822 {
823 return 3;
824 }
825
GetBBox(double * boxmin,double * boxmax,ON_BOOL32 bGrowBox) const826 ON_BOOL32 ON_InstanceRef::GetBBox(
827 double* boxmin,
828 double* boxmax,
829 ON_BOOL32 bGrowBox
830 ) const
831 {
832 if ( !boxmin || !boxmax )
833 {
834 bGrowBox = false;
835 }
836 else if ( bGrowBox )
837 {
838 bGrowBox = ON_BoundingBox(ON_3dPoint(boxmin),ON_3dPoint(boxmax)).IsValid();
839 }
840
841 if( m_bbox.IsValid() )
842 {
843 if( bGrowBox )
844 {
845 if( boxmin[0] > m_bbox.m_min.x ) boxmin[0] = m_bbox.m_min.x;
846 if( boxmin[1] > m_bbox.m_min.y ) boxmin[1] = m_bbox.m_min.y;
847 if( boxmin[2] > m_bbox.m_min.z ) boxmin[2] = m_bbox.m_min.z;
848
849 if( boxmax[0] < m_bbox.m_max.x ) boxmax[0] = m_bbox.m_max.x;
850 if( boxmax[1] < m_bbox.m_max.y ) boxmax[1] = m_bbox.m_max.y;
851 if( boxmax[2] < m_bbox.m_max.z ) boxmax[2] = m_bbox.m_max.z;
852 }
853 else
854 {
855 if( boxmin )
856 {
857 boxmin[0] = m_bbox.m_min.x;
858 boxmin[1] = m_bbox.m_min.y;
859 boxmin[2] = m_bbox.m_min.z;
860 }
861 if( boxmax )
862 {
863 boxmax[0] = m_bbox.m_max.x;
864 boxmax[1] = m_bbox.m_max.y;
865 boxmax[2] = m_bbox.m_max.z;
866 }
867 bGrowBox = true;
868 }
869 }
870
871 return bGrowBox;
872 }
873
Transform(const ON_Xform & xform)874 ON_BOOL32 ON_InstanceRef::Transform(
875 const ON_Xform& xform
876 )
877 {
878 ON_Geometry::Transform(xform);
879 m_xform = xform*m_xform;
880 m_bbox.Transform(xform);
881 return true;
882 }
883
IsDeformable() const884 bool ON_InstanceRef::IsDeformable() const
885 {
886 // 25 Feb 2006 Dale Lear - this seems wrong to me.
887 return true;
888 }
889
MakeDeformable()890 bool ON_InstanceRef::MakeDeformable()
891 {
892 // 25 Feb 2006 Dale Lear - this seems wrong to me.
893 return true;
894 }
895
896
897 class /*NEVER EXPORT THIS CLASS DEFINITION*/ ON__IDefLayerSettingsUserData : public ON_UserData
898 {
899 #if !defined(ON_BOZO_VACCINE_11EE2C1FF90D4C6AA7CDEC8532E1E32D)
900 #error Never copy this class definition or put this definition in a header file!
901 #endif
902 ON_OBJECT_DECLARE(ON__IDefLayerSettingsUserData);
903
904 public:
905 ON__IDefLayerSettingsUserData();
906 ~ON__IDefLayerSettingsUserData();
907 // default copy constructor and operator= work fine.
908
909 ON__IDefLayerSettingsUserData(const ON__IDefLayerSettingsUserData& src);
910 ON__IDefLayerSettingsUserData& operator=(const ON__IDefLayerSettingsUserData& src);
911
912
913 static ON__IDefLayerSettingsUserData* FindOrCreate(const ON_InstanceDefinition& idef,bool bCreate);
914
915 private:
CreateHelper()916 void CreateHelper()
917 {
918 m_layers.Destroy();
919 m_idef_layer_table_parent_layer = 0;
920 }
921
CopyHelper(const ON__IDefLayerSettingsUserData & src)922 void CopyHelper(const ON__IDefLayerSettingsUserData& src)
923 {
924 m_layers.Reserve(src.m_layers.Count());
925 for ( int i = 0; i < src.m_layers.Count(); i++ )
926 {
927 const ON_Layer* src_layer = src.m_layers[i];
928 if ( 0 != src_layer )
929 {
930 m_layers.Append( new ON_Layer( *src_layer ) );
931 }
932 }
933
934 if ( 0 != src.m_idef_layer_table_parent_layer )
935 {
936 m_idef_layer_table_parent_layer = new ON_Layer( *src.m_idef_layer_table_parent_layer );
937 }
938
939 m_runtime_layer_id_map = src.m_runtime_layer_id_map;
940 m_runtime_layer_id_map.ImproveSearchSpeed();
941 }
942
DestroyHelper()943 void DestroyHelper()
944 {
945 for ( int i = 0; i < m_layers.Count(); i++ )
946 {
947 delete m_layers[i];
948 m_layers[i] = 0;
949 }
950 m_layers.Destroy();
951 if ( 0 != m_idef_layer_table_parent_layer )
952 {
953 delete m_idef_layer_table_parent_layer;
954 m_idef_layer_table_parent_layer = 0;
955 }
956 m_runtime_layer_id_map.Empty();
957 }
958
959 public:
960 // virtual ON_Object override
961 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
962 // virtual ON_Object override
963 unsigned int SizeOf() const;
964 // virtual ON_Object override
965 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
966 // virtual ON_Object override
967 ON_BOOL32 Write(ON_BinaryArchive& binary_archive) const;
968 // virtual ON_Object override
969 ON_BOOL32 Read(ON_BinaryArchive& binary_archive);
970 // virtual ON_UserData override
971 ON_BOOL32 Archive() const;
972 // virtual ON_UserData override
973 ON_BOOL32 GetDescription( ON_wString& description );
974
975 public:
976 // m_layers[] satisfies
977 // * has no null members
978 // * is always sorted by layer id
979 // * has no duplicate layer ids
980 // * has no nil layer ids
981 // * the m_layer_id and m_parent_layer_id
982 // values are from the linked file.
983 ON_SimpleArray<ON_Layer*> m_layers;
984
985 // Settings for the layer that is the
986 // parent of the layers in the linked
987 // files layer table. This layer is
988 // not in the linked file and is not
989 // saved in the layer table of file containing
990 // the idef. If null, it is created
991 ON_Layer* m_idef_layer_table_parent_layer;
992
993 // When a linked idef is inserted and a layer id
994 // collision occures, the runtime id of the layer
995 // has to be changed. This list keeps track of the
996 // changes so we can determine which runtime layer
997 // correspondes to a layer in m_layers[].
998 // The first index id in the pair is the runtime
999 // id and the second id in the pair is the m_layer[]
1000 // id.
1001 ON_UuidPairList m_runtime_layer_id_map;
1002 };
1003
1004 #undef ON_BOZO_VACCINE_11EE2C1FF90D4C6AA7CDEC8532E1E32D
1005
1006 ON_OBJECT_IMPLEMENT(ON__IDefLayerSettingsUserData,ON_UserData,"11EE2C1F-F90D-4C6A-A7CD-EC8532E1E32D");
1007
FindOrCreate(const ON_InstanceDefinition & idef,bool bCreate)1008 ON__IDefLayerSettingsUserData* ON__IDefLayerSettingsUserData::FindOrCreate(const ON_InstanceDefinition& idef,bool bCreate)
1009 {
1010 ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::Cast(idef.GetUserData(ON__IDefLayerSettingsUserData::m_ON__IDefLayerSettingsUserData_class_id.Uuid()));
1011 if ( !ud && bCreate )
1012 {
1013 ud = new ON__IDefLayerSettingsUserData();
1014 const_cast<ON_InstanceDefinition&>(idef).AttachUserData(ud);
1015 }
1016 return ud;
1017 }
1018
ON__IDefLayerSettingsUserData()1019 ON__IDefLayerSettingsUserData::ON__IDefLayerSettingsUserData()
1020 {
1021 m_userdata_uuid = ON__IDefLayerSettingsUserData::m_ON__IDefLayerSettingsUserData_class_id.Uuid();
1022 m_application_uuid = ON_opennurbs5_id;
1023 m_userdata_copycount = 1;
1024 CreateHelper();
1025 }
1026
~ON__IDefLayerSettingsUserData()1027 ON__IDefLayerSettingsUserData::~ON__IDefLayerSettingsUserData()
1028 {
1029 DestroyHelper();
1030 }
1031
ON__IDefLayerSettingsUserData(const ON__IDefLayerSettingsUserData & src)1032 ON__IDefLayerSettingsUserData::ON__IDefLayerSettingsUserData(const ON__IDefLayerSettingsUserData& src)
1033 : ON_UserData(src)
1034 {
1035 m_userdata_uuid = ON__IDefLayerSettingsUserData::m_ON__IDefLayerSettingsUserData_class_id.Uuid();
1036 m_application_uuid = ON_opennurbs5_id;
1037 CreateHelper();
1038 CopyHelper(src);
1039 }
1040
operator =(const ON__IDefLayerSettingsUserData & src)1041 ON__IDefLayerSettingsUserData& ON__IDefLayerSettingsUserData::operator=(const ON__IDefLayerSettingsUserData& src)
1042 {
1043 if ( this != &src )
1044 {
1045 DestroyHelper();
1046 ON_UserData::operator=(src);
1047 CopyHelper(src);
1048 }
1049 return *this;
1050 }
1051
1052 // virtual ON_Object override
IsValid(ON_TextLog * text_log) const1053 ON_BOOL32 ON__IDefLayerSettingsUserData::IsValid( ON_TextLog* text_log ) const
1054 {
1055 return true;
1056 }
1057
1058 // virtual ON_Object override
SizeOf() const1059 unsigned int ON__IDefLayerSettingsUserData::SizeOf() const
1060 {
1061 return (unsigned int)(sizeof(*this));
1062 }
1063
1064 // virtual ON_Object override
DataCRC(ON__UINT32 current_remainder) const1065 ON__UINT32 ON__IDefLayerSettingsUserData::DataCRC(ON__UINT32 current_remainder) const
1066 {
1067 ON__UINT32 crc = current_remainder;
1068 for ( int i = 0; i < m_layers.Count(); i++ )
1069 crc = m_layers.DataCRC(crc);
1070 return crc;
1071 }
1072
1073 // virtual ON_Object override
Write(ON_BinaryArchive & binary_archive) const1074 ON_BOOL32 ON__IDefLayerSettingsUserData::Write(ON_BinaryArchive& binary_archive) const
1075 {
1076 bool rc = binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,1);
1077 if ( !rc )
1078 return false;
1079
1080 rc = false;
1081 for(;;)
1082 {
1083 if ( !binary_archive.WriteArray(m_layers.Count(),m_layers.Array()) )
1084 break;
1085
1086 // added in version 1.1 chunks
1087 bool bHaveParentLayer = ( 0 != m_idef_layer_table_parent_layer );
1088 if ( !binary_archive.WriteBool(bHaveParentLayer) )
1089 break;
1090
1091 if ( bHaveParentLayer )
1092 {
1093 if ( !binary_archive.WriteObject(m_idef_layer_table_parent_layer) )
1094 break;
1095 }
1096
1097 rc = true;
1098 break;
1099 }
1100
1101 if ( !binary_archive.EndWrite3dmChunk() )
1102 rc = false;
1103
1104 return rc;
1105 }
1106
1107 // virtual ON_Object override
Read(ON_BinaryArchive & binary_archive)1108 ON_BOOL32 ON__IDefLayerSettingsUserData::Read(ON_BinaryArchive& binary_archive)
1109 {
1110 DestroyHelper();
1111
1112 int major_version = 0;
1113 int minor_version = 0;
1114 bool rc = binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
1115 if ( !rc )
1116 return false;
1117
1118 rc = false;
1119 while ( 1 == major_version )
1120 {
1121 if ( !binary_archive.ReadArray(m_layers) )
1122 break;
1123
1124 if ( minor_version <= 0 )
1125 {
1126 rc = true;
1127 break;
1128 }
1129
1130 // added in version 1.1 chunks
1131 bool bHaveParentLayer = false;
1132 if ( !binary_archive.ReadBool(&bHaveParentLayer) )
1133 break;
1134
1135 if ( bHaveParentLayer )
1136 {
1137 ON_Object* p = 0;
1138 if ( !binary_archive.ReadObject(&p) || 0 == p )
1139 {
1140 if (p)
1141 {
1142 delete p;
1143 break;
1144 }
1145 }
1146
1147 m_idef_layer_table_parent_layer = ON_Layer::Cast(p);
1148 if ( 0 == m_idef_layer_table_parent_layer )
1149 {
1150 delete p;
1151 break;
1152 }
1153 }
1154
1155 rc = true;
1156 break;
1157 }
1158
1159 if ( !binary_archive.EndRead3dmChunk() )
1160 rc = false;
1161
1162 return rc;
1163 }
1164
1165 // virtual ON_UserData override
Archive() const1166 ON_BOOL32 ON__IDefLayerSettingsUserData::Archive() const
1167 {
1168 // don't save empty settings
1169 return m_layers.Count() > 0;
1170 }
1171
1172 // virtual ON_UserData override
GetDescription(ON_wString & description)1173 ON_BOOL32 ON__IDefLayerSettingsUserData::GetDescription( ON_wString& description )
1174 {
1175 description = L"Linked Instance Definition Layer Settings";
1176 return true;
1177 }
1178
1179
1180
HasLinkedIdefLayerSettings() const1181 bool ON_InstanceDefinition::HasLinkedIdefLayerSettings() const
1182 {
1183 const ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
1184 return ud ? (ud->m_layers.Count() > 0) : false;
1185 }
1186
1187 ///////*
1188 //////Description:
1189 ////// Get layer settings for the context where the idef
1190 ////// is being used.
1191 //////Parameters:
1192 ////// layer_settings - [out]
1193 ////// Each layer has the settings from the linked reference file
1194 ////// and layer.GetSavedSettings() reports any changes for the
1195 ////// corresponding layers in the current context.
1196 //////*/
1197 //////void GetLinkedIdefLayerSettings( class ON_ObjectArray<ON_Layer>& layer_settings ) const;
1198 //////
1199 ///////*
1200 //////Description:
1201 ////// Get the most recently read layer settings from the reference file.
1202 //////Parameters:
1203 ////// layer_settings - [out]
1204 ////// The pointers in this array point memory managed by this
1205 ////// instance definition and may be deleted by other
1206 ////// ON_InstanceDefinition layer settings tools. Use the
1207 ////// returned information immediately or copy it to memory
1208 ////// you are managing.
1209 //////*/
1210 //////void GetLinkedIdefLayerReferenceSettings( class ON_SimpleArray<const ON_Layer*>& layer_settings ) const;
1211 //////
1212 //////
1213 //////void ON_InstanceDefinition::GetLinkedIdefLayerReferenceSettings( class ON_SimpleArray<const ON_Layer*>& layer_settings ) const
1214 //////{
1215 ////// const ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::LayerSettings(*this,false);
1216 ////// const int count = 0 != ud ? ud->m_layers.Count() : 0;
1217 ////// if ( count > 0 )
1218 ////// {
1219 ////// layer_settings.Reserve(count);
1220 ////// for ( int i = 0; i < count; i++ )
1221 ////// {
1222 ////// if ( 0 != ud->m_layers[i] )
1223 ////// layer_settings.Append(ud->m_layers[i]);
1224 ////// }
1225 ////// }
1226 ////// else
1227 ////// {
1228 ////// layer_settings.SetCount(0);
1229 ////// }
1230 //////}
1231 //////
1232 //////void ON_InstanceDefinition::GetLinkedIdefLayerSettings( class ON_ObjectArray<ON_Layer>& layer_settings ) const
1233 //////{
1234 ////// layer_settings.SetCount(0);
1235 //////
1236 ////// // Get the layers with settings from the referenced file.
1237 ////// ON_SimpleArray<const ON_Layer*> layers;
1238 ////// GetLinkedIdefLayerReferenceSettings(layers);
1239 //////
1240 ////// // Update those settings with any modifications made in the idef's current context.
1241 ////// layer_settings.Reserve(layers.Count());
1242 ////// unsigned int settings;
1243 ////// for ( int i = 0; i < layers.Count(); i++ )
1244 ////// {
1245 ////// if ( 0 != layers[i] )
1246 ////// {
1247 ////// ON_Layer& layer = layer_settings.AppendNew();
1248 ////// layer = *layers[i];
1249 ////// settings = 0;
1250 ////// layer.GetSavedSettings(layer,settings);
1251 ////// }
1252 ////// }
1253 //////}
1254
compareLayerPtrId(const void * A,const void * B)1255 static int compareLayerPtrId(const void* A, const void*B)
1256 {
1257 if ( 0 == A )
1258 {
1259 return 0 == B ? 0 : -1;
1260 }
1261 if ( 0 == B )
1262 {
1263 return 1;
1264 }
1265
1266 const ON_Layer* a = (0!=A) ? ( *((ON_Layer**)A) ) : 0;
1267 const ON_Layer* b = (0!=B) ? ( *((ON_Layer**)B) ) : 0;
1268 if ( 0 == a )
1269 {
1270 return (0 == b) ? 0 : -1;
1271 }
1272 if ( 0 == b )
1273 {
1274 return 1;
1275 }
1276
1277 // NOTE WELL:
1278 // Compare only m_layer_id. Other values may differ and
1279 // adding compares to them will break the code that uses
1280 // this function.
1281 return ON_UuidCompare(a->m_layer_id,b->m_layer_id);
1282 }
1283
compareUuidIndexId(const void * a,const void * b)1284 static int compareUuidIndexId(const void* a, const void* b)
1285 {
1286 return ON_UuidIndex::CompareId((const ON_UuidIndex*)a,(const ON_UuidIndex*)b);
1287 }
1288
UpdateLinkedIdefReferenceFileLayerRuntimeId(const ON_UuidPairList & id_map)1289 void ON_InstanceDefinition::UpdateLinkedIdefReferenceFileLayerRuntimeId( const ON_UuidPairList& id_map )
1290 {
1291 ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
1292 if ( 0 == ud || ud->m_layers.Count() <= 0 )
1293 return;
1294 ud->m_runtime_layer_id_map = id_map;
1295 ud->m_runtime_layer_id_map.ImproveSearchSpeed();
1296 }
1297
UpdateLinkedIdefParentLayerSettings(const ON_Layer * linked_idef_parent_layer)1298 void ON_InstanceDefinition::UpdateLinkedIdefParentLayerSettings( const ON_Layer* linked_idef_parent_layer )
1299 {
1300 bool bCreate = ( 0 != linked_idef_parent_layer );
1301 ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,bCreate);
1302 if ( 0 != ud && ud->m_idef_layer_table_parent_layer != linked_idef_parent_layer )
1303 {
1304 if ( ud->m_idef_layer_table_parent_layer )
1305 {
1306 delete ud->m_idef_layer_table_parent_layer;
1307 ud->m_idef_layer_table_parent_layer = 0;
1308 }
1309 if ( 0 != linked_idef_parent_layer )
1310 {
1311 ud->m_idef_layer_table_parent_layer = new ON_Layer( *linked_idef_parent_layer );
1312 }
1313 }
1314 }
1315
LinkedIdefParentLayerSettings() const1316 const ON_Layer* ON_InstanceDefinition::LinkedIdefParentLayerSettings() const
1317 {
1318 ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
1319 return (0 != ud) ? ud->m_idef_layer_table_parent_layer : 0;
1320 }
1321
UpdateLinkedIdefReferenceFileLayerSettings(unsigned int layer_count,ON_Layer ** layer_settings)1322 void ON_InstanceDefinition::UpdateLinkedIdefReferenceFileLayerSettings( unsigned int layer_count, ON_Layer** layer_settings )
1323 {
1324 ON__IDefLayerSettingsUserData* ud;
1325
1326 if ( layer_count <= 0 || 0 == layer_settings )
1327 {
1328 // delete linked idef layer settings
1329 ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
1330 if ( 0 != ud )
1331 delete ud;
1332 return;
1333 }
1334
1335 // Create an index_map[] into the layer_settings[] array that is sorted
1336 // by layer_settings[]->m_layer_id
1337 ON_Workspace ws;
1338 int* index_map = (int*)ws.GetMemory(layer_count*sizeof(index_map[0]));
1339 ON_Sort(ON::quick_sort,index_map,layer_settings,layer_count,sizeof(layer_settings[0]),compareLayerPtrId);
1340
1341 // Use index_map[] to get a unique list of layers with valid ids
1342 ON_UuidIndex* iddex = (ON_UuidIndex*)ws.GetMemory(layer_count*sizeof(iddex[0]));
1343 unsigned int iddex_count = 0;
1344 unsigned int i;
1345 ON_Layer* layer;
1346 for ( i = 0; i < layer_count; i++ )
1347 {
1348 layer = layer_settings[index_map[i]];
1349 if ( 0 == layer )
1350 continue;
1351 layer->SaveSettings(0,false); // remove any saved settings on input layers
1352 if ( ON_UuidIsNil(layer->m_layer_id) )
1353 continue;
1354 if ( iddex_count > 0 && iddex[iddex_count-1].m_id == layer->m_layer_id )
1355 continue;
1356 iddex[iddex_count].m_i = index_map[i];
1357 iddex[iddex_count].m_id = layer->m_layer_id;
1358 iddex_count++;
1359 }
1360
1361 if ( iddex_count <= 0 )
1362 {
1363 // delete settings
1364 UpdateLinkedIdefReferenceFileLayerSettings(0,0);
1365 return;
1366 }
1367
1368 // Create or get user data where the saved layer settings
1369 // are stored.
1370 ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,true);
1371 if ( 0 == ud )
1372 return;
1373
1374 // Go through the saved settings that were previously
1375 // on this idef apply those settings to the layer_settings[]
1376 // list. Then delete the information from ud->m_layers[].
1377 ON_UuidIndex idx;
1378 idx.m_i = 0;
1379 unsigned int settings;
1380 for ( i = 0; i < ud->m_layers.UnsignedCount(); i++ )
1381 {
1382 if ( 0 == ud->m_layers[i] )
1383 continue;
1384 layer = ud->m_layers[i];
1385 ud->m_layers[i] = 0;
1386 for(;;)
1387 {
1388 settings = layer->SavedSettings();
1389 if ( 0 == settings )
1390 break; // no settings were modified
1391 idx.m_id = layer->m_layer_id;
1392 const ON_UuidIndex* idx0 = (const ON_UuidIndex*)bsearch(&idx,iddex,iddex_count,sizeof(iddex[0]),compareUuidIndexId);
1393 if ( 0 == idx0)
1394 break; // this layer is not in the current layer_settings[] list
1395 layer_settings[idx0->m_i]->SaveSettings(settings,false); // saves the layer settings found in linked file
1396 layer_settings[idx0->m_i]->Set(settings,*layer); // applies modifications found on idef
1397 break;
1398 }
1399 delete layer;
1400 }
1401
1402 // Save a copy of this information on the user data
1403 // so it will persist in the file containing the idef.
1404 ud->m_layers.SetCount(0);
1405 ud->m_layers.Reserve(iddex_count);
1406 for ( i = 0; i < iddex_count; i++ )
1407 {
1408 layer = new ON_Layer( *layer_settings[iddex[i].m_i] );
1409 ud->m_layers.Append(layer);
1410 }
1411 }
1412
1413
1414
UpdateLinkedIdefLayerSettings(unsigned int layer_count,const ON_Layer * const * layer_settings)1415 void ON_InstanceDefinition::UpdateLinkedIdefLayerSettings( unsigned int layer_count, const ON_Layer*const* layer_settings )
1416 {
1417 if ( layer_count <= 0 || 0 == layer_settings )
1418 {
1419 // delete linked idef layer settings
1420 UpdateLinkedIdefReferenceFileLayerSettings(0,0);
1421 return;
1422 }
1423
1424 // Get layer information (saved on this idef) from the linked file
1425 ON__IDefLayerSettingsUserData* ud = ON__IDefLayerSettingsUserData::FindOrCreate(*this,false);
1426 if ( 0 == ud )
1427 return;
1428 if ( ud->m_layers.Count() <= 0 )
1429 {
1430 delete ud;
1431 return;
1432 }
1433
1434 // Apply any saved settings
1435 ON_Layer** ud_layers = ud->m_layers.Array();
1436 size_t ud_layers_count = ud->m_layers.Count();
1437 ON_Layer layerId;
1438 const ON_Layer* layerPtrId = &layerId;
1439 for ( unsigned int i = 0; i < layer_count; i++ )
1440 {
1441 const ON_Layer* layer1 = layer_settings[i];
1442 if ( !ud->m_runtime_layer_id_map.FindId1(layer1->m_layer_id,&layerId.m_layer_id) )
1443 layerId.m_layer_id = layer1->m_layer_id;
1444 ON_Layer** pp = (ON_Layer**)bsearch(&layerPtrId,ud_layers,ud_layers_count,sizeof(ud_layers[0]),compareLayerPtrId);
1445 ON_Layer* layer0 = (0 != pp) ? *pp : 0;
1446 if ( 0 == layer0 )
1447 continue;
1448 unsigned int settings0 = layer0->SavedSettings();
1449 unsigned int settings1 = ON_Layer::Differences(*layer0,*layer1);
1450 // settings0 = settings changes
1451 // new_settings = settings changed since we opened the model
1452 unsigned int new_settings = (settings1 ^ (settings0 & settings1));
1453 if ( 0 != new_settings )
1454 layer0->SaveSettings( new_settings, true );
1455 layer0->Set((settings0|settings1),*layer1);
1456 }
1457 }
1458
1459
1460
1461 ///////////////////////////////////////////////////////////////////
1462
1463
1464 class /*NEVER EXPORT THIS CLASS DEFINITION*/ ON__IDefAlternativePathUserData : public ON_UserData
1465 {
1466 #if !defined(ON_BOZO_VACCINE_F42D967121EB46929B9ABC3507FF28F5)
1467 #error Never copy this class definition or put this definition in a header file!
1468 #endif
1469 ON_OBJECT_DECLARE(ON__IDefAlternativePathUserData);
1470
1471 public:
1472 ON__IDefAlternativePathUserData();
1473 ~ON__IDefAlternativePathUserData();
1474 // default copy constructor and operator= work fine.
1475
1476 ON__IDefAlternativePathUserData(const ON__IDefAlternativePathUserData& src);
1477 ON__IDefAlternativePathUserData& operator=(const ON__IDefAlternativePathUserData& src);
1478
1479
1480 static ON__IDefAlternativePathUserData* FindOrCreate(const ON_InstanceDefinition& idef,bool bCreate);
1481
1482 private:
CreateHelper()1483 void CreateHelper()
1484 {
1485 m_alternate_path.Destroy();
1486 m_bRelativePath = false;
1487 }
1488
CopyHelper(const ON__IDefAlternativePathUserData & src)1489 void CopyHelper(const ON__IDefAlternativePathUserData& src)
1490 {
1491 m_alternate_path = src.m_alternate_path;
1492 m_bRelativePath = src.m_bRelativePath;
1493 }
1494
DestroyHelper()1495 void DestroyHelper()
1496 {
1497 m_alternate_path.Destroy();
1498 m_bRelativePath = false;
1499 }
1500
1501 public:
1502 // virtual ON_Object override
1503 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
1504 // virtual ON_Object override
1505 unsigned int SizeOf() const;
1506 // virtual ON_Object override
1507 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
1508 // virtual ON_Object override
1509 ON_BOOL32 Write(ON_BinaryArchive& binary_archive) const;
1510 // virtual ON_Object override
1511 ON_BOOL32 Read(ON_BinaryArchive& binary_archive);
1512 // virtual ON_UserData override
1513 ON_BOOL32 Archive() const;
1514 // virtual ON_UserData override
1515 ON_BOOL32 GetDescription( ON_wString& description );
1516
1517 public:
1518 ON_wString m_alternate_path;
1519 bool m_bRelativePath;
1520 };
1521
1522 #undef ON_BOZO_VACCINE_F42D967121EB46929B9ABC3507FF28F5
1523
1524 ON_OBJECT_IMPLEMENT(ON__IDefAlternativePathUserData,ON_UserData,"F42D9671-21EB-4692-9B9A-BC3507FF28F5");
1525
FindOrCreate(const ON_InstanceDefinition & idef,bool bCreate)1526 ON__IDefAlternativePathUserData* ON__IDefAlternativePathUserData::FindOrCreate(const ON_InstanceDefinition& idef,bool bCreate)
1527 {
1528 ON__IDefAlternativePathUserData* ud = ON__IDefAlternativePathUserData::Cast(idef.GetUserData(ON__IDefAlternativePathUserData::m_ON__IDefAlternativePathUserData_class_id.Uuid()));
1529 if ( !ud && bCreate )
1530 {
1531 ud = new ON__IDefAlternativePathUserData();
1532 const_cast<ON_InstanceDefinition&>(idef).AttachUserData(ud);
1533 }
1534 return ud;
1535 }
1536
ON__IDefAlternativePathUserData()1537 ON__IDefAlternativePathUserData::ON__IDefAlternativePathUserData()
1538 {
1539 m_userdata_uuid = ON__IDefAlternativePathUserData::m_ON__IDefAlternativePathUserData_class_id.Uuid();
1540 m_application_uuid = ON_opennurbs5_id;
1541 m_userdata_copycount = 1;
1542 CreateHelper();
1543 }
1544
~ON__IDefAlternativePathUserData()1545 ON__IDefAlternativePathUserData::~ON__IDefAlternativePathUserData()
1546 {
1547 DestroyHelper();
1548 }
1549
ON__IDefAlternativePathUserData(const ON__IDefAlternativePathUserData & src)1550 ON__IDefAlternativePathUserData::ON__IDefAlternativePathUserData(const ON__IDefAlternativePathUserData& src)
1551 : ON_UserData(src)
1552 {
1553 m_userdata_uuid = ON__IDefAlternativePathUserData::m_ON__IDefAlternativePathUserData_class_id.Uuid();
1554 m_application_uuid = ON_opennurbs5_id;
1555 CreateHelper();
1556 CopyHelper(src);
1557 }
1558
operator =(const ON__IDefAlternativePathUserData & src)1559 ON__IDefAlternativePathUserData& ON__IDefAlternativePathUserData::operator=(const ON__IDefAlternativePathUserData& src)
1560 {
1561 if ( this != &src )
1562 {
1563 DestroyHelper();
1564 ON_UserData::operator=(src);
1565 CopyHelper(src);
1566 }
1567 return *this;
1568 }
1569
1570 // virtual ON_Object override
IsValid(ON_TextLog * text_log) const1571 ON_BOOL32 ON__IDefAlternativePathUserData::IsValid( ON_TextLog* text_log ) const
1572 {
1573 return !m_alternate_path.IsEmpty();
1574 }
1575
1576 // virtual ON_Object override
SizeOf() const1577 unsigned int ON__IDefAlternativePathUserData::SizeOf() const
1578 {
1579 return (unsigned int)(sizeof(*this) + m_alternate_path.SizeOf());
1580 }
1581
1582 // virtual ON_Object override
DataCRC(ON__UINT32 current_remainder) const1583 ON__UINT32 ON__IDefAlternativePathUserData::DataCRC(ON__UINT32 current_remainder) const
1584 {
1585 ON__UINT32 crc = ON_CRC32(current_remainder,sizeof(m_bRelativePath),&m_bRelativePath);
1586 crc = m_alternate_path.DataCRC(crc);
1587 return crc;
1588 }
1589
1590 // virtual ON_Object override
Write(ON_BinaryArchive & binary_archive) const1591 ON_BOOL32 ON__IDefAlternativePathUserData::Write(ON_BinaryArchive& binary_archive) const
1592 {
1593 bool rc = binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
1594 if ( !rc )
1595 return false;
1596
1597 rc = false;
1598 for(;;)
1599 {
1600 if ( !binary_archive.WriteString(m_alternate_path) )
1601 break;
1602 if ( !binary_archive.WriteBool(m_bRelativePath) )
1603 break;
1604 rc = true;
1605 break;
1606 }
1607
1608 if ( !binary_archive.EndWrite3dmChunk() )
1609 rc = false;
1610
1611 return rc;
1612 }
1613
1614 // virtual ON_Object override
Read(ON_BinaryArchive & binary_archive)1615 ON_BOOL32 ON__IDefAlternativePathUserData::Read(ON_BinaryArchive& binary_archive)
1616 {
1617 DestroyHelper();
1618
1619 int major_version = 0;
1620 int minor_version = 0;
1621 bool rc = binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
1622 if ( !rc )
1623 return false;
1624
1625 rc = false;
1626 while ( 1 == major_version )
1627 {
1628 if ( !binary_archive.ReadString(m_alternate_path) )
1629 break;
1630 if ( !binary_archive.ReadBool(&m_bRelativePath) )
1631 break;
1632 rc = true;
1633 break;
1634 }
1635
1636 if ( !binary_archive.EndRead3dmChunk() )
1637 rc = false;
1638
1639 return rc;
1640 }
1641
1642 // virtual ON_UserData override
Archive() const1643 ON_BOOL32 ON__IDefAlternativePathUserData::Archive() const
1644 {
1645 // don't save empty settings
1646 return !m_alternate_path.IsEmpty();
1647 }
1648
1649 // virtual ON_UserData override
GetDescription(ON_wString & description)1650 ON_BOOL32 ON__IDefAlternativePathUserData::GetDescription( ON_wString& description )
1651 {
1652 description = L"Linked Instance Definition Alternate Path";
1653 return true;
1654 }
1655
1656
SetAlternateSourceArchivePath(const wchar_t * alternate_source_archive_path,bool bRelativePath)1657 void ON_InstanceDefinition::SetAlternateSourceArchivePath(
1658 const wchar_t* alternate_source_archive_path,
1659 bool bRelativePath
1660 )
1661 {
1662 ON_wString s;
1663 if ( 0 != alternate_source_archive_path )
1664 {
1665 s = alternate_source_archive_path;
1666 s.TrimLeftAndRight();
1667 alternate_source_archive_path = s;
1668 if ( 0 != alternate_source_archive_path && 0 == alternate_source_archive_path[0] )
1669 alternate_source_archive_path = 0;
1670 }
1671 ON__IDefAlternativePathUserData* ud = ON__IDefAlternativePathUserData::FindOrCreate(*this,0!=alternate_source_archive_path);
1672 if ( 0 != ud )
1673 {
1674 if ( 0 == alternate_source_archive_path )
1675 delete ud;
1676 else
1677 {
1678 ud->m_alternate_path = alternate_source_archive_path;
1679 ud->m_bRelativePath = bRelativePath;
1680 }
1681 }
1682 }
1683
GetAlternateSourceArchivePath(ON_wString & alternate_source_archive_path,bool & bRelativePath) const1684 bool ON_InstanceDefinition::GetAlternateSourceArchivePath(
1685 ON_wString& alternate_source_archive_path,
1686 bool& bRelativePath
1687 ) const
1688 {
1689 const ON__IDefAlternativePathUserData* ud = ON__IDefAlternativePathUserData::FindOrCreate(*this,false);
1690 const wchar_t* s = (0 != ud) ? ((const wchar_t*)ud->m_alternate_path) : 0;
1691 if ( 0 != s && 0 != s[0] )
1692 {
1693 alternate_source_archive_path = s;
1694 bRelativePath = ud->m_bRelativePath;
1695 }
1696 else
1697 {
1698 alternate_source_archive_path.Destroy();
1699 bRelativePath = false;
1700 }
1701 return !alternate_source_archive_path.IsEmpty();
1702 }
1703