Blender V4.3
clay.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
10#include "BKE_pbvh.hh"
11#include "BKE_subdiv_ccg.hh"
12
14#include "BLI_math_base.hh"
15#include "BLI_math_geom.h"
16#include "BLI_math_vector.hh"
17#include "BLI_task.h"
18#include "BLI_utildefines.h"
19
23
25inline namespace clay_cc {
32
33BLI_NOINLINE static void calc_closest_to_plane(const float4 &test_plane,
34 const Span<float3> positions,
35 const Span<int> verts,
36 const MutableSpan<float3> translations)
37{
38 /* Equivalent to #closest_to_plane_normalized_v3 */
39 BLI_assert(verts.size() == translations.size());
40 for (const int i : verts.index_range()) {
41 const float side = plane_point_side_v3(test_plane, positions[verts[i]]);
42 translations[i] = float3(test_plane) * -side;
43 }
44}
45
46BLI_NOINLINE static void calc_closest_to_plane(const float4 &test_plane,
47 const Span<float3> positions,
48 const MutableSpan<float3> translations)
49{
50 /* Equivalent to #closest_to_plane_normalized_v3 */
51 BLI_assert(positions.size() == translations.size());
52 for (const int i : positions.index_range()) {
53 const float side = plane_point_side_v3(test_plane, positions[i]);
54 translations[i] = float3(test_plane) * -side;
55 }
56}
57
58static void calc_faces(const Depsgraph &depsgraph,
59 const Sculpt &sd,
60 const Brush &brush,
61 const float4 &test_plane,
62 const float strength,
63 const MeshAttributeData &attribute_data,
64 const Span<float3> vert_normals,
65 const bke::pbvh::MeshNode &node,
66 Object &object,
67 LocalData &tls,
68 const PositionDeformData &position_data)
69{
70 SculptSession &ss = *object.sculpt;
71
72 const Span<int> verts = node.verts();
73
75 brush,
76 object,
77 attribute_data,
78 position_data.eval,
79 vert_normals,
80 node,
81 tls.factors,
82 tls.distances);
83
84 tls.translations.resize(verts.size());
85 const MutableSpan<float3> translations = tls.translations;
86
87 calc_closest_to_plane(test_plane, position_data.eval, verts, translations);
88 scale_translations(translations, strength);
89 scale_translations(translations, tls.factors);
90
91 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
92 position_data.deform(translations, verts);
93}
94
95static void calc_grids(const Depsgraph &depsgraph,
96 const Sculpt &sd,
97 Object &object,
98 const Brush &brush,
99 const float4 &test_plane,
100 const float strength,
102 LocalData &tls)
103{
104 SculptSession &ss = *object.sculpt;
105 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
106
107 const Span<int> grids = node.grids();
108 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
109
110 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
111
112 tls.translations.resize(positions.size());
113 const MutableSpan<float3> translations = tls.translations;
114
115 calc_closest_to_plane(test_plane, positions, translations);
116 scale_translations(translations, strength);
117 scale_translations(translations, tls.factors);
118
119 clip_and_lock_translations(sd, ss, positions, translations);
120 apply_translations(translations, grids, subdiv_ccg);
121}
122
123static void calc_bmesh(const Depsgraph &depsgraph,
124 const Sculpt &sd,
125 Object &object,
126 const Brush &brush,
127 const float4 &test_plane,
128 const float strength,
130 LocalData &tls)
131{
132 SculptSession &ss = *object.sculpt;
133
135 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
136
137 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
138
139 tls.translations.resize(verts.size());
140 const MutableSpan<float3> translations = tls.translations;
141
142 calc_closest_to_plane(test_plane, positions, translations);
143 scale_translations(translations, strength);
144 scale_translations(translations, tls.factors);
145
146 clip_and_lock_translations(sd, ss, positions, translations);
147 apply_translations(translations, verts);
148}
149
150} // namespace clay_cc
151
152void do_clay_brush(const Depsgraph &depsgraph,
153 const Sculpt &sd,
154 Object &object,
155 const IndexMask &node_mask)
156{
157 SculptSession &ss = *object.sculpt;
158 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
159 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
160
161 float3 area_no;
162 float3 area_co;
163 calc_brush_plane(depsgraph, brush, object, node_mask, area_no, area_co);
164
165 const float initial_radius = fabsf(ss.cache->initial_radius);
166 const float offset = SCULPT_brush_plane_offset_get(sd, ss);
167
168 /* This implementation skips a factor calculation as it currently has
169 * no user-facing impact (i.e. is effectively a constant)
170 * See: #123518 */
171 float displace = fabsf(initial_radius * (0.25f + offset + 0.15f));
172
173 const bool flip = ss.cache->bstrength < 0.0f;
174 if (flip) {
175 displace = -displace;
176 }
177
178 const float3 modified_area_co = ss.cache->location_symm + (area_no * ss.cache->scale * displace);
179
180 float4 test_plane;
181 plane_from_point_normal_v3(test_plane, modified_area_co, area_no);
182 BLI_ASSERT_UNIT_V3(test_plane);
183
184 const float bstrength = fabsf(ss.cache->bstrength);
186 switch (pbvh.type()) {
188 const Mesh &mesh = *static_cast<Mesh *>(object.data);
189 const MeshAttributeData attribute_data(mesh.attributes());
190 const PositionDeformData position_data(depsgraph, object);
191 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
193 node_mask.foreach_index(GrainSize(1), [&](const int i) {
194 LocalData &tls = all_tls.local();
196 sd,
197 brush,
198 test_plane,
199 bstrength,
200 attribute_data,
201 vert_normals,
202 nodes[i],
203 object,
204 tls,
205 position_data);
206 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
207 });
208 break;
209 }
211 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
212 MutableSpan<float3> positions = subdiv_ccg.positions;
214 node_mask.foreach_index(GrainSize(1), [&](const int i) {
215 LocalData &tls = all_tls.local();
216 calc_grids(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
217 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
218 });
219 break;
220 }
223 node_mask.foreach_index(GrainSize(1), [&](const int i) {
224 LocalData &tls = all_tls.local();
225 calc_bmesh(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
227 });
228 break;
229 }
230 }
231 pbvh.tag_positions_changed(node_mask);
233}
234
235} // 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)
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_NOINLINE
#define BLI_ASSERT_UNIT_V3(v)
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
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
constexpr int64_t size() const
Definition BLI_span.hh:494
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
#define fabsf(x)
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_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float4 &test_plane, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
Definition clay.cc:123
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 BLI_NOINLINE void calc_closest_to_plane(const float4 &test_plane, const Span< float3 > positions, const Span< int > verts, const MutableSpan< float3 > translations)
Definition clay.cc:33
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
void do_clay_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition clay.cc:152
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 calc_factors_common_mesh_indexed(const Depsgraph &depsgraph, const Brush &brush, const Object &object, const MeshAttributeData &attribute_data, Span< float3 > vert_positions, Span< float3 > vert_normals, const bke::pbvh::MeshNode &node, Vector< float > &r_factors, Vector< float > &r_distances)
Definition sculpt.cc:6199
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7210
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
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
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
VecBase< float, 3 > float3
float SCULPT_brush_plane_offset_get(const Sculpt &sd, const SculptSession &ss)
Definition sculpt.cc:2883
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions