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()
|