68 int next_face_set_id = 0;
70 next_face_set_id =
max_ii(next_face_set_id,
abs(face_sets[i]));
74 return next_face_set_id;
86 face_sets[i] = new_id;
121 ss, &test,
data->brush->falloff_shape);
132 float poly_center[3];
135 if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
154 if (!sculpt_brush_test_sq_fn(&test, vd.
co)) {
188 ss, &test,
data->brush->falloff_shape);
192 if (relax_face_sets) {
199 if (!sculpt_brush_test_sq_fn(&test, vd.
co)) {
243 for (
int i = 0; i < 4; i++) {
266 "Face Set from Masked",
267 "Create a new Face Set from the masked faces",
273 "Face Set from Visible",
274 "Create a new Face Set from the visible vertices",
280 "Face Set Full Mesh",
281 "Create an unique Face Set with all faces in the sculpt",
287 "Face Set from Edit Mode Selection",
288 "Create an Face Set corresponding to the Edit Mode face selection",
326 for (
int i = 0; i < tot_vert; i++) {
338 bool all_visible =
true;
339 for (
int i = 0; i < tot_vert; i++) {
353 for (
int i = 0; i < tot_vert; i++) {
361 for (
int i = 0; i < tot_vert; i++) {
372 .use_toolflags =
true,
378 .calc_face_normal =
true,
379 .calc_vert_normal =
true,
392 for (
int i = 0; i < totnode; i++) {
408 ot->
name =
"Create Face Set";
409 ot->
idname =
"SCULPT_OT_face_sets_create";
439 "Face Sets from Loose Parts",
440 "Create a Face Set per loose part in the mesh",
446 "Face Sets from Material Slots",
447 "Create a Face Set per Material Slot",
453 "Face Sets from Mesh Normals",
454 "Create Face Sets for Faces that have similar normal",
460 "Face Sets from UV Seams",
461 "Create Face Sets using UV Seams as boundaries",
467 "Face Sets from Edge Creases",
468 "Create Face Sets using Edge Creases as boundaries",
474 "Face Sets from Bevel Weight",
475 "Create Face Sets using Bevel Weights as boundaries",
481 "Face Sets from Sharp Edges",
482 "Create Face Sets using Sharp Edges as boundaries",
488 "Face Sets from Face Maps",
489 "Create a Face Set per Face Map",
493 "FACE_SET_BOUNDARIES",
495 "Face Sets from Face Set Boundaries",
496 "Create a Face Set per isolated Face Set",
568 .use_toolflags =
true,
574 .calc_face_normal =
true,
575 .calc_vert_normal =
true,
586 int next_face_set = 1;
588 for (
int i = 0; i < totfaces; i++) {
595 face_sets[i] = next_face_set;
611 if (f_neighbor == f) {
622 face_sets[neighbor_face_index] = next_face_set;
647 .use_toolflags =
true,
653 .calc_face_normal =
true,
654 .calc_vert_normal =
true,
666 if (cd_fmaps_offset != -1) {
742 for (
int i = 0; i < totnode; i++) {
762 ot->
name =
"Init Face Sets";
763 ot->
idname =
"SCULPT_OT_face_sets_init";
781 "Minimum value to consider a certain attribute a boundary when creating the Face Sets",
800 "Hide all Face Sets except for the active one",
806 "Show Active Face Set",
807 "Show Active Face Set",
813 "Hide Active Face Sets",
814 "Hide Active Face Sets",
820 "Invert Face Set Visibility",
821 "Invert Face Set Visibility",
827 "Show All Face Sets",
828 "Show All Face Sets",
866 bool hidden_vertex =
false;
871 for (
int i = 0; i < tot_vert; i++) {
873 hidden_vertex =
true;
879 for (
int i = 0; i < ss->
totfaces; i++) {
881 hidden_vertex =
true;
929 for (
int i = 0; i < totnode; i++) {
962 ot->
name =
"Face Sets Visibility";
963 ot->
idname =
"SCULPT_OT_face_set_change_visibility";
964 ot->
description =
"Change the visibility of the Face Sets of the sculpt";
1007 for (
int i = 0; i < totnode; i++) {
1021 ot->
name =
"Randomize Face Sets Colors";
1022 ot->
idname =
"SCULPT_OT_face_sets_randomize_colors";
1023 ot->
description =
"Generates a new set of random colors to render the Face Sets in the viewport";
1046 "Grows the Face Sets boundary by one face based on mesh topology",
1053 "Shrinks the Face Sets boundary by one face based on mesh topology",
1060 "Deletes the faces that are assigned to the Face Set",
1067 "Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
1075 "Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
1083 const int *prev_face_sets,
1084 const int active_face_set_id,
1085 const bool modify_hidden)
1089 if (!modify_hidden && prev_face_sets[p] <= 0) {
1096 for (
int i = 0; i < vert_map->
count; i++) {
1097 const int neighbor_face_index = vert_map->
indices[i];
1098 if (neighbor_face_index == p) {
1101 if (
abs(prev_face_sets[neighbor_face_index]) == active_face_set_id) {
1111 const int *prev_face_sets,
1112 const int active_face_set_id,
1113 const bool modify_hidden)
1117 if (!modify_hidden && prev_face_sets[p] <= 0) {
1120 if (
abs(prev_face_sets[p]) == active_face_set_id) {
1125 for (
int i = 0; i < vert_map->
count; i++) {
1126 const int neighbor_face_index = vert_map->
indices[i];
1127 if (neighbor_face_index == p) {
1130 if (
abs(prev_face_sets[neighbor_face_index]) != active_face_set_id) {
1131 ss->
face_sets[p] = prev_face_sets[neighbor_face_index];
1143 if (check_visible_only) {
1144 for (
int f = 0; f < ss->
totfaces; f++) {
1145 if (face_sets[f] > 0) {
1146 first_face_set = face_sets[f];
1152 first_face_set =
abs(face_sets[0]);
1159 for (
int f = 0; f < ss->
totfaces; f++) {
1160 const int face_set_id = check_visible_only ? face_sets[f] :
abs(face_sets[f]);
1161 if (face_set_id != first_face_set) {
1170 const int active_face_set_id,
1171 const bool modify_hidden)
1178 .use_toolflags =
true,
1184 .calc_face_normal =
true,
1185 .calc_vert_normal =
true,
1195 const int face_set_id = modify_hidden ?
abs(ss->
face_sets[face_index]) :
1206 .calc_object_remap = false,
1213 const int active_face_set_id,
1214 const int fair_order)
1220 bool *fair_vertices =
MEM_malloc_arrayN(totvert,
sizeof(
bool),
"fair vertices");
1224 for (
int i = 0; i < totvert; i++) {
1236 const int active_face_set_id,
1238 const bool modify_hidden)
1269 const bool modify_hidden)
1305 const int active_face_set,
1307 const bool modify_hidden)
1325 for (
int i = 0; i < totnode; i++) {
1337 const int active_face_set,
1339 const bool modify_hidden)
1359 const int active_face_set,
1369 for (
int i = 0; i < totnode; i++) {
1431 ot->
name =
"Edit Face Set";
1432 ot->
idname =
"SCULPT_OT_face_set_edit";
1447 "Apply the edit operation to hidden Face Sets");
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
struct Object * CTX_data_active_object(const bContext *C)
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
struct ToolSettings * CTX_data_tool_settings(const bContext *C)
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer(const struct CustomData *data, int type)
int CustomData_get_offset(const struct CustomData *data, int type)
struct Mesh * BKE_mesh_from_object(struct Object *ob)
void BKE_mesh_calc_poly_center(const struct MPoly *mpoly, const struct MLoop *loopstart, const struct MVert *mvarray, float r_cent[3])
void BKE_mesh_batch_cache_dirty_tag(struct Mesh *me, eMeshBatchDirtyMode mode)
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me)
@ MESH_FAIRING_DEPTH_POSITION
@ MESH_FAIRING_DEPTH_TANGENCY
void BKE_mesh_prefair_and_fair_vertices(struct Mesh *mesh, struct MVert *deform_mverts, bool *affect_vertices, eMeshFairingDepth depth)
@ BKE_MESH_BATCH_DIRTY_ALL
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 is_paint_tool)
struct Brush * BKE_paint_brush(struct Paint *paint)
#define SCULPT_FACE_SET_NONE
A BVH for high poly meshes.
void BKE_pbvh_node_mark_update(PBVHNode *node)
#define BKE_pbvh_vertex_iter_begin(pbvh, node, vi, mode)
void BKE_pbvh_node_mark_update_visibility(PBVHNode *node)
PBVHType BKE_pbvh_type(const PBVH *pbvh)
void BKE_pbvh_face_sets_color_set(PBVH *pbvh, int seed, int color_default)
#define BKE_pbvh_vertex_iter_end
void BKE_pbvh_vert_tag_update_normal(PBVH *pbvh, int index)
void BKE_pbvh_parallel_range_settings(struct TaskParallelSettings *settings, bool use_threading, int totnode)
void BKE_pbvh_update_vertex_data(PBVH *pbvh, int flags)
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)
#define BLI_BITMAP_NEW(_num, _alloc_string)
#define BLI_BITMAP_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
void BLI_gsqueue_free(GSQueue *queue)
GSQueue * BLI_gsqueue_new(size_t elem_size)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
bool BLI_gsqueue_is_empty(const GSQueue *queue)
BLI_INLINE float BLI_hash_int_01(unsigned int k)
MINLINE int max_ii(int a, int b)
MINLINE int clamp_i(int value, int min, int max)
void mul_m4_v3(const float M[4][4], float r[3])
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
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
int BLI_task_parallel_thread_id(const TaskParallelTLS *tls)
struct Depsgraph Depsgraph
void DEG_id_tag_update(struct ID *id, int flag)
Object is a sort of wrapper for general info.
void ED_sculpt_undo_geometry_begin(struct Object *ob, const char *name)
void ED_sculpt_undo_geometry_end(struct Object *ob)
Read Guarded memory(de)allocation.
#define BM_ELEM_CD_GET_INT(ele, offset)
void BM_mesh_delete_hflag_context(BMesh *bm, const char hflag, const int type)
#define BM_elem_index_get(ele)
#define BM_elem_flag_set(ele, hflag, val)
#define BM_elem_flag_test(ele, hflag)
float BM_elem_float_data_get(CustomData *cd, void *element, int type)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BM_mesh_free(BMesh *bm)
BMesh Free Mesh.
BMesh * BM_mesh_create(const BMAllocTemplate *allocsize, const struct BMeshCreateParams *params)
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
void BM_mesh_elem_table_init(BMesh *bm, const char htype)
BLI_INLINE BMFace * BM_face_at_index(BMesh *bm, const int index)
#define BMALLOC_TEMPLATE_FROM_ME(...)
void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params)
void BM_mesh_bm_to_me(Main *bmain, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
const Depsgraph * depsgraph
ccl_gpu_kernel_postfix ccl_global float int int int int float threshold
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
thread_local int thread_id
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
float RNA_float_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_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
int SCULPT_vertex_count_get(SculptSession *ss)
void SCULPT_boundary_info_ensure(Object *object)
bool SCULPT_cursor_geometry_info_update(bContext *C, SculptCursorGeometryInfo *out, const float mval[2], bool use_sampled_normal)
void SCULPT_face_set_visibility_set(SculptSession *ss, int face_set, bool visible)
bool SCULPT_vertex_has_face_set(SculptSession *ss, int index, int face_set)
bool SCULPT_vertex_has_unique_face_set(SculptSession *ss, int index)
SculptBrushTestFn SCULPT_brush_test_init_with_falloff_shape(SculptSession *ss, SculptBrushTest *test, char falloff_shape)
void SCULPT_vertex_face_set_set(SculptSession *ss, int index, int face_set)
float SCULPT_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], const float len, const float vno[3], const float fno[3], const float mask, const int vertex_index, const int thread_id)
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)
bool SCULPT_vertex_visible_get(SculptSession *ss, int index)
void SCULPT_face_sets_visibility_all_set(SculptSession *ss, bool visible)
void SCULPT_face_sets_visibility_invert(SculptSession *ss)
void SCULPT_flush_update_step(bContext *C, SculptUpdateType update_flags)
bool SCULPT_vertex_is_boundary(const SculptSession *ss, const int index)
bool SCULPT_mode_poll(bContext *C)
float SCULPT_vertex_mask_get(SculptSession *ss, int index)
int SCULPT_face_set_next_available_get(SculptSession *ss)
void SCULPT_flush_stroke_deform(Sculpt *sd, Object *ob, bool is_proxy_used)
MVert * SCULPT_mesh_deformed_mverts_get(SculptSession *ss)
int SCULPT_active_face_set_get(SculptSession *ss)
void SCULPT_visibility_sync_all_face_sets_to_vertices(Object *ob)
void SCULPT_tag_update_overlays(bContext *C)
void SCULPT_relax_vertex(SculptSession *ss, PBVHVertexIter *vd, float factor, bool filter_boundary_face_sets, float *r_final_pos)
static int sculpt_face_set_create_exec(bContext *C, wmOperator *op)
void SCULPT_OT_face_sets_change_visibility(wmOperatorType *ot)
static void sculpt_face_sets_init_flood_fill(Object *ob, face_sets_flood_fill_test test, const float threshold)
bool(* face_sets_flood_fill_test)(BMesh *bm, BMFace *from_f, BMEdge *from_e, BMFace *to_f, const float threshold)
void SCULPT_OT_face_sets_init(wmOperatorType *ot)
static bool sculpt_face_sets_init_crease_test(BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
int ED_sculpt_face_sets_find_next_available_id(struct Mesh *mesh)
static void sculpt_face_set_edit_modify_geometry(bContext *C, Object *ob, const int active_face_set, const eSculptFaceSetEditMode mode, const bool modify_hidden)
static void do_draw_face_sets_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static void sculpt_face_set_apply_edit(Object *ob, const int active_face_set_id, const int mode, const bool modify_hidden)
int ED_sculpt_face_sets_active_update_and_get(bContext *C, Object *ob, const float mval[2])
static void sculpt_face_set_shrink(Object *ob, SculptSession *ss, const int *prev_face_sets, const int active_face_set_id, const bool modify_hidden)
static void sculpt_face_set_edit_modify_coordinates(bContext *C, Object *ob, const int active_face_set, const eSculptFaceSetEditMode mode)
static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
@ SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT
@ SCULPT_FACE_SETS_FROM_LOOSE_PARTS
@ SCULPT_FACE_SETS_FROM_CREASES
@ SCULPT_FACE_SETS_FROM_SHARP_EDGES
@ SCULPT_FACE_SETS_FROM_MATERIALS
@ SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES
@ SCULPT_FACE_SETS_FROM_FACE_MAPS
@ SCULPT_FACE_SETS_FROM_NORMALS
@ SCULPT_FACE_SETS_FROM_UV_SEAMS
eSculptFaceGroupsCreateModes
@ SCULPT_FACE_SET_VISIBLE
@ SCULPT_FACE_SET_SELECTION
static void sculpt_face_set_delete_geometry(Object *ob, SculptSession *ss, const int active_face_set_id, const bool modify_hidden)
eSculptFaceGroupVisibilityModes
@ SCULPT_FACE_SET_VISIBILITY_SHOW_ACTIVE
@ SCULPT_FACE_SET_VISIBILITY_INVERT
@ SCULPT_FACE_SET_VISIBILITY_HIDE_ACTIVE
@ SCULPT_FACE_SET_VISIBILITY_TOGGLE
@ SCULPT_FACE_SET_VISIBILITY_SHOW_ALL
void ED_sculpt_face_sets_initialize_none_to_id(struct Mesh *mesh, const int new_id)
static void sculpt_face_set_grow(Object *ob, SculptSession *ss, const int *prev_face_sets, const int active_face_set_id, const bool modify_hidden)
static int sculpt_face_sets_change_visibility_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static EnumPropertyItem prop_sculpt_face_sets_change_visibility_types[]
static void sculpt_face_set_edit_fair_face_set(Object *ob, const int active_face_set_id, const int fair_order)
void SCULPT_OT_face_sets_create(wmOperatorType *ot)
static bool sculpt_face_sets_init_sharp_edges_test(BMesh *UNUSED(bm), BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float UNUSED(threshold))
static void do_relax_face_sets_brush_task_cb_ex(void *__restrict userdata, const int n, const TaskParallelTLS *__restrict tls)
static EnumPropertyItem prop_sculpt_face_sets_init_types[]
@ SCULPT_FACE_SET_EDIT_SHRINK
@ SCULPT_FACE_SET_EDIT_DELETE_GEOMETRY
@ SCULPT_FACE_SET_EDIT_FAIR_TANGENCY
@ SCULPT_FACE_SET_EDIT_GROW
@ SCULPT_FACE_SET_EDIT_FAIR_POSITIONS
static bool sculpt_face_sets_init_normals_test(BMesh *UNUSED(bm), BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float threshold)
static bool check_single_face_set(SculptSession *ss, int *face_sets, const bool check_visible_only)
static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot)
static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss, const eSculptFaceSetEditMode mode, const bool modify_hidden)
static bool sculpt_face_sets_init_loose_parts_test(BMesh *UNUSED(bm), BMFace *UNUSED(from_f), BMEdge *UNUSED(from_e), BMFace *UNUSED(to_f), const float UNUSED(threshold))
static void face_set_edit_do_post_visibility_updates(Object *ob, PBVHNode **nodes, int totnode)
void SCULPT_OT_face_sets_randomize_colors(wmOperatorType *ot)
static bool sculpt_face_sets_init_face_set_boundary_test(BMesh *bm, BMFace *from_f, BMEdge *UNUSED(from_e), BMFace *to_f, const float UNUSED(threshold))
static EnumPropertyItem prop_sculpt_face_set_create_types[]
static void sculpt_face_sets_init_loop(Object *ob, const int mode)
static void sculpt_face_set_edit_modify_face_sets(Object *ob, const int active_face_set, const eSculptFaceSetEditMode mode, const bool modify_hidden)
static int sculpt_face_sets_randomize_colors_exec(bContext *C, wmOperator *UNUSED(op))
static bool sculpt_face_sets_init_uv_seams_test(BMesh *UNUSED(bm), BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float UNUSED(threshold))
void SCULPT_do_draw_face_sets_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
static int sculpt_face_sets_change_visibility_exec(bContext *C, wmOperator *op)
static bool sculpt_face_sets_init_bevel_weight_test(BMesh *bm, BMFace *UNUSED(from_f), BMEdge *from_e, BMFace *UNUSED(to_f), const float threshold)
static EnumPropertyItem prop_sculpt_face_sets_edit_types[]
void SCULPT_undo_push_begin(struct Object *ob, const char *name)
void SCULPT_undo_push_end(struct Object *ob)
bool(* SculptBrushTestFn)(SculptBrushTest *test, const float co[3])
SculptUndoNode * SCULPT_undo_push_node(Object *ob, PBVHNode *node, SculptUndoType type)
struct CurveMapping * curve
int face_sets_color_default
struct SculptSession * sculpt
struct KeyBlock * shapekey_active
struct MeshElemMap * pmap
struct StrokeCache * cache
bool deform_modifiers_active
float average_stroke_accum[3]
int average_stroke_counter
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
void WM_event_add_notifier(const bContext *C, uint type, void *reference)