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->texcoords.resize(num_vt * 2);
|
||||||
attrib->indices.resize(num_f);
|
attrib->indices.resize(num_f);
|
||||||
attrib->face_num_verts.resize(num_indices);
|
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 v_offsets[kMaxThreads];
|
||||||
size_t n_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 t_count = t_offsets[t];
|
||||||
size_t f_count = f_offsets[t];
|
size_t f_count = f_offsets[t];
|
||||||
size_t face_count = face_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++) {
|
for (size_t i = 0; i < commands[t].size(); i++) {
|
||||||
if (commands[t][i].type == COMMAND_EMPTY) {
|
if (commands[t][i].type == COMMAND_EMPTY) {
|
||||||
continue;
|
continue;
|
||||||
} else if (commands[t][i].type == COMMAND_USEMTL) {
|
} else if (commands[t][i].type == COMMAND_USEMTL) {
|
||||||
if (commands[t][i].material_name &&
|
if (commands[t][i].material_name &&
|
||||||
commands[t][i].material_name_len > 0) {
|
commands[t][i].material_name_len > 0 &&
|
||||||
std::string material_name(commands[t][i].material_name,
|
// check if there are still faces after this command
|
||||||
commands[t][i].material_name_len);
|
face_count < num_indices) {
|
||||||
|
// Find next face
|
||||||
if (material_map.find(material_name) != material_map.end()) {
|
bool found = false;
|
||||||
material_id = material_map[material_name];
|
size_t i_start = i + 1, t_next, i_next;
|
||||||
} else {
|
for (t_next = t; t_next < num_threads; t_next++) {
|
||||||
// Assign invalid material ID
|
for (i_next = i_start; i_next < commands[t_next].size(); i_next++) {
|
||||||
material_id = -1;
|
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) {
|
} 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);
|
index_t(vertex_index, texcoord_index, normal_index);
|
||||||
}
|
}
|
||||||
for (size_t k = 0; k < commands[t][i].f_num_verts.size(); k++) {
|
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] =
|
attrib->face_num_verts[face_count + k] =
|
||||||
commands[t][i].f_num_verts[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++) {
|
for (size_t t = 0; t < workers->size(); t++) {
|
||||||
workers[t].join();
|
workers[t].join();
|
||||||
}
|
}
|
||||||
if(material_map.size()>1&& num_threads>1) {
|
|
||||||
for (size_t t = 0; t < num_threads; t++) {
|
// To each face with uninitialized material id,
|
||||||
size_t face_count = face_offsets[t];
|
// assign the material id of the last face preceding it that has one
|
||||||
if (-1 == attrib->material_ids[face_count]) {
|
for (size_t face_count = 1; face_count < num_indices; ++face_count)
|
||||||
int prev_material_id = attrib->material_ids[face_count - 1];
|
if (attrib->material_ids[face_count] == -1)
|
||||||
size_t max_face_offset = (t == num_threads - 1) ? attrib->material_ids.size() : face_offsets[t + 1];
|
attrib->material_ids[face_count] = attrib->material_ids[face_count - 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto t_end = std::chrono::high_resolution_clock::now();
|
auto t_end = std::chrono::high_resolution_clock::now();
|
||||||
ms_merge = t_end - t_start;
|
ms_merge = t_end - t_start;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user