Skip to content

Commit 502550e

Browse files
author
Lawrence D'Oliveiro
committed
Split off demo code to reduce size of addon proper.
1 parent 4b8eb21 commit 502550e

File tree

3 files changed

+160
-144
lines changed

3 files changed

+160
-144
lines changed

__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
{
33
"name" : "Spaceship Generator",
44
"author" : "Michael Davies, Lawrence D'Oliveiro",
5-
"version" : (1, 3, 0),
5+
"version" : (1, 3, 1),
66
"blender" : (2, 82, 0),
77
"location" : "View3D > Add > Mesh",
88
"description" : "Procedurally generate 3D spaceships from a random seed.",

demo.py

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
#+
2+
# Demo script that can generate a single spaceship, or a movie
3+
# comprising multiple spaceships. Enable the add_mesh_SpaceshipGenerator
4+
# addon, open/copy this script in/into Blender’s Text Editor, and
5+
# press ALT-P to run it.
6+
#-
7+
8+
import bpy
9+
from add_mesh_SpaceshipGenerator.spaceship_generator import \
10+
deg, \
11+
parms_defaults, \
12+
generate_spaceship
13+
14+
# When true, this script will generate a single spaceship in the scene.
15+
# When false, this script will render multiple movie frames showcasing lots of ships.
16+
generate_single_spaceship = True
17+
18+
import os
19+
import math
20+
import datetime
21+
import bpy
22+
from mathutils import \
23+
Vector
24+
25+
# Deletes all existing spaceships and unused materials from the scene
26+
def reset_scene() :
27+
for item in bpy.data.objects :
28+
item.select_set(item.name.startswith("Spaceship"))
29+
#end for
30+
bpy.ops.object.delete()
31+
for material in bpy.data.materials :
32+
if not material.users :
33+
bpy.data.materials.remove(material)
34+
#end if
35+
#end for
36+
for texture in bpy.data.textures :
37+
if not texture.users :
38+
bpy.data.textures.remove(texture)
39+
#end if
40+
#end for
41+
#end reset_scene
42+
43+
class parms(parms_defaults) :
44+
geom_ranseed = ""
45+
mat_ranseed = ""
46+
# add anything here to generate the same spaceship
47+
#end class
48+
49+
if generate_single_spaceship :
50+
# Reset the scene, generate a single spaceship and focus on it
51+
reset_scene()
52+
obj = generate_spaceship(parms)
53+
54+
# View the selected object in all views
55+
for area in bpy.context.screen.areas :
56+
if area.type == "VIEW_3D" :
57+
ctx = bpy.context.copy()
58+
ctx["area"] = area
59+
ctx["region"] = area.regions[-1]
60+
bpy.ops.view3d.view_selected(ctx)
61+
#end if
62+
#end for
63+
64+
else :
65+
# Export a movie showcasing many different kinds of ships
66+
67+
# Settings
68+
output_path = "" # leave empty to use script folder
69+
total_movie_duration = 16
70+
total_spaceship_duration = 1
71+
yaw_rate = 45 * deg # angle/sec
72+
yaw_offset = 220 * deg # angle/sec
73+
camera_pole_rate = 1
74+
camera_pole_pitch_min = 15 * deg
75+
camera_pole_pitch_max = 30 * deg
76+
camera_pole_pitch_offset = 0 * deg
77+
camera_pole_length = 10
78+
camera_refocus_object_every_frame = False
79+
fov = 60 * deg
80+
fps = 30
81+
res_x = 1920
82+
res_y = 1080
83+
84+
# Batch render the movie frames
85+
inv_fps = 1 / fps
86+
movie_duration = 0
87+
spaceship_duration = total_spaceship_duration
88+
scene = bpy.data.scenes["Scene"]
89+
scene.render.resolution_x = res_x
90+
scene.render.resolution_y = res_y
91+
scene.camera.rotation_mode = "XYZ"
92+
scene.camera.data.angle = fov
93+
frame = 0
94+
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
95+
while movie_duration < total_movie_duration :
96+
movie_duration += inv_fps
97+
spaceship_duration += inv_fps
98+
if spaceship_duration >= total_spaceship_duration :
99+
spaceship_duration -= total_spaceship_duration
100+
101+
# Generate a new spaceship
102+
reset_scene()
103+
obj = generate_spaceship(parms)
104+
105+
# look for a mirror plane in the scene, and position it
106+
# just underneath the ship if found
107+
lowest_z = centre = min((Vector(b).z for b in obj.bound_box))
108+
plane_obj = bpy.data.objects.get("Plane")
109+
if plane_obj :
110+
plane_obj.location.z = lowest_z - 0.3
111+
#end if
112+
#end if
113+
114+
# Position and orient the camera
115+
yaw = yaw_offset + yaw_rate * movie_duration
116+
camera_pole_pitch_lerp = 0.5 * (1 + math.cos(camera_pole_rate * movie_duration)) # 0-1
117+
camera_pole_pitch = \
118+
(
119+
camera_pole_pitch_max * camera_pole_pitch_lerp
120+
+
121+
camera_pole_pitch_min * (1 - camera_pole_pitch_lerp)
122+
)
123+
scene.camera.rotation_euler = \
124+
(
125+
90 * deg - camera_pole_pitch + camera_pole_pitch_offset,
126+
0,
127+
yaw
128+
)
129+
scene.camera.location = \
130+
(
131+
math.sin(yaw) * camera_pole_length,
132+
math.cos(yaw) * -camera_pole_length,
133+
math.sin(camera_pole_pitch) * camera_pole_length
134+
)
135+
if camera_refocus_object_every_frame :
136+
bpy.ops.view3d.camera_to_view_selected()
137+
#end if
138+
139+
# Render the scene to disk
140+
script_path = bpy.context.space_data.text.filepath if bpy.context.space_data else __file__
141+
folder = output_path if output_path else os.path.split(os.path.realpath(script_path))[0]
142+
filename = os.path.join \
143+
(
144+
"renders",
145+
timestamp,
146+
timestamp + "_" + str(frame).zfill(5) + ".png"
147+
)
148+
bpy.data.scenes["Scene"].render.filepath = os.path.join(folder, filename)
149+
print("Rendering frame " + str(frame) + "...")
150+
bpy.ops.render.render(write_still = True)
151+
frame += 1
152+
#end while movie_duration < total_movie_duration
153+
154+
#end if generate_single_spaceship

spaceship_generator.py

Lines changed: 5 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
#
1+
#+
22
# spaceship_generator.py
33
#
44
# This is a Blender script that uses procedural generation to create
5-
# textured 3D spaceship models. Tested with Blender 2.79.
6-
#
7-
8-
# https://github.com/a1studmuffin/SpaceshipGenerator
5+
# textured 3D spaceship models. Tested with Blender 2.82.
96
#
7+
# [email protected], Lawrence D'Oliveiro
8+
# https://github.com/ldo/SpaceshipGenerator
9+
#-
1010

1111
import os
1212
import bpy
@@ -1097,141 +1097,3 @@ def add_disc_to_face(bm, face) :
10971097

10981098
return obj
10991099
#end generate_spaceship
1100-
1101-
if __name__ == "__main__" :
1102-
1103-
import datetime
1104-
1105-
# Deletes all existing spaceships and unused materials from the scene
1106-
def reset_scene() :
1107-
for item in bpy.data.objects :
1108-
item.select = item.name.startswith("Spaceship")
1109-
#end for
1110-
bpy.ops.object.delete()
1111-
for material in bpy.data.materials :
1112-
if not material.users :
1113-
bpy.data.materials.remove(material)
1114-
#end if
1115-
#end for
1116-
for texture in bpy.data.textures :
1117-
if not texture.users :
1118-
bpy.data.textures.remove(texture)
1119-
#end if
1120-
#end for
1121-
#end reset_scene
1122-
1123-
# When true, this script will generate a single spaceship in the scene.
1124-
# When false, this script will render multiple movie frames showcasing lots of ships.
1125-
generate_single_spaceship = True
1126-
1127-
if generate_single_spaceship :
1128-
# Reset the scene, generate a single spaceship and focus on it
1129-
reset_scene()
1130-
parms_defaults.geom_ranseed = ""
1131-
parms_defaults.mat_ranseed = ""
1132-
# add anything here to generate the same spaceship
1133-
obj = generate_spaceship(parms_defaults)
1134-
1135-
# View the selected object in all views
1136-
for area in bpy.context.screen.areas :
1137-
if area.type == "VIEW_3D" :
1138-
ctx = bpy.context.copy()
1139-
ctx["area"] = area
1140-
ctx["region"] = area.regions[-1]
1141-
bpy.ops.view3d.view_selected(ctx)
1142-
#end if
1143-
#end for
1144-
1145-
else :
1146-
# Export a movie showcasing many different kinds of ships
1147-
1148-
# Settings
1149-
output_path = "" # leave empty to use script folder
1150-
total_movie_duration = 16
1151-
total_spaceship_duration = 1
1152-
yaw_rate = 45 * deg # angle/sec
1153-
yaw_offset = 220 * deg # angle/sec
1154-
camera_pole_rate = 1
1155-
camera_pole_pitch_min = 15 * deg
1156-
camera_pole_pitch_max = 30 * deg
1157-
camera_pole_pitch_offset = 0 * deg
1158-
camera_pole_length = 10
1159-
camera_refocus_object_every_frame = False
1160-
fov = 60 * deg
1161-
fps = 30
1162-
res_x = 1920
1163-
res_y = 1080
1164-
1165-
# Batch render the movie frames
1166-
inv_fps = 1 / fps
1167-
movie_duration = 0
1168-
spaceship_duration = total_spaceship_duration
1169-
scene = bpy.data.scenes["Scene"]
1170-
scene.render.resolution_x = res_x
1171-
scene.render.resolution_y = res_y
1172-
scene.camera.rotation_mode = "XYZ"
1173-
scene.camera.data.angle = fov
1174-
frame = 0
1175-
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
1176-
while movie_duration < total_movie_duration :
1177-
movie_duration += inv_fps
1178-
spaceship_duration += inv_fps
1179-
if spaceship_duration >= total_spaceship_duration :
1180-
spaceship_duration -= total_spaceship_duration
1181-
1182-
# Generate a new spaceship
1183-
reset_scene()
1184-
obj = generate_spaceship(parms_defaults)
1185-
1186-
# look for a mirror plane in the scene, and position it
1187-
# just underneath the ship if found
1188-
lowest_z = centre = min((Vector(b).z for b in obj.bound_box))
1189-
plane_obj = bpy.data.objects.get("Plane")
1190-
if plane_obj :
1191-
plane_obj.location.z = lowest_z - 0.3
1192-
#end if
1193-
#end if
1194-
1195-
# Position and orient the camera
1196-
yaw = yaw_offset + yaw_rate * movie_duration
1197-
camera_pole_pitch_lerp = 0.5 * (1 + math.cos(camera_pole_rate * movie_duration)) # 0-1
1198-
camera_pole_pitch = \
1199-
(
1200-
camera_pole_pitch_max * camera_pole_pitch_lerp
1201-
+
1202-
camera_pole_pitch_min * (1 - camera_pole_pitch_lerp)
1203-
)
1204-
scene.camera.rotation_euler = \
1205-
(
1206-
90 * deg - camera_pole_pitch + camera_pole_pitch_offset,
1207-
0,
1208-
yaw
1209-
)
1210-
scene.camera.location = \
1211-
(
1212-
math.sin(yaw) * camera_pole_length,
1213-
math.cos(yaw) * -camera_pole_length,
1214-
math.sin(camera_pole_pitch) * camera_pole_length
1215-
)
1216-
if camera_refocus_object_every_frame :
1217-
bpy.ops.view3d.camera_to_view_selected()
1218-
#end if
1219-
1220-
# Render the scene to disk
1221-
script_path = bpy.context.space_data.text.filepath if bpy.context.space_data else __file__
1222-
folder = output_path if output_path else os.path.split(os.path.realpath(script_path))[0]
1223-
filename = os.path.join \
1224-
(
1225-
"renders",
1226-
timestamp,
1227-
timestamp + "_" + str(frame).zfill(5) + ".png"
1228-
)
1229-
bpy.data.scenes["Scene"].render.filepath = os.path.join(folder, filename)
1230-
print("Rendering frame " + str(frame) + "...")
1231-
bpy.ops.render.render(write_still = True)
1232-
frame += 1
1233-
#end while movie_duration < total_movie_duration
1234-
1235-
#end if generate_single_spaceship
1236-
1237-
#end if __name__ == "__main__"

0 commit comments

Comments
 (0)