void OnSceneGUI()
    {
        if (!plotter)
        {
            return;
        }

        plotter.InitEditing();

        if (plotter.CurrentAction == HairyPlotterActions.None)
        {
            // don't hover triangle when moving vertices
            if (allowMoveVerts)
            {
                plotter.SetTriangleHover(null);
            }
            else
            {
                plotter.SetTriangleHover(HoverTriangle());
            }

            if (plotter.ToggleSelected(PickTriangle()) && !allowMoveVerts)
            {
                Repaint();
            }

            if (plotter.HoveredTriangle != null)
            {
                SceneView.lastActiveSceneView.Repaint();
            }

            // detect if dragging a single vertex or selected vertices and update position/s according mouse position
            if (Event.current.button == 0)
            {
                KeyCode   _keyCode = Event.current.keyCode;
                EventType _type    = Event.current.type;

                if (_type == EventType.MouseDown)
                {
                    // pick selected vertices?
                    if (_keyCode == KeyCode.LeftShift || _keyCode == KeyCode.RightShift)
                    {
                        // use plotter.SelectedVertices
                    }
                    // or pick single vertex
                    else
                    {
                        hoveredVertex = PickVertex();
                    }
                    // set flag for allow moving vertices
                    allowMoveVerts = true;
                }
                // on mouse up finish the edition
                else if (_type == EventType.MouseUp)
                {
                    allowMoveVerts = false;
                    hoveredVertex  = null;
                }
                // while dragging mouse update vertex position
                else if (_type == EventType.MouseDrag && allowMoveVerts)
                {
                    Ray       r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    Transform t = plotter.transform;                     // this for position gizmo vertices and triangles according parent game object world coordinates
                    Vector2   p = t.InverseTransformPoint(r.origin);     // use inverse trasnform because then we transform again for displaying

                    // moving selected vertices?
                    if (_keyCode == KeyCode.LeftShift || _keyCode == KeyCode.RightShift)
                    {
                        for (int i = 0, c = plotter.SelectedVertices.Count; i < c; ++i)
                        {
                            plotter.SelectedVertices[i].Position.x = p.x;
                            plotter.SelectedVertices[i].Position.y = p.y;
                            if (HairyPlotterEditor.KeepUVOnVertsMove)
                            {
                                plotter.SelectedVertices[i].Uv.x = 0.5f + p.x;
                                plotter.SelectedVertices[i].Uv.y = 0.5f + p.y;
                            }
                        }
                    }
                    // or single vertex?
                    else if (hoveredVertex != null)
                    {
                        hoveredVertex.Position.x = p.x;
                        hoveredVertex.Position.y = p.y;
                        if (HairyPlotterEditor.KeepUVOnVertsMove)
                        {
                            hoveredVertex.Uv.x = 0.5f + p.x;
                            hoveredVertex.Uv.y = 0.5f + p.y;
                        }
                    }
                    plotter.Dirty = true;
                    plotter.ResetSelectionPosition();
                }
            }
        }

        if (plotter.CurrentAction == HairyPlotterActions.TriangleSwitch)
        {
            HairyPlotterTriangle triangle = PickTriangle();

            if (triangle != null)
            {
                List <HairyPlotterVertex> vertices = plotter.SelectedVertices;

                if (vertices.Count == 2)
                {
                    triangle.SwitchVertices(vertices[0], vertices[1]);
                    plotter.ClearVertexSelection();
                }
                else
                {
                    Debug.LogWarning("Switch In Triangle requires exactly two selected vertices");
                }
            }
        }

        DrawTriangles();
    }
    void VertexSelectionToolbox()
    {
        if (plotter.VertexSelectionCount > 0)
        {
            GUI.color = VertexSelectionToolbarColor;

            EditorGUILayout.LabelField("Vertex Selection", EditorStyles.boldLabel);
            EditorGUILayout.BeginHorizontal();

            if (GUILayout.Button("Clear", EditorStyles.miniButton))
            {
                plotter.ClearVertexSelection();
                SceneView.lastActiveSceneView.Repaint();
            }

            if (GUILayout.Button("Duplicate And Select", EditorStyles.miniButton))
            {
                // Copy current selection
                HashSet <HairyPlotterVertex> prevSelection = new HashSet <HairyPlotterVertex>(plotter.SelectedVertices);

                // Clear current selection
                plotter.ClearVertexSelection();

                // Duplicate each
                foreach (HairyPlotterVertex v in prevSelection)
                {
                    plotter.AddSelection(plotter.CreateVertex(v.Position, v.Uv));
                }
            }

            GUI.color = plotter.CurrentAction == HairyPlotterActions.TriangleSwitch ? ActiveUvEditorColor : VertexSelectionToolbarColor;

            if (GUILayout.Button("Switch In Triangle", EditorStyles.miniButton))
            {
                if (plotter.CurrentAction == HairyPlotterActions.TriangleSwitch)
                {
                    plotter.CurrentAction = HairyPlotterActions.None;
                }
                else
                {
                    if (plotter.SelectedVertices.Count == 2)
                    {
                        plotter.CurrentAction = HairyPlotterActions.TriangleSwitch;
                    }
                    else
                    {
                        Debug.LogWarning("Switch In Triangle requires exactly two selected vertices");
                    }
                }
            }

            GUI.color = VertexSelectionToolbarColor;

            if (plotter.CurrentAction == HairyPlotterActions.VertexDelete)
            {
                if (GUILayout.Button("Yes!", EditorStyles.miniButton))
                {
                    plotter.CurrentAction = HairyPlotterActions.None;

                    foreach (HairyPlotterVertex vertex in plotter.SelectedVertices)
                    {
                        plotter.DestroyVertex(vertex);
                    }
                }

                if (GUILayout.Button("No!", EditorStyles.miniButton))
                {
                    plotter.CurrentAction = HairyPlotterActions.None;
                }
            }
            else
            {
                if (GUILayout.Button("Delete Selected", EditorStyles.miniButton))
                {
                    plotter.CurrentAction = HairyPlotterActions.VertexDelete;
                }
            }

            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("All");
            plotter.SelectionPosition = EditVector3(plotter.SelectionPosition);
            EditorGUILayout.EndHorizontal();

            if (plotter.SelectionPosition.x != float.MaxValue)
            {
                plotter.ToEachSelection(v => v.Position.x = plotter.SelectionPosition.x);
            }

            if (plotter.SelectionPosition.y != float.MaxValue)
            {
                plotter.ToEachSelection(v => v.Position.y = plotter.SelectionPosition.y);
            }

            if (plotter.SelectionPosition.z != float.MaxValue)
            {
                plotter.ToEachSelection(v => v.Position.z = plotter.SelectionPosition.z);
            }
        }

        List <HairyPlotterVertex> selectedVertices = plotter.SelectedVertices;

        foreach (HairyPlotterVertex vertex in selectedVertices)
        {
            EditorGUILayout.BeginHorizontal();

            // Vertex index
            GUILayout.Label("#" + vertex.Index);

            // Lets us deselect a specific vertex
            if (GUILayout.Button("Deselect", EditorStyles.miniButton))
            {
                plotter.RemoveSelection(vertex);
            }

            // Edit XYZ of vertex
            Vector3 pos = EditVector3(vertex.Position);

            // When editing UVs allow switching
            if (selectedVertices.Count > 1 && plotter.CurrentAction == HairyPlotterActions.VertexUvEdit)
            {
                if (GUILayout.Button("Edit UVs"))
                {
                    plotter.SetUvEditVertex(vertex);
                }
            }

            EditorGUILayout.EndHorizontal();

            // If position was updated
            if (pos != vertex.Position)
            {
                vertex.Position = pos;

                plotter.Dirty = true;
                plotter.ResetSelectionPosition();
            }
        }

        GUI.color = Color.white;
    }