Add vertex skin radii scaling as a transform operator.

Add a new transform operator, "Skin Resize", which scales the X and Y
axes of the radius field in MVertSkin. It's bound to CTRL+AKEY.

Skin modifier documentation:
http://wiki.blender.org/index.php/User:Nicholasbishop/SkinModifier
This commit is contained in:
Nicholas Bishop 2012-05-22 15:30:14 +00:00
parent ec29e2620e
commit 6c67fc83ea
5 changed files with 154 additions and 3 deletions

@ -58,6 +58,7 @@ enum {
TFM_TRANSLATION,
TFM_ROTATION,
TFM_RESIZE,
TFM_SKIN_RESIZE,
TFM_TOSPHERE,
TFM_SHEAR,
TFM_WARP,

@ -1633,6 +1633,9 @@ int initTransform(bContext *C, TransInfo *t, wmOperator *op, wmEvent *event, int
case TFM_RESIZE:
initResize(t);
break;
case TFM_SKIN_RESIZE:
initSkinResize(t);
break;
case TFM_TOSPHERE:
initToSphere(t);
break;
@ -2701,7 +2704,7 @@ static void ElementResize(TransInfo *t, TransData *td, float mat[3][3])
constraintSizeLim(t, td);
}
/* For individual element center, Editmode need to use iloc */
if (t->flag & T_POINTS)
sub_v3_v3v3(vec, td->iloc, center);
@ -2799,6 +2802,96 @@ int Resize(TransInfo *t, const int mval[2])
return 1;
}
/* ************************** SKIN *************************** */
void initSkinResize(TransInfo *t)
{
t->mode = TFM_SKIN_RESIZE;
t->transform = SkinResize;
initMouseInputMode(t, &t->mouse, INPUT_SPRING_FLIP);
t->flag |= T_NULL_ONE;
t->num.flag |= NUM_NULL_ONE;
t->num.flag |= NUM_AFFECT_ALL;
if (!t->obedit) {
t->flag |= T_NO_ZERO;
t->num.flag |= NUM_NO_ZERO;
}
t->idx_max = 2;
t->num.idx_max = 2;
t->snap[0] = 0.0f;
t->snap[1] = 0.1f;
t->snap[2] = t->snap[1] * 0.1f;
t->num.increment = t->snap[1];
}
int SkinResize(TransInfo *t, const int UNUSED(mval[2]))
{
TransData *td;
float size[3], mat[3][3];
float ratio;
int i;
char str[200];
ratio = t->values[0];
size[0] = size[1] = size[2] = ratio;
snapGrid(t, size);
if (hasNumInput(&t->num)) {
applyNumInput(&t->num, size);
constraintNumInput(t, size);
}
applySnapping(t, size);
if (t->flag & T_AUTOVALUES) {
copy_v3_v3(size, t->auto_values);
}
copy_v3_v3(t->values, size);
size_to_mat3(mat, size);
headerResize(t, size, str);
for (i = 0, td = t->data; i < t->total; i++, td++) {
float tmat[3][3], smat[3][3];
float fsize[3];
if (td->flag & TD_NOACTION)
break;
if (td->flag & TD_SKIP)
continue;
if (t->flag & T_EDIT) {
mul_m3_m3m3(smat, mat, td->mtx);
mul_m3_m3m3(tmat, td->smtx, smat);
}
else {
copy_m3_m3(tmat, mat);
}
if (t->con.applySize) {
t->con.applySize(t, NULL, tmat);
}
mat3_to_size(fsize, tmat);
td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
}
recalcData(t);
ED_area_headerprint(t->sa, str);
return 1;
}
/* ************************** TOSPHERE *************************** */
void initToSphere(TransInfo *t)

@ -464,6 +464,9 @@ int Shear(TransInfo *t, const int mval[2]);
void initResize(TransInfo *t);
int Resize(TransInfo *t, const int mval[2]);
void initSkinResize(TransInfo *t);
int SkinResize(TransInfo *t, const int mval[2]);
void initTranslation(TransInfo *t);
int Translation(TransInfo *t, const int mval[2]);

@ -1885,7 +1885,8 @@ static void get_edge_center(float cent_r[3], BMVert *eve)
}
/* way to overwrite what data is edited with transform */
static void VertsToTransData(TransInfo *t, TransData *td, BMEditMesh *em, BMVert *eve, float *bweight)
static void VertsToTransData(TransInfo *t, TransData *td, TransDataExtension *tx,
BMEditMesh *em, BMVert *eve, float *bweight)
{
td->flag = 0;
//if (key)
@ -1919,12 +1920,23 @@ static void VertsToTransData(TransInfo *t, TransData *td, BMEditMesh *em, BMVert
td->val = bweight;
td->ival = bweight ? *(bweight) : 1.0f;
}
else if(t->mode == TFM_SKIN_RESIZE) {
MVertSkin *vs = CustomData_bmesh_get(&em->bm->vdata,
eve->head.data,
CD_MVERT_SKIN);
/* skin node size */
td->ext = tx;
copy_v3_v3(tx->isize, vs->radius);
tx->size = vs->radius;
td->val = vs->radius;
}
}
static void createTransEditVerts(bContext *C, TransInfo *t)
{
ToolSettings *ts = CTX_data_tool_settings(C);
TransData *tob = NULL;
TransDataExtension *tx = NULL;
BMEditMesh *em = BMEdit_FromObject(t->obedit);
BMesh *bm = em->bm;
BMVert *eve;
@ -2030,6 +2042,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
else t->total = countsel;
tob= t->data= MEM_callocN(t->total*sizeof(TransData), "TransObData(Mesh EditMode)");
if (t->mode == TFM_SKIN_RESIZE) {
tx = t->ext = MEM_callocN(t->total * sizeof(TransDataExtension),
"TransObData ext");
}
copy_m3_m4(mtx, t->obedit->obmat);
invert_m3_m3(smtx, mtx);
@ -2081,7 +2097,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
if (propmode || selstate[a]) {
float *bweight = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_BWEIGHT);
VertsToTransData(t, tob, em, eve, bweight);
VertsToTransData(t, tob, tx, em, eve, bweight);
if (tx)
tx++;
/* selected */
if (selstate[a]) tob->flag |= TD_SELECTED;

@ -27,6 +27,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "RNA_access.h"
@ -63,6 +64,7 @@ static char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
static char OP_ROTATION[] = "TRANSFORM_OT_rotate";
static char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere";
static char OP_RESIZE[] = "TRANSFORM_OT_resize";
static char OP_SKIN_RESIZE[] = "TRANSFORM_OT_skin_resize";
static char OP_SHEAR[] = "TRANSFORM_OT_shear";
static char OP_WARP[] = "TRANSFORM_OT_warp";
static char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten";
@ -79,6 +81,7 @@ static void TRANSFORM_OT_translate(struct wmOperatorType *ot);
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot);
static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot);
static void TRANSFORM_OT_resize(struct wmOperatorType *ot);
static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot);
static void TRANSFORM_OT_shear(struct wmOperatorType *ot);
static void TRANSFORM_OT_warp(struct wmOperatorType *ot);
static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot);
@ -97,6 +100,7 @@ static TransformModeItem transform_modes[] =
{OP_ROTATION, TFM_ROTATION, TRANSFORM_OT_rotate},
{OP_TOSPHERE, TFM_TOSPHERE, TRANSFORM_OT_tosphere},
{OP_RESIZE, TFM_RESIZE, TRANSFORM_OT_resize},
{OP_SKIN_RESIZE, TFM_SKIN_RESIZE, TRANSFORM_OT_skin_resize},
{OP_SHEAR, TFM_SHEAR, TRANSFORM_OT_shear},
{OP_WARP, TFM_WARP, TRANSFORM_OT_warp},
{OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten},
@ -118,6 +122,7 @@ EnumPropertyItem transform_mode_types[] =
{TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
{TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
{TFM_RESIZE, "RESIZE", 0, "Resize", ""},
{TFM_SKIN_RESIZE, "SKIN_RESIZE", 0, "Skin Resize", ""},
{TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
{TFM_SHEAR, "SHEAR", 0, "Shear", ""},
{TFM_WARP, "WARP", 0, "Warp", ""},
@ -542,6 +547,35 @@ static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS);
}
static int skin_resize_poll(bContext *C)
{
struct Object *obedit = CTX_data_edit_object(C);
if (obedit && obedit->type == OB_MESH) {
BMEditMesh *em = BMEdit_FromObject(obedit);
return (em && CustomData_has_layer(&em->bm->vdata, CD_MVERT_SKIN));
}
return 0;
}
static void TRANSFORM_OT_skin_resize(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Skin Resize";
ot->description = "Scale selected vertices' skin radii";
ot->idname = OP_SKIN_RESIZE;
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
/* api callbacks */
ot->invoke = transform_invoke;
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = skin_resize_poll;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS);
}
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
{
@ -901,6 +935,8 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
WM_keymap_add_item(keymap, OP_SKIN_RESIZE, AKEY, KM_PRESS, KM_CTRL, 0);
break;
case SPACE_ACTION:
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);