Blender V4.3
sculpt_filter_color.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "MEM_guardedalloc.h"
10
12#include "BLI_math_color.h"
14#include "BLI_math_vector.hh"
15#include "BLI_task.h"
16
17#include "BLT_translation.hh"
18
19#include "BKE_attribute.hh"
20#include "BKE_context.hh"
21#include "BKE_layer.hh"
22#include "BKE_mesh.hh"
23#include "BKE_paint.hh"
24#include "BKE_pbvh_api.hh"
25
27
28#include "WM_api.hh"
29#include "WM_types.hh"
30
31#include "ED_paint.hh"
32
33#include "mesh_brush_common.hh"
34#include "sculpt_automask.hh"
35#include "sculpt_color.hh"
36#include "sculpt_filter.hh"
37#include "sculpt_intern.hh"
38#include "sculpt_smooth.hh"
39#include "sculpt_undo.hh"
40
41#include "RNA_access.hh"
42#include "RNA_define.hh"
43
44#include "UI_interface.hh"
45#include "UI_resources.hh"
46
47#include <cmath>
48#include <cstdlib>
49
51
64
65static const float fill_filter_default_color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
66
68 {int(FilterType::Fill), "FILL", 0, "Fill", "Fill with a specific color"},
69 {int(FilterType::Hue), "HUE", 0, "Hue", "Change hue"},
70 {int(FilterType::Saturation), "SATURATION", 0, "Saturation", "Change saturation"},
71 {int(FilterType::Value), "VALUE", 0, "Value", "Change value"},
72 {int(FilterType::Brightness), "BRIGHTNESS", 0, "Brightness", "Change brightness"},
73 {int(FilterType::Contrast), "CONTRAST", 0, "Contrast", "Change contrast"},
74 {int(FilterType::Smooth), "SMOOTH", 0, "Smooth", "Smooth colors"},
75 {int(FilterType::Red), "RED", 0, "Red", "Change red channel"},
76 {int(FilterType::Green), "GREEN", 0, "Green", "Change green channel"},
77 {int(FilterType::Blue), "BLUE", 0, "Blue", "Change blue channel"},
78 {0, nullptr, 0, nullptr, nullptr},
79};
80
88
90 const float min,
91 const float max)
92{
93 for (float &factor : factors) {
94 factor = std::clamp(factor, min, max);
95 }
96}
97
98static void color_filter_task(const Depsgraph &depsgraph,
99 Object &ob,
101 const Span<int> corner_verts,
102 const GroupedSpan<int> vert_to_face_map,
103 const MeshAttributeData &attribute_data,
104 const FilterType mode,
105 const float filter_strength,
106 const float *filter_fill_color,
107 const bke::pbvh::MeshNode &node,
108 LocalData &tls,
109 bke::GSpanAttributeWriter &color_attribute)
110{
111 SculptSession &ss = *ob.sculpt;
112
113 const Span<float4> orig_colors = orig_color_data_get_mesh(ob, node);
114
115 const Span<int> verts = node.verts();
116
117 tls.factors.resize(verts.size());
118 const MutableSpan<float> factors = tls.factors;
119 fill_factor_from_hide_and_mask(attribute_data.hide_vert, attribute_data.mask, verts, factors);
121 depsgraph, ob, ss.filter_cache->automasking.get(), node, verts, factors);
122 scale_factors(factors, filter_strength);
123
124 tls.new_colors.resize(verts.size());
125 const MutableSpan<float4> new_colors = tls.new_colors;
126
127 /* Copy alpha. */
128 for (const int i : verts.index_range()) {
129 new_colors[i][3] = orig_colors[i][3];
130 }
131
132 switch (mode) {
133 case FilterType::Fill: {
134 clamp_factors(factors, 0.0f, 1.0f);
135 for (const int i : verts.index_range()) {
136 float fill_color_rgba[4];
137 copy_v3_v3(fill_color_rgba, filter_fill_color);
138 fill_color_rgba[3] = 1.0f;
139 mul_v4_fl(fill_color_rgba, factors[i]);
140 blend_color_mix_float(new_colors[i], orig_colors[i], fill_color_rgba);
141 }
142 break;
143 }
144 case FilterType::Hue: {
145 for (const int i : verts.index_range()) {
146 float3 hsv_color;
147 rgb_to_hsv_v(orig_colors[i], hsv_color);
148 const float hue = hsv_color[0];
149 hsv_color[0] = fmod((hsv_color[0] + fabs(factors[i])) - hue, 1);
150 hsv_to_rgb_v(hsv_color, new_colors[i]);
151 }
152 break;
153 }
154 case FilterType::Saturation: {
155 for (const int i : verts.index_range()) {
156 float3 hsv_color;
157 rgb_to_hsv_v(orig_colors[i], hsv_color);
158
159 if (hsv_color[1] > 0.001f) {
160 hsv_color[1] = std::clamp(hsv_color[1] + factors[i] * hsv_color[1], 0.0f, 1.0f);
161 hsv_to_rgb_v(hsv_color, new_colors[i]);
162 }
163 else {
164 copy_v3_v3(new_colors[i], orig_colors[i]);
165 }
166 }
167 break;
168 }
169 case FilterType::Value: {
170 for (const int i : verts.index_range()) {
171 float3 hsv_color;
172 rgb_to_hsv_v(orig_colors[i], hsv_color);
173 hsv_color[2] = std::clamp(hsv_color[2] + factors[i], 0.0f, 1.0f);
174 hsv_to_rgb_v(hsv_color, new_colors[i]);
175 }
176 break;
177 }
178 case FilterType::Red: {
179 for (const int i : verts.index_range()) {
180 copy_v3_v3(new_colors[i], orig_colors[i]);
181 new_colors[i][0] = std::clamp(orig_colors[i][0] + factors[i], 0.0f, 1.0f);
182 }
183 break;
184 }
185 case FilterType::Green: {
186 for (const int i : verts.index_range()) {
187 copy_v3_v3(new_colors[i], orig_colors[i]);
188 new_colors[i][1] = std::clamp(orig_colors[i][1] + factors[i], 0.0f, 1.0f);
189 }
190 break;
191 }
192 case FilterType::Blue: {
193 for (const int i : verts.index_range()) {
194 copy_v3_v3(new_colors[i], orig_colors[i]);
195 new_colors[i][2] = std::clamp(orig_colors[i][2] + factors[i], 0.0f, 1.0f);
196 }
197 break;
198 }
199 case FilterType::Brightness: {
200 clamp_factors(factors, -1.0f, 1.0f);
201 for (const int i : verts.index_range()) {
202 const float brightness = factors[i];
203 const float contrast = 0;
204 float delta = contrast / 2.0f;
205 const float gain = 1.0f - delta * 2.0f;
206 delta *= -1;
207 const float offset = gain * (brightness + delta);
208 for (int component = 0; component < 3; component++) {
209 new_colors[i][component] = std::clamp(
210 gain * orig_colors[i][component] + offset, 0.0f, 1.0f);
211 }
212 }
213 break;
214 }
215 case FilterType::Contrast: {
216 clamp_factors(factors, -1.0f, 1.0f);
217 for (const int i : verts.index_range()) {
218 const float brightness = 0;
219 const float contrast = factors[i];
220 float delta = contrast / 2.0f;
221 float gain = 1.0f - delta * 2.0f;
222
223 float offset;
224 if (contrast > 0) {
225 gain = 1.0f / ((gain != 0.0f) ? gain : FLT_EPSILON);
226 offset = gain * (brightness - delta);
227 }
228 else {
229 delta *= -1;
230 offset = gain * (brightness + delta);
231 }
232 for (int component = 0; component < 3; component++) {
233 new_colors[i][component] = std::clamp(
234 gain * orig_colors[i][component] + offset, 0.0f, 1.0f);
235 }
236 }
237 break;
238 }
239 case FilterType::Smooth: {
240 clamp_factors(factors, -1.0f, 1.0f);
241
242 tls.colors.resize(verts.size());
243 const MutableSpan<float4> colors = tls.colors;
244 for (const int i : verts.index_range()) {
245 colors[i] = color_vert_get(faces,
246 corner_verts,
247 vert_to_face_map,
248 color_attribute.span,
249 color_attribute.domain,
250 verts[i]);
251 }
252
253 tls.vert_neighbors.resize(verts.size());
254 calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
255 const Span<Vector<int>> neighbors = tls.vert_neighbors;
256
257 tls.average_colors.resize(verts.size());
258 const MutableSpan<float4> average_colors = tls.average_colors;
260 corner_verts,
261 vert_to_face_map,
262 color_attribute.span,
263 color_attribute.domain,
264 neighbors,
265 average_colors);
266
267 for (const int i : verts.index_range()) {
268 const int vert = verts[i];
269
270 if (factors[i] < 0.0f) {
271 interp_v4_v4v4(average_colors[i], average_colors[i], colors[i], 0.5f);
272 }
273
274 bool copy_alpha = colors[i][3] == average_colors[i][3];
275
276 if (factors[i] < 0.0f) {
277 float delta_color[4];
278
279 /* Unsharp mask. */
280 copy_v4_v4(delta_color, ss.filter_cache->pre_smoothed_color[vert]);
281 sub_v4_v4(delta_color, average_colors[i]);
282
283 copy_v4_v4(new_colors[i], colors[i]);
284 madd_v4_v4fl(new_colors[i], delta_color, factors[i]);
285 }
286 else {
287 blend_color_interpolate_float(new_colors[i], colors[i], average_colors[i], factors[i]);
288 }
289
290 new_colors[i] = math::clamp(new_colors[i], 0.0f, 1.0f);
291
292 /* Prevent accumulated numeric error from corrupting alpha. */
293 if (copy_alpha) {
294 new_colors[i][3] = average_colors[i][3];
295 }
296 }
297 break;
298 }
299 }
300
301 for (const int i : verts.index_range()) {
303 corner_verts,
304 vert_to_face_map,
305 color_attribute.domain,
306 verts[i],
307 new_colors[i],
308 color_attribute.span);
309 }
310}
311
312static void sculpt_color_presmooth_init(const Mesh &mesh, Object &object)
313{
314 SculptSession &ss = *object.sculpt;
315 bke::pbvh::Tree &pbvh = *bke::object::pbvh_get(object);
317 const IndexMask &node_mask = ss.filter_cache->node_mask;
318 const OffsetIndices<int> faces = mesh.faces();
319 const Span<int> corner_verts = mesh.corner_verts();
320 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
321 const bke::GAttributeReader color_attribute = active_color_attribute(mesh);
322 const GVArraySpan colors = *color_attribute;
323
324 if (ss.filter_cache->pre_smoothed_color.is_empty()) {
326 }
327 const MutableSpan<float4> pre_smoothed_color = ss.filter_cache->pre_smoothed_color;
328
329 node_mask.foreach_index(GrainSize(1), [&](const int i) {
330 for (const int vert : nodes[i].verts()) {
331 pre_smoothed_color[vert] = color_vert_get(
332 faces, corner_verts, vert_to_face_map, colors, color_attribute.domain, vert);
333 }
334 });
335
336 struct LocalData {
338 Vector<float4> averaged_colors;
339 };
341 for ([[maybe_unused]] const int iteration : IndexRange(2)) {
342 node_mask.foreach_index(GrainSize(1), [&](const int i) {
343 LocalData &tls = all_tls.local();
344 const Span<int> verts = nodes[i].verts();
345
346 tls.vert_neighbors.resize(verts.size());
347 calc_vert_neighbors(faces, corner_verts, vert_to_face_map, {}, verts, tls.vert_neighbors);
348 const Span<Vector<int>> vert_neighbors = tls.vert_neighbors;
349
350 tls.averaged_colors.resize(verts.size());
351 const MutableSpan<float4> averaged_colors = tls.averaged_colors;
353 pre_smoothed_color.as_span(), vert_neighbors, averaged_colors);
354
355 for (const int i : verts.index_range()) {
356 pre_smoothed_color[verts[i]] = math::interpolate(
357 pre_smoothed_color[verts[i]], averaged_colors[i], 0.5f);
358 }
359 });
360 }
361}
362
364{
365 const Depsgraph &depsgraph = *CTX_data_depsgraph_pointer(C);
366 SculptSession &ss = *ob.sculpt;
369
370 const FilterType mode = FilterType(RNA_enum_get(op->ptr, "type"));
371 float filter_strength = RNA_float_get(op->ptr, "strength");
372 float fill_color[3];
373
374 RNA_float_get_array(op->ptr, "fill_color", fill_color);
375 IMB_colormanagement_srgb_to_scene_linear_v3(fill_color, fill_color);
376
377 Mesh &mesh = *static_cast<Mesh *>(ob.data);
378 if (filter_strength < 0.0 && ss.filter_cache->pre_smoothed_color.is_empty()) {
380 }
381
382 const IndexMask &node_mask = ss.filter_cache->node_mask;
383
384 const OffsetIndices<int> faces = mesh.faces();
385 const Span<int> corner_verts = mesh.corner_verts();
386 const GroupedSpan<int> vert_to_face_map = mesh.vert_to_face_map();
388 const MeshAttributeData attribute_data(mesh.attributes());
389
391 node_mask.foreach_index(GrainSize(1), [&](const int i) {
392 LocalData &tls = all_tls.local();
394 ob,
395 faces,
396 corner_verts,
397 vert_to_face_map,
398 attribute_data,
399 mode,
400 filter_strength,
401 fill_color,
402 nodes[i],
403 tls,
404 color_attribute);
405 });
406 pbvh.tag_attribute_changed(node_mask, mesh.active_color_attribute);
407 color_attribute.finish();
409}
410
412{
413 SculptSession &ss = *ob.sculpt;
414
415 undo::push_end(ob);
416 MEM_delete(ss.filter_cache);
417 ss.filter_cache = nullptr;
419}
420
422{
424 SculptSession &ss = *ob.sculpt;
425
426 if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
428 return OPERATOR_FINISHED;
429 }
430
431 if (event->type != MOUSEMOVE) {
433 }
434
435 const float len = (event->prev_press_xy[0] - event->xy[0]) * 0.001f;
436 float filter_strength = ss.filter_cache->start_filter_strength * -len;
437 RNA_float_set(op->ptr, "strength", filter_strength);
438
440
442}
443
445{
446 const Scene &scene = *CTX_data_scene(C);
448 const Sculpt &sd = *CTX_data_tool_settings(C)->sculpt;
449 SculptSession &ss = *ob.sculpt;
450 View3D *v3d = CTX_wm_view3d(C);
451
452 const Base *base = CTX_data_active_base(C);
453 if (!BKE_base_is_visible(v3d, base)) {
454 return OPERATOR_CANCELLED;
455 }
456
457 int mval[2];
458 RNA_int_get_array(op->ptr, "start_mouse", mval);
459 float mval_fl[2] = {float(mval[0]), float(mval[1])};
460
461 const bool use_automasking = auto_mask::is_enabled(sd, ob, nullptr);
462 if (use_automasking) {
463 if (v3d) {
464 /* Update the active face set manually as the paint cursor is not enabled when using the Mesh
465 * Filter Tool. */
467 SCULPT_cursor_geometry_info_update(C, &sgi, mval_fl, false);
468 }
469 }
470
471 /* Disable for multires and dyntopo for now */
473 return OPERATOR_CANCELLED;
474 }
475
476 undo::push_begin(scene, ob, op);
478
479 /* CTX_data_ensure_evaluated_depsgraph should be used at the end to include the updates of
480 * earlier steps modifying the data. */
483
485 ob,
486 sd,
488 mval_fl,
489 RNA_float_get(op->ptr, "area_normal_radius"),
490 RNA_float_get(op->ptr, "strength"));
491 filter::Cache *filter_cache = ss.filter_cache;
493 filter_cache->automasking = auto_mask::cache_init(*depsgraph, sd, ob);
494
496}
497
499{
501
503 return OPERATOR_CANCELLED;
504 }
505
508
509 return OPERATOR_FINISHED;
510}
511
513{
515 View3D *v3d = CTX_wm_view3d(C);
516 if (v3d && v3d->shading.type == OB_SOLID) {
518 }
519
520 RNA_int_set_array(op->ptr, "start_mouse", event->mval);
521
523 return OPERATOR_CANCELLED;
524 }
525
527
530}
531
533{
535 const int value = RNA_property_enum_get(ptr, prop);
536 const char *ui_name = nullptr;
537
538 RNA_property_enum_name_gettexted(nullptr, ptr, prop, value, &ui_name);
539 return ui_name;
540}
541
543{
544 uiLayout *layout = op->layout;
545
546 uiItemR(layout, op->ptr, "strength", UI_ITEM_NONE, nullptr, ICON_NONE);
547
548 if (FilterType(RNA_enum_get(op->ptr, "type")) == FilterType::Fill) {
549 uiItemR(layout, op->ptr, "fill_color", UI_ITEM_NONE, nullptr, ICON_NONE);
550 }
551}
552
554{
555 /* identifiers */
556 ot->name = "Filter Color";
557 ot->idname = "SCULPT_OT_color_filter";
558 ot->description = "Applies a filter to modify the active color attribute";
559
560 /* api callbacks */
564 ot->poll = SCULPT_mode_poll;
567
569
570 /* rna */
572
574 ot->srna, "type", prop_color_filter_types, int(FilterType::Fill), "Filter Type", "");
575
576 PropertyRNA *prop = RNA_def_float_color(ot->srna,
577 "fill_color",
578 3,
580 0.0f,
581 FLT_MAX,
582 "Fill Color",
583 "",
584 0.0f,
585 1.0f);
588}
589
590} // namespace blender::ed::sculpt_paint::color
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
Object * CTX_data_active_object(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Base * CTX_data_active_base(const bContext *C)
ToolSettings * CTX_data_tool_settings(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
#define SCULPT_FACE_SET_NONE
Definition BKE_paint.hh:341
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
Definition paint.cc:2601
void BKE_sculpt_color_layer_create_if_needed(Object *object)
Definition paint.cc:2577
A BVH for high poly meshes.
#define BLI_NOINLINE
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
Definition math_color.cc:57
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t)
MINLINE void mul_v4_fl(float r[4], float f)
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v4_v4v4(float r[4], const float a[4], const float b[4], float t)
Definition math_vector.c:45
MINLINE void sub_v4_v4(float r[4], const float a[4])
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
#define BLT_I18NCONTEXT_ID_MESH
@ OB_SOLID
@ V3D_SHADING_VERTEX_COLOR
@ OPERATOR_RUNNING_MODAL
@ OPERATOR_PASS_THROUGH
void ED_image_paint_brush_type_update_sticky_shading_color(bContext *C, Object *ob)
BLI_INLINE void IMB_colormanagement_srgb_to_scene_linear_v3(float scene_linear[3], const float srgb[3])
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its hue
@ PROP_COLOR_GAMMA
Definition RNA_types.hh:175
#define C
Definition RandGen.cpp:29
#define UI_ITEM_NONE
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ OPTYPE_UNDO
Definition WM_types.hh:162
@ OPTYPE_REGISTER
Definition WM_types.hh:160
@ KM_RELEASE
Definition WM_types.hh:285
BPy_StructRNA * depsgraph
void resize(const int64_t new_size)
constexpr Span< T > as_span() const
Definition BLI_span.hh:662
void tag_attribute_changed(const IndexMask &node_mask, StringRef attribute_name)
Definition pbvh.cc:593
Span< NodeT > nodes() const
void foreach_index(Fn &&fn) const
int len
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
static float verts[][3]
ccl_device_inline float2 fmod(const float2 a, const float b)
ccl_device_inline float2 fabs(const float2 a)
static char faces[256]
pbvh::Tree * pbvh_get(Object &object)
Definition paint.cc:2846
std::unique_ptr< Cache > cache_init(const Depsgraph &depsgraph, const Sculpt &sd, Object &ob)
bool is_enabled(const Sculpt &sd, const Object &object, const Brush *br)
void calc_vert_factors(const Depsgraph &depsgraph, const Object &object, const Cache &cache, const bke::pbvh::MeshNode &node, Span< int > verts, MutableSpan< float > factors)
bke::GSpanAttributeWriter active_color_attribute_for_write(Mesh &mesh)
static std::string sculpt_color_filter_get_name(wmOperatorType *, PointerRNA *ptr)
static const float fill_filter_default_color[4]
static void color_filter_task(const Depsgraph &depsgraph, Object &ob, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const MeshAttributeData &attribute_data, const FilterType mode, const float filter_strength, const float *filter_fill_color, const bke::pbvh::MeshNode &node, LocalData &tls, bke::GSpanAttributeWriter &color_attribute)
static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static BLI_NOINLINE void clamp_factors(const MutableSpan< float > factors, const float min, const float max)
float4 color_vert_get(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, GSpan color_attribute, bke::AttrDomain color_domain, int vert)
void color_vert_set(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, bke::AttrDomain color_domain, int vert, const float4 &color, GMutableSpan color_attribute)
static int sculpt_color_filter_init(bContext *C, wmOperator *op)
void SCULPT_OT_color_filter(wmOperatorType *ot)
static int sculpt_color_filter_exec(bContext *C, wmOperator *op)
bke::GAttributeReader active_color_attribute(const Mesh &mesh)
static void sculpt_color_presmooth_init(const Mesh &mesh, Object &object)
static void sculpt_color_filter_end(bContext *C, Object &ob)
static void sculpt_color_filter_apply(bContext *C, wmOperator *op, Object &ob)
static void sculpt_color_filter_ui(bContext *, wmOperator *op)
static EnumPropertyItem prop_color_filter_types[]
static int sculpt_color_filter_modal(bContext *C, wmOperator *op, const wmEvent *event)
static BLI_NOINLINE void fill_factor_from_hide_and_mask(const Mesh &mesh, const Span< int > face_indices, const MutableSpan< float > r_factors)
void cache_init(bContext *C, Object &ob, const Sculpt &sd, undo::Type undo_type, const float mval_fl[2], float area_normal_radius, float start_strength)
void register_operator_props(wmOperatorType *ot)
void neighbor_color_average(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const GSpan color_attribute, const bke::AttrDomain color_domain, const Span< Vector< int > > vert_neighbors, const MutableSpan< float4 > smooth_colors)
void neighbor_data_average_mesh(const Span< T > src, const Span< Vector< int > > vert_neighbors, const MutableSpan< T > dst)
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
void flush_update_done(const bContext *C, Object &ob, UpdateType update_type)
Definition sculpt.cc:5069
void flush_update_step(bContext *C, UpdateType update_type)
Definition sculpt.cc:4960
void scale_factors(MutableSpan< float > factors, float strength)
Definition sculpt.cc:7247
Span< float4 > orig_color_data_get_mesh(const Object &object, const bke::pbvh::MeshNode &node)
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:7350
T clamp(const T &a, const T &min, const T &max)
T interpolate(const T &a, const T &b, const FactorT &t)
VecBase< float, 3 > float3
void RNA_int_set_array(PointerRNA *ptr, const char *name, const int *values)
void RNA_int_get_array(PointerRNA *ptr, const char *name, int *values)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
bool RNA_property_enum_name_gettexted(bContext *C, PointerRNA *ptr, PropertyRNA *prop, const int value, const char **r_name)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identifier, const int len, const float *default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
void RNA_def_property_translation_context(PropertyRNA *prop, const char *context)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
Definition sculpt.cc:4580
bool SCULPT_mode_poll(bContext *C)
Definition sculpt.cc:3560
bool SCULPT_handles_colors_report(const Object &object, ReportList *reports)
Definition sculpt.cc:5191
#define min(a, b)
Definition sort.c:32
#define FLT_MAX
Definition stdcycles.h:14
struct SculptSession * sculpt
blender::ed::sculpt_paint::filter::Cache * filter_cache
Definition BKE_paint.hh:428
View3DShading shading
Span< int > verts() const
std::unique_ptr< auto_mask::Cache > automasking
short val
Definition WM_types.hh:724
int mval[2]
Definition WM_types.hh:728
short type
Definition WM_types.hh:722
struct ReportList * reports
struct uiLayout * layout
struct PointerRNA * ptr
float max
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
@ MOUSEMOVE
@ LEFTMOUSE
PointerRNA * ptr
Definition wm_files.cc:4126
wmOperatorType * ot
Definition wm_files.cc:4125