Example #1
0
        PolyLine2d to_polyline(EdgeSpan span, Frame3f polyFrame)
        {
            int        NV   = span.VertexCount;
            PolyLine2d poly = new PolyLine2d();

            for (int k = 0; k < NV; ++k)
            {
                poly.AppendVertex(polyFrame.ToPlaneUV((Vector3f)span.GetVertex(k), 2));
            }
            return(poly);
        }
Example #2
0
        public void Constructor_FromPolyLine()
        {
            // Arrange
            var polyline = new PolyLine2d(CreateSimpleVector2dArray());

            // Act
            var curve = new FillCurve <FillSegment>(polyline);

            // Assert
            Assert.AreEqual(2, curve.Elements.Count);
        }
Example #3
0
        public static void Restore(PolyLine2d polyline, BinaryReader reader)
        {
            int count = reader.ReadInt32();

            for (int i = 0; i < count; ++i)
            {
                double x = reader.ReadDouble();
                double y = reader.ReadDouble();
                polyline.AppendVertex(new Vector2D(x, y));
            }
        }
Example #4
0
        public static CPolyPath ConvertToClipper(PolyLine2d pline, double nIntScale)
        {
            int       N            = pline.VertexCount;
            CPolyPath clipper_path = new CPolyPath(N);

            for (int i = 0; i < N; ++i)
            {
                Vector2d v = pline[i];
                clipper_path.Add(new IntPoint(nIntScale * v.x, nIntScale * v.y));
            }
            return(clipper_path);
        }
Example #5
0
        public static void test_svg()
        {
            Polygon2d  poly  = Polygon2d.MakeCircle(100.0f, 10);
            PolyLine2d pline = new PolyLine2d();

            pline.AppendVertex(Vector2d.Zero);
            pline.AppendVertex(200 * Vector2d.AxisX);
            pline.AppendVertex(200 * Vector2d.One);
            Circle2d  circ = new Circle2d(33 * Vector2d.One, 25);
            Segment2d seg  = new Segment2d(Vector2d.Zero, -50 * Vector2d.AxisY);

            SVGWriter writer = new SVGWriter();

            writer.AddPolygon(poly, SVGWriter.Style.Filled("lime", "black", 0.25f));
            writer.AddPolyline(pline, SVGWriter.Style.Outline("orange", 2.0f));
            writer.AddCircle(circ, SVGWriter.Style.Filled("yellow", "red", 5.0f));
            writer.AddLine(seg, SVGWriter.Style.Outline("blue", 10.0f));

            int      astep = 29;
            Vector2d c     = new Vector2d(-200, 100);

            for (int k = 1; k <= 12; ++k)
            {
                Arc2d arc = new Arc2d(c + k * 45 * Vector2d.AxisX, 20, 0, k * astep);
                writer.AddArc(arc);
                writer.AddBox(arc.Bounds, SVGWriter.Style.Outline("red", 0.5f));
            }
            c.y += 50;
            for (int k = 1; k <= 12; ++k)
            {
                Arc2d arc = new Arc2d(c + k * 45 * Vector2d.AxisX, 20, k * astep, (k + 5) * astep);
                writer.AddArc(arc);
                writer.AddBox(arc.Bounds, SVGWriter.Style.Outline("red", 0.5f));
            }
            c.y += 50;
            for (int k = 1; k <= 12; ++k)
            {
                Arc2d arc = new Arc2d(c + k * 45 * Vector2d.AxisX, 20, k * astep, (k + 10) * astep);
                writer.AddArc(arc);
                writer.AddBox(arc.Bounds, SVGWriter.Style.Outline("red", 0.5f));
            }
            c.y += 50;
            for (int k = 1; k <= 12; ++k)
            {
                Arc2d arc = new Arc2d(c + k * 45 * Vector2d.AxisX, 20, k * astep, (k + 10) * astep);
                arc.Reverse();
                writer.AddArc(arc);
                writer.AddBox(arc.Bounds, SVGWriter.Style.Outline("red", 0.5f));
            }

            writer.Write(TestUtil.GetTestOutputPath("test.svg"));
        }
Example #6
0
        public void AddClippedPathTest()
        {
            PlanarSlice slice = new PlanarSlice();
            PolyLine2d  line  = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddClippedPath(line);

            Assert.AreEqual(slice.ClippedPaths[0], line);
        }
Example #7
0
        public void ResolveEmbeddedPathWidthExceptionTest()
        {
            PlanarSlice slice = new PlanarSlice();
            PolyLine2d  line  = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddEmbeddedPath(line);

            Assert.ThrowsException <Exception>(() => slice.Resolve());
        }
Example #8
0
        bool self_intersects(PolyLine2d poly)
        {
            var seg = new Segment2d(poly.Start, poly.End);
            int NS  = poly.VertexCount - 2;

            for (int i = 1; i < NS; ++i)
            {
                if (poly.Segment(i).Intersects(ref seg))
                {
                    return(true);
                }
            }
            return(false);
        }
Example #9
0
        protected virtual Polygon2d make_thickened_path(PolyLine2d path, double width)
        {
            PolyLine2d pos = new PolyLine2d(path), neg = new PolyLine2d(path);

            pos.VertexOffset(width / 2);
            neg.VertexOffset(-width / 2); neg.Reverse();
            pos.AppendVertices(neg);
            Polygon2d poly = new Polygon2d(pos.Vertices);

            if (poly.IsClockwise)
            {
                poly.Reverse();
            }
            return(poly);
        }
Example #10
0
        public static PolyLine2d ConvertFromClipperPath(CPolyPath clipper_poly, double nIntScale)
        {
            double scale = 1.0 / (double)nIntScale;

            int        N    = clipper_poly.Count;
            PolyLine2d poly = new PolyLine2d();

            for (int i = 0; i < N; ++i)
            {
                IntPoint p = clipper_poly[i];
                Vector2d v = new Vector2d((double)p.X * scale, (double)p.Y * scale);
                poly.AppendVertex(v);
            }
            return(poly);
        }
Example #11
0
        virtual public void PreRender()
        {
            if (in_shutdown())
            {
                return;
            }

            if (parameters_dirty)
            {
                PolyLine2d spiral = PolyLine2d.MakeBoxSpiral(Vector2d.Zero, length, PathWidth + spacing);

                DMesh3 mesh = new DMesh3();

                List <int> bottom_verts = new List <int>();
                List <int> top_verts    = new List <int>();
                for (int i = 0; i < spiral.VertexCount; ++i)
                {
                    Vector2d x  = spiral[i];
                    Vector3d vb = new Vector3d(x.x, 0, x.y);
                    bottom_verts.Add(mesh.AppendVertex(vb));
                    top_verts.Add(mesh.AppendVertex(vb + Height * Vector3d.AxisY));
                }

                MeshEditor editor = new MeshEditor(mesh);
                editor.StitchSpan(bottom_verts, top_verts);

                PreviewSO.ReplaceMesh(mesh, true);

                Vector3d translate = scene_bounds.Point(1, -1, 1);
                translate.x += spiral.Bounds.Width + PathWidth;
                Frame3f sceneF = Frame3f.Identity.Translated((Vector3f)translate);
                PreviewSO.SetLocalFrame(sceneF, CoordSpace.SceneCoords);

                parameters_dirty = false;
            }
        }
Example #12
0
        private static bool compute_plane_curves(DMesh3 mesh, DMeshAABBTree3 spatial,
                                                 double z, bool is_solid,
                                                 out Polygon2d[] loops, out PolyLine2d[] curves)
        {
            Func <Vector3d, double> planeF = (v) =>
            {
                return(v.z - z);
            };

            // find list of triangles that intersect this z-value
            PlaneIntersectionTraversal planeIntr = new PlaneIntersectionTraversal(mesh, z);

            spatial.DoTraversal(planeIntr);
            List <int> triangles = planeIntr.triangles;

            // compute intersection iso-curves, which produces a 3D graph of undirected edges
            MeshIsoCurves iso = new MeshIsoCurves(mesh, planeF)
            {
                WantGraphEdgeInfo = true
            };

            iso.Compute(triangles);
            DGraph3 graph = iso.Graph;

            if (graph.EdgeCount == 0)
            {
                loops  = new Polygon2d[0];
                curves = new PolyLine2d[0];
                return(false);
            }

            // if this is a closed solid, any open spurs in the graph are errors
            if (is_solid)
            {
                DGraph3Util.ErodeOpenSpurs(graph);
            }

            // [RMS] debug visualization
            //DGraph2 graph2 = new DGraph2();
            //Dictionary<int, int> mapV = new Dictionary<int, int>();
            //foreach (int vid in graph.VertexIndices())
            //    mapV[vid] = graph2.AppendVertex(graph.GetVertex(vid).xy);
            //foreach (int eid in graph.EdgeIndices())
            //    graph2.AppendEdge(mapV[graph.GetEdge(eid).a], mapV[graph.GetEdge(eid).b]);
            //SVGWriter svg = new SVGWriter();
            //svg.AddGraph(graph2, SVGWriter.Style.Outline("black", 0.05f));
            //foreach (int vid in graph2.VertexIndices()) {
            //    if (graph2.IsJunctionVertex(vid))
            //        svg.AddCircle(new Circle2d(graph2.GetVertex(vid), 0.25f), SVGWriter.Style.Outline("red", 0.1f));
            //    else if (graph2.IsBoundaryVertex(vid))
            //        svg.AddCircle(new Circle2d(graph2.GetVertex(vid), 0.25f), SVGWriter.Style.Outline("blue", 0.1f));
            //}
            //svg.Write(string.Format("c:\\meshes\\EXPORT_SLICE_{0}.svg", z));

            // extract loops and open curves from graph
            DGraph3Util.Curves c = DGraph3Util.ExtractCurves(graph, false, iso.ShouldReverseGraphEdge);
            loops = new Polygon2d[c.Loops.Count];
            for (int li = 0; li < loops.Length; ++li)
            {
                DCurve3 loop = c.Loops[li];
                loops[li] = new Polygon2d();
                foreach (Vector3d v in loop.Vertices)
                {
                    loops[li].AppendVertex(v.xy);
                }
            }

            curves = new PolyLine2d[c.Paths.Count];
            for (int pi = 0; pi < curves.Length; ++pi)
            {
                DCurve3 span = c.Paths[pi];
                curves[pi] = new PolyLine2d();
                foreach (Vector3d v in span.Vertices)
                {
                    curves[pi].AppendVertex(v.xy);
                }
            }

            return(true);
        }
Example #13
0
 public void Add(PolyLine2d path, int gid = -1)
 {
     Graph.AppendPolyline(path, gid);
 }
Example #14
0
 /// <summary>
 /// Collision paths are fixed thickened paths we need to clip against
 /// </summary>
 public void AddCollisionConstraint(PolyLine2d path)
 {
     CollisionGraph.AppendPolyline(path);
 }
Example #15
0
 /// <summary>
 /// remove portions of polyline that are inside set of solids
 /// </summary>
 public static List <PolyLine2d> ClipAgainstPolygon(List <GeneralPolygon2d> solids, PolyLine2d polyline, bool bIntersect = false)
 {
     return(ClipAgainstPolygon((IEnumerable <GeneralPolygon2d>)solids, polyline, bIntersect));
 }
Example #16
0
        /// <summary>
        /// remove portions of polyline that are inside set of solids
        /// </summary>
        public static List <PolyLine2d> ClipAgainstPolygon(IEnumerable <GeneralPolygon2d> solids, PolyLine2d polyline, bool bIntersect = false)
        {
            double            nIntScale = Math.Max(GetIntScale(solids), GetIntScale(polyline.Vertices));
            List <PolyLine2d> result    = new List <PolyLine2d>();

            Clipper  clip = new Clipper();
            PolyTree tree = new PolyTree();

            try {
                foreach (GeneralPolygon2d poly in solids)
                {
                    CPolygonList clipper_poly = ConvertToClipper(poly, nIntScale);
                    clip.AddPaths(clipper_poly, PolyType.ptClip, true);
                }

                CPolyPath path = ConvertToClipper(polyline, nIntScale);
                clip.AddPath(path, PolyType.ptSubject, false);

                if (bIntersect)
                {
                    clip.Execute(ClipType.ctIntersection, tree);
                }
                else
                {
                    clip.Execute(ClipType.ctDifference, tree);
                }

                for (int ci = 0; ci < tree.ChildCount; ++ci)
                {
                    if (tree.Childs[ci].IsOpen == false)
                    {
                        continue;
                    }
                    PolyLine2d clippedPath = ConvertFromClipperPath(tree.Childs[ci].Contour, nIntScale);

                    // clipper just cuts up the polylines, we still have to figure out containment ourselves.
                    // Currently just checking based on point around middle of polyline...
                    // [TODO] can we get clipper to not return the inside ones?
                    Vector2d qp = (clippedPath.VertexCount > 2) ?
                                  clippedPath[clippedPath.VertexCount / 2] : clippedPath.Segment(0).Center;
                    bool inside = false;
                    foreach (var poly in solids)
                    {
                        if (poly.Contains(qp))
                        {
                            inside = true;
                            break;
                        }
                    }
                    if (inside == bIntersect)
                    {
                        result.Add(clippedPath);
                    }
                }
            } catch /*(Exception e)*/ {
                // [TODO] what to do here?
                //System.Diagnostics.Debug.WriteLine("ClipperUtil.ClipAgainstPolygon: Clipper threw exception: " + e.Message);
                return(new List <PolyLine2d>());
            }

            return(result);
        }
Example #17
0
        public void ResolveTest()
        {
            PlanarSlice slice = new PlanarSlice();
            Polygon2d   p2d   = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d poly = new GeneralPolygon2d(p2d);
            Polygon2d        p2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d poly2 = new GeneralPolygon2d(p2d2);

            slice.AddPolygons(new List <GeneralPolygon2d>()
            {
                poly, poly2
            });

            Assert.AreEqual(slice.InputSolids[0], poly);
            Assert.AreEqual(slice.InputSolids[1], poly2);

            PolyLine2d line = new PolyLine2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(-1, 0)
            });

            slice.AddEmbeddedPath(line);
            slice.EmbeddedPathWidth = 1;

            Polygon2d supportp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d supportpoly = new GeneralPolygon2d(supportp2d);
            Polygon2d        supportp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d supportpoly2 = new GeneralPolygon2d(supportp2d2);

            slice.AddSupportPolygons(new List <GeneralPolygon2d>()
            {
                supportpoly, supportpoly2
            });

            Polygon2d cavp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d cavpoly = new GeneralPolygon2d(cavp2d);
            Polygon2d        cavp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d cavpoly2 = new GeneralPolygon2d(cavp2d2);

            slice.AddCavityPolygons(new List <GeneralPolygon2d>()
            {
                cavpoly, cavpoly2
            });

            Polygon2d cropp2d = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(1, 0),
                new Vector2d(0, 1),
                new Vector2d(1, 1)
            });
            GeneralPolygon2d croppoly = new GeneralPolygon2d(cropp2d);
            Polygon2d        cropp2d2 = new Polygon2d(new List <Vector2d>()
            {
                new Vector2d(-1, 0),
                new Vector2d(0, -1),
                new Vector2d(-1, -1)
            });
            GeneralPolygon2d croppoly2 = new GeneralPolygon2d(cropp2d2);

            slice.AddCropRegions(new List <GeneralPolygon2d>()
            {
                croppoly, croppoly2
            });

            slice.Resolve();

            slice.BuildSpatialCaches();

            double dist = slice.DistanceSquared(new Vector2d(5, 5));

            Assert.AreEqual(41, dist);
        }
        public static void test_arrangement_demo()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("spheres_and_planes.obj");

            MeshTransforms.Scale(mesh, 8);
            AxisAlignedBox3d meshBounds      = mesh.CachedBounds;
            Vector3d         origin          = meshBounds.Center;
            double           simplify_thresh = 5.0;

            Frame3f      plane = new Frame3f(origin, Vector3d.AxisY);
            MeshPlaneCut cut   = new MeshPlaneCut(mesh, plane.Origin, plane.Z);

            cut.Cut();

            Arrangement2d builder = new Arrangement2d(new AxisAlignedBox2d(1024.0));

            // insert all cut edges
            HashSet <Vector2d> srcpts = new HashSet <Vector2d>();

            foreach (EdgeLoop loop in cut.CutLoops)
            {
                Polygon2d poly = new Polygon2d();
                foreach (int vid in loop.Vertices)
                {
                    poly.AppendVertex(mesh.GetVertex(vid).xz);
                }

                poly.Simplify(simplify_thresh, 0.01, true);
                foreach (Vector2d v in poly.Vertices)
                {
                    srcpts.Add(v);
                }

                builder.Insert(poly);
            }
            foreach (EdgeSpan span in cut.CutSpans)
            {
                PolyLine2d pline = new PolyLine2d();
                foreach (int vid in span.Vertices)
                {
                    pline.AppendVertex(mesh.GetVertex(vid).xz);
                }
                pline.Simplify(simplify_thresh, 0.01, true);
                foreach (Vector2d v in pline)
                {
                    srcpts.Add(v);
                }
                builder.Insert(pline);
            }

            SVGWriter svg = new SVGWriter();

            svg.AddGraph(builder.Graph);

            var vtx_style = SVGWriter.Style.Outline("red", 1.0f);

            foreach (int vid in builder.Graph.VertexIndices())
            {
                Vector2d v = builder.Graph.GetVertex(vid);
                if (srcpts.Contains(v) == false)
                {
                    svg.AddCircle(new Circle2d(v, 2), vtx_style);
                }
            }

            svg.Write(TestUtil.GetTestOutputPath("arrangement.svg"));
        }
Example #19
0
 public FillPolyline2d(PolyLine2d p) : base(p)
 {
     CustomThickness = 0;
 }
Example #20
0
 public void AddEmbeddedPath(PolyLine2d pline)
 {
     EmbeddedPaths.Add(pline);
 }
Example #21
0
        /// <summary>
        /// Slice the meshes and return the slice stack.
        /// </summary>
        public PlanarSliceStack Compute()
        {
            if (Meshes.Count == 0)
            {
                return(new PlanarSliceStack());
            }

            Interval1d zrange = Interval1d.Empty;

            foreach (var meshinfo in Meshes)
            {
                zrange.Contain(meshinfo.bounds.Min.z);
                zrange.Contain(meshinfo.bounds.Max.z);
            }
            if (SetMinZValue != double.MinValue)
            {
                zrange.a = SetMinZValue;
            }

            int nLayers = (int)(zrange.Length / LayerHeightMM);

            if (nLayers > MaxLayerCount)
            {
                throw new Exception("MeshPlanarSlicer.Compute: exceeded layer limit. Increase .MaxLayerCount.");
            }

            // make list of slice heights (could be irregular)
            List <double> heights = new List <double>();

            for (int i = 0; i < nLayers + 1; ++i)
            {
                double t = zrange.a + (double)i * LayerHeightMM;
                if (SliceLocation == SliceLocations.EpsilonBase)
                {
                    t += 0.01 * LayerHeightMM;
                }
                else if (SliceLocation == SliceLocations.MidLine)
                {
                    t += 0.5 * LayerHeightMM;
                }
                heights.Add(t);
            }
            int NH = heights.Count;

            // process each *slice* in parallel
            PlanarSlice[] slices = new PlanarSlice[NH];
            for (int i = 0; i < NH; ++i)
            {
                slices[i] = SliceFactoryF(heights[i], i);
                slices[i].EmbeddedPathWidth = OpenPathDefaultWidthMM;
            }

            // assume Resolve() takes 2x as long as meshes...
            TotalCompute = (Meshes.Count * NH) + (2 * NH);
            Progress     = 0;


            // compute slices separately for each mesh
            for (int mi = 0; mi < Meshes.Count; ++mi)
            {
                if (Cancelled())
                {
                    break;
                }

                DMesh3           mesh         = Meshes[mi].mesh;
                PrintMeshOptions mesh_options = Meshes[mi].options;

                // [TODO] should we hang on to this spatial? or should it be part of assembly?
                DMeshAABBTree3   spatial = new DMeshAABBTree3(mesh, true);
                AxisAlignedBox3d bounds  = Meshes[mi].bounds;

                bool is_cavity   = mesh_options.IsCavity;
                bool is_crop     = mesh_options.IsCropRegion;
                bool is_support  = mesh_options.IsSupport;
                bool is_closed   = (mesh_options.IsOpen) ? false : mesh.IsClosed();
                var  useOpenMode = (mesh_options.OpenPathMode == PrintMeshOptions.OpenPathsModes.Default) ?
                                   DefaultOpenPathMode : mesh_options.OpenPathMode;

                // each layer is independent so we can do in parallel
                gParallel.ForEach(Interval1i.Range(NH), (i) => {
                    if (Cancelled())
                    {
                        return;
                    }

                    double z = heights[i];
                    if (z < bounds.Min.z || z > bounds.Max.z)
                    {
                        return;
                    }

                    // compute cut
                    Polygon2d[] polys; PolyLine2d[] paths;
                    compute_plane_curves(mesh, spatial, z, is_closed, out polys, out paths);

                    // if we didn't hit anything, try again with jittered plane
                    // [TODO] this could be better...
                    if ((is_closed && polys.Length == 0) || (is_closed == false && polys.Length == 0 && paths.Length == 0))
                    {
                        compute_plane_curves(mesh, spatial, z + LayerHeightMM * 0.25, is_closed, out polys, out paths);
                    }

                    if (is_closed)
                    {
                        // construct planar complex and "solids"
                        // (ie outer polys and nested holes)
                        PlanarComplex complex = new PlanarComplex();
                        foreach (Polygon2d poly in polys)
                        {
                            complex.Add(poly);
                        }

                        PlanarComplex.FindSolidsOptions options
                            = PlanarComplex.FindSolidsOptions.Default;
                        options.WantCurveSolids            = false;
                        options.SimplifyDeviationTolerance = 0.001;
                        options.TrustOrientations          = true;
                        options.AllowOverlappingHoles      = true;

                        PlanarComplex.SolidRegionInfo solids =
                            complex.FindSolidRegions(options);

                        if (is_support)
                        {
                            add_support_polygons(slices[i], solids.Polygons, mesh_options);
                        }
                        else if (is_cavity)
                        {
                            add_cavity_polygons(slices[i], solids.Polygons, mesh_options);
                        }
                        else if (is_crop)
                        {
                            add_crop_region_polygons(slices[i], solids.Polygons, mesh_options);
                        }
                        else
                        {
                            add_solid_polygons(slices[i], solids.Polygons, mesh_options);
                        }
                    }
                    else if (useOpenMode != PrintMeshOptions.OpenPathsModes.Ignored)
                    {
                        foreach (PolyLine2d pline in paths)
                        {
                            if (useOpenMode == PrintMeshOptions.OpenPathsModes.Embedded)
                            {
                                slices[i].AddEmbeddedPath(pline);
                            }
                            else
                            {
                                slices[i].AddClippedPath(pline);
                            }
                        }

                        // [TODO]
                        //   - does not really handle clipped polygons properly, there will be an extra break somewhere...
                        foreach (Polygon2d poly in polys)
                        {
                            PolyLine2d pline = new PolyLine2d(poly, true);
                            if (useOpenMode == PrintMeshOptions.OpenPathsModes.Embedded)
                            {
                                slices[i].AddEmbeddedPath(pline);
                            }
                            else
                            {
                                slices[i].AddClippedPath(pline);
                            }
                        }
                    }

                    Interlocked.Increment(ref Progress);
                });       // end of parallel.foreach
            }             // end mesh iter

            // resolve planar intersections, etc
            gParallel.ForEach(Interval1i.Range(NH), (i) => {
                if (Cancelled())
                {
                    return;
                }
                slices[i].Resolve();
                Interlocked.Add(ref Progress, 2);
            });

            // discard spurious empty slices
            int last = slices.Length - 1;

            while (slices[last].IsEmpty && last > 0)
            {
                last--;
            }
            int first = 0;

            if (DiscardEmptyBaseSlices)
            {
                while (slices[first].IsEmpty && first < slices.Length)
                {
                    first++;
                }
            }

            PlanarSliceStack stack = SliceStackFactoryF();

            for (int k = first; k <= last; ++k)
            {
                stack.Add(slices[k]);
            }

            if (SupportMinZTips)
            {
                stack.AddMinZTipSupportPoints(MinZTipMaxDiam, MinZTipExtraLayers);
            }

            return(stack);
        }
Example #22
0
 public void AddClippedPath(PolyLine2d pline)
 {
     ClippedPaths.Add(pline);
 }
        public static void test_tube_generator()
        {
            Polygon2d  circle_path = Polygon2d.MakeCircle(50, 64);
            PolyLine2d arc_path    = new PolyLine2d(circle_path.Vertices.Take(circle_path.VertexCount / 2));
            Polygon2d  irreg_path  = new Polygon2d();

            for (int k = 0; k < circle_path.VertexCount; ++k)
            {
                irreg_path.AppendVertex(circle_path[k]);
                k += k / 2;
            }
            PolyLine2d irreg_arc_path = new PolyLine2d(irreg_path.Vertices.Take(circle_path.VertexCount - 1));

            Polygon2d square_profile = Polygon2d.MakeCircle(7, 32);

            square_profile.Translate(4 * Vector2d.One);
            //square_profile[0] = 20 * square_profile[0].Normalized;

            bool no_shared = true;

            WriteGeneratedMesh(
                new TubeGenerator(circle_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_loop_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(irreg_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_irregloop_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(arc_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_arc_standarduv.obj");

            WriteGeneratedMesh(
                new TubeGenerator(irreg_arc_path, Frame3f.Identity, square_profile)
            {
                WantUVs = true, NoSharedVertices = no_shared
            },
                "tubegen_irregarc_standarduv.obj");



            // append tube border around each hole of input mesh
            DMesh3            inMesh   = TestUtil.LoadTestInputMesh("n_holed_bunny.obj");
            Polygon2d         bdrycirc = Polygon2d.MakeCircle(0.25, 6);
            MeshBoundaryLoops loops    = new MeshBoundaryLoops(inMesh);

            foreach (EdgeLoop loop in loops)
            {
                DCurve3       curve = loop.ToCurve().ResampleSharpTurns();
                TubeGenerator gen   = new TubeGenerator(curve, bdrycirc)
                {
                    NoSharedVertices = false
                };
                MeshEditor.Append(inMesh, gen.Generate().MakeDMesh());
            }
            TestUtil.WriteTestOutputMesh(inMesh, "boundary_tubes.obj");
        }