Exemple #1
0
        public List <ContourStructure>[] Slice(double sliceThickness, double tolerance = 0.0001)
        {
            if (Facets == null)
            {
                return(null);
            }

            int numberOfSlices = (int)Math.Ceiling((MaxZ - MinZ) / sliceThickness);
            var contours       = new List <ContourStructure> [numberOfSlices];
            IntersectionStructure intersection;
            LinkedList <IntersectionStructure> contourLinkedList;
            STLFacet currentFacet;
            STLEdge  e1, e2;

            for (int i = 0; i < Facets.Count; i++)
            {
                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
                {
                    continue;
                }

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

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

                    // The Efficient Contour Construction Algorithm (ECC)

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

                    // 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++)
                    {
                        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
                                foreach (var node in contourLinkedList)
                                {
                                    contours[j][position].IntersectionList.AddLast(node);
                                }

                                // 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)
                                foreach (var node in contours[j][position].IntersectionList)
                                {
                                    contourLinkedList.AddLast(node);
                                }

                                // 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 ContourStructure(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
                {
                    continue;
                }

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

                    // create intersecting structure
                    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 <ContourStructure>();
                    }

                    // 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++)
                    {
                        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
                                foreach (var node in contourLinkedList)
                                {
                                    contours[k][position].IntersectionList.AddLast(node);
                                }

                                // 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)
                                foreach (var node in contours[k][position].IntersectionList)
                                {
                                    contourLinkedList.AddLast(node);
                                }

                                // 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 ContourStructure(intersection));
                    }
                }
            }

            return(contours);
        }
Exemple #2
0
        public ConnectionType GetConnectionType(MLinkedList <IntersectionStructure> contourLinkedList, IntersectionStructure intersection, double tolerance = 0.0001)
        {
            if (CompareEqual(contourLinkedList.First.Value.ForwardEdge, intersection.BackwardEdge, tolerance))
            {
                return(ConnectionType.START_TO_END);
            }
            else if (CompareEqual(contourLinkedList.Last.Value.BackwardEdge, intersection.ForwardEdge, tolerance))
            {
                return(ConnectionType.END_TO_START);
            }

            return(ConnectionType.NONE);
        }