49 ~EggToObjConverter() {
94 if (_egg_data->get_coordinate_system() == CS_default) {
95 _egg_data->set_coordinate_system(CS_zup_right);
98 if (!process(filename)) {
107 bool EggToObjConverter::
109 _egg_data->flatten_transforms();
110 collect_vertices(_egg_data);
113 Filename obj_filename = Filename::text_filename(filename);
116 if (file ==
nullptr) {
119 if (egg_precision != 0) {
120 file->precision(egg_precision);
123 _current_group =
nullptr;
132 write_vertices(*file,
"v", 3, _unique_vert3);
133 write_vertices(*file,
"v", 4, _unique_vert4);
134 write_vertices(*file,
"vt", 2, _unique_uv2);
135 write_vertices(*file,
"vt", 3, _unique_uv3);
136 write_vertices(*file,
"vn", 3, _unique_norm);
138 write_faces(*file, _egg_data);
140 bool success = (file !=
nullptr);
151 void EggToObjConverter::
152 collect_vertices(
EggNode *egg_node) {
153 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
155 EggPrimitive::iterator pi;
156 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
160 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
163 EggGroupNode::iterator ci;
164 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
165 collect_vertices(*ci);
174 void EggToObjConverter::
175 write_faces(ostream &out,
EggNode *egg_node) {
176 if (egg_node->
is_of_type(EggPrimitive::get_class_type())) {
177 const char *prim_type =
nullptr;
178 if (egg_node->
is_of_type(EggPolygon::get_class_type())) {
180 }
else if (egg_node->
is_of_type(EggPoint::get_class_type())) {
182 }
else if (egg_node->
is_of_type(EggLine::get_class_type())) {
186 if (prim_type !=
nullptr) {
187 write_group_reference(out, egg_node);
192 EggPrimitive::iterator pi;
193 for (pi = egg_prim->begin(); pi != egg_prim->end(); ++pi) {
194 VertexDef &vdef = _vmap[(*pi)];
199 if (vdef._vert3_index != -1) {
200 vert_index = vdef._vert3_index + 1;
201 }
else if (vdef._vert4_index != -1) {
202 vert_index = vdef._vert4_index + 1 + (int)_unique_vert3.size();
205 if (vdef._uv2_index != -1) {
206 uv_index = vdef._uv2_index + 1;
207 }
else if (vdef._uv3_index != -1) {
208 uv_index = vdef._uv3_index + 1 + (int)_unique_uv2.size();
211 if (vdef._norm_index != -1) {
212 norm_index = vdef._norm_index + 1;
215 if (vert_index == -1) {
219 if (norm_index != -1) {
220 if (uv_index != -1) {
221 out <<
" " << vert_index <<
"/" << uv_index <<
"/" << norm_index;
223 out <<
" " << vert_index <<
"//" << norm_index;
225 }
else if (uv_index != -1) {
226 out <<
" " << vert_index <<
"/" << uv_index;
228 out <<
" " << vert_index;
233 }
else if (egg_node->
is_of_type(EggGroupNode::get_class_type())) {
236 EggGroupNode::iterator ci;
237 for (ci = egg_group->begin(); ci != egg_group->end(); ++ci) {
238 write_faces(out, *ci);
246 void EggToObjConverter::
247 write_group_reference(ostream &out,
EggNode *egg_node) {
249 if (egg_group == _current_group) {
255 get_group_name(group_name, egg_group);
256 if (group_name.empty()) {
257 out <<
"g default\n";
259 out <<
"g" << group_name <<
"\n";
261 _current_group = egg_group;
268 void EggToObjConverter::
269 get_group_name(
string &group_name,
EggGroupNode *egg_group) {
270 string name =
trim(egg_group->get_name());
275 for (string::const_iterator ni = name.begin(); ni != name.end(); ++ni) {
286 if (egg_parent !=
nullptr) {
287 get_group_name(group_name, egg_parent);
295 void EggToObjConverter::
297 VertexDef &vdef = _vmap[vertex];
301 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos1());
304 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos2());
307 vdef._vert3_index = record_unique(_unique_vert3, vertex->
get_pos3());
310 vdef._vert4_index = record_unique(_unique_vert4, vertex->
get_pos4());
315 vdef._uv2_index = record_unique(_unique_uv2, vertex->
get_uv(
""));
316 }
else if (vertex->
has_uvw(
"")) {
317 vdef._uv3_index = record_unique(_unique_uv3, vertex->
get_uvw(
""));
320 if (vertex->has_normal()) {
321 vdef._norm_index = record_unique(_unique_norm, vertex->get_normal());
330 int EggToObjConverter::
331 record_unique(UniqueVertices &unique,
const LVecBase4d &vec) {
334 int index = unique.size();
335 UniqueVertices::iterator ui = unique.insert(UniqueVertices::value_type(vec, index)).first;
344 int EggToObjConverter::
345 record_unique(UniqueVertices &unique,
const LVecBase3d &vec) {
346 return record_unique(unique, LVecBase4d(vec[0], vec[1], vec[2], 0.0));
354 int EggToObjConverter::
355 record_unique(UniqueVertices &unique,
const LVecBase2d &vec) {
356 return record_unique(unique, LVecBase4d(vec[0], vec[1], 0.0, 0.0));
364 int EggToObjConverter::
365 record_unique(UniqueVertices &unique,
double pos) {
366 return record_unique(unique, LVecBase4d(pos, 0.0, 0.0, 0.0));
373 void EggToObjConverter::
374 write_vertices(ostream &out,
const string &prefix,
int num_components,
375 const UniqueVertices &unique) {
377 int num_vertices = (int)unique.size();
378 const LVecBase4d **vertices = (
const LVecBase4d **)PANDA_MALLOC_ARRAY(num_vertices *
sizeof(LVecBase4d *));
379 memset(vertices, 0, num_vertices *
sizeof(LVecBase4d *));
380 UniqueVertices::const_iterator ui;
381 for (ui = unique.begin(); ui != unique.end(); ++ui) {
382 int index = (*ui).second;
383 const LVecBase4d &vec = (*ui).first;
384 nassertv(index >= 0 && index < num_vertices);
385 nassertv(vertices[index] ==
nullptr);
386 vertices[index] = &vec;
389 for (
int i = 0; i < num_vertices; ++i) {
391 const LVecBase4d &vec = *(vertices[i]);
392 for (
int ci = 0; ci < num_components; ++ci) {
393 out <<
" " << vec[ci];
397 PANDA_FREE_ARRAY(vertices);
403 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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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),...
virtual std::string get_extension() const
Returns the common extension of the file type this converter supports.
A base class for nodes in the hierarchy that are not leaf nodes.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A hierarchy of directories and files that appears to be one continuous 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.
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 std::string get_name() const
Returns the English name of the file type this converter supports.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
const LTexCoord3d & get_uvw(const std::string &name) const
Returns the named UV coordinate triple on the vertex.
The name of a file, such as a texture file or an Egg file.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Any one-, two-, three-, or four-component vertex, possibly with attributes such as a normal.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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.
string trim(const string &str)
Returns a new string representing the contents of the given string with both leading and trailing whi...
static void close_write_file(std::ostream *stream)
Closes a file opened by a previous call to open_write_file().
std::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,...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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 has_uvw(const std::string &name) const
Returns true if the vertex has the named UV coordinate triple, and the named UV coordinate triple is ...
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.
double get_pos1() const
Only valid if get_num_dimensions() returns 1.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.