Skip to content

Commit b3d064f

Browse files
authored
fix: give vertex-weight-limit's arm its armor pass (#83)
Round four: the shells still read as lathe pottery, the hinge cap as a flat button, the pedestal as a lampshade. Thickened every shell ~15%, swapped the round caps for hex bolt heads (6-segment cones — fasteners, not buttons, flange bolts included), cut panel-seam grooves into the upper arm and forearm so the armor reads as plates, and set the pedestal on a wide bolted flange. The hinge mechanics from the previous round are untouched: pin and caps stay with the clevis (Shoulder), knuckle rotates. pre_max=5 holds; measured values identical on 5.1.2 and 4.5.11 (verts=1768, limited=160, sum 2.98e-08, pose 2.83e-03, lbs 2.67e-07). Re-falsified: exits 4/6/8 (sums 1.616e-02, LBS dev 1.782). Claw margin verified at 100 px by posed-vertex NDC projection. Signed-off-by: fOuttaMyPaint <TMhospitalitystrategies@gmail.com>
1 parent feb907a commit b3d064f

7 files changed

Lines changed: 88 additions & 75 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ as the caught failure mode.
506506
</tr>
507507
<tr>
508508
<td width="46%" valign="middle">
509-
<a href="examples/vertex-weight-limit/"><img src="examples/vertex-weight-limit/preview.webp" alt="Vertex weight limit: a posed mech arm on a dark studio floor - orange armor shells, a glowing teal elbow bellows around the hinge pin, long plated forearm, three-finger gripper - deformed by weights pruned to the four-influence engine cap" /></a>
509+
<a href="examples/vertex-weight-limit/"><img src="examples/vertex-weight-limit/preview.webp" alt="Vertex weight limit: a posed mech arm on a dark studio floor - orange armor shells, a glowing teal flex cuff around the hex-bolted elbow hinge, long plated forearm, three-finger gripper - deformed by weights pruned to the four-influence engine cap" /></a>
510510
</td>
511511
<td valign="middle">
512512

1.11 KB
Loading
312 Bytes
Loading

docs/gallery/vertex-weight-limit/index.html

Lines changed: 41 additions & 35 deletions
Large diffs are not rendered by default.

examples/vertex-weight-limit/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Vertex Weight Limit
22

3-
A runnable example that rigs a mech arm — bolted pedestal and shoulder
4-
fairing, an upper arm ending in clevis cheeks, the elbow hinge pin and
5-
knuckle barrel capped through a ribbed flex cuff, a long plated forearm,
6-
wrist cuff and collar, and a three-finger gripper — with deliberately rich five-bone weight
7-
bumps in the bellows, then enforces the game-engine
3+
A runnable example that rigs a mech arm — flanged bolted pedestal and
4+
shoulder fairing, a panel-seamed upper arm ending in clevis cheeks, the
5+
elbow hinge pin and knuckle barrel capped with hex bolts through a ribbed
6+
flex cuff, a long seam-grooved forearm, wrist cuff and collar, and a
7+
three-finger gripper — with deliberately rich five-bone weight bumps in
8+
the cuffs, then enforces the game-engine
89
**maximum of four bone influences per vertex** through the data API, following
910
[`mesh-editing-and-bmesh`](../../skills/mesh-editing-and-bmesh/SKILL.md) and
1011
building on the linear-blend-skinning precedent of
814 Bytes
Loading

examples/vertex-weight-limit/vertex_weight_limit.py

Lines changed: 40 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ def box_part(bm, size, loc, rot, mat, part_of, bone):
8888
part_of.extend([bone] * (len(bm.verts) - n0v))
8989

9090

91-
def cone_part(bm, r1, r2, depth, loc, rot, mat, part_of, bone):
91+
def cone_part(bm, r1, r2, depth, loc, rot, mat, part_of, bone, segments=24):
9292
"""One cylinder/cone shell along a rotated axis; tags `bone` for its verts."""
9393
n0f, n0v = len(bm.faces), len(bm.verts)
9494
m = (mathutils.Matrix.Translation(loc)
9595
@ mathutils.Euler(tuple(math.radians(a) for a in rot)).to_matrix().to_4x4())
96-
bmesh.ops.create_cone(bm, cap_ends=True, cap_tris=False, segments=24,
96+
bmesh.ops.create_cone(bm, cap_ends=True, cap_tris=False, segments=segments,
9797
radius1=r1, radius2=r2, depth=depth, matrix=m)
9898
for f in bm.faces[n0f:]:
9999
f.material_index = mat
@@ -116,62 +116,68 @@ def tag(rings_verts, bone):
116116
for v in ring:
117117
part_of.append(bone)
118118

119-
# bolted pedestal + shoulder fairing (rigid on Root)
120-
tag(lathe_part(bm, [(-0.35, 0.34), (-0.05, 0.34), (0.0, 0.40),
121-
(0.06, 0.42)], GUNMETAL), "Root")
122-
tag(lathe_part(bm, [(0.02, 0.40), (0.10, 0.44), (0.22, 0.33),
123-
(0.30, 0.17), (0.34, 0.07)], GUNMETAL), "Root")
124-
for k in range(6): # the fairing's bolt ring
125-
a = 2 * math.pi * k / 6
126-
cone_part(bm, 0.05, 0.04, 0.06,
127-
(0.36 * math.cos(a), 0.36 * math.sin(a), 0.03),
128-
(0, 0, 0), GUNMETAL, part_of, "Root")
119+
# bolted pedestal + shoulder fairing on a wide flange (rigid on Root)
120+
tag(lathe_part(bm, [(-0.35, 0.38), (-0.05, 0.38), (0.0, 0.44),
121+
(0.06, 0.46)], GUNMETAL), "Root")
122+
tag(lathe_part(bm, [(0.02, 0.44), (0.10, 0.48), (0.22, 0.37),
123+
(0.30, 0.19), (0.34, 0.08)], GUNMETAL), "Root")
124+
tag(lathe_part(bm, [(-0.02, 0.50), (0.05, 0.50)], GUNMETAL), "Root")
125+
for k in range(8): # hex bolts around the flange rim
126+
a = 2 * math.pi * k / 8
127+
cone_part(bm, 0.055, 0.055, 0.07,
128+
(0.43 * math.cos(a), 0.43 * math.sin(a), 0.06),
129+
(0, 0, 0), GUNMETAL, part_of, "Root", segments=6)
129130
# upper arm shell rooted deep inside the fairing — no gap at the
130131
# shoulder when the joint articulates (rigid on Shoulder)
131-
tag(lathe_part(bm, [(0.10, 0.14), (0.30, 0.19), (0.45, 0.19),
132-
(0.60, 0.23), (0.80, 0.24), (1.00, 0.23),
133-
(1.15, 0.21)], ORANGE), "Shoulder")
132+
tag(lathe_part(bm, [(0.10, 0.16), (0.30, 0.22), (0.45, 0.22),
133+
(0.60, 0.26), (0.80, 0.26), (1.00, 0.25),
134+
(1.20, 0.24)], ORANGE), "Shoulder")
135+
# panel-seam groove on the upper arm (plate separation line)
136+
tag(lathe_part(bm, [(0.90, 0.262), (0.94, 0.262)], GUNMETAL), "Shoulder")
134137
# clevis cheek plates flanking the joint (rigid on Shoulder)
135138
for sy in (-1, 1):
136-
box_part(bm, (0.10, 0.06, 0.50), (0.0, sy * 0.175, 1.30),
139+
box_part(bm, (0.12, 0.07, 0.50), (0.0, sy * 0.19, 1.30),
137140
(0, 0, 0), ORANGE, part_of, "Shoulder")
138141
# elbow flex cuff behind the hinge: the five-influence zone the
139142
# limit prunes (every ring inside the five-bump z window)
140-
tag(lathe_part(bm, [(1.33, 0.17), (1.38, 0.19), (1.43, 0.17),
141-
(1.49, 0.19), (1.55, 0.18)], RUBBER), "FLEX")
143+
tag(lathe_part(bm, [(1.33, 0.19), (1.38, 0.21), (1.43, 0.19),
144+
(1.49, 0.21), (1.55, 0.20)], RUBBER), "FLEX")
142145
# the hinge pin stays with the clevis (Shoulder): the forearm's
143146
# knuckle barrel (Elbow) rotates around it — pin caps must not tilt
144-
cone_part(bm, 0.13, 0.13, 0.44, (0.0, 0.0, 1.35), (90, 0, 0),
147+
cone_part(bm, 0.15, 0.15, 0.50, (0.0, 0.0, 1.35), (90, 0, 0),
145148
GUNMETAL, part_of, "Shoulder")
146-
cone_part(bm, 0.165, 0.165, 0.26, (0.0, 0.0, 1.35), (90, 0, 0),
149+
cone_part(bm, 0.185, 0.185, 0.28, (0.0, 0.0, 1.35), (90, 0, 0),
147150
GUNMETAL, part_of, "Elbow")
151+
# hex bolt heads flush on the cheeks — fasteners, not buttons
148152
for sy in (-1, 1):
149-
cone_part(bm, 0.17, 0.17, 0.05, (0.0, sy * 0.225, 1.35),
150-
(90, 0, 0), GUNMETAL, part_of, "Shoulder")
153+
cone_part(bm, 0.15, 0.15, 0.06, (0.0, sy * 0.255, 1.35),
154+
(90, 0, 0), GUNMETAL, part_of, "Shoulder", segments=6)
151155
# bright seal hoop on the cuff — the accent marking the primary
152156
# pruned-weight zone
153-
tag(lathe_part(bm, [(1.42, 0.20), (1.46, 0.20)], ACCENT), "Elbow")
154-
# long plated forearm with two ridges (rigid on Elbow)
155-
tag(lathe_part(bm, [(1.55, 0.19), (1.75, 0.21), (1.80, 0.23),
156-
(1.86, 0.21), (2.05, 0.20), (2.18, 0.22),
157-
(2.24, 0.20), (2.45, 0.18)], ORANGE), "Elbow")
157+
tag(lathe_part(bm, [(1.42, 0.22), (1.46, 0.22)], ACCENT), "Elbow")
158+
# long plated forearm with panel-seam grooves (rigid on Elbow)
159+
tag(lathe_part(bm, [(1.55, 0.22), (1.75, 0.24), (1.86, 0.25),
160+
(2.05, 0.23), (2.24, 0.23), (2.45, 0.21)],
161+
ORANGE), "Elbow")
162+
tag(lathe_part(bm, [(1.88, 0.262), (1.92, 0.262)], GUNMETAL), "Elbow")
163+
tag(lathe_part(bm, [(2.26, 0.242), (2.30, 0.242)], GUNMETAL), "Elbow")
158164
# armor blade along the forearm's back (rigid on Elbow)
159-
box_part(bm, (0.10, 0.05, 0.60), (0.0, 0.235, 2.02),
165+
box_part(bm, (0.12, 0.06, 0.60), (0.0, 0.26, 2.02),
160166
(0, 0, 0), ORANGE, part_of, "Elbow")
161167
# wrist flex bellows (second blend zone) + collar
162-
tag(lathe_part(bm, [(2.45, 0.18), (2.51, 0.20), (2.57, 0.16),
163-
(2.64, 0.19), (2.70, 0.16), (2.75, 0.17)],
168+
tag(lathe_part(bm, [(2.45, 0.20), (2.51, 0.22), (2.57, 0.18),
169+
(2.64, 0.21), (2.70, 0.18), (2.75, 0.19)],
164170
RUBBER), "FLEX")
165-
tag(lathe_part(bm, [(2.75, 0.16), (2.85, 0.175), (2.90, 0.16)],
171+
tag(lathe_part(bm, [(2.75, 0.18), (2.85, 0.195), (2.90, 0.18)],
166172
GUNMETAL), "Wrist")
167173
# palm block (rigid on Wrist)
168-
box_part(bm, (0.30, 0.22, 0.24), (0.0, 0.0, 2.98),
174+
box_part(bm, (0.34, 0.25, 0.26), (0.0, 0.0, 2.98),
169175
(0, 0, 0), GUNMETAL, part_of, "Wrist")
170176
# three two-segment fingers, splayed (rigid on Claw)
171177
for a_deg in (90.0, 210.0, 330.0):
172178
a = math.radians(a_deg)
173-
for pos, tilt, size in (((0.08, 3.08), 12.0, (0.085, 0.13, 0.22)),
174-
((0.14, 3.26), 26.0, (0.07, 0.11, 0.18))):
179+
for pos, tilt, size in (((0.09, 3.08), 12.0, (0.095, 0.14, 0.22)),
180+
((0.16, 3.26), 26.0, (0.08, 0.12, 0.18))):
175181
off, z = pos
176182
m = (mathutils.Matrix.Translation((0.0, 0.0, z))
177183
@ mathutils.Matrix.Rotation(a, 4, 'Z')

0 commit comments

Comments
 (0)