Blender V5.0
multires_reshape_apply_base.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "multires_reshape.hh"
10
11#include "MEM_guardedalloc.h"
12
13#include "DNA_mesh_types.h"
14
15#include "BLI_math_matrix.hh"
16#include "BLI_math_vector.h"
17
18#include "BKE_mesh.hh"
19#include "BKE_multires.hh"
20#include "BKE_subdiv_eval.hh"
21
23{
24 Mesh *base_mesh = reshape_context->base_mesh;
25 blender::MutableSpan<blender::float3> base_positions = base_mesh->vert_positions_for_write();
26 /* Update the context in case the vertices were duplicated. */
27 reshape_context->base_positions = base_positions;
28
29 const blender::Span<int> corner_verts = reshape_context->base_corner_verts;
30 for (const int loop_index : corner_verts.index_range()) {
31
32 GridCoord grid_coord;
33 grid_coord.grid_index = loop_index;
34 grid_coord.u = 1.0f;
35 grid_coord.v = 1.0f;
36
38 blender::float3x3 tangent_matrix;
40 reshape_context, &grid_coord, P, tangent_matrix);
41
43 reshape_context, &grid_coord);
45 grid_element.displacement);
46
47 base_positions[corner_verts[loop_index]] = P + D;
48 }
49}
50
51/* Assumes no is normalized; return value's sign is negative if v is on the other side of the
52 * plane.
53 *
54 * TODO: This should probably be substituted with a call in `math_geom.cc` or this should be
55 * promoted into that class.
56 */
58 const blender::float3 &center,
59 const blender::float3 &no)
60{
61 const blender::float3 s = v - center;
62 return blender::math::dot(s, no);
63}
64
66{
67 Mesh *base_mesh = reshape_context->base_mesh;
68 blender::MutableSpan<blender::float3> base_positions = base_mesh->vert_positions_for_write();
69 /* Update the context in case the vertices were duplicated. */
70 reshape_context->base_positions = base_positions;
71 const blender::GroupedSpan<int> vert_to_face_map = base_mesh->vert_to_face_map();
72
74 for (int i = 0; i < base_mesh->verts_num; i++) {
75 origco[i] = base_positions[i];
76 }
77
78 for (int i = 0; i < base_mesh->verts_num; i++) {
79 blender::float3 avg_no(0.0f);
80 blender::float3 center(0.0f);
81
82 /* Don't adjust vertices not used by at least one face. */
83 if (vert_to_face_map[i].is_empty()) {
84 continue;
85 }
86
87 /* Find center. */
88 int tot = 0;
89 for (const int face : vert_to_face_map[i]) {
90 /* This double counts, not sure if that's bad or good. */
91 for (const int corner : reshape_context->base_faces[face]) {
92 const int vndx = reshape_context->base_corner_verts[corner];
93 if (vndx != i) {
94 center += origco[vndx];
95 tot++;
96 }
97 }
98 }
99 center *= blender::math::rcp(float(tot));
100
101 /* Find normal. */
102 for (int j = 0; j < vert_to_face_map[i].size(); j++) {
103 const blender::IndexRange face = reshape_context->base_faces[vert_to_face_map[i][j]];
104
105 /* Set up face, loops, and coords in order to call #bke::mesh::face_normal_calc(). */
106 blender::Array<int> face_verts(face.size());
108
109 for (int k = 0; k < face.size(); k++) {
110 const int vndx = reshape_context->base_corner_verts[face[k]];
111
112 face_verts[k] = k;
113
114 if (vndx == i) {
115 fake_co[k] = center;
116 }
117 else {
118 fake_co[k] = origco[vndx];
119 }
120 }
121
122 const blender::float3 no = blender::bke::mesh::face_normal_calc(fake_co, face_verts);
123 avg_no += no;
124 }
125 avg_no = blender::math::normalize(avg_no);
126
127 /* Push vertex away from the plane. */
128 const float dist = v3_dist_from_plane(base_positions[i], center, avg_no);
129 const blender::float3 push = avg_no * dist;
130 base_positions[i] += push;
131 }
132
133 /* Vertices were moved around, need to update normals after all the vertices are updated
134 * Probably this is possible to do in the loop above, but this is rather tricky because
135 * we don't know all needed vertices' coordinates there yet. */
136 base_mesh->tag_positions_changed();
137}
138
140{
142 reshape_context->subdiv, reshape_context->base_mesh, {});
143}
144
146{
147 Depsgraph *depsgraph = reshape_context->depsgraph;
148 Object *object = reshape_context->object;
149 MultiresModifierData *mmd = reshape_context->mmd;
150 BLI_assert(depsgraph != nullptr);
151 BLI_assert(object != nullptr);
152 BLI_assert(mmd != nullptr);
153
154 blender::Array<blender::float3> deformed_verts =
156
158 reshape_context->subdiv, reshape_context->base_mesh, deformed_verts);
159}
blender::Array< blender::float3 > BKE_multires_create_deformed_base_mesh_vert_coords(Depsgraph *depsgraph, Object *object, MultiresModifierData *mmd)
Definition multires.cc:119
#define D
#define BLI_assert(a)
Definition BLI_assert.h:46
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v
BPy_StructRNA * depsgraph
constexpr int64_t size() const
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
ReshapeConstGridElement multires_reshape_orig_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
void multires_reshape_evaluate_base_mesh_limit_at_grid(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, blender::float3 &r_P, blender::float3x3 &r_tangent_matrix)
void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context)
static float v3_dist_from_plane(const blender::float3 &v, const blender::float3 &center, const blender::float3 &no)
void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context)
void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context)
void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *reshape_context)
float3 face_normal_calc(Span< float3 > vert_positions, Span< int > face_verts)
bool eval_refine_from_mesh(Subdiv *subdiv, const Mesh *mesh, Span< float3 > coarse_vert_positions)
T dot(const QuaternionBase< T > &a, const QuaternionBase< T > &b)
T rcp(const T &a)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< T, 3 > transform_direction(const MatBase< T, 3, 3 > &mat, const VecBase< T, 3 > &direction)
MatBase< float, 3, 3 > float3x3
VecBase< float, 3 > float3
int verts_num
blender::bke::subdiv::Subdiv * subdiv
blender::OffsetIndices< int > base_faces
blender::Span< blender::float3 > base_positions
blender::Span< int > base_corner_verts
MultiresModifierData * mmd
i
Definition text_draw.cc:230