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  */
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  */
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  */
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  */
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  */
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  */
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 }
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
LColor get_color() const
Returns the color set on this particular attribute.
Definition: eggAttributes.I:91
A base class for nodes in the hierarchy that are not leaf nodes.
Definition: eggGroupNode.h:46
The main glue of the egg hierarchy, this corresponds to the <Group>, <Instance>, and <Joint> type nod...
Definition: eggGroup.h:34
A base class for things that may be directly added into the egg hierarchy.
Definition: eggNode.h:36
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 single polygon.
Definition: eggPolygon.h:24
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
A single layer in the DXF file to be written by EggToDXF.
Definition: eggToDXFLayer.h:29
void write_polyline(EggPolygon *poly, std::ostream &out)
Writes a polygon as a POLYLINE entity.
void write_entities(std::ostream &out)
Writes out the "entities", e.g.
void write_3d_face(EggPolygon *poly, std::ostream &out)
Writes a polygon as a 3DFACE entity.
void write_layer(std::ostream &out)
Writes the layer definition into the table at the beginning of the DXF file.
void add_color(const LColor &color)
Records that one polygon is defined using the indicated color.
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
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
Definition: eggVertex.h:39
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
Definition: eggVertex.I:131
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
Definition: typedObject.I:28
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.