Blender V4.3
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_key.hh"
14#include "BKE_mesh.hh"
15#include "BKE_paint.hh"
16#include "BKE_pbvh.hh"
17#include "BKE_subdiv_ccg.hh"
18
19#include "BLI_array.hh"
21#include "BLI_math_geom.h"
22#include "BLI_math_matrix.hh"
23#include "BLI_math_vector.hh"
24#include "BLI_task.h"
25#include "BLI_task.hh"
26
30
32
33inline namespace crease_cc {
34
41
42BLI_NOINLINE static void translations_from_position(const Span<float3> positions_eval,
43 const Span<int> verts,
44 const float3 &location,
45 const MutableSpan<float3> translations)
46{
47 for (const int i : verts.index_range()) {
48 translations[i] = location - positions_eval[verts[i]];
49 }
50}
51
53 const float3 &location,
54 const MutableSpan<float3> translations)
55{
56 for (const int i : positions.index_range()) {
57 translations[i] = location - positions[i];
58 }
59}
60
62 const Span<float> factors,
63 const float3 &offset)
64{
65 for (const int i : translations.index_range()) {
66 translations[i] += offset * factors[i];
67 }
68}
69
70static void calc_faces(const Depsgraph &depsgraph,
71 const Sculpt &sd,
72 const Brush &brush,
73 const float3 &offset,
74 const float strength,
75 const MeshAttributeData &attribute_data,
76 const Span<float3> vert_normals,
77 const bke::pbvh::MeshNode &node,
78 Object &object,
79 LocalData &tls,
80 const PositionDeformData &position_data)
81{
82 SculptSession &ss = *object.sculpt;
83 const StrokeCache &cache = *ss.cache;
84
85 const Span<int> verts = node.verts();
86
88 brush,
89 object,
90 attribute_data,
91 position_data.eval,
92 vert_normals,
93 node,
94 tls.factors,
95 tls.distances);
96
97 tls.translations.resize(verts.size());
98 const MutableSpan<float3> translations = tls.translations;
99 translations_from_position(position_data.eval, verts, cache.location_symm, translations);
100
102 project_translations(translations, cache.view_normal_symm);
103 }
104
105 scale_translations(translations, tls.factors);
106 scale_translations(translations, strength);
107
108 /* The vertices are pinched towards a line instead of a single point. Without this we get a
109 * 'flat' surface surrounding the pinch. */
110 project_translations(translations, cache.sculpt_normal_symm);
111
112 add_offset_to_translations(translations, tls.factors, offset);
113
114 clip_and_lock_translations(sd, ss, position_data.eval, verts, translations);
115 position_data.deform(translations, verts);
116}
117
118static void calc_grids(const Depsgraph &depsgraph,
119 const Sculpt &sd,
120 Object &object,
121 const Brush &brush,
122 const float3 &offset,
123 const float strength,
125 LocalData &tls)
126{
127 SculptSession &ss = *object.sculpt;
128 const StrokeCache &cache = *ss.cache;
129 SubdivCCG &subdiv_ccg = *ss.subdiv_ccg;
130
131 const Span<int> grids = node.grids();
132 const MutableSpan positions = gather_grids_positions(subdiv_ccg, grids, tls.positions);
133
134 calc_factors_common_grids(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
135
136 tls.translations.resize(positions.size());
137 const MutableSpan<float3> translations = tls.translations;
138 translations_from_position(positions, cache.location_symm, translations);
139
141 project_translations(translations, cache.view_normal_symm);
142 }
143
144 scale_translations(translations, tls.factors);
145 scale_translations(translations, strength);
146
147 project_translations(translations, cache.sculpt_normal_symm);
148
149 add_offset_to_translations(translations, tls.factors, offset);
150
151 clip_and_lock_translations(sd, ss, positions, translations);
152 apply_translations(translations, grids, subdiv_ccg);
153}
154
155static void calc_bmesh(const Depsgraph &depsgraph,
156 const Sculpt &sd,
157 Object &object,
158 const Brush &brush,
159 const float3 &offset,
160 const float strength,
162 LocalData &tls)
163{
164 SculptSession &ss = *object.sculpt;
165 const StrokeCache &cache = *ss.cache;
166
168 const MutableSpan positions = gather_bmesh_positions(verts, tls.positions);
169
170 calc_factors_common_bmesh(depsgraph, brush, object, positions, node, tls.factors, tls.distances);
171
172 tls.translations.resize(verts.size());
173 const MutableSpan<float3> translations = tls.translations;
174 translations_from_position(positions, cache.location_symm, translations);
175
177 project_translations(translations, cache.view_normal_symm);
178 }
179
180 scale_translations(translations, tls.factors);
181 scale_translations(translations, strength);
182
183 project_translations(translations, cache.sculpt_normal_symm);
184
185 add_offset_to_translations(translations, tls.factors, offset);
186
187 clip_and_lock_translations(sd, ss, positions, translations);
188 apply_translations(translations, verts);
189}
190
191static void do_crease_or_blob_brush(const Depsgraph &depsgraph,
192 const Scene &scene,
193 const Sculpt &sd,
194 const bool invert_strength,
195 Object &object,
196 const IndexMask &node_mask)
197{
198 const SculptSession &ss = *object.sculpt;
199 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
200 const StrokeCache &cache = *ss.cache;
201 const Brush &brush = *BKE_paint_brush_for_read(&sd.paint);
202
203 /* Offset with as much as possible factored in already. */
204 const float3 offset = cache.sculpt_normal_symm * cache.scale * cache.radius * cache.bstrength;
205
206 /* We divide out the squared alpha and multiply by the squared crease
207 * to give us the pinch strength. */
208 float crease_correction = brush.crease_pinch_factor * brush.crease_pinch_factor;
209 float brush_alpha = BKE_brush_alpha_get(&scene, &brush);
210 if (brush_alpha > 0.0f) {
211 crease_correction /= brush_alpha * brush_alpha;
212 }
213
214 /* We always want crease to pinch or blob to relax even when draw is negative. */
215 const float strength = std::abs(cache.bstrength) * crease_correction *
216 (invert_strength ? -1.0f : 1.0f);
217
219 switch (pbvh.type()) {
221 const Mesh &mesh = *static_cast<Mesh *>(object.data);
222 const MeshAttributeData attribute_data(mesh.attributes());
223 const PositionDeformData position_data(depsgraph, object);
224 const Span<float3> vert_normals = bke::pbvh::vert_normals_eval(depsgraph, object);
226 node_mask.foreach_index(GrainSize(1), [&](const int i) {
227 LocalData &tls = all_tls.local();
229 sd,
230 brush,
231 offset,
232 strength,
233 attribute_data,
234 vert_normals,
235 nodes[i],
236 object,
237 tls,
238 position_data);
239 bke::pbvh::update_node_bounds_mesh(position_data.eval, nodes[i]);
240 });
241 break;
242 }
244 SubdivCCG &subdiv_ccg = *object.sculpt->subdiv_ccg;
245 MutableSpan<float3> positions = subdiv_ccg.positions;
247 node_mask.foreach_index(GrainSize(1), [&](const int i) {
248 LocalData &tls = all_tls.local();
249 calc_grids(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
250 bke::pbvh::update_node_bounds_grids(subdiv_ccg.grid_area, positions, nodes[i]);
251 });
252 break;
253 }
256 node_mask.foreach_index(GrainSize(1), [&](const int i) {
257 LocalData &tls = all_tls.local();
258 calc_bmesh(depsgraph, sd, object, brush, offset, strength, nodes[i], tls);
260 });
261 break;
262 }
263 }
264 pbvh.tag_positions_changed(node_mask);
266}
267
268} // namespace crease_cc
269
270void do_crease_brush(const Depsgraph &depsgraph,
271 const Scene &scene,
272 const Sculpt &sd,
273 Object &object,
274 const IndexMask &node_mask)
275{
276 do_crease_or_blob_brush(depsgraph, scene, sd, false, object, node_mask);
277}
278
279void do_blob_brush(const Depsgraph &depsgraph,
280 const Scene &scene,
281 const Sculpt &sd,
282 Object &object,
283 const IndexMask &node_mask)
284{
285 do_crease_or_blob_brush(depsgraph, scene, sd, true, object, node_mask);
286}
287
288} // namespace blender::ed::sculpt_paint
float BKE_brush_alpha_get(const Scene *scene, const Brush *brush)
Definition brush.cc:1153
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_NOINLINE
@ PAINT_FALLOFF_SHAPE_TUBE
Object is a sort of wrapper for general info.
constexpr IndexRange index_range() const
Definition BLI_span.hh:671
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
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:118
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:70
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:155
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:42
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:191
static BLI_NOINLINE void add_offset_to_translations(const MutableSpan< float3 > translations, const Span< float > factors, const float3 &offset)
Definition crease.cc:61
void do_blob_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition crease.cc:279
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_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
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 scale_translations(MutableSpan< float3 > translations, Span< float > factors)
Definition sculpt.cc:7210
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 project_translations(MutableSpan< float3 > translations, const float3 &plane)
Definition sculpt.cc:6998
void apply_translations(Span< float3 > translations, Span< int > verts, MutableSpan< float3 > positions)
Definition sculpt.cc:6958
void do_crease_brush(const Depsgraph &depsgraph, const Scene &scene, const Sculpt &sd, Object &object, const IndexMask &node_mask)
Definition crease.cc:270
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
char falloff_shape
float crease_pinch_factor
blender::ed::sculpt_paint::StrokeCache * cache
Definition BKE_paint.hh:427
SubdivCCG * subdiv_ccg
Definition BKE_paint.hh:405
blender::Array< blender::float3 > positions