MCPcopy Create free account
hub / github.com/apple/ml-pointersect / interp_surface_normal_from_ray_tracing_results

Function interp_surface_normal_from_ray_tracing_results

plib/render.py:182–222  ·  view source on GitHub ↗

Interpolate the surface normal of the intersection points using surface normal on the vertices. Args: mesh: raycast_results: the output of ray casting of o3d Returns: (*, 3) surface normal. Note that it fills in a random value if a ray does not hit

(
        mesh: o3d.geometry.TriangleMesh,
        raycast_results: T.Dict[str, T.Any],
)

Source from the content-addressed store, hash-verified

180
181
182def interp_surface_normal_from_ray_tracing_results(
183 mesh: o3d.geometry.TriangleMesh,
184 raycast_results: T.Dict[str, T.Any],
185) -> np.ndarray:
186 """
187 Interpolate the surface normal of the intersection points using surface normal on the vertices.
188
189 Args:
190 mesh:
191 raycast_results:
192 the output of ray casting of o3d
193
194 Returns:
195 (*, 3) surface normal. Note that it fills in a random value if a ray does not hit a surface
196
197 """
198 if not mesh.has_vertex_normals():
199 return raycast_results['primitive_normals'].numpy() # (*,3)
200
201 # barycentric coordinates of the intersection in the intersected triangle
202 barycentric_coords = raycast_results['primitive_uvs'].numpy() # (h,w,2), the third weight is 1-sum()
203 barycentric_coords = np.concatenate(
204 (1 - np.sum(barycentric_coords, axis=-1, keepdims=True), barycentric_coords),
205 # note that in open 3d, the primitive_uvs indicates last two coordinates rather than first two
206 # (barycentric_coords, 1 - np.sum(barycentric_coords, axis=-1, keepdims=True)),
207 axis=-1,
208 ) # (h,w,3)
209
210 # the intersected triangle index
211 primitive_ids = raycast_results['primitive_ids'].numpy() # (h, w)
212 # fillin a dummy primitive_id for the rays that go to inf
213 primitive_ids[primitive_ids == o3d.t.geometry.RaycastingScene.INVALID_ID] = 0 # (h, w)
214
215 # get triangle vertex
216 triangle_vidxs = np.asarray(mesh.triangles) # (n_triangle, 3) index of vertices
217 vertex_normals = np.asarray(mesh.vertex_normals) # (n_vertex, 3) surface normal of each vertex
218
219 vidxs = triangle_vidxs[primitive_ids] # (h, w, 3) the vertex id of each camera ray
220 v_normals = vertex_normals[vidxs] # (h, w, 3, 3) last dimension is normal (dx, dy, dz)
221 interped_normals = np.sum(np.expand_dims(barycentric_coords, axis=-1) * v_normals, axis=-2) # (h, w, 3)
222 return interped_normals
223
224
225def rasterize(

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected