Blender V4.3
stl_import_mesh.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include <iostream>
10
11#include "BKE_mesh.hh"
12
13#include "BLI_array_utils.hh"
14#include "BLI_span.hh"
15
16#include "DNA_mesh_types.h"
17
18#include "stl_data.hh"
19#include "stl_import_mesh.hh"
20
21namespace blender::io::stl {
22
23STLMeshHelper::STLMeshHelper(int tris_num, bool use_custom_normals)
24 : use_custom_normals_(use_custom_normals)
25{
26 degenerate_tris_num_ = 0;
27 duplicate_tris_num_ = 0;
28 tris_.reserve(tris_num);
29 /* Upper bound (all vertices are unique). */
30 verts_.reserve(tris_num * 3);
31 if (use_custom_normals) {
32 loop_normals_.reserve(tris_num * 3);
33 }
34}
35
37{
38 int v1_id = verts_.index_of_or_add(data.vertices[0]);
39 int v2_id = verts_.index_of_or_add(data.vertices[1]);
40 int v3_id = verts_.index_of_or_add(data.vertices[2]);
41 if ((v1_id == v2_id) || (v1_id == v3_id) || (v2_id == v3_id)) {
42 degenerate_tris_num_++;
43 return false;
44 }
45 if (!tris_.add({v1_id, v2_id, v3_id})) {
46 duplicate_tris_num_++;
47 return false;
48 }
49
50 if (use_custom_normals_) {
51 loop_normals_.append_n_times(data.normal, 3);
52 }
53 return true;
54}
55
57{
58 if (degenerate_tris_num_ > 0) {
59 std::cout << "STL Importer: " << degenerate_tris_num_ << " degenerate triangles were removed"
60 << std::endl;
61 }
62 if (duplicate_tris_num_ > 0) {
63 std::cout << "STL Importer: " << duplicate_tris_num_ << " duplicate triangles were removed"
64 << std::endl;
65 }
66
67 Mesh *mesh = BKE_mesh_new_nomain(verts_.size(), 0, tris_.size(), tris_.size() * 3);
68 mesh->vert_positions_for_write().copy_from(verts_);
69 offset_indices::fill_constant_group_size(3, 0, mesh->face_offsets_for_write());
70 array_utils::copy(tris_.as_span().cast<int>(), mesh->corner_verts_for_write());
71
72 bke::mesh_smooth_set(*mesh, false);
73
74 /* NOTE: edges must be calculated first before setting custom normals. */
75 bke::mesh_calc_edges(*mesh, false, false);
76
77 if (use_custom_normals_ && loop_normals_.size() == mesh->corners_num) {
78 BKE_mesh_set_custom_normals(mesh, reinterpret_cast<float(*)[3]>(loop_normals_.data()));
79 }
80
81 return mesh;
82}
83
84} // namespace blender::io::stl
void BKE_mesh_set_custom_normals(Mesh *mesh, float(*r_custom_loop_normals)[3])
Mesh * BKE_mesh_new_nomain(int verts_num, int edges_num, int faces_num, int corners_num)
bool add_triangle(const PackedTriangle &data)
STLMeshHelper(int tris_num, bool use_custom_normals)
void copy(const GVArray &src, GMutableSpan dst, int64_t grain_size=4096)
void mesh_smooth_set(Mesh &mesh, bool use_smooth, bool keep_sharp_edges=false)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
void fill_constant_group_size(int size, int start_offset, MutableSpan< int > offsets)