Repository: Genesis-Embodied-AI/Genesis
File: genesis/utils/mesh.py (Python)

Code before:
    if color is None:  # use checkerboard texture
        n_tile_x, n_tile_y = plane_size[0] / tile_size[0], plane_size[1] / tile_size[1]
        vmesh.visual = trimesh.visual.TextureVisuals(
            uv=np.array(
                [
                    [0, 0],
                    [n_tile_x, 0],
                    [n_tile_x, n_tile_y],
                    [0, 0],
                    [n_tile_x, n_tile_y],
                    [0, n_tile_y],
                ],
                dtype=np.float32,
            ),
            material=trimesh.visual.material.SimpleMaterial(
                image=Image.open(os.path.join(get_assets_dir(), DEFAULT_PLANE_TEXTURE_PATH)),
            ),
        )
        # Store texture path in metadata since we applied a texture
        metadata["texture_path"] = DEFAULT_PLANE_TEXTURE_PATH
    else:
        vmesh.visual = trimesh.visual.ColorVisuals(
            vertex_colors=np.tile(np.asarray(color, dtype=np.float32), (len(vmesh.vertices), 1))
        )

    return vmesh, mesh, metadata


def generate_tetgen_config_from_morph(morph):
    if not isinstance(morph, gs.options.morphs.TetGenMixin):
        raise TypeError(
            f"Expected an instance of a class that inherits from TetGenMixin, but got an instance of {type(morph).name}."
        )
    return dict(
        order=morph.order,
        mindihedral=morph.mindihedral,
        minratio=morph.minratio,
        nobisect=morph.nobisect,
        quality=morph.quality,
        maxvolume=morph.maxvolume,
        verbose=morph.verbose,
    )


def make_tetgen_switches(cfg):
    """Build a TetGen switches string from a config dict."""
    flags = ["p"]

    if cfg.get("quality", True):
        r = cfg.get("minratio", 1.1)
        di = cfg.get("mindihedral", 10)

Review comment (refactor):
I'm not a huge fan of returning metadata this way, because this helpers are not aware of what `metadata` is. 

Maybe create plane should take some `color_to_texture_path` input argument, that default to some global variable `DEFAULT_PLANE_TEXTURE_PATH` that would be defined on top of this module. Then when you create the plane, you can explicitly specify `color_or_texture`, and fill your metadata accordingly.

Code after:
    )
    faces = np.arange(6, dtype=np.int32).reshape(-1, 3)
    vmesh = trimesh.Trimesh(verts, faces, process=False)
    vmesh.vertices[:, 2] -= thickness / 2
    vmesh.vertices = gu.transform_by_R(vmesh.vertices, gu.z_up_to_R(np.asarray(normal, dtype=np.float32)))

    if texture_path is not None:
        n_tile_x, n_tile_y = plane_size[0] / tile_size[0], plane_size[1] / tile_size[1]
        vmesh.visual = trimesh.visual.TextureVisuals(
            uv=np.array(
                [
                    [0, 0],
                    [n_tile_x, 0],
                    [n_tile_x, n_tile_y],
                    [0, 0],
                    [n_tile_x, n_tile_y],
                    [0, n_tile_y],
                ],
                dtype=np.float32,
            ),
            material=trimesh.visual.material.SimpleMaterial(
                image=Image.open(os.path.join(get_assets_dir(), texture_path)),
            ),
        )
    else:
        vmesh.visual = trimesh.visual.ColorVisuals(
            vertex_colors=np.tile(np.asarray(color, dtype=np.float32), (len(vmesh.vertices), 1))
        )

    return vmesh, mesh


def generate_tetgen_config_from_morph(morph):
    if not isinstance(morph, gs.options.morphs.TetGenMixin):
        raise TypeError(
            f"Expected an instance of a class that inherits from TetGenMixin, but got an instance of {type(morph).name}."
        )
    return dict(
        order=morph.order,
        mindihedral=morph.mindihedral,
        minratio=morph.minratio,
        nobisect=morph.nobisect,
        quality=morph.quality,
        maxvolume=morph.maxvolume,
        verbose=morph.verbose,
    )


def make_tetgen_switches(cfg):
    """Build a TetGen switches string from a config dict."""
    flags = ["p"]