/// <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) { List <IGH_GeometricGoo> Geoms = new List <IGH_GeometricGoo>(); bool IsBake = false; Rhino.DocObjects.ObjectAttributes Attr = null; if (!DA.GetDataList(0, Geoms)) { return; } if (!DA.GetData(1, ref Attr)) { return; } if (!DA.GetData(2, ref IsBake)) { return; } if (!IsBake) { return; } foreach (IGH_GeometricGoo Geom in Geoms) { if (Geom != null) { Rhino.RhinoDoc.ActiveDoc.Objects.Add(GH_Convert.ToGeometryBase(Geom), Attr); } } }
/// <summary> /// Parses all geometries and adds to the linked lists. This does not clear the lists. /// </summary> /// <param name="geometricGoos"></param> /// <param name="breps"></param> /// <param name="meshes"></param> /// <param name="curves"></param> public static void ParseAll(IList <IGH_GeometricGoo> geometricGoos, List <Brep> breps = null, List <Mesh> meshes = null, List <Curve> curves = null) { for (int i = 0; i < geometricGoos.Count; i++) { IGH_GeometricGoo shape = geometricGoos[i]; if (shape is Mesh || shape is GH_Mesh) { if (meshes != null) { meshes.Add(GH_Convert.ToGeometryBase(shape) as Mesh); } } if (shape is Brep || shape is GH_Brep) { if (breps != null) { breps.Add(GH_Convert.ToGeometryBase(shape) as Brep); } } if (shape is Curve || shape is GH_Curve) { if (curves != null) { curves.Add(GH_Convert.ToGeometryBase(shape) as Curve); } } } }
/// <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); }
public override bool CastFrom(object source) { var target = GH_Convert.ToGeometryBase(source); if (target == null) { return(false); } Value = new DisplayGeometry(target, new DisplayMaterial(Color.Black, 0)); return(true); }
public static List <GeometryBase> AllVisableGeometryInGHDocmument() { var canvas = Instances.ActiveCanvas; if (canvas == null) { throw new Exception("No Document Server exist!"); } if (!canvas.IsDocument) { throw new Exception("No Document Server exist!"); } GH_Document doc = canvas.Document; if (doc == null) { throw new Exception("Tasker 未找到GH_Document"); } var list = new List <GeometryBase>(); foreach (IGH_DocumentObject obj in doc.Objects) { if (!(obj is IGH_PreviewObject prev) || prev.Hidden || !(obj is IGH_Component comp)) { continue; } comp.Params.Output.ForEach((IGH_Param output) => { IGH_Structure data = output.VolatileData; if (!data.IsEmpty) { foreach (var dat in data.AllData(true)) { GeometryBase geometry = GH_Convert.ToGeometryBase(dat); if (geometry == null) { continue; } list.Add(geometry); } } }); } return(list); }
private void writeRhino3dm(File3dm f, string filePath, List <ObjectLayerInfo> G, List <int> att) { for (int i = 0; i < G.Count; i++) { GeometryBase g = GH_Convert.ToGeometryBase(G[i].Geometry); ObjectAttributes attr = new ObjectAttributes(); attr.LayerIndex = att[i]; if (g != null) { switch (g.ObjectType) { case ObjectType.Brep: f.Objects.AddBrep(g as Brep, attr); break; case ObjectType.Curve: f.Objects.AddCurve(g as Curve, attr); break; case ObjectType.Point: f.Objects.AddPoint((g as Rhino.Geometry.Point).Location, attr); break; case ObjectType.Surface: f.Objects.AddSurface(g as Surface, attr); break; case ObjectType.Mesh: f.Objects.AddMesh(g as Mesh, attr); break; case ObjectType.PointSet: f.Objects.AddPointCloud(g as PointCloud, attr); //This is a speculative entry break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "不能识别的物体: " + G.GetType().FullName); break; } } } f.Write(filePath, 5); f.Dispose(); }
public void Write(List <ObjectLayerInfo> G, List <int> att) { for (int i = 0; i < G.Count; i++) { GeometryBase g = GH_Convert.ToGeometryBase(G[i].Geometry); ObjectAttributes attr = new ObjectAttributes(); attr.LayerIndex = att[i]; if (g != null) { switch (g.ObjectType) { case ObjectType.Brep: m_file.Objects.AddBrep(g as Brep, attr); break; case ObjectType.Curve: m_file.Objects.AddCurve(g as Curve, attr); break; case ObjectType.Point: m_file.Objects.AddPoint((g as Rhino.Geometry.Point).Location, attr); break; case ObjectType.Surface: m_file.Objects.AddSurface(g as Surface, attr); break; case ObjectType.Mesh: m_file.Objects.AddMesh(g as Mesh, attr); break; case ObjectType.PointSet: m_file.Objects.AddPointCloud(g as PointCloud, attr); //This is a speculative entry break; default: break; } } } m_file.Write(m_path, 6); m_file.Dispose(); }
protected override void SolveInstance(IGH_DataAccess DA) { IGH_GeometricGoo geometry = null; DisplayMaterial material = null; string layer = ""; if (!DA.GetData(0, ref geometry)) { return; } DA.GetData(1, ref material); DA.GetData(2, ref layer); var target = GH_Convert.ToGeometryBase(geometry); var displayStyle = new DisplayGeometry(target, material, layer); DA.SetData(0, new GH_DisplayGeometry(displayStyle)); }
/***************************************************/ /**** IGH_BakeAwareData methods ****/ /***************************************************/ public bool BakeGeometry(RhinoDoc doc, ObjectAttributes att, out Guid obj_guid) { if (m_RhinoGeometry != null) { if (att == null) { att = new ObjectAttributes(); att.LayerIndex = doc.Layers.CurrentLayerIndex; } if (Value is IRender) { //bake with render colour always att.ColorSource = ObjectColorSource.ColorFromObject; att.ObjectColor = m_Color; //special case for Text3d as it is not GeometryBase if (Value is RenderText) { obj_guid = doc.Objects.AddText((Rhino.Display.Text3d)m_RhinoGeometry, att); } else { obj_guid = doc.Objects.Add(GH_Convert.ToGeometryBase(m_RhinoGeometry), att); } } else { BHoMObject bhObj = Value as BHoMObject; if (string.IsNullOrEmpty(att.Name) && bhObj != null && !string.IsNullOrWhiteSpace(bhObj.Name)) { att.Name = bhObj.Name; } obj_guid = doc.Objects.Add(GH_Convert.ToGeometryBase(m_RhinoGeometry), att); } return(true); } obj_guid = Guid.Empty; return(false); }
protected override void SolveInstance(IGH_DataAccess DA) { IGH_GeometricGoo g = null; DA.GetData <IGH_GeometricGoo>(0, ref g); string geoType = g.TypeName; string name = null; DA.GetData(1, ref name); bool activate = false; DA.GetData(2, ref activate); Rhino.DocObjects.ObjectAttributes atts = new Rhino.DocObjects.ObjectAttributes(); string newID = null; atts.Name = name; if (activate) { GH_Point p = g as GH_Point; if (p != null) { GeometryBase geo = GH_Convert.ToGeometryBase(p); newID = RhinoDoc.ActiveDoc.Objects.Add(geo, atts).ToString(); } GH_Curve c = g as GH_Curve; if (c != null) { GeometryBase geo = GH_Convert.ToGeometryBase(c); newID = RhinoDoc.ActiveDoc.Objects.Add(geo, atts).ToString(); } } DA.SetData(0, newID); }
/// <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) { List <Object> geometry = new List <object>(); Guanaco.SupportType type = null; string name = string.Empty; DA.GetDataList(0, geometry); DA.GetData(1, ref type); DA.GetData(2, ref name); List <GeometryBase> rhgeo = new List <GeometryBase>(); foreach (object g in geometry) { GeometryBase gg = GH_Convert.ToGeometryBase(g); rhgeo.Add(gg); } Guanaco.Support support = new Guanaco.Support(rhgeo, type, name); DA.SetData(0, support); }
protected override void SolveInstance(IGH_DataAccess DA) { List <GeometryBase> castGeo = new List <GeometryBase>(); List <GH_ObjectWrapper> geoToTransform = new List <GH_ObjectWrapper>(); int rowCount = -1; double spacing = 2.0; if (!DA.GetDataList("Geometry", geoToTransform)) { return; } if (!DA.GetData("Items in Row", ref rowCount)) { return; } if (!DA.GetData("Spacing", ref spacing)) { return; } List <GeometryBase> transformedGeo = new List <GeometryBase>(); List <Transform> xforms = new List <Transform>(); geoToTransform.ForEach(item => { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, item.Value.GetType().ToString()); if (GH_Convert.ToGeometryBase(item.Value) == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, item.Value.GetType().ToString() + "not supported. Contact Woods Bagot DT to add support"); } else { castGeo.Add(GH_Convert.ToGeometryBase(item.Value)); } }); double x = 0; double y = 0; int i = 0; double maxY = 0; castGeo.ForEach(geo => { if (i == rowCount) { x = 0; i = 0; y += maxY + spacing; } i++; var bbox = geo.GetBoundingBox(false); var width = bbox.Diagonal.X; var height = bbox.Diagonal.Y; var lowerLeft = bbox.Min; var currPoint = new Point3d(x, y, 0); var transform = Transform.Translation(currPoint - lowerLeft); geo.Transform(transform); transformedGeo.Insert(0, geo); xforms.Add(transform); x += width + spacing; if (maxY < height) { maxY = height; } }); DA.SetDataList("Transformed Geometry", transformedGeo); DA.SetDataList("Transforms", xforms); }
private void StoreOutput() { DebugEvent("Start Store Output"); GH_DocumentServer doc_server = Instances.DocumentServer; if (doc_server == null) { throw new Exception("No Document Server exist!"); } GH_Document doc = doc_server.ToList().Find(x => x.Properties.ProjectFileName == ID.ToString()); if (doc == null) { throw new Exception("Tasker 未找到GH_Document"); } if (string.IsNullOrEmpty(workspace) || string.IsNullOrEmpty(ticket)) { throw new Exception("工作目录和Ticket为空"); } string outDir = Path.Combine(taskspace, ID.ToString(), ticket); var hooks = doc.ClusterOutputHooks(); if (hooks == null) { return; } foreach (var hook in hooks) { string info = hook.CustomDescription; if (string.IsNullOrEmpty(info)) { continue; } var paraMap = ConvertUrlParam(info); if (!paraMap.TryGetValue("Index", out string index) || !paraMap.TryGetValue("Type", out string type)) { continue; } DebugEvent($"Index: {index}; Type: {type}"); string fileName = Path.Combine(outDir, index + "@" + DateTime.Now.ToString("HH-mm-ss MM-dd")); var volatileData = hook.VolatileData; if (volatileData.IsEmpty) { continue; } dynamic content = null; switch (type) { case "CSV": { var allData = volatileData.AllData(true); List <string> sList = new List <string>(); allData.ToList().ForEach(el => { GH_Convert.ToString(el, out string tmp, GH_Conversion.Both); sList.Add(tmp); }); string csv = string.Join(Environment.NewLine, sList); fileName += ".csv"; File.WriteAllText(fileName, csv, Encoding.UTF8); content = fileName; break; } case "3DM": { fileName += ".3dm"; File3dmWriter writer = new File3dmWriter(fileName); foreach (var data in volatileData.AllData(true)) { GeometryBase obj = GH_Convert.ToGeometryBase(data); if (obj == null) { continue; } string layer = obj.GetUserString("Layer"); if (layer == null) { continue; } ObjectAttributes att = new ObjectAttributes { LayerIndex = writer.GetLayer(layer, Color.Black) }; writer.ObjectMap.Add(att, obj); } writer.Write(); content = fileName; break; } case "Data": { try { GH_Structure <IGH_Goo> tree = volatileData as GH_Structure <IGH_Goo>; content = IO.SerializeGrasshopperData(tree, hook.CustomName, volatileData.IsEmpty); } catch (Exception ex) { ErrorEvent(this, ex.Message); } break; } case "EPS": { List <GeometryBase> objs = new List <GeometryBase>(); foreach (var data in volatileData.AllData(true)) { if (data == null) { continue; } GeometryBase obj = GH_Convert.ToGeometryBase(data); if (obj == null) { continue; } objs.Add(obj); } if (!Directory.Exists(fileName)) { Directory.CreateDirectory(fileName); } content = JsonConvert.SerializeObject(SaveAdobeDocument(fileName, objs, AdobeDocType.EPS)); break; } case "PDF": { List <GeometryBase> objs = new List <GeometryBase>(); fileName += ".pdf"; foreach (var data in volatileData.AllData(true)) { if (data == null) { continue; } GeometryBase obj = GH_Convert.ToGeometryBase(data); if (obj == null) { continue; } objs.Add(obj); } var res = SaveAdobeDocument(fileName, objs, AdobeDocType.PDF); if (res == null || res.Count == 0) { break; } content = res[0]; break; } case "RhinoPDF": { var pdf = FilePdf.Create(); fileName += ".pdf"; DebugEvent("RhinoPDF Begin"); foreach (var page in volatileData.AllData(true)) { DebugEvent("RhinoPDF got 1 page"); if (!page.CastTo(out RhinoPageView view)) { DebugEvent(string.Format("{0} can not convert to RhinoPageView", page.GetType())); continue; } DebugEvent("Data is converted to RhinoPage"); ViewCaptureSettings settings = new ViewCaptureSettings(view, 300) { OutputColor = ViewCaptureSettings.ColorMode.DisplayColor, RasterMode = true }; pdf.AddPage(settings); } pdf.Write(fileName); content = fileName; break; } case "DXF": { break; } default: break; } StoreEvent(this, new JObject { ["route"] = "task-stored", ["id"] = ID.ToString(), ["index"] = index.ToString(), ["type"] = type, ["content"] = content }.ToString()); } }
/// <summary> /// Wrap input geometry into module cages. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from /// input parameters and to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { var geometryRaw = new List <IGH_GeometricGoo>(); var basePlane = new Plane(); var diagonal = new Vector3d(); var method = 2; var precision = 0.5; if (!DA.GetDataList(0, geometryRaw)) { return; } if (!DA.GetData(1, ref basePlane)) { return; } if (!DA.GetData(2, ref diagonal)) { return; } if (!DA.GetData(3, ref method)) { return; } if (!DA.GetData(4, ref precision)) { return; } if (diagonal.X <= 0 || diagonal.Y <= 0 || diagonal.Z <= 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "One or more slot dimensions are not larger than 0."); return; } if (method < 0 || method > 3) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Unknown Fill Method (F)."); return; } var geometryClean = geometryRaw .Where(goo => goo != null) .Select(goo => { var geo = goo.Duplicate(); var geometry = GH_Convert.ToGeometryBase(geo); // Transformation of BReps sometimes does not work as expected // For example non uniform scaling of a sphere results in a sphere // Mesh scaling is safe and populating is fast(er) if (geometry.HasBrepForm) { var meshingParameters = MeshingParameters.FastRenderMesh; var brep = Brep.TryConvertBrep(geometry); var meshes = Mesh.CreateFromBrep(brep, meshingParameters); var mesh = new Mesh(); foreach (var meshFace in meshes) { mesh.Append(meshFace); } mesh.Weld(Math.PI / 8); return(mesh); } else { return(geometry); } } ); if (!geometryClean.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Failed to collect any valid geometry."); return; } // Scale down to unit size var normalizationTransform = Transform.Scale(basePlane, 1 / diagonal.X, 1 / diagonal.Y, 1 / diagonal.Z); // Orient to the world coordinate system var worldAlignmentTransform = Transform.PlaneToPlane(basePlane, Plane.WorldXY); var centersNormalized = new List <Point3i>(); var ambiguityWarning = false; foreach (var goo in geometryClean) { var geometry = goo.Duplicate(); if (geometry.Transform(normalizationTransform) && geometry.Transform(worldAlignmentTransform)) { var objectType = goo.ObjectType; var isMesh = objectType == ObjectType.Mesh; if ((method == 0 || method == 2 || method == 3) && objectType == ObjectType.Point) { var p = ((Point)geometry).Location; if (!IsOnEdgeUnitized(p)) { centersNormalized.Add(new Point3i(p)); } else { ambiguityWarning = true; } } if ((method == 0 || method == 2 || method == 3) && objectType == ObjectType.Curve) { centersNormalized.AddRange(PopulateCurve(precision, (Curve)geometry) .Where(p => !IsOnEdgeUnitized(p)) .Select(p => new Point3i(p)) .Distinct()); ambiguityWarning = true; } if (objectType == ObjectType.Mesh && (method == 0 || ((method == 2 || method == 3) && !((Mesh)geometry).IsClosed))) { centersNormalized.AddRange(PopulateMeshSurface(precision, (Mesh)geometry) .Where(p => !IsOnEdgeUnitized(p)) .Select(p => new Point3i(p)) .Distinct()); ambiguityWarning = true; } if (method == 1 && objectType == ObjectType.Mesh && ((Mesh)geometry).IsClosed) { centersNormalized.AddRange(CentersFromMeshVolume((Mesh)geometry)); } if (method == 2 && objectType == ObjectType.Mesh && ((Mesh)geometry).IsClosed) { centersNormalized.AddRange(CentersFromMeshVolumeAndSurface((Mesh)geometry)); } if (method == 3 && objectType == ObjectType.Mesh && ((Mesh)geometry).IsClosed) { centersNormalized.AddRange(CentersFromMeshSurface((Mesh)geometry)); } } } if (ambiguityWarning) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Test points matching the Slot grid may have been skipped " + "due to ambiguity."); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Slightly move, scale or remodel the geometry where Slot " + "centers are missing."); } if (!centersNormalized.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Failed to collect any Slot centers from the given geometry."); return; } var centers = centersNormalized .Distinct() .Select(centerNormalized => centerNormalized.ToCartesian(basePlane, diagonal)); DA.SetDataList(0, centers); }
/// <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> /// 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) { var gridSize = Units.ConvertFromMeter(DA.Fetch <double>("GridSize [m]")); var edgeOffset = Units.ConvertFromMeter(DA.Fetch <double>("Edge Offset [m]")); var offset = Units.ConvertFromMeter(DA.Fetch <double>("Vertical Offset [m]")); var useCenters = DA.Fetch <bool>("IsoCurves"); var geometries = DA.FetchList <IGH_GeometricGoo>("Geometry"); var goLarge = DA.Fetch <bool>("GoLarge"); DataTree <Point3d> centers = new DataTree <Point3d>(); List <Grid> myGrids = new List <Grid>(); List <Mesh> meshes = new List <Mesh>(); //List<Mesh> inMeshes = new List<Mesh>(); List <Brep> inBreps = new List <Brep>(); List <Curve> inCrvs = new List <Curve>(); //string msg = ""; useCenters = !useCenters; for (int i = 0; i < geometries.Count; i++) { if (geometries[i] == null) { continue; } IGH_GeometricGoo shape = geometries[i].DuplicateGeometry(); shape.Transform(Transform.Translation(0, 0, offset)); if (shape is Mesh || shape is GH_Mesh) { //inMeshes.Add(GH_Convert.ToGeometryBase(shape) as Mesh); myGrids.Add(new Grid(GH_Convert.ToGeometryBase(shape) as Mesh, useCenters: useCenters)); } else if (shape is Brep || shape is GH_Brep) { //myGrids.Add(new Grid(GH_Convert.ToGeometryBase(shape) as Brep, gridSize, useCenters: useCenters)); inBreps.Add(GH_Convert.ToGeometryBase(shape) as Brep); } else if (shape is Curve || shape is GH_Curve) { //myGrids.Add(new Grid(GH_Convert.ToGeometryBase(shape) as Curve, gridSize, useCenters: useCenters)); inCrvs.Add(GH_Convert.ToGeometryBase(shape) as Curve); } else { myGrids.Add(null); meshes.Add(null); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "error on an input grid"); } } List <Brep> breps = InputGeometries.CurvesToOffsetBreps(inCrvs, edgeOffset) ?? new List <Brep>(); breps.AddRange(InputGeometries.BrepsToOffsetBreps(inBreps, edgeOffset)); for (int i = 0; i < breps.Count; i++) { myGrids.Add(new Grid(breps[i], gridSize, useCenters: useCenters, goLarge)); } for (int i = 0; i < myGrids.Count; i++) { meshes.Add(myGrids[i].SimMesh); GH_Path p = new GH_Path(i); centers.AddRange(myGrids[i].SimPoints, p); } DA.SetDataList(0, myGrids); DA.SetDataList(1, meshes); DA.SetDataTree(2, centers); //DA.SetData(3, msg); }
/// <summary> /// Wrap input geometry into module cages. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from /// input parameters and to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { var slotCenters = new List <Point3d>(); var productionGeometryRaw = new List <IGH_GeometricGoo>(); var nameRaw = new ModuleName(); var basePlane = new Plane(); var slotDiagonal = new Vector3d(); if (!DA.GetData(0, ref nameRaw)) { return; } if (!DA.GetDataList(1, slotCenters)) { return; } DA.GetDataList(2, productionGeometryRaw); if (!DA.GetData(3, ref basePlane)) { return; } if (!DA.GetData(4, ref slotDiagonal)) { return; } var name = nameRaw.Name.ToLower(); if (name.Length == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Monoceros Module name is empty."); return; } if (Config.RESERVED_CHARS.Any(chars => name.Contains(chars))) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Monoceros Module name contains " + "a forbidden content: :, ->, = or newline."); return; } if (Config.RESERVED_NAMES.Contains(name)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The Monoceros Module name cannot be \"" + name + "\" because it is reserved by Monoceros."); return; } if (!slotCenters.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Failed to collect Slot Points."); return; } if (slotDiagonal.X <= 0 || slotDiagonal.Y <= 0 || slotDiagonal.Z <= 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "One or more slot dimensions are not larger than 0."); return; } // Scale down to unit size var normalizationTransform = Transform.Scale(basePlane, 1 / slotDiagonal.X, 1 / slotDiagonal.Y, 1 / slotDiagonal.Z); // Orient to the world coordinate system var worldAlignmentTransform = Transform.PlaneToPlane(basePlane, Plane.WorldXY); // Slot dimension is for the sake of this calculation 1,1,1 var partCenters = slotCenters.Select(center => { center.Transform(normalizationTransform); center.Transform(worldAlignmentTransform); return(new Point3i(center)); }).Distinct() .ToList(); var gooClean = productionGeometryRaw .Where(goo => goo != null); var productionGeometryClean = gooClean .Where(goo => !goo.IsReferencedGeometry) .Select(ghGeo => { var geo = ghGeo.Duplicate(); return(GH_Convert.ToGeometryBase(geo)); }); var productionGeometryReferencedClean = gooClean .Where(goo => goo.IsReferencedGeometry) .Select(ghGeo => { var geo = ghGeo.Duplicate(); return(GH_Convert.ToGeometryBase(geo)); }); var guidsClean = gooClean .Where(goo => goo.IsReferencedGeometry) .Select(ghGeo => ghGeo.ReferenceID); var module = new Module(name, productionGeometryClean, productionGeometryReferencedClean, guidsClean, basePlane, partCenters, slotDiagonal); if (module.Geometry.Count + module.ReferencedGeometry.Count != productionGeometryRaw.Count) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Some geometry was not used."); } if (!module.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, module.IsValidWhyNot); } DA.SetData(0, module); }
/// <summary> /// Wrap input geometry into module cages. /// </summary> /// <param name="DA">The DA object can be used to retrieve data from /// input parameters and to store data in output parameters.</param> protected override void SolveInstance(IGH_DataAccess DA) { var geometryRaw = new List <IGH_GeometricGoo>(); var module = new Module(); var basePlane = new Plane(); if (!DA.GetDataList(0, geometryRaw)) { return; } if (!DA.GetData(1, ref module)) { return; } if (!DA.GetData(2, ref basePlane)) { return; } if (module == null || !module.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Module is null or invalid."); return; } // Transform the geometry to be oriented to world XYZ fore easier scanning var geometryTransform = Transform.PlaneToPlane(basePlane, Plane.WorldXY); var geometryClean = geometryRaw .Select(goo => GH_Convert.ToGeometryBase(goo)) .Where(geo => geo != null) .Select(geo => { var transformedGeometry = geo.Duplicate(); transformedGeometry.Transform(geometryTransform); return(transformedGeometry); }).ToList(); if (!geometryClean.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Failed to collect any valid geometry to scan."); return; } var moduleGeometry = module.Geometry .Concat(module.ReferencedGeometry); if (!moduleGeometry.Any()) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Module \"" + module.Name + "\" contains " + "no geometry and therefore will be skipped."); return; } var moduleGeometryBBoxes = moduleGeometry.Select(geo => geo.GetBoundingBox(true)); var bBoxUnionModule = BoundingBox.Empty; bBoxUnionModule.Union(module.Pivot.Origin); foreach (var moduleBBox in moduleGeometryBBoxes) { bBoxUnionModule.Union(moduleBBox); } var moduleDimensionSafetyBuffer = new Point3i( (int)Math.Ceiling(bBoxUnionModule.Diagonal.X / module.PartDiagonal.X) + 1, (int)Math.Ceiling(bBoxUnionModule.Diagonal.Y / module.PartDiagonal.Y) + 1, (int)Math.Ceiling(bBoxUnionModule.Diagonal.Z / module.PartDiagonal.Z) + 1); var geometryBBoxes = geometryClean.Select(geo => geo.GetBoundingBox(true)).ToList(); var bBoxUnionGeometry = BoundingBox.Empty; foreach (var bBox in geometryBBoxes) { bBoxUnionGeometry.Union(bBox); } var slots = new List <Slot>(); for (int z = (int)Math.Floor(bBoxUnionGeometry.Min.Z / module.PartDiagonal.Z) - moduleDimensionSafetyBuffer.Z; z < Math.Ceiling(bBoxUnionGeometry.Max.Z / module.PartDiagonal.Z) + moduleDimensionSafetyBuffer.Z; z++) { for (int y = (int)Math.Floor(bBoxUnionGeometry.Min.Y / module.PartDiagonal.Y) - moduleDimensionSafetyBuffer.Y; y < Math.Ceiling(bBoxUnionGeometry.Max.Y / module.PartDiagonal.Y) + moduleDimensionSafetyBuffer.Y; y++) { for (int x = (int)Math.Floor(bBoxUnionGeometry.Min.X / module.PartDiagonal.X) - moduleDimensionSafetyBuffer.X; x < Math.Ceiling(bBoxUnionGeometry.Max.X / module.PartDiagonal.X) + moduleDimensionSafetyBuffer.X; x++) { var currentRelativePosition = new Point3i(x, y, z); var currentPivot = Plane.WorldXY; currentPivot.Origin = currentRelativePosition.ToCartesian(Plane.WorldXY, module.PartDiagonal); var transformModuleToCurrentPivot = Transform.PlaneToPlane(module.Pivot, currentPivot); var moduleGeometryBBoxesAtCurrentPivot = moduleGeometryBBoxes.Select(bBox => { var transformedBBox = bBox; transformedBBox.Transform(transformModuleToCurrentPivot); return(transformedBBox); }); var indicesOfSimilarBBoxes = moduleGeometryBBoxesAtCurrentPivot.Select(moduleGeometryBBox => geometryBBoxes.Select((geometryBBox, index) => { var moduleCorners = moduleGeometryBBox.GetCorners().ToList(); var geometryCorners = geometryBBox.GetCorners().ToList(); moduleCorners.Sort(); geometryCorners.Sort(); if (Enumerable.SequenceEqual(moduleCorners, geometryCorners)) { return(index); } else { return(-1); } }).Where(index => index != -1) ); // If any module geometry doesn't have a bbox similar to any geometry, then early continue if (!indicesOfSimilarBBoxes.All(similarBBoxes => similarBBoxes.Any())) { continue; } // Heavy calculations var transformedModuleGeometry = moduleGeometry.Select(geo => { var transformedGeometry = geo.Duplicate(); transformedGeometry.Transform(transformModuleToCurrentPivot); return(transformedGeometry); }); var geometriesToCheck = indicesOfSimilarBBoxes.Select(indices => indices.Select(index => geometryClean[index])); var geometryEqualityPattern = transformedModuleGeometry .Zip(geometriesToCheck, (current, others) => others.Any(other => // TODO: when the original geometry is moved, the meshes become unequal // TODO: replace with visual similarity check (pull random points to geometry) // TODO: check if the two are of the same type first GeometryBase.GeometryEquals(current, other) )); if (geometryEqualityPattern.All(equal => equal)) { var firstModulePartRelativeCenter = module.PartCenters[0]; var modulePartsRelativeCentersRelativeToModulePivot = module.PartCenters.Select(center => center - firstModulePartRelativeCenter); var currentModuleSlots = modulePartsRelativeCentersRelativeToModulePivot .Zip( module.PartNames, (partCenter, partName) => new Slot(basePlane, currentRelativePosition + partCenter, module.PartDiagonal, false, new List <string>() { module.Name }, new List <string>() { partName }, 0)); slots.AddRange(currentModuleSlots); } } } } if (!Slot.AreSlotLocationsUnique(slots)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Slot centers are not unique."); } DA.SetDataList(0, slots); }
/// <summary> /// input a List/IGH_GeometricGoo/ /// List/IGH_GeometricGoo/ shapes = new List/IGH_GeometricGoo/(); /// DA.GetDataList/IGH_GeometricGoo/(2, shapes); /// </summary> /// <param name="geometricGoos">List IGH_GeometricGoo shapes, can be Brep and Mesh</param> /// <returns>joinedMesh</returns> /// public static Mesh ParseToJoinedMesh(List <IGH_GeometricGoo> geometricGoos, out BoundingBox boundingBox, bool parallel = true) { boundingBox = new BoundingBox(); if (geometricGoos.Count == 0) { return(null); } Mesh[] meshes = new Mesh[geometricGoos.Count]; Mesh joinedMesh = new Mesh(); if (parallel) { Parallel.For(0, geometricGoos.Count, delegate(int i) { IGH_GeometricGoo shape = geometricGoos[i]; if (shape is Mesh || shape is GH_Mesh) { var geobase = GH_Convert.ToGeometryBase(shape); meshes[i] = geobase as Mesh; } else if (shape is Brep || shape is GH_Brep) { var geobase = GH_Convert.ToGeometryBase(shape); Brep brep = geobase as Brep; MeshingParameters mp = MeshingParameters.Default; Mesh[] meshParts = Mesh.CreateFromBrep(brep, mp); meshes[i] = meshParts[0]; for (int j = 1; j < meshParts.Length; j++) { meshes[i].Append(meshParts[j]); } } }); } else { for (int i = 0; i < geometricGoos.Count; i++) { IGH_GeometricGoo shape = geometricGoos[i]; if (shape is Mesh || shape is GH_Mesh) { var geobase = GH_Convert.ToGeometryBase(shape); meshes[i] = geobase as Mesh; } else if (shape is Brep || shape is GH_Brep) { var geobase = GH_Convert.ToGeometryBase(shape); Brep brep = geobase as Brep; MeshingParameters mp = MeshingParameters.Default; Mesh[] meshParts = Mesh.CreateFromBrep(brep, mp); meshes[i] = meshParts[0]; for (int j = 1; j < meshParts.Length; j++) { meshes[i].Append(meshParts[j]); } } } } foreach (var mesh in meshes) { if (mesh != null) { joinedMesh.Append(mesh); } } CleanMesh(joinedMesh); boundingBox = joinedMesh.GetBoundingBox(true); return(joinedMesh); }