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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/io/stl/importer/stl_import_mesh.cc')
-rw-r--r--source/blender/io/stl/importer/stl_import_mesh.cc114
1 files changed, 114 insertions, 0 deletions
diff --git a/source/blender/io/stl/importer/stl_import_mesh.cc b/source/blender/io/stl/importer/stl_import_mesh.cc
new file mode 100644
index 00000000000..b9ed441f0d9
--- /dev/null
+++ b/source/blender/io/stl/importer/stl_import_mesh.cc
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup stl
+ */
+
+#include "BKE_customdata.h"
+#include "BKE_lib_id.h"
+#include "BKE_main.h"
+#include "BKE_mesh.h"
+
+#include "BLI_array.hh"
+#include "BLI_math_vector.h"
+#include "BLI_math_vector.hh"
+#include "BLI_task.hh"
+
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "stl_import_mesh.hh"
+
+namespace blender::io::stl {
+
+STLMeshHelper::STLMeshHelper(int tris_num, bool use_custom_normals)
+ : use_custom_normals_(use_custom_normals)
+{
+ degenerate_tris_num_ = 0;
+ duplicate_tris_num_ = 0;
+ tris_.reserve(tris_num);
+ /* Upper bound (all vertices are unique). */
+ verts_.reserve(tris_num * 3);
+ if (use_custom_normals) {
+ loop_normals_.reserve(tris_num * 3);
+ }
+}
+
+bool STLMeshHelper::add_triangle(const float3 &a, const float3 &b, const float3 &c)
+{
+ int v1_id = verts_.index_of_or_add(a);
+ int v2_id = verts_.index_of_or_add(b);
+ int v3_id = verts_.index_of_or_add(c);
+ if ((v1_id == v2_id) || (v1_id == v3_id) || (v2_id == v3_id)) {
+ degenerate_tris_num_++;
+ return false;
+ }
+ if (!tris_.add({v1_id, v2_id, v3_id})) {
+ duplicate_tris_num_++;
+ return false;
+ }
+ return true;
+}
+
+void STLMeshHelper::add_triangle(const float3 &a,
+ const float3 &b,
+ const float3 &c,
+ const float3 &custom_normal)
+{
+ if (add_triangle(a, b, c)) {
+ loop_normals_.append_n_times(custom_normal, 3);
+ }
+}
+
+Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
+{
+ if (degenerate_tris_num_ > 0) {
+ std::cout << "STL Importer: " << degenerate_tris_num_ << " degenerate triangles were removed"
+ << std::endl;
+ }
+ if (duplicate_tris_num_ > 0) {
+ std::cout << "STL Importer: " << duplicate_tris_num_ << " duplicate triangles were removed"
+ << std::endl;
+ }
+
+ Mesh *mesh = BKE_mesh_add(bmain, mesh_name);
+ /* User count is already 1 here, but will be set later in #BKE_mesh_assign_object. */
+ id_us_min(&mesh->id);
+
+ mesh->totvert = verts_.size();
+ mesh->mvert = static_cast<MVert *>(
+ CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, nullptr, mesh->totvert));
+ for (int i = 0; i < mesh->totvert; i++) {
+ copy_v3_v3(mesh->mvert[i].co, verts_[i]);
+ }
+
+ mesh->totpoly = tris_.size();
+ mesh->totloop = tris_.size() * 3;
+ mesh->mpoly = static_cast<MPoly *>(
+ CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, nullptr, mesh->totpoly));
+ mesh->mloop = static_cast<MLoop *>(
+ CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, nullptr, mesh->totloop));
+
+ threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) {
+ for (const int i : tris_range) {
+ mesh->mpoly[i].loopstart = 3 * i;
+ mesh->mpoly[i].totloop = 3;
+
+ mesh->mloop[3 * i].v = tris_[i].v1;
+ mesh->mloop[3 * i + 1].v = tris_[i].v2;
+ mesh->mloop[3 * i + 2].v = tris_[i].v3;
+ }
+ });
+
+ /* NOTE: edges must be calculated first before setting custom normals. */
+ BKE_mesh_calc_edges(mesh, false, false);
+
+ if (use_custom_normals_ && loop_normals_.size() == mesh->totloop) {
+ BKE_mesh_set_custom_normals(mesh, reinterpret_cast<float(*)[3]>(loop_normals_.data()));
+ mesh->flag |= ME_AUTOSMOOTH;
+ }
+
+ return mesh;
+}
+
+} // namespace blender::io::stl