From be3000773b4d0860a4c7bb1d262deaf655e2b522 Mon Sep 17 00:00:00 2001 From: Martin Poirier Date: Mon, 28 Sep 2009 19:49:36 +0000 Subject: Adding back more functionalities for transform orientations. Create new orientation is now Ctrl-Alt-Space (Alt-Space is select orientation and the old ctrl-shift-c is taken by add constraints). New orientation panel in 3d view sidebar (nkey) has operator buttons for select, create and delete. Eventually, this should become a list. Note that orientation operators are missing notifiers to properly redraw the 3d view and its header properly. --- release/scripts/ui/space_view3d.py | 21 ++ source/blender/editors/include/ED_transform.h | 4 +- .../blender/editors/space_view3d/view3d_buttons.c | 2 +- source/blender/editors/transform/transform.h | 13 +- .../editors/transform/transform_manipulator.c | 11 +- source/blender/editors/transform/transform_ops.c | 94 ++++++- .../editors/transform/transform_orientations.c | 288 ++++++++++++--------- 7 files changed, 296 insertions(+), 137 deletions(-) diff --git a/release/scripts/ui/space_view3d.py b/release/scripts/ui/space_view3d.py index 23f3b8a10ac..a270e053126 100644 --- a/release/scripts/ui/space_view3d.py +++ b/release/scripts/ui/space_view3d.py @@ -1285,6 +1285,26 @@ class VIEW3D_PT_background_image(bpy.types.Panel): col.itemR(bg, "offset_x", text="X") col.itemR(bg, "offset_y", text="Y") +class VIEW3D_PT_transform_orientations(bpy.types.Panel): + __space_type__ = 'VIEW_3D' + __region_type__ = 'UI' + __label__ = "Transform Orientations" + __default_closed__ = True + + def poll(self, context): + view = context.space_data + return (view) + + def draw(self, context): + layout = self.layout + + view = context.space_data + + col = layout.column() + col.itemO("TFM_OT_select_orientation", text="Select") + col.itemO("TFM_OT_create_orientation", text="Create") + col.itemO("TFM_OT_delete_orientation", text="Delete") + bpy.types.register(VIEW3D_HT_header) # Header bpy.types.register(VIEW3D_MT_view) #View Menus @@ -1360,3 +1380,4 @@ bpy.types.register(VIEW3D_PT_3dview_display) bpy.types.register(VIEW3D_PT_3dview_meshdisplay) bpy.types.register(VIEW3D_PT_3dview_curvedisplay) bpy.types.register(VIEW3D_PT_background_image) +bpy.types.register(VIEW3D_PT_transform_orientations) \ No newline at end of file diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index bf3111de5dc..7f08e95aceb 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -111,10 +111,12 @@ int BIF_snappingSupported(struct Object *obedit); struct TransformOrientation; struct bContext; +struct ReportList; void BIF_clearTransformOrientation(struct bContext *C); void BIF_removeTransformOrientation(struct bContext *C, struct TransformOrientation *ts); -void BIF_manageTransformOrientation(struct bContext *C, int confirm, int set); +void BIF_removeTransformOrientationIndex(struct bContext *C, int index); +void BIF_createTransformOrientation(struct bContext *C, struct ReportList *reports, char *name, int use, int overwrite); int BIF_menuselectTransformOrientation(void); void BIF_selectTransformOrientation(struct bContext *C, struct TransformOrientation *ts); void BIF_selectTransformOrientationValue(struct bContext *C, int orientation); diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 496db8c00f8..ec72d72013b 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -886,7 +886,7 @@ static void do_view3d_region_buttons(bContext *C, void *arg, int event) } break; case B_TRANSFORMSPACEADD: - BIF_manageTransformOrientation(C, 1, 0); + BIF_createTransformOrientation(C, NULL, "", 1, 0); break; case B_TRANSFORMSPACECLEAR: BIF_clearTransformOrientation(C); diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index abe73a755dc..2c19bf932eb 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -38,6 +38,7 @@ struct TransInfo; struct TransData; +struct TransformOrientation; struct TransSnap; struct NumInput; struct Object; @@ -54,6 +55,7 @@ struct bContext; struct wmEvent; struct wmTimer; struct ARegion; +struct ReportList; typedef struct NDofInput { int flag; @@ -663,18 +665,17 @@ int handleNDofInput(NDofInput *n, struct wmEvent *event); void initTransformOrientation(struct bContext *C, TransInfo *t); -int manageObjectSpace(struct bContext *C, int confirm, int set); -int manageMeshSpace(struct bContext *C, int confirm, int set); -int manageBoneSpace(struct bContext *C, int confirm, int set); +struct TransformOrientation *createObjectSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); +struct TransformOrientation *createMeshSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); +struct TransformOrientation *createBoneSpace(struct bContext *C, struct ReportList *reports, char *name, int overwrite); /* Those two fill in mat and return non-zero on success */ int createSpaceNormal(float mat[3][3], float normal[3]); int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]); -int addMatrixSpace(struct bContext *C, float mat[3][3], char name[]); +struct TransformOrientation *addMatrixSpace(struct bContext *C, float mat[3][3], char name[], int overwrite); int addObjectSpace(struct bContext *C, struct Object *ob); -void applyTransformOrientation(const struct bContext *C, TransInfo *t); - +void applyTransformOrientation(const struct bContext *C, float mat[3][3], char *name); #define ORIENTATION_NONE 0 #define ORIENTATION_NORMAL 1 diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index c116b037d6e..bdf0a91bf89 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -412,6 +412,9 @@ int calc_manipulator_stats(const bContext *C) if(ob && totsel) { switch(v3d->twmode) { + + case V3D_MANIP_GLOBAL: + break; /* nothing to do */ case V3D_MANIP_NORMAL: if(obedit || ob->mode & OB_MODE_POSE) { @@ -473,8 +476,12 @@ int calc_manipulator_stats(const bContext *C) } break; default: /* V3D_MANIP_CUSTOM */ - // XXX applyTransformOrientation(C, t); - break; + { + float mat[3][3]; + applyTransformOrientation(C, mat, NULL); + Mat4CpyMat3(rv3d->twmat, mat); + break; + } } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index f369fba79df..0440a957539 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -152,8 +152,9 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) /* identifiers */ ot->name = "Select Orientation"; - ot->description= "Select orientation type."; + ot->description= "Select transformation orientation."; ot->idname = "TFM_OT_select_orientation"; + ot->flag = OPTYPE_UNDO; /* api callbacks */ ot->invoke = select_orientation_invoke; @@ -164,6 +165,92 @@ void TFM_OT_select_orientation(struct wmOperatorType *ot) RNA_def_enum_funcs(prop, select_orientation_itemf); } + +static int delete_orientation_exec(bContext *C, wmOperator *op) +{ + View3D *v3d = CTX_wm_view3d(C); + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + + BIF_removeTransformOrientationIndex(C, selected_index); + + return OPERATOR_FINISHED; +} + +static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return delete_orientation_exec(C, op); +} + +static int delete_orientation_poll(bContext *C) +{ + int selected_index = -1; + View3D *v3d = CTX_wm_view3d(C); + + if (ED_operator_areaactive(C) == 0) + return 0; + + + if(v3d) { + selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + } + + return selected_index >= 0; +} + +void TFM_OT_delete_orientation(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Delete Orientation"; + ot->description= "Delete transformation orientation."; + ot->idname = "TFM_OT_delete_orientation"; + ot->flag = OPTYPE_UNDO; + + /* api callbacks */ + ot->invoke = delete_orientation_invoke; + ot->exec = delete_orientation_exec; + ot->poll = delete_orientation_poll; +} + +static int create_orientation_exec(bContext *C, wmOperator *op) +{ + char name[36]; + int use = RNA_boolean_get(op->ptr, "use"); + int overwrite = RNA_boolean_get(op->ptr, "overwrite"); + + RNA_string_get(op->ptr, "name", name); + + BIF_createTransformOrientation(C, op->reports, name, use, overwrite); + + /* Do we need more refined tags? */ + WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); + + return OPERATOR_FINISHED; +} + +static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + return create_orientation_exec(C, op); +} + +void TFM_OT_create_orientation(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Create Orientation"; + ot->description= "Create transformation orientation from selection."; + ot->idname = "TFM_OT_create_orientation"; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* api callbacks */ + ot->invoke = create_orientation_invoke; + ot->exec = create_orientation_exec; + ot->poll = ED_operator_areaactive; + ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position."); + RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation"); + RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name"); +} + static void transformops_exit(bContext *C, wmOperator *op) { saveTransform(C, op->customdata, op); @@ -643,6 +730,8 @@ void transform_operatortypes(void) WM_operatortype_append(TFM_OT_edge_slide); WM_operatortype_append(TFM_OT_select_orientation); + WM_operatortype_append(TFM_OT_create_orientation); + WM_operatortype_append(TFM_OT_delete_orientation); } void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid) @@ -675,6 +764,9 @@ void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *key km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0); + km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); + RNA_boolean_set(km->ptr, "use", 1); + break; case SPACE_ACTION: km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0); diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index d82be842596..c9344b97fb2 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -23,6 +23,7 @@ */ #include +#include #include "MEM_guardedalloc.h" @@ -43,6 +44,7 @@ #include "BKE_utildefines.h" #include "BKE_armature.h" #include "BKE_context.h" +#include "BKE_report.h" #include "BLI_arithb.h" #include "BLI_blenlib.h" @@ -67,108 +69,131 @@ void BIF_clearTransformOrientation(bContext *C) { + View3D *v3d = CTX_wm_view3d(C); + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; BLI_freelistN(transform_spaces); - // TRANSFORM_FIX_ME // Need to loop over all view3d -// if (G.vd->twmode >= V3D_MANIP_CUSTOM) -// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + if(v3d && v3d->twmode >= V3D_MANIP_CUSTOM) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + } +} + +TransformOrientation* findOrientationName(bContext *C, char *name) +{ + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; + TransformOrientation *ts= NULL; + + for (ts = transform_spaces->first; ts; ts = ts->next) { + if (strncmp(ts->name, name, 35) == 0) { + return ts; + } + } + + return NULL; +} + +void uniqueOrientationName(bContext *C, char *name) +{ + if (findOrientationName(C, name) != NULL) + { + char tempname[64]; + int number; + char *dot; + + + number = strlen(name); + + if (number && isdigit(name[number-1])) + { + dot = strrchr(name, '.'); // last occurrence + if (dot) + *dot=0; + } + + for (number = 1; number <= 999; number++) + { + sprintf(tempname, "%s.%03d", name, number); + if (findOrientationName(C, tempname) == NULL) + { + BLI_strncpy(name, tempname, 32); + break; + } + } + } } - -void BIF_manageTransformOrientation(bContext *C, int confirm, int set) { + +void BIF_createTransformOrientation(bContext *C, ReportList *reports, char *name, int use, int overwrite) +{ Object *obedit = CTX_data_edit_object(C); Object *ob = CTX_data_active_object(C); - int index = -1; + TransformOrientation *ts = NULL; if (obedit) { if (obedit->type == OB_MESH) - index = manageMeshSpace(C, confirm, set); + ts = createMeshSpace(C, reports, name, overwrite); else if (obedit->type == OB_ARMATURE) - index = manageBoneSpace(C, confirm, set); + ts = createBoneSpace(C, reports, name, overwrite); } else if (ob && (ob->mode & OB_MODE_POSE)) { - index = manageBoneSpace(C, confirm, set); + ts = createBoneSpace(C, reports, name, overwrite); } else { - index = manageObjectSpace(C, confirm, set); + ts = createObjectSpace(C, reports, name, overwrite); } - if (set && index != -1) + if (use && ts != NULL) { - BIF_selectTransformOrientationValue(C, V3D_MANIP_CUSTOM + index); + BIF_selectTransformOrientation(C, ts); } } -int manageObjectSpace(bContext *C, int confirm, int set) { +TransformOrientation *createObjectSpace(bContext *C, ReportList *reports, char *name, int overwrite) { Base *base = CTX_data_active_base(C); + Object *ob; + float mat[3][3]; if (base == NULL) - return -1; - -//XXX if (confirm == 0) { -// if (set && pupmenu("Custom Orientation %t|Add and Use Active Object%x1") != 1) { -// return -1; -// } -// else if (set == 0 && pupmenu("Custom Orientation %t|Add Active Object%x1") != 1) { -// return -1; -// } -// } - - return addObjectSpace(C, base->object); -} + return NULL; -/* return 1 on confirm */ -int confirmSpace(int set, char text[]) -{ - char menu[64]; + + ob = base->object; - if (set) { - sprintf(menu, "Custom Orientation %%t|Add and Use %s%%x1", text); - } - else { - sprintf(menu, "Custom Orientation %%t|Add %s%%x1", text); + Mat3CpyMat4(mat, ob->obmat); + Mat3Ortho(mat); + + /* use object name if no name is given */ + if (name[0] == 0) + { + strncpy(name, ob->id.name+2, 35); } - -//XXX if (pupmenu(menu) == 1) { - return 1; -// } -// else { -// return 0; -// } + + return addMatrixSpace(C, mat, name, overwrite); } -int manageBoneSpace(bContext *C, int confirm, int set) { +TransformOrientation *createBoneSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; float normal[3], plane[3]; - char name[36] = ""; - int index; getTransformOrientation(C, normal, plane, 0); - - if (confirm == 0 && confirmSpace(set, "Bone") == 0) { - return -1; - } if (createSpaceNormalTangent(mat, normal, plane) == 0) { -//XXX error("Cannot use zero-length bone"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-length bone"); + return NULL; } - strcpy(name, "Bone"); - - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); + if (name[0] == 0) + { + strcpy(name, "Bone"); + } - index = addMatrixSpace(C, mat, name); - return index; + return addMatrixSpace(C, mat, name, overwrite); } -int manageMeshSpace(bContext *C, int confirm, int set) { +TransformOrientation *createMeshSpace(bContext *C, ReportList *reports, char *name, int overwrite) { float mat[3][3]; float normal[3], plane[3]; - char name[36] = ""; - int index; int type; type = getTransformOrientation(C, normal, plane, 0); @@ -176,51 +201,44 @@ int manageMeshSpace(bContext *C, int confirm, int set) { switch (type) { case ORIENTATION_VERT: - if (confirm == 0 && confirmSpace(set, "vertex") == 0) { - return -1; - } - if (createSpaceNormal(mat, normal) == 0) { -// XXX error("Cannot use vertex with zero-length normal"); - return -1; + BKE_reports_prepend(reports, "Cannot use vertex with zero-length normal"); + return NULL; } - strcpy(name, "Vertex"); + if (name[0] == 0) + { + strcpy(name, "Vertex"); + } break; case ORIENTATION_EDGE: - if (confirm == 0 && confirmSpace(set, "Edge") == 0) { - return -1; - } - if (createSpaceNormalTangent(mat, normal, plane) == 0) { -// XXX error("Cannot use zero-length edge"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-length edge"); + return NULL; } - strcpy(name, "Edge"); + if (name[0] == 0) + { + strcpy(name, "Edge"); + } break; case ORIENTATION_FACE: - if (confirm == 0 && confirmSpace(set, "Face") == 0) { - return -1; - } - if (createSpaceNormalTangent(mat, normal, plane) == 0) { -// XXX error("Cannot use zero-area face"); - return -1; + BKE_reports_prepend(reports, "Cannot use zero-area face"); + return NULL; } - strcpy(name, "Face"); + if (name[0] == 0) + { + strcpy(name, "Face"); + } break; default: - return -1; + return NULL; break; } - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); - - index = addMatrixSpace(C, mat, name); - return index; + return addMatrixSpace(C, mat, name, overwrite); } int createSpaceNormal(float mat[3][3], float normal[3]) @@ -271,32 +289,17 @@ int createSpaceNormalTangent(float mat[3][3], float normal[3], float tangent[3]) return 1; } - -int addObjectSpace(bContext *C, Object *ob) { - float mat[3][3]; - char name[36] = ""; - - Mat3CpyMat4(mat, ob->obmat); - Mat3Ortho(mat); - - strncpy(name, ob->id.name+2, 35); - - /* Input name */ -//XXX sbutton(name, 1, 35, "name: "); - - return addMatrixSpace(C, mat, name); -} - -int addMatrixSpace(bContext *C, float mat[3][3], char name[]) { +TransformOrientation* addMatrixSpace(bContext *C, float mat[3][3], char name[], int overwrite) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; - TransformOrientation *ts; - int index = 0; + TransformOrientation *ts = NULL; - /* if name is found in list, reuse that transform space */ - for (index = 0, ts = transform_spaces->first; ts; ts = ts->next, index++) { - if (strncmp(ts->name, name, 35) == 0) { - break; - } + if (overwrite) + { + ts = findOrientationName(C, name); + } + else + { + uniqueOrientationName(C, name); } /* if not, create a new one */ @@ -310,31 +313,61 @@ int addMatrixSpace(bContext *C, float mat[3][3], char name[]) { /* copy matrix into transform space */ Mat3CpyMat3(ts->mat, mat); - ED_undo_push(C, "Add/Update Transform Orientation"); - - return index; + return ts; } void BIF_removeTransformOrientation(bContext *C, TransformOrientation *target) { ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; TransformOrientation *ts = transform_spaces->first; - //int selected_index = (G.vd->twmode - V3D_MANIP_CUSTOM); int i; for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { if (ts == target) { - // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D -// if (selected_index == i) { -// G.vd->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ -// } -// else if (selected_index > i) -// G.vd->twmode--; + View3D *v3d = CTX_wm_view3d(C); + if(v3d) { + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + + // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D + if (selected_index == i) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + } + else if (selected_index > i) { + v3d->twmode--; + } + + } + + BLI_freelinkN(transform_spaces, ts); + break; + } + } +} + +void BIF_removeTransformOrientationIndex(bContext *C, int index) { + ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces; + TransformOrientation *ts = transform_spaces->first; + int i; + + for (i = 0, ts = transform_spaces->first; ts; ts = ts->next, i++) { + if (i == index) { + View3D *v3d = CTX_wm_view3d(C); + if(v3d) { + int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); + + // Transform_fix_me NEED TO DO THIS FOR ALL VIEW3D + if (selected_index == i) { + v3d->twmode = V3D_MANIP_GLOBAL; /* fallback to global */ + } + else if (selected_index > i) { + v3d->twmode--; + } + + } BLI_freelinkN(transform_spaces, ts); break; } } - ED_undo_push(C, "Remove Transform Orientation"); } void BIF_selectTransformOrientation(bContext *C, TransformOrientation *target) { @@ -433,7 +466,7 @@ int BIF_countTransformOrientation(const bContext *C) { return count; } -void applyTransformOrientation(const bContext *C, TransInfo *t) { +void applyTransformOrientation(const bContext *C, float mat[3][3], char *name) { TransformOrientation *ts; View3D *v3d = CTX_wm_view3d(C); int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM); @@ -442,8 +475,11 @@ void applyTransformOrientation(const bContext *C, TransInfo *t) { if (selected_index >= 0) { for (i = 0, ts = CTX_data_scene(C)->transform_spaces.first; ts; ts = ts->next, i++) { if (selected_index == i) { - strcpy(t->spacename, ts->name); - Mat3CpyMat3(t->spacemtx, ts->mat); + + if (name) + strcpy(name, ts->name); + + Mat3CpyMat3(mat, ts->mat); break; } } @@ -558,7 +594,7 @@ void initTransformOrientation(bContext *C, TransInfo *t) } break; default: /* V3D_MANIP_CUSTOM */ - applyTransformOrientation(C, t); + applyTransformOrientation(C, t->spacemtx, t->spacename); break; } } -- cgit v1.2.3