Blender  V3.3
stl_import_mesh.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BKE_customdata.h"
8 #include "BKE_lib_id.h"
9 #include "BKE_main.h"
10 #include "BKE_mesh.h"
11 
12 #include "BLI_array.hh"
13 #include "BLI_math_vector.h"
14 #include "BLI_math_vector.hh"
15 #include "BLI_task.hh"
16 
17 #include "DNA_mesh_types.h"
18 #include "DNA_meshdata_types.h"
19 
20 #include "stl_import_mesh.hh"
21 
22 namespace blender::io::stl {
23 
24 STLMeshHelper::STLMeshHelper(int tris_num, bool use_custom_normals)
25  : use_custom_normals_(use_custom_normals)
26 {
27  degenerate_tris_num_ = 0;
28  duplicate_tris_num_ = 0;
29  tris_.reserve(tris_num);
30  /* Upper bound (all vertices are unique). */
31  verts_.reserve(tris_num * 3);
32  if (use_custom_normals) {
33  loop_normals_.reserve(tris_num * 3);
34  }
35 }
36 
37 bool STLMeshHelper::add_triangle(const float3 &a, const float3 &b, const float3 &c)
38 {
39  int v1_id = verts_.index_of_or_add(a);
40  int v2_id = verts_.index_of_or_add(b);
41  int v3_id = verts_.index_of_or_add(c);
42  if ((v1_id == v2_id) || (v1_id == v3_id) || (v2_id == v3_id)) {
43  degenerate_tris_num_++;
44  return false;
45  }
46  if (!tris_.add({v1_id, v2_id, v3_id})) {
47  duplicate_tris_num_++;
48  return false;
49  }
50  return true;
51 }
52 
54  const float3 &b,
55  const float3 &c,
56  const float3 &custom_normal)
57 {
58  if (add_triangle(a, b, c)) {
59  loop_normals_.append_n_times(custom_normal, 3);
60  }
61 }
62 
63 Mesh *STLMeshHelper::to_mesh(Main *bmain, char *mesh_name)
64 {
65  if (degenerate_tris_num_ > 0) {
66  std::cout << "STL Importer: " << degenerate_tris_num_ << " degenerate triangles were removed"
67  << std::endl;
68  }
69  if (duplicate_tris_num_ > 0) {
70  std::cout << "STL Importer: " << duplicate_tris_num_ << " duplicate triangles were removed"
71  << std::endl;
72  }
73 
74  Mesh *mesh = BKE_mesh_add(bmain, mesh_name);
75  /* User count is already 1 here, but will be set later in #BKE_mesh_assign_object. */
76  id_us_min(&mesh->id);
77 
78  mesh->totvert = verts_.size();
79  mesh->mvert = static_cast<MVert *>(
81  for (int i = 0; i < mesh->totvert; i++) {
82  copy_v3_v3(mesh->mvert[i].co, verts_[i]);
83  }
84 
85  mesh->totpoly = tris_.size();
86  mesh->totloop = tris_.size() * 3;
87  mesh->mpoly = static_cast<MPoly *>(
89  mesh->mloop = static_cast<MLoop *>(
91 
92  threading::parallel_for(tris_.index_range(), 2048, [&](IndexRange tris_range) {
93  for (const int i : tris_range) {
94  mesh->mpoly[i].loopstart = 3 * i;
95  mesh->mpoly[i].totloop = 3;
96 
97  mesh->mloop[3 * i].v = tris_[i].v1;
98  mesh->mloop[3 * i + 1].v = tris_[i].v2;
99  mesh->mloop[3 * i + 2].v = tris_[i].v3;
100  }
101  });
102 
103  /* NOTE: edges must be calculated first before setting custom normals. */
104  BKE_mesh_calc_edges(mesh, false, false);
105 
106  if (use_custom_normals_ && loop_normals_.size() == mesh->totloop) {
107  BKE_mesh_set_custom_normals(mesh, reinterpret_cast<float(*)[3]>(loop_normals_.data()));
108  mesh->flag |= ME_AUTOSMOOTH;
109  }
110 
111  return mesh;
112 }
113 
114 } // namespace blender::io::stl
CustomData interface, see also DNA_customdata_types.h.
@ CD_CALLOC
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
void id_us_min(struct ID *id)
Definition: lib_id.c:313
struct Mesh * BKE_mesh_add(struct Main *bmain, const char *name)
Definition: mesh.cc:963
void BKE_mesh_set_custom_normals(struct Mesh *mesh, float(*r_custom_loopnors)[3])
void BKE_mesh_calc_edges(struct Mesh *mesh, bool keep_existing_edges, bool select_new_edges)
MINLINE void copy_v3_v3(float r[3], const float a[3])
@ CD_MVERT
@ ME_AUTOSMOOTH
Mesh * to_mesh(Main *bmain, char *mesh_name)
bool add_triangle(const float3 &a, const float3 &b, const float3 &c)
STLMeshHelper(int tris_num, bool use_custom_normals)
static unsigned c
Definition: RandGen.cpp:83
static unsigned a[3]
Definition: RandGen.cpp:78
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)
Definition: BLI_task.hh:51
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
float co[3]
Definition: BKE_main.h:121
CustomData vdata
struct MVert * mvert
uint16_t flag
int totvert
struct MLoop * mloop
CustomData pdata
int totpoly
int totloop
struct MPoly * mpoly
CustomData ldata