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

operators.py « addon « blender « cycles « intern - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: c39aa386203512d171eb8a781b15563aa3f2e21c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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)