This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/transform/transform_ops.c

1232 lines
41 KiB
C
Raw Normal View History

/*
2008-12-29 04:14:27 +00:00
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
2010-02-12 13:34:04 +00:00
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
2008-12-29 04:14:27 +00:00
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
2011-02-27 20:29:51 +00:00
/** \file blender/editors/transform/transform_ops.c
* \ingroup edtransform
*/
2008-12-29 04:14:27 +00:00
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
2008-12-29 04:14:27 +00:00
#include "BLI_math.h"
#include "BLI_utildefines.h"
2008-12-29 04:14:27 +00:00
#include "BLT_translation.h"
2008-12-29 04:14:27 +00:00
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_report.h"
2015-04-29 19:39:58 +10:00
#include "BKE_editmesh.h"
2008-12-29 04:14:27 +00:00
2013-03-07 02:44:55 +00:00
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
2008-12-29 04:14:27 +00:00
#include "WM_api.h"
#include "WM_types.h"
#include "UI_interface.h"
#include "UI_resources.h"
2008-12-29 04:14:27 +00:00
#include "ED_screen.h"
/* for USE_LOOPSLIDE_HACK only */
#include "ED_mesh.h"
2008-12-29 04:14:27 +00:00
#include "transform.h"
2012-06-06 22:38:39 +00:00
typedef struct TransformModeItem {
const char *idname;
2012-06-10 19:59:02 +00:00
int mode;
void (*opfunc)(wmOperatorType *);
} TransformModeItem;
static const float VecOne[3] = {1, 1, 1};
2015-05-25 10:26:32 +10:00
static const char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
static const char OP_ROTATION[] = "TRANSFORM_OT_rotate";
static const char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere";
static const char OP_RESIZE[] = "TRANSFORM_OT_resize";
static const char OP_SKIN_RESIZE[] = "TRANSFORM_OT_skin_resize";
static const char OP_SHEAR[] = "TRANSFORM_OT_shear";
static const char OP_BEND[] = "TRANSFORM_OT_bend";
static const char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten";
static const char OP_PUSH_PULL[] = "TRANSFORM_OT_push_pull";
static const char OP_TILT[] = "TRANSFORM_OT_tilt";
static const char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
static const char OP_MIRROR[] = "TRANSFORM_OT_mirror";
static const char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
static const char OP_VERT_SLIDE[] = "TRANSFORM_OT_vert_slide";
static const char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
static const char OP_EDGE_BWEIGHT[] = "TRANSFORM_OT_edge_bevelweight";
static const char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
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);
2013-11-20 12:14:10 +11:00
static void TRANSFORM_OT_bend(struct wmOperatorType *ot);
static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot);
static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot);
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
static void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot);
static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
static TransformModeItem transform_modes[] =
{
{OP_TRANSLATION, TFM_TRANSLATION, TRANSFORM_OT_translate},
{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},
2013-11-20 12:14:10 +11:00
{OP_BEND, TFM_BEND, TRANSFORM_OT_bend},
{OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten},
{OP_PUSH_PULL, TFM_PUSHPULL, TRANSFORM_OT_push_pull},
{OP_TILT, TFM_TILT, TRANSFORM_OT_tilt},
{OP_TRACKBALL, TFM_TRACKBALL, TRANSFORM_OT_trackball},
{OP_MIRROR, TFM_MIRROR, TRANSFORM_OT_mirror},
{OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
{OP_VERT_SLIDE, TFM_VERT_SLIDE, TRANSFORM_OT_vert_slide},
{OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
{OP_EDGE_BWEIGHT, TFM_BWEIGHT, TRANSFORM_OT_edge_bevelweight},
{OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
{NULL, 0}
};
const EnumPropertyItem rna_enum_transform_mode_types[] =
{
{TFM_INIT, "INIT", 0, "Init", ""},
{TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
{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", ""},
2013-11-20 12:14:10 +11:00
{TFM_BEND, "BEND", 0, "Bend", ""},
{TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
{TFM_TILT, "TILT", 0, "Tilt", ""},
{TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
{TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
{TFM_CREASE, "CREASE", 0, "Crease", ""},
{TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
{TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""},
{TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
{TFM_BONE_ENVELOPE_DIST, "BONE_ENVELOPE_DIST", 0, "Bone_Envelope_Distance", ""},
{TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
{TFM_MASK_SHRINKFATTEN, "MASK_SHRINKFATTEN", 0, "Mask_Shrinkfatten", ""},
{TFM_GPENCIL_SHRINKFATTEN, "GPENCIL_SHRINKFATTEN", 0, "GPencil_Shrinkfatten", ""},
{TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
{TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
{TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
{TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
{TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
{TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
{TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
{TFM_ALIGN, "ALIGN", 0, "Align", ""},
{TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
{TFM_SEQ_SLIDE, "SEQSLIDE", 0, "Sequence Slide", ""},
{0, NULL, 0, NULL, NULL}
};
static int select_orientation_exec(bContext *C, wmOperator *op)
{
int orientation = RNA_enum_get(op->ptr, "orientation");
BIF_selectTransformOrientationValue(C, orientation);
2018-05-13 06:44:03 +02:00
2012-06-10 19:59:02 +00:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
return OPERATOR_FINISHED;
}
static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
{
uiPopupMenu *pup;
uiLayout *layout;
pup = UI_popup_menu_begin(C, IFACE_("Orientation"), ICON_NONE);
layout = UI_popup_menu_layout(pup);
uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation");
UI_popup_menu_end(C, pup);
return OPERATOR_INTERFACE;
}
static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Select Orientation";
ot->description = "Select transformation orientation";
ot->idname = "TRANSFORM_OT_select_orientation";
ot->flag = OPTYPE_UNDO;
/* api callbacks */
ot->invoke = select_orientation_invoke;
ot->exec = select_orientation_exec;
ot->poll = ED_operator_view3d_active;
2012-06-10 19:59:02 +00:00
prop = RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
}
static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
{
View3D *v3d = CTX_wm_view3d(C);
int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
BIF_removeTransformOrientationIndex(C, selected_index);
2018-05-13 06:44:03 +02:00
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
2012-06-10 19:59:02 +00:00
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C));
return OPERATOR_FINISHED;
}
static int delete_orientation_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
return delete_orientation_exec(C, op);
}
2018-07-02 11:47:00 +02:00
static bool delete_orientation_poll(bContext *C)
{
int selected_index = -1;
View3D *v3d = CTX_wm_view3d(C);
2018-05-13 06:44:03 +02:00
if (ED_operator_areaactive(C) == 0)
return 0;
2018-05-13 06:44:03 +02:00
if (v3d) {
selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
}
2018-05-13 06:44:03 +02:00
return selected_index >= 0;
}
static void TRANSFORM_OT_delete_orientation(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Orientation";
ot->description = "Delete transformation orientation";
ot->idname = "TRANSFORM_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[MAX_NAME];
2014-02-03 18:55:59 +11:00
const bool use = RNA_boolean_get(op->ptr, "use");
const bool overwrite = RNA_boolean_get(op->ptr, "overwrite");
const bool use_view = RNA_boolean_get(op->ptr, "use_view");
View3D *v3d = CTX_wm_view3d(C);
RNA_string_get(op->ptr, "name", name);
if (use && !v3d) {
BKE_report(op->reports, RPT_ERROR, "Create Orientation's 'use' parameter only valid in a 3DView context");
return OPERATOR_CANCELLED;
}
BIF_createTransformOrientation(C, op->reports, name, use_view, use, overwrite);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
2012-06-10 19:59:02 +00:00
WM_event_add_notifier(C, NC_SCENE | NA_EDITED, CTX_data_scene(C));
2018-05-13 06:44:03 +02:00
return OPERATOR_FINISHED;
}
static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Create Orientation";
ot->description = "Create transformation orientation from selection";
ot->idname = "TRANSFORM_OT_create_orientation";
2012-06-10 19:59:02 +00:00
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* api callbacks */
ot->exec = create_orientation_exec;
ot->poll = ED_operator_areaactive;
RNA_def_string(ot->srna, "name", NULL, MAX_NAME, "Name", "Name of the new custom orientation");
RNA_def_boolean(ot->srna, "use_view", false, "Use View",
"Use the current view instead of the active object to create the new orientation");
RNA_def_boolean(ot->srna, "use", false, "Use after creation", "Select orientation after its creation");
RNA_def_boolean(ot->srna, "overwrite", false, "Overwrite previous",
"Overwrite previously created orientation with same name");
}
#ifdef USE_LOOPSLIDE_HACK
/**
* Special hack for MESH_OT_loopcut_slide so we get back to the selection mode
*/
static void transformops_loopsel_hack(bContext *C, wmOperator *op)
{
if (op->type->idname == OP_EDGE_SLIDE) {
if (op->opm && op->opm->opm && op->opm->opm->prev) {
wmOperator *op_prev = op->opm->opm->prev;
Scene *scene = CTX_data_scene(C);
bool mesh_select_mode[3];
PropertyRNA *prop = RNA_struct_find_property(op_prev->ptr, "mesh_select_mode_init");
if (prop && RNA_property_is_set(op_prev->ptr, prop)) {
ToolSettings *ts = scene->toolsettings;
short selectmode_orig;
RNA_property_boolean_get_array(op_prev->ptr, prop, mesh_select_mode);
selectmode_orig = ((mesh_select_mode[0] ? SCE_SELECT_VERTEX : 0) |
(mesh_select_mode[1] ? SCE_SELECT_EDGE : 0) |
(mesh_select_mode[2] ? SCE_SELECT_FACE : 0));
/* still switch if we were originally in face select mode */
if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) {
BMEditMesh *em = BKE_editmesh_from_object(scene->obedit);
em->selectmode = ts->selectmode = selectmode_orig;
EDBM_selectmode_set(em);
}
}
}
}
}
2014-11-28 15:50:43 +01:00
#else
/* prevent removal by cleanup */
# error "loopslide hack removed!"
#endif /* USE_LOOPSLIDE_HACK */
2008-12-29 04:14:27 +00:00
static void transformops_exit(bContext *C, wmOperator *op)
{
#ifdef USE_LOOPSLIDE_HACK
transformops_loopsel_hack(C, op);
#endif
saveTransform(C, op->customdata, op);
2008-12-29 04:14:27 +00:00
MEM_freeN(op->customdata);
op->customdata = NULL;
G.moving = 0;
2008-12-29 04:14:27 +00:00
}
static int transformops_data(bContext *C, wmOperator *op, const wmEvent *event)
2008-12-29 04:14:27 +00:00
{
int retval = 1;
if (op->customdata == NULL) {
TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data2");
TransformModeItem *tmode;
int mode = -1;
for (tmode = transform_modes; tmode->idname; tmode++) {
if (op->type->idname == tmode->idname) {
mode = tmode->mode;
break;
}
}
if (mode == -1) {
mode = RNA_enum_get(op->ptr, "mode");
}
retval = initTransform(C, t, op, event, mode);
/* store data */
if (retval) {
G.moving = special_transform_moving(t);
op->customdata = t;
}
else {
MEM_freeN(t);
}
}
return retval; /* return 0 on error */
2008-12-29 04:14:27 +00:00
}
static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
2008-12-29 04:14:27 +00:00
{
int exit_code;
2008-12-29 04:14:27 +00:00
TransInfo *t = op->customdata;
const enum TfmMode mode_prev = t->mode;
#if defined(WITH_INPUT_NDOF) && 0
// stable 2D mouse coords map to different 3D coords while the 3D mouse is active
// in other words, 2D deltas are no longer good enough!
// disable until individual 'transformers' behave better
if (event->type == NDOF_MOTION)
return OPERATOR_PASS_THROUGH;
#endif
/* XXX insert keys are called here, and require context */
2012-06-10 19:59:02 +00:00
t->context = C;
exit_code = transformEvent(t, event);
2012-06-10 19:59:02 +00:00
t->context = NULL;
/* XXX, workaround: active needs to be calculated before transforming,
* since we're not reading from 'td->center' in this case. see: T40241 */
if (t->tsnap.target == SCE_SNAP_TARGET_ACTIVE) {
/* In camera view, tsnap callback is not set (see initSnappingMode() in transfrom_snap.c, and T40348). */
if (t->tsnap.targetSnap && ((t->tsnap.status & TARGET_INIT) == 0)) {
t->tsnap.targetSnap(t);
}
}
transformApply(C, t);
exit_code |= transformEnd(C, t);
if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
2008-12-29 04:14:27 +00:00
transformops_exit(C, op);
exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
2008-12-29 04:14:27 +00:00
}
else {
if (mode_prev != t->mode) {
/* WARNING: this is not normal to switch operator types
* normally it would not be supported but transform happens
2014-03-15 20:08:29 +11:00
* to share callbacks between different operators. */
wmOperatorType *ot_new = NULL;
TransformModeItem *item = transform_modes;
while (item->idname) {
if (item->mode == t->mode) {
ot_new = WM_operatortype_find(item->idname, false);
break;
}
item++;
}
BLI_assert(ot_new != NULL);
if (ot_new) {
WM_operator_type_set(op, ot_new);
}
/* end suspicious code */
}
}
return exit_code;
2008-12-29 04:14:27 +00:00
}
static void transform_cancel(bContext *C, wmOperator *op)
2008-12-29 04:14:27 +00:00
{
TransInfo *t = op->customdata;
t->state = TRANS_CANCEL;
transformEnd(C, t);
transformops_exit(C, op);
}
static int transform_exec(bContext *C, wmOperator *op)
{
TransInfo *t;
if (!transformops_data(C, op, NULL)) {
G.moving = 0;
return OPERATOR_CANCELLED;
}
t = op->customdata;
t->options |= CTX_AUTOCONFIRM;
transformApply(C, t);
transformEnd(C, t);
2008-12-29 04:14:27 +00:00
transformops_exit(C, op);
2018-05-13 06:44:03 +02:00
2012-06-10 19:59:02 +00:00
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
2008-12-29 04:14:27 +00:00
return OPERATOR_FINISHED;
}
static int transform_invoke(bContext *C, wmOperator *op, const wmEvent *event)
2008-12-29 04:14:27 +00:00
{
if (!transformops_data(C, op, event)) {
G.moving = 0;
return OPERATOR_CANCELLED;
}
2008-12-29 04:14:27 +00:00
if (RNA_struct_property_is_set(op->ptr, "value")) {
2008-12-29 04:14:27 +00:00
return transform_exec(C, op);
}
else {
/* add temp handler */
WM_event_add_modal_handler(C, op);
2008-12-29 04:14:27 +00:00
op->flag |= OP_IS_MODAL_GRAB_CURSOR; // XXX maybe we want this with the manipulator only?
2008-12-29 04:14:27 +00:00
return OPERATOR_RUNNING_MODAL;
}
}
static bool transform_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
{
const char *prop_id = RNA_property_identifier(prop);
/* Orientation/Constraints. */
{
/* Hide orientation axis if no constraints are set, since it wont be used. */
PropertyRNA *prop_con = RNA_struct_find_property(op->ptr, "constraint_axis");
if (prop_con && !RNA_property_is_set(op->ptr, prop_con)) {
if (STRPREFIX(prop_id, "constraint")) {
return false;
}
}
}
/* Proportional Editing. */
{
PropertyRNA *prop_pet = RNA_struct_find_property(op->ptr, "proportional");
if (prop_pet && (prop_pet != prop) &&
(RNA_property_enum_get(op->ptr, prop_pet) == PROP_EDIT_OFF))
{
if (STRPREFIX(prop_id, "proportional")) {
return false;
}
}
}
return true;
}
void Transform_Properties(struct wmOperatorType *ot, int flags)
{
PropertyRNA *prop;
if (flags & P_AXIS) {
2012-06-10 19:59:02 +00:00
prop = RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION);
RNA_def_property_array(prop, 3);
/* Make this not hidden when there's a nice axis selection widget */
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
}
if (flags & P_CONSTRAINT) {
RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
2012-06-10 19:59:02 +00:00
prop = RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
}
if (flags & P_MIRROR) {
prop = RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
if (flags & P_MIRROR_DUMMY) {
/* only used so macros can disable this option */
RNA_def_property_flag(prop, PROP_HIDDEN);
}
}
if (flags & P_PROPORTIONAL) {
RNA_def_enum(ot->srna, "proportional", rna_enum_proportional_editing_items, 0, "Proportional Editing", "");
prop = RNA_def_enum(ot->srna, "proportional_edit_falloff", rna_enum_proportional_falloff_items, 0,
"Proportional Editing Falloff", "Falloff type for proportional editing mode");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
RNA_def_float(ot->srna, "proportional_size", 1, T_PROP_SIZE_MIN, T_PROP_SIZE_MAX,
"Proportional Size", "", 0.001f, 100.0f);
}
if (flags & P_SNAP) {
2012-06-10 19:59:02 +00:00
prop = RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
if (flags & P_GEO_SNAP) {
prop = RNA_def_enum(ot->srna, "snap_target", rna_enum_snap_target_items, 0, "Target", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
2012-06-10 19:59:02 +00:00
prop = RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
2018-05-13 06:44:03 +02:00
if (flags & P_ALIGN_SNAP) {
2012-06-10 19:59:02 +00:00
prop = RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
2012-06-10 19:59:02 +00:00
prop = RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
RNA_def_property_flag(prop, PROP_HIDDEN);
}
}
}
2018-05-13 06:44:03 +02:00
Grease Pencil - Storyboarding Features (merge from GPencil_EditStrokes branch) This merge-commit brings in a number of new features and workflow/UI improvements for working with Grease Pencil. While these were originally targetted at improving the workflow for creating 3D storyboards in Blender using the Grease Pencil, many of these changes should also prove useful in other workflows too. The main highlights here are: 1) It is now possible to edit Grease Pencil strokes - Use D Tab, or toggle the "Enable Editing" toggles in the Toolbar/Properties regions to enter "Stroke Edit Mode". In this mode, many common editing tools will operate on Grease Pencil stroke points instead. - Tools implemented include Select, Select All/Border/Circle/Linked/More/Less, Grab, Rotate, Scale, Bend, Shear, To Sphere, Mirror, Duplicate, Delete. - Proportional Editing works when using the transform tools 2) Grease Pencil stroke settings can now be animated NOTE: Currently drivers don't work, but if time allows, this may still be added before the release. 3) Strokes can be drawn with "filled" interiors, using a separate set of colour/opacity settings to the ones used for the lines themselves. This makes use of OpenGL filled polys, which has the limitation of only being able to fill convex shapes. Some artifacts may be visible on concave shapes (e.g. pacman's mouth will be overdrawn) 4) "Volumetric Strokes" - An alternative drawing technique for stroke drawing has been added which draws strokes as a series of screen-aligned discs. While this was originally a partial experimental technique at getting better quality 3D lines, the effects possible using this technique were interesting enough to warrant making this a dedicated feature. Best results when partial opacity and large stroke widths are used. 5) Improved Onion Skinning Support - Different colours can be selected for the before/after ghosts. To do so, enable the "colour wheel" toggle beside the Onion Skinning toggle, and set the colours accordingly. - Different numbers of ghosts can be shown before/after the current frame 6) Grease Pencil datablocks are now attached to the scene by default instead of the active object. - For a long time, the object-attachment has proved to be quite problematic for users to keep track of. Now that this is done at scene level, it is easier for most users to use. - An exception for old files (and for any addons which may benefit from object attachment instead), is that if the active object has a Grease Pencil datablock, that will be used instead. - It is not currently possible to choose object-attachment from the UI, but it is simple to do this from the console instead, by doing: context.active_object.grease_pencil = bpy.data.grease_pencil["blah"] 7) Various UI Cleanups - The layers UI has been cleaned up to use a list instead of the nested-panels design. Apart from saving space, this is also much nicer to look at now. - The UI code is now all defined in Python. To support this, it has been necessary to add some new context properties to make it easier to access these settings. e.g. "gpencil_data" for the datablock "active_gpencil_layer" and "active_gpencil_frame" for active data, "editable_gpencil_strokes" for the strokes that can be edited - The "stroke placement/alignment" settings (previously "Drawing Settings" at the bottom of the Grease Pencil panel in the Properties Region) is now located in the toolbar. These were more toolsettings than properties for how GPencil got drawn. - "Use Sketching Sessions" has been renamed "Continuous Drawing", as per a suggestion for an earlier discussion on developer.blender.org - By default, the painting operator will wait for a mouse button to be pressed before it starts creating the stroke. This is to make it easier to include this operator in various toolbars/menus/etc. To get it immediately starting (as when you hold down DKEy to draw), set "wait_for_input" to False. - GPencil Layers can be rearranged in the "Grease Pencil" mode of the Action Editor - Toolbar panels have been added to all the other editors which support these. 8) Pie menus for quick-access to tools A set of experimental pie menus has been included for quick access to many tools and settings. It is not necessary to use these to get things done, but they have been designed to help make certain common tasks easier. - Ctrl-D = The main pie menu. Reveals tools in a context sensitive and spatially stable manner. - D Q = "Quick Settings" pie. This allows quick access to the active layer's settings. Notably, colours, thickness, and turning onion skinning on/off.
2014-12-01 01:52:06 +13:00
if (flags & P_GPENCIL_EDIT) {
RNA_def_boolean(ot->srna, "gpencil_strokes", 0, "Edit Grease Pencil", "Edit selected Grease Pencil strokes");
}
2018-05-13 06:44:03 +02:00
if ((flags & P_OPTIONS) && !(flags & P_NO_TEXSPACE)) {
RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
prop = RNA_def_boolean(ot->srna, "remove_on_cancel", 0, "Remove on Cancel", "Remove elements on cancel");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
if (flags & P_CORRECT_UV) {
RNA_def_boolean(ot->srna, "correct_uv", 0, "Correct UVs", "Correct UV coordinates when transforming");
2011-08-03 08:02:32 +00:00
}
if (flags & P_CENTER) {
/* For manipulators that define their own center. */
prop = RNA_def_property(ot->srna, "center_override", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 3);
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
RNA_def_property_ui_text(prop, "Center Override", "Force using this center value (when set)");
}
if ((flags & P_NO_DEFAULTS) == 0) {
prop = RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_boolean(ot->srna, "use_accurate", 0, "Accurate", "Use accurate transformation");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
}
static void TRANSFORM_OT_translate(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Translate";
ot->description = "Translate (move) selected items";
ot->idname = OP_TRANSLATION;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Move", "", -FLT_MAX, FLT_MAX);
Grease Pencil - Storyboarding Features (merge from GPencil_EditStrokes branch) This merge-commit brings in a number of new features and workflow/UI improvements for working with Grease Pencil. While these were originally targetted at improving the workflow for creating 3D storyboards in Blender using the Grease Pencil, many of these changes should also prove useful in other workflows too. The main highlights here are: 1) It is now possible to edit Grease Pencil strokes - Use D Tab, or toggle the "Enable Editing" toggles in the Toolbar/Properties regions to enter "Stroke Edit Mode". In this mode, many common editing tools will operate on Grease Pencil stroke points instead. - Tools implemented include Select, Select All/Border/Circle/Linked/More/Less, Grab, Rotate, Scale, Bend, Shear, To Sphere, Mirror, Duplicate, Delete. - Proportional Editing works when using the transform tools 2) Grease Pencil stroke settings can now be animated NOTE: Currently drivers don't work, but if time allows, this may still be added before the release. 3) Strokes can be drawn with "filled" interiors, using a separate set of colour/opacity settings to the ones used for the lines themselves. This makes use of OpenGL filled polys, which has the limitation of only being able to fill convex shapes. Some artifacts may be visible on concave shapes (e.g. pacman's mouth will be overdrawn) 4) "Volumetric Strokes" - An alternative drawing technique for stroke drawing has been added which draws strokes as a series of screen-aligned discs. While this was originally a partial experimental technique at getting better quality 3D lines, the effects possible using this technique were interesting enough to warrant making this a dedicated feature. Best results when partial opacity and large stroke widths are used. 5) Improved Onion Skinning Support - Different colours can be selected for the before/after ghosts. To do so, enable the "colour wheel" toggle beside the Onion Skinning toggle, and set the colours accordingly. - Different numbers of ghosts can be shown before/after the current frame 6) Grease Pencil datablocks are now attached to the scene by default instead of the active object. - For a long time, the object-attachment has proved to be quite problematic for users to keep track of. Now that this is done at scene level, it is easier for most users to use. - An exception for old files (and for any addons which may benefit from object attachment instead), is that if the active object has a Grease Pencil datablock, that will be used instead. - It is not currently possible to choose object-attachment from the UI, but it is simple to do this from the console instead, by doing: context.active_object.grease_pencil = bpy.data.grease_pencil["blah"] 7) Various UI Cleanups - The layers UI has been cleaned up to use a list instead of the nested-panels design. Apart from saving space, this is also much nicer to look at now. - The UI code is now all defined in Python. To support this, it has been necessary to add some new context properties to make it easier to access these settings. e.g. "gpencil_data" for the datablock "active_gpencil_layer" and "active_gpencil_frame" for active data, "editable_gpencil_strokes" for the strokes that can be edited - The "stroke placement/alignment" settings (previously "Drawing Settings" at the bottom of the Grease Pencil panel in the Properties Region) is now located in the toolbar. These were more toolsettings than properties for how GPencil got drawn. - "Use Sketching Sessions" has been renamed "Continuous Drawing", as per a suggestion for an earlier discussion on developer.blender.org - By default, the painting operator will wait for a mouse button to be pressed before it starts creating the stroke. This is to make it easier to include this operator in various toolbars/menus/etc. To get it immediately starting (as when you hold down DKEy to draw), set "wait_for_input" to False. - GPencil Layers can be rearranged in the "Grease Pencil" mode of the Action Editor - Toolbar panels have been added to all the other editors which support these. 8) Pie menus for quick-access to tools A set of experimental pie menus has been included for quick access to many tools and settings. It is not necessary to use these to get things done, but they have been designed to help make certain common tasks easier. - Ctrl-D = The main pie menu. Reveals tools in a context sensitive and spatially stable manner. - D Q = "Quick Settings" pie. This allows quick access to the active layer's settings. Notably, colours, thickness, and turning onion skinning on/off.
2014-12-01 01:52:06 +13:00
Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_OPTIONS | P_GPENCIL_EDIT);
}
static void TRANSFORM_OT_resize(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Resize";
2018-05-13 06:44:03 +02:00
ot->description = "Scale (resize) selected items";
ot->idname = OP_RESIZE;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Scale", "", -FLT_MAX, FLT_MAX);
Transform_Properties(
ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_GPENCIL_EDIT | P_CENTER);
}
2018-07-02 11:47:00 +02:00
static bool skin_resize_poll(bContext *C)
{
struct Object *obedit = CTX_data_edit_object(C);
if (obedit && obedit->type == OB_MESH) {
BMEditMesh *em = BKE_editmesh_from_object(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";
2018-05-13 06:44:03 +02:00
ot->description = "Scale selected vertices' skin radii";
ot->idname = OP_SKIN_RESIZE;
2012-06-10 19:59:02 +00:00
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;
ot->poll_property = transform_poll_property;
RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Scale", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_OPTIONS | P_NO_TEXSPACE);
}
static void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Trackball";
ot->description = "Trackball style rotation of selected items";
ot->idname = OP_TRACKBALL;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
/* Maybe we could use float_vector_xyz here too? */
RNA_def_float_rotation(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
static void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
{
/* identifiers */
2012-10-08 20:01:36 +00:00
ot->name = "Rotate";
ot->description = "Rotate selected items";
ot->idname = OP_ROTATION;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
Transform_Properties(
ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
static void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
{
/* identifiers */
2012-10-08 20:01:36 +00:00
ot->name = "Tilt";
2016-06-08 22:30:53 +10:00
/* optional -
* "Tilt selected vertices"
2012-10-08 21:03:35 +00:00
* "Specify an extra axis rotation for selected vertices of 3D curve" */
2018-05-13 06:44:03 +02:00
ot->description = "Tilt selected control vertices of 3D curve";
ot->idname = OP_TILT;
2012-06-10 19:59:02 +00:00
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 = ED_operator_editcurve_3d;
ot->poll_property = transform_poll_property;
RNA_def_float_rotation(ot->srna, "value", 0, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
2012-10-08 20:01:36 +00:00
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
}
2013-11-20 12:14:10 +11:00
static void TRANSFORM_OT_bend(struct wmOperatorType *ot)
{
/* identifiers */
2013-11-20 12:14:10 +11:00
ot->name = "Bend";
ot->description = "Bend selected items between the 3D cursor and the mouse";
ot->idname = OP_BEND;
2012-06-10 19:59:02 +00:00
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
/* api callbacks */
ot->invoke = transform_invoke;
2013-11-27 18:36:04 +11:00
// ot->exec = transform_exec; // unsupported
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_region_view3d_active;
ot->poll_property = transform_poll_property;
2012-06-10 19:59:02 +00:00
RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
static void TRANSFORM_OT_shear(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Shear";
ot->description = "Shear selected items along the horizontal screen axis";
ot->idname = OP_SHEAR;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
Grease Pencil - Storyboarding Features (merge from GPencil_EditStrokes branch) This merge-commit brings in a number of new features and workflow/UI improvements for working with Grease Pencil. While these were originally targetted at improving the workflow for creating 3D storyboards in Blender using the Grease Pencil, many of these changes should also prove useful in other workflows too. The main highlights here are: 1) It is now possible to edit Grease Pencil strokes - Use D Tab, or toggle the "Enable Editing" toggles in the Toolbar/Properties regions to enter "Stroke Edit Mode". In this mode, many common editing tools will operate on Grease Pencil stroke points instead. - Tools implemented include Select, Select All/Border/Circle/Linked/More/Less, Grab, Rotate, Scale, Bend, Shear, To Sphere, Mirror, Duplicate, Delete. - Proportional Editing works when using the transform tools 2) Grease Pencil stroke settings can now be animated NOTE: Currently drivers don't work, but if time allows, this may still be added before the release. 3) Strokes can be drawn with "filled" interiors, using a separate set of colour/opacity settings to the ones used for the lines themselves. This makes use of OpenGL filled polys, which has the limitation of only being able to fill convex shapes. Some artifacts may be visible on concave shapes (e.g. pacman's mouth will be overdrawn) 4) "Volumetric Strokes" - An alternative drawing technique for stroke drawing has been added which draws strokes as a series of screen-aligned discs. While this was originally a partial experimental technique at getting better quality 3D lines, the effects possible using this technique were interesting enough to warrant making this a dedicated feature. Best results when partial opacity and large stroke widths are used. 5) Improved Onion Skinning Support - Different colours can be selected for the before/after ghosts. To do so, enable the "colour wheel" toggle beside the Onion Skinning toggle, and set the colours accordingly. - Different numbers of ghosts can be shown before/after the current frame 6) Grease Pencil datablocks are now attached to the scene by default instead of the active object. - For a long time, the object-attachment has proved to be quite problematic for users to keep track of. Now that this is done at scene level, it is easier for most users to use. - An exception for old files (and for any addons which may benefit from object attachment instead), is that if the active object has a Grease Pencil datablock, that will be used instead. - It is not currently possible to choose object-attachment from the UI, but it is simple to do this from the console instead, by doing: context.active_object.grease_pencil = bpy.data.grease_pencil["blah"] 7) Various UI Cleanups - The layers UI has been cleaned up to use a list instead of the nested-panels design. Apart from saving space, this is also much nicer to look at now. - The UI code is now all defined in Python. To support this, it has been necessary to add some new context properties to make it easier to access these settings. e.g. "gpencil_data" for the datablock "active_gpencil_layer" and "active_gpencil_frame" for active data, "editable_gpencil_strokes" for the strokes that can be edited - The "stroke placement/alignment" settings (previously "Drawing Settings" at the bottom of the Grease Pencil panel in the Properties Region) is now located in the toolbar. These were more toolsettings than properties for how GPencil got drawn. - "Use Sketching Sessions" has been renamed "Continuous Drawing", as per a suggestion for an earlier discussion on developer.blender.org - By default, the painting operator will wait for a mouse button to be pressed before it starts creating the stroke. This is to make it easier to include this operator in various toolbars/menus/etc. To get it immediately starting (as when you hold down DKEy to draw), set "wait_for_input" to False. - GPencil Layers can be rearranged in the "Grease Pencil" mode of the Action Editor - Toolbar panels have been added to all the other editors which support these. 8) Pie menus for quick-access to tools A set of experimental pie menus has been included for quick access to many tools and settings. It is not necessary to use these to get things done, but they have been designed to help make certain common tasks easier. - Ctrl-D = The main pie menu. Reveals tools in a context sensitive and spatially stable manner. - D Q = "Quick Settings" pie. This allows quick access to the active layer's settings. Notably, colours, thickness, and turning onion skinning on/off.
2014-12-01 01:52:06 +13:00
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT);
// XXX Shear axis?
}
static void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Push/Pull";
ot->description = "Push/Pull selected items";
ot->idname = OP_PUSH_PULL;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_CENTER);
}
static void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Shrink/Fatten";
ot->description = "Shrink/fatten selected vertices along normals";
ot->idname = OP_SHRINK_FATTEN;
2012-06-10 19:59:02 +00:00
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 = ED_operator_editmesh;
ot->poll_property = transform_poll_property;
RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness");
2012-06-10 19:59:02 +00:00
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP);
}
static void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "To Sphere";
2018-05-13 06:44:03 +02:00
//added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()"
ot->description = "Move selected vertices outward in a spherical shape around mesh center";
ot->idname = OP_TOSPHERE;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP | P_GPENCIL_EDIT | P_CENTER);
}
static void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Mirror";
ot->description = "Mirror selected items around one or more axes";
ot->idname = OP_MIRROR;
2012-06-10 19:59:02 +00:00
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 = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_GPENCIL_EDIT | P_CENTER);
}
static void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
{
PropertyRNA *prop;
/* identifiers */
ot->name = "Edge Slide";
2018-05-13 06:44:03 +02:00
ot->description = "Slide an edge loop along a mesh";
ot->idname = OP_EDGE_SLIDE;
2012-06-10 19:59:02 +00:00
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 = ED_operator_editmesh_region_view3d;
ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
prop = RNA_def_boolean(ot->srna, "single_side", false, "Single Side", "");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
2015-10-12 21:34:14 +02:00
RNA_def_boolean(ot->srna, "use_even", false, "Even",
"Make the edge loop match the shape of the adjacent edge loop");
RNA_def_boolean(ot->srna, "flipped", false, "Flipped",
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp",
"Clamp within the edge extents");
2012-06-10 19:59:02 +00:00
Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
static void TRANSFORM_OT_vert_slide(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Vertex Slide";
ot->description = "Slide a vertex along a mesh";
ot->idname = OP_VERT_SLIDE;
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 = ED_operator_editmesh_region_view3d;
ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -10.0f, 10.0f, "Factor", "", -1.0f, 1.0f);
2015-10-12 21:34:14 +02:00
RNA_def_boolean(ot->srna, "use_even", false, "Even",
"Make the edge loop match the shape of the adjacent edge loop");
RNA_def_boolean(ot->srna, "flipped", false, "Flipped",
"When Even mode is active, flips between the two adjacent edge loops");
RNA_def_boolean(ot->srna, "use_clamp", true, "Clamp",
"Clamp within the edge extents");
Transform_Properties(ot, P_MIRROR | P_SNAP | P_CORRECT_UV);
}
static void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Edge Crease";
ot->description = "Change the crease of edges";
ot->idname = OP_EDGE_CREASE;
2012-06-10 19:59:02 +00:00
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 = ED_operator_editmesh;
ot->poll_property = transform_poll_property;
RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
Transform_Properties(ot, P_SNAP);
}
static int edge_bevelweight_exec(bContext *C, wmOperator *op)
{
Mesh *me = (Mesh *)CTX_data_edit_object(C)->data;
/* auto-enable bevel edge weight drawing, then chain to common transform code */
me->drawflag |= ME_DRAWBWEIGHTS;
return transform_exec(C, op);
}
static int edge_bevelweight_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Mesh *me = (Mesh *)CTX_data_edit_object(C)->data;
/* auto-enable bevel edge weight drawing, then chain to common transform code */
me->drawflag |= ME_DRAWBWEIGHTS;
return transform_invoke(C, op, event);
}
static void TRANSFORM_OT_edge_bevelweight(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Edge Bevel Weight";
ot->description = "Change the bevel weight of edges";
ot->idname = OP_EDGE_BWEIGHT;
2012-06-10 19:59:02 +00:00
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
/* api callbacks */
ot->invoke = edge_bevelweight_invoke;
ot->exec = edge_bevelweight_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_editmesh;
RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
Transform_Properties(ot, P_SNAP);
}
static void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
{
/* identifiers */
ot->name = "Sequence Slide";
ot->description = "Slide a sequence strip in time";
ot->idname = OP_SEQ_SLIDE;
2012-06-10 19:59:02 +00:00
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 = ED_operator_sequencer_active;
RNA_def_float_vector_xyz(ot->srna, "value", 2, NULL, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
Transform_Properties(ot, P_SNAP);
}
static void TRANSFORM_OT_transform(struct wmOperatorType *ot)
2008-12-29 04:14:27 +00:00
{
PropertyRNA *prop;
2008-12-29 04:14:27 +00:00
/* identifiers */
ot->name = "Transform";
ot->description = "Transform selected items by mode type";
ot->idname = "TRANSFORM_OT_transform";
2012-06-10 19:59:02 +00:00
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING;
2008-12-29 04:14:27 +00:00
/* api callbacks */
ot->invoke = transform_invoke;
ot->exec = transform_exec;
ot->modal = transform_modal;
ot->cancel = transform_cancel;
ot->poll = ED_operator_screenactive;
ot->poll_property = transform_poll_property;
2008-12-29 04:14:27 +00:00
prop = RNA_def_enum(ot->srna, "mode", rna_enum_transform_mode_types, TFM_TRANSLATION, "Mode", "");
RNA_def_property_flag(prop, PROP_HIDDEN);
RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
Transform_Properties(
ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_ALIGN_SNAP | P_GPENCIL_EDIT | P_CENTER);
2008-12-29 04:14:27 +00:00
}
void transform_operatortypes(void)
{
TransformModeItem *tmode;
for (tmode = transform_modes; tmode->idname; tmode++) {
WM_operatortype_append(tmode->opfunc);
}
WM_operatortype_append(TRANSFORM_OT_transform);
WM_operatortype_append(TRANSFORM_OT_select_orientation);
WM_operatortype_append(TRANSFORM_OT_create_orientation);
WM_operatortype_append(TRANSFORM_OT_delete_orientation);
2008-12-29 04:14:27 +00:00
}
void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid)
2008-12-29 04:14:27 +00:00
{
wmKeyMapItem *kmi;
wmKeyMap *modalmap;
2018-05-13 06:44:03 +02:00
2.5 Modal keymaps. I've tried to make it as simple as possible, yet still using sufficient facilities to enable self-documenting UIs, saving/reading in files, and proper Python support. The simplicity is: the 'modal keymap' just checks an event, uses event matching similarly to other keymap matching, and if there's a match it changes the event type, and sets the event value to what the modal keymap has defined. The event values are being defined using EnumPropertyItem structs, so the UI will be able to show all options in self-documenting way. This system also allows to still handle hardcoded own events. Tech doc: 1) define keymap - Create map with unique name, WM_modalkeymap_add() - Give map property definitions (EnumPropertyItem *) This only for UI, so user can get information on available options 2) items - WM_modalkeymap_add_item(): give it an enum value for events 3) activate - In keymap definition code, assign the modal keymap to operatortype WM_modalkeymap_assign() 4) event manager - The event handler will check for modal keymap, if so: - If the modal map has a match: - Sets event->type to EVT_MODAL_MAP - Sets event->val to the enum value 5) modal handler - If event type is EVT_MODAL_MAP: - Check event->val, handle it - Other events can just be handled still Two examples added in the code: editors/transform/transform.c: transform_modal_keymap() editors/screen/screen_ops.c: keymap_modal_set() Also: to support 'key release' the define KM_RELEASE now is officially used in event manager, this is not '0', so don't check key events with the old convention if(event->val) but use if(event->val==KM_PRESS)
2009-07-21 11:03:07 +00:00
/* transform.c, only adds modal map once, checks if it's there */
modalmap = transform_modal_keymap(keyconf);
/* assign map to operators only the first time */
if (modalmap) {
TransformModeItem *tmode;
for (tmode = transform_modes; tmode->idname; tmode++) {
WM_modalkeymap_assign(modalmap, tmode->idname);
}
WM_modalkeymap_assign(modalmap, "TRANSFORM_OT_transform");
}
2018-05-13 06:44:03 +02:00
switch (spaceid) {
2008-12-29 04:14:27 +00:00
case SPACE_VIEW3D:
WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
2008-12-29 04:14:27 +00:00
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
2008-12-29 04:14:27 +00:00
2013-11-20 12:14:10 +11:00
WM_keymap_add_item(keymap, OP_BEND, WKEY, KM_PRESS, KM_SHIFT, 0);
2008-12-29 04:14:27 +00:00
2012-06-10 19:59:02 +00:00
WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
2012-06-10 19:59:02 +00:00
WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
2012-06-10 19:59:02 +00:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL | KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "use", true);
WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_element");
kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "texture_space", true);
2012-06-10 19:59:02 +00:00
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);
2008-12-29 04:14:27 +00:00
break;
case SPACE_ACTION:
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SLIDE);
break;
case SPACE_IPO:
WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
2018-05-13 06:44:03 +02:00
WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
2018-05-13 06:44:03 +02:00
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
2018-05-13 06:44:03 +02:00
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
break;
case SPACE_NLA:
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
2018-05-13 06:44:03 +02:00
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
break;
case SPACE_NODE:
WM_keymap_add_item(keymap, "NODE_OT_translate_attach", GKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_translate_attach", EVT_TWEAK_A, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, "NODE_OT_translate_attach", EVT_TWEAK_S, KM_ANY, 0, 0);
/* NB: small trick: macro operator poll may fail due to library data edit,
* in that case the secondary regular operators are called with same keymap.
*/
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_A, KM_ANY, 0, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
RNA_boolean_set(kmi->ptr, "release_confirm", true);
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
Implements a new operator for detaching nodes. In the process i overhauled the node muting system as well. There are a number of features that use a kind of "internal linking" in nodes: 1. muting 2. delete + reconnect (restore link to/from node after delete) 3. the new detach operator (same as 2, but don't delete the node) The desired behavior in all cases is the same: find a sensible mapping of inputs-to-outputs of a node. In the case of muting these links are displayed in red on the node itself. For the other operators they are used to relink connections, such that one gets the best possible ongoing link between previous up- and downstream nodes. Muting previously used a complicated callback system to ensure consistent behavior in the editor as well as execution in compositor, shader cpu/gpu and texture nodes. This has been greatly simplified by moving the muting step into the node tree localization functions. Any muted node is now bypassed using the generalized nodeInternalRelink function and then removed from the local tree. This way the internal execution system doesn't have to deal with muted nodes at all, as if they are non-existent. The same function is also used by the delete_reconnect and the new links_detach operators (which work directly in the editor node tree). Detaching nodes is currently keymapped as a translation variant (macro operator): pressing ALTKEY + moving node first detaches and then continues with regular transform operator. The default key is ALT+DKEY though, instead ALT+GKEY, since the latter is already used for the ungroup operator.
2012-02-27 17:38:16 +00:00
/* detach and translate */
WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", DKEY, KM_PRESS, KM_ALT, 0);
/* XXX release_confirm is set in the macro operator definition */
WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
Implements a new operator for detaching nodes. In the process i overhauled the node muting system as well. There are a number of features that use a kind of "internal linking" in nodes: 1. muting 2. delete + reconnect (restore link to/from node after delete) 3. the new detach operator (same as 2, but don't delete the node) The desired behavior in all cases is the same: find a sensible mapping of inputs-to-outputs of a node. In the case of muting these links are displayed in red on the node itself. For the other operators they are used to relink connections, such that one gets the best possible ongoing link between previous up- and downstream nodes. Muting previously used a complicated callback system to ensure consistent behavior in the editor as well as execution in compositor, shader cpu/gpu and texture nodes. This has been greatly simplified by moving the muting step into the node tree localization functions. Any muted node is now bypassed using the generalized nodeInternalRelink function and then removed from the local tree. This way the internal execution system doesn't have to deal with muted nodes at all, as if they are non-existent. The same function is also used by the delete_reconnect and the new links_detach operators (which work directly in the editor node tree). Detaching nodes is currently keymapped as a translation variant (macro operator): pressing ALTKEY + moving node first detaches and then continues with regular transform operator. The default key is ALT+DKEY though, instead ALT+GKEY, since the latter is already used for the ungroup operator.
2012-02-27 17:38:16 +00:00
WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_node_element");
break;
case SPACE_SEQ:
WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_SEQ_SLIDE, EVT_TWEAK_S, KM_ANY, 0, 0);
kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
break;
case SPACE_IMAGE:
WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
2012-06-10 19:59:02 +00:00
WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT | KM_CTRL | KM_SHIFT, 0);
WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", TABKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
RNA_string_set(kmi->ptr, "data_path", "tool_settings.snap_uv_element");
break;
Camera tracking integration =========================== Commiting camera tracking integration gsoc project into trunk. This commit includes: - Bundled version of libmv library (with some changes against official repo, re-sync with libmv repo a bit later) - New datatype ID called MovieClip which is optimized to work with movie clips (both of movie files and image sequences) and doing camera/motion tracking operations. - New editor called Clip Editor which is currently used for motion/tracking stuff only, but which can be easily extended to work with masks too. This editor supports: * Loading movie files/image sequences * Build proxies with different size for loaded movie clip, also supports building undistorted proxies to increase speed of playback in undistorted mode. * Manual lens distortion mode calibration using grid and grease pencil * Supervised 2D tracking using two different algorithms KLT and SAD. * Basic algorithm for feature detection * Camera motion solving. scene orientation - New constraints to "link" scene objects with solved motions from clip: * Follow Track (make object follow 2D motion of track with given name or parent object to reconstructed 3D position of track) * Camera Solver to make camera moving in the same way as reconstructed camera This commit NOT includes changes from tomato branch: - New nodes (they'll be commited as separated patch) - Automatic image offset guessing for image input node and image editor (need to do more tests and gather more feedback) - Code cleanup in libmv-capi. It's not so critical cleanup, just increasing readability and understanadability of code. Better to make this chaneg when Keir will finish his current patch. More details about this project can be found on this page: http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2011 Further development of small features would be done in trunk, bigger/experimental features would first be implemented in tomato branch.
2011-11-07 12:55:18 +00:00
case SPACE_CLIP:
WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
Planar tracking support for motion tracking =========================================== Major list of changes done in tomato branch: - Add a planar tracking implementation to libmv This adds a new planar tracking implementation to libmv. The tracker is based on Ceres[1], the new nonlinear minimizer that myself and Sameer released from Google as open source. Since the motion model is more involved, the interface is different than the RegionTracker interface used previously in Blender. The start of a C API in libmv-capi.{cpp,h} is also included. - Migrate from pat_{min,max} for markers to 4 corners representation Convert markers in the movie clip editor / 2D tracker from using pat_min and pat_max notation to using the a more general, 4-corner representation. There is still considerable porting work to do; in particular sliding from preview widget does not work correct for rotated markers. All other areas should be ported to new representation: * Added support of sliding individual corners. LMB slide + Ctrl would scale the whole pattern * S would scale the whole marker, S-S would scale pattern only * Added support of marker's rotation which is currently rotates only patterns around their centers or all markers around median, Rotation or other non-translation/scaling transformation of search area doesn't make sense. * Track Preview widget would display transformed pattern which libmv actually operates with. - "Efficient Second-order Minimization" for the planar tracker This implements the "Efficient Second-order Minimization" scheme, as supported by the existing translation tracker. This increases the amount of per-iteration work, but decreases the number of iterations required to converge and also increases the size of the basin of attraction for the optimization. - Remove the use of the legacy RegionTracker API from Blender, and replaces it with the new TrackRegion API. This also adds several features to the planar tracker in libmv: * Do a brute-force initialization of tracking similar to "Hybrid" mode in the stable release, but using all floats. This is slower but more accurate. It is still necessary to evaluate if the performance loss is worth it. In particular, this change is necessary to support high bit depth imagery. * Add support for masks over the search window. This is a step towards supporting user-defined tracker masks. The tracker masks will make it easy for users to make a mask for e.g. a ball. Not exposed into interface yet/ * Add Pearson product moment correlation coefficient checking (aka "Correlation" in the UI. This causes tracking failure if the tracked patch is not linearly related to the template. * Add support for warping a few points in addition to the supplied points. This is useful because the tracking code deliberately does not expose the underlying warp representation. Instead, warps are specified in an aparametric way via the correspondences. - Replace the old style tracker configuration panel with the new planar tracking panel. From a users perspective, this means: * The old "tracking algorithm" picker is gone. There is only 1 algorithm now. We may revisit this later, but I would much prefer to have only 1 algorithm. So far no optimization work has been done so the speed is not there yet. * There is now a dropdown to select the motion model. Choices: * Translation * Translation, rotation * Translation, scale * Translation, rotation, scale * Affine * Perspective * The old "Hybrid" mode is gone; instead there is a toggle to enable or disable translation-only tracker initialization. This is the equivalent of the hyrbid mode before, but rewritten to work with the new planar tracking modes. * The pyramid levels setting is gone. At a future date, the planar tracker will decide to use pyramids or not automatically. The pyramid setting was ultimately a mistake; with the brute force initialization it is unnecessary. - Add light-normalized tracking Added the ability to normalize patterns by their average value while tracking, to make them invariant to global illumination changes. Additional details could be found at wiki page [2] [1] http://code.google.com/p/ceres-solver [2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
Camera tracking integration =========================== Commiting camera tracking integration gsoc project into trunk. This commit includes: - Bundled version of libmv library (with some changes against official repo, re-sync with libmv repo a bit later) - New datatype ID called MovieClip which is optimized to work with movie clips (both of movie files and image sequences) and doing camera/motion tracking operations. - New editor called Clip Editor which is currently used for motion/tracking stuff only, but which can be easily extended to work with masks too. This editor supports: * Loading movie files/image sequences * Build proxies with different size for loaded movie clip, also supports building undistorted proxies to increase speed of playback in undistorted mode. * Manual lens distortion mode calibration using grid and grease pencil * Supervised 2D tracking using two different algorithms KLT and SAD. * Basic algorithm for feature detection * Camera motion solving. scene orientation - New constraints to "link" scene objects with solved motions from clip: * Follow Track (make object follow 2D motion of track with given name or parent object to reconstructed 3D position of track) * Camera Solver to make camera moving in the same way as reconstructed camera This commit NOT includes changes from tomato branch: - New nodes (they'll be commited as separated patch) - Automatic image offset guessing for image input node and image editor (need to do more tests and gather more feedback) - Code cleanup in libmv-capi. It's not so critical cleanup, just increasing readability and understanadability of code. Better to make this chaneg when Keir will finish his current patch. More details about this project can be found on this page: http://wiki.blender.org/index.php/User:Nazg-gul/GSoC-2011 Further development of small features would be done in trunk, bigger/experimental features would first be implemented in tomato branch.
2011-11-07 12:55:18 +00:00
break;
2008-12-29 04:14:27 +00:00
default:
break;
}
}