Repository: Genesis-Embodied-AI/Genesis
File: genesis/engine/entities/fem_entity.py (Python)

Code before:
                n_surfaces=self._n_surfaces,
                v_start=self._v_start,
                el_start=self._el_start,
                s_start=self._s_start,
                verts=verts_numpy,
                elems=elems_np,
                tri2v=self._surface_tri_np,
                tri2el=self._surface_el_np,
            )

        # Add UVs to solver if available
        self._add_uvs_to_solver()

        self.active = True

    def _add_uvs_to_solver(self):
        """
        Copy UV coordinates to the solver's surface_render_uvs field.
        """
        if self._uvs is None:
            return

        # Copy UVs to solver field starting at v_start
        uvs_np = self._uvs.astype(gs.np_float, copy=False)
        for i, uv in enumerate(uvs_np):
            self._solver.surface_render_uvs[self._v_start + i] = uv

    def compute_pressure_field(self):
        """
        Compute the pressure field for the FEM entity based on its tetrahedral elements.

        For hydroelastic contact: https://drake.mit.edu/doxygen_cxx/group__hydroelastic__user__guide.html

        Notes
        -----
        https://github.com/RobotLocomotion/drake/blob/master/geometry/proximity/make_mesh_field.cc
        TODO: Add margin support
        Drake's implementation of margin seems buggy.
        """
        init_positions = tensor_to_array(self.init_positions)
        signed_distance, *_ = igl.signed_distance(init_positions, init_positions, self._surface_tri_np)
        signed_distance = signed_distance.astype(gs.np_float, copy=False)

        unsigned_distance = np.abs(signed_distance)
        max_distance = np.max(unsigned_distance)
        if max_distance < gs.EPS:
            gs.raise_exception(
                f"Pressure field max distance is too small: {max_distance}. "
                "This might be due to a mesh having no internal vertices."
            )
        self.pressure_field_np = unsigned_distance / max_distance * self.material._hydroelastic_modulus  # normalize

Review comment (performance):
This is extremely inefficient (one kernel call per assignment). You should modify `_kernel_add_elements` to take into account `uv`. Just pass an 0-length vector if unspecified and check this condition inside the kernel to avoid out of bound access. 

Code after:
                f=self._sim.cur_substep_local,
                mat_idx=self._material.idx,
                mat_mu=self._material.mu,
                mat_lam=self._material.lam,
                mat_rho=self._material.rho,
                mat_friction_mu=self._material.friction_mu,
                n_surfaces=self._n_surfaces,
                v_start=self._v_start,
                el_start=self._el_start,
                s_start=self._s_start,
                verts=verts_numpy,
                elems=elems_np,
                tri2v=self._surface_tri_np,
                tri2el=self._surface_el_np,
                uvs=uvs_np,
            )

        self.active = True

    def compute_pressure_field(self):
        """
        Compute the pressure field for the FEM entity based on its tetrahedral elements.

        For hydroelastic contact: https://drake.mit.edu/doxygen_cxx/group__hydroelastic__user__guide.html

        Notes
        -----
        https://github.com/RobotLocomotion/drake/blob/master/geometry/proximity/make_mesh_field.cc
        TODO: Add margin support
        Drake's implementation of margin seems buggy.
        """
        init_positions = tensor_to_array(self.init_positions)
        signed_distance, *_ = igl.signed_distance(init_positions, init_positions, self._surface_tri_np)
        signed_distance = signed_distance.astype(gs.np_float, copy=False)

        unsigned_distance = np.abs(signed_distance)
        max_distance = np.max(unsigned_distance)
        if max_distance < gs.EPS:
            gs.raise_exception(
                f"Pressure field max distance is too small: {max_distance}. "
                "This might be due to a mesh having no internal vertices."
            )
        self.pressure_field_np = unsigned_distance / max_distance * self.material._hydroelastic_modulus  # normalize

    # ------------------------------------------------------------------------------------
    # ---------------------------- checkpoint and buffer ---------------------------------
    # ------------------------------------------------------------------------------------

    def init_tgt_keys(self):
        """
        Initialize the keys used in target state management.