Notifications
Clear all
[Closed] Skin Weight code optimization
Page 1 / 2
Next
Nov 01, 2018 10:16 pm
This is an example of my code to rig a simple cloth to some bones. I’m looking for any tip-trick, update-upgrade to speed up or optimize my code:
delete objects
clearlistener()
(
/*############################################*/
/* Functions */
/*############################################*/
fn PrepareModifier TheModifier =
(
Obj = (refs.dependentNodes TheModifier)[1]
if isvalidnode Obj do
(
setCommandPanelTaskMode mode:#modify
classof Obj
select Obj
if modPanel.getCurrentObject() != TheModifier do modPanel.setCurrentObject TheModifier
)
)
fn GetBoneIndex SkinModifier TheBone =
(
if isvalidnode TheBone then
(
findItem (for i =1 to (skinOps.GetNumberBones SkinModifier) collect (skinOps.GetBoneName SkinModifier i 0)) TheBone.name
)
else 0
)
/*############################################*/
/* Localizing SkinOps */
/*############################################*/
local GetNumberVertices = skinOps.GetNumberVertices
local GetVertexWeightCount = skinOps.GetVertexWeightCount
local GetVertexWeight = skinOps.GetVertexWeight
local GetVertexWeightBoneID = skinOps.GetVertexWeightBoneID
local SetVertexWeights = skinOps.SetVertexWeights
local ReplaceVertexWeights = skinOps.ReplaceVertexWeights
local SelectVertices = skinOps.SelectVertices
local SelectBone = skinOps.SelectBone
fn AddBone TheSkin TheBone UpdateInteger = (skinOps.addbone TheSkin TheBone 0 ; classof (refs.dependentnodes TheSkin)[1])
local RemoveBone = skinOps.RemoveBone
local BlendSelectedBone = skinOps.blendSelected
local GetNumberBones = skinOps.GetNumberBones
local GetBoneName = skinOps.GetBoneName
/*############################################*/
/* Default Variables */
/*############################################*/
Width = 100.0
Height = 100.0
WidthSegments = 4
HeightSegments = 4
WidthDistance = Width/WidthSegments
HeightDistance = Height/HeightSegments
/*############################################*/
/* Skin Object */
/*############################################*/
Obj = Rectangle name:"Skin Object" length:Height width:Width transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [Width/2,0,Height/2]) wirecolor:blue
GarmentModifier = Garment_Maker autoMesh:true preserve:true relax:true outputType:0 figure:undefined stretchMapping:false showMesh:false showSeams:false
addmodifier Obj GarmentModifier
SkinModifier = skin()
addmodifier Obj SkinModifier
/*############################################*/
/* Bones */
/*############################################*/
BoneArray = #()
for i = 1 to WidthSegments + 1 do
(
for j = 1 to HeightSegments + 1 do
(
append BoneArray (sphere name:("Bone_"+(i as string)+"_"+(j as string)) radius:5 segments:6 pos:[(i-1)*WidthDistance,0,(j-1)*HeightDistance] wirecolor:yellow)
)
)
/*############################################*/
/* Skin */
/*############################################*/
PrepareModifier SkinModifier
for TheBone in BoneArray do AddBone SkinModifier TheBone 0
/*############################################*/
/* Skin Weights */
/*############################################*/
WDis = WidthDistance/2
HDis = HeightDistance/2
NumberVertices = GetNumberVertices SkinModifier
BonesTrueIndexes = for TheBone in BoneArray collect GetBoneIndex SkinModifier TheBone
for i = 1 to NumberVertices do
(
VertexPos = getvert Obj.mesh i * Obj.objecttransform
for BoneId = 1 to BoneArray.count do
(
TheBone = BoneArray[BoneId]
BonePos = TheBone.pos
if BonePos.x >= VertexPos.x - WDis and \
BonePos.x < VertexPos.x + WDis and \
BonePos.z >= VertexPos.z - HDis and \
BonePos.z < VertexPos.z + HDis do ReplaceVertexWeights SkinModifier i BonesTrueIndexes[BoneId] 1
)
)
/*############################################*/
/* Blend Weights */
/*############################################*/
SelectVertices SkinModifier #{1..NumberVertices}
for i = 1 to BoneArray.count do
(
SelectBone SkinModifier i
BlendSelectedBone SkinModifier
)
)
13 Replies
Nov 01, 2018 10:16 pm
Dude. Make some explanations of what it does and how you don’t like it.
Or else…
Nov 01, 2018 10:16 pm
It works too slow at hi-res meshes, I just want to optimize it as possible.
Nov 01, 2018 10:16 pm
Added a few little optimizations
Time: 0.963sec. Mem: 281152L – unoptimized
- 0.025
- 0.116
- 0.075
- 0.036
Time: 0.284sec. Mem: 167408L – optimized
delete objects
gc();t1=timestamp();hf = heapfree
(
times = [0,0,0,0]
t2 = timestamp()
fn PrepareModifier TheModifier =
(
Obj = (refs.dependentNodes TheModifier)[1]
if isvalidnode Obj do
(
setCommandPanelTaskMode mode:#modify
select Obj
if modPanel.getCurrentObject() != TheModifier do modPanel.setCurrentObject TheModifier
)
)
fn GetBoneIndex SkinModifier TheBone =
(
if isvalidnode TheBone then
(
findItem (for i=1 to (skinOps.GetNumberBones SkinModifier) collect (skinOps.GetBoneName SkinModifier i 0)) TheBone.name
)
else 0
)
/* Localizing SkinOps */
local GetNumberVertices = skinOps.GetNumberVertices
local GetVertexWeightCount = skinOps.GetVertexWeightCount
local GetVertexWeight = skinOps.GetVertexWeight
local GetVertexWeightBoneID = skinOps.GetVertexWeightBoneID
local SetVertexWeights = skinOps.SetVertexWeights
local ReplaceVertexWeights = skinOps.ReplaceVertexWeights
local SelectVertices = skinOps.SelectVertices
local SelectBone = skinOps.SelectBone
local SkinOpsAddBone = skinOps.addbone
local RemoveBone = skinOps.RemoveBone
local BlendSelectedBone = skinOps.blendSelected
local GetNumberBones = skinOps.GetNumberBones
local GetBoneName = skinOps.GetBoneName
/* Default Variables */
Width = 100.0
Height = 100.0
WidthSegments = 4
HeightSegments = 4
WidthDistance = Width/WidthSegments
HeightDistance = Height/HeightSegments
/* Skin Object */
t2 = timestamp()
Obj = Rectangle name:"Skin Object" length:Height width:Width transform:(matrix3 [1,0,0] [0,0,1] [0,-1,0] [Width/2,0,Height/2]) wirecolor:blue
GarmentModifier = Garment_Maker autoMesh:true preserve:true relax:true outputType:0 figure:undefined stretchMapping:false showMesh:false showSeams:false
addmodifier Obj GarmentModifier
SkinModifier = skin()
addmodifier Obj SkinModifier
times[1] += timeStamp() - t2
/* Bones */
t2 = timestamp()
BoneArray = #()
for i = 1 to WidthSegments + 1 do
(
for j = 1 to HeightSegments + 1 do
(
append BoneArray (sphere name:("Bone_"+(i as string)+"_"+(j as string)) radius:5 segments:6 pos:[(i-1)*WidthDistance,0,(j-1)*HeightDistance] wirecolor:yellow)
)
)
/* Skin */
PrepareModifier SkinModifier
for TheBone in BoneArray do SkinOpsAddBone SkinModifier TheBone 0
classof (refs.dependentnodes SkinModifier)[1] -- nice trick btw
times[2] += timeStamp() - t2
t2 = timestamp()
/* Skin Weights */
WDis = WidthDistance/2
HDis = HeightDistance/2
NumberVertices = GetNumberVertices SkinModifier
BonesTrueIndexes = for TheBone in BoneArray collect GetBoneIndex SkinModifier TheBone
tri = Obj.mesh
tm = Obj.objecttransform
for i = 1 to NumberVertices do
(
VertexPos = getvert tri i * tm
val = [ VertexPos.x - WDis, VertexPos.x + WDis, VertexPos.z - HDis, VertexPos.z + HDis ]
for BoneId = 1 to BoneArray.count do
(
BonePos = BoneArray[BoneId].pos
if BonePos.x >= val[1] and BonePos.x < val[2] and BonePos.z >= val[3] and BonePos.z < val[4] do
(
ReplaceVertexWeights SkinModifier i BonesTrueIndexes[BoneId] 1
)
)
)
free tri
times[3] += timeStamp() - t2
t2 = timestamp()
/* Blend Weights */
SelectVertices SkinModifier #{1..NumberVertices}
for i = 1 to BoneArray.count do
(
SelectBone SkinModifier i
BlendSelectedBone SkinModifier
)
times[4] += timeStamp() - t2
format "1. %\n2. %\n3. %\n4. %\n" (times[1]/1000 as float) (times[2]/1000 as float) (times[3]/1000 as float) (times[4]/1000 as float)
)
format "Time: %sec. Mem: %\n" ((timestamp()-t1)/1000 as float) (hf-heapfree)
this new forum text formatting is just disgusting…
1 Reply
Nov 01, 2018 10:16 pm
you can collect bone ids first and replace vertex weights for array instead of one by one. it might be faster
Nov 01, 2018 10:16 pm
for k=1 to BoneArray.count do SkinOpsAddBone SkinModifier BoneArray[k] (k/BoneArray.count)
you can put the count into variable of course
Nov 01, 2018 10:16 pm
It’s a bug I think and this should be called after AddBone , otherwise ReplaceVertexWeights doesn’t work correctly.
Page 1 / 2
Next