code: def weighted_random_sample_triangle_mesh(
      vertex_attributes: type_alias.TensorLike,
      faces: type_alias.TensorLike,
      num_samples: int,
      face_weights: type_alias.TensorLike,
      seed: Optional[type_alias.TensorLike] = None,
      stateless: bool = False,
      name: str = "weighted_random_sample_triangle_mesh",
  ) -> Tuple[type_alias.TensorLike, type_alias.TensorLike]:
      """Performs a face probability weighted random sampling of a tri mesh.
  
      Note:
        In the following, A1 to An are optional batch dimensions.
  
      Args:
        vertex_attributes: A `float` tensor of shape `[A1, ..., An, V, D]`, where V
          is the number of vertices, and D is dimensionality of each vertex.
        faces: A `int` tensor of shape `[A1, ..., An, F, 3]`, where F is the number
          of faces.
        num_samples: A `int` 0-D tensor denoting number of samples to be drawn from
          each mesh.
        face_weights: A `float` tensor of shape ``[A1, ..., An, F]`, denoting
          unnormalized sampling probability of each face, where F is the number of
          faces.
        seed: Optional random seed.
        stateless: Optional flag to use stateless random sampler. If stateless=True,
          then seed must be provided as shape `[2]` int tensor. Stateless random
          sampling is useful for testing to generate same sequence across calls.
        name: Name for op. Defaults to "weighted_random_sample_triangle_mesh".
  
      Returns:
        sample_points: A `float` tensor of shape `[A1, ..., An, num_samples, D]`,
          where D is dimensionality of each sampled point.
        sample_face_indices: A `int` tensor of shape `[A1, ..., An, num_samples]`.
      """
      with tf.name_scope(name):
          faces = tf.convert_to_tensor(value=faces)
          vertex_attributes = tf.convert_to_tensor(
              value=vertex_attributes
          )
          face_weights = tf.convert_to_tensor(value=face_weights)
          num_samples = tf.convert_to_tensor(value=num_samples)
  
          shape.check_static(
              tensor=vertex_attributes,
              tensor_name="vertex_attributes",
              has_rank_greater_than=1,
          )
          shape.check_static(
              tensor=faces, tensor_name="faces", has_rank_greater_than=1
          )
          shape.check_static(
              tensor=face_weights,
              tensor_name="face_weights",
              has_rank_greater_than=0,
          )
          shape.compare_batch_dimensions(
              tensors=(faces, face_weights),
              last_axes=(-2, -1),
              tensor_names=("faces", "face_weights"),
              broadcast_compatible=False,
          )
          shape.compare_batch_dimensions(
              tensors=(vertex_attributes, faces, face_weights),
              last_axes=(-3, -3, -2),
              tensor_names=(
                  "vertex_attributes",
                  "faces",
                  "face_weights",
              ),
              broadcast_compatible=False,
          )
  
          asserts.assert_all_above(face_weights, 0)
  
          batch_dims = faces.shape.ndims - 2
          batch_shape = faces.shape.as_list()[:-2]
          sample_shape = tf.concat(
              (
                  batch_shape,
                  tf.convert_to_tensor(
                      value=(num_samples,), dtype=tf.int32
                  ),
              ),
              axis=0,
          )
  
          sample_face_indices = generate_random_face_indices(
              num_samples, face_weights, seed=seed, stateless=stateless
          )
          sample_vertex_indices = tf.gather(
              faces, sample_face_indices, batch_dims=batch_dims
          )
          sample_vertices = tf.gather(
              vertex_attributes,
              sample_vertex_indices,
              batch_dims=batch_dims,
          )
          barycentric = generate_random_barycentric_coordinates(
              sample_shape,
              dtype=vertex_attributes.dtype,
              seed=seed,
              stateless=stateless,
          )
          barycentric = tf.expand_dims(barycentric, axis=-1)
          sample_points = tf.math.multiply(sample_vertices, barycentric)
          sample_points = tf.reduce_sum(
              input_tensor=sample_points, axis=-2
          )
          return sample_points, sample_face_indices
  
file_path: graphics/tensorflow_graphics/geometry/representation/mesh/sampler.py
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  from typing import Optional, Tuple
  import tensorflow
  from tensorflow_graphics.geometry.representation import triangle
  from tensorflow_graphics.geometry.representation.mesh import normals
  from tensorflow_graphics.util import asserts
  from tensorflow_graphics.util import export_api
  from tensorflow_graphics.util import shape
  from tensorflow_graphics.util import type_alias
label_desc: Use image node_id 5 for calling a global function with example usage: weighted_random_sample_triangle_mesh(vertex_attributes, faces, num_samples, face_weights, seed, stateless, name) and returns: sample_points,  sample_face_indices