Skip to content

Commit 707014f

Browse files
authored
Update obj_writer.cc
1 parent 12837cc commit 707014f

File tree

1 file changed

+82
-92
lines changed

1 file changed

+82
-92
lines changed

examples/obj_sticher/obj_writer.cc

Lines changed: 82 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ bool WriteMat(const std::string& filename, const std::vector<tinyobj::material_t
3030
fprintf(fp, "Ke %f %f %f\n", mat.emission[0], mat.emission[1], mat.emission[2]);
3131
fprintf(fp, "Ns %f\n", mat.shininess);
3232
fprintf(fp, "Ni %f\n", mat.ior);
33+
fprintf(fp, "illum %d\n", mat.illum);
34+
fprintf(fp, "\n");
3335
// @todo { texture }
3436
}
3537

@@ -38,7 +40,7 @@ bool WriteMat(const std::string& filename, const std::vector<tinyobj::material_t
3840
return true;
3941
}
4042

41-
bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform) {
43+
bool WriteObj(const std::string& filename, const tinyobj::attrib_t& attributes, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform) {
4244
FILE* fp = fopen(filename.c_str(), "w");
4345
if (!fp) {
4446
fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
@@ -48,119 +50,107 @@ bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>&
4850
std::string basename = GetFileBasename(filename);
4951
std::string material_filename = basename + ".mtl";
5052

51-
int v_offset = 0;
52-
int vn_offset = 0;
53-
int vt_offset = 0;
5453
int prev_material_id = -1;
5554

56-
fprintf(fp, "mtllib %s\n", material_filename.c_str());
55+
fprintf(fp, "mtllib %s\n\n", material_filename.c_str());
5756

58-
for (size_t i = 0; i < shapes.size(); i++) {
57+
// facevarying vtx
58+
for (size_t k = 0; k < attributes.vertices.size(); k+=3) {
59+
if (coordTransform) {
60+
fprintf(fp, "v %f %f %f\n",
61+
attributes.vertices[k + 0],
62+
attributes.vertices[k + 2],
63+
-attributes.vertices[k + 1]);
64+
} else {
65+
fprintf(fp, "v %f %f %f\n",
66+
attributes.vertices[k + 0],
67+
attributes.vertices[k + 1],
68+
attributes.vertices[k + 2]);
69+
}
70+
}
5971

60-
bool has_vn = false;
61-
bool has_vt = false;
72+
fprintf(fp, "\n");
73+
74+
// facevarying normal
75+
for (size_t k = 0; k < attributes.normals.size(); k += 3) {
76+
if (coordTransform) {
77+
fprintf(fp, "vn %f %f %f\n",
78+
attributes.normals[k + 0],
79+
attributes.normals[k + 2],
80+
-attributes.normals[k + 1]);
81+
} else {
82+
fprintf(fp, "vn %f %f %f\n",
83+
attributes.normals[k + 0],
84+
attributes.normals[k + 1],
85+
attributes.normals[k + 2]);
86+
}
87+
}
88+
89+
fprintf(fp, "\n");
90+
91+
// facevarying texcoord
92+
for (size_t k = 0; k < attributes.texcoords.size(); k += 2) {
93+
fprintf(fp, "vt %f %f\n",
94+
attributes.texcoords[k + 0],
95+
attributes.texcoords[k + 1]);
96+
}
97+
98+
for (size_t i = 0; i < shapes.size(); i++) {
99+
fprintf(fp, "\n");
62100

63101
if (shapes[i].name.empty()) {
64102
fprintf(fp, "g Unknown\n");
65103
} else {
66104
fprintf(fp, "g %s\n", shapes[i].name.c_str());
67105
}
68106

69-
//if (!shapes[i].material.name.empty()) {
70-
// fprintf(fp, "usemtl %s\n", shapes[i].material.name.c_str());
71-
//}
72-
73-
// facevarying vtx
74-
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
75-
for (int j = 0; j < 3; j++) {
76-
int idx = shapes[i].mesh.indices[3*k+j];
77-
if (coordTransform) {
78-
fprintf(fp, "v %f %f %f\n",
79-
shapes[i].mesh.positions[3*idx+0],
80-
shapes[i].mesh.positions[3*idx+2],
81-
-shapes[i].mesh.positions[3*idx+1]);
82-
} else {
83-
fprintf(fp, "v %f %f %f\n",
84-
shapes[i].mesh.positions[3*idx+0],
85-
shapes[i].mesh.positions[3*idx+1],
86-
shapes[i].mesh.positions[3*idx+2]);
87-
}
88-
}
89-
}
90-
91-
// facevarying normal
92-
if (shapes[i].mesh.normals.size() > 0) {
93-
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
94-
for (int j = 0; j < 3; j++) {
95-
int idx = shapes[i].mesh.indices[3*k+j];
96-
if (coordTransform) {
97-
fprintf(fp, "vn %f %f %f\n",
98-
shapes[i].mesh.normals[3*idx+0],
99-
shapes[i].mesh.normals[3*idx+2],
100-
-shapes[i].mesh.normals[3*idx+1]);
101-
} else {
102-
fprintf(fp, "vn %f %f %f\n",
103-
shapes[i].mesh.normals[3*idx+0],
104-
shapes[i].mesh.normals[3*idx+1],
105-
shapes[i].mesh.normals[3*idx+2]);
106-
}
107-
}
108-
}
109-
}
110-
if (shapes[i].mesh.normals.size() > 0) has_vn = true;
111-
112-
// facevarying texcoord
113-
if (shapes[i].mesh.texcoords.size() > 0) {
114-
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
115-
for (int j = 0; j < 3; j++) {
116-
int idx = shapes[i].mesh.indices[3*k+j];
117-
fprintf(fp, "vt %f %f\n",
118-
shapes[i].mesh.texcoords[2*idx+0],
119-
shapes[i].mesh.texcoords[2*idx+1]);
120-
}
121-
}
107+
bool has_vn = false;
108+
bool has_vt = false;
109+
// Assumes normals and textures are set shape-wise.
110+
if(shapes[i].mesh.indices.size() > 0){
111+
has_vn = shapes[i].mesh.indices[0].normal_index != -1;
112+
has_vt = shapes[i].mesh.indices[0].texcoord_index != -1;
122113
}
123-
if (shapes[i].mesh.texcoords.size() > 0) has_vt = true;
124114

125115
// face
126-
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
127-
128-
// Face index is 1-base.
129-
//int v0 = shapes[i].mesh.indices[3*k+0] + 1 + v_offset;
130-
//int v1 = shapes[i].mesh.indices[3*k+1] + 1 + v_offset;
131-
//int v2 = shapes[i].mesh.indices[3*k+2] + 1 + v_offset;
132-
int v0 = (3*k + 0) + 1 + v_offset;
133-
int v1 = (3*k + 1) + 1 + v_offset;
134-
int v2 = (3*k + 2) + 1 + v_offset;
135-
136-
int vt0 = (3*k + 0) + 1 + vt_offset;
137-
int vt1 = (3*k + 1) + 1 + vt_offset;
138-
int vt2 = (3*k + 2) + 1 + vt_offset;
139-
140-
int material_id = shapes[i].mesh.material_ids[k];
116+
int face_index = 0;
117+
for (size_t k = 0; k < shapes[i].mesh.indices.size(); k += shapes[i].mesh.num_face_vertices[face_index++]) {
118+
// Check Materials
119+
int material_id = shapes[i].mesh.material_ids[face_index];
141120
if (material_id != prev_material_id) {
142121
std::string material_name = materials[material_id].name;
143122
fprintf(fp, "usemtl %s\n", material_name.c_str());
144123
prev_material_id = material_id;
145124
}
146125

147-
if (has_vn && has_vt) {
148-
fprintf(fp, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
149-
v0, vt0, v0, v1, vt1, v1, v2, vt2, v2);
150-
} else if (has_vn && !has_vt) {
151-
fprintf(fp, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2);
152-
} else if (!has_vn && has_vt) {
153-
fprintf(fp, "f %d/%d %d/%d %d/%d\n", v0, v0, v1, v1, v2, v2);
154-
} else {
155-
fprintf(fp, "f %d %d %d\n", v0, v1, v2);
126+
unsigned char v_per_f = shapes[i].mesh.num_face_vertices[face_index];
127+
// Imperformant, but if you want to have variable vertices per face, you need some kind of a dynamic loop.
128+
fprintf(fp, "f");
129+
for(int l = 0; l < v_per_f; l++){
130+
const tinyobj::index_t& ref = shapes[i].mesh.indices[k + l];
131+
if(has_vn && has_vt){
132+
// v0/t0/vn0
133+
fprintf(fp, " %d/%d/%d", ref.vertex_index + 1, ref.texcoord_index + 1, ref.normal_index + 1);
134+
continue;
135+
}
136+
if(has_vn && !has_vt){
137+
// v0//vn0
138+
fprintf(fp, " %d//%d", ref.vertex_index + 1, ref.normal_index + 1);
139+
continue;
140+
}
141+
if(!has_vn && has_vt){
142+
// v0/vt0
143+
fprintf(fp, " %d/%d", ref.vertex_index + 1, ref.texcoord_index + 1);
144+
continue;
145+
}
146+
if(!has_vn && !has_vt){
147+
// v0 v1 v2
148+
fprintf(fp, " %d", ref.vertex_index + 1);
149+
continue;
150+
}
156151
}
157-
152+
fprintf(fp, "\n");
158153
}
159-
160-
v_offset += shapes[i].mesh.indices.size();
161-
//vn_offset += shapes[i].mesh.normals.size() / 3;
162-
vt_offset += shapes[i].mesh.texcoords.size() / 2;
163-
164154
}
165155

166156
fclose(fp);

0 commit comments

Comments
 (0)