Exemplo n.º 1
0
        public void PrintStats(string label = "")
        {
            System.Console.WriteLine("PlanarComplex Stats {0}", label);
            List <SmoothLoopElement>  Loops  = new List <SmoothLoopElement>(LoopsItr());
            List <SmoothCurveElement> Curves = new List <SmoothCurveElement>(CurvesItr());

            AxisAlignedBox2d bounds = Bounds();

            System.Console.WriteLine("  Bounding Box  w: {0} h: {1}  range {2} ", bounds.Width, bounds.Height, bounds);

            List <ComplexEndpoint2d> vEndpoints = new List <ComplexEndpoint2d>(EndpointsItr());

            System.Console.WriteLine("  Closed Loops {0}  Open Curves {1}   Open Endpoints {2}",
                                     Loops.Count, Curves.Count, vEndpoints.Count);

            int nSegments    = CountType(typeof(Segment2d));
            int nArcs        = CountType(typeof(Arc2d));
            int nCircles     = CountType(typeof(Circle2d));
            int nNURBS       = CountType(typeof(NURBSCurve2));
            int nEllipses    = CountType(typeof(Ellipse2d));
            int nEllipseArcs = CountType(typeof(EllipseArc2d));
            int nSeqs        = CountType(typeof(ParametricCurveSequence2));

            System.Console.WriteLine("  [Type Counts]   // {0} multi-curves", nSeqs);
            System.Console.WriteLine("    segments {0,4}  arcs     {1,4}  circles      {2,4}", nSegments, nArcs, nCircles);
            System.Console.WriteLine("    nurbs    {0,4}  ellipses {1,4}  ellipse-arcs {2,4}", nNURBS, nEllipses, nEllipseArcs);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Fallback to deal with very tiny polygons that disappear when insetting.
        /// This happens at Z-minima-tips, which can be a problem because it may leave
        /// gaps between layers. For tips we draw a tiny circle.
        /// For elongated shapes we...?? currently do something dumb.
        /// Probably should use robust thinning!
        /// </summary>
        public virtual void HandleTinyPolygon()
        {
            //(InsetFromInputPolygon) ?
            //ClipperUtil.ComputeOffsetPolygon(Polygon, -ToolWidth / 2, true) :
            AxisAlignedBox2d bounds = Polygon.Bounds;

            if (bounds.MaxDim < ToolWidth)
            {
                GeneralPolygon2d min_poly = new GeneralPolygon2d(Polygon2d.MakeCircle(ToolWidth / 4, 6));
                min_poly.Outer.Translate(bounds.Center);
                FillCurveSet2d paths = ShellPolysToPaths(new List <GeneralPolygon2d>()
                {
                    min_poly
                }, 0);
                Shells.Add(paths);
            }
            else
            {
                FillCurveSet2d paths = ShellPolysToPaths(new List <GeneralPolygon2d>()
                {
                    Polygon
                }, 0);
                Shells.Add(paths);
            }

            InnerPolygons = new List <GeneralPolygon2d>();
        }
Exemplo n.º 3
0
        public static void test_tiling()
        {
            Vector2d         origin     = Vector2d.Zero;
            double           radius     = 22;
            Circle2d         circ       = new Circle2d(origin, radius);
            AxisAlignedBox2d elemBounds = circ.Bounds;
            //elemBounds.Max.x += radius / 2;

            AxisAlignedBox2d packBounds = new AxisAlignedBox2d(0, 0, 800, 400);
            double           spacing    = 5;
            Polygon2d        boundsPoly = new Polygon2d();

            for (int i = 0; i < 4; ++i)
            {
                boundsPoly.AppendVertex(packBounds.GetCorner(i));
            }

            //List<Vector2d> packed = TilingUtil.BoundedRegularTiling2(elemBounds, packBounds, spacing);
            List <Vector2d> packed = TilingUtil.BoundedCircleTiling2(elemBounds, packBounds, spacing);

            System.Console.WriteLine("packed {0}", packed.Count);

            SVGWriter writer = new SVGWriter();

            foreach (Vector2d t in packed)
            {
                writer.AddCircle(new Circle2d(origin + t, radius), SVGWriter.Style.Outline("black", 1.0f));
            }
            writer.AddPolygon(boundsPoly, SVGWriter.Style.Outline("red", 2.0f));
            writer.Write(TestUtil.GetTestOutputPath("test.svg"));
        }
Exemplo n.º 4
0
        void OnExpose(object sender, ExposeEventArgs args)
        {
            DrawingArea area = (DrawingArea)sender;

            Cairo.Context cairoContext = Gdk.CairoHelper.Create(area.GdkWindow);

            int width  = area.Allocation.Width;
            int height = area.Allocation.Height;

            PixelDimensions = new Vector2i(width, height);

            AxisAlignedBox2d bounds = DrawingBounds;

            double sx = (double)width / bounds.Width;
            double sy = (double)height / bounds.Height;

            float scale = (float)Math.Min(sx, sy);

            // we apply this translate after scaling to pixel coords
            Vector2f pixC      = Zoom * scale * (Vector2f)bounds.Center;
            Vector2f translate = new Vector2f(width / 2, height / 2) - pixC;


            using (var bitmap = new SKBitmap(width, height, SkiaUtil.ColorType(), SKAlphaType.Premul)) {
                IntPtr len;
                using (var skSurface = SKSurface.Create(bitmap.Info.Width, bitmap.Info.Height, SkiaUtil.ColorType(), SKAlphaType.Premul, bitmap.GetPixels(out len), bitmap.Info.RowBytes)) {
                    var canvas = skSurface.Canvas;

                    // update scene xform
                    Func <Vector2d, Vector2f> ViewTransformF = (pOrig) => {
                        Vector2f pNew = (Vector2f)pOrig - (Vector2f)bounds.Center;
                        pNew   = Zoom * scale * pNew;
                        pNew  += (Vector2f)pixC;
                        pNew  += translate + Zoom * PixelTranslate;
                        pNew.y = canvas.ClipBounds.Height - pNew.y;
                        return(pNew);
                    };

                    DrawScene(canvas, ViewTransformF);

                    Cairo.Surface cairoSurf = new Cairo.ImageSurface(
                        bitmap.GetPixels(out len),
                        Cairo.Format.Argb32,
                        bitmap.Width, bitmap.Height,
                        bitmap.Width * 4);

                    cairoSurf.MarkDirty();
                    cairoContext.SetSourceSurface(cairoSurf, 0, 0);
                    cairoContext.Paint();

                    cairoSurf.Dispose();
                }
            }

            cairoContext.Dispose();

            //return true;
        }
Exemplo n.º 5
0
        public AxisAlignedBox2d Bounds()
        {
            AxisAlignedBox2d box = AxisAlignedBox2d.Empty;

            foreach (Element e in vElements)
            {
                box.Contain(e.Bounds());
            }
            return(box);
        }
Exemplo n.º 6
0
        public static Polygon2d ToPolygon(this AxisAlignedBox2d _box)
        {
            var p0 = _box.Min;
            var p1 = new Vector2d(_box.Max.x, _box.Min.y);
            var p2 = _box.Max;
            var p3 = new Vector2d(_box.Min.x, _box.Max.y);

            return(new Polygon2d(new List <Vector2d>()
            {
                p0, p1, p2, p3
            }));
        }
Exemplo n.º 7
0
        public MakerbotAssembler(GCodeBuilder useBuilder, SingleMaterialFFFSettings settings) : base(useBuilder, settings.Machine)
        {
            Settings = settings as SingleMaterialFFFSettings;

            PositionBounds = new AxisAlignedBox2d(settings.Machine.BedSizeXMM, settings.Machine.BedSizeYMM);
            PositionBounds.Translate(-PositionBounds.Center);

            // [RMS] currently bed dimensions are hardcoded in header setup, and this trips bounds-checker.
            // So, disable this checking for now.
            EnableBoundsChecking = false;

            TravelGCode = 1;
        }
Exemplo n.º 8
0
        public MakerbotAssembler(GCodeBuilder useBuilder, SingleMaterialFFFSettings settings) : base(useBuilder, settings.Machine)
        {
            if (settings is MakerbotSettings == false)
            {
                throw new Exception("MakerbotAssembler: incorrect settings type!");
            }

            Settings = settings as MakerbotSettings;

            PositionBounds = new AxisAlignedBox2d(settings.Machine.BedSizeXMM, settings.Machine.BedSizeYMM);
            PositionBounds.Translate(-PositionBounds.Center);

            TravelGCode = 1;
        }
Exemplo n.º 9
0
        public AxisAlignedBox2d GetBounds()
        {
            if (vertices.Count == 0)
            {
                return(AxisAlignedBox2d.Empty);
            }
            AxisAlignedBox2d box = new AxisAlignedBox2d(vertices[0]);

            for (int i = 1; i < vertices.Count; ++i)
            {
                box.Contain(vertices[i]);
            }
            return(box);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Add explicit support points for any small floating polygons.
        /// These can be used at toolpathing time to ensure support for
        /// such areas, which otherwise might be lost (or insufficiently
        /// supported) by the standard techniques to detect support regions.
        /// </summary>
        public void AddMinZTipSupportPoints(double tipDiamThresh = 2.0, int nExtraLayers = 0)
        {
            List <Vector3d> tips    = new List <Vector3d>();
            SpinLock        tiplock = new SpinLock();

            int N = Slices.Count;

            gParallel.ForEach(Interval1i.FromToInclusive(1, N - 1), (li) =>
            {
                PlanarSlice slice = Slices[li];
                PlanarSlice prev  = Slices[li - 1];
                foreach (GeneralPolygon2d poly in slice.InputSolids)
                {
                    AxisAlignedBox2d bounds = poly.Bounds;
                    if (bounds.MaxDim > tipDiamThresh)
                    {
                        continue;
                    }
                    Vector2d c     = bounds.Center;
                    bool contained = false;
                    foreach (var poly2 in prev.InputSolids)
                    {
                        if (poly2.Contains(c))
                        {
                            contained = true;
                            break;
                        }
                    }
                    if (contained)
                    {
                        continue;
                    }
                    bool entered = false;
                    tiplock.Enter(ref entered);
                    tips.Add(new Vector3d(c.x, c.y, li));
                    tiplock.Exit();
                }
            });

            foreach (var tip in tips)
            {
                int layer_i = (int)tip.z;
                int add_to  = Math.Min(N - 1, layer_i + nExtraLayers);
                for (int i = layer_i; i < add_to; ++i)
                {
                    Slices[i].InputSupportPoints.Add(tip.xy);
                }
            }
        }
Exemplo n.º 11
0
 public AABBTree(IList <Triangle2d> mesh)
 {
     _box = mesh.GetBBox();
     mesh = (_box.Height > _box.Width ?
             mesh.OrderBy(tra => tra.V0.y)
         : mesh.OrderBy(tra => tra.V0.x)).ToList();
     if (mesh.Count != 1)
     {
         _isALeef = false;
         var midIndex = mesh.Count / 2;
         _left  = new AABBTree(mesh.Take(midIndex).ToList());
         _right = new AABBTree(mesh.Skip(midIndex).Take(mesh.Count - midIndex).ToList());
     }
     else
     {
         _isALeef = true;
         _mesh    = mesh.First();
     }
 }
Exemplo n.º 12
0
        /// <summary>
        /// Precompute spatial caching information. This is not thread-safe.
        /// (Currently just list of bboxes for each solid/path.)
        /// </summary>
        public void BuildSpatialCaches()
        {
            int NS = Solids.Count;

            solid_bounds = new AxisAlignedBox2d[NS];
            for (int i = 0; i < NS; ++i)
            {
                solid_bounds[i] = Solids[i].Bounds;
            }

            int NP = Paths.Count;

            path_bounds = new AxisAlignedBox2d[NP];
            for (int i = 0; i < NP; ++i)
            {
                path_bounds[i] = Paths[i].Bounds;
            }

            spatial_caches_available = true;
        }
Exemplo n.º 13
0
        public static void CalculateUVs(this DMesh3 dMesh)
        {
            dMesh.EnableVertexUVs(Vector2f.Zero);
            OrthogonalPlaneFit3 orth          = new OrthogonalPlaneFit3(dMesh.Vertices());
            Frame3f             frame         = new Frame3f(orth.Origin, orth.Normal);
            AxisAlignedBox3d    bounds        = dMesh.CachedBounds;
            AxisAlignedBox2d    boundsInFrame = new AxisAlignedBox2d();

            for (int i = 0; i < 8; i++)
            {
                boundsInFrame.Contain(frame.ToPlaneUV((Vector3f)bounds.Corner(i), 3));
            }
            Vector2f min    = (Vector2f)boundsInFrame.Min;
            float    width  = (float)boundsInFrame.Width;
            float    height = (float)boundsInFrame.Height;

            for (int i = 0; i < dMesh.VertexCount; i++)
            {
                Vector2f UV = frame.ToPlaneUV((Vector3f)dMesh.GetVertex(i), 3);
                UV.x = (UV.x - min.x) / width;
                UV.y = (UV.y - min.y) / height;
                dMesh.SetVertexUV(i, UV);
            }
        }
Exemplo n.º 14
0
        /// <summary>
        /// This function is supposed to take a set of spans in a plane and sort them
        /// into regions that can be filled with a polygon. Currently kind of clusters
        /// based on intersecting bboxes. Does not work.
        ///
        /// I think fundamentally it needs to look back at the input mesh, to see what
        /// is connected/not-connected. Or possibly use polygon winding number? Need
        /// to somehow define what the holes are...
        /// </summary>
        List <List <EdgeSpan> > sort_planar_spans(List <EdgeSpan> allspans, Vector3d normal)
        {
            var result    = new List <List <EdgeSpan> >();
            var polyFrame = new Frame3f(Vector3d.Zero, normal);

            int N = allspans.Count;

            var plines = new List <PolyLine2d>();

            foreach (EdgeSpan span in allspans)
            {
                plines.Add(to_polyline(span, polyFrame));
            }

            bool[] bad_poly = new bool[N];
            for (int k = 0; k < N; ++k)
            {
                bad_poly[k] = false;                 // self_intersects(plines[k]);
            }

            bool[] used = new bool[N];
            for (int k = 0; k < N; ++k)
            {
                if (used[k])
                {
                    continue;
                }

                bool             is_bad = bad_poly[k];
                AxisAlignedBox2d bounds = plines[k].Bounds;
                used[k] = true;

                var set = new List <int>()
                {
                    k
                };

                for (int j = k + 1; j < N; ++j)
                {
                    if (used[j])
                    {
                        continue;
                    }

                    AxisAlignedBox2d boundsj = plines[j].Bounds;
                    if (bounds.Intersects(boundsj))
                    {
                        used[j] = true;
                        is_bad  = is_bad || bad_poly[j];
                        bounds.Contain(boundsj);
                        set.Add(j);
                    }
                }

                if (is_bad == false)
                {
                    var span_set = new List <EdgeSpan>();
                    foreach (int idx in set)
                    {
                        span_set.Add(allspans[idx]);
                    }

                    result.Add(span_set);
                }
            }

            return(result);
        }
Exemplo n.º 15
0
        public static Vector2d TranslatePointsCoordinationInsideTheBoundingBox(Vector2d point, AxisAlignedBox2d bounds)
        {
            Vector2d tmpPoint = new Vector2d();

            tmpPoint.x = bounds.Min.x + (bounds.Max.x - bounds.Min.x) * point.x;
            tmpPoint.y = bounds.Min.y + (bounds.Max.y - bounds.Min.y) * point.y;
            return(tmpPoint);
        }
Exemplo n.º 16
0
        // exports svg w/ different containments of point set (created by slicing mesh)
        public static void containment_demo_svg()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj");

            MeshTransforms.Scale(mesh, 4);

            AxisAlignedBox3d meshBounds = mesh.CachedBounds;
            Vector3d         origin     = meshBounds.Center;

            origin -= 0.2 * meshBounds.Height * Vector3d.AxisY;
            Frame3f      plane = new Frame3f(origin, new Vector3d(1, 3, 0).Normalized);
            MeshPlaneCut cut   = new MeshPlaneCut(mesh, plane.Origin, plane.Z);

            cut.Cut();

            AxisAlignedBox2d polyBounds = AxisAlignedBox2d.Empty;
            List <Polygon2d> polys      = new List <Polygon2d>();

            foreach (EdgeLoop loop in cut.CutLoops)
            {
                Polygon2d poly = new Polygon2d();
                foreach (int vid in loop.Vertices)
                {
                    poly.AppendVertex(mesh.GetVertex(vid).xz);
                }
                poly.Rotate(new Matrix2d(90, true), Vector2d.Zero);
                polys.Add(poly);
                polyBounds.Contain(poly.Bounds);
            }

            SVGWriter svg       = new SVGWriter();
            var       polyStyle = SVGWriter.Style.Outline("red", 1.0f);
            var       contStyle = SVGWriter.Style.Outline("black", 1.0f);

            for (int k = 0; k < 3; ++k)
            {
                double          shift = (k == 2) ? 1.4f : 1.1f;
                Vector2d        tx    = (k - 1) * (polyBounds.Width * shift) * Vector2d.AxisX;
                List <Vector2d> pts   = new List <Vector2d>();
                foreach (Polygon2d poly in polys)
                {
                    var p2 = new Polygon2d(poly).Translate(tx);
                    pts.AddRange(p2.Vertices);
                    svg.AddPolygon(p2, polyStyle);
                }

                if (k == 0)
                {
                    ConvexHull2 hull = new ConvexHull2(pts, 0.001, QueryNumberType.QT_DOUBLE);
                    svg.AddPolygon(hull.GetHullPolygon(), contStyle);
                }
                else if (k == 1)
                {
                    ContMinBox2 contbox = new ContMinBox2(pts, 0.001, QueryNumberType.QT_DOUBLE, false);
                    svg.AddPolygon(new Polygon2d(contbox.MinBox.ComputeVertices()), contStyle);
                }
                else if (k == 2)
                {
                    ContMinCircle2 contcirc = new ContMinCircle2(pts);
                    svg.AddCircle(contcirc.Result, contStyle);
                }
            }


            svg.Write(TestUtil.GetTestOutputPath("contain_demos.svg"));
        }
Exemplo n.º 17
0
        void OnExpose(object sender, ExposeEventArgs args)
        {
            DrawingArea area = (DrawingArea)sender;

            Cairo.Context cr = Gdk.CairoHelper.Create(area.GdkWindow);

            int width  = area.Allocation.Width;
            int height = area.Allocation.Height;

            AxisAlignedBox3d bounds3 = Stack.Bounds;
            AxisAlignedBox2d bounds  = (bounds3 == AxisAlignedBox3d.Empty) ?
                                       new AxisAlignedBox2d(0, 0, 500, 500) :
                                       new AxisAlignedBox2d(bounds3.Min.x, bounds3.Min.y, bounds3.Max.x, bounds3.Max.y);

            double sx = (double)width / bounds.Width;
            double sy = (double)height / bounds.Height;

            float scale = (float)Math.Min(sx, sy);

            // we apply this translate after scaling to pixel coords
            Vector2f pixC      = Zoom * scale * (Vector2f)bounds.Center;
            Vector2f translate = new Vector2f(width / 2, height / 2) - pixC;

            using (var bitmap = new SKBitmap(width, height, SkiaUtil.ColorType(), SKAlphaType.Premul))
            {
                IntPtr len;
                using (var skSurface = SKSurface.Create(bitmap.Info.Width, bitmap.Info.Height, SkiaUtil.ColorType(), SKAlphaType.Premul, bitmap.GetPixels(out len), bitmap.Info.RowBytes))
                {
                    var canvas = skSurface.Canvas;
                    canvas.Clear(SkiaUtil.Color(240, 240, 240, 255));

                    Func <Vector2d, Vector2f> xformF = (pOrig) => {
                        Vector2f pNew = (Vector2f)pOrig;
                        pNew  -= (Vector2f)bounds.Center;
                        pNew   = Zoom * scale * pNew;
                        pNew  += (Vector2f)pixC;
                        pNew  += translate + Zoom * Translate;
                        pNew.y = canvas.LocalClipBounds.Height - pNew.y;
                        return(pNew);
                    };
                    Func <Vector2d, SKPoint> mapToSkiaF = (pOrig) => {
                        Vector2f p = xformF(pOrig);
                        return(new SKPoint(p.x, p.y));
                    };

                    using (var paint = new SKPaint())
                    {
                        SKBitmap sliceImg = get_slice_image(currentLayer);
                        float    w = sliceImg.Width / CurrentDPIMM, h = sliceImg.Height / CurrentDPIMM;
                        w *= Zoom * scale;
                        h *= Zoom * scale;
                        SKPoint sliceCenter = mapToSkiaF(Vector2d.Zero);
                        SKRect  drawRect    = new SKRect(
                            sliceCenter.X - w / 2, sliceCenter.Y - h / 2,
                            sliceCenter.X + w / 2, sliceCenter.Y + h / 2);
                        canvas.DrawBitmap(sliceImg, drawRect, paint);


                        paint.IsAntialias = true;
                        paint.Style       = SKPaintStyle.Stroke;

                        PlanarSlice slice = Stack.Slices[currentLayer];

                        paint.Color       = SkiaUtil.Color(255, 0, 0, 255);;
                        paint.StrokeWidth = 2;
                        foreach (GeneralPolygon2d poly in slice.Solids)
                        {
                            SKPath path = SkiaUtil.ToSKPath(poly, mapToSkiaF);
                            canvas.DrawPath(path, paint);
                        }
                    }

                    Cairo.Surface surface = new Cairo.ImageSurface(
                        bitmap.GetPixels(out len),
                        Cairo.Format.Argb32,
                        bitmap.Width, bitmap.Height,
                        bitmap.Width * 4);

                    surface.MarkDirty();
                    cr.SetSourceSurface(surface, 0, 0);
                    cr.Paint();
                }
            }

            //return true;
        }
Exemplo n.º 18
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DMesh3_goo goo             = null;
            double     lattice_radius  = 0.05;
            double     lattice_spacing = 0.4;
            double     shell_thickness = 0.05;
            int        mesh_resolution = 64;

            DA.GetData(0, ref goo);
            DA.GetData(1, ref lattice_radius);
            DA.GetData(2, ref lattice_spacing);
            DA.GetData(3, ref shell_thickness);
            DA.GetData(4, ref mesh_resolution);

            DMesh3 mesh = new DMesh3(goo.Value);

            var              shellMeshImplicit = g3ghUtil.MeshToImplicit(mesh, 128, shell_thickness);
            double           max_dim           = mesh.CachedBounds.MaxDim;
            AxisAlignedBox3d bounds            = new AxisAlignedBox3d(mesh.CachedBounds.Center, max_dim / 2);

            bounds.Expand(2 * lattice_spacing);
            AxisAlignedBox2d element   = new AxisAlignedBox2d(lattice_spacing);
            AxisAlignedBox2d bounds_xy = new AxisAlignedBox2d(bounds.Min.xy, bounds.Max.xy);
            AxisAlignedBox2d bounds_xz = new AxisAlignedBox2d(bounds.Min.xz, bounds.Max.xz);
            AxisAlignedBox2d bounds_yz = new AxisAlignedBox2d(bounds.Min.yz, bounds.Max.yz);

            List <BoundedImplicitFunction3d> Tiling = new List <BoundedImplicitFunction3d>();

            foreach (g3.Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xy, 0))
            {
                Segment3d seg = new Segment3d(new g3.Vector3d(uv.x, uv.y, bounds.Min.z), new g3.Vector3d(uv.x, uv.y, bounds.Max.z));
                Tiling.Add(new ImplicitLine3d()
                {
                    Segment = seg, Radius = lattice_radius
                });
            }
            foreach (g3.Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xz, 0))
            {
                Segment3d seg = new Segment3d(new g3.Vector3d(uv.x, bounds.Min.y, uv.y), new g3.Vector3d(uv.x, bounds.Max.y, uv.y));
                Tiling.Add(new ImplicitLine3d()
                {
                    Segment = seg, Radius = lattice_radius
                });
            }
            foreach (g3.Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_yz, 0))
            {
                Segment3d seg = new Segment3d(new g3.Vector3d(bounds.Min.x, uv.x, uv.y), new g3.Vector3d(bounds.Max.x, uv.x, uv.y));
                Tiling.Add(new ImplicitLine3d()
                {
                    Segment = seg, Radius = lattice_radius
                });
            }

            ImplicitNaryUnion3d lattice = new ImplicitNaryUnion3d()
            {
                Children = Tiling
            };
            ImplicitIntersection3d lattice_clipped = new ImplicitIntersection3d()
            {
                A = lattice, B = shellMeshImplicit
            };

            g3.MarchingCubes c = new g3.MarchingCubes();
            c.Implicit      = lattice_clipped;
            c.RootMode      = g3.MarchingCubes.RootfindingModes.LerpSteps;
            c.RootModeSteps = 5;
            c.Bounds        = lattice_clipped.Bounds();
            c.CubeSize      = c.Bounds.MaxDim / mesh_resolution;
            c.Bounds.Expand(3 * c.CubeSize);
            c.Generate();
            MeshNormals.QuickCompute(c.Mesh);


            DA.SetData(0, c.Mesh);
        }
Exemplo n.º 19
0
        // Finds set of "solid" regions - eg boundary loops with interior holes.
        // Result has outer loops being clockwise, and holes counter-clockwise
        public SolidRegionInfo FindSolidRegions(double fSimplifyDeviationTol = 0.1, bool bWantCurveSolids = true)
        {
            List <SmoothLoopElement> validLoops = new List <SmoothLoopElement>(LoopsItr());
            int N = validLoops.Count;

            // precompute bounding boxes
            int maxid = 0;

            foreach (var v in validLoops)
            {
                maxid = Math.Max(maxid, v.ID + 1);
            }
            AxisAlignedBox2d[] bounds = new AxisAlignedBox2d[maxid];
            foreach (var v in validLoops)
            {
                bounds[v.ID] = v.Bounds();
            }

            // copy polygons, simplify if desired
            double fClusterTol   = 0.0;                         // don't do simple clustering, can lose corners
            double fDeviationTol = fSimplifyDeviationTol;

            Polygon2d[] polygons = new Polygon2d[maxid];
            foreach (var v in validLoops)
            {
                Polygon2d p = new Polygon2d(v.polygon);
                if (fClusterTol > 0 || fDeviationTol > 0)
                {
                    p.Simplify(fClusterTol, fDeviationTol);
                }
                polygons[v.ID] = p;
            }

            // sort by bbox containment to speed up testing (does it??)
            validLoops.Sort((x, y) => {
                return(bounds[x.ID].Contains(bounds[y.ID]) ? -1 : 1);
            });

            // containment sets
            bool[] bIsContained = new bool[N];
            Dictionary <int, List <int> > ContainSets      = new Dictionary <int, List <int> >();
            Dictionary <int, List <int> > ContainedParents = new Dictionary <int, List <int> >();

            // construct containment sets
            for (int i = 0; i < N; ++i)
            {
                SmoothLoopElement loopi = validLoops[i];
                Polygon2d         polyi = polygons[loopi.ID];

                for (int j = 0; j < N; ++j)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    SmoothLoopElement loopj = validLoops[j];
                    Polygon2d         polyj = polygons[loopj.ID];

                    // cannot be contained if bounds are not contained
                    if (bounds[loopi.ID].Contains(bounds[loopj.ID]) == false)
                    {
                        continue;
                    }

                    // any other early-outs??

                    if (polyi.Contains(polyj))
                    {
                        if (ContainSets.ContainsKey(i) == false)
                        {
                            ContainSets.Add(i, new List <int>());
                        }
                        ContainSets[i].Add(j);
                        bIsContained[j] = true;

                        if (ContainedParents.ContainsKey(j) == false)
                        {
                            ContainedParents.Add(j, new List <int>());
                        }
                        ContainedParents[j].Add(i);
                    }
                }
            }

            List <GeneralPolygon2d>     polysolids = new List <GeneralPolygon2d>();
            List <PlanarSolid2d>        solids     = new List <PlanarSolid2d>();
            HashSet <SmoothLoopElement> used       = new HashSet <SmoothLoopElement>();

            Dictionary <SmoothLoopElement, int> LoopToOuterIndex = new Dictionary <SmoothLoopElement, int>();

            List <int> ParentsToProcess = new List <int>();


            // The following is a lot of code but it is very similar, just not clear how
            // to refactor out the common functionality
            //   1) we find all the top-level uncontained polys and add them to the final polys list
            //   2a) for any poly contained in those parent-polys, that is not also contained in anything else,
            //       add as hole to that poly
            //   2b) remove all those used parents & holes from consideration
            //   2c) now find all the "new" top-level polys
            //   3) repeat 2a-c until done all polys
            //   4) any remaining polys must be interior solids w/ no holes
            //          **or** weird leftovers like intersecting polys...

            // add all top-level uncontained polys
            for (int i = 0; i < N; ++i)
            {
                SmoothLoopElement loopi = validLoops[i];
                if (bIsContained[i])
                {
                    continue;
                }

                Polygon2d          outer_poly = polygons[loopi.ID];
                IParametricCurve2d outer_loop = (bWantCurveSolids) ? loopi.source.Clone() : null;
                if (outer_poly.IsClockwise == false)
                {
                    outer_poly.Reverse();
                    if (bWantCurveSolids)
                    {
                        outer_loop.Reverse();
                    }
                }

                GeneralPolygon2d g = new GeneralPolygon2d {
                    Outer = outer_poly
                };
                PlanarSolid2d s = new PlanarSolid2d();
                if (bWantCurveSolids)
                {
                    s.SetOuter(outer_loop, true);
                }

                int idx = polysolids.Count;
                LoopToOuterIndex[loopi] = idx;
                used.Add(loopi);

                if (ContainSets.ContainsKey(i))
                {
                    ParentsToProcess.Add(i);
                }

                polysolids.Add(g);
                if (bWantCurveSolids)
                {
                    solids.Add(s);
                }
            }


            // keep iterating until we processed all parent loops
            while (ParentsToProcess.Count > 0)
            {
                List <int> ContainersToRemove = new List <int>();

                // now for all top-level polys that contain children, add those children
                // as long as they do not have multiple contain-parents
                foreach (int i in ParentsToProcess)
                {
                    SmoothLoopElement parentloop = validLoops[i];
                    int outer_idx = LoopToOuterIndex[parentloop];

                    List <int> children = ContainSets[i];
                    foreach (int childj in children)
                    {
                        SmoothLoopElement childLoop = validLoops[childj];
                        Debug.Assert(used.Contains(childLoop) == false);

                        // skip multiply-contained children
                        List <int> parents = ContainedParents[childj];
                        if (parents.Count > 1)
                        {
                            continue;
                        }

                        Polygon2d          hole_poly = polygons[childLoop.ID];
                        IParametricCurve2d hole_loop = (bWantCurveSolids) ? childLoop.source.Clone() : null;
                        if (hole_poly.IsClockwise)
                        {
                            hole_poly.Reverse();
                            if (bWantCurveSolids)
                            {
                                hole_loop.Reverse();
                            }
                        }

                        try {
                            polysolids[outer_idx].AddHole(hole_poly);
                            if (hole_loop != null)
                            {
                                solids[outer_idx].AddHole(hole_loop);
                            }
                        } catch {
                            // don't add this hole - must intersect or something?
                            // We should have caught this earlier!
                        }

                        used.Add(childLoop);
                        if (ContainSets.ContainsKey(childj))
                        {
                            ContainersToRemove.Add(childj);
                        }
                    }
                    ContainersToRemove.Add(i);
                }

                // remove all containers that are no longer valid
                foreach (int ci in ContainersToRemove)
                {
                    ContainSets.Remove(ci);

                    // have to remove from each ContainedParents list
                    List <int> keys = new List <int>(ContainedParents.Keys);
                    foreach (int j in keys)
                    {
                        if (ContainedParents[j].Contains(ci))
                        {
                            ContainedParents[j].Remove(ci);
                        }
                    }
                }

                ParentsToProcess.Clear();


                // ok now find next-level uncontained parents...
                for (int i = 0; i < N; ++i)
                {
                    SmoothLoopElement loopi = validLoops[i];
                    if (used.Contains(loopi))
                    {
                        continue;
                    }
                    if (ContainSets.ContainsKey(i) == false)
                    {
                        continue;
                    }
                    List <int> parents = ContainedParents[i];
                    if (parents.Count > 0)
                    {
                        continue;
                    }

                    Polygon2d          outer_poly = polygons[loopi.ID];
                    IParametricCurve2d outer_loop = (bWantCurveSolids) ? loopi.source.Clone() : null;
                    if (outer_poly.IsClockwise == false)
                    {
                        outer_poly.Reverse();
                        if (bWantCurveSolids)
                        {
                            outer_loop.Reverse();
                        }
                    }

                    GeneralPolygon2d g = new GeneralPolygon2d {
                        Outer = outer_poly
                    };
                    PlanarSolid2d s = new PlanarSolid2d();
                    if (bWantCurveSolids)
                    {
                        s.SetOuter(outer_loop, true);
                    }

                    int idx = polysolids.Count;
                    LoopToOuterIndex[loopi] = idx;
                    used.Add(loopi);

                    if (ContainSets.ContainsKey(i))
                    {
                        ParentsToProcess.Add(i);
                    }

                    polysolids.Add(g);
                    if (bWantCurveSolids)
                    {
                        solids.Add(s);
                    }
                }
            }


            // any remaining loops must be top-level
            for (int i = 0; i < N; ++i)
            {
                SmoothLoopElement loopi = validLoops[i];
                if (used.Contains(loopi))
                {
                    continue;
                }

                Polygon2d          outer_poly = polygons[loopi.ID];
                IParametricCurve2d outer_loop = (bWantCurveSolids) ? loopi.source.Clone() : null;
                if (outer_poly.IsClockwise == false)
                {
                    outer_poly.Reverse();
                    if (bWantCurveSolids)
                    {
                        outer_loop.Reverse();
                    }
                }

                GeneralPolygon2d g = new GeneralPolygon2d {
                    Outer = outer_poly
                };
                PlanarSolid2d s = new PlanarSolid2d();
                if (bWantCurveSolids)
                {
                    s.SetOuter(outer_loop, true);
                }

                polysolids.Add(g);
                if (bWantCurveSolids)
                {
                    solids.Add(s);
                }
            }



            return(new SolidRegionInfo()
            {
                Polygons = polysolids,
                Solids = (bWantCurveSolids) ? solids : null
            });
        }
Exemplo n.º 20
0
        public static void Main(string[] args)
        {
            GtkUtil.CheckWindowsGtk();

            ExceptionManager.UnhandledException += delegate(UnhandledExceptionArgs expArgs) {
                Console.WriteLine(expArgs.ExceptionObject.ToString());
                expArgs.ExitApplication = true;
            };

            Gtk.Application.Init();

            MainWindow = new Window("gsSlicerViewer");
            MainWindow.SetDefaultSize(900, 600);
            MainWindow.SetPosition(WindowPosition.Center);
            MainWindow.DeleteEvent += delegate {
                Gtk.Application.Quit();
            };

            string sPath = "../../../sample_files/disc_single_layer.gcode";
            //string sPath = "../../../sample_files/disc_0p6mm.gcode";
            //string sPath = "../../../sample_files/square_linearfill.gcode";
            //string sPath = "../../../sample_files/thin_hex_test_part.gcode";
            //string sPath = "../../../sample_files/box_infill_50.gcode";
            //string sPath = "../../../sample_files/tube_adapter.gcode";
            //string sPath = "../../../sample_files/ring_2p2_makerbot.gcode";
            //string sPath = "/Users/rms/Desktop/print_experiment/cura_ring_2p2.gcode";
            //string sPath = "/Users/rms/Desktop/print_experiment/slic3r_ring_2p2.gcode";

            DMesh3 readMesh = null;

            //GCodeFile genGCode = MakerbotTests.SimpleFillTest();
            //GCodeFile genGCode = MakerbotTests.SimpleShellsTest();
            //GCodeFile genGCode = MakerbotTests.InfillBoxTest();

            //GeneralPolygon2d poly = GetPolygonFromMesh("../../../sample_files/bunny_open.obj");
            //GCodeFile genGCode = MakerbotTests.ShellsPolygonTest(poly);
            //GCodeFile genGCode = MakerbotTests.StackedPolygonTest(poly, 2);
            //GCodeFile genGCode = MakerbotTests.StackedScaledPolygonTest(poly, 20, 0.5);

            readMesh = StandardMeshReader.ReadMesh("../../../sample_files/cotan_cylinder.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/bunny_solid_2p5cm.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/bunny_solid_5cm_min.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/basic_step.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/slab_5deg.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/sphere_angles_1cm.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/inverted_cone_1.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/tube_adapter.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/tube_1.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/50x50x1_box.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/crop_bracket.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/thinwall2.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/box_and_cylsheet.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/box_and_opensheet.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/radial_fins.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/radial_fins_larger.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/bunny_hollow_5cm.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/notch_test_1.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/square_minus_shapes.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/variable_thins.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/arrow_posx.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/blobby_shape.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/socket_ros_simplified.obj");
            //readMesh = StandardMeshReader.ReadMesh("c:\\scratch\\bunny_fixed_flat.obj");
            //MeshUtil.ScaleMesh(readMesh, Frame3f.Identity, 1.1f*Vector3f.One);
            //readMesh = StandardMeshReader.ReadMesh("c:\\scratch\\ARCHFORM_EXPORT_stage_12_lower.stl");

            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/unsupported_slab_5deg.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/overhang_slab_1.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/edge_overhang.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/support_tilted_cone.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/support_mintip.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/support_mintip_vtx.obj");
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/tilted_thin_slab.obj");

            //readMesh = StandardMeshReader.ReadMesh("C:\\meshes\\user_bugs\\inverted_part.obj");
            //readMesh = StandardMeshReader.ReadMesh("C:\\meshes\\user_bugs\\tail_tiny_support_dots.obj");
            //readMesh = StandardMeshReader.ReadMesh("C:\\meshes\\user_bugs\\cone_inner.obj");

            // interesting test case for clipselfoverlaps and scheduler
            //readMesh = StandardMeshReader.ReadMesh("../../../sample_files/Slim_Type1.stl");

            DMesh3 cavityMesh = null;

            DMesh3 supportMesh = null;

            //supportMesh = StandardMeshReader.ReadMesh("../../../sample_files/edge_overhang_support.obj");

            // rotate to be z-up
            //MeshTransforms.Rotate(readMesh, Vector3d.Zero, Quaternionf.AxisAngleD(Vector3f.AxisX, 90));
            //if ( supportMesh != null )
            //    MeshTransforms.Rotate(supportMesh, Vector3d.Zero, Quaternionf.AxisAngleD(Vector3f.AxisX, 90));

            //readMesh = CalibrationModelGenerator.MakePrintStepSizeTest(10.0f, 10.0f, 0.1, 1.0, 10);

            //DMesh3[] meshComponents = MeshConnectedComponents.Separate(readMesh);
            DMesh3[] meshComponents = new DMesh3[] { readMesh };

            PrintMeshAssembly meshes = new PrintMeshAssembly();

            meshes.AddMeshes(meshComponents);

            if (cavityMesh != null)
            {
                meshes.AddMesh(cavityMesh, PrintMeshOptions.Cavity());
            }
            if (supportMesh != null)
            {
                meshes.AddMesh(supportMesh, PrintMeshOptions.Support());
            }

            AxisAlignedBox3d bounds  = meshes.TotalBounds;
            AxisAlignedBox2d bounds2 = new AxisAlignedBox2d(bounds.Center.xy, bounds.Width / 2, bounds.Height / 2);

            View = new SliceViewCanvas();
            MainWindow.Add(View);

            if (readMesh != null)
            {
                // generate gcode file for mesh
                sPath = GenerateGCodeForMeshes(meshes);
            }

            if (SHOW_RELOADED_GCODE_PATHS)
            {
                LoadGeneratedGCodeFile(sPath);
            }

            //GenerateGCodeForSliceFile("c:\\scratch\\output.gslice");

            MainWindow.KeyReleaseEvent += Window_KeyReleaseEvent;

            // support drag-drop
            Gtk.TargetEntry[] target_table = new TargetEntry[] {
                new TargetEntry("text/uri-list", 0, 0),
            };
            Gtk.Drag.DestSet(MainWindow, DestDefaults.All, target_table, Gdk.DragAction.Copy);
            MainWindow.DragDataReceived += MainWindow_DragDataReceived;;


            MainWindow.ShowAll();

            Gtk.Application.Run();
        }
Exemplo n.º 21
0
        public static void test_uv_insert_string()
        {
            DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_xy_25x25.obj");

            mesh.EnableVertexUVs(Vector2f.Zero);

            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh);

            spatial.Build();
            int tid = spatial.FindNearestTriangle(Vector3d.Zero);

            PolygonFont2d font = PolygonFont2d.ReadFont("c:\\scratch\\font.bin");

            //List<GeneralPolygon2d> letter = new List<GeneralPolygon2d>(font.Characters.First().Value.Polygons);
            //double targetWidth = 20.0f;
            List <GeneralPolygon2d> letter = font.GetCharacter('a');
            double targetWidth             = 10.0f;

            AxisAlignedBox2d bounds  = font.MaxBounds;
            Vector2d         center  = bounds.Center;
            Vector2d         scale2d = (targetWidth / font.MaxBounds.Width) * new Vector2d(1, 1);


            for (int li = 0; li < letter.Count; ++li)
            {
                GeneralPolygon2d gp = new GeneralPolygon2d(letter[li]);
                gp.Scale(scale2d, center);
                gp.Translate(-center);
                letter[li] = gp;
            }


            List <MeshFaceSelection> letter_interiors = new List <MeshFaceSelection>();

            bool bSimplify = true;

            for (int li = 0; li < letter.Count; ++li)
            {
                GeneralPolygon2d gp = letter[li];

                MeshInsertUVPolyCurve outer = new MeshInsertUVPolyCurve(mesh, gp.Outer);
                Util.gDevAssert(outer.Validate() == ValidationStatus.Ok);
                outer.Apply();
                if (bSimplify)
                {
                    outer.Simplify();
                }

                List <MeshInsertUVPolyCurve> holes = new List <MeshInsertUVPolyCurve>(gp.Holes.Count);
                for (int hi = 0; hi < gp.Holes.Count; ++hi)
                {
                    MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(mesh, gp.Holes[hi]);
                    Util.gDevAssert(insert.Validate() == ValidationStatus.Ok);
                    insert.Apply();
                    if (bSimplify)
                    {
                        insert.Simplify();
                    }
                    holes.Add(insert);
                }


                // find a triangle connected to loop that is inside the polygon
                //   [TODO] maybe we could be a bit more robust about this? at least
                //   check if triangle is too degenerate...
                int      seed_tri   = -1;
                EdgeLoop outer_loop = outer.Loops[0];
                for (int i = 0; i < outer_loop.EdgeCount; ++i)
                {
                    if (!mesh.IsEdge(outer_loop.Edges[i]))
                    {
                        continue;
                    }

                    Index2i  et   = mesh.GetEdgeT(outer_loop.Edges[i]);
                    Vector3d ca   = mesh.GetTriCentroid(et.a);
                    bool     in_a = gp.Outer.Contains(ca.xy);
                    Vector3d cb   = mesh.GetTriCentroid(et.b);
                    bool     in_b = gp.Outer.Contains(cb.xy);
                    if (in_a && in_b == false)
                    {
                        seed_tri = et.a;
                        break;
                    }
                    else if (in_b && in_a == false)
                    {
                        seed_tri = et.b;
                        break;
                    }
                }
                Util.gDevAssert(seed_tri != -1);

                // make list of all outer & hole edges
                HashSet <int> loopEdges = new HashSet <int>(outer_loop.Edges);
                foreach (var insertion in holes)
                {
                    foreach (int eid in insertion.Loops[0].Edges)
                    {
                        loopEdges.Add(eid);
                    }
                }

                // flood-fill inside loop from seed triangle
                MeshFaceSelection sel = new MeshFaceSelection(mesh);
                sel.FloodFill(seed_tri, null, (eid) => { return(loopEdges.Contains(eid) == false); });
                letter_interiors.Add(sel);
            }

            // extrude regions
            Func <Vector3d, Vector3f, int, Vector3d> OffsetF = (v, n, i) => {
                return(v + Vector3d.AxisZ);
            };

            foreach (var interior in letter_interiors)
            {
                MeshExtrudeFaces extrude = new MeshExtrudeFaces(mesh, interior);
                extrude.ExtrudedPositionF = OffsetF;
                extrude.Extrude();
            }

            TestUtil.WriteTestOutputMesh(mesh, "insert_uv_string.obj");
        }
Exemplo n.º 22
0
        public static List <GeneralPolygon2d> ConvertFromClipper(CPolygonList clipper_polys, double nIntScale)
        {
            List <GeneralPolygon2d> result = new List <GeneralPolygon2d>();

            try {
                // convert clipper polys to Polygon2d
                List <Polygon2d> polys = new List <Polygon2d>();
                int N = clipper_polys.Count;
                for (int i = 0; i < N; ++i)
                {
                    Polygon2d poly = ConvertFromClipper(clipper_polys[i], nIntScale);
                    if (poly != null)
                    {
                        polys.Add(poly);
                    }
                }

                // sort polygons into outer/holes
                // [TODO] clipper can figure this out for us...perhaps faster??


                // find the 'outer' polygons. Here we are assuming
                // that outer polygons are CCW...
                bool[] done = new bool[N];
                Array.Clear(done, 0, N);
                for (int i = 0; i < N; ++i)
                {
                    if (polys[i].IsClockwise == false)
                    {
                        GeneralPolygon2d gp = new GeneralPolygon2d();
                        gp.Outer = polys[i];
                        result.Add(gp);
                        done[i] = true;
                    }
                }

                // compute bboxes
                AxisAlignedBox2d[] outerBounds = new AxisAlignedBox2d[result.Count];
                for (int i = 0; i < result.Count; ++i)
                {
                    outerBounds[i] = result[i].Outer.GetBounds();
                }

                // remaining polygons are holes. Figure out which outer
                // they belong too. Only difficult if there is more than one option.
                for (int i = 0; i < N; ++i)
                {
                    if (done[i])
                    {
                        continue;
                    }
                    if (result.Count == 1)
                    {
                        result[0].AddHole(polys[i], false);
                        done[i] = true;
                        continue;
                    }

                    AxisAlignedBox2d box = polys[i].GetBounds();
                    for (int j = 0; j < result.Count; ++j)
                    {
                        if (outerBounds[j].Contains(box) == false)
                        {
                            continue;
                        }
                        if (result[j].Outer.Contains(polys[i]))
                        {
                            result[j].AddHole(polys[i], false);
                        }
                        done[i] = true;
                    }

                    // uh-oh...now what? perhaps should force a full N-pair test/sort if this happens?
                    if (done[i] == false)
                    {
                        System.Diagnostics.Debug.WriteLine("ClipperUtil.ConvertFromClipper: could not find parent for polygon " + i.ToString());
                    }
                }
            } catch /*( Exception e )*/ {
                //System.Diagnostics.Debug.WriteLine("ClipperUtil.ConvertFromClipper: caught exception: " + e.Message);
            }
            return(result);
        }
Exemplo n.º 23
0
        public bool Compute()
        {
            AxisAlignedBox2d bounds = Polygon.Bounds;

            ScaleGridIndexer2 index = new ScaleGridIndexer2()
            {
                CellSize = TileSize
            };

            Vector2i min = index.ToGrid(bounds.Min) - Vector2i.One;
            Vector2i max = index.ToGrid(bounds.Max);

            List <Tile> Tiles = new List <Tile>();

            for (int y = min.y; y <= max.y; ++y)
            {
                for (int x = min.x; x <= max.x; ++x)
                {
                    Tile t = new Tile();
                    t.index = new Vector2i(x, y);
                    Vector2d         tile_min = index.FromGrid(t.index);
                    Vector2d         tile_max = index.FromGrid(t.index + Vector2i.One);
                    AxisAlignedBox2d tile_box = new AxisAlignedBox2d(tile_min, tile_max);
                    tile_box.Expand(TileOverlap);
                    t.poly = new Polygon2d(new Vector2d[] { tile_box.GetCorner(0), tile_box.GetCorner(1), tile_box.GetCorner(2), tile_box.GetCorner(3) });
                    Tiles.Add(t);
                }
            }

            gParallel.ForEach(Tiles, (tile) =>
            {
                tile.regions =
                    ClipperUtil.PolygonBoolean(Polygon, new GeneralPolygon2d(tile.poly), ClipperUtil.BooleanOp.Intersection);
            });

            List <ICurvesFillPolygon> all_fills = new List <ICurvesFillPolygon>();

            foreach (Tile t in Tiles)
            {
                if (t.regions.Count == 0)
                {
                    continue;
                }
                t.fills = new ICurvesFillPolygon[t.regions.Count];
                for (int k = 0; k < t.regions.Count; ++k)
                {
                    t.fills[k] = TileFillGeneratorF(t.regions[k], t.index);
                    if (t.fills[k] != null)
                    {
                        all_fills.Add(t.fills[k]);
                    }
                }
            }

            gParallel.ForEach(all_fills, (fill) =>
            {
                fill.Compute();
            });

            FillCurves = new List <FillCurveSet2d>();
            foreach (ICurvesFillPolygon fill in all_fills)
            {
                List <FillCurveSet2d> result = fill.GetFillCurves();
                if (result != null && result.Count > 0)
                {
                    FillCurves.AddRange(result);
                }
            }

            return(true);
        }
Exemplo n.º 24
0
        public bool Solve(int MaxRounds = 1024)
        {
            AxisAlignedBox2d TargetBounds = Target.Bounds;

            Box2d fitBounds = new Box2d(Fit.GetBounds());

            InputTranslate = -fitBounds.Center;
            int N = Fit.VertexCount;

            Polygon2d FitCentered = new Polygon2d(Fit);

            for (int k = 0; k < N; ++k)
            {
                FitCentered[k] = Fit[k] + InputTranslate;
            }
            fitBounds = new Box2d(FitCentered.GetBounds());


            Polygon2d FitXForm = new Polygon2d(FitCentered);

            Random r = new Random(31337);

            int  ri     = 0;
            bool solved = false;

            while (ri++ < MaxRounds && solved == false)
            {
                Vector2d center = random_point_in_target(r, TargetBounds.SampleT, Target.Contains);

                Matrix2d rotate = Matrix2d.Identity;
                if (EnableRotate)
                {
                    Util.gDevAssert(EnableRandomRotations == false);
                    double rotAngle = ValidRotationsDeg[r.Next() % ValidRotationsDeg.Length];
                    rotate.SetToRotationDeg(rotAngle);
                }

                for (int k = 0; k < N; ++k)
                {
                    FitXForm[k] = rotate * (ApplyScale * FitCentered[k]) + center;
                }

                if (!Target.Outer.Contains(FitXForm))
                {
                    continue;
                }

                if (Target.Intersects(FitXForm))
                {
                    continue;
                }

                FitBounds = fitBounds;
                FitBounds.RotateAxes(rotate);
                FitBounds.Translate(center);
                FitRotation = rotate;
                FitPolygon  = FitXForm;
                solved      = true;
            }

            return(solved);
        }