예제 #1
0
    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
예제 #2
0
    def is_point_inside_object(obj: MeshObject,
                               obj_BVHtree: mathutils.bvhtree.BVHTree,
                               point: Vector):
        """ Checks whether the given point is inside the given object.

        This only works if the given object is watertight and has correct normals

        :param obj: The object
        :param obj_BVHtree: A bvh tree of the object
        :param point: The point to check
        :return: True, if the point is inside the object
        """
        # Look for closest point on object
        nearest, normal, _, _ = obj_BVHtree.find_nearest(point)
        # Compute direction
        p2 = nearest - point
        # Compute dot product between direction and normal vector
        a = p2.normalized().dot(
            (obj.get_rotation().to_matrix() @ normal).normalized())
        return a >= 0.0