Exemplo n.º 1
0
    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.get_rotation().rotate(
                    Euler(self.config.get_list("relative_rotation_sampler")))
        else:
            relative_pose_sampler = None

        ObjectReplacer.replace_multiple(
            objects_to_be_replaced=MeshObject.convert_to_meshes(
                self.config.get_list("objects_to_be_replaced", [])),
            objects_to_replace_with=MeshObject.convert_to_meshes(
                self.config.get_list("objects_to_replace_with", [])),
            ignore_collision_with=MeshObject.convert_to_meshes(
                self.config.get_list("ignore_collision_with", [])),
            replace_ratio=self.config.get_float("replace_ratio", 1),
            copy_properties=self.config.get_float("copy_properties", 1),
            max_tries=self.config.get_int("max_tries", 100),
            relative_pose_sampler=relative_pose_sampler)
Exemplo n.º 2
0
    def sample(objects_to_sample: [MeshObject], sample_pose_func: Callable[[MeshObject], None], objects_to_check_collisions: [MeshObject] = None, max_tries: int = 1000):
        """ Samples positions and rotations of selected object inside the sampling volume while performing mesh and bounding box collision checks.

        :param objects_to_sample: A list of mesh objects whose poses are sampled based on the given function.
        :param sample_pose_func: The function to use for sampling the pose of a given object.
        :param objects_to_check_collisions: A list of mesh objects who should not be considered when checking for collisions.
        :param max_tries: Amount of tries before giving up on an object and moving to the next one.
        """
        # After this many tries we give up on current object and continue with the rest
        if objects_to_check_collisions is None:
            objects_to_check_collisions = MeshObject.convert_to_meshes(get_all_blender_mesh_objects())

        # Among objects_to_sample only check collisions against already placed objects
        cur_objects_to_check_collisions = list(set(objects_to_check_collisions) - set(objects_to_sample))

        if max_tries <= 0:
            raise ValueError("The value of max_tries must be greater than zero: {}".format(max_tries))

        if not objects_to_sample:
            raise Exception("The list of objects_to_sample can not be empty!")

        # cache to fasten collision detection
        bvh_cache = {}

        # for every selected object
        for obj in objects_to_sample:
            no_collision = True

            amount_of_tries_done = -1

            # Try max_iter amount of times
            for i in range(max_tries):

                # Put the top object in queue at the sampled point in space
                sample_pose_func(obj)
                bpy.context.view_layer.update()
                # Remove bvh cache, as object has changed
                if obj.get_name() in bvh_cache:
                    del bvh_cache[obj.get_name()]

                no_collision = CollisionUtility.check_intersections(obj, bvh_cache, cur_objects_to_check_collisions, [])

                # If no collision then keep the position
                if no_collision:
                    amount_of_tries_done = i
                    break

            # After placing an object, we will check collisions with it
            cur_objects_to_check_collisions.append(obj)

            if amount_of_tries_done == -1:
                amount_of_tries_done = max_tries

            if not no_collision:
                print("Could not place " + obj.get_name() + " without a collision.")
            else:
                print("It took " + str(amount_of_tries_done + 1) + " tries to place " + obj.get_name())
Exemplo n.º 3
0
    def run(self):
        """
        Run this current module.
        """
        # get all objects which material should be changed
        objects = MeshObject.convert_to_meshes(
            self.config.get_list("selector"))

        self.add_emission_to_materials(objects)
Exemplo n.º 4
0
    def run(self):
        """
        :return: Point of interest in the scene. Type: mathutils.Vector.
        """
        # For every selected object in the scene
        selected_objects = MeshObject.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 MeshObject.compute_poi(selected_objects)
Exemplo n.º 5
0
    def run(self):
        """
        Run this current module.
        """
        # get all objects which material should be changed
        objects = MeshObject.convert_to_meshes(self.config.get_list("selector"))

        SurfaceLighting.run(
            objects,
            emission_strength=self.emission_strength,
            keep_using_base_color=self.keep_using_base_color,
            emission_color=self.emission_color
        )
Exemplo n.º 6
0
    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"))

        ObjectPoseSampler.sample(
            objects_to_sample=MeshObject.convert_to_meshes(objects_to_sample),
            sample_pose_func=sample_pose,
            objects_to_check_collisions=MeshObject.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 = MeshObject.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 UpperRegionSampler.sample(
            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)
Exemplo n.º 8
0
    def load(filepath: str, cached_objects: dict = 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 = ObjectLoader.load(filepath, cached_objects=None, **kwargs)
                    cached_objects[filepath] = loaded_objects
                    return loaded_objects
            else:
                # save all selected objects
                previously_selected_objects = set(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
                    loaded_objects = list(set(bpy.context.selected_objects) - previously_selected_objects)
                    for obj in loaded_objects:
                        obj.data.materials.append(mat)

                # return all currently selected objects
                return MeshObject.convert_to_meshes(list(set(bpy.context.selected_objects) - previously_selected_objects))
        else:
            raise Exception("The given filepath does not exist: {}".format(filepath))
Exemplo n.º 9
0
    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 = Material.convert_to_materials(material_getter.run())

        RandomRoomConstructor.construct(
            used_floor_area=self.used_floor_area,
            interior_objects=MeshObject.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)
Exemplo n.º 10
0
 def run(self):
     self.point_sampler = Front3DPointInRoomSampler(
         MeshObject.convert_to_meshes(get_all_blender_mesh_objects()))
     super().run()
Exemplo n.º 11
0
    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 = MeshObject.convert_to_meshes(
            config.get_list("check_if_pose_above_object_list", []))
        self.check_visible_objects = MeshObject.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 = MeshObject.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")
Exemplo n.º 12
0
 def run(self):
     self.point_sampler = SuncgPointInRoomSampler(
         MeshObject.convert_to_meshes(bpy.context.scene.objects))
     super().run()
Exemplo n.º 13
0
def get_all_mesh_objects():
    return MeshObject.convert_to_meshes(get_all_blender_mesh_objects())
Exemplo n.º 14
0
def get_all_meshes_with_name(name: str):
    return MeshObject.convert_to_meshes([obj for obj in get_all_blender_mesh_objects() if obj.name == name])