Skip to content

load_camera

CameraLoader

Bases: Cinema4DLoader

Load the camera.

Source code in client/ayon_cinema4d/plugins/load/load_camera.py
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
class CameraLoader(plugin.Cinema4DLoader):
    """Load the camera."""

    color = "orange"
    product_types = {"camera"}
    representations = {"abc"}
    icon = "file-video-o"
    label = "Load Camera"
    order = -11

    def _merge_camera(self, filepath, doc=None):
        """Merge a camera from a file.

        Arguments:
            filepath (str): The full path to the file that contains the camera.
            doc (optional c4d.documents.BaseDocument): The document to put the
                camera in. By default this will be the active document.

        Returns:
            c4d.BaseList2D: The merge camera object
        """

        doc = doc or lib.active_document()
        camera_doc = c4d.documents.LoadDocument(
            filepath,
            c4d.SCENEFILTER_OBJECTS
            # | c4d.SCENEFILTER_MERGESCENE
            | c4d.SCENEFILTER_NOUNDO
            | c4d.SCENEFILTER_IGNOREXREFS
            | c4d.SCENEFILTER_DONTCORRECTOUTPUTFORMAT,
        )

        # TODO: We should include the parent hierarchy of the loaded camera
        #  to ensure the full correct transformations? As such, maybe we should
        #  merge the full camera - and only make editable the camera objects
        for obj in lib.iter_objects(camera_doc.GetFirstObject()):
            # Get internal camera data from the Alembic Generator
            data = {"res": None}
            if not obj.Message(c4d.MSG_GETREALCAMERADATA, data):
                continue

            if data["res"] is not None:
                camera_alembic = obj
                break
        else:
            raise RuntimeError(f"No camera found in {filepath}")

        # The camera should be the only object in the file
        result = c4d.utils.SendModelingCommand(
            command=c4d.MCOMMAND_MAKEEDITABLE,
            list=[camera_alembic],
            doc=doc,
        )
        assert result, "Making the camera editable failed."
        camera = result[0]
        assert camera.GetTypeName() == "Camera", "No camera found in: {}".format(
            filepath
        )

        self.log.info("Loaded camera '%s' from %s", camera.GetName(), filepath)

        return camera

    def _protect_camera(self, camera):
        """Add a protection tag to the camera.

        Arguments:
            camera (c4d.CameraObject): The camera to protect.
        """

        protection_tag = c4d.BaseTag(c4d.Tprotection)
        camera.InsertTag(protection_tag)
        self.log.debug("Added a protection tag to camera '%s'", camera.GetName())

    def load(self, context, name=None, namespace=None, options=None):
        """Load the camera."""

        doc = lib.active_document()
        name, namespace = self.get_name_and_namespace(
            context, name, namespace, doc)
        basename = f"{namespace}_{name}"

        filepath = self.filepath_from_context(context)
        camera = self._merge_camera(filepath, doc)

        doc.InsertObject(camera)
        camera.SetName(str(basename))

        # Set the camera as the active camera
        for basedraw in (doc.GetActiveBaseDraw(), doc.GetRenderBaseDraw()):
            basedraw.SetSceneCamera(camera)

        self._protect_camera(camera)

        container = pipeline.containerise(
            name=str(name),
            namespace=str(namespace),
            nodes=[camera],
            context=context,
            loader=str(self.__class__.__name__),
        )

        c4d.EventAdd()

        return container

    def update(self, container, context):
        doc = lib.active_document()
        container_node = container["node"]
        filepath = self.filepath_from_context(context)

        camera_name = None
        camera_tags = None
        # There should be only 1 camera node here, remove it
        for obj in lib.get_objects_from_container(container_node):
            if obj.GetTypeName() == "Camera":
                camera_name = obj.GetName()
                camera_tags = obj.GetTags()
            obj.Remove()

        # Add new camera
        camera = self._merge_camera(filepath, doc=doc)
        doc.InsertObject(camera)

        if camera_name:
            camera.SetName(str(camera_name))
        if camera_tags:
            for tag in camera_tags:
                camera.InsertTag(tag)

        # Set the camera as the active camera
        for basedraw in (doc.GetActiveBaseDraw(), doc.GetRenderBaseDraw()):
            basedraw.SetSceneCamera(camera)

        self._protect_camera(camera)

        lib.add_objects_to_container(container_node, [camera])

        # Update representation id
        for i, base_container in container_node.GetUserDataContainer():
            if base_container[c4d.DESC_NAME] == "representation":
                container_node[i] = context["representation"]["id"]

        c4d.EventAdd()

load(context, name=None, namespace=None, options=None)

Load the camera.

Source code in client/ayon_cinema4d/plugins/load/load_camera.py
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def load(self, context, name=None, namespace=None, options=None):
    """Load the camera."""

    doc = lib.active_document()
    name, namespace = self.get_name_and_namespace(
        context, name, namespace, doc)
    basename = f"{namespace}_{name}"

    filepath = self.filepath_from_context(context)
    camera = self._merge_camera(filepath, doc)

    doc.InsertObject(camera)
    camera.SetName(str(basename))

    # Set the camera as the active camera
    for basedraw in (doc.GetActiveBaseDraw(), doc.GetRenderBaseDraw()):
        basedraw.SetSceneCamera(camera)

    self._protect_camera(camera)

    container = pipeline.containerise(
        name=str(name),
        namespace=str(namespace),
        nodes=[camera],
        context=context,
        loader=str(self.__class__.__name__),
    )

    c4d.EventAdd()

    return container