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 ON_OBJECT_IMPLEMENT(ON_Layer,ON_Object,"95809813-E985-11d3-BFE5-0010830122F0");
20
21 #define ON_BOZO_VACCINE_3E4904E6E9304fbcAA42EBD407AEFE3B
22 #define ON_BOZO_VACCINE_BFB63C094BC7472789BB7CC754118200
23
ON_Layer()24 ON_Layer::ON_Layer()
25 : m_extension_bits(0)
26 {
27 Default();
28 }
29
Default()30 void ON_Layer::Default()
31 {
32 m_layer_id = ON_nil_uuid;
33 m_parent_layer_id = ON_nil_uuid;
34 m_layer_index = -1; // 10 March 2006 Dale Lear - changed from 0 to -1
35 m_iges_level = -1;
36 m_material_index = -1;
37 m_rendering_attributes.Default();
38 m_linetype_index = -1;
39 m_color.SetRGB(0,0,0);
40 m_display_material_id = ON_nil_uuid;
41 m_plot_color = ON_UNSET_COLOR;
42 m_plot_weight_mm = 0.0;
43 m_name.Destroy();
44 m_bVisible = true;
45 m_bLocked = false;
46 m_bExpanded = true;
47 m_extension_bits = 0;
48 }
49
~ON_Layer()50 ON_Layer::~ON_Layer()
51 {
52 m_name.Destroy();
53 }
54
SetExtensionBit(unsigned char * layer_m_extension_bits,unsigned char mask)55 static void SetExtensionBit( unsigned char* layer_m_extension_bits, unsigned char mask )
56 {
57 *layer_m_extension_bits |= mask;
58 }
59
ClearExtensionBit(unsigned char * layer_m_extension_bits,unsigned char mask)60 static void ClearExtensionBit( unsigned char* layer_m_extension_bits, unsigned char mask )
61 {
62 unsigned char notmask = ~mask;
63 *layer_m_extension_bits &= notmask;
64 }
65
ExtensionBit(unsigned char layer_m_extension_bits,unsigned char mask)66 static bool ExtensionBit( unsigned char layer_m_extension_bits, unsigned char mask )
67 {
68 return (0 != (layer_m_extension_bits & mask));
69 }
70
IsValid(ON_TextLog * text_log) const71 ON_BOOL32 ON_Layer::IsValid( ON_TextLog* text_log ) const
72 {
73 if ( m_name.IsEmpty() )
74 {
75 if ( text_log )
76 {
77 text_log->Print("Layer name is empty.\n");
78 }
79 return false;
80 }
81 return true;
82 }
83
NameReferenceDelimiter()84 const wchar_t* ON::NameReferenceDelimiter()
85 {
86 // If this string is changed, also update code
87 // in ON::NameReferenceDelimiterLength().
88 return L" : ";
89 }
90
NameReferenceDelimiterLength()91 unsigned int ON::NameReferenceDelimiterLength()
92 {
93 return 3;
94 }
95
IsNameReferenceDelimiter(const wchar_t * s)96 const wchar_t* ON::IsNameReferenceDelimiter(const wchar_t* s)
97 {
98 const wchar_t* d = ON::NameReferenceDelimiter();
99 if ( 0 != s )
100 {
101 while ( 0 != *d && *d == *s )
102 {
103 d++;
104 s++;
105 }
106 if ( 0 == *d )
107 return s;
108 }
109 return 0;
110 }
111
112
113
LayerNameReferenceDelimiter()114 const wchar_t* ON_Layer::LayerNameReferenceDelimiter()
115 {
116 return ON::NameReferenceDelimiter();
117 }
118
LayerNamePathDelimiter()119 const wchar_t* ON_Layer::LayerNamePathDelimiter()
120 {
121 return L"::";
122 }
123
LayerFullName(const wchar_t * s0)124 static const wchar_t* LayerFullName( const wchar_t* s0 )
125 {
126 if ( 0 == s0 || 0 == s0[0] )
127 return 0;
128 const wchar_t* t;
129 const wchar_t* d;
130 const wchar_t* d0 = ON_Layer::LayerNameReferenceDelimiter();
131 const wchar_t* s = s0;
132
133 // start at the beginning and look for a reference delimiter
134 while ( 0 != *s )
135 {
136 if ( *s == *d0 )
137 {
138 d = d0;
139 t = s;
140 while ( *t == *d)
141 {
142 t++;
143 d++;
144 if ( 0 == *d )
145 {
146 return ((0 != *t) ? t : 0);
147 }
148 }
149 }
150 s++;
151 }
152 return s0;
153 }
154
155
LayerLeafName(const wchar_t * s)156 static const wchar_t* LayerLeafName( const wchar_t* s )
157 {
158 // this static helper function assumes s0 does not being with "reference : ".
159 if ( 0 == s || 0 == s[0] )
160 return 0;
161
162 const wchar_t* t;
163 const wchar_t* d;
164 const wchar_t* d0 = ON_Layer::LayerNamePathDelimiter();
165 const wchar_t* s0 = s;
166
167 while ( 0 != *s0 )
168 {
169 if ( *s0 == *d0 )
170 {
171 // NOTE:
172 // This code must work for a delimiter of length one or more
173 // so the string returned by ON_Layer::LayerNamePathDelimiter()
174 // can be adjusted as needed.
175 d = d0;
176 t = s0;
177 while ( *t == *d)
178 {
179 t++;
180 d++;
181 if ( 0 == *d )
182 {
183 if ( 0 == *t )
184 return 0;
185 s = t;
186 s0 = t-1;
187 break;
188 }
189 }
190 }
191 s0++;
192 }
193
194 return s;
195 }
196
197
198
GetLeafName(const wchar_t * layer_name,ON_wString & leaf_name)199 bool ON_Layer::GetLeafName( const wchar_t* layer_name, ON_wString& leaf_name)
200 {
201 const wchar_t* s0 = LayerFullName(layer_name);
202 const wchar_t* s1 = LayerLeafName( s0 );
203 if ( 0 != s1 && 0 != *s1 )
204 {
205 leaf_name = s1;
206 return true;
207 }
208 leaf_name.Empty();
209 return false;
210 }
211
GetParentName(const wchar_t * layer_name,ON_wString & parent_path_name)212 bool ON_Layer::GetParentName( const wchar_t* layer_name, ON_wString& parent_path_name)
213 {
214 const wchar_t* s0 = LayerFullName(layer_name);
215 const wchar_t* s1 = LayerLeafName( s0 );
216 if ( 0 != s1 && 0 != *s1 && s0 < s1 )
217 {
218 // back up over the delimiter
219 const wchar_t* d0 = ON_Layer::LayerNamePathDelimiter();
220 const wchar_t* d = d0;
221 while (*d)
222 d++;
223 while ( d > d0 && s0 < s1 && d[-1] == s1[-1] )
224 {
225 d--;
226 s1--;
227 }
228 if ( s0 < s1 )
229 {
230 parent_path_name = s0;
231 parent_path_name.SetLength(s1-s0);
232 return true;
233 }
234 }
235 parent_path_name.Empty();
236 return false;
237 }
238
RemoveReferenceName(const wchar_t * layer_name,ON_wString & layer_path_name)239 bool ON_Layer::RemoveReferenceName( const wchar_t* layer_name, ON_wString& layer_path_name)
240 {
241 const wchar_t* s = LayerFullName(layer_name);
242 if ( 0 != s && 0 != *s )
243 {
244 layer_path_name = s;
245 return true;
246 }
247 layer_path_name.Empty();
248 return false;
249 }
250
GetReferenceName(const wchar_t * layer_name,ON_wString & reference_name)251 bool ON_Layer::GetReferenceName( const wchar_t* layer_name, ON_wString& reference_name)
252 {
253 const wchar_t* s0 = layer_name;
254 const wchar_t* s1 = LayerFullName(layer_name);
255 if ( 0 != s1 && 0 != *s1 && s0 < s1 )
256 {
257 const wchar_t* d = ON_Layer::LayerNameReferenceDelimiter();
258 while ( *d++ && s0 < s1 )
259 s1--;
260 if ( 0 != *s1 && s0 < s1 )
261 {
262 reference_name = s0;
263 reference_name.SetLength(s1-s0);
264 return true;
265 }
266 }
267 reference_name.Empty();
268 return false;
269 }
270
Dump(ON_TextLog & dump) const271 void ON_Layer::Dump( ON_TextLog& dump ) const
272 {
273 const wchar_t* sName = LayerName();
274 if ( !sName )
275 sName = L"";
276 dump.Print("index = %d\n",m_layer_index);
277 dump.Print("name = \"%ls\"\n",sName);
278 dump.Print("display = %s\n",m_bVisible?"visible":"hidden");
279 dump.Print("picking = %s\n",m_bLocked?"locked":"unlocked");
280 dump.Print("display color rgb = "); dump.PrintRGB(m_color); dump.Print("\n");
281 dump.Print("plot color rgb = "); dump.PrintRGB(m_plot_color); dump.Print("\n");
282 dump.Print("default material index = %d\n",m_material_index);
283 }
284
Write(ON_BinaryArchive & file) const285 ON_BOOL32 ON_Layer::Write(
286 ON_BinaryArchive& file // serialize definition to binary archive
287 ) const
288 {
289 int i;
290 bool rc = file.Write3dmChunkVersion(1,8);
291 while(rc)
292 {
293 // Save the visibility state this layer has when its parent
294 // is visible ignoring current parent visibility value.
295 bool bVisible = PersistentVisibility();
296
297 // Save the locked state this layer has when its parent
298 // is unlocked ignoring current parenting locked setting.
299 const bool bLocked = PersistentLocking();
300
301 // Save OBSOLETE mode value so we don't break file format
302 if ( bVisible )
303 i = 0; // "normal" layer mode
304 else if ( bLocked )
305 i = 2; // "locked" layer mode
306 else
307 i = 1; // "hidden" layer mode
308
309 rc = file.WriteInt( i );
310 if (!rc) break;
311
312 rc = file.WriteInt( m_layer_index );
313 if (!rc) break;
314
315 rc = file.WriteInt( m_iges_level );
316 if (!rc) break;
317
318 rc = file.WriteInt( m_material_index );
319 if (!rc) break;
320
321 // Starting with version 200312110, this value is zero. For files written
322 // with earlier versions, the number was a "model index" value that was
323 // set to something >= 1, but never used. We have to continue to
324 // read/write an integer here so that old/new versions of opennurbs can
325 // read files written by new/old versions.
326 i = 0;
327 rc = file.WriteInt( i );
328 if (!rc) break;
329
330 rc = file.WriteColor( m_color );
331 if (!rc) break;
332
333 {
334 // OBSOLETE LINE STYLE if ( rc ) rc = file.WriteLineStyle( LineStyle() );
335 // Starting with version 200503170, this section is "officially" not used.
336 // Prior to that, it was old ON_LineStyle information that has
337 // never been used.
338 short s = 0;
339 if (rc) rc = file.WriteShort(s); // default pattern
340 if (rc) rc = file.WriteShort(s); // default pattern index
341 if (rc) rc = file.WriteDouble(0.0); // default thickness
342 if (rc) rc = file.WriteDouble(1.0); // default scale
343 }
344 if (!rc) break;
345
346 rc = file.WriteString( m_name );
347 if (!rc) break;
348
349 // 1.1 fields
350 rc = file.WriteBool(bVisible);
351 if (!rc) break;
352
353 // 1.2 field
354 rc = file.WriteInt( m_linetype_index);
355 if (!rc) break;
356
357 // 1.3 field - 23 March 2005 Dale Lear
358 rc = file.WriteColor( m_plot_color);
359 if (!rc) break;
360 rc = file.WriteDouble( m_plot_weight_mm);
361 if (!rc) break;
362
363 // 1.4 field - 3 May 2005 Dale Lear
364 // - locked and visible are independent settings
365 rc = file.WriteBool( bLocked );
366 if (!rc) break;
367
368 // 1.5 field
369 rc = file.WriteUuid( m_layer_id );
370 if (!rc) break;
371
372 // 1.6 field
373 rc = file.WriteUuid( m_parent_layer_id );
374 if (!rc) break;
375
376 // 1.6 field
377 rc = file.WriteBool( m_bExpanded );
378 if (!rc) break;
379
380 // 1.7 field - added 6 June 2006
381 rc = m_rendering_attributes.Write(file);
382 if (!rc) break;
383
384 // 1.8 field - added 19 Sep 2006
385 rc = file.WriteUuid(m_display_material_id);
386
387 break;
388 }
389
390 return rc;
391 }
392
Read(ON_BinaryArchive & file)393 ON_BOOL32 ON_Layer::Read(
394 ON_BinaryArchive& file // restore definition from binary archive
395 )
396 {
397 int obsolete_value1 = 0; // see ON_Layer::Write
398 int major_version=0;
399 int minor_version=0;
400 int mode = ON::normal_layer;
401 Default();
402 ON_BOOL32 rc = file.Read3dmChunkVersion(&major_version,&minor_version);
403 if ( rc && major_version == 1 )
404 {
405 // common to all 1.x formats
406 if ( rc ) rc = file.ReadInt( &mode );
407 if ( rc )
408 {
409 switch(mode)
410 {
411 case 0: // OBSOLETE ON::normal_layer
412 m_bVisible = true;
413 m_bLocked = false;
414 break;
415 case 1: // OBSOLETE ON::hidden_layer
416 m_bVisible = false;
417 m_bLocked = false;
418 break;
419 case 2: // OBSOLETE ON::locked_layer
420 m_bVisible = true;
421 m_bLocked = true;
422 break;
423 default:
424 m_bVisible = true;
425 m_bLocked = false;
426 break;
427 }
428 }
429 if ( rc ) rc = file.ReadInt( &m_layer_index );
430 if ( rc ) rc = file.ReadInt( &m_iges_level );
431 if ( rc ) rc = file.ReadInt( &m_material_index );
432 if ( rc ) rc = file.ReadInt( &obsolete_value1 );
433 if ( rc ) rc = file.ReadColor( m_color );
434
435 {
436 // OBSOLETE line style was never used - read and discard the next 20 bytes
437 short s;
438 double x;
439 if (rc) file.ReadShort(&s);
440 if (rc) file.ReadShort(&s);
441 if (rc) file.ReadDouble(&x);
442 if (rc) file.ReadDouble(&x);
443 }
444
445 if ( rc ) rc = file.ReadString( m_name );
446 if ( rc && minor_version >= 1 )
447 {
448 rc = file.ReadBool(&m_bVisible);
449 if ( rc && minor_version >= 2 )
450 {
451 rc = file.ReadInt( &m_linetype_index);
452 if (rc && minor_version >= 3 )
453 {
454 // 23 March 2005 Dale Lear
455 rc = file.ReadColor( m_plot_color);
456 if (rc) rc = file.ReadDouble( &m_plot_weight_mm);
457
458 if (rc && minor_version >= 4 )
459 {
460 rc = file.ReadBool(&m_bLocked);
461 if (rc && minor_version >= 5 )
462 {
463 rc = file.ReadUuid(m_layer_id);
464 if ( rc
465 && minor_version >= 6
466 && file.ArchiveOpenNURBSVersion() > 200505110
467 )
468 {
469 // Some files saved with opennurbs version 200505110
470 // do not contain correctly written m_parent_layer_id
471 // and m_bExpanded values.
472 // It is ok to default these values.
473 rc = file.ReadUuid(m_parent_layer_id);
474 if (rc)
475 {
476 if ( ON_UuidIsNotNil(m_parent_layer_id) )
477 {
478 if ( m_bVisible )
479 SetPersistentVisibility(true);
480 if ( !m_bLocked )
481 SetPersistentLocking(false);
482 }
483 rc = file.ReadBool(&m_bExpanded);
484 }
485 }
486
487 if ( rc && minor_version >= 7 )
488 {
489 // 1.7 field - added 6 June 2006
490 rc = m_rendering_attributes.Read(file);
491
492 if ( rc && minor_version >= 8 )
493 {
494 // 1.8 field - added 19 Sep 2006
495 rc = file.ReadUuid(m_display_material_id);
496 }
497 }
498 }
499 }
500 }
501 }
502 }
503
504 if ( ON_UuidIsNil(m_layer_id) )
505 {
506 // old files didn't have layer ids and we need unique ones.
507 ON_CreateUuid(m_layer_id);
508 }
509 }
510 else {
511 ON_ERROR("ON_Layer::Read() encountered a layer written by future code.");
512 rc = false;
513 }
514
515 return rc;
516 }
517
ObjectType() const518 ON::object_type ON_Layer::ObjectType() const
519 {
520 return ON::layer_object;
521 }
522
523 //////////////////////////////////////////////////////////////////////
524 //
525 // Interface
526
SetLayerName(const char * s)527 bool ON_Layer::SetLayerName( const char* s )
528 {
529 m_name = s;
530 return IsValid()?true:false;
531 }
532
SetLayerName(const wchar_t * s)533 bool ON_Layer::SetLayerName( const wchar_t* s )
534 {
535 m_name = s;
536 return IsValid()?true:false;
537 }
538
LayerName() const539 const ON_wString& ON_Layer::LayerName() const
540 {
541 return m_name;
542 }
543
SetColor(ON_Color c)544 void ON_Layer::SetColor( ON_Color c)
545 {
546 m_color = c;
547 }
548
SetPlotColor(ON_Color c)549 void ON_Layer::SetPlotColor( ON_Color c)
550 {
551 m_plot_color = c;
552 }
553
Color() const554 ON_Color ON_Layer::Color() const
555 {
556 return m_color;
557 }
558
PlotColor() const559 ON_Color ON_Layer::PlotColor() const
560 {
561 return ((m_plot_color == ON_UNSET_COLOR) ? m_color : m_plot_color);
562 }
563
SetLinetypeIndex(int index)564 bool ON_Layer::SetLinetypeIndex( int index)
565 {
566 if( index >= -1)
567 {
568 m_linetype_index = index;
569 return true;
570 }
571 return false;
572 }
573
LinetypeIndex() const574 int ON_Layer::LinetypeIndex() const
575 {
576 return m_linetype_index;
577 }
578
IsVisible() const579 bool ON_Layer::IsVisible() const
580 {
581 return m_bVisible;
582 }
583
SetVisible(bool bVisible)584 void ON_Layer::SetVisible( bool bVisible )
585 {
586 m_bVisible = ( bVisible ? true : false );
587 if ( ON_UuidIsNil(m_parent_layer_id) )
588 UnsetPersistentVisibility();
589 else if ( bVisible )
590 {
591 // When a parent layer is turned off, the m_bVisible value for
592 // every child layer layer is set to false. When a parent layer
593 // is turned on and the visible child setting is true, the
594 // child's m_bVisible value is set to true.
595 //
596 // This call ensures that if, at some point in the future, the
597 // parent layer is turned off and then turned back on, this
598 // layer will get turned back on as well.
599 SetPersistentVisibility(true);
600 }
601 }
602
SetLocked(bool bLocked)603 void ON_Layer::SetLocked( bool bLocked )
604 {
605 m_bLocked = ( bLocked ? true : false );
606 if ( ON_UuidIsNil(m_parent_layer_id) )
607 UnsetPersistentLocking();
608 else if ( !bLocked )
609 {
610 // When a parent layer is locked off, the m_bLocked value for
611 // every child layer layer is set to true. When a parent layer
612 // is unlocked on and the locked child setting is false, the
613 // child's m_bLocked value is set to false.
614 //
615 // This call ensures that if, at some point in the future, the
616 // parent layer is locked and then unlocked, this layer will
617 // get unlocked on as well.
618 SetPersistentLocking(false);
619 }
620 }
621
IsLocked() const622 bool ON_Layer::IsLocked() const
623 {
624 return m_bLocked;
625 }
626
IsVisibleAndNotLocked() const627 bool ON_Layer::IsVisibleAndNotLocked() const
628 {
629 return (m_bVisible && !m_bLocked);
630 }
631
IsVisibleAndLocked() const632 bool ON_Layer::IsVisibleAndLocked() const
633 {
634 return (m_bVisible && m_bLocked);
635 }
636
SetRenderMaterialIndex(int i)637 bool ON_Layer::SetRenderMaterialIndex( int i )
638 {
639 m_material_index = i;
640 return true;
641 }
642
RenderMaterialIndex() const643 int ON_Layer::RenderMaterialIndex() const
644 {
645 return m_material_index;
646 }
647
SetLayerIndex(int i)648 bool ON_Layer::SetLayerIndex( int i )
649 {
650 m_layer_index = i;
651 return true;
652 }
653
LayerIndex() const654 int ON_Layer::LayerIndex() const
655 {
656 return m_layer_index;
657 }
658
659
SetIgesLevel(int level)660 bool ON_Layer::SetIgesLevel( int level )
661 {
662 m_iges_level = level;
663 return true;
664 }
665
IgesLevel() const666 int ON_Layer::IgesLevel() const
667 {
668 return m_iges_level;
669 }
670
PlotWeight() const671 double ON_Layer::PlotWeight() const
672 {
673 return m_plot_weight_mm;
674 }
675
SetPlotWeight(double plot_weight_mm)676 void ON_Layer::SetPlotWeight(double plot_weight_mm)
677 {
678 m_plot_weight_mm = (ON_IsValid(plot_weight_mm) && (plot_weight_mm>0.0 || -1.0==plot_weight_mm) )
679 ? plot_weight_mm
680 : 0.0;
681 }
682
683
684 ////////////////////////////////////////////////////////////////
685 //
686 // BEGIN ON__LayerPerViewSettings class
687 //
688
689 class /*NEVER EXPORT THIS CLASS DEFINITION*/ ON__LayerPerViewSettings
690 {
691 #if !defined(ON_BOZO_VACCINE_3E4904E6E9304fbcAA42EBD407AEFE3B)
692 #error Never copy this class definition or put this definition in a header file!
693 #endif
694 public:
695 ON__LayerPerViewSettings();
696 void SetDefaultValues();
697 bool Write( const ON_Layer& layer, ON_BinaryArchive& binary_archive ) const;
698 bool Read( const ON_Layer& layer, ON_BinaryArchive& binary_archive);
699
700 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
701
702 ON_UUID m_viewport_id; // id of the viewport with custom layer settings
703 // if this id is nil, then the rest of the settings
704 // in this class are meaningless.
705 ON_Color m_color; // ON_UNSET_COLOR means use ON_Layer::m_color
706 ON_Color m_plot_color; // ON_UNSET_COLOR means use ON_Layer::m_plot_color
707 double m_plot_weight_mm; // ON_UNSET_VALUE means use ON_Layer::m_plot_weight_mm
708
709 unsigned char m_visible; // 0 means use ON_Layer::m_bVisible
710 // 1 = visible in viewport
711 // 2 = off in viewport
712 unsigned char m_persistent_visibility; // 0 = unset, 1 = visible, 2 = not visible
713
714 static
715 int Compare(
716 const ON__LayerPerViewSettings* a,
717 const ON__LayerPerViewSettings* b
718 );
719
720 static
721 int CompareViewportId(
722 const ON__LayerPerViewSettings* a,
723 const ON__LayerPerViewSettings* b
724 );
725
726 /*
727 Returns:
728 A bitfield that sets the bits if a layer setting is
729 per viewport for the specified for the viewport.
730 The ON_Layer::PER_VIEWPORT_SETTINGS enum values
731 which bits correspond to which settings.
732 Remarks:
733 If m_viewport_id is nil, this function returns 0.
734 */
735 unsigned int SettingsMask() const;
736
737 /*
738 Description:
739 Copy specified settings from src to this class.
740 Parameters:
741 src - [in]
742 settings to copy
743 settings_mask - [in]
744 a bitfield that specifies which settings to copy. The bits
745 are defined in the ON_Layer::PER_VIEWPORT_SETTINGS enum.
746 */
747 void CopySettings(
748 const ON__LayerPerViewSettings* src,
749 unsigned int settings_mask
750 );
751 };
752
DataCRC(ON__UINT32 current_remainder) const753 ON__UINT32 ON__LayerPerViewSettings::DataCRC(ON__UINT32 current_remainder) const
754 {
755 const unsigned int settings_mask = SettingsMask();
756 if ( 0 != settings_mask )
757 {
758 if ( 0 != (settings_mask & ON_Layer::per_viewport_id) )
759 current_remainder = ON_CRC32(current_remainder,sizeof(m_viewport_id),&m_viewport_id);
760 if ( 0 != (settings_mask & ON_Layer::per_viewport_color) )
761 current_remainder = ON_CRC32(current_remainder,sizeof(m_color),&m_color);
762 if ( 0 != (settings_mask & ON_Layer::per_viewport_plot_color) )
763 current_remainder = ON_CRC32(current_remainder,sizeof(m_plot_color),&m_plot_color);
764 if ( 0 != (settings_mask & ON_Layer::per_viewport_plot_weight) )
765 current_remainder = ON_CRC32(current_remainder,sizeof(m_plot_weight_mm),&m_plot_weight_mm);
766 if ( 0 != (settings_mask & ON_Layer::per_viewport_visible) )
767 current_remainder = ON_CRC32(current_remainder,sizeof(m_visible),&m_visible);
768 if ( 0 != (settings_mask & ON_Layer::per_viewport_persistent_visibility) )
769 current_remainder = ON_CRC32(current_remainder,sizeof(m_persistent_visibility),&m_persistent_visibility);
770 }
771 return current_remainder;
772 }
773
CopySettings(const ON__LayerPerViewSettings * src,unsigned int settings_mask)774 void ON__LayerPerViewSettings::CopySettings( const ON__LayerPerViewSettings* src, unsigned int settings_mask )
775 {
776 if ( 0 != src && this != src && 0 != settings_mask )
777 {
778 if ( 0 != (settings_mask & ON_Layer::per_viewport_id) )
779 m_viewport_id = src->m_viewport_id;
780 if ( 0 != (settings_mask & ON_Layer::per_viewport_color) )
781 m_color = src->m_color;
782 if ( 0 != (settings_mask & ON_Layer::per_viewport_plot_color) )
783 m_plot_color = src->m_plot_color;
784 if ( 0 != (settings_mask & ON_Layer::per_viewport_plot_weight) )
785 m_plot_weight_mm = src->m_plot_weight_mm;
786 if ( 0 != (settings_mask & ON_Layer::per_viewport_visible) )
787 m_visible = src->m_visible;
788 if ( 0 != (settings_mask & ON_Layer::per_viewport_persistent_visibility) )
789 m_persistent_visibility = src->m_persistent_visibility;
790 }
791 }
792
Compare(const ON__LayerPerViewSettings * a,const ON__LayerPerViewSettings * b)793 int ON__LayerPerViewSettings::Compare( const ON__LayerPerViewSettings* a, const ON__LayerPerViewSettings* b )
794 {
795 int rc = ON_UuidCompare(a->m_viewport_id,b->m_viewport_id);
796 if ( 0 == rc )
797 {
798 unsigned int abits = a->SettingsMask();
799 unsigned int bbits = b->SettingsMask();
800 rc = ((int)abits) - ((int)bbits);
801 if ( 0 == rc )
802 {
803 if ( 0 != (ON_Layer::per_viewport_visible & abits) )
804 {
805 rc = ((int)a->m_visible) - ((int)b->m_visible);
806 }
807 if ( 0 == rc && 0 != (ON_Layer::per_viewport_persistent_visibility & abits) )
808 {
809 rc = ((int)a->m_persistent_visibility) - ((int)b->m_persistent_visibility);
810 }
811 if ( 0 == rc && 0 != (ON_Layer::per_viewport_color & abits) )
812 {
813 rc = ((int)a->m_color) - ((int)b->m_color);
814 }
815 if ( 0 == rc && 0 != (ON_Layer::per_viewport_plot_color & abits) )
816 {
817 rc = ((int)a->m_plot_color) - ((int)b->m_plot_color);
818 }
819 if ( 0 == rc && 0 != (ON_Layer::per_viewport_plot_weight & abits) )
820 {
821 if ( a->m_plot_weight_mm < b->m_plot_weight_mm )
822 rc = -1;
823 else if ( a->m_plot_weight_mm > b->m_plot_weight_mm )
824 rc = 1;
825 }
826 }
827 }
828 return rc;
829 }
830
CompareViewportId(const ON__LayerPerViewSettings * a,const ON__LayerPerViewSettings * b)831 int ON__LayerPerViewSettings::CompareViewportId( const ON__LayerPerViewSettings* a, const ON__LayerPerViewSettings* b )
832 {
833 return ON_UuidCompare(a->m_viewport_id,b->m_viewport_id);
834 }
835
SettingsMask() const836 unsigned int ON__LayerPerViewSettings::SettingsMask() const
837 {
838 // It is critical that this function returns
839 // zero when m_viewport_id = nil and returns
840 // zero when no layer properties are overridden
841 // for the specified viewport.
842 unsigned int bits = 0;
843 if ( !ON_UuidIsNil(m_viewport_id) )
844 {
845 if ( ON_UNSET_COLOR != m_color )
846 bits |= ON_Layer::per_viewport_color;
847 if ( ON_UNSET_COLOR != m_plot_color )
848 bits |= ON_Layer::per_viewport_plot_color;
849 if ( (m_plot_weight_mm >= 0.0 || -1.0 == m_plot_weight_mm) && ON_IsValid(m_plot_weight_mm) )
850 bits |= ON_Layer::per_viewport_plot_weight;
851 if ( 1 == m_visible || 2 == m_visible )
852 bits |= ON_Layer::per_viewport_visible;
853 if ( 1 == m_persistent_visibility || 2 == m_persistent_visibility )
854 bits |= ON_Layer::per_viewport_persistent_visibility;
855 // It is critical that bit "1" is set only if
856 // some layer property is overridden. That's
857 // why the 0 != bits test is here.
858 if ( 0 != bits )
859 bits |= ON_Layer::per_viewport_id;
860 }
861
862 return bits;
863 }
864
ON__LayerPerViewSettings()865 ON__LayerPerViewSettings::ON__LayerPerViewSettings()
866 {
867 SetDefaultValues();
868 }
869
SetDefaultValues()870 void ON__LayerPerViewSettings::SetDefaultValues()
871 {
872 memset(this,0,sizeof(*this));
873 m_color = ON_UNSET_COLOR;
874 m_plot_color = ON_UNSET_COLOR;
875 m_plot_weight_mm = ON_UNSET_VALUE;
876 }
877
Write(const ON_Layer & layer,ON_BinaryArchive & binary_archive) const878 bool ON__LayerPerViewSettings::Write(const ON_Layer& layer, ON_BinaryArchive& binary_archive) const
879 {
880 if ( !binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,2) )
881 return false;
882
883 bool rcc = false;
884 for(;;)
885 {
886 // This complicated "bits" stuff is to minimize number of bytes
887 // written in the file. Even though long term storage space is
888 // nearly free, we have lots of customers who complain about
889 // large file size and so ...
890 unsigned int bits = SettingsMask();
891 if ( !binary_archive.WriteInt(1,&bits) )
892 break;
893
894 if ( 0 == bits )
895 {
896 rcc = true;
897 break; // all settings are defaults or viewport_id is nil
898 }
899
900 if ( !binary_archive.WriteUuid(m_viewport_id) )
901 break;
902
903 if ( 0 != (ON_Layer::per_viewport_color & bits) )
904 {
905 if ( !binary_archive.WriteColor(m_color) )
906 break;
907 }
908
909 if ( 0 != (ON_Layer::per_viewport_plot_color & bits) )
910 {
911 if ( !binary_archive.WriteColor(m_plot_color) )
912 break;
913 }
914
915 if ( 0 != (ON_Layer::per_viewport_plot_weight & bits) )
916 {
917 if ( !binary_archive.WriteDouble(m_plot_weight_mm) )
918 break;
919 }
920
921 if ( 0 != (ON_Layer::per_viewport_visible & bits) )
922 {
923 if ( !binary_archive.WriteChar(m_visible) )
924 break;
925 // version 1.1 addition
926 if ( !binary_archive.WriteChar(m_visible) ) // (makes old a file old rhinos can read)
927 break;
928 }
929
930 // 1.2 addition
931 if ( 0 != (ON_Layer::per_viewport_persistent_visibility & bits) )
932 {
933 if ( !binary_archive.WriteChar(m_persistent_visibility) )
934 break;
935 }
936
937 rcc = true;
938 break;
939 }
940
941 if ( !binary_archive.EndWrite3dmChunk() )
942 rcc = false;
943
944 return rcc;
945 }
946
Read(const ON_Layer & layer,ON_BinaryArchive & binary_archive)947 bool ON__LayerPerViewSettings::Read(const ON_Layer& layer, ON_BinaryArchive& binary_archive)
948 {
949 SetDefaultValues();
950
951 int major_version = 0;
952 int minor_version = 0;
953 if ( !binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version) )
954 return false;
955
956 bool rc = false;
957 for(;;)
958 {
959 if (1 != major_version)
960 break;
961
962 // This complicated "bits" stuff is to minimize number of bytes
963 // written in the file. Even though long term storage space is
964 // nearly free, we have lots of customers who complain about
965 // large file size and so ...
966 unsigned int bits = 0;
967 if ( !binary_archive.ReadInt(1,&bits) )
968 break;
969 if ( 0 == bits )
970 {
971 rc = true;
972 break;
973 }
974
975 if ( !binary_archive.ReadUuid(m_viewport_id) )
976 break;
977
978 if ( 0 != (ON_Layer::per_viewport_color & bits) )
979 {
980 if ( !binary_archive.ReadColor(m_color) )
981 break;
982 }
983
984 if ( 0 != (ON_Layer::per_viewport_plot_color & bits) )
985 {
986 if ( !binary_archive.ReadColor(m_plot_color) )
987 break;
988 }
989
990 if ( 0 != (ON_Layer::per_viewport_plot_weight & bits) )
991 {
992 if ( !binary_archive.ReadDouble(&m_plot_weight_mm) )
993 break;
994 }
995
996 if ( 0 != (ON_Layer::per_viewport_visible & bits) )
997 {
998 if ( !binary_archive.ReadChar(&m_visible) )
999 break;
1000 if ( minor_version >= 1 )
1001 {
1002 // for reading older Rhino files
1003 // Yes, writing m_visible and reading m_persistent_visibility is done on purpose.
1004 if ( !binary_archive.ReadChar(&m_persistent_visibility) )
1005 break;
1006 }
1007 }
1008
1009 if ( minor_version >= 2 )
1010 {
1011 if ( 0 != (ON_Layer::per_viewport_persistent_visibility & bits) )
1012 {
1013 if ( !binary_archive.ReadChar(&m_persistent_visibility) )
1014 break;
1015 }
1016 }
1017
1018 if ( ON_UuidIsNil(layer.m_parent_layer_id) )
1019 m_persistent_visibility = 0;
1020 rc = true;
1021 break;
1022 }
1023
1024 if ( !binary_archive.EndRead3dmChunk() )
1025 rc = false;
1026
1027 return rc;
1028 }
1029
1030
1031 //
1032 //
1033 // END ON__LayerPerViewSettings class
1034 //
1035 ////////////////////////////////////////////////////////////////
1036
1037
1038 ////////////////////////////////////////////////////////////////
1039 //
1040 // BEGIN ON__LayerExtensions user data class
1041 //
1042
1043 class /*NEVER EXPORT THIS CLASS DEFINITION*/ ON__LayerExtensions : public ON_UserData
1044 {
1045 #if !defined(ON_BOZO_VACCINE_3E4904E6E9304fbcAA42EBD407AEFE3B)
1046 #error Never copy this class definition or put this definition in a header file!
1047 #endif
1048 ON_OBJECT_DECLARE(ON__LayerExtensions);
1049
1050 public:
1051 ON__LayerExtensions();
1052 ~ON__LayerExtensions();
1053 // default copy constructor and operator= work fine.
1054
1055 public:
1056 // virtual ON_Object override
1057 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
1058 // virtual ON_Object override
1059 unsigned int SizeOf() const;
1060 // virtual ON_Object override
1061 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
1062 // virtual ON_Object override
1063 ON_BOOL32 Write(ON_BinaryArchive& binary_archive) const;
1064 // virtual ON_Object override
1065 ON_BOOL32 Read(ON_BinaryArchive& binary_archive);
1066 // virtual ON_UserData override
1067 ON_BOOL32 Archive() const;
1068 // virtual ON_UserData override
1069 ON_BOOL32 GetDescription( ON_wString& description );
1070
1071 public:
1072 bool IsEmpty() const;
1073
1074 static
1075 ON__LayerPerViewSettings* ViewportSettings(
1076 const ON_Layer& layer, const unsigned char* layer_m_extension_bits,
1077 ON_UUID viewport_id,
1078 bool bCreate
1079 );
1080
1081 static
1082 void DeleteViewportSettings(
1083 const ON_Layer& layer, const unsigned char* layer_m_extension_bits,
1084 const ON__LayerPerViewSettings* vp_settings_to_delete
1085 );
1086
1087 static
1088 ON__LayerExtensions* LayerExtensions(
1089 const ON_Layer& layer, const unsigned char* layer_m_extension_bits,
1090 bool bCreate
1091 );
1092
1093 // per viewport overrides of color, linetype, plot color, plot weight, and visibility
1094 ON_SimpleArray<ON__LayerPerViewSettings> m_vp_settings;
1095 };
1096
1097 #undef ON_BOZO_VACCINE_3E4904E6E9304fbcAA42EBD407AEFE3B
1098
1099 ON_OBJECT_IMPLEMENT(ON__LayerExtensions,ON_UserData,"3E4904E6-E930-4fbc-AA42-EBD407AEFE3B");
1100
LayerExtensions(const ON_Layer & layer,const unsigned char * layer_m_extension_bits,bool bCreate)1101 ON__LayerExtensions* ON__LayerExtensions::LayerExtensions(const ON_Layer& layer, const unsigned char* layer_m_extension_bits, bool bCreate)
1102 {
1103 ON__LayerExtensions* ud = ON__LayerExtensions::Cast(layer.GetUserData(ON__LayerExtensions::m_ON__LayerExtensions_class_id.Uuid()));
1104
1105 if ( 0 == ud )
1106 {
1107 if ( bCreate )
1108 {
1109 ud = new ON__LayerExtensions();
1110 const_cast<ON_Layer&>(layer).AttachUserData(ud);
1111 // Clear 0x01 bit of ON_Layer::m_extension_bits so
1112 // ON_Layer visibility and color queries will check
1113 // for ON__LayerExtensions userdata.
1114 ClearExtensionBit( const_cast<unsigned char*>(layer_m_extension_bits), 0x01 );
1115 }
1116 else
1117 {
1118 // Set 0x01 bit of ON_Layer::m_extension_bits so
1119 // ON_Layer visibility and color queries will not
1120 // perform the expensive check for ON__LayerExtensions
1121 // userdata. This speeds up visibility and color queries
1122 // that occur millions of times when complicated models
1123 // are rendered.
1124 SetExtensionBit( const_cast<unsigned char*>(layer_m_extension_bits), 0x01 );
1125 }
1126 }
1127 else
1128 {
1129 // Clear 0x01 bit of ON_Layer::m_extension_bits so
1130 // ON_Layer visibility and color queries will check
1131 // for ON__LayerExtensions userdata.
1132 ClearExtensionBit( const_cast<unsigned char*>(layer_m_extension_bits), 0x01 );
1133 }
1134
1135 return ud;
1136 }
1137
ON__LayerExtensions()1138 ON__LayerExtensions::ON__LayerExtensions()
1139 {
1140 m_userdata_uuid = ON__LayerExtensions::m_ON__LayerExtensions_class_id.Uuid();
1141 m_application_uuid = ON_opennurbs5_id;
1142 m_userdata_copycount = 1;
1143 }
1144
~ON__LayerExtensions()1145 ON__LayerExtensions::~ON__LayerExtensions()
1146 {
1147 }
1148
1149 // virtual ON_Object override
IsValid(ON_TextLog * text_log) const1150 ON_BOOL32 ON__LayerExtensions::IsValid( ON_TextLog* text_log ) const
1151 {
1152 return true;
1153 }
1154
1155 // virtual ON_Object override
SizeOf() const1156 unsigned int ON__LayerExtensions::SizeOf() const
1157 {
1158 size_t sz = sizeof(*this) - sizeof(ON_UserData);
1159 sz += m_vp_settings.SizeOfArray();
1160 return (unsigned int)sz;
1161 }
1162
1163 // virtual ON_Object override
DataCRC(ON__UINT32 current_remainder) const1164 ON__UINT32 ON__LayerExtensions::DataCRC(ON__UINT32 current_remainder) const
1165 {
1166 ON__UINT32 crc = 0;
1167 crc = m_vp_settings.DataCRC(crc);
1168 return crc;
1169 }
1170
1171 // virtual ON_Object override
Write(ON_BinaryArchive & binary_archive) const1172 ON_BOOL32 ON__LayerExtensions::Write(ON_BinaryArchive& binary_archive) const
1173 {
1174 bool rc = binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
1175 if ( !rc )
1176 return false;
1177
1178 for(;;)
1179 {
1180 const ON_Layer* layer = ON_Layer::Cast( Owner() );
1181 if ( 0 == layer )
1182 break;
1183 int count = m_vp_settings.Count();
1184 rc = binary_archive.WriteInt(count);
1185 if ( !rc ) break;
1186 for ( int i = 0; i < count && rc; i++ )
1187 {
1188 rc = m_vp_settings[i].Write( *layer, binary_archive );
1189 }
1190 if (!rc) break;
1191
1192 break;
1193 }
1194
1195 if ( !binary_archive.EndWrite3dmChunk() )
1196 rc = false;
1197
1198 return rc;
1199 }
1200
1201 // virtual ON_Object override
Read(ON_BinaryArchive & binary_archive)1202 ON_BOOL32 ON__LayerExtensions::Read(ON_BinaryArchive& binary_archive)
1203 {
1204 m_vp_settings.SetCount(0);
1205
1206 int major_version = 0;
1207 int minor_version = 0;
1208 bool rc = binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
1209 if ( !rc )
1210 return false;
1211
1212 for(;;)
1213 {
1214 const ON_Layer* layer = ON_Layer::Cast( Owner() );
1215 rc = ( 0 != layer );
1216 if (!rc) break;
1217
1218 rc = (1 == major_version);
1219 if (!rc) break;
1220
1221 int count = 0;
1222 rc = binary_archive.ReadInt(&count);
1223 if ( !rc ) break;
1224 m_vp_settings.Reserve(count);
1225 for ( int i = 0; i < count; i++ )
1226 {
1227 rc = m_vp_settings.AppendNew().Read(*layer,binary_archive);
1228 if (!rc)
1229 {
1230 m_vp_settings.Remove();
1231 break;
1232 }
1233 if ( 0 == m_vp_settings.Last()->SettingsMask() )
1234 m_vp_settings.Remove();
1235 }
1236
1237 // to make ON_Layer::PerViewportSettingsCRC() return
1238 // equal values for equal settings, it is critical
1239 // that m_vp_settings[] be sorted.
1240 m_vp_settings.QuickSort(ON__LayerPerViewSettings::Compare);
1241
1242 if (!rc) break;
1243
1244 break;
1245 }
1246
1247 if ( !binary_archive.EndRead3dmChunk() )
1248 rc = false;
1249
1250 return rc;
1251 }
1252
1253 // virtual ON_UserData override
Archive() const1254 ON_BOOL32 ON__LayerExtensions::Archive() const
1255 {
1256 return !IsEmpty();
1257 }
1258
1259 // virtual ON_UserData override
GetDescription(ON_wString & description)1260 ON_BOOL32 ON__LayerExtensions::GetDescription( ON_wString& description )
1261 {
1262 description = L"Layer Extensions";
1263 return true;
1264 }
1265
ViewportSettings(const ON_Layer & layer,const unsigned char * layer_m_extension_bits,ON_UUID viewport_id,bool bCreate)1266 ON__LayerPerViewSettings* ON__LayerExtensions::ViewportSettings(
1267 const ON_Layer& layer,
1268 const unsigned char* layer_m_extension_bits,
1269 ON_UUID viewport_id,
1270 bool bCreate
1271 )
1272 {
1273 if ( !ON_UuidIsNil(viewport_id) )
1274 {
1275 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(layer,layer_m_extension_bits,bCreate);
1276 if ( ud )
1277 {
1278 int i;
1279 const int vp_settings_count = ud->m_vp_settings.Count();
1280 ON__LayerPerViewSettings* vp_settings = ud->m_vp_settings.Array();
1281 for ( i = 0; i < vp_settings_count; i++ )
1282 {
1283 if ( 0 == memcmp(&viewport_id,&vp_settings[i].m_viewport_id,sizeof(ON_UUID)) )
1284 return (vp_settings+i);
1285 }
1286 if ( bCreate )
1287 {
1288 ON__LayerPerViewSettings& new_vp_settings = ud->m_vp_settings.AppendNew();
1289 vp_settings = ud->m_vp_settings.Array(); // appending can grow the array
1290 new_vp_settings.SetDefaultValues();
1291 new_vp_settings.m_viewport_id = viewport_id;
1292
1293 // to make ON_Layer::PerViewportSettingsCRC() return
1294 // equal values for equal settings, it is critical
1295 // that m_vp_settings[] be sorted.
1296 ud->m_vp_settings.QuickSort(ON__LayerPerViewSettings::Compare);
1297
1298 for ( i = 0; i <= vp_settings_count; i++ ) // "i <= ..." is correct because of the .AppendNew()
1299 {
1300 if ( 0 == memcmp(&viewport_id,&vp_settings[i].m_viewport_id,sizeof(ON_UUID)) )
1301 return (vp_settings+i);
1302 }
1303 }
1304 }
1305 }
1306 return 0;
1307 }
1308
DeleteViewportSettings(const ON_Layer & layer,const unsigned char * layer_m_extension_bits,const ON__LayerPerViewSettings * vp_settings_to_delete)1309 void ON__LayerExtensions::DeleteViewportSettings(
1310 const ON_Layer& layer,
1311 const unsigned char* layer_m_extension_bits,
1312 const ON__LayerPerViewSettings* vp_settings_to_delete
1313 )
1314 {
1315 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(layer,layer_m_extension_bits,false);
1316 if ( ud )
1317 {
1318 if ( 0 == vp_settings_to_delete )
1319 {
1320 delete ud;
1321 // Set bit 0x01 of ON_Layer::m_extension_bits to prevent
1322 // ON_Layer visibilty and color queries from wasting
1323 // time looking for userdata.
1324 SetExtensionBit( const_cast<unsigned char*>(layer_m_extension_bits), 0x01 );
1325 }
1326 else
1327 {
1328 const size_t vp_settings_count = ud->m_vp_settings.Count();
1329 if ( vp_settings_count > 0 )
1330 {
1331 const ON__LayerPerViewSettings* vp_settings0 = ud->m_vp_settings.Array();
1332 if ( vp_settings0 <= vp_settings_to_delete )
1333 {
1334 int i = (int)(vp_settings_to_delete-vp_settings0);
1335 ud->m_vp_settings.Remove(i);
1336 }
1337 }
1338 if ( ud->IsEmpty() )
1339 {
1340 delete ud;
1341 // Set bit 0x01 of ON_Layer::m_extension_bits to prevent
1342 // ON_Layer visibilty and color queries from wasting
1343 // time looking for userdata.
1344 SetExtensionBit( const_cast<unsigned char*>(layer_m_extension_bits), 0x01 );
1345 }
1346 }
1347 }
1348 }
1349
IsEmpty() const1350 bool ON__LayerExtensions::IsEmpty() const
1351 {
1352 const int count = m_vp_settings.Count();
1353
1354 for ( int i = 0; i < count; i++ )
1355 if ( 0 != m_vp_settings[i].SettingsMask() )
1356 return false;
1357
1358 return true; // nothing of value in this user data
1359 }
1360
1361 //
1362 // END ON__LayerExtensions user data class
1363 //
1364 ////////////////////////////////////////////////////////////////
1365
1366
1367
1368 ////////////////////////////////////////////////////////////////
1369 //
1370 // BEGIN ON_Layer per viewport interface functions
1371 //
1372
SetPerViewportColor(ON_UUID viewport_id,ON_Color layer_color)1373 void ON_Layer::SetPerViewportColor( ON_UUID viewport_id, ON_Color layer_color )
1374 {
1375 if ( ON_UuidIsNil(viewport_id) )
1376 {
1377 DeletePerViewportColor(viewport_id);
1378 if ( ON_Color::UnsetColor != layer_color )
1379 m_color = layer_color;
1380 }
1381 else
1382 {
1383 bool bSet = ( layer_color != ON_UNSET_COLOR );
1384 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, bSet );
1385 if ( vp_settings )
1386 {
1387 vp_settings->m_color = layer_color;
1388 if ( !bSet && 0 == vp_settings->SettingsMask() )
1389 ON__LayerExtensions::DeleteViewportSettings(*this, &m_extension_bits, vp_settings);
1390 }
1391 }
1392 }
1393
SetColor(ON_Color layer_color,const ON_UUID & viewport_id)1394 void ON_Layer::SetColor( ON_Color layer_color, const ON_UUID& viewport_id )
1395 {
1396 SetPerViewportColor( viewport_id, layer_color );
1397 }
1398
PerViewportColor(ON_UUID viewport_id) const1399 ON_Color ON_Layer::PerViewportColor( ON_UUID viewport_id ) const
1400 {
1401 if ( !ExtensionBit(m_extension_bits,0x01) )
1402 {
1403 const ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1404 if ( 0 != vp_settings && ON_UNSET_COLOR != vp_settings->m_color )
1405 return vp_settings->m_color;
1406 }
1407
1408 return m_color;
1409 }
1410
Color(const ON_UUID & viewport_id) const1411 ON_Color ON_Layer::Color( const ON_UUID& viewport_id ) const
1412 {
1413 return PerViewportColor( viewport_id );
1414 }
1415
SetPerViewportPlotColor(ON_UUID viewport_id,ON_Color plot_color)1416 void ON_Layer::SetPerViewportPlotColor( ON_UUID viewport_id, ON_Color plot_color )
1417 {
1418 if ( ON_UuidIsNil(viewport_id) )
1419 {
1420 DeletePerViewportPlotColor(viewport_id);
1421 SetPlotColor(plot_color);
1422 }
1423 else
1424 {
1425 bool bSet = ( plot_color != ON_UNSET_COLOR );
1426 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, bSet );
1427 if ( vp_settings )
1428 {
1429 vp_settings->m_plot_color = plot_color;
1430 if ( !bSet && 0 == vp_settings->SettingsMask() )
1431 ON__LayerExtensions::DeleteViewportSettings(*this, &m_extension_bits,vp_settings);
1432 }
1433 }
1434 }
1435
SetPlotColor(ON_Color plot_color,const ON_UUID & viewport_id)1436 void ON_Layer::SetPlotColor( ON_Color plot_color, const ON_UUID& viewport_id )
1437 {
1438 return SetPerViewportPlotColor( viewport_id, plot_color );
1439 }
1440
PerViewportPlotColor(ON_UUID viewport_id) const1441 ON_Color ON_Layer::PerViewportPlotColor( ON_UUID viewport_id ) const
1442 {
1443 if ( !ExtensionBit(m_extension_bits,0x01) )
1444 {
1445 const ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1446 if ( 0 != vp_settings && vp_settings->m_plot_color != ON_UNSET_COLOR )
1447 return vp_settings->m_plot_color;
1448 }
1449
1450 // no per viewport settings
1451 // 2-Nov-2009 Dale Fugier, modified to call default PlotColor()
1452 return PlotColor();
1453 }
1454
PlotColor(const ON_UUID & viewport_id) const1455 ON_Color ON_Layer::PlotColor( const ON_UUID& viewport_id ) const
1456 {
1457 return PerViewportPlotColor(viewport_id);
1458 }
1459
SetPerViewportPlotWeight(ON_UUID viewport_id,double plot_weight_mm)1460 void ON_Layer::SetPerViewportPlotWeight( ON_UUID viewport_id, double plot_weight_mm )
1461 {
1462 if ( ON_UuidIsNil(viewport_id) )
1463 {
1464 DeletePerViewportPlotWeight(viewport_id);
1465 SetPlotWeight(plot_weight_mm); // this call handles invalid plot weights
1466 }
1467 else
1468 {
1469 bool bSet = ( ON_IsValid(plot_weight_mm) && (plot_weight_mm>=0.0 || -1.0==plot_weight_mm) );
1470 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, bSet );
1471 if ( vp_settings )
1472 {
1473 vp_settings->m_plot_weight_mm = (bSet) ? plot_weight_mm : ON_UNSET_VALUE;
1474 if ( !bSet && 0 == vp_settings->SettingsMask() )
1475 ON__LayerExtensions::DeleteViewportSettings(*this, &m_extension_bits, vp_settings);
1476 }
1477 }
1478 }
1479
SetPlotWeight(double plot_weight_mm,const ON_UUID & viewport_id)1480 void ON_Layer::SetPlotWeight( double plot_weight_mm, const ON_UUID& viewport_id )
1481 {
1482 SetPerViewportPlotWeight( viewport_id, plot_weight_mm );
1483 }
1484
PerViewportPlotWeight(ON_UUID viewport_id) const1485 double ON_Layer::PerViewportPlotWeight( ON_UUID viewport_id ) const
1486 {
1487 if ( !ExtensionBit(m_extension_bits,0x01) )
1488 {
1489 const ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1490 if ( 0 != vp_settings && (vp_settings->m_plot_weight_mm >= 0.0 || -1.0 == vp_settings->m_plot_weight_mm) )
1491 return vp_settings->m_plot_weight_mm;
1492 }
1493 return PlotWeight();
1494 }
1495
PlotWeight(const ON_UUID & viewport_id) const1496 double ON_Layer::PlotWeight( const ON_UUID& viewport_id ) const
1497 {
1498 return PerViewportPlotWeight(viewport_id);
1499 }
1500
1501
PerViewportIsVisible(ON_UUID viewport_id) const1502 bool ON_Layer::PerViewportIsVisible( ON_UUID viewport_id ) const
1503 {
1504 if ( !ExtensionBit(m_extension_bits,0x01) )
1505 {
1506 if ( ON_UuidIsNil(viewport_id) )
1507 {
1508 // see if layer is possibly visible in any viewport
1509 if ( !m_bVisible )
1510 {
1511 // default setting is off - check for per view visibility
1512 const ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1513 if ( 0 != ud )
1514 {
1515 int i, count = ud->m_vp_settings.Count();
1516 for ( i = 0; i < count; i++ )
1517 {
1518 if ( 1 == ud->m_vp_settings[i].m_visible )
1519 return true; // layer is visible in this viewport
1520 }
1521 }
1522 }
1523 }
1524 else
1525 {
1526 const ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1527 if (vp_settings)
1528 {
1529 if ( 1 == vp_settings->m_visible )
1530 return true; // per viewport ON setting overrides layer setting
1531 if ( 2 == vp_settings->m_visible )
1532 return false; // per viewport OFF setting overrides layer setting
1533 }
1534 }
1535 }
1536
1537 return IsVisible(); // use layer setting
1538 }
1539
IsVisible(const ON_UUID & viewport_id) const1540 bool ON_Layer::IsVisible( const ON_UUID& viewport_id ) const
1541 {
1542 return PerViewportIsVisible(viewport_id);
1543 }
1544
SetVisible(bool bVisible,const ON_UUID & viewport_id)1545 void ON_Layer::SetVisible( bool bVisible, const ON_UUID& viewport_id )
1546 {
1547 SetPerViewportVisible(viewport_id,bVisible);
1548 }
1549
SetPerViewportVisible(ON_UUID viewport_id,bool bVisible)1550 void ON_Layer::SetPerViewportVisible( ON_UUID viewport_id, bool bVisible )
1551 {
1552 if ( ON_UuidIsNil(viewport_id) )
1553 {
1554 // remove per view visible settings
1555 DeletePerViewportVisible(viewport_id);
1556
1557 // set general visibility setting
1558 SetVisible(bVisible);
1559 }
1560 else
1561 {
1562 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, true );
1563 if (vp_settings)
1564 {
1565 vp_settings->m_visible = (bVisible)
1566 ? 1 // layer is on in this viewport
1567 : 2; // layer is off in this viewport
1568 if ( ON_UuidIsNil(m_parent_layer_id) )
1569 vp_settings->m_persistent_visibility = 0;
1570 else if ( bVisible )
1571 vp_settings->m_persistent_visibility = 1;
1572 }
1573 }
1574 }
1575
PerViewportPersistentVisibility(ON_UUID viewport_id) const1576 bool ON_Layer::PerViewportPersistentVisibility( ON_UUID viewport_id ) const
1577 {
1578 // added to fix bug 82587
1579 if ( !ExtensionBit(m_extension_bits,0x01) && ON_UuidIsNotNil(viewport_id) )
1580 {
1581 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1582 if ( 0 != vp_settings )
1583 {
1584 if ( 1 == vp_settings->m_visible )
1585 return true;
1586 if ( ON_UuidIsNotNil(m_parent_layer_id) )
1587 {
1588 if ( 1 == vp_settings->m_persistent_visibility )
1589 return true;
1590 if ( 2 == vp_settings->m_persistent_visibility )
1591 return false;
1592 }
1593 if ( 2 == vp_settings->m_visible )
1594 return false;
1595 }
1596 }
1597
1598 return PersistentVisibility();
1599 }
1600
SetPerViewportPersistentVisibility(ON_UUID viewport_id,bool bVisibleChild)1601 void ON_Layer::SetPerViewportPersistentVisibility( ON_UUID viewport_id, bool bVisibleChild )
1602 {
1603 // added to fix bug 82587
1604 if ( ON_UuidIsNotNil(viewport_id) )
1605 {
1606 bool bCreate = false; // This "false" is correct because the per viewport visibility
1607 // setting needs to be in existance for this call to make any
1608 // sense in the first place.
1609 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, bCreate );
1610 if (vp_settings )
1611 vp_settings->m_persistent_visibility = bVisibleChild ? 1 : 2;
1612 }
1613 }
1614
UnsetPerViewportPersistentVisibility(ON_UUID viewport_id)1615 void ON_Layer::UnsetPerViewportPersistentVisibility( ON_UUID viewport_id )
1616 {
1617 // added to fix bug 82587
1618 if ( ON_UuidIsNil(viewport_id) )
1619 {
1620 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions( *this, &m_extension_bits, false );
1621 if ( 0 != ud )
1622 {
1623 for ( int i = 0; i < ud->m_vp_settings.Count(); i++ )
1624 {
1625 ud->m_vp_settings[i].m_persistent_visibility = 0;
1626 }
1627 }
1628 }
1629 else
1630 {
1631 bool bCreate = false; // This "false" is correct because the per viewport visibility
1632 // setting needs to be in existance for this call to make any
1633 // sense in the first place.
1634 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, bCreate );
1635 if (vp_settings )
1636 vp_settings->m_persistent_visibility = 0;
1637 }
1638 }
1639
DeletePerViewportColor(const ON_UUID & viewport_id)1640 void ON_Layer::DeletePerViewportColor( const ON_UUID& viewport_id )
1641 {
1642 if ( ON_UuidIsNil(viewport_id) )
1643 {
1644 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1645 if ( 0 != ud )
1646 {
1647 for ( int i = ud->m_vp_settings.Count(); i--; /*empty iterator*/ )
1648 {
1649 ud->m_vp_settings[i].m_color = ON_Color::UnsetColor;
1650 if ( 0 == ud->m_vp_settings[i].SettingsMask() )
1651 ud->m_vp_settings.Remove(i);
1652 }
1653 if ( ud->IsEmpty() )
1654 {
1655 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1656 ud = 0;
1657 }
1658 }
1659 }
1660 else
1661 {
1662 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1663 if (vp_settings)
1664 {
1665 vp_settings->m_color = ON_Color::UnsetColor;
1666 if ( 0 == vp_settings->SettingsMask() )
1667 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,vp_settings);
1668 }
1669 }
1670 }
1671
DeletePerViewportPlotColor(const ON_UUID & viewport_id)1672 void ON_Layer::DeletePerViewportPlotColor( const ON_UUID& viewport_id )
1673 {
1674 if ( ON_UuidIsNil(viewport_id) )
1675 {
1676 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1677 if ( 0 != ud )
1678 {
1679 for ( int i = ud->m_vp_settings.Count(); i--; /*empty iterator*/ )
1680 {
1681 ud->m_vp_settings[i].m_plot_color = ON_UNSET_COLOR;
1682 if ( 0 == ud->m_vp_settings[i].SettingsMask() )
1683 ud->m_vp_settings.Remove(i);
1684 }
1685 if ( ud->IsEmpty() )
1686 {
1687 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1688 ud = 0;
1689 }
1690 }
1691 }
1692 else
1693 {
1694 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1695 if (vp_settings)
1696 {
1697 vp_settings->m_plot_color = ON_UNSET_COLOR;
1698 if ( 0 == vp_settings->SettingsMask() )
1699 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,vp_settings);
1700 }
1701 }
1702 }
1703
UpdateViewportIds(const ON_UuidPairList & viewport_id_map)1704 int ON_Layer::UpdateViewportIds( const ON_UuidPairList& viewport_id_map )
1705 {
1706 if ( viewport_id_map.Count() <= 0 )
1707 return 0;
1708 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1709 if ( 0 == ud )
1710 return 0;
1711 int rc = 0;
1712 ON_UUID new_id;
1713 for ( int i = 0; i < ud->m_vp_settings.Count(); i++ )
1714 {
1715 ON__LayerPerViewSettings& s = ud->m_vp_settings[i];
1716 if ( viewport_id_map.FindId1(s.m_viewport_id,&new_id) && s.m_viewport_id != new_id )
1717 {
1718 s.m_viewport_id = new_id;
1719 rc++;
1720 }
1721 }
1722 return rc;
1723 }
1724
DeletePerViewportPlotWeight(const ON_UUID & viewport_id)1725 void ON_Layer::DeletePerViewportPlotWeight( const ON_UUID& viewport_id )
1726 {
1727 if ( ON_UuidIsNil(viewport_id) )
1728 {
1729 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1730 if ( 0 != ud )
1731 {
1732 for ( int i = ud->m_vp_settings.Count(); i--; /*empty iterator*/ )
1733 {
1734 ud->m_vp_settings[i].m_plot_weight_mm = ON_UNSET_VALUE;
1735 if ( 0 == ud->m_vp_settings[i].SettingsMask() )
1736 ud->m_vp_settings.Remove(i);
1737 }
1738 if ( ud->IsEmpty() )
1739 {
1740 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1741 ud = 0;
1742 }
1743 }
1744 }
1745 else
1746 {
1747 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1748 if (vp_settings)
1749 {
1750 vp_settings->m_plot_weight_mm = ON_UNSET_VALUE;
1751 if ( 0 == vp_settings->SettingsMask() )
1752 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,vp_settings);
1753 }
1754 }
1755 }
1756
DeletePerViewportVisible(const ON_UUID & viewport_id)1757 void ON_Layer::DeletePerViewportVisible( const ON_UUID& viewport_id )
1758 {
1759 if ( ON_UuidIsNil(viewport_id) )
1760 {
1761 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1762 if ( 0 != ud )
1763 {
1764 for ( int i = ud->m_vp_settings.Count(); i--; /*empty iterator*/ )
1765 {
1766 ud->m_vp_settings[i].m_visible = 0;
1767 ud->m_vp_settings[i].m_persistent_visibility = 0;
1768 if ( 0 == ud->m_vp_settings[i].SettingsMask() )
1769 ud->m_vp_settings.Remove(i);
1770 }
1771 if ( ud->IsEmpty() )
1772 {
1773 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1774 ud = 0;
1775 }
1776 }
1777 }
1778 else
1779 {
1780 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1781 if (vp_settings)
1782 {
1783 vp_settings->m_visible = 0;
1784 vp_settings->m_persistent_visibility = 0;
1785 if ( 0 == vp_settings->SettingsMask() )
1786 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,vp_settings);
1787 }
1788 }
1789 }
1790
GetPerViewportVisibilityViewportIds(ON_SimpleArray<ON_UUID> & viewport_id_list) const1791 void ON_Layer::GetPerViewportVisibilityViewportIds(
1792 ON_SimpleArray<ON_UUID>& viewport_id_list
1793 ) const
1794 {
1795 viewport_id_list.SetCount(0);
1796 const ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1797 if ( 0 != ud )
1798 {
1799 const int count = ud->m_vp_settings.Count();
1800 if ( count > 0 )
1801 {
1802 viewport_id_list.Reserve(count);
1803 for( int i = 0; i < count; i++ )
1804 {
1805 const ON__LayerPerViewSettings& s = ud->m_vp_settings[i];
1806 if ( 0 != ( ON_Layer::per_viewport_visible & s.SettingsMask() )
1807 || 0 != ( ON_Layer::per_viewport_persistent_visibility & s.SettingsMask() )
1808 )
1809 {
1810 viewport_id_list.Append(s.m_viewport_id);
1811 }
1812 }
1813 }
1814 }
1815 }
1816
HasPerViewportSettings(const ON_UUID & viewport_id) const1817 bool ON_Layer::HasPerViewportSettings( const ON_UUID& viewport_id ) const
1818 {
1819 return HasPerViewportSettings( viewport_id, 0xFFFFFFFF );
1820 }
1821
HasPerViewportSettings(ON_UUID viewport_id,unsigned int settings_mask) const1822 bool ON_Layer::HasPerViewportSettings(
1823 ON_UUID viewport_id,
1824 unsigned int settings_mask
1825 ) const
1826 {
1827
1828 if ( 0 != settings_mask )
1829 {
1830 if ( ON_UuidIsNil(viewport_id) )
1831 {
1832 const ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1833 if ( 0 != ud )
1834 {
1835 const int count = ud->m_vp_settings.Count();
1836 for ( int i = 0; i < count; i++ )
1837 {
1838 const ON__LayerPerViewSettings& s = ud->m_vp_settings[i];
1839 if ( 0 != (settings_mask & s.SettingsMask()) )
1840 return true;
1841 }
1842 }
1843 }
1844 else
1845 {
1846 const ON__LayerPerViewSettings* pvs = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1847 if ( 0 != pvs && 0 != (settings_mask & pvs->SettingsMask() ) )
1848 return true;
1849 }
1850 }
1851
1852 return false;
1853 }
1854
CopyPerViewportSettings(ON_UUID source_viewport_id,ON_UUID destination_viewport_id)1855 bool ON_Layer::CopyPerViewportSettings(ON_UUID source_viewport_id, ON_UUID destination_viewport_id)
1856 {
1857 bool rc = false;
1858 if ( ON_UuidIsNotNil(source_viewport_id)
1859 && ON_UuidIsNotNil(destination_viewport_id)
1860 && 0 != ON_UuidCompare(source_viewport_id, destination_viewport_id)
1861 )
1862 {
1863 const ON__LayerPerViewSettings* src = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, source_viewport_id, false );
1864 if( 0 != src )
1865 {
1866 // Make a local copy of the source settings because
1867 // the pointer to the source settings may be invalid
1868 // after adding storage for the destination settings.
1869 const ON__LayerPerViewSettings local_src(*src);
1870 src = 0; // never use this pointer again in this function.
1871 ON__LayerPerViewSettings* dst = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, destination_viewport_id, true);
1872 if( 0 != dst )
1873 {
1874 *dst = local_src;
1875 dst->m_viewport_id = destination_viewport_id;
1876 rc = true;
1877 }
1878 }
1879 }
1880 return rc;
1881 }
1882
CopyPerViewportSettings(const ON_Layer & source_layer,ON_UUID viewport_id,unsigned int settings_mask)1883 bool ON_Layer::CopyPerViewportSettings(
1884 const ON_Layer& source_layer,
1885 ON_UUID viewport_id,
1886 unsigned int settings_mask
1887 )
1888 {
1889 bool rc = false;
1890 if ( 0 != settings_mask && this != &source_layer )
1891 {
1892 if ( ON_UuidIsNil(viewport_id) )
1893 {
1894 // copy per viwport settings for every viewport
1895 const ON__LayerExtensions* soruce_layer_ud = ON__LayerExtensions::LayerExtensions(source_layer,&source_layer.m_extension_bits,false);
1896 if ( 0 != soruce_layer_ud )
1897 {
1898 const int count = soruce_layer_ud->m_vp_settings.Count();
1899 for ( int i = 0; i < count; i++ )
1900 {
1901 const ON__LayerPerViewSettings& src = soruce_layer_ud->m_vp_settings[i];
1902 ON__LayerPerViewSettings* dst = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, src.m_viewport_id, true);
1903 if ( 0 != dst )
1904 {
1905 dst->CopySettings(&src,settings_mask);
1906 rc = true;
1907 }
1908 }
1909 }
1910 }
1911 else
1912 {
1913 // copy per viwport settings for a specified viewport.
1914 const ON__LayerPerViewSettings* src = ON__LayerExtensions::ViewportSettings( source_layer, &source_layer.m_extension_bits, viewport_id, false);
1915 if ( 0 != src )
1916 {
1917 ON__LayerPerViewSettings* dst = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, true);
1918 if ( 0 != dst )
1919 {
1920 dst->CopySettings(src,settings_mask);
1921 rc = true;
1922 }
1923 }
1924 }
1925 }
1926 return rc;
1927 }
1928
1929
DeletePerViewportSettings(const ON_UUID & viewport_id) const1930 void ON_Layer::DeletePerViewportSettings( const ON_UUID& viewport_id ) const
1931 {
1932 if ( ON_UuidIsNil(viewport_id) )
1933 {
1934 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,0);
1935 }
1936 else
1937 {
1938 ON__LayerPerViewSettings* vp_settings = ON__LayerExtensions::ViewportSettings( *this, &m_extension_bits, viewport_id, false );
1939 if ( vp_settings )
1940 ON__LayerExtensions::DeleteViewportSettings(*this,&m_extension_bits,vp_settings);
1941 }
1942 }
1943
1944
CullPerViewportSettings(int viewport_id_count,const ON_UUID * viewport_id_list)1945 void ON_Layer::CullPerViewportSettings( int viewport_id_count, const ON_UUID* viewport_id_list )
1946 {
1947 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1948 if ( 0 != ud )
1949 {
1950 if ( viewport_id_count <= 0 )
1951 {
1952 // delete all per viewport settings
1953 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1954 ud = 0;
1955 }
1956 else if ( viewport_id_count > 0 && 0 != viewport_id_list )
1957 {
1958 int i, j;
1959 for ( i = ud->m_vp_settings.Count(); i--; /*empty iterator*/ )
1960 {
1961 const ON_UUID vp_id = ud->m_vp_settings[i].m_viewport_id;
1962 for ( j = 0; j < viewport_id_count; j++ )
1963 {
1964 if ( 0 == memcmp(&viewport_id_list[i],&vp_id,sizeof(vp_id)) )
1965 break;
1966 }
1967 if ( j >= viewport_id_count )
1968 {
1969 // ud->m_vp_settings[i].m_viewport_id is NOT in viewport_id_list[]
1970 ud->m_vp_settings.Remove(i);
1971 }
1972 }
1973 if ( ud->IsEmpty() )
1974 {
1975 // nothing useful in ud
1976 ON__LayerExtensions::DeleteViewportSettings( *this, &m_extension_bits, 0 );
1977 ud = 0;
1978 }
1979 }
1980 }
1981 }
1982
PerViewportSettingsCRC() const1983 ON__UINT32 ON_Layer::PerViewportSettingsCRC() const
1984 {
1985 ON__UINT32 crc = 0;
1986 if ( !ExtensionBit(m_extension_bits,0x01) )
1987 {
1988 ON__LayerExtensions* ud = ON__LayerExtensions::LayerExtensions(*this,&m_extension_bits,false);
1989 if ( 0 != ud )
1990 {
1991 for ( int i = 0; i < ud->m_vp_settings.Count(); i++ )
1992 crc = ud->m_vp_settings[i].DataCRC(crc);
1993 }
1994 }
1995 return crc;
1996 }
1997
1998 //
1999 // END ON_Layer per viewport interface functions
2000 //
2001 ////////////////////////////////////////////////////////////////
2002
2003
2004
Differences(const ON_Layer & layer0,const ON_Layer & layer1)2005 unsigned int ON_Layer::Differences( const ON_Layer& layer0, const ON_Layer& layer1 )
2006 {
2007 /*
2008 enum
2009 {
2010 none = 0,
2011 userdata = 1,
2012 color = 2,
2013 plot_color = 4,
2014 plot_weight = 8,
2015 visible = 16,
2016 locked = 32,
2017 expanded = 64,
2018 all = 0xFFFFFFFF
2019 }
2020 */
2021 unsigned int differences = 0;
2022
2023
2024 const ON_UserData* ud0 = layer0.FirstUserData();
2025 const ON_UserData* ud1 = layer1.FirstUserData();
2026 while ( 0 != ud0 && 0 != ud1 )
2027 {
2028 if ( ud0->m_userdata_uuid != ud1->m_userdata_uuid )
2029 break;
2030 ud0 = ud0->Next();
2031 ud1 = ud1->Next();
2032 }
2033 if ( 0 != ud0 || 0 != ud1 )
2034 differences |= ON_Layer::userdata_settings;
2035
2036 if ( layer0.m_color != layer1.m_color )
2037 differences |= ON_Layer::color_settings;
2038
2039 if ( layer0.m_plot_color != layer1.m_plot_color )
2040 differences |= ON_Layer::plot_color_settings;
2041
2042 if ( layer0.m_plot_weight_mm != layer1.m_plot_weight_mm )
2043 differences |= ON_Layer::plot_weight_settings;
2044
2045 if ( layer0.m_bVisible != layer1.m_bVisible )
2046 differences |= ON_Layer::visible_settings;
2047
2048 if ( layer0.m_bLocked != layer1.m_bLocked )
2049 differences |= ON_Layer::locked_settings;
2050
2051 // Note:
2052 // This function is used for comparing layers from different
2053 // documents. It does not make sense to compare values
2054 // like m_linetype_index, m_material_index and so on because
2055 // different indices may actually reference the same linetype
2056 // or material. If there is a compelling reason to compare
2057 // other settings, they can be added.
2058
2059 return differences;
2060 }
2061
2062
Set(unsigned int settings,const ON_Layer & settings_values)2063 void ON_Layer::Set( unsigned int settings, const ON_Layer& settings_values )
2064 {
2065 if ( 0 != (ON_Layer::userdata_settings & settings) )
2066 {
2067 // save original user data on this layer
2068 ON_UserDataHolder ud;
2069 ud.MoveUserDataFrom(*this);
2070
2071 // make a complete copy of the userdata on settings_values
2072 CopyUserData(settings_values);
2073
2074 // now restore any original user data that was not present on settings_values.
2075 ud.MoveUserDataTo(*this,true);
2076 }
2077
2078 if ( 0 != (ON_Layer::color_settings & settings) )
2079 {
2080 m_color = settings_values.m_color;
2081 }
2082
2083 if ( 0 != (ON_Layer::plot_color_settings & settings) )
2084 {
2085 m_plot_color = settings_values.m_plot_color;
2086 }
2087
2088 if ( 0 != (ON_Layer::plot_weight_settings & settings) )
2089 {
2090 m_plot_weight_mm = settings_values.m_plot_weight_mm;
2091 }
2092
2093 if ( 0 != (ON_Layer::visible_settings & settings) )
2094 {
2095 m_bVisible = settings_values.m_bVisible ? true : false;
2096 }
2097
2098 if ( 0 != (ON_Layer::locked_settings & settings) )
2099 {
2100 m_bLocked = settings_values.m_bLocked ? true : false;
2101 }
2102 }
2103
2104 class /*NEVER EXPORT THIS CLASS DEFINITION*/ ON__LayerSettingsUserData : public ON_UserData
2105 {
2106 #if !defined(ON_BOZO_VACCINE_BFB63C094BC7472789BB7CC754118200)
2107 #error Never copy this class definition or put this definition in a header file!
2108 #endif
2109 ON_OBJECT_DECLARE(ON__LayerSettingsUserData);
2110
2111 public:
2112 ON__LayerSettingsUserData();
2113 ~ON__LayerSettingsUserData();
2114 // default copy constructor and operator= work fine.
2115
2116 static ON__LayerSettingsUserData* LayerSettings(const ON_Layer& layer,bool bCreate);
2117
2118
2119 public:
2120 // virtual ON_Object override
2121 ON_BOOL32 IsValid( ON_TextLog* text_log = NULL ) const;
2122 // virtual ON_Object override
2123 unsigned int SizeOf() const;
2124 // virtual ON_Object override
2125 ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
2126 // virtual ON_Object override
2127 ON_BOOL32 Write(ON_BinaryArchive& binary_archive) const;
2128 // virtual ON_Object override
2129 ON_BOOL32 Read(ON_BinaryArchive& binary_archive);
2130 // virtual ON_UserData override
2131 ON_BOOL32 Archive() const;
2132 // virtual ON_UserData override
2133 ON_BOOL32 GetDescription( ON_wString& description );
2134
2135 public:
2136
2137 enum
2138 {
2139 valid_settings =
2140 (
2141 ON_Layer::color_settings
2142 | ON_Layer::plot_color_settings
2143 | ON_Layer::visible_settings
2144 | ON_Layer::locked_settings
2145 | ON_Layer::plot_weight_settings
2146 )
2147 };
2148
HaveSettings() const2149 bool HaveSettings() const {return 0 != (m_settings & ON__LayerSettingsUserData::valid_settings);}
2150
HaveColor() const2151 bool HaveColor() const {return 0 != (m_settings & ON_Layer::color_settings);}
HavePlotColor() const2152 bool HavePlotColor() const {return 0 != (m_settings & ON_Layer::plot_color_settings);}
HaveVisible() const2153 bool HaveVisible() const {return 0 != (m_settings & ON_Layer::visible_settings);}
HaveLocked() const2154 bool HaveLocked() const {return 0 != (m_settings & ON_Layer::locked_settings);}
HavePlotWeight() const2155 bool HavePlotWeight() const {return 0 != (m_settings & ON_Layer::plot_weight_settings);}
2156
Defaults()2157 void Defaults()
2158 {
2159 m_settings = 0;
2160 m_color = 0;
2161 m_plot_color = 0;
2162 m_bVisible = 0;
2163 m_bLocked = 0;
2164 m_plot_weight_mm = 0.0;
2165 }
2166
2167 unsigned int m_settings;
2168 ON_Color m_color;
2169 ON_Color m_plot_color;
2170 bool m_bVisible;
2171 bool m_bLocked;
2172 double m_plot_weight_mm;
2173
2174 };
2175
2176 #undef ON_BOZO_VACCINE_BFB63C094BC7472789BB7CC754118200
2177
2178 ON_OBJECT_IMPLEMENT(ON__LayerSettingsUserData,ON_UserData,"BFB63C09-4BC7-4727-89BB-7CC754118200");
2179
LayerSettings(const ON_Layer & layer,bool bCreate)2180 ON__LayerSettingsUserData* ON__LayerSettingsUserData::LayerSettings(const ON_Layer& layer,bool bCreate)
2181 {
2182 ON__LayerSettingsUserData* ud = ON__LayerSettingsUserData::Cast(layer.GetUserData(ON__LayerSettingsUserData::m_ON__LayerSettingsUserData_class_id.Uuid()));
2183 if ( !ud && bCreate )
2184 {
2185 ud = new ON__LayerSettingsUserData();
2186 const_cast<ON_Layer&>(layer).AttachUserData(ud);
2187 }
2188 return ud;
2189 }
2190
ON__LayerSettingsUserData()2191 ON__LayerSettingsUserData::ON__LayerSettingsUserData()
2192 {
2193 m_userdata_uuid = ON__LayerSettingsUserData::m_ON__LayerSettingsUserData_class_id.Uuid();
2194 m_application_uuid = ON_opennurbs5_id;
2195 m_userdata_copycount = 1;
2196 Defaults();
2197 }
2198
~ON__LayerSettingsUserData()2199 ON__LayerSettingsUserData::~ON__LayerSettingsUserData()
2200 {
2201 }
2202
2203 // virtual ON_Object override
IsValid(ON_TextLog * text_log) const2204 ON_BOOL32 ON__LayerSettingsUserData::IsValid( ON_TextLog* text_log ) const
2205 {
2206 return true;
2207 }
2208
2209 // virtual ON_Object override
SizeOf() const2210 unsigned int ON__LayerSettingsUserData::SizeOf() const
2211 {
2212 return (unsigned int)(sizeof(*this));
2213 }
2214
2215 // virtual ON_Object override
DataCRC(ON__UINT32 current_remainder) const2216 ON__UINT32 ON__LayerSettingsUserData::DataCRC(ON__UINT32 current_remainder) const
2217 {
2218 ON__UINT32 crc = current_remainder;
2219 crc = ON_CRC32(crc,sizeof(m_settings),&m_settings);
2220 if ( HaveColor() ) crc = ON_CRC32(crc,sizeof(m_color),&m_color);
2221 if ( HavePlotColor() ) crc = ON_CRC32(crc,sizeof(m_plot_color),&m_plot_color);
2222 if ( HaveVisible() ) crc = ON_CRC32(crc,sizeof(m_bVisible),&m_bVisible);
2223 if ( HaveLocked() ) crc = ON_CRC32(crc,sizeof(m_bLocked),&m_bLocked);
2224 if ( HavePlotWeight() ) crc = ON_CRC32(crc,sizeof(m_plot_weight_mm),&m_plot_weight_mm);
2225 return crc;
2226 }
2227
2228 // virtual ON_Object override
Write(ON_BinaryArchive & binary_archive) const2229 ON_BOOL32 ON__LayerSettingsUserData::Write(ON_BinaryArchive& binary_archive) const
2230 {
2231 bool rc = binary_archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
2232 if ( !rc )
2233 return false;
2234
2235 rc = false;
2236 for(;;)
2237 {
2238 if ( !binary_archive.WriteInt(m_settings) )
2239 break;
2240 if ( HaveColor() && !binary_archive.WriteColor(m_color) )
2241 break;
2242 if ( HavePlotColor() && !binary_archive.WriteColor(m_plot_color) )
2243 break;
2244 if ( HaveVisible() && !binary_archive.WriteBool(m_bVisible) )
2245 break;
2246 if ( HaveLocked() && !binary_archive.WriteBool(m_bLocked) )
2247 break;
2248 if ( HavePlotWeight() && !binary_archive.WriteDouble(m_plot_weight_mm) )
2249 break;
2250
2251 rc = true;
2252 break;
2253 }
2254
2255 if ( !binary_archive.EndWrite3dmChunk() )
2256 rc = false;
2257
2258 return rc;
2259 }
2260
2261 // virtual ON_Object override
Read(ON_BinaryArchive & binary_archive)2262 ON_BOOL32 ON__LayerSettingsUserData::Read(ON_BinaryArchive& binary_archive)
2263 {
2264 Defaults();
2265
2266 int major_version = 0;
2267 int minor_version = 0;
2268 bool rc = binary_archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
2269 if ( !rc )
2270 return false;
2271
2272 rc = false;
2273 while ( 1 == major_version )
2274 {
2275 if ( !binary_archive.ReadInt(&m_settings) )
2276 break;
2277 if ( HaveColor() && !binary_archive.ReadColor(m_color) )
2278 break;
2279 if ( HavePlotColor() && !binary_archive.ReadColor(m_plot_color) )
2280 break;
2281 if ( HaveVisible() && !binary_archive.ReadBool(&m_bVisible) )
2282 break;
2283 if ( HaveLocked() && !binary_archive.ReadBool(&m_bLocked) )
2284 break;
2285 if ( HavePlotWeight() && !binary_archive.ReadDouble(&m_plot_weight_mm) )
2286 break;
2287 rc = true;
2288 break;
2289 }
2290
2291 if ( !binary_archive.EndRead3dmChunk() )
2292 rc = false;
2293
2294 return rc;
2295 }
2296
2297 // virtual ON_UserData override
Archive() const2298 ON_BOOL32 ON__LayerSettingsUserData::Archive() const
2299 {
2300 // don't save empty settings
2301 return HaveSettings();
2302 }
2303
2304 // virtual ON_UserData override
GetDescription(ON_wString & description)2305 ON_BOOL32 ON__LayerSettingsUserData::GetDescription( ON_wString& description )
2306 {
2307 description = L"Saved Layer Settings";
2308 return true;
2309 }
2310
2311
2312
SaveSettings(unsigned int settings,bool bUpdate)2313 void ON_Layer::SaveSettings( unsigned int settings, bool bUpdate )
2314 {
2315 ON__LayerSettingsUserData* ud;
2316 if ( 0 == (settings & ON__LayerSettingsUserData::valid_settings) )
2317 {
2318 if ( !bUpdate )
2319 {
2320 // delete any existing user data
2321 ud = ON__LayerSettingsUserData::LayerSettings(*this,false);
2322 if ( ud )
2323 {
2324 delete ud;
2325 ud = 0;
2326 }
2327 }
2328 }
2329 else
2330 {
2331 ud = ON__LayerSettingsUserData::LayerSettings(*this,true);
2332 if ( !bUpdate )
2333 {
2334 ud->Defaults();
2335 ud->m_settings = settings;
2336 }
2337 else
2338 {
2339 ud->m_settings |= settings;
2340 }
2341 if ( ud->HaveColor() )
2342 ud->m_color = m_color;
2343
2344 if ( ud->HavePlotColor() )
2345 ud->m_plot_color = m_plot_color;
2346
2347 if ( ud->HaveVisible() )
2348 ud->m_bVisible = PersistentVisibility();
2349
2350 if ( ud->HaveLocked() )
2351 ud->m_bLocked = PersistentLocking();
2352
2353 if ( ud->HavePlotWeight() )
2354 ud->m_plot_weight_mm = m_plot_weight_mm;
2355 }
2356 }
2357
SavedSettings() const2358 unsigned int ON_Layer::SavedSettings() const
2359 {
2360 const ON__LayerSettingsUserData* ud = ON__LayerSettingsUserData::LayerSettings(*this,false);
2361 return ( 0 != ud ? ud->m_settings : 0 );
2362 }
2363
GetSavedSettings(ON_Layer & layer,unsigned int & settings) const2364 bool ON_Layer::GetSavedSettings( ON_Layer& layer, unsigned int& settings ) const
2365 {
2366 const ON__LayerSettingsUserData* ud = ON__LayerSettingsUserData::LayerSettings(*this,false);
2367 if ( 0 == ud )
2368 return false;
2369 bool rc = false;
2370
2371 if ( ud->HaveColor() )
2372 {
2373 layer.m_color = ud->m_color;
2374 rc = true;
2375 }
2376
2377 if ( ud->HavePlotColor() )
2378 {
2379 layer.m_plot_color = ud->m_plot_color;
2380 rc = true;
2381 }
2382
2383 if ( ud->HaveVisible() )
2384 {
2385 layer.m_bVisible = ud->m_bVisible;
2386 rc = true;
2387 }
2388
2389 if ( ud->HaveLocked() )
2390 {
2391 layer.m_bLocked = ud->m_bLocked;
2392 rc = true;
2393 }
2394
2395 if ( ud->HavePlotWeight() )
2396 {
2397 layer.m_plot_weight_mm = ud->m_plot_weight_mm;
2398 rc = true;
2399 }
2400
2401 (void)rc;//G+Smo
2402 return true;
2403 }
2404
PersistentVisibility() const2405 bool ON_Layer::PersistentVisibility() const
2406 {
2407 if ( !m_bVisible && ON_UuidIsNotNil(m_parent_layer_id) )
2408 {
2409 switch ( 0x06 & m_extension_bits )
2410 {
2411 case 0x02:
2412 return true;
2413 case 0x04:
2414 return false;
2415 }
2416 }
2417
2418 return m_bVisible;
2419 }
2420
SetPersistentVisibility(bool bVisibleChild)2421 void ON_Layer::SetPersistentVisibility(bool bVisibleChild)
2422 {
2423 const unsigned char and_mask = 0xF9;
2424 const unsigned char or_bit = ON_UuidIsNotNil(m_parent_layer_id)
2425 ? (bVisibleChild ? 0x02 : 0x04)
2426 : 0x00;
2427 m_extension_bits &= and_mask;
2428 m_extension_bits |= or_bit;
2429 }
2430
UnsetPersistentVisibility()2431 void ON_Layer::UnsetPersistentVisibility()
2432 {
2433 const unsigned char and_mask = 0xF9;
2434 m_extension_bits &= and_mask;
2435 }
2436
PersistentLocking() const2437 bool ON_Layer::PersistentLocking() const
2438 {
2439 if ( m_bLocked && ON_UuidIsNotNil(m_parent_layer_id) )
2440 {
2441 switch ( 0x18 & m_extension_bits )
2442 {
2443 case 0x08:
2444 return true;
2445 case 0x10:
2446 return false;
2447 }
2448 }
2449
2450 return m_bLocked;
2451 }
2452
SetPersistentLocking(bool bLockedChild)2453 void ON_Layer::SetPersistentLocking(bool bLockedChild)
2454 {
2455 const unsigned char and_mask = 0xE7;
2456 const unsigned char or_bit = ON_UuidIsNotNil(m_parent_layer_id)
2457 ? (bLockedChild ? 0x08 : 0x10)
2458 : 0x00;
2459 m_extension_bits &= and_mask;
2460 m_extension_bits |= or_bit;
2461 }
2462
UnsetPersistentLocking()2463 void ON_Layer::UnsetPersistentLocking()
2464 {
2465 // a set bit means the child will be unlocked when the parent is unlocked
2466 const unsigned char and_mask = 0xE7;
2467 m_extension_bits &= and_mask;
2468 }
2469
2470