In the future, it would be best to add a .blend file or to be more specific about your objectives. In lieu of this, here is a quick script that does folding and then unfolding of cloth. Hopefully you can build upon this for your own needs. I am using Blender 2.82a. Quick summary of the script:
- Removes starting cube and creates a supporting plane to go under the cloth.
- Creates the cloth via a plane and subdividing, and adds cloth modifier.
- Creates an armature, and assigns a vertex group to a designated index. (Unfortunately, finding desired vertex indices is sometimes challenging, and to start I refer you to this question. The code is also somewhat delicate in that re-arranging some of the lines of code will lead to undesired results even if it seems harmless.)
- Assigns keyframes to the armature so that it will make a fold, and then an unfold because why not?
The script:
import bpy
from mathutils import Vector
def clear_scene():
# Get rid of the starting cube..
bpy.ops.object.select_all(action='DESELECT')
bpy.data.objects['Cube'].select_set(True)
bpy.ops.object.delete()
def make_supporting_plane():
# Make an underlying plane to support cloth, with high cloth_friction.
bpy.ops.mesh.primitive_plane_add(size=6, location=(0, 0, 0))
#bpy.ops.transform.resize(value=(6.0, 6.0, 6.0))
bpy.ops.object.modifier_add(type='COLLISION')
bpy.context.object.collision.cloth_friction = 50
def make_cloth_and_arm():
# Add the cloth. Tune the number of cuts for cloth detail.
bpy.ops.mesh.primitive_plane_add(size=3, location=(0, 0, 0.1))
bpy.ops.object.editmode_toggle()
bpy.ops.mesh.subdivide(number_cuts=20)
bpy.ops.object.editmode_toggle()
bpy.ops.object.modifier_add(type='CLOTH')
# Turn on collisions an increase the quality of the steps.
cloth = bpy.data.objects["Plane.001"]
cloth.modifiers["Cloth"].settings.quality = 10
cloth.modifiers["Cloth"].collision_settings.collision_quality = 5
cloth.modifiers["Cloth"].collision_settings.use_self_collision = True
# Add armature, and make it the parent of the cloth. Creating the
# armature 'deselects' cloth, so re-select cloth (in addition to armature).
bpy.ops.object.armature_add(enter_editmode=False, location=(0, 0, 0))
arm = bpy.context.object
cloth.select_set(True)
# The arm must be the active object if it is the parent (else it's the child).
bpy.context.view_layer.objects.active = arm
bpy.ops.object.parent_set(type='ARMATURE_NAME')
# Hard-code a vertex index to see which ones to pin. Look in edit mode.
bpy.ops.object.select_all(action='DESELECT')
bpy.context.view_layer.objects.active = cloth
vertices_to_pin = [1]
cloth_vgroup = cloth.vertex_groups.new(name='Pinned')
cloth_vgroup.add(vertices_to_pin, 1.0, 'ADD')
cloth.modifiers["Cloth"].settings.vertex_group_mass = cloth_vgroup.name
# The modifier must be at the TOP of the modifier stack (over cloth)!
for _ in range(3):
bpy.ops.object.modifier_move_up(modifier="Armature")
# Need this to make armature move the vertices. But I'm not sure why it works. :)
arm_group = bpy.context.object.vertex_groups["Bone"]
arm_group.add(vertices_to_pin, 1.0, 'ADD')
return (cloth, arm)
def animate(cloth, arm):
# Select items, enter Pose mode.
arm.select_set(True)
bpy.context.view_layer.objects.active = arm
bpy.ops.object.posemode_toggle()
# Adjust keyframes of armature, which will move it along with cloth vertices.
frames = [0, 30, 90, 120, 130, 160, 220, 250]
bone = arm.pose.bones['Bone']
bone.keyframe_insert("location", frame=frames[0])
bone.location += Vector((0, 1, 0))
bone.keyframe_insert("location", frame=frames[1])
bone.location += Vector((-2, 0, -2))
bone.keyframe_insert("location", frame=frames[2])
bone.location += Vector((0, -1, 0))
bone.keyframe_insert("location", frame=frames[3])
bone.keyframe_insert("location", frame=frames[4]) # pause 10 frames
bone.location += Vector((0, 1, 0))
bone.keyframe_insert("location", frame=frames[5])
bone.location += Vector((2, 0, 2))
bone.keyframe_insert("location", frame=frames[6])
bone.location += Vector((0, -1, 0))
bone.keyframe_insert("location", frame=frames[7])
# Back to Object mode.
bpy.ops.object.posemode_toggle()
if name == 'main':
clear_scene()
make_supporting_plane()
cloth, arm = make_cloth_and_arm()
animate(cloth, arm)
If the script is in test.py, then run blender -P test.py from the command line. Upon opening Blender, I click the cloth and bake the simulation. Then, I click "play," I see this in my screen recording:

Hope this helps!