-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathfunctions.py
192 lines (158 loc) · 7.98 KB
/
functions.py
1
2
3
4
5
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
'''
Copyright (C) 2021-2022 Orange Turbine
https://orangeturbine.com
orangeturbine@cgcookie.com
Created by Jason van Gumster
This file is part of Export to .blend.
Export to .blend is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 3
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>.
'''
import bpy
import time
def actually_export(export_scene, filepath):
# Set the export scene as the active scene
bpy.context.window.scene = export_scene
# Remove all other scenes
for scn in bpy.data.scenes:
if scn != export_scene:
bpy.data.scenes.remove(scn)
# Go through and remove all the orphans that've been created
bpy.data.orphans_purge(do_recursive = True)
# Save data to desired path
bpy.ops.wm.save_as_mainfile(filepath=filepath, copy=True)
# Undo the scene deletion stuff
#XXX Yes, this *is* a kind of kludgey way to put everything back... but it works!
bpy.ops.ed.undo_push()
bpy.ops.ed.undo()
def export_blend_objects(context, export_settings):
print("Exporting objects to .blend...")
objects = []
object_names = []
if export_settings["export_selected"] and not export_settings["is_collection"]:
for ob in context.selected_objects:
objects.append(ob)
object_names.append(ob.name)
elif export_settings["is_collection"]:
for ob in bpy.data.collections[export_settings["collection_name"]].objects:
objects.append(ob)
object_names.append(ob.name)
else:
for ob in bpy.data.objects:
objects.append(ob)
object_names.append(ob.name)
# Create a new empty scene to hold export objects
export_scene = bpy.data.scenes.new("blend_export")
# Create a collection if we're exporting the selection as one
if export_settings["export_selected"] and export_settings["export_as_collection"]:
if export_settings["is_collection"] == False:
export_collection = bpy.data.collections.new(export_settings["collection_name"])
else:
export_collection = bpy.data.collections[export_settings["collection_name"]]
export_scene.collection.children.link(export_collection)
# Add objects from list to scene
for ob in objects:
export_scene.collection.objects.link(ob)
if export_settings["export_selected"]:
if export_settings["export_as_collection"] and export_settings["is_collection"] == False:
export_collection.objects.link(ob)
elif export_settings["export_as_collection"] == False and export_settings["mark_asset"]:
ob.asset_mark()
ob.asset_generate_preview()
# If exporting as a collection and marking as an asset, only mark the collection as an asset
if export_settings["export_selected"] and export_settings["export_as_collection"] and export_settings["mark_asset"]:
export_collection.asset_mark()
export_collection.asset_generate_preview()
# Temporary hack to give the preview time to generate.
# Ideally, we would wait until preview.image_size[0] != 0
time.sleep(0.5)
actually_export(export_scene, export_settings["filepath"])
# If backlinks are activated, replace each object with a link to the exported one
if export_settings["export_selected"] and export_settings["backlink"]:
if export_settings["export_as_collection"]:
linkpath = export_settings["filepath"] + "\\Collection\\" + export_settings["collection_name"]
linkdir = export_settings["filepath"] + "\\Collection\\"
linkcol = export_settings["collection_name"]
# Remove objects from scene so they can be replaced
for obname in object_names:
bpy.data.objects.remove(bpy.data.objects[obname], do_unlink=True)
# Do the actual replacing thing
bpy.ops.wm.link(
filepath=linkpath,
directory=linkdir,
filename = linkcol
)
else:
for obname in object_names:
linkpath = export_settings["filepath"] + "\\Object\\" + obname
linkdir = export_settings["filepath"] + "\\Object\\"
linkob = obname
bpy.data.objects.remove(bpy.data.objects[obname], do_unlink=True)
bpy.ops.wm.link(
filepath=linkpath,
directory=linkdir,
filename = linkob
)
def export_blend_nodes(context, export_settings):
print("Exporting nodes to .blend...")
current_nodetree = context.active_node.id_data
if export_settings["export_selected"]:
# Remove any nodes that aren't selected
for node in current_nodetree.nodes:
if not node.select:
current_nodetree.nodes.remove(node)
#XXX Right now forcing compositor nodes to export as group
if export_settings["export_as_group"] or current_nodetree.type == 'COMPOSITING':
# Create a node group with the selected nodes
#XXX Would be nice to do this without operators, but that seems non-trivial
bpy.ops.node.group_make()
bpy.ops.node.group_edit(exit=True)
context.active_node.name = export_settings["group_name"]
context.active_node.node_tree.name = export_settings["group_name"]
# Set the current node tree to have a fake user
current_nodetree.use_fake_user = True
# Create a new empty scene to hold export objects
export_scene = bpy.data.scenes.new("blend_export")
if current_nodetree.type == 'COMPOSITING':
export_scene.use_nodes = True
# Remove default Render Layers and Output node
for node in export_scene.node_tree.nodes:
export_scene.node_tree.nodes.remove(node)
#XXX Right now forcing compositor nodes to export as group
temp_group = export_scene.node_tree.nodes.new("CompositorNodeGroup")
temp_group.node_tree = bpy.data.node_groups[export_settings["group_name"]]
actually_export(export_scene, export_settings["filepath"])
# If backlinks are activated, replace each object with a link to the exported one
if export_settings["export_selected"] and export_settings["export_as_group"] and export_settings["backlink"]:
linkpath = export_settings["filepath"] + "\\NodeTree\\" + export_settings["group_name"]
linkdir = export_settings["filepath"] + "\\NodeTree\\"
linkcol = export_settings["group_name"]
# Remove nodes from scene so they can be replaced
current_nodetree = context.active_node.id_data # Blender needs to be reminded where it is
for node in current_nodetree.nodes:
if node.select:
current_nodetree.nodes.remove(node)
# Do the actual replacing thing, first link the exported group
bpy.ops.wm.link(
filepath=linkpath,
directory=linkdir,
filename=linkcol
)
# Add the node group to the tree
#XXX Assumes unique group names
linked_nodegroup = bpy.data.node_groups[linkcol]
# Get node group type
#XXX Assuming here that the node group type for adding is it's self-reported type + "NodeGroup". May break for custom nodes
if linked_nodegroup.type == 'COMPOSITING':
nodetree_type = "CompositorNodeGroup"
else:
nodetree_type = linked_nodegroup.type.title() + "NodeGroup"
replacement_group = current_nodetree.nodes.new(nodetree_type)
replacement_group.node_tree = linked_nodegroup