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"
54 #include "BKE_global.h"
55 #include "BKE_image.h"
56 #include "BKE_layer.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"
68 #include "DEG_depsgraph.h"
69 #include "DEG_depsgraph_build.h"
72 # include "BKE_freestyle.h"
73 # include "FRS_freestyle.h"
74 # include "RNA_enum_types.h"
77 #include "RNA_access.h"
82 #include "ED_object.h"
86 #include "ED_render.h"
88 #include "ED_screen.h"
90 #include "RNA_define.h"
92 #include "UI_interface.h"
94 #include "RE_pipeline.h"
96 #include "render_intern.h" // own include
98 /********************** material slot operators *********************/
100 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
102 Object *ob = ED_object_context(C);
105 return OPERATOR_CANCELLED;
107 BKE_object_material_slot_add(ob);
109 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
110 Scene *scene = CTX_data_scene(C);
111 BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
112 WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
115 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
116 WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
117 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
119 return OPERATOR_FINISHED;
122 void OBJECT_OT_material_slot_add(wmOperatorType *ot)
125 ot->name = "Add Material Slot";
126 ot->idname = "OBJECT_OT_material_slot_add";
127 ot->description = "Add a new material slot";
130 ot->exec = material_slot_add_exec;
131 ot->poll = ED_operator_object_active_editable;
134 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
137 static int material_slot_remove_exec(bContext *C, wmOperator *op)
139 Object *ob = ED_object_context(C);
142 return OPERATOR_CANCELLED;
144 /* Removing material slots in edit mode screws things up, see bug #21822.*/
145 if (ob == CTX_data_edit_object(C)) {
146 BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
147 return OPERATOR_CANCELLED;
150 BKE_object_material_slot_remove(ob);
152 if (ob->mode & OB_MODE_TEXTURE_PAINT) {
153 Scene *scene = CTX_data_scene(C);
154 BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
155 WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
158 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
159 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
160 WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
161 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
163 return OPERATOR_FINISHED;
166 void OBJECT_OT_material_slot_remove(wmOperatorType *ot)
169 ot->name = "Remove Material Slot";
170 ot->idname = "OBJECT_OT_material_slot_remove";
171 ot->description = "Remove the selected material slot";
174 ot->exec = material_slot_remove_exec;
175 ot->poll = ED_operator_object_active_editable;
178 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
181 static int material_slot_assign_exec(bContext *C, wmOperator *UNUSED(op))
183 Object *ob = ED_object_context(C);
186 return OPERATOR_CANCELLED;
188 if (ob && ob->actcol > 0) {
189 if (ob->type == OB_MESH) {
190 BMEditMesh *em = BKE_editmesh_from_object(ob);
195 BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
196 if (BM_elem_flag_test(efa, BM_ELEM_SELECT))
197 efa->mat_nr = ob->actcol - 1;
201 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
203 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
206 for (nu = nurbs->first; nu; nu = nu->next) {
207 if (ED_curve_nurb_select_check(ob->data, nu)) {
208 nu->mat_nr = ob->actcol - 1;
213 else if (ob->type == OB_FONT) {
214 EditFont *ef = ((Curve *)ob->data)->editfont;
215 int i, selstart, selend;
217 if (ef && BKE_vfont_select_get(ob, &selstart, &selend)) {
218 for (i = selstart; i <= selend; i++)
219 ef->textbufinfo[i].mat_nr = ob->actcol;
224 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
225 WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
227 return OPERATOR_FINISHED;
230 void OBJECT_OT_material_slot_assign(wmOperatorType *ot)
233 ot->name = "Assign Material Slot";
234 ot->idname = "OBJECT_OT_material_slot_assign";
235 ot->description = "Assign active material slot to selection";
238 ot->exec = material_slot_assign_exec;
239 ot->poll = ED_operator_object_active_editable;
242 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
245 static int material_slot_de_select(bContext *C, bool select)
247 Object *ob = ED_object_context(C);
250 return OPERATOR_CANCELLED;
252 if (ob->type == OB_MESH) {
253 BMEditMesh *em = BKE_editmesh_from_object(ob);
256 EDBM_deselect_by_material(em, ob->actcol - 1, select);
259 else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
260 ListBase *nurbs = BKE_curve_editNurbs_get((Curve *)ob->data);
267 for (nu = nurbs->first; nu; nu = nu->next) {
268 if (nu->mat_nr == ob->actcol - 1) {
273 if (bezt->hide == 0) {
289 a = nu->pntsu * nu->pntsv;
293 if (select) bp->f1 |= SELECT;
294 else bp->f1 &= ~SELECT;
304 WM_event_add_notifier(C, NC_GEOM | ND_SELECT, ob->data);
306 return OPERATOR_FINISHED;
309 static int material_slot_select_exec(bContext *C, wmOperator *UNUSED(op))
311 return material_slot_de_select(C, true);
314 void OBJECT_OT_material_slot_select(wmOperatorType *ot)
317 ot->name = "Select Material Slot";
318 ot->idname = "OBJECT_OT_material_slot_select";
319 ot->description = "Select by active material slot";
322 ot->exec = material_slot_select_exec;
325 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
328 static int material_slot_deselect_exec(bContext *C, wmOperator *UNUSED(op))
330 return material_slot_de_select(C, false);
333 void OBJECT_OT_material_slot_deselect(wmOperatorType *ot)
336 ot->name = "Deselect Material Slot";
337 ot->idname = "OBJECT_OT_material_slot_deselect";
338 ot->description = "Deselect by active material slot";
341 ot->exec = material_slot_deselect_exec;
344 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
348 static int material_slot_copy_exec(bContext *C, wmOperator *UNUSED(op))
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(ob_iter, matar, ob->totcol);
362 if (ob_iter->totcol == ob->totcol) {
363 ob_iter->actcol = ob->actcol;
364 DEG_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 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
430 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | ND_DATA, ob);
432 return OPERATOR_FINISHED;
435 void OBJECT_OT_material_slot_move(wmOperatorType *ot)
437 static EnumPropertyItem material_slot_move[] = {
438 {1, "UP", 0, "Up", ""},
439 {-1, "DOWN", 0, "Down", ""},
440 {0, NULL, 0, NULL, NULL}
444 ot->name = "Move Material";
445 ot->idname = "OBJECT_OT_material_slot_move";
446 ot->description = "Move the active material up/down in the list";
449 ot->exec = material_slot_move_exec;
452 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
454 RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction",
455 "Direction to move the active material towards");
458 /********************** new material operator *********************/
460 static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
462 Scene *scene = CTX_data_scene(C);
463 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
464 Main *bmain = CTX_data_main(C);
465 PointerRNA ptr, idptr;
468 /* add or copy material */
470 ma = BKE_material_copy(bmain, ma);
473 ma = BKE_material_add(bmain, DATA_("Material"));
475 if (BKE_scene_use_new_shading_nodes(scene)) {
476 ED_node_shader_default(C, &ma->id);
477 ma->use_nodes = true;
482 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
485 /* when creating new ID blocks, use is already 1, but RNA
486 * pointer use also increases user, so this compensates it */
489 RNA_id_pointer_create(&ma->id, &idptr);
490 RNA_property_pointer_set(&ptr, prop, idptr);
491 RNA_property_update(C, &ptr, prop);
494 WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
496 return OPERATOR_FINISHED;
499 void MATERIAL_OT_new(wmOperatorType *ot)
502 ot->name = "New Material";
503 ot->idname = "MATERIAL_OT_new";
504 ot->description = "Add a new material";
507 ot->exec = new_material_exec;
510 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
513 /********************** new texture operator *********************/
515 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
517 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
518 Main *bmain = CTX_data_main(C);
519 PointerRNA ptr, idptr;
522 /* add or copy texture */
524 tex = BKE_texture_copy(bmain, tex);
527 tex = BKE_texture_add(bmain, DATA_("Texture"));
531 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
534 /* when creating new ID blocks, use is already 1, but RNA
535 * pointer use also increases user, so this compensates it */
538 if (ptr.id.data && GS(((ID *)ptr.id.data)->name) == ID_MA &&
539 RNA_property_pointer_get(&ptr, prop).id.data == NULL)
541 /* In case we are assigning new texture to a material, and active slot was empty, reset 'use' flag. */
542 Material *ma = (Material *)ptr.id.data;
543 ma->septex &= ~(1 << ma->texact);
546 RNA_id_pointer_create(&tex->id, &idptr);
547 RNA_property_pointer_set(&ptr, prop, idptr);
548 RNA_property_update(C, &ptr, prop);
551 WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
553 return OPERATOR_FINISHED;
556 void TEXTURE_OT_new(wmOperatorType *ot)
559 ot->name = "New Texture";
560 ot->idname = "TEXTURE_OT_new";
561 ot->description = "Add a new texture";
564 ot->exec = new_texture_exec;
567 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
570 /********************** new world operator *********************/
572 static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
574 Scene *scene = CTX_data_scene(C);
575 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
576 Main *bmain = CTX_data_main(C);
577 PointerRNA ptr, idptr;
580 /* add or copy world */
582 wo = BKE_world_copy(bmain, wo);
585 wo = add_world(bmain, DATA_("World"));
587 if (BKE_scene_use_new_shading_nodes(scene)) {
588 ED_node_shader_default(C, &wo->id);
589 wo->use_nodes = true;
594 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
597 /* when creating new ID blocks, use is already 1, but RNA
598 * pointer use also increases user, so this compensates it */
601 RNA_id_pointer_create(&wo->id, &idptr);
602 RNA_property_pointer_set(&ptr, prop, idptr);
603 RNA_property_update(C, &ptr, prop);
606 WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
608 return OPERATOR_FINISHED;
611 void WORLD_OT_new(wmOperatorType *ot)
614 ot->name = "New World";
615 ot->idname = "WORLD_OT_new";
616 ot->description = "Create a new world Data-Block";
619 ot->exec = new_world_exec;
622 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
625 /********************** render layer operators *********************/
627 static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
629 Scene *scene = CTX_data_scene(C);
631 BKE_scene_layer_add(scene, NULL);
632 scene->active_layer = BLI_listbase_count(&scene->render_layers) - 1;
634 DEG_id_tag_update(&scene->id, 0);
635 DEG_relations_tag_update(CTX_data_main(C));
636 WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
638 return OPERATOR_FINISHED;
641 void SCENE_OT_render_layer_add(wmOperatorType *ot)
644 ot->name = "Add Render Layer";
645 ot->idname = "SCENE_OT_render_layer_add";
646 ot->description = "Add a render layer";
649 ot->exec = render_layer_add_exec;
652 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
655 static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
657 Main *bmain = CTX_data_main(C);
658 Scene *scene = CTX_data_scene(C);
659 SceneLayer *sl = CTX_data_scene_layer(C);
661 if (!ED_scene_render_layer_delete(bmain, scene, sl, NULL)) {
662 return OPERATOR_CANCELLED;
665 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
667 return OPERATOR_FINISHED;
670 void SCENE_OT_render_layer_remove(wmOperatorType *ot)
673 ot->name = "Remove Render Layer";
674 ot->idname = "SCENE_OT_render_layer_remove";
675 ot->description = "Remove the selected render layer";
678 ot->exec = render_layer_remove_exec;
681 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
684 /********************** render view operators *********************/
686 static int render_view_remove_poll(bContext *C)
688 Scene *scene = CTX_data_scene(C);
690 /* don't allow user to remove "left" and "right" views */
691 return scene->r.actview > 1;
694 static int render_view_add_exec(bContext *C, wmOperator *UNUSED(op))
696 Scene *scene = CTX_data_scene(C);
698 BKE_scene_add_render_view(scene, NULL);
699 scene->r.actview = BLI_listbase_count(&scene->r.views) - 1;
701 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
703 return OPERATOR_FINISHED;
706 void SCENE_OT_render_view_add(wmOperatorType *ot)
709 ot->name = "Add Render View";
710 ot->idname = "SCENE_OT_render_view_add";
711 ot->description = "Add a render view";
714 ot->exec = render_view_add_exec;
717 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
720 static int render_view_remove_exec(bContext *C, wmOperator *UNUSED(op))
722 Scene *scene = CTX_data_scene(C);
723 SceneRenderView *rv = BLI_findlink(&scene->r.views, scene->r.actview);
725 if (!BKE_scene_remove_render_view(scene, rv))
726 return OPERATOR_CANCELLED;
728 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
730 return OPERATOR_FINISHED;
733 void SCENE_OT_render_view_remove(wmOperatorType *ot)
736 ot->name = "Remove Render View";
737 ot->idname = "SCENE_OT_render_view_remove";
738 ot->description = "Remove the selected render view";
741 ot->exec = render_view_remove_exec;
742 ot->poll = render_view_remove_poll;
745 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
748 #ifdef WITH_FREESTYLE
750 static bool freestyle_linestyle_check_report(FreestyleLineSet *lineset, ReportList *reports)
753 BKE_report(reports, RPT_ERROR, "No active lineset and associated line style to manipulate the modifier");
756 if (!lineset->linestyle) {
757 BKE_report(reports, RPT_ERROR, "The active lineset does not have a line style (indicating data corruption)");
764 static int freestyle_active_module_poll(bContext *C)
766 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
767 FreestyleModuleConfig *module = ptr.data;
769 return module != NULL;
772 static int freestyle_module_add_exec(bContext *C, wmOperator *UNUSED(op))
774 Scene *scene = CTX_data_scene(C);
775 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
777 BKE_freestyle_module_add(&srl->freestyleConfig);
779 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
781 return OPERATOR_FINISHED;
784 void SCENE_OT_freestyle_module_add(wmOperatorType *ot)
787 ot->name = "Add Freestyle Module";
788 ot->idname = "SCENE_OT_freestyle_module_add";
789 ot->description = "Add a style module into the list of modules";
792 ot->exec = freestyle_module_add_exec;
795 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
798 static int freestyle_module_remove_exec(bContext *C, wmOperator *UNUSED(op))
800 Scene *scene = CTX_data_scene(C);
801 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
802 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
803 FreestyleModuleConfig *module = ptr.data;
805 BKE_freestyle_module_delete(&srl->freestyleConfig, module);
807 DEG_id_tag_update(&scene->id, 0);
808 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
810 return OPERATOR_FINISHED;
813 void SCENE_OT_freestyle_module_remove(wmOperatorType *ot)
816 ot->name = "Remove Freestyle Module";
817 ot->idname = "SCENE_OT_freestyle_module_remove";
818 ot->description = "Remove the style module from the stack";
821 ot->poll = freestyle_active_module_poll;
822 ot->exec = freestyle_module_remove_exec;
825 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
828 static int freestyle_module_move_exec(bContext *C, wmOperator *op)
830 Scene *scene = CTX_data_scene(C);
831 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
832 PointerRNA ptr = CTX_data_pointer_get_type(C, "freestyle_module", &RNA_FreestyleModuleSettings);
833 FreestyleModuleConfig *module = ptr.data;
834 int dir = RNA_enum_get(op->ptr, "direction");
836 if (BKE_freestyle_module_move(&srl->freestyleConfig, module, dir)) {
837 DEG_id_tag_update(&scene->id, 0);
838 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
841 return OPERATOR_FINISHED;
844 void SCENE_OT_freestyle_module_move(wmOperatorType *ot)
846 static EnumPropertyItem direction_items[] = {
847 {-1, "UP", 0, "Up", ""},
848 {1, "DOWN", 0, "Down", ""},
849 {0, NULL, 0, NULL, NULL}
853 ot->name = "Move Freestyle Module";
854 ot->idname = "SCENE_OT_freestyle_module_move";
855 ot->description = "Change the position of the style module within in the list of style modules";
858 ot->poll = freestyle_active_module_poll;
859 ot->exec = freestyle_module_move_exec;
862 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
865 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
866 "Direction to move the chosen style module towards");
869 static int freestyle_lineset_add_exec(bContext *C, wmOperator *UNUSED(op))
871 Main *bmain = CTX_data_main(C);
872 Scene *scene = CTX_data_scene(C);
873 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
875 BKE_freestyle_lineset_add(bmain, &srl->freestyleConfig, NULL);
877 DEG_id_tag_update(&scene->id, 0);
878 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
880 return OPERATOR_FINISHED;
883 void SCENE_OT_freestyle_lineset_add(wmOperatorType *ot)
886 ot->name = "Add Line Set";
887 ot->idname = "SCENE_OT_freestyle_lineset_add";
888 ot->description = "Add a line set into the list of line sets";
891 ot->exec = freestyle_lineset_add_exec;
894 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
897 static int freestyle_active_lineset_poll(bContext *C)
899 Scene *scene = CTX_data_scene(C);
900 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
906 return BKE_freestyle_lineset_get_active(&srl->freestyleConfig) != NULL;
909 static int freestyle_lineset_copy_exec(bContext *C, wmOperator *UNUSED(op))
911 Scene *scene = CTX_data_scene(C);
912 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
914 FRS_copy_active_lineset(&srl->freestyleConfig);
916 return OPERATOR_FINISHED;
919 void SCENE_OT_freestyle_lineset_copy(wmOperatorType *ot)
922 ot->name = "Copy Line Set";
923 ot->idname = "SCENE_OT_freestyle_lineset_copy";
924 ot->description = "Copy the active line set to a buffer";
927 ot->exec = freestyle_lineset_copy_exec;
928 ot->poll = freestyle_active_lineset_poll;
931 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
934 static int freestyle_lineset_paste_exec(bContext *C, wmOperator *UNUSED(op))
936 Scene *scene = CTX_data_scene(C);
937 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
939 FRS_paste_active_lineset(&srl->freestyleConfig);
941 DEG_id_tag_update(&scene->id, 0);
942 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
944 return OPERATOR_FINISHED;
947 void SCENE_OT_freestyle_lineset_paste(wmOperatorType *ot)
950 ot->name = "Paste Line Set";
951 ot->idname = "SCENE_OT_freestyle_lineset_paste";
952 ot->description = "Paste the buffer content to the active line set";
955 ot->exec = freestyle_lineset_paste_exec;
956 ot->poll = freestyle_active_lineset_poll;
959 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
962 static int freestyle_lineset_remove_exec(bContext *C, wmOperator *UNUSED(op))
964 Scene *scene = CTX_data_scene(C);
965 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
967 FRS_delete_active_lineset(&srl->freestyleConfig);
969 DEG_id_tag_update(&scene->id, 0);
970 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
972 return OPERATOR_FINISHED;
975 void SCENE_OT_freestyle_lineset_remove(wmOperatorType *ot)
978 ot->name = "Remove Line Set";
979 ot->idname = "SCENE_OT_freestyle_lineset_remove";
980 ot->description = "Remove the active line set from the list of line sets";
983 ot->exec = freestyle_lineset_remove_exec;
984 ot->poll = freestyle_active_lineset_poll;
987 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
990 static int freestyle_lineset_move_exec(bContext *C, wmOperator *op)
992 Scene *scene = CTX_data_scene(C);
993 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
994 int dir = RNA_enum_get(op->ptr, "direction");
996 if (FRS_move_active_lineset(&srl->freestyleConfig, dir)) {
997 DEG_id_tag_update(&scene->id, 0);
998 WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, scene);
1001 return OPERATOR_FINISHED;
1004 void SCENE_OT_freestyle_lineset_move(wmOperatorType *ot)
1006 static EnumPropertyItem direction_items[] = {
1007 {-1, "UP", 0, "Up", ""},
1008 {1, "DOWN", 0, "Down", ""},
1009 {0, NULL, 0, NULL, NULL}
1013 ot->name = "Move Line Set";
1014 ot->idname = "SCENE_OT_freestyle_lineset_move";
1015 ot->description = "Change the position of the active line set within the list of line sets";
1018 ot->exec = freestyle_lineset_move_exec;
1019 ot->poll = freestyle_active_lineset_poll;
1022 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1025 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
1026 "Direction to move the active line set towards");
1029 static int freestyle_linestyle_new_exec(bContext *C, wmOperator *op)
1031 Main *bmain = CTX_data_main(C);
1032 Scene *scene = CTX_data_scene(C);
1033 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1034 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1037 BKE_report(op->reports, RPT_ERROR, "No active lineset to add a new line style to");
1038 return OPERATOR_CANCELLED;
1040 if (lineset->linestyle) {
1041 id_us_min(&lineset->linestyle->id);
1042 lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
1045 lineset->linestyle = BKE_linestyle_new(bmain, "LineStyle");
1047 DEG_id_tag_update(&lineset->linestyle->id, 0);
1048 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1050 return OPERATOR_FINISHED;
1053 void SCENE_OT_freestyle_linestyle_new(wmOperatorType *ot)
1056 ot->name = "New Line Style";
1057 ot->idname = "SCENE_OT_freestyle_linestyle_new";
1058 ot->description = "Create a new line style, reusable by multiple line sets";
1061 ot->exec = freestyle_linestyle_new_exec;
1062 ot->poll = freestyle_active_lineset_poll;
1065 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1068 static int freestyle_color_modifier_add_exec(bContext *C, wmOperator *op)
1070 Scene *scene = CTX_data_scene(C);
1071 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1072 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1073 int type = RNA_enum_get(op->ptr, "type");
1075 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1076 return OPERATOR_CANCELLED;
1079 if (BKE_linestyle_color_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1080 BKE_report(op->reports, RPT_ERROR, "Unknown line color modifier type");
1081 return OPERATOR_CANCELLED;
1083 DEG_id_tag_update(&lineset->linestyle->id, 0);
1084 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1086 return OPERATOR_FINISHED;
1089 void SCENE_OT_freestyle_color_modifier_add(wmOperatorType *ot)
1092 ot->name = "Add Line Color Modifier";
1093 ot->idname = "SCENE_OT_freestyle_color_modifier_add";
1094 ot->description = "Add a line color modifier to the line style associated with the active lineset";
1097 ot->invoke = WM_menu_invoke;
1098 ot->exec = freestyle_color_modifier_add_exec;
1099 ot->poll = freestyle_active_lineset_poll;
1102 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1105 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_color_modifier_type_items, 0, "Type", "");
1108 static int freestyle_alpha_modifier_add_exec(bContext *C, wmOperator *op)
1110 Scene *scene = CTX_data_scene(C);
1111 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1112 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1113 int type = RNA_enum_get(op->ptr, "type");
1115 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1116 return OPERATOR_CANCELLED;
1119 if (BKE_linestyle_alpha_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1120 BKE_report(op->reports, RPT_ERROR, "Unknown alpha transparency modifier type");
1121 return OPERATOR_CANCELLED;
1123 DEG_id_tag_update(&lineset->linestyle->id, 0);
1124 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1126 return OPERATOR_FINISHED;
1129 void SCENE_OT_freestyle_alpha_modifier_add(wmOperatorType *ot)
1132 ot->name = "Add Alpha Transparency Modifier";
1133 ot->idname = "SCENE_OT_freestyle_alpha_modifier_add";
1134 ot->description = "Add an alpha transparency modifier to the line style associated with the active lineset";
1137 ot->invoke = WM_menu_invoke;
1138 ot->exec = freestyle_alpha_modifier_add_exec;
1139 ot->poll = freestyle_active_lineset_poll;
1142 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1145 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_alpha_modifier_type_items, 0, "Type", "");
1148 static int freestyle_thickness_modifier_add_exec(bContext *C, wmOperator *op)
1150 Scene *scene = CTX_data_scene(C);
1151 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1152 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1153 int type = RNA_enum_get(op->ptr, "type");
1155 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1156 return OPERATOR_CANCELLED;
1159 if (BKE_linestyle_thickness_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1160 BKE_report(op->reports, RPT_ERROR, "Unknown line thickness modifier type");
1161 return OPERATOR_CANCELLED;
1163 DEG_id_tag_update(&lineset->linestyle->id, 0);
1164 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1166 return OPERATOR_FINISHED;
1169 void SCENE_OT_freestyle_thickness_modifier_add(wmOperatorType *ot)
1172 ot->name = "Add Line Thickness Modifier";
1173 ot->idname = "SCENE_OT_freestyle_thickness_modifier_add";
1174 ot->description = "Add a line thickness modifier to the line style associated with the active lineset";
1177 ot->invoke = WM_menu_invoke;
1178 ot->exec = freestyle_thickness_modifier_add_exec;
1179 ot->poll = freestyle_active_lineset_poll;
1182 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1185 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_thickness_modifier_type_items, 0, "Type", "");
1188 static int freestyle_geometry_modifier_add_exec(bContext *C, wmOperator *op)
1190 Scene *scene = CTX_data_scene(C);
1191 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1192 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1193 int type = RNA_enum_get(op->ptr, "type");
1195 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1196 return OPERATOR_CANCELLED;
1199 if (BKE_linestyle_geometry_modifier_add(lineset->linestyle, NULL, type) == NULL) {
1200 BKE_report(op->reports, RPT_ERROR, "Unknown stroke geometry modifier type");
1201 return OPERATOR_CANCELLED;
1203 DEG_id_tag_update(&lineset->linestyle->id, 0);
1204 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1206 return OPERATOR_FINISHED;
1209 void SCENE_OT_freestyle_geometry_modifier_add(wmOperatorType *ot)
1212 ot->name = "Add Stroke Geometry Modifier";
1213 ot->idname = "SCENE_OT_freestyle_geometry_modifier_add";
1214 ot->description = "Add a stroke geometry modifier to the line style associated with the active lineset";
1217 ot->invoke = WM_menu_invoke;
1218 ot->exec = freestyle_geometry_modifier_add_exec;
1219 ot->poll = freestyle_active_lineset_poll;
1222 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1225 ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_linestyle_geometry_modifier_type_items, 0, "Type", "");
1228 static int freestyle_get_modifier_type(PointerRNA *ptr)
1230 if (RNA_struct_is_a(ptr->type, &RNA_LineStyleColorModifier))
1231 return LS_MODIFIER_TYPE_COLOR;
1232 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleAlphaModifier))
1233 return LS_MODIFIER_TYPE_ALPHA;
1234 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleThicknessModifier))
1235 return LS_MODIFIER_TYPE_THICKNESS;
1236 else if (RNA_struct_is_a(ptr->type, &RNA_LineStyleGeometryModifier))
1237 return LS_MODIFIER_TYPE_GEOMETRY;
1241 static int freestyle_modifier_remove_exec(bContext *C, wmOperator *op)
1243 Scene *scene = CTX_data_scene(C);
1244 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1245 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1246 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1247 LineStyleModifier *modifier = ptr.data;
1249 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1250 return OPERATOR_CANCELLED;
1253 switch (freestyle_get_modifier_type(&ptr)) {
1254 case LS_MODIFIER_TYPE_COLOR:
1255 BKE_linestyle_color_modifier_remove(lineset->linestyle, modifier);
1257 case LS_MODIFIER_TYPE_ALPHA:
1258 BKE_linestyle_alpha_modifier_remove(lineset->linestyle, modifier);
1260 case LS_MODIFIER_TYPE_THICKNESS:
1261 BKE_linestyle_thickness_modifier_remove(lineset->linestyle, modifier);
1263 case LS_MODIFIER_TYPE_GEOMETRY:
1264 BKE_linestyle_geometry_modifier_remove(lineset->linestyle, modifier);
1267 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1268 return OPERATOR_CANCELLED;
1270 DEG_id_tag_update(&lineset->linestyle->id, 0);
1271 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1273 return OPERATOR_FINISHED;
1276 void SCENE_OT_freestyle_modifier_remove(wmOperatorType *ot)
1279 ot->name = "Remove Modifier";
1280 ot->idname = "SCENE_OT_freestyle_modifier_remove";
1281 ot->description = "Remove the modifier from the list of modifiers";
1284 ot->exec = freestyle_modifier_remove_exec;
1285 ot->poll = freestyle_active_lineset_poll;
1288 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1291 static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
1293 Scene *scene = CTX_data_scene(C);
1294 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1295 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1296 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1297 LineStyleModifier *modifier = ptr.data;
1299 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1300 return OPERATOR_CANCELLED;
1303 switch (freestyle_get_modifier_type(&ptr)) {
1304 case LS_MODIFIER_TYPE_COLOR:
1305 BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
1307 case LS_MODIFIER_TYPE_ALPHA:
1308 BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
1310 case LS_MODIFIER_TYPE_THICKNESS:
1311 BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
1313 case LS_MODIFIER_TYPE_GEOMETRY:
1314 BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
1317 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1318 return OPERATOR_CANCELLED;
1320 DEG_id_tag_update(&lineset->linestyle->id, 0);
1321 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1323 return OPERATOR_FINISHED;
1326 void SCENE_OT_freestyle_modifier_copy(wmOperatorType *ot)
1329 ot->name = "Copy Modifier";
1330 ot->idname = "SCENE_OT_freestyle_modifier_copy";
1331 ot->description = "Duplicate the modifier within the list of modifiers";
1334 ot->exec = freestyle_modifier_copy_exec;
1335 ot->poll = freestyle_active_lineset_poll;
1338 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1341 static int freestyle_modifier_move_exec(bContext *C, wmOperator *op)
1343 Scene *scene = CTX_data_scene(C);
1344 SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, scene->r.actlay);
1345 FreestyleLineSet *lineset = BKE_freestyle_lineset_get_active(&srl->freestyleConfig);
1346 PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", &RNA_LineStyleModifier);
1347 LineStyleModifier *modifier = ptr.data;
1348 int dir = RNA_enum_get(op->ptr, "direction");
1349 bool changed = false;
1351 if (!freestyle_linestyle_check_report(lineset, op->reports)) {
1352 return OPERATOR_CANCELLED;
1355 switch (freestyle_get_modifier_type(&ptr)) {
1356 case LS_MODIFIER_TYPE_COLOR:
1357 changed = BKE_linestyle_color_modifier_move(lineset->linestyle, modifier, dir);
1359 case LS_MODIFIER_TYPE_ALPHA:
1360 changed = BKE_linestyle_alpha_modifier_move(lineset->linestyle, modifier, dir);
1362 case LS_MODIFIER_TYPE_THICKNESS:
1363 changed = BKE_linestyle_thickness_modifier_move(lineset->linestyle, modifier, dir);
1365 case LS_MODIFIER_TYPE_GEOMETRY:
1366 changed = BKE_linestyle_geometry_modifier_move(lineset->linestyle, modifier, dir);
1369 BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
1370 return OPERATOR_CANCELLED;
1374 DEG_id_tag_update(&lineset->linestyle->id, 0);
1375 WM_event_add_notifier(C, NC_LINESTYLE, lineset->linestyle);
1378 return OPERATOR_FINISHED;
1381 void SCENE_OT_freestyle_modifier_move(wmOperatorType *ot)
1383 static EnumPropertyItem direction_items[] = {
1384 {-1, "UP", 0, "Up", ""},
1385 {1, "DOWN", 0, "Down", ""},
1386 {0, NULL, 0, NULL, NULL}
1390 ot->name = "Move Modifier";
1391 ot->idname = "SCENE_OT_freestyle_modifier_move";
1392 ot->description = "Move the modifier within the list of modifiers";
1395 ot->exec = freestyle_modifier_move_exec;
1396 ot->poll = freestyle_active_lineset_poll;
1399 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1402 RNA_def_enum(ot->srna, "direction", direction_items, 0, "Direction",
1403 "Direction to move the chosen modifier towards");
1406 static int freestyle_stroke_material_create_exec(bContext *C, wmOperator *op)
1408 Main *bmain = CTX_data_main(C);
1409 Scene *scene = CTX_data_scene(C);
1410 FreestyleLineStyle *linestyle = BKE_linestyle_active_from_scene(scene);
1413 BKE_report(op->reports, RPT_ERROR, "No active line style in the current scene");
1414 return OPERATOR_CANCELLED;
1417 FRS_create_stroke_material(bmain, linestyle);
1419 return OPERATOR_FINISHED;
1422 void SCENE_OT_freestyle_stroke_material_create(wmOperatorType *ot)
1425 ot->name = "Create Freestyle Stroke Material";
1426 ot->idname = "SCENE_OT_freestyle_stroke_material_create";
1427 ot->description = "Create Freestyle stroke material for testing";
1430 ot->exec = freestyle_stroke_material_create_exec;
1433 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1436 #endif /* WITH_FREESTYLE */
1438 static int texture_slot_move_exec(bContext *C, wmOperator *op)
1440 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1443 MTex **mtex_ar, *mtexswap;
1445 int type = RNA_enum_get(op->ptr, "type");
1446 struct AnimData *adt = BKE_animdata_from_id(id);
1448 give_active_mtex(id, &mtex_ar, &act);
1450 if (type == -1) { /* Up */
1452 mtexswap = mtex_ar[act];
1453 mtex_ar[act] = mtex_ar[act - 1];
1454 mtex_ar[act - 1] = mtexswap;
1456 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act - 1, -1, 0);
1457 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act - 1, 0);
1458 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1460 if (GS(id->name) == ID_MA) {
1461 Material *ma = (Material *)id;
1462 int mtexuse = ma->septex & (1 << act);
1463 ma->septex &= ~(1 << act);
1464 ma->septex |= (ma->septex & (1 << (act - 1))) << 1;
1465 ma->septex &= ~(1 << (act - 1));
1466 ma->septex |= mtexuse >> 1;
1469 set_active_mtex(id, act - 1);
1473 if (act < MAX_MTEX - 1) {
1474 mtexswap = mtex_ar[act];
1475 mtex_ar[act] = mtex_ar[act + 1];
1476 mtex_ar[act + 1] = mtexswap;
1478 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act + 1, -1, 0);
1479 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, act, act + 1, 0);
1480 BKE_animdata_fix_paths_rename(id, adt, NULL, "texture_slots", NULL, NULL, -1, act, 0);
1482 if (GS(id->name) == ID_MA) {
1483 Material *ma = (Material *)id;
1484 int mtexuse = ma->septex & (1 << act);
1485 ma->septex &= ~(1 << act);
1486 ma->septex |= (ma->septex & (1 << (act + 1))) >> 1;
1487 ma->septex &= ~(1 << (act + 1));
1488 ma->septex |= mtexuse << 1;
1491 set_active_mtex(id, act + 1);
1495 DEG_id_tag_update(id, 0);
1496 WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
1499 return OPERATOR_FINISHED;
1502 void TEXTURE_OT_slot_move(wmOperatorType *ot)
1504 static EnumPropertyItem slot_move[] = {
1505 {-1, "UP", 0, "Up", ""},
1506 {1, "DOWN", 0, "Down", ""},
1507 {0, NULL, 0, NULL, NULL}
1511 ot->name = "Move Texture Slot";
1512 ot->idname = "TEXTURE_OT_slot_move";
1513 ot->description = "Move texture slots up and down";
1516 ot->exec = texture_slot_move_exec;
1519 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1521 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
1526 /********************** environment map operators *********************/
1528 static int save_envmap(wmOperator *op, Scene *scene, EnvMap *env, char *path, const char imtype)
1533 if ((prop = RNA_struct_find_property(op->ptr, "layout"))) {
1534 RNA_property_float_get_array(op->ptr, prop, layout);
1537 memcpy(layout, default_envmap_layout, sizeof(layout));
1540 if (RE_WriteEnvmapResult(op->reports, scene, env, path, imtype, layout)) {
1541 return OPERATOR_FINISHED;
1544 return OPERATOR_CANCELLED;
1549 static int envmap_save_exec(bContext *C, wmOperator *op)
1551 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1552 Scene *scene = CTX_data_scene(C);
1553 //int imtype = RNA_enum_get(op->ptr, "file_type");
1554 char imtype = scene->r.im_format.imtype;
1555 char path[FILE_MAX];
1557 RNA_string_get(op->ptr, "filepath", path);
1559 if (scene->r.scemode & R_EXTENSION) {
1560 BKE_image_path_ensure_ext_from_imformat(path, &scene->r.im_format);
1565 save_envmap(op, scene, tex->env, path, imtype);
1569 WM_event_add_notifier(C, NC_TEXTURE, tex);
1571 return OPERATOR_FINISHED;
1574 static int envmap_save_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
1576 //Scene *scene= CTX_data_scene(C);
1578 if (RNA_struct_property_is_set(op->ptr, "filepath"))
1579 return envmap_save_exec(C, op);
1581 //RNA_enum_set(op->ptr, "file_type", scene->r.im_format.imtype);
1582 RNA_string_set(op->ptr, "filepath", G.main->name);
1583 WM_event_add_fileselect(C, op);
1585 return OPERATOR_RUNNING_MODAL;
1588 static int envmap_save_poll(bContext *C)
1590 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1594 if (!tex->env || !tex->env->ok)
1596 if (tex->env->cube[1] == NULL)
1602 void TEXTURE_OT_envmap_save(wmOperatorType *ot)
1606 ot->name = "Save Environment Map";
1607 ot->idname = "TEXTURE_OT_envmap_save";
1608 ot->description = "Save the current generated Environment map to an image file";
1611 ot->exec = envmap_save_exec;
1612 ot->invoke = envmap_save_invoke;
1613 ot->poll = envmap_save_poll;
1616 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo since this doesnt modify the env-map */
1619 prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f,
1621 "Flat array describing the X,Y position of each cube face in the output image, "
1622 "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] "
1623 "(use -1 to skip a face)", 0.0f, 0.0f);
1624 RNA_def_property_flag(prop, PROP_HIDDEN);
1626 WM_operator_properties_filesel(
1627 ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_SAVE,
1628 WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
1631 static int envmap_clear_exec(bContext *C, wmOperator *UNUSED(op))
1633 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1635 BKE_texture_envmap_free_data(tex->env);
1637 WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
1639 return OPERATOR_FINISHED;
1642 static int envmap_clear_poll(bContext *C)
1644 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
1648 if (!tex->env || !tex->env->ok)
1650 if (tex->env->cube[1] == NULL)
1656 void TEXTURE_OT_envmap_clear(wmOperatorType *ot)
1659 ot->name = "Clear Environment Map";
1660 ot->idname = "TEXTURE_OT_envmap_clear";
1661 ot->description = "Discard the environment map and free it from memory";
1664 ot->exec = envmap_clear_exec;
1665 ot->poll = envmap_clear_poll;
1668 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1671 static int envmap_clear_all_exec(bContext *C, wmOperator *UNUSED(op))
1673 Main *bmain = CTX_data_main(C);
1676 for (tex = bmain->tex.first; tex; tex = tex->id.next)
1678 BKE_texture_envmap_free_data(tex->env);
1680 WM_event_add_notifier(C, NC_TEXTURE | NA_EDITED, tex);
1682 return OPERATOR_FINISHED;
1685 void TEXTURE_OT_envmap_clear_all(wmOperatorType *ot)
1688 ot->name = "Clear All Environment Maps";
1689 ot->idname = "TEXTURE_OT_envmap_clear_all";
1690 ot->description = "Discard all environment maps in the .blend file and free them from memory";
1693 ot->exec = envmap_clear_all_exec;
1694 ot->poll = envmap_clear_poll;
1697 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
1700 /********************** material operators *********************/
1702 /* material copy/paste */
1703 static int copy_material_exec(bContext *C, wmOperator *UNUSED(op))
1705 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1708 return OPERATOR_CANCELLED;
1710 copy_matcopybuf(ma);
1712 return OPERATOR_FINISHED;
1715 void MATERIAL_OT_copy(wmOperatorType *ot)
1718 ot->name = "Copy Material";
1719 ot->idname = "MATERIAL_OT_copy";
1720 ot->description = "Copy the material settings and nodes";
1723 ot->exec = copy_material_exec;
1726 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo needed since no changes are made to the material */
1729 static int paste_material_exec(bContext *C, wmOperator *UNUSED(op))
1731 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1734 return OPERATOR_CANCELLED;
1736 paste_matcopybuf(ma);
1738 WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
1740 return OPERATOR_FINISHED;
1743 void MATERIAL_OT_paste(wmOperatorType *ot)
1746 ot->name = "Paste Material";
1747 ot->idname = "MATERIAL_OT_paste";
1748 ot->description = "Paste the material settings and nodes";
1751 ot->exec = paste_material_exec;
1754 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
1758 static short mtexcopied = 0; /* must be reset on file load */
1759 static MTex mtexcopybuf;
1761 void ED_render_clear_mtex_copybuf(void)
1762 { /* use for file reload */
1766 static void copy_mtex_copybuf(ID *id)
1770 switch (GS(id->name)) {
1772 mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]);
1775 mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]);
1776 // la->mtex[(int)la->texact] // TODO
1779 mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]);
1780 // mtex= wrld->mtex[(int)wrld->texact]; // TODO
1783 mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1786 mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1792 if (mtex && *mtex) {
1793 memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
1801 static void paste_mtex_copybuf(ID *id)
1805 if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
1808 switch (GS(id->name)) {
1810 mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]);
1813 mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]);
1814 // la->mtex[(int)la->texact] // TODO
1817 mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]);
1818 // mtex= wrld->mtex[(int)wrld->texact]; // TODO
1821 mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1824 mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1827 BLI_assert(!"invalid id type");
1832 if (*mtex == NULL) {
1833 *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
1835 else if ((*mtex)->tex) {
1836 id_us_min(&(*mtex)->tex->id);
1839 memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
1841 id_us_plus((ID *)mtexcopybuf.tex);
1846 static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1848 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1851 /* copying empty slot */
1852 ED_render_clear_mtex_copybuf();
1853 return OPERATOR_CANCELLED;
1856 copy_mtex_copybuf(id);
1858 return OPERATOR_FINISHED;
1861 static int copy_mtex_poll(bContext *C)
1863 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1865 return (id != NULL);
1868 void TEXTURE_OT_slot_copy(wmOperatorType *ot)
1871 ot->name = "Copy Texture Slot Settings";
1872 ot->idname = "TEXTURE_OT_slot_copy";
1873 ot->description = "Copy the material texture settings and nodes";
1876 ot->exec = copy_mtex_exec;
1877 ot->poll = copy_mtex_poll;
1880 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo needed since no changes are made to the mtex */
1883 static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1885 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1888 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1889 Lamp *la = CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data;
1890 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
1891 ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1892 FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
1901 id = &psys->part->id;
1903 id = &linestyle->id;
1906 return OPERATOR_CANCELLED;
1909 paste_mtex_copybuf(id);
1911 WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
1913 return OPERATOR_FINISHED;
1916 void TEXTURE_OT_slot_paste(wmOperatorType *ot)
1919 ot->name = "Paste Texture Slot Settings";
1920 ot->idname = "TEXTURE_OT_slot_paste";
1921 ot->description = "Copy the texture settings and nodes";
1924 ot->exec = paste_mtex_exec;
1927 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;