void DrawGUIAttachmentDataValidation(SkinAttachmentTarget driver)
        {
            var checksum       = driver.attachData.Checksum();
            var checksumFailed = driver.CommitRequired();

            if (checksumFailed)
            {
                EditorGUILayout.HelpBox("Rebuild required: Checksum of driver or one or more subjects does not match checksum of data.", MessageType.Warning);
            }
            else if (driver.attachData.subjectCount != driver.subjects.Count)
            {
                EditorGUILayout.HelpBox("Rebuild suggested: Data contains poses that are no longer referenced.", MessageType.Warning);
            }

            if (GUILayout.Button("Rebuild"))
            {
                driver.CommitSubjects();
            }
        }
        public static void DrawSceneGUIMouseOver(SkinAttachmentTarget driver)
        {
            var mouseScreen   = Event.current.mousePosition;
            var mouseWorldRay = HandleUtility.GUIPointToWorldRay(mouseScreen);

            var objectRayPos = driver.transform.InverseTransformPoint(mouseWorldRay.origin);
            var objectRayDir = driver.transform.InverseTransformDirection(mouseWorldRay.direction);

            var meshInfo = driver.GetCachedMeshInfo();

            if (meshInfo.valid == false)
            {
                return;
            }

            var vertex = meshInfo.meshVertexBSP.RaycastApprox(ref objectRayPos, ref objectRayDir, 10);

            if (vertex == -1)
            {
                return;
            }

            using (var scope = new Handles.DrawingScope(Color.blue, driver.transform.localToWorldMatrix))
            {
                const int maxDepth = 3;

                var triangleColor = Handles.color;
                var triangleDepth = 0;

                using (var triangleBFS = new UnsafeBFS(meshInfo.meshAdjacency.triangleCount))
                {
                    foreach (var triangle in meshInfo.meshAdjacency.vertexTriangles[vertex])
                    {
                        triangleBFS.Insert(triangle);
                    }

                    while (triangleBFS.MoveNext() && triangleBFS.depth < maxDepth)
                    {
                        if (triangleDepth < triangleBFS.depth)
                        {
                            triangleDepth = triangleBFS.depth;
                            Handles.color = Color.Lerp(triangleColor, Color.clear, Mathf.InverseLerp(0, maxDepth, triangleDepth));
                        }

                        var _e = meshInfo.meshAdjacency.triangleVertices[triangleBFS.position].GetEnumerator();
                        int v0 = _e.ReadNext();
                        int v1 = _e.ReadNext();
                        int v2 = _e.ReadNext();

                        Handles.DrawLine(meshInfo.meshBuffers.vertexPositions[v0], meshInfo.meshBuffers.vertexPositions[v1]);
                        Handles.DrawLine(meshInfo.meshBuffers.vertexPositions[v1], meshInfo.meshBuffers.vertexPositions[v2]);
                        Handles.DrawLine(meshInfo.meshBuffers.vertexPositions[v2], meshInfo.meshBuffers.vertexPositions[v0]);

                        foreach (var triangle in meshInfo.meshAdjacency.triangleTriangles[triangleBFS.position])
                        {
                            triangleBFS.Insert(triangle);
                        }
                    }
                }
            }
        }