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 // Easy way to toggle the name of the obsolete ON_3dmView::m_target
20 // variable when you want to change the name and compile to insure
21 // no rogue code is directly accessing this variable.  See
22 // ON_3dmView header for more comments.
23 //
24 //#define OBSOLETE_3DM_VIEW_TARGET m_target_HIDEME
25 #define OBSOLETE_3DM_VIEW_TARGET m_target
26 
27 //////////////////////////////////////////////////////////////////////////////////////////
28 //
29 // ON_3dmUnitsAndTolerances
30 //
31 
ON_UnitSystem()32 ON_UnitSystem::ON_UnitSystem()
33 : m_unit_system(ON::millimeters)
34 , m_custom_unit_scale(1.0)
35 {
36 }
37 
ON_UnitSystem(ON::unit_system us)38 ON_UnitSystem::ON_UnitSystem(ON::unit_system us)
39 : m_unit_system(ON::UnitSystem(us))
40 , m_custom_unit_scale(ON::UnitScale(ON::meters,m_unit_system))
41 {
42 }
43 
operator =(ON::unit_system us)44 ON_UnitSystem& ON_UnitSystem::operator=(ON::unit_system us)
45 {
46   m_unit_system = ON::UnitSystem(us);
47   if ( ON::custom_unit_system != us )
48   {
49     m_custom_unit_scale = ON::UnitScale(ON::meters,m_unit_system);
50     m_custom_unit_name.Destroy();
51   }
52   return *this;
53 }
54 
operator ==(const ON_UnitSystem & other)55 bool ON_UnitSystem::operator==(const ON_UnitSystem& other)
56 {
57   if ( m_unit_system != other.m_unit_system )
58     return false;
59 
60   if ( ON::custom_unit_system == m_unit_system )
61   {
62     if ( m_custom_unit_name.Compare(other.m_custom_unit_name) )
63       return false;
64     if ( !(m_custom_unit_scale == other.m_custom_unit_scale) )
65       return false;
66   }
67 
68   return true;
69 }
70 
operator !=(const ON_UnitSystem & other)71 bool ON_UnitSystem::operator!=(const ON_UnitSystem& other)
72 {
73   if ( m_unit_system != other.m_unit_system )
74     return true;
75 
76   if ( ON::custom_unit_system == m_unit_system )
77   {
78     if ( m_custom_unit_name.Compare(other.m_custom_unit_name) )
79       return true;
80     if ( m_custom_unit_scale != other.m_custom_unit_scale )
81       return true;
82   }
83 
84   return false;
85 }
86 
~ON_UnitSystem()87 ON_UnitSystem::~ON_UnitSystem()
88 {
89 }
90 
Default()91 void ON_UnitSystem::Default()
92 {
93   m_unit_system = ON::millimeters;
94   m_custom_unit_scale = 1.0;
95   m_custom_unit_name.Destroy();
96 }
97 
IsValid() const98 bool ON_UnitSystem::IsValid() const
99 {
100   if ( m_unit_system != ON::UnitSystem(m_unit_system) )
101   {
102     // bogus enum value
103     return false;
104   }
105 
106   if ( ON::custom_unit_system == m_unit_system )
107   {
108     if ( !ON_IsValid(m_custom_unit_scale) || m_custom_unit_scale <= 0.0 )
109     {
110       // m_custom_unit_scale should be > 0.0 and a valid double
111       return false;
112     }
113   }
114 
115   return true;
116 }
117 
IsSet() const118 bool ON_UnitSystem::IsSet() const
119 {
120   return ( ON::no_unit_system != m_unit_system && IsValid() );
121 }
122 
Unset()123 void ON_UnitSystem::Unset()
124 {
125   Default();
126   m_unit_system = ON::no_unit_system;
127 }
128 
129 
130 
Read(ON_BinaryArchive & file)131 bool ON_UnitSystem::Read( ON_BinaryArchive& file )
132 {
133   Default();
134 
135   int major_version = 0;
136   int minor_version = 0;
137 
138   if ( !file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version) )
139     return false;
140 
141   bool rc = (1 == major_version);
142   int i = m_unit_system;
143   if (rc)
144     rc = file.ReadInt( &i );
145   if (rc)
146     m_unit_system = ON::UnitSystem(i);
147   if (rc)
148     rc = file.ReadDouble( &m_custom_unit_scale );
149   if (rc)
150     rc = file.ReadString( m_custom_unit_name );
151 
152   if ( !file.EndRead3dmChunk() )
153     rc = false;
154 
155   return rc;
156 }
157 
Write(ON_BinaryArchive & file) const158 bool ON_UnitSystem::Write( ON_BinaryArchive& file ) const
159 {
160   if ( !file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0) )
161     return false;
162 
163 
164   // values saved in the file
165   //no_unit_system =  0,
166   //microns        =  1,  // 1.0e-6 meters
167   //millimeters    =  2,  // 1.0e-3 meters
168   //centimeters    =  3,  // 1.0e-2 meters
169   //meters         =  4,
170   //kilometers     =  5,  // 1.0e+3 meters
171   //microinches    =  6,  // 1.0e-6 inches
172   //mils           =  7,  // 1.0e-3 inches
173   //inches         =  8,  // 0.0254 meters
174   //feet           =  9,  // 12 inches
175   //miles          = 10,  // 63360 inches
176   //custom_unit_system = 11, // x meters with x defined in ON_3dmUnitsAndTolerances.m_custom_unit_scale
177 
178   bool rc = file.WriteInt( m_unit_system );
179   if (rc)
180     rc = file.WriteDouble( m_custom_unit_scale );
181   if (rc)
182     rc = file.WriteString( m_custom_unit_name );
183 
184   if ( !file.EndWrite3dmChunk() )
185     rc = false;
186 
187   return rc;
188 }
189 
Dump(ON_TextLog & dump) const190 void ON_UnitSystem::Dump( ON_TextLog& dump ) const
191 {
192   ON_wString sUnitSystem;
193   switch( m_unit_system )
194   {
195   case ON::no_unit_system:
196     sUnitSystem = "no units";
197     break;
198   case ON::angstroms:
199     sUnitSystem = "angstroms";
200     break;
201   case ON::nanometers:
202     sUnitSystem = "nanometers";
203     break;
204   case ON::microns:
205     sUnitSystem = "microns";
206     break;
207   case ON::millimeters:
208     sUnitSystem = "millimeters";
209     break;
210   case ON::decimeters:
211     sUnitSystem = "decimeters";
212     break;
213   case ON::centimeters:
214     sUnitSystem = "centimeters";
215     break;
216   case ON::meters:
217     sUnitSystem = "meters";
218     break;
219   case ON::dekameters:
220     sUnitSystem = "dekameters";
221     break;
222   case ON::hectometers:
223     sUnitSystem = "hectometers";
224     break;
225   case ON::kilometers:
226     sUnitSystem = "kilometers";
227     break;
228   case ON::megameters:
229     sUnitSystem = "megameters";
230     break;
231   case ON::gigameters:
232     sUnitSystem = "gigameters";
233     break;
234   case ON::microinches:
235     sUnitSystem = "microinches";
236     break;
237   case ON::mils:
238     sUnitSystem = "mils (= 0.001 inches)";
239     break;
240   case ON::inches:
241     sUnitSystem = "inches";
242     break;
243   case ON::feet:
244     sUnitSystem = "feet";
245     break;
246   case ON::yards:
247     sUnitSystem = "yards";
248     break;
249   case ON::miles:
250     sUnitSystem = "miles";
251     break;
252   case ON::printer_point:
253     sUnitSystem = "points (1/72 inch)";
254     break;
255   case ON::printer_pica:
256     sUnitSystem = "picas (1/6 inch)";
257     break;
258   case ON::nautical_mile:
259     sUnitSystem = "nautical miles";
260     break;
261   case ON::astronomical:
262     sUnitSystem = "astronomical units";
263     break;
264   case ON::lightyears:
265     sUnitSystem = "light years";
266     break;
267   case ON::parsecs:
268     sUnitSystem = "parsecs";
269     break;
270 
271   case ON::custom_unit_system:
272     if ( m_custom_unit_name.Length() > 0 )
273     {
274       const wchar_t* wsCustomUnitName = m_custom_unit_name.Array();
275       if ( 0 != wsCustomUnitName && 0 != wsCustomUnitName[0] )
276       {
277         sUnitSystem.Format("%ls (= %g meters)",
278                            wsCustomUnitName,
279                            m_custom_unit_scale);
280       }
281     }
282     else
283       sUnitSystem.Format("user defined unit (= %g meters)",m_custom_unit_scale);
284     break;
285   default:
286     sUnitSystem = "unknown unit system";
287     break;
288   }
289   const wchar_t* wsUnitSystem = sUnitSystem.Array();
290   if ( 0 != wsUnitSystem )
291     dump.Print("Unit system: %ls\n",wsUnitSystem);
292 }
293 
294 const ON_3dmUnitsAndTolerances ON_3dmUnitsAndTolerances::DefaultValue;
295 
Default()296 void ON_3dmUnitsAndTolerances::Default()
297 {
298   *this = ON_3dmUnitsAndTolerances::DefaultValue;
299   m_unit_system.m_custom_unit_name = L"Units";
300 }
301 
ON_3dmUnitsAndTolerances()302 ON_3dmUnitsAndTolerances::ON_3dmUnitsAndTolerances()
303 : m_unit_system(ON::millimeters)
304 , m_absolute_tolerance(0.001)
305 , m_angle_tolerance(ON_PI/180.0)
306 , m_relative_tolerance(0.01)
307 , m_distance_display_mode(ON::decimal)
308 , m_distance_display_precision(3)
309 {
310   // Do not set m_unit_system.m_custom_unit_name here.
311   // Doing so creates a heap allocation in the construction of
312   // ON_3dmUnitsAndTolerances::DefaultValue
313   // and doesn't make much sense in any case.
314 }
315 
~ON_3dmUnitsAndTolerances()316 ON_3dmUnitsAndTolerances::~ON_3dmUnitsAndTolerances()
317 {}
318 
ON_3dmUnitsAndTolerances(const ON_3dmUnitsAndTolerances & src)319 ON_3dmUnitsAndTolerances::ON_3dmUnitsAndTolerances(const ON_3dmUnitsAndTolerances& src )
320 : m_unit_system(src.m_unit_system)
321 , m_absolute_tolerance(src.m_absolute_tolerance)
322 , m_angle_tolerance(src.m_angle_tolerance)
323 , m_relative_tolerance(src.m_relative_tolerance)
324 , m_distance_display_mode(src.m_distance_display_mode)
325 , m_distance_display_precision(src.m_distance_display_precision)
326 {}
327 
operator =(const ON_3dmUnitsAndTolerances & src)328 ON_3dmUnitsAndTolerances& ON_3dmUnitsAndTolerances::operator=(const ON_3dmUnitsAndTolerances& src )
329 {
330   if ( this != &src )
331   {
332     m_unit_system = src.m_unit_system;
333     m_absolute_tolerance = src.m_absolute_tolerance;
334     m_angle_tolerance = src.m_angle_tolerance;
335     m_relative_tolerance = src.m_relative_tolerance;
336     m_distance_display_mode = src.m_distance_display_mode;
337     m_distance_display_precision = src.m_distance_display_precision;
338   }
339   return *this;
340 }
341 
Write(ON_BinaryArchive & file) const342 bool ON_3dmUnitsAndTolerances::Write( ON_BinaryArchive& file ) const
343 {
344   const int version = 102;
345   int i;
346 
347   // version 100 ON_3dmUnitsAndTolerances settings
348   bool rc = file.WriteInt( version );
349   i = m_unit_system.m_unit_system;
350   if ( rc ) rc = file.WriteInt( i );
351   if ( rc ) rc = file.WriteDouble( m_absolute_tolerance );
352   if ( rc ) rc = file.WriteDouble( m_angle_tolerance );
353   if ( rc ) rc = file.WriteDouble( m_relative_tolerance );
354 
355   // added in version 101
356   i = m_distance_display_mode;
357   if ( rc ) rc = file.WriteInt( i );
358   i = m_distance_display_precision;
359   if ( i < 0 || i > 20 ) {
360     ON_ERROR("ON_3dmUnitsAndTolerances::Write() - m_distance_display_precision out of range.");
361     i = 3;
362   }
363   if ( rc ) rc = file.WriteInt( i );
364 
365   // added in version 102
366   if ( rc ) rc = file.WriteDouble( m_unit_system.m_custom_unit_scale );
367   if ( rc ) rc = file.WriteString( m_unit_system.m_custom_unit_name );
368   return rc;
369 }
370 
Read(ON_BinaryArchive & file)371 bool ON_3dmUnitsAndTolerances::Read( ON_BinaryArchive& file )
372 {
373   *this = ON_3dmUnitsAndTolerances::DefaultValue;
374   int version = 0;
375   bool rc = file.ReadInt( &version );
376   if ( rc && version >= 100 && version < 200 ) {
377     int us = ON::no_unit_system;
378     rc = file.ReadInt( &us );
379     if ( rc )
380       m_unit_system.m_unit_system = ON::UnitSystem(us);
381     if ( rc ) rc = file.ReadDouble( &m_absolute_tolerance );
382     if ( rc ) rc = file.ReadDouble( &m_angle_tolerance );
383     if ( rc ) rc = file.ReadDouble( &m_relative_tolerance );
384     if ( version >= 101 ) {
385       int dm = ON::decimal;
386       if ( rc ) rc = file.ReadInt( &dm );
387       if ( rc ) m_distance_display_mode = ON::DistanceDisplayMode(dm);
388       if ( rc ) rc = file.ReadInt( &m_distance_display_precision );
389       if ( m_distance_display_precision < 0 || m_distance_display_precision > 20 )
390         m_distance_display_precision = 3; // some beta files had bogus values stored in file
391       if ( version >= 102 ) {
392         if ( rc ) rc = file.ReadDouble( &m_unit_system.m_custom_unit_scale );
393         if ( rc ) rc = file.ReadString( m_unit_system.m_custom_unit_name );
394       }
395     }
396   }
397   return rc;
398 }
399 
Dump(ON_TextLog & dump) const400 void ON_3dmUnitsAndTolerances::Dump( ON_TextLog& dump) const
401 {
402   m_unit_system.Dump(dump);
403   dump.Print("Absolute tolerance: %g\n",m_absolute_tolerance);
404   dump.Print("Angle tolerance: %g\n",m_angle_tolerance);
405 }
406 
Scale(ON::unit_system us) const407 double ON_3dmUnitsAndTolerances::Scale( ON::unit_system us ) const
408 {
409   // Example: If us = meters and m_unit_system = centimeters,
410   // then Scale() returns 100.
411   return ON::UnitScale( us, m_unit_system );
412 }
413 
414 
TolerancesAreValid() const415 bool ON_3dmUnitsAndTolerances::TolerancesAreValid() const
416 {
417   for(;;)
418   {
419     if ( !(m_absolute_tolerance > 0.0) )
420       break;
421 
422     if ( !(m_angle_tolerance > 0.0 && m_angle_tolerance <= ON_PI) )
423       break;
424 
425     if ( !( m_relative_tolerance > 0.0 && m_relative_tolerance < 1.0) )
426       break;
427 
428     return true;
429   }
430 
431   return false;
432 }
433 
SetInvalidTolerancesToDefaultValues()434 unsigned int ON_3dmUnitsAndTolerances::SetInvalidTolerancesToDefaultValues()
435 {
436   unsigned int rc = 0;
437 
438   if ( !(m_absolute_tolerance > 0.0) )
439   {
440     rc |= 1;
441     m_absolute_tolerance = ON_3dmUnitsAndTolerances::DefaultValue.m_absolute_tolerance;
442   }
443 
444   if ( !(m_angle_tolerance > 0.0 && m_angle_tolerance <= ON_PI) )
445   {
446     rc |= 2;
447     m_angle_tolerance = ON_3dmUnitsAndTolerances::DefaultValue.m_angle_tolerance;
448   }
449 
450   if ( !( m_relative_tolerance > 0.0 && m_relative_tolerance < 1.0) )
451   {
452     rc |= 4;
453     m_relative_tolerance = ON_3dmUnitsAndTolerances::DefaultValue.m_relative_tolerance;
454   }
455 
456   return rc;
457 }
458 
459 //////////////////////////////////////////////////////////////////////////////////////////
460 //
461 // ON_3dmRenderSettings
462 //
Dump(ON_TextLog & text_log) const463 void ON_3dmRenderSettings::Dump( ON_TextLog& text_log ) const
464 {
465   text_log.Print("m_bCustomImageSize = %s\n",m_bCustomImageSize?"true":"false");
466   text_log.Print("m_image_width = %d\n",m_image_width);
467   text_log.Print("m_image_height = %d\n",m_image_height);
468   text_log.Print("m_image_dpi = %g\n",m_image_dpi);
469   text_log.Print("m_image_us = %d\n",m_image_us);
470   text_log.Print("m_ambient_light rgb = ");text_log.PrintRGB(m_ambient_light);text_log.Print("\n");
471   text_log.Print("m_background_style = %d\n",m_background_style);
472   text_log.Print("m_background_color rgb = ");text_log.PrintRGB(m_background_color);text_log.Print("\n");
473   text_log.Print("m_background_bitmap_filename = ");text_log.Print(m_background_bitmap_filename);text_log.Print("\n");
474   text_log.Print("m_bUseHiddenLights = %s\n",m_bUseHiddenLights?"true":"false");
475   text_log.Print("m_bDepthCue = %s\n",m_bDepthCue?"true":"false");
476   text_log.Print("m_bFlatShade = %s\n",m_bFlatShade?"true":"false");
477   text_log.Print("m_bRenderBackfaces = %s\n",m_bRenderBackfaces?"true":"false");
478   text_log.Print("m_bRenderPoints = %s\n",m_bRenderPoints?"true":"false");
479   text_log.Print("m_bRenderCurves = %s\n",m_bRenderCurves?"true":"false");
480   text_log.Print("m_bRenderIsoparams = %s\n",m_bRenderIsoparams?"true":"false");
481   text_log.Print("m_bRenderMeshEdges = %s\n",m_bRenderMeshEdges?"true":"false");
482   text_log.Print("m_bRenderAnnotation = %s\n",m_bRenderAnnotation?"true":"false");
483 
484   text_log.Print("m_antialias_style = %d\n",m_antialias_style);
485   text_log.Print("m_shadowmap_style = %d\n",m_shadowmap_style);
486   text_log.Print("m_shadowmap_width = %d\n",m_shadowmap_width);
487   text_log.Print("m_shadowmap_height = %d\n",m_shadowmap_height);
488   text_log.Print("m_shadowmap_offset = %g\n",m_shadowmap_offset);
489 
490   text_log.Print("m_bScaleBackgroundToFit = %s\n",m_bScaleBackgroundToFit?"true":"false");
491 }
492 
Default()493 void ON_3dmRenderSettings::Default()
494 {
495   m_bCustomImageSize = false;
496   m_image_width  = 800;
497   m_image_height = 600;
498   m_bScaleBackgroundToFit = false;
499   memset(m_reserved1,0,sizeof(m_reserved1));
500   m_image_dpi = 72.0;
501   m_image_us = ON::inches;
502 
503 
504   m_ambient_light.SetRGB( 0, 0, 0);
505 
506   m_background_style = 0;
507   m_background_color.SetRGB(160,160,160);
508   m_background_bottom_color.SetRGB(160,160,160);
509   m_background_bitmap_filename.Destroy();
510 
511   m_bUseHiddenLights = false;
512 
513   m_bDepthCue = false;
514   m_bFlatShade = false;
515 
516   m_bRenderBackfaces = true;
517   m_bRenderPoints = false;
518   m_bRenderCurves = false;
519   m_bRenderIsoparams = false;
520   m_bRenderMeshEdges = false;
521   m_bRenderAnnotation = false;
522 
523   m_antialias_style = 1;
524 
525   m_shadowmap_style = 1;
526   m_shadowmap_width = 1000;
527   m_shadowmap_height = 1000;
528   m_shadowmap_offset = 0.75;
529 
530   m_bUsesAmbientAttr      = true;
531   m_bUsesBackgroundAttr   = true;
532   m_bUsesBackfaceAttr     = false;
533   m_bUsesPointsAttr       = false;
534   m_bUsesCurvesAttr       = true;
535   m_bUsesIsoparmsAttr     = true;
536   m_bUsesMeshEdgesAttr    = false;
537   m_bUsesAnnotationAttr   = true;
538   m_bUsesHiddenLightsAttr = true;
539 
540   memset(m_reserved2,0,sizeof(m_reserved2));
541 }
542 
ON_3dmRenderSettings()543 ON_3dmRenderSettings::ON_3dmRenderSettings()
544 {
545   Default();
546 }
547 
~ON_3dmRenderSettings()548 ON_3dmRenderSettings::~ON_3dmRenderSettings()
549 {
550   m_background_bitmap_filename.Destroy();
551 }
552 
ON_3dmRenderSettings(const ON_3dmRenderSettings & src)553 ON_3dmRenderSettings::ON_3dmRenderSettings(const ON_3dmRenderSettings& src )
554 {
555   Default();
556   *this = src;
557 }
558 
operator =(const ON_3dmRenderSettings & src)559 ON_3dmRenderSettings& ON_3dmRenderSettings::operator=(const ON_3dmRenderSettings& src )
560 {
561   if ( this != &src ) {
562     m_bCustomImageSize = src.m_bCustomImageSize;
563     m_image_width = src.m_image_width;
564     m_image_height = src.m_image_height;
565     m_bScaleBackgroundToFit = src.m_bScaleBackgroundToFit;
566     m_image_dpi = src.m_image_dpi;
567     m_image_us = src.m_image_us;
568     m_ambient_light = src.m_ambient_light;
569     m_background_style = src.m_background_style;
570     m_background_color = src.m_background_color;
571     m_background_bitmap_filename = src.m_background_bitmap_filename;
572     m_bUseHiddenLights = src.m_bUseHiddenLights;
573     m_bDepthCue = src.m_bDepthCue;
574     m_bFlatShade = src.m_bFlatShade;
575     m_bRenderBackfaces = src.m_bRenderBackfaces;
576     m_bRenderPoints = src.m_bRenderPoints;
577     m_bRenderCurves = src.m_bRenderCurves;
578     m_bRenderIsoparams = src.m_bRenderIsoparams;
579     m_bRenderMeshEdges = src.m_bRenderMeshEdges;
580     m_bRenderAnnotation = src.m_bRenderAnnotation;
581     m_antialias_style = src.m_antialias_style;
582     m_shadowmap_style = src.m_shadowmap_style;
583     m_shadowmap_width = src.m_shadowmap_width;
584     m_shadowmap_height = src.m_shadowmap_height;
585     m_shadowmap_offset = src.m_shadowmap_offset;
586 
587     m_background_bottom_color = src.m_background_bottom_color;
588     m_bUsesAmbientAttr      = src.m_bUsesAmbientAttr;
589     m_bUsesBackgroundAttr   = src.m_bUsesBackgroundAttr;
590     m_bUsesBackfaceAttr     = src.m_bUsesBackfaceAttr;
591     m_bUsesPointsAttr       = src.m_bUsesPointsAttr;
592     m_bUsesCurvesAttr       = src.m_bUsesCurvesAttr;
593     m_bUsesIsoparmsAttr     = src.m_bUsesIsoparmsAttr;
594     m_bUsesMeshEdgesAttr    = src.m_bUsesMeshEdgesAttr;
595     m_bUsesAnnotationAttr   = src.m_bUsesAnnotationAttr;
596     m_bUsesHiddenLightsAttr = src.m_bUsesHiddenLightsAttr;
597   }
598   return *this;
599 }
600 
Write(ON_BinaryArchive & file) const601 bool ON_3dmRenderSettings::Write( ON_BinaryArchive& file ) const
602 {
603   int i;
604   // version 103: 11 November 2010
605   const int version = 103;
606   bool rc = file.WriteInt( version );
607   // version >= 100
608   if (rc) rc = file.WriteInt( m_bCustomImageSize );
609   if (rc) rc = file.WriteInt( m_image_width );
610   if (rc) rc = file.WriteInt( m_image_height );
611   if (rc) rc = file.WriteColor( m_ambient_light );
612   if (rc) rc = file.WriteInt( m_background_style );
613   if (rc) rc = file.WriteColor( m_background_color );
614   if (rc) rc = file.WriteString( m_background_bitmap_filename );
615   if (rc) rc = file.WriteInt( m_bUseHiddenLights );
616   if (rc) rc = file.WriteInt( m_bDepthCue );
617   if (rc) rc = file.WriteInt( m_bFlatShade );
618 
619   // 26 August 2003 Dale Lear:
620   //     When saving V2 files, turn on backfaces. RR 11656
621   //
622   i = (file.Archive3dmVersion() >= 3) ? m_bRenderBackfaces : 1;
623   if (rc) rc = file.WriteInt( i );
624 
625   if (rc) rc = file.WriteInt( m_bRenderPoints );
626   if (rc) rc = file.WriteInt( m_bRenderCurves );
627   if (rc) rc = file.WriteInt( m_bRenderIsoparams );
628   if (rc) rc = file.WriteInt( m_bRenderMeshEdges );
629   if (rc) rc = file.WriteInt( m_bRenderAnnotation );
630   if (rc) rc = file.WriteInt( m_antialias_style );
631   if (rc) rc = file.WriteInt( m_shadowmap_style );
632   if (rc) rc = file.WriteInt( m_shadowmap_width );
633   if (rc) rc = file.WriteInt( m_shadowmap_height );
634   if (rc) rc = file.WriteDouble( m_shadowmap_offset );
635   // version >= 101 begins here
636   if (rc) rc = file.WriteDouble( m_image_dpi );
637   i = m_image_us;
638   if (rc) rc = file.WriteInt( i );
639   // version >= 102 begins here
640   if (rc) rc = file.WriteColor( m_background_bottom_color );
641 
642   // version >= 103 begins here - added 11 November 2010
643   if (rc) rc = file.WriteBool( m_bScaleBackgroundToFit );
644 
645   return rc;
646 }
647 
Read(ON_BinaryArchive & file)648 bool ON_3dmRenderSettings::Read( ON_BinaryArchive& file )
649 {
650   Default();
651   int version = 0;
652   bool rc = file.ReadInt( &version );
653   if ( rc && version >= 100 && version < 200 )
654   {
655     if (rc)
656       rc = file.ReadInt( &m_bCustomImageSize );
657     if (rc)
658       rc = file.ReadInt( &m_image_width );
659     if (rc)
660       rc = file.ReadInt( &m_image_height );
661     if (rc)
662       rc = file.ReadColor( m_ambient_light );
663     if (rc)
664       rc = file.ReadInt( &m_background_style );
665     if (rc)
666       rc = file.ReadColor( m_background_color );
667     if (rc)
668       rc = file.ReadString( m_background_bitmap_filename );
669     if (rc)
670       rc = file.ReadInt( &m_bUseHiddenLights );
671     if (rc)
672       rc = file.ReadInt( &m_bDepthCue );
673     if (rc)
674       rc = file.ReadInt( &m_bFlatShade );
675     if (rc)
676       rc = file.ReadInt( &m_bRenderBackfaces );
677     if (rc)
678       rc = file.ReadInt( &m_bRenderPoints );
679     if (rc)
680       rc = file.ReadInt( &m_bRenderCurves );
681     if (rc)
682       rc = file.ReadInt( &m_bRenderIsoparams );
683     if (rc)
684       rc = file.ReadInt( &m_bRenderMeshEdges );
685     if (rc)
686       rc = file.ReadInt( &m_bRenderAnnotation );
687     if (rc)
688       rc = file.ReadInt( &m_antialias_style );
689     if (rc)
690       rc = file.ReadInt( &m_shadowmap_style );
691     if (rc)
692       rc = file.ReadInt( &m_shadowmap_width );
693     if (rc)
694       rc = file.ReadInt( &m_shadowmap_height );
695     if (rc)
696       rc = file.ReadDouble( &m_shadowmap_offset );
697     if (rc && version >= 101)
698     {
699       if (rc)
700         rc = file.ReadDouble( &m_image_dpi );
701       if (rc)
702       {
703         int i;
704         rc = file.ReadInt(&i);
705         if (rc)
706           m_image_us = ON::UnitSystem(i);
707       }
708 
709       if (rc && version >= 102)
710       {
711         rc = file.ReadColor( m_background_bottom_color );
712         if (rc && version >= 103)
713         {
714           rc = file.ReadBool( &m_bScaleBackgroundToFit );
715         }
716       }
717     }
718   }
719   return rc;
720 }
721 
ScaleBackgroundToFit() const722 bool ON_3dmRenderSettings::ScaleBackgroundToFit() const
723 {
724   return m_bScaleBackgroundToFit;
725 }
726 
SetScaleBackgroundToFit(bool bScaleBackgroundToFit)727 void ON_3dmRenderSettings::SetScaleBackgroundToFit( bool bScaleBackgroundToFit )
728 {
729   // The "? true : false" is here to prevent hacks from using a bool
730   // to store settings besides 1 and 0.
731   m_bScaleBackgroundToFit = bScaleBackgroundToFit?true:false;
732 }
733 
734 
735 //////////////////////////////////////////////////////////////////////////////////////////
736 //
737 // ON_3dmAnnotationSettings
738 //
739 
ON_3dmAnnotationSettings()740 ON_3dmAnnotationSettings::ON_3dmAnnotationSettings()
741 {
742   Default();
743 }
744 
~ON_3dmAnnotationSettings()745 ON_3dmAnnotationSettings::~ON_3dmAnnotationSettings()
746 {
747 }
748 
ON_3dmAnnotationSettings(const ON_3dmAnnotationSettings & src)749 ON_3dmAnnotationSettings::ON_3dmAnnotationSettings(const ON_3dmAnnotationSettings& src)
750 {
751   Default();
752   *this = src;
753 
754 }
755 
operator =(const ON_3dmAnnotationSettings & src)756 ON_3dmAnnotationSettings& ON_3dmAnnotationSettings::operator=(const ON_3dmAnnotationSettings& src)
757 {
758   if ( this != &src ) {
759     m_dimscale = src.m_dimscale;
760     m_textheight = src.m_textheight;
761     m_dimexe = src.m_dimexe;
762     m_dimexo = src.m_dimexo;
763     m_arrowlength = src.m_arrowlength;
764     m_arrowwidth = src.m_arrowwidth;
765     m_centermark = src.m_centermark;
766     m_dimunits = src.m_dimunits;;
767     m_arrowtype = src.m_arrowtype;
768     m_angularunits = src.m_angularunits;
769     m_lengthformat = src.m_lengthformat;
770     m_angleformat = src.m_angleformat;
771     m_textalign = src.m_textalign;
772     m_resolution = src.m_resolution;
773     m_facename = src.m_facename;
774     m_world_view_text_scale = src.m_world_view_text_scale;
775     m_world_view_hatch_scale = src.m_world_view_hatch_scale;
776     m_bEnableAnnotationScaling = src.m_bEnableAnnotationScaling;
777     m_bEnableHatchScaling = src.m_bEnableHatchScaling;
778   }
779   return *this;
780 }
781 
Dump(ON_TextLog & text_log) const782 void ON_3dmAnnotationSettings::Dump( ON_TextLog& text_log ) const
783 {
784   // TODO
785 }
786 
Default()787 void ON_3dmAnnotationSettings::Default()
788 {
789   memset(this,0,sizeof(*this));
790 
791   m_dimscale = 1.0;       // model size / plotted size
792   m_textheight = 1.0;
793   m_dimexe = 1.0;
794   m_dimexo = 1.0;
795   m_arrowlength = 1.0;
796   m_arrowwidth = 1.0;
797   m_centermark = 1.0;
798 
799   m_dimunits = ON::no_unit_system;  // units used to measure the dimension
800   m_arrowtype = 0;     // 0: filled narrow triangular arrow
801   m_angularunits = 0;  // 0: degrees, 1: radians
802   m_lengthformat = 0;  // 0: decimal, ...
803   m_angleformat = 0;   // 0: decimal degrees, ...
804   m_textalign = 0;     // 0: above line, 1: in line, 2: horizontal
805   m_resolution = 0;    // depends on m_lengthformat
806                        // for decimal, digits past the decimal point
807 
808   m_facename.Destroy(); // [LF_FACESIZE] // windows font name
809 
810   m_world_view_text_scale = 1.0f;
811   m_world_view_hatch_scale = 1.0f;
812   m_bEnableAnnotationScaling = 1;
813   m_bEnableHatchScaling = 1;
814 }
815 
WorldViewTextScale() const816 double ON_3dmAnnotationSettings::WorldViewTextScale() const
817 {
818   return m_world_view_text_scale;
819 }
820 
WorldViewHatchScale() const821 double ON_3dmAnnotationSettings::WorldViewHatchScale() const
822 {
823   return m_world_view_hatch_scale;
824 }
825 
SetWorldViewTextScale(double world_view_text_scale)826 void ON_3dmAnnotationSettings::SetWorldViewTextScale(double world_view_text_scale )
827 {
828   if ( ON_IsValid(world_view_text_scale) && world_view_text_scale > 0.0 )
829     m_world_view_text_scale = (float)world_view_text_scale;
830 }
831 
SetWorldViewHatchScale(double world_view_hatch_scale)832 void ON_3dmAnnotationSettings::SetWorldViewHatchScale(double world_view_hatch_scale )
833 {
834   if ( ON_IsValid(world_view_hatch_scale) && world_view_hatch_scale > 0.0 )
835     m_world_view_hatch_scale = (float)world_view_hatch_scale;
836 }
837 
IsAnnotationScalingEnabled() const838 bool ON_3dmAnnotationSettings::IsAnnotationScalingEnabled() const
839 {
840   return m_bEnableAnnotationScaling?true:false;
841 }
842 
EnableAnnotationScaling(bool bEnable)843 void ON_3dmAnnotationSettings::EnableAnnotationScaling( bool bEnable )
844 {
845   m_bEnableAnnotationScaling = bEnable?1:0;
846 }
847 
848 
IsHatchScalingEnabled() const849 bool ON_3dmAnnotationSettings::IsHatchScalingEnabled() const
850 {
851   return m_bEnableHatchScaling?true:false;
852 }
853 
EnableHatchScaling(bool bEnable)854 void ON_3dmAnnotationSettings::EnableHatchScaling( bool bEnable )
855 {
856   m_bEnableHatchScaling = bEnable?1:0;
857 }
858 
859 
Read(ON_BinaryArchive & file)860 bool ON_3dmAnnotationSettings::Read( ON_BinaryArchive& file )
861 {
862   Default();
863 
864   int major_version = 0;
865   int minor_version = 0;
866   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
867   if ( major_version == 1 ) {
868     if ( minor_version >= 0 ) {
869       if (rc) rc = file.ReadDouble(&m_dimscale);
870       if (rc) rc = file.ReadDouble(&m_textheight);
871       if (rc) rc = file.ReadDouble(&m_dimexe);
872       if (rc) rc = file.ReadDouble(&m_dimexo);
873       if (rc) rc = file.ReadDouble(&m_arrowlength);
874       if (rc) rc = file.ReadDouble(&m_arrowwidth);
875       if (rc) rc = file.ReadDouble(&m_centermark);
876 
877       {
878         int i;
879         if (rc)
880         {
881           rc = file.ReadInt( &i );
882           if (rc)
883             m_dimunits = ON::UnitSystem(i);
884         }
885       }
886 
887       if (rc) rc = file.ReadInt( &m_arrowtype );
888       if (rc) rc = file.ReadInt( &m_angularunits );
889       if (rc) rc = file.ReadInt( &m_lengthformat );
890       if (rc) rc = file.ReadInt( &m_angleformat );
891       if (rc) rc = file.ReadInt( &m_textalign );
892       if (rc) rc = file.ReadInt( &m_resolution );
893 
894       if (rc) rc = file.ReadString( m_facename );
895 
896       // files that do not contain m_bEnableAnnotationScaling,
897       // set m_bEnableAnnotationScaling = false so the display
898       // image does not change.
899       m_bEnableAnnotationScaling = 0;
900 
901       // files that do not contain m_bEnableHatchScaling,
902       // set m_bEnableHatchScaling = false so the display
903       // image does not change.
904       m_bEnableHatchScaling = 0;
905 
906       if ( minor_version >= 1 )
907       {
908         // Added 25 August 2010 chunk version 1.1
909         double d = m_world_view_text_scale;
910         if (rc) rc = file.ReadDouble(&d);
911         if (rc && ON_IsValid(d) && d >= 0.0 ) m_world_view_text_scale = (float)d;
912         if (rc) rc = file.ReadChar(&m_bEnableAnnotationScaling);
913         if ( minor_version >= 2 )
914         {
915           d = m_world_view_hatch_scale;
916           if (rc) rc = file.ReadDouble(&d);
917           if (rc && ON_IsValid(d) && d >= 0.0) m_world_view_hatch_scale = (float)d;
918           if (rc) rc = file.ReadChar(&m_bEnableHatchScaling);
919         }
920       }
921     }
922   }
923   else {
924     rc = false;
925   }
926   return rc;
927 }
928 
Write(ON_BinaryArchive & file) const929 bool ON_3dmAnnotationSettings::Write( ON_BinaryArchive& file ) const
930 {
931   int i;
932   bool rc = file.Write3dmChunkVersion(1,2);
933   // March 22, 2010 - Global DimScale abandoned and moved into DimStyles, so now
934   // in older files, the dimscale values are multiplied into the DimStyle lengths and
935   // DimScale is written as 1.0
936   if (rc) rc = file.WriteDouble(1.0);
937 
938   if (rc) rc = file.WriteDouble(m_textheight);
939   if (rc) rc = file.WriteDouble(m_dimexe);
940   if (rc) rc = file.WriteDouble(m_dimexo);
941   if (rc) rc = file.WriteDouble(m_arrowlength);
942   if (rc) rc = file.WriteDouble(m_arrowwidth);
943   if (rc) rc = file.WriteDouble(m_centermark);
944 
945   i = m_dimunits;
946   if (rc) rc = file.WriteInt( i );
947   if (rc) rc = file.WriteInt( m_arrowtype );
948   if (rc) rc = file.WriteInt( m_angularunits );
949   if (rc) rc = file.WriteInt( m_lengthformat );
950   if (rc) rc = file.WriteInt( m_angleformat );
951   int textalign = (int)m_textalign;
952 
953   // 8-20-03 lw
954   // How the hell did this get changed?
955   if( file.Archive3dmVersion() <= 2)
956   {
957     switch( m_textalign)
958     {
959     case ON::dtHorizontal:
960       textalign = 2;
961       break;
962     case ON::dtInLine:
963       textalign = 1;
964       break;
965     default:
966       textalign = 0;
967       break;
968     }
969   }
970   if (rc) rc = file.WriteInt( textalign );
971   if (rc) rc = file.WriteInt( m_resolution );
972 
973   if (rc) rc = file.WriteString( m_facename );
974 
975   // Added 25 August 2010 chunk version 1.1
976   double d = m_world_view_text_scale;
977   if (rc) rc = file.WriteDouble(d);
978   if (rc) rc = file.WriteChar(m_bEnableAnnotationScaling);
979 
980   // Added 14 January 2011 chunk version 1.2
981   d = m_world_view_hatch_scale;
982   if (rc) rc = file.WriteDouble(d);
983   if (rc) rc = file.WriteChar(m_bEnableHatchScaling);
984 
985   return rc;
986 }
987 
988 //////////////////////////////////////////////////////////////////////////////////////////
989 //
990 // ON_3dmConstructionPlane
991 //
ON_3dmConstructionPlane()992 ON_3dmConstructionPlane::ON_3dmConstructionPlane()
993 {
994   Default();
995 }
996 
~ON_3dmConstructionPlane()997 ON_3dmConstructionPlane::~ON_3dmConstructionPlane()
998 {
999 }
1000 
1001 // default copy constructor and operator= work fine
1002 /*
1003 ON_3dmConstructionPlane::ON_3dmConstructionPlane(const ON_3dmConstructionPlane& src)
1004 {
1005   Default();
1006   *this = src;
1007 }
1008 ON_3dmConstructionPlane& ON_3dmConstructionPlane::operator=(const ON_3dmConstructionPlane& src)
1009 {
1010   if ( this != &src )
1011   {
1012     m_plane = src.m_plane;
1013     m_grid_spacing = src.m_grid_spacing;
1014     m_snap_spacing = src.m_snap_spacing;
1015     m_grid_line_count = src.m_grid_line_count;
1016     m_grid_thick_frequency = src.m_grid_thick_frequency;
1017     m_name = src.m_name;
1018     m_bDepthBuffer = src.m_bDepthBuffer;
1019   }
1020   return *this;
1021 }
1022 */
1023 
Dump(ON_TextLog & text_log) const1024 void ON_3dmConstructionPlane::Dump( ON_TextLog& text_log ) const
1025 {
1026   // TODO
1027 }
1028 
Default()1029 void ON_3dmConstructionPlane::Default()
1030 {
1031   m_name.Destroy();
1032   m_plane = ON_xy_plane;
1033 
1034   // construction grid appearance
1035 	m_grid_spacing = 1.0;   // distance between grid lines
1036 	m_snap_spacing = 1.0;   // distance between grid snap points
1037 	m_grid_line_count = 70;     // number of grid lines in each direction
1038   m_grid_thick_frequency = 5; // thick line frequency
1039   m_bDepthBuffer = true;
1040 }
1041 
Write(ON_BinaryArchive & file) const1042 bool ON_3dmConstructionPlane::Write( ON_BinaryArchive& file ) const
1043 {
1044   bool rc = file.Write3dmChunkVersion(1,1);
1045 
1046   if (rc) rc = file.WritePlane(m_plane);
1047   if (rc) rc = file.WriteDouble(m_grid_spacing);
1048   if (rc) rc = file.WriteDouble(m_snap_spacing);
1049   if (rc) rc = file.WriteInt(m_grid_line_count);
1050   if (rc) rc = file.WriteInt(m_grid_thick_frequency);
1051   if (rc) rc = file.WriteString(m_name);
1052 
1053   // added for version 1.1 chunks
1054   if (rc) rc = file.WriteBool(m_bDepthBuffer);
1055 
1056   return rc;
1057 }
1058 
Read(ON_BinaryArchive & file)1059 bool ON_3dmConstructionPlane::Read( ON_BinaryArchive& file )
1060 {
1061   Default();
1062   int major_version = 0;
1063   int minor_version = 0;
1064   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
1065   if (rc && major_version==1)
1066   {
1067     if (rc) rc = file.ReadPlane(m_plane);
1068     if (rc) rc = file.ReadDouble(&m_grid_spacing);
1069     if (rc) rc = file.ReadDouble(&m_snap_spacing);
1070     if (rc) rc = file.ReadInt(&m_grid_line_count);
1071     if (rc) rc = file.ReadInt(&m_grid_thick_frequency);
1072     if (rc) rc = file.ReadString(m_name);
1073 
1074     if ( minor_version >= 1 )
1075     {
1076       if (rc) rc = file.ReadBool(&m_bDepthBuffer);
1077     }
1078   }
1079   return rc;
1080 }
1081 
1082 //////////////////////////////////////////////////////////////////////////////////////////
1083 //
1084 // ON_3dmConstructionPlaneGridDefaults
1085 //
ON_3dmConstructionPlaneGridDefaults()1086 ON_3dmConstructionPlaneGridDefaults::ON_3dmConstructionPlaneGridDefaults()
1087 {
1088   Default();
1089 }
1090 
~ON_3dmConstructionPlaneGridDefaults()1091 ON_3dmConstructionPlaneGridDefaults::~ON_3dmConstructionPlaneGridDefaults()
1092 {
1093 }
1094 
ON_3dmConstructionPlaneGridDefaults(const ON_3dmConstructionPlaneGridDefaults & src)1095 ON_3dmConstructionPlaneGridDefaults::ON_3dmConstructionPlaneGridDefaults(const ON_3dmConstructionPlaneGridDefaults& src)
1096 {
1097   Default();
1098   *this = src;
1099 }
operator =(const ON_3dmConstructionPlaneGridDefaults & src)1100 ON_3dmConstructionPlaneGridDefaults& ON_3dmConstructionPlaneGridDefaults::operator=(const ON_3dmConstructionPlaneGridDefaults& src)
1101 {
1102   if ( this != &src ) {
1103     m_grid_spacing = src.m_grid_spacing;
1104     m_snap_spacing = src.m_snap_spacing;
1105     m_grid_line_count = src.m_grid_line_count;
1106     m_grid_thick_frequency = src.m_grid_thick_frequency;
1107     m_bShowGrid = src.m_bShowGrid;
1108     m_bShowGridAxes = src.m_bShowGridAxes;
1109     m_bShowWorldAxes = src.m_bShowWorldAxes;
1110   }
1111   return *this;
1112 }
1113 
Dump(ON_TextLog & text_log) const1114 void ON_3dmConstructionPlaneGridDefaults::Dump(ON_TextLog& text_log) const
1115 {
1116   // TODO
1117 }
1118 
Default()1119 void ON_3dmConstructionPlaneGridDefaults::Default()
1120 {
1121   // construction grid appearance
1122 	m_grid_spacing = 1.0;   // distance between grid lines
1123 	m_snap_spacing = 1.0;   // distance between grid snap points
1124 	m_grid_line_count = 70;     // number of grid lines in each direction
1125   m_grid_thick_frequency = 5; // thick line frequency
1126   m_bShowGrid = true;
1127   m_bShowGridAxes = true;
1128   m_bShowWorldAxes = true;
1129 }
1130 
Write(ON_BinaryArchive & file) const1131 bool ON_3dmConstructionPlaneGridDefaults::Write( ON_BinaryArchive& file ) const
1132 {
1133   bool rc = file.Write3dmChunkVersion(1,0);
1134   if (rc) rc = file.WriteDouble(m_grid_spacing);
1135   if (rc) rc = file.WriteDouble(m_snap_spacing);
1136   if (rc) rc = file.WriteInt(m_grid_line_count);
1137   if (rc) rc = file.WriteInt(m_grid_thick_frequency);
1138   if (rc) rc = file.WriteInt(m_bShowGrid);
1139   if (rc) rc = file.WriteInt(m_bShowGridAxes);
1140   if (rc) rc = file.WriteInt(m_bShowWorldAxes);
1141   return rc;
1142 }
1143 
Read(ON_BinaryArchive & file)1144 bool ON_3dmConstructionPlaneGridDefaults::Read( ON_BinaryArchive& file )
1145 {
1146   int major_version = 0;
1147   int minor_version = 0;
1148   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
1149   if (rc && major_version==1) {
1150     if (rc) rc = file.ReadDouble(&m_grid_spacing);
1151     if (rc) rc = file.ReadDouble(&m_snap_spacing);
1152     if (rc) rc = file.ReadInt(&m_grid_line_count);
1153     if (rc) rc = file.ReadInt(&m_grid_thick_frequency);
1154     if (rc) rc = file.ReadInt(&m_bShowGrid);
1155     if (rc) rc = file.ReadInt(&m_bShowGridAxes);
1156     if (rc) rc = file.ReadInt(&m_bShowWorldAxes);
1157   }
1158   return rc;
1159 }
1160 
1161 
1162 
1163 //////////////////////////////////////////////////////////////////////////////////////////
1164 //
1165 // ON_3dmViewPosition
1166 //
ON_3dmViewPosition()1167 ON_3dmViewPosition::ON_3dmViewPosition()
1168 {
1169   Default();
1170 }
1171 
~ON_3dmViewPosition()1172 ON_3dmViewPosition::~ON_3dmViewPosition()
1173 {
1174 }
1175 
ON_3dmViewPosition(const ON_3dmViewPosition & src)1176 ON_3dmViewPosition::ON_3dmViewPosition(const ON_3dmViewPosition& src)
1177 {
1178   Default();
1179   *this = src;
1180 }
1181 
operator =(const ON_3dmViewPosition & src)1182 ON_3dmViewPosition& ON_3dmViewPosition::operator=(const ON_3dmViewPosition& src)
1183 {
1184   if ( this != &src ) {
1185     m_wnd_left   = src.m_wnd_left;
1186     m_wnd_right  = src.m_wnd_right;
1187     m_wnd_top    = src.m_wnd_top;
1188     m_wnd_bottom = src.m_wnd_bottom;
1189     m_bMaximized = src.m_bMaximized;
1190     m_floating_viewport = src.m_floating_viewport;
1191 
1192     // reserved fields are not used
1193     // m_reserved_1 = src.m_reserved_1;
1194     // m_reserved_2 = src.m_reserved_2;
1195     // m_reserved_3 = src.m_reserved_3;
1196   }
1197   return *this;
1198 }
1199 
Default()1200 void ON_3dmViewPosition::Default()
1201 {
1202   m_wnd_left   = 0.0;
1203   m_wnd_right  = 1.0;
1204   m_wnd_top    = 0.0;
1205   m_wnd_bottom = 1.0;
1206   m_bMaximized = false;
1207 
1208   m_floating_viewport = 0;
1209   m_reserved_1 = 0;
1210   m_reserved_2 = 0;
1211   m_reserved_3 = 0;
1212 }
1213 
Write(ON_BinaryArchive & file) const1214 bool ON_3dmViewPosition::Write( ON_BinaryArchive& file ) const
1215 {
1216   int minor_version =  ( file.Archive3dmVersion() >= 5 ) ? 1 : 0;
1217 
1218   bool rc = file.Write3dmChunkVersion(1,minor_version);
1219   if (rc)
1220   {
1221     if (rc) rc = file.WriteInt( m_bMaximized );
1222     if (rc) rc = file.WriteDouble( m_wnd_left );
1223     if (rc) rc = file.WriteDouble( m_wnd_right );
1224     if (rc) rc = file.WriteDouble( m_wnd_top );
1225     if (rc) rc = file.WriteDouble( m_wnd_bottom );
1226 
1227     if ( minor_version >= 1 )
1228     {
1229       // 13 March 2009 S. Baer
1230       // version 1.1 added support for m_floating_viewport
1231       // in V5 files.  This info is not in V4 files because
1232       // they might use this to write userdata.
1233       if (rc) rc = file.WriteChar( m_floating_viewport );
1234     }
1235   }
1236   return rc;
1237 }
1238 
Read(ON_BinaryArchive & file)1239 bool ON_3dmViewPosition::Read( ON_BinaryArchive& file )
1240 {
1241   int major_version = 0;
1242   int minor_version = 0;
1243   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
1244   double x;
1245   Default();
1246   if (rc && major_version==1)
1247   {
1248     if (rc) rc = file.ReadInt( &m_bMaximized );
1249     if (rc) rc = file.ReadDouble( &m_wnd_left );
1250     if (rc) rc = file.ReadDouble( &m_wnd_right );
1251     if (rc) rc = file.ReadDouble( &m_wnd_top );
1252     if (rc) rc = file.ReadDouble( &m_wnd_bottom );
1253 
1254     // 13 March 2009 S. Baer
1255     // version 1.1 added support for m_floating_viewport
1256     if( rc && minor_version >= 1 )
1257     {
1258       rc = file.ReadChar( &m_floating_viewport );
1259     }
1260   }
1261 
1262   // if people put bogus values in a file, tune them up to something that will work
1263   if ( m_wnd_left > m_wnd_right ) {
1264     x = m_wnd_left; m_wnd_left = m_wnd_right; m_wnd_right = x;
1265   }
1266   if ( m_wnd_left  < 0.0 )
1267     m_wnd_left  = 0.0;
1268   if ( m_wnd_right >= 1.0 )
1269     m_wnd_right = 1.0;
1270   if ( m_wnd_left >= m_wnd_right ) {
1271     m_wnd_left = 0.0;
1272     m_wnd_right = 1.0;
1273   }
1274 
1275   if ( m_wnd_top > m_wnd_bottom ) {
1276     x = m_wnd_top; m_wnd_top = m_wnd_bottom; m_wnd_bottom = x;
1277   }
1278   if ( m_wnd_top  < 0.0 )
1279     m_wnd_top  = 0.0;
1280   if ( m_wnd_bottom >= 1.0 )
1281     m_wnd_bottom = 1.0;
1282   if ( m_wnd_top >= m_wnd_bottom ) {
1283     m_wnd_top = 0.0;
1284     m_wnd_bottom = 1.0;
1285   }
1286 
1287   return rc;
1288 }
1289 
1290 //////////////////////////////////////////////////////////////////////////////////////////
1291 //
1292 // ON_3dmViewTraceImage
1293 //
ON_3dmViewTraceImage()1294 ON_3dmViewTraceImage::ON_3dmViewTraceImage()
1295 {
1296   Default();
1297 }
1298 
~ON_3dmViewTraceImage()1299 ON_3dmViewTraceImage::~ON_3dmViewTraceImage()
1300 {
1301 }
1302 
Default()1303 void ON_3dmViewTraceImage::Default()
1304 {
1305   m_plane = ON_xy_plane;
1306   m_width = 0.0;
1307   m_height = 0.0;
1308   m_bitmap_filename.Destroy();
1309   m_bGrayScale = true;
1310   m_bHidden = false;
1311   m_bFiltered = false;
1312 }
1313 
Write(ON_BinaryArchive & file) const1314 bool ON_3dmViewTraceImage::Write( ON_BinaryArchive& file ) const
1315 {
1316   // opennurbs version  < 200307300 - version 1.0 or 1.1 chunk
1317   // opennurbs version >= 200307300 - version 1.2 chunk
1318   bool rc = file.Write3dmChunkVersion(1,3);
1319   if (rc)
1320   {
1321     if (rc) rc = file.WriteString( m_bitmap_filename );
1322     if (rc) rc = file.WriteDouble( m_width );
1323     if (rc) rc = file.WriteDouble( m_height );
1324     if (rc) rc = file.WritePlane( m_plane );
1325 
1326     // version 1.1
1327     if (rc) rc = file.WriteBool( m_bGrayScale );
1328 
1329     // version 1.2
1330     if (rc) rc = file.WriteBool( m_bHidden );
1331 
1332     // version 1.3
1333     if (rc) rc = file.WriteBool( m_bFiltered );
1334   }
1335   return rc;
1336 }
1337 
1338 
Read(ON_BinaryArchive & file)1339 bool ON_3dmViewTraceImage::Read( ON_BinaryArchive& file )
1340 {
1341   // opennurbs version  < 200307300 - version 1.0 or 1.1 chunk
1342   // opennurbs version >= 200307300 - version 1.2 chunk
1343   int major_version = 0;
1344   int minor_version = 0;
1345   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
1346   if (rc && major_version==1)
1347   {
1348     if (rc) rc = file.ReadString( m_bitmap_filename );
1349     if (rc) rc = file.ReadDouble( &m_width );
1350     if (rc) rc = file.ReadDouble( &m_height );
1351     if (rc) rc = file.ReadPlane( m_plane );
1352     if ( minor_version >= 1 )
1353     {
1354       if (rc) rc = file.ReadBool(&m_bGrayScale);
1355 
1356       if ( minor_version >= 2 )
1357       {
1358         if (rc) rc = file.ReadBool(&m_bHidden);
1359 
1360         if ( minor_version >= 3 )
1361         {
1362           if (rc) rc = file.ReadBool( &m_bFiltered );
1363         }
1364       }
1365     }
1366   }
1367   else
1368     rc = false;
1369   return rc;
1370 }
1371 
1372 
operator ==(const ON_3dmViewTraceImage & other) const1373 bool ON_3dmViewTraceImage::operator==( const ON_3dmViewTraceImage& other ) const
1374 {
1375   if ( m_plane != other.m_plane )
1376     return false;
1377   if ( m_width != other.m_width )
1378     return false;
1379   if ( m_height != other.m_height )
1380     return false;
1381   if( m_bitmap_filename != other.m_bitmap_filename )
1382     return false;
1383   if ( m_bHidden != other.m_bHidden )
1384     return false;
1385   if ( m_bGrayScale != other.m_bGrayScale )
1386     return false;
1387   if ( m_bFiltered != other.m_bFiltered )
1388     return false;
1389 
1390   return true;
1391 }
1392 
operator !=(const ON_3dmViewTraceImage & other) const1393 bool ON_3dmViewTraceImage::operator!=( const ON_3dmViewTraceImage& other ) const
1394 {
1395   return operator==(other) ? false : true;
1396 }
1397 
1398 
ON_3dmWallpaperImage()1399 ON_3dmWallpaperImage::ON_3dmWallpaperImage()
1400 {
1401   Default();
1402 }
1403 
~ON_3dmWallpaperImage()1404 ON_3dmWallpaperImage::~ON_3dmWallpaperImage()
1405 {
1406 }
1407 
operator ==(const ON_3dmWallpaperImage & other) const1408 bool ON_3dmWallpaperImage::operator==( const ON_3dmWallpaperImage& other ) const
1409 {
1410   if ( m_bitmap_filename != other.m_bitmap_filename )
1411     return false;
1412   if ( m_bHidden != other.m_bHidden )
1413     return false;
1414   return ( m_bGrayScale == other.m_bGrayScale );
1415 }
1416 
operator !=(const ON_3dmWallpaperImage & other) const1417 bool ON_3dmWallpaperImage::operator!=( const ON_3dmWallpaperImage& other ) const
1418 {
1419   return operator==(other) ? false : true;
1420 }
1421 
Default()1422 void ON_3dmWallpaperImage::Default()
1423 {
1424   m_bitmap_filename.Destroy();
1425   m_bGrayScale = true;
1426   m_bHidden = false;
1427 }
1428 
Write(ON_BinaryArchive & file) const1429 bool ON_3dmWallpaperImage::Write( ON_BinaryArchive& file ) const
1430 {
1431   // version  < 200307300 - version 1.0 chunk
1432   // version >= 200307300 - version 1.1 chunk
1433   bool rc = file.Write3dmChunkVersion(1,1);
1434   if (rc)
1435   {
1436     if (rc) rc = file.WriteString( m_bitmap_filename );
1437     if (rc) rc = file.WriteBool( m_bGrayScale );
1438 
1439     if (rc) rc = file.WriteBool( m_bHidden ); // added in 1.1 chunk
1440   }
1441   return rc;
1442 }
1443 
Read(ON_BinaryArchive & file)1444 bool ON_3dmWallpaperImage::Read( ON_BinaryArchive& file )
1445 {
1446   // version  < 200307300 - version 1.0 chunk
1447   // version >= 200307300 - version 1.1 chunk
1448   Default();
1449   int major_version = 0;
1450   int minor_version = 0;
1451   bool rc = file.Read3dmChunkVersion(&major_version,&minor_version);
1452   if (rc && major_version==1)
1453   {
1454     if (rc) rc = file.ReadString( m_bitmap_filename );
1455     if (rc) rc = file.ReadBool( &m_bGrayScale );
1456 
1457     if ( minor_version >= 1 )
1458     {
1459       if (rc) rc = file.ReadBool( &m_bHidden );
1460     }
1461   }
1462   else
1463     rc = false;
1464   return rc;
1465 }
1466 
1467 
1468 //////////////////////////////////////////////////////////////////////////////////////////
1469 //
1470 // ON_3dmView
1471 //
1472 
ON_3dmPageSettings()1473 ON_3dmPageSettings::ON_3dmPageSettings()
1474 {
1475   Default();
1476 }
1477 
~ON_3dmPageSettings()1478 ON_3dmPageSettings::~ON_3dmPageSettings()
1479 {
1480 }
1481 
Default()1482 void ON_3dmPageSettings::Default()
1483 {
1484   m_page_number = 0;
1485 
1486   m_width_mm  = 0.0;
1487   m_height_mm = 0.0;
1488 
1489   m_left_margin_mm   = 0.0;
1490   m_right_margin_mm  = 0.0;
1491   m_top_margin_mm    = 0.0;
1492   m_bottom_margin_mm = 0.0;
1493 
1494   m_printer_name.Destroy();
1495 }
1496 
1497 
IsValid(ON_TextLog * text_log) const1498 bool ON_3dmPageSettings::IsValid( ON_TextLog* text_log ) const
1499 {
1500   bool rc = true;
1501 
1502   if ( m_width_mm != 0.0 || m_height_mm != 0.0 )
1503   {
1504     if ( !ON_IsValid(m_width_mm) || m_width_mm <= 0.0 )
1505     {
1506       if ( text_log )
1507       {
1508         text_log->Print("ON_3dmPageSettings has m_width_mm = %g (should be > 0.0).\n",m_width_mm);
1509       }
1510       rc = false;
1511     }
1512     if ( !ON_IsValid(m_height_mm) || m_height_mm <= 0.0 )
1513     {
1514       if ( text_log )
1515       {
1516         text_log->Print("ON_3dmPageSettings has m_height_mm = %g (should be > 0.0).\n",m_height_mm);
1517       }
1518       rc = false;
1519     }
1520     if ( !ON_IsValid(m_top_margin_mm) || m_top_margin_mm < 0.0 )
1521     {
1522       if ( text_log )
1523       {
1524         text_log->Print("ON_3dmPageSettings has m_top_margin_mm = %g (should be >= 0.0).\n",m_top_margin_mm);
1525       }
1526       rc = false;
1527     }
1528     if ( !ON_IsValid(m_bottom_margin_mm) || m_bottom_margin_mm < 0.0 )
1529     {
1530       if ( text_log )
1531       {
1532         text_log->Print("ON_3dmPageSettings has m_bottom_margin_mm = %g (should be >= 0.0).\n",m_bottom_margin_mm);
1533       }
1534       rc = false;
1535     }
1536     if ( !ON_IsValid(m_left_margin_mm) || m_left_margin_mm < 0.0 )
1537     {
1538       if ( text_log )
1539       {
1540         text_log->Print("ON_3dmPageSettings has m_left_margin_mm = %g (should be >= 0.0).\n",m_left_margin_mm);
1541       }
1542       rc = false;
1543     }
1544     if ( !ON_IsValid(m_right_margin_mm) || m_right_margin_mm < 0.0 )
1545     {
1546       if ( text_log )
1547       {
1548         text_log->Print("ON_3dmPageSettings has m_right_margin_mm = %g (should be >= 0.0).\n",m_right_margin_mm);
1549       }
1550       rc = false;
1551     }
1552     if ( m_left_margin_mm + m_right_margin_mm >= m_width_mm )
1553     {
1554       if ( text_log )
1555       {
1556         text_log->Print("ON_3dmPageSettings has m_left_margin_mm+m_right_margin_mm = %g > %g = m_width_mm.\n",m_left_margin_mm + m_right_margin_mm, m_width_mm);
1557       }
1558       rc = false;
1559     }
1560     if ( m_top_margin_mm + m_bottom_margin_mm >= m_height_mm )
1561     {
1562       if ( text_log )
1563       {
1564         text_log->Print("ON_3dmPageSettings has m_top_margin_mm+m_bottom_margin_mm = %g > %g = m_height_mm.\n",m_top_margin_mm + m_bottom_margin_mm, m_height_mm);
1565       }
1566       rc = false;
1567     }
1568   }
1569   else
1570   {
1571     if ( m_top_margin_mm != 0.0 )
1572     {
1573       if ( text_log )
1574       {
1575         text_log->Print("ON_3dmPageSettings has m_top_margin_mm = %g (should be 0.0).\n",m_top_margin_mm);
1576       }
1577       rc = false;
1578     }
1579     if ( m_bottom_margin_mm != 0.0 )
1580     {
1581       if ( text_log )
1582       {
1583         text_log->Print("ON_3dmPageSettings has m_bottom_margin_mm = %g (should be 0.0).\n",m_bottom_margin_mm);
1584       }
1585       rc = false;
1586     }
1587     if ( m_left_margin_mm != 0.0 )
1588     {
1589       if ( text_log )
1590       {
1591         text_log->Print("ON_3dmPageSettings has m_left_margin_mm = %g (should be 0.0).\n",m_left_margin_mm);
1592       }
1593       rc = false;
1594     }
1595     if ( m_right_margin_mm != 0.0 )
1596     {
1597       if ( text_log )
1598       {
1599         text_log->Print("ON_3dmPageSettings has m_right_margin_mm = %g (should be 0.0).\n",m_right_margin_mm);
1600       }
1601       rc = false;
1602     }
1603   }
1604 
1605   return rc;
1606 }
1607 
Write(ON_BinaryArchive & archive) const1608 bool ON_3dmPageSettings::Write(ON_BinaryArchive& archive) const
1609 {
1610   bool rc = archive.BeginWrite3dmChunk( TCODE_ANONYMOUS_CHUNK, 1, 0 );
1611   if ( !rc )
1612     return false;
1613 
1614   for(;;)
1615   {
1616     rc = archive.WriteInt( m_page_number );
1617     if (!rc) break;
1618 
1619     rc = archive.WriteDouble(m_width_mm);
1620     if ( !rc) break;
1621 
1622     rc = archive.WriteDouble(m_height_mm);
1623     if ( !rc) break;
1624 
1625     rc = archive.WriteDouble(m_left_margin_mm);
1626     if ( !rc) break;
1627 
1628     rc = archive.WriteDouble(m_right_margin_mm);
1629     if ( !rc) break;
1630 
1631     rc = archive.WriteDouble(m_top_margin_mm);
1632     if ( !rc) break;
1633 
1634     rc = archive.WriteDouble(m_bottom_margin_mm);
1635     if ( !rc) break;
1636 
1637     rc = archive.WriteString(m_printer_name);
1638     if (!rc) break;
1639 
1640     break;
1641   }
1642 
1643   if ( !archive.EndWrite3dmChunk() )
1644     rc = false;
1645 
1646   return rc;
1647 }
1648 
Read(ON_BinaryArchive & archive)1649 bool ON_3dmPageSettings::Read(ON_BinaryArchive& archive)
1650 {
1651   int major_version = 0;
1652   int minor_version = 0;
1653   bool rc = archive.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version );
1654   if ( !rc )
1655     return false;
1656 
1657   for(;;)
1658   {
1659     rc = (1 == major_version);
1660     if (!rc) break;
1661 
1662     rc = archive.ReadInt(&m_page_number );
1663     if (!rc) break;
1664 
1665     rc = archive.ReadDouble(&m_width_mm);
1666     if ( !rc) break;
1667 
1668     rc = archive.ReadDouble(&m_height_mm);
1669     if ( !rc) break;
1670 
1671     rc = archive.ReadDouble(&m_left_margin_mm);
1672     if ( !rc) break;
1673 
1674     rc = archive.ReadDouble(&m_right_margin_mm);
1675     if ( !rc) break;
1676 
1677     rc = archive.ReadDouble(&m_top_margin_mm);
1678     if ( !rc) break;
1679 
1680     rc = archive.ReadDouble(&m_bottom_margin_mm);
1681     if ( !rc) break;
1682 
1683     rc = archive.ReadString(m_printer_name);
1684     if (!rc) break;
1685 
1686     break;
1687   }
1688 
1689   if ( !archive.EndRead3dmChunk() )
1690     rc = false;
1691 
1692   return rc;
1693 }
1694 
1695 //////////////////////////////////////////////////////////////////////////////////////////
1696 //
1697 // ON_3dmView
1698 //
ON_3dmView()1699 ON_3dmView::ON_3dmView()
1700 {
1701   Default();
1702 }
1703 
~ON_3dmView()1704 ON_3dmView::~ON_3dmView()
1705 {
1706 }
1707 
Dump(ON_TextLog & dump) const1708 void ON_3dmView::Dump( ON_TextLog& dump ) const
1709 {
1710   const wchar_t* wsViewName = m_name;
1711   if ( !wsViewName )
1712     wsViewName = L"";
1713   ON::view_projection proj = m_vp.Projection();
1714 
1715 
1716   ON_3dPoint camLoc;
1717   ON_3dVector camX, camY, camZ;
1718   ON_BOOL32 bValidCamera = m_vp.GetCameraFrame( camLoc, camX, camY, camZ );
1719   double frus_left,frus_right,frus_bottom,frus_top,frus_near,frus_far;
1720   ON_BOOL32 bValidFrustum = m_vp.GetFrustum(&frus_left,&frus_right,&frus_bottom,&frus_top,&frus_near,&frus_far);
1721   int port_left, port_right, port_bottom, port_top, port_near, port_far;
1722   ON_BOOL32 bValidPort = m_vp.GetScreenPort(&port_left,&port_right,&port_bottom,&port_top,&port_near,&port_far);
1723 
1724   const char* sProjectionName;
1725   switch(proj)
1726   {
1727   case ON::parallel_view: sProjectionName = "parallel"; break;
1728   case ON::perspective_view: sProjectionName = "perspective"; break;
1729   case ON::unknown_view:
1730   default:
1731     sProjectionName = "unknown";
1732     break;
1733   }
1734   dump.Print("Viewport: name = \"%ls\" projection = %s\n",wsViewName,sProjectionName);
1735 
1736   dump.PushIndent();
1737 
1738   if ( bValidCamera )
1739   {
1740     dump.Print("viewport camera frame\n"
1741            "  location = %g, %g, %g\n"
1742            "  X = %g, %g, %g\n"
1743            "  Y = %g, %g, %g\n"
1744            "  Z = %g, %g, %g\n",
1745            camLoc.x,camLoc.y,camLoc.z,
1746            camX.x,camX.y,camX.z,
1747            camY.x,camY.y,camY.z,
1748            camZ.x,camZ.y,camZ.z
1749            );
1750     ON_3dPoint target_point = TargetPoint();
1751     double target_distance = target_point.DistanceTo( camLoc );
1752     dump.Print("camera target\n"
1753                "  distance = %g\n"
1754                "  point = %g,%g,%g\n",
1755                target_distance,
1756                target_point.x,target_point.y,target_point.z
1757                );
1758   }
1759 
1760 
1761   if ( bValidFrustum ) {
1762     dump.Print("view frustum\n"
1763            "  left   = %g, right = %g\n"
1764            "  bottom = %g, top   = %g\n"
1765            "  near   = %g, far   = %g\n",
1766            frus_left,frus_right,
1767            frus_bottom,frus_top,
1768            frus_near,frus_far
1769            );
1770   }
1771 
1772   if ( bValidPort ) {
1773     // location of viewport window on screen
1774     dump.Print("viewport window screen location\n"
1775            "  left   = %4d, right = %4d\n"
1776            "  bottom = %4d, top   = %4d\n"
1777            "  near   = %4d, far   = %4d\n",
1778            port_left,port_right,
1779            port_bottom,port_top,
1780            port_near,port_far
1781            );
1782   }
1783 
1784 
1785   // relative position of viewport window in application main frame
1786   double rel_left,rel_right,rel_bottom,rel_top;
1787   rel_left = m_position.m_wnd_left;
1788   rel_right = m_position.m_wnd_right;
1789   rel_bottom = m_position.m_wnd_bottom;
1790   rel_top = m_position.m_wnd_top;
1791   dump.Print("relative viewport window position in application frame window\n"
1792              "  left   = %6.2f%%, right = %6.2f%%\n"
1793              "  bottom = %6.2f%%, top   = %6.2f%%\n",
1794              100.0*rel_left, 100.0*rel_right,
1795              100.0*rel_bottom, 100.0*rel_top
1796              );
1797 
1798   dump.PopIndent();
1799 
1800 }
1801 
Default()1802 void ON_3dmView::Default()
1803 {
1804   m_name.Destroy();
1805 
1806   m_vp.Initialize();
1807   // ON_3dmView::m_target is obsolete - keep it in sync with m_vp.m_target_point
1808   OBSOLETE_3DM_VIEW_TARGET = m_vp.TargetPoint();
1809 
1810   m_cplane.Default();
1811   m_display_mode_id = ON_nil_uuid;
1812   m_display_mode = ON::wireframe_display;
1813   m_view_type = ON::model_view_type;
1814   m_position.Default();
1815   if ( m_vp.Projection() == ON::parallel_view ) {
1816     m_cplane.m_plane.CreateFromFrame( m_cplane.m_plane.origin, m_vp.CameraX(), m_vp.CameraY() );
1817   }
1818   m_bShowConstructionGrid = true;
1819   m_bShowConstructionAxes = true;
1820   m_bShowWorldAxes = true;
1821 
1822   m_trace_image.Default();
1823   m_wallpaper_image.Default();
1824 
1825   m_page_settings.Default();
1826 
1827   m_bLockedProjection = false;
1828 }
1829 
TargetPoint() const1830 ON_3dPoint ON_3dmView::TargetPoint() const
1831 {
1832   ON_3dPoint target_point = m_vp.TargetPoint();
1833   if ( OBSOLETE_3DM_VIEW_TARGET != target_point )
1834   {
1835     ON_ERROR("Obsolete ON_3dmView::m_target is not set correctly");
1836     const_cast<ON_3dmView*>(this)->OBSOLETE_3DM_VIEW_TARGET = target_point; // fix error condition
1837   }
1838   return target_point;
1839 }
1840 
SetTargetPoint(ON_3dPoint target_point)1841 bool ON_3dmView::SetTargetPoint(ON_3dPoint target_point)
1842 {
1843   bool rc = m_vp.SetTargetPoint(target_point);
1844   OBSOLETE_3DM_VIEW_TARGET = m_vp.TargetPoint(); // keep obsolete m_target in sync with m_vp.m_target_point
1845   return rc;
1846 }
1847 
IsValid(ON_TextLog * text_log) const1848 bool ON_3dmView::IsValid(ON_TextLog* text_log) const
1849 {
1850   bool rc = m_vp.IsValid(text_log)?true:false;
1851   while(rc)
1852   {
1853     switch(m_view_type)
1854     {
1855     case ON::model_view_type:
1856       if ( m_page_settings.m_width_mm != 0.0 || m_page_settings.m_height_mm != 0.0 )
1857       {
1858         if ( text_log )
1859         {
1860           text_log->Print("ON_3dmView has m_view_type = ON::model_view_type but m_page_settings width,height = (%g,%g) (both should be zero).\n",
1861                           m_page_settings.m_width_mm,
1862                           m_page_settings.m_height_mm);
1863         }
1864         rc = false;
1865       }
1866       //if (    m_nested_view_position.m_min.x != 0.0 || m_nested_view_position.m_max.x != 0.0
1867       //     || m_nested_view_position.m_min.y != 0.0 || m_nested_view_position.m_max.y != 0.0
1868       //     || m_nested_view_position.m_min.z != 0.0 || m_nested_view_position.m_max.z != 0.0 )
1869       //{
1870       //  if ( text_log )
1871       //  {
1872       //    text_log->Print("ON_3dmView has m_view_type = ON::model_view_type and m_nested_view_position is not identically zero.\n");
1873       //  }
1874       //  rc = false;
1875       //}
1876       //if ( !ON_UuidIsNil(m_parent_viewport_id) )
1877       //{
1878       //  if ( text_log )
1879       //  {
1880       //    text_log->Print("ON_3dmView has m_view_type = ON::model_view_type and m_parent_viewport_id is not nil\n");
1881       //  }
1882       //  rc = false;
1883       //}
1884       break;
1885     case ON::page_view_type:
1886       //if (    m_nested_view_position.m_min.x != 0.0 || m_nested_view_position.m_max.x != 0.0
1887       //     || m_nested_view_position.m_min.y != 0.0 || m_nested_view_position.m_max.y != 0.0
1888       //     || m_nested_view_position.m_min.z != 0.0 || m_nested_view_position.m_max.z != 0.0 )
1889       //{
1890       //  if ( text_log )
1891       //  {
1892       //    text_log->Print("ON_3dmView has m_view_type = ON::page_view_type and m_nested_view_position is not identically zero.\n");
1893       //  }
1894       //  rc = false;
1895       //}
1896       //if ( !ON_UuidIsNil(m_parent_viewport_id) )
1897       //{
1898       //  if ( text_log )
1899       //  {
1900       //    text_log->Print("ON_3dmView has m_view_type = ON::page_view_type and m_parent_viewport_id is not nil\n");
1901       //  }
1902       //  rc = false;
1903       //}
1904       if ( m_page_settings.m_width_mm <= 0.0 || m_page_settings.m_height_mm <= 0.0 )
1905       {
1906         if ( text_log )
1907         {
1908           text_log->Print("ON_3dmView has m_view_type = ON::page_view_type but page width,height = (%g,%g)\n",
1909                           m_page_settings.m_width_mm,
1910                           m_page_settings.m_height_mm);
1911         }
1912         rc = false;
1913       }
1914       break;
1915 
1916     case ON::nested_view_type:
1917       if ( m_page_settings.m_width_mm != 0.0 || m_page_settings.m_height_mm != 0.0 )
1918       {
1919         if ( text_log )
1920         {
1921           text_log->Print("ON_3dmView has m_view_type = ON::nested_view_type but m_page_settings width,height = (%g,%g) (both should be zero).\n",
1922                           m_page_settings.m_width_mm,
1923                           m_page_settings.m_height_mm);
1924         }
1925         rc = false;
1926       }
1927       //if ( ON_UuidIsNil(m_parent_viewport_id) )
1928       //{
1929       //  if ( text_log )
1930       //  {
1931       //    text_log->Print("ON_3dmView has m_view_type = ON::nested_view_type and m_parent_viewport_id is nil.\n");
1932       //  }
1933       //  rc = false;
1934       //}
1935 
1936       //if ( !m_nested_view_position.IsValid()
1937       //     || m_nested_view_position.m_min.x >= m_nested_view_position.m_max.x
1938       //     || m_nested_view_position.m_min.y >= m_nested_view_position.m_max.y
1939       //     || m_nested_view_position.m_min.z != m_nested_view_position.m_max.z )
1940       //{
1941       //  if ( text_log )
1942       //  {
1943       //    text_log->Print("ON_3dmView has m_view_type = ON::nested_view_type and m_nested_view_position is bogus.\n");
1944       //  }
1945       //  rc = false;
1946       //}
1947       break;
1948 
1949     default:
1950       if ( text_log )
1951       {
1952         text_log->Print("ON_3dmView m_view_type = %d (illegal enum value)\n",m_view_type);
1953       }
1954       rc = false;
1955       break;
1956     }
1957     if (rc)
1958       break;
1959 
1960 
1961 
1962 
1963     break;
1964   }
1965   return rc;
1966 }
1967 
Write(ON_BinaryArchive & file) const1968 bool ON_3dmView::Write( ON_BinaryArchive& file ) const
1969 {
1970   // Everything in a view is in a subchunk so new records can
1971   // be added to a view and old I/O code will still
1972   // work.
1973   bool rc = true;
1974 
1975   // 27 June 2008 Dale Lear
1976   //   I added support for saving userdata attached to
1977   //   the m_vp ON_Viewport.  Ideally, I would just call
1978   //   file.WriteObject(m_vp), but userdata support is being
1979   //   added years after millions of files have been written
1980   //   by calling m_vp.Write().
1981   if(rc) {
1982     rc = file.BeginWrite3dmChunk( TCODE_VIEW_VIEWPORT, 0 );
1983     if(rc) {
1984       rc = m_vp.Write(file)?true:false;
1985       if ( !file.EndWrite3dmChunk() )
1986         rc = false;
1987     }
1988   }
1989   if(rc && 0 != m_vp.FirstUserData() && file.Archive3dmVersion() >= 4)
1990   {
1991     rc = file.BeginWrite3dmChunk( TCODE_VIEW_VIEWPORT_USERDATA, 0 );
1992     if(rc)
1993     {
1994       rc = file.WriteObjectUserData(m_vp);
1995       // write a "fake" TCODE_OPENNURBS_CLASS_END end of class
1996       // mark so I can use
1997       // ON_BinaryArchive::ReadObjectUserData()
1998       // to read this user data.
1999       if ( file.BeginWrite3dmChunk( TCODE_OPENNURBS_CLASS_END, 0 ) )
2000       {
2001         if ( !file.EndWrite3dmChunk() )
2002           rc = false;
2003       }
2004       else
2005       {
2006         rc = false;
2007       }
2008       if ( !file.EndWrite3dmChunk() ) // end of TCODE_VIEW_VIEWPORT_USERDATA
2009         rc = false;
2010     }
2011   }
2012   if(rc) {
2013     rc = file.BeginWrite3dmChunk( TCODE_VIEW_CPLANE, 0 );
2014     if(rc) {
2015       rc = m_cplane.Write(file);
2016       if ( !file.EndWrite3dmChunk() )
2017         rc = false;
2018     }
2019   }
2020   if(rc) {
2021     rc = file.BeginWrite3dmChunk( TCODE_VIEW_TARGET, 0 );
2022     if(rc) {
2023       ON_3dPoint target_point = TargetPoint();
2024       if(rc) rc = file.WritePoint(target_point);
2025       if ( !file.EndWrite3dmChunk() )
2026         rc = false;
2027     }
2028   }
2029   if(rc) {
2030     rc = file.BeginWrite3dmChunk( TCODE_VIEW_DISPLAYMODE, m_display_mode );
2031     if(rc) {
2032       if ( !file.EndWrite3dmChunk() )
2033         rc = false;
2034     }
2035   }
2036   if(rc) {
2037     rc = file.BeginWrite3dmChunk( TCODE_VIEW_POSITION, 0 );
2038     if(rc) {
2039       if(rc) rc = m_position.Write(file);
2040       if ( !file.EndWrite3dmChunk() )
2041         rc = false;
2042     }
2043   }
2044   if(rc) {
2045     rc = file.BeginWrite3dmChunk( TCODE_VIEW_SHOWCONGRID, m_bShowConstructionGrid );
2046     if(rc) {
2047       if ( !file.EndWrite3dmChunk() )
2048         rc = false;
2049     }
2050   }
2051   if(rc) {
2052     rc = file.BeginWrite3dmChunk( TCODE_VIEW_SHOWCONAXES, m_bShowConstructionAxes );
2053     if(rc) {
2054       if ( !file.EndWrite3dmChunk() )
2055         rc = false;
2056     }
2057   }
2058   if(rc) {
2059     rc = file.BeginWrite3dmChunk( TCODE_VIEW_SHOWWORLDAXES, m_bShowWorldAxes );
2060     if(rc) {
2061       if ( !file.EndWrite3dmChunk() )
2062         rc = false;
2063     }
2064   }
2065   if(rc) {
2066     rc = file.BeginWrite3dmChunk( TCODE_VIEW_NAME, 0 );
2067     if(rc) {
2068       if(rc) rc = file.WriteString(m_name);
2069       if ( !file.EndWrite3dmChunk() )
2070         rc = false;
2071     }
2072   }
2073   if(rc) {
2074     rc = file.BeginWrite3dmChunk( TCODE_VIEW_TRACEIMAGE, 0 );
2075     if(rc)
2076     {
2077       if(rc)
2078         rc = m_trace_image.Write(file);
2079       if ( !file.EndWrite3dmChunk() )
2080         rc = false;
2081     }
2082   }
2083   if(rc)
2084   {
2085     rc = file.BeginWrite3dmChunk( TCODE_VIEW_WALLPAPER, 0 );
2086     if(rc)
2087     {
2088       if(rc) rc = file.WriteString(m_wallpaper_image.m_bitmap_filename);
2089       if ( !file.EndWrite3dmChunk() )
2090         rc = false;
2091     }
2092   }
2093   if(rc && file.Archive3dmVersion() >= 3 )
2094   {
2095     // Added 5 June 2003 to support additional wallpaper attributes.
2096     // Older versions of Rhino/opennurbs
2097     // will just skip this chunk and get filename from the
2098     // TCODE_VIEW_WALLPAPER chunk written above.
2099     rc = file.BeginWrite3dmChunk( TCODE_VIEW_WALLPAPER_V3, 0 );
2100     if(rc)
2101     {
2102       if(rc)
2103         rc = m_wallpaper_image.Write(file);
2104       if ( !file.EndWrite3dmChunk() )
2105         rc = false;
2106     }
2107   }
2108 
2109   if (rc && file.Archive3dmVersion() >= 4)
2110   {
2111     // 23 March 2005 Dale Lear:
2112     //   The "chunks" above trace their history back to Rhino 1.0;
2113     //   The TCODE_VIEW_ATTRIBUTES chunk uses a chunk version so that
2114     //   new view information can be added without inventing a new
2115     //   TCODE for each new piece of information.
2116 
2117     rc = file.BeginWrite3dmChunk( TCODE_VIEW_ATTRIBUTES, 0 );
2118     if (rc)
2119     {
2120       rc = file.Write3dmChunkVersion( 1, 4 ); // (there are no 1.0 fields)
2121 
2122       while(rc)
2123       {
2124         // 1.1 fields (there are no 1.0 fields)
2125         rc = file.WriteInt( m_view_type );
2126         if (!rc) break;
2127 
2128         // obsolete values - superceded by m_page_settings
2129         rc = file.WriteDouble( m_page_settings.m_width_mm );
2130         if (!rc) break;
2131 
2132         rc = file.WriteDouble( m_page_settings.m_height_mm );
2133         if (!rc) break;
2134 
2135         ON_UUID obsolete_parent_viewport_id;
2136         memset(&obsolete_parent_viewport_id,0,sizeof(obsolete_parent_viewport_id));
2137         rc = file.WriteUuid( obsolete_parent_viewport_id );
2138         if (!rc) break;
2139 
2140         ON_BoundingBox obsolete_nested_view_position;
2141         rc = file.WriteBoundingBox( obsolete_nested_view_position );
2142         if (!rc) break;
2143 
2144         // 28 feb 2006 version 1.2 fields
2145         rc = file.WriteUuid(m_display_mode_id);
2146         if (!rc) break;
2147 
2148         rc = m_page_settings.Write(file);
2149         if (!rc) break;
2150 
2151         // 7 March 2006 version 1.3 fields
2152         rc = file.WriteBool(m_bLockedProjection);
2153         if (!rc) break;
2154 
2155         // 12 December 2010 version 1.4
2156         rc = file.WriteArray(m_clipping_planes);
2157         if (!rc) break;
2158 
2159         break;
2160       }
2161 
2162       // Since BeginWrite3dmChunk() returned true, EndWrite3dmChunk()
2163       // must be called even when rc is false
2164       if ( !file.EndWrite3dmChunk() )
2165         rc = false;
2166     }
2167   }
2168 
2169   // required TCODE_ENDOFTABLE chunk - marks end of view table
2170   if ( rc ) {
2171     rc = file.BeginWrite3dmChunk( TCODE_ENDOFTABLE, 0 );
2172     if ( rc ) {
2173       if ( !file.EndWrite3dmChunk() )
2174         rc = false;
2175     }
2176   }
2177   return rc;
2178 }
2179 
Read(ON_BinaryArchive & file)2180 bool ON_3dmView::Read( ON_BinaryArchive& file )
2181 {
2182   // Everything in a view is in a subchunk so new records can
2183   // be added to a view and old I/O code will still
2184   // work.
2185   unsigned int tcode = 0;
2186   ON__INT64 big_value = 0;
2187   int i32;
2188   bool rc = true;
2189 
2190   Default();
2191 
2192   bool bHaveTargetPoint = false;
2193   bool bHaveViewport = false;
2194   ON_3dPoint target_point = ON_3dPoint::UnsetPoint;
2195 
2196   while(rc) {
2197     rc = file.BeginRead3dmBigChunk(&tcode,&big_value);
2198     if (!rc)
2199       break;
2200     switch(tcode)
2201     {
2202     case TCODE_VIEW_CPLANE:
2203       rc = m_cplane.Read(file);
2204       break;
2205     case TCODE_VIEW_VIEWPORT:
2206       rc = m_vp.Read(file)?true:false;
2207       if (rc)
2208         bHaveViewport = true;
2209       break;
2210     case TCODE_VIEW_VIEWPORT_USERDATA:
2211       // 27 June 2008 Dale Lear
2212       //   I added support for saving userdata attached to
2213       //   the m_vp ON_Viewport.  Ideally, the ON_Viewport
2214       //   would be read by calling file.ReadObject(), but
2215       //   userdata support is being added years after
2216       //   millions of files have been written by calling
2217       //   m_vp.Write()/Read().
2218       rc = file.ReadObjectUserData(m_vp);
2219       break;
2220     case TCODE_VIEW_SHOWCONGRID:
2221       m_bShowConstructionGrid = big_value?true:false;
2222       break;
2223     case TCODE_VIEW_SHOWCONAXES:
2224       m_bShowConstructionAxes = big_value?true:false;
2225       break;
2226     case TCODE_VIEW_SHOWWORLDAXES:
2227       m_bShowWorldAxes = big_value?true:false;
2228       break;
2229     case TCODE_VIEW_TRACEIMAGE:
2230       rc = m_trace_image.Read(file);
2231       break;
2232     case TCODE_VIEW_WALLPAPER:
2233       // used prior to 5 June 2003 and still written
2234       // after 5 June 2003 so older Rhinos/opennurbs
2235       // will not loose the filename information.
2236       rc = file.ReadString(m_wallpaper_image.m_bitmap_filename);
2237       m_wallpaper_image.m_bGrayScale = true;
2238       break;
2239     case TCODE_VIEW_WALLPAPER_V3:
2240       // Added 5 June 2003 to support additional wallpaper attributes.
2241       rc = m_wallpaper_image.Read(file);
2242       break;
2243     case TCODE_VIEW_TARGET:
2244       rc = file.ReadPoint(target_point);
2245       if (rc)
2246         bHaveTargetPoint = true;
2247       break;
2248     case TCODE_VIEW_DISPLAYMODE:
2249       i32 = (int)big_value;
2250       m_display_mode = ON::DisplayMode(i32);
2251       break;
2252     case TCODE_VIEW_NAME:
2253       rc = file.ReadString(m_name);
2254       break;
2255     case TCODE_VIEW_POSITION:
2256       rc = m_position.Read(file);
2257       break;
2258 
2259     case TCODE_VIEW_ATTRIBUTES:
2260       {
2261         int major_version = 0;
2262         int minor_version = 0;
2263         rc = file.Read3dmChunkVersion(&major_version,&minor_version);
2264         // there are no 1.0 fields in this chunk
2265         while ( rc
2266                 && major_version == 1 && minor_version >= 1
2267                 && file.Archive3dmVersion() >= 4
2268                 && file.ArchiveOpenNURBSVersion() >= 200503170 )
2269         {
2270           // Added 23 March 2005 Dale Lear
2271           // 1.1 fields (there are no 1.0 fields)
2272           i32 = 0;
2273           rc = file.ReadInt( &i32 );
2274           if (!rc) break;
2275           m_view_type = ON::ViewType(i32);
2276 
2277           rc = file.ReadDouble( &m_page_settings.m_width_mm );
2278           if (!rc) break;
2279 
2280           rc = file.ReadDouble( &m_page_settings.m_height_mm );
2281           if (!rc) break;
2282 
2283           ON_UUID obsolete_parent_viewport_id;
2284           rc = file.ReadUuid( obsolete_parent_viewport_id );
2285           if (!rc) break;
2286 
2287           ON_BoundingBox obsolete_nested_view_position;
2288           rc = file.ReadBoundingBox( obsolete_nested_view_position );
2289           if (!rc) break;
2290 
2291           if ( minor_version >= 2 )
2292           {
2293             // 28 feb 2006 version 1.2 field
2294             rc = file.ReadUuid(m_display_mode_id);
2295             if (!rc) break;
2296 
2297             rc = m_page_settings.Read(file);
2298             if (!rc) break;
2299 
2300             if ( minor_version >= 3 )
2301             {
2302               rc = file.ReadBool(&m_bLockedProjection);
2303               if (!rc) break;
2304 
2305               if ( minor_version >= 4 )
2306               {
2307                 rc = file.ReadArray(m_clipping_planes);
2308                 if (!rc) break;
2309               }
2310             }
2311           }
2312 
2313           // Add new inforamation here - ask Dale Lear for help.
2314 
2315           break;
2316         }
2317       }
2318       break;
2319     }
2320 
2321     if (!file.EndRead3dmChunk())
2322       rc = false;
2323     if ( tcode == TCODE_ENDOFTABLE )
2324       break;
2325   }
2326 
2327   if (    bHaveViewport
2328        && bHaveTargetPoint
2329        && target_point.IsValid()
2330        && !OBSOLETE_3DM_VIEW_TARGET.IsValid()
2331      )
2332   {
2333     // m_target is obsolete, but some older files
2334     // have the good value stored in ON_3dmView. In this
2335     // case use the good value as the target point.
2336     SetTargetPoint(target_point); // sets both this->m_target and m_vp.m_target_point
2337   }
2338   else
2339   {
2340     // Assume the value on m_vp.m_target_point is the right one and
2341     // Keep the obsolete m_target in sync with m_vp.m_target_point.
2342     OBSOLETE_3DM_VIEW_TARGET = m_vp.TargetPoint();
2343   }
2344 
2345   return rc;
2346 }
2347 
ON_EarthAnchorPoint()2348 ON_EarthAnchorPoint::ON_EarthAnchorPoint()
2349 {
2350   Default();
2351 }
2352 
~ON_EarthAnchorPoint()2353 ON_EarthAnchorPoint::~ON_EarthAnchorPoint()
2354 {
2355 }
2356 
Default()2357 void ON_EarthAnchorPoint::Default()
2358 {
2359   m_earth_basepoint_latitude = 0.0;
2360   m_earth_basepoint_longitude = 0.0;
2361   m_earth_basepoint_elevation = 0.0;
2362   m_earth_basepoint_elevation_zero = 0;
2363 
2364   m_model_basepoint.Set(0.0,0.0,0.0);
2365   m_model_north.Set(0.0,1.0,0.0);
2366   m_model_east.Set(1.0,0.0,0.0);
2367 
2368   m_id = ON_nil_uuid;
2369   m_name.Destroy();
2370   m_description.Destroy();
2371   m_url.Destroy();
2372   m_url_tag.Destroy();
2373 }
2374 
CompareEarthLocation(const ON_EarthAnchorPoint * a,const ON_EarthAnchorPoint * b)2375 int ON_EarthAnchorPoint::CompareEarthLocation(const ON_EarthAnchorPoint* a, const ON_EarthAnchorPoint* b)
2376 {
2377   if ( !a )
2378   {
2379     return b ? -1 : 0;
2380   }
2381   if (!b)
2382   {
2383     return 1;
2384   }
2385 
2386   double xa = a->m_earth_basepoint_longitude;
2387   double xb = b->m_earth_basepoint_longitude;
2388   if ( !ON_IsValid(xa) )
2389   {
2390     if ( ON_IsValid(xb) ) return -1;
2391   }
2392   else if ( !ON_IsValid(xb) )
2393   {
2394     return 1;
2395   }
2396   else
2397   {
2398     while(xa <= 0.0)
2399       xa += 360.0;
2400     while(xa > 360.0)
2401       xa -= 360.0;
2402     while(xb <= 0.0)
2403       xb += 360.0;
2404     while(xb > 360.0)
2405       xb -= 360.0;
2406     if ( xa < xb ) return -1;
2407     if ( xa > xb ) return 1;
2408   }
2409 
2410   xa = a->m_earth_basepoint_latitude;
2411   xb = b->m_earth_basepoint_latitude;
2412   if ( !ON_IsValid(xa) )
2413   {
2414     if ( ON_IsValid(xb) ) return -1;
2415   }
2416   else if ( !ON_IsValid(xb) )
2417   {
2418     return 1;
2419   }
2420   else
2421   {
2422     while(xa <= 0.0)
2423       xa += 360.0;
2424     while(xa > 360.0)
2425       xa -= 360.0;
2426     while(xb <= 0.0)
2427       xb += 360.0;
2428     while(xb > 360.0)
2429       xb -= 360.0;
2430     if ( xa < xb ) return -1;
2431     if ( xa > xb ) return 1;
2432   }
2433 
2434   int i = a->m_earth_basepoint_elevation_zero - b->m_earth_basepoint_elevation_zero;
2435   if ( i != 0 )
2436     return i;
2437 
2438   xa = a->m_earth_basepoint_elevation;
2439   xb = b->m_earth_basepoint_elevation;
2440   if ( !ON_IsValid(xa) )
2441   {
2442     if ( ON_IsValid(xb) ) return -1;
2443   }
2444   else if ( !ON_IsValid(xb) )
2445   {
2446     return 1;
2447   }
2448   else
2449   {
2450     if ( xa < xb ) return -1;
2451     if ( xa > xb ) return 1;
2452   }
2453 
2454   return 0;
2455 }
2456 
CompareModelDirection(const ON_EarthAnchorPoint * a,const ON_EarthAnchorPoint * b)2457 int ON_EarthAnchorPoint::CompareModelDirection(const ON_EarthAnchorPoint* a, const ON_EarthAnchorPoint* b)
2458 {
2459   if ( !a )
2460   {
2461     return b ? -1 : 0;
2462   }
2463   if (!b)
2464   {
2465     return 1;
2466   }
2467 
2468   int i = ON_ComparePoint(3,false,&a->m_model_basepoint.x,&b->m_model_basepoint.x);
2469   if ( !i )
2470   {
2471     i = ON_ComparePoint(3,false,&a->m_model_north.x,&b->m_model_north.x);
2472     if ( !i )
2473     {
2474       i = ON_ComparePoint(3,false,&a->m_model_east.x,&b->m_model_east.x);
2475     }
2476   }
2477   return i;
2478 }
2479 
CompareIdentification(const ON_EarthAnchorPoint * a,const ON_EarthAnchorPoint * b)2480 int ON_EarthAnchorPoint::CompareIdentification(const ON_EarthAnchorPoint* a, const ON_EarthAnchorPoint* b)
2481 {
2482   if ( !a )
2483   {
2484     return b ? -1 : 0;
2485   }
2486   if (!b)
2487   {
2488     return 1;
2489   }
2490 
2491   int i = ON_UuidCompare(a->m_id,b->m_id);
2492   if ( !i)
2493   {
2494     i = a->m_name.Compare(b->m_name);
2495     if (!i)
2496     {
2497       i = a->m_description.Compare(b->m_description);
2498       if (!i)
2499       {
2500         i = a->m_url.CompareNoCase(b->m_url);
2501         if ( !i)
2502         {
2503           i = a->m_url_tag.Compare(b->m_url_tag);
2504         }
2505       }
2506     }
2507   }
2508   return i;
2509 }
2510 
Compare(const ON_EarthAnchorPoint * a,const ON_EarthAnchorPoint * b)2511 int ON_EarthAnchorPoint::Compare(const ON_EarthAnchorPoint* a, const ON_EarthAnchorPoint* b)
2512 {
2513   int i = ON_EarthAnchorPoint::CompareEarthLocation(a,b);
2514   if ( !i)
2515   {
2516     i = ON_EarthAnchorPoint::CompareModelDirection(a,b);
2517     if (!i)
2518     {
2519       i = ON_EarthAnchorPoint::CompareIdentification(a,b);
2520     }
2521   }
2522   return i;
2523 }
2524 
Read(ON_BinaryArchive & file)2525 bool ON_EarthAnchorPoint::Read( ON_BinaryArchive& file )
2526 {
2527   Default();
2528   int major_version = 0;
2529   int minor_version = 0;
2530   bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
2531   if ( !rc )
2532     return false;
2533 
2534   for(;;)
2535   {
2536     rc = (1 == major_version);
2537     if (!rc) break;
2538 
2539     rc = file.ReadDouble(&m_earth_basepoint_latitude);
2540     if (!rc) break;
2541     rc = file.ReadDouble(&m_earth_basepoint_longitude);
2542     if (!rc) break;
2543     rc = file.ReadDouble(&m_earth_basepoint_elevation);
2544     if (!rc) break;
2545     rc = file.ReadPoint(m_model_basepoint);
2546     if (!rc) break;
2547     rc = file.ReadVector(m_model_north);
2548     if (!rc) break;
2549     rc = file.ReadVector(m_model_east);
2550     if (!rc) break;
2551 
2552     if ( minor_version >= 1 )
2553     {
2554       // 1.1 fields
2555       rc = file.ReadInt(&m_earth_basepoint_elevation_zero);
2556       if (!rc) break;
2557       rc = file.ReadUuid(m_id);
2558       if (!rc) break;
2559       rc = file.ReadString(m_name);
2560       if (!rc) break;
2561       rc = file.ReadString(m_description);
2562       if (!rc) break;
2563       rc = file.ReadString(m_url);
2564       if (!rc) break;
2565       rc = file.ReadString(m_url_tag);
2566       if (!rc) break;
2567     }
2568 
2569     break;
2570   }
2571 
2572   if ( !file.EndRead3dmChunk() )
2573     rc = false;
2574 
2575   return rc;
2576 }
2577 
Write(ON_BinaryArchive & file) const2578 bool ON_EarthAnchorPoint::Write( ON_BinaryArchive& file ) const
2579 {
2580   bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,1);
2581   if ( !rc )
2582     return false;
2583 
2584   for(;;)
2585   {
2586     rc = file.WriteDouble(m_earth_basepoint_latitude);
2587     if (!rc) break;
2588     rc = file.WriteDouble(m_earth_basepoint_longitude);
2589     if (!rc) break;
2590     rc = file.WriteDouble(m_earth_basepoint_elevation);
2591     if (!rc) break;
2592     rc = file.WritePoint(m_model_basepoint);
2593     if (!rc) break;
2594     rc = file.WriteVector(m_model_north);
2595     if (!rc) break;
2596     rc = file.WriteVector(m_model_east);
2597     if (!rc) break;
2598 
2599     // 1.1 fields
2600     rc = file.WriteInt(m_earth_basepoint_elevation_zero);
2601     if (!rc) break;
2602     rc = file.WriteUuid(m_id);
2603     if (!rc) break;
2604     rc = file.WriteString(m_name);
2605     if (!rc) break;
2606     rc = file.WriteString(m_description);
2607     if (!rc) break;
2608     rc = file.WriteString(m_url);
2609     if (!rc) break;
2610     rc = file.WriteString(m_url_tag);
2611     if (!rc) break;
2612 
2613 
2614     break;
2615   }
2616 
2617   if ( !file.EndWrite3dmChunk() )
2618     rc = false;
2619 
2620   return rc;
2621 }
2622 
2623 
GetModelCompass(ON_Plane & model_compass) const2624 bool ON_EarthAnchorPoint::GetModelCompass(ON_Plane& model_compass) const
2625 {
2626   ON_Plane mc;
2627   mc.xaxis = m_model_east;
2628   mc.yaxis = m_model_north;
2629   if ( fabs(mc.xaxis.Length() - 1.0) > ON_SQRT_EPSILON )
2630   {
2631     if ( !mc.xaxis.Unitize() )
2632       return false;
2633   }
2634   if ( fabs(mc.yaxis.Length() - 1.0) > ON_SQRT_EPSILON )
2635   {
2636     if ( !mc.yaxis.Unitize() )
2637       return false;
2638   }
2639   double d = mc.xaxis*mc.yaxis;
2640   if ( fabs(d) > ON_SQRT_EPSILON )
2641   {
2642     // assume north is correct
2643     mc.xaxis.x -= d*mc.yaxis.x;
2644     mc.xaxis.y -= d*mc.yaxis.y;
2645     mc.xaxis.z -= d*mc.yaxis.z;
2646     if( !mc.xaxis.Unitize() )
2647       return false;
2648   }
2649   mc.zaxis = ON_CrossProduct(mc.xaxis,mc.yaxis);
2650   if ( fabs(mc.zaxis.Length() - 1.0) > ON_SQRT_EPSILON )
2651   {
2652     if ( !mc.zaxis.Unitize() )
2653       return false;
2654   }
2655   mc.origin = m_model_basepoint;
2656   mc.UpdateEquation();
2657   model_compass = mc;
2658   return model_compass.IsValid();
2659 }
2660 
GetModelToEarthXform(const ON_UnitSystem & model_unit_system,ON_Xform & model_to_earth) const2661 bool ON_EarthAnchorPoint::GetModelToEarthXform(
2662           const ON_UnitSystem& model_unit_system,
2663           ON_Xform& model_to_earth
2664           ) const
2665 {
2666   // The orient_model rotates the model so that
2667   //   xaxis runs from west to east
2668   //   yaxis runs from south to north
2669   //   zaxis points "up"
2670   ON_Plane model_compass;
2671   bool rc = GetModelCompass( model_compass );
2672   model_compass.origin = m_model_basepoint;
2673   model_compass.UpdateEquation();
2674   ON_Xform orient_model;
2675   orient_model.Rotation( model_compass, ON_xy_plane  );
2676 
2677   ON_Xform coord_change(1.0);
2678 
2679   const double lat_radians = m_earth_basepoint_latitude/180.0*ON_PI;
2680   const double cos_lat = cos(lat_radians);
2681   const double sin_lat = sin(lat_radians);
2682 
2683   // get radius of earth at this latitude
2684   const double earth_polar_radius      = 6356750.0; // Earth's radius at poles (meters)
2685   const double earth_equatorial_radius = 6378135.0; // Earth's radius at equator (meters)
2686   ON_2dVector r;
2687   r.x = cos_lat;
2688   r.y = sin_lat*(earth_equatorial_radius/earth_polar_radius);
2689   double earth_radius = earth_equatorial_radius/r.Length();
2690   if ( earth_radius > earth_equatorial_radius )
2691     earth_radius = earth_equatorial_radius;
2692   else if ( earth_radius < earth_polar_radius )
2693     earth_radius = earth_polar_radius;
2694 
2695   const double meters_per_degree_latitude = earth_radius*ON_PI/180.0; // meters per degree of latitude
2696 
2697   const double model_to_meters_scale = ON::UnitScale(model_unit_system, ON::meters);
2698   const double north_south_scale  = model_to_meters_scale/meters_per_degree_latitude;
2699   const double east_west_scale = ( 1.0e100*cos_lat < north_south_scale )
2700                                ? north_south_scale
2701                                : north_south_scale/cos_lat;
2702 
2703   coord_change.m_xform[0][0] = east_west_scale;
2704   coord_change.m_xform[0][3] = m_earth_basepoint_longitude;
2705   coord_change.m_xform[1][1] = north_south_scale;
2706   coord_change.m_xform[1][3] = m_earth_basepoint_latitude;
2707   coord_change.m_xform[2][2] = model_to_meters_scale;
2708   coord_change.m_xform[3][2] = m_earth_basepoint_elevation;
2709 
2710   model_to_earth = coord_change*orient_model;
2711 
2712   return rc;
2713 }
2714 
2715 
2716 //////////////////////////////////////////////////////////////////////////////////////////
2717 //
2718 // ON_3dmSettings
2719 //
2720 
Default()2721 void ON_3dmSettings::Default()
2722 {
2723   // default properties
2724   m_model_URL.Destroy();
2725   m_model_basepoint.Set(0.0,0.0,0.0);
2726   m_earth_anchor_point.Default();
2727   m_ModelUnitsAndTolerances = ON_3dmUnitsAndTolerances::DefaultValue;
2728   m_PageUnitsAndTolerances = ON_3dmUnitsAndTolerances::DefaultValue;
2729   m_RenderMeshSettings.Default();
2730   m_CustomRenderMeshSettings.Default();
2731 
2732   m_IO_settings.Default();
2733 
2734   // 28 Febuary 2003 Dale Lear:
2735   //     Add analysis mesh default settings
2736   m_AnalysisMeshSettings.DefaultAnalysisMeshParameters();
2737 
2738   m_AnnotationSettings.Default();
2739   m_named_cplanes.Empty();
2740   m_named_views.Empty();
2741   m_views.Empty();
2742   m_active_view_id = ON_nil_uuid;
2743 
2744   m_current_layer_index = 0;
2745   m_current_font_index = 0;
2746   m_current_dimstyle_index = 0;
2747 
2748   m_current_material_index = -1; // -1 = "default" material
2749   m_current_material_source = ON::material_from_layer;
2750 
2751   m_current_color.SetRGB(0,0,0);
2752   m_current_color_source = ON::color_from_layer;
2753 
2754   m_current_linetype_index = -1;  // -1 = "default" solid line
2755   m_current_linetype_source = ON::linetype_from_layer;
2756 
2757   m_current_plot_color = ON_UNSET_COLOR;
2758   m_current_plot_color_source = ON::plot_color_from_layer;
2759 
2760   m_current_wire_density = 1;
2761   m_RenderSettings.Default();
2762   m_GridDefaults.Default();
2763 
2764   m_linetype_display_scale = 1.0;
2765 
2766   m_plugin_list.Destroy();
2767 }
2768 
ON_3dmSettings()2769 ON_3dmSettings::ON_3dmSettings()
2770 {
2771   Default();
2772 };
2773 
~ON_3dmSettings()2774 ON_3dmSettings::~ON_3dmSettings()
2775 {
2776 }
2777 
ON_3dmIOSettings()2778 ON_3dmIOSettings::ON_3dmIOSettings()
2779 {
2780   Default();
2781 }
2782 
Default()2783 void ON_3dmIOSettings::Default()
2784 {
2785   m_bSaveTextureBitmapsInFile = false;
2786   // 7 February 2011 - default changed to 1.
2787   //m_idef_link_update = 0;
2788   m_idef_link_update = 1;
2789 }
2790 
2791 
Read(ON_BinaryArchive & file)2792 bool ON_3dmIOSettings::Read(ON_BinaryArchive& file)
2793 {
2794   Default();
2795 
2796   int major_version = 0;
2797   int minor_version = 0;
2798   bool rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
2799   if (!rc)
2800     return false;
2801 
2802   for(;;)
2803   {
2804     rc = ( 1 == major_version );
2805     if (!rc) break;
2806 
2807     rc = file.ReadBool(&m_bSaveTextureBitmapsInFile);
2808     if(!rc) break;
2809 
2810     rc = file.ReadInt(&m_idef_link_update);
2811     if(!rc) break;
2812 
2813     if ( 0 == m_idef_link_update && file.Archive3dmVersion() >= 5 )
2814     {
2815       // 7 February 2011 - old 0 value is no longer an option.
2816       m_idef_link_update = 1;
2817     }
2818 
2819     break;
2820   }
2821 
2822   if ( !file.EndRead3dmChunk() )
2823     rc = false;
2824 
2825   return rc;
2826 }
2827 
Write(ON_BinaryArchive & file) const2828 bool ON_3dmIOSettings::Write(ON_BinaryArchive& file) const
2829 {
2830   bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
2831   if (!rc)
2832     return false;
2833   for(;;)
2834   {
2835     rc = file.WriteBool(m_bSaveTextureBitmapsInFile);
2836     if(!rc) break;
2837 
2838     int i = m_idef_link_update;
2839     if ( 0 == i && file.Archive3dmVersion() >= 5 )
2840     {
2841       // 7 February 2011 - old 0 value is no longer an option.
2842       i = 1;
2843     }
2844     rc = file.WriteInt(i);
2845     if(!rc) break;
2846 
2847     break;
2848   }
2849   if ( !file.EndWrite3dmChunk() )
2850     rc = false;
2851 
2852   return rc;
2853 }
2854 
2855 
ON_3dmSettings_Read_v1_TCODE_NAME(ON_BinaryArchive & file,ON_wString & str)2856 static bool ON_3dmSettings_Read_v1_TCODE_NAME(ON_BinaryArchive& file, ON_wString& str )
2857 {
2858   // reads legacy 1.0 named view TCODE_NAME chunk
2859   str.Empty();
2860   int len = 0;
2861   bool rc = file.ReadInt( &len );
2862   if (rc && len > 0) {
2863     char* name = (char*)oncalloc( 1, len + 1);
2864     rc = file.ReadString( len, name );
2865     if (rc)
2866       str = name; // ASCII -> UNICODE
2867     if (name)
2868       onfree(name);
2869   }
2870   return rc;
2871 }
2872 
ON_3dmSettings_Read_v1_TCODE_CPLANE(ON_BinaryArchive & file,ON_3dmConstructionPlane & cplane)2873 static bool ON_3dmSettings_Read_v1_TCODE_CPLANE(ON_BinaryArchive& file, ON_3dmConstructionPlane& cplane)
2874 {
2875   // reads legacy 1.0 named view TCODE_CPLANE chunk
2876 
2877   // do NOT call cplane.Default() here
2878   bool rc = true;
2879 	ON_3dPoint origin;
2880 	ON_3dVector xaxis, yaxis;
2881 	double gridsize;
2882 	int gridsections, gridthicksections;
2883   if (rc) rc = file.ReadPoint( origin );
2884   if (rc) rc = file.ReadVector( xaxis );
2885   if (rc) rc = file.ReadVector( yaxis );
2886   if (rc)
2887   {
2888     rc = file.ReadDouble(&gridsize);
2889     if (rc)
2890     {
2891       rc = file.ReadInt(&gridsections);
2892       if (rc)
2893       {
2894         rc = file.ReadInt(&gridthicksections);
2895         if (rc)
2896         {
2897           cplane.m_plane.CreateFromFrame(origin,xaxis,yaxis);
2898           cplane.m_grid_line_count = gridsections;
2899           cplane.m_grid_thick_frequency = gridthicksections;
2900           cplane.m_grid_spacing = gridsize;
2901           cplane.m_snap_spacing = gridsize;
2902         }
2903         }
2904     }
2905   }
2906   return rc;
2907 }
2908 
ON_3dmSettings_Read_v1_TCODE_VIEW(ON_BinaryArchive & file,ON_3dmView & view)2909 static bool ON_3dmSettings_Read_v1_TCODE_VIEW(ON_BinaryArchive& file, ON_3dmView& view)
2910 {
2911   // reads legacy 1.0 named view TCODE_VIEW chunk
2912   // do NOT call view.Default() here
2913   bool rc = true;
2914 
2915 	int projection, valid;
2916 	double angle1, angle2, angle3, viewsize, cameradist;
2917   ON_3dPoint target_point;
2918   while(rc)
2919   {
2920     rc = file.ReadInt(&projection);
2921     if (!rc) break;
2922     rc = file.ReadInt(&valid);
2923     if (!rc) break;
2924     rc = file.ReadPoint( target_point );
2925     if (!rc) break;
2926     rc = file.ReadDouble( &angle1 );
2927     if (!rc) break;
2928     rc = file.ReadDouble( &angle2 );
2929     if (!rc) break;
2930     rc = file.ReadDouble( &angle3 );
2931     if (!rc) break;
2932     rc = file.ReadDouble( &viewsize );
2933     if (!rc) break;
2934     rc = file.ReadDouble( &cameradist );
2935     if (!rc) break;
2936 
2937     if( cameradist <= 0.0 || cameradist >= ( DBL_MAX / 2.0 ))
2938       cameradist = 100.0;
2939     if( viewsize <= 0.0 || viewsize >= ( DBL_MAX / 2.0 ))
2940       viewsize = 0.125;
2941     ON_ViewportFromRhinoView(
2942           projection == 2 ? ON::perspective_view : ON::parallel_view,
2943           target_point,
2944           angle1,
2945           angle2,
2946           angle3,
2947           viewsize,
2948           cameradist,
2949           100, // screen_width,
2950           100, // screen_height,
2951           view.m_vp
2952           );
2953     // keep obsolete view.m_target in sync with view.m_vp.m_target_point
2954     view.OBSOLETE_3DM_VIEW_TARGET = view.m_vp.TargetPoint();
2955     break;
2956   }
2957 
2958   return rc;
2959 }
2960 
ON_3dmSettings_Read_v1_TCODE_NAMED_VIEW(ON_BinaryArchive & file,ON_3dmView & view)2961 static bool ON_3dmSettings_Read_v1_TCODE_NAMED_VIEW(ON_BinaryArchive& file, ON_3dmView& view)
2962 {
2963   // reads legacy 1.0 named view TCODE_NAMED_VIEW chunk
2964   view.Default();
2965   bool rc = true;
2966   unsigned int tcode;
2967   ON__INT64 big_value;
2968 
2969   while(rc)
2970   {
2971     rc = file.BeginRead3dmBigChunk( &tcode, &big_value );
2972     if (!rc )
2973       break;
2974     switch(tcode) {
2975 
2976     case TCODE_NAME:
2977       rc = ON_3dmSettings_Read_v1_TCODE_NAME(file,view.m_name);
2978       break;
2979 
2980     case TCODE_CPLANE:
2981       rc = ON_3dmSettings_Read_v1_TCODE_CPLANE(file,view.m_cplane);
2982       break;
2983 
2984     case TCODE_VIEW:
2985       rc = ON_3dmSettings_Read_v1_TCODE_VIEW( file, view );
2986       break;
2987 
2988     case TCODE_SHOWGRID:
2989       view.m_bShowConstructionGrid = big_value?true:false;
2990       break;
2991 
2992     case TCODE_SHOWGRIDAXES:
2993       view.m_bShowConstructionAxes = big_value?true:false;
2994       break;
2995 
2996     case TCODE_SHOWWORLDAXES:
2997       view.m_bShowWorldAxes = big_value?true:false;
2998       break;
2999 
3000     }
3001     if ( !file.EndRead3dmChunk() )
3002       rc = false;
3003     if ( tcode == TCODE_ENDOFTABLE )
3004       break;
3005   }
3006   return rc;
3007 }
3008 
ON_3dmSettings_Read_v1_TCODE_NAMED_CPLANE(ON_BinaryArchive & file,ON_3dmConstructionPlane & cplane)3009 static bool ON_3dmSettings_Read_v1_TCODE_NAMED_CPLANE(ON_BinaryArchive& file, ON_3dmConstructionPlane& cplane)
3010 {
3011   // reads legacy 1.0 named construction plane TCODE_NAMED_CPLANE chunk
3012   cplane.Default();
3013 
3014   bool rc = true;
3015   unsigned int tcode;
3016   ON__INT64 big_value;
3017 
3018   while(rc)
3019   {
3020     rc = file.BeginRead3dmBigChunk( &tcode, &big_value );
3021     if (!rc )
3022       break;
3023     switch(tcode) {
3024 
3025     case TCODE_NAME:
3026       rc = ON_3dmSettings_Read_v1_TCODE_NAME(file, cplane.m_name );
3027       break;
3028 
3029     case TCODE_CPLANE:
3030       rc = ON_3dmSettings_Read_v1_TCODE_CPLANE(file, cplane );
3031       break;
3032     }
3033     if ( !file.EndRead3dmChunk() )
3034       rc = false;
3035     if ( tcode == TCODE_ENDOFTABLE )
3036       break;
3037   }
3038   return rc;
3039 }
3040 
ON_3dmSettings_Read_v1_TCODE_UNIT_AND_TOLERANCES(ON_BinaryArchive & file,ON_3dmUnitsAndTolerances & UnitsAndTolerances)3041 static bool ON_3dmSettings_Read_v1_TCODE_UNIT_AND_TOLERANCES(
3042   ON_BinaryArchive& file,
3043   ON_3dmUnitsAndTolerances& UnitsAndTolerances
3044   )
3045 {
3046   bool rc = true;
3047   int v = 0;
3048   int us = 0;
3049   UnitsAndTolerances = ON_3dmUnitsAndTolerances::DefaultValue;
3050   if (rc)
3051     rc = file.ReadInt( &v ); // should get v = 1
3052   if (rc)
3053     rc = file.ReadInt( &us );
3054   switch (us)
3055   {
3056   case 0: // NO_UNIT_SYSTEM:
3057     UnitsAndTolerances.m_unit_system.m_unit_system = ON::no_unit_system;
3058     break;
3059   case 1: // MICRONS:
3060     UnitsAndTolerances.m_unit_system.m_unit_system = ON::microns;
3061     break;
3062   case 2: // MILLIMETERS:
3063     UnitsAndTolerances.m_unit_system.m_unit_system = ON::millimeters;
3064     break;
3065   case 3: // CENTIMETERS:
3066     UnitsAndTolerances.m_unit_system.m_unit_system = ON::centimeters;
3067     break;
3068   case 4: // METERS:
3069     UnitsAndTolerances.m_unit_system.m_unit_system = ON::meters;
3070     break;
3071   case 5: // KILOMETERS:
3072     UnitsAndTolerances.m_unit_system.m_unit_system = ON::kilometers;
3073     break;
3074   case 6: // MICROINCHES:
3075     UnitsAndTolerances.m_unit_system.m_unit_system = ON::microinches;
3076     break;
3077   case 7: // MILS:
3078     UnitsAndTolerances.m_unit_system.m_unit_system = ON::mils;
3079     break;
3080   case 8: // INCHES:
3081     UnitsAndTolerances.m_unit_system.m_unit_system = ON::inches;
3082     break;
3083   case 9: // FEET:
3084     UnitsAndTolerances.m_unit_system.m_unit_system = ON::feet;
3085     break;
3086   case 10: // MILES:
3087     UnitsAndTolerances.m_unit_system.m_unit_system = ON::miles;
3088     break;
3089   default: // NO_UNIT_SYSTEM:
3090     UnitsAndTolerances.m_unit_system.m_unit_system = ON::no_unit_system;
3091     break;
3092   }
3093   if (rc) rc = file.ReadDouble( &UnitsAndTolerances.m_absolute_tolerance );
3094   if (rc) rc = file.ReadDouble( &UnitsAndTolerances.m_relative_tolerance );
3095   if (rc) rc = file.ReadDouble( &UnitsAndTolerances.m_angle_tolerance );
3096   return rc;
3097 }
3098 
ON_3dmSettings_Read_v1_TCODE_VIEWPORT(ON_BinaryArchive & file,ON_3dmView & view)3099 static bool ON_3dmSettings_Read_v1_TCODE_VIEWPORT(ON_BinaryArchive& file, ON_3dmView& view)
3100 {
3101   // reads legacy 1.0 named construction plane TCODE_VIEWPORT chunk
3102   view.Default();
3103   bool rc = true;
3104   ON__UINT32 tcode;
3105   ON__INT64 big_value;
3106 
3107   double clipdist = 0.0;
3108   double snapsize = 0.0;
3109 
3110   int chunk_count = 0;// debugging counter
3111   for ( chunk_count = 0; rc; chunk_count++ )
3112   {
3113     rc = file.BeginRead3dmBigChunk( &tcode, &big_value );
3114     if (!rc )
3115       break;
3116     switch(tcode) {
3117 
3118     case TCODE_NEAR_CLIP_PLANE:
3119       rc = file.ReadDouble(&clipdist);
3120       break;
3121 
3122     case TCODE_SNAPSIZE:
3123       rc = file.ReadDouble(&snapsize);
3124       break;
3125 
3126     case TCODE_NAME:
3127       rc = ON_3dmSettings_Read_v1_TCODE_NAME(file,view.m_name);
3128       break;
3129 
3130     case TCODE_CPLANE:
3131       rc = ON_3dmSettings_Read_v1_TCODE_CPLANE(file,view.m_cplane);
3132       break;
3133 
3134     case TCODE_VIEW:
3135       rc = ON_3dmSettings_Read_v1_TCODE_VIEW( file, view );
3136       break;
3137 
3138     case TCODE_SHOWGRID:
3139       view.m_bShowConstructionGrid = big_value?true:false;
3140       break;
3141 
3142     case TCODE_SHOWGRIDAXES:
3143       view.m_bShowConstructionAxes = big_value?true:false;
3144       break;
3145 
3146     case TCODE_SHOWWORLDAXES:
3147       view.m_bShowWorldAxes = big_value?true:false;
3148       break;
3149 
3150     case TCODE_VIEWPORT_POSITION:
3151       rc = file.ReadDouble(&view.m_position.m_wnd_left);
3152       rc = file.ReadDouble(&view.m_position.m_wnd_top);
3153       rc = file.ReadDouble(&view.m_position.m_wnd_right);
3154       rc = file.ReadDouble(&view.m_position.m_wnd_bottom);
3155       break;
3156 
3157     case TCODE_VIEWPORT_TRACEINFO:
3158       {
3159         ON_3dPoint origin;
3160         ON_3dVector xaxis, yaxis;
3161         if (rc) rc = file.ReadPoint( origin );
3162         if (rc) rc = file.ReadVector( xaxis );
3163         if (rc) rc = file.ReadVector( yaxis );
3164         view.m_trace_image.m_plane.CreateFromFrame(origin,xaxis,yaxis);
3165         if (rc) rc = file.ReadDouble(&view.m_trace_image.m_width);
3166         if (rc) rc = file.ReadDouble(&view.m_trace_image.m_height);
3167         if (rc) rc = ON_3dmSettings_Read_v1_TCODE_NAME(file,view.m_trace_image.m_bitmap_filename);
3168       }
3169       break;
3170 
3171     case TCODE_VIEWPORT_WALLPAPER:
3172       rc = ON_3dmSettings_Read_v1_TCODE_NAME(file,view.m_wallpaper_image.m_bitmap_filename);
3173       break;
3174 
3175     case TCODE_HIDE_TRACE:
3176       // TCODE_HIDE_TRACE was used in early 1.0 betas.
3177       // It should have add the short bit set and it is no longer used.
3178       // This case is here so that these old files will read correctly.
3179       tcode |= TCODE_SHORT; // so goo skip will work
3180       break;
3181 
3182     case TCODE_MAXIMIZED_VIEWPORT:
3183       if ( big_value )
3184         view.m_position.m_bMaximized = true;
3185       break;
3186 
3187     case TCODE_VIEWPORT_DISPLAY_MODE: // short TCODE with display mode value
3188       switch ( big_value )
3189       {
3190       case 0: // wireframe working mode
3191         view.m_display_mode = ON::wireframe_display;
3192         break;
3193       case 1: // shaded working mode
3194         view.m_display_mode = ON::shaded_display;
3195         break;
3196       }
3197       break;
3198 
3199     }
3200     if ( !file.EndRead3dmChunk() )
3201       rc = false;
3202     if ( tcode == TCODE_ENDOFTABLE )
3203       break;
3204   }
3205   return rc;
3206 }
3207 
Read_v1(ON_BinaryArchive & file)3208 bool ON_3dmSettings::Read_v1( ON_BinaryArchive& file )
3209 {
3210   bool bGotSomething = false;
3211   bool rc = false;
3212   // read settings from old version 1 file
3213   size_t pos0 = file.CurrentPosition();
3214 
3215   // need to start at the beginning of the file
3216   ON__UINT32 tcode;
3217   ON__INT64 big_value;
3218   rc = file.SeekFromStart(32)?true:false; // skip 32 byte header
3219 
3220   int chunk_count = 0; // debugging counter
3221   for ( chunk_count = 0; rc; chunk_count++ )
3222   {
3223     rc = file.BeginRead3dmBigChunk( &tcode, &big_value );
3224     if ( !rc )
3225       break; // assume we are at the end of the file
3226 
3227     switch(tcode) {
3228     case TCODE_VIEWPORT:
3229       bGotSomething = true;
3230       {
3231         ON_3dmView view;
3232         rc = ON_3dmSettings_Read_v1_TCODE_VIEWPORT(file, view);
3233         if (rc)
3234           m_views.Append(view);
3235       }
3236       break;
3237 
3238     case TCODE_NAMED_CPLANE:
3239       bGotSomething = true;
3240       {
3241         ON_3dmConstructionPlane cplane;
3242         rc = ON_3dmSettings_Read_v1_TCODE_NAMED_CPLANE(file,cplane);
3243         if (rc)
3244           m_named_cplanes.Append(cplane);
3245       }
3246       break;
3247 
3248     case TCODE_NAMED_VIEW:
3249       bGotSomething = true;
3250       {
3251         ON_3dmView view;
3252         rc = ON_3dmSettings_Read_v1_TCODE_NAMED_VIEW(file, view);
3253         if (rc)
3254           m_named_views.Append(view);
3255       }
3256       break;
3257 
3258     case TCODE_UNIT_AND_TOLERANCES:
3259       bGotSomething = true;
3260       rc = ON_3dmSettings_Read_v1_TCODE_UNIT_AND_TOLERANCES(file,m_ModelUnitsAndTolerances);
3261       break;
3262     }
3263 
3264     rc = file.EndRead3dmChunk();
3265   }
3266 
3267   file.SeekFromStart(pos0);
3268   return bGotSomething;
3269 }
3270 
Read_v2(ON_BinaryArchive & file)3271 bool ON_3dmSettings::Read_v2(ON_BinaryArchive& file )
3272 {
3273   bool rc = true;
3274   ON__UINT32 tcode;
3275   ON__INT64 big_value;
3276 
3277   while(rc)
3278   {
3279     tcode = 0;
3280     big_value = 0;
3281     rc = file.BeginRead3dmBigChunk( &tcode, &big_value );
3282     if ( !rc )
3283       break;
3284 
3285     switch(tcode)
3286     {
3287     case TCODE_SETTINGS_PLUGINLIST:
3288       {
3289         int major_version = 0, minor_version = 0, count = 0, i;
3290         rc = file.Read3dmChunkVersion(&major_version,&minor_version);
3291         if (rc && 1 == major_version && minor_version >= 0 )
3292         {
3293           rc = file.ReadInt( &count );
3294           if ( count > 0 )
3295           {
3296             for ( i = 0; rc && i < count; i++ )
3297             {
3298               rc = m_plugin_list.AppendNew().Read(file);
3299             }
3300           }
3301         }
3302       }
3303       break;
3304 
3305     case TCODE_SETTINGS_UNITSANDTOLS: // units and tolerances
3306       rc = m_ModelUnitsAndTolerances.Read(file);
3307       // Copy model settings to page settings so reading old files
3308       // will work right.  If the file is new enough to have page
3309       // units and tolerances in it, they get read later.
3310       m_PageUnitsAndTolerances = m_ModelUnitsAndTolerances;
3311       break;
3312 
3313     case TCODE_SETTINGS_RENDERMESH:
3314       rc = m_RenderMeshSettings.Read(file);
3315       break;
3316 
3317     case TCODE_SETTINGS_ANALYSISMESH:
3318       rc = m_AnalysisMeshSettings.Read(file);
3319       break;
3320 
3321     case TCODE_SETTINGS_ANNOTATION:
3322       rc = m_AnnotationSettings.Read(file);
3323       break;
3324 
3325     case TCODE_SETTINGS_NAMED_CPLANE_LIST: // named cplanes
3326       {
3327         m_named_cplanes.Empty();
3328         ON__UINT32 subtcode = 0;
3329         ON__INT64 subvalue = 0;
3330         int count, i;
3331         rc = file.ReadInt(&count);
3332         for ( i = 0; i < count && rc ; i++ ) {
3333           rc = file.BeginRead3dmBigChunk( &subtcode, &subvalue );
3334           if (rc ) {
3335             if ( subtcode != TCODE_VIEW_CPLANE )
3336               rc = false;
3337             else {
3338               ON_3dmConstructionPlane& cplane = m_named_cplanes.AppendNew();
3339               rc = cplane.Read(file);
3340             }
3341             if ( !file.EndRead3dmChunk() ) {
3342               rc = false;
3343             }
3344           }
3345         }
3346       }
3347       break;
3348 
3349     case TCODE_SETTINGS_NAMED_VIEW_LIST: // named views
3350       {
3351         m_named_views.Empty();
3352         ON__UINT32 subtcode = 0;
3353         ON__INT64 subvalue = 0;
3354         int count, i;
3355         rc = file.ReadInt(&count);
3356         for ( i = 0; i < count && rc ; i++ )
3357         {
3358           rc = file.BeginRead3dmBigChunk( &subtcode, &subvalue );
3359           if (rc )
3360           {
3361             if ( subtcode != TCODE_VIEW_RECORD )
3362               rc = false;
3363             else
3364             {
3365               ON_3dmView& cplane = m_named_views.AppendNew();
3366               rc = cplane.Read(file);
3367             }
3368             if ( !file.EndRead3dmChunk() )
3369             {
3370               rc = false;
3371             }
3372           }
3373         }
3374       }
3375       break;
3376 
3377     case TCODE_SETTINGS_VIEW_LIST: // active view is first in list
3378       {
3379         m_views.Empty();
3380         ON__UINT32 subtcode = 0;
3381         ON__INT64 subvalue = 0;
3382         int count, i;
3383         rc = file.ReadInt(&count);
3384         m_views.Reserve(count);
3385         for ( i = 0; i < count && rc ; i++ )
3386         {
3387           rc = file.BeginRead3dmBigChunk( &subtcode, &subvalue );
3388           if (rc )
3389           {
3390             if ( subtcode != TCODE_VIEW_RECORD )
3391               rc = false;
3392             else
3393             {
3394               ON_3dmView& view = m_views.AppendNew();
3395               rc = view.Read(file);
3396             }
3397             if ( !file.EndRead3dmChunk() )
3398             {
3399               rc = false;
3400             }
3401           }
3402         }
3403       }
3404       break;
3405 
3406     case TCODE_SETTINGS__NEVER__USE__THIS:
3407       {
3408         if ( 28 == big_value )
3409         {
3410           // 23 March 2005 Dale Lear - this was the ON_LineStyle
3411           //                           and a linesytlesource int
3412           //                           that never got used.
3413           unsigned char b[24];
3414           if (rc) rc = file.ReadByte(24,b);
3415           // The other 4 bytes are a 32 bit chunk crc
3416           // that gets read by EndRead3dmChunk()
3417         }
3418       }
3419       break;
3420 
3421     case TCODE_SETTINGS_CURRENT_LAYER_INDEX:
3422       if ( big_value < -1 || big_value > 0x7FFFFFFF )
3423       {
3424         ON_ERROR("ON_3dmSettings::Read_v2() - TCODE_SETTINGS_CURRENT_LAYER_INDEX - invalid layer index value");
3425       }
3426       else
3427       {
3428         m_current_layer_index = (int)big_value;
3429       }
3430       break;
3431 
3432     case TCODE_SETTINGS_CURRENT_FONT_INDEX:
3433       if ( big_value < -1 || big_value > 0x7FFFFFFF )
3434       {
3435         ON_ERROR("ON_3dmSettings::Read_v2() - TCODE_SETTINGS_CURRENT_FONT_INDEX - invalid font index value");
3436       }
3437       else
3438       {
3439         // in archives with opennurbs version >= 200106100
3440         m_current_font_index = (int)big_value;
3441       }
3442       break;
3443 
3444     case TCODE_SETTINGS_CURRENT_DIMSTYLE_INDEX:
3445       if ( big_value < -1 || big_value > 0x7FFFFFFF )
3446       {
3447         ON_ERROR("ON_3dmSettings::Read_v2() - TCODE_SETTINGS_CURRENT_DIMSTYLE_INDEX - invalid dimstyle index value");
3448       }
3449       else
3450       {
3451         // in archives with opennurbs version >= 200106100
3452         m_current_dimstyle_index = (int)big_value;
3453       }
3454       break;
3455 
3456     case TCODE_SETTINGS_CURRENT_MATERIAL_INDEX:
3457       {
3458         int i32 = 0;
3459         if (rc) rc = file.ReadInt( &m_current_material_index );
3460         if (rc) rc = file.ReadInt( &i32 );
3461         if (rc) m_current_material_source = ON::ObjectMaterialSource(i32);
3462       }
3463       break;
3464 
3465     case TCODE_SETTINGS_CURRENT_COLOR:
3466       {
3467         int i32 = 0;
3468         if (rc) rc = file.ReadColor( m_current_color );
3469         if (rc) rc = file.ReadInt( &i32 );
3470         if (rc) m_current_color_source = ON::ObjectColorSource(i32);
3471       }
3472       break;
3473 
3474     case TCODE_SETTINGS_CURRENT_WIRE_DENSITY:
3475       if ( big_value < -2 || big_value > 0x7FFFFFFF )
3476       {
3477         ON_ERROR("ON_3dmSettings::Read_v2() - TCODE_SETTINGS_CURRENT_WIRE_DENSITY - invalid current_wire_density value");
3478       }
3479       else
3480       {
3481         m_current_wire_density = (int)big_value;
3482       }
3483       break;
3484 
3485     case TCODE_SETTINGS_RENDER:
3486       rc = m_RenderSettings.Read(file);
3487       break;
3488 
3489     case TCODE_SETTINGS_GRID_DEFAULTS:
3490       rc = m_GridDefaults.Read(file);
3491       break;
3492 
3493     case TCODE_SETTINGS_MODEL_URL: // added 21 June 2001
3494       rc = file.ReadString(m_model_URL);
3495       break;
3496 
3497     case TCODE_SETTINGS_ATTRIBUTES:
3498       {
3499         int major_version = 0;
3500         int minor_version = 0;
3501         for(;;)
3502         {
3503           rc = file.Read3dmChunkVersion(&major_version,&minor_version);
3504           if (!rc) break;
3505           if ( 1 == major_version )
3506           {
3507             // version 1.0 fields 23 March 2005
3508             rc = file.ReadDouble( &m_linetype_display_scale );
3509             if (!rc) break;
3510 
3511             rc = file.ReadColor(m_current_plot_color);
3512             if (!rc) break;
3513 
3514             int i;
3515             rc = file.ReadInt(&i);
3516             if (!rc) break;
3517             m_current_plot_color_source = ON::PlotColorSource(i);
3518 
3519             rc = file.ReadInt(&m_current_linetype_index);
3520             if (!rc) break;
3521 
3522             rc = file.ReadInt(&i);
3523             if (!rc) break;
3524             m_current_linetype_source = ON::ObjectLinetypeSource(i);
3525 
3526             if ( minor_version >= 1 )
3527             {
3528               // Added 6 Feb 2006
3529               int mjv = 1, mnv = 1;
3530               rc = file.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&mjv,&mnv);
3531               if (rc)
3532               {
3533                 rc = m_PageUnitsAndTolerances.Read(file);
3534                 if ( !file.EndRead3dmChunk() )
3535                   rc = false;
3536               }
3537 
3538 
3539               if ( minor_version >= 2 )
3540               {
3541                 // 1 Mar 2006 1.2 fields
3542                 rc = file.ReadUuid(m_active_view_id);
3543                 if (!rc) break;
3544 
3545                 if ( minor_version >= 3 )
3546                 {
3547                   rc = file.ReadPoint( m_model_basepoint);
3548                   if (!rc) break;
3549                   rc = m_earth_anchor_point.Read(file);
3550                   if (!rc) break;
3551 
3552                   if ( minor_version >= 4 )
3553                   {
3554                     rc = file.ReadBool(&m_IO_settings.m_bSaveTextureBitmapsInFile);
3555                     if (rc && minor_version >= 5)
3556                     {
3557                       rc = m_IO_settings.Read(file);
3558                       if (rc && minor_version >= 6 )
3559                       {
3560                         // 7 June 2006
3561                         m_CustomRenderMeshSettings.Read(file);
3562                       }
3563                     }
3564                   }
3565                 }
3566               }
3567             }
3568 
3569           }
3570 
3571           break;
3572         }
3573       }
3574       break;
3575 
3576     default:
3577       // information added in future will be skipped by file.EndRead3dmChunk()
3578       break;
3579     }
3580 
3581     if ( !file.EndRead3dmChunk() )
3582       rc = false;
3583     if ( TCODE_ENDOFTABLE == tcode )
3584       break;
3585   }
3586 
3587   return rc;
3588 }
3589 
Read(ON_BinaryArchive & file)3590 bool ON_3dmSettings::Read(ON_BinaryArchive& file )
3591 {
3592   bool rc = false;
3593 
3594   Default();
3595 
3596   if ( 1 == file.Archive3dmVersion() )
3597   {
3598     rc = Read_v1(file);
3599   }
3600   else
3601   {
3602     rc = Read_v2(file);
3603   }
3604 
3605   return rc;
3606 }
3607 
3608 
ON_3dmSettings_Write_v1_TCODE_UNIT_AND_TOLERANCES(ON_BinaryArchive & file,const ON_3dmUnitsAndTolerances & UnitsAndTolerances)3609 static bool ON_3dmSettings_Write_v1_TCODE_UNIT_AND_TOLERANCES(ON_BinaryArchive& file, const ON_3dmUnitsAndTolerances& UnitsAndTolerances )
3610 {
3611   bool rc = true;
3612   int v = 1, us = 0;
3613   if (rc) rc = file.WriteInt( v ); // v = 1
3614   switch (UnitsAndTolerances.m_unit_system.m_unit_system)
3615   {
3616   case ON::no_unit_system:
3617     us=0; // NO_UNIT_SYSTEM
3618     break;
3619   case ON::microns:
3620     us=1; // MICRONS
3621     break;
3622   case ON::millimeters:
3623     us=2; // MILLIMETERS
3624     break;
3625   case ON::centimeters:
3626     us=3; // CENTIMETERS
3627     break;
3628   case ON::meters:
3629     us=4; // METERS
3630     break;
3631   case ON::kilometers:
3632     us=5; // KILOMETERS
3633     break;
3634   case ON::microinches:
3635     us=6; // MICROINCHES
3636     break;
3637   case ON::mils:
3638     us=7; // MILS
3639     break;
3640   case ON::inches:
3641     us=8; // INCHES
3642     break;
3643   case ON::feet:
3644     us=9; // FEET
3645     break;
3646   case ON::miles:
3647     us=10; // MILES
3648     break;
3649   default:
3650     us=0; // NO_UNIT_SYSTEM
3651     break;
3652   }
3653   if (rc) rc = file.WriteInt( us );
3654   if (rc) rc = file.WriteDouble( UnitsAndTolerances.m_absolute_tolerance );
3655   if (rc) rc = file.WriteDouble( UnitsAndTolerances.m_relative_tolerance );
3656   if (rc) rc = file.WriteDouble( UnitsAndTolerances.m_angle_tolerance );
3657 
3658   return rc;
3659 }
3660 
Write_v1(ON_BinaryArchive & file) const3661 bool ON_3dmSettings::Write_v1(ON_BinaryArchive& file) const
3662 {
3663   bool rc = true;
3664 
3665   // version 1 units and tolerances chunk
3666   rc = file.BeginWrite3dmChunk(TCODE_UNIT_AND_TOLERANCES,0);
3667   if (rc) {
3668     rc = ON_3dmSettings_Write_v1_TCODE_UNIT_AND_TOLERANCES( file, m_ModelUnitsAndTolerances );
3669     if (!file.EndWrite3dmChunk())
3670       rc = false;
3671   }
3672 
3673   return rc;
3674 }
3675 
Write_v2(ON_BinaryArchive & file) const3676 bool ON_3dmSettings::Write_v2(ON_BinaryArchive& file) const
3677 {
3678   int i;
3679   bool rc = true;
3680 
3681   // TCODE_SETTINGS_PLUGINLIST - plugins that may have saved userdata in the file
3682   if (rc && file.Archive3dmVersion() >= 4 && m_plugin_list.Count() > 0 )
3683   {
3684     // The plug-in list chunk needs to be first, so the plug-ins that save
3685     // userdata on views can be loaded as needed.
3686     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_PLUGINLIST,0);
3687     if ( rc )
3688     {
3689       if (rc) rc = file.Write3dmChunkVersion(1,0);
3690       if (rc) rc = file.WriteInt( m_plugin_list.Count() );
3691       for ( i = 0; rc && i < m_plugin_list.Count(); i++ )
3692       {
3693         rc = m_plugin_list[i].Write(file);
3694       }
3695 
3696       if ( !file.EndWrite3dmChunk() )
3697         rc = false;
3698     }
3699   }
3700 
3701   // TCODE_PROPERTIES_UNITSANDTOLS - units and tolerances
3702   if ( rc  ) {
3703     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_UNITSANDTOLS,0);
3704     if ( rc ) {
3705       rc = m_ModelUnitsAndTolerances.Write(file);
3706       if ( !file.EndWrite3dmChunk() )
3707         rc = false;
3708     }
3709   }
3710 
3711   // TCODE_SETTINGS_RENDERMESH - rendering defaults
3712   if ( rc  ) {
3713     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_RENDERMESH,0);
3714     if ( rc ) {
3715       rc = m_RenderMeshSettings.Write(file);
3716       if ( !file.EndWrite3dmChunk() )
3717         rc = false;
3718     }
3719   }
3720 
3721   // TCODE_SETTINGS_ANALYSISMESH - analysis mesh defaults
3722   if ( rc  ) {
3723     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_ANALYSISMESH,0);
3724     if ( rc ) {
3725       rc = m_AnalysisMeshSettings.Write(file);
3726       if ( !file.EndWrite3dmChunk() )
3727         rc = false;
3728     }
3729   }
3730 
3731   // TCODE_SETTINGS_ANNOTATION - annotation settings
3732   if ( rc  ) {
3733     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_ANNOTATION,0);
3734     if ( rc ) {
3735       rc = m_AnnotationSettings.Write(file);
3736       if ( !file.EndWrite3dmChunk() )
3737         rc = false;
3738     }
3739   }
3740 
3741   // TCODE_SETTINGS_NAMED_CPLANE_LIST
3742   if ( rc  ) {
3743     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_NAMED_CPLANE_LIST,0);
3744     if ( rc ) {
3745       const int count = m_named_cplanes.Count();
3746       rc = file.WriteInt(count);
3747       for ( i = 0; i < count && rc; i++ ) {
3748         rc = file.BeginWrite3dmChunk( TCODE_VIEW_CPLANE, 0 );
3749         if (rc ) {
3750           rc = m_named_cplanes[i].Write(file);
3751           if ( !file.EndWrite3dmChunk() )
3752             rc = false;
3753         }
3754       }
3755       if ( !file.EndWrite3dmChunk() )
3756         rc = false;
3757     }
3758   }
3759 
3760   // TCODE_SETTINGS_NAMED_VIEW_LIST
3761   if ( rc  ) {
3762     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_NAMED_VIEW_LIST,0);
3763     if ( rc ) {
3764       const int count = m_named_views.Count();
3765       rc = file.WriteInt(count);
3766       for ( i = 0; i < count && rc; i++ ) {
3767         rc = file.BeginWrite3dmChunk( TCODE_VIEW_RECORD, 0 );
3768         if (rc ) {
3769           rc = m_named_views[i].Write(file);
3770           if ( !file.EndWrite3dmChunk() )
3771             rc = false;
3772         }
3773       }
3774       if ( !file.EndWrite3dmChunk() )
3775         rc = false;
3776     }
3777   }
3778 
3779   // TCODE_SETTINGS_VIEW_LIST
3780   if ( rc  ) {
3781     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_VIEW_LIST,0);
3782     if ( rc ) {
3783       const int count = m_views.Count();
3784       rc = file.WriteInt(count);
3785       for ( i = 0; i < count && rc; i++ ) {
3786         rc = file.BeginWrite3dmChunk( TCODE_VIEW_RECORD, 0 );
3787         if (rc ) {
3788           rc = m_views[i].Write(file);
3789           if ( !file.EndWrite3dmChunk() )
3790             rc = false;
3791         }
3792       }
3793       if ( !file.EndWrite3dmChunk() )
3794         rc = false;
3795     }
3796   }
3797 
3798   // TCODE_SETTINGS_CURRENT_LAYER_INDEX
3799   if (rc) {
3800     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_LAYER_INDEX, m_current_layer_index );
3801     if ( !file.EndWrite3dmChunk() )
3802       rc = false;
3803   }
3804 
3805   // TCODE_SETTINGS_CURRENT_MATERIAL_INDEX
3806   if (rc) {
3807     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_MATERIAL_INDEX, 0 );
3808     if (rc) {
3809       rc = file.WriteInt( m_current_material_index );
3810       i = m_current_material_source;
3811       if (rc) rc = file.WriteInt( i );
3812       if ( !file.EndWrite3dmChunk() )
3813         rc = false;
3814     }
3815   }
3816 
3817   // TCODE_SETTINGS_CURRENT_COLOR
3818   if (rc) {
3819     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_COLOR, 0 );
3820     if (rc) {
3821       rc = file.WriteColor( m_current_color );
3822       i = m_current_color_source;
3823       if (rc) rc = file.WriteInt( i );
3824       if ( !file.EndWrite3dmChunk() )
3825         rc = false;
3826     }
3827   }
3828 
3829 
3830   // TCODE_SETTINGS_CURRENT_WIRE_DENSITY
3831   if (rc) {
3832     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_WIRE_DENSITY, m_current_wire_density );
3833     if (rc) {
3834       if ( !file.EndWrite3dmChunk() )
3835         rc = false;
3836     }
3837   }
3838 
3839   // TCODE_SETTINGS_RENDER
3840   if (rc) {
3841     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_RENDER, 0 );
3842     if (rc) {
3843       rc = m_RenderSettings.Write(file);
3844       if ( !file.EndWrite3dmChunk() )
3845         rc = false;
3846     }
3847   }
3848 
3849   // TCODE_SETTINGS_GRID_DEFAULTS
3850   if (rc) {
3851     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_GRID_DEFAULTS, 0 );
3852     if (rc) {
3853       rc = m_GridDefaults.Write(file);
3854       if ( !file.EndWrite3dmChunk() )
3855         rc = false;
3856     }
3857   }
3858 
3859   // TCODE_SETTINGS_MODEL_URL - added 21 June 2001
3860   if (rc && m_model_URL.Length() > 0 ) {
3861     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_MODEL_URL, 0 );
3862     if (rc) {
3863       rc = file.WriteString(m_model_URL);
3864       if ( !file.EndWrite3dmChunk() )
3865         rc = false;
3866     }
3867   }
3868 
3869   // TCODE_SETTINGS_CURRENT_FONT_INDEX - added 10 June 2002
3870   if (rc) {
3871     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_FONT_INDEX, m_current_font_index );
3872     if ( !file.EndWrite3dmChunk() )
3873       rc = false;
3874   }
3875 
3876   // TCODE_SETTINGS_CURRENT_DIMSTYLE_INDEX - added 10 June 2002
3877   if (rc) {
3878     rc = file.BeginWrite3dmChunk( TCODE_SETTINGS_CURRENT_DIMSTYLE_INDEX, m_current_dimstyle_index );
3879     if ( !file.EndWrite3dmChunk() )
3880       rc = false;
3881   }
3882 
3883   // TCODE_SETTINGS_ATTRIBUTES
3884   if (rc && file.Archive3dmVersion() >= 4 )
3885   {
3886     // 23 March 2005 Dale Lear
3887     rc = file.BeginWrite3dmChunk(TCODE_SETTINGS_ATTRIBUTES, 0 );
3888     if (rc)
3889     {
3890       for(;;)
3891       {
3892         // 1.0 - 23 March 2005
3893         // 1.1 -  6 Feb   2006
3894         // 1.2 -  1 March 2006
3895         // 1.3 - 29 March 2006
3896         // 1.4 - 18 April 2006
3897         // 1.5 - 21 April 2006
3898         // 1.6 -  7 June  2006
3899         rc = file.Write3dmChunkVersion(1,6);
3900 
3901         // version 1.0 fields
3902         rc = file.WriteDouble( m_linetype_display_scale );
3903         if (!rc) break;
3904 
3905         rc = file.WriteColor(m_current_plot_color);
3906         if (!rc) break;
3907 
3908         rc = file.WriteInt(m_current_plot_color_source);
3909         if (!rc) break;
3910 
3911         rc = file.WriteInt(m_current_linetype_index);
3912         if (!rc) break;
3913 
3914         rc = file.WriteInt(m_current_linetype_source);
3915         if (!rc) break;
3916 
3917         // 6 Feb 2006, 1.1 fields
3918 
3919         // the units and tols has to be inside a chunk
3920         rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
3921         if (rc)
3922         {
3923           rc = m_PageUnitsAndTolerances.Write(file);
3924           if ( !file.EndWrite3dmChunk() )
3925             rc = false;
3926         }
3927         if (!rc) break;
3928 
3929         // 1 Mar 2006 1.2 fields
3930         rc = file.WriteUuid(m_active_view_id);
3931         if (!rc) break;
3932 
3933         // 29 March 2006 1.3 fields
3934         rc = file.WritePoint( m_model_basepoint);
3935         if (!rc) break;
3936         rc = m_earth_anchor_point.Write(file);
3937         if (!rc) break;
3938 
3939         // 18 April 2006 1.4 fields
3940         rc = file.WriteBool(m_IO_settings.m_bSaveTextureBitmapsInFile);
3941         if (!rc) break;
3942 
3943         // 21 April 2006 1.5 fields
3944         rc = m_IO_settings.Write(file);
3945         if (!rc) break;
3946 
3947         // 7 June 2006 1.6 fields
3948         rc = m_CustomRenderMeshSettings.Write(file);
3949         if (!rc) break;
3950 
3951         break;
3952       }
3953 
3954       if ( !file.EndWrite3dmChunk() )
3955         rc = false;
3956     }
3957   }
3958 
3959   // required TCODE_ENDOFTABLE chunk - marks end of settings table
3960   if ( rc ) {
3961     rc = file.BeginWrite3dmChunk( TCODE_ENDOFTABLE, 0 );
3962     if ( rc ) {
3963       if ( !file.EndWrite3dmChunk() )
3964         rc = false;
3965     }
3966   }
3967 
3968 
3969   return rc;
3970 }
3971 
Write(ON_BinaryArchive & file) const3972 bool ON_3dmSettings::Write(ON_BinaryArchive& file) const
3973 {
3974   bool rc = false;
3975   if ( 1 == file.Archive3dmVersion() )
3976   {
3977     rc = Write_v1(file);
3978   }
3979   else
3980   {
3981     rc = Write_v2(file);
3982   }
3983   return rc;
3984 }
3985 
Dump(ON_TextLog & dump) const3986 void ON_3dmSettings::Dump( ON_TextLog& dump ) const
3987 {
3988   int i;
3989 
3990   const wchar_t* model_URL = m_model_URL;
3991   if ( model_URL && *model_URL )
3992   {
3993     dump.Print("Model URL: %ls\n",model_URL);
3994   }
3995   dump.Print("Model space units and tolerances:\n");
3996   dump.PushIndent();
3997   m_ModelUnitsAndTolerances.Dump(dump);
3998   dump.PopIndent();
3999 
4000   dump.Print("Page space units and tolerances:\n");
4001   dump.PushIndent();
4002   m_PageUnitsAndTolerances.Dump(dump);
4003   dump.PopIndent();
4004 
4005   dump.Print("Render mesh settings:\n");
4006   dump.PushIndent();
4007   m_RenderMeshSettings.Dump(dump);
4008   dump.PopIndent();
4009 
4010   dump.Print("Analysis mesh settings:\n");
4011   dump.PushIndent();
4012   m_AnalysisMeshSettings.Dump(dump);
4013   dump.PopIndent();
4014 
4015   dump.Print("Render settings:\n");
4016   dump.PushIndent();
4017   m_RenderSettings.Dump(dump);
4018   dump.PopIndent();
4019 
4020   dump.Print("Annotation settings:\n");
4021   dump.PushIndent();
4022   m_AnnotationSettings.Dump(dump);
4023   dump.PopIndent();
4024 
4025   dump.Print("Construction plane grid defaults:\n");
4026   dump.PushIndent();
4027   m_GridDefaults.Dump(dump);
4028   dump.PopIndent();
4029 
4030   dump.Print("Named construction planes:\n");
4031   dump.PushIndent();
4032   for ( i = 0; i < m_named_cplanes.Count(); i++ )
4033   {
4034     dump.Print("named construction plane %d:\n");
4035     dump.PushIndent();
4036     m_named_cplanes[i].Dump(dump);
4037     dump.PopIndent();
4038   }
4039   dump.PopIndent();
4040 
4041   dump.Print("Named views:\n");
4042   dump.PushIndent();
4043   for ( i = 0; i < m_named_views.Count(); i++ )
4044   {
4045     dump.Print("named view %d:\n",i);
4046     dump.PushIndent();
4047     m_named_views[i].Dump(dump);
4048     dump.PopIndent();
4049   }
4050   dump.PopIndent();
4051 
4052   dump.Print("Model views:\n");
4053   dump.PushIndent();
4054   for ( i = 0; i < m_views.Count(); i++ )
4055   {
4056     dump.Print("model view %d:\n",i);
4057     dump.PushIndent();
4058     m_views[i].Dump(dump);
4059     dump.PopIndent();
4060   }
4061   dump.PopIndent();
4062 
4063   dump.Print("New object attributes:\n");
4064   dump.PushIndent();
4065   {
4066     dump.Print("Current display color rgb");dump.PrintRGB(m_current_color); dump.Print(":\n");
4067     dump.Print("Current display color source = %d\n",m_current_color_source);
4068     dump.Print("Current plot color rgb");dump.PrintRGB(m_current_plot_color); dump.Print(":\n");
4069     dump.Print("Current plot color source = %d\n",m_current_plot_color_source);
4070     dump.Print("Current material index = %d\n",m_current_material_index);
4071     dump.Print("Current material source = %d\n",m_current_material_source);
4072     dump.Print("Current linetype index = %d\n",m_current_linetype_index);
4073     dump.Print("Current linetype source = %d\n",m_current_linetype_source);
4074     dump.Print("Current layer index = %d\n",m_current_layer_index);
4075     dump.Print("Current font index = %d\n",m_current_font_index);
4076     dump.Print("Current dimstyle index = %d\n",m_current_dimstyle_index);
4077     dump.Print("Current wire density = %d\n",m_current_wire_density);
4078     dump.Print("Linetype diaplay scale = %g\n",m_linetype_display_scale);
4079   }
4080   dump.PopIndent();
4081 
4082   dump.Print("Plug-in list\n");
4083   dump.PushIndent();
4084   for ( i = 0; i < m_plugin_list.Count(); i++ )
4085   {
4086     dump.Print("plug-in %d:\n",i);
4087     dump.PushIndent();
4088     m_plugin_list[i].Dump(dump);
4089     dump.PopIndent();
4090   }
4091   dump.PopIndent();
4092 
4093 }
4094 
4095