def run(self): """ Replaces mesh objects with another mesh objects and scales them accordingly, the replaced objects and the objects to replace with in following steps: 1. Find which object to replace. 2. Place the new object in place of the object to be replaced and scale accordingly. 2. If there is no collision, between that object and the objects in the scene, then do replace and delete the original object. """ if self.config.has_param("relative_rotation_sampler"): def relative_pose_sampler(obj): # Sample random rotation and apply it to the objects pose obj.blender_obj.rotation_euler.rotate( Euler(self.config.get_list("relative_rotation_sampler"))) else: relative_pose_sampler = None replace_objects( objects_to_be_replaced=convert_to_meshes( self.config.get_list("objects_to_be_replaced", [])), objects_to_replace_with=convert_to_meshes( self.config.get_list("objects_to_replace_with", [])), ignore_collision_with=convert_to_meshes( self.config.get_list("ignore_collision_with", [])), replace_ratio=self.config.get_float("replace_ratio", 1), copy_properties=self.config.get_bool("copy_properties", True), max_tries=self.config.get_int("max_tries", 100), relative_pose_sampler=relative_pose_sampler)
def run(self): """ Samples the selected objects poses on a selected surface. """ # Collect parameters up_direction = self.config.get_vector3d( "up_direction", mathutils.Vector([0., 0., 1.])).normalized() min_distance = self.config.get_float("min_distance", 0.25) max_distance = self.config.get_float("max_distance", 0.6) max_tries = self.config.get_int("max_iterations", 100) objects = convert_to_meshes(self.config.get_list("objects_to_sample")) surface = self.config.get_list("surface") if len(surface) > 1: raise Exception( "This module operates with only one `surface` object while more than one was returned by " "the Provider. Please, configure the corresponding Provider's `conditions` accordingly such " "that it returns only one object! Tip: use getter.Entity's 'index' parameter." ) else: surface = MeshObject(surface[0]) # Define method to sample new object poses def sample_pose(obj: MeshObject): obj.set_location(self.config.get_vector3d("pos_sampler")) obj.set_rotation_euler(self.config.get_vector3d("rot_sampler")) # Sample objects on the given surface sample_poses_on_surface(objects_to_sample=objects, surface=surface, sample_pose_func=sample_pose, max_tries=max_tries, min_distance=min_distance, max_distance=max_distance, up_direction=up_direction)
def run(self): """ Run this current module. """ # get all objects which material should be changed objects = convert_to_meshes(self.config.get_list("selector")) light_surface(objects, emission_strength=self.emission_strength, keep_using_base_color=self.keep_using_base_color, emission_color=self.emission_color)
def run(self): """ :return: Point of interest in the scene. Type: mathutils.Vector. """ # For every selected object in the scene selected_objects = convert_to_meshes( self.config.get_list("selector", get_all_blender_mesh_objects())) if len(selected_objects) == 0: raise Exception("No objects were selected!") return compute_poi(selected_objects)
def load_obj(filepath: str, cached_objects: Optional[Dict[str, List[MeshObject]]] = None, **kwargs) -> List[MeshObject]: """ Import all objects for the given file and returns the loaded objects In .obj files a list of objects can be saved in. In .ply files only one object can saved so the list has always at most one element :param filepath: the filepath to the location where the data is stored :param cached_objects: a dict of filepath to objects, which have been loaded before, to avoid reloading (the dict is updated in this function) :param kwargs: all other params are handed directly to the bpy loading fct. check the corresponding documentation :return: The list of loaded mesh objects. """ if os.path.exists(filepath): if cached_objects is not None and isinstance(cached_objects, dict): if filepath in cached_objects.keys(): created_obj = [] for obj in cached_objects[filepath]: # duplicate the object created_obj.append(obj.duplicate()) return created_obj else: loaded_objects = load_obj(filepath, cached_objects=None, **kwargs) cached_objects[filepath] = loaded_objects return loaded_objects else: # save all selected objects previously_selected_objects = bpy.context.selected_objects if filepath.endswith('.obj'): # load an .obj file: bpy.ops.import_scene.obj(filepath=filepath, **kwargs) elif filepath.endswith('.ply'): # load a .ply mesh bpy.ops.import_mesh.ply(filepath=filepath, **kwargs) # add a default material to ply file mat = bpy.data.materials.new(name="ply_material") mat.use_nodes = True selected_objects = [ obj for obj in bpy.context.selected_objects if obj not in previously_selected_objects ] for obj in selected_objects: obj.data.materials.append(mat) return convert_to_meshes([ obj for obj in bpy.context.selected_objects if obj not in previously_selected_objects ]) else: raise Exception( "The given filepath does not exist: {}".format(filepath))
def run(self): """ Samples positions and rotations of selected object inside the sampling volume while performing mesh and bounding box collision checks in the following steps: 1. While we have objects remaining and have not run out of tries - sample a point. 2. If no collisions are found keep the point. """ objects_to_sample = self.config.get_list( "objects_to_sample", get_all_blender_mesh_objects()) objects_to_check_collisions = self.config.get_list( "objects_to_check_collisions", get_all_blender_mesh_objects()) max_tries = self.config.get_int("max_iterations", 1000) def sample_pose(obj: MeshObject): obj.set_location(self.config.get_vector3d("pos_sampler")) obj.set_rotation_euler(self.config.get_vector3d("rot_sampler")) sample_poses(objects_to_sample=convert_to_meshes(objects_to_sample), sample_pose_func=sample_pose, objects_to_check_collisions=convert_to_meshes( objects_to_check_collisions), max_tries=max_tries)
def run(self): """ Samples based on the description above. :return: Sampled value. Type: mathutils.Vector """ # invoke a Getter, get a list of objects to manipulate objects = convert_to_meshes(self.config.get_list("to_sample_on")) if len(objects) == 0: raise Exception( "The used selector returns an empty list, check the self.config value: \"to_sample_on\"" ) # relative area on selected face where to sample points face_sample_range = self.config.get_vector2d("face_sample_range", [0.0, 1.0]) # min and max distance to the bounding box min_height = self.config.get_float("min_height", 0.0) max_height = self.config.get_float("max_height", 1.0) if max_height < min_height: raise Exception("The minimum height ({}) must be smaller " "than the maximum height ({})!".format( min_height, max_height)) use_ray_trace_check = self.config.get_bool('use_ray_trace_check', False) # the upper direction, to define what is up in the scene # is used to selected the correct face upper_dir = self.config.get_vector3d("upper_dir", [0.0, 0.0, 1.0]) upper_dir.normalize() # if this is true the up direction is determined by the upper_dir vector, if it is false the # face normal is used use_upper_dir = self.config.get_bool("use_upper_dir", True) return upper_region(objects_to_sample_on=objects, face_sample_range=face_sample_range, min_height=min_height, max_height=max_height, use_ray_trace_check=use_ray_trace_check, upper_dir=upper_dir, use_upper_dir=use_upper_dir)
def run(self): # use a loader module to load objects bpy.ops.object.select_all(action='SELECT') previously_selected_objects = set(bpy.context.selected_objects) module_list_config = self.config.get_list("used_loader_config") modules = Utility.initialize_modules(module_list_config) for module in modules: print("Running module " + module.__class__.__name__) module.run() bpy.ops.object.select_all(action='SELECT') loaded_objects = list( set(bpy.context.selected_objects) - previously_selected_objects) # only select non see through materials config = { "conditions": { "cp_is_cc_texture": True, "cf_principled_bsdf_Alpha_eq": 1.0 } } material_getter = MaterialProvider(Config(config)) all_cc_materials = MaterialLoaderUtility.convert_to_materials( material_getter.run()) construct_random_room( used_floor_area=self.used_floor_area, interior_objects=convert_to_meshes(loaded_objects), materials=all_cc_materials, amount_of_extrusions=self.amount_of_extrusions, fac_from_square_room=self.fac_from_square_room, corridor_width=self.corridor_width, wall_height=self.wall_height, amount_of_floor_cuts=self.amount_of_floor_cuts, only_use_big_edges=self.only_use_big_edges, create_ceiling=self.create_ceiling, assign_material_to_ceiling=self.assign_material_to_ceiling, placement_tries_per_face=self.tries_per_face, amount_of_objects_per_sq_meter=self.amount_of_objects_per_sq_meter)
def run(self): self.point_sampler = SuncgPointInRoomSampler(convert_to_meshes(bpy.context.scene.objects)) super().run()
def _sample_cam_poses(self, config): """ Samples camera poses according to the given config :param config: The config object """ cam_ob = bpy.context.scene.camera cam = cam_ob.data # Set global parameters self.sqrt_number_of_rays = config.get_int("sqrt_number_of_rays", 10) self.max_tries = config.get_int("max_tries", 10000) self.proximity_checks = config.get_raw_dict("proximity_checks", {}) self.excluded_objects_in_proximity_check = config.get_list( "excluded_objs_in_proximity_check", []) self.min_interest_score = config.get_float("min_interest_score", 0.0) self.interest_score_range = config.get_float("interest_score_range", self.min_interest_score) self.interest_score_step = config.get_float("interest_score_step", 0.1) self.special_objects = config.get_list("special_objects", []) self.special_objects_weight = config.get_float( "special_objects_weight", 2) self._above_objects = convert_to_meshes( config.get_list("check_if_pose_above_object_list", [])) self.check_visible_objects = convert_to_meshes( config.get_list("check_if_objects_visible", [])) # Set camera intrinsics self._set_cam_intrinsics( cam, Config(self.config.get_raw_dict("intrinsics", {}))) if self.proximity_checks: # needs to build an bvh tree mesh_objects = [ MeshObject(obj) for obj in get_all_blender_mesh_objects() if obj not in self.excluded_objects_in_proximity_check ] self.bvh_tree = create_bvh_tree_multi_objects(mesh_objects) if self.interest_score_step <= 0.0: raise Exception( "Must have an interest score step size bigger than 0") # Determine the number of camera poses to sample number_of_poses = config.get_int("number_of_samples", 1) print("Sampling " + str(number_of_poses) + " cam poses") # Start with max interest score self.interest_score = self.interest_score_range # Init all_tries = 0 tries = 0 existing_poses = [] for i in range(number_of_poses): # Do until a valid pose has been found or the max number of tries has been reached while tries < self.max_tries: tries += 1 all_tries += 1 # Sample a new cam pose and check if its valid if self.sample_and_validate_cam_pose(config, existing_poses): break # If max tries has been reached if tries >= self.max_tries: # Decrease interest score and try again, if we have not yet reached minimum continue_trying, self.interest_score = CameraValidation.decrease_interest_score( self.interest_score, self.min_interest_score, self.interest_score_step) if continue_trying: tries = 0 print(str(all_tries) + " tries were necessary")