Как векторизовать приведение лучей с помощью 3D сетки точек? - PullRequest
0 голосов
/ 19 октября 2019

Я работаю с алгоритмом функции расстояния со знаком, где я подаю его в качестве ввода массива координатных точек трехмерной сетки (скажем, [32768, 3] для сетки 32x32x32), и он выводит значение расстояния со знаком в каждом изэти точки, имеющие форму [32768]. Этот вывод затем возвращается в исходную форму сетки 32x32x32. Затем я использую эту сетку, чтобы выполнить приведение лучей, чтобы создать изображение силуэта фигуры, содержащейся в ней.

Чтобы выполнить упрощенное приведение лучей, в данный момент я выбираю одно измерение, чтобы прорезать (например, третье измерение z), а затем я зацикливаюсь на каждой точке x и y и выполняю приведениелуч, чтобы увидеть, попадает ли он на поверхность (когда значение расстояния со знаком становится отрицательным).

# 32x32x32 grid containing SDF values at each point on grid
sdf_values = np.load('sdf_values_32.npy')

# 2D silhouette output from ray casting
silhouette = np.zeros((sdf_values.shape[0], sdf_values.shape[1]))

# Obtain a pixel value for each pixel of silhouette by casting 
# a ray from it
# Max number of steps for ray to travel
max_steps = sdf_values.shape[0]
# Which dimension we're casting ray through, 0 = x, 1 = y, 2 = z
slice_dim = 'z' 
for row in range(silhouette.shape[0]):
    for col in range(silhouette.shape[1]):
        # Starting position
        pos_x = col
        pos_y = row

        # Tracing loop
        for i in range(max_steps):
            # Get current location of ray based on which dimension we're slicing through
            if slice_dim == 'x':
                sample_point_location = np.array([i, pos_y, pos_x])
            elif slice_dim == 'y':
                sample_point_location = np.array([pos_y, i, pos_x])
            elif slice_dim == 'z':
                sample_point_location = np.array([pos_y, pos_x, i])
            else:
                print('Incorrect dimension selected!')

            # Get distance to closest shape
            dist = sdf_values[sample_point_location[0], sample_point_location[1], sample_point_location[2]]

            # If distance < 0 then we're inside shape
            if dist < 0:
                silhouette[pos_y, pos_x] = dist

                break

Однако, как вы можете видеть, это включает в себя много итераций точка за точкой по измерению с использованием нескольких циклов. Есть ли способ векторизовать вещи, чтобы сделать это быстрее и эффективнее?

Спасибо!

...