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 
ON_IsHairlinePrintWidth(double width_mm)19 bool ON_IsHairlinePrintWidth(double width_mm)
20 {
21   if(width_mm > 0.0 && width_mm < 0.001)
22     return true;
23 
24   return false;
25 }
26 
ON_HairlinePrintWidth()27 double ON_HairlinePrintWidth()
28 {
29   return 0.0001;
30 }
31 
32 
33 //////////////////////////////////////////////////////////////////////
34 // class ON_LinetypeSegment
operator ==(const ON_LinetypeSegment & src) const35 bool ON_LinetypeSegment::operator==( const ON_LinetypeSegment& src) const
36 {
37   return ( m_length == src.m_length && m_seg_type == src.m_seg_type);
38 }
39 
operator !=(const ON_LinetypeSegment & src) const40 bool ON_LinetypeSegment::operator!=( const ON_LinetypeSegment& src) const
41 {
42   return ( m_length != src.m_length || m_seg_type != src.m_seg_type);
43 }
44 
45 
Dump(ON_TextLog & dump) const46 void ON_LinetypeSegment::Dump( ON_TextLog& dump) const
47 {
48   switch( m_seg_type)
49   {
50   case stLine:
51     dump.Print( "Segment type = Line: %g\n", m_length);
52     break;
53   case stSpace:
54     dump.Print( "Segment type = Space: %g\n", m_length);
55     break;
56   }
57 }
58 
ON_LinetypeSegment()59 ON_LinetypeSegment::ON_LinetypeSegment()
60 {
61   memset(this,0,sizeof(*this));
62   m_length = 1.0;
63   m_seg_type = stLine;
64 }
65 
66 //////////////////////////////////////////////////////////////////////
67 // class ON_Linetype
68 
69 ON_OBJECT_IMPLEMENT( ON_Linetype, ON_Object, "26F10A24-7D13-4f05-8FDA-8E364DAF8EA6" );
70 
ON_Linetype()71 ON_Linetype::ON_Linetype() : m_linetype_index(-1)
72 {
73   memset(&m_linetype_id,0,sizeof(m_linetype_id));
74 }
75 
~ON_Linetype()76 ON_Linetype::~ON_Linetype()
77 {
78   m_linetype_name.Destroy();
79 }
80 
Default()81 void ON_Linetype::Default()
82 {
83   m_linetype_index = -1;
84   memset(&m_linetype_id,0,sizeof(m_linetype_id));
85   m_linetype_name.Destroy();
86   m_segments.Destroy();
87 }
88 
IsValid(ON_TextLog * text_log) const89 ON_BOOL32 ON_Linetype::IsValid( ON_TextLog* text_log ) const
90 {
91   int i, count = m_segments.Count();
92 
93   // An ON_Linetype with an empty name is valid.
94 
95   if ( count < 1 )
96   {
97     if ( text_log )
98       text_log->Print("ON_Linetype m_segments.Count() = 0\n");
99     return false;
100   }
101 
102   if ( 1 == count )
103   {
104     if ( m_segments[0].m_length <= 0.0  )
105     {
106       if ( text_log )
107         text_log->Print("ON_Linetype bogus single segment linetype - length <= 0.0 (it must be > 0)\n");
108       return false;
109     }
110 
111     if ( ON_LinetypeSegment::stLine != m_segments[0].m_seg_type )
112     {
113       if ( text_log )
114         text_log->Print("ON_Linetype bogus single segment linetype - type != stLine\n");
115       return false;
116     }
117   }
118   else
119   {
120     for (i = 0; i < count; i++ )
121     {
122       if ( m_segments[i].m_length < 0.0 )
123       {
124         if ( text_log )
125           text_log->Print("ON_Linetype segment has negative length.\n");
126         return false;
127       }
128 
129       if ( ON_LinetypeSegment::stLine != m_segments[i].m_seg_type && ON_LinetypeSegment::stSpace != m_segments[i].m_seg_type )
130       {
131         if ( text_log )
132           text_log->Print("ON_Linetype segment has invalid m_seg_type.\n");
133         return false;
134       }
135 
136       if ( i )
137       {
138         if ( m_segments[i].m_seg_type == m_segments[i-1].m_seg_type )
139         {
140           if ( text_log )
141             text_log->Print("ON_Linetype consecutive segments have same type.\n");
142           return false;
143         }
144 
145         if ( 0.0 == m_segments[i].m_length && 0.0 == m_segments[i-1].m_length )
146         {
147           if ( text_log )
148             text_log->Print("ON_Linetype consecutive segments have length zero.\n");
149           return false;
150         }
151       }
152     }
153   }
154 
155   return true;
156 }
157 
Dump(ON_TextLog & dump) const158 void ON_Linetype::Dump( ON_TextLog& dump ) const
159 {
160   const wchar_t* sName = LinetypeName();
161   if ( !sName )
162     sName = L"";
163   dump.Print( "Segment count = %d\n", m_segments.Count());
164   dump.Print( "Pattern length = %g\n", PatternLength());
165   dump.Print( "Pattern = (" );
166   for( int i = 0; i < m_segments.Count(); i++)
167   {
168     const ON_LinetypeSegment& seg = m_segments[i];
169     if ( i )
170       dump.Print(",");
171     switch( seg.m_seg_type)
172     {
173     case ON_LinetypeSegment::stLine:
174       dump.Print( "line");
175       break;
176     case ON_LinetypeSegment::stSpace:
177       dump.Print( "space");
178       break;
179     default:
180       dump.Print( "invalid");
181       break;
182     }
183   }
184   dump.Print(")\n");
185 }
186 
Write(ON_BinaryArchive & file) const187 ON_BOOL32 ON_Linetype::Write( ON_BinaryArchive& file) const
188 {
189   bool rc = file.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,1);
190   if (rc)
191   {
192     for(;;)
193     {
194       // chunk version 1.0 fields
195       rc = file.WriteInt( LinetypeIndex());
196       if(!rc) break;
197 
198       rc = file.WriteString( m_linetype_name );
199       if (!rc) break;
200 
201       rc = file.WriteArray( m_segments );
202       if(!rc) break;
203 
204       // chunk version 1.1 fields
205       rc = file.WriteUuid( m_linetype_id );
206       if (!rc) break;
207 
208       break;
209     }
210 
211     if ( !file.EndWrite3dmChunk() )
212       rc = false;
213   }
214   return rc;
215 }
216 
Read(ON_BinaryArchive & file)217 ON_BOOL32 ON_Linetype::Read( ON_BinaryArchive& file)
218 {
219   Default();
220   m_linetype_index = -1;
221 
222   int major_version=0;
223   int minor_version=0;
224   bool rc = file.BeginRead3dmChunk( TCODE_ANONYMOUS_CHUNK, &major_version, &minor_version );
225 
226   if (rc)
227   {
228     if( 1 == major_version )
229     {
230       // chunk version 1.0 fields
231       if( rc)
232         rc = file.ReadInt( &m_linetype_index );
233       if( rc)
234         rc = file.ReadString( m_linetype_name );
235       if( rc)
236         rc = file.ReadArray( m_segments );
237 
238       if ( minor_version >= 1 )
239       {
240         if (rc)
241           rc = file.ReadUuid( m_linetype_id );
242       }
243     }
244     else
245     {
246       rc = false;
247     }
248 
249     if ( !file.EndRead3dmChunk() )
250       rc = false;
251   }
252 
253   return rc;
254 }
255 
SetLinetypeName(const char * s)256 bool ON_Linetype::SetLinetypeName( const char* s)
257 {
258   m_linetype_name = s;
259   return IsValid()?true:false;
260 }
261 
SetLinetypeName(const wchar_t * s)262 bool ON_Linetype::SetLinetypeName( const wchar_t* s)
263 {
264   m_linetype_name = s;
265   return IsValid()?true:false;
266 }
267 
LinetypeName() const268 const wchar_t* ON_Linetype::LinetypeName() const
269 {
270   const wchar_t* s = m_linetype_name;
271   return s;
272 }
273 
SetLinetypeIndex(int i)274 bool ON_Linetype::SetLinetypeIndex( int i)
275 {
276   m_linetype_index = i;
277   return true;
278 }
279 
LinetypeIndex() const280 int ON_Linetype::LinetypeIndex() const
281 {
282   return m_linetype_index;
283 }
284 
PatternLength() const285 double ON_Linetype::PatternLength() const
286 {
287   double length = 0.0;
288   int seg_count = m_segments.Count();
289   for( int i = 0; i < seg_count; i++)
290   {
291     length += m_segments[i].m_length;
292   }
293   return length;
294 }
295 
Segments()296 ON_SimpleArray<ON_LinetypeSegment>& ON_Linetype::Segments()
297 {
298   return m_segments;
299 }
300 
Segments() const301 const ON_SimpleArray<ON_LinetypeSegment>& ON_Linetype::Segments() const
302 {
303   return m_segments;
304 }
305 
SegmentCount() const306 int ON_Linetype::SegmentCount() const
307 {
308   return m_segments.Count();
309 }
310 
AppendSegment(const ON_LinetypeSegment & segment)311 int ON_Linetype::AppendSegment( const ON_LinetypeSegment& segment)
312 {
313   m_segments.Append( segment);
314   return( m_segments.Count()-1);
315 }
316 
RemoveSegment(int index)317 bool ON_Linetype::RemoveSegment( int index )
318 {
319   bool rc = ( index >= 0 && index < m_segments.Count());
320   if (rc)
321     m_segments.Remove(index);
322   return rc;
323 }
324 
SetSegment(int index,const ON_LinetypeSegment & segment)325 bool ON_Linetype::SetSegment( int index, const ON_LinetypeSegment& segment)
326 {
327   if( index >= 0 && index < m_segments.Count())
328   {
329     m_segments[index] = segment;
330     return true;
331   }
332   else
333     return false;
334 }
335 
SetSegment(int index,double length,ON_LinetypeSegment::eSegType type)336 bool ON_Linetype::SetSegment( int index, double length, ON_LinetypeSegment::eSegType type)
337 {
338   if( index >= 0 && index < m_segments.Count())
339   {
340     m_segments[index].m_length = length;
341     m_segments[index].m_seg_type = type;
342     return true;
343   }
344   else
345     return false;
346 }
347 
Segment(int index) const348 ON_LinetypeSegment ON_Linetype::Segment( int index) const
349 {
350   if( index >= 0 && index < m_segments.Count())
351     return m_segments[index];
352   else
353     return ON_LinetypeSegment();
354 }
355 
356 
357 
358 
359 
360 
361 
362