From 11309a19e2cdeaeed3a2462b1bcb4138084cd7bf Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Tue, 22 May 2012 15:29:44 +0000 Subject: Add skin vertex operators. * Add operator to mark selected vertices as skin roots. * Add operator to mark/clear selected vertices as loose. * Add operator to equalize skin radii. Skin modifier documentation: http://wiki.blender.org/index.php/User:Nicholasbishop/SkinModifier --- source/blender/editors/object/object_intern.h | 3 + source/blender/editors/object/object_modifier.c | 175 ++++++++++++++++++++++++ source/blender/editors/object/object_ops.c | 3 + 3 files changed, 181 insertions(+) (limited to 'source/blender/editors') diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index e834c93b0d8..2bd53a3c0a7 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -160,6 +160,9 @@ void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot); void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot); void OBJECT_OT_explode_refresh(struct wmOperatorType *ot); void OBJECT_OT_ocean_bake(struct wmOperatorType *ot); +void OBJECT_OT_skin_root_mark(struct wmOperatorType *ot); +void OBJECT_OT_skin_loose_mark_clear(struct wmOperatorType *ot); +void OBJECT_OT_skin_radii_equalize(struct wmOperatorType *ot); /* object_constraint.c */ void OBJECT_OT_constraint_add(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 60a11f59f0e..e98ff4a6984 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1367,6 +1367,181 @@ static void modifier_skin_customdata_ensure(Object *ob) } } +static int skin_edit_poll(bContext *C) +{ + return (CTX_data_edit_object(C) && + edit_modifier_poll_generic(C, &RNA_SkinModifier, (1<vdata, + v2->head.data, + CD_MVERT_SKIN); + + /* clear vertex root flag and add to visited set */ + vs->flag &= ~MVERT_SKIN_ROOT; + BLI_ghash_insert(visited, v2, v2); + + skin_root_clear(bm, v2, visited); + } + } +} + +static int skin_root_mark_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob= CTX_data_edit_object(C); + Mesh *me = ob->data; + BMesh *bm = me->edit_btmesh->bm; + BMVert *bm_vert; + BMIter bm_iter; + GHash *visited; + + visited = BLI_ghash_ptr_new("skin_root_mark_exec visited"); + + modifier_skin_customdata_ensure(ob); + + BM_ITER_MESH(bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { + if(!BLI_ghash_lookup(visited, bm_vert) && + bm_vert->head.hflag & BM_ELEM_SELECT) + { + MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, + bm_vert->head.data, + CD_MVERT_SKIN); + + /* mark vertex as root and add to visited set */ + vs->flag |= MVERT_SKIN_ROOT; + BLI_ghash_insert(visited, bm_vert, bm_vert); + + /* clear root flag from all connected vertices (recursively) */ + skin_root_clear(bm, bm_vert, visited); + } + } + + BLI_ghash_free(visited, NULL, NULL); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_skin_root_mark(wmOperatorType *ot) +{ + ot->name = "Skin Root Mark"; + ot->description = "Mark selected vertices as roots"; + ot->idname = "OBJECT_OT_skin_root_mark"; + + ot->poll = skin_edit_poll; + ot->exec = skin_root_mark_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + +typedef enum { + SKIN_LOOSE_MARK, + SKIN_LOOSE_CLEAR, +} SkinLooseAction; + +static int skin_loose_mark_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_edit_object(C); + Mesh *me = ob->data; + BMesh *bm = me->edit_btmesh->bm; + BMVert *bm_vert; + BMIter bm_iter; + SkinLooseAction action = RNA_enum_get(op->ptr, "action"); + + BM_ITER_MESH(bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { + if (bm_vert->head.hflag & BM_ELEM_SELECT) { + MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, + bm_vert->head.data, + CD_MVERT_SKIN); + + + switch (action) { + case SKIN_LOOSE_MARK: + vs->flag |= MVERT_SKIN_LOOSE; + break; + case SKIN_LOOSE_CLEAR: + vs->flag &= ~MVERT_SKIN_LOOSE; + break; + } + } + } + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_skin_loose_mark_clear(wmOperatorType *ot) +{ + static EnumPropertyItem action_items[] = { + {SKIN_LOOSE_MARK, "MARK", 0, "Mark", "Mark selected vertices as loose"}, + {SKIN_LOOSE_CLEAR, "CLEAR", 0, "Clear", "Set selected vertices as not loose"}, + {0, NULL, 0, NULL, NULL}}; + + ot->name = "Skin Mark/Clear Loose"; + ot->description = "Mark/clear selected vertices as loose"; + ot->idname = "OBJECT_OT_skin_loose_mark_clear"; + + ot->poll = skin_edit_poll; + ot->exec = skin_loose_mark_clear_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_enum(ot->srna, "action", action_items, SKIN_LOOSE_MARK, "Action", NULL); +} + +static int skin_radii_equalize_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob= CTX_data_edit_object(C); + Mesh *me = ob->data; + BMesh *bm = me->edit_btmesh->bm; + BMVert *bm_vert; + BMIter bm_iter; + + BM_ITER_MESH(bm_vert, &bm_iter, bm, BM_VERTS_OF_MESH) { + if (bm_vert->head.hflag & BM_ELEM_SELECT) { + MVertSkin *vs = CustomData_bmesh_get(&bm->vdata, + bm_vert->head.data, + CD_MVERT_SKIN); + float avg = (vs->radius[0] + vs->radius[1]) * 0.5f; + + vs->radius[0] = vs->radius[1] = avg; + } + } + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_skin_radii_equalize(wmOperatorType *ot) +{ + ot->name = "Skin Radii Equalize"; + ot->description = "Make skin radii of selected vertices equal"; + ot->idname = "OBJECT_OT_skin_radii_equalize"; + + ot->poll = skin_edit_poll; + ot->exec = skin_radii_equalize_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; +} + /************************ mdef bind operator *********************/ diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index d618d17f797..1f09d8fd5e4 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -139,6 +139,9 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_multires_base_apply); WM_operatortype_append(OBJECT_OT_multires_external_save); WM_operatortype_append(OBJECT_OT_multires_external_pack); + WM_operatortype_append(OBJECT_OT_skin_root_mark); + WM_operatortype_append(OBJECT_OT_skin_loose_mark_clear); + WM_operatortype_append(OBJECT_OT_skin_radii_equalize); WM_operatortype_append(OBJECT_OT_meshdeform_bind); WM_operatortype_append(OBJECT_OT_explode_refresh); WM_operatortype_append(OBJECT_OT_ocean_bake); -- cgit v1.2.3