Blender V5.0
importer_mesh_utils.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
8
9#include "BKE_mesh.hh"
10#include "BKE_object.hh"
11
12#include "BLI_delaunay_2d.hh"
13#include "BLI_math_geom.h"
14#include "BLI_math_matrix.h"
15#include "BLI_math_rotation.h"
16#include "BLI_math_vector.h"
17
18#include "DNA_object_types.h"
19
20#include "IO_wavefront_obj.hh"
21
23
24#include <numeric>
25
26namespace blender::io::obj {
27
29{
30 using namespace blender::meshintersect;
31 if (face_verts.size() < 3) {
32 return {};
33 }
34
35 const float3 normal = bke::mesh::face_normal_calc(vert_positions, face_verts);
36 float axis_mat[3][3];
37 axis_dominant_v3_to_m3(axis_mat, normal);
38
39 /* Project vertices to 2D. */
40 Array<double2> input_verts(face_verts.size());
41 for (const int i : face_verts.index_range()) {
42 int idx = face_verts[i];
43 BLI_assert(idx >= 0 && idx < vert_positions.size());
44 float2 coord2d;
45 mul_v2_m3v3(coord2d, axis_mat, vert_positions[idx]);
46 input_verts[i] = double2(coord2d.x, coord2d.y);
47 }
48
49 Array<Vector<int>> input_faces(1);
50 input_faces.first().resize(input_verts.size());
51
52 std::iota(input_faces.first().begin(), input_faces.first().end(), 0);
53
54 /* Prepare data for CDT. */
56 input.vert = std::move(input_verts);
57 input.face = std::move(input_faces);
58 input.epsilon = 1.0e-6f;
59 input.need_ids = true;
61
62 /* Emit new face information from CDT result. */
64 faces.reserve(res.face.size());
65 for (const auto &res_face : res.face) {
66 Vector<int> res_face_verts;
67 res_face_verts.reserve(res_face.size());
68 for (int64_t i = 0; i < res_face.size(); ++i) {
69 int idx = res_face[i];
70 BLI_assert(idx >= 0 && idx < res.vert_orig.size());
71 if (res.vert_orig[idx].is_empty()) {
72 /* If we have a whole new vertex in the tessellated result, we won't quite know what to do
73 * with it (how to create normal/UV for it, for example). Such vertices are often due to
74 * self-intersecting faces. Just skip them from the output face. */
75 }
76 else {
77 /* Vertex corresponds to one or more of the input vertices, use it. */
78 idx = res.vert_orig[idx][0];
79 BLI_assert(idx >= 0 && idx < face_verts.size());
80 res_face_verts.append(idx);
81 }
82 }
83 faces.append(res_face_verts);
84 }
85 return faces;
86}
87
88void transform_object(Object *object, const OBJImportParams &import_params)
89{
90 float axes_transform[3][3];
91 unit_m3(axes_transform);
92 float obmat[4][4];
93 unit_m4(obmat);
94 /* +Y-forward and +Z-up are the default Blender axis settings. */
96 IO_AXIS_Y, IO_AXIS_Z, import_params.forward_axis, import_params.up_axis, axes_transform);
97 copy_m4_m3(obmat, axes_transform);
98
99 float scale_vec[3] = {
100 import_params.global_scale, import_params.global_scale, import_params.global_scale};
101 rescale_m4(obmat, scale_vec);
102 BKE_object_apply_mat4(object, obmat, true, false);
103}
104
105std::string get_geometry_name(const std::string &full_name, char separator)
106{
107 if (separator == 0) {
108 return full_name;
109 }
110 size_t pos = full_name.find_last_of(separator);
111 if (pos == std::string::npos) {
112 return full_name;
113 }
114 return full_name.substr(pos + 1);
115}
116
117} // namespace blender::io::obj
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4(Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
#define BLI_assert(a)
Definition BLI_assert.h:46
@ CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
void unit_m3(float m[3][3])
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void rescale_m4(float mat[4][4], const float scale[3])
void unit_m4(float m[4][4])
bool mat3_from_axis_conversion(int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
Object is a sort of wrapper for general info.
@ IO_AXIS_Y
@ IO_AXIS_Z
long long int int64_t
int64_t size() const
Definition BLI_array.hh:256
const T & first() const
Definition BLI_array.hh:281
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
void append(const T &value)
void reserve(const int64_t min_capacity)
uint pos
#define input
static char faces[256]
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
void transform_object(Object *object, const OBJImportParams &import_params)
Vector< Vector< int > > fixup_invalid_face(Span< float3 > vert_positions, Span< int > face_verts)
std::string get_geometry_name(const std::string &full_name, char separator)
CDT_result< double > delaunay_2d_calc(const CDT_input< double > &input, CDT_output_type output_type)
VecBase< double, 2 > double2
VecBase< float, 2 > float2
VecBase< float, 3 > float3
i
Definition text_draw.cc:230