From ce8c2d364e966f5d5f296646fd05b948f648af93 Mon Sep 17 00:00:00 2001 From: Nathan Rozendaal Date: Thu, 16 Feb 2023 15:09:31 +0100 Subject: [PATCH] Implemented feedback from Hans --- source/blender/editors/io/io_ply_ops.c | 29 ++-- source/blender/io/ply/IO_ply.cc | 4 +- source/blender/io/ply/IO_ply.h | 1 - source/blender/io/ply/exporter/ply_export.cc | 8 +- .../io/ply/exporter/ply_export_data.cc | 49 +++---- .../io/ply/exporter/ply_export_data.hh | 6 +- .../io/ply/exporter/ply_export_header.cc | 60 ++++----- .../io/ply/exporter/ply_export_header.hh | 4 +- .../ply/exporter/ply_export_load_plydata.cc | 15 +-- .../io/ply/exporter/ply_file_buffer.hh | 3 +- .../io/ply/exporter/ply_file_buffer_ascii.hh | 5 +- .../io/ply/exporter/ply_file_buffer_binary.hh | 18 +-- .../io/ply/importer/ply_import_ascii.cc | 126 +++++++++--------- .../io/ply/importer/ply_import_ascii.hh | 4 +- .../io/ply/importer/ply_import_binary.cc | 5 +- .../io/ply/importer/ply_import_binary.hh | 10 +- .../io/ply/importer/ply_import_mesh.cc | 30 +---- source/blender/io/ply/intern/ply_data.hh | 3 +- .../io/ply/tests/io_ply_exporter_test.cc | 16 +-- .../io/ply/tests/io_ply_importer_test.cc | 11 +- 20 files changed, 184 insertions(+), 223 deletions(-) diff --git a/source/blender/editors/io/io_ply_ops.c b/source/blender/editors/io/io_ply_ops.c index b29ed9fb736..49c21920ab8 100644 --- a/source/blender/editors/io/io_ply_ops.c +++ b/source/blender/editors/io/io_ply_ops.c @@ -181,8 +181,7 @@ void WM_OT_ply_export(struct wmOperatorType *ot) FILE_SORT_DEFAULT); /* Object transform options. */ - prop = RNA_def_enum( - ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", ""); + prop = RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", ""); RNA_def_property_update_runtime(prop, (void *)forward_axis_update); prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", ""); RNA_def_property_update_runtime(prop, (void *)up_axis_update); @@ -205,12 +204,14 @@ void WM_OT_ply_export(struct wmOperatorType *ot) "Export Selected Objects", "Export only selected objects instead of all supported objects"); RNA_def_boolean(ot->srna, "export_uv", false, "Export UVs", ""); - RNA_def_boolean(ot->srna, - "export_normals", - false, - "Export Vertex Normals", - "Export specific vertex normals if available, export calculated normals otherwise"); - RNA_def_boolean(ot->srna, "export_colors", true, "Export Vertex Colors", "Export per-vertex colors"); + RNA_def_boolean( + ot->srna, + "export_normals", + false, + "Export Vertex Normals", + "Export specific vertex normals if available, export calculated normals otherwise"); + RNA_def_boolean( + ot->srna, "export_colors", true, "Export Vertex Colors", "Export per-vertex colors"); RNA_def_boolean(ot->srna, "export_triangulated_mesh", false, @@ -241,7 +242,6 @@ static int wm_ply_import_execute(bContext *C, wmOperator *op) params.up_axis = RNA_enum_get(op->ptr, "up_axis"); params.use_scene_unit = RNA_boolean_get(op->ptr, "use_scene_unit"); params.global_scale = RNA_float_get(op->ptr, "global_scale"); - params.import_normals_as_attribute = RNA_boolean_get(op->ptr, "import_normals_as_attribute"); params.merge_verts = RNA_boolean_get(op->ptr, "merge_verts"); int files_len = RNA_collection_length(op->ptr, "files"); @@ -321,16 +321,7 @@ void WM_OT_ply_import(struct wmOperatorType *ot) "Apply current scene's unit (as defined by unit scale) to imported data"); RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", ""); RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", ""); - RNA_def_boolean(ot->srna, - "import_normals_as_attribute", - false, - "Normals As Attribute", - "Sets the vertex normal data as a vertex attribute"); - RNA_def_boolean(ot->srna, - "merge_verts", - false, - "Merge Vertices", - "Merges vertices by distance"); + RNA_def_boolean(ot->srna, "merge_verts", false, "Merge Vertices", "Merges vertices by distance"); /* Only show .ply files by default. */ prop = RNA_def_string(ot->srna, "filter_glob", "*.ply", 0, "Extension Filter", ""); diff --git a/source/blender/io/ply/IO_ply.cc b/source/blender/io/ply/IO_ply.cc index f792f5f4444..d5b0c76e627 100644 --- a/source/blender/io/ply/IO_ply.cc +++ b/source/blender/io/ply/IO_ply.cc @@ -11,13 +11,13 @@ #include "ply_export.hh" #include "ply_import.hh" -void PLY_export(bContext *C, const struct PLYExportParams *export_params) +void PLY_export(bContext *C, const PLYExportParams *export_params) { SCOPED_TIMER("PLY Export"); blender::io::ply::exporter_main(C, *export_params); } -void PLY_import(bContext *C, const struct PLYImportParams *import_params, wmOperator *op) +void PLY_import(bContext *C, const PLYImportParams *import_params, wmOperator *op) { SCOPED_TIMER("PLY Import"); blender::io::ply::importer_main(C, *import_params, op); diff --git a/source/blender/io/ply/IO_ply.h b/source/blender/io/ply/IO_ply.h index ecca1958e35..be957090490 100644 --- a/source/blender/io/ply/IO_ply.h +++ b/source/blender/io/ply/IO_ply.h @@ -49,7 +49,6 @@ struct PLYImportParams { eIOAxis up_axis; bool use_scene_unit; float global_scale; - bool import_normals_as_attribute; bool merge_verts; }; diff --git a/source/blender/io/ply/exporter/ply_export.cc b/source/blender/io/ply/exporter/ply_export.cc index a40dbcfb937..768c2e1647c 100644 --- a/source/blender/io/ply/exporter/ply_export.cc +++ b/source/blender/io/ply/exporter/ply_export.cc @@ -50,16 +50,16 @@ void exporter_main(Main *bmain, } /* Generate and write header. */ - write_header(buffer, plyData, export_params); + write_header(*buffer.get(), *plyData.get(), export_params); /* Generate and write vertices. */ - write_vertices(buffer, plyData); + write_vertices(*buffer.get(), *plyData.get()); /* Generate and write faces. */ - write_faces(buffer, plyData); + write_faces(*buffer.get(), *plyData.get()); /* Generate and write edges. */ - write_edges(buffer, plyData); + write_edges(*buffer.get(), *plyData.get()); /* Clean up. */ buffer->close_file(); diff --git a/source/blender/io/ply/exporter/ply_export_data.cc b/source/blender/io/ply/exporter/ply_export_data.cc index 101ec6bf5f1..032ea933516 100644 --- a/source/blender/io/ply/exporter/ply_export_data.cc +++ b/source/blender/io/ply/exporter/ply_export_data.cc @@ -3,48 +3,49 @@ /** \file * \ingroup ply */ +#include "BLI_array.hh" #include "ply_data.hh" #include "ply_file_buffer.hh" namespace blender::io::ply { -void write_vertices(std::unique_ptr &buffer, std::unique_ptr &plyData) +void write_vertices(FileBuffer &buffer, const PlyData &ply_data) { - for (int i = 0; i < plyData->vertices.size(); i++) { - buffer->write_vertex(plyData->vertices[i].x, plyData->vertices[i].y, plyData->vertices[i].z); + for (int i = 0; i < ply_data.vertices.size(); i++) { + buffer.write_vertex(ply_data.vertices[i].x, ply_data.vertices[i].y, ply_data.vertices[i].z); - if (!plyData->vertex_normals.is_empty()) - buffer->write_vertex_normal(plyData->vertex_normals[i].x, - plyData->vertex_normals[i].y, - plyData->vertex_normals[i].z); + if (!ply_data.vertex_normals.is_empty()) + buffer.write_vertex_normal(ply_data.vertex_normals[i].x, + ply_data.vertex_normals[i].y, + ply_data.vertex_normals[i].z); - if (!plyData->vertex_colors.is_empty()) - buffer->write_vertex_color(uchar(plyData->vertex_colors[i].x * 255), - uchar(plyData->vertex_colors[i].y * 255), - uchar(plyData->vertex_colors[i].z * 255), - uchar(plyData->vertex_colors[i].w * 255)); + if (!ply_data.vertex_colors.is_empty()) + buffer.write_vertex_color(uchar(ply_data.vertex_colors[i].x * 255), + uchar(ply_data.vertex_colors[i].y * 255), + uchar(ply_data.vertex_colors[i].z * 255), + uchar(ply_data.vertex_colors[i].w * 255)); - if (!plyData->UV_coordinates.is_empty()) - buffer->write_UV(plyData->UV_coordinates[i].x, plyData->UV_coordinates[i].y); + if (!ply_data.UV_coordinates.is_empty()) + buffer.write_UV(ply_data.UV_coordinates[i].x, ply_data.UV_coordinates[i].y); - buffer->write_vertex_end(); + buffer.write_vertex_end(); } - buffer->write_to_file(); + buffer.write_to_file(); } -void write_faces(std::unique_ptr &buffer, std::unique_ptr &plyData) +void write_faces(FileBuffer &buffer, const PlyData &ply_data) { - for (const Vector &face : plyData->faces) { - buffer->write_face(char(face.size()), face); + for (const Array &face : ply_data.faces) { + buffer.write_face(char(face.size()), face); } - buffer->write_to_file(); + buffer.write_to_file(); } -void write_edges(std::unique_ptr &buffer, std::unique_ptr &plyData) +void write_edges(FileBuffer &buffer, const PlyData &ply_data) { - for (const std::pair &edge : plyData->edges) { - buffer->write_edge(edge.first, edge.second); + for (const std::pair &edge : ply_data.edges) { + buffer.write_edge(edge.first, edge.second); } - buffer->write_to_file(); + buffer.write_to_file(); } } // namespace blender::io::ply diff --git a/source/blender/io/ply/exporter/ply_export_data.hh b/source/blender/io/ply/exporter/ply_export_data.hh index ac1da11e013..376051fb32b 100644 --- a/source/blender/io/ply/exporter/ply_export_data.hh +++ b/source/blender/io/ply/exporter/ply_export_data.hh @@ -11,10 +11,10 @@ namespace blender::io::ply { -void write_vertices(std::unique_ptr &buffer, std::unique_ptr &plyData); +void write_vertices(FileBuffer &buffer, const PlyData &ply_data); -void write_faces(std::unique_ptr &buffer, std::unique_ptr &plyData); +void write_faces(FileBuffer &buffer, const PlyData &ply_data); -void write_edges(std::unique_ptr &buffer, std::unique_ptr &plyData); +void write_edges(FileBuffer &buffer, const PlyData &ply_data); } // namespace blender::io::ply diff --git a/source/blender/io/ply/exporter/ply_export_header.cc b/source/blender/io/ply/exporter/ply_export_header.cc index 01eead52d63..fc41b764caa 100644 --- a/source/blender/io/ply/exporter/ply_export_header.cc +++ b/source/blender/io/ply/exporter/ply_export_header.cc @@ -13,54 +13,54 @@ namespace blender::io::ply { -void write_header(std::unique_ptr &buffer, - std::unique_ptr &plyData, +void write_header(FileBuffer &buffer, + const PlyData &ply_data, const PLYExportParams &export_params) { - buffer->write_string("ply"); + buffer.write_string("ply"); StringRef format = export_params.ascii_format ? "ascii" : "binary_little_endian"; - buffer->write_string("format " + format + " 1.0"); + buffer.write_string("format " + format + " 1.0"); StringRef version = BKE_blender_version_string(); - buffer->write_string("comment Created in Blender version " + version); + buffer.write_string("comment Created in Blender version " + version); - buffer->write_header_element("vertex", int32_t(plyData->vertices.size())); - buffer->write_header_scalar_property("float", "x"); - buffer->write_header_scalar_property("float", "y"); - buffer->write_header_scalar_property("float", "z"); + buffer.write_header_element("vertex", int32_t(ply_data.vertices.size())); + buffer.write_header_scalar_property("float", "x"); + buffer.write_header_scalar_property("float", "y"); + buffer.write_header_scalar_property("float", "z"); - if (!plyData->vertex_normals.is_empty()) { - buffer->write_header_scalar_property("float", "nx"); - buffer->write_header_scalar_property("float", "ny"); - buffer->write_header_scalar_property("float", "nz"); + if (!ply_data.vertex_normals.is_empty()) { + buffer.write_header_scalar_property("float", "nx"); + buffer.write_header_scalar_property("float", "ny"); + buffer.write_header_scalar_property("float", "nz"); } - if (!plyData->vertex_colors.is_empty()) { - buffer->write_header_scalar_property("uchar", "red"); - buffer->write_header_scalar_property("uchar", "green"); - buffer->write_header_scalar_property("uchar", "blue"); - buffer->write_header_scalar_property("uchar", "alpha"); + if (!ply_data.vertex_colors.is_empty()) { + buffer.write_header_scalar_property("uchar", "red"); + buffer.write_header_scalar_property("uchar", "green"); + buffer.write_header_scalar_property("uchar", "blue"); + buffer.write_header_scalar_property("uchar", "alpha"); } - if (!plyData->UV_coordinates.is_empty()) { - buffer->write_header_scalar_property("float", "s"); - buffer->write_header_scalar_property("float", "t"); + if (!ply_data.UV_coordinates.is_empty()) { + buffer.write_header_scalar_property("float", "s"); + buffer.write_header_scalar_property("float", "t"); } - if (!plyData->faces.is_empty()) { - buffer->write_header_element("face", int32_t(plyData->faces.size())); - buffer->write_header_list_property("uchar", "uint", "vertex_indices"); + if (!ply_data.faces.is_empty()) { + buffer.write_header_element("face", int32_t(ply_data.faces.size())); + buffer.write_header_list_property("uchar", "uint", "vertex_indices"); } - if (!plyData->edges.is_empty()) { - buffer->write_header_element("edge", int32_t(plyData->edges.size())); - buffer->write_header_scalar_property("int", "vertex1"); - buffer->write_header_scalar_property("int", "vertex2"); + if (!ply_data.edges.is_empty()) { + buffer.write_header_element("edge", int32_t(ply_data.edges.size())); + buffer.write_header_scalar_property("int", "vertex1"); + buffer.write_header_scalar_property("int", "vertex2"); } - buffer->write_string("end_header"); - buffer->write_to_file(); + buffer.write_string("end_header"); + buffer.write_to_file(); } } // namespace blender::io::ply diff --git a/source/blender/io/ply/exporter/ply_export_header.hh b/source/blender/io/ply/exporter/ply_export_header.hh index 45dafd1b793..85e1361340c 100644 --- a/source/blender/io/ply/exporter/ply_export_header.hh +++ b/source/blender/io/ply/exporter/ply_export_header.hh @@ -11,8 +11,8 @@ namespace blender::io::ply { -void write_header(std::unique_ptr &buffer, - std::unique_ptr &plyData, +void write_header(FileBuffer &buffer, + const PlyData &ply_data, const PLYExportParams &export_params); } // namespace blender::io::ply diff --git a/source/blender/io/ply/exporter/ply_export_load_plydata.cc b/source/blender/io/ply/exporter/ply_export_load_plydata.cc index 5bc5672a3e6..85f2c270661 100644 --- a/source/blender/io/ply/exporter/ply_export_load_plydata.cc +++ b/source/blender/io/ply/exporter/ply_export_load_plydata.cc @@ -4,6 +4,7 @@ * \ingroup ply */ +#include "BLI_array.hh" #include "BLI_math.h" #include "BKE_attribute.hh" @@ -40,8 +41,6 @@ Mesh *do_triangulation(const Mesh *mesh, bool force_triangulation) BMeshFromMeshParams bm_convert_params{}; bm_convert_params.calc_face_normal = true; bm_convert_params.calc_vert_normal = true; - bm_convert_params.add_key_index = false; - bm_convert_params.use_shapekey = false; const int triangulation_threshold = force_triangulation ? 4 : 255; BMesh *bmesh = BKE_mesh_to_bmesh_ex(mesh, &bm_create_params, &bm_convert_params); @@ -115,7 +114,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams const float2 *uv_map = static_cast( CustomData_get_layer(&mesh->ldata, CD_PROP_FLOAT2)); - blender::Map vertex_map = generate_vertex_map(mesh, uv_map, export_params); + Map vertex_map = generate_vertex_map(mesh, uv_map, export_params); set_world_axes_transform( &export_object_eval_, export_params.forward_axis, export_params.up_axis); @@ -123,9 +122,9 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams /* Load faces into plyData. */ int loop_offset = 0; Span loops = mesh->loops(); - for (auto &&poly : mesh->polys()) { + for (const MPoly poly : mesh->polys()) { Span loopSpan = loops.slice(poly.loopstart, poly.totloop); - Vector polyVector; + Array polyVector(loopSpan.size()); for (int i = 0; i < loopSpan.size(); ++i) { float2 uv; @@ -137,7 +136,7 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams } UV_vertex_key key = UV_vertex_key(uv, loopSpan[i].v); int ply_vertex_index = vertex_map.lookup(key); - polyVector.append(uint32_t(ply_vertex_index + vertex_offset)); + polyVector[i] = (uint32_t(ply_vertex_index + vertex_offset)); } loop_offset += loopSpan.size(); @@ -185,12 +184,12 @@ void load_plydata(PlyData &plyData, Depsgraph *depsgraph, const PLYExportParams const StringRef name = mesh->active_color_attribute; if (!name.is_empty()) { const bke::AttributeAccessor attributes = mesh->attributes(); - const VArray colorAttribute = + const VArray color_attribute = attributes.lookup_or_default( name, ATTR_DOMAIN_POINT, {0.0f, 0.0f, 0.0f, 0.0f}); for (int i = 0; i < vertex_map.size(); i++) { - ColorGeometry4f colorGeometry = colorAttribute[mesh_vertex_index_LUT[i]]; + ColorGeometry4f colorGeometry = color_attribute[mesh_vertex_index_LUT[i]]; float4 vertColor(colorGeometry.r, colorGeometry.g, colorGeometry.b, colorGeometry.a); plyData.vertex_colors.append(vertColor); } diff --git a/source/blender/io/ply/exporter/ply_file_buffer.hh b/source/blender/io/ply/exporter/ply_file_buffer.hh index 5d52f24c647..faa2b07a980 100644 --- a/source/blender/io/ply/exporter/ply_file_buffer.hh +++ b/source/blender/io/ply/exporter/ply_file_buffer.hh @@ -10,6 +10,7 @@ #include #include +#include "BLI_array.hh" #include "BLI_compiler_attrs.h" #include "BLI_fileops.h" #include "BLI_string_ref.hh" @@ -101,7 +102,7 @@ class FileBuffer : private NonMovable { virtual void write_vertex_end() = 0; - virtual void write_face(char count, Vector const &vertex_indices) = 0; + virtual void write_face(char count, Array const &vertex_indices) = 0; virtual void write_edge(int first, int second) = 0; diff --git a/source/blender/io/ply/exporter/ply_file_buffer_ascii.hh b/source/blender/io/ply/exporter/ply_file_buffer_ascii.hh index 588b1178022..6ce17d55fbe 100644 --- a/source/blender/io/ply/exporter/ply_file_buffer_ascii.hh +++ b/source/blender/io/ply/exporter/ply_file_buffer_ascii.hh @@ -8,13 +8,12 @@ #include #include -#include +#include "BLI_array.hh" #include "BLI_compiler_attrs.h" #include "BLI_fileops.h" #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" -#include "BLI_vector.hh" #include "ply_file_buffer.hh" @@ -53,7 +52,7 @@ class FileBufferAscii : public FileBuffer { write_fstring("\n"); } - void write_face(char count, Vector const &vertex_indices) override + void write_face(char count, Array const &vertex_indices) override { write_fstring("{}", int(count)); diff --git a/source/blender/io/ply/exporter/ply_file_buffer_binary.hh b/source/blender/io/ply/exporter/ply_file_buffer_binary.hh index 608cee3a3a7..85ed666425c 100644 --- a/source/blender/io/ply/exporter/ply_file_buffer_binary.hh +++ b/source/blender/io/ply/exporter/ply_file_buffer_binary.hh @@ -9,12 +9,12 @@ #include #include +#include "BLI_array.hh" #include "BLI_compiler_attrs.h" #include "BLI_fileops.h" #include "BLI_math_vector_types.hh" #include "BLI_string_ref.hh" #include "BLI_utility_mixins.hh" -#include "BLI_vector.hh" #include "ply_file_buffer.hh" @@ -70,19 +70,13 @@ class FileBufferBinary : public FileBuffer { /* In binary, there is no end to a vertex. */ } - void write_face(char size, Vector const &vertex_indices) override + void write_face(char size, Array const &vertex_indices) override { - /* Pre allocate memory so no further allocation has to be done for typical faces. */ - Vector data; - data.append(size); - for (auto &&vertexIndex : vertex_indices) { - uint32_t x = vertexIndex; - auto *vtxbits = static_cast(static_cast(&x)); - data.insert(data.end(), vtxbits, vtxbits + sizeof(uint32_t)); - } + write_bytes(Span({size})); - Span span(data); - write_bytes(span); + Span dataSpan(reinterpret_cast(vertex_indices.data()), + vertex_indices.size() * sizeof(uint32_t)); + write_bytes(dataSpan); } void write_edge(int first, int second) override diff --git a/source/blender/io/ply/importer/ply_import_ascii.cc b/source/blender/io/ply/importer/ply_import_ascii.cc index 48295ecf096..7f672ae55cb 100644 --- a/source/blender/io/ply/importer/ply_import_ascii.cc +++ b/source/blender/io/ply/importer/ply_import_ascii.cc @@ -24,46 +24,46 @@ PlyData load_ply_ascii(std::ifstream &file, const PlyHeader *header) PlyData data; /* Check if header contains alpha. */ std::pair alpha = {"alpha", PlyDataTypes::UCHAR}; - bool hasAlpha = std::find(header->properties[0].begin(), header->properties[0].end(), alpha) != - header->properties[0].end(); + bool has_alpha = std::find(header->properties[0].begin(), header->properties[0].end(), alpha) != + header->properties[0].end(); /* Check if header contains colors. */ std::pair red = {"red", PlyDataTypes::UCHAR}; - bool hasColor = std::find(header->properties[0].begin(), header->properties[0].end(), red) != - header->properties[0].end(); + bool has_color = std::find(header->properties[0].begin(), header->properties[0].end(), red) != + header->properties[0].end(); /* Check if header contains normals. */ std::pair normalx = {"nx", PlyDataTypes::FLOAT}; - bool hasNormals = std::find(header->properties[0].begin(), - header->properties[0].end(), - normalx) != header->properties[0].end(); + bool has_normals = std::find(header->properties[0].begin(), + header->properties[0].end(), + normalx) != header->properties[0].end(); /* Check if header contains uv data. */ std::pair uv = {"s", PlyDataTypes::FLOAT}; - bool hasUv = std::find(header->properties[0].begin(), header->properties[0].end(), uv) != - header->properties[0].end(); + bool has_UV = std::find(header->properties[0].begin(), header->properties[0].end(), uv) != + header->properties[0].end(); - int3 vertexIndex = get_vertex_index(header); - int alphaIndex; - int3 colorIndex; - int3 normalIndex; - int2 uvIndex; + int3 vertex_index = get_vertex_index(header); + int alpha_index; + int3 color_index; + int3 normal_index; + int2 UV_index; - if (hasAlpha) { - alphaIndex = get_index(header, "alpha", PlyDataTypes::UCHAR); + if (has_alpha) { + alpha_index = get_index(header, "alpha", PlyDataTypes::UCHAR); } - if (hasColor) { + if (has_color) { /* x=red, y=green, z=blue */ - colorIndex = get_color_index(header); + color_index = get_color_index(header); } - if (hasNormals) { - normalIndex = get_normal_index(header); + if (has_normals) { + normal_index = get_normal_index(header); } - if (hasUv) { - uvIndex = get_uv_index(header); + if (has_UV) { + UV_index = get_uv_index(header); } for (int i = 0; i < header->vertex_count; i++) { @@ -73,20 +73,20 @@ PlyData load_ply_ascii(std::ifstream &file, const PlyHeader *header) /* Vertex coords */ float3 vertex3; - vertex3.x = std::stof(value_vec[vertexIndex.x]); - vertex3.y = std::stof(value_vec[vertexIndex.y]); - vertex3.z = std::stof(value_vec[vertexIndex.z]); + vertex3.x = std::stof(value_vec[vertex_index.x]); + vertex3.y = std::stof(value_vec[vertex_index.y]); + vertex3.z = std::stof(value_vec[vertex_index.z]); data.vertices.append(vertex3); /* Vertex colors */ - if (hasColor) { + if (has_color) { float4 colors4; - colors4.x = std::stof(value_vec[colorIndex.x]) / 255.0f; - colors4.y = std::stof(value_vec[colorIndex.y]) / 255.0f; - colors4.z = std::stof(value_vec[colorIndex.z]) / 255.0f; - if (hasAlpha) { - colors4.w = std::stof(value_vec[alphaIndex]) / 255.0f; + colors4.x = std::stof(value_vec[color_index.x]) / 255.0f; + colors4.y = std::stof(value_vec[color_index.y]) / 255.0f; + colors4.z = std::stof(value_vec[color_index.z]) / 255.0f; + if (has_alpha) { + colors4.w = std::stof(value_vec[alpha_index]) / 255.0f; } else { colors4.w = 1.0f; @@ -96,20 +96,20 @@ PlyData load_ply_ascii(std::ifstream &file, const PlyHeader *header) } /* If normals */ - if (hasNormals) { + if (has_normals) { float3 normals3; - normals3.x = std::stof(value_vec[normalIndex.x]); - normals3.y = std::stof(value_vec[normalIndex.y]); - normals3.z = std::stof(value_vec[normalIndex.z]); + normals3.x = std::stof(value_vec[normal_index.x]); + normals3.y = std::stof(value_vec[normal_index.y]); + normals3.z = std::stof(value_vec[normal_index.z]); data.vertex_normals.append(normals3); } /* If uv */ - if (hasUv) { + if (has_UV) { float2 uvmap; - uvmap.x = std::stof(value_vec[uvIndex.x]); - uvmap.y = std::stof(value_vec[uvIndex.y]); + uvmap.x = std::stof(value_vec[UV_index.x]); + uvmap.y = std::stof(value_vec[UV_index.y]); data.UV_coordinates.append(uvmap); } @@ -118,14 +118,16 @@ PlyData load_ply_ascii(std::ifstream &file, const PlyHeader *header) std::string line; getline(file, line); Vector value_vec = explode(line, ' '); - Vector vertex_indices; + int count = std::stoi(value_vec[0]); + Array vertex_indices(count); - for (int j = 1; j <= std::stoi(value_vec[0]); j++) { + for (int j = 1; j <= count; j++) { + int index = std::stoi(value_vec[j]); /* If the face has a vertex index that is outside the range. */ - if (std::stoi(value_vec[j]) >= data.vertices.size()) { + if (index >= data.vertices.size()) { throw std::runtime_error("Vertex index out of bounds"); } - vertex_indices.append(std::stoi(value_vec[j])); + vertex_indices[j - 1] = index; } data.faces.append(vertex_indices); } @@ -144,41 +146,41 @@ PlyData load_ply_ascii(std::ifstream &file, const PlyHeader *header) int3 get_vertex_index(const PlyHeader *header) { - int3 vertexPos; - vertexPos.x = get_index(header, "x", PlyDataTypes::FLOAT); - vertexPos.y = get_index(header, "y", PlyDataTypes::FLOAT); - vertexPos.z = get_index(header, "z", PlyDataTypes::FLOAT); + int3 vertex_index; + vertex_index.x = get_index(header, "x", PlyDataTypes::FLOAT); + vertex_index.y = get_index(header, "y", PlyDataTypes::FLOAT); + vertex_index.z = get_index(header, "z", PlyDataTypes::FLOAT); - return vertexPos; + return vertex_index; } int3 get_color_index(const PlyHeader *header) { - int3 vertexPos; - vertexPos.x = get_index(header, "red", PlyDataTypes::UCHAR); - vertexPos.y = get_index(header, "green", PlyDataTypes::UCHAR); - vertexPos.z = get_index(header, "blue", PlyDataTypes::UCHAR); + int3 color_index; + color_index.x = get_index(header, "red", PlyDataTypes::UCHAR); + color_index.y = get_index(header, "green", PlyDataTypes::UCHAR); + color_index.z = get_index(header, "blue", PlyDataTypes::UCHAR); - return vertexPos; + return color_index; } int3 get_normal_index(const PlyHeader *header) { - int3 vertexPos; - vertexPos.x = get_index(header, "nx", PlyDataTypes::FLOAT); - vertexPos.y = get_index(header, "ny", PlyDataTypes::FLOAT); - vertexPos.z = get_index(header, "nz", PlyDataTypes::FLOAT); + int3 normal_index; + normal_index.x = get_index(header, "nx", PlyDataTypes::FLOAT); + normal_index.y = get_index(header, "ny", PlyDataTypes::FLOAT); + normal_index.z = get_index(header, "nz", PlyDataTypes::FLOAT); - return vertexPos; + return normal_index; } int2 get_uv_index(const PlyHeader *header) { - int2 uvPos; - uvPos.x = get_index(header, "s", PlyDataTypes::FLOAT); - uvPos.y = get_index(header, "t", PlyDataTypes::FLOAT); + int2 uv_index; + uv_index.x = get_index(header, "s", PlyDataTypes::FLOAT); + uv_index.y = get_index(header, "t", PlyDataTypes::FLOAT); - return uvPos; + return uv_index; } int get_index(const PlyHeader *header, std::string property, PlyDataTypes datatype) @@ -188,7 +190,7 @@ int get_index(const PlyHeader *header, std::string property, PlyDataTypes dataty return (int)(it - header->properties[0].begin()); } -Vector explode(const StringRef &str, const char &ch) +Vector explode(const StringRef str, const char &ch) { std::string next; Vector result; diff --git a/source/blender/io/ply/importer/ply_import_ascii.hh b/source/blender/io/ply/importer/ply_import_ascii.hh index 01c6e2800fb..1a065ca8cf7 100644 --- a/source/blender/io/ply/importer/ply_import_ascii.hh +++ b/source/blender/io/ply/importer/ply_import_ascii.hh @@ -6,8 +6,6 @@ #pragma once -#include "BKE_mesh.h" - #include "DNA_mesh_types.h" #include "IO_ply.h" @@ -35,5 +33,5 @@ int3 get_color_index(const PlyHeader *header); int3 get_normal_index(const PlyHeader *header); int2 get_uv_index(const PlyHeader *header); int get_index(const PlyHeader *header, std::string property, PlyDataTypes datatype); -Vector explode(const StringRef &str, const char &ch); +Vector explode(const StringRef str, const char &ch); } // namespace blender::io::ply diff --git a/source/blender/io/ply/importer/ply_import_binary.cc b/source/blender/io/ply/importer/ply_import_binary.cc index 649d291be66..c74b845a90e 100644 --- a/source/blender/io/ply/importer/ply_import_binary.cc +++ b/source/blender/io/ply/importer/ply_import_binary.cc @@ -3,6 +3,7 @@ /** \file * \ingroup ply */ +#include "BLI_array.hh" #include "ply_import_binary.hh" @@ -113,7 +114,7 @@ PlyData load_ply_binary(std::ifstream &file, const PlyHeader *header) for (int j = 0; j < header->elements[i].second; j++) { /* Assume vertex_index_count_type is uchar. */ uint8_t count = read(file, isBigEndian); - Vector vertex_indices; + Array vertex_indices(count); /* Loop over the amount of vertex indices in this face. */ for (uint8_t k = 0; k < count; k++) { @@ -122,7 +123,7 @@ PlyData load_ply_binary(std::ifstream &file, const PlyHeader *header) if (index >= data.vertices.size()) { throw std::runtime_error("Vertex index out of bounds"); } - vertex_indices.append(index); + vertex_indices[k] = index; } data.faces.append(vertex_indices); } diff --git a/source/blender/io/ply/importer/ply_import_binary.hh b/source/blender/io/ply/importer/ply_import_binary.hh index da2c78220be..64cdd29154a 100644 --- a/source/blender/io/ply/importer/ply_import_binary.hh +++ b/source/blender/io/ply/importer/ply_import_binary.hh @@ -6,24 +6,22 @@ #pragma once -#include "BKE_mesh.h" - #include "ply_data.hh" namespace blender::io::ply { /** * The function that gets called from the importer. - * \param file The PLY file that was opened. - * \param header The information in the PLY header. + * \param file: The PLY file that was opened. + * \param header: The information in the PLY header. * \return The PlyData datastructure that can be used for conversion to a Mesh. */ std::unique_ptr import_ply_binary(std::ifstream &file, const PlyHeader *header); /** * Loads the information from the PLY file in binary format to the PlyData datastructure. - * \param file The PLY file that was opened. - * \param header The information in the PLY header. + * \param file: The PLY file that was opened. + * \param header: The information in the PLY header. * \return The PlyData datastructure that can be used for conversion to a Mesh. */ PlyData load_ply_binary(std::ifstream &file, const PlyHeader *header); diff --git a/source/blender/io/ply/importer/ply_import_mesh.cc b/source/blender/io/ply/importer/ply_import_mesh.cc index 9a4300a02a2..55e2761435e 100644 --- a/source/blender/io/ply/importer/ply_import_mesh.cc +++ b/source/blender/io/ply/importer/ply_import_mesh.cc @@ -24,8 +24,7 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ mesh->totvert = int(data.vertices.size()); CustomData_add_layer_named( &mesh->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, mesh->totvert, "position"); - MutableSpan verts = mesh->vert_positions_for_write(); - verts.copy_from(data.vertices); + mesh->vert_positions_for_write().copy_from(data.vertices); bke::MutableAttributeAccessor attributes = mesh->attributes_for_write(); @@ -83,16 +82,16 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ /* Uvmap */ if (!data.UV_coordinates.is_empty()) { - bke::SpanAttributeWriter Uv = attributes.lookup_or_add_for_write_only_span( + bke::SpanAttributeWriter uv_map = attributes.lookup_or_add_for_write_only_span( "UVMap", ATTR_DOMAIN_CORNER); int counter = 0; for (int i = 0; i < data.faces.size(); i++) { for (int j = 0; j < data.faces[i].size(); j++) { - copy_v2_v2(Uv.span[counter], data.UV_coordinates[data.faces[i][j]]); + copy_v2_v2(uv_map.span[counter], data.UV_coordinates[data.faces[i][j]]); counter++; } } - Uv.finish(); + uv_map.finish(); } /* Calculate edges from the rest of the mesh. */ @@ -100,25 +99,8 @@ Mesh *convert_ply_to_mesh(PlyData &data, Mesh *mesh, const PLYImportParams ¶ /* Note: This is important to do after initializing the loops. */ if (!data.vertex_normals.is_empty()) { - float(*vertex_normals)[3] = static_cast( - MEM_malloc_arrayN(data.vertex_normals.size(), sizeof(float[3]), __func__)); - - /* Below code is necessary to access vertex normals within Blender. - * Until Blender supports custom vertex normals, this is a workaround. */ - bke::SpanAttributeWriter normals; - if (params.import_normals_as_attribute) { - normals = attributes.lookup_or_add_for_write_span("Normal", ATTR_DOMAIN_POINT); - } - - for (int i = 0; i < data.vertex_normals.size(); i++) { - copy_v3_v3(vertex_normals[i], data.vertex_normals[i]); - if (normals) { - copy_v3_v3(normals.span[i], data.vertex_normals[i]); - } - } - normals.finish(); - BKE_mesh_set_custom_normals_from_verts(mesh, vertex_normals); - MEM_freeN(vertex_normals); + BKE_mesh_set_custom_normals_from_verts( + mesh, reinterpret_cast(data.vertex_normals.data())); } /* Merge all vertices on the same location. */ diff --git a/source/blender/io/ply/intern/ply_data.hh b/source/blender/io/ply/intern/ply_data.hh index daa390b4a9f..b3d7736dec6 100644 --- a/source/blender/io/ply/intern/ply_data.hh +++ b/source/blender/io/ply/intern/ply_data.hh @@ -6,6 +6,7 @@ #pragma once +#include "BLI_array.hh" #include "BLI_math_vector_types.hh" #include "BLI_vector.hh" @@ -20,7 +21,7 @@ struct PlyData { Vector vertex_colors; Vector> edges; Vector edge_colors; - Vector> faces; + Vector> faces; Vector UV_coordinates; }; diff --git a/source/blender/io/ply/tests/io_ply_exporter_test.cc b/source/blender/io/ply/tests/io_ply_exporter_test.cc index 664c95dc386..f9ffd491925 100644 --- a/source/blender/io/ply/tests/io_ply_exporter_test.cc +++ b/source/blender/io/ply/tests/io_ply_exporter_test.cc @@ -127,7 +127,7 @@ TEST_F(PlyExportTest, WriteHeaderAscii) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_header(buffer, plyData, _params); + write_header(*buffer.get(), *plyData.get(), _params); buffer->close_file(); @@ -165,7 +165,7 @@ TEST_F(PlyExportTest, WriteHeaderBinary) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_header(buffer, plyData, _params); + write_header(*buffer.get(), *plyData.get(), _params); buffer->close_file(); @@ -203,7 +203,7 @@ TEST_F(PlyExportTest, WriteVerticesAscii) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_vertices(buffer, plyData); + write_vertices(*buffer.get(), *plyData.get()); buffer->close_file(); @@ -235,7 +235,7 @@ TEST_F(PlyExportTest, WriteVerticesBinary) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_vertices(buffer, plyData); + write_vertices(*buffer.get(), *plyData.get()); buffer->close_file(); @@ -277,7 +277,7 @@ TEST_F(PlyExportTest, WriteFacesAscii) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_faces(buffer, plyData); + write_faces(*buffer.get(), *plyData.get()); buffer->close_file(); @@ -309,7 +309,7 @@ TEST_F(PlyExportTest, WriteFacesBinary) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_faces(buffer, plyData); + write_faces(*buffer.get(), *plyData.get()); buffer->close_file(); @@ -352,7 +352,7 @@ TEST_F(PlyExportTest, WriteVertexNormalsAscii) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_vertices(buffer, plyData); + write_vertices(*buffer.get(), *plyData.get()); buffer->close_file(); @@ -384,7 +384,7 @@ TEST_F(PlyExportTest, WriteVertexNormalsBinary) std::unique_ptr buffer = std::make_unique(_params.filepath); - write_vertices(buffer, plyData); + write_vertices(*buffer.get(), *plyData.get()); buffer->close_file(); diff --git a/source/blender/io/ply/tests/io_ply_importer_test.cc b/source/blender/io/ply/tests/io_ply_importer_test.cc index c2408e60aa5..a1f27cde110 100644 --- a/source/blender/io/ply/tests/io_ply_importer_test.cc +++ b/source/blender/io/ply/tests/io_ply_importer_test.cc @@ -53,7 +53,6 @@ class PlyImportTest : public BlendfileLoadingBaseTest { params.global_scale = 1.0f; params.forward_axis = IO_AXIS_NEGATIVE_Z; params.up_axis = IO_AXIS_Y; - params.import_normals_as_attribute = true; params.merge_verts = false; /* Import the test file. */ @@ -97,14 +96,10 @@ class PlyImportTest : public BlendfileLoadingBaseTest { EXPECT_V3_NEAR(verts.last(), exp.vert_last, 0.0001f); /* Fetch normal data from mesh and test if it matches expectation. */ - /* This uses the normal import workaround for vertex normals. This should be changed when - * Blender supports custom vertex normals. */ if (BKE_mesh_has_custom_loop_normals(mesh)) { - const float3 *vertex_normals = (const float3 *)CustomData_get_layer_named( - &mesh->vdata, CD_PROP_FLOAT3, "Normal"); - ASSERT_TRUE(vertex_normals != nullptr); - float3 normal_first = vertex_normals != nullptr ? vertex_normals[0] : float3(0, 0, 0); - EXPECT_V3_NEAR(normal_first, exp.normal_first, 0.0001f); + const Span vertex_normals = mesh->vertex_normals(); + ASSERT_FALSE(vertex_normals.is_empty()); + EXPECT_V3_NEAR(vertex_normals[0], exp.normal_first, 0.0001f); } /* Fetch UV data from mesh and test if it matches expectation. */ -- 2.30.2