2
$\begingroup$

Imagine a piece of paper and you fold it in half and then fold it again. that's what I am trying to do and cant. If I use bones the influence of the bones won't allow me to because I need 2 bones to control the same area. If I try shape keys it just deforms the mesh if I try to make it in multiple steps or does the wrong animation because it draws the shortest path instead of rotating from a point like a piece of paper would.enter image description here

$\endgroup$

1 Answer 1

3
$\begingroup$

Hinge bone armature.

In the second part of this answer I wrote a script to make an armature, can be used here

import bpy
from mathutils import Matrix, Vector
from mathutils.geometry import intersect_point_line
import bmesh
context = bpy.context

def hinge(armob, ob, pb, face):
    arm = armob.data
    # add a bone from edge center to face center
    face.select_set(True)
    edges = [(l, f) for l in face.loops for f in l.edge.link_faces if not f.select]

    for l, f in edges:
        e = l.edge
        b = arm.edit_bones.new(f"Hinge_{f.index}")
        b.parent = pb
        pt, dist = intersect_point_line(
                f.calc_center_median(),
                e.verts[1].co,
                e.verts[0].co,
                ) 
        b.head = pt
        b.tail = f.calc_center_median()
        vg = (
                ob.vertex_groups.get(b.name) or
                ob.vertex_groups.new(name=b.name)
                )
        vg.add([v.index for v in f.verts], 1, 'ADD')
        hinge(armob, ob, b, f)

def make_armature(ob, face_index):
    me = ob.data
    bm = bmesh.from_edit_mesh(me).copy()
    
    face = bm.faces.active
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.armature_add()
    arm = context.object

    mw = (
            ob.parent.matrix_world.copy() if ob.parent
            else ob.matrix_world.copy()
        )

    ob.matrix_parent_inverse.identity()
    #ob.matrix_world.identity()
    ob.parent = arm
    ob.matrix_parent_inverse = ob.matrix_world.inverted()
    ob.vertex_groups.clear()
    
    arm.matrix_world = ob.matrix_world
    bpy.ops.object.mode_set(mode='EDIT')
    b = arm.data.edit_bones[0]
    b.tail += face.calc_center_median()
    b.head += face.calc_center_median()
    hinge(arm, ob, b, face) 

    bpy.ops.object.mode_set(mode='OBJECT')  
    for pb in arm.pose.bones[1:]:

        pb.rotation_mode = 'AXIS_ANGLE'
        pb.rotation_axis_angle = (0, 1, 0, 0)
    ob.modifiers.clear() 
    mod = ob.modifiers.new(
            "Hinger",
            type='ARMATURE',
            )
    mod.object = arm 
    bpy.ops.object.mode_set(mode='POSE') 
make_armature(context.object, 0) 

With the mesh in edit mode, select one face, Run the script, creates an armature, with root bone at that face.

enter image description here

Now with the armature in pose mode Shift select the two bones going same way to fold. Can Alt change the property of one to change same property all selected. Type in 180 to fold in half.

enter image description here

Now the slightly tricky bit because the script wasn't designed to do this... Shift select the two bones going the other way. Change the axis of one by negating the X axis (1 -> -1) this will ensure both spin the same way for this fold. (Alternately one to 180 and one to -180 degrees, will do same.)

Now same as before press Alt and change the angle, and rotate to 180.

enter image description here

$\endgroup$
1
  • 2
    $\begingroup$ Holly shit this is amazing. It works so well I am about to cry. thanks, man. I had to do another fold and it worked by changing to -1 also this great!! $\endgroup$ Commented Mar 1, 2021 at 17:04

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .