Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc')
-rw-r--r--source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc137
1 files changed, 98 insertions, 39 deletions
diff --git a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
index a32fd90594d..7d5f023af4b 100644
--- a/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
+++ b/source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc
@@ -10,9 +10,11 @@
#include "BLI_string_ref.hh"
#include "BLI_vector.hh"
+#include "obj_export_mtl.hh"
#include "obj_import_file_reader.hh"
#include "obj_import_string_utils.hh"
+#include <algorithm>
#include <charconv>
namespace blender::io::obj {
@@ -101,10 +103,10 @@ static void geom_add_mrgb_colors(const char *p, const char *end, GlobalVertices
while (p + mrgb_length <= end) {
uint32_t value = 0;
std::from_chars_result res = std::from_chars(p, p + mrgb_length, value, 16);
- if (res.ec == std::errc::invalid_argument || res.ec == std::errc::result_out_of_range) {
+ if (ELEM(res.ec, std::errc::invalid_argument, std::errc::result_out_of_range)) {
return;
}
- unsigned char srgb[4];
+ uchar srgb[4];
srgb[0] = (value >> 16) & 0xFF;
srgb[1] = (value >> 8) & 0xFF;
srgb[2] = value & 0xFF;
@@ -162,7 +164,7 @@ static void geom_add_edge(Geometry *geom,
edge_v1 += edge_v1 < 0 ? r_global_vertices.vertices.size() : -1;
edge_v2 += edge_v2 < 0 ? r_global_vertices.vertices.size() : -1;
BLI_assert(edge_v1 >= 0 && edge_v2 >= 0);
- geom->edges_.append({static_cast<uint>(edge_v1), static_cast<uint>(edge_v2)});
+ geom->edges_.append({uint(edge_v1), uint(edge_v2)});
geom->track_vertex_index(edge_v1);
geom->track_vertex_index(edge_v2);
}
@@ -214,7 +216,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid vertex index %i (valid range [0, %zu)), ignoring face\n",
corner.vert_index,
- (size_t)global_vertices.vertices.size());
+ size_t(global_vertices.vertices.size()));
face_valid = false;
}
else {
@@ -226,7 +228,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid UV index %i (valid range [0, %zu)), ignoring face\n",
corner.uv_vert_index,
- (size_t)global_vertices.uv_vertices.size());
+ size_t(global_vertices.uv_vertices.size()));
face_valid = false;
}
}
@@ -242,7 +244,7 @@ static void geom_add_polygon(Geometry *geom,
fprintf(stderr,
"Invalid normal index %i (valid range [0, %zu)), ignoring face\n",
corner.vertex_normal_index,
- (size_t)global_vertices.vertex_normals.size());
+ size_t(global_vertices.vertex_normals.size()));
face_valid = false;
}
}
@@ -394,6 +396,22 @@ static bool parse_keyword(const char *&p, const char *end, StringRef keyword)
return true;
}
+/* Special case: if there were no faces/edges in any geometries,
+ * treat all the vertices as a point cloud. */
+static void use_all_vertices_if_no_faces(Geometry *geom,
+ const Vector<std::unique_ptr<Geometry>> &all_geometries,
+ const GlobalVertices &global_vertices)
+{
+ if (!global_vertices.vertices.is_empty() && geom && geom->geom_type_ == GEOM_MESH) {
+ if (std::all_of(
+ all_geometries.begin(), all_geometries.end(), [](const std::unique_ptr<Geometry> &g) {
+ return g->get_vertex_count() == 0;
+ })) {
+ geom->track_all_vertices(global_vertices.vertices.size());
+ }
+ }
+}
+
void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
GlobalVertices &r_global_vertices)
{
@@ -467,7 +485,7 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
/* Parse the buffer (until last newline) that we have so far,
* line by line. */
- StringRef buffer_str{buffer.data(), (int64_t)last_nl};
+ StringRef buffer_str{buffer.data(), int64_t(last_nl)};
while (!buffer_str.is_empty()) {
StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
@@ -490,6 +508,15 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
}
/* Faces. */
else if (parse_keyword(p, end, "f")) {
+ /* If we don't have a material index assigned yet, get one.
+ * It means "usemtl" state came from the previous object. */
+ if (state_material_index == -1 && !state_material_name.empty() &&
+ curr_geom->material_indices_.is_empty()) {
+ curr_geom->material_indices_.add_new(state_material_name, 0);
+ curr_geom->material_order_.append(state_material_name);
+ state_material_index = 0;
+ }
+
geom_add_polygon(curr_geom,
p,
end,
@@ -506,7 +533,10 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
else if (parse_keyword(p, end, "o")) {
state_shaded_smooth = false;
state_group_name = "";
- state_material_name = "";
+ /* Reset object-local material index that's used in face infos.
+ * NOTE: do not reset the material name; that has to carry over
+ * into the next object if needed. */
+ state_material_index = -1;
curr_geom = create_geometry(
curr_geom, GEOM_MESH, StringRef(p, end).trim(), r_all_geometries);
}
@@ -571,39 +601,44 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries,
buffer_offset = left_size;
}
+ use_all_vertices_if_no_faces(curr_geom, r_all_geometries, r_global_vertices);
add_default_mtl_library();
}
-static eMTLSyntaxElement mtl_line_start_to_enum(const char *&p, const char *end)
+static MTLTexMapType mtl_line_start_to_texture_type(const char *&p, const char *end)
{
if (parse_keyword(p, end, "map_Kd")) {
- return eMTLSyntaxElement::map_Kd;
+ return MTLTexMapType::Color;
}
if (parse_keyword(p, end, "map_Ks")) {
- return eMTLSyntaxElement::map_Ks;
+ return MTLTexMapType::Specular;
}
if (parse_keyword(p, end, "map_Ns")) {
- return eMTLSyntaxElement::map_Ns;
+ return MTLTexMapType::SpecularExponent;
}
if (parse_keyword(p, end, "map_d")) {
- return eMTLSyntaxElement::map_d;
+ return MTLTexMapType::Alpha;
}
- if (parse_keyword(p, end, "refl")) {
- return eMTLSyntaxElement::map_refl;
- }
- if (parse_keyword(p, end, "map_refl")) {
- return eMTLSyntaxElement::map_refl;
+ if (parse_keyword(p, end, "refl") || parse_keyword(p, end, "map_refl")) {
+ return MTLTexMapType::Reflection;
}
if (parse_keyword(p, end, "map_Ke")) {
- return eMTLSyntaxElement::map_Ke;
+ return MTLTexMapType::Emission;
+ }
+ if (parse_keyword(p, end, "bump") || parse_keyword(p, end, "map_Bump") ||
+ parse_keyword(p, end, "map_bump")) {
+ return MTLTexMapType::Normal;
}
- if (parse_keyword(p, end, "bump")) {
- return eMTLSyntaxElement::map_Bump;
+ if (parse_keyword(p, end, "map_Pr")) {
+ return MTLTexMapType::Roughness;
}
- if (parse_keyword(p, end, "map_Bump") || parse_keyword(p, end, "map_bump")) {
- return eMTLSyntaxElement::map_Bump;
+ if (parse_keyword(p, end, "map_Pm")) {
+ return MTLTexMapType::Metallic;
}
- return eMTLSyntaxElement::string;
+ if (parse_keyword(p, end, "map_Ps")) {
+ return MTLTexMapType::Sheen;
+ }
+ return MTLTexMapType::Count;
}
static const std::pair<StringRef, int> unsupported_texture_options[] = {
@@ -621,7 +656,7 @@ static const std::pair<StringRef, int> unsupported_texture_options[] = {
static bool parse_texture_option(const char *&p,
const char *end,
MTLMaterial *material,
- tex_map_XX &tex_map)
+ MTLTexMap &tex_map)
{
p = drop_whitespace(p, end);
if (parse_keyword(p, end, "-o")) {
@@ -633,7 +668,7 @@ static bool parse_texture_option(const char *&p,
return true;
}
if (parse_keyword(p, end, "-bm")) {
- p = parse_float(p, end, 1.0f, material->map_Bump_strength, true, true);
+ p = parse_float(p, end, 1.0f, material->normal_strength, true, true);
return true;
}
if (parse_keyword(p, end, "-type")) {
@@ -675,13 +710,13 @@ static void parse_texture_map(const char *p,
if (!is_map && !is_refl && !is_bump) {
return;
}
- eMTLSyntaxElement key = mtl_line_start_to_enum(p, end);
- if (key == eMTLSyntaxElement::string || !material->texture_maps.contains(key)) {
+ MTLTexMapType key = mtl_line_start_to_texture_type(p, end);
+ if (key == MTLTexMapType::Count) {
/* No supported texture map found. */
std::cerr << "OBJ import: MTL texture map type not supported: '" << line << "'" << std::endl;
return;
}
- tex_map_XX &tex_map = material->texture_maps.lookup(key);
+ MTLTexMap &tex_map = material->tex_map_of_type(key);
tex_map.mtl_dir_path = mtl_dir_path;
/* Parse texture map options. */
@@ -730,7 +765,7 @@ MTLParser::MTLParser(StringRefNull mtl_library, StringRefNull obj_filepath)
{
char obj_file_dir[FILE_MAXDIR];
BLI_split_dir_part(obj_filepath.data(), obj_file_dir, FILE_MAXDIR);
- BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data(), NULL);
+ BLI_path_join(mtl_file_path_, FILE_MAX, obj_file_dir, mtl_library.data());
BLI_split_dir_part(mtl_file_path_, mtl_dir_path_, FILE_MAXDIR);
}
@@ -745,7 +780,7 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
MTLMaterial *material = nullptr;
- StringRef buffer_str{(const char *)buffer, (int64_t)buffer_len};
+ StringRef buffer_str{(const char *)buffer, int64_t(buffer_len)};
while (!buffer_str.is_empty()) {
const StringRef line = read_next_line(buffer_str);
const char *p = line.begin(), *end = line.end();
@@ -766,31 +801,55 @@ void MTLParser::parse_and_store(Map<string, std::unique_ptr<MTLMaterial>> &r_mat
}
else if (material != nullptr) {
if (parse_keyword(p, end, "Ns")) {
- parse_float(p, end, 324.0f, material->Ns);
+ parse_float(p, end, 324.0f, material->spec_exponent);
}
else if (parse_keyword(p, end, "Ka")) {
- parse_floats(p, end, 0.0f, material->Ka, 3);
+ parse_floats(p, end, 0.0f, material->ambient_color, 3);
}
else if (parse_keyword(p, end, "Kd")) {
- parse_floats(p, end, 0.8f, material->Kd, 3);
+ parse_floats(p, end, 0.8f, material->color, 3);
}
else if (parse_keyword(p, end, "Ks")) {
- parse_floats(p, end, 0.5f, material->Ks, 3);
+ parse_floats(p, end, 0.5f, material->spec_color, 3);
}
else if (parse_keyword(p, end, "Ke")) {
- parse_floats(p, end, 0.0f, material->Ke, 3);
+ parse_floats(p, end, 0.0f, material->emission_color, 3);
}
else if (parse_keyword(p, end, "Ni")) {
- parse_float(p, end, 1.45f, material->Ni);
+ parse_float(p, end, 1.45f, material->ior);
}
else if (parse_keyword(p, end, "d")) {
- parse_float(p, end, 1.0f, material->d);
+ parse_float(p, end, 1.0f, material->alpha);
}
else if (parse_keyword(p, end, "illum")) {
/* Some files incorrectly use a float (T60135). */
float val;
parse_float(p, end, 1.0f, val);
- material->illum = val;
+ material->illum_mode = val;
+ }
+ else if (parse_keyword(p, end, "Pr")) {
+ parse_float(p, end, 0.5f, material->roughness);
+ }
+ else if (parse_keyword(p, end, "Pm")) {
+ parse_float(p, end, 0.0f, material->metallic);
+ }
+ else if (parse_keyword(p, end, "Ps")) {
+ parse_float(p, end, 0.0f, material->sheen);
+ }
+ else if (parse_keyword(p, end, "Pc")) {
+ parse_float(p, end, 0.0f, material->cc_thickness);
+ }
+ else if (parse_keyword(p, end, "Pcr")) {
+ parse_float(p, end, 0.0f, material->cc_roughness);
+ }
+ else if (parse_keyword(p, end, "aniso")) {
+ parse_float(p, end, 0.0f, material->aniso);
+ }
+ else if (parse_keyword(p, end, "anisor")) {
+ parse_float(p, end, 0.0f, material->aniso_rot);
+ }
+ else if (parse_keyword(p, end, "Kt") || parse_keyword(p, end, "Tf")) {
+ parse_floats(p, end, 0.0f, material->transmit_color, 3);
}
else {
parse_texture_map(p, end, material, mtl_dir_path_);