/// <summary>
        /// Creates a new topology based on the one provided, subdividing each face into multiple smaller faces, and adding extra vertices and edges accordingly.  Uses spherical linear interpolation for deriving the positions of new vertices.
        /// </summary>
        /// <param name="surface">The spherical surface describing the overall shape of the manifold.</param>
        /// <param name="topology">The original topology to be subdivided.  Cannot contain internal faces with neighbor counts of any value other than 3 or 4.</param>
        /// <param name="vertexPositions">The positions of the original topology's vertices.</param>
        /// <param name="degree">The degree of subdivision, equivalent to the number of additional vertices that will be added along each original edge.  Must be non-negative, and a value of zero will result in an exact duplicate with no subdivision.</param>
        /// <param name="subdividedTopology">The copied and subdivided topology.</param>
        /// <param name="subdividedVertexPositions">The positions of the subdivided vertices.</param>
        public static void Subdivide(SphericalSurface surface, Topology topology, IVertexAttribute <Vector3> vertexPositions, int degree, out Topology subdividedTopology, out Vector3[] subdividedVertexPositions)
        {
            Func <Vector3, Vector3, float, Vector3> interpolator;

            if (surface.radius == 1f)
            {
                interpolator = (Vector3 p0, Vector3 p1, float t) => { return(Geometry.SlerpUnitVectors(p0, p1, t)); };
            }
            else
            {
                interpolator = (Vector3 p0, Vector3 p1, float t) => { return(Geometry.SlerpUnitVectors(p0 / surface.radius, p1 / surface.radius, t) * surface.radius); };
            }
            ManifoldUtility.Subdivide(topology, vertexPositions, degree, interpolator, out subdividedTopology, out subdividedVertexPositions);
        }
 /// <summary>
 /// Reverses the roles of vertices and faces, as when taking the dual of a polyhedron.
 /// </summary>
 /// <param name="topology">The topology containing the vertices and faces to swap.</param>
 /// <param name="vertexPositions">The positions of the vertices, which will become the new positions after the call is complete, calculated as the face centroids of the original topology.</param>
 public static void MakeDual(Topology topology, ref Vector3[] vertexPositions)
 {
     ManifoldUtility.MakeDual(topology, FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.faces, vertexPositions.AsVertexAttribute()), out vertexPositions);
 }
 /// <summary>
 /// Reverses the roles of vertices and faces, as when taking the dual of a polyhedron.
 /// </summary>
 /// <param name="topology">The topology containing the vertices and faces to swap.</param>
 /// <param name="vertexPositions">The original positions of the vertices.</param>
 /// <param name="dualVertexPositions">The positions of the vertices after the swap, calculated as the face centroids of the original topology.</param>
 public static void MakeDual(Topology topology, IVertexAttribute <Vector3> vertexPositions, out Vector3[] dualVertexPositions)
 {
     ManifoldUtility.MakeDual(topology, FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.faces, vertexPositions), out dualVertexPositions);
 }