59 for (
const int i :
verts.index_range()) {
60 if (hide_vert[
verts[i]]) {
61 new_mask[i] = mask[
verts[i]];
72 dst[i] = factor * src[i] + offset;
79 const float contrast = 0.1f;
80 const float delta = contrast * 0.5f;
81 const float gain =
math::rcp(1.0f - contrast);
82 const float offset = gain * -delta;
91 const float contrast = -0.1f;
92 const float delta = contrast * 0.5f;
93 const float gain = 1.0f - contrast;
94 const float offset = gain * -delta;
104 float val = new_mask[i];
105 float mask = old_masks[i];
148 node_changed[i] =
true;
217 for (
const int i :
verts.index_range()) {
218 new_mask[i] = mask[
verts[i]];
219 for (
const int neighbor : neighbors[i]) {
220 new_mask[i] = std::max(mask[neighbor], new_mask[i]);
242 for (
const int i :
verts.index_range()) {
243 new_mask[i] = mask[
verts[i]];
244 for (
const int neighbor : neighbors[i]) {
245 new_mask[i] = std::min(mask[neighbor], new_mask[i]);
267 if (node_mask == new_mask.
as_span()) {
293 if (node_mask == new_mask.
as_span()) {
317 [&](
const int offset) { grid_dst[offset] = grid_masks[offset]; });
337 const Span<int> grids = nodes[i].grids();
345 node_changed[i] =
true;
395 const int grid = grids[i];
407 grid_dst[offset] = grid_masks[offset];
409 grid_dst[offset] = std::max(masks[neighbor.to_index(key)], grid_dst[offset]);
428 const int grid = grids[i];
440 grid_dst[offset] = grid_masks[offset];
442 grid_dst[offset] = std::min(masks[neighbor.to_index(key)], grid_dst[offset]);
530 const int mask_offset,
551 node_changed[i] =
true;
568 const int mask_offset,
626 const int mask_offset,
657 const int mask_offset,
722 switch (pbvh.
type()) {
727 const Span<int> corner_verts = mesh.corner_verts();
736 nodes, node_mask, node_vert_offset_data);
739 for ([[maybe_unused]]
const int iteration :
IndexRange(iterations)) {
740 switch (filter_type) {
741 case FilterType::Smooth: {
757 case FilterType::Sharpen: {
773 case FilterType::Grow: {
789 case FilterType::Shrink: {
805 case FilterType::ContrastIncrease: {
810 *
depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
816 case FilterType::ContrastDecrease: {
821 *
depsgraph, ob, hide_vert, nodes[i], tls, mask.span);
841 for ([[maybe_unused]]
const int iteration :
IndexRange(iterations)) {
842 switch (filter_type) {
843 case FilterType::Smooth: {
851 case FilterType::Sharpen: {
860 case FilterType::Grow: {
868 case FilterType::Shrink: {
876 case FilterType::ContrastIncrease: {
886 case FilterType::ContrastDecrease: {
909 nodes, node_mask, node_vert_offset_data);
912 for ([[maybe_unused]]
const int iteration :
IndexRange(iterations)) {
913 switch (filter_type) {
914 case FilterType::Smooth: {
922 case FilterType::Sharpen: {
934 case FilterType::Grow: {
942 case FilterType::Shrink: {
950 case FilterType::ContrastIncrease: {
955 *
depsgraph, ob, mask_offset, nodes[i], tls);
961 case FilterType::ContrastDecrease: {
966 *
depsgraph, ob, mask_offset, nodes[i], tls);
991 ot->
idname =
"SCULPT_OT_mask_filter";
992 ot->
description =
"Applies a filter to modify the current mask";
1000 {
int(FilterType::Smooth),
"SMOOTH", 0,
"Smooth Mask",
""},
1001 {
int(FilterType::Sharpen),
"SHARPEN", 0,
"Sharpen Mask",
""},
1002 {
int(FilterType::Grow),
"GROW", 0,
"Grow Mask",
""},
1003 {
int(FilterType::Shrink),
"SHRINK", 0,
"Shrink Mask",
""},
1004 {
int(FilterType::ContrastIncrease),
"CONTRAST_INCREASE", 0,
"Increase Contrast",
""},
1005 {
int(FilterType::ContrastDecrease),
"CONTRAST_DECREASE", 0,
"Decrease Contrast",
""},
1006 {0,
nullptr, 0,
nullptr,
nullptr},
1012 int(FilterType::Smooth),
1014 "Filter that is going to be applied to the mask");
1021 "Number of times that the filter is going to be applied",
1026 "auto_iteration_count",
1028 "Auto Iteration Count",
1029 "Use an automatic number of iterations based on the number of vertices of the sculpt");
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
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)
Main * CTX_data_main(const bContext *C)
View3D * CTX_wm_view3d(const bContext *C)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool BKE_base_is_visible(const View3D *v3d, const Base *base)
MultiresModifierData * BKE_sculpt_multires_active(const Scene *scene, Object *ob)
void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bool is_paint_tool)
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph, Main *bmain, Object *ob, MultiresModifierData *mmd)
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_average_grids(SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, bool include_duplicates, SubdivCCGNeighbors &r_neighbors)
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_elem_flag_test(ele, hflag)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr Span< T > as_span() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
void resize(const int64_t new_size)
Span< NodeT > nodes() const
void tag_masks_changed(const IndexMask &node_mask)
int64_t min_array_size() const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void foreach_index(Fn &&fn) const
const Depsgraph * depsgraph
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
bool indexed_data_equal(const Span< T > all_values, const Span< int > indices, const Span< T > values)
void foreach_1_index(const BitSpanT &data, Fn &&fn)
IndexRange grid_range(const int grid_area, const int grid)
pbvh::Tree * pbvh_get(Object &object)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
void node_update_mask_bmesh(int mask_offset, BMeshNode &node)
void node_update_mask_mesh(Span< float > mask, MeshNode &node)
void node_update_mask_grids(const CCGKey &key, Span< float > masks, GridsNode &node)
Span< int > node_visible_verts(const bke::pbvh::MeshNode &node, const Span< bool > hide_vert, Vector< int > &indices)
static void shrink_mask_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const Span< bool > hide_vert, const Span< float > mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
static BLI_NOINLINE void copy_old_hidden_mask_mesh(const Span< int > verts, const Span< bool > hide_vert, const Span< float > mask, const MutableSpan< float > new_mask)
bool mask_equals_array_bmesh(const int mask_offset, const Set< BMVert *, 0 > &verts, const Span< float > values)
static BLI_NOINLINE void multiply_add(const Span< float > src, const float factor, const float offset, const MutableSpan< float > dst)
static void grow_mask_bmesh(const int mask_offset, bke::pbvh::BMeshNode &node, MutableSpan< float > new_mask)
void SCULPT_OT_mask_filter(wmOperatorType *ot)
static void smooth_mask_bmesh(const int mask_offset, bke::pbvh::BMeshNode &node, MutableSpan< float > new_mask)
static void smooth_mask_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const Span< bool > hide_vert, const Span< float > mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
bool mask_equals_array_grids(const Span< float > masks, const CCGKey &key, const Span< int > grids, const Span< float > values)
static void shrink_mask_bmesh(const int mask_offset, bke::pbvh::BMeshNode &node, MutableSpan< float > new_mask)
static void sharpen_mask_bmesh(const BMesh &bm, const int mask_offset, bke::pbvh::BMeshNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
static bool increase_contrast_mask_grids(const Depsgraph &depsgraph, const Object &object, bke::pbvh::GridsNode &node, FilterLocalData &tls)
static bool decrease_contrast_mask_grids(const Depsgraph &depsgraph, const Object &object, bke::pbvh::GridsNode &node, FilterLocalData &tls)
static bool decrease_contrast_mask_bmesh(const Depsgraph &depsgraph, Object &object, const int mask_offset, bke::pbvh::BMeshNode &node, FilterLocalData &tls)
static void smooth_mask_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, MutableSpan< float > new_mask)
static void grow_mask_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const Span< bool > hide_vert, const Span< float > mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
static bool increase_contrast_mask_mesh(const Depsgraph &depsgraph, const Object &object, const Span< bool > hide_vert, bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > mask)
static void apply_new_mask_grids(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const OffsetIndices< int > node_verts, const Span< float > new_mask)
static bool increase_contrast_mask_bmesh(const Depsgraph &depsgraph, Object &object, const int mask_offset, bke::pbvh::BMeshNode &node, FilterLocalData &tls)
static BLI_NOINLINE void sharpen_masks(const Span< float > old_masks, const MutableSpan< float > new_mask)
void scatter_mask_bmesh(const Span< float > mask, const BMesh &bm, const Set< BMVert *, 0 > &verts)
void gather_mask_bmesh(const BMesh &bm, const Set< BMVert *, 0 > &verts, const MutableSpan< float > r_mask)
static void sharpen_mask_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const Span< bool > hide_poly, const Span< bool > hide_vert, const Span< float > mask, const bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
static void shrink_mask_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, MutableSpan< float > new_mask)
static void apply_new_mask_mesh(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const OffsetIndices< int > node_verts, const Span< float > new_mask, MutableSpan< float > mask)
static BLI_NOINLINE void mask_increase_contrast(const Span< float > src, const MutableSpan< float > dst)
static BLI_NOINLINE void mask_decrease_contrast(const Span< float > src, const MutableSpan< float > dst)
static void apply_new_mask_bmesh(const Depsgraph &depsgraph, Object &object, const int mask_offset, const IndexMask &node_mask, const OffsetIndices< int > node_verts, const Span< float > new_mask)
static void sharpen_mask_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, FilterLocalData &tls, MutableSpan< float > new_mask)
static void grow_mask_grids(const SubdivCCG &subdiv_ccg, const bke::pbvh::GridsNode &node, MutableSpan< float > new_mask)
static int sculpt_mask_filter_exec(bContext *C, wmOperator *op)
static BLI_NOINLINE void copy_old_hidden_mask_bmesh(const int mask_offset, const Set< BMVert *, 0 > &verts, const MutableSpan< float > new_mask)
void clamp_mask(const MutableSpan< float > masks)
static bool decrease_contrast_mask_mesh(const Depsgraph &depsgraph, const Object &object, const Span< bool > hide_vert, bke::pbvh::MeshNode &node, FilterLocalData &tls, MutableSpan< float > mask)
void average_neighbor_mask_bmesh(const int mask_offset, const Set< BMVert *, 0 > &verts, const MutableSpan< float > new_masks)
static BLI_NOINLINE void copy_old_hidden_mask_grids(const SubdivCCG &subdiv_ccg, const Span< int > grids, const MutableSpan< float > new_mask)
void neighbor_data_average_mesh(const Span< T > src, 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 push_end(Object &ob)
void push_node(const Depsgraph &depsgraph, const Object &object, const bke::pbvh::Node *node, Type type)
void push_begin(const Scene &scene, Object &ob, const wmOperator *op)
void gather_data_grids(const SubdivCCG &subdiv_ccg, Span< T > src, Span< int > grids, MutableSpan< T > node_data)
OffsetIndices< int > create_node_vert_offsets_bmesh(const Span< bke::pbvh::BMeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
void flush_update_done(const bContext *C, Object &ob, UpdateType update_type)
void flush_update_step(bContext *C, UpdateType update_type)
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
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)
OffsetIndices< int > create_node_vert_offsets(const Span< bke::pbvh::MeshNode > nodes, const IndexMask &nodes_mask, Array< int > &node_data)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, const int default_value, const int hardmin, const int hardmax, const char *ui_name, const char *ui_description, const int softmin, const int softmax)
bool SCULPT_mode_poll(bContext *C)
int SCULPT_vertex_count_get(const Object &object)
void SCULPT_tag_update_overlays(bContext *C)
struct SculptSession * sculpt
blender::Vector< SubdivCCGCoord, 256 > coords
blender::BitGroupVector grid_hidden
blender::Array< float > masks
Vector< Vector< int > > vert_neighbors
Vector< int > visible_verts
Vector< float > node_mask
bool(* poll)(bContext *C) ATTR_WARN_UNUSED_RESULT
int(* exec)(bContext *C, wmOperator *op) ATTR_WARN_UNUSED_RESULT