83 int next_face_set_id = 0;
85 next_face_set_id =
max_ii(next_face_set_id,
abs(face_sets[i]));
89 return next_face_set_id;
101 face_sets[i] = new_id;
136 ss, &test,
data->brush->falloff_shape);
147 float poly_center[3];
150 if (!sculpt_brush_test_sq_fn(&test, poly_center)) {
171 if (!sculpt_brush_test_sq_fn(&test, vd.
co)) {
206 ss, &test,
data->brush->falloff_shape);
210 if (relax_face_sets) {
217 if (!sculpt_brush_test_sq_fn(&test, vd.
co)) {
261 for (
int i = 0; i < 4; i++) {
284 "Face Set from Masked",
285 "Create a new Face Set from the masked faces",
291 "Face Set from Visible",
292 "Create a new Face Set from the visible vertices",
298 "Face Set Full Mesh",
299 "Create an unique Face Set with all faces in the sculpt",
305 "Face Set from Edit Mode Selection",
306 "Create an Face Set corresponding to the Edit Mode face selection",
327 float threshold = 0.5f;
344 for (
int i = 0; i < tot_vert; i++) {
356 bool all_visible =
true;
357 for (
int i = 0; i < tot_vert; i++) {
371 for (
int i = 0; i < tot_vert; i++) {
379 for (
int i = 0; i < tot_vert; i++) {
390 .use_toolflags =
true,
396 .calc_face_normal =
true,
409 for (
int i = 0; i < totnode; i++) {
425 ot->
name =
"Create Face Set";
426 ot->
idname =
"SCULPT_OT_face_sets_create";
456 "Face Sets from Loose Parts",
457 "Create a Face Set per loose part in the mesh",
463 "Face Sets from Material Slots",
464 "Create a Face Set per Material Slot",
470 "Face Sets from Mesh Normals",
471 "Create Face Sets for Faces that have similar normal",
477 "Face Sets from UV Seams",
478 "Create Face Sets using UV Seams as boundaries",
484 "Face Sets from Edge Creases",
485 "Create Face Sets using Edge Creases as boundaries",
491 "Face Sets from Bevel Weight",
492 "Create Face Sets using Bevel Weights as boundaries",
498 "Face Sets from Sharp Edges",
499 "Create Face Sets using Sharp Edges as boundaries",
505 "Face Sets from Face Maps",
506 "Create a Face Set per Face Map",
510 "FACE_SET_BOUNDARIES",
512 "Face Sets from Face Set Boundaries",
513 "Create a Face Set per isolated Face Set",
526 const float UNUSED(threshold))
541 const float UNUSED(threshold))
562 const float UNUSED(threshold))
577 const float threshold)
585 .use_toolflags =
true,
591 .calc_face_normal =
true,
602 int next_face_set = 1;
604 for (
int i = 0; i < totfaces; i++) {
611 face_sets[i] = next_face_set;
627 if (f_neighbor == f) {
634 if (!test(
bm, f, ed, f_neighbor, threshold)) {
638 face_sets[neighbor_face_index] = next_face_set;
663 .use_toolflags =
true,
669 .calc_face_normal =
true,
681 if (cd_fmaps_offset != -1) {
757 for (
int i = 0; i < totnode; i++) {
777 ot->
name =
"Init Face Sets";
778 ot->
idname =
"SCULPT_OT_face_sets_init";
796 "Minimum value to consider a certain attribute a boundary when creating the Face Sets",
815 "Hide all Face Sets except for the active one",
821 "Show Active Face Set",
822 "Show Active Face Set",
828 "Hide Active Face Sets",
829 "Hide Active Face Sets",
835 "Invert Face Set Visibility",
836 "Invert Face Set Visibility",
842 "Show All Face Sets",
843 "Show All Face Sets",
881 bool hidden_vertex =
false;
886 for (
int i = 0; i < tot_vert; i++) {
888 hidden_vertex =
true;
894 for (
int i = 0; i < ss->
totfaces; i++) {
896 hidden_vertex =
true;
944 for (
int i = 0; i < totnode; i++) {
968 mouse[0] =
event->mval[0];
969 mouse[1] =
event->mval[1];
979 ot->
name =
"Face Sets Visibility";
980 ot->
idname =
"SCULPT_OT_face_set_change_visibility";
981 ot->
description =
"Change the visibility of the Face Sets of the sculpt";
1024 for (
int i = 0; i < totnode; i++) {
1038 ot->
name =
"Randomize Face Sets Colors";
1039 ot->
idname =
"SCULPT_OT_face_sets_randomize_colors";
1040 ot->
description =
"Generates a new set of random colors to render the Face Sets in the viewport";
1063 "Grows the Face Sets boundary by one face based on mesh topology",
1070 "Shrinks the Face Sets boundary by one face based on mesh topology",
1077 "Deletes the faces that are assigned to the Face Set",
1084 "Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
1092 "Creates a smooth as possible geometry patch from the Face Set minimizing changes in "
1100 const int *prev_face_sets,
1101 const int active_face_set_id,
1102 const bool modify_hidden)
1106 if (!modify_hidden && prev_face_sets[p] <= 0) {
1113 for (
int i = 0; i < vert_map->
count; i++) {
1114 const int neighbor_face_index = vert_map->
indices[i];
1115 if (neighbor_face_index == p) {
1118 if (
abs(prev_face_sets[neighbor_face_index]) == active_face_set_id) {
1128 const int *prev_face_sets,
1129 const int active_face_set_id,
1130 const bool modify_hidden)
1134 if (!modify_hidden && prev_face_sets[p] <= 0) {
1137 if (
abs(prev_face_sets[p]) == active_face_set_id) {
1142 for (
int i = 0; i < vert_map->
count; i++) {
1143 const int neighbor_face_index = vert_map->
indices[i];
1144 if (neighbor_face_index == p) {
1147 if (
abs(prev_face_sets[neighbor_face_index]) != active_face_set_id) {
1148 ss->
face_sets[p] = prev_face_sets[neighbor_face_index];
1160 if (check_visible_only) {
1161 for (
int f = 0; f < ss->
totfaces; f++) {
1162 if (face_sets[f] > 0) {
1163 first_face_set = face_sets[f];
1169 first_face_set =
abs(face_sets[0]);
1176 for (
int f = 0; f < ss->
totfaces; f++) {
1177 const int face_set_id = check_visible_only ? face_sets[f] :
abs(face_sets[f]);
1178 if (face_set_id != first_face_set) {
1187 const int active_face_set_id,
1188 const bool modify_hidden)
1195 .use_toolflags =
true,
1201 .calc_face_normal =
true,
1211 const int face_set_id = modify_hidden ?
abs(ss->
face_sets[face_index]) :
1222 .calc_object_remap = false,
1229 const int active_face_set_id,
1230 const int fair_order)
1236 bool *fair_vertices =
MEM_malloc_arrayN(
sizeof(
bool), totvert,
"fair vertices");
1240 for (
int i = 0; i < totvert; i++) {
1252 const int active_face_set_id,
1254 const bool modify_hidden)
1285 const bool modify_hidden)
1321 const int active_face_set,
1323 const bool modify_hidden)
1341 for (
int i = 0; i < totnode; i++) {
1353 const int active_face_set,
1355 const bool modify_hidden)
1375 const int active_face_set,
1385 for (
int i = 0; i < totnode; i++) {
1418 const float mouse[2] = {
event->mval[0],
event->mval[1]};
1447 ot->
name =
"Edit Face Set";
1448 ot->
idname =
"SCULPT_OT_face_set_edit";
1463 "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)
void BKE_mesh_prefair_and_fair_vertices(struct Mesh *mesh, struct MVert *deform_mverts, bool *affect_vertices, const eMeshFairingDepth depth)
@ MESH_FAIRING_DEPTH_POSITION
@ MESH_FAIRING_DEPTH_TANGENCY
@ 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 need_colors)
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_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_TEST(_bitmap, _index)
#define BLI_BITMAP_ENABLE(_bitmap, _index)
#define BLI_BITMAP_NEW(_tot, _alloc_string)
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
GSQueue * BLI_gsqueue_new(const size_t elem_size)
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(const int start, const 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)
BMesh Make Mesh.
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)
Mesh -> BMesh.
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
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_dupallocN)(const void *vmemh)
ThreadQueue * queue
all scheduled work for the cpu
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 mouse[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)
void SCULPT_relax_vertex(SculptSession *ss, PBVHVertexIter *vd, float factor, bool filter_boundary_face_sets, float *r_final_pos)
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)
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_brush_strength_factor(SculptSession *ss, const Brush *br, const float brush_point[3], const float len, const short vno[3], const float fno[3], const float mask, const int vertex_index, const int thread_id)
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)
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)
bool(* SculptBrushTestFn)(SculptBrushTest *test, const float co[3])
void SCULPT_undo_push_end(void)
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
CCL_NAMESPACE_BEGIN ccl_device float fade(float t)
__forceinline const avxi abs(const avxi &a)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)