Blender V5.0
enhance_details.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_mesh.hh"
13#include "BKE_paint.hh"
14#include "BKE_paint_bvh.hh"
15#include "BKE_subdiv_ccg.hh"
16
17#include "BLI_array.hh"
19#include "BLI_task.hh"
20
25
26#include "bmesh.hh"
27
29inline namespace enhance_details_cc {
30
40
41static void calc_faces(const Depsgraph &depsgraph,
42 const Sculpt &sd,
43 const Brush &brush,
44 const MeshAttributeData &attribute_data,
45 const Span<float3> vert_normals,
46 const Span<float3> all_translations,
47 const float strength,
48 const bke::pbvh::MeshNode &node,
49 Object &object,
50 LocalData &tls,
51 const PositionDeformData &position_data)
52{
53 SculptSession &ss = *object.sculpt;
54
55 const Span<int> verts = node.verts();
56
58 brush,
59 object,
60 attribute_data,
61 position_data.eval,
62 vert_normals,
63 node,
64 tls.factors,
65 tls.distances);
66
67 scale_factors(tls.factors, strength);
68
69 tls.translations.resize(verts.size());
70 const MutableSpan<float3> translations = tls.translations;
71 gather_data_mesh(all_translations, verts, translations);
72 scale_translations(translations, tls.factors);
73
74 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
75 position_data.deform(translations, verts);
76}
77
78static void calc_grids(const Depsgraph &depsgraph,
79 const Sculpt &sd,
80 Object &object,
81 const Brush &brush,
82 const Span<float3> all_translations,
83 const float strength,
84 const bke::pbvh::GridsNode &node,
85 LocalData &tls)
86{
87 SculptSession &ss = *object.sculpt;
88 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
89
90 const Span<int> grids = node.grids();
91 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
92
93 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
94
95 scale_factors(tls.factors, strength);
96
97 const MutableSpan<float3> translations = gather_data_grids(
98 subdiv_ccg, all_translations, grids, tls.translations);
99 scale_translations(translations, tls.factors);
100
101 clip_and_lock_translations(sd, ss, positions, translations);
102 apply_translations(translations, grids, subdiv_ccg);
103}
104
105static void calc_bmesh(const Depsgraph &depsgraph,
106 const Sculpt &sd,
107 Object &object,
108 const Brush &brush,
109 const Span<float3> all_translations,
110 const float strength,
112 LocalData &tls)
113{
114 SculptSession &ss = *object.sculpt;
115
117 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
118
119 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
120
121 scale_factors(tls.factors, strength);
122
123 const MutableSpan translations = gather_data_bmesh(all_translations, verts, tls.translations);
124 scale_translations(translations, tls.factors);
125
126 clip_and_lock_translations(sd, ss, positions, translations);
127 apply_translations(translations, verts);
128}
129
130static void calc_translations_faces(const Span<float3> vert_positions,
132 const Span<int> corner_verts,
133 const GroupedSpan<int> vert_to_face_map,
134 const Span<bool> hide_poly,
135 const bke::pbvh::MeshNode &node,
136 LocalData &tls,
137 const MutableSpan<float3> all_translations)
138{
139 const Span<int> verts = node.verts();
140
142 corner_verts,
143 vert_to_face_map,
144 hide_poly,
145 verts,
146 tls.neighbor_offsets,
147 tls.neighbor_data);
148
149 tls.new_positions.resize(verts.size());
150 const MutableSpan<float3> new_positions = tls.new_positions;
151 smooth::neighbor_data_average_mesh_check_loose(vert_positions, verts, neighbors, new_positions);
152
153 tls.translations.resize(verts.size());
154 const MutableSpan<float3> translations = tls.translations;
155 translations_from_new_positions(new_positions, verts, vert_positions, translations);
156 scatter_data_mesh(translations.as_span(), verts, all_translations);
157}
158
159static void calc_translations_grids(const SubdivCCG &subdiv_ccg,
160 const bke::pbvh::GridsNode &node,
161 LocalData &tls,
162 const MutableSpan<float3> all_translations)
163{
164 const Span<int> grids = node.grids();
165 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
166
167 tls.new_positions.resize(positions.size());
168 const MutableSpan<float3> new_positions = tls.new_positions;
169 smooth::average_data_grids(subdiv_ccg, subdiv_ccg.positions.as_span(), grids, new_positions);
170
171 tls.translations.resize(positions.size());
172 const MutableSpan<float3> translations = tls.translations;
173 translations_from_new_positions(new_positions, positions, translations);
174 scatter_data_grids(subdiv_ccg, translations.as_span(), grids, all_translations);
175}
176
178 LocalData &tls,
179 const MutableSpan<float3> all_translations)
180{
182 const_cast<bke::pbvh::BMeshNode *>(&node));
183 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
184
185 tls.new_positions.resize(verts.size());
186 const MutableSpan<float3> new_positions = tls.new_positions;
188
189 tls.translations.resize(verts.size());
190 const MutableSpan<float3> translations = tls.translations;
191 translations_from_new_positions(new_positions, positions, translations);
192 scatter_data_bmesh(translations.as_span(), verts, all_translations);
193}
194
195} // namespace enhance_details_cc
196
198 const Sculpt &sd,
199 Object &object,
200 const IndexMask &node_mask)
201{
202 SculptSession &ss = *object.sculpt;
203 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
204 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
205
206 if (ss.cache->detail_directions.is_empty()) {
207 ss.cache->detail_directions.reinitialize(SCULPT_vertex_count_get(object));
208 IndexMaskMemory memory;
209 const IndexMask effective_nodes = bke::pbvh::search_nodes(
210 pbvh, memory, [&](const bke::pbvh::Node &node) {
211 return !node_fully_masked_or_hidden(node);
212 });
213 calc_smooth_translations(depsgraph, object, effective_nodes, ss.cache->detail_directions);
214 }
215
216 const float strength = std::clamp(ss.cache->bstrength, -1.0f, 1.0f);
218
220 switch (pbvh.type()) {
222 const Mesh &mesh = *static_cast<Mesh *>(object.data);
223 const MeshAttributeData attribute_data(mesh);
224 const PositionDeformData position_data(depsgraph, object);
225 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
227 node_mask.foreach_index(GrainSize(1), [&](const int i) {
228 LocalData &tls = all_tls.local();
230 sd,
231 brush,
232 attribute_data,
233 vert_normals,
234 translations,
235 strength,
236 nodes[i],
237 object,
238 tls,
239 position_data);
240 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
241 });
242 break;
243 }
245 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
246 MutableSpan<float3> positions = subdiv_ccg.positions;
248 node_mask.foreach_index(GrainSize(1), [&](const int i) {
249 LocalData &tls = all_tls.local();
250 calc_grids(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
251 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
252 });
253 break;
254 }
257 node_mask.foreach_index(GrainSize(1), [&](const int i) {
258 LocalData &tls = all_tls.local();
259 calc_bmesh(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
261 });
262 break;
263 }
264 }
265 pbvh.tag_positions_changed(node_mask);
267}
268
269} // namespace blender::ed::sculpt_paint::brushes
272 const Object &object,
273 const IndexMask &node_mask,
274 const MutableSpan<float3> translations)
275{
276 const SculptSession &ss = *object.sculpt;
277 const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
278
280 switch (pbvh.type()) {
282 Mesh &mesh = *static_cast<Mesh *>(object.data);
283 const MeshAttributeData attribute_data(mesh);
284 const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
285 const OffsetIndices faces = mesh.faces();
286 const Span<int> corner_verts = mesh.corner_verts();
287 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
289 node_mask.foreach_index(GrainSize(1), [&](const int i) {
290 brushes::LocalData &tls = all_tls.local();
291 calc_translations_faces(positions_eval,
292 faces,
293 corner_verts,
294 vert_to_face_map,
295 attribute_data.hide_poly,
296 nodes[i],
297 tls,
298 translations);
299 });
300 break;
301 }
303 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
305 node_mask.foreach_index(GrainSize(1), [&](const int i) {
306 brushes::LocalData &tls = all_tls.local();
307 calc_translations_grids(subdiv_ccg, nodes[i], tls, translations);
308 });
309 break;
310 }
312 vert_random_access_ensure(const_cast<Object &>(object));
314 node_mask.foreach_index(GrainSize(1), [&](const int i) {
315 brushes::LocalData &tls = all_tls.local();
316 calc_translations_bmesh(nodes[i], tls, translations);
317 });
318 break;
319 }
320}
321
322} // namespace blender::ed::sculpt_paint
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)
Object is a sort of wrapper for general info.
BPy_StructRNA * depsgraph
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr Span< T > as_span() const
Definition BLI_span.hh:661
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]
static char faces[256]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:3052
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
Definition pbvh.cc:2663
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
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:1040
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: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
static void calc_translations_faces(const Span< float3 > vert_positions, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const bke::pbvh::MeshNode &node, LocalData &tls, const MutableSpan< float3 > all_translations)
static void calc_translations_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, LocalData &tls, const MutableSpan< float3 > all_translations)
static void calc_translations_bmesh(const bke::pbvh::BMeshNode &node, LocalData &tls, const MutableSpan< float3 > all_translations)
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const MeshAttributeData &attribute_data, const Span< float3 > vert_normals, const Span< float3 > all_translations, const float strength, const bke::pbvh::MeshNode &node, Object &object, LocalData &tls, const PositionDeformData &position_data)
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const Span< float3 > all_translations, const float strength, const bke::pbvh::GridsNode &node, LocalData &tls)
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const Span< float3 > all_translations, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
void do_enhance_details_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
void neighbor_data_average_mesh_check_loose(const Span< T > src, const Span< int > verts, const GroupedSpan< int > vert_neighbors, const MutableSpan< T > dst)
void average_data_grids(const SubdivCCG &subdiv_ccg, const Span< T > src, const Span< int > grids, const MutableSpan< T > dst)
void neighbor_position_average_bmesh(const Set< BMVert *, 0 > &verts, const MutableSpan< float3 > new_positions)
MutableSpan< float3 > gather_grids_positions(const SubdivCCG &subdiv_ccg, const Span< int > grids, Vector< float3 > &positions)
void calc_smooth_translations(const Depsgraph &depsgraph, const Object &object, const IndexMask &node_mask, const MutableSpan< float3 > translations)
void scatter_data_bmesh(Span< T > node_data, const Set< BMVert *, 0 > &verts, MutableSpan< T > dst)
Definition sculpt.cc:6461
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6367
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
Definition sculpt.cc:6405
void vert_random_access_ensure(Object &object)
Definition sculpt.cc:141
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
GroupedSpan< int > calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, Vector< int > &r_offset_data, Vector< int > &r_data)
Definition sculpt.cc:7597
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node)
Definition sculpt.cc:2418
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 gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
Definition sculpt.cc:6421
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7495
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7512
void translations_from_new_positions(Span< float3 > new_positions, Span< int > verts, Span< float3 > old_positions, MutableSpan< float3 > translations)
Definition sculpt.cc:7542
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 scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6435
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7268
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6395
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
Definition sculpt.cc:6445
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
int SCULPT_vertex_count_get(const Object &object)
Definition sculpt.cc:151
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