powroupi / blender_mmd_tools

mmd_tools is a blender addon for importing Models and Motions of MikuMikuDance.
GNU General Public License v3.0
1.83k stars 277 forks source link

After I bind SDEF some part stay still in blender 2.8 #238

Closed qsqsaaw closed 4 years ago

qsqsaaw commented 5 years ago

After I bind SDEF ,the part that covered by mask (e.g.pigtail)doesn't move in render result. (Mesh doesn't defom with bone moving.)

nagadomi commented 5 years ago

@powroupi I will send PR for this issue.

driver issue

SDEF driver is not linked to the armature, so driver_function is not called for bone deformation. The solution is to add a dummy variable referencing the armature to the driver.

normal mode and skip=True does not work on 2.8

I don't know why. However, it works with skip = False or bulk mode. It seems that shape key data is broken when active_shape_key_index is updated or rendering.

powroupi commented 5 years ago

Yeah, I'm aware of this issue. That's because current method is designed for Blender 2.7x. Blender 2.8 use new dependency graph and I am still figuring out how it works. :cry:

There might be an issue that SDEF could delay 1 frame, not sure if bone.matrix is evaluated and updated before executing driver function or not. :confusing:

qsqsaaw commented 5 years ago

@powroupi I will send PR for this issue.

driver issue

SDEF driver is not linked to the armature, so driver_function is not called for bone deformation. The solution is to add a dummy variable referencing the armature to the driver.

normal mode and skip=True does not work on 2.8

I don't know why. However, it works with skip = False or bulk mode. It seems that shape key data is broken when active_shape_key_index is updated or rendering.

The option doesn't work in render animation result.It's only works in viewport.

nagadomi commented 5 years ago

It seems that bone.matrix is not updated at animation rendering time. However, when bpy.context.evaluated_depsgraph_get () is called from the driver, Blender freezes. I don't know how to fix this for now.

nagadomi commented 5 years ago

Workaround: It works when rendering every frame from the script.

render_script.py

import bpy
import os

OUTPUT_DIR="/tmp/sdef"
FRAME_START=1
FRAME_END=3

os.makedirs(OUTPUT_DIR, exist_ok=True)
scene = bpy.context.scene
for frame_no in range(FRAME_START, FRAME_END+1):
    scene.frame_set(frame_no)
    scene.render.filepath = os.path.join(OUTPUT_DIR, "%06d.png" % frame_no)
    bpy.ops.render.render( write_still=True)
    print("render %d" % frame_no)

run with input_file=./test/sdef28.blend, script=./test/render_script.py

blender -b ./test/sdef28.blend -P ./test/render_script.py
qsqsaaw commented 5 years ago

Workaround: It works when rendering every frame from the script.

render_script.py

import bpy
import os

OUTPUT_DIR="/tmp/sdef"
FRAME_START=1
FRAME_END=3

os.makedirs(OUTPUT_DIR, exist_ok=True)
scene = bpy.context.scene
for frame_no in range(FRAME_START, FRAME_END+1):
    scene.frame_set(frame_no)
    scene.render.filepath = os.path.join(OUTPUT_DIR, "%06d.png" % frame_no)
    bpy.ops.render.render( write_still=True)
    print("render %d" % frame_no)

run with input_file=./test/sdef28.blend, script=./test/render_script.py

blender -b ./test/sdef28.blend -P ./test/render_script.py

This script is good.Thank you.

powroupi commented 4 years ago

Okay, finally, I think this issue is fixed now. It's working fine in both viewport and render from my test. You might update your mmd_tools and test it again. Thank you. :smile:

nagadomi commented 4 years ago

@powroupi I was writing an error report, but it was fixed in https://github.com/powroupi/blender_mmd_tools/commit/8d4579eed0b858860e3c1ad5c14560cdf9c4b413 :sweat: It works. Thank you :smile:

Edit:

TODO basically we can not cache any bone reference

This is a patch I wrote for the previous version. This worked as well. maybe obj and obj.original have different vertex_groups index order?

diff --git a/mmd_tools/core/sdef.py b/mmd_tools/core/sdef.py
index bc91ddb..6779791 100644
--- a/mmd_tools/core/sdef.py
+++ b/mmd_tools/core/sdef.py
@@ -81,12 +81,13 @@ class FnSDEF():
             return {}

         vertices = {}
+        obj = getattr(obj, 'original', obj)
         pose_bones = obj.modifiers.get('mmd_bone_order_override').object.pose.bones
         bone_map = {g.index:pose_bones[g.name] for g in obj.vertex_groups if g.name in pose_bones}
         sdef_c = obj.data.shape_keys.key_blocks['mmd_sdef_c'].data
         sdef_r0 = obj.data.shape_keys.key_blocks['mmd_sdef_r0'].data
         sdef_r1 = obj.data.shape_keys.key_blocks['mmd_sdef_r1'].data
-        vd = getattr(obj, 'original', obj).data.vertices
+        vd = obj.data.vertices

         for i in range(len(sdef_c)):
             if vd[i].co != sdef_c[i].co:

Edit: The above patch may delay drawing in the viewport. Your patch looks better.