blender 绘制离散顶点, SMPL骨架绘制

Posted 长虹剑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了blender 绘制离散顶点, SMPL骨架绘制相关的知识,希望对你有一定的参考价值。

给定一些点,如何绘制出来,借助 blender 看下效果。纠结于 unity 还是 blender, 最终还是 blender 了。

目前还都不太满意,思路一比较靠谱,但是需要更复杂的计算 思路一,第二版,已完成,吐血制作!

文章目录

blender 一些快捷键

alt+p 运行脚本
h , alt+h 隐藏与显示

shift+c , / 如果找不到模型,可以通过这两个快捷键,或者 视图->局部视图 来选择。
f3 可以用于查找命令

1 3 7 三视图

blender 急救箱

思路一: 绘制顶点,和边

就是用物体代表顶点和边,并添加各自的材质。 动作通过设置关键帧,其中顶点比较好办就设置一个位置就行,边的话还需要计算旋转,就是旋转到点之间的向量

第一版,只画了点

import numpy as np
import os
import bpy

# short-key alt+p

from bpy import context
import builtins as __builtin__

def console_print(*args, **kwargs):
    for a in context.screen.areas:
        if a.type == 'CONSOLE':
            c = 
            c['area'] = a
            c['space_data'] = a.spaces.active
            c['region'] = a.regions[-1]
            c['window'] = context.window
            c['screen'] = context.screen
            s = " ".join([str(arg) for arg in args])
            for line in s.split("\\n"):
                bpy.ops.console.scrollback_append(c, text=line)

def print(*args, **kwargs):
    """Console print() function."""

    console_print(*args, **kwargs) # to py consoles
    __builtin__.print(*args, **kwargs) # to system console


this_file="D:/myprog/2021-10-25-dance/7.show_points/tmp/draw_by_blender.py"


os.chdir( os.path.dirname(os.path.realpath(this_file)) )


#basic info about limb composition
joint_relationship18 = [
    [1, 2], [1, 5], [2, 3], [3, 4], [5, 6], [6, 7], [1, 8], [8, 9], [9, 10],
    [1, 11], [11, 12], [12, 13], [1, 0], [0, 14], [14, 16], [0, 15], [15, 17],
    [2, 16], [5, 17]]
joint_relationship24 = [
    [0,1],[1,4],[4,7],[7,10],[0,2],[2,5],[5,8],[8,11],[0,3],[3,6],[6,9],[9,12],[12,15],
    [13,16],[16,18],[18,20],[20,22],[9,14],[14,17],[17,19],[19,21],[21,23]
]

#for plot usage
colors_18 = [
    [255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0],
    [85, 255, 0], [0, 255, 0], [0, 255, 85], [0, 255, 170], [0, 255, 255],
    [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], [170, 0, 255],
    [255, 0, 255], [255, 0, 170], [255, 0, 85]]


joint_relationship = joint_relationship24

j3d=np.load("joint3d.npy")[:100] * 10
bpy.context.scene.render.fps = 60

print(j3d.shape)

# https://github.com/Apress/blender-python-api/blob/master/ch03_code/3-4.py
# https://blender.stackexchange.com/questions/134826/how-do-you-specify-the-name-of-a-primitive-created-via-the-python-api
# https://danielhnyk.cz/creating-animation-blender-using-python/


# Must start in object mode

print( len( bpy.data.objects) )
if len(bpy.data.objects) > 0:
    #bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete()

#bpy.ops.wm.open_mainfile(filepath=bpy.data.filepath)

#for obj in bpy.context.scene.objects:
#     if obj.type == 'MESH':
#         obj.select = True
#     else:
#         obj.select = False
#bpy.ops.object.delete()

#print(111)
for m in bpy.data.materials:
    bpy.data.materials.remove(m)

obj_scale = 0.5 
for i in range(24):
    bpy.ops.mesh.primitive_cube_add(location=(i,i,i), size=obj_scale )
    bpy.context.active_object.name = f'Jointi'
    object = bpy.data.objects.get( f'Jointi' )
    mat = bpy.data.materials.new(f'Jmati')
    
    r, g, b = colors_18[ i%18 ][::-1]
    mat.diffuse_color = ( r/255, g/255, b/255, 1 )
    #bpy.data.materials[f'Jmati'].node_tree.nodes["Principled BSDF"].inputs[0].default_value=(r/255, g/255, b/255, 1)
    object.data.materials.append(mat)


# drop
'''
for i, rel in enumerate( joint_relationship ):
    bpy.ops.mesh.primitive_cylinder_add(radius=1, depth=2, enter_editmode=False, align='WORLD', location=(0, 0, 0), scale=(obj_scale, obj_scale, obj_scale))
    bpy.context.active_object.name = f'JRi'
    object = bpy.data.objects.get( f'JRi' )
    mat = bpy.data.materials.new(f'JRmati')
    
    r, g, b = colors_18[ i%18 ][::-1]
    mat.diffuse_color = ( r/255, g/255, b/255, 1 )
    object.data.materials.append(mat)
'''   
    
FPS=60
for rcnt, frame in enumerate( j3d ):
    frame=frame.reshape(24, 3)
    for i in range(24):
        joint = bpy.data.objects.get( f'Jointi' )
        joint.location = frame[i]
        joint.keyframe_insert(data_path="location", frame=rcnt)

#joint = bpy.data.objects.get( f'Joint0' )
#bpy.context.scene.objects.active = joint


bpy.context.scene.frame_current = 1
bpy.context.scene.frame_end = len(j3d)
        

效果

第二版,最终版

#from _chj.comm.pic import *
import numpy as np
import os
import bpy
from scipy.spatial.transform import Rotation as sciR
# short-key alt+p
from mathutils import Euler

from bpy import context
import builtins as __builtin__

def console_print(*args, **kwargs):
    for a in context.screen.areas:
        if a.type == 'CONSOLE':
            c = 
            c['area'] = a
            c['space_data'] = a.spaces.active
            c['region'] = a.regions[-1]
            c['window'] = context.window
            c['screen'] = context.screen
            s = " ".join([str(arg) for arg in args])
            for line in s.split("\\n"):
                bpy.ops.console.scrollback_append(c, text=line)

def print(*args, **kwargs):
    """Console print() function."""

    console_print(*args, **kwargs) # to py consoles
    __builtin__.print(*args, **kwargs) # to system console


def rotation_matrix_from_vectors(vec1, vec2):
    """ Find the rotation matrix that aligns vec1 to vec2
    :param vec1: A 3d "source" vector
    :param vec2: A 3d "destination" vector
    :return mat: A transform matrix (3x3) which when applied to vec1, aligns it with vec2.
    """
    a, b = (vec1 / np.linalg.norm(vec1)).reshape(3), (vec2 / np.linalg.norm(vec2)).reshape(3)
    v = np.cross(a, b)
    if any(v):  # if not all zeros then
        c = np.dot(a, b)
        s = np.linalg.norm(v)
        kmat = np.array([[0, -v[2], v[1]], [v[2], 0, -v[0]], [-v[1], v[0], 0]])
        return np.eye(3) + kmat + kmat.dot(kmat) * ((1 - c) / (s ** 2))

    else:
        return np.eye(3)  # cross of all zeros only occurs on identical directions

this_file="D:/myprog/2021-10-25-dance/7.show_points/tmp/draw_by_blender.py"


os.chdir( os.path.dirname(os.path.realpath(this_file)) )


#basic info about limb composition
joint_relationship18 = [
    [1, 2], [1, 5], [2, 3], [3, 4], [5, 6], [6, 7], [1, 8], [8, 9], [9, 10],
    [1, 11], [11, 12], [12, 13], [1, 0], [0, 14], [14, 16], [0, 15], [15, 17],
    [2, 16], [5, 17]]
joint_relationship24 = [
    [0,1],[1,4],[4,7],[7,10],[0,2],[2,5],[5,8],[8,11],[0,3],[3,6],[6,9],[9,12],[12,15],
    [9,13],[13,16],[16,18],[18,20],[20,22],[9,14],[14,17],[17,19],[19,21],[21,23]
]

#for plot usage
colors_18 = [
    [255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255, 0], [170, 255, 0],
    [85, 255, 0], [0, 255, 0], [0, 255, 85], [0, 255, 170], [0, 255, 255],
    [0, 170, 255], [0, 85, 255], [0, 0, 255], [85, 0, 255], [170, 0, 255],
    [255, 0, 255], [255, 0, 170], [255, 0, 85]]


joint_relationship = joint_relationship24

cord_cvt = sciR.from_rotvec( np.array([1, 0, 0])*np.deg2rad(90) ).as_matrix()
j3d=np.load("joint3d.npy")[1400:1500] * 5
j3d = np.einsum( "cd,bjd->bjc", cord_cvt, j3d.reshape(-1, 24, 3) )
j3d -= j3d[:1, :1].copy()


bpy.context.scene.render.fps = 60

print(j3d.shape)

# https://github.com/Apress/blender-python-api/blob/master/ch03_code/3-4.py
# https://blender.stackexchange.com/questions/134826/how-do-you-specify-the-name-of-a-primitive-created-via-the-python-api
# https://danielhnyk.cz/creating-animation-blender-using-python/


# Must start in object mode

print( len( bpy.data.objects以上是关于blender 绘制离散顶点, SMPL骨架绘制的主要内容,如果未能解决你的问题,请参考以下文章

blender 绘制离散顶点, SMPL骨架绘制

blender 绘制离散顶点, SMPL骨架绘制

blender中焊接顶点的方法

blender怎么合并顶点?求教程谢谢

blender中在网格两个顶点间加线的几种方法

blender中顶点吸附对齐的几点操作细节