各位大佬好,
我有这样一个需求:我希望读入网格。于是我采用最笨的方法,就是直接把OBJ文件的所有顶点拷贝成代码。因此我在python中定义了一个字典:
我希望这样读入
然后就得到了报错:
这是为什么呢?
版本:Win10 python==3.9 taichi==1.04
各位大佬好,
我有这样一个需求:我希望读入网格。于是我采用最笨的方法,就是直接把OBJ文件的所有顶点拷贝成代码。因此我在python中定义了一个字典:
我希望这样读入
然后就得到了报错:
这是为什么呢?
版本:Win10 python==3.9 taichi==1.04
Hi beidou,
目前看来bunnyMesh[‘verts’]应该是个list类型,而Taichi暂时不支持将Kernel外的list捕获到Kernel内部使用。
但你可以把numpy array传入Kernel来使用,比如:
import taichi as ti
import numpy as np
ti.init(arch=ti.cpu)
x = ti.field(ti.i32, shape=3)
dic = { "verts" : np.array([10, 20, 30]) }
@ti.kernel
def test(arr: ti.types.ndarray()):
for i in range(3):
x[i] = arr[i]
test(dic["verts"])
Taichi 是不能识别你的字典的,你需要把字典里面的数组都开成单独的 field,或者是 numpy array。可以参考下这个项目:
好的,谢谢
可以参考我在taichi three里的实现:
def _tri_append(faces, indices):
if len(indices) == 3:
faces.append(indices)
elif len(indices) == 4:
faces.append([indices[0], indices[1], indices[2]])
faces.append([indices[2], indices[3], indices[0]])
elif len(indices) > 4:
for n in range(1, len(indices) - 1):
faces.append([indices[0], indices[n], indices[n + 1]])
else:
assert False, len(indices)
def readobj(path, orient='xyz', scale=None, simple=False, usemtl=True, quadok=False):
v = []
vt = []
vn = []
faces = []
usemtls = []
mtllib = None
if callable(getattr(path, 'read', None)):
lines = path.readlines()
else:
with open(path, 'rb') as myfile:
lines = myfile.readlines()
# cache vertices
for line in lines:
line = line.strip()
assert isinstance(line, bytes), f'BytesIO expected! (got {type(line)})'
try:
type, fields = line.split(maxsplit=1)
fields = [float(_) for _ in fields.split()]
except ValueError:
continue
if type == b'v':
v.append(fields)
elif type == b'vt':
vt.append(fields)
elif type == b'vn':
vn.append(fields)
# cache faces
for line in lines:
line = line.strip()
try:
type, fields = line.split(maxsplit=1)
fields = fields.split()
except ValueError:
continue
if type == b'mtllib':
mtllib = fields[0]
continue
if type == b'usemtl':
usemtls.append([len(faces), fields[0]])
continue
# line looks like 'f 5/1/1 1/2/1 4/3/1'
# or 'f 314/380/494 382/400/494 388/550/494 506/551/494' for quads
if type != b'f':
continue
# a field should look like '5/1/1'
# for vertex/vertex UV coords/vertex Normal (indexes number in the list)
# the index in 'f 5/1/1 1/2/1 4/3/1' STARTS AT 1 !!!
indices = [[int(_) - 1 if _ else 0 for _ in field.split(b'/')] for field in fields]
if quadok:
faces.append(indices)
else:
_tri_append(faces, indices)
ret = {}
ret['v'] = np.array([[0, 0, 0]], dtype=np.float32) if len(v) == 0 else np.array(v, dtype=np.float32)
ret['vt'] = np.array([[0, 0]], dtype=np.float32) if len(vt) == 0 else np.array(vt, dtype=np.float32)
ret['vn'] = np.array([[0, 0, 0]], dtype=np.float32) if len(vn) == 0 else np.array(vn, dtype=np.float32)
ret['f'] = np.zeros((1, 3, 3), dtype=np.int32) if len(faces) == 0 else np.array(faces, dtype=np.int32)
if usemtl:
ret['usemtl'] = usemtls
ret['mtllib'] = mtllib
if orient is not None:
objorient(ret, orient)
if scale is not None:
if scale == 'auto':
objautoscale(ret)
else:
ret['v'] *= scale
if simple:
return ret['v'], ret['f'][:, :, 0]
return ret
总之,不要在taichi-scope里写业务逻辑,python-scope里写,读到numpy数组,之后再from_numpy导入太极field就行了。
好,谢谢啦
谢谢