Beispiel #1
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>();
        }
Beispiel #2
0
 protected ElementBase()
 {
     AtomId = Guid.NewGuid();
     Shells.Add(new KShell(this));
     if (AtomicNumber > 2)
     {
         Shells.Add(new LShell(this));
     }
     if (AtomicNumber > 10)
     {
         Shells.Add(new MShell(this));
     }
     if (AtomicNumber > 28)
     {
         Shells.Add(new NShell(this));
     }
     if (AtomicNumber > 60)
     {
         Shells.Add(new OShell(this));
     }
     for (var i = 0; i < AtomicNumber; i++)
     {
         AddElectron();
     }
 }
Beispiel #3
0
        public static Shell LoadPMF(string root, string dir, string name)
        {
            var shell = new Shell();

            shell.LoadPMF(root, dir, name);
            lock (me.lockobj) {
                Shells.Add(shell);
            }
            return(shell);
        }
Beispiel #4
0
        public bool Compute()
        {
            bool   enable_thin_check     = false;
            double thin_check_offset     = ToolWidth * 0.45;
            double thin_check_thresh_sqr = ToolWidth * 0.3;

            thin_check_thresh_sqr *= thin_check_thresh_sqr;

            // first shell is either polygon, or inset from that polygon
            List <GeneralPolygon2d> current = null;

            if (InsetFromInputPolygonX != 0)
            {
                current = ComputeInitialInsetPolygon(PreserveInputInsetTopology);
            }
            else
            {
                current = new List <GeneralPolygon2d>()
                {
                    Polygon
                };
            }
            List <GeneralPolygon2d> current_prev = null;

            if (current.Count == 0)
            {
                HandleTinyPolygon();
                return(true);
            }

            // convert previous layer to shell, and then compute next layer
            List <GeneralPolygon2d> failedShells     = new List <GeneralPolygon2d>();
            List <GeneralPolygon2d> nextShellTooThin = new List <GeneralPolygon2d>();

            for (int i = 0; i < Layers; ++i)
            {
                FillCurveSet2d paths = ShellPolysToPaths(current, i);
                Shells.Add(paths);

                List <GeneralPolygon2d> all_next = new List <GeneralPolygon2d>();
                foreach (GeneralPolygon2d gpoly in current)
                {
                    List <GeneralPolygon2d> offsets =
                        ClipperUtil.ComputeOffsetPolygon(gpoly, -PathSpacing, true);

                    List <GeneralPolygon2d> filtered = new List <GeneralPolygon2d>();
                    foreach (var v in offsets)
                    {
                        bool bTooSmall = (v.Perimeter < DiscardTinyPerimterLengthMM ||
                                          v.Area < DiscardTinyPolygonAreaMM2);
                        if (bTooSmall)
                        {
                            continue;
                        }

                        if (enable_thin_check && is_too_thin(v, thin_check_offset, thin_check_thresh_sqr))
                        {
                            nextShellTooThin.Add(v);
                        }
                        else
                        {
                            filtered.Add(v);
                        }
                    }

                    if (filtered.Count == 0)
                    {
                        failedShells.Add(gpoly);
                    }
                    else
                    {
                        all_next.AddRange(filtered);
                    }
                }

                current_prev = current;
                current      = all_next;
            }


            // failedShells have no space for internal contours. But
            // we might be able to fit a single line...
            //foreach (GeneralPolygon2d gpoly in failedShells) {
            //	if (gpoly.Perimeter < DiscardTinyPerimterLengthMM ||
            //		 gpoly.Area < DiscardTinyPolygonAreaMM2)
            //		continue;

            //	List<FillPolyline2d> thin_shells = thin_offset(gpoly);
            //	Shells[Shells.Count - 1].Append(thin_shells);
            //}


            // remaining inner polygons
            if (InsetInnerPolygons)
            {
                InnerPolygons = current;
                InnerPolygons.AddRange(nextShellTooThin);
            }
            else
            {
                InnerPolygons = current_prev;
                InnerPolygons.AddRange(nextShellTooThin);
            }
            return(true);
        }