Exemplo n.º 1
0
        public static void ConvexHull(ref Surface surf)
        {
            if (surf.NumPoints < 4)
                return;

            //add the middle point to make a tetrahedron for some numerical stability
            Point3D Middle = new Point3D();
            for (int i = 0; i < surf.NumPoints; i++)
            {
                Middle += surf.Point(i);
            }
            Middle /= surf.NumPoints;
            int mid = surf.AddPoint(Middle);

            //clean out the faces, and add faces of a tetrahedron using the first 3 pts and the middle.
            Point3D inside = (surf.Point(0) + surf.Point(1) + surf.Point(2) + surf.Point(mid)) / 4.0;
            while (surf.NumFaces > 0)
                surf.RemoveFace(0);
            surf.AddFace(0, 1, 2, inside);
            surf.AddFace(0, 1, mid, inside);
            surf.AddFace(0, 2, mid, inside);
            surf.AddFace(1, 2, mid, inside);

            // add in points one at a time, remove and replace faces as necessary
            for (int i = 3; i < surf.NumPoints; i++)
            {
                List<Edge> Edges = new List<Edge>();
                //for the ith point...

                //go through the each existing face,
                for (int j = surf.NumFaces - 1; j >= 0; j--)
                {
                    //if a triangle is facing our new point, remove the face, add its edges to a list.
                    double tmp = Point3D.Dot(surf.FaceNormal(j), surf.Point(i) - surf.Point(surf.Face(j).I));
                    if (Point3D.Dot(surf.FaceNormal(j), (surf.Point(i) - surf.Point(surf.Face(j).I)).Normalized) > -DMS.EPSILON)
                    {
                        Edges.Add(new Edge(surf.Face(j).I, surf.Face(j).J));
                        Edges.Add(new Edge(surf.Face(j).J, surf.Face(j).K));
                        Edges.Add(new Edge(surf.Face(j).K, surf.Face(j).I));
                        surf.RemoveFace(j);
                    }
                }

                //now add a triangle using any non duplicated edges together with our new point.
                Edges.Sort(Edge.Comparison);
                for (int j = 0; j < Edges.Count(); j++)
                {
                    if (j != Edges.Count() - 1 && Edges[j] == Edges[j + 1])
                    {
                        //this edge is a duplicate, do nothing.
                        j++; //we'll skip the next one which is a duplicate too.
                        continue;
                    }

                    surf.AddFace(Edges[j].I, Edges[j].J, i, inside);
                }
            }
        }
Exemplo n.º 2
0
        static void Main(string[] args)
        {
            #if false //test code
            StreamWriter testsw = new StreamWriter("D:\\PersonalProjects\\Bridges 2011\\artshow\\sphere.stl");
            testsw.WriteLine("solid sphereshell");
            new Sphere(36.128, 5, true).Output(testsw, 1.0);
            //Torus(5, 1.5, 3).Output(testsw, 1.0);
            testsw.WriteLine("endsolid");
            testsw.Close();
            return;
            #endif

            ModelType model = ModelType.Outside;
            if (args.Count() > 1)
            {
                try { model = (ModelType)(Int16.Parse(args[1])); }
                catch { model = ModelType.Outside; }
            }

            double dRadius = 50.0;
            double dHalfLineWidth = 0.5;
            double dHalfLineHeight = 0.4;

            if (model == ModelType.Empty)
            {
                dHalfLineWidth = 0.5;
                dHalfLineHeight = 1.0;
                dRadius = 36.128 + dHalfLineHeight; //inside shell is a little smaller than white plastic ball
            }

            string Filename = args[0];
            if (model == ModelType.Empty)
                Filename += "_empty.stl";
            else if (model == ModelType.Inside)
                Filename += "_glow.stl";
            else if (model == ModelType.Outside)
                Filename += ".stl";

            StreamWriter sw = new StreamWriter(Filename);

            if (model == ModelType.Inside || model == ModelType.Outside)
            {
                sw.WriteLine("solid sphereshell");
                Surface SphereSurface = new Surface();

                if (model == ModelType.Inside)
                {
                    SphereSurface.AddSurface(new Sphere(dRadius + dHalfLineHeight + 1.95, 6, true));
                    SphereSurface.AddSurface(new Sphere(dRadius + dHalfLineHeight - 0.05, 4, false));
                }
                else if (model == ModelType.Outside)
                {
                    SphereSurface.AddSurface(new Sphere(dRadius - dHalfLineHeight - 1.95, 4, true));
                    SphereSurface.AddSurface(new Sphere(dRadius - dHalfLineHeight + 0.05, 6, false));
                }

                Point3D HolePunch = new Point3D(0, -1, 0).ScaledTo(dRadius);
                SurfaceTools.PunchHole(ref SphereSurface, //surf
                                        HolePunch, //center
                                        HolePunch, //direction
                                        10,        //length
                                        1.2);      //radius

                SphereSurface.Output(sw, 1.0);
                sw.WriteLine("endsolid");
            }

            sw.WriteLine("solid tour");

            Tour newTour = new Tour(args[0] + ".csv", dRadius, dHalfLineWidth, dHalfLineHeight);
            Surface TourSurface = new Surface();
            TourSurface.AddSurface(newTour);
            TourSurface.Output(sw, 1.0);

            sw.WriteLine("endsolid");

            sw.Close();
        }
Exemplo n.º 3
0
        public static void PunchHole(ref Surface surf, Point3D center, Point3D direction, double Length, double Radius)
        {
            Surface HoleWall = new Surface();
            List<int> HoleIdxs = new List<int>();
            Point3D dir = direction.Normalized;

            for (int i = 0; i < surf.NumPoints; i++)
            {
                if (!IsInCylinder(surf.Point(i), center, dir, Length, Radius))
                    continue;

                for (int j = surf.NumFaces - 1; j >= 0; j--)
                {
                    if (surf.Face(j).I == i ||
                        surf.Face(j).J == i ||
                        surf.Face(j).K == i)
                    {
                        if (!IsInCylinder(surf.Point(surf.Face(j).I), center, dir, Length, Radius)) HoleIdxs.Add(surf.Face(j).I);
                        if (!IsInCylinder(surf.Point(surf.Face(j).J), center, dir, Length, Radius)) HoleIdxs.Add(surf.Face(j).J);
                        if (!IsInCylinder(surf.Point(surf.Face(j).K), center, dir, Length, Radius)) HoleIdxs.Add(surf.Face(j).K);
                        surf.RemoveFace(j);
                    }
                }

            }

            //make sure points in hole wall are unique
            for (int j = HoleIdxs.Count() - 1; j >= 0; j--)
            {
                Point3D NewPt = surf.Point(HoleIdxs[j]);

                //check that existing points in HoleWall surface don't match
                int k;
                for (k = 0; k < HoleWall.NumPoints; k++)
                {
                    if (NewPt == HoleWall.Point(k))
                        break;
                }

                //add if we haven't found it.
                if (k == HoleWall.NumPoints)
                    HoleWall.AddPoint(NewPt);
            }

            //get the convex hull faces, then either remove them if they're pointing in our direction, or reverse them

            ConvexHull(ref HoleWall);
            for (int i = HoleWall.NumFaces - 1; i >= 0; i--)
            {
                double IR = HoleWall.Point(HoleWall.Face(i).I).R;
                double JR = HoleWall.Point(HoleWall.Face(i).J).R;
                double KR = HoleWall.Point(HoleWall.Face(i).K).R;

                if ( IR > center.R && JR > center.R && KR > center.R ||
                     IR < center.R && JR < center.R && KR < center.R )
                {
                    HoleWall.RemoveFace(i);
                }
                else
                {
                    HoleWall.Face(i).Reverse();
                }
            }

            //add in the new hole wall
            surf.AddSurface(HoleWall);
        }
Exemplo n.º 4
0
 public void AddSurface(Surface s2)
 {
     int nFaces = mFaces.Count;
     int nPoints = mPts.Count;
     mFaces.AddRange(s2.mFaces);
     mPts.AddRange(s2.mPts);
     for (int i = nFaces; i < mFaces.Count; i++)
     {
         mFaces[i].Offset(nPoints);
     }
 }