15 #include "eggToObjConverter.h" 16 #include "config_objegg.h" 18 #include "string_utils.h" 19 #include "streamReader.h" 20 #include "virtualFileSystem.h" 21 #include "eggPolygon.h" 52 ~EggToObjConverter() {
111 if (_egg_data->get_coordinate_system() == CS_default) {
112 _egg_data->set_coordinate_system(CS_zup_right);
115 if (!process(filename)) {
126 bool EggToObjConverter::
128 _egg_data->flatten_transforms();
129 collect_vertices(_egg_data);
132 Filename obj_filename = Filename::text_filename(filename);
135 if (file == (ostream *)NULL) {
139 _current_group = NULL;
148 write_vertices(*file,
"v", 3, _unique_vert3);
149 write_vertices(*file,
"v", 4, _unique_vert4);
150 write_vertices(*file,
"vt", 2, _unique_uv2);
151 write_vertices(*file,
"vt", 3, _unique_uv3);
152 write_vertices(*file,
"vn", 3, _unique_norm);
154 write_faces(*file, _egg_data);
156 bool success = (file != (ostream *)NULL);
170 void EggToObjConverter::
171 collect_vertices(
EggNode *egg_node) {
172 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
174 EggPrimitive::iterator pi;
175 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
179 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
182 EggGroupNode::iterator ci;
183 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
184 collect_vertices(*ci);
196 void EggToObjConverter::
197 write_faces(ostream &out,
EggNode *egg_node) {
198 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
199 const char *prim_type = NULL;
200 if (egg_node->
is_of_type(EggPolygon::get_class_type())) {
202 }
else if (egg_node->
is_of_type(EggPoint::get_class_type())) {
204 }
else if (egg_node->
is_of_type(EggLine::get_class_type())) {
208 if (prim_type != NULL) {
209 write_group_reference(out, egg_node);
214 EggPrimitive::iterator pi;
215 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
216 VertexDef &vdef = _vmap[(*pi)];
221 if (vdef._vert3_index != -1) {
222 vert_index = vdef._vert3_index + 1;
223 }
else if (vdef._vert4_index != -1) {
224 vert_index = vdef._vert4_index + 1 + (int)_unique_vert3.size();
227 if (vdef._uv2_index != -1) {
228 uv_index = vdef._uv2_index + 1;
229 }
else if (vdef._uv3_index != -1) {
230 uv_index = vdef._uv3_index + 1 + (int)_unique_uv2.size();
233 if (vdef._norm_index != -1) {
234 norm_index = vdef._norm_index + 1;
237 if (vert_index == -1) {
241 if (norm_index != -1) {
242 if (uv_index != -1) {
243 out <<
" " << vert_index <<
"/" << uv_index <<
"/" << norm_index;
245 out <<
" " << vert_index <<
"//" << norm_index;
247 }
else if (uv_index != -1) {
248 out <<
" " << vert_index <<
"/" << uv_index;
250 out <<
" " << vert_index;
255 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
258 EggGroupNode::iterator ci;
259 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
260 write_faces(out, *ci);
271 void EggToObjConverter::
272 write_group_reference(ostream &out,
EggNode *egg_node) {
274 if (egg_group == _current_group) {
280 get_group_name(group_name, egg_group);
281 if (group_name.empty()) {
282 out <<
"g default\n";
284 out <<
"g" << group_name <<
"\n";
286 _current_group = egg_group;
296 void EggToObjConverter::
297 get_group_name(
string &group_name,
EggGroupNode *egg_group) {
298 string name = trim(egg_group->get_name());
303 for (string::const_iterator ni = name.begin(); ni != name.end(); ++ni) {
314 if (egg_parent != NULL) {
315 get_group_name(group_name, egg_parent);
325 void EggToObjConverter::
327 VertexDef &vdef = _vmap[vertex];
331 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos1());
334 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos2());
337 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos3());
340 vdef._vert4_index = record_unique(_unique_vert4, vertex->
get_pos4());
345 vdef._uv2_index = record_unique(_unique_uv2, vertex->
get_uv(
""));
346 }
else if (vertex->
has_uvw(
"")) {
347 vdef._uv3_index = record_unique(_unique_uv3, vertex->
get_uvw(
""));
350 if (vertex->has_normal()) {
351 vdef._norm_index = record_unique(_unique_norm, vertex->get_normal());
363 int EggToObjConverter::
368 int index = unique.size();
369 UniqueVertices::iterator ui = unique.insert(UniqueVertices::value_type(vec, index)).first;
381 int EggToObjConverter::
383 return record_unique(unique,
LVecBase4d(vec[0], vec[1], vec[2], 0.0));
394 int EggToObjConverter::
396 return record_unique(unique,
LVecBase4d(vec[0], vec[1], 0.0, 0.0));
407 int EggToObjConverter::
409 return record_unique(unique,
LVecBase4d(pos, 0.0, 0.0, 0.0));
418 void EggToObjConverter::
419 write_vertices(ostream &out,
const string &prefix,
int num_components,
422 int num_vertices = (int)unique.size();
424 memset(vertices, 0, num_vertices *
sizeof(
LVecBase4d *));
425 UniqueVertices::const_iterator ui;
426 for (ui = unique.begin(); ui != unique.end(); ++ui) {
427 int index = (*ui).second;
429 nassertv(index >= 0 && index < num_vertices);
430 nassertv(vertices[index] == NULL);
431 vertices[index] = &vec;
434 for (
int i = 0; i < num_vertices; ++i) {
437 for (
int ci = 0; ci < num_components; ++ci) {
438 out <<
" " << vec[ci];
442 PANDA_FREE_ARRAY(vertices);
450 EggToObjConverter::VertexDef::
A base class for any of a number of kinds of geometry primitives: polygons, point lights...
bool had_error() const
Returns true if an error was detected during the conversion process, false otherwise.
int get_num_dimensions() const
Returns the number of dimensions the vertex uses.
virtual bool supports_compressed() const
Returns true if this file type can transparently save compressed files (with a .pz extension)...
bool has_uvw(const string &name) const
Returns true if the vertex has the named UV coordinate triple, and the named UV coordinate triple is ...
virtual string get_extension() const
Returns the common extension of the file type this converter supports.
This is the base class for all two-component vectors and points.
A base class for nodes in the hierarchy that are not leaf nodes.
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS's file system.
virtual bool write_file(const Filename &filename)
Handles the conversion of the internal EggData to the target file format, written to the specified fi...
LTexCoordd get_uv() const
Returns the unnamed UV coordinate pair on the vertex.
This is the base class for all three-component vectors and points.
const LTexCoord3d & get_uvw(const string &name) const
Returns the named UV coordinate triple on the vertex.
LPoint2d get_pos2() const
Only valid if get_num_dimensions() returns 2.
LVertexd get_pos3() const
Valid if get_num_dimensions() returns 3 or 4.
virtual EggToSomethingConverter * make_copy()
Allocates and returns a new copy of the converter.
virtual string get_name() const
Returns the English name of the file type this converter supports.
This is a base class for a family of converter classes that manage a conversion from egg format to so...
void clear_error()
Resets the error flag to the no-error state.
The name of a file, such as a texture file or an Egg file.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal...
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
bool has_uv() const
Returns true if the vertex has an unnamed UV coordinate pair, false otherwise.
This is the base class for all three-component vectors and points.
ostream * open_write_file(const Filename &filename, bool auto_wrap, bool truncate)
Convenience function; returns a newly allocated ostream if the file exists and can be written...
A base class for things that may be directly added into the egg hierarchy.
LPoint4d get_pos4() const
This is always valid, regardless of the value of get_num_dimensions.
bool is_of_type(TypeHandle handle) const
Returns true if the current object is or derives from the indicated type.
bool delete_file(const Filename &filename)
Attempts to delete the indicated file or directory.
Convert an obj file to egg data.
static void close_write_file(ostream *stream)
Closes a file opened by a previous call to open_write_file().
double get_pos1() const
Only valid if get_num_dimensions() returns 1.