60 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
73 return subdiv_ccg.
masks;
84 for (
const int i :
result.index_range()) {
100 masks[
i] += (new_masks[
i] - masks[
i]) * factor;
112 masks[
i] += (new_masks[
i] - masks[
i]) * factors[
i];
118 for (
float &
mask : masks) {
119 mask = std::clamp(
mask, 0.0f, 1.0f);
125 for (
float &
mask : masks) {
233 node_changed[
i] =
true;
250 return std::all_of(range.
begin(), range.
end(), [&](
const int i) {
251 return masks.slice(bke::ccg::grid_range(key, grids[i])) ==
252 values.slice(bke::ccg::grid_range(key, i));
298 "Set mask to the level specified by the 'value' property"},
303 "Set mask to the level specified by the inverted 'value' property"},
319 const int *end = std::copy_if(
verts.begin(),
verts.end(),
indices.begin(), [&](
const int vert) {
320 return hide_vert[vert];
335 if (
mask.is_empty()) {
358 if (std::any_of(
verts.begin(),
verts.end(), [&](
int i) { return mask[i] > 0.0f; })) {
366 if (hidden_masked_verts) {
372 node_mask,
GrainSize(1), memory, [&](
const int i) {
375 verts.begin(),
verts.end(), [&](
const int i) { return mask[i] != 0.0f; });
378 undo::push_nodes(
depsgraph,
object, changed_nodes, undo::Type::Mask);
379 attributes.remove(
".sculpt_mask");
384 pbvh.tag_masks_changed(changed_nodes);
414 if (std::all_of(
verts.begin(),
verts.end(), [&](
int i) { return mask.span[i] == value; })) {
419 node_changed[
i] =
true;
462 if (std::all_of(grid_indices.
begin(), grid_indices.
end(), [&](
const int grid) {
463 const Span<float> grid_masks = masks.slice(bke::ccg::grid_range(key, grid));
464 return std::all_of(grid_masks.begin(), grid_masks.end(), [&](const float mask) {
465 return mask == value;
474 for (
const int grid : grid_indices) {
479 for (
const int grid : grid_indices) {
484 node_changed[
i] =
true;
489 if (node_changed.is_empty()) {
492 pbvh.tag_masks_changed(changed_nodes);
511 if (value == 0.0f && offset == -1) {
525 bool changed =
false;
535 node_changed[
i] =
true;
556 switch (pbvh.
type()) {
592 for (
const int grid : grid_indices) {
594 value = 1.0f - value;
599 for (
const int grid : grid_indices) {
602 [&](
const int i) { grid_masks[
i] = 1.0f - grid_masks[
i]; });
618 BMesh &
bm = *
object.sculpt->bm;
645 for (
const int vert :
verts) {
694 ot->name =
"Mask Flood Fill";
695 ot->idname =
"PAINT_OT_mask_flood_fill";
696 ot->description =
"Fill the whole mask with a given value, or invert its values";
713 "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
766 for (
const int i :
verts.index_range()) {
767 const int vert =
verts[
i];
789 bool any_changed =
false;
790 for (
const int grid : node.
grids()) {
791 const int vert_start = grid * key.
grid_area;
793 const int vert = vert_start +
i;
795 float &
mask = masks[vert];
805 node_changed[node_index] =
true;
823 bool any_changed =
false;
837 node_changed[
i] =
true;
888 "Mask level to use when mode is 'Value'; zero means no masking and one is fully masked",
939 ot->name =
"Mask Lasso Gesture";
940 ot->idname =
"PAINT_OT_mask_lasso_gesture";
941 ot->description =
"Mask within a shape defined by the cursor";
959 ot->name =
"Mask Box Gesture";
960 ot->idname =
"PAINT_OT_mask_box_gesture";
961 ot->description =
"Mask within a rectangle defined by the cursor";
979 ot->name =
"Mask Line Gesture";
980 ot->idname =
"PAINT_OT_mask_line_gesture";
981 ot->description =
"Mask to one side of a line defined by the cursor";
999 ot->name =
"Mask Polyline Gesture";
1000 ot->idname =
"PAINT_OT_mask_polyline_gesture";
1001 ot->description =
"Mask within a shape defined by the cursor";
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)
Main * CTX_data_main(const bContext *C)
int CustomData_get_offset_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
@ MULTIRES_COORDS_MODIFIED
void multires_mark_as_modified(Depsgraph *depsgraph, Object *object, MultiresModifiedFlags flags)
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.
bool BKE_pbvh_node_fully_hidden_get(const blender::bke::pbvh::Node &node)
void BKE_pbvh_node_fully_unmasked_set(blender::bke::pbvh::Node &node, int fully_masked)
void BKE_pbvh_node_fully_masked_set(blender::bke::pbvh::Node &node, int fully_masked)
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_foreach_visible_grid_vert(const CCGKey &key, const blender::BitGroupVector<> &grid_hidden, const int grid, const Fn &fn)
#define BLI_assert_unreachable()
Object is a sort of wrapper for general info.
Read Guarded memory(de)allocation.
@ OPTYPE_DEPENDS_ON_CURSOR
#define BM_ELEM_CD_SET_FLOAT(ele, offset, f)
#define BM_ELEM_CD_GET_FLOAT(ele, offset)
#define BM_elem_flag_test(ele, hflag)
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
BPy_StructRNA * depsgraph
static T sum(const btAlignedObjectArray< T > &items)
Span< T > as_span() const
MutableSpan< T > as_mutable_span()
static IndexMask from_predicate(const IndexMask &universe, GrainSize grain_size, IndexMaskMemory &memory, Fn &&predicate)
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
void resize(const int64_t new_size)
MutableSpan< T > as_mutable_span()
Span< T > as_span() const
static IndexMask from_bools(Span< bool > bools, IndexMaskMemory &memory)
constexpr Iterator end() const
constexpr Iterator begin() const
constexpr int64_t size() const
constexpr MutableSpan slice(const int64_t start, const int64_t size) const
constexpr void fill(const T &value) const
constexpr IndexRange index_range() const
constexpr int64_t size() const
constexpr const T * end() const
constexpr IndexRange index_range() const
constexpr const T * begin() const
constexpr bool is_empty() const
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
Span< NodeT > nodes() const
void tag_masks_changed(const IndexMask &node_mask)
IndexMask slice(IndexRange range) const
int64_t min_array_size() const
IndexRange index_range() const
void foreach_index(Fn &&fn) const
static float normals[][3]
void * MEM_callocN(size_t len, const char *str)
bool indexed_data_equal(const Span< T > all_values, const Span< int > indices, const Span< T > values)
void foreach_0_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< float3 > vert_normals_eval(const Depsgraph &depsgraph, const Object &object_orig)
Span< float3 > vert_positions_eval(const Depsgraph &depsgraph, const Object &object_orig)
std::unique_ptr< GestureData > init_from_box(bContext *C, wmOperator *op)
void operator_properties(wmOperatorType *ot, ShapeType shapeType)
std::unique_ptr< GestureData > init_from_polyline(bContext *C, wmOperator *op)
std::unique_ptr< GestureData > init_from_line(bContext *C, const wmOperator *op)
void apply(bContext &C, GestureData &gesture_data, wmOperator &op)
std::unique_ptr< GestureData > init_from_lasso(bContext *C, wmOperator *op)
bool is_affected(const GestureData &gesture_data, const float3 &position, const float3 &normal)
Span< int > node_visible_verts(const bke::pbvh::MeshNode &node, const Span< bool > hide_vert, Vector< int > &indices)
bool mask_equals_array_bmesh(const int mask_offset, const Set< BMVert *, 0 > &verts, const Span< float > values)
void scatter_mask_grids(const Span< float > mask, SubdivCCG &subdiv_ccg, const Span< int > grids)
static void gesture_end(bContext &C, gesture::GestureData &gesture_data)
static float average_masks(const int mask_offset, const Span< const BMVert * > verts)
void PAINT_OT_mask_polyline_gesture(wmOperatorType *ot)
bool mask_equals_array_grids(const Span< float > masks, const CCGKey &key, const Span< int > grids, const Span< float > values)
void PAINT_OT_mask_line_gesture(wmOperatorType *ot)
void write_mask_mesh(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, FunctionRef< void(MutableSpan< float >, Span< int >)> write_fn)
static wmOperatorStatus gesture_polyline_exec(bContext *C, wmOperator *op)
static const EnumPropertyItem mode_items[]
static wmOperatorStatus mask_flood_fill_exec(bContext *C, wmOperator *op)
static void fill_mask_grids(Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object, const float value, const IndexMask &node_mask)
static void invert_mask_bmesh(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask)
void update_mask_mesh(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, FunctionRef< void(MutableSpan< float >, Span< int >)> update_fn)
static void init_operation(bContext &C, gesture::GestureData &gesture_data, wmOperator &op)
static bool try_remove_mask_mesh(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask)
void scatter_mask_bmesh(const Span< float > mask, const BMesh &bm, const Set< BMVert *, 0 > &verts)
static void gesture_apply_for_symmetry_pass(bContext &, gesture::GestureData &gesture_data)
void gather_mask_bmesh(const BMesh &bm, const Set< BMVert *, 0 > &verts, const MutableSpan< float > r_mask)
void mix_new_masks(const Span< float > new_masks, const float factor, const MutableSpan< float > masks)
static void gesture_begin(bContext &C, wmOperator &op, gesture::GestureData &gesture_data)
static wmOperatorStatus gesture_lasso_exec(bContext *C, wmOperator *op)
Array< float > duplicate_mask(const Object &object)
static Span< int > get_hidden_verts(const bke::pbvh::MeshNode &node, const Span< bool > hide_vert, Vector< int > &indices)
static void fill_mask(Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object, const float value)
void invert_mask(const MutableSpan< float > masks)
void gather_mask_grids(const SubdivCCG &subdiv_ccg, const Span< int > grids, const MutableSpan< float > r_mask)
static wmOperatorStatus gesture_line_exec(bContext *C, wmOperator *op)
static void fill_mask_bmesh(const Depsgraph &depsgraph, Object &object, const float value, const IndexMask &node_mask)
static float mask_gesture_get_new_value(const float elem, FloodFillMode mode, float value)
static void gesture_operator_properties(wmOperatorType *ot)
void PAINT_OT_mask_box_gesture(wmOperatorType *ot)
static void invert_mask_grids(Main &bmain, const Scene &scene, Depsgraph &depsgraph, Object &object, const IndexMask &node_mask)
void PAINT_OT_mask_lasso_gesture(wmOperatorType *ot)
static wmOperatorStatus gesture_box_exec(bContext *C, wmOperator *op)
void clamp_mask(const MutableSpan< float > masks)
void PAINT_OT_mask_flood_fill(wmOperatorType *ot)
void average_neighbor_mask_bmesh(const int mask_offset, const Set< BMVert *, 0 > &verts, const MutableSpan< float > new_masks)
static void fill_mask_mesh(const Depsgraph &depsgraph, Object &object, const float value, const IndexMask &node_mask)
void push_end(Object &ob)
void push_nodes(const Depsgraph &depsgraph, Object &object, const IndexMask &node_mask, const Type type)
void push_node(const Depsgraph &depsgraph, const Object &object, const bke::pbvh::Node *node, const 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)
void vert_random_access_ensure(Object &object)
Vector< BMVert *, 64 > BMeshNeighborVerts
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, BMeshNeighborVerts &r_neighbors)
void gather_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
float RNA_float_get(PointerRNA *ptr, const char *name)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, 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)
bool SCULPT_mode_poll_view3d(bContext *C)
bool SCULPT_mode_poll(bContext *C)
void SCULPT_tag_update_overlays(bContext *C)
blender::Array< float > masks
blender::Array< blender::float3 > positions
Span< int > grids() const
Span< int > verts() const
void(* end)(bContext &, GestureData &)
void(* begin)(bContext &, wmOperator &, GestureData &)
void(* apply_for_symmetry_pass)(bContext &, GestureData &)
wmOperatorStatus WM_gesture_polyline_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_lasso_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_modal(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_box_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_straightline_active_side_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_polyline_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_lasso_invoke(bContext *C, wmOperator *op, const wmEvent *event)
wmOperatorStatus WM_gesture_straightline_oneshot_modal(bContext *C, wmOperator *op, const wmEvent *event)
void WM_operator_properties_gesture_straightline(wmOperatorType *ot, int cursor)
void WM_operator_properties_border(wmOperatorType *ot)
void WM_operator_properties_gesture_lasso(wmOperatorType *ot)
void WM_operator_properties_gesture_polyline(wmOperatorType *ot)