Ejemplo n.º 1
0
		public static Matrix3D CalcRotationMatrix(double x, double y, double z, Point3D center, Vector3D up, Vector3D look, Transform3D transform, RotationType type)
		{
			//Transform3DGroup trm = new Transform3DGroup();
			//trm.Children.Add(transform);
			Vector3D realup = transform.Transform(up);
			if (type != RotationType.LockAxisY)
			{
				up = realup;
			}
			if (type != RotationType.LockAxisZ)
			{
				look = transform.Transform(look);
			}
			center = transform.Transform(center);
			Vector3D axisX = Vector3D.CrossProduct(up, look);
			Matrix3D matrix = new Matrix3D();
			//Quaternion q = new Quaternion();
			//q.
			double ang = AngleBetween(realup, YAxis) + x;
			if (ang >= 90)
			{
				x = 90 - ang;
			}
			matrix.RotateAt(new Quaternion(axisX, x), center);
			matrix.RotateAt(new Quaternion(up, y), center);
			matrix.RotateAt(new Quaternion(look, z), center);
			return matrix;
		}
 public static PerspectiveCamera GetTransformedPerspectiveCamera(PerspectiveCamera camera, Transform3D transform)
 {
     return new PerspectiveCamera
     {
         LookDirection = transform.Transform(camera.LookDirection),
         UpDirection = transform.Transform(camera.UpDirection),
         FieldOfView = camera.FieldOfView,
         FarPlaneDistance = camera.FarPlaneDistance,
         NearPlaneDistance = camera.NearPlaneDistance,
         Position = transform.Transform(camera.Position)
     };
 }
Ejemplo n.º 3
0
		public static Matrix3D CalculateRotationMatrix(double x, double y, double z, Point3D center, Vector3D up, Vector3D look, Transform3D transform)
		{
			//Transform3DGroup trm = new Transform3DGroup();
			//trm.Children.Add(transform);
			up = transform.Transform(up);
			look = transform.Transform(look);
			center = transform.Transform(center);
			Vector3D axisZ = Vector3D.CrossProduct(up, look);
			Matrix3D matrix = new Matrix3D();
			matrix.RotateAt(new Quaternion(axisZ, x), center);
			matrix.RotateAt(new Quaternion(up, y), center);
			matrix.RotateAt(new Quaternion(look, z), center);
			return matrix;
		}
        // http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Components-PostAttachments/00-04-01-86-12/SceneSortingHelper_2E00_cs

        /// <summary>
        /// Sort Modelgroups in Farthest to Closest order, to enable transparency
        /// Should be applied whenever the scene is significantly re-oriented
        /// </summary>
        public static void AlphaSort(Point3D cameraPosition, Model3DCollection models, Transform3D worldTransform)
        {
            var sortedList = models.OrderBy(model => Point3D.Subtract(cameraPosition, worldTransform.Transform(model.Bounds.Location)).Length);
            models.Clear();
            foreach (var model in sortedList)
            {
                models.Add(model);
            }
        }
Ejemplo n.º 5
0
		public static MatrixTransform3D Rotate3D(Transform3D transform, Vector3D look, Vector3D dir, Point3D center)
		{
			Matrix3D m = new Matrix3D();
			Vector3D realook = transform.Transform(look);
			Vector3D axis = Vector3D.CrossProduct(realook, dir);
			double angle = Math.Acos(Vector3D.DotProduct(realook, dir));
			Quaternion q = new Quaternion(axis, angle);
			m.RotateAt(q, center);
			MatrixTransform3D rlt = transform as MatrixTransform3D;
			return new MatrixTransform3D(Matrix3D.Multiply(rlt.Matrix, m));
		}
Ejemplo n.º 6
0
 public void ExportMesh(MeshGeometry3D m, Transform3D t)
 {
     Dictionary<int, int> dictionary = new Dictionary<int, int>();
     Dictionary<int, int> dictionary2 = new Dictionary<int, int>();
     Dictionary<int, int> dictionary3 = new Dictionary<int, int>();
     int num = 0;
     foreach (Point3D pointd in m.Positions)
     {
         dictionary.Add(num++, this.vertexIndex++);
         Point3D pointd2 = t.Transform(pointd);
         this.writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "v {0} {1} {2}", new object[] { pointd2.X, pointd2.Y, pointd2.Z }));
     }
     num = 0;
     foreach (Point point in m.TextureCoordinates)
     {
         if (!(double.IsNegativeInfinity(point.X) || double.IsPositiveInfinity(point.Y)))
         {
             dictionary2.Add(num++, this.textureIndex++);
             this.writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "vt {0} {1}", new object[] { point.X, point.Y }));
         }
         else
         {
             num++;
         }
     }
     num = 0;
     foreach (Vector3D vectord in m.Normals)
     {
         if (!(double.IsNegativeInfinity(vectord.X) || double.IsPositiveInfinity(vectord.Y)))
         {
             dictionary3.Add(num++, this.normalIndex++);
             this.writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "vn {0} {1} {2}", new object[] { vectord.X, vectord.Y, vectord.Z }));
         }
         else
         {
             num++;
         }
     }
     for (int i = 0; i < m.TriangleIndices.Count; i += 3)
     {
         int num6;
         int key = m.TriangleIndices[i];
         int num4 = m.TriangleIndices[i + 1];
         int num5 = m.TriangleIndices[i + 2];
         this.writer.WriteLine("f {0}/{1}{2} {3}/{4}{5} {6}/{7}{8}", new object[] { dictionary[key], dictionary2.ContainsKey(key) ? (num6 = dictionary2[key]).ToString() : string.Empty, dictionary3.ContainsKey(key) ? ("/" + (num6 = dictionary3[key]).ToString()) : string.Empty, dictionary[num4], dictionary2.ContainsKey(num4) ? (num6 = dictionary2[num4]).ToString() : string.Empty, dictionary3.ContainsKey(num4) ? ("/" + (num6 = dictionary3[num4]).ToString()) : string.Empty, dictionary[num5], dictionary2.ContainsKey(num5) ? (num6 = dictionary2[num5]).ToString() : string.Empty, dictionary3.ContainsKey(num5) ? ("/" + (num6 = dictionary3[num5]).ToString()) : string.Empty });
     }
 }
Ejemplo n.º 7
0
        private static void GetDome(ref int pointOffset, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, int numSegmentsPhi, double radiusX, double radiusY, double radiusZ)
        {
            #region Initial calculations

            // NOTE: There is one more than what the passed in
            Point[] pointsPhi = new Point[numSegmentsPhi + 1];

            pointsPhi[0] = new Point(1d, 0d);		// along the equator
            pointsPhi[numSegmentsPhi] = new Point(0d, 1d);		// north pole

            if (pointsPhi.Length > 2)
            {
                // Need to go from 0 to half pi
                double halfPi = Math.PI * .5d;
                double deltaPhi = halfPi / pointsPhi.Length;		// there is one more point than numSegmentsPhi

                for (int cntr = 1; cntr < numSegmentsPhi; cntr++)
                {
                    double phi = deltaPhi * cntr;		// phi goes from 0 to pi for a full sphere, so start halfway up
                    pointsPhi[cntr] = new Point(Math.Cos(phi), Math.Sin(phi));
                }
            }

            #endregion

            #region Positions/Normals

            // Can't use all of the transform passed in for the normal, because translate portions will skew the normal funny
            Transform3DGroup normalTransform = new Transform3DGroup();
            if (transform is Transform3DGroup)
            {
                foreach (var subTransform in ((Transform3DGroup)transform).Children)
                {
                    if (!(subTransform is TranslateTransform3D))
                    {
                        normalTransform.Children.Add(subTransform);
                    }
                }
            }
            else if (transform is TranslateTransform3D)
            {
                normalTransform.Children.Add(Transform3D.Identity);
            }
            else
            {
                normalTransform.Children.Add(transform);
            }

            //for (int phiCntr = 0; phiCntr < numSegmentsPhi; phiCntr++)		// The top point will be added after this loop
            for (int phiCntr = pointsPhi.Length - 1; phiCntr > 0; phiCntr--)
            {
                for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++)
                {
                    // Phi points are going from bottom to equator.  

                    Point3D point = new Point3D(
                        radiusX * pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y,
                        radiusY * pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y,
                        radiusZ * pointsPhi[phiCntr].X);

                    geometry.Positions.Add(transform.Transform(point));

                    //TODO: For a standalone dome, the bottom rings will point straight out.  But for something like a snow cone, the normal will have to be averaged with the cone
                    geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit());		// the normal is the same as the point for a sphere (but no tranlate transform)
                }
            }

            // This is north pole point
            geometry.Positions.Add(transform.Transform(new Point3D(0, 0, radiusZ)));
            geometry.Normals.Add(transform.Transform(new Vector3D(0, 0, 1)));

            #endregion

            #region Triangles - Rings

            int zOffsetBottom = pointOffset;
            int zOffsetTop;

            for (int phiCntr = 0; phiCntr < numSegmentsPhi - 1; phiCntr++)		// The top cone will be added after this loop
            {
                zOffsetTop = zOffsetBottom + pointsTheta.Length;

                for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++)
                {
                    // Top/Left triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0);
                    geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1);
                    geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 0);

                    // Bottom/Right triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0);
                    geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 1);
                    geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1);
                }

                // Connecting the last 2 points to the first 2
                // Top/Left triangle
                geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0);
                geometry.TriangleIndices.Add(zOffsetTop);		// wrapping back around
                geometry.TriangleIndices.Add(zOffsetTop + (pointsTheta.Length - 1) + 0);

                // Bottom/Right triangle
                geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0);
                geometry.TriangleIndices.Add(zOffsetBottom);
                geometry.TriangleIndices.Add(zOffsetTop);

                // Prep for the next ring
                zOffsetBottom = zOffsetTop;
            }

            #endregion
            #region Triangles - Cap

            int topIndex = geometry.Positions.Count - 1;

            for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++)
            {
                geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                geometry.TriangleIndices.Add(topIndex);
            }

            // The last triangle links back to zero
            geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0);
            geometry.TriangleIndices.Add(zOffsetBottom + 0);
            geometry.TriangleIndices.Add(topIndex);

            #endregion

            pointOffset = geometry.Positions.Count;
        }
Ejemplo n.º 8
0
        public static MeshGeometry3D GetCircle2D(int numSides, Transform3D transform, Transform3D normalTransform)
        {
            //NOTE: This also sets the texture coordinates

            int pointOffset = 0;
            Point[] pointsTheta = Math2D.GetCircle_Cached(numSides);

            MeshGeometry3D retVal = new MeshGeometry3D();

            #region Positions/Normals

            for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++)
            {
                Point3D point = new Point3D(pointsTheta[thetaCntr].X, pointsTheta[thetaCntr].Y, 0d);
                retVal.Positions.Add(transform.Transform(point));

                Point texturePoint = new Point(.5d + (pointsTheta[thetaCntr].X * .5d), .5d + (pointsTheta[thetaCntr].Y * .5d));
                retVal.TextureCoordinates.Add(texturePoint);

                Vector3D normal = new Vector3D(0, 0, 1);
                retVal.Normals.Add(normalTransform.Transform(normal));
            }

            #endregion

            #region Add the triangles

            // Start with 0,1,2
            retVal.TriangleIndices.Add(pointOffset + 0);
            retVal.TriangleIndices.Add(pointOffset + 1);
            retVal.TriangleIndices.Add(pointOffset + 2);

            int lowerIndex = 2;
            int upperIndex = pointsTheta.Length - 1;
            int lastUsedIndex = 0;
            bool shouldBumpLower = true;

            // Do the rest of the triangles
            while (lowerIndex < upperIndex)
            {
                retVal.TriangleIndices.Add(pointOffset + lowerIndex);
                retVal.TriangleIndices.Add(pointOffset + upperIndex);
                retVal.TriangleIndices.Add(pointOffset + lastUsedIndex);

                if (shouldBumpLower)
                {
                    lastUsedIndex = lowerIndex;
                    lowerIndex++;
                }
                else
                {
                    lastUsedIndex = upperIndex;
                    upperIndex--;
                }

                shouldBumpLower = !shouldBumpLower;
            }

            #endregion

            return retVal;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// This overload takes an actual mesh
        /// </summary>
        public static Point3D[] GetPointsFromMesh(MeshGeometry3D mesh, Transform3D transform = null)
        {
            if (mesh == null)
            {
                return null;
            }

            Point3D[] points = null;
            if (mesh.TriangleIndices != null && mesh.TriangleIndices.Count > 0)
            {
                // Referenced points
                points = mesh.TriangleIndices.Select(o => mesh.Positions[o]).ToArray();
            }
            else
            {
                // Directly used points
                points = mesh.Positions.ToArray();
            }

            if (transform != null)
            {
                transform.Transform(points);
            }

            // Exit Function
            return points;
        }
Ejemplo n.º 10
0
            private static void EndCap_PlateHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingBase ring, bool isFirst)
            {
                Vector3D normal = normalTransform.Transform(new Vector3D(0, 0, 1)).ToUnit();

                // Start with 0,1,2
                geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[0].X, pointsTheta[0].Y, 0d)));
                geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[1].X, pointsTheta[1].Y, 0d)));
                geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[2].X, pointsTheta[2].Y, 0d)));

                geometry.Normals.Add(normal);
                geometry.Normals.Add(normal);
                geometry.Normals.Add(normal);

                geometry.TriangleIndices.Add(pointOffset + 0);
                geometry.TriangleIndices.Add(pointOffset + 1);
                geometry.TriangleIndices.Add(pointOffset + 2);

                int lowerIndex = 2;
                int upperIndex = pointsTheta.Length - 1;
                int lastUsedIndex = 0;
                bool shouldBumpLower = true;

                int localOffset = 3;

                // Do the rest of the triangles
                while (lowerIndex < upperIndex)
                {
                    geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[lowerIndex].X, pointsTheta[lowerIndex].Y, 0d)));
                    geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[upperIndex].X, pointsTheta[upperIndex].Y, 0d)));
                    geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[lastUsedIndex].X, pointsTheta[lastUsedIndex].Y, 0d)));

                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(pointOffset + localOffset + 0);
                    geometry.TriangleIndices.Add(pointOffset + localOffset + 1);
                    geometry.TriangleIndices.Add(pointOffset + localOffset + 2);

                    if (shouldBumpLower)
                    {
                        lastUsedIndex = lowerIndex;
                        lowerIndex++;
                    }
                    else
                    {
                        lastUsedIndex = upperIndex;
                        upperIndex--;
                    }

                    shouldBumpLower = !shouldBumpLower;

                    localOffset += 3;
                }

                // Update ref param
                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 11
0
        private static void GetRingSprtCap(ref int pointOffset, MeshGeometry3D geometry, Transform3D transform, Point[] points, int numSides, double innerRadius, double outerRadius)
        {
            // Points/Normals
            for (int cntr = 0; cntr < numSides; cntr++)
            {
                geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * outerRadius, points[cntr].Y * outerRadius, 0d)));
                geometry.Normals.Add(transform.Transform(new Vector3D(0, 0, 1)).ToUnit());
            }

            for (int cntr = 0; cntr < numSides; cntr++)
            {
                geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * innerRadius, points[cntr].Y * innerRadius, 0d)));
                geometry.Normals.Add(transform.Transform(new Vector3D(0, 0, 1)).ToUnit());
            }

            int zOffsetOuter = pointOffset;
            int zOffsetInner = zOffsetOuter + numSides;

            // Triangles
            for (int cntr = 0; cntr < numSides - 1; cntr++)
            {
                // Bottom Right triangle
                geometry.TriangleIndices.Add(zOffsetOuter + cntr + 0);
                geometry.TriangleIndices.Add(zOffsetOuter + cntr + 1);
                geometry.TriangleIndices.Add(zOffsetInner + cntr + 1);

                // Top Left triangle
                geometry.TriangleIndices.Add(zOffsetOuter + cntr + 0);
                geometry.TriangleIndices.Add(zOffsetInner + cntr + 1);
                geometry.TriangleIndices.Add(zOffsetInner + cntr + 0);
            }

            // Connecting the last 2 points to the first 2
            // Bottom/Right triangle
            geometry.TriangleIndices.Add(zOffsetOuter + (numSides - 1) + 0);
            geometry.TriangleIndices.Add(zOffsetOuter);
            geometry.TriangleIndices.Add(zOffsetInner);

            // Top/Left triangle
            geometry.TriangleIndices.Add(zOffsetOuter + (numSides - 1) + 0);
            geometry.TriangleIndices.Add(zOffsetInner);		// wrapping back around
            geometry.TriangleIndices.Add(zOffsetInner + (numSides - 1) + 0);

            pointOffset = geometry.Positions.Count;
        }
Ejemplo n.º 12
0
            private static void EndCap_ConeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, TubeRingPoint ring, double capHeight, bool isFirst)
            {
                Point3D tipPosition = transform.Transform(new Point3D(0, 0, capHeight));

                int localOffset = 0;

                for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++)
                {
                    geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[cntr].X, pointsTheta[cntr].Y, 0d)));
                    geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[cntr + 1].X, pointsTheta[cntr + 1].Y, 0d)));
                    geometry.Positions.Add(tipPosition);

                    Vector3D normal = GetNormal(geometry.Positions[pointOffset + localOffset + 0], geometry.Positions[pointOffset + localOffset + 1], geometry.Positions[pointOffset + localOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(pointOffset + localOffset + 0);
                    geometry.TriangleIndices.Add(pointOffset + localOffset + 1);
                    geometry.TriangleIndices.Add(pointOffset + localOffset + 2);

                    localOffset += 3;
                }

                // The last triangle links back to zero
                geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[pointsTheta.Length - 1].X, pointsTheta[pointsTheta.Length - 1].Y, 0d)));
                geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[0].X, pointsTheta[0].Y, 0d)));
                geometry.Positions.Add(tipPosition);

                Vector3D normal2 = GetNormal(geometry.Positions[pointOffset + localOffset + 0], geometry.Positions[pointOffset + localOffset + 1], geometry.Positions[pointOffset + localOffset + 2]);
                geometry.Normals.Add(normal2);		// the normals point straight out of the face
                geometry.Normals.Add(normal2);
                geometry.Normals.Add(normal2);

                geometry.TriangleIndices.Add(pointOffset + localOffset + 0);
                geometry.TriangleIndices.Add(pointOffset + localOffset + 1);
                geometry.TriangleIndices.Add(pointOffset + localOffset + 2);

                // Update ref param
                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 13
0
        private static ShipDNA RotateDNA_DoIt(ShipDNA dna, Quaternion rotation, Transform3D positionTransform)
        {
            ShipDNA retVal = UtilityCore.Clone(dna);

            foreach (ShipPartDNA part in retVal.PartsByLayer.SelectMany(o => o.Value))
            {
                // Rotate the orientation
                //part.Orientation = part.Orientation.RotateBy(rotation);
                part.Orientation = rotation.RotateBy(part.Orientation);


                // Apply a transform to the poisition
                part.Position = positionTransform.Transform(part.Position);


                //TODO: See if these need to be rotated as well
                //part.Neurons;
                //part.ExternalLinks;
                //part.InternalLinks;
            }

            return retVal;
        }
Ejemplo n.º 14
0
        public static Dodecahedron GetDodecahedron(double radius, Transform3D transform = null)
        {
            // This is 12 pentagons

            #region Points

            double t = (1d + Math.Sqrt(5d)) / 2d;
            double t1 = 1d / t;

            Point3D[] points = new Point3D[]
            {
                //(±1, ±1, ±1)
                new Point3D(1, 1, 1),       // 0
                new Point3D(1, 1, -1),      // 1
                new Point3D(1, -1, 1),      // 2
                new Point3D(1, -1, -1),     // 3
                new Point3D(-1, 1, 1),      // 4
                new Point3D(-1, 1, -1),     // 5
                new Point3D(-1, -1, 1),     // 6
                new Point3D(-1, -1, -1),        // 7

                //(0, ±1/φ, ±φ)
                new Point3D(0, t1, t),      // 8
                new Point3D(0, t1, -t),     // 9
                new Point3D(0, -t1, t),     // 10
                new Point3D(0, -t1, -t),        // 11

                //(±1/φ, ±φ, 0)
                new Point3D(t1, t, 0),      // 12
                new Point3D(t1, -t, 0),     // 13
                new Point3D(-t1, t, 0),     // 14
                new Point3D(-t1, -t, 0),        // 15

                //(±φ, 0, ±1/φ)
                new Point3D(t, 0, t1),      // 16
                new Point3D(t, 0, -t1),     // 17
                new Point3D(-t, 0, t1),     // 18
                new Point3D(-t, 0, -t1),        // 19
            };

            double maxLength = points[8].ToVector().Length;     // this represents the longest vector
            double ratio = radius / maxLength;
            points = points.Select(o => (o.ToVector() * ratio).ToPoint()).ToArray();

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] pentagonPolys = new int[][]
            {
                new int [] { 2, 10, 6, 15, 13 },
                new int [] { 0, 8, 10, 2, 16 },
                new int [] { 0, 12, 14, 4, 8 },
                new int [] { 1, 9, 5, 14, 12 },
                new int [] { 1, 17, 3, 11, 9 },
                new int [] { 2, 13, 3, 17, 16 },
                new int [] { 3, 13, 15, 7, 11 },
                new int [] { 6, 18, 19, 7, 15 },
                new int [] { 4, 18, 6, 10, 8 },
                new int [] { 4, 14, 5, 19, 18 },
                new int [] { 5, 9, 11, 7, 19 },
                new int [] { 0, 16, 17, 1, 12 },
            };

            return new Dodecahedron(pentagonPolys, points);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// The export mesh.
        /// </summary>
        /// <param name="m">
        /// The m.
        /// </param>
        /// <param name="t">
        /// The t.
        /// </param>
        public void ExportMesh(MeshGeometry3D m, Transform3D t)
        {
            if (m == null)
            {
                throw new ArgumentNullException("m");
            }

            if (t == null)
            {
                throw new ArgumentNullException("t");
            }

            // mapping from local indices (0-based) to the obj file indices (1-based)
            var vertexIndexMap = new Dictionary<int, int>();
            var textureIndexMap = new Dictionary<int, int>();
            var normalIndexMap = new Dictionary<int, int>();

            int index = 0;
            if (m.Positions != null)
            {
                foreach (var v in m.Positions)
                {
                    vertexIndexMap.Add(index++, this.vertexIndex++);
                    var p = t.Transform(v);
                    this.writer.WriteLine(
                        string.Format(
                            CultureInfo.InvariantCulture,
                            "v {0} {1} {2}",
                            p.X,
                            this.SwitchYZ ? p.Z : p.Y,
                            this.SwitchYZ ? -p.Y : p.Z));
                }

                this.writer.WriteLine(string.Format("# {0} vertices", index));
            }

            if (m.TextureCoordinates != null)
            {
                index = 0;
                foreach (var vt in m.TextureCoordinates)
                {
                    textureIndexMap.Add(index++, this.textureIndex++);
                    this.writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "vt {0} {1}", vt.X, 1 - vt.Y));
                }

                this.writer.WriteLine(string.Format("# {0} texture coordinates", index));
            }

            if (m.Normals != null && ExportNormals)
            {
                index = 0;
                foreach (var vn in m.Normals)
                {
                    normalIndexMap.Add(index++, this.normalIndex++);
                    this.writer.WriteLine(
                        string.Format(CultureInfo.InvariantCulture, "vn {0} {1} {2}", vn.X, vn.Y, vn.Z));
                }

                this.writer.WriteLine(string.Format("# {0} normals", index));
            }

            Func<int, string> formatIndices = i0 =>
                {
                    bool hasTextureIndex = textureIndexMap.ContainsKey(i0);
                    bool hasNormalIndex = normalIndexMap.ContainsKey(i0);
                    if (hasTextureIndex && hasNormalIndex)
                    {
                        return string.Format("{0}/{1}/{2}", vertexIndexMap[i0], textureIndexMap[i0], normalIndexMap[i0]);
                    }

                    if (hasTextureIndex)
                    {
                        return string.Format("{0}/{1}", vertexIndexMap[i0], textureIndexMap[i0]);
                    }

                    if (hasNormalIndex)
                    {
                        return string.Format("{0}//{1}", vertexIndexMap[i0], normalIndexMap[i0]);
                    }

                    return vertexIndexMap[i0].ToString();
                };

            if (m.TriangleIndices != null)
            {
                for (int i = 0; i < m.TriangleIndices.Count; i += 3)
                {
                    int i0 = m.TriangleIndices[i];
                    int i1 = m.TriangleIndices[i + 1];
                    int i2 = m.TriangleIndices[i + 2];

                    this.writer.WriteLine("f {0} {1} {2}", formatIndices(i0), formatIndices(i1), formatIndices(i2));
                }

                this.writer.WriteLine(string.Format("# {0} faces", m.TriangleIndices.Count / 3));
            }

            this.writer.WriteLine();
        }
Ejemplo n.º 16
0
        public static Rhombicuboctahedron GetRhombicuboctahedron(double sizeX, double sizeY, double sizeZ, Transform3D transform = null)
        {
            #region Points

            double hX = sizeX / 2d;
            double hY = sizeY / 2d;
            double hZ = sizeZ / 2d;

            double sqrt2_1 = Math.Sqrt(2) + 1d;
            double sX = (sizeX / sqrt2_1) / 2d;     // sX is half the width of one of the faces (the faces form an octogon)
            double sY = (sizeY / sqrt2_1) / 2d;
            double sZ = (sizeZ / sqrt2_1) / 2d;

            // Points
            Point3D[] points = new Point3D[]
            {
                // Top 4
                new Point3D(sX, sY, hZ),        // 0
                new Point3D(sX, -sY, hZ),       // 1
                new Point3D(-sX, -sY, hZ),      // 2
                new Point3D(-sX, sY, hZ),      // 3

                // Top 8
                new Point3D(hX, sY, sZ),        // 4
                new Point3D(hX, -sY, sZ),       // 5
                new Point3D(sX, -hY, sZ),       // 6
                new Point3D(-sX, -hY, sZ),      // 7
                new Point3D(-hX, -sY, sZ),      // 8
                new Point3D(-hX, sY, sZ),       // 9
                new Point3D(-sX, hY, sZ),       // 10
                new Point3D(sX, hY, sZ),        // 11

                // Bottom 8
                new Point3D(hX, sY, -sZ),       // 12
                new Point3D(hX, -sY, -sZ),      // 13
                new Point3D(sX, -hY, -sZ),      // 14
                new Point3D(-sX, -hY, -sZ),     // 15
                new Point3D(-hX, -sY, -sZ),     // 16
                new Point3D(-hX, sY, -sZ),      // 17
                new Point3D(-sX, hY, -sZ),      // 18
                new Point3D(sX, hY, -sZ),       // 19

                // Bottom 4
                new Point3D(sX, sY, -hZ),       // 20
                new Point3D(sX, -sY, -hZ),      // 21
                new Point3D(-sX, -sY, -hZ),     // 22
                new Point3D(-sX, sY, -hZ),     // 23
            };

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] squarePolys_Orth = new int[][]
            {
                new int[] { 0, 3, 2, 1 },       // Top
                new int[] { 4, 5, 13, 12 },     // Right
                new int[] { 6, 7, 15, 14 },     // Front
                new int[] { 8, 9, 17, 16 },     // Left
                new int[] { 10, 11, 19, 18 },       // Back
                new int[] { 20, 21, 22, 23 },       // Bottom
            };

            int[][] squarePolys_Diag = new int[][]
            {
                // Top 4 angled
                new int[] {0, 1, 5, 4 },
                new int[] { 1, 2, 7, 6 },
                new int[] { 2, 3, 9, 8 },
                new int[] { 0, 11, 10, 3 },

                // Middle 4 angled
                new int[] { 4, 12, 19, 11 },
                new int[] { 5, 6, 14, 13 },
                new int[] { 7, 8, 16, 15 },
                new int[] { 9, 10, 18, 17 },

                // Bottom 4 angled
                new int[] { 12, 13, 21, 20 },
                new int[] { 14, 15, 22, 21 },
                new int[] { 16, 17, 23, 22 },
                new int[] { 18, 19, 20, 23 },
            };

            TriangleIndexed[] triangles = new TriangleIndexed[]
            {
                // Top 4
                new TriangleIndexed(0, 4, 11, points),
                new TriangleIndexed(1, 6, 5, points),
                new TriangleIndexed(2, 8, 7, points),
                new TriangleIndexed(3, 10, 9, points),

                // Bottom 4
                new TriangleIndexed(12, 20, 19, points),
                new TriangleIndexed(13, 14, 21, points),
                new TriangleIndexed(15, 16, 22, points),
                new TriangleIndexed(17, 18, 23, points),
            };

            return new Rhombicuboctahedron(squarePolys_Orth, squarePolys_Diag, triangles, points);
        }
Ejemplo n.º 17
0
        public static Icosidodecahedron GetIcosidodecahedron(double radius, Transform3D transform = null)
        {
            //NOTE: Don't confuse this with an icosahedron.  That is the more common object (made of equilateral triangles).
            //This object is made of pentagons and triangles.  I'm just making this because it looks cool

            #region Points

            double t = (1d + Math.Sqrt(5d)) / 2d;
            double t2 = t / 2d;
            double t3 = (1d + t) / 2d;

            Point3D[] points = new Point3D[]
            {
                //(0,0,±φ)
                new Point3D(0, 0, t),       // 0
                new Point3D(0, 0, -t),      // 1

                //(0,±φ,0)
                new Point3D(0, t, 0),       // 2
                new Point3D(0, -t, 0),      // 3

                //(±φ,0,0)
                new Point3D(t, 0, 0),       // 4
                new Point3D(-t, 0, 0),      // 5

                //(±1/2, ±φ/2, ±(1+φ)/2)
                new Point3D(.5, t2, t3),        // 6
                new Point3D(.5, t2, -t3),       // 7
                new Point3D(.5, -t2, t3),       // 8
                new Point3D(.5, -t2, -t3),      // 9
                new Point3D(-.5, t2, t3),       // 10
                new Point3D(-.5, t2, -t3),      // 11
                new Point3D(-.5, -t2, t3),      // 12
                new Point3D(-.5, -t2, -t3),     // 13

                //(±φ/2, ±(1+φ)/2, ±1/2)
                new Point3D(t2, t3, .5),        // 14
                new Point3D(t2, t3, -.5),       // 15
                new Point3D(t2, -t3, .5),       // 16
                new Point3D(t2, -t3, -.5),      // 17
                new Point3D(-t2, t3, .5),       // 18
                new Point3D(-t2, t3, -.5),      // 19
                new Point3D(-t2, -t3, .5),      // 20
                new Point3D(-t2, -t3, -.5),     // 21

                //(±(1+φ)/2, ±1/2, ±φ/2)
                new Point3D(t3, .5, t2),        // 22
                new Point3D(t3, .5, -t2),       // 23
                new Point3D(t3, -.5, t2),       // 24
                new Point3D(t3, -.5, -t2),      // 25
                new Point3D(-t3, .5, t2),       // 26
                new Point3D(-t3, .5, -t2),      // 27
                new Point3D(-t3, -.5, t2),      // 28
                new Point3D(-t3, -.5, -t2),     // 29
            };

            double maxLength = points[6].ToVector().Length;     // this represents the longest vector
            double ratio = radius / maxLength;
            points = points.Select(o => (o.ToVector() * ratio).ToPoint()).ToArray();

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] pentagonPolys = new int[][]
            {
                new int [] { 0, 10, 26, 28, 12 },
                new int [] { 26, 18, 19, 27, 5 },
                new int [] { 5, 29, 21, 20, 28 },
                new int [] { 10, 6, 14, 2, 18 },
                new int [] { 3, 16, 8, 12, 20 },
                new int [] { 0, 8, 24, 22, 6 },
                new int [] { 9, 17, 3, 21, 13 },
                new int [] { 27, 11, 1, 13, 29 },
                new int [] { 4, 24, 16, 17, 25 },
                new int [] { 1, 7, 23, 25, 9 },
                new int [] { 4, 23, 15, 14, 22 },
                new int [] { 2, 15, 7, 11, 19 },
            };

            TriangleIndexed[] triangles = new TriangleIndexed[]
            {
                new TriangleIndexed(0, 12, 8, points),
                new TriangleIndexed(0, 6, 10, points),
                new TriangleIndexed(10, 18, 26, points),
                new TriangleIndexed(5, 28, 26, points),
                new TriangleIndexed(12, 28, 20, points),
                new TriangleIndexed(3, 20, 21, points),
                new TriangleIndexed(8, 16, 24, points),
                new TriangleIndexed(3, 17, 16, points),
                new TriangleIndexed(9, 25, 17, points),
                new TriangleIndexed(4, 25, 23, points),
                new TriangleIndexed(4, 22, 24, points),
                new TriangleIndexed(13, 21, 29, points),
                new TriangleIndexed(1, 9, 13, points),
                new TriangleIndexed(1, 11, 7, points),
                new TriangleIndexed(11, 27, 19, points),
                new TriangleIndexed(5, 27, 29, points),
                new TriangleIndexed(6, 22, 14, points),
                new TriangleIndexed(2, 14, 15, points),
                new TriangleIndexed(2, 19, 18, points),
                new TriangleIndexed(7, 15, 23, points),
            };

            return new Icosidodecahedron(pentagonPolys, triangles, points);
        }
Ejemplo n.º 18
0
            private static void EndCap_DomeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst)
            {
                // NOTE: There is one more than NumSegmentsPhi
                Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi);

                #region Positions/Normals

                //for (int phiCntr = 0; phiCntr < numSegmentsPhi; phiCntr++)		// The top point will be added after this loop
                for (int phiCntr = pointsPhi.Length - 1; phiCntr > 0; phiCntr--)
                {
                    if (!isFirst && ring.MergeNormalWithPrevIfSoft)
                    {
                        // Just reuse the points/normals from the previous ring
                        continue;
                    }

                    for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++)
                    {
                        // Phi points are going from bottom to equator.  
                        // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle)

                        Point3D point = new Point3D(
                            pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y,
                            pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y,
                            capHeight * pointsPhi[phiCntr].X);

                        geometry.Positions.Add(transform.Transform(point));

                        if (ring.MergeNormalWithPrevIfSoft)
                        {
                            //TODO:  Merge the normal with rotateAngleForPerp (see the GetCone method)
                            throw new ApplicationException("finish this");
                        }
                        else
                        {
                            geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit());		// the normal is the same as the point for a sphere (but no tranlate transform)
                        }
                    }
                }

                // This is north pole point
                geometry.Positions.Add(transform.Transform(new Point3D(0, 0, capHeight)));
                geometry.Normals.Add(normalTransform.Transform(new Vector3D(0, 0, capHeight < 0 ? -1 : 1)));        // they can enter a negative height (which would make a bowl)

                #endregion

                #region Triangles - Rings

                int zOffsetBottom = pointOffset;
                int zOffsetTop;

                for (int phiCntr = 0; phiCntr < ring.NumSegmentsPhi - 1; phiCntr++)		// The top cone will be added after this loop
                {
                    zOffsetTop = zOffsetBottom + pointsTheta.Length;

                    for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++)
                    {
                        // Top/Left triangle
                        geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0);
                        geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1);
                        geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 0);

                        // Bottom/Right triangle
                        geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0);
                        geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 1);
                        geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1);
                    }

                    // Connecting the last 2 points to the first 2
                    // Top/Left triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0);
                    geometry.TriangleIndices.Add(zOffsetTop);		// wrapping back around
                    geometry.TriangleIndices.Add(zOffsetTop + (pointsTheta.Length - 1) + 0);

                    // Bottom/Right triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0);
                    geometry.TriangleIndices.Add(zOffsetBottom);
                    geometry.TriangleIndices.Add(zOffsetTop);

                    // Prep for the next ring
                    zOffsetBottom = zOffsetTop;
                }

                #endregion
                #region Triangles - Cap

                int topIndex = geometry.Positions.Count - 1;

                for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++)
                {
                    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                    geometry.TriangleIndices.Add(topIndex);
                }

                // The last triangle links back to zero
                geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0);
                geometry.TriangleIndices.Add(zOffsetBottom + 0);
                geometry.TriangleIndices.Add(topIndex);


                //for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++)
                //{
                //    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                //    geometry.TriangleIndices.Add(topIndex);
                //    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                //}

                //// The last triangle links back to zero
                //geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0);
                //geometry.TriangleIndices.Add(topIndex);
                //geometry.TriangleIndices.Add(zOffsetBottom + 0);


                #endregion

                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 19
0
            private static void Middle_TubeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Transform3D transform, int numSides, TubeRingRegularPolygon ring1, TubeRingRegularPolygon ring2, double curZ)
            {
                Point[] points = Math2D.GetCircle_Cached(numSides);

                int zOffset = pointOffset;

                for (int cntr = 0; cntr < numSides - 1; cntr++)
                {
                    // Top/Left triangle (each triangle gets its own 3 points)
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * ring1.RadiusX, points[cntr].Y * ring1.RadiusY, curZ)));
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr + 1].X * ring2.RadiusX, points[cntr + 1].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * ring2.RadiusX, points[cntr].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));

                    Vector3D normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(zOffset + 0);
                    geometry.TriangleIndices.Add(zOffset + 1);
                    geometry.TriangleIndices.Add(zOffset + 2);

                    zOffset += 3;

                    // Bottom/Right triangle
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * ring1.RadiusX, points[cntr].Y * ring1.RadiusY, curZ)));
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr + 1].X * ring1.RadiusX, points[cntr + 1].Y * ring1.RadiusY, curZ)));
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr + 1].X * ring2.RadiusX, points[cntr + 1].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));

                    normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(zOffset + 0);
                    geometry.TriangleIndices.Add(zOffset + 1);
                    geometry.TriangleIndices.Add(zOffset + 2);

                    zOffset += 3;
                }

                // Connecting the last 2 points to the first 2

                // Top/Left triangle
                geometry.Positions.Add(transform.Transform(new Point3D(points[numSides - 1].X * ring1.RadiusX, points[numSides - 1].Y * ring1.RadiusY, curZ)));
                geometry.Positions.Add(transform.Transform(new Point3D(points[0].X * ring2.RadiusX, points[0].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));
                geometry.Positions.Add(transform.Transform(new Point3D(points[numSides - 1].X * ring2.RadiusX, points[numSides - 1].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));

                Vector3D normal2 = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                geometry.Normals.Add(normal2);		// the normals point straight out of the face
                geometry.Normals.Add(normal2);
                geometry.Normals.Add(normal2);

                geometry.TriangleIndices.Add(zOffset + 0);
                geometry.TriangleIndices.Add(zOffset + 1);
                geometry.TriangleIndices.Add(zOffset + 2);

                zOffset += 3;

                // Bottom/Right triangle
                geometry.Positions.Add(transform.Transform(new Point3D(points[numSides - 1].X * ring1.RadiusX, points[numSides - 1].Y * ring1.RadiusY, curZ)));
                geometry.Positions.Add(transform.Transform(new Point3D(points[0].X * ring1.RadiusX, points[0].Y * ring1.RadiusY, curZ)));
                geometry.Positions.Add(transform.Transform(new Point3D(points[0].X * ring2.RadiusX, points[0].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));

                normal2 = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                geometry.Normals.Add(normal2);		// the normals point straight out of the face
                geometry.Normals.Add(normal2);
                geometry.Normals.Add(normal2);

                geometry.TriangleIndices.Add(zOffset + 0);
                geometry.TriangleIndices.Add(zOffset + 1);
                geometry.TriangleIndices.Add(zOffset + 2);

                // Update ref param
                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 20
0
            private static void Middle_TubeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Transform3D transform, int numSides, TubeRingRegularPolygon ring1, TubeRingRegularPolygon ring2, double curZ)
            {
                if (ring1.MergeNormalWithPrevIfSoft || ring2.MergeNormalWithPrevIfSoft)
                {
                    throw new ApplicationException("finish this");
                }

                Point[] points = Math2D.GetCircle_Cached(numSides);

                #region Points/Normals

                //TODO: Don't add the bottom ring's points, only the top

                // Ring 1
                for (int cntr = 0; cntr < numSides; cntr++)
                {
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * ring1.RadiusX, points[cntr].Y * ring1.RadiusY, curZ)));
                    geometry.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * ring1.RadiusX, points[cntr].Y * ring1.RadiusY, 0d).ToUnit()));		// the normals point straight out of the side
                }

                // Ring 2
                for (int cntr = 0; cntr < numSides; cntr++)
                {
                    geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * ring2.RadiusX, points[cntr].Y * ring2.RadiusY, curZ + ring2.DistFromPrevRing)));
                    geometry.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * ring2.RadiusX, points[cntr].Y * ring2.RadiusY, 0d).ToUnit()));		// the normals point straight out of the side
                }

                #endregion

                #region Triangles

                int zOffsetBottom = pointOffset;
                int zOffsetTop = zOffsetBottom + numSides;

                for (int cntr = 0; cntr < numSides - 1; cntr++)
                {
                    // Top/Left triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    geometry.TriangleIndices.Add(zOffsetTop + cntr + 1);
                    geometry.TriangleIndices.Add(zOffsetTop + cntr + 0);

                    // Bottom/Right triangle
                    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                    geometry.TriangleIndices.Add(zOffsetTop + cntr + 1);
                }

                // Connecting the last 2 points to the first 2
                // Top/Left triangle
                geometry.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                geometry.TriangleIndices.Add(zOffsetTop);		// wrapping back around
                geometry.TriangleIndices.Add(zOffsetTop + (numSides - 1) + 0);

                // Bottom/Right triangle
                geometry.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                geometry.TriangleIndices.Add(zOffsetBottom);
                geometry.TriangleIndices.Add(zOffsetTop);

                #endregion

                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 21
0
            private static void EndCap_DomeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst)
            {
                // NOTE: There is one more than NumSegmentsPhi
                Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi);

                Point3D point;
                Vector3D normal;
                int zOffset = pointOffset;

                #region Triangles - Rings

                for (int phiCntr = 1; phiCntr < pointsPhi.Length - 1; phiCntr++)		// The top cone will be added after this loop
                {
                    for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++)
                    {
                        // Phi points are going from bottom to equator                          <----------- NO?????????
                        // Phi points are going from the equator to the top

                        // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle)

                        #region Top/Left triangle

                        point = new Point3D(
                            pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y,
                            pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y,
                            capHeight * pointsPhi[phiCntr].X);

                        geometry.Positions.Add(transform.Transform(point));

                        point = new Point3D(
                            pointsTheta[thetaCntr].X * pointsPhi[phiCntr + 1].Y,
                            pointsTheta[thetaCntr].Y * pointsPhi[phiCntr + 1].Y,
                            capHeight * pointsPhi[phiCntr + 1].X);

                        geometry.Positions.Add(transform.Transform(point));

                        point = new Point3D(
                            pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y,
                            pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y,
                            capHeight * pointsPhi[phiCntr + 1].X);

                        geometry.Positions.Add(transform.Transform(point));

                        normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                        geometry.Normals.Add(normal);		// the normals point straight out of the face
                        geometry.Normals.Add(normal);
                        geometry.Normals.Add(normal);

                        geometry.TriangleIndices.Add(zOffset + 0);
                        geometry.TriangleIndices.Add(zOffset + 1);
                        geometry.TriangleIndices.Add(zOffset + 2);

                        #endregion

                        zOffset += 3;

                        #region Bottom/Right triangle

                        point = new Point3D(
                            pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y,
                            pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y,
                            capHeight * pointsPhi[phiCntr].X);

                        geometry.Positions.Add(transform.Transform(point));

                        point = new Point3D(
                            pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y,
                            pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y,
                            capHeight * pointsPhi[phiCntr + 1].X);

                        geometry.Positions.Add(transform.Transform(point));

                        point = new Point3D(
                            pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr].Y,
                            pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr].Y,
                            capHeight * pointsPhi[phiCntr].X);

                        geometry.Positions.Add(transform.Transform(point));

                        normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                        geometry.Normals.Add(normal);		// the normals point straight out of the face
                        geometry.Normals.Add(normal);
                        geometry.Normals.Add(normal);

                        geometry.TriangleIndices.Add(zOffset + 0);
                        geometry.TriangleIndices.Add(zOffset + 1);
                        geometry.TriangleIndices.Add(zOffset + 2);

                        #endregion

                        zOffset += 3;
                    }

                    // Connecting the last 2 points to the first 2
                    #region Top/Left triangle

                    point = new Point3D(
                        pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y,
                        pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y,
                        capHeight * pointsPhi[phiCntr].X);

                    geometry.Positions.Add(transform.Transform(point));

                    point = new Point3D(
                        pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr + 1].Y,
                        pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr + 1].Y,
                        capHeight * pointsPhi[phiCntr + 1].X);

                    geometry.Positions.Add(transform.Transform(point));

                    point = new Point3D(
                        pointsTheta[0].X * pointsPhi[phiCntr + 1].Y,        // wrapping theta back around
                        pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y,
                        capHeight * pointsPhi[phiCntr + 1].X);

                    geometry.Positions.Add(transform.Transform(point));

                    normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(zOffset + 0);
                    geometry.TriangleIndices.Add(zOffset + 1);
                    geometry.TriangleIndices.Add(zOffset + 2);

                    #endregion

                    zOffset += 3;

                    #region Bottom/Right triangle

                    point = new Point3D(
                        pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y,
                        pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y,
                        capHeight * pointsPhi[phiCntr].X);

                    geometry.Positions.Add(transform.Transform(point));

                    point = new Point3D(
                        pointsTheta[0].X * pointsPhi[phiCntr + 1].Y,
                        pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y,
                        capHeight * pointsPhi[phiCntr + 1].X);

                    geometry.Positions.Add(transform.Transform(point));

                    point = new Point3D(
                        pointsTheta[0].X * pointsPhi[phiCntr].Y,
                        pointsTheta[0].Y * pointsPhi[phiCntr].Y,
                        capHeight * pointsPhi[phiCntr].X);

                    geometry.Positions.Add(transform.Transform(point));

                    normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(zOffset + 0);
                    geometry.TriangleIndices.Add(zOffset + 1);
                    geometry.TriangleIndices.Add(zOffset + 2);

                    #endregion

                    zOffset += 3;
                }

                #endregion
                #region Triangles - Cap

                // This is basically the same idea as EndCap_ConeHard, except for the extra phi bits

                Point3D topPoint = transform.Transform(new Point3D(0, 0, capHeight));

                for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++)
                {
                    point = new Point3D(
                        pointsTheta[thetaCntr].X * pointsPhi[1].Y,
                        pointsTheta[thetaCntr].Y * pointsPhi[1].Y,
                        capHeight * pointsPhi[1].X);

                    geometry.Positions.Add(transform.Transform(point));

                    point = new Point3D(
                        pointsTheta[thetaCntr + 1].X * pointsPhi[1].Y,
                        pointsTheta[thetaCntr + 1].Y * pointsPhi[1].Y,
                        capHeight * pointsPhi[1].X);

                    geometry.Positions.Add(transform.Transform(point));

                    geometry.Positions.Add(topPoint);

                    normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                    geometry.Normals.Add(normal);		// the normals point straight out of the face
                    geometry.Normals.Add(normal);
                    geometry.Normals.Add(normal);

                    geometry.TriangleIndices.Add(zOffset + 0);
                    geometry.TriangleIndices.Add(zOffset + 1);
                    geometry.TriangleIndices.Add(zOffset + 2);

                    zOffset += 3;
                }

                // The last triangle links back to zero
                point = new Point3D(
                    pointsTheta[pointsTheta.Length - 1].X * pointsPhi[1].Y,
                    pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[1].Y,
                    capHeight * pointsPhi[1].X);

                geometry.Positions.Add(transform.Transform(point));

                point = new Point3D(
                    pointsTheta[0].X * pointsPhi[1].Y,
                    pointsTheta[0].Y * pointsPhi[1].Y,
                    capHeight * pointsPhi[1].X);

                geometry.Positions.Add(transform.Transform(point));

                geometry.Positions.Add(topPoint);

                normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]);
                geometry.Normals.Add(normal);		// the normals point straight out of the face
                geometry.Normals.Add(normal);
                geometry.Normals.Add(normal);

                geometry.TriangleIndices.Add(zOffset + 0);
                geometry.TriangleIndices.Add(zOffset + 1);
                geometry.TriangleIndices.Add(zOffset + 2);

                zOffset += 3;

                #endregion

                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 22
0
        private static void GetMeshSprtFace_OLD(ref int pointOffset, MeshGeometry3D mesh, Transform3D transform, double halfWidth, double halfHeight, double tip)
        {
            // Bottom
            mesh.Positions.Add(transform.Transform(new Point3D(-halfWidth, -halfHeight, 0)));		// left bottom
            mesh.Positions.Add(transform.Transform(new Point3D(halfWidth, -halfHeight, 0)));		// right bottom
            mesh.Positions.Add(transform.Transform(new Point3D(0, 0, tip)));		// tip
            mesh.TriangleIndices.Add(pointOffset + 0);
            mesh.TriangleIndices.Add(pointOffset + 1);
            mesh.TriangleIndices.Add(pointOffset + 2);
            pointOffset += 3;

            // Right
            mesh.Positions.Add(transform.Transform(new Point3D(halfWidth, -halfHeight, 0)));		// right bottom
            mesh.Positions.Add(transform.Transform(new Point3D(halfWidth, halfHeight, 0)));		// right top
            mesh.Positions.Add(transform.Transform(new Point3D(0, 0, tip)));		// tip
            mesh.TriangleIndices.Add(pointOffset + 0);
            mesh.TriangleIndices.Add(pointOffset + 1);
            mesh.TriangleIndices.Add(pointOffset + 2);
            pointOffset += 3;

            // Top
            mesh.Positions.Add(transform.Transform(new Point3D(halfWidth, halfHeight, 0)));		// right top
            mesh.Positions.Add(transform.Transform(new Point3D(-halfWidth, halfHeight, 0)));		// left top
            mesh.Positions.Add(transform.Transform(new Point3D(0, 0, tip)));		// tip
            mesh.TriangleIndices.Add(pointOffset + 0);
            mesh.TriangleIndices.Add(pointOffset + 1);
            mesh.TriangleIndices.Add(pointOffset + 2);
            pointOffset += 3;

            // Left
            mesh.Positions.Add(transform.Transform(new Point3D(-halfWidth, halfHeight, 0)));		// left top
            mesh.Positions.Add(transform.Transform(new Point3D(-halfWidth, -halfHeight, 0)));		// left bottom
            mesh.Positions.Add(transform.Transform(new Point3D(0, 0, tip)));		// tip
            mesh.TriangleIndices.Add(pointOffset + 0);
            mesh.TriangleIndices.Add(pointOffset + 1);
            mesh.TriangleIndices.Add(pointOffset + 2);
            pointOffset += 3;
        }
Ejemplo n.º 23
0
            private static void EndCap_ConeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingPoint ring, double capHeight, bool isFirst)
            {
                #region Positions/Normals

                if (isFirst || !ring.MergeNormalWithPrevIfSoft)
                {
                    for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++)
                    {
                        Point3D point = new Point3D(pointsTheta[thetaCntr].X, pointsTheta[thetaCntr].Y, 0d);
                        geometry.Positions.Add(transform.Transform(point));
                        geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit());		// the normal is the same as the point for a sphere (but no tranlate transform)
                    }
                }

                // Cone tip
                geometry.Positions.Add(transform.Transform(new Point3D(0, 0, capHeight)));
                geometry.Normals.Add(transform.Transform(new Vector3D(0, 0, capHeight < 0 ? -1 : 1)));      // they can pass in a negative cap height

                #endregion

                #region Triangles

                int topIndex = geometry.Positions.Count - 1;

                for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++)
                {
                    geometry.TriangleIndices.Add(pointOffset + cntr + 0);
                    geometry.TriangleIndices.Add(pointOffset + cntr + 1);
                    geometry.TriangleIndices.Add(topIndex);
                }

                // The last triangle links back to zero
                geometry.TriangleIndices.Add(pointOffset + pointsTheta.Length - 1 + 0);
                geometry.TriangleIndices.Add(pointOffset + 0);
                geometry.TriangleIndices.Add(topIndex);

                #endregion

                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 24
0
        private static void GetCylinder_AlongXSprtEndCap(ref int pointOffset, MeshGeometry3D geometry, Point[] points, Vector3D normal, double radiusX, double radiusY, double z, Transform3D transform)
        {
            //NOTE: This expects the cylinder's height to be along z, but will transform the points before commiting them to the geometry
            //TODO: This was copied from GetMultiRingedTubeSprtEndCap, make a good generic method

            #region Add points and normals

            for (int cntr = 0; cntr < points.Length; cntr++)
            {
                geometry.Positions.Add(transform.Transform(new Point3D(points[cntr].X * radiusX, points[cntr].Y * radiusY, z)));
                geometry.Normals.Add(transform.Transform(normal));
            }

            #endregion

            #region Add the triangles

            // Start with 0,1,2
            geometry.TriangleIndices.Add(pointOffset + 0);
            geometry.TriangleIndices.Add(pointOffset + 1);
            geometry.TriangleIndices.Add(pointOffset + 2);

            int lowerIndex = 2;
            int upperIndex = points.Length - 1;
            int lastUsedIndex = 0;
            bool shouldBumpLower = true;

            // Do the rest of the triangles
            while (lowerIndex < upperIndex)
            {
                geometry.TriangleIndices.Add(pointOffset + lowerIndex);
                geometry.TriangleIndices.Add(pointOffset + upperIndex);
                geometry.TriangleIndices.Add(pointOffset + lastUsedIndex);

                if (shouldBumpLower)
                {
                    lastUsedIndex = lowerIndex;
                    lowerIndex++;
                }
                else
                {
                    lastUsedIndex = upperIndex;
                    upperIndex--;
                }

                shouldBumpLower = !shouldBumpLower;
            }

            #endregion

            pointOffset += points.Length;
        }
Ejemplo n.º 25
0
            private static void EndCap_PlateSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingBase ring, bool isFirst)
            {
                #region Positions/Normals

                if (isFirst || !ring.MergeNormalWithPrevIfSoft)
                {
                    for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++)
                    {
                        Point3D point = new Point3D(pointsTheta[thetaCntr].X, pointsTheta[thetaCntr].Y, 0d);
                        geometry.Positions.Add(transform.Transform(point));

                        Vector3D normal;
                        if (ring.MergeNormalWithPrevIfSoft)
                        {
                            //normal = point.ToVector();		// this isn't right
                            throw new ApplicationException("finish this");
                        }
                        else
                        {
                            normal = new Vector3D(0, 0, 1);
                        }

                        geometry.Normals.Add(normalTransform.Transform(normal).ToUnit());
                    }
                }

                #endregion

                #region Add the triangles

                // Start with 0,1,2
                geometry.TriangleIndices.Add(pointOffset + 0);
                geometry.TriangleIndices.Add(pointOffset + 1);
                geometry.TriangleIndices.Add(pointOffset + 2);

                int lowerIndex = 2;
                int upperIndex = pointsTheta.Length - 1;
                int lastUsedIndex = 0;
                bool shouldBumpLower = true;

                // Do the rest of the triangles
                while (lowerIndex < upperIndex)
                {
                    geometry.TriangleIndices.Add(pointOffset + lowerIndex);
                    geometry.TriangleIndices.Add(pointOffset + upperIndex);
                    geometry.TriangleIndices.Add(pointOffset + lastUsedIndex);

                    if (shouldBumpLower)
                    {
                        lastUsedIndex = lowerIndex;
                        lowerIndex++;
                    }
                    else
                    {
                        lastUsedIndex = upperIndex;
                        upperIndex--;
                    }

                    shouldBumpLower = !shouldBumpLower;
                }

                #endregion

                pointOffset = geometry.Positions.Count;
            }
Ejemplo n.º 26
0
        public static MeshGeometry3D GetRing(int numSides, double innerRadius, double outerRadius, double height, Transform3D transform = null, bool includeInnerRingFaces = true, bool includeOuterRingFaces = true)
        {
            MeshGeometry3D retVal = new MeshGeometry3D();

            if (transform == null)
            {
                transform = Transform3D.Identity;
            }

            Point[] points = Math2D.GetCircle_Cached(numSides);
            double halfHeight = height * .5d;

            int pointOffset = 0;
            int zOffsetBottom, zOffsetTop;

            #region Outer Ring

            #region Positions/Normals

            for (int cntr = 0; cntr < numSides; cntr++)
            {
                retVal.Positions.Add(transform.Transform(new Point3D(points[cntr].X * outerRadius, points[cntr].Y * outerRadius, -halfHeight)));
                retVal.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * outerRadius, points[cntr].Y * outerRadius, 0d).ToUnit()));		// the normals point straight out of the side
            }

            for (int cntr = 0; cntr < numSides; cntr++)
            {
                retVal.Positions.Add(transform.Transform(new Point3D(points[cntr].X * outerRadius, points[cntr].Y * outerRadius, halfHeight)));
                retVal.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * outerRadius, points[cntr].Y * outerRadius, 0d).ToUnit()));		// the normals point straight out of the side
            }

            #endregion

            if (includeOuterRingFaces)
            {
                #region Triangles

                zOffsetBottom = pointOffset;
                zOffsetTop = zOffsetBottom + numSides;

                for (int cntr = 0; cntr < numSides - 1; cntr++)
                {
                    // Top/Left triangle
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 1);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 0);

                    // Bottom/Right triangle
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 1);
                }

                // Connecting the last 2 points to the first 2
                // Top/Left triangle
                retVal.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                retVal.TriangleIndices.Add(zOffsetTop);		// wrapping back around
                retVal.TriangleIndices.Add(zOffsetTop + (numSides - 1) + 0);

                // Bottom/Right triangle
                retVal.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                retVal.TriangleIndices.Add(zOffsetBottom);
                retVal.TriangleIndices.Add(zOffsetTop);

                #endregion
            }

            pointOffset = retVal.Positions.Count;

            #endregion

            #region Inner Ring

            #region Positions/Normals

            for (int cntr = 0; cntr < numSides; cntr++)
            {
                retVal.Positions.Add(transform.Transform(new Point3D(points[cntr].X * innerRadius, points[cntr].Y * innerRadius, -halfHeight)));
                retVal.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * innerRadius, points[cntr].Y * innerRadius, 0d).ToUnit() * -1d));		// the normals point straight in from the side
            }

            for (int cntr = 0; cntr < numSides; cntr++)
            {
                retVal.Positions.Add(transform.Transform(new Point3D(points[cntr].X * innerRadius, points[cntr].Y * innerRadius, halfHeight)));
                retVal.Normals.Add(transform.Transform(new Vector3D(points[cntr].X * innerRadius, points[cntr].Y * innerRadius, 0d).ToUnit() * -1d));		// the normals point straight in from the side
            }

            #endregion

            if (includeInnerRingFaces)
            {
                #region Triangles

                zOffsetBottom = pointOffset;
                zOffsetTop = zOffsetBottom + numSides;

                for (int cntr = 0; cntr < numSides - 1; cntr++)
                {
                    // Top/Left triangle
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 0);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 1);

                    // Bottom/Right triangle
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 0);
                    retVal.TriangleIndices.Add(zOffsetTop + cntr + 1);
                    retVal.TriangleIndices.Add(zOffsetBottom + cntr + 1);
                }

                // Connecting the last 2 points to the first 2
                // Top/Left triangle
                retVal.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                retVal.TriangleIndices.Add(zOffsetTop + (numSides - 1) + 0);
                retVal.TriangleIndices.Add(zOffsetTop);		// wrapping back around

                // Bottom/Right triangle
                retVal.TriangleIndices.Add(zOffsetBottom + (numSides - 1) + 0);
                retVal.TriangleIndices.Add(zOffsetTop);
                retVal.TriangleIndices.Add(zOffsetBottom);

                #endregion
            }

            pointOffset = retVal.Positions.Count;

            #endregion

            #region Top Cap

            Transform3DGroup capTransform = new Transform3DGroup();
            capTransform.Children.Add(new TranslateTransform3D(0, 0, halfHeight));
            capTransform.Children.Add(transform);

            GetRingSprtCap(ref pointOffset, retVal, capTransform, points, numSides, innerRadius, outerRadius);

            #endregion

            #region Bottom Cap

            capTransform = new Transform3DGroup();
            capTransform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 180d)));
            capTransform.Children.Add(new TranslateTransform3D(0, 0, -halfHeight));
            capTransform.Children.Add(transform);

            GetRingSprtCap(ref pointOffset, retVal, capTransform, points, numSides, innerRadius, outerRadius);

            #endregion

            // Exit Function
            return retVal;
        }
Ejemplo n.º 27
0
        public static TruncatedIcosahedron GetTruncatedIcosahedron(double radius, Transform3D transform = null)
        {
            #region Points

            double t = (1d + Math.Sqrt(5d)) / 2d;
            double t2 = t * 2d;
            double t3 = t * 3d;
            double tA = 1d + (2d * t);
            double tB = 2d + t;

            // Length compare:
            //  t3  4.8541019662496847
            //  tA  4.23606797749979
            //  tB  3.6180339887498949
            //  t2  3.23606797749979
            //  2   2
            //  t   1.6180339887498949
            //  1   1
            //  0   0

            Point3D[] points = new Point3D[]
            {
                //------------------------------------------------- X axis
                //(±3φ, 0, ±1)
                new Point3D(t3, 0, 1),      // 0
                new Point3D(-t3, 0, 1),
                new Point3D(t3, 0, -1),
                new Point3D(-t3, 0, -1),        // 3

                //(±(1+2φ), ±φ, ±2)
                new Point3D(tA, t, 2),      // 4
                new Point3D(tA, -t, 2),
                new Point3D(-tA, t, 2),
                new Point3D(-tA, -t, 2),
                new Point3D(tA, t, -2),
                new Point3D(tA, -t, -2),
                new Point3D(-tA, t, -2),
                new Point3D(-tA, -t, -2),       // 11

                //(±(2+φ), ±2φ, ±1)
                new Point3D(tB, t2, 1),     // 12
                new Point3D(tB, t2, -1),
                new Point3D(tB, -t2, 1),
                new Point3D(tB, -t2, -1),
                new Point3D(-tB, t2, 1),
                new Point3D(-tB, t2, -1),
                new Point3D(-tB, -t2, 1),
                new Point3D(-tB, -t2, -1),      // 19

                //------------------------------------------------- Y axis
                //(±1, ±3φ, 0)
                new Point3D(1, t3, 0),      // 20
                new Point3D(1, -t3, 0),
                new Point3D(-1, t3, 0),
                new Point3D(-1, -t3, 0),        // 23

                //(±2, ±(1+2φ), ±φ)
                new Point3D(2, tA, t),      // 24
                new Point3D(2, tA, -t),
                new Point3D(2, -tA, t),
                new Point3D(2, -tA, -t),
                new Point3D(-2, tA, t),
                new Point3D(-2, tA, -t),
                new Point3D(-2, -tA, t),
                new Point3D(-2, -tA, -t),       // 31

                //(±1, ±(2+φ), ±2φ)
                new Point3D(1, tB, t2),     // 32
                new Point3D(1, tB, -t2),
                new Point3D(1, -tB, t2),
                new Point3D(1, -tB, -t2),
                new Point3D(-1, tB, t2),
                new Point3D(-1, tB, -t2),
                new Point3D(-1, -tB, t2),
                new Point3D(-1, -tB, -t2),      // 39

                //------------------------------------------------- Z axis
                //(0, ±1, ±3φ)
                new Point3D(0, 1, t3),      // 40
                new Point3D(0, 1, -t3),
                new Point3D(0, -1, t3),
                new Point3D(0, -1, -t3),        // 43

                //(±φ, ±2, ±(1+2φ))
                new Point3D(t, 2, tA),      // 44
                new Point3D(-t, 2, tA),
                new Point3D(t, 2, -tA),
                new Point3D(-t, 2, -tA),
                new Point3D(t, -2, tA),
                new Point3D(-t, -2, tA),
                new Point3D(t, -2, -tA),
                new Point3D(-t, -2, -tA),       // 51

                //(±2φ, ±1, ±(2+φ))
                new Point3D(t2, 1, tB),     // 52
                new Point3D(t2, 1, -tB),
                new Point3D(t2, -1, tB),
                new Point3D(t2, -1, -tB),
                new Point3D(-t2, 1, tB),
                new Point3D(-t2, 1, -tB),
                new Point3D(-t2, -1, tB),
                new Point3D(-t2, -1, -tB),      // 59
            };

            double maxLength = points[0].ToVector().Length;
            double ratio = radius / maxLength;
            points = points.Select(o => (o.ToVector() * ratio).ToPoint()).ToArray();

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            // Pentagons
            int[][] pentagonPolys = new int[][]
            {
                new int [] { 40, 44, 32, 36, 45 },
                new int [] { 42, 49, 38, 34, 48 },
                new int [] { 41, 47, 37, 33, 46 },
                new int [] { 43, 50, 35, 39, 51 },
                new int [] { 1, 7, 58, 56, 6 },
                new int [] { 0, 4, 52, 54, 5 },
                new int [] { 3, 10, 57, 59, 11 },
                new int [] { 2, 9, 55, 53, 8 },
                new int [] { 18, 19, 31, 23, 30 },
                new int [] { 14, 26, 21, 27, 15 },
                new int [] { 12, 13, 25, 20, 24 },
                new int [] { 16, 28, 22, 29, 17 },
            };

            // Hexagons
            int[][] hexagonPolys = new int[][]
            {
                new int [] { 40, 45, 56, 58, 49, 42 },
                new int [] { 40, 42, 48, 54, 52, 44 },
                new int [] { 41, 43, 51, 59, 57, 47 },
                new int [] { 41, 46, 53, 55, 50, 43 },
                new int [] { 1, 6, 16, 17, 10, 3 },
                new int [] { 1, 3, 11, 19, 18, 7 },
                new int [] { 0, 2, 8, 13, 12, 4 },
                new int [] { 0, 5, 14, 15, 9, 2 },
                new int [] { 34, 26, 14, 5, 54, 48 },
                new int [] { 32, 44, 52, 4, 12, 24 },
                new int [] { 38, 49, 58, 7, 18, 30 },
                new int [] { 33, 25, 13, 8, 53, 46 },
                new int [] { 35, 50, 55, 9, 15, 27 },
                new int [] { 36, 28, 16, 6, 56, 45 },
                new int [] { 39, 31, 19, 11, 59, 51 },
                new int [] { 37, 47, 57, 10, 17, 29 },
                new int [] { 20, 25, 33, 37, 29, 22 },
                new int [] { 20, 22, 28, 36, 32, 24 },
                new int [] { 21, 26, 34, 38, 30, 23 },
                new int [] { 21, 23, 31, 39, 35, 27 },
            };

            return new TruncatedIcosahedron(pentagonPolys, hexagonPolys, points);
        }
        internal static void GetMeshFace(ref int pointOffset, MeshGeometry3D mesh, Transform3D transform, double halfWidth, double halfHeight, double tip, int numPyramids)
        {
            double faceWidth = halfWidth / numPyramids;
            double faceHeight = halfHeight / numPyramids;

            int to = numPyramids - 1;
            int from = to * -1;

            for (int x = from; x <= to; x += 2)
            {
                for (int y = from; y <= to; y += 2)
                {
                    double offsetX = faceWidth * x;
                    double offsetY = faceHeight * y;

                    // Bottom
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX - faceWidth, offsetY - faceHeight, 0)));		// left bottom
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX + faceWidth, offsetY - faceHeight, 0)));		// right bottom
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX, offsetY, tip)));		// tip
                    mesh.TriangleIndices.Add(pointOffset + 0);
                    mesh.TriangleIndices.Add(pointOffset + 1);
                    mesh.TriangleIndices.Add(pointOffset + 2);
                    pointOffset += 3;

                    // Right
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX + faceWidth, offsetY - faceHeight, 0)));		// right bottom
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX + faceWidth, offsetY + faceHeight, 0)));		// right top
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX, offsetY, tip)));		// tip
                    mesh.TriangleIndices.Add(pointOffset + 0);
                    mesh.TriangleIndices.Add(pointOffset + 1);
                    mesh.TriangleIndices.Add(pointOffset + 2);
                    pointOffset += 3;

                    // Top
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX + faceWidth, offsetY + faceHeight, 0)));		// right top
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX - faceWidth, offsetY + faceHeight, 0)));		// left top
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX, offsetY, tip)));		// tip
                    mesh.TriangleIndices.Add(pointOffset + 0);
                    mesh.TriangleIndices.Add(pointOffset + 1);
                    mesh.TriangleIndices.Add(pointOffset + 2);
                    pointOffset += 3;

                    // Left
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX - faceWidth, offsetY + faceHeight, 0)));		// left top
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX - faceWidth, offsetY - faceHeight, 0)));		// left bottom
                    mesh.Positions.Add(transform.Transform(new Point3D(offsetX, offsetY, tip)));		// tip
                    mesh.TriangleIndices.Add(pointOffset + 0);
                    mesh.TriangleIndices.Add(pointOffset + 1);
                    mesh.TriangleIndices.Add(pointOffset + 2);
                    pointOffset += 3;
                }
            }
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Volumes are calculated across axis where they are whole numbers (rounded to 0 decimal places).
        /// </summary>
        /// <param name="modelFile"></param>
        /// <param name="scaleMultiplyierX"></param>
        /// <param name="scaleMultiplyierY"></param>
        /// <param name="scaleMultiplyierZ"></param>
        /// <param name="transform"></param>
        /// <param name="traceType"></param>
        /// <param name="resetProgress"></param>
        /// <param name="incrementProgress"></param>
        /// <returns></returns>
        public static CubeType[][][] ReadModelVolmetic(string modelFile, double scaleMultiplyierX, double scaleMultiplyierY, double scaleMultiplyierZ, Transform3D transform, ModelTraceVoxel traceType, Action<double, double> resetProgress, Action incrementProgress)
        {
            var model = MeshHelper.Load(modelFile, ignoreErrors: true);

            // How far to check in from the proposed Volumetric edge.
            // This number is just made up, but small enough that it still represents the corner edge of the Volumetric space.
            // But still large enough that it isn't the exact corner.
            const double offset = 0.00000456f;

            if (scaleMultiplyierX > 0 && scaleMultiplyierY > 0 && scaleMultiplyierZ > 0 && scaleMultiplyierX != 1.0f && scaleMultiplyierY != 1.0f && scaleMultiplyierZ != 1.0f)
            {
                model.TransformScale(scaleMultiplyierX, scaleMultiplyierY, scaleMultiplyierZ);
            }

            var tbounds = model.Bounds;
            if (transform != null)
                tbounds = transform.TransformBounds(tbounds);

            var xMin = (int)Math.Floor(tbounds.X);
            var yMin = (int)Math.Floor(tbounds.Y);
            var zMin = (int)Math.Floor(tbounds.Z);

            var xMax = (int)Math.Ceiling(tbounds.X + tbounds.SizeX);
            var yMax = (int)Math.Ceiling(tbounds.Y + tbounds.SizeY);
            var zMax = (int)Math.Ceiling(tbounds.Z + tbounds.SizeZ);

            var xCount = xMax - xMin;
            var yCount = yMax - yMin;
            var zCount = zMax - zMin;

            var ccubic = ArrayHelper.Create<CubeType>(xCount, yCount, zCount);

            if (resetProgress != null)
            {
                double count = (from GeometryModel3D gm in model.Children select gm.Geometry as MeshGeometry3D).Aggregate<MeshGeometry3D, double>(0, (current, g) => current + (g.TriangleIndices.Count / 3));
                if (traceType == ModelTraceVoxel.ThinSmoothed || traceType == ModelTraceVoxel.ThickSmoothedUp)
                {
                    count += (xCount * yCount * zCount * 3);
                }

                resetProgress.Invoke(0, count);
            }

            #region basic ray trace of every individual triangle.

            foreach (var model3D in model.Children)
            {
                var gm = (GeometryModel3D)model3D;
                var g = gm.Geometry as MeshGeometry3D;
                var materials = gm.Material as MaterialGroup;
                System.Windows.Media.Color color = Colors.Transparent;

                if (materials != null)
                {
                    var material = materials.Children.OfType<DiffuseMaterial>().FirstOrDefault();

                    if (material != null && material != null && material.Brush is SolidColorBrush)
                    {
                        color = ((SolidColorBrush)material.Brush).Color;
                    }
                }

                for (var t = 0; t < g.TriangleIndices.Count; t += 3)
                {
                    if (incrementProgress != null)
                    {
                        incrementProgress.Invoke();
                    }

                    var p1 = g.Positions[g.TriangleIndices[t]];
                    var p2 = g.Positions[g.TriangleIndices[t + 1]];
                    var p3 = g.Positions[g.TriangleIndices[t + 2]];

                    if (transform != null)
                    {
                        p1 = transform.Transform(p1);
                        p2 = transform.Transform(p2);
                        p3 = transform.Transform(p3);
                    }

                    var minBound = MeshHelper.Min(p1, p2, p3).Floor();
                    var maxBound = MeshHelper.Max(p1, p2, p3).Ceiling();

                    Point3D[] rays;

                    for (var y = minBound.Y; y < maxBound.Y; y++)
                    {
                        for (var z = minBound.Z; z < maxBound.Z; z++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(xMin, y + 0.5 + offset, z + 0.5 + offset), new Point3D(xMax, y + 0.5 + offset, z + 0.5 + offset)
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(xMin, y + offset, z + offset), new Point3D(xMax, y + offset, z + offset),
                                        new Point3D(xMin, y + 1 - offset, z + offset), new Point3D(xMax, y + 1 - offset, z + offset),
                                        new Point3D(xMin, y + offset, z + 1 - offset), new Point3D(xMax, y + offset, z + 1 - offset),
                                        new Point3D(xMin, y + 1 - offset, z + 1 - offset), new Point3D(xMax, y + 1 - offset, z + 1 - offset)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }

                    for (var x = minBound.X; x < maxBound.X; x++)
                    {
                        for (var z = minBound.Z; z < maxBound.Z; z++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(x + 0.5 + offset, yMin, z + 0.5 + offset), new Point3D(x + 0.5 + offset, yMax, z + 0.5 + offset)
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(x + offset, yMin, z + offset), new Point3D(x + offset, yMax, z + offset),
                                        new Point3D(x + 1 - offset, yMin, z + offset), new Point3D(x + 1 - offset, yMax, z + offset),
                                        new Point3D(x + offset, yMin, z + 1 - offset), new Point3D(x + offset, yMax, z + 1 - offset),
                                        new Point3D(x + 1 - offset, yMin, z + 1 - offset), new Point3D(x + 1 - offset, yMax, z + 1 - offset)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }

                    for (var x = minBound.X; x < maxBound.X; x++)
                    {
                        for (var y = minBound.Y; y < maxBound.Y; y++)
                        {
                            if (traceType == ModelTraceVoxel.Thin || traceType == ModelTraceVoxel.ThinSmoothed)
                            {
                                rays = new Point3D[] // 1 point ray trace in the center.
                                    {
                                        new Point3D(x + 0.5 + offset, y + 0.5 + offset, zMin), new Point3D(x + 0.5 + offset, y + 0.5 + offset, zMax),
                                    };
                            }
                            else
                            {
                                rays = new Point3D[] // 4 point ray trace within each corner of the expected Volumetric cube.
                                    {
                                        new Point3D(x + offset, y + offset, zMin), new Point3D(x + offset, y + offset, zMax),
                                        new Point3D(x + 1 - offset, y + offset, zMin), new Point3D(x + 1 - offset, y + offset, zMax),
                                        new Point3D(x + offset, y + 1 - offset, zMin), new Point3D(x + offset, y + 1 - offset, zMax),
                                        new Point3D(x + 1 - offset, y + 1 - offset, zMin), new Point3D(x + 1 - offset, y + 1 - offset, zMax)
                                    };
                            }

                            Point3D intersect;
                            int normal;
                            if (MeshHelper.RayIntersetTriangleRound(p1, p2, p3, rays, out intersect, out normal))
                            {
                                ccubic[(int)Math.Floor(intersect.X) - xMin][(int)Math.Floor(intersect.Y) - yMin][(int)Math.Floor(intersect.Z) - zMin] = CubeType.Cube;
                            }
                        }
                    }
                }
            }

            #endregion

            CrawlExterior(ccubic);

            if (traceType == ModelTraceVoxel.ThinSmoothed || traceType == ModelTraceVoxel.ThickSmoothedUp)
            {
                CalculateAddedInverseCorners(ccubic, incrementProgress);
                CalculateAddedSlopes(ccubic, incrementProgress);
                CalculateAddedCorners(ccubic, incrementProgress);
            }

            //if (traceType == ModelTraceVoxel.ThickSmoothedDown)
            //{
            //    CalculateSubtractedCorners(ccubic);
            //    CalculateSubtractedSlopes(ccubic);
            //    CalculateSubtractedInverseCorners(ccubic);
            //}

            return ccubic;
        }
Ejemplo n.º 30
0
        public static TruncatedIcosidodecahedron GetTruncatedIcosidodecahedron(double radius, Transform3D transform = null)
        {
            //TODO: Currently, the points are hardcoded.  All the polygons are regular.  Take in a ratio for the length of side of the decagons.
            //  0 would make the decagons disappar, and the squares and hexagons would be it
            //  1 would make the squares disappear and the hexagons would become triangles
            //
            //The squares are the cornerstones.  When calculating points, figure out what the centers of the various polygons are.  Then adjust the
            //sizes of the squares.  From that, find the rest of the points using the decagons.  No need to find points for the hexagons, they have
            //no unique points

            #region Points

            double t = (1d + Math.Sqrt(5d)) / 2d;       // φ
            double tS = t * t;      // φ^2
            double tI1 = 1d / t;        // 1/φ
            double tI2 = 2d / t;        // 2/φ
            double t2 = 2d * t;     // 2φ
            double tA = 1d + (2d * t);      // 1+2φ
            double tB = 2d + t;     // 2+φ
            double tC = 3d + t;     // 3+φ
            double tN1 = -1d + (3d * t);        // -1+3φ
            double tN2 = -1d + (2d * t);        // -1+2φ

            Point3D[] points = new Point3D[]
            {
                //(±1/φ, ±1/φ, ±(3+φ))
                new Point3D(tI1, tI1, tC),
                new Point3D(tI1, tI1, -tC),
                new Point3D(tI1, -tI1, tC),
                new Point3D(tI1, -tI1, -tC),
                new Point3D(-tI1, tI1, tC),
                new Point3D(-tI1, tI1, -tC),
                new Point3D(-tI1, -tI1, tC),
                new Point3D(-tI1, -tI1, -tC),

                //(±2/φ, ±φ, ±(1+2φ))
                new Point3D(tI2, t, tA),
                new Point3D(tI2, t, -tA),
                new Point3D(tI2, -t, tA),
                new Point3D(tI2, -t, -tA),
                new Point3D(-tI2, t, tA),
                new Point3D(-tI2, t, -tA),
                new Point3D(-tI2, -t, tA),
                new Point3D(-tI2, -t, -tA),

                //(±1/φ, ±φ^2, ±(-1+3φ))
                new Point3D(tI1, tS, tN1),
                new Point3D(tI1, tS, -tN1),
                new Point3D(tI1, -tS, tN1),
                new Point3D(tI1, -tS, -tN1),
                new Point3D(-tI1, tS, tN1),
                new Point3D(-tI1, tS, -tN1),
                new Point3D(-tI1, -tS, tN1),
                new Point3D(-tI1, -tS, -tN1),

                //(±(-1+2φ), ±2, ±(2+φ))
                new Point3D(tN2, 2, tB),
                new Point3D(tN2, 2, -tB),
                new Point3D(tN2, -2, tB),
                new Point3D(tN2, -2, -tB),
                new Point3D(-tN2, 2, tB),
                new Point3D(-tN2, 2, -tB),
                new Point3D(-tN2, -2, tB),
                new Point3D(-tN2, -2, -tB),

                //(±φ, ±3, ±2φ),
                new Point3D(t, 3, t2),
                new Point3D(t, 3, -t2),
                new Point3D(t, -3, t2),
                new Point3D(t, -3, -t2),
                new Point3D(-t, 3, t2),
                new Point3D(-t, 3, -t2),
                new Point3D(-t, -3, t2),
                new Point3D(-t, -3, -t2),
            };

            points = points.Select(o => new Point3D[]
            { 
                o,      // orig
                new Point3D(o.Y, o.Z, o.X),      // shift left
                new Point3D(o.Z, o.X, o.Y)       // shift left twice
            }).
            SelectMany(o => o).
            ToArray();

            double maxLength = points[0].ToVector().Length;
            double ratio = radius / maxLength;
            points = points.Select(o => (o.ToVector() * ratio).ToPoint()).ToArray();

            if (transform != null)
            {
                points = points.Select(o => transform.Transform(o)).ToArray();
            }

            #endregion

            int[][] decagonPolys = new int[][]
            {
                new int [] { 0, 6, 30, 78, 110, 62, 50, 98, 72, 24 },
                new int [] { 14, 38, 86, 100, 52, 64, 112, 92, 44, 20 },
                new int [] { 3, 27, 75, 104, 56, 68, 116, 81, 33, 9 },
                new int [] { 15, 21, 45, 93, 119, 71, 59, 107, 87, 39 },
                new int [] { 2, 8, 32, 80, 109, 61, 49, 97, 74, 26 },
                new int [] { 1, 7, 31, 79, 108, 60, 48, 96, 73, 25 },
                new int [] { 12, 36, 84, 101, 53, 65, 113, 90, 42, 18 },
                new int [] { 4, 28, 76, 102, 54, 66, 114, 82, 34, 10 },
                new int [] { 16, 22, 46, 94, 117, 69, 57, 105, 88, 40 },
                new int [] { 17, 23, 47, 95, 118, 70, 58, 106, 89, 41 },
                new int [] { 5, 29, 77, 103, 55, 67, 115, 83, 35, 11 },
                new int [] { 13, 37, 85, 99, 51, 63, 111, 91, 43, 19 },
            };

            int[][] hexagonPolys = new int[][]
            {
                new int [] { 6, 18, 42, 66, 54, 30 },
                new int [] { 82, 114, 90, 113, 89, 106 },
                new int [] { 5, 17, 41, 65, 53, 29 },
                new int [] { 77, 101, 84, 108, 79, 103 },
                new int [] { 7, 19, 43, 67, 55, 31 },
                new int [] { 83, 115, 91, 111, 87, 107 },
                new int [] { 3, 15, 39, 63, 51, 27 },
                new int [] { 0, 24, 48, 60, 36, 12 },
                new int [] { 72, 98, 74, 97, 73, 96 },
                new int [] { 1, 25, 49, 61, 37, 13 },
                new int [] { 75, 99, 85, 109, 80, 104 },
                new int [] { 76, 100, 86, 110, 78, 102 },
                new int [] { 2, 26, 50, 62, 38, 14 },
                new int [] { 8, 20, 44, 68, 56, 32 },
                new int [] { 81, 116, 92, 112, 88, 105 },
                new int [] { 9, 33, 57, 69, 45, 21 },
                new int [] { 11, 35, 59, 71, 47, 23 },
                new int [] { 93, 117, 94, 118, 95, 119 },
                new int [] { 10, 34, 58, 70, 46, 22 },
                new int [] { 4, 16, 40, 64, 52, 28 },
            };

            int[][] squarePolys = new int[][]
            {
                new int [] { 0, 12, 18, 6 },
                new int [] { 36, 60, 108, 84 },
                new int [] { 31, 55, 103, 79 },
                new int [] { 43, 91, 115, 67 },
                new int [] { 39, 87, 111, 63 },
                new int [] { 3, 9, 21, 15 },
                new int [] { 24, 72, 96, 48 },
                new int [] { 25, 73, 97, 49 },
                new int [] { 1, 13, 19, 7 },
                new int [] { 37, 61, 109, 85 },
                new int [] { 27, 51, 99, 75 },
                new int [] { 33, 81, 105, 57 },
                new int [] { 42, 90, 114, 66 },
                new int [] { 41, 89, 113, 65 },
                new int [] { 5, 11, 23, 17 },
                new int [] { 35, 83, 107, 59 },
                new int [] { 45, 69, 117, 93 },
                new int [] { 29, 53, 101, 77 },
                new int [] { 30, 54, 102, 78 },
                new int [] { 28, 52, 100, 76 },
                new int [] { 38, 62, 110, 86 },
                new int [] { 26, 74, 98, 50 },
                new int [] { 2, 14, 20, 8 },
                new int [] { 32, 56, 104, 80 },
                new int [] { 34, 82, 106, 58 },
                new int [] { 46, 70, 118, 94 },
                new int [] { 47, 71, 119, 95 },
                new int [] { 4, 10, 22, 16 },
                new int [] { 40, 88, 112, 64 },
                new int [] { 44, 92, 116, 68 },
            };

            return new TruncatedIcosidodecahedron(decagonPolys, hexagonPolys, squarePolys, points);
        }