def sample_new_object_poses_on_face(self, current_obj, face_bb):
        """
        Sample new object poses on the current `self.floor_obj`.

        :param face_bb:
        :return: True, if there is no collision
        """
        random_placed_value = [
            random.uniform(face_bb[0][i], face_bb[1][i]) for i in range(2)
        ]
        random_placed_value.append(0.0)  # floor z value

        random_placed_rotation = [0, 0, random.uniform(0, np.pi * 2.0)]

        current_obj = MeshObject(current_obj)
        current_obj.set_location(random_placed_value)
        current_obj.set_rotation_euler(random_placed_rotation)
        bpy.context.view_layer.update()

        # Remove bvh cache, as object has changed
        if current_obj.get_name() in self.bvh_cache_for_intersection:
            del self.bvh_cache_for_intersection[current_obj.get_name()]

        # perform check if object can be placed there
        no_collision = CollisionUtility.check_intersections(
            current_obj,
            bvh_cache=self.bvh_cache_for_intersection,
            objects_to_check_against=self.placed_objects,
            list_of_objects_with_no_inside_check=[MeshObject(self.wall_obj)])
        return no_collision
Exemple #2
0
    def check_mesh_intersection(obj1: MeshObject,
                                obj2: MeshObject,
                                skip_inside_check: bool = False,
                                bvh_cache: dict = None):
        """
        Checks if the two objects are intersecting.

        This will use BVH trees to check whether the objects are overlapping.

        It is further also checked if one object is completely inside the other.
        This check requires that both objects are watertight, have correct normals and are coherent.
        If this is not the case it can be disabled via the parameter skip_inside_check.

        :param obj1: object 1 to check for intersection, must be a mesh
        :param obj2: object 2 to check for intersection, must be a mesh
        :param skip_inside_check: Disables checking whether one object is completely inside the other.
        :return: True, if they are intersecting
        """

        if bvh_cache is None:
            bvh_cache = {}

        # If one of the objects has no vertices, collision is impossible
        if len(obj1.get_mesh().vertices) == 0 or len(
                obj2.get_mesh().vertices) == 0:
            return False, bvh_cache

        # create bvhtree for obj1
        if obj1.get_name() not in bvh_cache:
            obj1_BVHtree = obj1.create_bvh_tree()
            bvh_cache[obj1.get_name()] = obj1_BVHtree
        else:
            obj1_BVHtree = bvh_cache[obj1.get_name()]

        # create bvhtree for obj2
        if obj2.get_name() not in bvh_cache:
            obj2_BVHtree = obj2.create_bvh_tree()
            bvh_cache[obj2.get_name()] = obj2_BVHtree
        else:
            obj2_BVHtree = bvh_cache[obj2.get_name()]

        # Check whether both meshes intersect
        inter = len(obj1_BVHtree.overlap(obj2_BVHtree)) > 0

        # Optionally check whether obj2 is contained in obj1
        if not inter and not skip_inside_check:
            inter = CollisionUtility.is_point_inside_object(
                obj1, obj1_BVHtree,
                Matrix(obj2.get_local2world_mat())
                @ obj2.get_mesh().vertices[0].co)
            if inter:
                print(
                    "Warning: Detected that " + obj2.get_name() +
                    " is completely inside " + obj1.get_name() +
                    ". This might be wrong, if " + obj1.get_name() +
                    " is not water tight or has incorrect normals. If that is the case, consider setting "
                    "skip_inside_check to True.")

        # Optionally check whether obj1 is contained in obj2
        if not inter and not skip_inside_check:
            inter = CollisionUtility.is_point_inside_object(
                obj2, obj2_BVHtree,
                Matrix(obj1.get_local2world_mat())
                @ obj1.get_mesh().vertices[0].co)
            if inter:
                print("Warning: Detected that " + obj1.get_name() +
                      " is completely inside " + obj2.get_name() +
                      ". This might be wrong, if " + obj2.get_name() +
                      " is not water tight or has incorrect "
                      "normals. If that is the case, consider "
                      "setting skip_inside_check to True.")

        return inter, bvh_cache