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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user