Blender Experiment Class#

class BlenderExperiment(Nb_frames=1, verbose=False)[source]#

Bases: object

Represents a Blender experiment with a defined scene and objects.

The BlenderExperiment class provides methods to add and configure cameras, spot lights, and objects (mesh + material) in a Blender scene. The class also allows setting the properties of the scene such as resolution and pixel aspect ratio. Then the class provides methods to render the scene and save the rendered images.

The number of frames in the experiment can be set using the end_frame parameter. This parameters can not be updated after the experiment is created.

from pysdic.blender import BlenderExperiment

# Example instantiation
experiment = BlenderExperiment(Nb_frames=10)
Parameters:
  • Nb_frames (int, optional) – The number of frames for the experiment (default is 1).

  • verbose (bool, optional) – If True, prints additional information during the experiment setup (default is False).

activate_smooth_shading(name)[source]#

Activate smooth shading for the mesh.

Smooth shading is a rendering technique that gives the appearance of a smooth surface by interpolating vertex normals across the surface of the mesh.

Parameters:

name (str) – The name of the mesh to activate smooth shading for.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data.

Return type:

None

add_camera(name, camera, frames=None)[source]#

Add a camera to the experiment.

The frames parameter indicates which frames the camera will be active. If None, the camera will be active for all frames. Else a list of booleans must be provided, where each boolean indicates if the camera is active for that frame.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
camera = BlenderCamera()
# Define the camera properties here
# ...
experiment.add_camera(name="Camera1", camera=camera, frames=[True, False, True, False, True, False, True, False, True, False])

Note

The name of the camera must be unique in the experiment and in Blender data. Furthemore, because Blender limits the name of the objects to 63 characters and pysdic add prefixe for sub-dependant object of the camera, the name of the camera must be less than 50 characters.

See also

Parameters:
  • name (str) – The name of the camera with less than 50 characters.

  • camera (BlenderCamera) – The camera object to be added.

  • frames (List[bool], optional) – A list of booleans indicating which frames the camera will be active. If None, the camera will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or camera is not an instance of BlenderCamera.

  • ValueError – If a camera with the same name already exists in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame). If the camera is not completely defined.

  • Blender Details

  • ---------------

  • The camera is created in the Blender scene and linked to the experiment scene with the name {name}.

Return type:

None

add_mesh(name, mesh, frames=None)[source]#

Add a mesh to the experiment. (Must be a 3D triangular mesh)

The mesh must be an instance of Mesh.

The frames parameter indicates which frames the mesh will be active. If None, the mesh will be active for all frames. Else a list of booleans must be provided, where each boolean indicates if the mesh is active for that frame.

Note

The name of the mesh must be unique in the experiment and in Blender data. Furthemore, because Blender limits the name of the objects to 63 characters and pysdic add prefixe for sub-dependant object of the mesh, the name of the mesh must be less than 50 characters.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
# Define the mesh properties here
# ...
mesh = Mesh(vertices=..., connectivity=...)
experiment.add_mesh(name="Mesh1", mesh=mesh, frames=[True, False, True, False, True, False, True, False, True, False])

See also

Parameters:
  • name (str) – The name of the mesh with less than 50 characters.

  • mesh (Mesh) – The mesh object to be added. It must be an instance of Mesh. Must be a 3D triangular mesh.

  • frames (List[bool], optional) – A list of booleans indicating which frames the mesh will be active. If None, the mesh will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or mesh is not an instance of Mesh.

  • ValueError – If a mesh with the same name already exists in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame). If the mesh is not completely defined.

  • Blender Details

  • ---------------

  • The mesh is created in the Blender scene and linked to the experiment scene.

  • The mesh name is set to the provided name.

  • A material is created for the mesh with the name [pysdic]_{name}_mat.

  • The material uses a Principled BSDF shader and is set to use_nodes = True.

  • The material is located at the first index of the mesh data materials.

  • A MixRGB node is created at the input of the Principled BSDF Base Color node.

  • The MixRGB node name is set to [pysdic]_{name}_mbp for "Mix BaseColor Pattern".

  • The first input of the MixRGB node is the default base color of the material (white).

  • It can be setted to any color using the add_mesh_material method.

  • The second input of the MixRGB node is the default pattern of the material (white).

  • It can be setted to any pattern using the add_mesh_pattern method.

  • The output of the MixRGB node is connected to the Base Color input of the Principled BSDF node.

Return type:

None

add_mesh_material(name, material)[source]#

Add a material to the mesh.

The material must be an instance of BlenderMaterialBSDF.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
# Define the mesh properties here
# ...
mesh = Mesh(points, cells_dict={"triangle": elements}, point_data={"uvmap": texture_coordinates})
experiment.set_mesh(name="Mesh1", mesh=mesh, frames=[True, False, True, False, True, False, True, False, True, False])
material = BlenderMaterialBSDF()
# Define the material properties here
# ...
experiment.add_mesh_material(name="Mesh1", material=material)

See also

Note

The material is not updated when the mesh is updated. To update the material, you must call this method again with the new material.

Parameters:
Raises:
  • TypeError – If name is not a string or material is not an instance of BlenderMaterialBSDF.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data.

Return type:

None

add_mesh_pattern(name, pattern_path)[source]#

Add a pattern to the mesh material.

The pattern must be a valid image file path (e.g., PNG, JPEG). The pattern will be applied to the mesh material as a texture.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
# Define the mesh properties here
# ...
mesh = Mesh(vertices=..., triangles=...)
mesh.uvmap = ...
experiment.add_mesh(name="Mesh1", mesh=mesh, frames=[True, False, True, False, True, False, True, False, True, False])
experiment.add_mesh_pattern(name="Mesh1", pattern_path="path/to/pattern.png")

Warning

The UV coordinates of the mesh must be defined in the Mesh object. as “uvmap” in the point_data dictionary.

See also

  • pysdic.Mesh for more information on how to define a mesh.

Parameters:
  • name (str) – The name of the mesh.

  • pattern_path (str) – The path to the pattern image file.

Raises:
  • TypeError – If name is not a string or pattern_path is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data. If the pattern path is not valid or the image format is not supported. If the mesh does not have a UVMAP defined.

  • Blender Details

  • ---------------

  • A uv_layer is created for the mesh and the UVMAP is set to the texture coordinates defined in the mesh.

  • The uv_layer is named [pysdic]_{name}_uvm.

  • A node is created in the material node tree to load the image texture.

  • The node is named [pysdic]_{name}_imt.

  • This node is in CLIP mode to avoid stretching the image.

  • The color output of the image texture node is connected to the second input of the MixRGB node.

  • The MixRGB node is connected to the Base Color input of the Principled BSDF node in multiply mode.

Return type:

None

add_spotlight(name, spotlight, frames=None)[source]#

Add a spotlight to the experiment.

The spotlight must be an instance of BlenderSpotLight.

Note

The name of the light must be unique in the experiment and in Blender data. Furthemore, because Blender limits the name of the objects to 63 characters and pysdic add prefixe for sub-dependant object of the light, the name of the light must be less than 50 characters.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
spotlight = BlenderSpotLight()
# Define the BlenderSpotLight properties here
# ...
experiment.add_spotlight(name="Spotlight1", spotlight=BlenderSpotLight, frames=[True, False, True, False, True, False, True, False, True, False])

See also

Parameters:
  • name (str) – The name of the spotlight with less than 50 characters.

  • spotlight (BlenderSpotLight) – The spotlight object to be added.

  • frames (List[bool], optional) – A list of booleans indicating which frames the spotlight will be active. If None, the spotlight will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or spotlight is not an instance of BlenderSpotLight.

  • ValueError – If a spotlight with the same name already exists in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame).

Return type:

None

change_mesh_pattern(name, pattern_path)[source]#

Change the pattern of the mesh material.

The pattern must be a valid image file path (e.g., PNG, JPEG). The pattern will be applied to the mesh material as a texture.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
# Define the mesh properties here
# ...
mesh = Mesh(points, cells_dict={"triangle": elements}, point_data={"uvmap": texture_coordinates})
experiment.add_mesh(name="Mesh1", mesh=mesh, frames=[True, False, True, False, True, False, True, False, True, False])
experiment.add_mesh_pattern(name="Mesh1", pattern_path="path/to/pattern.png")
experiment.change_mesh_pattern(name="Mesh1", pattern_path="path/to/new_pattern.png")

See also

Parameters:
  • name (str) – The name of the mesh.

  • pattern_path (str) – The path to the new pattern image file.

Raises:
  • TypeError – If name is not a string or pattern_path is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data. If the pattern path is not valid or the image format is not supported.

Return type:

None

deactivate_smooth_shading(name)[source]#

Deactivate smooth shading for the mesh.

Smooth shading is a rendering technique that gives the appearance of a smooth surface by interpolating vertex normals across the surface of the mesh.

Parameters:

name (str) – The name of the mesh to deactivate smooth shading for.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data.

Return type:

None

get_active_camera()[source]#

Get the name of the active camera.

Returns:

The name of the active camera.

Return type:

str

Raises:

ValueError – If no active camera is set.

get_camera(name)[source]#

Get the camera object and its Blender object.

Parameters:

name (str) – The name of the camera to retrieve.

Returns:

A tuple containing the BlenderCamera object and its corresponding Blender object.

Return type:

Tuple[BlenderCamera, Object]

get_camera_frames(name)[source]#

Get the frames for which the camera is active.

Parameters:

name (str) – The name of the camera.

Returns:

A list of booleans indicating which frames the camera is active.

Return type:

List[bool]

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a camera with the same name does not exist in the experiment or in Blender data.

get_camera_names()[source]#

Get the names of all cameras in the experiment.

Returns:

A list of camera names.

Return type:

List[str]

get_mesh(name)[source]#

Get the mesh object and its Blender object.

Parameters:

name (str) – The name of the mesh to retrieve.

Returns:

A tuple containing the Mesh object and its corresponding Blender object.

Return type:

Tuple[Mesh, Object]

get_mesh_frames(name)[source]#

Get the frames for which the mesh is active.

Parameters:

name (str) – The name of the mesh.

Returns:

A list of booleans indicating which frames the mesh is active.

Return type:

List[bool]

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data.

get_mesh_names()[source]#

Get the names of all meshes in the experiment.

Returns:

A list of mesh names.

Return type:

List[str]

get_spotlight(name)[source]#

Get the spotlight object and its Blender object.

Parameters:

name (str) – The name of the spotlight to retrieve.

Returns:

A tuple containing the BlenderSpotLight object and its corresponding Blender object.

Return type:

Tuple[BlenderSpotLight, Object]

get_spotlight_frames(name)[source]#

Get the frames for which the spotlight is active.

Parameters:

name (str) – The name of the spotlight.

Returns:

A list of booleans indicating which frames the spotlight is active.

Return type:

List[bool]

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a spotlight with the same name does not exist in the experiment or in Blender data.

remove_camera(name)[source]#

Remove a camera from the experiment.

Parameters:

name (str) – The name of the camera to remove.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a camera with the same name does not exist in the experiment or in Blender data.

Return type:

None

remove_mesh(name)[source]#

Remove a mesh from the experiment.

Parameters:

name (str) – The name of the mesh to remove.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data.

  • Blender Details

  • ---------------

  • When removing a mesh, the following actions are performed:

  • - The mesh {name} is removed from the Blender scene.

  • - The material [pysdic]_{name}_mat is removed from the Blender data.

  • - The MixRGB node [pysdic]_{name}_mbp is removed from the material node tree.

  • - The uv_layer [pysdic]_{name}_uvm is removed from the mesh data.

  • - The node texture [pysdic]_{name}_imt is removed from the material node tree.

Return type:

None

remove_spotlight(name)[source]#

Remove a spotlight from the experiment.

Parameters:

name (str) – The name of the spotlight to remove.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a spotlight with the same name does not exist in the experiment or in Blender data.

Return type:

None

render(output_path, output_format='TIFF', color_mode='BW', color_depth='8', N_samples=200, default=True)[source]#

Render the experiment scene.

Parameters:
  • output_path (str) – The path to save the rendered image.

  • output_format (str, optional) – The output format of the rendered image (default is “TIFF”).

  • color_mode (str, optional) – The color mode of the rendered image (default is “BW”).

  • color_depth (str, optional) – The color depth of the rendered image (default is “8”).

  • N_samples (int, optional) – The number of samples for rendering (default is 200).

  • default (bool, optional) – If True, the default render settings will be used (default is True).

Raises:
  • TypeError – If name or output_path is not a string.

  • ValueError – If the output format is not supported. If the frame or the camera is not set.

Return type:

None

set_active_camera(name)[source]#

Set the active camera for the experiment.

Parameters:

name (str) – The name of the camera to set as active.

Raises:
  • TypeError – If name is not a string.

  • ValueError – If a camera with the same name does not exist in the experiment or in Blender data.

Return type:

None

set_active_frame(frame)[source]#

Set the current frame of the Blender scene.

Parameters:

frame (int) – The frame number to set.

Raises:
Return type:

None

set_camera_frames(name, frames=None)[source]#

Set the frames for which the camera will be active. If None, the camera will be active for all frames. Else a list of booleans must be provided, where each boolean indicates if the camera is active for that frame.

Parameters:
  • name (str) – The name of the camera.

  • frames (List[bool], optional) – A list of booleans indicating which frames the camera will be active. If None, the camera will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or frames is not a list of booleans.

  • ValueError – If a camera with the same name does not exist in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame).

Return type:

None

set_default_background()[source]#

Set the default background for the experiment scene.

Return type:

None

set_mesh_frames(name, frames=None)[source]#

Set the frames for which the mesh will be active. If None, the mesh will be active for all frames. Else a list of booleans must be provided, where each boolean indicates if the mesh is active for that frame.

Parameters:
  • name (str) – The name of the mesh.

  • frames (List[bool], optional) – A list of booleans indicating which frames the mesh will be active. If None, the mesh will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or frames is not a list of booleans.

  • ValueError – If a mesh with the same name does not exist in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame).

Return type:

None

set_spotlight_frames(name, frames=None)[source]#

Set the frames for which the spotlight will be active. If None, the spotlight will be active for all frames. Else a list of booleans must be provided, where each boolean indicates if the spotlight is active for that frame.

Parameters:
  • name (str) – The name of the spotlight.

  • frames (List[bool], optional) – A list of booleans indicating which frames the spotlight will be active. If None, the spotlight will be active for all frames (default is None).

Raises:
  • TypeError – If name is not a string or frames is not a list of booleans.

  • ValueError – If a spotlight with the same name does not exist in the experiment or in Blender data. If the length of frames is not equal to the number of frames in the experiment (end_frame).

Return type:

None

update_camera(name)[source]#

Update the camera properties in the Blender scene. This method must be called after updating the camera properties in the BlenderCamera object.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
camera = BlenderCamera()
# Define the camera properties here
# ...
experiment.add_camera(name="Camera1", camera=camera, frames=[True, False, True, False, True, False, True, False, True, False])
# Update some properties of the camera here
# ...
experiment.update_camera(name="Camera1") # To set active the modifications in the Blender scene
Parameters:

name (str) – The name of the camera to update.

Return type:

None

update_mesh(name)[source]#

Update the mesh properties in the Blender scene. This method must be called after updating the mesh properties in the Mesh object.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
# Define the mesh properties here
# ...
mesh = Mesh(points, cells_dict={"triangle": elements}, point_data={"uvmap": texture_coordinates})
experiment.add_mesh(name="Mesh1", mesh=mesh, frames=[True, False, True, False, True, False, True, False, True, False])
# Update some nodes of the mesh here
# ...
experiment.update_mesh(name="Mesh1") # To set active the modifications in the Blender scene

Note

If a pattern is setted to the mesh, the uvmap are also updated.

Warning

The number of nodes must be unchanged !!!

Furthermore, this method does not update the material properties of the mesh and the pattern image:

Parameters:

name (str) – The name of the mesh to update.

Return type:

None

update_scene()[source]#

Update the Blender scene. This method must be called after adding or modifying any objects in the scene.

  • Free bake all

  • Bake all

  • Update the view layer and depsgraph

Return type:

None

update_spotlight(name)[source]#

Update the spotlight properties in the Blender scene. This method must be called after updating the spotlight properties in the BlenderSpotLight object.

# Example usage
experiment = BlenderExperiment(Nb_frames=10)
spotlight = BlenderSpotLight()
# Define the BlenderSpotLight properties here
# ...
experiment.add_spotlight(name="Spotlight1", spotlight=spotlight, frames=[True, False, True, False, True, False, True, False, True, False])
# Update some nodes of the spotlight here
# ...
experiment.update_spotlight(name="Spotlight1") # To set active the modifications in the Blender scene

Warning

This method does not update the material properties of the spotlight. Only the position and rotation are updated. The number of nodes mustnot be changed.

Parameters:

name (str) – The name of the spotlight to update.

Return type:

None