diff options
11 files changed, 371 insertions, 542 deletions
diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index 66dd71d4246..9bcc061caf7 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -44,7 +44,7 @@ static const char *DEFORM_GROUP_DISABLED = "off"; * So an empty material name is written. */ static const char *MATERIAL_GROUP_DISABLED = ""; -void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_vert_uv_normal_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> uv_indices, @@ -57,12 +57,12 @@ void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, const int uv_offset = offsets.uv_vertex_offset + 1; const int normal_offset = offsets.normal_offset + 1; const int n = vert_indices.size(); - fh.write<eOBJSyntaxElement::poly_element_begin>(); + fh.write_obj_poly_begin(); if (!flip) { for (int j = 0; j < n; ++j) { - fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>(vert_indices[j] + vertex_offset, - uv_indices[j] + uv_offset, - normal_indices[j] + normal_offset); + fh.write_obj_poly_v_uv_normal(vert_indices[j] + vertex_offset, + uv_indices[j] + uv_offset, + normal_indices[j] + normal_offset); } } else { @@ -71,15 +71,15 @@ void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, * then go backwards. Same logic in other write_*_indices functions below. */ for (int k = 0; k < n; ++k) { int j = k == 0 ? 0 : n - k; - fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>(vert_indices[j] + vertex_offset, - uv_indices[j] + uv_offset, - normal_indices[j] + normal_offset); + fh.write_obj_poly_v_uv_normal(vert_indices[j] + vertex_offset, + uv_indices[j] + uv_offset, + normal_indices[j] + normal_offset); } } - fh.write<eOBJSyntaxElement::poly_element_end>(); + fh.write_obj_poly_end(); } -void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_vert_normal_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> /*uv_indices*/, @@ -90,24 +90,24 @@ void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh, const int vertex_offset = offsets.vertex_offset + 1; const int normal_offset = offsets.normal_offset + 1; const int n = vert_indices.size(); - fh.write<eOBJSyntaxElement::poly_element_begin>(); + fh.write_obj_poly_begin(); if (!flip) { for (int j = 0; j < n; ++j) { - fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + vertex_offset, - normal_indices[j] + normal_offset); + fh.write_obj_poly_v_normal(vert_indices[j] + vertex_offset, + normal_indices[j] + normal_offset); } } else { for (int k = 0; k < n; ++k) { int j = k == 0 ? 0 : n - k; - fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + vertex_offset, - normal_indices[j] + normal_offset); + fh.write_obj_poly_v_normal(vert_indices[j] + vertex_offset, + normal_indices[j] + normal_offset); } } - fh.write<eOBJSyntaxElement::poly_element_end>(); + fh.write_obj_poly_end(); } -void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_vert_uv_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> uv_indices, @@ -118,24 +118,22 @@ void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh, const int vertex_offset = offsets.vertex_offset + 1; const int uv_offset = offsets.uv_vertex_offset + 1; const int n = vert_indices.size(); - fh.write<eOBJSyntaxElement::poly_element_begin>(); + fh.write_obj_poly_begin(); if (!flip) { for (int j = 0; j < n; ++j) { - fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + vertex_offset, - uv_indices[j] + uv_offset); + fh.write_obj_poly_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset); } } else { for (int k = 0; k < n; ++k) { int j = k == 0 ? 0 : n - k; - fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + vertex_offset, - uv_indices[j] + uv_offset); + fh.write_obj_poly_v_uv(vert_indices[j] + vertex_offset, uv_indices[j] + uv_offset); } } - fh.write<eOBJSyntaxElement::poly_element_end>(); + fh.write_obj_poly_end(); } -void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_vert_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> /*uv_indices*/, @@ -144,27 +142,27 @@ void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh, { const int vertex_offset = offsets.vertex_offset + 1; const int n = vert_indices.size(); - fh.write<eOBJSyntaxElement::poly_element_begin>(); + fh.write_obj_poly_begin(); if (!flip) { for (int j = 0; j < n; ++j) { - fh.write<eOBJSyntaxElement::vertex_indices>(vert_indices[j] + vertex_offset); + fh.write_obj_poly_v(vert_indices[j] + vertex_offset); } } else { for (int k = 0; k < n; ++k) { int j = k == 0 ? 0 : n - k; - fh.write<eOBJSyntaxElement::vertex_indices>(vert_indices[j] + vertex_offset); + fh.write_obj_poly_v(vert_indices[j] + vertex_offset); } } - fh.write<eOBJSyntaxElement::poly_element_end>(); + fh.write_obj_poly_end(); } void OBJWriter::write_header() const { using namespace std::string_literals; - FormatHandler<eFileType::OBJ> fh; - fh.write<eOBJSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + "\n"); - fh.write<eOBJSyntaxElement::string>("# www.blender.org\n"); + FormatHandler fh; + fh.write_string("# Blender "s + BKE_blender_version_string()); + fh.write_string("# www.blender.org"); fh.write_to_file(outfile_); } @@ -174,8 +172,8 @@ void OBJWriter::write_mtllib_name(const StringRefNull mtl_filepath) const char mtl_file_name[FILE_MAXFILE]; char mtl_dir_name[FILE_MAXDIR]; BLI_split_dirfile(mtl_filepath.data(), mtl_dir_name, mtl_file_name, FILE_MAXDIR, FILE_MAXFILE); - FormatHandler<eFileType::OBJ> fh; - fh.write<eOBJSyntaxElement::mtllib>(mtl_file_name); + FormatHandler fh; + fh.write_obj_mtllib(mtl_file_name); fh.write_to_file(outfile_); } @@ -184,18 +182,17 @@ static void spaces_to_underscores(std::string &r_name) std::replace(r_name.begin(), r_name.end(), ' ', '_'); } -void OBJWriter::write_object_name(FormatHandler<eFileType::OBJ> &fh, - const OBJMesh &obj_mesh_data) const +void OBJWriter::write_object_name(FormatHandler &fh, const OBJMesh &obj_mesh_data) const { std::string object_name = obj_mesh_data.get_object_name(); spaces_to_underscores(object_name); if (export_params_.export_object_groups) { std::string mesh_name = obj_mesh_data.get_object_mesh_name(); spaces_to_underscores(mesh_name); - fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + mesh_name); + fh.write_obj_group(object_name + "_" + mesh_name); return; } - fh.write<eOBJSyntaxElement::object_name>(object_name); + fh.write_obj_object(object_name); } /* Split up large meshes into multi-threaded jobs; each job processes @@ -213,9 +210,7 @@ static int calc_chunk_count(int count) * will be written into the final /fh/ buffer at the end. */ template<typename Function> -void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh, - int tot_count, - const Function &function) +void obj_parallel_chunked_output(FormatHandler &fh, int tot_count, const Function &function) { if (tot_count <= 0) { return; @@ -231,7 +226,7 @@ void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh, return; } /* Give each chunk its own temporary output buffer, and process them in parallel. */ - std::vector<FormatHandler<eFileType::OBJ>> buffers(chunk_count); + std::vector<FormatHandler> buffers(chunk_count); blender::threading::parallel_for(IndexRange(chunk_count), 1, [&](IndexRange range) { for (const int r : range) { int i_start = r * chunk_size; @@ -248,7 +243,7 @@ void obj_parallel_chunked_output(FormatHandler<eFileType::OBJ> &fh, } } -void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_vertex_coords(FormatHandler &fh, const OBJMesh &obj_mesh_data, bool write_colors) const { @@ -265,41 +260,40 @@ void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, colors_layer->name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); BLI_assert(tot_count == attribute.size()); - obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) { + obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) { float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor); ColorGeometry4f linear = attribute.get(i); float srgb[3]; linearrgb_to_srgb_v3_v3(srgb, linear); - buf.write<eOBJSyntaxElement::vertex_coords_color>( - vertex[0], vertex[1], vertex[2], srgb[0], srgb[1], srgb[2]); + buf.write_obj_vertex_color(vertex[0], vertex[1], vertex[2], srgb[0], srgb[1], srgb[2]); }); } else { - obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) { + obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) { float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor); - buf.write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]); + buf.write_obj_vertex(vertex[0], vertex[1], vertex[2]); }); } } -void OBJWriter::write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &r_obj_mesh_data) const +void OBJWriter::write_uv_coords(FormatHandler &fh, OBJMesh &r_obj_mesh_data) const { const Vector<float2> &uv_coords = r_obj_mesh_data.get_uv_coords(); const int tot_count = uv_coords.size(); - obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) { + obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) { const float2 &uv_vertex = uv_coords[i]; - buf.write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]); + buf.write_obj_uv(uv_vertex[0], uv_vertex[1]); }); } -void OBJWriter::write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data) +void OBJWriter::write_poly_normals(FormatHandler &fh, OBJMesh &obj_mesh_data) { /* Poly normals should be calculated earlier via store_normal_coords_and_indices. */ const Vector<float3> &normal_coords = obj_mesh_data.get_normal_coords(); const int tot_count = normal_coords.size(); - obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler<eFileType::OBJ> &buf, int i) { + obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) { const float3 &normal = normal_coords[i]; - buf.write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]); + buf.write_obj_normal(normal[0], normal[1], normal[2]); }); } @@ -334,7 +328,7 @@ static int get_smooth_group(const OBJMesh &mesh, const OBJExportParams ¶ms, return group; } -void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_poly_elements(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data, std::function<const char *(int)> matname_fn) @@ -346,7 +340,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, const int tot_deform_groups = obj_mesh_data.tot_deform_groups(); threading::EnumerableThreadSpecific<Vector<float>> group_weights; - obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler<eFileType::OBJ> &buf, int idx) { + obj_parallel_chunked_output(fh, tot_polygons, [&](FormatHandler &buf, int idx) { /* Polygon order for writing into the file is not necessarily the same * as order in the mesh; it will be sorted by material indices. Remap current * and previous indices here according to the order. */ @@ -362,7 +356,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, const int prev_group = get_smooth_group(obj_mesh_data, export_params_, prev_i); const int group = get_smooth_group(obj_mesh_data, export_params_, i); if (group != prev_group) { - buf.write<eOBJSyntaxElement::smooth_group>(group); + buf.write_obj_smooth(group); } } @@ -375,9 +369,8 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, prev_i, local_weights); const int16_t group = obj_mesh_data.get_poly_deform_group_index(i, local_weights); if (group != prev_group) { - buf.write<eOBJSyntaxElement::object_group>( - group == NOT_FOUND ? DEFORM_GROUP_DISABLED : - obj_mesh_data.get_poly_deform_group_name(group)); + buf.write_obj_group(group == NOT_FOUND ? DEFORM_GROUP_DISABLED : + obj_mesh_data.get_poly_deform_group_name(group)); } } @@ -387,7 +380,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, const int16_t mat = obj_mesh_data.ith_poly_matnr(i); if (mat != prev_mat) { if (mat == NOT_FOUND) { - buf.write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED); + buf.write_obj_usemtl(MATERIAL_GROUP_DISABLED); } else { const char *mat_name = matname_fn(mat); @@ -397,9 +390,9 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, if (export_params_.export_material_groups) { std::string object_name = obj_mesh_data.get_object_name(); spaces_to_underscores(object_name); - fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + mat_name); + fh.write_obj_group(object_name + "_" + mat_name); } - buf.write<eOBJSyntaxElement::poly_usemtl>(mat_name); + buf.write_obj_usemtl(mat_name); } } } @@ -414,7 +407,7 @@ void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, }); } -void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh, +void OBJWriter::write_edges_indices(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data) const { @@ -426,13 +419,12 @@ void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh, if (!vertex_indices) { continue; } - fh.write<eOBJSyntaxElement::edge>((*vertex_indices)[0] + offsets.vertex_offset + 1, - (*vertex_indices)[1] + offsets.vertex_offset + 1); + fh.write_obj_edge((*vertex_indices)[0] + offsets.vertex_offset + 1, + (*vertex_indices)[1] + offsets.vertex_offset + 1); } } -void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, - const OBJCurve &obj_nurbs_data) const +void OBJWriter::write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_data) const { const int total_splines = obj_nurbs_data.total_splines(); for (int spline_idx = 0; spline_idx < total_splines; spline_idx++) { @@ -440,15 +432,14 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, for (int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) { const float3 vertex_coords = obj_nurbs_data.vertex_coordinates( spline_idx, vertex_idx, export_params_.scaling_factor); - fh.write<eOBJSyntaxElement::vertex_coords>( - vertex_coords[0], vertex_coords[1], vertex_coords[2]); + fh.write_obj_vertex(vertex_coords[0], vertex_coords[1], vertex_coords[2]); } const char *nurbs_name = obj_nurbs_data.get_curve_name(); const int nurbs_degree = obj_nurbs_data.get_nurbs_degree(spline_idx); - fh.write<eOBJSyntaxElement::object_group>(nurbs_name); - fh.write<eOBJSyntaxElement::cstype>(); - fh.write<eOBJSyntaxElement::nurbs_degree>(nurbs_degree); + fh.write_obj_group(nurbs_name); + fh.write_obj_cstype(); + fh.write_obj_nurbs_degree(nurbs_degree); /** * The numbers written here are indices into the vertex coordinates written * earlier, relative to the line that is going to be written. @@ -457,13 +448,13 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, * 0.0 1.0 -1 -2 -3 -4 -1 -2 -3 for a cyclic curve with 4 vertices. */ const int total_control_points = obj_nurbs_data.total_spline_control_points(spline_idx); - fh.write<eOBJSyntaxElement::curve_element_begin>(); + fh.write_obj_curve_begin(); for (int i = 0; i < total_control_points; i++) { /* "+1" to keep indices one-based, even if they're negative: i.e., -1 refers to the * last vertex coordinate, -2 second last. */ - fh.write<eOBJSyntaxElement::vertex_indices>(-((i % total_vertices) + 1)); + fh.write_obj_poly_v(-((i % total_vertices) + 1)); } - fh.write<eOBJSyntaxElement::curve_element_end>(); + fh.write_obj_curve_end(); /** * In `parm u 0 0.1 ..` line:, (total control points + 2) equidistant numbers in the @@ -474,7 +465,7 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, const short flagsu = obj_nurbs_data.get_nurbs_flagu(spline_idx); const bool cyclic = flagsu & CU_NURB_CYCLIC; const bool endpoint = !cyclic && (flagsu & CU_NURB_ENDPOINT); - fh.write<eOBJSyntaxElement::nurbs_parameter_begin>(); + fh.write_obj_nurbs_parm_begin(); for (int i = 1; i <= total_control_points + 2; i++) { float parm = 1.0f * i / (total_control_points + 2 + 1); if (endpoint) { @@ -485,11 +476,10 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, parm = 1; } } - fh.write<eOBJSyntaxElement::nurbs_parameters>(parm); + fh.write_obj_nurbs_parm(parm); } - fh.write<eOBJSyntaxElement::nurbs_parameter_end>(); - - fh.write<eOBJSyntaxElement::nurbs_group_end>(); + fh.write_obj_nurbs_parm_end(); + fh.write_obj_nurbs_group_end(); } } @@ -497,6 +487,18 @@ void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, /** \name .MTL writers. * \{ */ +static const char *tex_map_type_to_string[] = { + "map_Kd", + "map_Ks", + "map_Ns", + "map_d", + "map_refl", + "map_Ke", + "map_Bump", +}; +BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_string) == (int)MTLTexMapType::Count, + "array size mismatch"); + /** * Convert #float3 to string of space-separated numbers, with no leading or trailing space. * Only to be used in NON-performance-critical code. @@ -537,9 +539,9 @@ void MTLWriter::write_header(const char *blen_filepath) const char *blen_basename = (blen_filepath && blen_filepath[0] != '\0') ? BLI_path_basename(blen_filepath) : "None"; - fmt_handler_.write<eMTLSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + - " MTL File: '" + blen_basename + "'\n"); - fmt_handler_.write<eMTLSyntaxElement::string>("# www.blender.org\n"); + fmt_handler_.write_string("# Blender "s + BKE_blender_version_string() + " MTL File: '" + + blen_basename + "'"); + fmt_handler_.write_string("# www.blender.org"); } StringRefNull MTLWriter::mtl_file_path() const @@ -552,67 +554,52 @@ void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl) /* For various material properties, we only capture information * coming from the texture, or the default value of the socket. * When the texture is present, do not emit the default value. */ - if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ns).is_valid()) { - fmt_handler_.write<eMTLSyntaxElement::Ns>(mtl.Ns); + if (!mtl.tex_map_of_type(MTLTexMapType::Ns).is_valid()) { + fmt_handler_.write_mtl_float("Ns", mtl.Ns); } - fmt_handler_.write<eMTLSyntaxElement::Ka>(mtl.Ka.x, mtl.Ka.y, mtl.Ka.z); - if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Kd).is_valid()) { - fmt_handler_.write<eMTLSyntaxElement::Kd>(mtl.Kd.x, mtl.Kd.y, mtl.Kd.z); + fmt_handler_.write_mtl_float3("Ka", mtl.Ka.x, mtl.Ka.y, mtl.Ka.z); + if (!mtl.tex_map_of_type(MTLTexMapType::Kd).is_valid()) { + fmt_handler_.write_mtl_float3("Kd", mtl.Kd.x, mtl.Kd.y, mtl.Kd.z); } - if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ks).is_valid()) { - fmt_handler_.write<eMTLSyntaxElement::Ks>(mtl.Ks.x, mtl.Ks.y, mtl.Ks.z); + if (!mtl.tex_map_of_type(MTLTexMapType::Ks).is_valid()) { + fmt_handler_.write_mtl_float3("Ks", mtl.Ks.x, mtl.Ks.y, mtl.Ks.z); } - if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_Ke).is_valid()) { - fmt_handler_.write<eMTLSyntaxElement::Ke>(mtl.Ke.x, mtl.Ke.y, mtl.Ke.z); + if (!mtl.tex_map_of_type(MTLTexMapType::Ke).is_valid()) { + fmt_handler_.write_mtl_float3("Ke", mtl.Ke.x, mtl.Ke.y, mtl.Ke.z); } - fmt_handler_.write<eMTLSyntaxElement::Ni>(mtl.Ni); - if (!mtl.tex_map_of_type(eMTLSyntaxElement::map_d).is_valid()) { - fmt_handler_.write<eMTLSyntaxElement::d>(mtl.d); + fmt_handler_.write_mtl_float("Ni", mtl.Ni); + if (!mtl.tex_map_of_type(MTLTexMapType::d).is_valid()) { + fmt_handler_.write_mtl_float("d", mtl.d); } - fmt_handler_.write<eMTLSyntaxElement::illum>(mtl.illum); + fmt_handler_.write_mtl_illum(mtl.illum); } -void MTLWriter::write_texture_map( - const MTLMaterial &mtl_material, - const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map, - const char *blen_filedir, - const char *dest_dir, - ePathReferenceMode path_mode, - Set<std::pair<std::string, std::string>> ©_set) +void MTLWriter::write_texture_map(const MTLMaterial &mtl_material, + MTLTexMapType texture_key, + const MTLTexMap &texture_map, + const char *blen_filedir, + const char *dest_dir, + ePathReferenceMode path_mode, + Set<std::pair<std::string, std::string>> ©_set) { std::string options; /* Option strings should have their own leading spaces. */ - if (texture_map.value.translation != float3{0.0f, 0.0f, 0.0f}) { - options.append(" -o ").append(float3_to_string(texture_map.value.translation)); + if (texture_map.translation != float3{0.0f, 0.0f, 0.0f}) { + options.append(" -o ").append(float3_to_string(texture_map.translation)); } - if (texture_map.value.scale != float3{1.0f, 1.0f, 1.0f}) { - options.append(" -s ").append(float3_to_string(texture_map.value.scale)); + if (texture_map.scale != float3{1.0f, 1.0f, 1.0f}) { + options.append(" -s ").append(float3_to_string(texture_map.scale)); } - if (texture_map.key == eMTLSyntaxElement::map_Bump && mtl_material.map_Bump_strength > 0.0001f) { + if (texture_key == MTLTexMapType::bump && mtl_material.map_Bump_strength > 0.0001f) { options.append(" -bm ").append(std::to_string(mtl_material.map_Bump_strength)); } std::string path = path_reference( - texture_map.value.image_path.c_str(), blen_filedir, dest_dir, path_mode, ©_set); + texture_map.image_path.c_str(), blen_filedir, dest_dir, path_mode, ©_set); /* Always emit forward slashes for cross-platform compatibility. */ std::replace(path.begin(), path.end(), '\\', '/'); -#define SYNTAX_DISPATCH(eMTLSyntaxElement) \ - if (texture_map.key == eMTLSyntaxElement) { \ - fmt_handler_.write<eMTLSyntaxElement>(options, path.c_str()); \ - return; \ - } - - SYNTAX_DISPATCH(eMTLSyntaxElement::map_Kd); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ks); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ns); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_d); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_refl); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_Ke); - SYNTAX_DISPATCH(eMTLSyntaxElement::map_Bump); -#undef SYNTAX_DISPATCH - - BLI_assert(!"This map type was not written to the file."); + fmt_handler_.write_mtl_map(tex_map_type_to_string[(int)texture_key], options, path); } void MTLWriter::write_materials(const char *blen_filepath, @@ -633,14 +620,16 @@ void MTLWriter::write_materials(const char *blen_filepath, [](const MTLMaterial &a, const MTLMaterial &b) { return a.name < b.name; }); Set<std::pair<std::string, std::string>> copy_set; for (const MTLMaterial &mtlmat : mtlmaterials_) { - fmt_handler_.write<eMTLSyntaxElement::string>("\n"); - fmt_handler_.write<eMTLSyntaxElement::newmtl>(mtlmat.name); + fmt_handler_.write_string(""); + fmt_handler_.write_mtl_newmtl(mtlmat.name); write_bsdf_properties(mtlmat); - for (const auto &tex : mtlmat.texture_maps.items()) { - if (!tex.value.is_valid()) { + for (int key = 0; key < (int)MTLTexMapType::Count; key++) { + const MTLTexMap &tex = mtlmat.texture_maps[key]; + if (!tex.is_valid()) { continue; } - write_texture_map(mtlmat, tex, blen_filedir, dest_dir, path_mode, copy_set); + write_texture_map( + mtlmat, (MTLTexMapType)key, tex, blen_filedir, dest_dir, path_mode, copy_set); } } path_reference_copy(copy_set); diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh index 97c23484426..4544037fbc1 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh @@ -66,7 +66,7 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write object's name or group. */ - void write_object_name(FormatHandler<eFileType::OBJ> &fh, const OBJMesh &obj_mesh_data) const; + void write_object_name(FormatHandler &fh, const OBJMesh &obj_mesh_data) const; /** * Write file name of Material Library in .OBJ file. */ @@ -74,19 +74,19 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write vertex coordinates for all vertices as "v x y z" or "v x y z r g b". */ - void write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, + void write_vertex_coords(FormatHandler &fh, const OBJMesh &obj_mesh_data, bool write_colors) const; /** * Write UV vertex coordinates for all vertices as `vt u v`. * \note UV indices are stored here, but written with polygons later. */ - void write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data) const; + void write_uv_coords(FormatHandler &fh, OBJMesh &obj_mesh_data) const; /** * Write loop normals for smooth-shaded polygons, and polygon normals otherwise, as "vn x y z". * \note Normal indices ares stored here, but written with polygons later. */ - void write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data); + void write_poly_normals(FormatHandler &fh, OBJMesh &obj_mesh_data); /** * Write polygon elements with at least vertex indices, and conditionally with UV vertex * indices and polygon normal indices. Also write groups: smooth, vertex, material. @@ -94,23 +94,23 @@ class OBJWriter : NonMovable, NonCopyable { * name used in the .obj file. * \note UV indices were stored while writing UV vertices. */ - void write_poly_elements(FormatHandler<eFileType::OBJ> &fh, + void write_poly_elements(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data, std::function<const char *(int)> matname_fn); /** * Write loose edges of a mesh as "l v1 v2". */ - void write_edges_indices(FormatHandler<eFileType::OBJ> &fh, + void write_edges_indices(FormatHandler &fh, const IndexOffsets &offsets, const OBJMesh &obj_mesh_data) const; /** * Write a NURBS curve to the .OBJ file in parameter form. */ - void write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, const OBJCurve &obj_nurbs_data) const; + void write_nurbs_curve(FormatHandler &fh, const OBJCurve &obj_nurbs_data) const; private: - using func_vert_uv_normal_indices = void (OBJWriter::*)(FormatHandler<eFileType::OBJ> &fh, + using func_vert_uv_normal_indices = void (OBJWriter::*)(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> uv_indices, @@ -124,7 +124,7 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write one line of polygon indices as "f v1/vt1/vn1 v2/vt2/vn2 ...". */ - void write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, + void write_vert_uv_normal_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> uv_indices, @@ -133,7 +133,7 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write one line of polygon indices as "f v1//vn1 v2//vn2 ...". */ - void write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh, + void write_vert_normal_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> /*uv_indices*/, @@ -142,7 +142,7 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write one line of polygon indices as "f v1/vt1 v2/vt2 ...". */ - void write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh, + void write_vert_uv_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> uv_indices, @@ -151,7 +151,7 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write one line of polygon indices as "f v1 v2 ...". */ - void write_vert_indices(FormatHandler<eFileType::OBJ> &fh, + void write_vert_indices(FormatHandler &fh, const IndexOffsets &offsets, Span<int> vert_indices, Span<int> /*uv_indices*/, @@ -164,7 +164,7 @@ class OBJWriter : NonMovable, NonCopyable { */ class MTLWriter : NonMovable, NonCopyable { private: - FormatHandler<eFileType::MTL> fmt_handler_; + FormatHandler fmt_handler_; FILE *outfile_; std::string mtl_filepath_; Vector<MTLMaterial> mtlmaterials_; @@ -208,7 +208,8 @@ class MTLWriter : NonMovable, NonCopyable { * Write a texture map in the form "map_XX -s 1. 1. 1. -o 0. 0. 0. [-bm 1.] path/to/image". */ void write_texture_map(const MTLMaterial &mtl_material, - const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map, + MTLTexMapType texture_key, + const MTLTexMap &texture_map, const char *blen_filedir, const char *dest_dir, ePathReferenceMode mode, diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh index 5413c9969e3..cc0f7c0824c 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh @@ -23,268 +23,24 @@ namespace blender::io::obj { -enum class eFileType { - OBJ, - MTL, -}; - -enum class eOBJSyntaxElement { - vertex_coords, - vertex_coords_color, - uv_vertex_coords, - normal, - poly_element_begin, - vertex_uv_normal_indices, - vertex_normal_indices, - vertex_uv_indices, - vertex_indices, - poly_element_end, - poly_usemtl, - edge, - cstype, - nurbs_degree, - curve_element_begin, - curve_element_end, - nurbs_parameter_begin, - nurbs_parameters, - nurbs_parameter_end, - nurbs_group_end, - new_line, - mtllib, - smooth_group, - object_group, - object_name, - /* Use rarely. New line is NOT included for string. */ - string, -}; - -enum class eMTLSyntaxElement { - newmtl, - Ni, - d, - Ns, - illum, - Ka, - Kd, - Ks, - Ke, - map_Kd, - map_Ks, - map_Ns, - map_d, - map_refl, - map_Ke, - map_Bump, - /* Use rarely. New line is NOT included for string. */ - string, -}; - -template<eFileType filetype> struct FileTypeTraits; - -/* Used to prevent mixing of say OBJ file format with MTL syntax elements. */ -template<> struct FileTypeTraits<eFileType::OBJ> { - using SyntaxType = eOBJSyntaxElement; -}; - -template<> struct FileTypeTraits<eFileType::MTL> { - using SyntaxType = eMTLSyntaxElement; -}; - -struct FormattingSyntax { - /* Formatting syntax with the file format key like `newmtl %s\n`. */ - const char *fmt = nullptr; - /* Number of arguments needed by the syntax. */ - const int total_args = 0; - /* Whether types of the given arguments are accepted by the syntax above. Fail to compile by - * default. - */ - const bool are_types_valid = false; -}; - -/** - * Type dependent but always false. Use to add a `constexpr` conditional compile-time error. - */ -template<typename T> struct always_false : std::false_type { -}; - -template<typename... T> -constexpr bool is_type_float = (... && std::is_floating_point_v<std::decay_t<T>>); - -template<typename... T> -constexpr bool is_type_integral = (... && std::is_integral_v<std::decay_t<T>>); - -template<typename... T> -constexpr bool is_type_string_related = (... && std::is_constructible_v<std::string, T>); - -/* GCC (at least 9.3) while compiling the obj_exporter_tests.cc with optimizations on, - * results in "obj_export_io.hh:205:18: warning: ā%sā directive output truncated writing 34 bytes - * into a region of size 6" and similar warnings. Yes the output is truncated, and that is covered - * as an edge case by tests on purpose. */ -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wformat-truncation" -#endif -template<typename... T> -constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key) -{ - switch (key) { - case eOBJSyntaxElement::vertex_coords: { - return {"v {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; - } - case eOBJSyntaxElement::vertex_coords_color: { - return {"v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", 6, is_type_float<T...>}; - } - case eOBJSyntaxElement::uv_vertex_coords: { - return {"vt {:.6f} {:.6f}\n", 2, is_type_float<T...>}; - } - case eOBJSyntaxElement::normal: { - return {"vn {:.4f} {:.4f} {:.4f}\n", 3, is_type_float<T...>}; - } - case eOBJSyntaxElement::poly_element_begin: { - return {"f", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::vertex_uv_normal_indices: { - return {" {}/{}/{}", 3, is_type_integral<T...>}; - } - case eOBJSyntaxElement::vertex_normal_indices: { - return {" {}//{}", 2, is_type_integral<T...>}; - } - case eOBJSyntaxElement::vertex_uv_indices: { - return {" {}/{}", 2, is_type_integral<T...>}; - } - case eOBJSyntaxElement::vertex_indices: { - return {" {}", 1, is_type_integral<T...>}; - } - case eOBJSyntaxElement::poly_usemtl: { - return {"usemtl {}\n", 1, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::edge: { - return {"l {} {}\n", 2, is_type_integral<T...>}; - } - case eOBJSyntaxElement::cstype: { - return {"cstype bspline\n", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::nurbs_degree: { - return {"deg {}\n", 1, is_type_integral<T...>}; - } - case eOBJSyntaxElement::curve_element_begin: { - return {"curv 0.0 1.0", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::nurbs_parameter_begin: { - return {"parm u 0.0", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::nurbs_parameters: { - return {" {:.6f}", 1, is_type_float<T...>}; - } - case eOBJSyntaxElement::nurbs_parameter_end: { - return {" 1.0\n", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::nurbs_group_end: { - return {"end\n", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::poly_element_end: { - ATTR_FALLTHROUGH; - } - case eOBJSyntaxElement::curve_element_end: { - ATTR_FALLTHROUGH; - } - case eOBJSyntaxElement::new_line: { - return {"\n", 0, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::mtllib: { - return {"mtllib {}\n", 1, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::smooth_group: { - return {"s {}\n", 1, is_type_integral<T...>}; - } - case eOBJSyntaxElement::object_group: { - return {"g {}\n", 1, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::object_name: { - return {"o {}\n", 1, is_type_string_related<T...>}; - } - case eOBJSyntaxElement::string: { - return {"{}", 1, is_type_string_related<T...>}; - } - } -} - -template<typename... T> -constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key) -{ - switch (key) { - case eMTLSyntaxElement::newmtl: { - return {"newmtl {}\n", 1, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::Ni: { - return {"Ni {:.6f}\n", 1, is_type_float<T...>}; - } - case eMTLSyntaxElement::d: { - return {"d {:.6f}\n", 1, is_type_float<T...>}; - } - case eMTLSyntaxElement::Ns: { - return {"Ns {:.6f}\n", 1, is_type_float<T...>}; - } - case eMTLSyntaxElement::illum: { - return {"illum {}\n", 1, is_type_integral<T...>}; - } - case eMTLSyntaxElement::Ka: { - return {"Ka {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; - } - case eMTLSyntaxElement::Kd: { - return {"Kd {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; - } - case eMTLSyntaxElement::Ks: { - return {"Ks {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; - } - case eMTLSyntaxElement::Ke: { - return {"Ke {:.6f} {:.6f} {:.6f}\n", 3, is_type_float<T...>}; - } - /* NOTE: first texture map related argument, if present, will have its own leading space. */ - case eMTLSyntaxElement::map_Kd: { - return {"map_Kd{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_Ks: { - return {"map_Ks{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_Ns: { - return {"map_Ns{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_d: { - return {"map_d{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_refl: { - return {"map_refl{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_Ke: { - return {"map_Ke{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::map_Bump: { - return {"map_Bump{} {}\n", 2, is_type_string_related<T...>}; - } - case eMTLSyntaxElement::string: { - return {"{}", 1, is_type_string_related<T...>}; - } - } -} -#if defined(__GNUC__) && !defined(__clang__) -# pragma GCC diagnostic pop -#endif - /** - * File format and syntax agnostic file buffer writer. + * File buffer writer. * All writes are done into an internal chunked memory buffer * (list of default 64 kilobyte blocks). * Call write_fo_file once in a while to write the memory buffer(s) * into the given file. */ -template<eFileType filetype, size_t buffer_chunk_size = 64 * 1024> class FormatHandler : NonCopyable, NonMovable { private: typedef std::vector<char> VectorChar; std::vector<VectorChar> blocks_; + size_t buffer_chunk_size_; public: + FormatHandler(size_t buffer_chunk_size = 64 * 1024) : buffer_chunk_size_(buffer_chunk_size) + { + } + /* Write contents to the buffer(s) into a file, and clear the buffers. */ void write_to_file(FILE *f) { @@ -305,7 +61,7 @@ class FormatHandler : NonCopyable, NonMovable { return blocks_.size(); } - void append_from(FormatHandler<filetype, buffer_chunk_size> &v) + void append_from(FormatHandler &v) { blocks_.insert(blocks_.end(), std::make_move_iterator(v.blocks_.begin()), @@ -313,24 +69,132 @@ class FormatHandler : NonCopyable, NonMovable { v.blocks_.clear(); } - /** - * Example invocation: `writer->write<eMTLSyntaxElement::newmtl>("foo")`. - * - * \param key: Must match what the instance's filetype expects; i.e., `eMTLSyntaxElement` for - * `eFileType::MTL`. - */ - template<typename FileTypeTraits<filetype>::SyntaxType key, typename... T> - constexpr void write(T &&...args) - { - /* Get format syntax, number of arguments expected and whether types of given arguments are - * valid. - */ - constexpr FormattingSyntax fmt_nargs_valid = syntax_elem_to_formatting<T...>(key); - BLI_STATIC_ASSERT(fmt_nargs_valid.are_types_valid && - (sizeof...(T) == fmt_nargs_valid.total_args), - "Types of all arguments and the number of arguments should match what the " - "formatting specifies."); - write_impl(fmt_nargs_valid.fmt, std::forward<T>(args)...); + void write_obj_vertex(float x, float y, float z) + { + write_impl("v {:.6f} {:.6f} {:.6f}\n", x, y, z); + } + void write_obj_vertex_color(float x, float y, float z, float r, float g, float b) + { + write_impl("v {:.6f} {:.6f} {:.6f} {:.4f} {:.4f} {:.4f}\n", x, y, z, r, g, b); + } + void write_obj_uv(float x, float y) + { + write_impl("vt {:.6f} {:.6f}\n", x, y); + } + void write_obj_normal(float x, float y, float z) + { + write_impl("vn {:.4f} {:.4f} {:.4f}\n", x, y, z); + } + void write_obj_poly_begin() + { + write_impl("f"); + } + void write_obj_poly_end() + { + write_obj_newline(); + } + void write_obj_poly_v_uv_normal(int v, int uv, int n) + { + write_impl(" {}/{}/{}", v, uv, n); + } + void write_obj_poly_v_normal(int v, int n) + { + write_impl(" {}//{}", v, n); + } + void write_obj_poly_v_uv(int v, int uv) + { + write_impl(" {}/{}", v, uv); + } + void write_obj_poly_v(int v) + { + write_impl(" {}", v); + } + void write_obj_usemtl(StringRef s) + { + write_impl("usemtl {}\n", s); + } + void write_obj_mtllib(StringRef s) + { + write_impl("mtllib {}\n", s); + } + void write_obj_smooth(int s) + { + write_impl("s {}\n", s); + } + void write_obj_group(StringRef s) + { + write_impl("g {}\n", s); + } + void write_obj_object(StringRef s) + { + write_impl("o {}\n", s); + } + void write_obj_edge(int a, int b) + { + write_impl("l {} {}\n", a, b); + } + void write_obj_cstype() + { + write_impl("cstype bspline\n"); + } + void write_obj_nurbs_degree(int deg) + { + write_impl("deg {}\n", deg); + } + void write_obj_curve_begin() + { + write_impl("curv 0.0 1.0"); + } + void write_obj_curve_end() + { + write_obj_newline(); + } + void write_obj_nurbs_parm_begin() + { + write_impl("parm u 0.0"); + } + void write_obj_nurbs_parm(float v) + { + write_impl(" {:.6f}", v); + } + void write_obj_nurbs_parm_end() + { + write_impl(" 1.0\n"); + } + void write_obj_nurbs_group_end() + { + write_impl("end\n"); + } + void write_obj_newline() + { + write_impl("\n"); + } + + void write_mtl_newmtl(StringRef s) + { + write_impl("newmtl {}\n", s); + } + void write_mtl_float(const char *type, float v) + { + write_impl("{} {:.6f}\n", type, v); + } + void write_mtl_float3(const char *type, float r, float g, float b) + { + write_impl("{} {:.6f} {:.6f} {:.6f}\n", type, r, g, b); + } + void write_mtl_illum(int mode) + { + write_impl("illum {}\n", mode); + } + /* Note: options, if present, will have its own leading space. */ + void write_mtl_map(const char *type, StringRef options, StringRef value) + { + write_impl("{}{} {}\n", type, options, value); + } + + void write_string(StringRef s) + { + write_impl("{}\n", s); } private: @@ -340,7 +204,7 @@ class FormatHandler : NonCopyable, NonMovable { { if (blocks_.empty() || (blocks_.back().capacity() - blocks_.back().size() < at_least)) { VectorChar &b = blocks_.emplace_back(VectorChar()); - b.reserve(std::max(at_least, buffer_chunk_size)); + b.reserve(std::max(at_least, buffer_chunk_size_)); } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc index 4ed148ec64e..dafbca0f995 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.cc @@ -22,6 +22,18 @@ namespace blender::io::obj { +const char *tex_map_type_to_socket_id[] = { + "Base Color", + "Specular", + "Roughness", + "Alpha", + "Metallic", + "Emission", + "Normal", +}; +BLI_STATIC_ASSERT(ARRAY_SIZE(tex_map_type_to_socket_id) == (int)MTLTexMapType::Count, + "array size mismatch"); + /** * Copy a float property of the given type from the bNode to given buffer. */ @@ -73,7 +85,7 @@ static void copy_property_from_node(const eNodeSocketDatatype property_type, */ static void linked_sockets_to_dest_id(const bNode *dest_node, const nodes::NodeTreeRef &node_tree, - StringRefNull dest_socket_id, + const char *dest_socket_id, Vector<const nodes::OutputSocketRef *> &r_linked_sockets) { r_linked_sockets.clear(); @@ -84,7 +96,7 @@ static void linked_sockets_to_dest_id(const bNode *dest_node, Span<const nodes::InputSocketRef *> dest_inputs = object_dest_nodes.first()->inputs(); const nodes::InputSocketRef *dest_socket = nullptr; for (const nodes::InputSocketRef *curr_socket : dest_inputs) { - if (STREQ(curr_socket->bsocket()->identifier, dest_socket_id.c_str())) { + if (STREQ(curr_socket->bsocket()->identifier, dest_socket_id)) { dest_socket = curr_socket; break; } @@ -269,12 +281,12 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node, * - finding "Strength" property of the node for `-bm` option. */ - for (Map<const eMTLSyntaxElement, tex_map_XX>::MutableItem texture_map : - r_mtl_mat.texture_maps.items()) { + for (int key = 0; key < (int)MTLTexMapType::Count; ++key) { + MTLTexMap &value = r_mtl_mat.texture_maps[key]; Vector<const nodes::OutputSocketRef *> linked_sockets; const bNode *normal_map_node{nullptr}; - if (texture_map.key == eMTLSyntaxElement::map_Bump) { + if (key == (int)MTLTexMapType::bump) { /* Find sockets linked to destination "Normal" socket in P-BSDF node. */ linked_sockets_to_dest_id(bnode, *node_tree, "Normal", linked_sockets); /* Among the linked sockets, find Normal Map shader node. */ @@ -285,7 +297,7 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node, } else { /* Skip emission map if emission strength is zero. */ - if (texture_map.key == eMTLSyntaxElement::map_Ke) { + if (key == (int)MTLTexMapType::Ke) { float emission_strength = 0.0f; copy_property_from_node(SOCK_FLOAT, bnode, "Emission Strength", {&emission_strength, 1}); if (emission_strength == 0.0f) { @@ -293,8 +305,7 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node, } } /* Find sockets linked to the destination socket of interest, in P-BSDF node. */ - linked_sockets_to_dest_id( - bnode, *node_tree, texture_map.value.dest_socket_id, linked_sockets); + linked_sockets_to_dest_id(bnode, *node_tree, tex_map_type_to_socket_id[key], linked_sockets); } /* Among the linked sockets, find Image Texture shader node. */ @@ -317,10 +328,10 @@ static void store_image_textures(const nodes::NodeRef *bsdf_node, } /* Texture transform options. Only translation (origin offset, "-o") and scale * ("-o") are supported. */ - copy_property_from_node(SOCK_VECTOR, mapping, "Location", {texture_map.value.translation, 3}); - copy_property_from_node(SOCK_VECTOR, mapping, "Scale", {texture_map.value.scale, 3}); + copy_property_from_node(SOCK_VECTOR, mapping, "Location", {value.translation, 3}); + copy_property_from_node(SOCK_VECTOR, mapping, "Scale", {value.scale, 3}); - texture_map.value.image_path = tex_image_filepath; + value.image_path = tex_image_filepath; } } diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh index f83b3b49bf5..d8eafff107b 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mtl.hh @@ -6,36 +6,23 @@ #pragma once -#include "BLI_map.hh" #include "BLI_math_vec_types.hh" #include "DNA_node_types.h" -#include "obj_export_io.hh" - -namespace blender { -template<> struct DefaultHash<io::obj::eMTLSyntaxElement> { - uint64_t operator()(const io::obj::eMTLSyntaxElement value) const - { - return static_cast<uint64_t>(value); - } -}; - -} // namespace blender +struct Material; namespace blender::io::obj { -/** - * Generic container for texture node properties. - */ -struct tex_map_XX { - tex_map_XX(StringRef to_socket_id) : dest_socket_id(to_socket_id){}; +enum class MTLTexMapType { Kd = 0, Ks, Ns, d, refl, Ke, bump, Count }; +extern const char *tex_map_type_to_socket_id[]; + +struct MTLTexMap { bool is_valid() const { return !image_path.empty(); } /* Target socket which this texture node connects to. */ - const std::string dest_socket_id; float3 translation{0.0f}; float3 scale{1.0f}; /* Only Flat and Sphere projections are supported. */ @@ -48,26 +35,13 @@ struct tex_map_XX { * Container suited for storing Material data for/from a .MTL file. */ struct MTLMaterial { - MTLMaterial() - { - texture_maps.add(eMTLSyntaxElement::map_Kd, tex_map_XX("Base Color")); - texture_maps.add(eMTLSyntaxElement::map_Ks, tex_map_XX("Specular")); - texture_maps.add(eMTLSyntaxElement::map_Ns, tex_map_XX("Roughness")); - texture_maps.add(eMTLSyntaxElement::map_d, tex_map_XX("Alpha")); - texture_maps.add(eMTLSyntaxElement::map_refl, tex_map_XX("Metallic")); - texture_maps.add(eMTLSyntaxElement::map_Ke, tex_map_XX("Emission")); - texture_maps.add(eMTLSyntaxElement::map_Bump, tex_map_XX("Normal")); - } - - const tex_map_XX &tex_map_of_type(const eMTLSyntaxElement key) const + const MTLTexMap &tex_map_of_type(MTLTexMapType key) const { - BLI_assert(texture_maps.contains(key)); - return texture_maps.lookup(key); + return texture_maps[(int)key]; } - tex_map_XX &tex_map_of_type(const eMTLSyntaxElement key) + MTLTexMap &tex_map_of_type(MTLTexMapType key) { - BLI_assert(texture_maps.contains(key)); - return texture_maps.lookup(key); + return texture_maps[(int)key]; } std::string name; @@ -81,7 +55,7 @@ struct MTLMaterial { float Ni{-1.0f}; float d{-1.0f}; int illum{-1}; - Map<const eMTLSyntaxElement, tex_map_XX> texture_maps; + MTLTexMap texture_maps[(int)MTLTexMapType::Count]; /** Only used for Normal Map node: "map_Bump". */ float map_Bump_strength{-1.0f}; }; diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc index 77d4f6268bc..76cf9066bf4 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc @@ -143,7 +143,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me * we have to have the output text buffer for each object, * and write them all into the file at the end. */ size_t count = exportable_as_mesh.size(); - std::vector<FormatHandler<eFileType::OBJ>> buffers(count); + std::vector<FormatHandler> buffers(count); /* Serial: gather material indices, ensure normals & edges. */ Vector<Vector<int>> mtlindices; @@ -242,7 +242,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me static void write_nurbs_curve_objects(const Vector<std::unique_ptr<OBJCurve>> &exportable_as_nurbs, const OBJWriter &obj_writer) { - FormatHandler<eFileType::OBJ> fh; + FormatHandler fh; /* #OBJCurve doesn't have any dynamically allocated memory, so it's fine * to wait for #blender::Vector to clean the objects up. */ for (const std::unique_ptr<OBJCurve> &obj_curve : exportable_as_nurbs) { 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 633f70b2e38..088784b4194 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 @@ -592,36 +592,31 @@ void OBJParser::parse(Vector<std::unique_ptr<Geometry>> &r_all_geometries, 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::Kd; } if (parse_keyword(p, end, "map_Ks")) { - return eMTLSyntaxElement::map_Ks; + return MTLTexMapType::Ks; } if (parse_keyword(p, end, "map_Ns")) { - return eMTLSyntaxElement::map_Ns; + return MTLTexMapType::Ns; } if (parse_keyword(p, end, "map_d")) { - return eMTLSyntaxElement::map_d; + return MTLTexMapType::d; } - 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::refl; } if (parse_keyword(p, end, "map_Ke")) { - return eMTLSyntaxElement::map_Ke; - } - if (parse_keyword(p, end, "bump")) { - return eMTLSyntaxElement::map_Bump; + return MTLTexMapType::Ke; } - if (parse_keyword(p, end, "map_Bump") || parse_keyword(p, end, "map_bump")) { - return eMTLSyntaxElement::map_Bump; + if (parse_keyword(p, end, "bump") || parse_keyword(p, end, "map_Bump") || + parse_keyword(p, end, "map_bump")) { + return MTLTexMapType::bump; } - return eMTLSyntaxElement::string; + return MTLTexMapType::Count; } static const std::pair<StringRef, int> unsupported_texture_options[] = { @@ -639,7 +634,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")) { @@ -693,13 +688,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. */ diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc index 093cbec32fe..c28de14f2f7 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc +++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.cc @@ -17,8 +17,6 @@ #include "NOD_shader.h" -/* TODO: move eMTLSyntaxElement out of following file into a more neutral place */ -#include "obj_export_io.hh" #include "obj_import_mtl.hh" #include "obj_import_string_utils.hh" @@ -29,12 +27,12 @@ namespace blender::io::obj { * Only float value(s) can be set using this method. */ static void set_property_of_socket(eNodeSocketDatatype property_type, - StringRef socket_id, + const char *socket_id, Span<float> value, bNode *r_node) { BLI_assert(r_node); - bNodeSocket *socket{nodeFindSocket(r_node, SOCK_IN, socket_id.data())}; + bNodeSocket *socket{nodeFindSocket(r_node, SOCK_IN, socket_id)}; BLI_assert(socket && socket->type == property_type); switch (property_type) { case SOCK_FLOAT: { @@ -95,7 +93,7 @@ static Image *create_placeholder_image(Main *bmain, const std::string &path) return image; } -static Image *load_texture_image(Main *bmain, const tex_map_XX &tex_map, bool relative_paths) +static Image *load_texture_image(Main *bmain, const MTLTexMap &tex_map, bool relative_paths) { Image *image = nullptr; @@ -206,15 +204,15 @@ std::pair<float, float> ShaderNodetreeWrap::set_node_locations(const int pos_x) } void ShaderNodetreeWrap::link_sockets(bNode *from_node, - StringRef from_node_id, + const char *from_node_id, bNode *to_node, - StringRef to_node_id, + const char *to_node_id, const int from_node_pos_x) { std::tie(from_node->locx, from_node->locy) = set_node_locations(from_node_pos_x); std::tie(to_node->locx, to_node->locy) = set_node_locations(from_node_pos_x + 1); - bNodeSocket *from_sock{nodeFindSocket(from_node, SOCK_OUT, from_node_id.data())}; - bNodeSocket *to_sock{nodeFindSocket(to_node, SOCK_IN, to_node_id.data())}; + bNodeSocket *from_sock{nodeFindSocket(from_node, SOCK_OUT, from_node_id)}; + bNodeSocket *to_sock{nodeFindSocket(to_node, SOCK_IN, to_node_id)}; BLI_assert(from_sock && to_sock); nodeAddLink(nodetree_.get(), from_node, from_sock, to_node, to_sock); } @@ -338,7 +336,7 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat) if (emission_color.x >= 0 && emission_color.y >= 0 && emission_color.z >= 0) { set_property_of_socket(SOCK_RGBA, "Emission", {emission_color, 3}, bsdf_); } - if (mtl_mat_.tex_map_of_type(eMTLSyntaxElement::map_Ke).is_valid()) { + if (mtl_mat_.tex_map_of_type(MTLTexMapType::Ke).is_valid()) { set_property_of_socket(SOCK_FLOAT, "Emission Strength", {1.0f}, bsdf_); } set_property_of_socket(SOCK_FLOAT, "Specular", {specular}, bsdf_); @@ -359,38 +357,36 @@ void ShaderNodetreeWrap::set_bsdf_socket_values(Material *mat) void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat, bool relative_paths) { - for (const Map<const eMTLSyntaxElement, tex_map_XX>::Item texture_map : - mtl_mat_.texture_maps.items()) { - if (!texture_map.value.is_valid()) { + for (int key = 0; key < (int)MTLTexMapType::Count; ++key) { + const MTLTexMap &value = mtl_mat_.texture_maps[key]; + if (!value.is_valid()) { /* No Image texture node of this map type can be added to this material. */ continue; } bNode *image_texture = add_node_to_tree(SH_NODE_TEX_IMAGE); BLI_assert(image_texture); - Image *image = load_texture_image(bmain, texture_map.value, relative_paths); + Image *image = load_texture_image(bmain, value, relative_paths); if (image == nullptr) { continue; } image_texture->id = &image->id; - static_cast<NodeTexImage *>(image_texture->storage)->projection = - texture_map.value.projection_type; + static_cast<NodeTexImage *>(image_texture->storage)->projection = value.projection_type; /* Add normal map node if needed. */ bNode *normal_map = nullptr; - if (texture_map.key == eMTLSyntaxElement::map_Bump) { + if (key == (int)MTLTexMapType::bump) { normal_map = add_node_to_tree(SH_NODE_NORMAL_MAP); const float bump = std::max(0.0f, mtl_mat_.map_Bump_strength); set_property_of_socket(SOCK_FLOAT, "Strength", {bump}, normal_map); } /* Add UV mapping & coordinate nodes only if needed. */ - if (texture_map.value.translation != float3(0, 0, 0) || - texture_map.value.scale != float3(1, 1, 1)) { + if (value.translation != float3(0, 0, 0) || value.scale != float3(1, 1, 1)) { bNode *mapping = add_node_to_tree(SH_NODE_MAPPING); bNode *texture_coordinate = add_node_to_tree(SH_NODE_TEX_COORD); - set_property_of_socket(SOCK_VECTOR, "Location", {texture_map.value.translation, 3}, mapping); - set_property_of_socket(SOCK_VECTOR, "Scale", {texture_map.value.scale, 3}, mapping); + set_property_of_socket(SOCK_VECTOR, "Location", {value.translation, 3}, mapping); + set_property_of_socket(SOCK_VECTOR, "Scale", {value.scale, 3}, mapping); link_sockets(texture_coordinate, "UV", mapping, "Vector", 0); link_sockets(mapping, "Vector", image_texture, "Vector", 1); @@ -400,12 +396,12 @@ void ShaderNodetreeWrap::add_image_textures(Main *bmain, Material *mat, bool rel link_sockets(image_texture, "Color", normal_map, "Color", 2); link_sockets(normal_map, "Normal", bsdf_, "Normal", 3); } - else if (texture_map.key == eMTLSyntaxElement::map_d) { - link_sockets(image_texture, "Alpha", bsdf_, texture_map.value.dest_socket_id, 2); + else if (key == (int)MTLTexMapType::d) { + link_sockets(image_texture, "Alpha", bsdf_, tex_map_type_to_socket_id[key], 2); mat->blend_method = MA_BM_BLEND; } else { - link_sockets(image_texture, "Color", bsdf_, texture_map.value.dest_socket_id, 2); + link_sockets(image_texture, "Color", bsdf_, tex_map_type_to_socket_id[key], 2); } } } diff --git a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh index 17dd0106fea..2c51d92a2cd 100644 --- a/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh +++ b/source/blender/io/wavefront_obj/importer/obj_import_mtl.hh @@ -10,7 +10,6 @@ #include "BLI_map.hh" #include "BLI_math_vec_types.hh" -#include "BLI_string_ref.hh" #include "BLI_vector.hh" #include "DNA_node_types.h" @@ -75,9 +74,9 @@ class ShaderNodetreeWrap { * \param from_node_pos_x: 0 to 4 value as per nodetree arrangement. */ void link_sockets(bNode *from_node, - StringRef from_node_id, + const char *from_node_id, bNode *to_node, - StringRef to_node_id, + const char *to_node_id, const int from_node_pos_x); /** * Set values of sockets in p-BSDF node of the nodetree. diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index f582064e0c1..0fd711bdac6 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -185,17 +185,17 @@ TEST(obj_exporter_writer, mtllib) TEST(obj_exporter_writer, format_handler_buffer_chunking) { /* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */ - FormatHandler<eFileType::OBJ, 16> h; - h.write<eOBJSyntaxElement::object_name>("abc"); - h.write<eOBJSyntaxElement::object_name>("abcd"); - h.write<eOBJSyntaxElement::object_name>("abcde"); - h.write<eOBJSyntaxElement::object_name>("abcdef"); - h.write<eOBJSyntaxElement::object_name>("012345678901234567890123456789abcd"); - h.write<eOBJSyntaxElement::object_name>("123"); - h.write<eOBJSyntaxElement::curve_element_begin>(); - h.write<eOBJSyntaxElement::new_line>(); - h.write<eOBJSyntaxElement::nurbs_parameter_begin>(); - h.write<eOBJSyntaxElement::new_line>(); + FormatHandler h(16); + h.write_obj_object("abc"); + h.write_obj_object("abcd"); + h.write_obj_object("abcde"); + h.write_obj_object("abcdef"); + h.write_obj_object("012345678901234567890123456789abcd"); + h.write_obj_object("123"); + h.write_obj_curve_begin(); + h.write_obj_newline(); + h.write_obj_nurbs_parm_begin(); + h.write_obj_newline(); size_t got_blocks = h.get_block_count(); ASSERT_EQ(got_blocks, 7); diff --git a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc index 08050ac34c9..41faba95b30 100644 --- a/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_mtl_parser_tests.cc @@ -58,9 +58,9 @@ class obj_mtl_parser_test : public testing::Test { EXPECT_NEAR(exp.d, got.d, tol); EXPECT_NEAR(exp.map_Bump_strength, got.map_Bump_strength, tol); EXPECT_EQ(exp.illum, got.illum); - for (const auto &it : exp.texture_maps.items()) { - const tex_map_XX &exp_tex = it.value; - const tex_map_XX &got_tex = got.texture_maps.lookup(it.key); + for (int key = 0; key < (int)MTLTexMapType::Count; key++) { + const MTLTexMap &exp_tex = exp.texture_maps[key]; + const MTLTexMap &got_tex = got.texture_maps[key]; EXPECT_STREQ(exp_tex.image_path.c_str(), got_tex.image_path.c_str()); EXPECT_V3_NEAR(exp_tex.translation, got_tex.translation, tol); EXPECT_V3_NEAR(exp_tex.scale, got_tex.scale, tol); @@ -113,8 +113,8 @@ TEST_F(obj_mtl_parser_test, string_newlines_whitespace) mat[4].Kd = {0.6f, 0.7f, 0.8f}; mat[5].name = "crlf_ending"; mat[5].Ns = 5.0f; - mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd).image_path = "sometex_d.png"; - mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks).image_path = "sometex_s_spaces_after_name.png"; + mat[5].tex_map_of_type(MTLTexMapType::Kd).image_path = "sometex_d.png"; + mat[5].tex_map_of_type(MTLTexMapType::Ks).image_path = "sometex_s_spaces_after_name.png"; check_string(text, mat, ARRAY_SIZE(mat)); } @@ -175,13 +175,13 @@ TEST_F(obj_mtl_parser_test, materials) mat[1].illum = 2; mat[1].map_Bump_strength = 1; { - tex_map_XX &kd = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[1].tex_map_of_type(MTLTexMapType::Kd); kd.image_path = "texture.png"; - tex_map_XX &ns = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[1].tex_map_of_type(MTLTexMapType::Ns); ns.image_path = "sometexture_Roughness.png"; - tex_map_XX &refl = mat[1].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[1].tex_map_of_type(MTLTexMapType::refl); refl.image_path = "sometexture_Metallic.png"; - tex_map_XX &bump = mat[1].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[1].tex_map_of_type(MTLTexMapType::bump); bump.image_path = "sometexture_Normal.png"; } @@ -202,13 +202,13 @@ TEST_F(obj_mtl_parser_test, materials) mat[3].Ns = 800; mat[3].map_Bump_strength = 0.5f; { - tex_map_XX &kd = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[3].tex_map_of_type(MTLTexMapType::Kd); kd.image_path = "someHatTexture_BaseColor.jpg"; - tex_map_XX &ns = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[3].tex_map_of_type(MTLTexMapType::Ns); ns.image_path = "someHatTexture_Roughness.jpg"; - tex_map_XX &refl = mat[3].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[3].tex_map_of_type(MTLTexMapType::refl); refl.image_path = "someHatTexture_Metalness.jpg"; - tex_map_XX &bump = mat[3].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[3].tex_map_of_type(MTLTexMapType::bump); bump.image_path = "someHatTexture_Normal.jpg"; } @@ -222,30 +222,30 @@ TEST_F(obj_mtl_parser_test, materials) mat[4].d = 0.5; mat[4].map_Bump_strength = 0.1f; { - tex_map_XX &kd = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[4].tex_map_of_type(MTLTexMapType::Kd); kd.image_path = "sometex_d.png"; - tex_map_XX &ns = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[4].tex_map_of_type(MTLTexMapType::Ns); ns.image_path = "sometex_ns.psd"; - tex_map_XX &refl = mat[4].tex_map_of_type(eMTLSyntaxElement::map_refl); + MTLTexMap &refl = mat[4].tex_map_of_type(MTLTexMapType::refl); refl.image_path = "clouds.tiff"; refl.scale = {1.5f, 2.5f, 3.5f}; refl.translation = {4.5f, 5.5f, 6.5f}; refl.projection_type = SHD_PROJ_SPHERE; - tex_map_XX &bump = mat[4].tex_map_of_type(eMTLSyntaxElement::map_Bump); + MTLTexMap &bump = mat[4].tex_map_of_type(MTLTexMapType::bump); bump.image_path = "somebump.tga"; bump.scale = {3, 4, 5}; } mat[5].name = "Parser_ScaleOffset_Test"; { - tex_map_XX &kd = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Kd); + MTLTexMap &kd = mat[5].tex_map_of_type(MTLTexMapType::Kd); kd.translation = {2.5f, 0.0f, 0.0f}; kd.image_path = "OffsetOneValue.png"; - tex_map_XX &ks = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ks); + MTLTexMap &ks = mat[5].tex_map_of_type(MTLTexMapType::Ks); ks.scale = {1.5f, 2.5f, 1.0f}; ks.translation = {3.5f, 4.5f, 0.0f}; ks.image_path = "ScaleOffsetBothTwovalues.png"; - tex_map_XX &ns = mat[5].tex_map_of_type(eMTLSyntaxElement::map_Ns); + MTLTexMap &ns = mat[5].tex_map_of_type(MTLTexMapType::Ns); ns.scale = {0.5f, 1.0f, 1.0f}; ns.image_path = "1.Value.png"; } |