bool ValidateMeshSet(Shape shape, GameObject obj)
    {
        bool ok = true;

        Tes.Handlers.MeshCache meshCache = (Tes.Handlers.MeshCache)tes.GetHandler((ushort)RoutingID.Mesh);

        // First the first *child* ShapeComponent. This identfies the mesh.
        var part = GetFirstChildComponent <Tes.Handlers.ShapeComponent>(obj);

        if (part == null)
        {
            Debug.LogError("Missing mesh set part resource.");
            return(false);
        }

        // Find the resource.
        var meshDetails = meshCache.GetEntry(part.ObjectID);

        if (meshDetails == null)
        {
            Debug.LogError(string.Format("Missing mesh {0}", part.ObjectID));
            return(false);
        }

        ok = ValidateVectors("Vertex", meshDetails.Builder.Vertices, _sampleMesh.Vertices()) && ok;
        ok = ValidateVectors("Normal", meshDetails.Builder.Normals, _sampleMesh.Normals()) && ok;
        ok = ValidateIndices("Index", meshDetails.Builder.Indices, _sampleMesh.Indices4()) && ok;

        return(ok);
    }
    bool ValidateCloud(Shape shape, GameObject obj)
    {
        PointsComponent points = obj.GetComponent <PointsComponent>();

        if (points == null)
        {
            Debug.LogError("Missing mesh data object.");
            return(false);
        }

        bool ok = true;

        Tes.Handlers.MeshCache meshCache = (Tes.Handlers.MeshCache)tes.GetHandler((ushort)RoutingID.Mesh);

        // Find the resource.
        var meshDetails = meshCache.GetEntry(points.MeshID);

        if (meshDetails == null)
        {
            Debug.LogError(string.Format("Missing mesh {0}", points.MeshID));
            return(false);
        }


        ok = ValidateVectors("Point", meshDetails.Builder.Vertices, _sampleMesh.Vertices()) && ok;

        return(ok);
    }
    bool ValidateMeshSet(Shape shape, Shape referenceShape, MessageHandler handler)
    {
        MeshSetHandler meshSetHandler = (MeshSetHandler)handler;

        MeshSetHandler.PartSet parts     = meshSetHandler.ShapeCache.GetShapeData <MeshSetHandler.PartSet>(shape.ID);
        Tes.Handlers.MeshCache meshCache = (Tes.Handlers.MeshCache)_tes.GetHandler((ushort)RoutingID.Mesh);
        MeshSet meshSetReference         = (MeshSet)referenceShape;
        bool    ok = true;

        // Validate the number of parts.
        if (parts.MeshIDs.Length != meshSetReference.PartCount)
        {
            Debug.LogError("Part count mismatch.");
            return(false);
        }

        // Validate each part.
        for (int i = 0; i < meshSetReference.PartCount; ++i)
        {
            MeshResource referenceMesh = meshSetReference.PartResource(i);
            if (parts.MeshIDs[i] != referenceMesh.ID)
            {
                Debug.LogError($"Part resource mismatch. {parts.MeshIDs[i]} != {meshSetReference.PartResource(i).ID}");
                ok = false;
                continue;
            }

            // Resolve the mesh resource from the cache.
            Tes.Handlers.MeshCache.MeshDetails meshDetails = meshCache.GetEntry(parts.MeshIDs[i]);

            if (meshDetails == null)
            {
                Debug.LogError($"Unable to resolve mesh resource {parts.MeshIDs[i]}");
                ok = false;
                continue;
            }

            // Validate mesh content.
            ok = ValidateVectors("Vertex", meshDetails.Mesh.Vertices, referenceMesh.Vertices()) && ok;
            if (meshDetails.Mesh.HasNormals)
            {
                Vector3[] normals = meshDetails.Mesh.Normals;
                if (referenceMesh.Normals().Length == 1)
                {
                    // Single uniform normal will have been expanded. Extract just the first normal.
                    normals = new Vector3[] { meshDetails.Mesh.Normals[0] };
                }
                ok = ValidateVectors("Normal", normals, referenceMesh.Normals()) && ok;
            }
            else
            {
                if (referenceMesh.Normals() != null && referenceMesh.Normals().Length > 0)
                {
                    Debug.LogError("Missing normals.");
                    ok = false;
                }
            }
            if (meshDetails.Mesh.IndexCount > 0)
            {
                ok = ValidateIndices("Index", meshDetails.Mesh.Indices, referenceMesh.Indices4()) && ok;
            }
            else
            {
                if (referenceMesh.Indices4() != null && referenceMesh.Indices4().Length > 0)
                {
                    Debug.LogError("Missing indices.");
                    ok = false;
                }
            }
        }

        return(ok);
    }