Material ids were not assigned to faces if the

first face with this material was in another thread buffer than where
the usemtl command was
This commit is contained in:
Victor Ripplinger
2018-02-21 11:36:36 +01:00
parent 16f3041c76
commit 72529f02fe

View File

@@ -1492,7 +1492,7 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
attrib->texcoords.resize(num_vt * 2);
attrib->indices.resize(num_f);
attrib->face_num_verts.resize(num_indices);
attrib->material_ids.resize(num_indices);
attrib->material_ids.resize(num_indices, -1);
size_t v_offsets[kMaxThreads];
size_t n_offsets[kMaxThreads];
@@ -1523,22 +1523,44 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
size_t t_count = t_offsets[t];
size_t f_count = f_offsets[t];
size_t face_count = face_offsets[t];
int material_id = -1; // -1 = default unknown material.
int material_id = -1; // -1 = default unknown material.
for (size_t i = 0; i < commands[t].size(); i++) {
if (commands[t][i].type == COMMAND_EMPTY) {
continue;
} else if (commands[t][i].type == COMMAND_USEMTL) {
if (commands[t][i].material_name &&
commands[t][i].material_name_len > 0) {
std::string material_name(commands[t][i].material_name,
commands[t][i].material_name_len);
if (material_map.find(material_name) != material_map.end()) {
material_id = material_map[material_name];
} else {
// Assign invalid material ID
material_id = -1;
commands[t][i].material_name_len > 0 &&
// check if there are still faces after this command
face_count < num_indices) {
// Find next face
bool found = false;
size_t i_start = i + 1, t_next, i_next;
for (t_next = t; t_next < num_threads; t_next++) {
for (i_next = i_start; i_next < commands[t_next].size(); i_next++) {
if (commands[t_next][i_next].type == COMMAND_F) {
found = true;
break;
}
}
if (found)
break;
i_start = 0;
}
// Assign material to this face
if (found) {
std::string material_name(commands[t][i].material_name,
commands[t][i].material_name_len);
for (size_t k = 0; k < commands[t_next][i_next].f_num_verts.size(); k++) {
if (material_map.find(material_name) != material_map.end()) {
attrib->material_ids[face_count + k] = material_map[material_name];
} else {
// Assign invalid material ID
// Set a different value than the default, to
// prevent following faces from being assigned a valid material
attrib->material_ids[face_count + k] = -2;
}
}
}
}
} else if (commands[t][i].type == COMMAND_V) {
@@ -1565,7 +1587,6 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
index_t(vertex_index, texcoord_index, normal_index);
}
for (size_t k = 0; k < commands[t][i].f_num_verts.size(); k++) {
attrib->material_ids[face_count + k] = material_id;
attrib->face_num_verts[face_count + k] =
commands[t][i].f_num_verts[k];
}
@@ -1580,19 +1601,13 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
for (size_t t = 0; t < workers->size(); t++) {
workers[t].join();
}
if(material_map.size()>1&& num_threads>1) {
for (size_t t = 0; t < num_threads; t++) {
size_t face_count = face_offsets[t];
if (-1 == attrib->material_ids[face_count]) {
int prev_material_id = attrib->material_ids[face_count - 1];
size_t max_face_offset = (t == num_threads - 1) ? attrib->material_ids.size() : face_offsets[t + 1];
for (int i = face_count; i<max_face_offset; ++i) {
if (attrib->material_ids[i] != -1) break;
attrib->material_ids[i] = prev_material_id;
}
}
}
}
// To each face with uninitialized material id,
// assign the material id of the last face preceding it that has one
for (size_t face_count = 1; face_count < num_indices; ++face_count)
if (attrib->material_ids[face_count] == -1)
attrib->material_ids[face_count] = attrib->material_ids[face_count - 1];
auto t_end = std::chrono::high_resolution_clock::now();
ms_merge = t_end - t_start;
}