glitch3d 0.2.3.8 → 0.2.4.0
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.
- checksums.yaml +4 -4
- data/fixtures/base.blend +0 -0
- data/fixtures/female_head_slim.obj +55099 -0
- data/fixtures/male_body.obj +345023 -0
- data/fixtures/male_head_slim.obj +56739 -0
- data/fixtures/textures/corbusier_haus.jpg +0 -0
- data/fixtures/textures/mario_faces.jpg +0 -0
- data/fixtures/textures/putin_wave.jpg +0 -0
- data/fixtures/textures/texture_wave.jpg +0 -0
- data/fixtures/woman_body.obj +502845 -0
- data/lib/glitch3d.rb +8 -3
- data/lib/glitch3d/bpy/canvas/aether.py +6 -5
- data/lib/glitch3d/bpy/canvas/dreamatorium.py +1 -3
- data/lib/glitch3d/bpy/canvas/frame_generator.py +21 -0
- data/lib/glitch3d/bpy/canvas/lyfe.py +34 -28
- data/lib/glitch3d/bpy/canvas/particles.py +19 -0
- data/lib/glitch3d/bpy/helpers.py +62 -25
- data/lib/glitch3d/bpy/main.py +23 -16
- data/lib/glitch3d/bpy/render_settings.py +5 -0
- data/lib/glitch3d/version.rb +1 -1
- metadata +12 -2
data/lib/glitch3d.rb
CHANGED
@@ -11,7 +11,7 @@ module Glitch3d
|
|
11
11
|
|
12
12
|
FACE_GLITCH_ITERATION_RATIO = 0.1
|
13
13
|
FACE_GLITCH_OFFSET = 0.5
|
14
|
-
BOUNDARY_LIMIT =
|
14
|
+
BOUNDARY_LIMIT = 3 # Contain model within BOUNDARY_LIMITxBOUNDARY_LIMITxBOUNDARY_LIMIT cube
|
15
15
|
CHUNK_SIZE=20
|
16
16
|
|
17
17
|
BLENDER_EXECUTABLE_PATH = ENV['BLENDER_EXECUTABLE_PATH'].freeze
|
@@ -34,7 +34,7 @@ module Glitch3d
|
|
34
34
|
source_file = random_fixture if source_file.nil?
|
35
35
|
print_version if args.has_key?('version')
|
36
36
|
raise 'Set Blender executable path in your env variables before using glitch3d' if BLENDER_EXECUTABLE_PATH.nil?
|
37
|
-
self.class.include infer_strategy(args['mode']
|
37
|
+
self.class.include infer_strategy(args['mode'])
|
38
38
|
@quality = args['quality'] || 'low'
|
39
39
|
source_file = source_file
|
40
40
|
base_file_name = source_file&.gsub(/.obj/, '')
|
@@ -60,7 +60,12 @@ module Glitch3d
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def infer_strategy(mode)
|
63
|
-
|
63
|
+
if !mode
|
64
|
+
mode_chosen = [ Glitch3d::Default, Glitch3d::Duplication, Glitch3d::FindAndReplace, Glitch3d::Localized, Glitch3d::None].sample
|
65
|
+
puts "Defaulting to #{mode_chosen}"
|
66
|
+
return mode_chosen
|
67
|
+
end
|
68
|
+
puts "Using #{mode}"
|
64
69
|
begin
|
65
70
|
return eval("Glitch3d::#{mode.to_s.gsub(/(?:_|^)(\w)/){$1.upcase}}")
|
66
71
|
rescue
|
@@ -5,10 +5,9 @@ SCENE.frame_end = NUMBER_OF_FRAMES
|
|
5
5
|
|
6
6
|
RADIUS=20
|
7
7
|
|
8
|
-
# Container
|
9
8
|
bpy.ops.mesh.primitive_cube_add(location=(0, 0, -0.4),radius=RADIUS)
|
10
9
|
container = last_added_object('CUBE')
|
11
|
-
container.name = '
|
10
|
+
container.name = 'fluid_container'
|
12
11
|
container.modifiers.new(name='container', type='FLUID_SIMULATION')
|
13
12
|
container.modifiers['container'].settings.type = 'DOMAIN'
|
14
13
|
container.modifiers['container'].settings.generate_particles = 1
|
@@ -16,14 +15,13 @@ container.modifiers['container'].settings.surface_subdivisions = 100
|
|
16
15
|
container.modifiers['container'].settings.viscosity_exponent = 6
|
17
16
|
container.modifiers['container'].settings.viscosity_base = 1.0
|
18
17
|
container.modifiers['container'].settings.simulation_scale = 1
|
19
|
-
|
20
18
|
container.location = (0, 0, 0)
|
21
19
|
|
22
20
|
def spawn_emitter_fuild(location, emission_vector):
|
23
21
|
bpy.ops.mesh.primitive_uv_sphere_add(location=location)
|
24
22
|
emitter = last_added_object('Sphere')
|
25
23
|
emitter.cycles_visibility.camera = False
|
26
|
-
emitter.name = 'Emitter' + str(uuid.uuid1())
|
24
|
+
emitter.name = 'Fluid Emitter' + str(uuid.uuid1())
|
27
25
|
emitter.modifiers.new(name='emitter', type='FLUID_SIMULATION')
|
28
26
|
emitter.modifiers['emitter'].settings.type = 'INFLOW'
|
29
27
|
emitter.modifiers['emitter'].settings.inflow_velocity = emission_vector
|
@@ -40,8 +38,11 @@ spawn_emitter_fuild((0,0,((RADIUS/2) - 2)),mathutils.Vector((0.5, 0.5, -2)))
|
|
40
38
|
spawn_emitter_fuild((0,3,((RADIUS/2) - 2)),mathutils.Vector((0., -0.5, -0.5)))
|
41
39
|
|
42
40
|
make_object_gradient_fabulous(container, rand_color(), rand_color())
|
41
|
+
container.modifiers.new(name='Container Subsurf', type='SUBSURF')
|
43
42
|
make_object_fluid_collider(SUBJECT)
|
44
|
-
|
43
|
+
|
44
|
+
if OCEAN:
|
45
|
+
make_object_fluid_collider(OCEAN[1])
|
45
46
|
|
46
47
|
# Bake animation
|
47
48
|
print("*** Baking commence *** (you might see a bunch of gibberish popping up cause baking is not supposed to be used headlessly")
|
@@ -41,12 +41,10 @@ make_object_gradient_fabulous(m4a1, rand_color(), rand_color())
|
|
41
41
|
# Make floor
|
42
42
|
bpy.ops.mesh.primitive_plane_add(location=(0, 0, -2))
|
43
43
|
floor = last_added_object('Plane')
|
44
|
+
floor.name = 'Floor'
|
44
45
|
floor.scale = (20,20,20)
|
45
46
|
subdivide(floor, int(random.uniform(3, 7)))
|
46
47
|
displace(floor)
|
47
|
-
texture_object(floor)
|
48
|
-
unwrap_model(floor)
|
49
|
-
bpy.data.groups['Displays'].objects.link(floor)
|
50
48
|
|
51
49
|
OCEAN = add_ocean(10, 20)
|
52
50
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# Generate a frame that you can 3D Print
|
2
|
+
# generate line -> rotate 45 degrees -> extrude -> mirror end -> cursor to center -> mirror
|
3
|
+
|
4
|
+
def spawn_frame(profile_function, length=3, side = 40):
|
5
|
+
side = 40
|
6
|
+
profile = build_segment((-side, side, 0), series, 2)
|
7
|
+
profile.name = 'Profile'
|
8
|
+
profile.rotation_euler.z -= math.radians(45)
|
9
|
+
SCENE.objects.active = profile
|
10
|
+
bpy.ops.object.editmode_toggle()
|
11
|
+
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(+side, side, 0), "constraint_axis":(True, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
|
12
|
+
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(side, -side, 0), "constraint_axis":(False, True, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
|
13
|
+
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(-side, -side, 0), "constraint_axis":(True, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
|
14
|
+
bpy.ops.mesh.extrude_region_move(MESH_OT_extrude_region={"mirror":False}, TRANSFORM_OT_translate={"value":(-side, side, 0), "constraint_axis":(False, True, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "gpencil_strokes":False, "texture_space":False, "remove_on_cancel":False, "release_confirm":False, "use_accurate":False})
|
15
|
+
bpy.ops.object.editmode_toggle()
|
16
|
+
bpy.ops.mesh.remove_doubles()
|
17
|
+
return profile
|
18
|
+
|
19
|
+
frame = spawn_frame(series(3))
|
20
|
+
assign_material(frame, random_material())
|
21
|
+
apply_displacement(frame)
|
@@ -1,49 +1,55 @@
|
|
1
1
|
# Game of life inspired scene
|
2
|
-
SIZE =
|
2
|
+
SIZE = 5
|
3
3
|
DURATION=NUMBER_OF_FRAMES
|
4
4
|
SCENE.frame_start = 0
|
5
5
|
SCENE.frame_end = DURATION
|
6
|
-
cubes =
|
6
|
+
cubes = build_composite_object('CUBE', SIZE-1, 0.5)
|
7
7
|
|
8
|
-
cells = [[ 0 for i in range(SIZE)] for j in range(SIZE)]
|
9
|
-
next_generation = [[ 0 for i in range(SIZE)] for j in range(SIZE)]
|
8
|
+
cells = [[[ 0 for i in range(SIZE)] for k in range(SIZE)] for j in range(SIZE)]
|
9
|
+
next_generation = [[[ 0 for i in range(SIZE)] for k in range(SIZE)] for j in range(SIZE)]
|
10
10
|
|
11
11
|
for x in range(SIZE):
|
12
12
|
for y in range(SIZE):
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
for z in range(SIZE):
|
14
|
+
cubes[x][y][z].scale=(.1,.1,.1)
|
15
|
+
cells[x][y][z] = random.choice(range(2))
|
16
|
+
make_object_gradient_fabulous(cubes[x][y][z], rand_color(), rand_color())
|
16
17
|
|
17
18
|
def adjust_scale():
|
18
19
|
for x in range(SIZE):
|
19
20
|
for y in range(SIZE):
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
add_frame(
|
21
|
+
for z in range(SIZE):
|
22
|
+
if cells[x][y][z] == 1 :
|
23
|
+
cubes[x][y][z].scale=(random.uniform(0.4, 0.6), random.uniform(0.4, 0.6), random.uniform(0.4, 0.6))
|
24
|
+
else:
|
25
|
+
cubes[x][y][z].scale=(.1,.1,.1)
|
26
|
+
add_frame([cubes[x][y][z]])
|
26
27
|
|
27
28
|
def life(l):
|
28
29
|
print("Life in " + str(l))
|
29
30
|
for x in range(SIZE):
|
30
31
|
for y in range(SIZE):
|
31
|
-
|
32
|
-
|
33
|
-
for
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
32
|
+
for z in range(SIZE):
|
33
|
+
neighbors_alive_count = 0
|
34
|
+
for i in range(-1,2):
|
35
|
+
for j in range(-1,2):
|
36
|
+
for k in range( -1, 2):
|
37
|
+
x_index = (x + i + SIZE) % SIZE
|
38
|
+
y_index = (y + j + SIZE) % SIZE
|
39
|
+
z_index = (z + k + SIZE) % SIZE
|
40
|
+
print("Checking: " + str((x_index, y_index, z_index)) + " for: " + str((x, y, z)))
|
41
|
+
if not( x_index == x and y_index == y and z_index == z):
|
42
|
+
neighbors_alive_count += cells[x_index][y_index][z_index]
|
43
|
+
if ( cells[x][y][z] == 1 and (neighbors_alive_count == 2 or neighbors_alive_count == 3)):
|
44
|
+
next_generation[x][y][z] = 1
|
45
|
+
elif ( cells[x][y][z] == 0 and neighbors_alive_count == 3 ):
|
46
|
+
next_generation[x][y][z] = 1
|
47
|
+
else:
|
48
|
+
next_generation[x][y][z] = 0
|
44
49
|
for x in range(SIZE):
|
45
|
-
for
|
46
|
-
|
50
|
+
for k in range(SIZE):
|
51
|
+
for y in range(SIZE):
|
52
|
+
cells[x][y][z] = next_generation[x][y][z]
|
47
53
|
adjust_scale()
|
48
54
|
|
49
55
|
print("Synthetic life begin")
|
@@ -0,0 +1,19 @@
|
|
1
|
+
def spawn_particles_system(base, object):
|
2
|
+
particles = base.modifiers.new("Particles", type='PARTICLE_SYSTEM')
|
3
|
+
settings = bpy.data.particles[-1]
|
4
|
+
settings.emit_from = 'VERT'
|
5
|
+
settings.physics_type = 'NO'
|
6
|
+
settings.count = 10000 #default 1000
|
7
|
+
settings.particle_size = 0.01
|
8
|
+
settings.render_type = 'OBJECT'
|
9
|
+
settings.dupli_object = bpy.data.objects['Cube']
|
10
|
+
settings.show_unborn = True
|
11
|
+
settings.use_dead = True
|
12
|
+
settings.size_random = 0.5
|
13
|
+
bpy.ops.object.duplicates_make_real()
|
14
|
+
|
15
|
+
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 100),radius=1)
|
16
|
+
cube = last_added_object('CUBE')
|
17
|
+
assign_material(cube, random_material(['emission']))
|
18
|
+
spawn_particles_system(SUBJECT, cube)
|
19
|
+
|
data/lib/glitch3d/bpy/helpers.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
REFLECTOR_SCALE = random.uniform(5, 8)
|
2
2
|
REFLECTOR_STRENGTH = random.uniform(10, 15)
|
3
3
|
REFLECTOR_LOCATION_PADDING = random.uniform(10, 12)
|
4
|
-
WIREFRAME_THICKNESS = random.uniform(0.
|
4
|
+
WIREFRAME_THICKNESS = random.uniform(0.0004, 0.002)
|
5
5
|
DISPLACEMENT_AMPLITUDE = random.uniform(0.02, 0.1)
|
6
6
|
REPLACE_TARGET = str(random.uniform(0, 9))
|
7
7
|
REPLACEMENT = str(random.uniform(0, 9))
|
8
8
|
ORIGIN = (0,0,2)
|
9
|
-
NUMBER_OF_FRAMES =
|
9
|
+
NUMBER_OF_FRAMES = 100
|
10
10
|
SCATTER_INTENSITY = 0.015
|
11
11
|
ABSORPTION_INTENSITY = 0.25
|
12
12
|
DISPLAY_SCALE = (2, 2, 2)
|
@@ -19,6 +19,7 @@ PINK = (0.8, 0.2, 0.7, 1.0)
|
|
19
19
|
WORDS = string.ascii_lowercase
|
20
20
|
RENDER_OUTPUT_PATHS = []
|
21
21
|
NORMALS_RENDERING = False #(random.randint(0, 1) == 1)
|
22
|
+
MATERIALS_NAMES = []
|
22
23
|
|
23
24
|
def pry():
|
24
25
|
code.interact(local=dict(globals(), **locals()))
|
@@ -28,7 +29,16 @@ def fetch_material(material_name):
|
|
28
29
|
new_material = bpy.data.materials[material_name].copy()
|
29
30
|
return new_material
|
30
31
|
|
31
|
-
|
32
|
+
def apply_displacement(obj):
|
33
|
+
subdivide(obj, 6)
|
34
|
+
subsurf = obj.modifiers.new(name='subsurf', type='SUBSURF')
|
35
|
+
subsurf.levels = 2
|
36
|
+
subsurf.render_levels = 2
|
37
|
+
displace = obj.modifiers.new(name='displace', type='DISPLACE')
|
38
|
+
new_texture = bpy.data.textures.new(name='texture', type='IMAGE')
|
39
|
+
new_texture.image = random_height_map()
|
40
|
+
displace.texture = new_texture
|
41
|
+
|
32
42
|
def look_at(obj):
|
33
43
|
location_camera = CAMERA.matrix_world.to_translation()
|
34
44
|
location_object = obj.matrix_world.to_translation()
|
@@ -98,7 +108,11 @@ def camera_location_string(camera):
|
|
98
108
|
return str(int(camera.location.x)) + ' ' + str(int(camera.location.y)) + ' ' + str(int(camera.location.z))
|
99
109
|
|
100
110
|
def assign_material(obj, material):
|
101
|
-
obj.data.materials
|
111
|
+
flush_materials(obj.data.materials)
|
112
|
+
if len(obj.data.materials) == 0:
|
113
|
+
obj.data.materials.append(material)
|
114
|
+
else:
|
115
|
+
obj.data.materials[0] = material
|
102
116
|
return material
|
103
117
|
|
104
118
|
# Returns a new Cycles material with default DiffuseBsdf node linked to output
|
@@ -114,8 +128,13 @@ def random_texture():
|
|
114
128
|
print("LOADING TEXTURE -> " + texture_path)
|
115
129
|
return bpy.data.images.load(texture_path)
|
116
130
|
|
117
|
-
def
|
118
|
-
|
131
|
+
def random_height_map():
|
132
|
+
path = HEIGHT_MAP_FOLDER_PATH + random.choice(os.listdir(HEIGHT_MAP_FOLDER_PATH))
|
133
|
+
print("LOADING HEIGHT MAP -> " + path)
|
134
|
+
return bpy.data.images.load(path)
|
135
|
+
|
136
|
+
def random_material(blacklist=[]):
|
137
|
+
return fetch_material(random.choice(MATERIALS_NAMES))
|
119
138
|
|
120
139
|
def assign_texture_to_material(material, texture):
|
121
140
|
assert material.use_nodes == True
|
@@ -166,7 +185,7 @@ def make_object_transparent(obj):
|
|
166
185
|
assign_node_to_output(material, trans)
|
167
186
|
assign_material(obj, material)
|
168
187
|
|
169
|
-
def make_object_emitter(obj, emission_strength):
|
188
|
+
def make_object_emitter(obj, emission_strength = 1):
|
170
189
|
emissive_material = assign_material(obj, fetch_material('emission'))
|
171
190
|
emission_node = emissive_material.node_tree.nodes['Emission']
|
172
191
|
emission_node.inputs[0].default_value = rand_color()
|
@@ -208,9 +227,9 @@ def random_text():
|
|
208
227
|
global WORDS
|
209
228
|
return random.choice(WORDS)
|
210
229
|
|
211
|
-
def create_mesh(name, verts, faces, location):
|
230
|
+
def create_mesh(name, verts, faces, location, edges=[]):
|
212
231
|
mesh_data = bpy.data.meshes.new("mesh_data")
|
213
|
-
mesh_data.from_pydata(verts,
|
232
|
+
mesh_data.from_pydata(verts, edges, faces)
|
214
233
|
mesh_data.update()
|
215
234
|
obj = bpy.data.objects.new(name, mesh_data)
|
216
235
|
obj.location = location
|
@@ -226,11 +245,11 @@ def spawn_text():
|
|
226
245
|
SCENE.objects.link(new_text)
|
227
246
|
return new_text
|
228
247
|
|
229
|
-
def wireframize(obj):
|
248
|
+
def wireframize(obj, emission_strength = 1):
|
230
249
|
SCENE.objects.active = obj
|
231
|
-
|
232
|
-
obj.modifiers['
|
233
|
-
make_object_emitter(obj,
|
250
|
+
obj.modifiers.new(name = 'wireframe', type='WIREFRAME')
|
251
|
+
obj.modifiers['wireframe'].thickness = WIREFRAME_THICKNESS
|
252
|
+
make_object_emitter(obj, emission_strength)
|
234
253
|
return obj
|
235
254
|
|
236
255
|
def shuffle(obj):
|
@@ -238,8 +257,8 @@ def shuffle(obj):
|
|
238
257
|
obj.scale = rand_scale_vector()
|
239
258
|
obj.rotation_euler = rand_rotation()
|
240
259
|
|
241
|
-
def series(length):
|
242
|
-
return list(map(lambda x: (0, x,
|
260
|
+
def series(length, function = math.cos):
|
261
|
+
return list(map(lambda x: (0, x, function(x)), pitched_array(0.0, length, 0.1)))
|
243
262
|
|
244
263
|
def randomize_reflectors_colors():
|
245
264
|
for r in bpy.data.groups['Reflectors'].objects:
|
@@ -330,6 +349,7 @@ def subdivide(object, cuts):
|
|
330
349
|
bpy.ops.object.mode_set(mode='EDIT')
|
331
350
|
for index in range(0, cuts):
|
332
351
|
bpy.ops.mesh.subdivide(cuts)
|
352
|
+
bpy.ops.object.editmode_toggle()
|
333
353
|
|
334
354
|
def clone(obj):
|
335
355
|
new_obj = obj.copy()
|
@@ -363,12 +383,18 @@ def flush_objects(objs = bpy.data.objects):
|
|
363
383
|
# Delete materials
|
364
384
|
def flush_materials(mats = bpy.data.materials):
|
365
385
|
for mat in mats:
|
366
|
-
|
386
|
+
if mat != None:
|
387
|
+
bpy.data.materials.remove(mat, do_unlink=True)
|
367
388
|
|
368
389
|
def flush_nodes(material):
|
369
390
|
for node in material.node_tree.nodes:
|
370
391
|
material.node_tree.nodes.remove(node)
|
371
392
|
|
393
|
+
def delete_useless_materials():
|
394
|
+
for mat in bpy.data.materials:
|
395
|
+
if mat.name.startswith('Material'):
|
396
|
+
bpy.data.materials.remove(mat, do_unlink=True)
|
397
|
+
|
372
398
|
# Rotate hue to generate palette
|
373
399
|
def adjacent_colors(r, g, b, number):
|
374
400
|
angle = (360 / 5) / 360
|
@@ -402,6 +428,13 @@ def build_pyramid(width=random.uniform(1,3), length=random.uniform(1,3), height=
|
|
402
428
|
faces.append([3,0,4])
|
403
429
|
return create_mesh('Pyramid ' + str(uuid.uuid1()), verts, faces, location)
|
404
430
|
|
431
|
+
def build_segment(location, function = series, length = 2):
|
432
|
+
verts = function(length)
|
433
|
+
edges = []
|
434
|
+
for v in range(0, (len(verts) - 1)):
|
435
|
+
edges.append([v, v+1])
|
436
|
+
return create_mesh('Segment ' + str(uuid.uuid1()), verts, [], location, edges)
|
437
|
+
|
405
438
|
def camera_path(pitch = NUMBER_OF_FRAMES):
|
406
439
|
res = []
|
407
440
|
initial_z = INITIAL_CAMERA_LOCATION[2]
|
@@ -419,16 +452,17 @@ def camera_path(pitch = NUMBER_OF_FRAMES):
|
|
419
452
|
def pitched_array(minimum, maximum, pitch):
|
420
453
|
return list(map(lambda x: (minimum + pitch * x), range(int((maximum - minimum) / pitch))))
|
421
454
|
|
422
|
-
def still_routine(index = 1):
|
423
|
-
CAMERA.location =
|
455
|
+
def still_routine(max_index, index = 1):
|
456
|
+
CAMERA.location = CAMERA_PATH[int((len(CAMERA_PATH) / max_index) * index)]
|
457
|
+
CAMERA.rotation_euler.y += math.radians(round(random.uniform(-25, +25)))
|
424
458
|
randomize_reflectors_colors()
|
425
|
-
|
459
|
+
if OCEAN:
|
460
|
+
make_object_glossy(OCEAN[0])
|
426
461
|
assign_material(SUBJECT, random_material())
|
427
462
|
rotate(SUBJECT, index)
|
428
|
-
CAMERA.rotation_euler.y += math.radians(round(random.uniform(-50, +50)))
|
429
463
|
for ocean in OCEAN:
|
430
464
|
ocean.modifiers['Ocean'].random_seed = round(random.uniform(0, 100))
|
431
|
-
ocean.modifiers['Ocean'].choppiness += random.uniform(0, 0.
|
465
|
+
ocean.modifiers['Ocean'].choppiness += random.uniform(0, 0.3)
|
432
466
|
if bpy.data.groups['Lines'].objects:
|
433
467
|
for l in bpy.data.groups['Lines'].objects:
|
434
468
|
rotation = rand_rotation()
|
@@ -447,14 +481,17 @@ def still_routine(index = 1):
|
|
447
481
|
rotate(display, index)
|
448
482
|
|
449
483
|
def animation_routine(frame):
|
450
|
-
assert len(CAMERA_PATH) >= NUMBER_OF_FRAMES
|
451
484
|
CAMERA.location = CAMERA_PATH[frame]
|
452
485
|
look_at(SUBJECT)
|
486
|
+
assign_material(SUBJECT, random_material())
|
453
487
|
randomize_reflectors_colors()
|
454
488
|
displace(SUBJECT)
|
455
489
|
for ocean in OCEAN:
|
456
490
|
ocean.modifiers['Ocean'].time += 0.5
|
457
|
-
|
491
|
+
if OCEAN:
|
492
|
+
make_object_glossy(OCEAN[0])
|
493
|
+
for particle_system in bpy.data.particles:
|
494
|
+
particle_system.phase_factor_random += 0.01
|
458
495
|
SUBJECT.rotation_euler.z += math.radians(1)
|
459
496
|
for l in bpy.data.groups['Lines'].objects:
|
460
497
|
l.rotation_euler.x += math.radians(1)
|
@@ -507,8 +544,8 @@ def make_world_volumetric(world, scatter_intensity = SCATTER_INTENSITY, absorpti
|
|
507
544
|
absorption_node.inputs['Density'].default_value = ABSORPTION_INTENSITY
|
508
545
|
bg_node.inputs[0].default_value = rand_color()
|
509
546
|
|
510
|
-
def add_frame(collection = bpy.data.objects):
|
511
|
-
for obj in collection:
|
547
|
+
def add_frame(collection = bpy.data.objects, blacklist = set([])):
|
548
|
+
for obj in set(collection) - blacklist:
|
512
549
|
obj.keyframe_insert(data_path="rotation_euler", index=-1)
|
513
550
|
obj.keyframe_insert(data_path="location", index=-1)
|
514
551
|
obj.keyframe_insert(data_path="scale", index=-1)
|
data/lib/glitch3d/bpy/main.py
CHANGED
@@ -20,7 +20,6 @@ def get_args():
|
|
20
20
|
parsed_script_args, _ = parser.parse_known_args(script_args)
|
21
21
|
return parsed_script_args
|
22
22
|
|
23
|
-
|
24
23
|
args = get_args()
|
25
24
|
file = args.file
|
26
25
|
mode = args.mode
|
@@ -49,6 +48,11 @@ load_file(os.path.join(path + '/glitch3d/bpy/helpers.py'))
|
|
49
48
|
load_file(os.path.join(path + '/glitch3d/bpy/render_settings.py'))
|
50
49
|
load_file(os.path.join(path + '/glitch3d/bpy/lighting.py'))
|
51
50
|
|
51
|
+
# Fill base materials list
|
52
|
+
for mat in bpy.data.materials:
|
53
|
+
MATERIALS_NAMES.append(mat.name)
|
54
|
+
print("Detected " + str(len(MATERIALS_NAMES)) + " materials in base scene: " + str(MATERIALS_NAMES))
|
55
|
+
|
52
56
|
# Create groups
|
53
57
|
WIREFRAMES = []
|
54
58
|
VORONOIED = []
|
@@ -67,6 +71,7 @@ CAMERA_OFFSET = 1
|
|
67
71
|
INITIAL_CAMERA_LOCATION = (CAMERA_OFFSET, CAMERA_OFFSET, 1)
|
68
72
|
FIXTURES_FOLDER_PATH = path + '/../fixtures/'
|
69
73
|
TEXTURE_FOLDER_PATH = FIXTURES_FOLDER_PATH + 'textures/'
|
74
|
+
HEIGHT_MAP_FOLDER_PATH = FIXTURES_FOLDER_PATH + 'height_maps/'
|
70
75
|
|
71
76
|
# Scene
|
72
77
|
context = bpy.context
|
@@ -100,40 +105,41 @@ SUBJECT = bpy.data.objects['0_glitch3d']
|
|
100
105
|
SUBJECT.select = True
|
101
106
|
bpy.ops.object.origin_set(type="ORIGIN_CENTER_OF_MASS")
|
102
107
|
SUBJECT.location = ORIGIN
|
103
|
-
|
104
|
-
assign_material(SUBJECT, fetch_material('magma'))
|
105
|
-
look_at(SUBJECT)
|
108
|
+
SUBJECT.modifiers.new(name='Subject Subsurf', type='SUBSURF')
|
106
109
|
let_there_be_light(SCENE)
|
107
110
|
|
108
111
|
if debug == False:
|
109
|
-
load_file(os.path.join(path + '/glitch3d/bpy/canvas', '
|
110
|
-
load_file(os.path.join(path + '/glitch3d/bpy/canvas', 'lyfe.py'))
|
112
|
+
load_file(os.path.join(path + '/glitch3d/bpy/canvas', 'particles.py'))
|
111
113
|
load_file (os.path.join(path + '/glitch3d/bpy/canvas', 'aether.py'))
|
114
|
+
load_file(os.path.join(path + '/glitch3d/bpy/canvas', 'lyfe.py'))
|
115
|
+
load_file(os.path.join(path + '/glitch3d/bpy/canvas', 'dreamatorium.py'))
|
112
116
|
|
113
117
|
print('Rendering images with resolution: ' + str(SCENE.render.resolution_x) + ' x ' + str(SCENE.render.resolution_y))
|
114
118
|
|
119
|
+
x = 0.08
|
120
|
+
while len(camera_path(x)) <= NUMBER_OF_FRAMES:
|
121
|
+
x -= 0.01
|
122
|
+
CAMERA_PATH = camera_path(x)
|
123
|
+
assert len(CAMERA_PATH) >= NUMBER_OF_FRAMES
|
124
|
+
|
115
125
|
if animate:
|
116
126
|
print('ANIMATION RENDERING BEGIN')
|
117
127
|
SCENE.frame_start = 0
|
118
128
|
SCENE.frame_end = NUMBER_OF_FRAMES
|
119
129
|
|
120
|
-
x = 0.08
|
121
|
-
while len(camera_path(x)) <= NUMBER_OF_FRAMES:
|
122
|
-
x -= 0.01
|
123
|
-
CAMERA_PATH = camera_path(x)
|
124
|
-
|
125
130
|
for frame in range(0, NUMBER_OF_FRAMES):
|
126
131
|
SCENE.frame_set(frame)
|
127
132
|
animation_routine(frame)
|
128
|
-
|
133
|
+
look_at(SUBJECT)
|
134
|
+
add_frame(bpy.data.objects, set([bpy.data.objects['fluid_container']]))
|
129
135
|
shoot(output_name(model_path))
|
130
136
|
|
131
137
|
else:
|
132
138
|
print('STILL RENDERING BEGIN')
|
133
|
-
for index in range(0,
|
139
|
+
for index in range(0, shots_number):
|
134
140
|
print("-------------------------- " + str(index) + " --------------------------")
|
135
141
|
look_at(SUBJECT)
|
136
|
-
still_routine(index)
|
142
|
+
still_routine(shots_number, index)
|
137
143
|
SCENE.frame_set(int(SCENE.frame_end/(index+1)))
|
138
144
|
shoot(output_name(model_path, index))
|
139
145
|
else:
|
@@ -147,7 +153,8 @@ print("Files rendered:")
|
|
147
153
|
for p in RENDER_OUTPUT_PATHS:
|
148
154
|
print(p)
|
149
155
|
|
150
|
-
|
151
|
-
call(["python", os.path.join(path + '/glitch3d/bpy/post-processing/
|
156
|
+
if animate == False and debug == False:
|
157
|
+
call(["python", os.path.join(path + '/glitch3d/bpy/post-processing/optimize.py')])
|
158
|
+
call(["python", os.path.join(path + '/glitch3d/bpy/post-processing/mosaic.py')])
|
152
159
|
|
153
160
|
print('FINISHED ¯\_(ツ)_/¯')
|