Cleanup: remove "Tweak" event type
[blender-addons.git] / render_copy_settings / operator.py
blobd097a35be1034322cc29a36b27f75d3eb8726e1b
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 # <pep8 compliant>
5 import bpy
6 from . import presets
8 # A sorting func for collections (working in-place).
9 # XXX Not optimized at all…
10 # XXX If some items in the collection do not have the sortkey property, they are just ignored…
11 def collection_property_sort(collection, sortkey, start_idx=0):
12 while start_idx + 1 < len(collection):
13 while not hasattr(collection[start_idx], sortkey):
14 start_idx += 1
15 if start_idx + 1 >= len(collection):
16 return collection
17 min_idx = start_idx
18 min_prop = collection[start_idx]
19 for i, prop in enumerate(collection[start_idx + 1:]):
20 if not hasattr(prop, sortkey):
21 continue
22 if getattr(prop, sortkey) < getattr(min_prop, sortkey):
23 min_prop = prop
24 min_idx = i + start_idx + 1
25 collection.move(min_idx, start_idx)
26 start_idx += 1
27 return collection
30 def scene_render_copy_settings_update():
31 """Prepare internal data for render_copy_settings (gathering all existing render settings, and scenes)."""
32 current_scene = getattr(bpy.context, "scene", None)
33 if current_scene is None:
34 return
35 cp_sett = current_scene.render_copy_settings
37 # Get all available render settings, and update accordingly affected_settings…
38 props = {}
39 for prop in current_scene.render.bl_rna.properties:
40 if prop.identifier in {'rna_type'}:
41 continue
42 if prop.is_readonly:
43 continue
44 props[prop.identifier] = prop.name
45 corr = 0
46 for i, sett in enumerate(cp_sett.affected_settings):
47 if sett.strid not in props:
48 cp_sett.affected_settings.remove(i - corr)
49 corr += 1
50 else:
51 del props[sett.strid]
52 for strid, name in props.items():
53 sett = cp_sett.affected_settings.add()
54 sett.name = "{} [{}]".format(name, strid)
55 sett.strid = strid
56 collection_property_sort(cp_sett.affected_settings, "name")
58 # Get all available scenes, and update accordingly allowed_scenes…
59 regex = None
60 if cp_sett.filter_scene:
61 try:
62 import re
63 try:
64 regex = re.compile(cp_sett.filter_scene)
65 except Exception as e:
66 print("The filter-scene regex did not compile:\n (%s)." % str(e))
67 return
68 except:
69 regex = None
70 print("Unable to import the re module, regex scene filtering will be disabled!")
71 scenes = set()
72 for scene in bpy.data.scenes:
73 if scene == current_scene: # Exclude current scene!
74 continue
75 # If a valid filtering regex, only keep scenes matching it.
76 if regex:
77 if regex.match(scene.name):
78 scenes.add(scene.name)
79 else:
80 scenes.add(scene.name)
81 for i, scene in enumerate(cp_sett.allowed_scenes):
82 if scene.name not in scenes:
83 cp_sett.allowed_scenes.remove(i)
84 else:
85 scenes.remove(scene.name)
86 for scene in scenes:
87 sett = cp_sett.allowed_scenes.add()
88 sett.name = scene
89 collection_property_sort(cp_sett.allowed_scenes, "name")
92 from bpy.props import EnumProperty
95 class RenderCopySettingsOPPreset(bpy.types.Operator):
96 """Apply some presets of render settings to copy to other scenes"""
97 bl_idname = "scene.render_copy_settings_preset"
98 bl_label = "Render: Copy Settings Preset"
99 bl_description = "Apply or clear this preset of render settings"
100 # Enable undo…
101 bl_option = {'REGISTER', 'UNDO'}
103 presets: EnumProperty(items=(p.rna_enum for p in presets.presets),
104 default=set(),
105 options={'ENUM_FLAG'})
107 @staticmethod
108 def process_elements(settings, elts):
109 setts = []
110 val = True
111 for sett in settings:
112 if sett.strid in elts:
113 setts.append(sett)
114 val = val and sett.copy
115 for e in setts:
116 e.copy = not val
118 @classmethod
119 def poll(cls, context):
120 return context.scene is not None
122 def execute(self, context):
123 cp_sett = context.scene.render_copy_settings
124 for p in presets.presets:
125 if p.rna_enum[0] in self.presets:
126 self.process_elements(cp_sett.affected_settings, p.elements)
127 return {'FINISHED'}
130 # Real interesting stuff…
132 def do_copy(context, affected_settings, allowed_scenes):
133 # Stores render settings from current scene.
134 p = {sett: getattr(context.scene.render, sett)
135 for sett in affected_settings}
136 # put it in all other (valid) scenes’ render settings!
137 for scene in bpy.data.scenes:
138 # If scene not in allowed scenes, skip.
139 if scene.name not in allowed_scenes:
140 continue
141 # Propagate all affected settings.
142 for sett, val in p.items():
143 setattr(scene.render, sett, val)
146 class RenderCopySettingsOPCopy(bpy.types.Operator):
147 """Copy render settings from current scene to others"""
148 bl_idname = "scene.render_copy_settings"
149 bl_label = "Render: Copy Settings"
150 # Enable undo…
151 bl_option = {'REGISTER', 'UNDO'}
153 @classmethod
154 def poll(cls, context):
155 return context.scene is not None
157 def execute(self, context):
158 regex = None
159 cp_sett = context.scene.render_copy_settings
160 affected_settings = {sett.strid for sett in cp_sett.affected_settings if sett.copy}
161 allowed_scenes = {sce.name for sce in cp_sett.allowed_scenes if sce.allowed}
162 do_copy(context, affected_settings=affected_settings, allowed_scenes=allowed_scenes)
163 return {'FINISHED'}
166 classes = (
167 RenderCopySettingsOPPreset,
168 RenderCopySettingsOPCopy,