/// <summary>
        /// Returns the rotation of an <see cref="Edge"/> in world space.
        /// </summary>
        /// <param name="mesh">The mesh that edge belongs to.</param>
        /// <param name="edge">The edge you want to calculate the rotation for.</param>
        /// <returns>The rotation of the edge in world space coordinates.</returns>
        public static Quaternion GetEdgeRotation(ProBuilderMesh mesh, Edge edge)
        {
            if (mesh == null)
            {
                return(Quaternion.identity);
            }

            return(GetFaceRotation(mesh, EdgeUtility.GetFace(mesh, edge)));
        }
        /// <summary>
        /// Get a rotation suitable for orienting a handle or gizmo relative to the element selection.
        /// </summary>
        /// <param name="mesh">The target mesh.</param>
        /// <param name="orientation">The type of <see cref="HandleOrientation"/> to calculate.</param>
        /// <param name="edges">Edges to consider in the rotation calculations. Only used when
        /// <see cref="HandleOrientation"/> is <see cref="HandleOrientation.ActiveElement"/>.</param>
        /// <returns>A rotation appropriate to the orientation and element selection.</returns>
        public static Quaternion GetEdgeRotation(ProBuilderMesh mesh, HandleOrientation orientation, IEnumerable <Edge> edges)
        {
            if (mesh == null)
            {
                return(Quaternion.identity);
            }

            switch (orientation)
            {
            case HandleOrientation.ActiveElement:
                if (mesh.selectedEdgeCount < 1)
                {
                    goto case HandleOrientation.ActiveObject;
                }

                // Getting an average of the edge normals isn't very helpful in real world uses, so we just use the
                // first selected edge for orientation.
                // This function accepts an enumerable because in the future we may want to do something more
                // sophisticated, and it's convenient because selections are stored as collections.
                var face = EdgeUtility.GetFace(mesh, edges.First());

                if (face == null)
                {
                    goto case HandleOrientation.ActiveObject;
                }

                Normal nrm = Math.NormalTangentBitangent(mesh, face);

                if (nrm.normal == Vector3.zero || nrm.bitangent == Vector3.zero)
                {
                    goto case HandleOrientation.ActiveObject;
                }

                return(mesh.transform.rotation * Quaternion.LookRotation(nrm.normal, nrm.bitangent));

            case HandleOrientation.ActiveObject:
                return(mesh.transform.rotation);

            default:
                return(Quaternion.identity);
            }
        }