Blender V4.3
clay_thumb.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2024 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
6
7#include "DNA_brush_types.h"
8#include "DNA_mesh_types.h"
9#include "DNA_object_types.h"
10#include "DNA_scene_types.h"
11
12#include "BKE_key.hh"
13#include "BKE_mesh.hh"
14#include "BKE_paint.hh"
15#include "BKE_pbvh.hh"
16#include "BKE_subdiv_ccg.hh"
17
18#include "BLI_array.hh"
20#include "BLI_math_geom.h"
21#include "BLI_math_matrix.h"
22#include "BLI_math_matrix.hh"
23#include "BLI_math_rotation.h"
24#include "BLI_math_vector.h"
25#include "BLI_math_vector.hh"
26#include "BLI_task.h"
27#include "BLI_task.hh"
28
32
34
35inline namespace clay_thumb_cc {
36
43
44static void calc_faces(const Depsgraph &depsgraph,
45 const Sculpt &sd,
46 const Brush &brush,
47 const float4 &plane_tilt,
48 const float strength,
49 const MeshAttributeData &attribute_data,
50 const Span<float3> vert_normals,
51 const bke::pbvh::MeshNode &node,
52 Object &object,
53 LocalData &tls,
54 const PositionDeformData &position_data)
55{
56 SculptSession &ss = *object.sculpt;
57
58 const Span<int> verts = node.verts();
59 const MutableSpan positions = gather_data_mesh(position_data.eval, verts, tls.positions);
60
62 brush,
63 object,
64 attribute_data,
65 positions,
66 vert_normals,
67 node,
68 tls.factors,
69 tls.distances);
70
71 scale_factors(tls.factors, strength);
72
73 tls.translations.resize(verts.size());
74 const MutableSpan<float3> translations = tls.translations;
75 calc_translations_to_plane(positions, plane_tilt, translations);
76
77 scale_translations(translations, tls.factors);
78
79 clip_and_lock_translations(sd, ss, positions, translations);
80 position_data.deform(translations, verts);
81}
82
83static void calc_grids(const Depsgraph &depsgraph,
84 const Sculpt &sd,
85 const Brush &brush,
86 const float4 &plane_tilt,
87 const float strength,
88 const bke::pbvh::GridsNode &node,
89 Object &object,
90 LocalData &tls)
91{
92 SculptSession &ss = *object.sculpt;
93 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
94
95 const Span<int> grids = node.grids();
96 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
97
98 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
99
100 scale_factors(tls.factors, strength);
101
102 tls.translations.resize(positions.size());
103 const MutableSpan<float3> translations = tls.translations;
104 calc_translations_to_plane(positions, plane_tilt, translations);
105
106 scale_translations(translations, tls.factors);
107
108 clip_and_lock_translations(sd, ss, positions, translations);
109 apply_translations(translations, grids, subdiv_ccg);
110}
111
112static void calc_bmesh(const Depsgraph &depsgraph,
113 const Sculpt &sd,
114 const Brush &brush,
115 const float4 &plane_tilt,
116 const float strength,
117 Object &object,
119 LocalData &tls)
120{
121 SculptSession &ss = *object.sculpt;
122
124 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
125
126 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
127
128 scale_factors(tls.factors, strength);
129
130 tls.translations.resize(verts.size());
131 const MutableSpan<float3> translations = tls.translations;
132 calc_translations_to_plane(positions, plane_tilt, translations);
133
134 scale_translations(translations, tls.factors);
135
136 clip_and_lock_translations(sd, ss, positions, translations);
137 apply_translations(translations, verts);
138}
139
140} // namespace clay_thumb_cc
141
142void do_clay_thumb_brush(const Depsgraph &depsgraph,
143 const Sculpt &sd,
144 Object &object,
145 const IndexMask &node_mask)
146{
147 const SculptSession &ss = *object.sculpt;
148 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
149 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
150 const float3 &location = ss.cache->location_symm;
151
152 /* Sampled geometry normal and area center. */
153 float3 area_no_sp;
154 float3 area_no;
155 float3 area_co_tmp;
156
157 float4x4 tmat;
158
159 calc_brush_plane(depsgraph, brush, object, node_mask, area_no_sp, area_co_tmp);
160
162 area_no = calc_area_normal(depsgraph, brush, object, node_mask).value_or(float3(0));
163 }
164 else {
165 area_no = area_no_sp;
166 }
167
168 /* Delay the first daub because grab delta is not setup. */
171 return;
172 }
173
174 /* Simulate the clay accumulation by increasing the plane angle as more samples are added to the
175 * stroke. */
178 ss.cache->clay_thumb_brush.front_angle = std::clamp(
179 ss.cache->clay_thumb_brush.front_angle, 0.0f, 60.0f);
180 }
181
183 return;
184 }
185
186 /* Initialize brush local-space matrix. */
188 mat.x_axis() = math::cross(area_no, ss.cache->grab_delta_symm);
189 mat.y_axis() = math::cross(area_no, mat.x_axis());
190 mat.z_axis() = area_no;
191 mat.location() = ss.cache->location_symm;
192 normalize_m4(mat.ptr());
193
194 /* Scale brush local space matrix. */
196 mul_m4_m4m4(tmat.ptr(), mat.ptr(), scale.ptr());
197 invert_m4_m4(mat.ptr(), tmat.ptr());
198
199 float clay_strength = ss.cache->bstrength * clay_thumb_get_stabilized_pressure(*ss.cache);
200
201 float4 plane_tilt;
202 float3 normal_tilt;
203 float4x4 imat;
204
205 invert_m4_m4(imat.ptr(), mat.ptr());
207 normal_tilt, area_no_sp, imat[0], DEG2RADF(-ss.cache->clay_thumb_brush.front_angle));
208
209 /* Tilted plane (front part of the brush). */
210 plane_from_point_normal_v3(plane_tilt, location, normal_tilt);
211
213 switch (pbvh.type()) {
215 const Mesh &mesh = *static_cast<Mesh *>(object.data);
216 const MeshAttributeData attribute_data(mesh.attributes());
218 const PositionDeformData position_data(depsgraph, object);
219 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
220 node_mask.foreach_index(GrainSize(1), [&](const int i) {
221 LocalData &tls = all_tls.local();
223 sd,
224 brush,
225 plane_tilt,
226 clay_strength,
227 attribute_data,
228 vert_normals,
229 nodes[i],
230 object,
231 tls,
232 position_data);
233 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
234 });
235 break;
236 }
238 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
239 MutableSpan<float3> positions = subdiv_ccg.positions;
241 node_mask.foreach_index(GrainSize(1), [&](const int i) {
242 LocalData &tls = all_tls.local();
243 calc_grids(depsgraph, sd, brush, plane_tilt, clay_strength, nodes[i], object, tls);
244 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
245 });
246 break;
247 }
250 node_mask.foreach_index(GrainSize(1), [&](const int i) {
251 LocalData &tls = all_tls.local();
252 calc_bmesh(depsgraph, sd, brush, plane_tilt, clay_strength, object, nodes[i], tls);
254 });
255 break;
256 }
257 }
258 pbvh.tag_positions_changed(node_mask);
260}
261
263{
264 const float pressure_sum = std::accumulate(cache.clay_thumb_brush.pressure_stabilizer.begin(),
266 0.0f);
267 return pressure_sum / cache.clay_thumb_brush.pressure_stabilizer.size();
268}
269
270} // namespace blender::ed::sculpt_paint
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:654
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition math_geom.cc:215
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void normalize_m4(float R[4][4]) ATTR_NONNULL()
#define DEG2RADF(_deg)
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], float angle)
@ BRUSH_ORIGINAL_NORMAL
@ SCULPT_DISP_DIR_AREA
Object is a sort of wrapper for general info.
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:549
Span< NodeT > nodes() const
void deform(MutableSpan< float3 > translations, Span< int > verts) const
Definition sculpt.cc:7139
void foreach_index(Fn &&fn) const
const Depsgraph * depsgraph
static float verts[][3]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1095
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1075
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2502
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1084
void flush_bounds_to_parents(Tree &pbvh)
Definition pbvh.cc:1132
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float3 &direction, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float4 &test_plane, const float strength, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
Definition clay.cc:58
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float4 &test_plane, const float strength, bke::pbvh::GridsNode &node, LocalData &tls)
Definition clay.cc:95
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float4 &plane_tilt, const float strength, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
Definition clay_thumb.cc:44
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float4 &plane_tilt, const float strength, Object &object, bke::pbvh::BMeshNode &node, LocalData &tls)
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float4 &plane_tilt, const float strength, const bke::pbvh::GridsNode &node, Object &object, LocalData &tls)
Definition clay_thumb.cc:83
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6054
void calc_factors_common_grids(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, const bke::pbvh::GridsNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6270
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7210
float clay_thumb_get_stabilized_pressure(const StrokeCache &cache)
void calc_translations_to_plane(Span< float3 > vert_positions, Span< int > verts, const float4 &plane, MutableSpan< float3 > translations)
Definition sculpt.cc:7479
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7227
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7022
void calc_brush_plane(const Depsgraph &depsgraph, const Brush &brush, Object &ob, const IndexMask &node_mask, float3 &r_area_no, float3 &r_area_co)
Definition sculpt.cc:2789
std::optional< float3 > calc_area_normal(const Depsgraph &depsgraph, const Brush &brush, const Object &ob, const IndexMask &node_mask)
Definition sculpt.cc:1848
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
void calc_factors_common_mesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > positions, Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6235
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6082
void calc_factors_common_bmesh(const Depsgraph &depsgraph, const Brush &brush, const Object &object, Span< float3 > positions, bke::pbvh::BMeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6304
void do_clay_thumb_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
bool is_zero(const T &a)
AxisSigned cross(const AxisSigned a, const AxisSigned b)
MatT from_scale(const VecBase< typename MatT::base_type, ScaleDim > &scale)
VecBase< float, 3 > float3
bool SCULPT_stroke_is_first_brush_step_of_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
Definition sculpt.cc:513
bool SCULPT_stroke_is_main_symmetry_pass(const blender::ed::sculpt_paint::StrokeCache &cache)
Definition sculpt.cc:501
int sculpt_plane
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions
const c_style_mat & ptr() const
struct blender::ed::sculpt_paint::StrokeCache::@481 clay_thumb_brush
std::array< float, 10 > pressure_stabilizer