Source code for blenderproc.python.loader.RockEssentialsRockLoader

"""Loading the rock essential dataset: https://blendermarket.com/products/the-rock-essentials"""

import os
from random import choice
from typing import List, Union, Optional

import bpy
import numpy as np
from mathutils import Vector

from blenderproc.python.types.MeshObjectUtility import MeshObject


[docs] class RockEssentialsRockLoader: """ Loads rocks/cliffs from a specified .blend Rocks Essentials file. """
[docs] @staticmethod def load_rocks(path: str, subsec_num: int, objects: Optional[List[str]] = None, sample_objects: bool = False, amount: int = None) -> List[MeshObject]: """ Loads rocks from the given blend file. :param path: Path to a .blend file containing desired rock/cliff objects in //Object// section. :param subsec_num: Number of a corresponding cell (batch) in `rocks` list in configuration. Used for name generation. :param objects: List of rock-/cliff-object names to be loaded. If not specified then `amount` property is used for consequential loading. :param sample_objects: Toggles the uniform sampling of objects to load. Takes into account `objects` and `amount` parameters. Requires 'amount' param to be defined. :param amount: Amount of rock-/cliff-object to load. If not specified, the amount will be set to the amount of suitable objects in the current section of a blend file. Must be bigger than 0. :return: List of loaded objects. """ loaded_objects = [] obj_types = ["Rock", "Cliff"] amount_defined = False if objects is None: objects = [] obj_list = [] with bpy.data.libraries.load(path) as (data_from, _): # if list of names is empty if not objects: # get list of rocks suitable for loading - objects that are rocks or cliffs for obj_type in obj_types: obj_list += [obj for obj in data_from.objects if obj_type in obj] else: # if names are defined - get those that are available in this .blend file obj_list = [obj for obj in data_from.objects if obj in objects] # get amount of rocks in this batch, set to all suitable if not defined if amount is not None: amount_defined = True if amount == 0: raise RuntimeError("Amount param can't be equal to zero!") else: amount = len(obj_list) for i in range(amount): # load rock: choose random from the list if sampling is True, go through list if not if sample_objects and amount_defined: obj = choice(obj_list) else: obj = obj_list[i % len(obj_list)] bpy.ops.wm.append(filepath=os.path.join(path, "Object", obj), filename=obj, directory=os.path.join(path, "Object")) loaded_obj = MeshObject(bpy.context.scene.objects[obj]) # set custom name for easier tracking in the scene loaded_obj.set_name(obj + "_" + str(subsec_num) + "_" + str(i)) # append to return list loaded_objects.append(loaded_obj) return loaded_objects
[docs] @staticmethod def set_rocks_properties(objects: List[MeshObject], physics: bool = False, render_levels: int = 3, high_detail_mode: bool = False, scale: Optional[Union[Vector, np.ndarray, list]] = None, reflection_amount: Optional[float] = None, reflection_roughness: Optional[float] = None, hsv: Optional[List[float]] = None): """ Sets rocks properties in accordance to the given parameters. :param objects: List of loaded rock mesh objects. :param physics: Custom property for physics/rigidbody state. :param render_levels: Number of subdivisions to perform when rendering. :param high_detail_mode: Flag for enabling HDM when possible. :param scale: Scale of a rock as a 3d-vector with each value as a scaling factor per according dimension. :param reflection_amount: Reflection texture value. Default: rock-specific. Range: [0,1] :param reflection_roughness: Roughness texture value. Default: rock-specific. Range: [0,1] :param hsv: Hue-Saturation-Value parameters of the HSV node. (3 values). Range: H: [0, 1], S: [0, 2], V: [0, 2]. Default: rock-specific. """ if scale is None: scale = [1.0, 1.0, 1.0] for obj in objects: # set physics parameter obj.set_cp("physics", physics) # set category id obj.set_cp("category_id", 1) # set render value obj.blender_obj.modifiers["Subsurf"].render_levels = render_levels # set scale obj.set_scale(scale) # set HDM if enabled if obj.has_cp("01) High Detail Mode"): obj.set_cp("01) High Detail Mode", high_detail_mode) else: print("High Detail Mode is unavailable for " + str(obj.get_name()) + ", omitting.") if reflection_amount is not None: obj.set_cp("05) Reflection Amount", reflection_amount) if reflection_roughness is not None: obj.set_cp("06) Reflection Roughness", reflection_roughness) if hsv is not None: obj.set_cp("02) Saturation", hsv[1]) obj.set_cp("03) Hue", hsv[0]) obj.set_cp("04) Value", hsv[2])