Panda3D
eggToDXFLayer.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 eggToDXFLayer.cxx
10  * @author drose
11  * @date 2004-05-04
12  */
13 
14 #include "eggToDXFLayer.h"
15 #include "eggToDXF.h"
16 #include "dxfFile.h"
17 #include "eggGroup.h"
18 #include "eggGroupNode.h"
19 #include "eggPolygon.h"
20 #include "dcast.h"
21 
22 using std::ostream;
23 
24 /**
25  *
26  */
27 EggToDXFLayer::
28 EggToDXFLayer(EggToDXF *egg2dxf, EggGroupNode *group) :
29  _egg2dxf(egg2dxf), _group(group)
30 {
31  _layer_color = -1;
32 }
33 
34 /**
35  *
36  */
37 EggToDXFLayer::
38 EggToDXFLayer(const EggToDXFLayer &copy) :
39  _egg2dxf(copy._egg2dxf),
40  _group(copy._group),
41  _layer_color(copy._layer_color)
42 {
43  // The copy constructor doesn't bother with the ColorCounts.
44 }
45 
46 /**
47  *
48  */
49 void EggToDXFLayer::
50 operator = (const EggToDXFLayer &copy) {
51  _egg2dxf = copy._egg2dxf;
52  _group = copy._group;
53  _layer_color = copy._layer_color;
54 
55  // The copy constructor doesn't bother with the ColorCounts.
56 }
57 
58 /**
59  * Records that one polygon is defined using the indicated color. This will
60  * get accumulated; the color used by the majority of polygons will become the
61  * layer color.
62  */
63 void EggToDXFLayer::
64 add_color(const LColor &color) {
65  int autocad_color = get_autocad_color(color);
66 
67  ColorCounts::iterator cci;
68  cci = _color_counts.find(autocad_color);
69  if (cci == _color_counts.end()) {
70  // The first time a particular color was used. Count it once.
71  _color_counts[autocad_color] = 1;
72  } else {
73  // This color has been used before. Count it again.
74  (*cci).second++;
75  }
76 }
77 
78 
79 /**
80  * After all polygons have been accounted for, chooses the polygon color that
81  * occurred most often as the layer color.
82  */
83 void EggToDXFLayer::
85  int max_count = 0;
86 
87  ColorCounts::iterator cci;
88  for (cci = _color_counts.begin(); cci != _color_counts.end(); ++cci) {
89  int count = (*cci).second;
90  if (count > max_count) {
91  _layer_color = (*cci).first;
92  max_count = count;
93  }
94  }
95 }
96 
97 
98 /**
99  * Writes the layer definition into the table at the beginning of the DXF
100  * file. This does not write the actual geometry; that gets done later by
101  * write_entities().
102  */
103 void EggToDXFLayer::
104 write_layer(ostream &out) {
105  out << "0\nLAYER\n"
106  << "2\n" << _group->get_name() << "\n"
107  << "70\n0\n"
108  << "62\n" << _layer_color << "\n"
109  << "6\nCONTINUOUS\n";
110 }
111 
112 /**
113  * Writes a polygon as a POLYLINE entity.
114  */
115 void EggToDXFLayer::
116 write_polyline(EggPolygon *poly, ostream &out) {
117  out << "0\nPOLYLINE\n"
118  << "8\n" << _group->get_name() << "\n"
119  << "66\n1\n"
120  << "70\n1\n"
121  << "62\n" << get_autocad_color(poly->get_color()) << "\n";
122 
123  // Since DXF uses a clockwise ordering convention, we must reverse the order
124  // in which we write out the vertices.
125  EggPolygon::reverse_iterator vi;
126  for (vi = poly->rbegin(); vi != poly->rend(); ++vi) {
127  EggVertex *vtx = (*vi);
128  LVecBase3d pos = vtx->get_pos3() * _group->get_vertex_frame();
129  out << "0\nVERTEX\n"
130  << "10\n" << pos[0] << "\n"
131  << "20\n" << pos[1] << "\n"
132  << "30\n" << pos[2] << "\n";
133  }
134  out << "0\nSEQEND\n";
135 }
136 
137 /**
138  * Writes a polygon as a 3DFACE entity.
139  */
140 void EggToDXFLayer::
141 write_3d_face(EggPolygon *poly, ostream &out) {
142  if (poly->size() > 4) {
143  // If we have a big polygon, we have to triangulate it, since 3DFaces can
144  // only be tris and quads.
145  PT(EggGroup) group = new EggGroup;
146  poly->triangulate_into(group, true);
147 
148  EggGroupNode::iterator ci;
149  for (ci = group->begin(); ci != group->end(); ++ci) {
150  EggNode *child = (*ci);
151  if (child->is_of_type(EggPolygon::get_class_type())) {
152  write_3d_face(DCAST(EggPolygon, child), out);
153  }
154  }
155 
156  } else if (poly->size() > 2) {
157  // Otherwise, if we have a tri or a quad, just write it out.
158  out << "0\n3DFACE\n"
159  << "8\n" << _group->get_name() << "\n";
160 
161  // Since DXF uses a clockwise ordering convention, we must reverse the
162  // order in which we write out the vertices.
163  int i;
164  EggPolygon::reverse_iterator vi;
165  for (i = 0, vi = poly->rbegin(); vi != poly->rend(); ++i, ++vi) {
166  EggVertex *vtx = (*vi);
167  LVecBase3d pos = vtx->get_pos3() * _group->get_vertex_frame();
168  out << 10 + i << "\n" << pos[0] << "\n"
169  << 20 + i << "\n" << pos[1] << "\n"
170  << 30 + i << "\n" << pos[2] << "\n";
171  if (i == 2 && poly->size() == 3) {
172  // A special case for triangles: repeat the last vertex.
173  out << 11 + i << "\n" << pos[0] << "\n"
174  << 21 + i << "\n" << pos[1] << "\n"
175  << 31 + i << "\n" << pos[2] << "\n";
176  }
177  }
178  }
179 }
180 
181 
182 /**
183  * Writes out the "entities", e.g. polygons, defined for the current layer.
184  */
185 void EggToDXFLayer::
186 write_entities(ostream &out) {
187  EggGroupNode::iterator ci;
188  for (ci = _group->begin(); ci != _group->end(); ++ci) {
189  EggNode *child = (*ci);
190  if (child->is_of_type(EggPolygon::get_class_type())) {
191  EggPolygon *poly = DCAST(EggPolygon, child);
192  if (_egg2dxf->_use_polyline) {
193  write_polyline(poly, out);
194  } else {
195  write_3d_face(poly, out);
196  }
197  }
198  }
199 }
200 
201 /**
202  * Returns the AutoCAD color index that most closely matches the indicated
203  * EggColor.
204  */
205 int EggToDXFLayer::
206 get_autocad_color(const LColor &color) {
207  typedef pmap<LColor, int> ColorMap;
208  static ColorMap _map;
209 
210  ColorMap::iterator cmi;
211  cmi = _map.find(color);
212  if (cmi != _map.end()) {
213  return (*cmi).second;
214  }
215 
216  int result = DXFFile::find_color(color[0], color[1], color[2]);
217  _map[color] = result;
218  return result;
219 }
void write_3d_face(EggPolygon *poly, std::ostream &out)
Writes a polygon as a 3DFACE entity.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
const LMatrix4d & get_vertex_frame() const
Returns the coordinate frame of the vertices referenced by primitives at or under this node.
Definition: eggNode.I:108
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
Definition: eggVertex.I:131
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void write_polyline(EggPolygon *poly, std::ostream &out)
Writes a polygon as a POLYLINE entity.
bool triangulate_into(EggGroupNode *container, bool convex_also) const
Subdivides the polygon into triangles and adds each one to the indicated container.
Definition: eggPolygon.I:67
void write_layer(std::ostream &out)
Writes the layer definition into the table at the beginning of the DXF file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A single polygon.
Definition: eggPolygon.h:24
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:35
void choose_overall_color()
After all polygons have been accounted for, chooses the polygon color that occurred most often as the...
A program to read an egg file and write a DXF file.
Definition: eggToDXF.h:27
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
void write_entities(std::ostream &out)
Writes out the "entities", e.g.
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
A single layer in the DXF file to be written by EggToDXF.
Definition: eggToDXFLayer.h:29
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void add_color(const LColor &color)
Records that one polygon is defined using the indicated color.