Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/sculpt_paint/sculpt_face_set.c
| Show First 20 Lines • Show All 998 Lines • ▼ Show 20 Lines | static EnumPropertyItem prop_sculpt_face_sets_edit_types[] = { | ||||
| "Shrink Face Set", | "Shrink Face Set", | ||||
| "Shrinks the Face Sets boundary by one face based on mesh topology", | "Shrinks the Face Sets boundary by one face based on mesh topology", | ||||
| }, | }, | ||||
| {0, NULL, 0, NULL, NULL}, | {0, NULL, 0, NULL, NULL}, | ||||
| }; | }; | ||||
| static void sculpt_face_set_grow(Object *ob, | static void sculpt_face_set_grow(Object *ob, | ||||
| SculptSession *ss, | SculptSession *ss, | ||||
| int *prev_face_sets, | int *prev_face_sets, | ||||
sergey: Seems this should be `const`. Would help to easier understand whats going on. | |||||
| const int active_face_set_id) | const int active_face_set_id, | ||||
| const bool modify_hidden) | |||||
| { | { | ||||
| Mesh *mesh = BKE_mesh_from_object(ob); | Mesh *mesh = BKE_mesh_from_object(ob); | ||||
| for (int p = 0; p < mesh->totpoly; p++) { | for (int p = 0; p < mesh->totpoly; p++) { | ||||
| const MPoly *c_poly = &mesh->mpoly[p]; | const MPoly *c_poly = &mesh->mpoly[p]; | ||||
| for (int l = 0; l < c_poly->totloop; l++) { | for (int l = 0; l < c_poly->totloop; l++) { | ||||
| const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; | const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; | ||||
| const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; | const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; | ||||
| for (int i = 0; i < vert_map->count; i++) { | for (int i = 0; i < vert_map->count; i++) { | ||||
| const int neighbor_face_index = vert_map->indices[i]; | const int neighbor_face_index = vert_map->indices[i]; | ||||
| if (neighbor_face_index != p) { | if (neighbor_face_index != p) { | ||||
sergeyUnsubmitted Done Inline ActionsUse continue, sergey: Use `continue`, | |||||
| if (!modify_hidden && prev_face_sets[p] <= 0) { | |||||
| continue; | |||||
| } | |||||
sergeyUnsubmitted Done Inline ActionsSeems this is unnecessarily is in the inner loop and can be moved to the outer-most loop. sergey: Seems this is unnecessarily is in the inner loop and can be moved to the outer-most loop. | |||||
| if (abs(prev_face_sets[neighbor_face_index]) == active_face_set_id) { | if (abs(prev_face_sets[neighbor_face_index]) == active_face_set_id) { | ||||
| ss->face_sets[p] = active_face_set_id; | ss->face_sets[p] = active_face_set_id; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void sculpt_face_set_shrink(Object *ob, | static void sculpt_face_set_shrink(Object *ob, | ||||
| SculptSession *ss, | SculptSession *ss, | ||||
| int *prev_face_sets, | int *prev_face_sets, | ||||
| const int active_face_set_id) | const int active_face_set_id, | ||||
| const bool modify_hidden) | |||||
| { | { | ||||
| Mesh *mesh = BKE_mesh_from_object(ob); | Mesh *mesh = BKE_mesh_from_object(ob); | ||||
| for (int p = 0; p < mesh->totpoly; p++) { | for (int p = 0; p < mesh->totpoly; p++) { | ||||
| if (abs(prev_face_sets[p]) == active_face_set_id) { | if (abs(prev_face_sets[p]) == active_face_set_id) { | ||||
| const MPoly *c_poly = &mesh->mpoly[p]; | const MPoly *c_poly = &mesh->mpoly[p]; | ||||
| for (int l = 0; l < c_poly->totloop; l++) { | for (int l = 0; l < c_poly->totloop; l++) { | ||||
| const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; | const MLoop *c_loop = &mesh->mloop[c_poly->loopstart + l]; | ||||
| const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; | const MeshElemMap *vert_map = &ss->pmap[c_loop->v]; | ||||
| for (int i = 0; i < vert_map->count; i++) { | for (int i = 0; i < vert_map->count; i++) { | ||||
| const int neighbor_face_index = vert_map->indices[i]; | const int neighbor_face_index = vert_map->indices[i]; | ||||
| if (neighbor_face_index != p) { | if (neighbor_face_index != p) { | ||||
| if (!modify_hidden && prev_face_sets[p] <= 0) { | |||||
| continue; | |||||
| } | |||||
sergeyUnsubmitted Done Inline ActionsSame as above. sergey: Same as above. | |||||
| if (abs(prev_face_sets[neighbor_face_index]) != active_face_set_id) { | if (abs(prev_face_sets[neighbor_face_index]) != active_face_set_id) { | ||||
| ss->face_sets[p] = prev_face_sets[neighbor_face_index]; | ss->face_sets[p] = prev_face_sets[neighbor_face_index]; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void sculpt_face_set_apply_edit(Object *ob, const int active_face_set_id, const int mode) | static void sculpt_face_set_apply_edit(Object *ob, | ||||
| const int active_face_set_id, | |||||
| const int mode, | |||||
| const bool modify_hidden) | |||||
| { | { | ||||
| SculptSession *ss = ob->sculpt; | SculptSession *ss = ob->sculpt; | ||||
| int *prev_face_sets = MEM_dupallocN(ss->face_sets); | int *prev_face_sets = MEM_dupallocN(ss->face_sets); | ||||
| switch (mode) { | switch (mode) { | ||||
| case SCULPT_FACE_SET_EDIT_GROW: | case SCULPT_FACE_SET_EDIT_GROW: | ||||
| sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id); | sculpt_face_set_grow(ob, ss, prev_face_sets, active_face_set_id, modify_hidden); | ||||
| break; | break; | ||||
| case SCULPT_FACE_SET_EDIT_SHRINK: | case SCULPT_FACE_SET_EDIT_SHRINK: | ||||
| sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id); | sculpt_face_set_shrink(ob, ss, prev_face_sets, active_face_set_id, modify_hidden); | ||||
| break; | break; | ||||
| } | } | ||||
| MEM_SAFE_FREE(prev_face_sets); | MEM_SAFE_FREE(prev_face_sets); | ||||
| } | } | ||||
| static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| Show All 19 Lines | static int sculpt_face_set_edit_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| if (!nodes) { | if (!nodes) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| SCULPT_undo_push_begin("face set edit"); | SCULPT_undo_push_begin("face set edit"); | ||||
| SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS); | SCULPT_undo_push_node(ob, nodes[0], SCULPT_UNDO_FACE_SETS); | ||||
| const int active_face_set = SCULPT_active_face_set_get(ss); | const int active_face_set = SCULPT_active_face_set_get(ss); | ||||
| const bool modify_hidden = RNA_boolean_get(op->ptr, "modify_hidden"); | |||||
| sculpt_face_set_apply_edit(ob, abs(active_face_set), mode); | sculpt_face_set_apply_edit(ob, abs(active_face_set), mode, modify_hidden); | ||||
| SCULPT_undo_push_end(); | SCULPT_undo_push_end(); | ||||
| /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ | /* Sync face sets visibility and vertex visibility as now all Face Sets are visible. */ | ||||
| SCULPT_visibility_sync_all_face_sets_to_vertices(ss); | SCULPT_visibility_sync_all_face_sets_to_vertices(ss); | ||||
| for (int i = 0; i < totnode; i++) { | for (int i = 0; i < totnode; i++) { | ||||
| BKE_pbvh_node_mark_update_visibility(nodes[i]); | BKE_pbvh_node_mark_update_visibility(nodes[i]); | ||||
| Show All 28 Lines | void SCULPT_OT_face_sets_edit(struct wmOperatorType *ot) | ||||
| /* Api callbacks. */ | /* Api callbacks. */ | ||||
| ot->invoke = sculpt_face_set_edit_invoke; | ot->invoke = sculpt_face_set_edit_invoke; | ||||
| ot->poll = SCULPT_mode_poll; | ot->poll = SCULPT_mode_poll; | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| RNA_def_enum( | RNA_def_enum( | ||||
| ot->srna, "mode", prop_sculpt_face_sets_edit_types, SCULPT_FACE_SET_EDIT_GROW, "Mode", ""); | ot->srna, "mode", prop_sculpt_face_sets_edit_types, SCULPT_FACE_SET_EDIT_GROW, "Mode", ""); | ||||
| ot->prop = RNA_def_boolean(ot->srna, | |||||
| "modify_hidden", | |||||
| true, | |||||
| "Modify Hidden", | |||||
| "Apply the edit operation to hidden Face Sets"); | |||||
| } | } | ||||
Seems this should be const. Would help to easier understand whats going on.