def identifier_simple(mesh):
    """
    Return a basic identifier for a mesh, consisting of properties
    that have been hand tuned to be somewhat robust to rigid
    transformations and different tesselations.

    Parameters
    ----------
    mesh : Trimesh object
      Source geometry

    Returns
    ----------
    identifier : (6,) float
      Identifying values of the mesh
    """
    # verify the cache once
    mesh._cache.verify()

    # don't check hashes during identifier as we aren't
    # changing any data values of the mesh inside block
    # if we did change values in cache block things would break
    with mesh._cache:
        # pre-allocate identifier so indexes of values can't move around
        # like they might if we used hstack or something else
        identifier = np.zeros(6, dtype=np.float64)
        # avoid thrashing the cache unnecessarily
        mesh_area = mesh.area
        # start with properties that are valid regardless of watertightness
        # note that we're going to try to make all parameters relative
        # to area so other values don't get blown up at weird scales
        identifier[0] = mesh_area

        # topological constant and the only thing we can really
        # trust in this fallen world
        identifier[1] = mesh.euler_number

        # if we have a watertight mesh include volume and inertia
        if mesh.is_volume:
            # side length of a cube ratio
            # 1.0 for cubes, different values for other things
            identifier[2] = (((mesh_area / 6.0) ** (1.0 / 2.0)) /
                             (mesh.volume ** (1.0 / 3.0)))
            # save vertices for radius calculation
            vertices = mesh.vertices - mesh.center_mass
            # we are going to special case radially symmetric meshes
            # to replace their surface area with ratio of their
            # surface area to a primitive sphere or cylinder surface area
            # this is because tessellated curved surfaces are really rough
            # to reliably hash as they are very sensitive to floating point
            # and tessellation error. By making area proportionate to a fit
            # primitive area we are able to reliably hash at more sigfigs
            if mesh.symmetry == 'radial':
                # cylinder height
                h = np.dot(vertices, mesh.symmetry_axis).ptp()
                # section radius
                R2 = (np.dot(vertices, mesh.symmetry_section.T)
                      ** 2).sum(axis=1).max()
                # area of a cylinder primitive
                area = (2 * np.pi * (R2**.5) * h) + (2 * np.pi * R2)
                # replace area in this case with area ratio
                identifier[0] = mesh_area / area
            elif mesh.symmetry == 'spherical':
                # handle a spherically symmetric mesh
                R2 = (vertices ** 2).sum(axis=1).max()
                area = 4 * np.pi * R2
                identifier[0] = mesh_area / area
        else:
            # if we don't have a watertight mesh add information about the
            # convex hull, which is slow to compute and unreliable
            # just what we're looking for in a hash but hey
            identifier[3] = mesh_area / mesh.convex_hull.area
            # cube side length ratio for the hull
            identifier[4] = (((mesh.convex_hull.area / 6.0) ** (1.0 / 2.0)) /
                             (mesh.convex_hull.volume ** (1.0 / 3.0)))
            vertices = mesh.vertices - mesh.centroid

            # add in max radius^2 to area ratio
            R2 = (vertices ** 2).sum(axis=1).max()
            identifier[5] = R2 / mesh_area

    return identifier
def identifier_simple ( mesh ) : mesh . _cache . verify ( ) with mesh . _cache : identifier = np . zeros ( 6 , dtype = np . float64 ) mesh_area = mesh . area identifier [ 0 ] = mesh_area identifier [ 1 ] = mesh . euler_number if mesh . is_volume : identifier [ 2 ] = ( ( ( mesh_area / 6.0 ) ** ( 1.0 / 2.0 ) ) / ( mesh . volume ** ( 1.0 / 3.0 ) ) ) vertices = mesh . vertices - mesh . center_mass if mesh . symmetry == 'radial' : h = np . dot ( vertices , mesh . symmetry_axis ) . ptp ( ) R2 = ( np . dot ( vertices , mesh . symmetry_section . T ) ** 2 ) . sum ( axis = 1 ) . max ( ) area = ( 2 * np . pi * ( R2 ** .5 ) * h ) + ( 2 * np . pi * R2 ) identifier [ 0 ] = mesh_area / area elif mesh . symmetry == 'spherical' : R2 = ( vertices ** 2 ) . sum ( axis = 1 ) . max ( ) area = 4 * np . pi * R2 identifier [ 0 ] = mesh_area / area else : identifier [ 3 ] = mesh_area / mesh . convex_hull . area identifier [ 4 ] = ( ( ( mesh . convex_hull . area / 6.0 ) ** ( 1.0 / 2.0 ) ) / ( mesh . convex_hull . volume ** ( 1.0 / 3.0 ) ) ) vertices = mesh . vertices - mesh . centroid R2 = ( vertices ** 2 ) . sum ( axis = 1 ) . max ( ) identifier [ 5 ] = R2 / mesh_area return identifier
Return a basic identifier for a mesh, consisting of properties
    that have been hand tuned to be somewhat robust to rigid
    transformations and different tesselations.

    Parameters
    ----------
    mesh : Trimesh object
      Source geometry

    Returns
    ----------
    identifier : (6,) float
      Identifying values of the mesh