Panda3D
|
00001 // Filename: eggToDXFLayer.cxx 00002 // Created by: drose (04May04) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "eggToDXFLayer.h" 00016 #include "eggToDXF.h" 00017 #include "dxfFile.h" 00018 #include "eggGroup.h" 00019 #include "eggGroupNode.h" 00020 #include "eggPolygon.h" 00021 #include "dcast.h" 00022 00023 //////////////////////////////////////////////////////////////////// 00024 // Function: EggToDXFLayer::Constructor 00025 // Access: Public 00026 // Description: 00027 //////////////////////////////////////////////////////////////////// 00028 EggToDXFLayer:: 00029 EggToDXFLayer(EggToDXF *egg2dxf, EggGroupNode *group) : 00030 _egg2dxf(egg2dxf), _group(group) 00031 { 00032 _layer_color = -1; 00033 } 00034 00035 //////////////////////////////////////////////////////////////////// 00036 // Function: EggToDXFLayer::Copy Constructor 00037 // Access: Public 00038 // Description: 00039 //////////////////////////////////////////////////////////////////// 00040 EggToDXFLayer:: 00041 EggToDXFLayer(const EggToDXFLayer ©) : 00042 _egg2dxf(copy._egg2dxf), 00043 _group(copy._group), 00044 _layer_color(copy._layer_color) 00045 { 00046 // The copy constructor doesn't bother with the ColorCounts. 00047 } 00048 00049 //////////////////////////////////////////////////////////////////// 00050 // Function: EggToDXFLayer::Copy Assignment Operator 00051 // Access: Public 00052 // Description: 00053 //////////////////////////////////////////////////////////////////// 00054 void EggToDXFLayer:: 00055 operator = (const EggToDXFLayer ©) { 00056 _egg2dxf = copy._egg2dxf; 00057 _group = copy._group; 00058 _layer_color = copy._layer_color; 00059 00060 // The copy constructor doesn't bother with the ColorCounts. 00061 } 00062 00063 //////////////////////////////////////////////////////////////////// 00064 // Function: EggToDXFLayer::add_color 00065 // Access: Public 00066 // Description: Records that one polygon is defined using the 00067 // indicated color. This will get accumulated; the 00068 // color used by the majority of polygons will become 00069 // the layer color. 00070 //////////////////////////////////////////////////////////////////// 00071 void EggToDXFLayer:: 00072 add_color(const LColor &color) { 00073 int autocad_color = get_autocad_color(color); 00074 00075 ColorCounts::iterator cci; 00076 cci = _color_counts.find(autocad_color); 00077 if (cci == _color_counts.end()) { 00078 // The first time a particular color was used. Count it once. 00079 _color_counts[autocad_color] = 1; 00080 } else { 00081 // This color has been used before. Count it again. 00082 (*cci).second++; 00083 } 00084 } 00085 00086 00087 //////////////////////////////////////////////////////////////////// 00088 // Function: EggToDXFLayer::choose_overall_color 00089 // Access: Public 00090 // Description: After all polygons have been accounted for, chooses 00091 // the polygon color that occurred most often as the 00092 // layer color. 00093 //////////////////////////////////////////////////////////////////// 00094 void EggToDXFLayer:: 00095 choose_overall_color() { 00096 int max_count = 0; 00097 00098 ColorCounts::iterator cci; 00099 for (cci = _color_counts.begin(); cci != _color_counts.end(); ++cci) { 00100 int count = (*cci).second; 00101 if (count > max_count) { 00102 _layer_color = (*cci).first; 00103 max_count = count; 00104 } 00105 } 00106 } 00107 00108 00109 //////////////////////////////////////////////////////////////////// 00110 // Function: EggToDXFLayer::write_layer 00111 // Access: Public 00112 // Description: Writes the layer definition into the table at the 00113 // beginning of the DXF file. This does not write the 00114 // actual geometry; that gets done later by 00115 // write_entities(). 00116 //////////////////////////////////////////////////////////////////// 00117 void EggToDXFLayer:: 00118 write_layer(ostream &out) { 00119 out << "0\nLAYER\n" 00120 << "2\n" << _group->get_name() << "\n" 00121 << "70\n0\n" 00122 << "62\n" << _layer_color << "\n" 00123 << "6\nCONTINUOUS\n"; 00124 } 00125 00126 //////////////////////////////////////////////////////////////////// 00127 // Function: EggToDXFLayer::write_polyline 00128 // Access: Public 00129 // Description: Writes a polygon as a POLYLINE entity. 00130 //////////////////////////////////////////////////////////////////// 00131 void EggToDXFLayer:: 00132 write_polyline(EggPolygon *poly, ostream &out) { 00133 out << "0\nPOLYLINE\n" 00134 << "8\n" << _group->get_name() << "\n" 00135 << "66\n1\n" 00136 << "70\n1\n" 00137 << "62\n" << get_autocad_color(poly->get_color()) << "\n"; 00138 00139 // Since DXF uses a clockwise ordering convention, we must 00140 // reverse the order in which we write out the vertices. 00141 EggPolygon::reverse_iterator vi; 00142 for (vi = poly->rbegin(); vi != poly->rend(); ++vi) { 00143 EggVertex *vtx = (*vi); 00144 LVecBase3d pos = vtx->get_pos3() * _group->get_vertex_frame(); 00145 out << "0\nVERTEX\n" 00146 << "10\n" << pos[0] << "\n" 00147 << "20\n" << pos[1] << "\n" 00148 << "30\n" << pos[2] << "\n"; 00149 } 00150 out << "0\nSEQEND\n"; 00151 } 00152 00153 //////////////////////////////////////////////////////////////////// 00154 // Function: EggToDXFLayer::write_3d_face 00155 // Access: Public 00156 // Description: Writes a polygon as a 3DFACE entity. 00157 //////////////////////////////////////////////////////////////////// 00158 void EggToDXFLayer:: 00159 write_3d_face(EggPolygon *poly, ostream &out) { 00160 if (poly->size() > 4) { 00161 // If we have a big polygon, we have to triangulate it, since 00162 // 3DFaces can only be tris and quads. 00163 PT(EggGroup) group = new EggGroup; 00164 poly->triangulate_into(group, true); 00165 00166 EggGroupNode::iterator ci; 00167 for (ci = group->begin(); ci != group->end(); ++ci) { 00168 EggNode *child = (*ci); 00169 if (child->is_of_type(EggPolygon::get_class_type())) { 00170 write_3d_face(DCAST(EggPolygon, child), out); 00171 } 00172 } 00173 00174 } else if (poly->size() > 2) { 00175 // Otherwise, if we have a tri or a quad, just write it out. 00176 out << "0\n3DFACE\n" 00177 << "8\n" << _group->get_name() << "\n"; 00178 00179 // Since DXF uses a clockwise ordering convention, we must 00180 // reverse the order in which we write out the vertices. 00181 int i; 00182 EggPolygon::reverse_iterator vi; 00183 for (i = 0, vi = poly->rbegin(); vi != poly->rend(); ++i, ++vi) { 00184 EggVertex *vtx = (*vi); 00185 LVecBase3d pos = vtx->get_pos3() * _group->get_vertex_frame(); 00186 out << 10 + i << "\n" << pos[0] << "\n" 00187 << 20 + i << "\n" << pos[1] << "\n" 00188 << 30 + i << "\n" << pos[2] << "\n"; 00189 if (i == 2 && poly->size() == 3) { 00190 // A special case for triangles: repeat the last vertex. 00191 out << 11 + i << "\n" << pos[0] << "\n" 00192 << 21 + i << "\n" << pos[1] << "\n" 00193 << 31 + i << "\n" << pos[2] << "\n"; 00194 } 00195 } 00196 } 00197 } 00198 00199 00200 //////////////////////////////////////////////////////////////////// 00201 // Function: EggToDXFLayer::write_entities 00202 // Access: Public 00203 // Description: Writes out the "entities", e.g. polygons, defined for 00204 // the current layer. 00205 //////////////////////////////////////////////////////////////////// 00206 void EggToDXFLayer:: 00207 write_entities(ostream &out) { 00208 EggGroupNode::iterator ci; 00209 for (ci = _group->begin(); ci != _group->end(); ++ci) { 00210 EggNode *child = (*ci); 00211 if (child->is_of_type(EggPolygon::get_class_type())) { 00212 EggPolygon *poly = DCAST(EggPolygon, child); 00213 if (_egg2dxf->_use_polyline) { 00214 write_polyline(poly, out); 00215 } else { 00216 write_3d_face(poly, out); 00217 } 00218 } 00219 } 00220 } 00221 00222 //////////////////////////////////////////////////////////////////// 00223 // Function: EggToDXFLayer::get_autocad_color 00224 // Access: Private 00225 // Description: Returns the AutoCAD color index that most closely 00226 // matches the indicated EggColor. 00227 //////////////////////////////////////////////////////////////////// 00228 int EggToDXFLayer:: 00229 get_autocad_color(const LColor &color) { 00230 typedef pmap<LColor, int> ColorMap; 00231 static ColorMap _map; 00232 00233 ColorMap::iterator cmi; 00234 cmi = _map.find(color); 00235 if (cmi != _map.end()) { 00236 return (*cmi).second; 00237 } 00238 00239 int result = DXFFile::find_color(color[0], color[1], color[2]); 00240 _map[color] = result; 00241 return result; 00242 }