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