Blender V4.5
crease.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_brush.hh"
13#include "BKE_mesh.hh"
14#include "BKE_paint.hh"
15#include "BKE_paint_bvh.hh"
16#include "BKE_subdiv_ccg.hh"
17
19#include "BLI_task.hh"
20
24
25#include "bmesh.hh"
26
28
29inline namespace crease_cc {
30
37
38BLI_NOINLINE static void translations_from_position(const Span<float3> positions_eval,
39 const Span<int> verts,
40 const float3 &location,
41 const MutableSpan<float3> translations)
42{
43 for (const int i : verts.index_range()) {
44 translations[i] = location - positions_eval[verts[i]];
45 }
46}
47
49 const float3 &location,
50 const MutableSpan<float3> translations)
51{
52 for (const int i : positions.index_range()) {
53 translations[i] = location - positions[i];
54 }
55}
56
58 const Span<float> factors,
59 const float3 &offset)
60{
61 for (const int i : translations.index_range()) {
62 translations[i] += offset * factors[i];
63 }
64}
65
66static void calc_faces(const Depsgraph &depsgraph,
67 const Sculpt &sd,
68 const Brush &brush,
69 const float3 &offset,
70 const float strength,
71 const MeshAttributeData &attribute_data,
72 const Span<float3> vert_normals,
73 const bke::pbvh::MeshNode &node,
74 Object &object,
75 LocalData &tls,
76 const PositionDeformData &position_data)
77{
78 SculptSession &ss = *object.sculpt;
79 const StrokeCache &cache = *ss.cache;
80
81 const Span<int> verts = node.verts();
82
84 brush,
85 object,
86 attribute_data,
87 position_data.eval,
88 vert_normals,
89 node,
90 tls.factors,
91 tls.distances);
92
93 tls.translations.resize(verts.size());
94 const MutableSpan<float3> translations = tls.translations;
95 translations_from_position(position_data.eval, verts, cache.location_symm, translations);
96
98 project_translations(translations, cache.view_normal_symm);
99 }
100
101 scale_translations(translations, tls.factors);
102 scale_translations(translations, strength);
103
104 /* The vertices are pinched towards a line instead of a single point. Without this we get a
105 * 'flat' surface surrounding the pinch. */
106 project_translations(translations, cache.sculpt_normal_symm);
107
108 add_offset_to_translations(translations, tls.factors, offset);
109
110 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
111 position_data.deform(translations, verts);
112}
113
114static void calc_grids(const Depsgraph &depsgraph,
115 const Sculpt &sd,
116 Object &object,
117 const Brush &brush,
118 const float3 &offset,
119 const float strength,
121 LocalData &tls)
122{
123 SculptSession &ss = *object.sculpt;
124 const StrokeCache &cache = *ss.cache;
125 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
126
127 const Span<int> grids = node.grids();
128 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
129
130 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
131
132 tls.translations.resize(positions.size());
133 const MutableSpan<float3> translations = tls.translations;
134 translations_from_position(positions, cache.location_symm, translations);
135
137 project_translations(translations, cache.view_normal_symm);
138 }
139
140 scale_translations(translations, tls.factors);
141 scale_translations(translations, strength);
142
143 project_translations(translations, cache.sculpt_normal_symm);
144
145 add_offset_to_translations(translations, tls.factors, offset);
146
147 clip_and_lock_translations(sd, ss, positions, translations);
148 apply_translations(translations, grids, subdiv_ccg);
149}
150
151static void calc_bmesh(const Depsgraph &depsgraph,
152 const Sculpt &sd,
153 Object &object,
154 const Brush &brush,
155 const float3 &offset,
156 const float strength,
158 LocalData &tls)
159{
160 SculptSession &ss = *object.sculpt;
161 const StrokeCache &cache = *ss.cache;
162
164 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
165
166 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
167
168 tls.translations.resize(verts.size());
169 const MutableSpan<float3> translations = tls.translations;
170 translations_from_position(positions, cache.location_symm, translations);
171
173 project_translations(translations, cache.view_normal_symm);
174 }
175
176 scale_translations(translations, tls.factors);
177 scale_translations(translations, strength);
178
179 project_translations(translations, cache.sculpt_normal_symm);
180
181 add_offset_to_translations(translations, tls.factors, offset);
182
183 clip_and_lock_translations(sd, ss, positions, translations);
184 apply_translations(translations, verts);
185}
186
187static void do_crease_or_blob_brush(const Depsgraph &depsgraph,
188 const Scene &scene,
189 const Sculpt &sd,
190 const bool invert_strength,
191 Object &object,
192 const IndexMask &node_mask)
193{
194 const SculptSession &ss = *object.sculpt;
195 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
196 const StrokeCache &cache = *ss.cache;
197 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
198
199 /* Offset with as much as possible factored in already. */
200 const float3 offset = cache.sculpt_normal_symm * cache.scale * cache.radius * cache.bstrength;
201
202 /* We divide out the squared alpha and multiply by the squared crease
203 * to give us the pinch strength. */
204 float crease_correction = brush.crease_pinch_factor * brush.crease_pinch_factor;
205 float brush_alpha = BKE_brush_alpha_get(&scene, &brush);
206 if (brush_alpha > 0.0f) {
207 crease_correction /= brush_alpha * brush_alpha;
208 }
209
210 /* We always want crease to pinch or blob to relax even when draw is negative. */
211 const float strength = std::abs(cache.bstrength) * crease_correction *
212 (invert_strength ? -1.0f : 1.0f);
213
215 switch (pbvh.type()) {
217 const Mesh &mesh = *static_cast<Mesh *>(object.data);
218 const MeshAttributeData attribute_data(mesh);
219 const PositionDeformData position_data(depsgraph, object);
220 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
222 node_mask.foreach_index(GrainSize(1), [&](const int i) {
223 LocalData &tls = all_tls.local();
225 sd,
226 brush,
227 offset,
228 strength,
229 attribute_data,
230 vert_normals,
231 nodes[i],
232 object,
233 tls,
234 position_data);
236 });
237 break;
238 }
240 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
241 MutableSpan<float3> positions = subdiv_ccg.positions;
243 node_mask.foreach_index(GrainSize(1), [&](const int i) {
244 LocalData &tls = all_tls.local();
245 calc_grids(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
246 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
247 });
248 break;
249 }
252 node_mask.foreach_index(GrainSize(1), [&](const int i) {
253 LocalData &tls = all_tls.local();
254 calc_bmesh(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
256 });
257 break;
258 }
259 }
260 pbvh.tag_positions_changed(node_mask);
262}
263
264} // namespace crease_cc
265
266void do_crease_brush(const Depsgraph &depsgraph,
267 const Scene &scene,
268 const Sculpt &sd,
269 Object &object,
270 const IndexMask &node_mask)
271{
272 do_crease_or_blob_brush(depsgraph, scene, sd, false, object, node_mask);
273}
274
275void do_blob_brush(const Depsgraph &depsgraph,
276 const Scene &scene,
277 const Sculpt &sd,
278 Object &object,
279 const IndexMask &node_mask)
280{
281 do_crease_or_blob_brush(depsgraph, scene, sd, true, object, node_mask);
282}
283
284} // namespace blender::ed::sculpt_paint::brushes
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1269
const Brush * BKE_paint_brush_for_read(const Paint *paint)
Definition paint.cc:641
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
#define BLI_NOINLINE
@ PAINT_FALLOFF_SHAPE_TUBE
Object is a sort of wrapper for general info.
BPy_StructRNA * depsgraph
constexpr int64_t size() const
Definition BLI_span.hh:493
constexpr IndexRange index_range() const
Definition BLI_span.hh:670
constexpr IndexRange index_range() const
Definition BLI_span.hh:401
void tag_positions_changed(const IndexMask &node_mask)
Definition pbvh.cc:559
Span< NodeT > nodes() const
void flush_bounds_to_parents()
Definition pbvh.cc:1122
void deform(MutableSpan< float3 > translations, Span< int > verts) const
Definition sculpt.cc:7443
void foreach_index(Fn &&fn) const
static float verts[][3]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2912
void update_node_bounds_bmesh(BMeshNode &node)
Definition pbvh.cc:1110
void update_node_bounds_mesh(Span< float3 > positions, MeshNode &node)
Definition pbvh.cc:1090
Span< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Definition pbvh.cc:2435
void update_node_bounds_grids(int grid_area, Span< float3 > positions, GridsNode &node)
Definition pbvh.cc:1099
static BLI_NOINLINE void translations_from_position(const Span< float3 > positions_eval, const Span< int > verts, const float3 &location, const MutableSpan< float3 > translations)
Definition crease.cc:38
static void calc_grids(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float3 &offset, const float strength, bke::pbvh::GridsNode &node, LocalData &tls)
Definition crease.cc:114
static void calc_bmesh(const Depsgraph &depsgraph, const Sculpt &sd, Object &object, const Brush &brush, const float3 &offset, const float strength, bke::pbvh::BMeshNode &node, LocalData &tls)
Definition crease.cc:151
static void calc_faces(const Depsgraph &depsgraph, const Sculpt &sd, const Brush &brush, const float3 &offset, 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 crease.cc:66
static void do_crease_or_blob_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, const bool invert_strength, Object &object, const IndexMask &node_mask)
Definition crease.cc:187
static BLI_NOINLINE void add_offset_to_translations(const MutableSpan< float3 > translations, const Span< float > factors, const float3 &offset)
Definition crease.cc:57
void do_crease_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
Definition crease.cc:266
void do_blob_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &ob, const IndexMask &node_mask)
Definition crease.cc:275
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:6351
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:6587
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:6496
void scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7476
void clip_and_lock_translations(const Sculpt &sd, const SculptSession &ss, Span< float3 > positions, Span< int > verts, MutableSpan< float3 > translations)
Definition sculpt.cc:7316
void project_translations(MutableSpan< float3 > translations, const float3 &plane)
Definition sculpt.cc:7292
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:7249
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:6621
VecBase< float, 3 > float3
char falloff_shape
float crease_pinch_factor
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:437
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:415
blender::Array< blender::float3 > positions
i
Definition text_draw.cc:230