Blender V4.3
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_pbvh.hh"
15#include "BKE_subdiv_ccg.hh"
16
17#include "BLI_array.hh"
19#include "BLI_task.hh"
20
25
27
28inline namespace enhance_details_cc {
29
38
39static void calc_faces(const Depsgraph &depsgraph,
40 const Sculpt &sd,
41 const Brush &brush,
42 const MeshAttributeData &attribute_data,
43 const Span<float3> vert_normals,
44 const Span<float3> all_translations,
45 const float strength,
46 const bke::pbvh::MeshNode &node,
47 Object &object,
48 LocalData &tls,
49 const PositionDeformData &position_data)
50{
51 SculptSession &ss = *object.sculpt;
52
53 const Span<int> verts = node.verts();
54
56 brush,
57 object,
58 attribute_data,
59 position_data.eval,
60 vert_normals,
61 node,
62 tls.factors,
63 tls.distances);
64
65 scale_factors(tls.factors, strength);
66
67 tls.translations.resize(verts.size());
68 const MutableSpan<float3> translations = tls.translations;
69 gather_data_mesh(all_translations, verts, translations);
70 scale_translations(translations, tls.factors);
71
72 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
73 position_data.deform(translations, verts);
74}
75
76static void calc_grids(const Depsgraph &depsgraph,
77 const Sculpt &sd,
78 Object &object,
79 const Brush &brush,
80 const Span<float3> all_translations,
81 const float strength,
82 const bke::pbvh::GridsNode &node,
83 LocalData &tls)
84{
85 SculptSession &ss = *object.sculpt;
86 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
87
88 const Span<int> grids = node.grids();
89 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
90
91 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
92
93 scale_factors(tls.factors, strength);
94
95 const MutableSpan<float3> translations = gather_data_grids(
96 subdiv_ccg, all_translations, grids, tls.translations);
97 scale_translations(translations, tls.factors);
98
99 clip_and_lock_translations(sd, ss, positions, translations);
100 apply_translations(translations, grids, subdiv_ccg);
101}
102
103static void calc_bmesh(const Depsgraph &depsgraph,
104 const Sculpt &sd,
105 Object &object,
106 const Brush &brush,
107 const Span<float3> all_translations,
108 const float strength,
110 LocalData &tls)
111{
112 SculptSession &ss = *object.sculpt;
113
115 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
116
117 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
118
119 scale_factors(tls.factors, strength);
120
121 const MutableSpan translations = gather_data_bmesh(all_translations, verts, tls.translations);
122 scale_translations(translations, tls.factors);
123
124 clip_and_lock_translations(sd, ss, positions, translations);
125 apply_translations(translations, verts);
126}
127
128static void calc_translations_faces(const Span<float3> vert_positions,
129 const OffsetIndices<int> faces,
130 const Span<int> corner_verts,
131 const GroupedSpan<int> vert_to_face_map,
132 const Span<bool> hide_poly,
133 const bke::pbvh::MeshNode &node,
134 LocalData &tls,
135 const MutableSpan<float3> all_translations)
136{
137 const Span<int> verts = node.verts();
138
139 tls.vert_neighbors.resize(verts.size());
140 const MutableSpan<Vector<int>> neighbors = tls.vert_neighbors;
141 calc_vert_neighbors(faces, corner_verts, vert_to_face_map, hide_poly, verts, neighbors);
142
143 tls.new_positions.resize(verts.size());
144 const MutableSpan<float3> new_positions = tls.new_positions;
145 smooth::neighbor_data_average_mesh_check_loose(vert_positions, verts, neighbors, new_positions);
146
147 tls.translations.resize(verts.size());
148 const MutableSpan<float3> translations = tls.translations;
149 translations_from_new_positions(new_positions, verts, vert_positions, translations);
150 scatter_data_mesh(translations.as_span(), verts, all_translations);
151}
152
153static void calc_translations_grids(const SubdivCCG &subdiv_ccg,
154 const bke::pbvh::GridsNode &node,
155 LocalData &tls,
156 const MutableSpan<float3> all_translations)
157{
158 const Span<int> grids = node.grids();
159 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
160
161 tls.new_positions.resize(positions.size());
162 const MutableSpan<float3> new_positions = tls.new_positions;
163 smooth::average_data_grids(subdiv_ccg, subdiv_ccg.positions.as_span(), grids, new_positions);
164
165 tls.translations.resize(positions.size());
166 const MutableSpan<float3> translations = tls.translations;
167 translations_from_new_positions(new_positions, positions, translations);
168 scatter_data_grids(subdiv_ccg, translations.as_span(), grids, all_translations);
169}
170
172 LocalData &tls,
173 const MutableSpan<float3> all_translations)
174{
176 const_cast<bke::pbvh::BMeshNode *>(&node));
177 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
178
179 tls.new_positions.resize(verts.size());
180 const MutableSpan<float3> new_positions = tls.new_positions;
182
183 tls.translations.resize(verts.size());
184 const MutableSpan<float3> translations = tls.translations;
185 translations_from_new_positions(new_positions, positions, translations);
186 scatter_data_bmesh(translations.as_span(), verts, all_translations);
187}
188
189} // namespace enhance_details_cc
190
192 const Object &object,
193 const IndexMask &node_mask,
194 const MutableSpan<float3> translations)
195{
196 const SculptSession &ss = *object.sculpt;
197 const bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
198
200 switch (pbvh.type()) {
202 Mesh &mesh = *static_cast<Mesh *>(object.data);
203 const MeshAttributeData attribute_data(mesh.attributes());
204 const Span<float3> positions_eval = bke::pbvh::vert_positions_eval(depsgraph, object);
205 const OffsetIndices faces = mesh.faces();
206 const Span<int> corner_verts = mesh.corner_verts();
207 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
209 node_mask.foreach_index(GrainSize(1), [&](const int i) {
210 LocalData &tls = all_tls.local();
211 calc_translations_faces(positions_eval,
212 faces,
213 corner_verts,
214 vert_to_face_map,
215 attribute_data.hide_poly,
216 nodes[i],
217 tls,
218 translations);
219 });
220 break;
221 }
223 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
225 node_mask.foreach_index(GrainSize(1), [&](const int i) {
226 LocalData &tls = all_tls.local();
227 calc_translations_grids(subdiv_ccg, nodes[i], tls, translations);
228 });
229 break;
230 }
235 node_mask.foreach_index(GrainSize(1), [&](const int i) {
236 LocalData &tls = all_tls.local();
237 calc_translations_bmesh(nodes[i], tls, translations);
238 });
239 break;
240 }
241}
242
244 const Sculpt &sd,
245 Object &object,
246 const IndexMask &node_mask)
247{
248 SculptSession &ss = *object.sculpt;
249 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
250 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
251
254 IndexMaskMemory memory;
255 const IndexMask effective_nodes = bke::pbvh::search_nodes(
256 pbvh, memory, [&](const bke::pbvh::Node &node) {
257 return !node_fully_masked_or_hidden(node);
258 });
259 calc_smooth_translations(depsgraph, object, effective_nodes, ss.cache->detail_directions);
260 }
261
262 const float strength = std::clamp(ss.cache->bstrength, -1.0f, 1.0f);
264
266 switch (pbvh.type()) {
268 const Mesh &mesh = *static_cast<Mesh *>(object.data);
269 const MeshAttributeData attribute_data(mesh.attributes());
270 const PositionDeformData position_data(depsgraph, object);
271 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
273 node_mask.foreach_index(GrainSize(1), [&](const int i) {
274 LocalData &tls = all_tls.local();
276 sd,
277 brush,
278 attribute_data,
279 vert_normals,
280 translations,
281 strength,
282 nodes[i],
283 object,
284 tls,
285 position_data);
286 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
287 });
288 break;
289 }
291 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
292 MutableSpan<float3> positions = subdiv_ccg.positions;
294 node_mask.foreach_index(GrainSize(1), [&](const int i) {
295 LocalData &tls = all_tls.local();
296 calc_grids(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
297 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
298 });
299 break;
300 }
303 node_mask.foreach_index(GrainSize(1), [&](const int i) {
304 LocalData &tls = all_tls.local();
305 calc_bmesh(depsgraph, sd, object, brush, translations, strength, nodes[i], tls);
307 });
308 break;
309 }
310 }
311 pbvh.tag_positions_changed(node_mask);
313}
314
315} // 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)
Object is a sort of wrapper for general info.
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
#define BM_VERT
void reinitialize(const int64_t new_size)
Definition BLI_array.hh:388
constexpr Span< T > as_span() const
Definition BLI_span.hh:662
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
IndexMask search_nodes(const Tree &pbvh, IndexMaskMemory &memory, FunctionRef< bool(const Node &)> filter_fn)
Definition pbvh.cc:2647
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
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2482
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_translations_bmesh(const bke::pbvh::BMeshNode &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_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)
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_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_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)
void neighbor_data_average_mesh_check_loose(const Span< T > src, const Span< int > verts, const Span< Vector< 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:6148
void gather_bmesh_positions(const Set< BMVert *, 0 > &verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6054
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
Definition sculpt.cc:6092
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
bool node_fully_masked_or_hidden(const bke::pbvh::Node &node)
Definition sculpt.cc:2315
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 gather_data_bmesh(Span< T > src, const Set< BMVert *, 0 > &verts, MutableSpan< T > node_data)
Definition sculpt.cc:6108
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7210
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7227
void translations_from_new_positions(Span< float3 > new_positions, Span< int > verts, Span< float3 > old_positions, MutableSpan< float3 > translations)
Definition sculpt.cc:7257
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 scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6122
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Definition sculpt.cc:6082
void calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, MutableSpan< Vector< int > > result)
Definition sculpt.cc:7330
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
Definition sculpt.cc:6132
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_enhance_details_brush(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const IndexMask &node_mask)
int SCULPT_vertex_count_get(const Object &object)
Definition sculpt.cc:153
bool SCULPT_stroke_is_first_brush_step(const blender::ed::sculpt_paint::StrokeCache &cache)
Definition sculpt.cc:507
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions