/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { IGH_GeometricGoo shape = null; if (!DA.GetData <IGH_GeometricGoo>(0, ref shape)) { return; } GeometryBase geo = null; if (shape is Mesh || shape is GH_Mesh || shape is Brep || shape is GH_Brep || shape is Surface || shape is GH_Surface || shape is Curve || shape is GH_Curve || shape is GH_Box || shape is GH_Line) { geo = GH_Convert.ToGeometryBase(shape); } else { return; } var bbox = geo.GetBoundingBox(true); DA.SetData(0, bbox.Center); }
//This method creates a bounding box to a geometry in a given plane and returns the min and max coordinates of that box in the plane coordinates. private static Tuple <Point3d, Point3d> getMinAndMax(GeometryBase geometry, Plane plane) { Transform vali = Transform.PlaneToPlane(Plane.WorldXY, plane); BoundingBox box = geometry.GetBoundingBox(plane); Point3d minPoint = box.Min; Point3d maxPoint = box.Max; return(Tuple.Create(minPoint, maxPoint)); }
/// <summary> /// Extract bounding Z frames -- slice planes -- of a given geometry. /// </summary> /// <param name="G"></param> /// <param name="XSpan"></param> /// <param name="YSpan"></param> /// <param name="ZSpan"></param> /// <param name="DXSpan"></param> /// <param name="DYSpan"></param> /// <param name="AngleDegrees"></param> /// <returns></returns> public static List <Plane> SlicePlanes( GeometryBase G, double LayerHeight, double OffsetBottomGlobal = 0, double OffsetBottom = 0, double OffsetTop = 0, bool ShouldForceTop = false) { List <Plane> Frames = new List <Plane>(); // Default BoundingBox BoundingBox bb = G.GetBoundingBox(true); Point3d[] corners = bb.GetCorners(); Line ZLine = new Line(corners[0], corners[4]); double ZLineLength = ZLine.Length; // Safety int FrameCap = 150; if (ZLineLength / LayerHeight > FrameCap - 1) { LayerHeight = ZLine.Length / (FrameCap - 1); } // Z Frames double ZAmount = ZLineLength / LayerHeight; bool HasTopLayer = false; for (double i = 0; i <= ZAmount; i++) { double distance = i * LayerHeight + OffsetBottomGlobal; if (i == 0) { distance += OffsetBottom; } if (distance == ZLineLength) { HasTopLayer = true; } if (distance == ZLineLength || !ShouldForceTop && LayerHeight * (i + 1) + OffsetBottomGlobal > ZLineLength) { distance += -OffsetTop; } double param = distance / ZLineLength; if (param <= 1) { Plane pl; ZLine.ToNurbsCurve().PerpendicularFrameAt(param, out pl); Frames.Add(pl); } } if (ShouldForceTop && !HasTopLayer) { Plane pl; double param = 1 - OffsetTop / ZLineLength; if (param > 1) { param = 1; } ZLine.ToNurbsCurve().PerpendicularFrameAt(param, out pl); Frames.Add(pl); } return(Frames); }
/// <summary> /// Extract bounding frames to slice a given geometry. /// </summary> /// <param name="G"></param> /// <param name="XSpan"></param> /// <param name="YSpan"></param> /// <param name="ZSpan"></param> /// <param name="DXSpan"></param> /// <param name="DYSpan"></param> /// <param name="AngleDegrees"></param> /// <returns></returns> public static List <List <Plane> > BoundingFrames(GeometryBase G, double XSpan, double YSpan, double ZSpan, double DXSpan, double DYSpan, double AngleDegrees = 45.0) { // Nono.Util // BoundingFrames // Nono Martínez Alonso (nono.ma) // 160622, Autodesk Generative Design List <List <Plane> > Frames = new List <List <Plane> >(); // 1. Default BoundingBox BoundingBox bb = G.GetBoundingBox(true); Point3d[] corners = bb.GetCorners(); Line XLine = new Line(corners[0], corners[1]); Line YLine = new Line(corners[0], corners[3]); Line ZLine = new Line(corners[0], corners[4]); List <Plane> XFrames = new List <Plane>(); List <Plane> YFrames = new List <Plane>(); List <Plane> ZFrames = new List <Plane>(); // X Frames if (XSpan > 0) { double XAmount = Math.Floor(XLine.Length / XSpan); double XStep = XLine.Length / XAmount; double Xt = 0; for (double i = 0; i <= XAmount; i++) { Plane pl; Xt = i * XStep / XLine.Length; XLine.ToNurbsCurve().PerpendicularFrameAt(Xt, out pl); XFrames.Add(pl); } } // Y Frames if (YSpan > 0) { double YAmount = Math.Floor(YLine.Length / YSpan); double YStep = YLine.Length / YAmount; double Yt = 0; for (double i = 0; i <= YAmount; i++) { Plane pl; Yt = i * YStep / YLine.Length; YLine.ToNurbsCurve().PerpendicularFrameAt(Yt, out pl); YFrames.Add(pl); } } // Z Frames double ZAmount = ZLine.Length / ZSpan; for (double i = 0; i <= ZAmount; i++) { Plane pl; ZLine.ToNurbsCurve().PerpendicularFrameAt(i * ZSpan / ZLine.Length, out pl); ZFrames.Add(pl); } // 2. Diagonal BoundingBox Transform rotate = Transform.Rotation(-V2GMath.DEGREES_TO_RADIANS * AngleDegrees, new Vector3d(0, 0, 1), bb.Center); Transform rotateBack = Transform.Rotation(V2GMath.DEGREES_TO_RADIANS * AngleDegrees, new Vector3d(0, 0, 1), bb.Center); G.Transform(rotate); BoundingBox Dbb = G.GetBoundingBox(true); Point3d DbbCenter = Dbb.Center; Point3d[] Dcorners = Dbb.GetCorners(); Line DXLine = new Line(Dcorners[0], Dcorners[1]); Line DYLine = new Line(Dcorners[0], Dcorners[3]); List <Plane> DXFrames = new List <Plane>(); List <Plane> DYFrames = new List <Plane>(); // DX Frames if (DXSpan > 0) { double DXAmount = Math.Floor(DXLine.Length / DXSpan); double DXStep = DXLine.Length / DXAmount; double DXt = 0; for (double i = 0; i <= DXAmount; i++) { Plane pl; DXt = i * DXStep / DXLine.Length; DXLine.ToNurbsCurve().PerpendicularFrameAt(DXt, out pl); pl.Transform(rotateBack); DXFrames.Add(pl); } } // DY Frames if (DYSpan > 0) { double DYAmount = Math.Floor(DYLine.Length / DYSpan); double DYStep = DYLine.Length / DYAmount; double DYt = 0; for (double i = 0; i <= DYAmount; i++) { Plane pl; DYt = i * DYStep / DYLine.Length; DYLine.ToNurbsCurve().PerpendicularFrameAt(DYt, out pl); pl.Transform(rotateBack); DYFrames.Add(pl); } } Frames.Add(XFrames); Frames.Add(YFrames); Frames.Add(ZFrames); Frames.Add(DXFrames); Frames.Add(DYFrames); return(Frames); }
public Primitive(Mesh m, Part p) { geometry = m; ClippingBox = geometry.GetBoundingBox(false); part = p; }
public Primitive(Curve c) { geometry = c; ClippingBox = geometry.GetBoundingBox(false); }
public Primitive(PointCloud pc, Part p) { geometry = pc; ClippingBox = geometry.GetBoundingBox(false); part = p; }
public Primitive(Point p) { geometry = p; ClippingBox = geometry.GetBoundingBox(false); }
private List <string> SaveAdobeDocument(string savePath, List <GeometryBase> objs, AdobeDocType type) { SortedDictionary <string, List <GeometryBase> > geometries = new SortedDictionary <string, List <GeometryBase> >(); GeometryBase boundObj = null; List <string> outputFiles = new List <string>(); DebugEvent($"{type}_BOUND"); foreach (var obj in objs) { if (obj.GetUserString($"{type}_BOUND") == $"{type}_BOUND") { boundObj = obj; DebugEvent($"{type}文档找到边界"); continue; } string page = obj.GetUserString($"{type}_PAGE"); if (type == AdobeDocType.EPS && Directory.Exists(savePath)) { page = Path.Combine(savePath, page + ".eps"); outputFiles.Add(page); } if (!geometries.ContainsKey(page)) { geometries.Add(page, new List <GeometryBase>()); } geometries[page].Add(obj); } if (geometries.Count == 0 || boundObj == null) { return(null); } boundObj.GetBoundingBox(Plane.WorldXY, out Box boundBox); try { var eps = new EncapsulatedPostScript(boundBox, savePath); if (type == AdobeDocType.PDF) { eps.SavePDF(geometries); outputFiles.Add(savePath); } else if (type == AdobeDocType.EPS) { eps.SaveEPS(geometries); } } catch (Exception ex) { ErrorEvent(this, ex.Message); } return(outputFiles); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { IGH_GeometricGoo shape = null; int num = -1; int ite = -1; List <Point3d> attractors = new List <Point3d>(); List <double> radiuses = new List <double>(); List <double> weights = new List <double>(); if (!DA.GetData <IGH_GeometricGoo>(0, ref shape)) { return; } if (!DA.GetData(1, ref num)) { return; } if (!DA.GetData(2, ref ite)) { return; } DA.GetDataList(3, attractors); DA.GetDataList(4, radiuses); DA.GetDataList(5, weights); GeometryBase geo = GH_Convert.ToGeometryBase(shape); var points = new Point3dList(); var attracts = new Point3dList(attractors); var rnd = new Random(); var bbox = geo.GetBoundingBox(true); for (int i = 0; i < num; i++) { if (points.Count == 0) { var rndpt = CreateRandomPoint(rnd, geo, bbox); points.Add(rndpt); } else { double fdist = -1; Point3d fpos = new Point3d(); for (int t = 0; t < Math.Max(Math.Min(ite, i), 10); t++) { var nrndpt = CreateRandomPoint(rnd, geo, bbox); double nattractdist = 1; for (int n = 0; n < attracts.Count; n++) { var nattract = attracts[n]; var rad = radiuses[Math.Min(n, radiuses.Count - 1)]; var pow = weights[Math.Min(n, radiuses.Count - 1)]; var ntdist = Math.Pow(JellyUtility.Remap(Math.Min(nattract.DistanceTo(nrndpt), rad), 0, rad, 0, 1.0), pow); nattractdist *= ntdist; } var nindex = points.ClosestIndex(nrndpt); var npos = points[nindex]; var ndist = npos.DistanceTo(nrndpt) * nattractdist; if (fdist < ndist) { fdist = ndist; fpos = nrndpt; } } points.Add(fpos); } } DA.SetDataList(0, points); }
///<summary>The only instance of this command.</summary> ///<param name="doc" RhinoDoc></param> ///<param name="mode" Run mode></param> ///<returns>returns sucess if doc is successfully created </returns> protected override Result RunCommand(RhinoDoc doc, RunMode mode) { #region set all the file parameters pdfOptionForm = new PDFOptionForm(); Application.Run(pdfOptionForm); getSelectedOption = PDFOptionForm.optionsSelected; myUniqueFileName = string.Format(@"{0}" + ext, Guid.NewGuid()); string logFilePath = Rhino.ApplicationSettings.FileSettings.WorkingFolder + "\\Log-" + DateTime.Now.GetHashCode().ToString() + ".txt"; string curveType = "C"; try { string[] checkFileName = Rhino.ApplicationSettings.FileSettings.RecentlyOpenedFiles()[0].ToString().Split('\\'); int checklength = checkFileName.Length; rhinoFile = Rhino.ApplicationSettings.FileSettings.RecentlyOpenedFiles()[0].ToString().Split('\\')[--checklength]; } catch (FileNotFoundException fnf) { logFile(fnf.Message); } catch (IndexOutOfRangeException ioor) { logFile(ioor.Message); } string rhinoFileName = rhinoFile.Split('.')[0]; string filename = Rhino.ApplicationSettings.FileSettings.WorkingFolder + '\\' + rhinoFileName + "-" + myUniqueFileName; #endregion Rhino.RhinoApp.RunScript("-_Save Enter", false); logFile("Process started for ---> " + rhinoFileName + "-" + myUniqueFileName); PdfDocument document = new PdfDocument(); PdfPage page = document.AddPage(); XGraphics gfx = XGraphics.FromPdfPage(page); XFont font = new XFont("Verdana", 20, XFontStyle.Bold); #region Check the selected curve GetObject go = new GetObject(); go.GroupSelect = true; go.SubObjectSelect = false; go.EnableClearObjectsOnEntry(false); go.EnableUnselectObjectsOnExit(false); go.DeselectAllBeforePostSelect = false; go.EnableSelPrevious(true); go.EnablePreSelect(true, false); go.GeometryFilter = ObjectType.AnyObject; GetResult result = go.GetMultiple(1, -1); if (go.CommandResult() != Rhino.Commands.Result.Success) { return(go.CommandResult()); } RhinoApp.WriteLine("{0} objects are selected.", go.ObjectCount); #endregion // Process the list of objects logFile("Processing List of Object"); #region set the paramenters for Xgraph to process shapes List <GeometryBase> geoList = new List <GeometryBase>(); double minX, minY, maxX, maxY; minX = double.MaxValue; minY = double.MaxValue; maxX = double.MinValue; maxY = double.MinValue; List <Curve> curveList = new List <Curve>(); List <TextEntity> textEntityList = new List <TextEntity>(); List <Circle> circleList = new List <Circle>(); List <Polyline> polyList = new List <Polyline>(); Circle circleCurve; Polyline polygon; #endregion for (int i = 0; i < go.ObjectCount; i++) { // Check the type of the Object and process differently Curve curve = go.Object(i).Curve(); if (go.Object(i).Curve().TryGetCircle(out circleCurve)) { circleList.Add(circleCurve); } if (go.Object(i).Curve().TryGetPolyline(out polygon)) { polyList.Add(polygon); } if (curve != null) { curveList.Add(curve); } TextEntity te = go.Object(i).TextEntity(); if (te != null) { textEntityList.Add(te); } GeometryBase geo = go.Object(i).Geometry(); BoundingBox bbox = geo.GetBoundingBox(Rhino.Geometry.Plane.WorldXY); if (bbox.Min.X < minX) { minX = bbox.Min.X; } if (bbox.Min.Y < minY) { minY = bbox.Min.Y; } if (bbox.Max.X > maxX) { maxX = bbox.Max.X; } if (bbox.Max.Y > maxY) { maxY = bbox.Max.Y; } geoList.Add(geo); } page.Height = maxY - minY; page.Width = maxX - minX; foreach (GeometryBase g in geoList) { if (g.GetType().Equals(typeof(PolyCurve))) { //System.Windows.Forms.MessageBox.Show("PolyCurve changed"); PolyCurve polyCurve = (PolyCurve)g; curveType = "NC"; break; } else if (g.GetType().Equals(typeof(Curve))) { System.Windows.Forms.MessageBox.Show("Curve"); Curve curve = (Curve)g; } else if (g.GetType().Equals(typeof(TextEntity))) { System.Windows.Forms.MessageBox.Show("TextEntity"); TextEntity textEntity = (TextEntity)g; curveType = "T"; } } logFile("Checking the pattern"); if (curveType.Equals("C") || curveType.Equals("T")) { logFile("Objects processed sucessfully"); double x1, y1, width, height; logFile("Creating Circles on the PDF"); //Loop to draw the circles foreach (Circle c in circleList) { XPen pen = new XPen(XColors.Black, 0.5); x1 = c.BoundingBox.Min.X - minX; y1 = maxY - c.BoundingBox.Max.Y; width = c.BoundingBox.Max.X - c.BoundingBox.Min.X; height = c.BoundingBox.Max.Y - c.BoundingBox.Min.Y; gfx.DrawEllipse(XBrushes.Black, x1, y1, width, height); } //Loop used to draw rectangles foreach (Polyline p in polyList) { XPen pen = new XPen(XColors.Black, 0.5); x1 = p.BoundingBox.Min.X - minX; y1 = maxY - p.BoundingBox.Max.Y; width = p.BoundingBox.Max.X - p.BoundingBox.Min.X; height = p.BoundingBox.Max.Y - p.BoundingBox.Min.Y; XPoint p1 = new XPoint(x1, y1); XPoint p2 = new XPoint(x1 + width, y1); XPoint p3 = new XPoint(x1, y1 + height); XPoint p4 = new XPoint(x1 + width, y1 + height); XRect rect = new XRect(x1, y1, width, height); XPoint[] xPoint = new XPoint[] { p1, p2, p4, p3 }; //XPoint mid = new XPoint( (x1 + x1)/2); XGraphicsState gs = gfx.Save(); gfx.RotateAtTransform(-45, p1); gfx.DrawPolygon(pen, XBrushes.Black, xPoint, XFillMode.Alternate); gfx.Restore(gs); } #region Print the PDF as per the option selected if (getSelectedOption.Equals('N')) { logFile("Normal PDF feature was selected"); document.Save(filename); logFile("Document saved successfully - " + Rhino.ApplicationSettings.FileSettings.WorkingFolder); } if (getSelectedOption.Equals('C')) { logFile("Compressed PDF feature was selected"); CompressMyPdf(document); string compressedFileName = Rhino.ApplicationSettings.FileSettings.WorkingFolder + '\\' + "C-" + rhinoFileName + "-" + myUniqueFileName; document.Save(compressedFileName); } if (getSelectedOption.Equals('E')) { logFile("Encrypted PDF feature was selected"); EncryptMyPdf(document); string encryptPdf = Rhino.ApplicationSettings.FileSettings.WorkingFolder + '\\' + "E-" + rhinoFileName + "-" + myUniqueFileName; document.Save(encryptPdf); } if (getSelectedOption.Equals('P')) { logFile("Password Protection PDF feature was selected"); PasswordProtectMyPdf(document); string passwordProtectPdf = Rhino.ApplicationSettings.FileSettings.WorkingFolder + '\\' + "PP-" + rhinoFileName + "-" + myUniqueFileName; document.Save(passwordProtectPdf); } #endregion logFile("Document saved successfully - " + Rhino.ApplicationSettings.FileSettings.WorkingFolder); logFile("Panel perforated successfully. Check File --> " + rhinoFileName + "-" + myUniqueFileName); System.Windows.Forms.MessageBox.Show(" <----SUCCESS----> " + Environment.NewLine + Environment.NewLine + " Pannels perforated Successfully. "); } else { System.Windows.Forms.MessageBox.Show(" ERROR! " + Environment.NewLine + Environment.NewLine + "The curve you have selected contains some invalid shape." + Environment.NewLine + " Please select the appropriate patterns. "); logFile("Please select the appropriate pattern"); } logFile("----------------- WAITING FOR THE NEXT PANEL PERFORATION ---------------------"); return(Result.Success); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { // 1. Retrieve and validate data var cell = new UnitCell(); GeometryBase designSpace = null; Plane orientationPlane = Plane.Unset; double xCellSize = 0; double yCellSize = 0; double zCellSize = 0; double minLength = 0; // the trim tolerance (i.e. minimum strut length) double maxLength = 0; bool strictlyIn = false; if (!DA.GetData(0, ref cell)) { return; } if (!DA.GetData(1, ref designSpace)) { return; } if (!DA.GetData(2, ref orientationPlane)) { return; } if (!DA.GetData(3, ref xCellSize)) { return; } if (!DA.GetData(4, ref yCellSize)) { return; } if (!DA.GetData(5, ref zCellSize)) { return; } if (!DA.GetData(6, ref minLength)) { return; } if (!DA.GetData(7, ref maxLength)) { return; } if (!DA.GetData(8, ref strictlyIn)) { return; } if (!cell.isValid) { return; } if (!designSpace.IsValid) { return; } if (!orientationPlane.IsValid) { return; } if (xCellSize == 0) { return; } if (yCellSize == 0) { return; } if (zCellSize == 0) { return; } if (minLength >= xCellSize || minLength >= yCellSize || minLength >= zCellSize) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Tolerance parameter cannot be larger than the unit cell dimensions."); return; } // 2. Validate the design space int spaceType = FrameTools.ValidateSpace(ref designSpace); if (spaceType == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Design space must be a closed Brep, Mesh or Surface"); return; } double tol = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; // 3. Compute oriented bounding box and its corner points Box bBox = new Box(); designSpace.GetBoundingBox(orientationPlane, out bBox); Point3d[] bBoxCorners = bBox.GetCorners(); // Set basePlane based on the bounding box Plane basePlane = new Plane(bBoxCorners[0], bBoxCorners[1], bBoxCorners[3]); // 4. Determine number of iterations required to fill the box, and package into array double xLength = bBoxCorners[0].DistanceTo(bBoxCorners[1]); double yLength = bBoxCorners[0].DistanceTo(bBoxCorners[3]); double zLength = bBoxCorners[0].DistanceTo(bBoxCorners[4]); int nX = (int)Math.Ceiling(xLength / xCellSize); // Roundup to next integer if non-integer int nY = (int)Math.Ceiling(yLength / yCellSize); int nZ = (int)Math.Ceiling(zLength / zCellSize); float[] N = new float[3] { nX, nY, nZ }; // 5. Initialize nodeTree var lattice = new Lattice(); // 6. Prepare cell (this is a UnitCell object) cell = cell.Duplicate(); cell.FormatTopology(); // 7. Define iteration vectors in each direction (accounting for Cell Size) Vector3d vectorU = xCellSize * basePlane.XAxis; Vector3d vectorV = yCellSize * basePlane.YAxis; Vector3d vectorW = zCellSize * basePlane.ZAxis; // 8. Map nodes to design space // Loop through the uvw cell grid for (int u = 0; u <= N[0]; u++) { for (int v = 0; v <= N[1]; v++) { for (int w = 0; w <= N[2]; w++) { // Construct cell path in tree GH_Path treePath = new GH_Path(u, v, w); // Fetch the list of nodes to append to, or initialise it var nodeList = lattice.Nodes.EnsurePath(treePath); // This loop maps each node in the cell for (int i = 0; i < cell.Nodes.Count; i++) { double usub = cell.Nodes[i].X; // u-position within unit cell (local) double vsub = cell.Nodes[i].Y; // v-position within unit cell (local) double wsub = cell.Nodes[i].Z; // w-position within unit cell (local) double[] uvw = { u + usub, v + vsub, w + wsub }; // uvw-position (global) // Check if the node belongs to another cell (i.e. it's relative path points outside the current cell) bool isOutsideCell = (cell.NodePaths[i][0] > 0 || cell.NodePaths[i][1] > 0 || cell.NodePaths[i][2] > 0); // Check if current uvw-position is beyond the upper boundary bool isOutsideSpace = (uvw[0] > N[0] || uvw[1] > N[1] || uvw[2] > N[2]); if (isOutsideCell || isOutsideSpace) { nodeList.Add(null); } else { // Compute position vector Vector3d V = uvw[0] * vectorU + uvw[1] * vectorV + uvw[2] * vectorW; var newNode = new LatticeNode(basePlane.Origin + V); // Check if point is inside - use unstrict tolerance, meaning it can be outside the surface by the specified tolerance bool isInside = FrameTools.IsPointInside(designSpace, newNode.Point3d, spaceType, tol, strictlyIn); // Set the node state (it's location wrt the design space) if (isInside) { newNode.State = LatticeNodeState.Inside; } else { newNode.State = LatticeNodeState.Outside; } // Add node to tree nodeList.Add(newNode); } } } } } // 9. Map struts to the node tree lattice.UniformMapping(cell, designSpace, spaceType, N, minLength, maxLength); // 10. Set output DA.SetDataList(0, lattice.Struts); }