Taichi读入python的字典报错?

各位大佬好,
我有这样一个需求:我希望读入网格。于是我采用最笨的方法,就是直接把OBJ文件的所有顶点拷贝成代码。因此我在python中定义了一个字典:
image

我希望这样读入
image
image

然后就得到了报错:

这是为什么呢?

版本: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"])
1 个赞

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就行了。

1 个赞

好,谢谢啦

谢谢