Source code for blendify.renderables.collection

from typing import Dict, Iterable, Union, Sequence

import numpy as np

from . import primitives
from .base import Renderable
from .mesh import Mesh
from .pointcloud import PointCloud
from ..colors import UniformColors
from ..colors.base import Colors, ColorsList
from ..internal import Singleton
from ..internal.types import Vector3d, RotationParams
from ..materials.base import Material, MaterialList


[docs] class RenderablesCollection(metaclass=Singleton): def __init__(self): self._renderables: Dict[str, Renderable] = dict() # =================================================== PointCloud ===================================================
[docs] def add_pointcloud( self, vertices: np.ndarray, material: Material, colors: Colors, point_size: float = 0.006, base_primitive: str = "CUBE", particle_emission_strength: int = 1, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> PointCloud: """Add PointCloud object to the scene. The object supports uniform (UniformColors) and per-vertex (VertexColors) coloring. Args: vertices (np.ndarray): point cloud vertices material (Material): Material instance colors (Colors): VertexColors or UniformColors instance point_size (float, optional): size of a primitive, representing each vertex (default: 0.006) base_primitive (str, optional): type of primitive for representing each point (possible values are PLANE, CUBE, SPHERE, default: CUBE) particle_emission_strength (int, optional): strength of the emission from each primitive. This is used to increase realism. Values <= 0 turn emission off, values > 0 set the power of emission (default: 1) rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created collection in Blender to represent the point cloud. If None is passed the tag is automatically generated (default: None) Returns: PointCloud: created and added to the scene object """ tag = self._process_tag(tag, "PointCloud") obj = PointCloud( vertices=vertices, material=material, colors=colors, point_size=point_size, base_primitive=base_primitive, particle_emission_strength=particle_emission_strength, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag ) self._renderables[tag] = obj return obj
# =============================================== End of PointCloud ================================================ # ============================================ Mesh and Mesh Primitives ============================================
[docs] def add_mesh( self, vertices: np.ndarray, faces: np.ndarray, material: Union[Material, MaterialList], colors: Union[Colors, ColorsList], faces_material: Sequence[Sequence[int]] = None, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> Mesh: """Add Mesh object to the scene. The object supports uniform (UniformColors), per-vertex (VertexColors), per-vertex uv (VertexUV), per-face uv (FacesUV) and texture (TextureColors and FileTextureColors) coloring. Args: vertices (np.ndarray): mesh vertices faces (np.ndarray): mesh faces material (Union[Material, MaterialList]): Material instance or list of Material instances colors (Union[Colors, ColorsList]): Colors instance or list of Colors instances faces_material (Sequence[Sequence[int]], optional): for each face, the material index assigned to it rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: Mesh: created and added to the scene object """ tag = self._process_tag(tag, "Mesh") obj = Mesh( vertices=vertices, faces=faces, material=material, colors=colors, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag, faces_material=faces_material ) self._renderables[tag] = obj return obj
[docs] def add_cube_mesh( self, size: float, material: Union[Material, MaterialList], colors: Union[Colors, ColorsList], faces_material: Sequence[Sequence[int]] = None, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.CubeMesh: """Add primitives.CircleMesh object to the scene. The object supports only uniform coloring (UniformColors). Args: size (float): size of a primitive in [0, inf] material (Union[Material, MaterialList]): Material instance or list of Material instances colors (Union[Colors, ColorsList]): Colors instance or list of Colors instances faces_material (Sequence[Sequence[int]], optional): for each face, the material index assigned to it rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.CircleMesh: created and added to the scene object """ tag = self._process_tag(tag, "Cube") obj = primitives.CubeMesh( size=size, material=material, colors=colors, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag, faces_material=faces_material ) self._renderables[tag] = obj return obj
[docs] def add_circle_mesh( self, radius: float, material: Union[Material, MaterialList], colors: Union[Colors, ColorsList], faces_material: Sequence[Sequence[int]] = None, num_vertices: int = 32, fill_type: str = "NGON", rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.CircleMesh: """Add primitives.CircleMesh object to the scene. The object supports only uniform coloring (UniformColors). Args: radius (float): radius of a primitive in [0, inf] material (Union[Material, MaterialList]): Material instance or list of Material instances colors (Union[Colors, ColorsList]): Colors instance or list of Colors instances faces_material (Sequence[Sequence[int]], optional): for each face, the material index assigned to it num_vertices (int, optional): number of vertices in primitive in [3, 10000000] (default: 32) fill_type (str, optional): fill type, one of [NOTHING, NGON, TRIFAN] (default: NGON) rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.CircleMesh: created and added to the scene object """ tag = self._process_tag(tag, "Circle") obj = primitives.CircleMesh( radius=radius, material=material, colors=colors, num_vertices=num_vertices, fill_type=fill_type, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag, faces_material=faces_material ) self._renderables[tag] = obj return obj
[docs] def add_cylinder_mesh( self, radius: float, height: float, material: Union[Material, MaterialList], colors: Union[Colors, ColorsList], faces_material: Sequence[Sequence[int]] = None, num_vertices: int = 32, fill_type: str = "NGON", rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.CylinderMesh: """Add primitives.CylinderMesh object to the scene. The object supports only uniform coloring (UniformColors). Args: radius (float): radius of a primitive in [0, inf] height (float): height of a primitive in [0, inf] material (Union[Material, MaterialList]): Material instance or list of Material instances colors (Union[Colors, ColorsList]): Colors instance or list of Colors instances faces_material (Sequence[Sequence[int]], optional): for each face, the material index assigned to it num_vertices (int, optional): number of vertices in primitive in [3, 10000000] (default: 32) fill_type (str, optional): fill type, one of [NOTHING, NGON, TRIFAN] (default: NGON) rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.CylinderMesh: created and added to the scene object """ tag = self._process_tag(tag, "Cylinder") obj = primitives.CylinderMesh( radius=radius, height=height, material=material, colors=colors, num_vertices=num_vertices, fill_type=fill_type, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag, faces_material=faces_material ) self._renderables[tag] = obj return obj
[docs] def add_plane_mesh( self, size: float, material: Union[Material, MaterialList], colors: Union[Colors, ColorsList], faces_material: Sequence[Sequence[int]] = None, shadow_catcher: bool = False, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.PlaneMesh: """Add primitives.PlaneMesh object to the scene. The object supports only uniform coloring (UniformColors). Args: size (float): size of a plane in [0, inf] material (Union[Material, MaterialList]): Material instance or list of Material instances colors (Union[Colors, ColorsList]): Colors instance or list of Colors instances faces_material (Sequence[Sequence[int]], optional): for each face, the material index assigned to it shadow_catcher (bool, optional): if True, the plane will act as a shadow catcher (default: False) rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.PlaneMesh: created and added to the scene object """ tag = self._process_tag(tag, "Plane") obj = primitives.PlaneMesh( size=size, material=material, colors=colors, shadow_catcher=shadow_catcher, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag, faces_material=faces_material ) self._renderables[tag] = obj return obj
# ======================================== End of Mesh and Mesh Primitives ========================================= # ============================================= Parametric Primitives ==============================================
[docs] def add_ellipsoid_nurbs( self, radius: Vector3d, material: Material, colors: UniformColors, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.EllipsoidNURBS: """Add primitives.EllipsoidNURBS object to the scene. Implemented as NURBS Sphere that is rescaled along axes, supports only uniform coloring (UniformColors). Args: radius (float): radius of a primitive in [0, inf] material (Material): Material instance colors (UniformColors): UniformColors instance rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.EllipsoidNURBS: created and added to the scene object """ tag = self._process_tag(tag, "Ellipsoid") obj = primitives.EllipsoidNURBS( radius=radius, material=material, colors=colors, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag ) self._renderables[tag] = obj return obj
[docs] def add_sphere_nurbs( self, radius: float, material: Material, colors: UniformColors, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.SphereNURBS: """Add primitives.SphereNURBS object to the scene. The object supports only uniform coloring (UniformColors). Args: radius (float): radius of a primitive in [0, inf] material (Material): Material instance colors (UniformColors): UniformColors instance rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.SphereNURBS: created and added to the scene object """ tag = self._process_tag(tag, "Sphere") obj = primitives.SphereNURBS( radius=radius, material=material, colors=colors, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag ) self._renderables[tag] = obj return obj
[docs] def add_curve_nurbs( self, keypoints: np.ndarray, radius: float, material: Material, colors: UniformColors, rotation_mode: str = "quaternionWXYZ", rotation: RotationParams = None, translation: Vector3d = (0, 0, 0), tag: str = None ) -> primitives.CurveBezier: """Add primitives.CurveBezier object to the scene. Keypoints are intermediate points of the Bezier Curve. The object supports only uniform coloring (UniformColors). Args: keypoints (np.ndarray): keypoints for the curve radius (float): radius of a primitive in [0, inf] material (Material): Material instance colors (UniformColors): UniformColors instance rotation_mode (str): type of rotation representation. Can be one of the following: - "quaternionWXYZ" - WXYZ quaternion - "quaternionXYZW" - XYZW quaternion - "rotvec" - axis-angle representation of rotation - "rotmat" - 3x3 rotation matrix - "euler<mode>" - Euler angles with the specified order of rotation, e.g. XYZ, xyz, ZXZ, etc. Refer to scipy.spatial.transform.Rotation.from_euler for details. - "look_at" - look at rotation, the rotation is defined by the point to look at and, optional, the rotation around the forward direction vector (a single float value in tuple or list) rotation (RotationParams): rotation parameters according to the rotation_mode - for "quaternionWXYZ" and "quaternionXYZW" - Vec4d - for "rotvec" - Vec3d - for "rotmat" - Mat3x3 - for "euler<mode>" - Vec3d - for "look_at" - Vec3d, Positionable or Tuple[Vec3d/Positionable, float], where float is the rotation around the forward direction vector in degrees translation (Vector3d, optional): translation applied to the Blender object (default: (0,0,0)) tag (str, optional): name of the created object in Blender. If None is passed, the tag is automatically generated (default: None) Returns: primitives.CurveBezier: created and added to the scene object """ tag = self._process_tag(tag, "Curve") obj = primitives.CurveBezier( keypoints=keypoints, radius=radius, material=material, colors=colors, rotation_mode=rotation_mode, rotation=rotation, translation=translation, tag=tag ) self._renderables[tag] = obj return obj
# ========================================== End of Parametric Primitives ========================================== def _process_tag(self, tag: str, default_prefix: str = "Renderable"): renderable_keys = self._renderables.keys() if tag is None: _tag = default_prefix + "_{:03d}" index = 0 while _tag.format(index) in renderable_keys: index += 1 tag = _tag.format(index) elif tag in renderable_keys: raise RuntimeError(f"Object with tag {tag} is already in collection.") return tag
[docs] def keys(self): return self._renderables.keys()
[docs] def values(self): return self._renderables.values()
[docs] def items(self): return self._renderables.items()
[docs] def remove(self, obj_or_tag: Union[Renderable, str]): assert isinstance(obj_or_tag, (Renderable, str)), "Only Renderable object or it's tag is allowed" if isinstance(obj_or_tag, str): tag = obj_or_tag else: obj = obj_or_tag tag = obj.tag self.__delitem__(tag)
def __getitem__(self, key: str) -> Renderable: return self._renderables[key] def __delitem__(self, key: str): self._renderables[key]._blender_remove_object() del self._renderables[key] def __iter__(self) -> Iterable: return iter(self._renderables) def __len__(self) -> int: return len(self._renderables) def _reset(self): self._renderables = dict()