Blender  V3.3
importer_mesh_utils.cc
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include "BKE_mesh.h"
8 #include "BKE_object.h"
9 
10 #include "BLI_delaunay_2d.h"
11 #include "BLI_math_vector.h"
12 #include "BLI_set.hh"
13 
14 #include "DNA_object_types.h"
15 
16 #include "IO_wavefront_obj.h"
17 
18 #include "importer_mesh_utils.hh"
19 
20 namespace blender::io::obj {
21 
23  Span<int> face_vertex_indices)
24 {
25  using namespace blender::meshintersect;
26  if (face_vertex_indices.size() < 3) {
27  return {};
28  }
29 
30  /* Calculate face normal, to project verts to 2D. */
31  float normal[3] = {0, 0, 0};
32  float3 co_prev = vertex_coords[face_vertex_indices.last()];
33  for (int idx : face_vertex_indices) {
34  BLI_assert(idx >= 0 && idx < vertex_coords.size());
35  float3 co_curr = vertex_coords[idx];
36  add_newell_cross_v3_v3v3(normal, co_prev, co_curr);
37  co_prev = co_curr;
38  }
39  if (UNLIKELY(normalize_v3(normal) == 0.0f)) {
40  normal[2] = 1.0f;
41  }
42  float axis_mat[3][3];
43  axis_dominant_v3_to_m3(axis_mat, normal);
44 
45  /* Prepare data for CDT. */
47  input.vert.reinitialize(face_vertex_indices.size());
48  input.face.reinitialize(1);
49  input.face[0].resize(face_vertex_indices.size());
50  for (int64_t i = 0; i < face_vertex_indices.size(); ++i) {
51  input.face[0][i] = i;
52  }
53  input.epsilon = 1.0e-6f;
54  input.need_ids = true;
55  /* Project vertices to 2D. */
56  for (size_t i = 0; i < face_vertex_indices.size(); ++i) {
57  int idx = face_vertex_indices[i];
58  BLI_assert(idx >= 0 && idx < vertex_coords.size());
59  float3 coord = vertex_coords[idx];
60  float2 coord2d;
61  mul_v2_m3v3(coord2d, axis_mat, coord);
62  input.vert[i] = double2(coord2d.x, coord2d.y);
63  }
64 
66 
67  /* Emit new face information from CDT result. */
69  faces.reserve(res.face.size());
70  for (const auto &f : res.face) {
71  Vector<int> face_verts;
72  face_verts.reserve(f.size());
73  for (int64_t i = 0; i < f.size(); ++i) {
74  int idx = f[i];
75  BLI_assert(idx >= 0 && idx < res.vert_orig.size());
76  if (res.vert_orig[idx].is_empty()) {
77  /* If we have a whole new vertex in the tessellated result,
78  * we won't quite know what to do with it (how to create normal/UV
79  * for it, for example). Such vertices are often due to
80  * self-intersecting polygons. Just skip them from the output
81  * polygon. */
82  }
83  else {
84  /* Vertex corresponds to one or more of the input vertices, use it. */
85  idx = res.vert_orig[idx][0];
86  BLI_assert(idx >= 0 && idx < face_vertex_indices.size());
87  face_verts.append(idx);
88  }
89  }
90  faces.append(face_verts);
91  }
92  return faces;
93 }
94 
95 void transform_object(Object *object, const OBJImportParams &import_params)
96 {
97  float axes_transform[3][3];
98  unit_m3(axes_transform);
99  float obmat[4][4];
100  unit_m4(obmat);
101  /* +Y-forward and +Z-up are the default Blender axis settings. */
103  IO_AXIS_Y, IO_AXIS_Z, import_params.forward_axis, import_params.up_axis, axes_transform);
104  copy_m4_m3(obmat, axes_transform);
105 
106  BKE_object_apply_mat4(object, obmat, true, false);
107 
108  if (import_params.clamp_size != 0.0f) {
109  float3 max_coord(-INT_MAX);
110  float3 min_coord(INT_MAX);
111  BoundBox *bb = BKE_mesh_boundbox_get(object);
112  for (const float(&vertex)[3] : bb->vec) {
113  for (int axis = 0; axis < 3; axis++) {
114  max_coord[axis] = max_ff(max_coord[axis], vertex[axis]);
115  min_coord[axis] = min_ff(min_coord[axis], vertex[axis]);
116  }
117  }
118  const float max_diff = max_fff(
119  max_coord[0] - min_coord[0], max_coord[1] - min_coord[1], max_coord[2] - min_coord[2]);
120  float scale = 1.0f;
121  while (import_params.clamp_size < max_diff * scale) {
122  scale = scale / 10;
123  }
124  copy_v3_fl(object->scale, scale);
125  }
126 }
127 
128 } // namespace blender::io::obj
struct BoundBox * BKE_mesh_boundbox_get(struct Object *ob)
Definition: mesh.cc:1207
General operations, lookup, etc. for blender objects.
void BKE_object_apply_mat4(struct Object *ob, const float mat[4][4], bool use_compat, bool use_parent)
Definition: object.cc:3575
#define BLI_assert(a)
Definition: BLI_assert.h:46
@ CDT_CONSTRAINTS_VALID_BMESH_WITH_HOLES
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
Normal to x,y matrix.
Definition: math_geom.c:3527
void unit_m3(float m[3][3])
Definition: math_matrix.c:40
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
Definition: math_matrix.c:917
void unit_m4(float m[4][4])
Definition: rct.c:1090
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:102
bool mat3_from_axis_conversion(int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
MINLINE float normalize_v3(float r[3])
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
MINLINE void copy_v3_fl(float r[3], float f)
#define UNLIKELY(x)
Object is a sort of wrapper for general info.
@ IO_AXIS_Y
Definition: IO_orientation.h:9
@ IO_AXIS_Z
constexpr const T & last(const int64_t n=0) const
Definition: BLI_span.hh:313
constexpr int64_t size() const
Definition: BLI_span.hh:240
void append(const T &value)
Definition: BLI_vector.hh:433
void reserve(const int64_t min_capacity)
Definition: BLI_vector.hh:340
blender::meshintersect::CDT_result< double > delaunay_2d_calc(const CDT_input< double > &input, CDT_output_type output_type)
IconTextureDrawCall normal
ccl_global KernelShaderEvalInput * input
static char faces[256]
Vector< Vector< int > > fixup_invalid_polygon(Span< float3 > vertex_coords, Span< int > face_vertex_indices)
void transform_object(Object *object, const OBJImportParams &import_params)
vec_base< double, 2 > double2
__int64 int64_t
Definition: stdint.h:89
float vec[8][3]
float scale[3]