def _cam2world_matrix_from_cam_extrinsics(self,
                                              config: Config) -> np.ndarray:
        """ Determines camera extrinsics by using the given config and returns them in form of a cam to world frame transformation matrix.

        :param config: The configuration object.
        :return: The 4x4 cam to world transformation matrix.
        """
        if not config.has_param("cam2world_matrix"):
            position = MathUtility.change_coordinate_frame_of_point(
                config.get_vector3d("location", [0, 0, 0]), self.source_frame)
            # position = Vector((-0.01111459918320179, -0.051188092678785324, 0.19301876425743103))

            rotation_format = config.get_string("rotation/format", "euler")
            value = config.get_vector3d("rotation/value", [0, 0, 0])
            # Transform to blender coord frame
            value = MathUtility.change_coordinate_frame_of_point(
                value, self.source_frame)
            if rotation_format == "euler":
                # Rotation, specified as euler angles
                rotation_matrix = Euler(value, 'XYZ').to_matrix()
            elif rotation_format == "forward_vec":
                # Convert forward vector to euler angle (Assume Up = Z)
                rotation_matrix = CameraUtility.rotation_from_forward_vec(
                    value)
            elif rotation_format == "look_at":
                # Convert forward vector to euler angle (Assume Up = Z)
                rotation_matrix = CameraUtility.rotation_from_forward_vec(
                    value - position)
            else:
                raise Exception("No such rotation format:" +
                                str(rotation_format))

            if rotation_format == "look_at" or rotation_format == "forward_vec":
                inplane_rot = config.get_float("rotation/inplane_rot", 0.0)
                rotation_matrix = np.matmul(
                    rotation_matrix,
                    Euler((0.0, 0.0, inplane_rot)).to_matrix())

                extra_rot = config.get_vector("rotation/extra_rot",
                                              mathutils.Vector([0., 0., 0.]))
                #extra_rot = Vector([0.3,-0.3,-0.7841])
                rotation_matrix = rotation_matrix @ Euler(
                    extra_rot).to_matrix()

            # cam2world_matrix = Matrix.Translation(Vector(position)) @ rotation_matrix.to_4x4()

            cam2world_matrix = MathUtility.build_transformation_mat(
                position, rotation_matrix)

        else:
            cam2world_matrix = np.array(
                config.get_list("cam2world_matrix")).reshape(4, 4).astype(
                    np.float32)
            cam2world_matrix = MathUtility.change_target_coordinate_frame_of_transformation_matrix(
                cam2world_matrix, self.source_frame)
        return cam2world_matrix
Exemple #2
0
    def get_common_attribute(
            item: bpy.types.Object,
            attribute_name: str,
            local_frame_change: Union[None, List[str]] = None,
            world_frame_change: Union[None, List[str]] = None) -> Any:
        """ Returns the value of the requested attribute for the given item.

        This method covers all general attributes that blender objects have.

        :param item: The item. Type: blender object.
        :param attribute_name: The attribute name. Type: string.
        :param local_frame_change: Can be used to change the local coordinate frame of matrices. Default: ["X", "Y", "Z"]
        :param world_frame_change: Can be used to change the world coordinate frame of points and matrices. Default: ["X", "Y", "Z"]
        :return: The attribute value.
        """

        if local_frame_change is None:
            local_frame_change = ["X", "Y", "Z"]
        if world_frame_change is None:
            world_frame_change = ["X", "Y", "Z"]

        # Print warning if local_frame_change is used with other attributes than matrix_world
        if local_frame_change != ["X", "Y", "Z"] and attribute_name in [
                "location", "rotation_euler", "rotation_forward_vec",
                "rotation_up_vec"
        ]:
            print(
                "Warning: The local_frame_change parameter is at the moment only supported by the matrix_world attribute."
            )

        if attribute_name == "name":
            return item.name
        elif attribute_name == "location":
            return MathUtility.change_coordinate_frame_of_point(
                item.location, world_frame_change)
        elif attribute_name == "rotation_euler":
            return MathUtility.change_coordinate_frame_of_point(
                item.rotation_euler, world_frame_change)
        elif attribute_name == "rotation_forward_vec":
            # Calc forward vector from rotation matrix
            rot_mat = item.rotation_euler.to_matrix()
            forward = rot_mat @ mathutils.Vector([0, 0, -1])
            return MathUtility.change_coordinate_frame_of_point(
                forward, world_frame_change)
        elif attribute_name == "rotation_up_vec":
            # Calc up vector from rotation matrix
            rot_mat = item.rotation_euler.to_matrix()
            up = rot_mat @ mathutils.Vector([0, 1, 0])
            return MathUtility.change_coordinate_frame_of_point(
                up, world_frame_change)
        elif attribute_name == "matrix_world":
            # Transform matrix_world to given destination frame
            matrix_world = MathUtility.change_source_coordinate_frame_of_transformation_matrix(
                item.matrix_world, local_frame_change)
            matrix_world = MathUtility.change_target_coordinate_frame_of_transformation_matrix(
                matrix_world, world_frame_change)
            return [[x for x in c] for c in matrix_world]
        elif attribute_name.startswith("customprop_"):
            custom_property_name = attribute_name[len("customprop_"):]
            # Make sure the requested custom property exist
            if custom_property_name in item:
                return item[custom_property_name]
            else:
                raise Exception("No such custom property: " +
                                custom_property_name)
        else:
            raise Exception("No such attribute: " + attribute_name)