def main():
    # load landmarks
    face_points = np.load(
        str(Path.home() / "Downloads/celeba_3d_landmarks.npy")).astype(
            np.float32)

    # if necessary expand face coordinates to 3D
    if face_points.shape[2] == 2:
        z = np.zeros((face_points.shape[0], face_points.shape[1], 1),
                     dtype=face_points.dtype)
        face_points = np.concatenate((face_points, z), axis=-1)

    print(face_points.shape)

    # translate and scale
    scale_factor = 10
    translate_vector = (0, 0, 0)
    face_points /= scale_factor
    face_points += translate_vector

    NUM_FRAMES = len(face_points)
    FRAMES_SPACING = 20
    bpy.context.scene.frame_start = 0
    bpy.context.scene.frame_end = NUM_FRAMES * FRAMES_SPACING

    delete_all()
    #gp_layer = init_grease_pencil(clear_layer=True)

    #bpy.ops.mesh.primitive_circle_add(vertices=face_points.shape[1]) #, fill_type='NGON')
    #obj = bpy.context.active_object

    #obj = bpy.context.scene.objects['3d_face']

    obj = create_face('face', face_points[0])

    sk_basis = obj.shape_key_add(name='Basis')
    sk_basis.interpolation = 'KEY_LINEAR'
    obj.data.shape_keys.use_relative = False

    for frame in range(NUM_FRAMES):
        if frame % 100 == 0:
            print("Updating frame {}".format(frame))

        # Create new shape-key block
        block = obj.shape_key_add(
            name=str(frame), from_mix=False)  # returns a key_blocks member
        block.interpolation = 'KEY_LINEAR'
        block.value = 0

        # Update vertices position
        for (vert, co) in zip(block.data, face_points[frame]):
            vert.co = co

        # Keyframe evaluation time
        obj.data.shape_keys.eval_time = frame * 10
        obj.data.shape_keys.keyframe_insert(data_path='eval_time',
                                            frame=frame * FRAMES_SPACING)
Exemple #2
0
def animate_hexagonal_automata(p_freeze,
                               p_melt,
                               nb_frames: 10,
                               material_index=0):
    nb_rows = 100
    nb_cols = 100
    automaton = HexagonalAutomaton(nb_rows=nb_rows,
                                   nb_cols=nb_cols,
                                   p_melt=p_melt,
                                   p_freeze=p_freeze)

    # Set middle cell as the only active one
    automaton.grid = np.zeros((nb_rows, nb_cols), dtype=np.uint8)
    automaton.grid[(nb_rows // 2, nb_cols // 2)] = 1

    FRAMES_SPACING = 1
    bpy.context.scene.frame_start = 0
    bpy.context.scene.frame_end = nb_frames * FRAMES_SPACING

    gp_layer = init_grease_pencil(clear_layer=True)

    #gp_frame = gp_layer.frames.new(0)
    z = 0
    delete_all()
    for frame in range(0, nb_frames):
        if frame % 10 == 0:
            print("Frame {}".format(frame))
        #gp_frame = gp_layer.frames.copy(gp_frame)
        gp_frame = gp_layer.frames.new(frame * FRAMES_SPACING)

        # reduce reference size at each new frame
        size = 1 / (frame + 1)
        # Hexagonal shape size for grid adjustment
        hex_size = size * math.cos(math.pi / 6)
        short_size = size / 2
        #z += size/2
        z = 0
        for row in range(nb_rows):
            for col in range(nb_cols):
                if automaton.grid[row, col]:
                    # Calculate row and col position for the current cell
                    # taking into account hexagonal shape and shifting by growth
                    row_pos = (row - nb_rows // 2) * (2 * size - short_size)
                    col_pos = (col - nb_cols // 2) * (2 * hex_size) - hex_size
                    # shift even rows
                    if row % 2 == 0:
                        col_pos += hex_size

                    # Render cell
                    #automata_blender_utils.cube_generator(size, row_pos, col_pos, z)
                    #draw_cube(gp_frame, (row_pos, col_pos, z), size, material_index=material_index)
                    draw_circle(gp_frame, (row_pos, col_pos, z),
                                size,
                                6,
                                material_index=material_index)
        automaton.update()
Exemple #3
0
    def execute(self, context):
        delete_all()

        sphere_size = context.scene.SPHERE_SIZE
        volume_size = context.scene.VOLUME_SIZE

        Flock.VISIBILITY_RADIUS = context.scene.VISIBILITY_RADIUS
        Flock.CLOSENESS = context.scene.CLOSENESS
        Flock.ATTRACTOR_CONFINE = context.scene.ATTRACTOR_CONFINE

        flock = init_flock(context.scene.FLOCK_SIZE,
                           sphere_size=sphere_size,
                           seed=context.scene.SEED,
                           volume_size=volume_size)

        spirograph = Spirograph((0, 0, 0), volume_size, sphere_size,
                                sphere_size, 0,
                                (2 * math.pi) / context.scene.NUM_FRAMES)

        bpy.context.scene.frame_end = context.scene.NUM_FRAMES

        # Animate directly by looping through frames
        if compute_animation:
            for i in range(context.scene.NUM_FRAMES):
                if i % 10 == 0:
                    print("Updating frame {}".format(i))
                bpy.context.scene.frame_set(i)
                if use_grease_pencil:
                    grease_pencil_frame_handler(bpy.context.scene, flock,
                                                spirograph, context)
                else:
                    frame_handler(bpy.context.scene, flock, context)

        else:
            # Animate by adding handler to frame change
            bpy.app.handlers.frame_change_pre.clear()
            if use_grease_pencil:
                grease_pencil_frame_handler(bpy.context.scene, flock,
                                            spirograph, context)
            else:
                bpy.app.handlers.frame_change_pre.append(
                    lambda x: frame_handler(x, flock, context))

        # better to return this string when done with the execution work
        return {'FINISHED'}
Exemple #4
0
def animate_2d_automata(rule, nb_frames: 10, use_grease_pencil=True):
    nb_rows = 10
    nb_cols = 10
    gol = Automaton2D(nb_rows, nb_cols, rule, seed=11)

    FRAMES_SPACING = 1
    bpy.context.scene.frame_start = 0
    bpy.context.scene.frame_end = nb_frames * FRAMES_SPACING

    if use_grease_pencil:
        gp_layer = init_grease_pencil(clear_layer=True)
    else:
        obj_size = 0.7
        subdivisions = 2
        scale_factor = 0.2
        init_mat_color = (0.7, 0.1, 0.1)

        # obj_generator = lambda idx: automata_blender_utils.icosphere_generator(obj_size, subdivisions, idx[0], idx[1], 0)
        obj_generator = lambda idx: automata_blender_utils.cube_generator(
            obj_size, idx[0], idx[1], 0)

        obj_updater = lambda obj, grid, idx: automata_blender_utils.object_updater_hide(
            obj, grid[idx])
        # obj_updater = lambda obj, grid, idx: automata_blender_utils.object_updater_scale(obj, grid[idx],
        #                                                                                 scale_factor=scale_factor)
        # obj_updater = lambda obj, grid, idx: automata_blender_utils.object_updater_color_vector(
        # obj, grid[:, idx[0], idx[1]])

        delete_all()
        obj_grid = automata_blender_utils.create_grid(gol, obj_generator)
        # automata_blender_utils.init_materials(obj_grid, init_mat_color)

    gol.update()
    for frame in range(nb_frames):
        if use_grease_pencil:
            gp_frame = gp_layer.frames.new(frame * FRAMES_SPACING)
            for idx, val in np.ndenumerate(gol.grid):
                if val:
                    draw_square(gp_frame, (idx[0], idx[1], 0), 1)
        else:
            bpy.context.scene.frame_set(frame)
            automata_blender_utils.update_grid(obj_grid, gol, obj_updater)
        gol.update()
    if obj:
        part.settings.render_type = 'OBJECT'
        part.settings.dupli_object = obj

    return outer_circle, inner_circle, hypotrochoid


if __name__ == "__main__":
    NUM_FRAMES = 150
    NUM_FRAMES_CHANGE = 1
    bpy.context.scene.frame_end = NUM_FRAMES

    #bpy.data.objects['Camera'].location = (0, 0, 30)
    #bpy.data.objects['Camera'].rotation_euler = (0, 0, 0)

    delete_all()
    particles_obj = create_circle(1, segments=1, name='copy_particle')

    R = 5
    dist = R*3
    cols = 10
    rows = 10
    spirographs = []

    for col in range(cols):
        for row in range(rows):
            origin = (dist*col, dist*row, 0)
            spirograph = Spirograph(origin=origin, R=R, r=row/2+0.1, d=row/2+0.1, angle=0, theta=col/10+0.1)

            o_c, i_c, hyp = add_to_scene(spirograph, obj=None)
            spirograph.b_outer_circle = o_c
def main():
    NUM_FRAMES_CHANGE = 5
    NUM_FRAMES = 160
    PATH_DURATION = 100
    MIRROR_FRAME = 80
    bpy.context.scene.frame_start = 0
    bpy.context.scene.frame_end = NUM_FRAMES

    assert (NUM_FRAMES % NUM_FRAMES_CHANGE == 0)

    torus_major_segments = 70
    torus_minor_segments = 25
    torus_major_radius = 1
    torus_minor_radius = 0.25
    seed = 10
    obj_size = 0.015
    move_factor = 2

    delete_all()

    automata_blender_utils.cube_generator(obj_size, 0, 0, 0)
    cube = bpy.context.view_layer.objects.active

    print("-----------------------")
    print("Start creation process")

    # create Donut
    bpy.ops.mesh.primitive_torus_add(location=(0, 0, 0),
                                     major_radius=torus_major_radius,
                                     minor_radius=torus_minor_radius,
                                     abso_major_rad=1.,
                                     abso_minor_rad=1.,
                                     major_segments=torus_major_segments,
                                     minor_segments=torus_minor_segments)
    torus = bpy.context.view_layer.objects.active

    # duplicate object by donut faces
    cube.select = True
    torus.select = True
    bpy.ops.object.parent_set(type='VERTEX')
    bpy.context.object.dupli_type = 'FACES'
    bpy.ops.object.duplicates_make_real()

    obj_updater = lambda obj, grid, idx: object_updater_move(obj, grid[idx])

    # create GOL data
    rule_gol = {
        'neighbours_count_born': 3,
        'neighbours_maxcount_survive': 3,
        'neighbours_mincount_survive': 2,
    }
    gol = Automaton2D(nb_rows=torus_major_segments,
                      nb_cols=torus_minor_segments,
                      config=rule_gol,
                      seed=seed)
    gol.update()  # update gol to start with a cleaner grid
    gol_grid_cache = []

    # create GOL object grid by selected all previously created objects
    objs = [
        obj for name, obj in bpy.context.scene.objects.items()
        if name.startswith('Cube.')
    ]
    assert len(objs) == gol.grid.shape[0] * gol.grid.shape[1]

    #set_gol_to_glider(gol)

    # Add camera path and follow path action
    bpy.ops.curve.primitive_bezier_circle_add(radius=torus_major_radius,
                                              location=(0, 0, 0))
    cube.select = False
    torus.select = False
    bpy.data.objects['BezierCircle'].select = False
    #bpy.data.objects['BezierCircle'].data.path_duration = PATH_DURATION
    camera = bpy.data.objects['Camera']
    camera.select = True
    camera.location = (0, 0, 0)
    camera.rotation_euler = (0, 0, 0)
    camera.constraints.new(type='FOLLOW_PATH')
    follow_path = camera.constraints['Follow Path']
    follow_path.target = bpy.data.objects["BezierCircle"]
    follow_path.forward_axis = 'TRACK_NEGATIVE_Z'
    follow_path.up_axis = 'UP_Y'
    follow_path.use_curve_follow = True

    # Animate path. Doesn't seem to work because of wrong context
    #bpy.ops.constraint.followpath_path_animate(constraint="Follow Path", owner='OBJECT')

    camera.rotation_euler = (0, -0.25, 0)

    # Set objects on and off location by translating across object axes
    obj_grid = []
    trans_local_adjust = Vector((0.0, 0.0, obj_size + obj_size / 10))
    trans_local_move = Vector((0.0, 0.0, -obj_size * move_factor))
    for obj in objs:
        trans_world = obj.matrix_world.to_3x3() * trans_local_adjust
        obj.matrix_world.translation += trans_world
        original_loc = obj.location.copy()
        trans_world = obj.matrix_world.to_3x3() * trans_local_move
        obj.matrix_world.translation += trans_world
        translated_loc = obj.location.copy()
        obj_grid.append({
            'obj': obj,
            'original_loc': original_loc,
            'translated_loc': translated_loc
        })

    obj_grid = np.array(obj_grid).reshape(gol.grid.shape)

    for frame in range(0, NUM_FRAMES + 1):
        if frame % 10 == 0:
            print("Updating frame {}".format(frame))

        bpy.context.scene.frame_set(frame)
        # When reaching final frame, clear handlers
        if (frame % NUM_FRAMES_CHANGE) == 0:
            if frame < MIRROR_FRAME:
                gol_grid_cache.append(gol.grid)
            elif frame > MIRROR_FRAME:
                gol.grid = gol_grid_cache.pop()
        automata_blender_utils.update_grid(obj_grid, gol, obj_updater)
        if frame >= NUM_FRAMES:
            bpy.app.handlers.frame_change_pre.clear()
            bpy.context.scene.frame_set(0)

    print("-----------------------")