blender 绘制离散顶点, SMPL骨架绘制
Posted 长虹剑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了blender 绘制离散顶点, SMPL骨架绘制相关的知识,希望对你有一定的参考价值。
给定一些点,如何绘制出来,借助 blender 看下效果。纠结于 unity 还是 blender, 最终还是 blender 了。
目前还都不太满意,思路一比较靠谱,但是需要更复杂的计算 思路一,第二版,已完成,吐血制作!
文章目录
blender 一些快捷键
alt+p
运行脚本
h , alt+h
隐藏与显示
shift+c
, /
如果找不到模型,可以通过这两个快捷键,或者 视图->局部视图 来选择。
f3
可以用于查找命令
1 3 7
三视图
思路一: 绘制顶点,和边
就是用物体代表顶点和边,并添加各自的材质。 动作通过设置关键帧,其中顶点比较好办就设置一个位置就行,边的话还需要计算旋转,就是旋转到点之间的向量
第一版,只画了点
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骨架绘制的主要内容,如果未能解决你的问题,请参考以下文章