# How to set vertex weight influence for bones based on x asis?

I usually only used ".. With automatic weights" when using Armatures. Now I hit a limitation and need help.

I am modeling a book (and want to do Pages later too, which are less stiff than the book cover!)

I'd be fine with 2 lanes of bones, but many vertices bent unwanted so I added more...

But for the Pages I'd like to have 3-5 lanes to make them bend more.

As you can see, the "belt" (brown) isn't affected by the bones at all.

Which makes sense, as there is 0 weight linked from the belt to the closest bone. I tried using envelope bones and "... with envelope weights" but that's also a bit strange to work with.

I don't want to paint the weight for every bone by hand. That's a really destructive workflow. I'd rather write a python script to assign weight based on x asis (which would be enough in this case)

Is there a builtin function, or how would you approach it? Otherwise, does anyone have a script that does something simliar (to get me started)? looping over bones and setting weights?

Thanks!

edit: Here is a .blend file:

• can you upload the file? Commented Oct 14, 2022 at 13:25
• @mqbakamqbaka - I added the file Commented Oct 14, 2022 at 14:40

I wrote a script for the pages and hand-assigned some vertex groups for the book cover. Here is a comparison of problems and my solutions:

The Page Mesh

Compare the Deformation of "With Automatic Weights" vs my Scripted weights. Automatic is a bit crooked and the center bone-row leaves the mesh, because there is not enough weight assigned:

The lower side of the page is not static, see gif here: https://i.imgur.com/2fzQFOn.mp4

Lets have a look at the actual weights:

See my script below. Now, here is how I fixed the book cover and belt:

I used "[Vertex Groups] -> Remove from All" and then assigned the vertices to a single group with 100% weight to make it stiff.

Here is the before/after comparison:

Here is a video where you can see the book and the pages in action:

https://i.imgur.com/3DrMeiV.mp4

And here is my script, if anyone is interested:

import bpy
from math import sqrt, pow

# HowTo: Select Armature, then Mesh, then go to WeightPaint mode.
# Clear all Vertex Groups / create them by parenting with automatic weights/empty groups
# make sure object is scaled uniformly (1,1,1)
# Replace 'Armature.005' with your Armatures Name
# run script

# ensure we are in edit mode
bpy.ops.object.mode_set(mode="EDIT")

obj = bpy.context.edit_object
mesh = obj.data

# bpy.ops.object.mode_set(mode="OBJECT")
bpy.ops.object.mode_set(mode="WEIGHT_PAINT")

print("Working")

for i in mesh.vertices:
# obj.vertex_groups[dst_group].add([i], 1 - obj.vertex_groups[src_group].weight(i), 'REPLACE')
for group in obj.vertex_groups:
boneName = group.name
armature = bpy.data.armatures['Armature.005']
bone = armature.bones[boneName]

vertexPos = i.co # .co = coordinates aka position

center_local = (bone.head_local + bone.tail_local) / 2

ydist = abs(center_local.y - vertexPos.y)
zdist = abs(center_local.z - vertexPos.z)

zFactor = 4
yFactor = 1
weight = min((1 - zdist * zFactor), (1 - ydist * yFactor))