Blender V5.0
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_paint_bvh.hh"
11#include "BKE_subdiv_ccg.hh"
12
14#include "BLI_math_geom.h"
15
19
20#include "bmesh.hh"
21
23inline namespace clay_cc {
30
31BLI_NOINLINE static void calc_closest_to_plane(const float4 &test_plane,
32 const Span<float3> positions,
33 const Span<int> verts,
34 const MutableSpan<float3> translations)
35{
36 /* Equivalent to #closest_to_plane_normalized_v3 */
37 BLI_assert(verts.size() == translations.size());
38 for (const int i : verts.index_range()) {
39 const float side = plane_point_side_v3(test_plane, positions[verts[i]]);
40 translations[i] = float3(test_plane) * -side;
41 }
42}
43
44BLI_NOINLINE static void calc_closest_to_plane(const float4 &test_plane,
45 const Span<float3> positions,
46 const MutableSpan<float3> translations)
47{
48 /* Equivalent to #closest_to_plane_normalized_v3 */
49 BLI_assert(positions.size() == translations.size());
50 for (const int i : positions.index_range()) {
51 const float side = plane_point_side_v3(test_plane, positions[i]);
52 translations[i] = float3(test_plane) * -side;
53 }
54}
55
56static void calc_faces(const Depsgraph &depsgraph,
57 const Sculpt &sd,
58 const Brush &brush,
59 const float4 &test_plane,
60 const float strength,
61 const MeshAttributeData &attribute_data,
62 const Span<float3> vert_normals,
63 const bke::pbvh::MeshNode &node,
64 Object &object,
65 LocalData &tls,
66 const PositionDeformData &position_data)
67{
68 SculptSession &ss = *object.sculpt;
69
70 const Span<int> verts = node.verts();
71
73 brush,
74 object,
75 attribute_data,
76 position_data.eval,
77 vert_normals,
78 node,
79 tls.factors,
80 tls.distances);
81
82 tls.translations.resize(verts.size());
83 const MutableSpan<float3> translations = tls.translations;
84
85 calc_closest_to_plane(test_plane, position_data.eval, verts, translations);
86 scale_translations(translations, strength);
87 scale_translations(translations, tls.factors);
88
89 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
90 position_data.deform(translations, verts);
91}
92
93static void calc_grids(const Depsgraph &depsgraph,
94 const Sculpt &sd,
95 Object &object,
96 const Brush &brush,
97 const float4 &test_plane,
98 const float strength,
100 LocalData &tls)
101{
102 SculptSession &ss = *object.sculpt;
103 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
104
105 const Span<int> grids = node.grids();
106 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
107
108 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
109
110 tls.translations.resize(positions.size());
111 const MutableSpan<float3> translations = tls.translations;
112
113 calc_closest_to_plane(test_plane, positions, translations);
114 scale_translations(translations, strength);
115 scale_translations(translations, tls.factors);
116
117 clip_and_lock_translations(sd, ss, positions, translations);
118 apply_translations(translations, grids, subdiv_ccg);
119}
120
121static void calc_bmesh(const Depsgraph &depsgraph,
122 const Sculpt &sd,
123 Object &object,
124 const Brush &brush,
125 const float4 &test_plane,
126 const float strength,
128 LocalData &tls)
129{
130 SculptSession &ss = *object.sculpt;
131
133 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
134
135 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
136
137 tls.translations.resize(verts.size());
138 const MutableSpan<float3> translations = tls.translations;
139
140 calc_closest_to_plane(test_plane, positions, translations);
141 scale_translations(translations, strength);
142 scale_translations(translations, tls.factors);
143
144 clip_and_lock_translations(sd, ss, positions, translations);
145 apply_translations(translations, verts);
146}
147
148} // namespace clay_cc
149
150void do_clay_brush(const Depsgraph &depsgraph,
151 const Sculpt &sd,
152 Object &object,
153 const IndexMask &node_mask)
154{
155 SculptSession &ss = *object.sculpt;
156 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
157 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
158
159 float3 area_no;
160 float3 area_co;
161 calc_brush_plane(depsgraph, brush, object, node_mask, area_no, area_co);
162
163 const float initial_radius = fabsf(ss.cache->initial_radius);
164 const float offset = brush_plane_offset_get(brush, ss);
165
166 /* This implementation skips a factor calculation as it currently has
167 * no user-facing impact (i.e. is effectively a constant)
168 * See: #123518 */
169 float displace = fabsf(initial_radius * offset);
170
171 const bool flip = ss.cache->bstrength < 0.0f;
172 if (flip) {
173 displace = -displace;
174 }
175
176 const float3 modified_area_co = ss.cache->location_symm + (area_no * ss.cache->scale * displace);
177
178 float4 test_plane;
179 plane_from_point_normal_v3(test_plane, modified_area_co, area_no);
180 BLI_ASSERT_UNIT_V3(test_plane);
181
182 const float bstrength = fabsf(ss.cache->bstrength);
184 switch (pbvh.type()) {
186 const Mesh &mesh = *static_cast<Mesh *>(object.data);
187 const MeshAttributeData attribute_data(mesh);
188 const PositionDeformData position_data(depsgraph, object);
189 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
191 node_mask.foreach_index(GrainSize(1), [&](const int i) {
192 LocalData &tls = all_tls.local();
194 sd,
195 brush,
196 test_plane,
197 bstrength,
198 attribute_data,
199 vert_normals,
200 nodes[i],
201 object,
202 tls,
203 position_data);
204 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
205 });
206 break;
207 }
209 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
210 MutableSpan<float3> positions = subdiv_ccg.positions;
212 node_mask.foreach_index(GrainSize(1), [&](const int i) {
213 LocalData &tls = all_tls.local();
214 calc_grids(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
215 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
216 });
217 break;
218 }
221 node_mask.foreach_index(GrainSize(1), [&](const int i) {
222 LocalData &tls = all_tls.local();
223 calc_bmesh(depsgraph, sd, object, brush, test_plane, bstrength, nodes[i], tls);
225 });
226 break;
227 }
228 }
229 pbvh.tag_positions_changed(node_mask);
231}
232
233} // namespace blender::ed::sculpt_paint::brushes
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:650
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
#define BLI_assert(a)
Definition BLI_assert.h:46
#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:217
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
BPy_StructRNA * depsgraph
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:635
Span< NodeT > nodes() const
void flush_bounds_to_parents()
Definition pbvh.cc:1306
void foreach_index(Fn &&fn) const
static float verts[][3]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:3052
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1294
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1274
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:1059
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1283
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 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:31
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:121
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:56
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:93
void do_clay_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
Definition clay.cc:150
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:6367
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:6603
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:6512
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7495
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7335
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:2910
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7268
float brush_plane_offset_get(const Brush &brush, const SculptSession &ss)
Definition sculpt.cc:2993
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:6637
VecBase< float, 4 > float4
VecBase< float, 3 > float3
#define fabsf
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:417
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:395
blender::Array< blender::float3 > positions
i
Definition text_draw.cc:230