Beispiel #1
0
        /// <summary>
        /// Resample parametric solid into polygonal solid
        /// </summary>
        public GeneralPolygon2d Convert(double fSpacingLength, double fSpacingT, double fDeviationTolerance)
        {
            GeneralPolygon2d poly = new GeneralPolygon2d();

            poly.Outer = new Polygon2d(
                CurveSampler2.AutoSample(this.outer, fSpacingLength, fSpacingT));
            poly.Outer.Simplify(0, fDeviationTolerance);
            foreach (var hole in this.Holes)
            {
                Polygon2d holePoly = new Polygon2d(
                    CurveSampler2.AutoSample(hole, fSpacingLength, fSpacingT));
                holePoly.Simplify(0, fDeviationTolerance);
                poly.AddHole(holePoly, false);
            }
            return(poly);
        }
Beispiel #2
0
        public static void Restore(GeneralPolygon2d polygon, BinaryReader reader)
        {
            Polygon2d outer = new Polygon2d();

            Restore(outer, reader);
            polygon.Outer = outer;

            int hole_count = reader.ReadInt32();

            for (int i = 0; i < hole_count; ++i)
            {
                Polygon2d holepoly = new Polygon2d();
                Restore(holepoly, reader);
                polygon.AddHole(holepoly, false);
            }
        }
        // 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> valid = new List <SmoothLoopElement>(LoopsItr());
            int N = valid.Count;

            // precompute bounding boxes
            int maxid = 0;

            foreach (var v in valid)
            {
                maxid = Math.Max(maxid, v.ID + 1);
            }
            AxisAlignedBox2d[] bounds = new AxisAlignedBox2d[maxid];
            foreach (var v in valid)
            {
                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 valid)
            {
                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??)
            valid.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> >();

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

                for (int j = 0; j < N; ++j)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    SmoothLoopElement loopj = valid[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;
                    }
                }
            }

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

            // extract solids from containment relationships
            foreach (var i in ContainSets.Keys)
            {
                SmoothLoopElement outer_element = valid[i];
                used.Add(outer_element);
                if (bIsContained[i])
                {
                    throw new Exception("PlanarComplex.FindSolidRegions: multiply-nested regions not supported!");
                }

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

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

                foreach (int hi in ContainSets[i])
                {
                    SmoothLoopElement he = valid[hi];
                    used.Add(he);
                    Polygon2d          hole_poly = polygons[he.ID];
                    IParametricCurve2d hole_loop = (bWantCurveSolids) ? he.source.Clone() : null;
                    if (hole_poly.IsClockwise)
                    {
                        hole_poly.Reverse();
                        if (bWantCurveSolids)
                        {
                            hole_loop.Reverse();
                        }
                    }

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

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

            for (int i = 0; i < N; ++i)
            {
                SmoothLoopElement loopi = valid[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();
                g.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
            });
        }