예제 #1
0
def grease_pencil_frame_handler(scene, flock: Flock, spirograph: Spirograph, context):
    frame = scene.frame_current
    if frame == 0:
        for i, unit in enumerate(flock.units):
            gp_layer = init_grease_pencil(gpencil_layer_name="unit_{}".format(i),
                                          clear_layer=True)
            gp_layer.frames.new(0)
    # When reaching final frame, clear handlers
    if frame >= context.scene.NUM_FRAMES:
        bpy.app.handlers.frame_change_pre.clear()
    elif (frame % context.scene.NUM_FRAMES_CHANGE) == 0:
        flock.update()
        spirograph.update()

        # Update target location
        target = flock.attractor_obj
        target.location = spirograph.get_hypotrochoid_loc()
        target.keyframe_insert("location")
        flock.attractor_pos = np.array(target.location)

        for i, unit in enumerate(flock.units):
            gp_layer = init_grease_pencil(gpencil_layer_name="unit_{}".format(i),
                                          clear_layer=False)
            gp_frame = gp_layer.frames.copy(gp_layer.frames[-1])
            gp_frame.frame_number = frame

            p0 = unit.pos
            p1 = unit.pos + unit.vel

            draw_line(gp_frame, p0, p1, i)
예제 #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()
예제 #3
0
def sketch_rnn_draw():
    with open("/tmp/stroke.npy", 'rb') as f:
        stroke = np.load(f)[0]

    gp_layer = init_grease_pencil()
    gp_frame = gp_layer.frames.new(0)
    gp_stroke = gp_frame.strokes.new()
    gp_stroke.points.add(count=len(stroke))
    for i, point in enumerate(stroke):
        gp_stroke.points[i].co = point
예제 #4
0
def animate_1d_automata(rule, nb_frames=10, scale=1., material_index=0):
    # Init automata
    automaton_size = nb_frames * 2
    automaton = Automaton1D(automaton_size, rule=rule)

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

    bpy.context.scene.frame_start = 0
    bpy.context.scene.frame_end = nb_frames

    gpencil_obj_name = "GPencil"
    gp_layer = init_grease_pencil(clear_layer=True,
                                  gpencil_obj_name=gpencil_obj_name)
    gp_frame = gp_layer.frames.new(0)

    gpencil = bpy.context.view_layer.objects[gpencil_obj_name]

    # center on middle cell
    cell_size = 1
    translate_vec = np.array([-(automaton_size / 2), 0, 0])
    for frame in range(nb_frames):
        gp_frame = gp_layer.frames.copy(gp_frame)
        for i, cell in enumerate(automaton.grid):
            # maintain pyramid shape (render only if further from the center at least the current frame number)
            if cell and ((automaton_size // 2 - frame) <= i <=
                         (automaton_size // 2 + frame)):
                # render cell
                centers = [
                    (i, frame, 0),  # normal center
                    #(i, frame - 1, automaton_size // 2 - frame),  # center down
                    #(i, frame - 1, -(automaton_size // 2) + frame),  # center up
                ]
                for center in centers:
                    centers_shifted = np.array(center) + translate_vec
                    draw_square(gp_frame,
                                centers_shifted,
                                cell_size,
                                material_index=material_index)
                    #draw_cube(gp_frame, centers_shifted, cell_size, material_index=material_index)

        automaton.update()

    # scale automaton size along the growth axis
    if scale != 1.:
        gpencil.scale[0] = scale
        gpencil.select_set(True)
        bpy.ops.object.transform_apply(location=False,
                                       rotation=False,
                                       scale=True)
def lsystem_params_anim(layer_name='GP_layer'):
    print("###################################")

    max_depth = 4
    nb_frames = 100
    bpy.context.scene.frame_end = nb_frames

    gp_layer = init_grease_pencil(clear_layer=True,
                                  gpencil_layer_name=layer_name)

    azimuth_adds = np.linspace(-40, 40, nb_frames)
    inclination_adds = np.linspace(-20, 20, nb_frames)

    for frame in range(nb_frames):
        base_systems = [
            fractal_plant, fractal_plant_b, fractal_plant_c, fractal_plant_e,
            stochastic_plant
        ]
        base_system = base_systems[np.random.randint(0, len(base_systems))]

        system = LSystem(
            axiom=base_system.axiom,
            constants=base_system.constants,
            rules=base_system.rules,
            rules_probs=base_system.rules_probs,
            render_config={
                'azimuth_add':
                azimuth_adds[np.random.randint(len(azimuth_adds))],  #20.,
                'inclination_add':
                inclination_adds[np.random.randint(
                    len(inclination_adds))],  #0.,
            })

        print("###################")
        print(
            f"azimuth_add {system.azimuth_add}, inclination_add {system.inclination_add}"
        )

        for i in range(max_depth):
            if i % 1 == 0:
                print(f"Depth {i}")
            system.rewrite()
        gp_frame = gp_layer.frames.new(frame)
        render(system.current_state.copy(),
               lambda x, y, context: draw(x, y, gp_layer, context),
               azimuth_add=system.azimuth_add,
               inclination_add=system.inclination_add,
               inclination=3.7,
               pos=(0, 0, 0),
               line_length=1.)
def lsystem_grid(layer_name='GP_layer'):
    print("###################################")

    max_depth = 4
    bpy.context.scene.frame_end = 100

    SPACING_FACTOR = 20
    NB_ROWS = 10
    NB_COLS = 8

    gp_layer = init_grease_pencil(clear_layer=True,
                                  gpencil_layer_name=layer_name)
    gp_frame = gp_layer.frames.new(0)

    azimuth_adds = np.linspace(5, 70, NB_ROWS)
    inclination_adds = np.linspace(-20, 20, NB_COLS)

    for row in range(NB_ROWS):
        for col in range(NB_COLS):
            base_lsystem = LSystem(axiom=['X'],
                                   constants=['-', '+', '[', ']'],
                                   rules={
                                       'X': 'F+[[X]-X]-F[-FX]+X',
                                       'F': 'FF',
                                   },
                                   render_config={
                                       'azimuth_add': azimuth_adds[row],
                                       'inclination_add':
                                       inclination_adds[col],
                                   })

            print("###################")
            print(f"row {row}, col {col}")
            print(
                f"azimuth_add {base_lsystem.azimuth_add}, inclination_add {base_lsystem.inclination_add}"
            )
            #print("n={}, alpha={}".format(max_depth, system.render_config['azimuth_add']))
            #print("{}".format(system.axiom))
            #print("{}".format(system.rules))
            for i in range(max_depth):
                if i % 1 == 0:
                    print(f"Depth {i}")
                base_lsystem.rewrite()
            render(base_lsystem.current_state.copy(),
                   lambda x, y, context: draw(x, y, gp_layer, context),
                   azimuth_add=base_lsystem.azimuth_add,
                   inclination_add=base_lsystem.inclination_add,
                   inclination=3.7,
                   pos=(row * SPACING_FACTOR, col * SPACING_FACTOR, 0),
                   line_length=.5)
예제 #7
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()
def animate_lsystem(system: LSystem,
                    max_depth: int,
                    pos=(0, 0, 0),
                    layer_name='GP_layer'):
    gp_layer = init_grease_pencil(clear_layer=True,
                                  gpencil_layer_name=layer_name)
    print("###################")
    print(f"{layer_name}")
    print("n={}, alpha={}".format(max_depth,
                                  system.render_config['azimuth_add']))
    print(system.axiom)
    print(system.rules)
    for i in range(max_depth):
        if i % 1 == 0:
            print(f"Depth {i}")
        gp_frame = gp_layer.frames.new(i)
        system.rewrite()  # notice we skip rendering axioms state
        render(system.current_state.copy(),
               lambda x, y, context: draw(x, y, gp_layer, context),
               azimuth_add=system.azimuth_add,
               inclination_add=system.inclination_add,
               inclination=4.,
               pos=(0, 0, 0),
               line_length=1.)