def check_bb_intersection(obj1: MeshObject, obj2: MeshObject): """ Checks if there is a bounding box collision, these don't have to be axis-aligned, but if they are not: The surrounding/including axis-aligned bounding box is calculated and used to check the intersection. :param obj1: object 1 to check for intersection, must be a mesh :param obj2: object 2 to check for intersection, must be a mesh :return: True if the two bounding boxes intersect with each other """ b1w = obj1.get_bound_box() def min_and_max_point(bb): """ Find the minimum and maximum point of the bounding box :param bb: bounding box :return: min, max """ values = np.array(bb) return np.min(values, axis=0), np.max(values, axis=0) # get min and max point of the axis-aligned bounding box min_b1, max_b1 = min_and_max_point(b1w) b2w = obj2.get_bound_box() # get min and max point of the axis-aligned bounding box min_b2, max_b2 = min_and_max_point(b2w) return CollisionUtility._check_bb_intersection_on_values( min_b1, max_b1, min_b2, max_b2)
def replace(obj_to_remove: MeshObject, obj_to_add: MeshObject, check_collision_with: [MeshObject] = [], scale: bool = True, relative_pose_sampler: Callable[[MeshObject], None] = None): """ Scale, translate, rotate obj_to_add to match obj_to_remove and check if there is a bounding box collision returns a boolean. :param obj_to_remove: An object to remove from the scene. :param obj_to_add: An object to put in the scene instead of obj_to_remove. :param check_collision_with: A list of objects, which are not checked for collisions with. :param scale: Scales obj_to_add to match obj_to_remove dimensions. :param relative_pose_sampler: A function that randomly perturbs the pose of the object to replace with (after it has been aligned to the object to replace). """ # New object takes location, rotation and rough scale of original object obj_to_add.set_location(obj_to_remove.get_location()) obj_to_add.set_rotation_euler(obj_to_remove.get_rotation()) if scale: obj_to_add.set_scale( ObjectReplacer._bb_ratio(obj_to_remove.get_bound_box(True), obj_to_add.get_bound_box(True))) if relative_pose_sampler is not None: relative_pose_sampler(obj_to_add) bpy.context.view_layer.update() # Check for collision between the new object and other objects in the scene for obj in check_collision_with: # for each object if obj != obj_to_add and obj_to_remove != obj: if check_bb_intersection(obj.blender_obj, obj_to_add.blender_obj): if check_intersection(obj.blender_obj, obj_to_add.blender_obj)[0]: return False return True
def __init__(self, replica_mesh: MeshObject, replica_floor: MeshObject, height_list_file_path: str): """ Collect object containing all floors of all rooms and read in text file containing possible height values. :param replica_mesh: The replica mesh object. :param replica_floor: The replica floor object. :param height_list_file_path: The path to the file containing possible height values. """ # Determine bounding box of the scene bounding_box = replica_mesh.get_bound_box() self.bounding_box = {"min": bounding_box[0], "max": bounding_box[-2]} self.floor_object = replica_floor with open(height_list_file_path) as file: self.floor_height_values = [ float(val) for val in ast.literal_eval(file.read()) ]