public static void VerifyDodecahedron()
        {
            // Get the points.
            Point3D A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T;

            G3.DodecahedronPoints(
                out A, out B, out C, out D, out E,
                out F, out G, out H, out I, out J,
                out K, out L, out M, out N, out O,
                out P, out Q, out R, out S, out T);

            // Verify the points.
            G3.VerifyPoints(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T);

            // Verify the faces.
            G3.VerifyPolygon(E, D, C, B, A);
            G3.VerifyPolygon(A, B, G, K, F);
            G3.VerifyPolygon(A, F, O, J, E);
            G3.VerifyPolygon(E, J, N, I, D);
            G3.VerifyPolygon(D, I, M, H, C);
            G3.VerifyPolygon(C, H, L, G, B);
            G3.VerifyPolygon(K, P, T, O, F);
            G3.VerifyPolygon(O, T, S, N, J);
            G3.VerifyPolygon(N, S, R, M, I);
            G3.VerifyPolygon(M, R, Q, L, H);
            G3.VerifyPolygon(L, Q, P, K, G);
            G3.VerifyPolygon(P, Q, R, S, T);
        }
        // Make a dodecahedron without texture coordinates or smoothing.
        public static void AddDodecahedron(this MeshGeometry3D mesh)
        {
            // Get the points.
            Point3D A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T;

            G3.DodecahedronPoints(
                out A, out B, out C, out D, out E,
                out F, out G, out H, out I, out J,
                out K, out L, out M, out N, out O,
                out P, out Q, out R, out S, out T);

            // Make the faces.
            mesh.AddPolygon(E, D, C, B, A);
            mesh.AddPolygon(A, B, G, K, F);
            mesh.AddPolygon(A, F, O, J, E);
            mesh.AddPolygon(E, J, N, I, D);
            mesh.AddPolygon(D, I, M, H, C);
            mesh.AddPolygon(C, H, L, G, B);
            mesh.AddPolygon(K, P, T, O, F);
            mesh.AddPolygon(O, T, S, N, J);
            mesh.AddPolygon(N, S, R, M, I);
            mesh.AddPolygon(M, R, Q, L, H);
            mesh.AddPolygon(L, Q, P, K, G);
            mesh.AddPolygon(P, Q, R, S, T);
        }
        public static void AddRegularPolygon(this MeshGeometry3D mesh,
                                             int numSides, Point3D center, Vector3D vx, Vector3D vy,
                                             Dictionary <Point3D, int> pointDict = null,
                                             Point[] textureCoords = null)
        {
            // Generate the points.
            Point3D[] points = G3.MakePolygonPoints(numSides, center, vx, vy);

            // Make the polygon.
            mesh.AddPolygon(points, textureCoords);
        }
        // Make a tetrahedron without texture coordinates or smoothing.
        public static void AddTetrahedron(this MeshGeometry3D mesh, bool centered = true)
        {
            // Get the points.
            Point3D A, B, C, D;

            G3.TetrahedronPoints(out A, out B, out C, out D, centered);

            // Make the faces.
            mesh.AddPolygon(A, B, C);
            mesh.AddPolygon(A, C, D);
            mesh.AddPolygon(A, D, B);
            mesh.AddPolygon(D, C, B);
        }
        // Make a cube without texture coordinates or smoothing.
        public static void AddCube(this MeshGeometry3D mesh)
        {
            // Get the points.
            Point3D A, B, C, D, E, F, G, H;

            G3.CubePoints(out A, out B, out C, out D, out E, out F, out G, out H);

            // Make the faces.
            mesh.AddPolygon(A, B, C, D);
            mesh.AddPolygon(A, D, H, E);
            mesh.AddPolygon(A, E, F, B);
            mesh.AddPolygon(G, C, B, F);
            mesh.AddPolygon(G, F, E, H);
            mesh.AddPolygon(G, H, D, C);
        }
        public static void VerifyTetrahedron()
        {
            // Get the points.
            Point3D A, B, C, D;

            G3.TetrahedronPoints(out A, out B, out C, out D, true);

            // Verify the points.
            G3.VerifyPoints(A, B, C, D);

            // Verify the faces.
            G3.VerifyPolygon(A, B, C);
            G3.VerifyPolygon(A, C, D);
            G3.VerifyPolygon(A, D, B);
            G3.VerifyPolygon(D, C, B);
        }
        // Make an octahedron without texture coordinates or smoothing.
        public static void AddOctahedron(this MeshGeometry3D mesh)
        {
            // Get the points.
            Point3D A, B, C, D, E, F;

            G3.OctahedronPoints(out A, out B, out C, out D, out E, out F);

            // Make the faces.
            mesh.AddPolygon(A, B, C);
            mesh.AddPolygon(A, C, D);
            mesh.AddPolygon(A, D, E);
            mesh.AddPolygon(A, E, B);
            mesh.AddPolygon(F, B, E);
            mesh.AddPolygon(F, C, B);
            mesh.AddPolygon(F, D, C);
            mesh.AddPolygon(F, E, D);
        }
        public static void VerifyCube()
        {
            // Get the points.
            Point3D A, B, C, D, E, F, G, H;

            G3.CubePoints(out A, out B, out C, out D, out E, out F, out G, out H);

            // Verify the points.
            G3.VerifyPoints(A, B, C, D, E, F, G, H);

            // Verify the faces.
            G3.VerifyPolygon(A, B, C, D);
            G3.VerifyPolygon(A, D, H, E);
            G3.VerifyPolygon(A, E, F, B);
            G3.VerifyPolygon(G, C, B, F);
            G3.VerifyPolygon(G, F, E, H);
            G3.VerifyPolygon(G, H, D, C);
        }
        public static void VerifyOctahedron()
        {
            // Get the points.
            Point3D A, B, C, D, E, F;

            G3.OctahedronPoints(out A, out B, out C, out D, out E, out F);

            // Verify the points.
            G3.VerifyPoints(A, B, C, D);

            // Verify the faces.
            G3.VerifyPolygon(A, B, C);
            G3.VerifyPolygon(A, C, D);
            G3.VerifyPolygon(A, D, E);
            G3.VerifyPolygon(A, E, B);
            G3.VerifyPolygon(F, B, E);
            G3.VerifyPolygon(F, C, B);
            G3.VerifyPolygon(F, D, C);
            G3.VerifyPolygon(F, E, D);
        }
        // Make a torus without texture coordinates.
        public static void AddTorus(this MeshGeometry3D mesh,
                                    Point3D center, double R, double r, int numTheta, int numPhi,
                                    bool smooth = false)
        {
            // Make a point dictionary if needed.
            Dictionary <Point3D, int> pointDict = null;

            if (smooth)
            {
                pointDict = new Dictionary <Point3D, int>();
            }

            // Generate the points.
            double dtheta = 2 * Math.PI / numTheta;
            double dphi   = 2 * Math.PI / numPhi;
            double theta  = 0;

            for (int t = 0; t < numTheta; t++)
            {
                double phi = 0;
                for (int p = 0; p < numPhi; p++)
                {
                    // Find this piece's points.
                    Point3D[] points =
                    {
                        G3.TorusPoint(center, R, r, theta + dtheta, phi),
                        G3.TorusPoint(center, R, r, theta + dtheta, phi + dphi),
                        G3.TorusPoint(center, R, r, theta,          phi + dphi),
                        G3.TorusPoint(center, R, r, theta,          phi),
                    };

                    // Make the polygon.
                    mesh.AddPolygon(pointDict, points);

                    phi += dphi;
                }
                theta += dtheta;
            }
        }
        // Add a textured torus.
        public static void AddTexturedTorus(this MeshGeometry3D mesh,
                                            Point3D center, double R, double r, int numTheta, int numPhi,
                                            bool smooth = false)
        {
            double dtheta = 2 * Math.PI / numTheta;
            double dphi   = 2 * Math.PI / numPhi;
            double theta  = Math.PI;        // Puts the texture's top/bottom on the inside.

            for (int t = 0; t < numTheta; t++)
            {
                double phi = 0;
                for (int p = 0; p < numPhi; p++)
                {
                    // Find this piece's points.
                    Point3D point1 = G3.TorusPoint(center, R, r, theta, phi).Round();
                    Point3D point2 = G3.TorusPoint(center, R, r, theta + dtheta, phi).Round();
                    Point3D point3 = G3.TorusPoint(center, R, r, theta + dtheta, phi + dphi).Round();
                    Point3D point4 = G3.TorusPoint(center, R, r, theta, phi + dphi).Round();

                    // Find this piece's normals.
                    Vector3D normal1 = G3.TorusNormal(D3.Origin, R, r, theta, phi);
                    Vector3D normal2 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi);
                    Vector3D normal3 = G3.TorusNormal(D3.Origin, R, r, theta + dtheta, phi + dphi);
                    Vector3D normal4 = G3.TorusNormal(D3.Origin, R, r, theta, phi + dphi);

                    // Find this piece's texture coordinates.
                    Point coords1 = new Point(1 - (double)p / numPhi, 1 - (double)t / numTheta);
                    Point coords2 = new Point(1 - (double)p / numPhi, 1 - (double)(t + 1) / numTheta);
                    Point coords3 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)(t + 1) / numTheta);
                    Point coords4 = new Point(1 - (double)(p + 1) / numPhi, 1 - (double)t / numTheta);

                    // Make the first triangle.
                    int index = mesh.Positions.Count;
                    mesh.Positions.Add(point1);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal1);
                    }
                    mesh.TextureCoordinates.Add(coords1);

                    mesh.Positions.Add(point2);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal2);
                    }
                    mesh.TextureCoordinates.Add(coords2);

                    mesh.Positions.Add(point3);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal3);
                    }
                    mesh.TextureCoordinates.Add(coords3);

                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);

                    // Make the second triangle.
                    mesh.Positions.Add(point1);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal1);
                    }
                    mesh.TextureCoordinates.Add(coords1);

                    mesh.Positions.Add(point3);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal3);
                    }
                    mesh.TextureCoordinates.Add(coords3);

                    mesh.Positions.Add(point4);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal4);
                    }
                    mesh.TextureCoordinates.Add(coords4);

                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);

                    phi += dphi;
                }
                theta += dtheta;
            }

            // Add texture coordinates 1.01 to prevent "seams."
            mesh.Positions.Add(new Point3D());
            mesh.TextureCoordinates.Add(new Point(1.01, 1.01));
        }
        // Add a sphere with texture coordinates.
        public static void AddTexturedSphere(this MeshGeometry3D mesh,
                                             Point3D center, double radius, int numTheta, int numPhi,
                                             bool smooth = false)
        {
            double dtheta = 2 * Math.PI / numTheta;
            double dphi   = Math.PI / numPhi;
            double theta  = 0;

            for (int t = 0; t < numTheta; t++)
            {
                double phi = 0;
                for (int p = 0; p < numPhi; p++)
                {
                    // Find this piece's points.
                    Point3D point1 = G3.SpherePoint(center, radius, theta, phi).Round();
                    Point3D point2 = G3.SpherePoint(center, radius, theta, phi + dphi).Round();
                    Point3D point3 = G3.SpherePoint(center, radius, theta + dtheta, phi + dphi).Round();
                    Point3D point4 = G3.SpherePoint(center, radius, theta + dtheta, phi).Round();

                    // Find this piece's texture coordinates.
                    Point coords1 = new Point((double)t / numTheta, (double)p / numPhi);
                    Point coords2 = new Point((double)t / numTheta, (double)(p + 1) / numPhi);
                    Point coords3 = new Point((double)(t + 1) / numTheta, (double)(p + 1) / numPhi);
                    Point coords4 = new Point((double)(t + 1) / numTheta, (double)p / numPhi);

                    // Find this piece's normals.
                    Vector3D normal1 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta, phi).Round();
                    Vector3D normal2 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta, phi + dphi).Round();
                    Vector3D normal3 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta + dtheta, phi + dphi).Round();
                    Vector3D normal4 = (Vector3D)G3.SpherePoint(D3.Origin, 1, theta + dtheta, phi).Round();

                    // Make the first triangle.
                    int index = mesh.Positions.Count;
                    mesh.Positions.Add(point1);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal1);
                    }
                    mesh.TextureCoordinates.Add(coords1);

                    mesh.Positions.Add(point2);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal2);
                    }
                    mesh.TextureCoordinates.Add(coords2);

                    mesh.Positions.Add(point3);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal3);
                    }
                    mesh.TextureCoordinates.Add(coords3);

                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);

                    // Make the second triangle.
                    mesh.Positions.Add(point1);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal1);
                    }
                    mesh.TextureCoordinates.Add(coords1);

                    mesh.Positions.Add(point3);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal3);
                    }
                    mesh.TextureCoordinates.Add(coords3);

                    mesh.Positions.Add(point4);
                    if (smooth)
                    {
                        mesh.Normals.Add(normal4);
                    }
                    mesh.TextureCoordinates.Add(coords4);

                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);
                    mesh.TriangleIndices.Add(index++);

                    phi += dphi;
                }
                theta += dtheta;
            }
        }