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"
87 #include "ED_screen.h"
89 #include "RNA_define.h"
91 #include "UI_interface.h"
93 #include "RE_pipeline.h"
95 #include "render_intern.h" // own include
97 /********************** material slot operators *********************/
99 static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
101 Object *ob = ED_object_context(C);
104 return OPERATOR_CANCELLED;
106 BKE_object_material_slot_add(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(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 DEG_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 DEG_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 Object *ob = ED_object_context(C);
352 if (!ob || !(matar = give_matarar(ob)))
353 return OPERATOR_CANCELLED;
355 CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects)
357 if (ob != ob_iter && give_matarar(ob_iter)) {
358 if (ob->data != ob_iter->data)
359 assign_matarar(ob_iter, matar, ob->totcol);
361 if (ob_iter->totcol == ob->totcol) {
362 ob_iter->actcol = ob->actcol;
363 DEG_id_tag_update(&ob_iter->id, OB_RECALC_DATA);
364 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
370 return OPERATOR_FINISHED;
374 void OBJECT_OT_material_slot_copy(wmOperatorType *ot)
377 ot->name = "Copy Material to Others";
378 ot->idname = "OBJECT_OT_material_slot_copy";
379 ot->description = "Copies materials to other selected objects";
382 ot->exec = material_slot_copy_exec;
385 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
388 static int material_slot_move_exec(bContext *C, wmOperator *op)
390 Object *ob = ED_object_context(C);
392 unsigned int *slot_remap;
395 int dir = RNA_enum_get(op->ptr, "direction");
397 if (!ob || ob->totcol < 2) {
398 return OPERATOR_CANCELLED;
402 if (dir == 1 && ob->actcol > 1) {
403 index_pair[0] = ob->actcol - 2;
404 index_pair[1] = ob->actcol - 1;
408 else if (dir == -1 && ob->actcol < ob->totcol) {
409 index_pair[0] = ob->actcol - 1;
410 index_pair[1] = ob->actcol - 0;
414 return OPERATOR_CANCELLED;
417 slot_remap = MEM_mallocN(sizeof(unsigned int) * ob->totcol, __func__);
419 range_vn_u(slot_remap, ob->totcol, 0);
421 slot_remap[index_pair[0]] = index_pair[1];
422 slot_remap[index_pair[1]] = index_pair[0];
424 BKE_material_remap_object(ob, slot_remap);
426 MEM_freeN(slot_remap);
428 DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
429 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW | ND_DATA, ob);
431 return OPERATOR_FINISHED;
434 void OBJECT_OT_material_slot_move(wmOperatorType *ot)
436 static EnumPropertyItem material_slot_move[] = {
437 {1, "UP", 0, "Up", ""},
438 {-1, "DOWN", 0, "Down", ""},
439 {0, NULL, 0, NULL, NULL}
443 ot->name = "Move Material";
444 ot->idname = "OBJECT_OT_material_slot_move";
445 ot->description = "Move the active material up/down in the list";
448 ot->exec = material_slot_move_exec;
451 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
453 RNA_def_enum(ot->srna, "direction", material_slot_move, 0, "Direction",
454 "Direction to move the active material towards");
457 /********************** new material operator *********************/
459 static int new_material_exec(bContext *C, wmOperator *UNUSED(op))
461 Scene *scene = CTX_data_scene(C);
462 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
463 Main *bmain = CTX_data_main(C);
464 PointerRNA ptr, idptr;
467 /* add or copy material */
469 ma = BKE_material_copy(bmain, ma);
472 ma = BKE_material_add(bmain, DATA_("Material"));
474 if (BKE_scene_use_new_shading_nodes(scene)) {
475 ED_node_shader_default(C, &ma->id);
476 ma->use_nodes = true;
481 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
484 /* when creating new ID blocks, use is already 1, but RNA
485 * pointer use also increases user, so this compensates it */
488 RNA_id_pointer_create(&ma->id, &idptr);
489 RNA_property_pointer_set(&ptr, prop, idptr);
490 RNA_property_update(C, &ptr, prop);
493 WM_event_add_notifier(C, NC_MATERIAL | NA_ADDED, ma);
495 return OPERATOR_FINISHED;
498 void MATERIAL_OT_new(wmOperatorType *ot)
501 ot->name = "New Material";
502 ot->idname = "MATERIAL_OT_new";
503 ot->description = "Add a new material";
506 ot->exec = new_material_exec;
509 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
512 /********************** new texture operator *********************/
514 static int new_texture_exec(bContext *C, wmOperator *UNUSED(op))
516 Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
517 Main *bmain = CTX_data_main(C);
518 PointerRNA ptr, idptr;
521 /* add or copy texture */
523 tex = BKE_texture_copy(bmain, tex);
526 tex = BKE_texture_add(bmain, DATA_("Texture"));
530 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
533 /* when creating new ID blocks, use is already 1, but RNA
534 * pointer use also increases user, so this compensates it */
537 if (ptr.id.data && GS(((ID *)ptr.id.data)->name) == ID_MA &&
538 RNA_property_pointer_get(&ptr, prop).id.data == NULL)
540 /* In case we are assigning new texture to a material, and active slot was empty, reset 'use' flag. */
541 Material *ma = (Material *)ptr.id.data;
542 ma->septex &= ~(1 << ma->texact);
545 RNA_id_pointer_create(&tex->id, &idptr);
546 RNA_property_pointer_set(&ptr, prop, idptr);
547 RNA_property_update(C, &ptr, prop);
550 WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, tex);
552 return OPERATOR_FINISHED;
555 void TEXTURE_OT_new(wmOperatorType *ot)
558 ot->name = "New Texture";
559 ot->idname = "TEXTURE_OT_new";
560 ot->description = "Add a new texture";
563 ot->exec = new_texture_exec;
566 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
569 /********************** new world operator *********************/
571 static int new_world_exec(bContext *C, wmOperator *UNUSED(op))
573 Scene *scene = CTX_data_scene(C);
574 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
575 Main *bmain = CTX_data_main(C);
576 PointerRNA ptr, idptr;
579 /* add or copy world */
581 wo = BKE_world_copy(bmain, wo);
584 wo = add_world(bmain, DATA_("World"));
586 if (BKE_scene_use_new_shading_nodes(scene)) {
587 ED_node_shader_default(C, &wo->id);
588 wo->use_nodes = true;
593 UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
596 /* when creating new ID blocks, use is already 1, but RNA
597 * pointer use also increases user, so this compensates it */
600 RNA_id_pointer_create(&wo->id, &idptr);
601 RNA_property_pointer_set(&ptr, prop, idptr);
602 RNA_property_update(C, &ptr, prop);
605 WM_event_add_notifier(C, NC_WORLD | NA_ADDED, wo);
607 return OPERATOR_FINISHED;
610 void WORLD_OT_new(wmOperatorType *ot)
613 ot->name = "New World";
614 ot->idname = "WORLD_OT_new";
615 ot->description = "Create a new world Data-Block";
618 ot->exec = new_world_exec;
621 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
624 /********************** render layer operators *********************/
626 static int render_layer_add_exec(bContext *C, wmOperator *UNUSED(op))
628 Scene *scene = CTX_data_scene(C);
630 BKE_scene_layer_add(scene, NULL);
631 scene->active_layer = BLI_listbase_count(&scene->render_layers) - 1;
633 DEG_id_tag_update(&scene->id, 0);
634 DEG_relations_tag_update(CTX_data_main(C));
635 WM_event_add_notifier(C, NC_SCENE | ND_LAYER, scene);
637 return OPERATOR_FINISHED;
640 void SCENE_OT_render_layer_add(wmOperatorType *ot)
643 ot->name = "Add Render Layer";
644 ot->idname = "SCENE_OT_render_layer_add";
645 ot->description = "Add a render layer";
648 ot->exec = render_layer_add_exec;
651 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
654 static int render_layer_remove_exec(bContext *C, wmOperator *UNUSED(op))
656 Scene *scene = CTX_data_scene(C);
657 SceneLayer *sl = BKE_scene_layer_context_active(scene);
659 if (!BKE_scene_layer_remove(CTX_data_main(C), scene, sl)) {
660 return OPERATOR_CANCELLED;
663 DEG_id_tag_update(&scene->id, 0);
664 DEG_relations_tag_update(CTX_data_main(C));
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);
1307 case LS_MODIFIER_TYPE_ALPHA:
1308 BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier);
1310 case LS_MODIFIER_TYPE_THICKNESS:
1311 BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier);
1313 case LS_MODIFIER_TYPE_GEOMETRY:
1314 BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier);
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]);
1790 if (mtex && *mtex) {
1791 memcpy(&mtexcopybuf, *mtex, sizeof(MTex));
1799 static void paste_mtex_copybuf(ID *id)
1803 if (mtexcopied == 0 || mtexcopybuf.tex == NULL)
1806 switch (GS(id->name)) {
1808 mtex = &(((Material *)id)->mtex[(int)((Material *)id)->texact]);
1811 mtex = &(((Lamp *)id)->mtex[(int)((Lamp *)id)->texact]);
1812 // la->mtex[(int)la->texact] // TODO
1815 mtex = &(((World *)id)->mtex[(int)((World *)id)->texact]);
1816 // mtex= wrld->mtex[(int)wrld->texact]; // TODO
1819 mtex = &(((ParticleSettings *)id)->mtex[(int)((ParticleSettings *)id)->texact]);
1822 mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
1825 BLI_assert("invalid id type");
1830 if (*mtex == NULL) {
1831 *mtex = MEM_mallocN(sizeof(MTex), "mtex copy");
1833 else if ((*mtex)->tex) {
1834 id_us_min(&(*mtex)->tex->id);
1837 memcpy(*mtex, &mtexcopybuf, sizeof(MTex));
1839 id_us_plus((ID *)mtexcopybuf.tex);
1844 static int copy_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1846 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1849 /* copying empty slot */
1850 ED_render_clear_mtex_copybuf();
1851 return OPERATOR_CANCELLED;
1854 copy_mtex_copybuf(id);
1856 return OPERATOR_FINISHED;
1859 static int copy_mtex_poll(bContext *C)
1861 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1863 return (id != NULL);
1866 void TEXTURE_OT_slot_copy(wmOperatorType *ot)
1869 ot->name = "Copy Texture Slot Settings";
1870 ot->idname = "TEXTURE_OT_slot_copy";
1871 ot->description = "Copy the material texture settings and nodes";
1874 ot->exec = copy_mtex_exec;
1875 ot->poll = copy_mtex_poll;
1878 ot->flag = OPTYPE_REGISTER | OPTYPE_INTERNAL; /* no undo needed since no changes are made to the mtex */
1881 static int paste_mtex_exec(bContext *C, wmOperator *UNUSED(op))
1883 ID *id = CTX_data_pointer_get_type(C, "texture_slot", &RNA_TextureSlot).id.data;
1886 Material *ma = CTX_data_pointer_get_type(C, "material", &RNA_Material).data;
1887 Lamp *la = CTX_data_pointer_get_type(C, "lamp", &RNA_Lamp).data;
1888 World *wo = CTX_data_pointer_get_type(C, "world", &RNA_World).data;
1889 ParticleSystem *psys = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem).data;
1890 FreestyleLineStyle *linestyle = CTX_data_pointer_get_type(C, "line_style", &RNA_FreestyleLineStyle).data;
1899 id = &psys->part->id;
1901 id = &linestyle->id;
1904 return OPERATOR_CANCELLED;
1907 paste_mtex_copybuf(id);
1909 WM_event_add_notifier(C, NC_TEXTURE | ND_SHADING_LINKS, NULL);
1911 return OPERATOR_FINISHED;
1914 void TEXTURE_OT_slot_paste(wmOperatorType *ot)
1917 ot->name = "Paste Texture Slot Settings";
1918 ot->idname = "TEXTURE_OT_slot_paste";
1919 ot->description = "Copy the texture settings and nodes";
1922 ot->exec = paste_mtex_exec;
1925 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;