示例#1
0
文件: STLSlicer.cs 项目: AdilGM/2DCAD
        public void PrintFacet(STLFacet stlFacet)
        {
            switch (stlFacet.OrientationType)
            {
            case OrientationType.TypeA:
                Console.WriteLine($"Orientation Type: TypeA");
                break;

            case OrientationType.TypeB:
                Console.WriteLine($"Orientation Type: TypeB");
                break;

            case OrientationType.TypeC:
                Console.WriteLine($"Orientation Type: TypeC");
                break;

            case OrientationType.TypeD:
                Console.WriteLine($"Orientation Type: TypeD");
                break;

            default:
                break;
            }

            Console.WriteLine("");
            PrintEdge("Edge S1", stlFacet.EdgeS1);
            Console.WriteLine("");

            PrintEdge("Edge S2", stlFacet.EdgeS2);
            Console.WriteLine("");

            PrintEdge("Edge S3", stlFacet.EdgeS3);
            Console.WriteLine("");

            PrintVertex("Vmin", stlFacet.Vmin);
            PrintVertex("Vmid", stlFacet.Vmid);
            PrintVertex("Vmax", stlFacet.Vmax);
            Console.WriteLine("");

            PrintSliceNumber("Slice Number", stlFacet);
            Console.WriteLine("");
        }
示例#2
0
文件: STLSlicer.cs 项目: AdilGM/2DCAD
        private (List <STLFacet>, double MinZ, double MaxZ) ParseASCII(StreamReader readerIn)
        {
            double[] normals;
            var      facets = new List <STLFacet>();

            double minZ = double.MaxValue;
            double maxZ = double.MinValue;

            while ((normals = GetNextMatch(readerIn, MatchDouble)) != null)
            {
                var facet = new STLFacet(
                    normals,
                    GetNextMatch(readerIn, MatchDouble),
                    GetNextMatch(readerIn, MatchDouble),
                    GetNextMatch(readerIn, MatchDouble)
                    );

                // ignore facets that are parallel to the slicing plane
                if ((facet.Vmax.Z - facet.Vmin.Z) <= 0.0001)
                {
                    continue;
                }

                // track the minimum and maximum z coordinate
                if (facet.Vmax.Z > maxZ)
                {
                    maxZ = facet.Vmax.Z;
                }
                if (facet.Vmin.Z < minZ)
                {
                    minZ = facet.Vmin.Z;
                }

                facets.Add(
                    facet
                    );
            }

            return(facets, minZ, maxZ);
        }
示例#3
0
文件: STLSlicer.cs 项目: AdilGM/2DCAD
        private (List <STLFacet>, double MinZ, double MaxZ) ParseBinary(BinaryReader readerIn)
        {
            // read the header and number of facets.
            readerIn.ReadBytes(80);

            double[] normals = new double[3];
            double[] vertex1 = new double[3];
            double[] vertex2 = new double[3];
            double[] vertex3 = new double[3];

            double minZ = double.MaxValue;
            double maxZ = double.MinValue;

            uint howmany = BitConverter.ToUInt32(readerIn.ReadBytes(4), 0);
            var  facets  = new List <STLFacet>((int)howmany);

            for (int i = 0; i < howmany; i++)
            {
                normals[0] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                normals[1] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                normals[2] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);

                vertex1[0] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex1[1] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex1[2] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);

                vertex2[0] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex2[1] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex2[2] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);

                vertex3[0] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex3[1] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);
                vertex3[2] = BitConverter.ToSingle(readerIn.ReadBytes(4), 0);

                // skip attribute byte count
                readerIn.ReadBytes(2);

                var facet = new STLFacet(
                    normals,
                    vertex1,
                    vertex2,
                    vertex3
                    );

                // ignore facets that are parallel to the slicing plane
                if ((facet.Vmax.Z - facet.Vmin.Z) <= 0.001)
                {
                    continue;
                }

                // track the minimum and maximum z coordinate
                if (facet.Vmax.Z > maxZ)
                {
                    maxZ = facet.Vmax.Z;
                }
                if (facet.Vmin.Z < minZ)
                {
                    minZ = facet.Vmin.Z;
                }

                facets.Add(
                    facet
                    );
            }

            return(facets, minZ, maxZ);
        }
示例#4
0
文件: STLSlicer.cs 项目: AdilGM/2DCAD
 public void PrintSliceNumber(string tag, STLFacet stlFacet)
 {
     Console.WriteLine($"{tag} Smin: {stlFacet.Smin}, Smid: {stlFacet.Smid}, Smax: {stlFacet.Smax}");
 }
示例#5
0
文件: STLSlicer.cs 项目: AdilGM/2DCAD
        public List <MContourStructure>[] SliceParallel(double sliceThickness, double tolerance = 0.0001)
        {
            if (Facets == null)
            {
                return(null);
            }

            int numberOfSlices = (int)Math.Ceiling((MaxZ - MinZ) / sliceThickness);
            var contours       = new List <MContourStructure> [numberOfSlices];

            Parallel.For(0, Facets.Count, (i) =>
            {
                STLEdge e1, e2;
                STLFacet currentFacet = Facets[i];

                // calculating the slice number
                currentFacet.UpdateSliceNumber(MinZ, sliceThickness);

                // forward edge and backward edge judgments
                // use to select edge to use for intersection
                if (
                    (currentFacet.OrientationType == OrientationType.TypeA) && // Group A : oriented from min to max
                    (currentFacet.Vmax.Flag > currentFacet.Vmin.Flag)          // and flagzmax > flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS2;
                    e2 = currentFacet.EdgeS1;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeB) && // Group B : oriented from min to max
                    (currentFacet.Vmax.Flag < currentFacet.Vmin.Flag)          // and flagzmax < flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS2;
                    e2 = currentFacet.EdgeS1;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeC) && // Group C : oriented from max to min
                    (currentFacet.Vmax.Flag < currentFacet.Vmin.Flag)          // and flagzmax < flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS1;
                    e2 = currentFacet.EdgeS2;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeD) && // Group D : oriented from max to min
                    (currentFacet.Vmax.Flag > currentFacet.Vmin.Flag)          // and flagzmax > flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS1;
                    e2 = currentFacet.EdgeS2;
                }
                else
                {
                    return;
                }

                // slicing facet section below Smid
                for (int j = currentFacet.Smin; j < currentFacet.Smid; j++)
                {
                    double slicePosition = (j * sliceThickness) + MinZ;

                    // create intersecting structure
                    var intersection = new IntersectionStructure()
                    {
                        ForwardEdgeIntersectionPoint = GetIntersection(
                            e1,
                            slicePosition // slice position
                            ),
                        ForwardEdge   = e1,
                        BackwardEdge  = e2,
                        SlicePosition = slicePosition
                    };

                    // The Efficient Contour Construction Algorithm (ECC)

                    // initialise contours array
                    if (contours[j] == null)
                    {
                        contours[j] = new List <MContourStructure>();
                    }

                    lock (contours[j])
                    {
                        // used to mark whether the forward adjacent intersection structure or
                        // the backward adjacent intersection structure of IS has been found
                        bool foundForward  = false;
                        bool foundBackward = false;

                        // used to mark the position where the backward adjacent intersection
                        // structure of IS has been found.
                        int position = -1;

                        for (int l = 0; l < contours[j].Count; l++)
                        {
                            var contourLinkedList = contours[j][l].IntersectionList;

                            var connectionType = GetConnectionType(
                                contourLinkedList,
                                intersection,
                                tolerance
                                );

                            switch (connectionType)
                            {
                            case ConnectionType.START_TO_START: // these should never happen
                            case ConnectionType.END_TO_END:     // must test to make sure
                            case ConnectionType.NONE:
                                continue;
                            }

                            if (
                                !foundForward &&
                                connectionType == ConnectionType.START_TO_END
                                )
                            {
                                if (foundBackward)
                                {
                                    // copy items from current location to position
                                    contours[j][position].IntersectionList.AddLast(contourLinkedList);

                                    // delete current location
                                    contours[j].RemoveAt(l);
                                    break;
                                }

                                foundForward = true;
                                position     = l;

                                contourLinkedList.AddFirst(intersection);
                            }

                            if (
                                !foundBackward &&
                                connectionType == ConnectionType.END_TO_START
                                )
                            {
                                if (foundForward && position == l)
                                {
                                    break; // contour must be closed since forward edge and backward edge are found in the same list
                                }
                                else if (foundForward)
                                {
                                    // copy nodes from position to current location
                                    // it's easier than copy from this location to the found location (reverse)
                                    contourLinkedList.AddLast(contours[j][position].IntersectionList);

                                    // delete current location
                                    contours[j].RemoveAt(position);
                                    break;
                                }

                                foundBackward = true;
                                position      = l;

                                contourLinkedList.AddLast(intersection);
                            }
                        }

                        if (!(foundForward || foundBackward)) // not forward or backward intersection; insert into contours list
                        {
                            contours[j].Add(new MContourStructure(intersection));
                        }
                    }
                }

                // forward edge and backward edge judgments
                // use to select edge to use for intersection
                if (
                    (currentFacet.OrientationType == OrientationType.TypeA) && // Group A : oriented from min to max
                    (currentFacet.Vmax.Flag > currentFacet.Vmin.Flag)          // and flagzmax > flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS3;
                    e2 = currentFacet.EdgeS1;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeB) && // Group B : oriented from min to max
                    (currentFacet.Vmax.Flag < currentFacet.Vmin.Flag)          // and flagzmax < flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS3;
                    e2 = currentFacet.EdgeS1;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeC) && // Group C : oriented from max to min
                    (currentFacet.Vmax.Flag < currentFacet.Vmin.Flag)          // and flagzmax < flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS1;
                    e2 = currentFacet.EdgeS3;
                }
                else if (
                    (currentFacet.OrientationType == OrientationType.TypeD) && // Group D : oriented from max to min
                    (currentFacet.Vmax.Flag > currentFacet.Vmin.Flag)          // and flagzmax > flagzmin
                    )
                {
                    e1 = currentFacet.EdgeS1;
                    e2 = currentFacet.EdgeS3;
                }
                else
                {
                    return;
                }

                // slicing facet section above Smid
                for (int k = currentFacet.Smid; k < currentFacet.Smax; k++)
                {
                    double slicePosition = (k * sliceThickness) + MinZ;

                    // create intersecting structure
                    var intersection = new IntersectionStructure()
                    {
                        ForwardEdgeIntersectionPoint = GetIntersection(
                            e1,
                            slicePosition // slice position
                            ),
                        ForwardEdge  = e1,
                        BackwardEdge = e2
                    };

                    // The Efficient Contour Construction Algorithm (ECC)

                    // initialise contours array
                    if (contours[k] == null)
                    {
                        contours[k] = new List <MContourStructure>();
                    }

                    lock (contours[k])
                    {
                        // used to mark whether the forward adjacent intersection structure or
                        // the backward adjacent intersection structure of IS has been found
                        bool foundForward  = false;
                        bool foundBackward = false;

                        // used to mark the position where the backward adjacent intersection
                        // structure of IS has been found.
                        int position = -1;

                        for (int l = 0; l < contours[k].Count; l++)
                        {
                            var contourLinkedList = contours[k][l].IntersectionList;

                            var connectionType = GetConnectionType(
                                contourLinkedList,
                                intersection
                                );

                            switch (connectionType)
                            {
                            case ConnectionType.START_TO_START: // these should never happen
                            case ConnectionType.END_TO_END:     // must test to make sure
                            case ConnectionType.NONE:
                                continue;
                            }

                            if (
                                !foundForward &&
                                connectionType == ConnectionType.START_TO_END
                                )
                            {
                                if (foundBackward)
                                {
                                    // copy items from current location to position
                                    contours[k][position].IntersectionList.AddLast(contourLinkedList);

                                    // delete current location
                                    contours[k].RemoveAt(l);
                                    break;
                                }

                                foundForward = true;
                                position     = l;

                                contourLinkedList.AddFirst(intersection);
                            }

                            if (
                                !foundBackward &&
                                connectionType == ConnectionType.END_TO_START
                                )
                            {
                                if (foundForward && position == l)
                                {
                                    break; // contour must be closed since forward edge and backward edge are found in the same list
                                }
                                else if (foundForward)
                                {
                                    // copy nodes from position to current location
                                    // it's easier than copy from this location to the found location (reverse)
                                    contourLinkedList.AddLast(contours[k][position].IntersectionList);

                                    // delete current location
                                    contours[k].RemoveAt(position);
                                    break;
                                }

                                foundBackward = true;
                                position      = l;

                                contourLinkedList.AddLast(intersection);
                            }
                        }

                        if (!(foundForward || foundBackward)) // not forward or backward intersection; insert into contours list
                        {
                            contours[k].Add(new MContourStructure(intersection));
                        }
                    }
                }
            });

            return(contours);
        }
示例#6
0
 public static Triangle ToTriangle(this STLFacet facet)
 {
     return(new Triangle(new Point(new Vect3(facet.Vertex1)), new Point(new Vect3(facet.Vertex2)), new Point(new Vect3(facet.Vertex3)), new Vect3(facet.Normal)));
 }