|
6 | 6 | import enum |
7 | 7 | import math |
8 | 8 |
|
| 9 | +import numpy as np |
| 10 | + |
9 | 11 | from .mat4 import Mat4 |
10 | 12 |
|
11 | 13 |
|
@@ -214,3 +216,53 @@ def renderman_look_at(eye, look, up): |
214 | 216 | result.m[3][2] = -eye.dot(n) |
215 | 217 |
|
216 | 218 | return result |
| 219 | + |
| 220 | + |
| 221 | +def prim_data_to_ri_points_polygons(triangles: np.ndarray): |
| 222 | + """ |
| 223 | + Convert a packed numpy array of triangles to RenderMan PointsPolygons format. |
| 224 | + This is designed to work with the PrimData class outputs. |
| 225 | + Parameters |
| 226 | + ---------- |
| 227 | + triangles : np.ndarray |
| 228 | + Array of shape (n_vertices, 8) where each row is: x, y, z, nx, ny, nz, u, v |
| 229 | + n_vertices must be divisible by 3 (since we have triangles) |
| 230 | +
|
| 231 | + Returns |
| 232 | + ------- |
| 233 | + tuple |
| 234 | + (nvertices, vertices, parameterlist) |
| 235 | + - nvertices: list of vertex counts per polygon (all 3 for triangles) |
| 236 | + - vertices: flat list of vertex indices |
| 237 | + - parameterlist: dict with 'P', 'N', 'st' arrays for RenderMan |
| 238 | + """ |
| 239 | + # Ensure it's a 2D array |
| 240 | + if triangles.ndim == 1: |
| 241 | + # If completely flat, reshape to (n_verts, 8) |
| 242 | + if len(triangles) % 8 != 0: |
| 243 | + raise ValueError("1D array length must be divisible by 8") |
| 244 | + triangles = triangles.reshape(-1, 8) |
| 245 | + |
| 246 | + n_verts = triangles.shape[0] |
| 247 | + if n_verts % 3 != 0: |
| 248 | + raise ValueError("Number of vertices must be divisible by 3") |
| 249 | + |
| 250 | + n_triangles = n_verts // 3 |
| 251 | + |
| 252 | + # Extract components from each row |
| 253 | + positions = triangles[:, 0:3] # (n_verts, 3) - x, y, z |
| 254 | + normals = triangles[:, 3:6] # (n_verts, 3) - nx, ny, nz |
| 255 | + uvs = triangles[:, 6:8] # (n_verts, 2) - u, v |
| 256 | + |
| 257 | + # RenderMan PointsPolygons format |
| 258 | + nvertices = [3] * n_triangles # Each polygon has 3 vertices |
| 259 | + vertices = list(range(n_verts)) # Sequential vertex indices |
| 260 | + |
| 261 | + # Parameter list - flatten to 1D arrays as RenderMan expects |
| 262 | + parameterlist = { |
| 263 | + "P": positions.flatten().tolist(), # Position |
| 264 | + "N": normals.flatten().tolist(), # Normals |
| 265 | + "st": uvs.flatten().tolist(), # Texture coordinates |
| 266 | + } |
| 267 | + |
| 268 | + return nvertices, vertices, parameterlist |
0 commit comments