/// <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>(); }
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(); } }
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); }
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); }