digichem-core 6.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- digichem/__init__.py +75 -0
- digichem/basis.py +116 -0
- digichem/config/README +3 -0
- digichem/config/__init__.py +5 -0
- digichem/config/base.py +321 -0
- digichem/config/locations.py +14 -0
- digichem/config/parse.py +90 -0
- digichem/config/util.py +117 -0
- digichem/data/README +4 -0
- digichem/data/batoms/COPYING +18 -0
- digichem/data/batoms/LICENSE +674 -0
- digichem/data/batoms/README +2 -0
- digichem/data/batoms/__init__.py +0 -0
- digichem/data/batoms/batoms-renderer.py +351 -0
- digichem/data/config/digichem.yaml +714 -0
- digichem/data/functionals.csv +15 -0
- digichem/data/solvents.csv +185 -0
- digichem/data/tachyon/COPYING.md +5 -0
- digichem/data/tachyon/LICENSE +30 -0
- digichem/data/tachyon/tachyon_LINUXAMD64 +0 -0
- digichem/data/vmd/common.tcl +468 -0
- digichem/data/vmd/generate_combined_orbital_images.tcl +70 -0
- digichem/data/vmd/generate_density_images.tcl +45 -0
- digichem/data/vmd/generate_dipole_images.tcl +68 -0
- digichem/data/vmd/generate_orbital_images.tcl +57 -0
- digichem/data/vmd/generate_spin_images.tcl +66 -0
- digichem/data/vmd/generate_structure_images.tcl +40 -0
- digichem/datas.py +14 -0
- digichem/exception/__init__.py +7 -0
- digichem/exception/base.py +133 -0
- digichem/exception/uncatchable.py +63 -0
- digichem/file/__init__.py +1 -0
- digichem/file/base.py +364 -0
- digichem/file/cube.py +284 -0
- digichem/file/fchk.py +94 -0
- digichem/file/prattle.py +277 -0
- digichem/file/types.py +97 -0
- digichem/image/__init__.py +6 -0
- digichem/image/base.py +113 -0
- digichem/image/excited_states.py +335 -0
- digichem/image/graph.py +293 -0
- digichem/image/orbitals.py +239 -0
- digichem/image/render.py +617 -0
- digichem/image/spectroscopy.py +797 -0
- digichem/image/structure.py +115 -0
- digichem/image/vmd.py +826 -0
- digichem/input/__init__.py +3 -0
- digichem/input/base.py +78 -0
- digichem/input/digichem_input.py +500 -0
- digichem/input/gaussian.py +140 -0
- digichem/log.py +179 -0
- digichem/memory.py +166 -0
- digichem/misc/__init__.py +4 -0
- digichem/misc/argparse.py +44 -0
- digichem/misc/base.py +61 -0
- digichem/misc/io.py +239 -0
- digichem/misc/layered_dict.py +285 -0
- digichem/misc/text.py +139 -0
- digichem/misc/time.py +73 -0
- digichem/parse/__init__.py +13 -0
- digichem/parse/base.py +220 -0
- digichem/parse/cclib.py +138 -0
- digichem/parse/dump.py +253 -0
- digichem/parse/gaussian.py +130 -0
- digichem/parse/orca.py +96 -0
- digichem/parse/turbomole.py +201 -0
- digichem/parse/util.py +523 -0
- digichem/result/__init__.py +6 -0
- digichem/result/alignment/AA.py +114 -0
- digichem/result/alignment/AAA.py +61 -0
- digichem/result/alignment/FAP.py +148 -0
- digichem/result/alignment/__init__.py +3 -0
- digichem/result/alignment/base.py +310 -0
- digichem/result/angle.py +153 -0
- digichem/result/atom.py +742 -0
- digichem/result/base.py +258 -0
- digichem/result/dipole_moment.py +332 -0
- digichem/result/emission.py +402 -0
- digichem/result/energy.py +323 -0
- digichem/result/excited_state.py +821 -0
- digichem/result/ground_state.py +94 -0
- digichem/result/metadata.py +644 -0
- digichem/result/multi.py +98 -0
- digichem/result/nmr.py +1086 -0
- digichem/result/orbital.py +647 -0
- digichem/result/result.py +244 -0
- digichem/result/soc.py +272 -0
- digichem/result/spectroscopy.py +514 -0
- digichem/result/tdm.py +267 -0
- digichem/result/vibration.py +167 -0
- digichem/test/__init__.py +6 -0
- digichem/test/conftest.py +4 -0
- digichem/test/test_basis.py +71 -0
- digichem/test/test_calculate.py +30 -0
- digichem/test/test_config.py +78 -0
- digichem/test/test_cube.py +369 -0
- digichem/test/test_exception.py +16 -0
- digichem/test/test_file.py +104 -0
- digichem/test/test_image.py +337 -0
- digichem/test/test_input.py +64 -0
- digichem/test/test_parsing.py +79 -0
- digichem/test/test_prattle.py +36 -0
- digichem/test/test_result.py +489 -0
- digichem/test/test_translate.py +112 -0
- digichem/test/util.py +207 -0
- digichem/translate.py +591 -0
- digichem_core-6.0.0rc1.dist-info/METADATA +96 -0
- digichem_core-6.0.0rc1.dist-info/RECORD +111 -0
- digichem_core-6.0.0rc1.dist-info/WHEEL +4 -0
- digichem_core-6.0.0rc1.dist-info/licenses/COPYING.md +10 -0
- digichem_core-6.0.0rc1.dist-info/licenses/LICENSE +11 -0
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# Render something with Beautiful Atoms.
|
|
2
|
+
# To use this script, run something like:
|
|
3
|
+
#
|
|
4
|
+
# # To disabled possibly conflicting packages outside of the conda env.
|
|
5
|
+
# PYTHONNOUSERSITE=1
|
|
6
|
+
# blender -b -P batoms-renderer.py
|
|
7
|
+
#
|
|
8
|
+
# Where 'blender' is the path to the Beautiful Atoms Blender executable.
|
|
9
|
+
|
|
10
|
+
import sys
|
|
11
|
+
import argparse
|
|
12
|
+
import itertools
|
|
13
|
+
import bpy
|
|
14
|
+
import yaml
|
|
15
|
+
import math
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
import logging
|
|
18
|
+
|
|
19
|
+
import ase.io
|
|
20
|
+
from batoms import Batoms
|
|
21
|
+
from batoms.utils.butils import object_mode
|
|
22
|
+
|
|
23
|
+
def add_molecule(
|
|
24
|
+
cube_file,
|
|
25
|
+
name,
|
|
26
|
+
rotations = None,
|
|
27
|
+
visible = True,
|
|
28
|
+
isovalues = None,
|
|
29
|
+
isotype = "both",
|
|
30
|
+
primary_color = [1, 0.058, 0.0, 0.55],
|
|
31
|
+
secondary_color = [0.1, 0.1, 0.9, 0.55],
|
|
32
|
+
style = "default"
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
"""
|
|
36
|
+
rotations = [] if rotations is None else rotations
|
|
37
|
+
isovalues = [] if isovalues is None else isovalues
|
|
38
|
+
|
|
39
|
+
surface_settings = []
|
|
40
|
+
for isovalue in isovalues:
|
|
41
|
+
if isotype in ["both", "positive"]:
|
|
42
|
+
surface_settings.append({'level': isovalue, 'color': primary_color, 'material_style': style})
|
|
43
|
+
|
|
44
|
+
if isotype in ["both", "negative"]:
|
|
45
|
+
surface_settings.append({'level': -isovalue, 'color': secondary_color, 'material_style': style})
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
# Load the input data.
|
|
49
|
+
cube = ase.io.read(cube_file, format="cube", read_data=True, full_output=True)
|
|
50
|
+
|
|
51
|
+
# The centre of the cube is often offset, fix that by shifting the atoms.
|
|
52
|
+
cube["atoms"].translate(-cube["origin"][0:3])
|
|
53
|
+
|
|
54
|
+
# Get the mol object.
|
|
55
|
+
mol = Batoms(name, from_ase = cube["atoms"])
|
|
56
|
+
|
|
57
|
+
# Set some look and feel options.
|
|
58
|
+
# Change molecule style.
|
|
59
|
+
mol.model_style = 1
|
|
60
|
+
|
|
61
|
+
# Hide cell boundaries.
|
|
62
|
+
mol.cell.hide = True
|
|
63
|
+
|
|
64
|
+
# Colour tuning.
|
|
65
|
+
# Carbon to 'black'.
|
|
66
|
+
try:
|
|
67
|
+
mol["C"].color = (0.095, 0.095, 0.095, 1)
|
|
68
|
+
except AttributeError:
|
|
69
|
+
pass
|
|
70
|
+
try:
|
|
71
|
+
mol["B"].color = (1.0, 0.396, 0.468, 1)
|
|
72
|
+
except AttributeError:
|
|
73
|
+
pass
|
|
74
|
+
|
|
75
|
+
if not visible:
|
|
76
|
+
mol.hide = True
|
|
77
|
+
|
|
78
|
+
# Add volumes.
|
|
79
|
+
if len(surface_settings) != 0:
|
|
80
|
+
mol.volumetric_data['surface'] = cube['data']
|
|
81
|
+
|
|
82
|
+
for index, settings in enumerate(surface_settings):
|
|
83
|
+
mol.isosurface.settings[index+1] = settings
|
|
84
|
+
|
|
85
|
+
mol.isosurface.draw()
|
|
86
|
+
|
|
87
|
+
# Now move the entire molecule (isosurface and all) back to the origin.
|
|
88
|
+
mol.translate(cube["origin"][0:3])
|
|
89
|
+
|
|
90
|
+
# Fix the origin point so we can still rotate properly.
|
|
91
|
+
# For some reason, this code moves the bond objects to a new location?
|
|
92
|
+
# object_mode()
|
|
93
|
+
# bpy.ops.object.select_all(action='DESELECT')
|
|
94
|
+
# mol.obj.select_set(True)
|
|
95
|
+
# bpy.context.view_layer.objects.active = mol.obj
|
|
96
|
+
# bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
|
|
97
|
+
|
|
98
|
+
# If we have any rotations, apply those.
|
|
99
|
+
for axis, angle in rotations:
|
|
100
|
+
# Convert to degree.
|
|
101
|
+
# Not used.
|
|
102
|
+
degree = angle * (180/math.pi)
|
|
103
|
+
|
|
104
|
+
if axis == 0:
|
|
105
|
+
axis = "x"
|
|
106
|
+
|
|
107
|
+
elif axis == 1:
|
|
108
|
+
axis = "y"
|
|
109
|
+
|
|
110
|
+
elif axis == 2:
|
|
111
|
+
axis = "z"
|
|
112
|
+
|
|
113
|
+
else:
|
|
114
|
+
raise ValueError("Unknown rotation axis '{}'".format(axis))
|
|
115
|
+
|
|
116
|
+
#mol.rotate(degree, axis)
|
|
117
|
+
|
|
118
|
+
# Taken from batoms source (collection.py: 51)
|
|
119
|
+
object_mode()
|
|
120
|
+
bpy.ops.object.select_all(action='DESELECT')
|
|
121
|
+
mol.obj.select_set(True)
|
|
122
|
+
bpy.context.view_layer.objects.active = mol.obj
|
|
123
|
+
bpy.ops.transform.rotate(value=angle, orient_axis=axis.upper(),
|
|
124
|
+
center_override = (0,0,0))
|
|
125
|
+
|
|
126
|
+
return mol
|
|
127
|
+
|
|
128
|
+
# Adapted from https://blender.stackexchange.com/questions/5898/how-can-i-create-a-cylinder-linking-two-points-with-python?newreg=f372ba9448694f5b97879a6dab963cee
|
|
129
|
+
def draw_primitive(start, end, radius, mesh_type, color, collection = None):
|
|
130
|
+
"""
|
|
131
|
+
"""
|
|
132
|
+
dx = end[0] - start[0]
|
|
133
|
+
dy = end[1] - start[1]
|
|
134
|
+
dz = end[2] - start[2]
|
|
135
|
+
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
|
136
|
+
|
|
137
|
+
# First draw the shape.
|
|
138
|
+
if mesh_type == "cylinder":
|
|
139
|
+
bpy.ops.mesh.primitive_cylinder_add(
|
|
140
|
+
radius = radius,
|
|
141
|
+
depth = dist,
|
|
142
|
+
vertices = 32,
|
|
143
|
+
location = (dx/2 + start[0], dy/2 + start[1], dz/2 + start[2])
|
|
144
|
+
)
|
|
145
|
+
elif mesh_type == "cone":
|
|
146
|
+
bpy.ops.mesh.primitive_cone_add(
|
|
147
|
+
radius1 = radius,
|
|
148
|
+
depth = dist,
|
|
149
|
+
vertices = 32,
|
|
150
|
+
location = (dx/2 + start[0], dy/2 + start[1], dz/2 + start[2])
|
|
151
|
+
)
|
|
152
|
+
else:
|
|
153
|
+
raise ValueError("Unknown mesh type '{}'".format(mesh_type))
|
|
154
|
+
|
|
155
|
+
# Get a reference to the object we just made.
|
|
156
|
+
obj = bpy.context.active_object
|
|
157
|
+
|
|
158
|
+
phi = math.atan2(dy, dx)
|
|
159
|
+
theta = math.acos(dz/dist)
|
|
160
|
+
|
|
161
|
+
bpy.context.object.rotation_euler[1] = theta
|
|
162
|
+
bpy.context.object.rotation_euler[2] = phi
|
|
163
|
+
|
|
164
|
+
# Get material
|
|
165
|
+
mat = bpy.data.materials.new(name="Material")
|
|
166
|
+
|
|
167
|
+
# assign to 1st material slot
|
|
168
|
+
obj.active_material = mat
|
|
169
|
+
|
|
170
|
+
mat.use_nodes = True
|
|
171
|
+
tree = mat.node_tree
|
|
172
|
+
nodes = tree.nodes
|
|
173
|
+
bsdf = nodes["Principled BSDF"]
|
|
174
|
+
bsdf.inputs["Base Color"].default_value = color
|
|
175
|
+
bsdf.inputs["Metallic"].default_value = 0.1
|
|
176
|
+
bsdf.inputs["Specular"].default_value = 0.2
|
|
177
|
+
bsdf.inputs["Roughness"].default_value = 0.2
|
|
178
|
+
mat.diffuse_color = color
|
|
179
|
+
|
|
180
|
+
# If we've been asked to, asign our new object to a given collection.
|
|
181
|
+
# First unlink from any old collections
|
|
182
|
+
for coll in obj.users_collection:
|
|
183
|
+
# Unlink the object
|
|
184
|
+
coll.objects.unlink(obj)
|
|
185
|
+
|
|
186
|
+
# Link each object to the target collection
|
|
187
|
+
collection.objects.link(obj)
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def draw_arrow(start, end, radius, color, split = 0.9, collection = None):
|
|
191
|
+
# Decide what proportion of the total vector to dedicate to the arrow stem and head.
|
|
192
|
+
dx = end[0] - start[0]
|
|
193
|
+
dy = end[1] - start[1]
|
|
194
|
+
dz = end[2] - start[2]
|
|
195
|
+
dist = math.sqrt(dx**2 + dy**2 + dz**2)
|
|
196
|
+
|
|
197
|
+
join = (dx * split + start[0], dy * split + start[1], dz * split + start[2])
|
|
198
|
+
draw_primitive(start, join, radius, "cylinder", color, collection = collection)
|
|
199
|
+
draw_primitive(join, end, radius*2, "cone", color, collection = collection)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def main():
|
|
203
|
+
parser = argparse.ArgumentParser(
|
|
204
|
+
prog='Beautiful Atoms Renderer',
|
|
205
|
+
description='Render images with BAtoms')
|
|
206
|
+
|
|
207
|
+
parser.add_argument("cube_file", help = "Path to the cube file to read")
|
|
208
|
+
parser.add_argument("output", help = "File to write to")
|
|
209
|
+
parser.add_argument("--second_cube", help = "Optional second cube file to read additional isosurface data from", default = None)
|
|
210
|
+
parser.add_argument("--isovalues", help = "List of isovalues to render", nargs = "*", type = float, default = [])
|
|
211
|
+
parser.add_argument("--isotype", help = "Whether to render positive, negative or both isosurfaces for each isovalue", choices = ["positive", "negative", "both"], default = "both")
|
|
212
|
+
parser.add_argument("--isocolor", help = "The colouring method to use for isosurfaces", choices = ["sign", "cube"], default = "sign")
|
|
213
|
+
parser.add_argument("--primary-color", help = "RGBA for one of the colors to use for isosurfaces", type = float, nargs = 4, default = [0.1, 0.1, 0.9, 0.7])
|
|
214
|
+
parser.add_argument("--secondary-color", help = "RGBA for the other color to use for isosurfaces", type = float, nargs = 4, default = [1, 0.058, 0.0, 0.7])
|
|
215
|
+
parser.add_argument("--style", help = "Material style for isosurfaces", choices = ('default', 'metallic', 'plastic', 'ceramic', 'mirror'), default = "default")
|
|
216
|
+
parser.add_argument("--cpus", help = "Number of parallel CPUs to use for rendering", type = int, default = 1)
|
|
217
|
+
parser.add_argument("--use-gpu", help = "Whether to enable GPU rendering", action = "store_true")
|
|
218
|
+
parser.add_argument("--orientation", help = "The orientation to render from, as x, y, z values", nargs = 3, type = float, default = [0, 0, 1])
|
|
219
|
+
parser.add_argument("--resolution", help = "The output resolution in px", type = int, default = 1024)
|
|
220
|
+
parser.add_argument("--render-samples", help = "The maximum number of render samples, more generally results in higher quality but longer render times", type = int, default = 256)
|
|
221
|
+
parser.add_argument("--rotations", help = "A list of rotations (in JSON) to rotate the molecule to a given alignment. The first item in each list item is the axis to rotate about (0=x, 1=y, 2=z), the second is the angle to rotate by (in radians)", nargs = "*", default = [])
|
|
222
|
+
parser.add_argument("--dipoles", help = "Draw dipoles from a list of the following data (in JSON): 0) start coord, 1) end coord, 2) RGBA color information", nargs = "*", default = [])
|
|
223
|
+
parser.add_argument("--alpha", help = "Override the opacity value for all molecule objects (but not dipoles) to this value, useful for showing dipole arrows more clearly", default = None, type = float)
|
|
224
|
+
parser.add_argument("--perspective", help = "The perspective mode, either orthographic or perspective", default = "perspective", choices = ["perspective", "orthographic"])
|
|
225
|
+
parser.add_argument("--padding", help = "Padding", type = float, default = 1.0)
|
|
226
|
+
|
|
227
|
+
# Both blender and python share the same command line arguments.
|
|
228
|
+
# They are separated by double dash ('--'), everything before is for blender,
|
|
229
|
+
# everything afterwards is for python (except for the first argument, wich is
|
|
230
|
+
# the program name, which is for both).
|
|
231
|
+
if "--" in sys.argv:
|
|
232
|
+
python_argv = sys.argv[sys.argv.index("--") +1:]
|
|
233
|
+
else:
|
|
234
|
+
python_argv = []
|
|
235
|
+
|
|
236
|
+
args = parser.parse_args(python_argv)
|
|
237
|
+
|
|
238
|
+
# Batoms or blender will silently set the extension to png if it's not already.
|
|
239
|
+
# This is surprising, so stop now before that happens.
|
|
240
|
+
if Path(args.output).suffix.lower() != ".png":
|
|
241
|
+
raise ValueError("Output location must have a .png extension")
|
|
242
|
+
|
|
243
|
+
if args.rotations is not None:
|
|
244
|
+
rotations = [yaml.safe_load(rotation) for rotation in args.rotations]
|
|
245
|
+
|
|
246
|
+
# Load the input data.
|
|
247
|
+
mol = add_molecule(
|
|
248
|
+
args.cube_file,
|
|
249
|
+
name = "molecule",
|
|
250
|
+
visible = True,
|
|
251
|
+
rotations = rotations,
|
|
252
|
+
isovalues = args.isovalues,
|
|
253
|
+
isotype = args.isotype,
|
|
254
|
+
primary_color = args.primary_color,
|
|
255
|
+
secondary_color = args.secondary_color if args.isocolor == "sign" else args.primary_color,
|
|
256
|
+
style = args.style
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
# Uncomment to show atom labels.
|
|
260
|
+
# Needs some tweaking to appear in render (viewport only by default).
|
|
261
|
+
#mol.show_label = 'species'
|
|
262
|
+
|
|
263
|
+
# If we have a second cube, add that too.
|
|
264
|
+
if args.second_cube is not None:
|
|
265
|
+
mol2 = add_molecule(
|
|
266
|
+
args.second_cube,
|
|
267
|
+
name = "molecule2",
|
|
268
|
+
visible = True,
|
|
269
|
+
rotations = rotations,
|
|
270
|
+
isovalues = args.isovalues,
|
|
271
|
+
isotype = args.isotype,
|
|
272
|
+
primary_color = args.primary_color if args.isocolor == "sign" else args.secondary_color,
|
|
273
|
+
secondary_color = args.secondary_color,
|
|
274
|
+
style = args.style
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
if args.alpha:
|
|
278
|
+
# Set all materials transparent.
|
|
279
|
+
for material in bpy.data.materials:
|
|
280
|
+
try:
|
|
281
|
+
material.node_tree.nodes['Principled BSDF'].inputs['Alpha'].default_value = args.alpha
|
|
282
|
+
except Exception as e:
|
|
283
|
+
pass
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
# Draw any dipoles.
|
|
287
|
+
if args.dipoles is not None:
|
|
288
|
+
|
|
289
|
+
dipoles = [yaml.safe_load(dipole) for dipole in args.dipoles]
|
|
290
|
+
for start_coord, end_coord, rgba in dipoles:
|
|
291
|
+
draw_arrow(start_coord, end_coord, 0.08, rgba, collection = mol.coll)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
# Setup rendering settings.
|
|
295
|
+
# mol.render.engine = 'workbench'
|
|
296
|
+
# mol.render.engine = 'eevee'
|
|
297
|
+
mol.render.engine = 'cycles'
|
|
298
|
+
mol.render.resolution = [args.resolution, args.resolution]
|
|
299
|
+
# Set up cycles for good quality rendering.
|
|
300
|
+
# Prevents early end to rendering (forces us to use the actual number of samples).
|
|
301
|
+
bpy.context.scene.cycles.use_adaptive_sampling = False
|
|
302
|
+
# Quality control, more = better and slower.
|
|
303
|
+
bpy.context.scene.cycles.samples = args.render_samples
|
|
304
|
+
# Post-processing to remove noise, works well for coloured backgrounds, useless for transparency.
|
|
305
|
+
bpy.context.scene.cycles.use_denoising = True
|
|
306
|
+
# Ray-tracing options
|
|
307
|
+
bpy.context.scene.cycles.max_bounces = 48
|
|
308
|
+
bpy.context.scene.cycles.transparent_max_bounces = 24
|
|
309
|
+
if args.use_gpu:
|
|
310
|
+
bpy.context.scene.cycles.device = "GPU"
|
|
311
|
+
|
|
312
|
+
# Use maximum compression.
|
|
313
|
+
bpy.context.scene.render.image_settings.compression = 1000
|
|
314
|
+
|
|
315
|
+
# Change light intensity.
|
|
316
|
+
bpy.data.lights["batoms_light_Default"].node_tree.nodes["Emission"].inputs[1].default_value = 0.5 #0.3
|
|
317
|
+
#mol.render.lights["Default"].energy=10
|
|
318
|
+
|
|
319
|
+
# Change view mode.
|
|
320
|
+
if args.perspective == "perspective":
|
|
321
|
+
mol.render.camera.type = "PERSP"
|
|
322
|
+
|
|
323
|
+
else:
|
|
324
|
+
mol.render.camera.type = "ORTHO"
|
|
325
|
+
|
|
326
|
+
# Enable to add an outline.
|
|
327
|
+
#bpy.context.scene.render.use_freestyle = True
|
|
328
|
+
|
|
329
|
+
# Performance options.
|
|
330
|
+
bpy.context.scene.render.threads_mode = 'FIXED'
|
|
331
|
+
bpy.context.scene.render.threads = args.cpus
|
|
332
|
+
|
|
333
|
+
mol.get_image(viewport = args.orientation, output = args.output, padding = args.padding)
|
|
334
|
+
# # Move the camera.
|
|
335
|
+
# mol.render.camera.location = (100,0,0)
|
|
336
|
+
# mol.render.camera.look_at = mol.get_center_of_geometry()
|
|
337
|
+
# bpy.ops.object.select_all(action='DESELECT')
|
|
338
|
+
# for obj in mol.coll.objects[:]:
|
|
339
|
+
# obj.select_set(True)
|
|
340
|
+
# #bpy.ops.view3d.camera_to_view_selected()
|
|
341
|
+
|
|
342
|
+
return 0
|
|
343
|
+
|
|
344
|
+
# If we've been invoked as a program, call main().
|
|
345
|
+
if __name__ == '__main__':
|
|
346
|
+
try:
|
|
347
|
+
sys.exit(main())
|
|
348
|
+
|
|
349
|
+
except Exception as e:
|
|
350
|
+
logging.error("Erro", exc_info = True)
|
|
351
|
+
sys.exit(1)
|