Edit vertex groups during cloth simulation

Hello peeps.

I’m trying to remove some vertices from a group during a cloth simulation without interrupting the simulation.
It seems like I’m either stuck with a “context is incorrect” error or some code that interrupts the simulation.

I’m new to python so be gentle.

I know this doesn’t work but here’s essentially what I’m trying to do:

import bpy


def set_weight(scene):
    print("Frame Change", scene.frame_current)
    if scene.frame_current == 5:
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.object.vertex_group_remove_from(use_all_groups=True, use_all_verts=True)
        bpy.ops.object.mode_set(mode='OBJECT')


bpy.app.handlers.frame_change_pre.append(set_weight)

Could you explain what you’re trying to achieve in a bit more depth ?
In your code, my guess is that going to edit mode and back to object mode interrupts the simulation.
From what I understand and from the code you’ve written, you want your cloth pinned with a vertex weight group until frame 5, and pinning stops at frame 5.

Why not deactivate the pinning or change the vertex pinning group with one of the following lines ?

bpy.data.object["yourobject"].modifiers["Cloth"].settings.use_pin_cloth=False

bpy.data.object["yourobject"].modifiers["Cloth"].settings.vertex_group_mass='YourNewVertexGroup'

I’ve got a shirt collar and I’m guiding it into shape. To guide it I’ve got some pinned points and sewing springs going to those points. Once the collar is guided into shape by the points, I’m hoping to turn off the force of the pinned points so the ends of the collar can relax into a more natural position after about 10 frames. I can’t use the sewing force because I’m using a patch that removes the sewing lines after a few frames.
this function:

bpy.data.object["yourobject"].modifiers["Cloth"].settings.use_pin_cloth=False

stops the simulation.
I don’t have any idea what to do with vertex_group_mass. It’s a function that requires a string argument. I couldn’t find any documentation on it. The api documentation says it’s used for pinning but I don’t know how it’s used for pinning.

The vertex group mass is the vertex group that you apply pinning to. The string argument is simply the name of the vertex group you want the pinning to apply. If you create a vertex group with your pinned points and another empty vertex group. In the middle of the simulation, change the pinned vertex group to the empty one. That will probably interrupt the simulation as well however.

Here are a few other possibilities to solve your issue :

  • You could unpin the cloth using the use_pin_cloth code, which stops the animation and then rerun the simulation using bpy.ops.screen.animation_play() line.
  • You could play the simulation up to frame 5 (or whichever frame you want the pinning to stop) and apply the cloth modifier to your mesh (or apply it as a shape if you want to keep the original mesh for whatever reason). Then you can run the simulation again but without any pinning.
  • You can make use of the Vertex Weight Edit/Mix/Proximity modifiers which allow you to animate vertex weights over time.

These are all good thoughts. I appreciate you taking some time for feedback.
I’m keeping the option of applying the cloth and running it again as sort of a last resort.
I’ve had some success using a shape key to animate the points I’m using as targets. This doesn’t interrupt the simulation but it also doesn’t offer much flexibility.
I’m thinking about doing some fancy code to move the vertices within the mesh based on where their neighbors are. I don’t suppose you know where I could find an approach to mesh editing that wouldn’t break the simulation?
Thanks for the info on the vertex group mass. I’ll give that a shot first.

Unfortunately no… I’m afraid that doing such a thing seems near to impossible as it is due to the way simulations are processed. During cloth simulation, I believe that blender stores data for each edge such as location, length, stiffness, etc. If you start messing around with data that is then used for simulation it’ll end up in unstable results in my opinion.
To my knowledge the only way to control vertices during animation is weight groups or shape keys (hooks don’t work with cloth). Editing the mesh means going through edit mode and back to object mode, canceling the animation immediately.
So maybe modifying these dynamically without accessing the mesh as the simulation runs is the only solution…

I’m leaning more towards doing the apply cloth then starting the simulation again. If I had to I could apply the cloth and drop the physics settings and modifiers back on at any frame I wanted using a basic frame handler.

Just an FYI you can use hooks with cloth and in fact I’ve made extensive use of cloth hooks and rigid body physics to pull the cloth around. You just have to make sure your hooks are above the cloth in the modifier stack.
Given that’s the case, I might be able to extract the vertex coordinates of the ones in my pin group and use that to bring hook objects closer to the neck to get a more relaxed fit. I think I have my next approach to try at least.

Just for fun, here is a screen shot. It’s pretty good for going from a pattern to a shirt sewn together on the avatar in about 30 frames of cloth simulation.


Nice image !
Thanks you just taught me something with hooks =) I’d never tested combining them with pinning and vertex groups, kind of awesome :smiley: !
I just tested a simple code to see if you could get the vertex locations during the simulation and it turns out you can’t, the data is stored somewhere else. My guess is that the simulation runs on blender’s C/C++ kernel and not python because C/C++ computes faster, and the data simply isn’t accessible through python… quite disappointing really…

Here’s my code I tested with a simple plane with 2 pinned vertices (only 4 vertices to print out, makes it easier to read =) ), locations stay identical throughout the simulation:

import bpy


def fchange(scene):
    obj = bpy.context.active_object
    print(bpy.context.scene.frame_current)
    for v in obj.data.vertices:
        print(v.co)
        
bpy.app.handlers.frame_change_pre(fchange)

It turns out you can get the vertex coordinates of a deformed cloth mesh. You just have to pull some trickery.
This creates a temporary duplicate with the cloth applied.


import bpy

C = bpy.context
ob = C.object

print(ob.data.vertices[0].co, "- Vert 0 (original)")

me = ob.to_mesh(scene=C.scene, apply_modifiers=True, settings='PREVIEW')
print(me.vertices[0].co, " - Vert 0 (deformed/modified)")

me.transform(ob.matrix_world)
print(me.vertices[0].co, " - Vert 0 (deformed/modified, world space)")

bpy.data.meshes.remove(me)

Nice ! Does that stop the simulation anyhow ?
If it doesn’t that could do the trick with hooks, although you may need dozens of them depending on how detailed your mesh is.