Panda3D
Loading...
Searching...
No Matches
dxfFile.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file dxfFile.cxx
10 * @author drose
11 * @date 2004-05-04
12 */
13
14#include "dxfFile.h"
15#include "string_utils.h"
16#include "virtualFileSystem.h"
17
18using std::istream;
19using std::ostream;
20using std::string;
21
22DXFFile::Color DXFFile::_colors[DXF_num_colors] = {
23 { 1, 1, 1 }, // Color 0 is not used.
24 { 1, 0, 0 }, // Color 1 = Red
25 { 1, 1, 0 }, // Color 2 = Yellow
26 { 0, 1, 0 }, // Color 3 = Green
27 { 0, 1, 1 }, // Color 4 = Cyan
28 { 0, 0, 1 }, // Color 5 = Blue
29 { 1, 0, 1 }, // Color 6 = Magenta
30 { 1, 1, 1 }, // Color 7 = Black/White
31 { 0.3, 0.3, 0.3 }, // Color 8 = Gray
32 { 0.7, 0.7, 0.7 }, // Color 9 = Gray
33 { 1, 0, 0 }, // Remaining colors are from the fancy palette.
34 { 1, 0.5, 0.5 },
35 { 0.65, 0, 0 },
36 { 0.65, 0.325, 0.325 },
37 { 0.5, 0, 0 },
38 { 0.5, 0.25, 0.25 },
39 { 0.3, 0, 0 },
40 { 0.3, 0.15, 0.15 },
41 { 0.15, 0, 0 },
42 { 0.15, 0.075, 0.075 },
43 { 1, 0.25, 0 },
44 { 1, 0.625, 0.5 },
45 { 0.65, 0.1625, 0 },
46 { 0.65, 0.4063, 0.325 },
47 { 0.5, 0.125, 0 },
48 { 0.5, 0.3125, 0.25 },
49 { 0.3, 0.075, 0 },
50 { 0.3, 0.1875, 0.15 },
51 { 0.15, 0.0375, 0 },
52 { 0.15, 0.0938, 0.075 },
53 { 1, 0.5, 0 },
54 { 1, 0.75, 0.5 },
55 { 0.65, 0.325, 0 },
56 { 0.65, 0.4875, 0.325 },
57 { 0.5, 0.25, 0 },
58 { 0.5, 0.375, 0.25 },
59 { 0.3, 0.15, 0 },
60 { 0.3, 0.225, 0.15 },
61 { 0.15, 0.075, 0 },
62 { 0.15, 0.1125, 0.075 },
63 { 1, 0.75, 0 },
64 { 1, 0.875, 0.5 },
65 { 0.65, 0.4875, 0 },
66 { 0.65, 0.5688, 0.325 },
67 { 0.5, 0.375, 0 },
68 { 0.5, 0.4375, 0.25 },
69 { 0.3, 0.225, 0 },
70 { 0.3, 0.2625, 0.15 },
71 { 0.15, 0.1125, 0 },
72 { 0.15, 0.1313, 0.075 },
73 { 1, 1, 0 },
74 { 1, 1, 0.5 },
75 { 0.65, 0.65, 0 },
76 { 0.65, 0.65, 0.325 },
77 { 0.5, 0.5, 0 },
78 { 0.5, 0.5, 0.25 },
79 { 0.3, 0.3, 0 },
80 { 0.3, 0.3, 0.15 },
81 { 0.15, 0.15, 0 },
82 { 0.15, 0.15, 0.075 },
83 { 0.75, 1, 0 },
84 { 0.875, 1, 0.5 },
85 { 0.4875, 0.65, 0 },
86 { 0.5688, 0.65, 0.325 },
87 { 0.375, 0.5, 0 },
88 { 0.4375, 0.5, 0.25 },
89 { 0.225, 0.3, 0 },
90 { 0.2625, 0.3, 0.15 },
91 { 0.1125, 0.15, 0 },
92 { 0.1313, 0.15, 0.075 },
93 { 0.5, 1, 0 },
94 { 0.75, 1, 0.5 },
95 { 0.325, 0.65, 0 },
96 { 0.4875, 0.65, 0.325 },
97 { 0.25, 0.5, 0 },
98 { 0.375, 0.5, 0.25 },
99 { 0.15, 0.3, 0 },
100 { 0.225, 0.3, 0.15 },
101 { 0.075, 0.15, 0 },
102 { 0.1125, 0.15, 0.075 },
103 { 0.25, 1, 0 },
104 { 0.625, 1, 0.5 },
105 { 0.1625, 0.65, 0 },
106 { 0.4063, 0.65, 0.325 },
107 { 0.125, 0.5, 0 },
108 { 0.3125, 0.5, 0.25 },
109 { 0.075, 0.3, 0 },
110 { 0.1875, 0.3, 0.15 },
111 { 0.0375, 0.15, 0 },
112 { 0.0938, 0.15, 0.075 },
113 { 0, 1, 0 },
114 { 0.5, 1, 0.5 },
115 { 0, 0.65, 0 },
116 { 0.325, 0.65, 0.325 },
117 { 0, 0.5, 0 },
118 { 0.25, 0.5, 0.25 },
119 { 0, 0.3, 0 },
120 { 0.15, 0.3, 0.15 },
121 { 0, 0.15, 0 },
122 { 0.075, 0.15, 0.075 },
123 { 0, 1, 0.25 },
124 { 0.5, 1, 0.625 },
125 { 0, 0.65, 0.1625 },
126 { 0.325, 0.65, 0.4063 },
127 { 0, 0.5, 0.125 },
128 { 0.25, 0.5, 0.3125 },
129 { 0, 0.3, 0.075 },
130 { 0.15, 0.3, 0.1875 },
131 { 0, 0.15, 0.0375 },
132 { 0.075, 0.15, 0.0938 },
133 { 0, 1, 0.5 },
134 { 0.5, 1, 0.75 },
135 { 0, 0.65, 0.325 },
136 { 0.325, 0.65, 0.4875 },
137 { 0, 0.5, 0.25 },
138 { 0.25, 0.5, 0.375 },
139 { 0, 0.3, 0.15 },
140 { 0.15, 0.3, 0.225 },
141 { 0, 0.15, 0.075 },
142 { 0.075, 0.15, 0.1125 },
143 { 0, 1, 0.75 },
144 { 0.5, 1, 0.875 },
145 { 0, 0.65, 0.4875 },
146 { 0.325, 0.65, 0.5688 },
147 { 0, 0.5, 0.375 },
148 { 0.25, 0.5, 0.4375 },
149 { 0, 0.3, 0.225 },
150 { 0.15, 0.3, 0.2625 },
151 { 0, 0.15, 0.1125 },
152 { 0.075, 0.15, 0.1313 },
153 { 0, 1, 1 },
154 { 0.5, 1, 1 },
155 { 0, 0.65, 0.65 },
156 { 0.325, 0.65, 0.65 },
157 { 0, 0.5, 0.5 },
158 { 0.25, 0.5, 0.5 },
159 { 0, 0.3, 0.3 },
160 { 0.15, 0.3, 0.3 },
161 { 0, 0.15, 0.15 },
162 { 0.075, 0.15, 0.15 },
163 { 0, 0.75, 1 },
164 { 0.5, 0.875, 1 },
165 { 0, 0.4875, 0.65 },
166 { 0.325, 0.5688, 0.65 },
167 { 0, 0.375, 0.5 },
168 { 0.25, 0.4375, 0.5 },
169 { 0, 0.225, 0.3 },
170 { 0.15, 0.2625, 0.3 },
171 { 0, 0.1125, 0.15 },
172 { 0.075, 0.1313, 0.15 },
173 { 0, 0.5, 1 },
174 { 0.5, 0.75, 1 },
175 { 0, 0.325, 0.65 },
176 { 0.325, 0.4875, 0.65 },
177 { 0, 0.25, 0.5 },
178 { 0.25, 0.375, 0.5 },
179 { 0, 0.15, 0.3 },
180 { 0.15, 0.225, 0.3 },
181 { 0, 0.075, 0.15 },
182 { 0.075, 0.1125, 0.15 },
183 { 0, 0.25, 1 },
184 { 0.5, 0.625, 1 },
185 { 0, 0.1625, 0.65 },
186 { 0.325, 0.4063, 0.65 },
187 { 0, 0.125, 0.5 },
188 { 0.25, 0.3125, 0.5 },
189 { 0, 0.075, 0.3 },
190 { 0.15, 0.1875, 0.3 },
191 { 0, 0.0375, 0.15 },
192 { 0.075, 0.0938, 0.15 },
193 { 0, 0, 1 },
194 { 0.5, 0.5, 1 },
195 { 0, 0, 0.65 },
196 { 0.325, 0.325, 0.65 },
197 { 0, 0, 0.5 },
198 { 0.25, 0.25, 0.5 },
199 { 0, 0, 0.3 },
200 { 0.15, 0.15, 0.3 },
201 { 0, 0, 0.15 },
202 { 0.075, 0.075, 0.15 },
203 { 0.25, 0, 1 },
204 { 0.625, 0.5, 1 },
205 { 0.1625, 0, 0.65 },
206 { 0.4063, 0.325, 0.65 },
207 { 0.125, 0, 0.5 },
208 { 0.3125, 0.25, 0.5 },
209 { 0.075, 0, 0.3 },
210 { 0.1875, 0.15, 0.3 },
211 { 0.0375, 0, 0.15 },
212 { 0.0938, 0.075, 0.15 },
213 { 0.5, 0, 1 },
214 { 0.75, 0.5, 1 },
215 { 0.325, 0, 0.65 },
216 { 0.4875, 0.325, 0.65 },
217 { 0.25, 0, 0.5 },
218 { 0.375, 0.25, 0.5 },
219 { 0.15, 0, 0.3 },
220 { 0.225, 0.15, 0.3 },
221 { 0.075, 0, 0.15 },
222 { 0.1125, 0.075, 0.15 },
223 { 0.75, 0, 1 },
224 { 0.875, 0.5, 1 },
225 { 0.4875, 0, 0.65 },
226 { 0.5688, 0.325, 0.65 },
227 { 0.375, 0, 0.5 },
228 { 0.4375, 0.25, 0.5 },
229 { 0.225, 0, 0.3 },
230 { 0.2625, 0.15, 0.3 },
231 { 0.1125, 0, 0.15 },
232 { 0.1313, 0.075, 0.15 },
233 { 1, 0, 1 },
234 { 1, 0.5, 1 },
235 { 0.65, 0, 0.65 },
236 { 0.65, 0.325, 0.65 },
237 { 0.5, 0, 0.5 },
238 { 0.5, 0.25, 0.5 },
239 { 0.3, 0, 0.3 },
240 { 0.3, 0.15, 0.3 },
241 { 0.15, 0, 0.15 },
242 { 0.15, 0.075, 0.15 },
243 { 1, 0, 0.75 },
244 { 1, 0.5, 0.875 },
245 { 0.65, 0, 0.4875 },
246 { 0.65, 0.325, 0.5688 },
247 { 0.5, 0, 0.375 },
248 { 0.5, 0.25, 0.4375 },
249 { 0.3, 0, 0.225 },
250 { 0.3, 0.15, 0.2625 },
251 { 0.15, 0, 0.1125 },
252 { 0.15, 0.075, 0.1313 },
253 { 1, 0, 0.5 },
254 { 1, 0.5, 0.75 },
255 { 0.65, 0, 0.325 },
256 { 0.65, 0.325, 0.4875 },
257 { 0.5, 0, 0.25 },
258 { 0.5, 0.25, 0.375 },
259 { 0.3, 0, 0.15 },
260 { 0.3, 0.15, 0.225 },
261 { 0.15, 0, 0.075 },
262 { 0.15, 0.075, 0.1125 },
263 { 1, 0, 0.25 },
264 { 1, 0.5, 0.625 },
265 { 0.65, 0, 0.1625 },
266 { 0.65, 0.325, 0.4063 },
267 { 0.5, 0, 0.125 },
268 { 0.5, 0.25, 0.3125 },
269 { 0.3, 0, 0.075 },
270 { 0.3, 0.15, 0.1875 },
271 { 0.15, 0, 0.0375 },
272 { 0.15, 0.075, 0.0938 },
273 { 0.33, 0.33, 0.33 },
274 { 0.464, 0.464, 0.464 },
275 { 0.598, 0.598, 0.598 },
276 { 0.732, 0.732, 0.732 },
277 { 0.866, 0.866, 0.866 },
278 { 1, 1, 1 },
279};
280
281
282/**
283 *
284 */
285DXFFile::
286DXFFile() {
287 _in = nullptr;
288 _owns_in = false;
289 _layer = nullptr;
290 reset_entity();
291 _color_index = -1;
292}
293
294/**
295 *
296 */
297DXFFile::
298~DXFFile() {
299 if (_owns_in) {
301 vfs->close_read_file(_in);
302 }
303}
304
305
306/**
307 * Opens the indicated filename and reads it as a DXF file.
308 */
310process(Filename filename) {
311 filename.set_text();
312
314 istream *in = vfs->open_read_file(filename, true);
315 if (in == nullptr) {
316 return;
317 }
318 process(in, true);
319}
320
321
322/**
323 * Reads the indicated stream as a DXF file. If owns_in is true, then the
324 * istream will be deleted via vfs->close_read_file() when the DXFFile object
325 * destructs.
326 */
328process(istream *in, bool owns_in) {
329 if (_owns_in) {
331 vfs->close_read_file(_in);
332 }
333 _in = in;
334 _owns_in = owns_in;
335 _state = ST_top;
336
337 begin_file();
338 while (_state != ST_done && _state != ST_error) {
339 if (get_group()) {
340 switch (_state) {
341 case ST_top:
342 state_top();
343 break;
344
345 case ST_section:
346 state_section();
347 break;
348
349 case ST_entity:
350 state_entity();
351 break;
352
353 case ST_verts:
354 state_verts();
355 break;
356
357 default:
358 break;
359 }
360 }
361 }
362}
363
364
365
366/**
367 * A hook for user code, if desired. This function is called whenever
368 * processing begins on the DXF file.
369 */
371begin_file() {
372}
373
374
375/**
376 * A hook for user code, if desired. This function is called whenever a new
377 * section in the DXF file is encountered.
378 */
381}
382
383
384/**
385 * A hook for user code, if desired. This function is called whenever a
386 * vertex is read from the DXF file. This function has the default behavior
387 * of adding the vertex to the _verts list, so that when done_entity() is
388 * called later, it will have the complete list of vertices available to it.
389 */
391done_vertex() {
392 DXFVertex v;
393 v._p = _p;
394 _verts.push_back(v);
395}
396
397
398/**
399 * This is the primary hook for user code. This function is called when an
400 * entity is read from the DXF file. This may be something like a polygon,
401 * point, or a polygon mesh: any geometry. It is up to the user code to
402 * override this function and do something interesting with each piece of
403 * geometry that is read.
404 */
406done_entity() {
407}
408
409
410/**
411 * A hook for user code, if desired. This function is called as each section
412 * in the DXF file is finished.
413 */
415end_section() {
416}
417
418
419/**
420 * A hook for user code, if desired. This function is called when the DXF
421 * processing is complete.
422 */
424end_file() {
425}
426
427
428/**
429 * A hook for user code, if desired. This function is called when some
430 * unexpected error occurs while reading the DXF file.
431 */
433error() {
434 nout << "Error!\n";
435}
436
437
438
439/**
440 * Returns the index of the closest matching AutoCAD color to the indicated r,
441 * g, b.
442 */
444find_color(double r, double g, double b) {
445 double best_diff = 4.0; // 4 is greater than our expected max, 3.
446 int best_index = 7;
447
448 for (int i = 0; i < 255; i++) {
449 double diff = ((r - _colors[i].r) * (r - _colors[i].r) +
450 (g - _colors[i].g) * (g - _colors[i].g) +
451 (b - _colors[i].b) * (b - _colors[i].b));
452 if (diff < best_diff) {
453 best_diff = diff;
454 best_index = i;
455 }
456 }
457
458 return best_index;
459}
460
461/**
462 * This is a convenience function to return the r,g,b color of the current
463 * entity (at the time of done_entity()). It's based on the _color_index
464 * value that was read from the DXF file.
465 */
467get_color() const {
468 if (_color_index >= 0 && _color_index <= 255) {
469 return _colors[_color_index];
470 }
471 return _colors[0];
472}
473
474
475/**
476 * Assuming the current entity is a planar-based entity, for instance, a 2-d
477 * polygon (as opposed to a 3-d polygon), this converts the coordinates from
478 * the funny planar coordinate system to the world coordinates. It converts
479 * the _p value of the entity, as well as all vertices in the _verts list.
480 */
482ocs_2_wcs() {
483 compute_ocs();
484
485 // Convert the entity's position.
486 _p = _p * _ocs2wcs;
487
488 // Maybe we have these coordinates too.
489 _q = _q * _ocs2wcs;
490 _r = _r * _ocs2wcs;
491 _s = _s * _ocs2wcs;
492
493 // If there are any vertices, convert them too.
494 DXFVertices::iterator vi;
495 for (vi = _verts.begin(); vi != _verts.end(); ++vi) {
496 (*vi)._p = (*vi)._p * _ocs2wcs;
497 }
498}
499
500
501/**
502 * Computes the matrix used to convert from the planar coordinate system to
503 * world coordinates.
504 */
505void DXFFile::
506compute_ocs() {
507 // A 2-d entity's vertices might be defined in an "Object Coordinate System"
508 // which has a funny definition. Its Z axis is defined by _z, and its X and
509 // Y axes are inferred from that. The origin is the same as the world
510 // coordinate system's origin.
511
512 // The Z axis is _z. Determine the x and y axes.
513 LVector3d x, y;
514
515 if (fabs(_z[0]) < 1.0/64.0 && fabs(_z[1]) < 1.0/64.0) {
516 x = cross(LVector3d(0.0, 1.0, 0.0), _z);
517 } else {
518 x = cross(LVector3d(0.0, 0.0, 1.0), _z);
519 }
520 x.normalize();
521 y = cross(x, _z);
522 y.normalize();
523
524 // Now build a rotate matrix from these vectors.
525 LMatrix4d
526 ocs( x[0], x[1], x[2], 0,
527 y[0], y[1], y[2], 0,
528 _z[0], _z[1], _z[2], 0,
529 0, 0, 0, 1);
530
531 _ocs2wcs.invert_from(ocs);
532}
533
534
535/**
536 * Reads the next code, string pair from the DXF file. This is the basic unit
537 * of data in a DXF file.
538 */
539bool DXFFile::
540get_group() {
541 istream &in = *_in;
542 do {
543 in >> _code;
544 if (!in) {
545 change_state(ST_error);
546 return false;
547 }
548
549 // Now skip past exactly one newline character and any number of other
550 // whitespace characters.
551 while (in && in.peek() != '\n') {
552 in.get();
553 }
554 in.get();
555 while (in && isspace(in.peek()) && in.peek() != '\n') {
556 in.get();
557 }
558
559 std::getline(in, _string);
560 _string = trim_right(_string);
561
562 if (!in) {
563 change_state(ST_error);
564 return false;
565 }
566
567 // If we just read a comment, go back and get another one.
568 } while (_code == 999);
569
570 return true;
571}
572
573
574/**
575 * Called as new nodes are read to update the internal state correctly.
576 */
577void DXFFile::
578change_state(State new_state) {
579 if (_state == ST_verts) {
580 done_vertex();
581 _p.set(0.0, 0.0, 0.0);
582 _q.set(0.0, 0.0, 0.0);
583 _r.set(0.0, 0.0, 0.0);
584 _s.set(0.0, 0.0, 0.0);
585 }
586 if ((_state == ST_entity || _state == ST_verts) &&
587 new_state != ST_verts) {
588 // We finish an entity when we read a new entity, or when we've read the
589 // last vertex (if we were scanning the vertices after an entity).
590 done_entity();
591 reset_entity();
592 }
593 switch (new_state) {
594 case ST_top:
595 end_section();
596 break;
597
598 case ST_done:
599 end_file();
600 break;
601
602 default:
603 break;
604 }
605 _state = new_state;
606}
607
608
609/**
610 *
611 */
612void DXFFile::
613change_section(Section new_section) {
614 change_state(ST_section);
615 _section = new_section;
617}
618
619
620/**
621 * Given a newly read layer name, sets the _layer pointer to point to the
622 * associate layer. If the layer name has not been encountered before,
623 * creates a new layer definition.
624 */
625void DXFFile::
626change_layer(const string &layer_name) {
627 if (_layer == nullptr || _layer->get_name() != layer_name) {
628 _layer = _layers.get_layer(layer_name, this);
629 }
630}
631
632
633/**
634 *
635 */
636void DXFFile::
637change_entity(Entity new_entity) {
638 if (new_entity == EN_vertex && _vertices_follow) {
639 // If we read a new vertex and we're still scanning the vertices that
640 // follow an entity, keep scanning it--we haven't finished the entity yet.
641 change_state(ST_verts);
642
643 } else {
644 // Otherwise, begin a new entity.
645 change_state(ST_entity);
646 _entity = new_entity;
647 }
648}
649
650
651/**
652 * Resets the current entity to its initial, default state prior to reading a
653 * new entity.
654 */
655void DXFFile::
656reset_entity() {
657 _p.set(0.0, 0.0, 0.0);
658 _q.set(0.0, 0.0, 0.0);
659 _r.set(0.0, 0.0, 0.0);
660 _s.set(0.0, 0.0, 0.0);
661 _z.set(0.0, 0.0, 1.0);
662 _vertices_follow = false;
663 // _color_index = -1;
664
665 _verts.erase(_verts.begin(), _verts.end());
666}
667
668
669/**
670 * Does the DXF processing when we are at the top of the file, outside of any
671 * section.
672 */
673void DXFFile::
674state_top() {
675 if (_code != 0) {
676 nout << "Group code 0 not found at top level; found code " << _code
677 << " instead.\n";
678 change_state(ST_error);
679 } else {
680 if (_string == "SECTION") {
681 if (get_group()) {
682 if (_code != 2) {
683 nout << "Group code 0 not immediately followed by code 2; found code "
684 << _code << " instead.\n";
685 } else {
686 if (_string == "HEADER") {
687 change_section(SE_header);
688 } else if (_string == "TABLES") {
689 change_section(SE_tables);
690 } else if (_string == "BLOCKS") {
691 change_section(SE_blocks);
692 } else if (_string == "ENTITIES") {
693 change_section(SE_entities);
694 } else if (_string == "OBJECTS") {
695 change_section(SE_objects);
696 } else {
697 change_section(SE_unknown);
698 }
699 }
700 }
701 } else if (_string == "EOF") {
702 change_state(ST_done);
703 } else {
704 nout << "Unexpected section at top level: '" << _string << "'\n";
705 change_state(ST_error);
706 }
707 }
708}
709
710
711
712/**
713 * Does the DXF processing when we are within some section.
714 */
715void DXFFile::
716state_section() {
717 string tail;
718
719 switch (_code) {
720 case 0:
721 if (_string == "ENDSEC") {
722 change_state(ST_top);
723 } else {
724 if (_section == SE_entities) {
725 if (_string == "3DFACE") {
726 change_entity(EN_3dface);
727 } else if (_string == "POINT") {
728 change_entity(EN_point);
729 } else if (_string == "INSERT") {
730 change_entity(EN_insert);
731 } else if (_string == "VERTEX") {
732 change_entity(EN_vertex);
733 } else if (_string == "POLYLINE") {
734 change_entity(EN_polyline);
735 } else {
736 change_entity(EN_unknown);
737 }
738 }
739 }
740 break;
741
742 case 8:
743 change_layer(_string);
744 break;
745
746 case 62: // Color.
747 _color_index = string_to_int(_string, tail);
748 break;
749
750 default:
751 break;
752 }
753}
754
755
756/**
757 * Does the DXF processing when we are reading an entity.
758 */
759void DXFFile::
760state_entity() {
761 string tail;
762
763 switch (_code) {
764 case 0:
765 state_section();
766 break;
767
768 case 8:
769 change_layer(_string);
770 break;
771
772 case 10:
773 _p[0] = string_to_double(_string, tail);
774 break;
775
776 case 11:
777 _q[0] = string_to_double(_string, tail);
778 break;
779
780 case 12:
781 _r[0] = string_to_double(_string, tail);
782 break;
783
784 case 13:
785 _s[0] = string_to_double(_string, tail);
786 break;
787
788 case 20:
789 _p[1] = string_to_double(_string, tail);
790 break;
791
792 case 21:
793 _q[1] = string_to_double(_string, tail);
794 break;
795
796 case 22:
797 _r[1] = string_to_double(_string, tail);
798 break;
799
800 case 23:
801 _s[1] = string_to_double(_string, tail);
802 break;
803
804 case 30:
805 _p[2] = string_to_double(_string, tail);
806 break;
807
808 case 31:
809 _q[2] = string_to_double(_string, tail);
810 break;
811
812 case 32:
813 _r[2] = string_to_double(_string, tail);
814 break;
815
816 case 33:
817 _s[2] = string_to_double(_string, tail);
818 break;
819
820 case 62: // Color.
821 _color_index = string_to_int(_string, tail);
822 break;
823
824 case 66: // Vertices-follow.
825 _vertices_follow = (string_to_int(_string, tail) != 0);
826 break;
827
828 case 70: // Polyline flags.
829 _flags = string_to_int(_string, tail);
830 break;
831
832 case 210:
833 _z[0] = string_to_double(_string, tail);
834 break;
835
836 case 220:
837 _z[1] = string_to_double(_string, tail);
838 break;
839
840 case 230:
841 _z[2] = string_to_double(_string, tail);
842 break;
843
844 default:
845 break;
846 }
847}
848
849
850/**
851 * Does the DXF processing when we are reading the list of vertices that might
852 * follow an entity.
853 */
854void DXFFile::
855state_verts() {
856 string tail;
857
858 switch (_code) {
859 case 0:
860 state_section();
861 break;
862
863 case 8:
864 change_layer(_string);
865 break;
866
867 case 10:
868 _p[0] = string_to_double(_string, tail);
869 break;
870
871 case 20:
872 _p[1] = string_to_double(_string, tail);
873 break;
874
875 case 30:
876 _p[2] = string_to_double(_string, tail);
877 break;
878
879 default:
880 break;
881 }
882}
883
884
885ostream &operator << (ostream &out, const DXFFile::State &state) {
886 switch (state) {
887 case DXFFile::ST_top:
888 return out << "ST_top";
889 case DXFFile::ST_section:
890 return out << "ST_section";
891 case DXFFile::ST_entity:
892 return out << "ST_entity";
893 case DXFFile::ST_verts:
894 return out << "ST_verts";
895 case DXFFile::ST_error:
896 return out << "ST_error";
897 case DXFFile::ST_done:
898 return out << "ST_done";
899 }
900 return out << "Unknown state";
901}
902
903ostream &operator << (ostream &out, const DXFFile::Section &section) {
904 switch (section) {
905 case DXFFile::SE_unknown:
906 return out << "SE_unknown";
907 case DXFFile::SE_header:
908 return out << "SE_header";
909 case DXFFile::SE_tables:
910 return out << "SE_tables";
911 case DXFFile::SE_blocks:
912 return out << "SE_blocks";
913 case DXFFile::SE_entities:
914 return out << "SE_entities";
915 case DXFFile::SE_objects:
916 return out << "SE_objects";
917 }
918 return out << "Unknown section";
919}
920
921ostream &operator << (ostream &out, const DXFFile::Entity &entity) {
922 switch (entity) {
923 case DXFFile::EN_unknown:
924 return out << "EN_unknown";
925 case DXFFile::EN_3dface:
926 return out << "EN_3dface";
927 case DXFFile::EN_point:
928 return out << "EN_point";
929 case DXFFile::EN_insert:
930 return out << "EN_insert";
931 case DXFFile::EN_vertex:
932 return out << "EN_vertex";
933 case DXFFile::EN_polyline:
934 return out << "EN_polyline";
935 }
936 return out << "Unknown entity";
937}
virtual void done_entity()
This is the primary hook for user code.
Definition dxfFile.cxx:406
virtual void end_file()
A hook for user code, if desired.
Definition dxfFile.cxx:424
void process(Filename filename)
Opens the indicated filename and reads it as a DXF file.
Definition dxfFile.cxx:310
static int find_color(double r, double g, double b)
Returns the index of the closest matching AutoCAD color to the indicated r, g, b.
Definition dxfFile.cxx:444
virtual void begin_section()
A hook for user code, if desired.
Definition dxfFile.cxx:380
void ocs_2_wcs()
Assuming the current entity is a planar-based entity, for instance, a 2-d polygon (as opposed to a 3-...
Definition dxfFile.cxx:482
virtual void error()
A hook for user code, if desired.
Definition dxfFile.cxx:433
virtual void begin_file()
A hook for user code, if desired.
Definition dxfFile.cxx:371
virtual void end_section()
A hook for user code, if desired.
Definition dxfFile.cxx:415
const Color & get_color() const
This is a convenience function to return the r,g,b color of the current entity (at the time of done_e...
Definition dxfFile.cxx:467
virtual void done_vertex()
A hook for user code, if desired.
Definition dxfFile.cxx:391
DXFLayer * get_layer(const std::string &name, DXFFile *dxffile)
Looks up the layer name in the map, and returns a pointer to the associated DXFLayer.
Stored within DXFFile, this is the basic Vertex data of a DXF file.
Definition dxfVertex.h:27
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
void set_text()
Indicates that the filename represents a text file.
Definition filename.I:424
A hierarchy of directories and files that appears to be one continuous file system,...
static void close_read_file(std::istream *stream)
Closes a file opened by a previous call to open_read_file().
std::istream * open_read_file(const Filename &filename, bool auto_unwrap) const
Convenience function; returns a newly allocated istream if the file exists and can be read,...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string trim_right(const string &str)
Returns a new string representing the contents of the given string with the trailing whitespace remov...
double string_to_double(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.