コード例 #1
0
        private static void RunOptions(Options opts)
        {
            // TODO: Make sure the best versions of these generic collections are being used in the right places.
            // Use arrays when size is known and is not expected to change
            // Otherwise, use a list
            // Consider places where we can avoid a conversion of .ToArray/.ToList and rely on the IEnumerable interface
            try
            {
                Mesh3 model = new Mesh3(ReadFacetsFromFile(opts.StlInputPath, opts.IsStlAscii));
                Console.WriteLine("Read " + model.Facets.Length + " facets from file");

                Polygon3[] unsupportedFacets = model.Facets.Where(facet => DoesFacetNeedSupported(facet, opts.CriticalAngle)).ToArray();
                Console.WriteLine("Identified " + unsupportedFacets.Length + " unsupported facets");

                Point3Tree <List <Polygon3> > edgeFacetIndex = new Point3Tree <List <Polygon3> >(GetEdgeFacetKeys(unsupportedFacets));
                Console.WriteLine("Created an index with " + edgeFacetIndex.Keys.Length + " edges");

                CreateEdgeFacetAssociation(unsupportedFacets, edgeFacetIndex);
                Console.WriteLine("Association created between facets and edges");

                List <Mesh3> unsupportedRegions = BuildUnsupportedRegions(unsupportedFacets, edgeFacetIndex);
                Console.WriteLine("Built " + unsupportedRegions.Count + " unsupported regions");

                List <Mesh3> largeRegions = unsupportedRegions.Where(region => IsLargeRegion(region, edgeFacetIndex, opts.DimensionLength, opts.ToleranceAngle)).ToList();
                Console.WriteLine("Removed " + (unsupportedRegions.Count - largeRegions.Count) + " small unsupported regions");

                List <Polygon3> scaffoldingFacets = new List <Polygon3>();
                if (opts.DoXScaffolding || opts.DoYScaffolding)
                {
                    List <Vector3> supportNormals = new List <Vector3>();
                    Quaternion     rotation       = new Quaternion(0, 0, (float)AngleConverter.DegToRad(opts.ScaffoldingAngle));
                    if (opts.DoXScaffolding)
                    {
                        supportNormals.Add(Vector3.Transform(YZNormal, rotation));
                    }
                    if (opts.DoYScaffolding)
                    {
                        supportNormals.Add(Vector3.Transform(XZNormal, rotation));
                    }
                    Console.WriteLine("Made support normals");
                    foreach (Vector3 supportNormal in supportNormals)
                    {
                        scaffoldingFacets.AddRange(GenerateLineScaffolding(model, largeRegions, supportNormal, (float)opts.SupportSpacing, (float)opts.PlateSpacing));
                    }
                }
                if (opts.DoContourScaffolding)
                {
                    scaffoldingFacets.AddRange(GenerateContourScaffolding(largeRegions, (float)opts.PlateSpacing, edgeFacetIndex));
                }
                StlBinaryWriter writer = new StlBinaryWriter();
                writer.Write(opts.StlOutputPath, scaffoldingFacets.ToArray());
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex);
                Environment.Exit(1);
            }
        }
コード例 #2
0
        private static List <Mesh3> BuildUnsupportedRegions(Polygon3[] unsupportedFacets, Point3Tree <List <Polygon3> > edgeFacetIndex)
        {
            Point3Tree <bool> facetVisitedIndex  = new Point3Tree <bool>(unsupportedFacets.Select(facet => facet.Centroid).ToArray());
            List <Mesh3>      unsupportedRegions = new List <Mesh3>();

            foreach (Polygon3 unsupportedFacet in unsupportedFacets)
            {
                if (!facetVisitedIndex[unsupportedFacet.Centroid])
                {
                    unsupportedRegions.Add(new Mesh3(GrowUnsupportedRegion(unsupportedFacet, edgeFacetIndex, facetVisitedIndex)));
                }
            }
            return(unsupportedRegions);
        }
コード例 #3
0
        private static List <Point3> GetBoundingVertices(Mesh3 region, Point3Tree <List <Polygon3> > edgeFacetIndex)
        {
            List <Point3> boundingVertices = new List <Point3>();

            foreach (Polygon3 facet in region.Facets)
            {
                foreach (Point3 edgeMidPoint in facet.EdgeMidPoints)
                {
                    if (edgeFacetIndex[edgeMidPoint].Count == 1)
                    {
                        boundingVertices.Add(edgeMidPoint);
                    }
                }
            }
            return(boundingVertices);
        }
コード例 #4
0
        private static List <Polygon3> GetAdjacentFacets(Polygon3 facet, Point3Tree <List <Polygon3> > edgeFacetIndex)
        {
            List <Polygon3> adjacentFacets = new List <Polygon3>(3);

            foreach (Point3 edgeMidPoint in facet.EdgeMidPoints)
            {
                foreach (Polygon3 adjacentFacet in edgeFacetIndex[edgeMidPoint])
                {
                    if (adjacentFacet != facet)
                    {
                        adjacentFacets.Add(adjacentFacet);
                    }
                }
            }
            return(adjacentFacets);
        }
コード例 #5
0
        private static Polygon3[] GrowUnsupportedRegion(Polygon3 unsupportedFacet, Point3Tree <List <Polygon3> > edgeFacetIndex, Point3Tree <bool> facetVisitedIndex)
        {
            Queue <Polygon3> adjacentQueue = new Queue <Polygon3>();

            adjacentQueue.Enqueue(unsupportedFacet);
            facetVisitedIndex[unsupportedFacet.Centroid] = true;

            List <Polygon3> unsupportedRegion = new List <Polygon3>();

            while (adjacentQueue.Count != 0)
            {
                Polygon3 adjacentFacet = adjacentQueue.Dequeue();
                unsupportedRegion.Add(adjacentFacet);
                EnqueueAdjacentFacets(adjacentFacet, adjacentQueue, edgeFacetIndex, facetVisitedIndex);
            }
            return(unsupportedRegion.ToArray());
        }
コード例 #6
0
        private static bool IsLargeRegion(Mesh3 region, Point3Tree <List <Polygon3> > edgeFacetIndex, double dimensionLength, double toleranceAngle)
        {
            bool           isLargeRegion  = false;
            List <Vector3> largeDiagonals = GetLargeDiagonals(GetBoundingVertices(region, edgeFacetIndex), dimensionLength);

            for (int i = 0; i != largeDiagonals.Count && !isLargeRegion; i++)
            {
                Vector3 diagonal1 = largeDiagonals[i];
                for (int j = i; j != largeDiagonals.Count && !isLargeRegion; j++)
                {
                    Vector3 diagonal2    = largeDiagonals[j];
                    double  angleBetween = AngleConverter.RadToDeg(Vector3.CalculateAngle(diagonal1, diagonal2));
                    if (angleBetween >= 90 - toleranceAngle && angleBetween <= 90 + toleranceAngle)
                    {
                        isLargeRegion = true;
                    }
                }
            }
            return(isLargeRegion);
        }
コード例 #7
0
 private static void CreateEdgeFacetAssociation(Polygon3[] facets, Point3Tree <List <Polygon3> > edgeFacetIndex)
 {
     foreach (Polygon3 facet in facets)
     {
         foreach (Point3 edgeMidPoint in facet.EdgeMidPoints)
         {
             List <Polygon3> edgeFacetList = edgeFacetIndex[edgeMidPoint];
             if (edgeFacetList == null)
             {
                 edgeFacetList = new List <Polygon3>(2);
                 edgeFacetIndex[edgeMidPoint] = edgeFacetList;
             }
             edgeFacetList.Add(facet);
         }
     }
     if (edgeFacetIndex.Values.Where(list => list != null && list.Count > 2).ToArray().Length > 0)
     {
         throw new Exception("Found bad STL file with more than two facets sharing an edge");
     }
 }
コード例 #8
0
        private static List <Polygon3> GenerateContourScaffolding(List <Mesh3> regions, float plateSpacing, Point3Tree <List <Polygon3> > edgeFacetIndex)
        {
            List <Polygon3> scaffolding = new List <Polygon3>();

            foreach (Mesh3 region in regions)
            {
                foreach (Polygon3 facet in region.Facets)
                {
                    for (int i = 0; i != facet.EdgeMidPoints.Length; i++)
                    {
                        if (edgeFacetIndex[facet.EdgeMidPoints[i]].Count == 1)
                        {
                            LineSegment3 boundingEdge = facet.Edges[i];
                            scaffolding.AddRange(CreateTesselatedLineSupport(new List <Point3> {
                                boundingEdge.StartPoint, boundingEdge.EndPoint
                            }, plateSpacing, region));
                        }
                    }
                }
            }
            return(scaffolding);
        }
コード例 #9
0
 private static void EnqueueAdjacentFacets(Polygon3 adjacentFacet, Queue <Polygon3> adjacentQueue, Point3Tree <List <Polygon3> > edgeFacetIndex, Point3Tree <bool> facetVisitedIndex)
 {
     foreach (Polygon3 facet in GetAdjacentFacets(adjacentFacet, edgeFacetIndex))
     {
         if (!facetVisitedIndex[facet.Centroid])
         {
             adjacentQueue.Enqueue(facet);
             facetVisitedIndex[facet.Centroid] = true;
         }
     }
 }