Blender V4.3
draw_vector_displacement.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_vector.hh"
21#include "BLI_task.h"
22#include "BLI_task.hh"
23
27
29
30inline namespace draw_vector_displacement_cc {
31
39
41 const Brush &brush,
42 const Span<float3> vert_positions,
43 const Span<int> verts,
44 const Span<float> factors,
45 const MutableSpan<float4> r_colors)
46{
47 BLI_assert(verts.size() == r_colors.size());
48
49 const int thread_id = BLI_task_parallel_thread_id(nullptr);
50
51 for (const int i : verts.index_range()) {
52 float texture_value;
53 float4 texture_rgba;
54 /* NOTE: This is not a thread-safe call. */
56 ss, brush, vert_positions[verts[i]], thread_id, &texture_value, texture_rgba);
57
58 r_colors[i] = texture_rgba * factors[i];
59 }
60}
61
63 const Brush &brush,
64 const Span<float3> positions,
65 const Span<float> factors,
66 const MutableSpan<float4> r_colors)
67{
68 BLI_assert(positions.size() == r_colors.size());
69
70 const int thread_id = BLI_task_parallel_thread_id(nullptr);
71
72 for (const int i : positions.index_range()) {
73 float texture_value;
74 float4 texture_rgba;
75 /* NOTE: This is not a thread-safe call. */
76 sculpt_apply_texture(ss, brush, positions[i], thread_id, &texture_value, texture_rgba);
77
78 r_colors[i] = texture_rgba * factors[i];
79 }
80}
81
82static void calc_faces(const Depsgraph &depsgraph,
83 const Sculpt &sd,
84 const Brush &brush,
85 const Span<float3> vert_normals,
86 const MeshAttributeData &attribute_data,
87 const bke::pbvh::MeshNode &node,
88 Object &object,
89 LocalData &tls,
90 const PositionDeformData &position_data)
91{
92 SculptSession &ss = *object.sculpt;
93 const StrokeCache &cache = *ss.cache;
94
95 const Span<int> verts = node.verts();
96
97 tls.factors.resize(verts.size());
98 const MutableSpan<float> factors = tls.factors;
99 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
100 filter_region_clip_factors(ss, position_data.eval, verts, factors);
101 if (brush.flag & BRUSH_FRONTFACE) {
102 calc_front_face(cache.view_normal_symm, vert_normals, verts, factors);
103 }
104
105 tls.distances.resize(verts.size());
106 const MutableSpan<float> distances = tls.distances;
108 ss, position_data.eval, verts, eBrushFalloffShape(brush.falloff_shape), distances);
109 filter_distances_with_radius(cache.radius, distances, factors);
110 apply_hardness_to_distances(cache, distances);
111 calc_brush_strength_factors(cache, brush, distances, factors);
112
113 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
114
115 tls.colors.resize(verts.size());
116 const MutableSpan<float4> colors = tls.colors;
117 calc_brush_texture_colors(ss, brush, position_data.eval, verts, factors, colors);
118
119 tls.translations.resize(verts.size());
120 const MutableSpan<float3> translations = tls.translations;
121 for (const int i : verts.index_range()) {
122 SCULPT_calc_vertex_displacement(ss, brush, colors[i], translations[i]);
123 }
124
125 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
126 position_data.deform(translations, verts);
127}
128
129static void calc_grids(const Depsgraph &depsgraph,
130 const Sculpt &sd,
131 Object &object,
132 const Brush &brush,
134 LocalData &tls)
135{
136 SculptSession &ss = *object.sculpt;
137 const StrokeCache &cache = *ss.cache;
138 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
139
140 const Span<int> grids = node.grids();
141 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
142
143 tls.factors.resize(positions.size());
144 const MutableSpan<float> factors = tls.factors;
145 fill_factor_from_hide_and_mask(subdiv_ccg, grids, factors);
146 filter_region_clip_factors(ss, positions, factors);
147 if (brush.flag & BRUSH_FRONTFACE) {
148 calc_front_face(cache.view_normal_symm, subdiv_ccg, grids, factors);
149 }
150
151 tls.distances.resize(positions.size());
152 const MutableSpan<float> distances = tls.distances;
153 calc_brush_distances(ss, positions, eBrushFalloffShape(brush.falloff_shape), distances);
154 filter_distances_with_radius(cache.radius, distances, factors);
155 apply_hardness_to_distances(cache, distances);
156 calc_brush_strength_factors(cache, brush, distances, factors);
157
158 auto_mask::calc_grids_factors(depsgraph, object, cache.automasking.get(), node, grids, factors);
159
160 tls.colors.resize(positions.size());
161 const MutableSpan<float4> colors = tls.colors;
162 calc_brush_texture_colors(ss, brush, positions, factors, colors);
163
164 tls.translations.resize(positions.size());
165 const MutableSpan<float3> translations = tls.translations;
166 for (const int i : positions.index_range()) {
167 SCULPT_calc_vertex_displacement(ss, brush, colors[i], translations[i]);
168 }
169
170 clip_and_lock_translations(sd, ss, positions, translations);
171 apply_translations(translations, grids, subdiv_ccg);
172}
173
174static void calc_bmesh(const Depsgraph &depsgraph,
175 const Sculpt &sd,
176 Object &object,
177 const Brush &brush,
179 LocalData &tls)
180{
181 SculptSession &ss = *object.sculpt;
182 const StrokeCache &cache = *ss.cache;
183
185 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
186
187 tls.factors.resize(verts.size());
188 const MutableSpan<float> factors = tls.factors;
190 filter_region_clip_factors(ss, positions, factors);
191 if (brush.flag & BRUSH_FRONTFACE) {
192 calc_front_face(cache.view_normal_symm, verts, factors);
193 }
194
195 tls.distances.resize(verts.size());
196 const MutableSpan<float> distances = tls.distances;
197 calc_brush_distances(ss, positions, eBrushFalloffShape(brush.falloff_shape), distances);
198 filter_distances_with_radius(cache.radius, distances, factors);
199 apply_hardness_to_distances(cache, distances);
200 calc_brush_strength_factors(cache, brush, distances, factors);
201
202 auto_mask::calc_vert_factors(depsgraph, object, cache.automasking.get(), node, verts, factors);
203
204 tls.colors.resize(verts.size());
205 const MutableSpan<float4> colors = tls.colors;
206 calc_brush_texture_colors(ss, brush, positions, factors, colors);
207
208 tls.translations.resize(verts.size());
209 const MutableSpan<float3> translations = tls.translations;
210 for (const int i : positions.index_range()) {
211 SCULPT_calc_vertex_displacement(ss, brush, colors[i], translations[i]);
212 }
213
214 clip_and_lock_translations(sd, ss, positions, translations);
215 apply_translations(translations, verts);
216}
217
218} // namespace draw_vector_displacement_cc
219
221 const Sculpt &sd,
222 Object &object,
223 const IndexMask &node_mask)
224{
225 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
226 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
227
229 switch (pbvh.type()) {
231 Mesh &mesh = *static_cast<Mesh *>(object.data);
232 const PositionDeformData position_data(depsgraph, object);
233 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
235 const MeshAttributeData attribute_data(mesh.attributes());
236 node_mask.foreach_index(GrainSize(1), [&](const int i) {
237 LocalData &tls = all_tls.local();
239 sd,
240 brush,
241 vert_normals,
242 attribute_data,
243 nodes[i],
244 object,
245 tls,
246 position_data);
247 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
248 });
249 break;
250 }
252 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
253 MutableSpan<float3> positions = subdiv_ccg.positions;
255 node_mask.foreach_index(GrainSize(1), [&](const int i) {
256 LocalData &tls = all_tls.local();
257 calc_grids(depsgraph, sd, object, brush, nodes[i], tls);
258 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
259 });
260 break;
261 }
264 node_mask.foreach_index(GrainSize(1), [&](const int i) {
265 LocalData &tls = all_tls.local();
266 calc_bmesh(depsgraph, sd, object, brush, nodes[i], tls);
268 });
269 break;
270 }
271 }
272 pbvh.tag_positions_changed(node_mask);
274}
275
276} // 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
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
@ BRUSH_FRONTFACE
eBrushFalloffShape
Object is a sort of wrapper for general info.
constexpr int64_t size() const
Definition BLI_span.hh:494
void resize(const int64_t new_size)
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
void calc_grids_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::GridsNode &node, Span< int > grids, MutableSpan< float > factors)
void calc_vert_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::MeshNode &node, Span< int > verts, MutableSpan< float > factors)
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 BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, bke::pbvh::BMeshNode &node, LocalData &tls)
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, bke::pbvh::GridsNode &node, LocalData &tls)
static void calc_brush_texture_colors(SculptSession &ss, const Brush &brush, const Span< float3 > vert_positions, const Span< int > verts, const Span< float > factors, const MutableSpan< float4 > r_colors)
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const Span< float3 > vert_normals, const MeshAttributeData &attribute_data, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
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_brush_strength_factors(const StrokeCache &cache, const Brush &brush, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:6889
void apply_hardness_to_distances(float radius, float hardness, MutableSpan< float > distances)
Definition sculpt.cc:6862
void filter_distances_with_radius(float radius, Span< float > distances, MutableSpan< float > factors)
Definition sculpt.cc:6772
void filter_region_clip_factors(const SculptSession &ss, Span< float3 > vert_positions, Span< int > verts, MutableSpan< float > factors)
Definition sculpt.cc:6639
void calc_brush_distances(const SculptSession &ss, Span< float3 > vert_positions, Span< int > vert_indices, eBrushFalloffShape falloff_shape, MutableSpan< float > r_distances)
Definition sculpt.cc:6722
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 apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
void do_draw_vector_displacement_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void calc_front_face(const float3 &view_normal, Span< float3 > normals, MutableSpan< float > factors)
Definition sculpt.cc:6581
void SCULPT_calc_vertex_displacement(const SculptSession &ss, const Brush &brush, float rgba[3], float r_offset[3])
Definition sculpt.cc:2285
void sculpt_apply_texture(const SculptSession &ss, const Brush &brush, const float brush_point[3], const int thread_id, float *r_value, float r_rgba[4])
Definition sculpt.cc:2219
char falloff_shape
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions
std::unique_ptr< auto_mask::Cache > automasking