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 ¯\_(ツ)_/¯')
         |