How to dynamically access ti.ext_arr() with taichi class(@ti.data_oriented ) as element

Say given a np.array of taichi class and a ti.Vector.field of index to the former array, I wonder how to access the array with the index?

To be more specific:

import taichi as ti
import numpy as np

ti.init(ti.cpu, debug=True)

@ti.data_oriented
class test_class:
    def __init__(self):
        pass

if __name__ == '__main__':
    int_list = [1, 2]
    int_array = np.array(int_list)

    class_list = []
    class_list.append(test_class())
    class_array = np.array(class_list)

    idx_field = ti.field(dtype=ti.int32, shape=[2])
    idx_field.fill(0)

    @ti.kernel
    def test_int_array(int_list:ti.ext_arr()):
        for I in ti.grouped(idx_field):
            print(int_list[idx_field[I]])

    @ti.kernel
    def test_class_array(class_list: ti.ext_arr()):
        for I in ti.grouped(idx_field):
            print(class_list[idx_field[I]])

    @ti.kernel
    def test_class_list():
        print(class_list[idx_field[1]])


    test_int_array(int_array) # no problem
    test_class_list() # TypeError: list indices must be integers or slices, not Expr
    test_class_array(class_array) # AssertionError: Unknown type object

In this example, I try to access with both np.array and list but neithter would make it work. So is there a typical way for this kind of problem or is there any workaround for this?

The related issue lies here and here. But I thought mine is kind of different access.

Only np.array with int or float as elements are supported.

So is there any workaround or indirect method for this if I wanna index(say index from a ti.field) the external array with self-defined class ?

No. This is impossible since arrays of object is simply impossible to be executed without Python runtime, which is required by Taichi.
What’s your test_class actually? If test_class is composed of several vectors, then you could use several vector fields instead.

In specific, it’s a collider class.

What I’m gonna do is to get the normal of the collider. So I tried to access the corresponding collider at the pixel (which is the index to the collider) and calculate its normal within the collider class.

If it’s helpful, the related code about accessing with index is here. Note that in order to pass the compilation, I only access the self.collider[0]with index 0.

Thank for the information. I see, so actually you want to have multiple colliders.

Yet the systematic solution would be make use of ts.TaichiClass, but I had a look into your code and find it would be too painful to refactor and adapt it… So here’s the ad-hoc walkaround for now:

normal = ti.Vector([0.0, 0.0, 0.0])
for i in ti.static(range(len(self.colliders))):
  if i == collid_idx:
    normal = self.colliders[i].surfaceshape.closest_normal(I)

oh ty, that works !
should have used taichi_glsl long time ago