Пример #1
0
        // a function for displaying the normals in an STL file
        public static void draw_stl_normals(GLWindow g, STLSurf s)
        {
            // draw triangle normas
            foreach (Geo.Tri t in s.tris)
            {
                // from STL file
                Geo.Point p1 = new Geo.Point(t.p[0].x, t.p[0].y, t.p[0].z);
                Geo.Point p2 = new Geo.Point(t.p[0].x + t.n.x, t.p[0].y + t.n.y, t.p[0].z + t.n.z);
                GeoLine l = new GeoLine(p1, p2);
                l.color = System.Drawing.Color.Green;
                g.addGeom(l);

                // calculate yourself:
                Vector v1 = new Vector(t.p[0].x - t.p[1].x, t.p[0].y - t.p[1].y, t.p[0].z - t.p[1].z);
                Vector v2 = new Vector(t.p[0].x - t.p[2].x, t.p[0].y - t.p[2].y, t.p[0].z - t.p[2].z);
                Vector n;
                n = v1.Cross(v2); // the normal is in the direction of the cross product between the edge vectors
                n = (1 / n.Length()) * n; // normalize to length==1
                p1 = new Geo.Point(t.p[0].x, t.p[0].y, t.p[0].z);
                p2 = new Geo.Point(t.p[0].x + n.x, t.p[0].y + n.y, t.p[0].z + n.z);
                l = new GeoLine(p1, p2);
                l.color = System.Drawing.Color.Blue;
                g.addGeom(l);

            }
        }
Пример #2
0
 public double Dot(Vector v)
 {
     // dot product
        return x * v.x + y * v.y + z * v.z;
 }
Пример #3
0
 public Vector Cross(Vector v)
 {
     // cross product
        // NEEDS TESTING!
        double xc = y * v.z - z * v.y;
        double yc = z * v.x - x * v.z;
        double zc = x * v.y - y * v.x;
        return new Vector(xc, yc, zc);
 }
Пример #4
0
 public void recalc_normals()
 {
     // normal data from STL files is usually junk, so recalculate:
        Vector v1 = new Vector(p[0].x - p[1].x, p[0].y - p[1].y, p[0].z - p[1].z);
        Vector v2 = new Vector(p[0].x - p[2].x, p[0].y - p[2].y, p[0].z- p[2].z);
        n = v1.Cross(v2); // the normal is in the direction of the cross product between the edge vectors
        n = (1 / n.Length()) * n; // normalize to length==1
 }
Пример #5
0
 public Tri(Vector N)
 {
     // a strange constructor indeed...
        p = new Point[3];
        bb = new Bbox();
        p[0] = new Point();
        p[1] = new Point();
        p[2] = new Point();
        n = N;
 }
Пример #6
0
 public Tri(Point P1, Point P2, Point P3, Vector N)
 {
     p = new Point[3];
        bb = new Bbox();
        p[0] = P1;
        p[1] = P2;
        p[2] = P3;
        n = N;
 }
Пример #7
0
 public Tri(Point P1, Point P2, Point P3)
 {
     p = new Point[3];
        bb = new Bbox();
        p[0] = P1;
        p[1] = P2;
        p[2] = P3;
        // if normal is not given, calculate it here.
        Vector v1 = new Vector(p[0].x - p[1].x, p[0].y - p[1].y, p[0].z - p[1].z);
        Vector v2 = new Vector(p[0].x - p[2].x, p[0].y - p[2].y, p[0].z- p[2].z);
        n = v1.Cross(v2); // the normal is in the direction of the cross product between the edge vectors
        n = (1 / n.Length()) * n; // normalize to length==1
 }
Пример #8
0
        public static double? FacetTest(Cutter cu, Point e, Tri t)
        {
            // local copy of the surface normal

            t.recalc_normals(); // don't trust the pre-calculated normal! calculate it separately here.

            Vector n = new Vector(t.n.x, t.n.y, t.n.z);
            Point cc;

            if (n.z == 0)
            {
                // vertical plane, can't touch cutter against that!
                return null;
            }
            else if (n.z < 0)
            {
                // flip the normal so it points up (? is this always required?)
                n = -1*n;
            }

            // define plane containing facet
            double a = n.x;
            double b = n.y;
            double c = n.z;
            double d = - n.x * t.p[0].x - n.y * t.p[0].y - n.z * t.p[0].z;

            // the z-direction normal is a special case (?required?)
            // in debug phase, see if this is a useful case!
            if ((a == 0) && (b == 0))
            {
                // System.Console.WriteLine("facet-test:z-dir normal case!");
                e.z = t.p[0].z;
                cc = new Point(e.x,e.y,e.z);
                if (isinside(t, cc))
                {
                    // System.Console.WriteLine("facet-test:z-dir normal case!, returning {0}",e.z);
                    // System.Console.ReadKey();
                    return e.z;
                }
                else
                    return null;
            }

            // System.Console.WriteLine("facet-test:general case!");
            // facet test general case
            // uses trigonometry, so might be too slow?

            // flat endmill and ballnose should be simple to do without trig
            // toroidal case might require offset-ellipse idea?

            /*
            theta = asin(c);
            zf= -d/c - (a*xe+b*ye)/c+ (R-r)/tan(theta) + r/sin(theta) -r;
            e=[xe ye zf];
            u=[0  0  1];
            rc=e + ((R-r)*tan(theta)+r)*u - ((R-r)/cos(theta) + r)*n;
            t=isinside(p1,p2,p3,rc);
            */

            double theta = Math.Asin(c);
            double zf = -d/c - (a*e.x+b*e.y)/c + (cu.R-cu.r)/Math.Tan(theta) + cu.r/Math.Sin(theta) - cu.r;
            Vector ve = new Vector(e.x,e.y,zf);
            Vector u = new Vector(0,0,1);
            Vector rc = new Vector();
            rc = ve +((cu.R-cu.r)*Math.Tan(theta)+cu.r)*u - ((cu.R-cu.r)/Math.Cos(theta)+cu.r)*n;

            /*
            if (rc.z > 1000)
                System.Console.WriteLine("z>1000 !");
             */

            cc = new Point(rc.x, rc.y, rc.z);

            // check that CC lies in plane:
            // a*rc(1)+b*rc(2)+c*rc(3)+d
            double test = a * cc.x + b * cc.y + c * cc.z + d;
            if (test > 0.000001)
                System.Console.WriteLine("FacetTest ERROR! CC point not in plane");

            if (isinside(t, cc))
            {
                if (Math.Abs(zf) > 100)
                {
                    System.Console.WriteLine("serious problem... at" +e.x + "," + e.y);
                }
                return zf;
            }
            else
                return null;
        }
Пример #9
0
 public Tri()
 {
     p = new Point[3];
        bb = new Bbox();
        p[0] = new Point(0,0,0);
        p[1] = new Point(0, 0, 0);
        p[2] = new Point(0, 0, 0);
        n = null;
 }
Пример #10
0
        public static STLSurf Load(System.IO.StreamReader fs)
        {
            // Here's where autodetection will be provided for loading binary stl files and by wrapping STLA(scii) and STLB(inary)
               // but for now as only one format is provided, not bothering with it, we need to define a object format for handling file loading/saving
               // System.IO.StreamReader fs = new System.IO.StreamReader(FileName);

               STLSurf surf = new STLSurf();
               int state = 0;
               int counter = 0;
               string[] data;
               Geo.Tri triangle = new Geo.Tri();
               Vector normal = new Vector();

               System.Globalization.CultureInfo locale =  new System.Globalization.CultureInfo("en-GB");
               int n_triangles=0;
               while ( !fs.EndOfStream ) {
               data = fs.ReadLine().TrimStart(' ').Split(' ');

               switch (state)
               {
                   case 0:
                       if (data[0].Equals("solid"))
                       {
                           surf.name = data[1];
                           state = 1; // continue readingx
                       }
                       break;
                   case 1:
                       if (data[0].Equals("facet")) {
                           normal.x = double.Parse(data[2], locale);
                           normal.y = double.Parse(data[3], locale);
                           normal.z = double.Parse(data[4], locale);
                           triangle = new Geo.Tri(normal);
                           counter = 0;
                           state = 2;
                       }
                       break;
                   case 2:
                       if (data[0].Equals("vertex"))
                       {
                           if ( counter <= 2 ) {
                               triangle.p[counter].x = double.Parse(data[1], locale);
                               triangle.p[counter].y = double.Parse(data[2], locale);
                               triangle.p[counter].z = double.Parse(data[3], locale);
                               // System.Console.WriteLine("STLReader: added point" + triangle.p[counter]);
                               // System.Console.ReadKey();
                               counter++;
                           }

                       } else if (data[0].Equals("endfacet"))
                       {
                           if (counter == 3)
                           {
                               surf.AddTriangle(triangle);
                               n_triangles += 1;

                           }
                           state = 1;
                       }
                   break;
               }
               }
               fs.Close();
               System.Console.WriteLine("STLReader: read {0} triangles!",n_triangles);
               return (surf);
        }
Пример #11
0
        public static STLSurf Load(System.IO.StreamReader fs)
        {
            STLSurf surf = new STLSurf();
               int state = 0;
               int counter = 0;
               string[] data;
               Tri triangle = new Tri();
               Vector normal = new Vector();

               System.Globalization.CultureInfo locale =  new System.Globalization.CultureInfo("en-GB");
               int n_triangles=0;
               while ( !fs.EndOfStream ) {
               data = fs.ReadLine().TrimStart(' ').Split(' ');

               switch (state)
               {
                   case 0:
                       if (data[0].Equals("solid"))
                       {

                           state = 1; // continue readingx
                       }
                       break;
                   case 1:
                       if (data[0].Equals("facet")) {
                           normal.x = double.Parse(data[2], locale);
                           normal.y = double.Parse(data[3], locale);
                           normal.z = double.Parse(data[4], locale);
                           triangle = new Tri(normal);
                           counter = 0;
                           state = 2;
                       }
                       break;
                   case 2:
                       if (data[0].Equals("vertex"))
                       {
                           if ( counter <= 2 ) {
                               triangle.p[counter].x = double.Parse(data[1], locale);
                               triangle.p[counter].y = double.Parse(data[2], locale);
                               triangle.p[counter].z = double.Parse(data[3], locale);
                               // System.Console.WriteLine("STLReader: added point" + triangle.p[counter]);
                               // System.Console.ReadKey();
                               counter++;
                           }

                       } else if (data[0].Equals("endfacet"))
                       {
                           if (counter == 3)
                           {
                               surf.AddTriangle(triangle);
                               n_triangles += 1;

                           }
                           state = 1;
                       }
                   break;
               }
               }
               fs.Close();
               System.Console.WriteLine("STLReader: read {0} triangles!",n_triangles);
               return (surf);
        }