2 * ***** BEGIN GPL LICENSE BLOCK *****
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software Foundation,
15 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * The Original Code is Copyright (C) 2009 Blender Foundation.
18 * All rights reserved.
20 * Contributor(s): Blender Foundation
22 * ***** END GPL LICENSE BLOCK *****
25 /** \file blender/editors/render/render_shading.c
32 #include "MEM_guardedalloc.h"
34 #include "DNA_curve_types.h"
35 #include "DNA_lamp_types.h"
36 #include "DNA_material_types.h"
37 #include "DNA_node_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_particle_types.h"
40 #include "DNA_scene_types.h"
41 #include "DNA_space_types.h"
42 #include "DNA_world_types.h"
44 #include "BLI_utildefines.h"
45 #include "BLI_listbase.h"
46 #include "BLI_math_vector.h"
48 #include "BLT_translation.h"
50 #include "BKE_animsys.h"
51 #include "BKE_context.h"
52 #include "BKE_curve.h"
53 #include "BKE_depsgraph.h"
55 #include "BKE_global.h"
56 #include "BKE_image.h"
57 #include "BKE_library.h"
58 #include "BKE_linestyle.h"
60 #include "BKE_material.h"
61 #include "BKE_paint.h"
62 #include "BKE_report.h"
63 #include "BKE_scene.h"
64 #include "BKE_texture.h"
65 #include "BKE_world.h"
66 #include "BKE_editmesh.h"
71 # include "BKE_freestyle.h"
72 # include "FRS_freestyle.h"
73 # include "RNA_enum_types.h"
76 #include "RNA_access.h"
81 #include "ED_object.h"
85 #include "ED_render.h"
86 #include "ED_screen.h"
88 #include "RNA_define.h"
90 #include "UI_interface.h"
92 #include "RE_pipeline.h"
94 #include "render_intern.h" // own include
96 /********************** material slot operators *********************/
98 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
100 Main *bmain = CTX_data_main(C);
101 Object *ob = ED_object_context(C);
104 return OPERATOR_CANCELLED;
106 BKE_object_material_slot_add(bmain, ob);
108 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
109 Scene *scene = CTX_data_scene(C);
110 BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
111 WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
114 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
115 WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
116 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
118 return OPERATOR_FINISHED;
121 void OBJECT_OT_material_slot_add(wmOperatorType *ot)
124 ot->name = "Add Material Slot";
125 ot->idname = "OBJECT_OT_material_slot_add";
126 ot->description = "Add a new material slot";
129 ot->exec = material_slot_add_exec;
130 ot->poll = ED_operator_object_active_editable;
133 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
136 static int material_slot_remove_exec(bContext *C, wmOperator *op)
138 Object *ob = ED_object_context(C);
141 return OPERATOR_CANCELLED;
143 /* Removing material slots in edit mode screws things up, see bug #21822.*/
144 if (ob == CTX_data_edit_object(C)) {
145 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
146 return OPERATOR_CANCELLED;
149 BKE_object_material_slot_remove(CTX_data_main(C), ob);
151 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
152 Scene *scene = CTX_data_scene(C);
153 BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
154 WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
157 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
158 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
159 WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
160 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
162 return OPERATOR_FINISHED;
165 void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
168 ot->name = "Remove Material Slot";
169 ot->idname = "OBJECT_OT_material_slot_remove";
170 ot->description = "Remove the selected material slot";
173 ot->exec = material_slot_remove_exec;
174 ot->poll = ED_operator_object_active_editable;
177 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
180 static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
182 Object *ob = ED_object_context(C);
185 return OPERATOR_CANCELLED;
187 if (ob && ob->actcol > 0) {
188 if (ob->type == OB_MESH) {
189 BMEditMesh *em = BKE_editmesh_from_object(ob);
194 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
195 if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
196 efa->mat_nr = ob->actcol - 1;
200 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
202 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
205 for (nu = nurbs->first; nu; nu = nu->next) {
206 if (ED_curve_nurb_select_check(ob->data, nu)) {
207 nu->mat_nr = ob->actcol - 1;
212 else if (ob->type == OB_FONT) {
213 EditFont *ef = ((Curve *)ob->data)->editfont;
214 int i, selstart, selend;
216 if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
217 for (i = selstart; i <= selend; i++)
218 ef->textbufinfo[i].mat_nr = ob->actcol;
223 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
224 WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
226 return OPERATOR_FINISHED;
229 void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
232 ot->name = "Assign Material Slot";
233 ot->idname = "OBJECT_OT_material_slot_assign";
234 ot->description = "Assign active material slot to selection";
237 ot->exec = material_slot_assign_exec;
238 ot->poll = ED_operator_object_active_editable;
241 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
244 static int material_slot_de_select(bContext *C, bool select)
246 Object *ob = ED_object_context(C);
249 return OPERATOR_CANCELLED;
251 if (ob->type == OB_MESH) {
252 BMEditMesh *em = BKE_editmesh_from_object(ob);
255 EDBM_deselect_by_material(em, ob->actcol - 1, select);
258 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
259 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
266 for (nu = nurbs->first; nu; nu = nu->next) {
267 if (nu->mat_nr == ob->actcol - 1) {
272 if (bezt->hide == 0) {
288 a = nu->pntsu * nu->pntsv;
292 if (select) bp->f1 |= SELECT;
293 else bp->f1 &= ~SELECT;
303 WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
305 return OPERATOR_FINISHED;
308 static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
310 return material_slot_de_select(C, true);
313 void OBJECT_OT_material_slot_select(wmOperatorType *ot)
316 ot->name = "Select Material Slot";
317 ot->idname = "OBJECT_OT_material_slot_select";
318 ot->description = "Select by active material slot";
321 ot->exec = material_slot_select_exec;
324 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
327 static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
329 return material_slot_de_select(C, false);
332 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
335 ot->name = "Deselect Material Slot";
336 ot->idname = "OBJECT_OT_material_slot_deselect";
337 ot->description = "Deselect by active material slot";
340 ot->exec = material_slot_deselect_exec;
343 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
347 static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
349 Main *bmain = CTX_data_main(C);
350 Object *ob = ED_object_context(C);
353 if (!ob || !(matar = give_matarar(ob)))
354 return OPERATOR_CANCELLED;
356 CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects)
358 if (ob != ob_iter && give_matarar(ob_iter)) {
359 if (ob->data != ob_iter->data)
360 assign_matarar(bmain, ob_iter, matar, ob->totcol);
362 if (ob_iter->totcol == ob->totcol) {
363 ob_iter->actcol = ob->actcol;
364 DAG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
365 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
371 return OPERATOR_FINISHED;
375 void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
378 ot->name = "Copy Material to Others";
379 ot->idname = "OBJECT_OT_material_slot_copy";
380 ot->description = "Copies materials to other selected objects";
383 ot->exec = material_slot_copy_exec;
386 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
389 static int material_slot_move_exec(bContext *C, wmOperator *op)
391 Object *ob = ED_object_context(C);
393 unsigned int *slot_remap;
396 int dir = RNA_enum_get(op->ptr, "direction");
398 if (!ob || ob->totcol < 2) {
399 return OPERATOR_CANCELLED;
403 if (dir == 1 && ob->actcol > 1) {
404 index_pair[0] = ob->actcol - 2;
405 index_pair[1] = ob->actcol - 1;
409 else if (dir == -1 && ob->actcol < ob->totcol) {
410 index_pair[0] = ob->actcol - 1;
411 index_pair[1] = ob->actcol - 0;
415 return OPERATOR_CANCELLED;
418 slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
420 range_vn_u(slot_remap, ob->totcol, 0);
422 slot_remap[index_pair[0]] = index_pair[1];
423 slot_remap[index_pair[1]] = index_pair[0];
425 BKE_material_remap_object(ob, slot_remap);
427 MEM_freeN(slot_remap);
429 DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
430 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
431 WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
433 return OPERATOR_FINISHED;
436 void OBJECT_OT_material_slot_move(wmOperatorType *ot)
438 static const EnumPropertyItem material_slot_move[] = {
439 {1, "UP", 0, "Up", ""},
440 {-1, "DOWN", 0, "Down", ""},
441 {0, NULL, 0, NULL, NULL}
445 ot->name = "Move Material";
446 ot->idname = "OBJECT_OT_material_slot_move";
447 ot->description = "Move the active material up/down in the list";
450 ot->exec = material_slot_move_exec;
453 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
455 RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction",
456 "Direction to move the active material towards");
459 /********************** new material operator *********************/
461 static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
463 Scene *scene = CTX_data_scene(C);
464 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
465 Main *bmain = CTX_data_main(C);
466 PointerRNA ptr, idptr;
469 /* add or copy material */
471 ma = BKE_material_copy(bmain, ma);
474 ma = BKE_material_add(bmain, DATA_("Material"));
476 if (BKE_scene_use_new_shading_nodes(scene)) {
477 ED_node_shader_default(C, &ma->id);
478 ma->use_nodes = true;
483 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
486 if (RNA_struct_is_a(ptr.type, &RNA_Object)) {
487 /* Add slot follows user-preferences for creating new slots,
488 * RNA pointer assignment doesn't, see: T60014. */
489 Object *ob = ptr.data;
490 if (give_current_material_p(ob, ob->actcol) == NULL) {
491 BKE_object_material_slot_add(bmain, ob);
495 /* when creating new ID blocks, use is already 1, but RNA
496 * pointer use also increases user, so this compensates it */
499 RNA_id_pointer_create(&ma->id, &idptr);
500 RNA_property_pointer_set(&ptr, prop, idptr);
501 RNA_property_update(C, &ptr, prop);
504 WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
506 return OPERATOR_FINISHED;
509 void MATERIAL_OT_new(wmOperatorType *ot)
512 ot->name = "New Material";
513 ot->idname = "MATERIAL_OT_new";
514 ot->description = "Add a new material";
517 ot->exec = new_material_exec;
520 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
523 /********************** new texture operator *********************/
525 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
527 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
528 Main *bmain = CTX_data_main(C);
529 PointerRNA ptr, idptr;
532 /* add or copy texture */
534 tex = BKE_texture_copy(bmain, tex);
537 tex = BKE_texture_add(bmain, DATA_("Texture"));
541 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
544 /* when creating new ID blocks, use is already 1, but RNA
545 * pointer use also increases user, so this compensates it */
548 if (ptr.id.data && GS(((ID *)ptr.id.data)->name) == ID_MA &&
549 RNA_property_pointer_get(&ptr, prop).id.data == NULL)
551 /* In case we are assigning new texture to a material, and active slot was empty, reset 'use' flag. */
552 Material *ma = (Material *)ptr.id.data;
553 ma->septex &= ~(1 << ma->texact);
556 RNA_id_pointer_create(&tex->id, &idptr);
557 RNA_property_pointer_set(&ptr, prop, idptr);
558 RNA_property_update(C, &ptr, prop);
561 WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
563 return OPERATOR_FINISHED;
566 void TEXTURE_OT_new(wmOperatorType *ot)
569 ot->name = "New Texture";
570 ot->idname = "TEXTURE_OT_new";
571 ot->description = "Add a new texture";
574 ot->exec = new_texture_exec;
577 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
580 /********************** new world operator *********************/
582 static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
584 Scene *scene = CTX_data_scene(C);
585 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
586 Main *bmain = CTX_data_main(C);
587 PointerRNA ptr, idptr;
590 /* add or copy world */
592 wo = BKE_world_copy(bmain, wo);
595 wo = BKE_world_add(bmain, DATA_("World"));
597 if (BKE_scene_use_new_shading_nodes(scene)) {
598 ED_node_shader_default(C, &wo->id);
599 wo->use_nodes = true;
604 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
607 /* when creating new ID blocks, use is already 1, but RNA
608 * pointer use also increases user, so this compensates it */
611 RNA_id_pointer_create(&wo->id, &idptr);
612 RNA_property_pointer_set(&ptr, prop, idptr);
613 RNA_property_update(C, &ptr, prop);
616 WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
618 return OPERATOR_FINISHED;
621 void WORLD_OT_new(wmOperatorType *ot)
624 ot->name = "New World";
625 ot->idname = "WORLD_OT_new";
626 ot->description = "Create a new world Data-Block";
629 ot->exec = new_world_exec;
632 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
635 /********************** render layer operators *********************/
637 static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
639 Scene *scene = CTX_data_scene(C);
641 BKE_scene_add_render_layer(scene, NULL);
642 scene->r.actlay = BLI_listbase_count(&scene->r.layers) - 1;
644 DAG_id_tag_update(&scene->id, 0);
645 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
647 return OPERATOR_FINISHED;
650 void SCENE_OT_render_layer_add(wmOperatorType *ot)
653 ot->name = "Add Render Layer";
654 ot->idname = "SCENE_OT_render_layer_add";
655 ot->description = "Add a render layer";
658 ot->exec = render_layer_add_exec;
661 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
664 static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
666 Scene *scene = CTX_data_scene(C);
667 SceneRenderLayer *rl = BLI_findlink(&scene->r.layers, scene->r.actlay);
669 if (!BKE_scene_remove_render_layer(CTX_data_main(C), scene, rl))
670 return OPERATOR_CANCELLED;
672 DAG_id_tag_update(&scene->id, 0);
673 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
675 return OPERATOR_FINISHED;
678 void SCENE_OT_render_layer_remove(wmOperatorType *ot)
681 ot->name = "Remove Render Layer";
682 ot->idname = "SCENE_OT_render_layer_remove";
683 ot->description = "Remove the selected render layer";
686 ot->exec = render_layer_remove_exec;
689 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
692 /********************** render view operators *********************/
694 static bool render_view_remove_poll(bContext *C)
696 Scene *scene = CTX_data_scene(C);
698 /* don't allow user to remove "left" and "right" views */
699 return scene->r.actview > 1;
702 static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
704 Scene *scene = CTX_data_scene(C);
706 BKE_scene_add_render_view(scene, NULL);
707 scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
709 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
711 return OPERATOR_FINISHED;
714 void SCENE_OT_render_view_add(wmOperatorType *ot)
717 ot->name = "Add Render View";
718 ot->idname = "SCENE_OT_render_view_add";
719 ot->description = "Add a render view";
722 ot->exec = render_view_add_exec;
725 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
728 static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
730 Scene *scene = CTX_data_scene(C);
731 SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
733 if (!BKE_scene_remove_render_view(scene, rv))
734 return OPERATOR_CANCELLED;
736 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
738 return OPERATOR_FINISHED;
741 void SCENE_OT_render_view_remove(wmOperatorType *ot)
744 ot->name = "Remove Render View";
745 ot->idname = "SCENE_OT_render_view_remove";
746 ot->description = "Remove the selected render view";
749 ot->exec = render_view_remove_exec;
750 ot->poll = render_view_remove_poll;
753 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
756 #ifdef WITH_FREESTYLE
758 static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
761 BKE_report(reports, RPT_ERROR, "No active lineset and associated line style to manipulate the modifier");
764 if (!lineset->linestyle) {
765 BKE_report(reports, RPT_ERROR, "The active lineset does not have a line style (indicating data corruption)");
772 static bool freestyle_active_module_poll(bContext *C)
774 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
775 FreestyleModuleConfig *module = ptr.data;
777 return module != NULL;
780 static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
782 Scene *scene = CTX_data_scene(C);
783 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
785 BKE_freestyle_module_add(&srl->freestyleConfig);
787 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
789 return OPERATOR_FINISHED;
792 void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
795 ot->name = "Add Freestyle Module";
796 ot->idname = "SCENE_OT_freestyle_module_add";
797 ot->description = "Add a style module into the list of modules";
800 ot->exec = freestyle_module_add_exec;
803 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
806 static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
808 Scene *scene = CTX_data_scene(C);
809 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
810 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
811 FreestyleModuleConfig *module = ptr.data;
813 BKE_freestyle_module_delete(&srl->freestyleConfig, module);
815 DAG_id_tag_update(&scene->id, 0);
816 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
818 return OPERATOR_FINISHED;
821 void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
824 ot->name = "Remove Freestyle Module";
825 ot->idname = "SCENE_OT_freestyle_module_remove";
826 ot->description = "Remove the style module from the stack";
829 ot->poll = freestyle_active_module_poll;
830 ot->exec = freestyle_module_remove_exec;
833 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
836 static int freestyle_module_move_exec(bContext *C, wmOperator *op)
838 Scene *scene = CTX_data_scene(C);
839 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
840 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
841 FreestyleModuleConfig *module = ptr.data;
842 int dir = RNA_enum_get(op->ptr, "direction");
844 if (BKE_freestyle_module_move(&srl->freestyleConfig, module, dir)) {
845 DAG_id_tag_update(&scene->id, 0);
846 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
849 return OPERATOR_FINISHED;
852 void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
854 static const EnumPropertyItem direction_items[] = {
855 {-1, "UP", 0, "Up", ""},
856 {1, "DOWN", 0, "Down", ""},
857 {0, NULL, 0, NULL, NULL}
861 ot->name = "Move Freestyle Module";
862 ot->idname = "SCENE_OT_freestyle_module_move";
863 ot->description = "Change the position of the style module within in the list of style modules";
866 ot->poll = freestyle_active_module_poll;
867 ot->exec = freestyle_module_move_exec;
870 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
873 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
874 "Direction to move the chosen style module towards");
877 static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
879 Main *bmain = CTX_data_main(C);
880 Scene *scene = CTX_data_scene(C);
881 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
883 BKE_freestyle_lineset_add(bmain, &srl->freestyleConfig, NULL);
885 DAG_id_tag_update(&scene->id, 0);
886 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
888 return OPERATOR_FINISHED;
891 void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
894 ot->name = "Add Line Set";
895 ot->idname = "SCENE_OT_freestyle_lineset_add";
896 ot->description = "Add a line set into the list of line sets";
899 ot->exec = freestyle_lineset_add_exec;
902 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
905 static bool freestyle_active_lineset_poll(bContext *C)
907 Scene *scene = CTX_data_scene(C);
908 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
914 return BKE_freestyle_lineset_get_active(&srl->freestyleConfig) != NULL;
917 static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
919 Scene *scene = CTX_data_scene(C);
920 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
922 FRS_copy_active_lineset(&srl->freestyleConfig);
924 return OPERATOR_FINISHED;
927 void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
930 ot->name = "Copy Line Set";
931 ot->idname = "SCENE_OT_freestyle_lineset_copy";
932 ot->description = "Copy the active line set to a buffer";
935 ot->exec = freestyle_lineset_copy_exec;
936 ot->poll = freestyle_active_lineset_poll;
939 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
942 static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
944 Scene *scene = CTX_data_scene(C);
945 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
947 FRS_paste_active_lineset(&srl->freestyleConfig);
949 DAG_id_tag_update(&scene->id, 0);
950 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
952 return OPERATOR_FINISHED;
955 void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
958 ot->name = "Paste Line Set";
959 ot->idname = "SCENE_OT_freestyle_lineset_paste";
960 ot->description = "Paste the buffer content to the active line set";
963 ot->exec = freestyle_lineset_paste_exec;
964 ot->poll = freestyle_active_lineset_poll;
967 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
970 static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
972 Scene *scene = CTX_data_scene(C);
973 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
975 FRS_delete_active_lineset(&srl->freestyleConfig);
977 DAG_id_tag_update(&scene->id, 0);
978 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
980 return OPERATOR_FINISHED;
983 void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
986 ot->name = "Remove Line Set";
987 ot->idname = "SCENE_OT_freestyle_lineset_remove";
988 ot->description = "Remove the active line set from the list of line sets";
991 ot->exec = freestyle_lineset_remove_exec;
992 ot->poll = freestyle_active_lineset_poll;
995 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
998 static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
1000 Scene *scene = CTX_data_scene(C);
1001 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1002 int dir = RNA_enum_get(op->ptr, "direction");
1004 if (FRS_move_active_lineset(&srl->freestyleConfig, dir)) {
1005 DAG_id_tag_update(&scene->id, 0);
1006 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1009 return OPERATOR_FINISHED;
1012 void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
1014 static const EnumPropertyItem direction_items[] = {
1015 {-1, "UP", 0, "Up", ""},
1016 {1, "DOWN", 0, "Down", ""},
1017 {0, NULL, 0, NULL, NULL}
1021 ot->name = "Move Line Set";
1022 ot->idname = "SCENE_OT_freestyle_lineset_move";
1023 ot->description = "Change the position of the active line set within the list of line sets";
1026 ot->exec = freestyle_lineset_move_exec;
1027 ot->poll = freestyle_active_lineset_poll;
1030 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1033 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
1034 "Direction to move the active line set towards");
1037 static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
1039 Main *bmain = CTX_data_main(C);
1040 Scene *scene = CTX_data_scene(C);
1041 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1042 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1045 BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
1046 return OPERATOR_CANCELLED;
1048 if (lineset->linestyle) {
1049 id_us_min(&lineset->linestyle->id);
1050 lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
1053 lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
1055 DAG_id_tag_update(&lineset->linestyle->id, 0);
1056 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1058 return OPERATOR_FINISHED;
1061 void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
1064 ot->name = "New Line Style";
1065 ot->idname = "SCENE_OT_freestyle_linestyle_new";
1066 ot->description = "Create a new line style, reusable by multiple line sets";
1069 ot->exec = freestyle_linestyle_new_exec;
1070 ot->poll = freestyle_active_lineset_poll;
1073 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1076 static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
1078 Scene *scene = CTX_data_scene(C);
1079 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1080 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1081 int type = RNA_enum_get(op->ptr, "type");
1083 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1084 return OPERATOR_CANCELLED;
1087 if (BKE_linestyle_color_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1088 BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
1089 return OPERATOR_CANCELLED;
1091 DAG_id_tag_update(&lineset->linestyle->id, 0);
1092 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1094 return OPERATOR_FINISHED;
1097 void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
1100 ot->name = "Add Line Color Modifier";
1101 ot->idname = "SCENE_OT_freestyle_color_modifier_add";
1102 ot->description = "Add a line color modifier to the line style associated with the active lineset";
1105 ot->invoke = WM_menu_invoke;
1106 ot->exec = freestyle_color_modifier_add_exec;
1107 ot->poll = freestyle_active_lineset_poll;
1110 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1113 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
1116 static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
1118 Scene *scene = CTX_data_scene(C);
1119 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1120 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1121 int type = RNA_enum_get(op->ptr, "type");
1123 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1124 return OPERATOR_CANCELLED;
1127 if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1128 BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
1129 return OPERATOR_CANCELLED;
1131 DAG_id_tag_update(&lineset->linestyle->id, 0);
1132 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1134 return OPERATOR_FINISHED;
1137 void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
1140 ot->name = "Add Alpha Transparency Modifier";
1141 ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
1142 ot->description = "Add an alpha transparency modifier to the line style associated with the active lineset";
1145 ot->invoke = WM_menu_invoke;
1146 ot->exec = freestyle_alpha_modifier_add_exec;
1147 ot->poll = freestyle_active_lineset_poll;
1150 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1153 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
1156 static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
1158 Scene *scene = CTX_data_scene(C);
1159 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1160 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1161 int type = RNA_enum_get(op->ptr, "type");
1163 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1164 return OPERATOR_CANCELLED;
1167 if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1168 BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
1169 return OPERATOR_CANCELLED;
1171 DAG_id_tag_update(&lineset->linestyle->id, 0);
1172 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1174 return OPERATOR_FINISHED;
1177 void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
1180 ot->name = "Add Line Thickness Modifier";
1181 ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
1182 ot->description = "Add a line thickness modifier to the line style associated with the active lineset";
1185 ot->invoke = WM_menu_invoke;
1186 ot->exec = freestyle_thickness_modifier_add_exec;
1187 ot->poll = freestyle_active_lineset_poll;
1190 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1193 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
1196 static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
1198 Scene *scene = CTX_data_scene(C);
1199 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1200 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1201 int type = RNA_enum_get(op->ptr, "type");
1203 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1204 return OPERATOR_CANCELLED;
1207 if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1208 BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
1209 return OPERATOR_CANCELLED;
1211 DAG_id_tag_update(&lineset->linestyle->id, 0);
1212 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1214 return OPERATOR_FINISHED;
1217 void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
1220 ot->name = "Add Stroke Geometry Modifier";
1221 ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
1222 ot->description = "Add a stroke geometry modifier to the line style associated with the active lineset";
1225 ot->invoke = WM_menu_invoke;
1226 ot->exec = freestyle_geometry_modifier_add_exec;
1227 ot->poll = freestyle_active_lineset_poll;
1230 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1233 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
1236 static int freestyle_get_modifier_type(PointerRNA *ptr)
1238 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
1239 return LS_MODIFIER_TYPE_COLOR;
1240 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
1241 return LS_MODIFIER_TYPE_ALPHA;
1242 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
1243 return LS_MODIFIER_TYPE_THICKNESS;
1244 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
1245 return LS_MODIFIER_TYPE_GEOMETRY;
1249 static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
1251 Scene *scene = CTX_data_scene(C);
1252 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1253 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1254 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1255 LineStyleModifier *modifier = ptr.data;
1257 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1258 return OPERATOR_CANCELLED;
1261 switch (freestyle_get_modifier_type(&ptr)) {
1262 case LS_MODIFIER_TYPE_COLOR:
1263 BKE_linestyle_color_modifier_remove(lineset->linestyle, modifier);
1265 case LS_MODIFIER_TYPE_ALPHA:
1266 BKE_linestyle_alpha_modifier_remove(lineset->linestyle, modifier);
1268 case LS_MODIFIER_TYPE_THICKNESS:
1269 BKE_linestyle_thickness_modifier_remove(lineset->linestyle, modifier);
1271 case LS_MODIFIER_TYPE_GEOMETRY:
1272 BKE_linestyle_geometry_modifier_remove(lineset->linestyle, modifier);
1275 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1276 return OPERATOR_CANCELLED;
1278 DAG_id_tag_update(&lineset->linestyle->id, 0);
1279 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1281 return OPERATOR_FINISHED;
1284 void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
1287 ot->name = "Remove Modifier";
1288 ot->idname = "SCENE_OT_freestyle_modifier_remove";
1289 ot->description = "Remove the modifier from the list of modifiers";
1292 ot->exec = freestyle_modifier_remove_exec;
1293 ot->poll = freestyle_active_lineset_poll;
1296 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1299 static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
1301 Scene *scene = CTX_data_scene(C);
1302 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1303 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1304 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1305 LineStyleModifier *modifier = ptr.data;
1307 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1308 return OPERATOR_CANCELLED;
1311 switch (freestyle_get_modifier_type(&ptr)) {
1312 case LS_MODIFIER_TYPE_COLOR:
1313 BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
1315 case LS_MODIFIER_TYPE_ALPHA:
1316 BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
1318 case LS_MODIFIER_TYPE_THICKNESS:
1319 BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
1321 case LS_MODIFIER_TYPE_GEOMETRY:
1322 BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
1325 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1326 return OPERATOR_CANCELLED;
1328 DAG_id_tag_update(&lineset->linestyle->id, 0);
1329 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1331 return OPERATOR_FINISHED;
1334 void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
1337 ot->name = "Copy Modifier";
1338 ot->idname = "SCENE_OT_freestyle_modifier_copy";
1339 ot->description = "Duplicate the modifier within the list of modifiers";
1342 ot->exec = freestyle_modifier_copy_exec;
1343 ot->poll = freestyle_active_lineset_poll;
1346 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1349 static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
1351 Scene *scene = CTX_data_scene(C);
1352 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1353 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1354 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1355 LineStyleModifier *modifier = ptr.data;
1356 int dir = RNA_enum_get(op->ptr, "direction");
1357 bool changed = false;
1359 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1360 return OPERATOR_CANCELLED;
1363 switch (freestyle_get_modifier_type(&ptr)) {
1364 case LS_MODIFIER_TYPE_COLOR:
1365 changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
1367 case LS_MODIFIER_TYPE_ALPHA:
1368 changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
1370 case LS_MODIFIER_TYPE_THICKNESS:
1371 changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
1373 case LS_MODIFIER_TYPE_GEOMETRY:
1374 changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
1377 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1378 return OPERATOR_CANCELLED;
1382 DAG_id_tag_update(&lineset->linestyle->id, 0);
1383 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1386 return OPERATOR_FINISHED;
1389 void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
1391 static const EnumPropertyItem direction_items[] = {
1392 {-1, "UP", 0, "Up", ""},
1393 {1, "DOWN", 0, "Down", ""},
1394 {0, NULL, 0, NULL, NULL}
1398 ot->name = "Move Modifier";
1399 ot->idname = "SCENE_OT_freestyle_modifier_move";
1400 ot->description = "Move the modifier within the list of modifiers";
1403 ot->exec = freestyle_modifier_move_exec;
1404 ot->poll = freestyle_active_lineset_poll;
1407 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1410 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
1411 "Direction to move the chosen modifier towards");
1414 static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
1416 Main *bmain = CTX_data_main(C);
1417 Scene *scene = CTX_data_scene(C);
1418 FreestyleLineStyle *linestyle = BKE_linestyle_active_from_scene(scene);
1421 BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
1422 return OPERATOR_CANCELLED;
1425 FRS_create_stroke_material(bmain, linestyle);
1427 return OPERATOR_FINISHED;
1430 void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
1433 ot->name = "Create Freestyle Stroke Material";
1434 ot->idname = "SCENE_OT_freestyle_stroke_material_create";
1435 ot->description = "Create Freestyle stroke material for testing";
1438 ot->exec = freestyle_stroke_material_create_exec;
1441 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1444 #endif /* WITH_FREESTYLE */
1446 static int texture_slot_move_exec(bContext *C, wmOperator *op)
1448 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1451 MTex **mtex_ar, *mtexswap;
1453 int type = RNA_enum_get(op->ptr, "type");
1454 struct AnimData *adt = BKE_animdata_from_id(id);
1456 give_active_mtex(id, &mtex_ar, &act);
1458 if (type == -1) { /* Up */
1460 mtexswap = mtex_ar[act];
1461 mtex_ar[act] = mtex_ar[act - 1];
1462 mtex_ar[act - 1] = mtexswap;
1464 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
1465 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
1466 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1468 if (GS(id->name) == ID_MA) {
1469 Material *ma = (Material *)id;
1470 int mtexuse = ma->septex & (1 << act);
1471 ma->septex &= ~(1 << act);
1472 ma->septex |= (ma->septex & (1 << (act - 1))) << 1;
1473 ma->septex &= ~(1 << (act - 1));
1474 ma->septex |= mtexuse >> 1;
1477 set_active_mtex(id, act - 1);
1481 if (act < MAX_MTEX - 1) {
1482 mtexswap = mtex_ar[act];
1483 mtex_ar[act] = mtex_ar[act + 1];
1484 mtex_ar[act + 1] = mtexswap;
1486 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
1487 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
1488 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1490 if (GS(id->name) == ID_MA) {
1491 Material *ma = (Material *)id;
1492 int mtexuse = ma->septex & (1 << act);
1493 ma->septex &= ~(1 << act);
1494 ma->septex |= (ma->septex & (1 << (act + 1))) >> 1;
1495 ma->septex &= ~(1 << (act + 1));
1496 ma->septex |= mtexuse << 1;
1499 set_active_mtex(id, act + 1);
1503 DAG_id_tag_update(id, 0);
1504 WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
1507 return OPERATOR_FINISHED;
1510 void TEXTURE_OT_slot_move(wmOperatorType *ot)
1512 static const EnumPropertyItem slot_move[] = {
1513 {-1, "UP", 0, "Up", ""},
1514 {1, "DOWN", 0, "Down", ""},
1515 {0, NULL, 0, NULL, NULL}
1519 ot->name = "Move Texture Slot";
1520 ot->idname = "TEXTURE_OT_slot_move";
1521 ot->description = "Move texture slots up and down";
1524 ot->exec = texture_slot_move_exec;
1527 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1529 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
1534 /********************** environment map operators *********************/
1536 static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype)
1541 if ((prop = RNA_struct_find_property(op->ptr, "layout"))) {
1542 RNA_property_float_get_array(op->ptr, prop, layout);
1545 memcpy(layout, default_envmap_layout, sizeof(layout));
1548 if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) {
1549 return OPERATOR_FINISHED;
1552 return OPERATOR_CANCELLED;
1557 static int envmap_save_exec(bContext *C, wmOperator *op)
1559 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1560 Scene *scene = CTX_data_scene(C);
1561 //int imtype = RNA_enum_get(op->ptr, "file_type");
1562 char imtype = scene->r.im_format.imtype;
1563 char path[FILE_MAX];
1565 RNA_string_get(op->ptr, "filepath", path);
1567 if (scene->r.scemode & R_EXTENSION) {
1568 BKE_image_path_ensure_ext_from_imformat(path, &scene->r.im_format);
1573 save_envmap(op, scene, tex->env, path, imtype);
1577 WM_event_add_notifier(C, NC_TEXTURE, tex);
1579 return OPERATOR_FINISHED;
1582 static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1584 Main *bmain = CTX_data_main(C);
1585 //Scene *scene= CTX_data_scene(C);
1587 if (RNA_struct_property_is_set(op->ptr, "filepath"))
1588 return envmap_save_exec(C, op);
1590 //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype);
1591 RNA_string_set(op->ptr, "filepath", BKE_main_blendfile_path(bmain));
1592 WM_event_add_fileselect(C, op);
1594 return OPERATOR_RUNNING_MODAL;
1597 static bool envmap_save_poll(bContext *C)
1599 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1603 if (!tex->env || !tex->env->ok)
1605 if (tex->env->cube[1] == NULL)
1611 void TEXTURE_OT_envmap_save(wmOperatorType *ot)
1615 ot->name = "Save Environment Map";
1616 ot->idname = "TEXTURE_OT_envmap_save";
1617 ot->description = "Save the current generated Environment map to an image file";
1620 ot->exec = envmap_save_exec;
1621 ot->invoke = envmap_save_invoke;
1622 ot->poll = envmap_save_poll;
1625 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo since this doesnt modify the env-map */
1628 prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f,
1630 "Flat array describing the X,Y position of each cube face in the output image, "
1631 "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] "
1632 "(use -1 to skip a face)", 0.0f, 0.0f);
1633 RNA_def_property_flag(prop, PROP_HIDDEN);
1635 WM_operator_properties_filesel(
1636 ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE,
1637 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
1640 static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op))
1642 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1644 BKE_texture_envmap_free_data(tex->env);
1646 WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
1648 return OPERATOR_FINISHED;
1651 static bool envmap_clear_poll(bContext *C)
1653 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1657 if (!tex->env || !tex->env->ok)
1659 if (tex->env->cube[1] == NULL)
1665 void TEXTURE_OT_envmap_clear(wmOperatorType *ot)
1668 ot->name = "Clear Environment Map";
1669 ot->idname = "TEXTURE_OT_envmap_clear";
1670 ot->description = "Discard the environment map and free it from memory";
1673 ot->exec = envmap_clear_exec;
1674 ot->poll = envmap_clear_poll;
1677 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1680 static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op))
1682 Main *bmain = CTX_data_main(C);
1685 for (tex = bmain->tex.first; tex; tex = tex->id.next)
1687 BKE_texture_envmap_free_data(tex->env);
1689 WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
1691 return OPERATOR_FINISHED;
1694 void TEXTURE_OT_envmap_clear_all(wmOperatorType *ot)
1697 ot->name = "Clear All Environment Maps";
1698 ot->idname = "TEXTURE_OT_envmap_clear_all";
1699 ot->description = "Discard all environment maps in the .blend file and free them from memory";
1702 ot->exec = envmap_clear_all_exec;
1703 ot->poll = envmap_clear_poll;
1706 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1709 /********************** material operators *********************/
1711 /* material copy/paste */
1712 static int copy_material_exec(bContext *C, wmOperator *UNUSED(op))
1714 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1717 return OPERATOR_CANCELLED;
1719 copy_matcopybuf(CTX_data_main(C), ma);
1721 return OPERATOR_FINISHED;
1724 void MATERIAL_OT_copy(wmOperatorType *ot)
1727 ot->name = "Copy Material";
1728 ot->idname = "MATERIAL_OT_copy";
1729 ot->description = "Copy the material settings and nodes";
1732 ot->exec = copy_material_exec;
1735 /* no undo needed since no changes are made to the material */
1736 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
1739 static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
1741 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1744 return OPERATOR_CANCELLED;
1746 paste_matcopybuf(CTX_data_main(C), ma);
1748 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
1750 return OPERATOR_FINISHED;
1753 void MATERIAL_OT_paste(wmOperatorType *ot)
1756 ot->name = "Paste Material";
1757 ot->idname = "MATERIAL_OT_paste";
1758 ot->description = "Paste the material settings and nodes";
1761 ot->exec = paste_material_exec;
1764 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1768 static short mtexcopied = 0; /* must be reset on file load */
1769 static MTex mtexcopybuf;
1771 void ED_render_clear_mtex_copybuf(void)
1772 { /* use for file reload */
1776 static void copy_mtex_copybuf(ID *id)
1780 switch (GS(id->name)) {
1782 mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]);
1785 mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]);
1786 // la->mtex[(int)la->texact] // TODO
1789 mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]);
1790 // mtex= wrld->mtex[(int)wrld->texact]; // TODO
1793 mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1796 mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1802 if (mtex && *mtex) {
1803 memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
1811 static void paste_mtex_copybuf(ID *id)
1815 if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
1818 switch (GS(id->name)) {
1820 mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]);
1823 mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]);
1824 // la->mtex[(int)la->texact] // TODO
1827 mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]);
1828 // mtex= wrld->mtex[(int)wrld->texact]; // TODO
1831 mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1834 mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1837 BLI_assert(!"invalid id type");
1842 if (*mtex == NULL) {
1843 *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
1845 else if ((*mtex)->tex) {
1846 id_us_min(&(*mtex)->tex->id);
1849 memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
1851 id_us_plus((ID *)mtexcopybuf.tex);
1856 static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1858 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1861 /* copying empty slot */
1862 ED_render_clear_mtex_copybuf();
1863 return OPERATOR_CANCELLED;
1866 copy_mtex_copybuf(id);
1868 return OPERATOR_FINISHED;
1871 static bool copy_mtex_poll(bContext *C)
1873 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1875 return (id != NULL);
1878 void TEXTURE_OT_slot_copy(wmOperatorType *ot)
1881 ot->name = "Copy Texture Slot Settings";
1882 ot->idname = "TEXTURE_OT_slot_copy";
1883 ot->description = "Copy the material texture settings and nodes";
1886 ot->exec = copy_mtex_exec;
1887 ot->poll = copy_mtex_poll;
1890 /* no undo needed since no changes are made to the mtex */
1891 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL;
1894 static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1896 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1899 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1900 Lamp *la = CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data;
1901 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
1902 ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1903 FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
1912 id = &psys->part->id;
1914 id = &linestyle->id;
1917 return OPERATOR_CANCELLED;
1920 paste_mtex_copybuf(id);
1922 WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
1924 return OPERATOR_FINISHED;
1927 void TEXTURE_OT_slot_paste(wmOperatorType *ot)
1930 ot->name = "Paste Texture Slot Settings";
1931 ot->idname = "TEXTURE_OT_slot_paste";
1932 ot->description = "Copy the texture settings and nodes";
1935 ot->exec = paste_mtex_exec;
1938 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;