81 if (create_face_set) {
82 for (
int i = 0; i < ss->
totfaces; i++) {
97 if (!create_face_set) {
114 int update_it =
data->mask_expand_update_it;
118 float final_mask = *vd.
mask;
119 if (
data->mask_expand_use_normals) {
138 if (
data->mask_expand_create_face_set) {
139 if (final_mask == 1.0f) {
146 if (
data->mask_expand_keep_prev_mask) {
150 if (
data->mask_expand_invert_mask) {
151 final_mask = 1.0f - final_mask;
154 if (*vd.
mask != final_mask) {
158 *vd.
mask = final_mask;
173 float prevclick_f[2];
175 const int prevclick[2] = {(int)prevclick_f[0], (
int)prevclick_f[1]};
179 int mask_expand_update_it =
len / mask_speed;
180 mask_expand_update_it = mask_expand_update_it + 1;
187 mouse[0] =
event->mval[0];
188 mouse[1] =
event->mval[1];
214 const int smooth_iterations =
RNA_int_get(op->
ptr,
"smooth_iterations");
221 const float threshold = 0.2f;
230 if (
mask < (0.5f + threshold) &&
mask > (0.5f - threshold)) {
277 if (mask_expand_update_it < ss->filter_cache->mask_update_last_it) {
279 if (create_face_set) {
280 for (
int i = 0; i < ss->
totfaces; i++) {
288 .mask_expand_update_it = mask_expand_update_it,
312 SculptSession *ss,
int from_v,
int to_v,
bool is_duplicate,
void *userdata)
323 if (
data->use_normals) {
324 float current_normal[3], prev_normal[3];
331 powf(from_edge_factor,
data->edge_sensitivity);
338 if (
data->use_normals) {
360 mouse[0] =
event->mval[0];
361 mouse[1] =
event->mval[1];
380 if (create_face_set) {
394 "mask update iteration");
397 "mask update normal factor");
399 "mask update normal factor");
400 for (
int i = 0; i < vertex_count; i++) {
405 if (create_face_set) {
407 for (
int i = 0; i < ss->
totfaces; i++) {
414 for (
int i = 0; i < vertex_count; i++) {
438 for (
int repeat = 0; repeat < 2; repeat++) {
439 for (
int i = 0; i < vertex_count; i++) {
457 .mask_expand_update_it = 0,
467 const char *status_str =
TIP_(
468 "Move the mouse to expand the mask from the active vertex. LMB: confirm mask, ESC/RMB: "
481 ot->
idname =
"SCULPT_OT_mask_expand";
482 ot->
description =
"Expands a mask from the initial active vertex under the cursor";
493 ot->
srna,
"use_cursor",
true,
"Use Cursor",
"Expand the mask to the cursor position");
497 "Update Pivot Position",
498 "Set the pivot position to the mask border after creating the mask");
506 "Generate the mask using the normals and curvature of the model");
508 "keep_previous_mask",
510 "Keep Previous Mask",
511 "Generate the new mask on top of the current one");
517 "Edge Detection Sensitivity",
518 "Sensitivity for expanding the mask across sculpted sharp edges when "
519 "using normals to generate the mask",
526 "Expand a new Face Mask instead of the sculpt mask");
struct Object * CTX_data_active_object(const bContext *C)
struct ARegion * CTX_wm_region(const bContext *C)
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
General operations, lookup, etc. for blender objects.
void BKE_sculpt_update_object_for_edit(struct Depsgraph *depsgraph, struct Object *ob_orig, bool need_pmap, bool need_mask, bool need_colors)
A BVH for high poly meshes.
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
#define BKE_pbvh_vertex_iter_end
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
void BKE_pbvh_node_mark_update_mask(PBVHNode *node)
void BKE_pbvh_node_mark_redraw(PBVHNode *node)
void BKE_pbvh_search_gather(PBVH *pbvh, BKE_pbvh_SearchCallback scb, void *search_data, PBVHNode ***array, int *tot)
MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
struct Depsgraph Depsgraph
Object is a sort of wrapper for general info.
void ED_region_tag_redraw(struct ARegion *region)
void ED_workspace_status_text(struct bContext *C, const char *str)
Read Guarded memory(de)allocation.
Group RGB to Bright Vector Camera CLAMP
const Depsgraph * depsgraph
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
int RNA_int_get(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax)
int SCULPT_vertex_count_get(SculptSession *ss)
int SCULPT_active_vertex_get(SculptSession *ss)
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mouse[2], bool use_sampled_normal)
void SCULPT_floodfill_init(SculptSession *ss, SculptFloodFill *flood)
void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
const float * SCULPT_active_vertex_co_get(SculptSession *ss)
void SCULPT_vertex_random_access_ensure(SculptSession *ss)
void SCULPT_flush_update_done(const bContext *C, Object *ob, SculptUpdateType update_flags)
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
void SCULPT_vertex_normal_get(SculptSession *ss, int index, float no[3])
void SCULPT_floodfill_free(SculptFloodFill *flood)
bool SCULPT_mode_poll(bContext *C)
void SCULPT_active_vertex_normal_get(SculptSession *ss, float normal[3])
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
int SCULPT_face_set_next_available_get(SculptSession *ss)
char SCULPT_mesh_symmetry_xyz_get(Object *object)
bool SCULPT_check_vertex_pivot_symmetry(const float vco[3], const float pco[3], const char symm)
void SCULPT_floodfill_add_active(Sculpt *sd, Object *ob, SculptSession *ss, SculptFloodFill *flood, float radius)
void SCULPT_floodfill_execute(SculptSession *ss, SculptFloodFill *flood, bool(*func)(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata), void *userdata)
void SCULPT_mask_filter_smooth_apply(Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, const int smooth_iterations)
void SCULPT_filter_cache_free(SculptSession *ss)
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
#define SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN(ss, v_index, neighbor_iterator)
#define SCULPT_VERTEX_NEIGHBORS_ITER_END(neighbor_iterator)
void SCULPT_undo_push_end(void)
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
static int sculpt_mask_expand_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool mask_expand_floodfill_cb(SculptSession *ss, int from_v, int to_v, bool is_duplicate, void *userdata)
struct MaskExpandFloodFillData MaskExpandFloodFillData
static int sculpt_mask_expand_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void sculpt_expand_task_cb(void *__restrict userdata, const int i, const TaskParallelTLS *__restrict UNUSED(tls))
static void sculpt_mask_expand_cancel(bContext *C, wmOperator *op)
void SCULPT_OT_mask_expand(wmOperatorType *ot)
float mask_expand_initial_co[3]
int mask_update_current_it
struct SculptSession * sculpt
struct FilterCache * filter_cache
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
void(* cancel)(struct bContext *, struct wmOperator *)
__forceinline const avxi abs(const avxi &a)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)