diff options
author | Aras Pranckevicius <aras@nesnausk.org> | 2022-06-14 10:19:02 +0300 |
---|---|---|
committer | Aras Pranckevicius <aras@nesnausk.org> | 2022-06-14 10:19:02 +0300 |
commit | 1b4f35f6a5889d8d2e65c6231e84f8b1744c4f96 (patch) | |
tree | cfae52865680308729ad955ad623c3151188097a /source/blender/io/wavefront_obj/importer/obj_import_file_reader.cc | |
parent | 827fa8176737f822b7f8d2354b05e59976c7101a (diff) |
obj: vertex colors support in importer and exporter
Adds support for vertex colors to OBJ I/O.
Importer:
- Supports both "xyzrgb" and "MRGB" vertex color formats.
- Whenever vertex color is present in the file for a model, it is
imported and a Color attribute is created (per-vertex, full float
color data type). Color coming from the file is assumed to be sRGB,
and is converted to linear upon import.
Exporter:
- Option to export the vertex colors. Defaults to "off", since not
all 3rd party software supports vertex colors.
- When the option is "on", if a mesh has a color attribute layer,
the active one is exported in "xyzrgb" form. If the mesh has
per-face-corner colors, they are averaged on the vertices.
Colors are converted from linear to sRGB upon export.
Reviewed By: Howard Trickey
Differential Revision: https://developer.blender.org/D15159
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.cc | 51 |
1 files changed, 50 insertions, 1 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 a627e7261e3..4a27d734819 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 @@ -5,12 +5,15 @@ */ #include "BLI_map.hh" +#include "BLI_math_color.h" #include "BLI_string_ref.hh" #include "BLI_vector.hh" #include "obj_import_file_reader.hh" #include "obj_import_string_utils.hh" +#include <charconv> + namespace blender::io::obj { using std::string; @@ -34,6 +37,7 @@ static Geometry *create_geometry(Geometry *const prev_geometry, g->geom_type_ = new_type; g->geometry_name_ = name.is_empty() ? "New object" : name; g->vertex_start_ = global_vertices.vertices.size(); + g->vertex_color_start_ = global_vertices.vertex_colors.size(); r_offset.set_index_offset(g->vertex_start_); return g; }; @@ -71,9 +75,51 @@ static void geom_add_vertex(Geometry *geom, GlobalVertices &r_global_vertices) { float3 vert; - parse_floats(p, end, 0.0f, vert, 3); + p = parse_floats(p, end, 0.0f, vert, 3); r_global_vertices.vertices.append(vert); geom->vertex_count_++; + /* OBJ extension: "xyzrgb" vertex colors, when the vertex position + * is followed by 3 more RGB color components. See + * http://paulbourke.net/dataformats/obj/colour.html */ + if (p < end) { + float3 srgb; + p = parse_floats(p, end, -1.0f, srgb, 3); + if (srgb.x >= 0 && srgb.y >= 0 && srgb.z >= 0) { + float3 linear; + srgb_to_linearrgb_v3_v3(linear, srgb); + r_global_vertices.vertex_colors.append(linear); + geom->vertex_color_count_++; + } + } +} + +static void geom_add_mrgb_colors(Geometry *geom, + const char *p, + const char *end, + GlobalVertices &r_global_vertices) +{ + /* MRGB color extension, in the form of + * "#MRGB MMRRGGBBMMRRGGBB ..." + * http://paulbourke.net/dataformats/obj/colour.html */ + p = drop_whitespace(p, end); + const int mrgb_length = 8; + 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) { + return; + } + unsigned char srgb[4]; + srgb[0] = (value >> 16) & 0xFF; + srgb[1] = (value >> 8) & 0xFF; + srgb[2] = value & 0xFF; + srgb[3] = 0xFF; + float linear[4]; + srgb_to_linearrgb_uchar4(linear, srgb); + r_global_vertices.vertex_colors.append({linear[0], linear[1], linear[2]}); + geom->vertex_color_count_++; + p += mrgb_length; + } } static void geom_add_vertex_normal(Geometry *geom, @@ -482,6 +528,9 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries, else if (parse_keyword(p, end, "mtllib")) { add_mtl_library(StringRef(p, end).trim()); } + else if (parse_keyword(p, end, "#MRGB")) { + geom_add_mrgb_colors(curr_geom, p, end, r_global_vertices); + } /* Comments. */ else if (*p == '#') { /* Nothing to do. */ |