Source code for blendersynth.blender.world

import bpy
from .nodes.node_arranger import tidy_tree
from typing import Union
from ..utils import io


[docs] class World: """World object - for managing world nodes, HDRIs, etc.""" def __init__(self): self.mode = "Color" if "World" not in bpy.data.worlds: world = bpy.data.worlds.new("World") world.use_nodes = True self.world = bpy.data.worlds["World"] self.node_tree = self.world.node_tree self.world_nodes = self.node_tree.nodes self.hdri_link = None # if default setup (a Background node and a WorldOutput node) if len(self.world_nodes) == 2 and all( [node.name in ["Background", "World Output"] for node in self.world_nodes] ): self._setup_nodes() self.set_color((0.051,) * 3) # match blender's default world color else: self._load_nodes() self._setup_hdri() def _check_exists(self): """Node tree may have been wiped, eg by loading a new file. Check if the nodes exist, and if not, recreate them.""" try: self.node_tree.rna_type except ReferenceError: self.__init__() def _setup_nodes(self): self._check_exists() nodes = self.world_nodes nodes.clear() self.node_texture = nodes.new(type="ShaderNodeTexEnvironment") self.node_background = nodes.new(type="ShaderNodeBackground") self.node_output = nodes.new(type="ShaderNodeOutputWorld") self.node_tree.links.new( self.node_background.outputs["Background"], self.node_output.inputs["Surface"], ) tidy_tree(self.node_tree) def _load_nodes(self): """If Nodes already exist, load them""" try: self.node_texture = self.world_nodes["Environment Texture"] self.node_background = self.world_nodes["Background"] self.node_output = self.world_nodes["World Output"] except KeyError: raise KeyError( "To load in a World, the World must have 'Environment Texture', 'Background', and 'World Output' nodes." ) # add links if they don't exist if len(self.node_tree.links) == 0: self.node_tree.links.new( self.node_background.outputs["Background"], self.node_output.inputs["Surface"], ) def _setup_color(self): self._check_exists() if self.mode == "Color": return if self.hdri_link is not None: self.node_tree.links.remove(self.hdri_link) tidy_tree(self.node_tree) self.mode = "Color" def _setup_hdri(self): self._check_exists() if self.mode == "HDRI": return # Link the nodes self.hdri_link = self.node_tree.links.new( self.node_texture.outputs["Color"], self.node_background.inputs["Color"] ) tidy_tree(self.node_tree) self.mode = "HDRI"
[docs] def set_color(self, color: Union[list, tuple], affect_scene: bool = True): """Set the world color. :param color: RGB or RGBA color :param affect_scene: Toggle for whether color's lighting should affect the scene (if False, functions as a solid background color) """ self._setup_color() assert len(color) in [3, 4], "Color must be RGB or RGBA" if len(color) == 3: color = (*color, 1.0) self.node_background.inputs["Color"].default_value = color self._lighting_from_background(affect_scene)
[docs] def set_hdri(self, pth: str, affect_scene: bool = True, intensity: float = None): """Set the HDRI image location :param pth: Path to the HDRI image (.hdr or .exr) :param affect_scene: Toggle for whether color's lighting should affect the scene (if False, functions as a solid background color) :param intensity: [Optional] Set the intensity of the HDRI lighting""" self._setup_hdri() self.world_nodes["Environment Texture"].image = io.load_image(pth) self._lighting_from_background(affect_scene) if intensity: self.set_intensity(intensity)
[docs] def set_intensity(self, intensity: float = 1.0): """Set the intensity of the color/HDRI. :param intensity: The intensity value """ self.world_nodes["Background"].inputs[1].default_value = intensity
def set_transparent(self, transparent=True): bpy.context.scene.render.film_transparent = transparent def _lighting_from_background(self, val=True): """Change the ability for the background to influence lighting on the scene""" self.world.cycles_visibility.diffuse = val
world = World()