/// <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) { // SET ALL INPUT PARAMETERS var curves = da.FetchList <Curve>("Polylines"); var dist = da.Fetch <double>("Distance"); var pln = da.Fetch <Plane>("Plane"); var tolerance = da.Fetch <double>("Tolerance"); var openType = da.FetchList <int>("OpenFillet").Cast <Polyline3D.OpenFilletType>().ToList(); if (openType.Count == 0) { openType = new List <Polyline3D.OpenFilletType> { Polyline3D.OpenFilletType.Square }; } var miter = da.Fetch <double>("Miter"); var closedType = da.FetchList <int>("ClosedFillet").Cast <Polyline3D.ClosedFilletType>().ToList(); var polylines = Polyline3D.ConvertCurvesToPolyline(curves).ToList(); if (curves.Count == 0) { return; } if (pln.Equals(default))
/// <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) { // SET ALL INPUT PARAMETERS List <Curve> A = DA.FetchList <Curve>("A"); List <Curve> B = DA.FetchList <Curve>("B"); try { ClipType type = (ClipType)DA.Fetch <int>("BooleanType"); Plane pln = DA.Fetch <Plane>("Plane"); double tolerance = DA.Fetch <double>("Tolerance"); // Convert the curves to polylines // This is a crude way of doing this. // Should we add some parameters for this perhaps? IEnumerable <Polyline> APl = Polyline3D.ConvertCurvesToPolyline(A); IEnumerable <Polyline> BPl = Polyline3D.ConvertCurvesToPolyline(B); // If we don't have a plane, let's try to create a plane from the first curve. if (pln.Equals(default(Plane)) || !pln.IsValid) { pln = APl.First().FitPlane(); } List <Polyline> result = new List <Polyline>(); // do the boolean operation result = Polyline3D.Boolean(type, APl, BPl, pln, tolerance, EvenOdd); // OUTPUT LOGIC DA.SetDataList("Result", result); } catch (Exception e) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message + ": " + e.StackTrace.ToString()); } }
/// <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) { // SET ALL INPUT PARAMETERS List <Curve> curves = DA.FetchList <Curve>("Polylines"); double dist = DA.Fetch <double>("Distance"); Plane pln = DA.Fetch <Plane>("Plane"); double tolerance = DA.Fetch <double>("Tolerance"); List <Polyline3D.OpenFilletType> openType = DA.FetchList <int>("OpenFillet").Cast <Polyline3D.OpenFilletType>().ToList(); if (openType == null || openType.Count == 0) { openType = new List <Polyline3D.OpenFilletType> { Polyline3D.OpenFilletType.Square }; } double miter = DA.Fetch <double> ("Miter"); List <Polyline3D.ClosedFilletType> closedType = DA.FetchList <int>("ClosedFillet").Cast <Polyline3D.ClosedFilletType>().ToList(); IEnumerable <Polyline> polylines = Polyline3D.ConvertCurvesToPolyline(curves); if (pln.Equals(default(Plane))) { pln = polylines.First().FitPlane(); } // set default fillet type. if (closedType == null || closedType.Count == 0) { closedType = new List <Polyline3D.ClosedFilletType> { Polyline3D.ClosedFilletType.Square }; } if (curves.Count == 0) { return; } List <List <Polyline> > outside; List <List <Polyline> > holes; Polyline3D.Offset(polylines, openType, closedType, pln, tolerance, new List <double> { dist }, miter, 0.25, out outside, out holes); // OUTPUT LOGIC DA.SetDataList("Contour", outside.First()); DA.SetDataList("Holes", holes.First()); }
protected override void SolveInstance(IGH_DataAccess DA) { MeshProps meshProps = DA.Fetch <MeshProps>("MeshProp"); //GH_Structure<GH_Number> D = DA.FetchTree<GH_Number>("Dist"); List <double> D = DA.FetchList <double>("Dist"); try { double firstDist = (D.Count > 0) ? D[0] : 0.01; double[][] DArray = new double[][] { new double[1] { D[0] } }; if (D.Count > 0) { DArray = new double[meshProps.FEFlatten.Length][]; for (int i = 0; i < meshProps.FEFlatten.Length; i++) { DArray[i] = new double[meshProps.FEFlatten[i].Length]; } for (int i = 0; i < meshProps._FlattenFE.Count; i++) { DArray[meshProps._FlattenFE[i][0]][meshProps._FlattenFE[i][1]] = D[i % D.Count]; } } //Compute translation //Create Nexors NGonsCore.Nexorades.Nexors nexors = new NGonsCore.Nexorades.Nexors(); for (int i = 0; i < meshProps.M._countF(); i++) { for (int j = 0; j < meshProps.M._countE(i); j++) { nexors.Add(meshProps.EFLines[i][j], i, j); nexors[i, j].translation = DArray[i][j]; } } Line[][] translatedLines = meshProps.NexorTranslateLines(ref nexors, DArray); //Output DA.SetDataTree(0, nexors.GetNexorLines()); DA.SetDataTree(1, nexors.GetNexorEccentricities()); DA.SetData(2, nexors); DA.SetData(3, meshProps); DA.SetDataTree(4, nexors.GetNexorLines(-1)); } catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } }
/// <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 <double> manuallySteps = DA.FetchList <double>("steps"); InputSelector inputSelector = new InputSelector(manuallySteps); DA.SetData(0, inputSelector); }
/// <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) { // SET ALL INPUT PARAMETERS var curvesA = da.FetchList <Curve>("A"); var curvesB = da.FetchList <Curve>("B"); try { var type = (ClipType)da.Fetch <int>("BooleanType"); var pln = da.Fetch <Plane>("Plane"); var tolerance = da.Fetch <double>("Tolerance"); // Convert the curves to polylines // This is a crude way of doing this. // Should we add some parameters for this perhaps? var polylinesA = Polyline3D.ConvertCurvesToPolyline(curvesA).ToList(); var polylinesB = Polyline3D.ConvertCurvesToPolyline(curvesB).ToList(); // If we don't have a plane, let's try to create a plane from the first curve. if (pln.Equals(default) || !pln.IsValid)
protected override void SolveInstance(IGH_DataAccess DA) { Surface m0 = DA.Fetch <Surface>("Srf0"); Surface m1 = DA.Fetch <Surface>("Srf1"); List <Curve> curves = DA.FetchList <Curve>("Curves"); List <Polyline> polylines = new List <Polyline>(); foreach (Curve c in curves) { Polyline polyline; if (c.TryGetPolyline(out polyline)) { polylines.Add(polyline); } } DA.SetDataList(0, polylines.MappedFromSurfaceToSurface(m0, m1)); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh m0 = DA.Fetch <Mesh>("Mesh0"); Mesh m1 = DA.Fetch <Mesh>("Mesh1"); List <Curve> curves = DA.FetchList <Curve>("Curves"); List <Polyline> polylines = new List <Polyline>(); foreach (Curve c in curves) { Polyline polyline; if (c.TryGetPolyline(out polyline)) { polylines.Add(polyline); } } DA.SetDataList(0, polylines.MappedFromMeshToMesh(m0, m1)); }
/// <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 divide the brep by the Z components of the grid (get Z values on plane of the grid //2 intersect the grid for reach Z value -> planar surface the results //3 check for each pixel if it is closer than the var geometry = DA.FetchList <IGH_GeometricGoo>(0); var pg = DA.Fetch <PixelGrid2D>(1); pg = (PixelGrid2D)pg.Clone(); if (pg == null || !pg.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The (input) voxelgrid was invalid"); return; } var geometryIndex = new Dictionary <int, IGH_GeometricGoo>(); for (int i = 0, count = geometry.Count; i < count; i++) { geometryIndex.Add(i, geometry[i]); } var ptList = GeometryHelper.TryCastGeometry <Point3d>(geometryIndex, false); var curveList = GeometryHelper.TryCastGeometry <Curve>(geometryIndex, false); foreach (var pt in ptList.Values) { AddPoint3d(pg, pt); } foreach (var c in curveList.Values) { AddCurve(pg, c); } DA.SetData(0, new GH_PixelGrid((PixelGrid2D)pg.Clone())); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh m = DA.Fetch <Mesh>("Mesh"); List <Point3d> p = DA.FetchList <Point3d>("Points"); int n = DA.Fetch <int>("Smooth"); int prune = DA.Fetch <int>("Prune"); if (m != null) { DataTree <Line> dt; DataTree <Point3d> naked; var c = NGonsCore.MeshSkeleton.GetCurves(m, p, out dt, out naked); //Smooth foreach (Polyline curve in c) { Point3d start = new Point3d(curve[0]); for (int i = 0; i < n; i++) { curve.Smooth(0.1); if (curve[0].DistanceToSquared(curve.Last()) < 0.001) { curve[0] = start; curve[curve.Count - 1] = start; } } } //Prune List <Polyline> c_ = new List <Polyline>(); foreach (Polyline cc in c) { c_.Add(new Polyline(cc)); } for (int y = 0; y < prune; y++) { List <Line> lines = new List <Line>(); foreach (Polyline cc in c_) { lines.Add(new Line(cc.First(), cc.Last())); } List <Polyline> curves = new List <Polyline>(); Tuple <Point3d[], List <string>, List <int>, List <int>, List <int>, DataTree <int> > data = NGonsCore.Graphs.LineGraph.GetGraphData(lines); for (int i = 0; i < data.Item3.Count; i++) { if (data.Item6.Branch(data.Item3[i]).Count != 1 && data.Item6.Branch(data.Item4[i]).Count != 1) { curves.Add(new Polyline(c_[i])); } } c_ = curves; } //A = curves; DA.SetDataList(0, c_); DA.SetDataTree(1, dt); DA.SetDataTree(2, naked); List <Point3d> ptAll = new List <Point3d>(); ptAll.AddRange(naked.AllData()); foreach (var cc in c_) { ptAll.Add(cc[0]); ptAll.Add(cc[cc.Count - 1]); } foreach (var cc in dt.AllData()) { ptAll.Add(cc.From); ptAll.Add(cc.To); } DA.SetDataList(3, ptAll); } }
protected override void SolveInstance(IGH_DataAccess DA) { try { //////////////////////////////////////////////////////////////////// //Inputs Grasshopper Mesh M = DA.Fetch <Mesh>("Mesh"); DataTree <Polyline> PanelOutlines = DA.FetchTree <GH_Curve>("Panels").ToPolylineDT(); //Create joints DataTree <Vector3d> order = DA.FetchTree <GH_Vector>("InsertionVec").ToVectorDT(); //////////////////////////////////////////////////////////////////// // Insertion vectors //DataTree<Vector3d> EV = M.insertionVectors(Center, EVec); bool Center = DA.Fetch <bool>("Center"); if (order.DataCount == 0) { order = M.insertionVectorsJoints(Center, null);//joints } DataTree <Vector3d> EV = order; //////////////////////////////////////////////////////////////////// List <Point3d> twoJoints = DA.FetchList <Point3d>("TwoJoints"); List <Line> extendedJoints = DA.FetchList <Line>("ExtendedJoints"); List <Line> deeperCutsJoints = DA.FetchList <Line>("DeeperCutsJoints"); List <JointsVDAInputs> joints = GetJoints(order, M, twoJoints, extendedJoints, deeperCutsJoints); if (order.DataCount != 0) { order = M.insertionVectorsJoints(Center, joints);//joints } bool Finger = DA.Fetch <bool>("Finger"); DataTree <Polyline> CChamfer = new DataTree <Polyline>(); int iterations = DA.Fetch <int>("Iterations"); List <int> sequence = DA.FetchList <int>("Sequence"); List <double> textSize = DA.FetchList <double>("TextScale"); if (textSize.Count != 8) { textSize = new List <double> { 30, 12, 15, 0.5, 0.6, 0, 1, 5 } } ; DataTree <Panel> PanelGroups = DA.FetchTree <GH_Curve>("Panels").ToPanelsDT(); DataTree <Panel> JointGroups = new DataTree <Panel>(); //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// int[][] tv = M.GetNGonsTopoBoundaries(); int[][] fe = M.GetNGonFacesEdges(tv); HashSet <int> e = M.GetAllNGonEdges(tv); Dictionary <int, int[]> efDict = M.GetFE(e, false); Point3d[] centers = M.GetNGonCenters(); Vector3d[] fn = M.GetNgonNormals(); //int[][] ef = M.GetNgonsConnectedToNGonsEdges(e, true); //////////////////////////////////////////////////////////////////// DataTree <Polyline> diagonalConnections = new DataTree <Polyline>(); //DataTree<Polyline> recJoints = new DataTree<Polyline>(); //Iterate insertion edges Dictionary <int, int> meshEdgeDict = new Dictionary <int, int>(); for (int i = 0; i < EV.BranchCount; i++) // EV.BranchCount { int meshEdge = EV.Path(i).Indices[0];//mesh edge is used as dataTree branch meshEdgeDict.Add(meshEdge, i); if (efDict[meshEdge].Length != 2) { continue; } int f0 = efDict[meshEdge][0]; int f1 = efDict[meshEdge][1]; //Divide line into points and create a planes on these point, following insertion direction and average face normal // Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(divisions, false); Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(joints[i].divisions, false); Vector3d avNormal = fn[f0] + fn[f1]; //Vector3d jointVector = Vector3d.CrossProduct(M.TopologyEdges.EdgeLine(meshEdge).Direction, avNormal); //EV.Branch(EV.Path(i))[0] = jointVector; for (int j = 0; j < pts.Length; j++) { //(new Line(pts[j], pts[j]+ avNormal*40)).Bake(); //JointGroups.Add(new Panel(new Plane(pts[j], EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge))), EV.Path(i)); Plane plane = new Plane(pts[j], avNormal, EV.Branch(EV.Path(i))[0].UnitVector()); // Plane plane = new Plane(pts[j],EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge)); plane = plane.Switch("YX"); JointGroups.Add(new Panel(plane), EV.Path(i)); //plane.Bake(40); } //Construct joint outlines from planes //Iterate number of joints per edge for (int j = 0; j < pts.Length; j++) { JointGroups.Branch(EV.Path(i))[j].planeOffset0 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(joints[i].thickness * 0.5); //offset planes JointGroups.Branch(EV.Path(i))[j].planeOffset1 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(-joints[i].thickness * 0.5); //offset planes JointGroups.Branch(EV.Path(i))[j].planeRot = new Plane(pts[j], Vector3d.CrossProduct(EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge)), M.GetMeshEdgePerpDir(meshEdge)); int[] ngons = M.GetEdgeNgons(meshEdge); Plane tempPlane = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(joints[i].length); int sign = tempPlane.Origin.DistanceToSquared(centers[ngons[0]]) < tempPlane.Origin.DistanceToSquared(centers[ngons[1]]) ? 1 : -1; JointGroups.Branch(EV.Path(i))[j].planeRotOffset0 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(joints[i].length * sign); //offset planes JointGroups.Branch(EV.Path(i))[j].planeRotOffset1 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(-joints[i].length * sign); //offset plane JointGroups.Branch(EV.Path(i))[j].planeEdge = new Plane(pts[j], M.TopologyEdges.EdgeLine(meshEdge).Direction, M.GetMeshEdgePerpDir(meshEdge)); List <Plane> planesF0 = new List <Plane>(); List <Plane> planesF1 = new List <Plane>(); for (int k = 0; k < PanelGroups.Branch(f0).Count; k++) { planesF0.Add(PanelGroups.Branch(f0)[k].plane); } for (int k = 0; k < PanelGroups.Branch(f1).Count; k++) { planesF1.Add(PanelGroups.Branch(f1)[k].plane); } JointGroups.Branch(EV.Path(i))[j].planeF0 = PlaneUtil.AveragePlaneOrigin(planesF0); JointGroups.Branch(EV.Path(i))[j].planeF1 = PlaneUtil.AveragePlaneOrigin(planesF1); //JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(joints[i].height).Bake(40); //JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(joints[i].height).Bake(40); List <Plane> jointPlaneLoop = new List <Plane> { JointGroups.Branch(EV.Path(i))[j].planeRotOffset0, JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(joints[i].height), JointGroups.Branch(EV.Path(i))[j].planeEdge, JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(joints[i].height), //3 JointGroups.Branch(EV.Path(i))[j].planeRotOffset1, JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(-joints[i].height), //5 JointGroups.Branch(EV.Path(i))[j].planeEdge, JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(-joints[i].height), }; //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20))); //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20))); JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset0, jointPlaneLoop); JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointPlaneLoop); JointGroups.Branch(EV.Path(i))[j].contour[0] = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0]); JointGroups.Branch(EV.Path(i))[j].contour[1] = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1]); //JointGroups.Branch(EV.Path(i))[j].contour[0].Bake(); } //Construct Cuts //Iterate number of joints per edge for (int j = 0; j < pts.Length; j++) { int localMeshEdgeF0 = Array.IndexOf(fe[f0], meshEdge); int localMeshEdgeF1 = Array.IndexOf(fe[f1], meshEdge); //Iterate number of panels and create cuts for (int k = 0; k < PanelGroups.Branch(f0).Count; k++) { Panel jointPanel = JointGroups.Branch(EV.Path(i))[j]; //Rhino.RhinoApp.WriteLine(jointPanel.contourNoJoints[0].Count.ToString()); jointPanel.id = f0.ToString() + "-" + f1.ToString(); if (pts.Length > 1) { jointPanel.id += "-" + j.ToString(); } PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel); //PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel); JointGroups.Branch(EV.Path(i))[j] = jointPanel; } //Iterate number of panels and create cuts for (int k = 0; k < PanelGroups.Branch(f1).Count; k++) { Panel jointPanel = JointGroups.Branch(EV.Path(i))[j]; jointPanel.id = f0.ToString() + "-" + f1.ToString(); if (pts.Length > 1) { jointPanel.id += "-" + j.ToString(); } //PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel); PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel); JointGroups.Branch(EV.Path(i))[j] = jointPanel; } } } for (int i = 0; i < JointGroups.BranchCount; i++) { for (int j = 0; j < JointGroups.Branch(i).Count; j++) { if (joints[i].custom == 0) { if (joints[i].custom > 0) { JointGroups.Branch(i)[j].ChangeJoint(joints[i].custom, 0, joints[i].cutExtend, joints[i].addExtend); } else if (joints[i].custom < 0) { JointGroups.Branch(i)[j].ChangeJoint(joints[i].custom, 1, joints[i].cutExtend, joints[i].addExtend); } } } } ////////////////////////Output var dtPlates = new DataTree <Polyline>(); var dtJoints = new DataTree <Polyline>(); var dtPlatesMid = new DataTree <Polyline>(); var dtJointsMid = new DataTree <Polyline>(); var dtPlatesPlanes = new DataTree <Plane>(); var dtJointsPlanes = new DataTree <Plane>(); var dtPlatesTxt = new DataTree <Curve>(); var dtJointsTxt = new DataTree <Curve>(); var dtPlatesLast = new DataTree <Polyline>(); var dtJointsLast = new DataTree <Polyline>(); var dtPlatesMidLast = new DataTree <Polyline>(); var dtJointsMidLast = new DataTree <Polyline>(); var dtPlatesPlanesLast = new DataTree <Plane>(); var dtJointsPlanesLast = new DataTree <Plane>(); var dtPlatesTxtLast = new DataTree <Curve>(); var dtJointsTxtLast = new DataTree <Curve>(); HashSet <int> jointSequenceTemp = new HashSet <int>(); HashSet <int> jointSequence = new HashSet <int>(); HashSet <int> jointSequenceLast = new HashSet <int>(); int last = Math.Min(iterations, PanelGroups.BranchCount); int prev = Math.Max(0, last - (int)textSize[6]); for (int i = 0; i < last; i++) //Math.Min(iterations, sequence.Count) PanelGroups.BranchCount { for (int j = 0; j < fe[i].Length; j++) { bool seq = jointSequenceTemp.Add(fe[i][j]); if (i >= prev) { if (seq) { jointSequenceLast.Add(fe[i][j]); } else { jointSequence.Add(fe[i][j]); } } else { jointSequence.Add(fe[i][j]); } } for (int j = 0; j < PanelGroups.Branch(i).Count; j++) { if (i >= prev) { dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j)); dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j)); dtPlatesMidLast.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); } else { dtPlates.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j)); dtPlates.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j)); dtPlatesMid.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); } Plane textPlane = PanelGroups.Branch(i)[j].planeOffset0; textPlane.Flip(); if (j > 0) { textPlane = PanelGroups.Branch(i)[j].planeOffset1; } if (i >= prev) { dtPlatesPlanesLast.Add(textPlane, new GH_Path(i, j)); } else { dtPlatesPlanes.Add(textPlane, new GH_Path(i, j)); } string text = i.ToString() + "-" + j.ToString(); var txtCrv = Typewriter.Regular.Write(text, textPlane, textSize[0]); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrv, new GH_Path(i, j)); } else { dtPlatesTxt.AddRange(txtCrv, new GH_Path(i, j)); } var a = PanelGroups.Branch(i)[j]; Line[] segments = PanelGroups.Branch(i)[j].contourNoJoints[Math.Min(1, j)].GetSegments(); int counter = 0; foreach (Line l in segments) { int meshEdge = fe[i][counter]; int neiF = M.GetOppositeNgon(meshEdge, i); //Adjacent face plane Point3d origin = l.PointAt(textSize[3]); Vector3d xaxis = l.Direction; Vector3d yaxis = l.Direction; origin.Transform(Rhino.Geometry.Transform.Scale(textPlane.Origin, textSize[4])); yaxis.Rotate(Math.PI * 0.5, textPlane.ZAxis); Plane ePlane = new Plane(origin, xaxis, yaxis); var txtCrvF = Typewriter.Regular.Write(neiF.ToString(), ePlane, textSize[2]); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF, new GH_Path(i, j)); } else { dtPlatesTxt.AddRange(txtCrvF, new GH_Path(i, j)); } //Mesh edge direction Line meshEdgeLine = M.TopologyEdges.EdgeLine(meshEdge); meshEdgeLine.Transform(Rhino.Geometry.Transform.Scale(meshEdgeLine.PointAt(0.5), textSize[4])); meshEdgeLine.Transform(Rhino.Geometry.Transform.Scale(textPlane.Origin, textSize[4])); //meshEdgeLine.Extend(-textSize[4], -textSize[4]); Plane e0Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.From), xaxis, yaxis); Plane e1Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.To), xaxis, yaxis); var txtCrvF0 = Typewriter.Regular.Write("I", e0Plane, textSize[2]); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF0, new GH_Path(i, j)); } else { dtPlatesTxt.AddRange(txtCrvF0, new GH_Path(i, j)); } var txtCrvF1 = Typewriter.Regular.Write("II", e1Plane, textSize[2]); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF1, new GH_Path(i, j)); } else { dtPlatesTxt.AddRange(txtCrvF1, new GH_Path(i, j)); } counter++; // } } } DataTree <Vector3d> insertionVectors = new DataTree <Vector3d>(); foreach (int meshEdge in jointSequence) { if (!meshEdgeDict.ContainsKey(meshEdge)) { continue; } int i = meshEdgeDict[meshEdge]; for (int j = 0; j < JointGroups.Branch(i).Count; j++) { GH_Path path = new GH_Path(meshEdge, j); insertionVectors.Add(JointGroups.Branch(i)[j].planeOffset0.XAxis, path); dtJoints.Add(JointGroups.Branch(i)[j].contour[0], path); dtJoints.Add(JointGroups.Branch(i)[j].contour[1], path); dtJointsMid.Add(JointGroups.Branch(i)[j].MidContour(), path); dtJointsPlanes.Add(JointGroups.Branch(i)[j].planeOffset0, path); Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis); string text = JointGroups.Branch(i)[j].id; var txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]); dtJointsTxt.AddRange(txtCrv, path); } } foreach (int meshEdge in jointSequenceLast) { if (!meshEdgeDict.ContainsKey(meshEdge)) { continue; } int i = meshEdgeDict[meshEdge]; for (int j = 0; j < JointGroups.Branch(i).Count; j++) { dtJointsLast.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j)); dtJointsLast.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j)); dtJointsMidLast.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(meshEdge, j)); dtJointsPlanesLast.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j)); Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis); string text = JointGroups.Branch(i)[j].id; var txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]); dtJointsTxtLast.AddRange(txtCrv, new GH_Path(meshEdge, j)); } } DA.SetDataTree(0, dtPlates); DA.SetDataTree(1, dtJoints); DA.SetDataTree(2, dtPlatesMid); DA.SetDataTree(3, dtJointsMid); DA.SetDataTree(4, dtPlatesPlanes); DA.SetDataTree(5, dtJointsPlanes); DA.SetDataTree(6, dtPlatesTxt); DA.SetDataTree(7, dtJointsTxt); DA.SetDataTree(8, dtPlatesLast); DA.SetDataTree(9, dtJointsLast); DA.SetDataTree(10, dtPlatesMidLast); DA.SetDataTree(11, dtJointsMidLast); DA.SetDataTree(12, dtPlatesPlanesLast); DA.SetDataTree(13, dtJointsPlanesLast); DA.SetDataTree(14, dtPlatesTxtLast); DA.SetDataTree(15, dtJointsTxtLast); } catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } }
/// <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> /// 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) { // SET ALL INPUT PARAMETERS List<Curve> curves = DA.FetchList<Curve>("Polylines"); double dist = DA.Fetch<double>("Distance"); Plane pln = DA.Fetch<Plane>("Plane"); double tolerance = DA.Fetch<double>("Tolerance"); List<Polyline3D.OpenFilletType> openType = DA.FetchList<int>("OpenFillet").Cast<Polyline3D.OpenFilletType>().ToList(); if (openType == null || openType.Count == 0) { openType = new List<Polyline3D.OpenFilletType> { Polyline3D.OpenFilletType.Square }; } double miter = DA.Fetch<double> ("Miter"); List<Polyline3D.ClosedFilletType> closedType = DA.FetchList<int>("ClosedFillet").Cast<Polyline3D.ClosedFilletType>().ToList(); IEnumerable<Polyline> polylines = Polyline3D.ConvertCurvesToPolyline(curves); if (pln.Equals(default(Plane))) { pln = polylines.First().FitPlane(); } // set default fillet type. if (closedType == null || closedType.Count == 0) { closedType = new List<Polyline3D.ClosedFilletType> { Polyline3D.ClosedFilletType.Square }; } if (curves.Count == 0) { return; } List<List<Polyline>> outside; List<List<Polyline>> holes; Polyline3D.Offset(polylines, openType, closedType, pln, tolerance, new List<double> { dist }, miter, 0.25, out outside, out holes); // OUTPUT LOGIC DA.SetDataList("Contour", outside.First()); DA.SetDataList("Holes", holes.First()); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh M = DA.Fetch <Mesh>("Mesh"); double A = DA.Fetch <double>("Angle"); double S = DA.Fetch <double>("Scale"); bool N = DA.Fetch <bool>("NormalType"); double D = DA.Fetch <double>("Height"); double O = DA.Fetch <double>("Offset"); double W1 = DA.Fetch <double>("W1"); double W2 = DA.Fetch <double>("W2"); double T = DA.Fetch <double>("Thickness"); Surface RS = DA.Fetch <Surface>("RoofSurface"); List <Curve> JointMale = DA.FetchList <Curve>("JointMale"); List <Curve> JointFemale = DA.FetchList <Curve>("JointFemale"); JointReciprocal jm = new JointReciprocal(JointMale); JointReciprocal jf = new JointReciprocal(JointFemale); int[][] tv = M.GetNGonsTopoBoundaries(); HashSet <int> ehash = M.GetAllNGonEdges(tv); int[] e = ehash.ToArray(); int[][] ef = M.GetNgonsConnectedToNGonsEdges(ehash, false); Plane[] planes = M.GetNgonPlanes(); Dictionary <int, int> eDict = new Dictionary <int, int>(); int[][] fe = M.GetNGonFacesEdges(tv); int i = 0; foreach (int meshedge in ehash) { eDict.Add(meshedge, i++); } int[][] fe_ = new int[fe.Length][]; int[][] fe_0 = new int[fe.Length][]; for (i = 0; i < fe.Length; i++) { fe_[i] = new int[fe[i].Length]; fe_0[i] = new int[fe[i].Length]; for (int j = 0; j < fe[i].Length; j++) { fe_[i][j] = eDict[fe[i][MathUtil.Wrap((j - 1), fe[i].Length)]]; } for (int j = 0; j < fe[i].Length; j++) { fe_0[i][j] = eDict[fe[i][MathUtil.Wrap((j + 0), fe[i].Length)]]; } } List <Vector3d> vecs = new List <Vector3d>(); i = 0; foreach (int n in e) { int[] edgeFaces = ef[i]; Vector3d vec = Vector3d.Zero; if (N) { for (int j = 0; j < edgeFaces.Length; j++) { vec += planes[edgeFaces[j]].ZAxis; } vec /= edgeFaces.Length; base.Message = "Average"; } else { int[] triangleFaces = M.TopologyEdges.GetConnectedFaces(n); for (int j = 0; j < triangleFaces.Length; j++) { vec += M.FaceNormals[triangleFaces[j]]; } vec /= triangleFaces.Length; base.Message = "Face"; } vecs.Add(vec); i++; } Line[] lines = M.GetAllNGonEdgesLines(ehash); //List<Line> ln = new List<Line>(); for (int j = 0; j < lines.Length; j++) { //Line l = lines[j]; lines[j].Transform(Rhino.Geometry.Transform.Scale(lines[j].PointAt(0.5), S)); lines[j].Transform(Rhino.Geometry.Transform.Rotation(A, vecs[j], lines[j].PointAt(0.5))); } //2nd part extend Plane[] linePlanes = new Plane[lines.Length]; for (i = 0; i < lines.Length; i++) { linePlanes[i] = new Plane(lines[i].PointAt(0.5), lines[i].Direction, vecs[i]); } Plane[][] endPlanes = new Plane[0][]; Line[] cutLines = new Line[0]; int[][] neighbours = new int[0][]; DA.SetDataList(1, GetLines(lines, linePlanes, fe_, out endPlanes, out neighbours, out cutLines, D)); DA.SetDataList(2, GetLines(lines, linePlanes, fe_, out endPlanes, out neighbours, out cutLines, -D)); DA.SetDataList(0, GetLines(lines, linePlanes, fe_, out endPlanes, out neighbours, out cutLines)); DA.SetDataList(3, linePlanes); DA.SetDataTree(4, NGonsCore.GrasshopperUtil.IE2(endPlanes)); DA.SetDataTree(5, NGonsCore.GrasshopperUtil.IE2(fe_)); DA.SetDataTree(6, NGonsCore.GrasshopperUtil.IE2(FaceOutlines(M, planes, linePlanes, fe_, fe, O, T, cutLines, eDict, RS))); DA.SetDataList(7, cutLines); //DA.SetDataTree(2, NGonsCore.GrasshopperUtil.IE2(fe_0)); //DA.SetDataList(3, vecs); //Get Support Structure Plane[] ep0 = null; Plane[] ep1 = null; Plane[] lp2 = null; Plane[] lp3 = null; Polyline[][] supportStructure = GetSupportStructure(M, W1, W2, planes, linePlanes, endPlanes, fe_0, fe, RS, eDict, ref ep0, ref ep1, ref lp2, ref lp3); DA.SetDataTree(8, NGonsCore.GrasshopperUtil.IE2(supportStructure)); DA.SetDataList(9, ep0); DA.SetDataList(10, ep1); DA.SetDataList(11, lp2); DA.SetDataList(12, lp3); //DA.SetDataTree(11, NGonsCore.GrasshopperUtil.IE2(neighbours)); //Orient joints var elements = new ElementReciprocal[e.Length]; for (i = 0; i < e.Length; i++) { elements[i] = new ElementReciprocal(supportStructure[i]); elements[i]._joints = new JointReciprocal[] { jm.OrientCopy(Plane.WorldXY, ep0[i]), jm.OrientCopy(Plane.WorldXY, ep1[i]) }; elements[i]._jointsFemale = new JointReciprocal[] { jf.OrientCopy(Plane.WorldXY, ep0[i]), jf.OrientCopy(Plane.WorldXY, ep1[i]) }; } //orient holes for (i = 0; i < neighbours.Length; i++) { for (int j = 0; j < neighbours[i].Length; j++) { elements[neighbours[i][j]]._jointsNei.Add(elements[i]._jointsFemale[j]); } } DA.SetDataTree(13, NGonsCore.GrasshopperUtil.IE3(elements.GetJointsGeo())); //DA.SetDataTree(12, NGonsCore.GrasshopperUtil.IE2(jointsMortise)); }
protected override void SolveInstance(IGH_DataAccess DA) { try { Mesh M = DA.Fetch <Mesh>("Mesh"); double D = DA.Fetch <double>("Offset"); int T = DA.Fetch <int>("Type"); double W = DA.Fetch <double>("Dist2"); double Tol = DA.Fetch <double>("Tol"); var mid = DA.FetchList <int>("Custom"); bool P = true; Polyline[] p0; Polyline[] p1; DataTree <Polyline> dt = new DataTree <Polyline>(); DataTree <Polyline> dtThickness = new DataTree <Polyline>(); if (D == 0) { switch (T) { case (1): base.Message = "No Offset \n Projection"; //output dt = new DataTree <Polyline>(); var polygons = M.ProjectedPolylinesToAveragePlane(P); for (int i = 0; i < M.Ngons.Count; i++) { dt.Add(polygons[i], new GH_Path(DA.Iteration, i)); } break; default: base.Message = "No Offset \n FaceEdgeBisector"; //Get edge planes and corner bisectors *----*----* Plane[][] bisePlanes; Plane[][] edgePlanes; M.GetEdgeAndBisectorPlanes(out bisePlanes, out edgePlanes); dt = new DataTree <Polyline>(); //Get Outlines p0 = M.GetPolylines(); for (int i = 0; i < M.Ngons.Count; i++) { Plane plane = p0[i].GetPlane(P); dt.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); if (W > 0) { plane = plane.MovePlanebyAxis(-W * 0.5); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(W); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(-W * 0.5); } } break; } DA.SetDataList(0, new Mesh[] { M }); } else { //Offset two meshes in both sides Mesh m0 = M.DuplicateMesh(); Mesh m1 = M.DuplicateMesh(); m0 = m0.Offset(D * 0.5); m1 = m1.Offset(-D * 0.5); switch (T) { case (1): //case (2): base.Message = "Offset \n Projection"; //output Mesh mA = M.DuplicateMesh(); Mesh mB = M.DuplicateMesh(); Mesh mC = M.DuplicateMesh(); Mesh mD = M.DuplicateMesh(); Mesh mA_ = M.DuplicateMesh(); Mesh mB_ = M.DuplicateMesh(); Mesh mE = M.DuplicateMesh(); Mesh mF = M.DuplicateMesh(); mA = mA.Offset(-D * 0.5 + W * 0.5); mB = mB.Offset(-D * 0.5 - W * 0.5); mC = mC.Offset(D * 0.5 + W * 0.5); mD = mD.Offset(D * 0.5 - W * 0.5); mA_ = mA_.Offset(-D * 0.5); mB_ = mB_.Offset(D * 0.5); mE = mE.Offset(W * 0.5); mF = mF.Offset(-W * 0.5); dtThickness = new DataTree <Polyline>(); dt = new DataTree <Polyline>(); //Rhino.RhinoApp.WriteLine("Hi"); var a = mA.ProjectedPolylinesToAveragePlane(P); var b = mB.ProjectedPolylinesToAveragePlane(P); var c = mC.ProjectedPolylinesToAveragePlane(P); var d = mD.ProjectedPolylinesToAveragePlane(P); var a_ = mA_.ProjectedPolylinesToAveragePlane(P); var b_ = mB_.ProjectedPolylinesToAveragePlane(P); var e = mE.ProjectedPolylinesToAveragePlane(P); var f = mF.ProjectedPolylinesToAveragePlane(P); for (int i = 0; i < a.Length; i++) { dtThickness.Add(a[i], new GH_Path(DA.Iteration, i)); dtThickness.Add(b[i], new GH_Path(DA.Iteration, i)); if (mid.Contains(i)) { dtThickness.Add(e[i], new GH_Path(DA.Iteration, i)); dtThickness.Add(f[i], new GH_Path(DA.Iteration, i)); } dtThickness.Add(c[i], new GH_Path(DA.Iteration, i)); dtThickness.Add(d[i], new GH_Path(DA.Iteration, i)); dt.Add(a_[i], new GH_Path(DA.Iteration, i)); dt.Add(b_[i], new GH_Path(DA.Iteration, i)); } break; default: base.Message = "Offset \n FaceEdgeBisector"; //Get edge planes and corner bisectors *----*----* Plane[][] bisePlanes; Plane[][] edgePlanes; M.GetEdgeAndBisectorPlanes(out bisePlanes, out edgePlanes); DataTree <Plane> pls = new DataTree <Plane>(); for (int i = 0; i < bisePlanes.Length; i++) { pls.AddRange(bisePlanes[i], new GH_Path(DA.Iteration, 0, i)); pls.AddRange(edgePlanes[i], new GH_Path(DA.Iteration, 1, i)); } //EdgePlanes = pls; DA.SetDataTree(3, pls); dt = new DataTree <Polyline>(); dtThickness = new DataTree <Polyline>(); //Get Outlines p0 = M.GetPolylines(); p1 = M.GetPolylines(); for (int i = 0; i < M.Ngons.Count; i++) { Plane plane = p0[i].GetPlane(P); plane = plane.MovePlanebyAxis(D * 0.5); dt.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); if (W > 0) { plane = plane.MovePlanebyAxis(-W * 0.5); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(W); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(-W * 0.5); } plane = plane.MovePlanebyAxis(-D); dt.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); if (W > 0) { plane = plane.MovePlanebyAxis(-W * 0.5); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(W); dtThickness.Add(PolylineUtil.OutlineFromFaceEdgeCorner(plane, edgePlanes[i], bisePlanes[i], T, Tol), new GH_Path(DA.Iteration, i)); plane = plane.MovePlanebyAxis(-W * 0.5); } } break; } //Output //OffsetMesh = new Mesh[] { m0, m1 }; this.PreparePreview(m0, DA.Iteration, dt.AllData(), false); DA.SetDataList(0, new Mesh[] { m0, m1 }); } DA.SetDataTree(1, dt); DA.SetDataTree(2, dtThickness); //ProjectedPolylines = dt; //Thickness = dtThickness; }catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = DA.Fetch <Mesh>("Mesh"); string v = DA.Fetch <string>("Start"); List <int> o = DA.FetchList <int>("Sequence"); v = Math.Min(Convert.ToInt32(v), mesh.Ngons.Count - 1).ToString(); var ve = NGonsCore.Graphs.UndirectedGraphBfsRhino.MeshBFS(mesh, v); List <int> order = ve.Item1[0]; DA.SetDataTree(0, NGonsCore.GrasshopperUtil.IE2(ve.Item1)); DA.SetDataTree(1, NGonsCore.GrasshopperUtil.IE3(ve.Item2)); if (mesh.Ngons.Count == o.Count) { order = o; } int S = mesh.Ngons.Count;//stop //Insertion vectors DataTree <int> N = SequenceNeighbours(mesh, order, S); //FN = N; //O_ = O; //Edge Vectors int[][] tv = mesh.GetNGonsTopoBoundaries(); int[][] fe = mesh.GetNGonFacesEdges(tv); HashSet <int> e = mesh.GetAllNGonEdges(tv); Dictionary <int, int[]> efDict = mesh.GetFE(e, false); Polyline[] outlines = mesh.GetPolylines(); //Dictionary<int, Vector3d> edgeVectors = new Dictionary<int, Vector3d> (); DataTree <Vector3d> edgeVectors = new DataTree <Vector3d>(); for (int i = 0; (i < S && i < mesh.Ngons.Count); i++) { ///////////// // Properties ///////////// //Current path and face GH_Path p = new GH_Path(i); int f = order[i];//O[i]; if (!N.PathExists(p)) { continue; //If no connectio nskip } HashSet <int> fadj = new HashSet <int>(N.Branch(p)); //adjacency list ///////////// // Solution ///////////// //Iterate mesh edges //Get connected faces //Check if they are in adjacency list //The order thoses ids List <int> NotOrderedEdges = new List <int>(); for (int j = 0; j < fe[f].Length; j++) { int[] facePair = efDict[fe[f][j]];//get face pair if (facePair.Length == 1) { continue; //if naked skip } if (fadj.Contains(facePair[0]) || fadj.Contains(facePair[1])) { NotOrderedEdges.Add(j); //if edge face are in fadj } } List <int> orderedEdges = SortIntegers(NotOrderedEdges, fe[f].Length); //Collect lines for Insertion Vector List <Line> el = new List <Line>(); //Line[] lines = outlines[f].GetSegments(); foreach (int j in orderedEdges) { el.Add(outlines[f].SegmentAt(j));//el.Add(M.TopologyEdges.EdgeLine(fe[f][j])); } //Create Insertion Vector Vector3d vec = NGonsCore.VectorUtil.BisectorVector(el, outlines[f].AverageNormal(), false); foreach (int j in orderedEdges) { //edgeVectors.Add(fe[f][j],vec); edgeVectors.Add(vec, new GH_Path(fe[f][j])); } //A = el; //B = vec; //C = outlines[f].AverageNormal(); } //EV = edgeVectors; DA.SetDataTree(2, edgeVectors); //Get current face edges //Take edge only connected in current set }
/// <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) { // SET ALL INPUT PARAMETERS List<Curve> A = DA.FetchList<Curve>("A"); List<Curve> B = DA.FetchList<Curve>("B"); try { ClipType type = (ClipType)DA.Fetch<int>("BooleanType"); Plane pln = DA.Fetch<Plane>("Plane"); double tolerance = DA.Fetch<double>("Tolerance"); // Convert the curves to polylines // This is a crude way of doing this. // Should we add some parameters for this perhaps? IEnumerable<Polyline> APl = Polyline3D.ConvertCurvesToPolyline(A); IEnumerable<Polyline> BPl = Polyline3D.ConvertCurvesToPolyline(B); // If we don't have a plane, let's try to create a plane from the first curve. if (pln.Equals(default(Plane)) || !pln.IsValid) { pln = APl.First().FitPlane(); } List<Polyline> result = new List<Polyline>(); // do the boolean operation result = Polyline3D.Boolean(type, APl, BPl, pln, tolerance, EvenOdd); // OUTPUT LOGIC DA.SetDataList("Result", result); } catch (Exception e) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message + ": " + e.StackTrace.ToString()); } }
/// <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) { #region updateInputs //if (!cap && this.Params.Input.Count ==7) //{ // this.Params.Input[5].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[5]); // this.Params.Input[6].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[6]); // Params.OnParametersChanged(); //} //if (cap && this.Params.Input.Count == 5) //{ // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MinColor", // NickName = "MinColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MaxColor", // NickName = "MaxColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // Params.OnParametersChanged(); //} #endregion updateInputs //bool caps = DA.Fetch<bool>("Cap"); Color?maxColor = DA.Fetch <Color?>(i_inputSelecterMax); Color?minColor = DA.Fetch <Color?>(i_inputSelectorMin); var allResults = DA.FetchTree <GH_Number>("Results"); var grids = DA.FetchList <Grid>("Grids"); //var gradientRange = DA.Fetch<string>("GradientRange"); //int maxCount = DA.Fetch<int>("MaxCount"); int maxCount = 200; //var inStepSize = DA.Fetch<int>("StepSize"); //var inSteps = DA.Fetch<int>("Steps"); InputSelector inputSelector = DA.Fetch <InputSelector>("_Section Type"); double globalMin = double.MaxValue; double globalMax = double.MinValue; for (int g = 0; g < grids.Count; g++) { globalMin = Math.Min(globalMin, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Min()); globalMax = Math.Max(globalMax, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Max()); } if (inputSelector == null) { inputSelector = new InputSelector(10, globalMin, globalMax); } if (allResults.Branches.Count != grids.Count) { throw new Exception("Grid count doesnt match results"); } //var colorDomain = Misc.AutoDomain(gradientRange, allResults); //Rhino.RhinoApp.WriteLine($"{range} -> {domain[0]} to {domain[1]}"); GH_GradientControl gc; try { gc = (GH_GradientControl)Params.Input[i_inputGradient].Sources[0].Attributes.GetTopLevel.DocObject; } catch (System.ArgumentOutOfRangeException) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Remember to add a gradient component in grasshopper!"); gc = null; } GradientParser gp = new GradientParser(gc) { //Cap = caps, AboveMax = maxColor == default(Color) ? null : maxColor, BelowMin = minColor == default(Color) ? null : minColor, //Min = domain[0], //Max = domain[1], Reverse = Params.Input[i_inputGradient].Reverse }; IDictionary <string, Color> colorDescriptions = new Dictionary <string, Color>(); IDictionary <string, int> colorPaths = new Dictionary <string, int>(); #region coloredMesh var outMeshes = new List <Mesh>(); for (int i = 0; i < grids.Count; i++) { //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Mesh vertices: {grids[i].SimMesh.Vertices.Count}, colors = {gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()).Length} f"); outMeshes.Add(grids[i].GetColoredMesh(gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()))); Mesh m = grids[i].SimMesh; Point3d[] points = grids[i].SimPoints.ToArray(); outMeshes[outMeshes.Count - 1].Translate(0, 0, Units.ConvertFromMeter(0.001)); } DA.SetDataList(0, outMeshes); #endregion coloredMesh #region layeredMesh if (grids[0].UseCenters == true) { return; } //Outputs GH_Structure <GH_Mesh> oLayeredMeshes = new GH_Structure <GH_Mesh>(); List <GH_Mesh> previewMeshes = new List <GH_Mesh>(); List <GH_Plane> outPlanes = new List <GH_Plane>(); GH_Structure <GH_Curve> outCurves = new GH_Structure <GH_Curve>(); GH_Structure <GH_String> outValues = new GH_Structure <GH_String>(); GH_Structure <GH_Colour> outColors = new GH_Structure <GH_Colour>(); const double SCALAR = 1; // don't change. if (((GH_Structure <GH_Number>)gc.Params.Input[1].VolatileData)[0][0].Value == 1) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "The gradient connected has 1 as max. Is that on purpose? Check the inputs of your gradient component." + $"\nI suggest you set your max somewhere around {globalMax:0.0}"); } for (int g = 0; g < grids.Count; g++) { //GH_Structure<GH_Curve> curves = new GH_Structure<GH_Curve>(); Grid grid = grids[g]; Mesh inputMesh = grids[g].SimMesh.DuplicateMesh(); //Mesh meshToCut = grids[g].SimMesh; List <double> results = ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).ToList(); if (grids[g].UseCenters == true) { results = RTreeSolver.FindClosestWeightedValues(grids[g], results, true).ToList(); // ADD CONVERSION TODO: } inputMesh.Normals.ComputeNormals(); Vector3f normal = inputMesh.FaceNormals[0]; Plane basePlane = new Plane(inputMesh.Vertices[0], normal); Transform ProjectToBase = Transform.PlanarProjection(basePlane); Plane cuttingPlane = new Plane(basePlane); Mesh meshToCut = CreateMeshToBeCut(SCALAR, inputMesh, results, cuttingPlane); previewMeshes.Add(new GH_Mesh(inputMesh)); MeshingParameters mp = new MeshingParameters(0); List <Mesh> layeredMeshesThisGrid = new List <Mesh>(); double valueForSmallAreas = double.MinValue; double resultsMin = results.Min(); foreach (var item in inputSelector) { if (resultsMin >= item) { valueForSmallAreas = item; break; } } //Color col = gp.GetColors(new List<double>() { inputSelector.Min.Value })[0]; Color col = gp.GetColors(new List <double>() { gp.BelowMin.HasValue&& inputSelector.Min.Value <= gp.Min ? resultsMin > gp.Min ? valueForSmallAreas : double.MinValue : inputSelector.Min.Value })[0]; Polyline[] outlinePolylines = inputMesh.GetNakedEdges(); PolylineCurve[] curvesFromOutline = new PolylineCurve[outlinePolylines.Length]; for (int i = 0; i < outlinePolylines.Length; i++) { curvesFromOutline[i] = new PolylineCurve(outlinePolylines[i]); curvesFromOutline[i].Transform(ProjectToBase); } Mesh meshFromCurves = GetMeshFromCurves(curvesFromOutline, mp, in col); GH_Path startPath = new GH_Path(g, -1); oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), startPath); string lessThanKey = gp.BelowMin.HasValue && inputSelector.Min.Value < gp.Min ? $"<{gp.Min:0.0}" : $"<{inputSelector.Min.Value:0.0}"; if (!colorDescriptions.ContainsKey(lessThanKey) && inputSelector.First() < gp.Min) { colorDescriptions.Add(lessThanKey, col); colorPaths.Add(lessThanKey, -1); } ////outColors.Append(new GH_Colour(col), startPath); ////outValues.Append(new GH_Number(double.MinValue), startPath); //Mesh[] meshesFromCurves = GetMeshesFromCurves(curvesFromOutline, mp, in col); //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), new GH_Path(g, -1)); int cuttingCount = 0; double previousValue = 0; foreach (double currentValue in inputSelector) { if (cuttingCount > maxCount) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Too many steps... I reached {maxCount} and then stopped"); break; } if (gp.BelowMin.HasValue && currentValue < gp.Min) { continue; } if (currentValue > results.Max()) { break; } // Create planes Vector3f moveUpVector = normal * (float)((currentValue - previousValue) * SCALAR); Transform t = Transform.Translation(moveUpVector); GH_Path path = new GH_Path(g, cuttingCount); cuttingPlane.Transform(t); outPlanes.Add(new GH_Plane(cuttingPlane)); // Create boundary intersected curves Curve[] intersectedCurves = GetIntersectedCurves(inputMesh, cuttingPlane); if (intersectedCurves != null) { outCurves.AppendRange(intersectedCurves.Select(c => new GH_Curve(c.DuplicateCurve())), path); foreach (var curve in intersectedCurves) { curve.Transform(ProjectToBase); } // Create meshes col = gp.GetColors(new List <double>() { currentValue })[0]; meshFromCurves = GetMeshFromCurves(intersectedCurves, mp, in col); meshFromCurves.Transform(Transform.Translation(0, 0, (cuttingCount + 1) * Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 12.0)); if (meshFromCurves != null) { //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), path); oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), path); string key = currentValue >= gp.Max.Value ? $">{currentValue:0.0}" : $"{currentValue:0.0}"; if (!colorDescriptions.ContainsKey(key)) { colorDescriptions.Add(key, col); colorPaths.Add(key, cuttingCount); } } if (currentValue >= gp.Max.Value) { break; } } previousValue = currentValue; cuttingCount++; } } foreach (KeyValuePair <string, Color> valuePair in colorDescriptions) { GH_Path path = new GH_Path(colorPaths[valuePair.Key]); outColors.Append(new GH_Colour(valuePair.Value), path); outValues.Append(new GH_String(valuePair.Key), path); } DA.SetDataTree(1, oLayeredMeshes); DA.SetDataTree(2, outCurves); DA.SetDataList("Planes", outPlanes); DA.SetDataList("TempMeshes", previewMeshes); DA.SetDataTree(6, outValues); DA.SetDataTree(5, outColors); #endregion layeredMesh }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh m = DA.Fetch <Mesh>("Mesh"); bool fixEdges = DA.Fetch <bool>("FixEdges"); double l = DA.Fetch <double>("EdgeLength"); int iterations = DA.Fetch <int>("Iterations"); List <Point3d> fixPt = DA.FetchList <Point3d>("FixPt"); bool project = DA.Fetch <bool>("Project"); bool loops = DA.Fetch <bool>("Loops"); Mesh mesh = m.DuplicateMesh(); mesh.Faces.ConvertQuadsToTriangles(); double len = (l == 0) ? mesh.GetBoundingBox(false).Diagonal.Length * 0.1 : l; //r.PreventNormalFlips = true; List <int> ids = new List <int>(); Point3d[] pts = mesh.Vertices.ToPoint3dArray(); foreach (Point3d p in fixPt) { ids.Add(NGonsCore.PointUtil.ClosestPoint(p, pts)); } DMesh3 dmesh = mesh.ToDMesh3(); Remesher r = new Remesher(dmesh); r.Precompute(); r.SetTargetEdgeLength(len); r.SmoothSpeedT = 0.5; if (project) { r.SetProjectionTarget(MeshProjectionTarget.Auto(dmesh)); } r.EnableFlips = r.EnableSplits = r.EnableCollapses = true; r.EnableSmoothing = true; MeshConstraints cons = new MeshConstraints(); if (ids.Count > 0) { foreach (int id in ids) { //cons.SetOrUpdateVertexConstraint(id, new VertexConstraint(true, 1)); cons.SetOrUpdateVertexConstraint(id, VertexConstraint.Pinned); } } r.SetExternalConstraints(cons); r.Precompute(); if (fixEdges) { //r.SetExternalConstraints(new MeshConstraints()); MeshConstraintUtil.FixAllBoundaryEdges(r); MeshConstraintUtil.FixAllBoundaryEdges_AllowSplit(cons, dmesh, 0); //MeshConstraintUtil.FixAllBoundaryEdges_AllowCollapse(cons, dmesh, 0); } if (loops) { MeshConstraintUtil.PreserveBoundaryLoops(r); //project to edge //MeshConstraintUtil.PreserveBoundaryLoops(cons,dmesh);//project to edge } r.SetExternalConstraints(cons); for (int k = 0; k < iterations; ++k) { r.BasicRemeshPass(); } //output if (ids.Count > 0 && !fixEdges) { this.Message = "Vertices"; } else if (ids.Count == 0 && fixEdges) { this.Message = "Edges"; } else if (ids.Count > 0 && fixEdges) { this.Message = "Vertices + Edges"; } else { this.Message = ""; } dmesh = new DMesh3(dmesh, true); Mesh rmesh = dmesh.ToRhinoMesh(); if (loops) { Mesh mesh_ = rmesh.DuplicateMesh(); Rhino.IndexPair[] closestEdges = new Rhino.IndexPair[fixPt.Count]; int counter = 0; foreach (Point3d p in fixPt) { double[] d = new double[rmesh.TopologyEdges.Count]; int[] eid = new int[rmesh.TopologyEdges.Count]; for (int i = 0; i < rmesh.TopologyEdges.Count; i++) { if (rmesh.TopologyEdges.GetConnectedFaces(i).Length == 1) { Line line = rmesh.TopologyEdges.EdgeLine(i); line.ClosestPoint(p, true); d[i] = line.ClosestPoint(p, true).DistanceToSquared(p); //line.From.DistanceToSquared(p) + line.To.DistanceToSquared(p); } else { d[i] = 99999; } eid[i] = i; } Array.Sort(d, eid); closestEdges[counter++] = rmesh.TopologyEdges.GetTopologyVertices(eid[0]); } for (int i = 0; i < fixPt.Count; i++) { mesh_.Vertices.Add(fixPt[i]); mesh_.Faces.AddFace(rmesh.Vertices.Count + i, closestEdges[i].I, closestEdges[i].J); } rmesh = mesh_; } rmesh.UnifyNormals(); rmesh.RebuildNormals(); // rmesh.UnifyNormals(); DA.SetData(0, rmesh); }
/// <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) { #region updateInputs //if (!cap && this.Params.Input.Count ==7) //{ // this.Params.Input[5].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[5]); // this.Params.Input[6].RemoveAllSources(); // this.Params.UnregisterInputParameter(this.Params.Input[6]); // Params.OnParametersChanged(); //} //if (cap && this.Params.Input.Count == 5) //{ // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MinColor", // NickName = "MinColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // this.Params.RegisterInputParam(new Param_Colour // { // Name = "MaxColor", // NickName = "MaxColor", // Description = "MinColor", // Access = GH_ParamAccess.item, // Optional = true // }); // Params.OnParametersChanged(); //} #endregion updateInputs //bool caps = DA.Fetch<bool>("Cap"); var maxColor = DA.Fetch <Color>(inputSelecterMax); var minColor = DA.Fetch <Color>(inputSelectorMin); var allResults = DA.FetchTree <GH_Number>("Results"); var grids = DA.FetchList <Grid>("Grids"); var range = DA.Fetch <string>("Range"); var inStepSize = DA.Fetch <int>("StepSize"); var inSteps = DA.Fetch <int>("Steps"); if (allResults.Branches.Count != grids.Count) { throw new Exception("Grid count doesnt match results"); } if (!caps) { this.Params.Input[inputSelectorMin].NickName = "-"; this.Params.Input[inputSelectorMin].Name = "-"; this.Params.Input[inputSelecterMax].NickName = "-"; this.Params.Input[inputSelecterMax].Name = "-"; } else { this.Params.Input[inputSelectorMin].NickName = "MinColor"; this.Params.Input[inputSelectorMin].Name = "MinColor"; this.Params.Input[inputSelecterMax].NickName = "MaxColor"; this.Params.Input[inputSelecterMax].Name = "MaxColor"; } var domain = Misc.AutoDomain(range, allResults); //Rhino.RhinoApp.WriteLine($"{range} -> {domain[0]} to {domain[1]}"); GH_GradientControl gc; try { gc = (GH_GradientControl)Params.Input[inputGradient].Sources[0].Attributes.GetTopLevel.DocObject; } catch (System.ArgumentOutOfRangeException) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Remember to add a gradient component in grasshopper!"); gc = null; } GradientParser gp = new GradientParser(gc) { Cap = caps, AboveMax = maxColor, BelowMin = minColor, Min = domain[0], Max = domain[1], Reverse = Params.Input[inputGradient].Reverse }; //Rhino.RhinoApp.WriteLine($"Probing {domain[0]} to the value of {gp.GetColors(new List<double> { domain[0] })[0]}"); //Rhino.RhinoApp.WriteLine($"Probing {domain[1]} to the value of {gp.GetColors(new List<double> { domain[1] })[0]}"); #region coloredMesh var outMeshes = new List <Mesh>(); for (int i = 0; i < grids.Count; i++) { //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Mesh vertices: {grids[i].SimMesh.Vertices.Count}, colors = {gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()).Length} f"); outMeshes.Add(grids[i].GetColoredMesh(gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()))); Mesh m = grids[i].SimMesh; Point3d[] points = grids[i].SimPoints.ToArray(); outMeshes[outMeshes.Count - 1].Translate(0, 0, Units.ConvertFromMeter(0.001)); } DA.SetDataList(0, outMeshes); #endregion coloredMesh #region layeredMesh if (grids[0].UseCenters == true) { return; } //Outputs GH_Structure <GH_Mesh> layeredMeshes = new GH_Structure <GH_Mesh>(); List <GH_Mesh> tempMeshes = new List <GH_Mesh>(); List <GH_Plane> outPlanes = new List <GH_Plane>(); GH_Structure <GH_Curve> outCurves = new GH_Structure <GH_Curve>(); const double SCALAR = 1; // don't change. const float OFFSET = 0.0001f; double allMin = double.MaxValue; double allMax = -double.MaxValue; for (int i = 0; i < allResults.Branches.Count; i++) { //System.Collections.IList results = allResults.get_Branch(i); for (int j = 0; j < allResults[i].Count; j++) { double result = allResults[i][j].Value; if (result < allMin) { allMin = result; } if (result > allMax) { allMax = result; } } } stepSize = inStepSize; double roundToNearest = 1; if (inStepSize == 0) // auto { //double digits = Math.Round(Math.Log10((domain[1] - domain[0]))) + 1; //double multiplier = Math.Pow(10, digits); //stepSize = Math.Log10((domain[1] - domain[0])); //if (allMax > 1000) // stepSize = 100; //else if (allMax > 100) // stepSize = 10; //else if (allMax > 10) // stepSize = 1; //else // stepSize = 0.1; stepSize = Misc.AutoStep(domain, out roundToNearest); // <-- TODO: We can set each slice in exactly the "round to nearest" number. } else if (inStepSize < 0) // fragment { stepSize = 1 / Math.Abs(inStepSize); } steps = Convert.ToInt32((domain[1] - domain[0]) / stepSize); for (int g = 0; g < grids.Count; g++) { //GH_Structure<GH_Curve> curves = new GH_Structure<GH_Curve>(); Grid grid = grids[g]; Mesh meshToCut = grids[g].SimMesh.DuplicateMesh(); //Mesh meshToCut = grids[g].SimMesh; List <double> results = ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).ToList(); if (grids[g].UseCenters == true) { results = RTreeSolver.FindClosestWeightedValues(grids[g], results, true).ToList(); // ADD CONVERSION TODO: } //Rhino.RhinoApp.WriteLine($"min = {allMin}, max = {allMax}, steps = {steps}, stepsize = {stepSize}"); if (steps <= 1 || steps > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"too {(steps < 4 ? "few" : "many")} steps (should be between 1 to 100)"); AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"min = {allMin}, max = {allMax}, steps = {steps}, stepsize = {stepSize}"); continue; } if (allMax == allMin) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"max==min"); continue; } meshToCut.Normals.ComputeNormals(); Plane cuttingPlane = new Plane(meshToCut.Vertices[0], meshToCut.FaceNormals[0]); //var planeOut = new Plane(plane); var planeBottom = new Plane(cuttingPlane); //List<int> belongsToWhichLayer = new List<int>(); Vector3f normal = (Vector3f)(cuttingPlane.ZAxis); //AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"normal x = {normal.X}, Y = {normal.Y}, Z = {normal.Z}"); planeBottom.Transform(Transform.Translation(-cuttingPlane.ZAxis)); //Moving the bottom down meshToCut.Translate(-normal * OFFSET); //Moving the vertices up for (int i = 0; i < results.Count; i++) { meshToCut.Vertices[i] += (normal) * (float)SCALAR * (OFFSET + (float)results[i]); } Mesh topMesh = meshToCut.DuplicateMesh(); tempMeshes.Add(new GH_Mesh(topMesh)); Mesh edgeMesh = new Mesh(); List <Point3d> ptOut = new List <Point3d>(); Polyline[] edges = meshToCut.GetNakedEdges(); double totalLength = 0; for (int i = 0; i < edges.Length; i++) { totalLength += edges[i].Length; } Polyline[] edgesProjected = new Polyline[edges.Length]; Transform p = Transform.PlanarProjection(planeBottom); for (int i = 0; i < edges.Length; i++) { for (int j = 0; j < edges[i].SegmentCount; j++) { Mesh msh = new Mesh(); Point3d[] pts = new Point3d[4]; int id = (j == edges[i].SegmentCount - 1) ? 0 : j + 1; pts[0] = new Point3d(edges[i].X[j], edges[i].Y[j], edges[i].Z[j]); pts[1] = new Point3d(edges[i].X[id], edges[i].Y[id], edges[i].Z[id]); pts[2] = new Point3d(pts[1]); pts[3] = new Point3d(pts[0]); pts[2].Transform(p); pts[3].Transform(p); msh.Vertices.AddVertices(pts); var fc = new MeshFace(3, 2, 1, 0); ptOut.AddRange(pts); msh.Faces.AddFace(fc); edgeMesh.Append(msh); } } meshToCut.Append(edgeMesh); meshToCut.Weld(Math.PI); tempMeshes.Add(new GH_Mesh(meshToCut)); //Transform t = Transform.Translation(new Vector3d(0, 0, inStepSize * SCALAR)); Vector3f v = normal * (float)(stepSize.RoundTo(roundToNearest) * SCALAR); Transform t = Transform.Translation(v); //AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Vector v = {v.X}, {v.Y}, {v.Z}, instep = "); Mesh meshPerArea = new Mesh(); MeshingParameters mp = new MeshingParameters(0); //double resultValue = inputMin; //stepSize = (inputMax - inputMin) / (float)steps; double currentValue = domain[0]; int cuttingCount = -1; while (currentValue <= domain[1]) { cuttingCount++; if (cuttingCount == 0) { currentValue = domain[0]; } if (cuttingCount == 1) { cuttingPlane.Translate(new Vector3d(0, 0, domain[0].RoundTo(roundToNearest))); //currentValue = domain[0]; } if (cuttingCount > 0) { currentValue += stepSize; } if (cuttingCount > 80) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "ERROR CUT THE CUTTINGCOUNT"); break; } //Rhino.RhinoApp.WriteLine($"CurrentValue = {currentValue}, cuttingCount = {cuttingCount}"); //var resultValue = (double)cuttingCount / steps * (allMax - allMin) + allMin; //resultValue = (double)cuttingCount / steps * (domain[1] - domain[0]) + domain[0]; //resultValue = (double)cuttingCount / steps * (domain[1] - domain[0]) + domain[0]; //var resultValue = currentValue; // new //Rhino.RhinoApp.WriteLine($"Cutting {cuttingCount}, {resultValue}, {currentValue}, {allMin} - {allMax}"); //if (resultValue < domain[0]) // continue; //if (resultValue > domain[1]) // break; Polyline[] pl = Rhino.Geometry.Intersect.Intersection.MeshPlane(meshToCut, cuttingPlane); outPlanes.Add(new GH_Plane(cuttingPlane)); if (pl == null) { break; } Color col = gp.GetColors(new List <double>() { cuttingCount == 0 ? double.MinValue : currentValue.RoundTo(roundToNearest) })[0]; //Rhino.RhinoApp.WriteLine($"Probing value {currentValue} to {col}"); //Mesh meshPerCut = new Mesh(); GH_Path path = new GH_Path(g, cuttingCount); if (pl.Length > 0) { List <Curve> curves = new List <Curve>(); for (int j = 0; j < pl.Length; j++) { Curve curve = new PolylineCurve(pl[j]); if (cuttingCount <= 0) { curve.Translate(normal * (float)(domain[0] - stepSize)); } curve.Translate(-normal * (float)(currentValue * 0.95 - stepSize)); // was 0.95 nice //curve.Translate(-normal * (float)allMin + normal * (float)(cuttingCount * Units.ConvertFromMeter(0.01))); curves.Add(curve); // to create brep later outCurves.Append(new GH_Curve(curve), path); // for output } Brep[] breps2 = Brep.CreatePlanarBreps(curves, Units.ConvertFromMeter(0.001)); for (int j = 0; j < breps2.Length; j++) { Mesh[] mesh2 = Mesh.CreateFromBrep(breps2[j], mp); for (int k = 0; k < mesh2.Length; k++) { mesh2[k].VertexColors.CreateMonotoneMesh(col); //meshPerCut.Append(mesh2[k]); layeredMeshes.Append(new GH_Mesh(mesh2[k]), path); } } } //meshPerCut.VertexColors.CreateMonotoneMesh(col); if (cuttingCount > 0) { cuttingPlane.Transform(t); } } //layeredMeshes.Append(new GH_Mesh(meshPerArea), new GH_Path(g, ); } //for (int j = 0; j < pl.Length; j++) //{ // Curve curve = pl[j].ToNurbsCurve(); // GH_Path path = new GH_Path(g, cuttingCount); // outCurves.Append(new GH_Curve(curve), path); // Brep[] breps = Brep.CreatePlanarBreps(curve, Units.ConvertFromMeter(0.001)); // if (breps == null) // continue; // Brep brep = breps[0]; // var area = AreaMassProperties.Compute(brep); // if (area.Area > maxSize) // { // maxSize = area.Area; // outerIndex = j; // } //} //boundaryEdge = pl[outerIndex]; //for (int j = 0; j < pl.Length; j++) //{ // if (j != outerIndex) // holes.Add(pl[j].ToNurbsCurve()); //} //Mesh mesh = null; //if (boundaryEdge.IsClosed) //{ // mesh = Mesh.CreatePatch(boundaryEdge, Math.PI / 2.0, null, holes, null, null, false, 0); //} //else //{ // AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Curve is not closed"); //} //outPlanes.Add(new GH_Plane(new Plane(cuttingPlane))); //int curvesCount = pl.Length; //int[] pointsRanges = new int[curvesCount]; //Point3d[][] pts = new Point3d[curvesCount][]; //for (int j = 0; j < pl.Length; j++) //{ // //Mesh mesh = GreenScenario.MeshUtil.CreateMeshWithHoles(pl); // //Mesh mesh = Mesh.CreateFromTessellation(points, pl, Plane.WorldXY, false); // //var mesh = Mesh.CreateFromClosedPolyline(pl[j]); // if (mesh == null) // continue; // //outCurves.Append(new GH_Curve(pl[j].ToNurbsCurve())); // //List<Color> colorList = new List<Color>(); // ////for (int i = 0; i < mesh.Faces.Count; i++) // ////{ // //// colorList.Add(col); // //// colorList.Add(col); // //// colorList.Add(col); // //// if (mesh.Faces[i].IsQuad) // //// colorList.Add(col); // ////} // //for (int i = 0; i < mesh.Vertices.Count; i++) // //{ // // colorList.Add(col); // //} // ////mesh.VertexColors.SetColors(colorList.ToArray()); // //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Vertices = {mesh.Vertices.Count}, colors = {mesh.VertexColors.Count}"); // // mesh.VertexColors.CreateMonotoneMesh(col); // //mesh.Translate(-normal * inStepSize * (float)SCALAR * cuttingCount * 0.90f); // // meshPerArea.Append(mesh); // // we don't have more heights to cut off. // //if (brep == null) // // continue; // //for (int i = 0; i < brep.Length; i++) // //{ // // belongsToWhichLayer.Add(count); // //} // //pts.Add(polylinecrv.PointAtStart); //} // By now curves are moved to different elevations. //crvs = crvs; //Rhino.RhinoApp.WriteLine("adding a mesh"); //oNumbers = outNumbers; //B = breps; //meshOut = mesh; Message = $"Cap = {(this.caps ? "on" : "off")} | Steps = {steps} | Step = {stepSize:0.0}"; DA.SetDataTree(1, layeredMeshes); DA.SetDataTree(2, outCurves); DA.SetDataList("Planes", outPlanes); DA.SetDataList("TempMeshes", tempMeshes); #endregion layeredMesh }
protected override void SolveInstance(IGH_DataAccess DA) { try { //////////////////////////////////////////////////////////////////// //Inputs Grasshopper Mesh M = DA.Fetch <Mesh>("Mesh"); DataTree <Polyline> PanelOutlines = DA.FetchTree <GH_Curve>("Panels").ToPolylineDT(); DataTree <Vector3d> EVec = DA.FetchTree <GH_Vector>("EdgeVectors").ToDT(); int D = DA.Fetch <int>("JointDiv"); double L = DA.Fetch <double>("JointLen"); double H = DA.Fetch <double>("JointHei"); double W = DA.Fetch <double>("JointThi"); bool Center = DA.Fetch <bool>("Center"); bool Finger = DA.Fetch <bool>("Finger"); double Custom = DA.Fetch <double>("Custom"); DataTree <Polyline> CChamfer = new DataTree <Polyline>(); int iterations = DA.Fetch <int>("Iterations"); List <int> sequence = DA.FetchList <int>("Sequence"); List <double> textSize = DA.FetchList <double>("TextScale"); if (textSize.Count < 6) { textSize = new List <double> { 20, 10, 10, 0.5, 0.75, 10 } } ; DataTree <Panel> PanelGroups = DA.FetchTree <GH_Curve>("Panels").ToPanelsDT(); DataTree <Panel> JointGroups = new DataTree <Panel>(); //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //Inputs Local int divisions = Math.Max(1, D); double jointLength = L;//Math.Max(0.1, L); double height = Math.Max(0.1, H); double width = Math.Max(0.1, W); int[][] tv = M.GetNGonsTopoBoundaries(); int[][] fe = M.GetNGonFacesEdges(tv); HashSet <int> e = M.GetAllNGonEdges(tv); Dictionary <int, int[]> efDict = M.GetFE(e, false); Point3d[] centers = M.GetNGonCenters(); //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // Insertion vectors DataTree <Vector3d> EV = M.insertionVectors(Center, EVec); //////////////////////////////////////////////////////////////////// DataTree <Polyline> diagonalConnections = new DataTree <Polyline>(); //DataTree<Polyline> recJoints = new DataTree<Polyline>(); //Iterate insertion edges Dictionary <int, int> meshEdgeDict = new Dictionary <int, int>(); for (int i = 0; i < EV.BranchCount; i++) // EV.BranchCount { int meshEdge = EV.Path(i).Indices[0];//mesh edge is used as dataTree branch meshEdgeDict.Add(meshEdge, i); if (efDict[meshEdge].Length != 2) { continue; } int f0 = efDict[meshEdge][0]; int f1 = efDict[meshEdge][1]; //Divide line into points and create a planes on these point, following insertion direction and average face normal Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(divisions, false); for (int j = 0; j < pts.Length; j++) { JointGroups.Add(new Panel(new Plane(pts[j], EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge))), EV.Path(i)); } //Construct joint outlines from planes //Iterate number of joints per edge for (int j = 0; j < pts.Length; j++) { JointGroups.Branch(EV.Path(i))[j].planeOffset0 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(W * 0.5); //offset planes JointGroups.Branch(EV.Path(i))[j].planeOffset1 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(-W * 0.5); //offset planes JointGroups.Branch(EV.Path(i))[j].planeRot = new Plane(pts[j], Vector3d.CrossProduct(EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge)), M.GetMeshEdgePerpDir(meshEdge)); JointGroups.Branch(EV.Path(i))[j].planeRotOffset0 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(jointLength); //offset planes JointGroups.Branch(EV.Path(i))[j].planeRotOffset1 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(-jointLength); //offset plane JointGroups.Branch(EV.Path(i))[j].planeEdge = new Plane(pts[j], M.TopologyEdges.EdgeLine(meshEdge).Direction, M.GetMeshEdgePerpDir(meshEdge)); List <Plane> planesF0 = new List <Plane>(); List <Plane> planesF1 = new List <Plane>(); for (int k = 0; k < PanelGroups.Branch(f0).Count; k++) { planesF0.Add(PanelGroups.Branch(f0)[k].plane); planesF1.Add(PanelGroups.Branch(f1)[k].plane); } JointGroups.Branch(EV.Path(i))[j].planeF0 = PlaneUtil.AveragePlaneOrigin(planesF0); JointGroups.Branch(EV.Path(i))[j].planeF1 = PlaneUtil.AveragePlaneOrigin(planesF1); List <Plane> jointPlaneLoop = new List <Plane> { JointGroups.Branch(EV.Path(i))[j].planeRotOffset0, JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(height), JointGroups.Branch(EV.Path(i))[j].planeEdge, JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(height), //3 JointGroups.Branch(EV.Path(i))[j].planeRotOffset1, JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(-height), //5 JointGroups.Branch(EV.Path(i))[j].planeEdge, JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(-height), }; //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20))); //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20))); JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset0, jointPlaneLoop); JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointPlaneLoop); JointGroups.Branch(EV.Path(i))[j].contour[0] = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0]); JointGroups.Branch(EV.Path(i))[j].contour[1] = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1]); } //Construct Cuts //Iterate number of joints per edge for (int j = 0; j < pts.Length; j++) { int localMeshEdgeF0 = Array.IndexOf(fe[f0], meshEdge); int localMeshEdgeF1 = Array.IndexOf(fe[f1], meshEdge); //Iterate number of panels and create cuts for (int k = 0; k < PanelGroups.Branch(f0).Count; k++) { Panel jointPanel = JointGroups.Branch(EV.Path(i))[j]; jointPanel.id = f0.ToString() + "-" + f1.ToString(); //if(f0==f1) // Rhino.RhinoApp.WriteLine(jointPanel.id); if (pts.Length > 1) { jointPanel.id += "-" + j.ToString(); } bool flag = f0 == 165 && f1 == 166; PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointLength, ref jointPanel, flag); //, ref neiPanel, ref jointPanel); PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointLength, ref jointPanel, flag); //, ref neiPanel, ref jointPanel); JointGroups.Branch(EV.Path(i))[j] = jointPanel; } } } for (int i = 0; i < JointGroups.BranchCount; i++) { for (int j = 0; j < JointGroups.Branch(i).Count; j++) { if (Custom > 0) { JointGroups.Branch(i)[j].ChangeJoint(Custom, 0); } else if (Custom < 0) { JointGroups.Branch(i)[j].ChangeJoint(Custom, 1, textSize[7]); } } } ////////////////////////Output var dtPlates = new DataTree <Polyline>(); var dtJoints = new DataTree <Polyline>(); var dtPlatesMid = new DataTree <Polyline>(); var dtJointsMid = new DataTree <Polyline>(); var dtPlatesPlanes = new DataTree <Plane>(); var dtJointsPlanes = new DataTree <Plane>(); var dtPlatesTxt = new DataTree <Curve>(); var dtJointsTxt = new DataTree <Curve>(); var dtPlatesLast = new DataTree <Polyline>(); var dtJointsLast = new DataTree <Polyline>(); var dtPlatesMidLast = new DataTree <Polyline>(); var dtJointsMidLast = new DataTree <Polyline>(); var dtPlatesPlanesLast = new DataTree <Plane>(); var dtJointsPlanesLast = new DataTree <Plane>(); var dtPlatesTxtLast = new DataTree <Curve>(); var dtJointsTxtLast = new DataTree <Curve>(); HashSet <int> jointSequence = new HashSet <int>(); HashSet <int> jointSequenceLast = new HashSet <int>(); int last = Math.Min(iterations, PanelGroups.BranchCount); int prev = Math.Max(0, last - (int)textSize[6]); for (int i = 0; i < last; i++) //Math.Min(iterations, sequence.Count) PanelGroups.BranchCount { for (int j = 0; j < fe[i].Length; j++) { bool seq = jointSequence.Add(fe[i][j]); if (i >= prev) { if (seq) { jointSequenceLast.Add(fe[i][j]); } } } for (int j = 0; j < PanelGroups.Branch(i).Count; j++) { dtPlates.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j)); dtPlates.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j)); dtPlatesMid.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); if (i >= prev) { dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j)); dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j)); dtPlatesMidLast.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); } Plane textPlane = PanelGroups.Branch(i)[j].planeOffset0; textPlane.Flip(); if (j == 1) { textPlane = PanelGroups.Branch(i)[j].planeOffset1; } dtPlatesPlanes.Add(textPlane, new GH_Path(i, j)); if (i >= prev) { dtPlatesPlanesLast.Add(textPlane, new GH_Path(i, j)); } string text = i.ToString() + "-" + j.ToString(); var txtCrv = Typewriter.Regular.Write(text, textPlane, textSize[0]); dtPlatesTxt.AddRange(txtCrv, new GH_Path(i, j)); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrv, new GH_Path(i, j)); } //for(int k = 0; k < PanelGroups.Branch(i)[j].contourNoJoints.Length; k++) { Line[] segments = PanelGroups.Branch(i)[j].contourNoJoints[j].GetSegments(); int counter = 0; foreach (Line l in segments) { int meshEdge = fe[i][counter]; int neiF = M.GetOppositeNgon(meshEdge, i); //Adjacent face plane Point3d origin = l.PointAt(textSize[3]); Vector3d xaxis = l.Direction; Vector3d yaxis = l.Direction; origin.Transform(Transform.Scale(textPlane.Origin, textSize[4])); yaxis.Rotate(Math.PI * 0.5, textPlane.ZAxis); Plane ePlane = new Plane(origin, xaxis, yaxis); var txtCrvF = Typewriter.Regular.Write(neiF.ToString(), ePlane, textSize[2]); dtPlatesTxt.AddRange(txtCrvF, new GH_Path(i, j)); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF, new GH_Path(i, j)); } //Mesh edge direction Line meshEdgeLine = M.TopologyEdges.EdgeLine(meshEdge); meshEdgeLine.Transform(Transform.Scale(meshEdgeLine.PointAt(0.5), textSize[4])); meshEdgeLine.Transform(Transform.Scale(textPlane.Origin, textSize[4])); //meshEdgeLine.Extend(-textSize[4], -textSize[4]); Plane e0Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.From), xaxis, yaxis); Plane e1Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.To), xaxis, yaxis); var txtCrvF0 = Typewriter.Regular.Write("I", e0Plane, textSize[2]); dtPlatesTxt.AddRange(txtCrvF0, new GH_Path(i, j)); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF0, new GH_Path(i, j)); } var txtCrvF1 = Typewriter.Regular.Write("II", e1Plane, textSize[2]); dtPlatesTxt.AddRange(txtCrvF1, new GH_Path(i, j)); if (i >= prev) { dtPlatesTxtLast.AddRange(txtCrvF1, new GH_Path(i, j)); } counter++; // } } } foreach (int meshEdge in jointSequence) { //for (int i = 0; i < Math.Min(iterations, sequence.Count); i++) {//JointGroups.BranchCount if (!meshEdgeDict.ContainsKey(meshEdge)) { continue; } int i = meshEdgeDict[meshEdge]; for (int j = 0; j < JointGroups.Branch(i).Count; j++) { dtJoints.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j)); dtJoints.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j)); dtJointsMid.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); dtJointsPlanes.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j)); Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis); string text = JointGroups.Branch(i)[j].id; var txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]); dtJointsTxt.AddRange(txtCrv, new GH_Path(meshEdge, j)); } } foreach (int meshEdge in jointSequenceLast) { //for (int i = 0; i < Math.Min(iterations, sequence.Count); i++) {//JointGroups.BranchCount if (!meshEdgeDict.ContainsKey(meshEdge)) { continue; } int i = meshEdgeDict[meshEdge]; for (int j = 0; j < JointGroups.Branch(i).Count; j++) { dtJointsLast.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j)); dtJointsLast.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j)); dtJointsMidLast.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(i, j)); dtJointsPlanesLast.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j)); Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis); string text = JointGroups.Branch(i)[j].id; var txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]); dtJointsTxtLast.AddRange(txtCrv, new GH_Path(meshEdge, j)); } } DA.SetDataTree(0, dtPlates); DA.SetDataTree(1, dtJoints); DA.SetDataTree(2, dtPlatesMid); DA.SetDataTree(3, dtJointsMid); DA.SetDataTree(4, dtPlatesPlanes); DA.SetDataTree(5, dtJointsPlanes); DA.SetDataTree(6, dtPlatesTxt); DA.SetDataTree(7, dtJointsTxt); DA.SetDataTree(8, dtPlatesLast); DA.SetDataTree(9, dtJointsLast); DA.SetDataTree(10, dtPlatesMidLast); DA.SetDataTree(11, dtJointsMidLast); DA.SetDataTree(12, dtPlatesPlanesLast); DA.SetDataTree(13, dtJointsPlanesLast); DA.SetDataTree(14, dtPlatesTxtLast); DA.SetDataTree(15, dtJointsTxtLast); } catch (Exception e) { Rhino.RhinoApp.WriteLine(e.ToString()); } }
protected override void SolveInstance(IGH_DataAccess DA) { List <Mesh> m_ = DA.FetchList <Mesh>("Mesh"); double radius = DA.Fetch <double>("Radius"); Mesh[] m = new Mesh[m_.Count]; Mesh mj = new Mesh(); for (int i = 0; i < m_.Count; i++) { m[i] = m_[i].DuplicateMesh(); mj.Append(m_[i]); } if (radius == -2) { for (int i = 0; i < m_.Count; i++) { if (m[i].SolidOrientation() == -1) { m[i].Flip(true, true, true); } m[i].Unweld(0, true); mj.Append(m[i]); } DA.SetDataList(0, m); this.PreparePreview(mj, DA.Iteration); } if (radius == -3) { for (int i = 0; i < m_.Count; i++) { if (m[i].SolidOrientation() == -1) { m[i].Flip(true, true, true); } m[i] = m[i].WeldUsingRTree(0.001, foo); m[i].Unweld(0, true); m[i].UnifyNormals(); mj.Append(m[i]); } DA.SetDataList(0, m); this.PreparePreview(mj, DA.Iteration); } //m.WeldUsingRTree(radius); else if (radius > 0) { //Rhino.RhinoApp.WriteLine("hi"); mj = mj.WeldUsingRTree(radius, foo); mj.Compact(); mj.Vertices.CombineIdentical(true, true); mj.Vertices.CullUnused(); if (mj.Ngons.Count > 0) { mj.UnifyNormalsNGons(); } else { mj.UnifyNormals(); } mj.Weld(3.14159265358979); mj.FaceNormals.ComputeFaceNormals(); mj.Normals.ComputeNormals(); if (mj.SolidOrientation() == -1) { mj.Flip(true, true, true); } this.PreparePreview(mj, DA.Iteration); DA.SetDataList(0, new Mesh[] { mj }); //m.WeldFull(radius); } //DA.SetData(0, m); }
protected override void SolveInstance(IGH_DataAccess DA) { Mesh mesh = DA.Fetch <Mesh>("Mesh"); string v = DA.Fetch <string>("Start"); List <int> o = DA.FetchList <int>("Sequence"); Curve sequenceCrv = DA.Fetch <Curve>("SequenceCrv"); List <Line> customVectors = DA.FetchList <Line>("CustomVectors"); double angleTol = DA.Fetch <double>("Angle"); v = Math.Min(Convert.ToInt32(v), mesh.Ngons.Count - 1).ToString(); if (mesh.Ngons.Count == o.Count) { mesh = mesh.ReoderMeshNgons(o); base.Message = "Sequence"; } else if (sequenceCrv != null) { if (sequenceCrv.IsValid) { mesh = mesh.ReoderMeshNgons(sequenceCrv); List <int> order = Enumerable.Range(0, mesh.Ngons.Count).ToList(); base.Message = "Sequence Curve"; } } else { var ve = NGonsCore.Graphs.UndirectedGraphBfsRhino.MeshBFS(mesh, v); List <int> order = ve.Item1[0]; mesh = mesh.ReoderMeshNgons(ve.Item1[0]); base.Message = "BFS"; DA.SetDataTree(0, GrasshopperUtil.IE2(ve.Item1)); DA.SetDataTree(1, GrasshopperUtil.IE3(ve.Item2)); } DA.SetData(4, mesh); List <int> order_ = Enumerable.Range(0, mesh.Ngons.Count).ToList(); DataTree <int> vertices_ = new DataTree <int>(order_); DataTree <int> edges_ = new DataTree <int>(); for (int i = 0; i < order_.Count - 1; i++) { edges_.Add(order_[i], new GH_Path(i)); edges_.Add(order_[i] + 1, new GH_Path(i)); } int S = mesh.Ngons.Count;//stop //Insertion vectors DataTree <int> N = SequenceNeighbours(mesh, order_, S); //FN = N; //O_ = O; //Edge Vectors int[][] tv = mesh.GetNGonsTopoBoundaries(); int[][] fe = mesh.GetNGonFacesEdges(tv); HashSet <int> e = mesh.GetAllNGonEdges(tv); Dictionary <int, int[]> efDict = mesh.GetFE(e, false); Polyline[] outlines = mesh.GetPolylines(); //Dictionary<int, Vector3d> edgeVectors = new Dictionary<int, Vector3d> (); DataTree <Vector3d> edgeVectors = new DataTree <Vector3d>(); List <Vector3d> faceVectors = new List <Vector3d>(); Dictionary <int, List <GH_Path> > faceEdgeID = new Dictionary <int, List <GH_Path> >(); for (int i = 0; (i < S && i < mesh.Ngons.Count); i++) { ///////////// // Properties ///////////// //Current path and face GH_Path p = new GH_Path(i); int f = order_[i];//O[i]; if (!N.PathExists(p)) { continue; //If no connectio nskip } HashSet <int> fadj = new HashSet <int>(N.Branch(p)); //adjacency list ///////////// // Solution ///////////// //Iterate mesh edges //Get connected faces //Check if they are in adjacency list //The order thoses ids List <int> NotOrderedEdges = new List <int>(); for (int j = 0; j < fe[f].Length; j++) { int[] facePair = efDict[fe[f][j]];//get face pair if (facePair.Length == 1) { continue; //if naked skip } if (fadj.Contains(facePair[0]) || fadj.Contains(facePair[1])) { NotOrderedEdges.Add(j); //if edge face are in fadj } } List <int> orderedEdges = SortIntegers(NotOrderedEdges, fe[f].Length); //Collect lines for Insertion Vector List <Line> el = new List <Line>(); //Line[] lines = outlines[f].GetSegments(); foreach (int j in orderedEdges) { el.Add(outlines[f].SegmentAt(j));//el.Add(M.TopologyEdges.EdgeLine(fe[f][j])); } //Create Insertion Vector Vector3d vec = NGonsCore.VectorUtil.BisectorVector(el, outlines[f].AverageNormal(), false); faceVectors.Add(vec); List <GH_Path> paths = new List <GH_Path>(); foreach (int j in orderedEdges) { //edgeVectors.Add(fe[f][j],vec); edgeVectors.Add(vec, new GH_Path(fe[f][j])); paths.Add(new GH_Path(fe[f][j])); } faceEdgeID.Add(i, paths); //Rhino.RhinoApp.WriteLine(i.ToString() + " " + paths.Count.ToString()); //A = el; //B = vec; //C = outlines[f].AverageNormal(); } DataTree <Vector3d> EV = mesh.insertionVectors(true); DataTree <Line> edges = new DataTree <Line>(); PointCloud cloud = new PointCloud(); //Check angles if vectors are not parallel to mesh edge foreach (GH_Path p in EV.Paths) { Line line = mesh.TopologyEdges.EdgeLine(p.Indices[0]); Plane edgePlane = new Plane(line.PointAt(0.5), mesh.GetMeshEdgePerpDir(p.Indices[0])); cloud.Add(line.PointAt(0.5), new Vector3d(p.Indices[0], 0, 0)); double angledifference = Math.Abs(Vector3d.VectorAngle(line.Direction, edgeVectors.Branch(p)[0], edgePlane) % Math.PI); //Rhino.RhinoApp.WriteLine(angledifference.ToString()); if (angledifference < angleTol || angledifference > (Math.PI - angleTol)) { edges.Add(new Line(line.PointAt(0.5), line.PointAt(0.5) + line.Direction.UnitVector() * line.Length * 0.25), p); edges.Add(new Line(line.PointAt(0.5), line.PointAt(0.5) + edgeVectors.Branch(p)[0].UnitVector() * line.Length * 0.25), p); edgeVectors.Branch(p)[0] = -EV.Branch(p)[0]; } else { } } //Change insertion vectors if (customVectors.Count > 0) { for (int i = 0; i < customVectors.Count; i++) { int edgeID = cloud.ClosestPoint(customVectors[i].From); edgeVectors.Branch(new GH_Path((int)cloud[edgeID].Normal.X))[0] = customVectors[i].Direction; } } //Rhino.RhinoApp.WriteLine (faceEdgeID.Count.ToString()); List <Vector3d> NGonsVectors = new List <Vector3d>() { Vector3d.ZAxis }; for (int i = 1; i < faceEdgeID.Count; i++) { Vector3d vec = Vector3d.Zero; for (int j = 0; j < faceEdgeID[i].Count; j++) { vec += edgeVectors.Branch(faceEdgeID[i][j])[0]; } vec.Unitize(); NGonsVectors.Add(vec); } DA.SetDataList(5, NGonsVectors); //EV = edgeVectors; DA.SetDataTree(2, edgeVectors); DA.SetDataTree(3, edges); //Get current face edges //Take edge only connected in current set }
protected override void SolveInstance(IGH_DataAccess DA) { try { this.reset = DA.Fetch <bool>("Reset"); this.run = DA.Fetch <bool>("Run"); this.iterations = DA.Fetch <int>("Iterations"); this.spacing = DA.Fetch <double>("Spacing"); this.placementType = DA.Fetch <int>("Placement"); this.tolerance = DA.Fetch <double>("Tolerance"); this.rotations = DA.Fetch <int>("Rotations"); this.seed = DA.Fetch <int>("Seed"); this.spacing *= (1 / tolerance); //Rhino.RhinoApp.WriteLine("ITER" + iterations.ToString()); if (((this.reset) || this.scales.Length == 0) || (this.iterations > 0)) { //Input //Rhino.RhinoApp.WriteLine("setup" + rotations.ToString()); List <Polyline> sheets = DA.FetchList <Curve>("Sheets").ToPolylines(true); if (sheets.Count == 1) { Polyline sheetCopy = new Polyline(sheets[0]); sheets.Clear(); Point3d p0 = sheetCopy.BoundingBox.PointAt(0, 0, 0); Point3d p1 = sheetCopy.BoundingBox.PointAt(1, 0, 0); Vector3d vec = p1 - p0; x = (p1.X - p0.X + this.spacing) / this.tolerance; for (int i = 0; i < 499; i++) { //Polyline sheetMoved = new Polyline(sheetCopy); //sheetMoved.Transform(Transform.Translation(vec * i)); sheets.Add(sheetCopy); } } else { this.x = 0; } List <IGH_GeometricGoo> geo_ = DA.FetchList <IGH_GeometricGoo>("Geo"); Polyline[][] outlines = GooToOutlines(geo_); ////////////Solution//////////// base.Message = "Setup"; this.scalesInv = new Transform[0]; this.scales = new Transform[0]; this.orient = new Transform[0]; this.sheetsRhino = new Polyline[0]; this.id = new int[0]; this.transforms = new Transform[0]; //Scale Transform scale = Transform.Scale(Point3d.Origin, 1 / tolerance); Transform scaleInv = Transform.Scale(Point3d.Origin, tolerance); for (int i = 0; i < sheets.Count; i++) { //sheets[i] = new Rectangle3d(sheets[i].Plane, sheets[i].Width * 1 / tolerance, sheets[i].Height * 1 / tolerance); Polyline polyline = new Polyline(sheets[i]); polyline.Transform(Transform.Scale(Point3d.Origin, 1 / tolerance)); sheets[i] = polyline; } //Scale polylines and holes by tolerance scalesInv = new Transform[n]; scales = new Transform[n]; for (int i = 0; i < n; i++) { for (int j = 0; j < outlines[i].Length; j++) { outlines[i][j].Transform(scale); } scalesInv[i] = scaleInv; scales[i] = scale; } //Translation orient = new Transform[n]; for (int i = 0; i < n; i++) { int last = (outlines[i].Length - 1) % outlines[i].Length; Tuple <Polyline, Transform> projectedPolyline = OpenNestUtil.FitPolylineToPlane(new Polyline(outlines[i][last])); //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(projectedPolyline.Item1); for (int j = 0; j < outlines[i].Length; j++) { outlines[i][j].Transform(projectedPolyline.Item2); } //foreach (var pp in outlines[i][0]) // Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(pp); orient[i] = projectedPolyline.Item2; } ////////////Run Solver//////////// //OpenNestSolver sample = new OpenNestSolver(); //sample.Context.LoadSampleData(sheets, outlines); //var output = sample.Run(spacing, iterations, placementType, rotations); //Context = new NestingContext(this.seed); Context = new NestingContext(); Context.LoadSampleData(sheets, outlines); //Rhino.RhinoApp.WriteLine("outlines " + polyline[0].Count.ToString()); Background.UseParallel = true; ONest.Config.placementType = (PlacementTypeEnum)(placementType % 3); //Rhino.RhinoApp.WriteLine(((PlacementTypeEnum)(placementType % 3)).ToString()); ONest.Config.spacing = this.spacing; ONest.Config.rotations = this.rotations; ONest.Config.seed = this.seed; ONest.Config.clipperScale = 1e7; ONest.Config.simplify = (placementType == 4); ONest.Config.exploreConcave = (placementType == 5); ONest.Config.mergeLines = false; //ONest.Config.useHoles = false; Context.StartNest(); } if ((run || this.scales.Length == 0) && iterations == 0) { Context.NestIterate(); base.Message = "Run " + Context.Iterations.ToString() + " \n Current Best: " + Context.Current.fitness; } if (iterations > 0) { for (int i = 0; i < iterations; i++) { Context.NestIterate(); } base.Message = "Static Solver " + Context.Iterations.ToString() + " \n Current Best: " + Context.Current.fitness; } if (Context.SheetsNotUsed != -1) { int sheetCount = Context.Sheets.Count - Context.SheetsNotUsed; this.sheetsRhino = new Polyline[sheetCount]; for (int i = 0; i < sheetCount; i++) { //Rhino.RhinoApp.WriteLine(Context.Sheets[i].id.ToString()); Polyline sheetPoly = Context.Sheets[i].ToPolyline(); sheetPoly.Transform(Transform.Translation(new Vector3d(this.x * i, 0, 0))); this.sheetsRhino[i] = sheetPoly; } } else { this.sheetsRhino = Context.Sheets.ToPolylines(); } this.id = Context.Polygons.ToIDArray(); //Context.Polygons[i].sheet.Id; Transform[] polygonsTransforms = Context.Polygons.GetTransforms(); this.transforms = new Transform[scalesInv.Length]; List <int> polygonIDinSheet = new List <int>(); for (int i = 0; i < scalesInv.Length; i++) { if (Context.Polygons[i].fitted) { this.transforms[i] = scalesInv[i] * Transform.Translation(new Vector3d(this.x * Context.Polygons[i].sheet.id, 0, 0)) * polygonsTransforms[i] * orient[i] * scales[i]; polygonIDinSheet.Add(Context.Polygons[i].sheet.id); } else { this.transforms[i] = Transform.Translation(new Vector3d(0, 0, 0)); //this.transforms[i] = scalesInv[i] * polygonsTransforms[i] * orient[i] * scales[i]; polygonIDinSheet.Add(-1); } } for (int i = 0; i < n; i++) { IGH_GeometricGoo goo = geo_Original[i].DuplicateGeometry(); //if not duplicated grasshopper will change original ones goo.Transform(transforms[i]); geo[i] = goo; } for (int i = 0; i < sheetsRhino.Length; i++) { sheetsRhino[i].Transform(Transform.Scale(Point3d.Origin, tolerance)); } ////////////Output//////////// DA.SetDataList(0, sheetsRhino); //Sheets DA.SetDataList(1, geo); //Surfaces or outlines DA.SetDataList(2, id); //ID DA.SetDataList(3, transforms); //transformations DA.SetDataList(4, polygonIDinSheet); } catch (Exception e) { base.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.ToString()); } }