[Bf-extensions-cvs] [e7c2b215] blender-v3.0-release: Fix T92924: Copy Render Settings doesn't work in 3.0.

Bastien Montagne noreply at git.blender.org
Tue Nov 16 14:20:17 CET 2021


Commit: e7c2b215bba1dd3b914cb19a35575be9c0050750
Author: Bastien Montagne
Date:   Tue Nov 16 14:18:31 2021 +0100
Branches: blender-v3.0-release
https://developer.blender.org/rBAe7c2b215bba1dd3b914cb19a35575be9c0050750

Fix T92924: Copy Render Settings doesn't work in 3.0.

It's not possible anymore to call an operator from drawing code in most
cases (since it may be called during some init phase where this is
forbidden).

Looks like here the only viable solution is to use a timer for now. :(

===================================================================

M	render_copy_settings/__init__.py
M	render_copy_settings/operator.py
M	render_copy_settings/panel.py

===================================================================

diff --git a/render_copy_settings/__init__.py b/render_copy_settings/__init__.py
index ecc3603d..ee445e71 100644
--- a/render_copy_settings/__init__.py
+++ b/render_copy_settings/__init__.py
@@ -21,8 +21,8 @@
 bl_info = {
     "name": "Copy Render Settings",
     "author": "Bastien Montagne",
-    "version": (1, 0, 0),
-    "blender": (2, 80, 0),
+    "version": (1, 1, 0),
+    "blender": (3, 0, 0),
     "location": "Render buttons (Properties window)",
     "description": "Allows to copy a selection of render settings "
                    "from current scene to others.",
@@ -56,6 +56,11 @@ from bpy.props import (
 classes = data.classes + operator.classes + panel.classes
 
 
+def scene_render_copy_settings_timer():
+    operator.scene_render_copy_settings_update()
+    return 1.0  # Run every second.
+
+
 def register():
     for cls in classes:
         bpy.utils.register_class(cls)
@@ -63,8 +68,12 @@ def register():
 
     bpy.app.translations.register(__name__, translations.translations_dict)
 
+    bpy.app.timers.register(scene_render_copy_settings_timer, persistent=True)
+
 
 def unregister():
+    bpy.app.timers.unregister(scene_render_copy_settings_timer)
+
     bpy.app.translations.unregister(__name__)
 
     del bpy.types.Scene.render_copy_settings
diff --git a/render_copy_settings/operator.py b/render_copy_settings/operator.py
index 5c633f1f..5de9bc3d 100644
--- a/render_copy_settings/operator.py
+++ b/render_copy_settings/operator.py
@@ -21,9 +21,6 @@
 import bpy
 from . import presets
 
-# These operators are only defined because it seems impossible to directly edit properties from UI code…
-
-
 # A sorting func for collections (working in-place).
 # XXX Not optimized at all…
 # XXX If some items in the collection do not have the sortkey property, they are just ignored…
@@ -46,74 +43,66 @@ def collection_property_sort(collection, sortkey, start_idx=0):
     return collection
 
 
-class RenderCopySettingsOPPrepare(bpy.types.Operator):
-    """Prepare internal data for render_copy_settings (gathering all existing render settings, and scenes)"""
-    bl_idname = "scene.render_copy_settings_prepare"
-    bl_label = "Render: Copy Settings Prepare"
-    bl_option = {'REGISTER'}
-
-    @classmethod
-    def poll(cls, context):
-        return context.scene is not None
-
-    def execute(self, context):
-        cp_sett = context.scene.render_copy_settings
+def scene_render_copy_settings_update():
+    """Prepare internal data for render_copy_settings (gathering all existing render settings, and scenes)."""
+    current_scene = getattr(bpy.context, "scene", None)
+    if current_scene is None:
+        return
+    cp_sett = current_scene.render_copy_settings
 
-        # Get all available render settings, and update accordingly affected_settings…
-        props = {}
-        for prop in context.scene.render.bl_rna.properties:
-            if prop.identifier in {'rna_type'}:
-                continue
-            if prop.is_readonly:
-                continue
-            props[prop.identifier] = prop.name
-        corr = 0
-        for i, sett in enumerate(cp_sett.affected_settings):
-            if sett.strid not in props:
-                cp_sett.affected_settings.remove(i - corr)
-                corr += 1
-            else:
-                del props[sett.strid]
-        for strid, name in props.items():
-            sett = cp_sett.affected_settings.add()
-            sett.name = "{} [{}]".format(name, strid)
-            sett.strid = strid
-        collection_property_sort(cp_sett.affected_settings, "name")
-
-        # Get all available scenes, and update accordingly allowed_scenes…
-        regex = None
-        if cp_sett.filter_scene:
+    # Get all available render settings, and update accordingly affected_settings…
+    props = {}
+    for prop in current_scene.render.bl_rna.properties:
+        if prop.identifier in {'rna_type'}:
+            continue
+        if prop.is_readonly:
+            continue
+        props[prop.identifier] = prop.name
+    corr = 0
+    for i, sett in enumerate(cp_sett.affected_settings):
+        if sett.strid not in props:
+            cp_sett.affected_settings.remove(i - corr)
+            corr += 1
+        else:
+            del props[sett.strid]
+    for strid, name in props.items():
+        sett = cp_sett.affected_settings.add()
+        sett.name = "{} [{}]".format(name, strid)
+        sett.strid = strid
+    collection_property_sort(cp_sett.affected_settings, "name")
+
+    # Get all available scenes, and update accordingly allowed_scenes…
+    regex = None
+    if cp_sett.filter_scene:
+        try:
+            import re
             try:
-                import re
-                try:
-                    regex = re.compile(cp_sett.filter_scene)
-                except Exception as e:
-                    self.report({'ERROR_INVALID_INPUT'}, "The filter-scene regex did not compile:\n    (%s)." % str(e))
-                    return {'CANCELLED'}
-            except:
-                regex = None
-                self.report({'WARNING'}, "Unable to import the re module, regex scene filtering will be disabled!")
-        scenes = set()
-        for scene in bpy.data.scenes:
-            if scene == bpy.context.scene:  # Exclude current scene!
-                continue
-            # If a valid filtering regex, only keep scenes matching it.
-            if regex:
-                if regex.match(scene.name):
-                    scenes.add(scene.name)
-            else:
+                regex = re.compile(cp_sett.filter_scene)
+            except Exception as e:
+                print("The filter-scene regex did not compile:\n    (%s)." % str(e))
+                return
+        except:
+            regex = None
+            print("Unable to import the re module, regex scene filtering will be disabled!")
+    scenes = set()
+    for scene in bpy.data.scenes:
+        if scene == current_scene:  # Exclude current scene!
+            continue
+        # If a valid filtering regex, only keep scenes matching it.
+        if regex:
+            if regex.match(scene.name):
                 scenes.add(scene.name)
-        for i, scene in enumerate(cp_sett.allowed_scenes):
-            if scene.name not in scenes:
-                cp_sett.allowed_scenes.remove(i)
-            else:
-                scenes.remove(scene.name)
-        for scene in scenes:
-            sett = cp_sett.allowed_scenes.add()
-            sett.name = scene
-        collection_property_sort(cp_sett.allowed_scenes, "name")
-
-        return {'FINISHED'}
+        else:
+            scenes.add(scene.name)
+    for i, scene in enumerate(cp_sett.allowed_scenes):
+        if scene.name not in scenes:
+            cp_sett.allowed_scenes.remove(i)
+        else:
+            scenes.remove(scene.name)
+    for scene in scenes:
+        sett = cp_sett.allowed_scenes.add()
+        sett.name = scene
+    collection_property_sort(cp_sett.allowed_scenes, "name")
 
 
 from bpy.props import EnumProperty
@@ -191,7 +180,6 @@ class RenderCopySettingsOPCopy(bpy.types.Operator):
 
 
 classes = (
-    RenderCopySettingsOPPrepare,
     RenderCopySettingsOPPreset,
     RenderCopySettingsOPCopy,
 )
diff --git a/render_copy_settings/panel.py b/render_copy_settings/panel.py
index 88f4e940..1e79bef7 100644
--- a/render_copy_settings/panel.py
+++ b/render_copy_settings/panel.py
@@ -55,11 +55,6 @@ class RENDER_PT_copy_settings(bpy.types.Panel):
 
         layout.operator("scene.render_copy_settings", text="Copy Render Settings")
 
-        # This will update affected_settings/allowed_scenes (as this seems
-        # to be impossible to do it from here…).
-        if bpy.ops.scene.render_copy_settings_prepare.poll():
-            bpy.ops.scene.render_copy_settings_prepare()
-
         split = layout.split(factor=0.75)
         split.template_list("RENDER_UL_copy_settings", "settings", cp_sett, "affected_settings",
                             cp_sett, "affected_settings_idx", rows=5)



More information about the Bf-extensions-cvs mailing list