1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup stl
*/
#include <cstdio>
#include "BKE_customdata.h"
#include "BKE_layer.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
#include "DNA_collection_types.h"
#include "DNA_scene_types.h"
#include "BLI_fileops.hh"
#include "BLI_math_vector.h"
#include "BLI_memory_utils.hh"
#include "DNA_object_types.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "stl_import.hh"
#include "stl_import_ascii_reader.hh"
#include "stl_import_binary_reader.hh"
namespace blender::io::stl {
void importer_main(bContext *C, const STLImportParams &import_params)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
importer_main(bmain, scene, view_layer, import_params);
}
void importer_main(Main *bmain,
Scene *scene,
ViewLayer *view_layer,
const STLImportParams &import_params)
{
FILE *file = BLI_fopen(import_params.filepath, "rb");
if (!file) {
fprintf(stderr, "Failed to open STL file:'%s'.\n", import_params.filepath);
return;
}
BLI_SCOPED_DEFER([&]() { fclose(file); });
/* Detect STL file type by comparing file size with expected file size,
* could check if file starts with "solid", but some files do not adhere,
* this is the same as the old Python importer.
*/
uint32_t num_tri = 0;
size_t file_size = BLI_file_size(import_params.filepath);
fseek(file, BINARY_HEADER_SIZE, SEEK_SET);
fread(&num_tri, sizeof(uint32_t), 1, file);
bool is_ascii_stl = (file_size != (BINARY_HEADER_SIZE + 4 + BINARY_STRIDE * num_tri));
/* Name used for both mesh and object. */
char ob_name[FILE_MAX];
BLI_strncpy(ob_name, BLI_path_basename(import_params.filepath), FILE_MAX);
BLI_path_extension_replace(ob_name, FILE_MAX, "");
Mesh *mesh;
if (is_ascii_stl) {
mesh = read_stl_ascii(import_params.filepath, bmain, ob_name, import_params.use_facet_normal);
}
else {
mesh = read_stl_binary(file, bmain, ob_name, import_params.use_facet_normal);
}
if (import_params.use_mesh_validate) {
bool verbose_validate = false;
#ifdef DEBUG
verbose_validate = true;
#endif
BKE_mesh_validate(mesh, verbose_validate, false);
}
BKE_view_layer_base_deselect_all(view_layer);
LayerCollection *lc = BKE_layer_collection_get_active(view_layer);
Object *obj = BKE_object_add_only_object(bmain, OB_MESH, ob_name);
BKE_mesh_assign_object(bmain, obj, mesh);
BKE_collection_object_add(bmain, lc->collection, obj);
Base *base = BKE_view_layer_base_find(view_layer, obj);
BKE_view_layer_base_select_and_set_active(view_layer, base);
float global_scale = import_params.global_scale;
if ((scene->unit.system != USER_UNIT_NONE) && import_params.use_scene_unit) {
global_scale *= scene->unit.scale_length;
}
float scale_vec[3] = {global_scale, global_scale, global_scale};
float obmat3x3[3][3];
unit_m3(obmat3x3);
float obmat4x4[4][4];
unit_m4(obmat4x4);
/* +Y-forward and +Z-up are the Blender's default axis settings. */
mat3_from_axis_conversion(
IO_AXIS_Y, IO_AXIS_Z, import_params.forward_axis, import_params.up_axis, obmat3x3);
copy_m4_m3(obmat4x4, obmat3x3);
rescale_m4(obmat4x4, scale_vec);
BKE_object_apply_mat4(obj, obmat4x4, true, false);
DEG_id_tag_update(&lc->collection->id, ID_RECALC_COPY_ON_WRITE);
int flags = ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION |
ID_RECALC_BASE_FLAGS;
DEG_id_tag_update_ex(bmain, &obj->id, flags);
DEG_id_tag_update(&scene->id, ID_RECALC_BASE_FLAGS);
DEG_relations_tag_update(bmain);
}
} // namespace blender::io::stl
|