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