svn merge ^/trunk/blender -r55594:55635
[blender.git] / source / blender / editors / render / render_shading.c
index 979ccf3cf023c3defec27c0ebebab0ced50be138..5652d4c4b71744a8f7a8e9dd8557fa7fba462a92 100644 (file)
 #include "BKE_curve.h"
 #include "BKE_depsgraph.h"
 #include "BKE_font.h"
+#include "BKE_freestyle.h"
 #include "BKE_global.h"
 #include "BKE_icons.h"
 #include "BKE_image.h"
 #include "BKE_library.h"
+#include "BKE_linestyle.h"
 #include "BKE_main.h"
 #include "BKE_material.h"
 #include "BKE_node.h"
 
 #include "GPU_material.h"
 
+#ifdef WITH_FREESTYLE
+#  include "FRS_freestyle.h"
+#endif
+
 #include "RNA_access.h"
+#include "RNA_enum_types.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -577,6 +584,624 @@ void SCENE_OT_render_layer_remove(wmOperatorType *ot)
        ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+#ifdef WITH_FREESTYLE
+
+static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       BKE_freestyle_module_add(&srl->freestyleConfig);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Freestyle Module";
+       ot->idname = "SCENE_OT_freestyle_module_add";
+       ot->description = "Add a style module into the list of modules";
+
+       /* api callbacks */
+       ot->exec = freestyle_module_add_exec;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
+       FreestyleModuleConfig *module = ptr.data;
+
+       BKE_freestyle_module_delete(&srl->freestyleConfig, module);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Remove Freestyle Module";
+       ot->idname = "SCENE_OT_freestyle_module_remove";
+       ot->description = "Remove the style module from the stack";
+
+       /* api callbacks */
+       ot->exec = freestyle_module_remove_exec;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_module_move_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
+       FreestyleModuleConfig *module = ptr.data;
+       int dir = RNA_enum_get(op->ptr, "direction");
+
+       if (dir == 1) {
+               BKE_freestyle_module_move_up(&srl->freestyleConfig, module);
+       }
+       else {
+               BKE_freestyle_module_move_down(&srl->freestyleConfig, module);
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
+{
+       static EnumPropertyItem direction_items[] = {
+               {1, "UP", 0, "Up", ""},
+               {-1, "DOWN", 0, "Down", ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+
+       /* identifiers */
+       ot->name = "Move Freestyle Module";
+       ot->idname = "SCENE_OT_freestyle_module_move";
+       ot->description = "Change the position of the style module within in the list of style modules";
+
+       /* api callbacks */
+       ot->exec = freestyle_module_move_exec;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* props */
+       RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
+static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       BKE_freestyle_lineset_add(&srl->freestyleConfig);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Line Set";
+       ot->idname = "SCENE_OT_freestyle_lineset_add";
+       ot->description = "Add a line set into the list of line sets";
+
+       /* api callbacks */
+       ot->exec = freestyle_lineset_add_exec;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_active_lineset_poll(bContext *C)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       return BKE_freestyle_lineset_get_active(&srl->freestyleConfig) != NULL;
+}
+
+static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       FRS_copy_active_lineset(&srl->freestyleConfig);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Copy Line Set";
+       ot->idname = "SCENE_OT_freestyle_lineset_copy";
+       ot->description = "Copy the active line set to a buffer";
+
+       /* api callbacks */
+       ot->exec = freestyle_lineset_copy_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       FRS_paste_active_lineset(&srl->freestyleConfig);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Paste Line Set";
+       ot->idname = "SCENE_OT_freestyle_lineset_paste";
+       ot->description = "Paste the buffer content to the active line set";
+
+       /* api callbacks */
+       ot->exec = freestyle_lineset_paste_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+
+       FRS_delete_active_lineset(&srl->freestyleConfig);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Remove Line Set";
+       ot->idname = "SCENE_OT_freestyle_lineset_remove";
+       ot->description = "Remove the active line set from the list of line sets";
+
+       /* api callbacks */
+       ot->exec = freestyle_lineset_remove_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       int dir = RNA_enum_get(op->ptr, "direction");
+
+       if (dir == 1) {
+               FRS_move_active_lineset_up(&srl->freestyleConfig);
+       }
+       else {
+               FRS_move_active_lineset_down(&srl->freestyleConfig);
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
+{
+       static EnumPropertyItem direction_items[] = {
+               {1, "UP", 0, "Up", ""},
+               {-1, "DOWN", 0, "Down", ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+
+       /* identifiers */
+       ot->name = "Move Line Set";
+       ot->idname = "SCENE_OT_freestyle_lineset_move";
+       ot->description = "Change the position of the active line set within the list of line sets";
+
+       /* api callbacks */
+       ot->exec = freestyle_lineset_move_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* props */
+       RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
+static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
+               return OPERATOR_CANCELLED;
+       }
+       lineset->linestyle->id.us--;
+       lineset->linestyle = BKE_copy_linestyle(lineset->linestyle);
+
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "New Line Style";
+       ot->idname = "SCENE_OT_freestyle_linestyle_new";
+       ot->description = "Create a new line style, reusable by multiple line sets";
+
+       /* api callbacks */
+       ot->exec = freestyle_linestyle_new_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       int type = RNA_enum_get(op->ptr, "type");
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+               return OPERATOR_CANCELLED;
+       }
+       if (BKE_add_linestyle_color_modifier(lineset->linestyle, type) == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type.");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Line Color Modifier";
+       ot->idname = "SCENE_OT_freestyle_color_modifier_add";
+       ot->description = "Add a line color modifier to the line style associated with the active lineset";
+
+       /* api callbacks */
+       ot->invoke = WM_menu_invoke;
+       ot->exec = freestyle_color_modifier_add_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       ot->prop = RNA_def_enum(ot->srna, "type", linestyle_color_modifier_type_items, 0, "Type", "");
+}
+
+static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       int type = RNA_enum_get(op->ptr, "type");
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+               return OPERATOR_CANCELLED;
+       }
+       if (BKE_add_linestyle_alpha_modifier(lineset->linestyle, type) == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Alpha Transparency Modifier";
+       ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
+       ot->description = "Add an alpha transparency modifier to the line style associated with the active lineset";
+
+       /* api callbacks */
+       ot->invoke = WM_menu_invoke;
+       ot->exec = freestyle_alpha_modifier_add_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       ot->prop = RNA_def_enum(ot->srna, "type", linestyle_alpha_modifier_type_items, 0, "Type", "");
+}
+
+static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       int type = RNA_enum_get(op->ptr, "type");
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+               return OPERATOR_CANCELLED;
+       }
+       if (BKE_add_linestyle_thickness_modifier(lineset->linestyle, type) == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Line Thickness Modifier";
+       ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
+       ot->description = "Add a line thickness modifier to the line style associated with the active lineset";
+
+       /* api callbacks */
+       ot->invoke = WM_menu_invoke;
+       ot->exec = freestyle_thickness_modifier_add_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       ot->prop = RNA_def_enum(ot->srna, "type", linestyle_thickness_modifier_type_items, 0, "Type", "");
+}
+
+static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       int type = RNA_enum_get(op->ptr, "type");
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style to add the modifier to");
+               return OPERATOR_CANCELLED;
+       }
+       if (BKE_add_linestyle_geometry_modifier(lineset->linestyle, type) == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Add Stroke Geometry Modifier";
+       ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
+       ot->description = "Add a stroke geometry modifier to the line style associated with the active lineset";
+
+       /* api callbacks */
+       ot->invoke = WM_menu_invoke;
+       ot->exec = freestyle_geometry_modifier_add_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* properties */
+       ot->prop = RNA_def_enum(ot->srna, "type", linestyle_geometry_modifier_type_items, 0, "Type", "");
+}
+
+static int freestyle_get_modifier_type(PointerRNA *ptr)
+{
+       if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
+               return LS_MODIFIER_TYPE_COLOR;
+       else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
+               return LS_MODIFIER_TYPE_ALPHA;
+       else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
+               return LS_MODIFIER_TYPE_THICKNESS;
+       else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
+               return LS_MODIFIER_TYPE_GEOMETRY;
+       return -1;
+}
+
+static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+       LineStyleModifier *modifier = ptr.data;
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+               return OPERATOR_CANCELLED;
+       }
+
+       switch (freestyle_get_modifier_type(&ptr)) {
+       case LS_MODIFIER_TYPE_COLOR:
+               BKE_remove_linestyle_color_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_ALPHA:
+               BKE_remove_linestyle_alpha_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_THICKNESS:
+               BKE_remove_linestyle_thickness_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_GEOMETRY:
+               BKE_remove_linestyle_geometry_modifier(lineset->linestyle, modifier);
+               break;
+       default:
+               BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Remove Modifier";
+       ot->idname = "SCENE_OT_freestyle_modifier_remove";
+       ot->description = "Remove the modifier from the list of modifiers";
+
+       /* api callbacks */
+       ot->exec = freestyle_modifier_remove_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+       LineStyleModifier *modifier = ptr.data;
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+               return OPERATOR_CANCELLED;
+       }
+
+       switch (freestyle_get_modifier_type(&ptr)) {
+       case LS_MODIFIER_TYPE_COLOR:
+               BKE_copy_linestyle_color_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_ALPHA:
+               BKE_copy_linestyle_alpha_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_THICKNESS:
+               BKE_copy_linestyle_thickness_modifier(lineset->linestyle, modifier);
+               break;
+       case LS_MODIFIER_TYPE_GEOMETRY:
+               BKE_copy_linestyle_geometry_modifier(lineset->linestyle, modifier);
+               break;
+       default:
+               BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name = "Copy Modifier";
+       ot->idname = "SCENE_OT_freestyle_modifier_copy";
+       ot->description = "Duplicate the modifier within the list of modifiers";
+
+       /* api callbacks */
+       ot->exec = freestyle_modifier_copy_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
+{
+       Scene *scene = CTX_data_scene(C);
+       SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
+       FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
+       PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
+       LineStyleModifier *modifier = ptr.data;
+       int dir = RNA_enum_get(op->ptr, "direction");
+
+       if (!lineset) {
+               BKE_report(op->reports, RPT_ERROR, "No active lineset and associated line style the modifier belongs to");
+               return OPERATOR_CANCELLED;
+       }
+
+       switch (freestyle_get_modifier_type(&ptr)) {
+       case LS_MODIFIER_TYPE_COLOR:
+               BKE_move_linestyle_color_modifier(lineset->linestyle, modifier, dir);
+               break;
+       case LS_MODIFIER_TYPE_ALPHA:
+               BKE_move_linestyle_alpha_modifier(lineset->linestyle, modifier, dir);
+               break;
+       case LS_MODIFIER_TYPE_THICKNESS:
+               BKE_move_linestyle_thickness_modifier(lineset->linestyle, modifier, dir);
+               break;
+       case LS_MODIFIER_TYPE_GEOMETRY:
+               BKE_move_linestyle_geometry_modifier(lineset->linestyle, modifier, dir);
+               break;
+       default:
+               BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
+               return OPERATOR_CANCELLED;
+       }
+       WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
+
+       return OPERATOR_FINISHED;
+}
+
+void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
+{
+       static EnumPropertyItem direction_items[] = {
+               {1, "UP", 0, "Up", ""},
+               {-1, "DOWN", 0, "Down", ""},
+               {0, NULL, 0, NULL, NULL}
+       };
+
+       /* identifiers */
+       ot->name = "Move Modifier";
+       ot->idname = "SCENE_OT_freestyle_modifier_move";
+       ot->description = "Move the modifier within the list of modifiers";
+
+       /* api callbacks */
+       ot->exec = freestyle_modifier_move_exec;
+       ot->poll = freestyle_active_lineset_poll;
+
+       /* flags */
+       ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+       /* props */
+       RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction", "Direction to move, UP or DOWN");
+}
+
+#endif /* WITH_FREESTYLE */
+
 static int texture_slot_move(bContext *C, wmOperator *op)
 {
        ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;