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