"""Node Group collections for use in Blender"""
import bpy
from ...utils import types
import numpy as np
from mathutils import Vector
from .node_group import ShaderNodeGroup
# docs-special-members: __init__
# no-inherited-members
[docs]
class DeformedGeneratedTextureCoordinates(ShaderNodeGroup):
"""
A :class:`ShaderNodeGroup` that outputs generated texture coordinates, but in the deformed space.
For example use, see :class:`DisplacementGeneratedAOV <blendersynth.blender.aov.DisplacementGeneratedAOV>`.
"""
[docs]
def __init__(
self,
node_tree: bpy.types.NodeTree,
mesh: types.Mesh,
bbox_min: types.VectorLike,
bbox_max: types.VectorLike,
):
"""To calculate the generated space, either needs mesh or bbox_min, bbox_max.
:param node_tree: NodeTree to add group to
:param mesh: If given, `bbox_min` and `bbox_max` are calculated using this
:param bbox_min: If given, `bbox_max` must also be given. The minimum of the bounding box of the mesh
:param bbox_max: If given, `bbox_min` must also be given. The maximum of the bounding box of the mesh
"""
super().__init__("DeformedGeneratedTextureCoordinates", node_tree)
self.group.outputs.new("NodeSocketVector", "Vector")
self.geometry_node = self.add_node("ShaderNodeNewGeometry")
self.vec_transform_node = self.add_node("ShaderNodeVectorTransform")
self.map_range_node = self.add_node("ShaderNodeMapRange")
self.vec_transform_node.vector_type = "POINT"
self.vec_transform_node.convert_from = "WORLD"
self.vec_transform_node.convert_to = "OBJECT"
self.map_range_node.clamp = False # avoid clamping to 0-1
self.map_range_node.data_type = "FLOAT_VECTOR"
self.register_bounds(mesh, bbox_min, bbox_max)
# link everything up
self.link(
self.geometry_node.outputs["Position"],
self.vec_transform_node.inputs["Vector"],
)
self.link(
self.vec_transform_node.outputs["Vector"],
self.map_range_node.inputs["Vector"],
)
self.link(
self.map_range_node.outputs["Vector"], self.output_node.inputs["Vector"]
)
self.tidy()
def register_bounds(
self, mesh: types.Mesh, bbox_min: types.VectorLike, bbox_max: types.VectorLike
):
# calculate bbox_min, bbox_max if not given
if mesh:
bbox_min, bbox_max = mesh.get_raw_bounds()
self.map_range_node.inputs[7].default_value = bbox_min
self.map_range_node.inputs[8].default_value = bbox_max