Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/blender/addon')
-rw-r--r--intern/cycles/blender/addon/__init__.py6
-rw-r--r--intern/cycles/blender/addon/operators.py133
-rw-r--r--intern/cycles/blender/addon/properties.py6
-rw-r--r--intern/cycles/blender/addon/ui.py23
4 files changed, 145 insertions, 23 deletions
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 038126278aa..1f148538328 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -37,6 +37,8 @@ if "bpy" in locals():
importlib.reload(version_update)
if "ui" in locals():
importlib.reload(ui)
+ if "operators" in locals():
+ importlib.reload(operators)
if "properties" in locals():
importlib.reload(properties)
if "presets" in locals():
@@ -118,6 +120,7 @@ classes = (
def register():
from bpy.utils import register_class
from . import ui
+ from . import operators
from . import properties
from . import presets
import atexit
@@ -130,6 +133,7 @@ def register():
properties.register()
ui.register()
+ operators.register()
presets.register()
for cls in classes:
@@ -141,6 +145,7 @@ def register():
def unregister():
from bpy.utils import unregister_class
from . import ui
+ from . import operators
from . import properties
from . import presets
import atexit
@@ -148,6 +153,7 @@ def unregister():
bpy.app.handlers.version_update.remove(version_update.do_versions)
ui.unregister()
+ operators.unregister()
properties.unregister()
presets.unregister()
diff --git a/intern/cycles/blender/addon/operators.py b/intern/cycles/blender/addon/operators.py
new file mode 100644
index 00000000000..c39aa386203
--- /dev/null
+++ b/intern/cycles/blender/addon/operators.py
@@ -0,0 +1,133 @@
+#
+# Copyright 2011-2019 Blender Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# <pep8 compliant>
+
+import bpy
+from bpy.types import Operator
+from bpy.props import StringProperty
+
+
+class CYCLES_OT_use_shading_nodes(Operator):
+ """Enable nodes on a material, world or light"""
+ bl_idname = "cycles.use_shading_nodes"
+ bl_label = "Use Nodes"
+
+ @classmethod
+ def poll(cls, context):
+ return (getattr(context, "material", False) or getattr(context, "world", False) or
+ getattr(context, "light", False))
+
+ def execute(self, context):
+ if context.material:
+ context.material.use_nodes = True
+ elif context.world:
+ context.world.use_nodes = True
+ elif context.light:
+ context.light.use_nodes = True
+
+ return {'FINISHED'}
+
+
+class CYCLES_OT_denoise_animation(Operator):
+ """Denoise rendered animation sequence using current scene and view """ \
+ """layer settings. Requires denoising data passes and output to """ \
+ """OpenEXR multilayer files"""
+ bl_idname = "cycles.denoise_animation"
+ bl_label = "Denoise Animation"
+
+ input_filepath = StringProperty(
+ name='Input Filepath',
+ description='File path for frames to denoise. If not specified, uses the render file path from the scene',
+ default='',
+ subtype='FILE_PATH')
+
+ output_filepath = StringProperty(
+ name='Output Filepath',
+ description='If not specified, renders will be denoised in-place',
+ default='',
+ subtype='FILE_PATH')
+
+ def execute(self, context):
+ import os
+
+ preferences = context.user_preferences
+ scene = context.scene
+ render_layer = scene.render.layers.active
+
+ in_filepath = self.input_filepath
+ out_filepath = self.output_filepath
+
+ if in_filepath == '':
+ in_filepath = scene.render.filepath
+ if out_filepath == '':
+ out_filepath = in_filepath
+
+ # Backup since we will overwrite the scene path temporarily
+ original_filepath = scene.render.filepath
+
+ # Expand filepaths for each frame so we match Blender render output exactly.
+ in_filepaths = []
+ out_filepaths = []
+
+ for frame in range(scene.frame_start, scene.frame_end + 1):
+ scene.render.filepath = in_filepath
+ filepath = scene.render.frame_path(frame=frame)
+ in_filepaths.append(filepath)
+
+ if not os.path.isfile(filepath):
+ scene.render.filepath = original_filepath
+ self.report({'ERROR'}, f"Frame '{filepath}' not found, animation must be complete.")
+ return {'CANCELLED'}
+
+ scene.render.filepath = out_filepath
+ filepath = scene.render.frame_path(frame=frame)
+ out_filepaths.append(filepath)
+
+ scene.render.filepath = original_filepath
+
+ # Run denoiser
+ # TODO: support cancel and progress reports.
+ import _cycles
+ try:
+ _cycles.denoise(preferences.as_pointer(),
+ scene.as_pointer(),
+ render_layer.as_pointer(),
+ input=in_filepaths,
+ output=out_filepaths)
+ except Exception as e:
+ self.report({'ERROR'}, str(e))
+ return {'FINISHED'}
+
+ self.report({'INFO'}, "Denoising completed.")
+ return {'FINISHED'}
+
+
+classes = (
+ CYCLES_OT_use_shading_nodes,
+ CYCLES_OT_denoise_animation
+)
+
+def register():
+ from bpy.utils import register_class
+ for cls in classes:
+ register_class(cls)
+
+
+def unregister():
+ from bpy.utils import unregister_class
+ for cls in classes:
+ unregister_class(cls)
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 23ab1cf6a30..1106923f529 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1344,6 +1344,12 @@ class CyclesRenderLayerSettings(bpy.types.PropertyGroup):
default=False,
update=update_render_passes,
)
+ denoising_neighbor_frames: IntProperty(
+ name="Neighbor Frames",
+ description="Number of neighboring frames to use for denoising animations (more frames produce smoother results at the cost of performance)",
+ min=0, max=7,
+ default=0,
+ )
cls.use_pass_crypto_object = BoolProperty(
name="Cryptomatte Object",
description="Render cryptomatte object pass, for isolating objects in compositing",
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 2f1adfe4178..e372843d763 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -22,7 +22,6 @@ import _cycles
from bpy.types import (
Panel,
Menu,
- Operator,
)
@@ -912,27 +911,6 @@ class CYCLES_OBJECT_PT_cycles_settings(CyclesButtonsPanel, Panel):
sub.prop(cob, "use_distance_cull")
-class CYCLES_OT_use_shading_nodes(Operator):
- """Enable nodes on a material, world or lamp"""
- bl_idname = "cycles.use_shading_nodes"
- bl_label = "Use Nodes"
-
- @classmethod
- def poll(cls, context):
- return (getattr(context, "material", False) or getattr(context, "world", False) or
- getattr(context, "lamp", False))
-
- def execute(self, context):
- if context.material:
- context.material.use_nodes = True
- elif context.world:
- context.world.use_nodes = True
- elif context.lamp:
- context.lamp.use_nodes = True
-
- return {'FINISHED'}
-
-
def find_node(material, nodetype):
if material and material.node_tree:
ntree = material.node_tree
@@ -1870,7 +1848,6 @@ classes = (
CYCLES_PT_context_material,
CYCLES_OBJECT_PT_motion_blur,
CYCLES_OBJECT_PT_cycles_settings,
- CYCLES_OT_use_shading_nodes,
CYCLES_LAMP_PT_preview,
CYCLES_LAMP_PT_lamp,
CYCLES_LAMP_PT_nodes,