/// <summary> /// Match the number of values of two given data structure, modifing the one with less elements. GH_Curve => GH_Plane /// </summary> /// <param name="refGhCurves"></param> /// <param name="inputPlanes"></param> /// <param name="outputPlanes"></param> /// <returns></returns> public static GH_Structure <GH_Plane> PlanesDSFromCurves(GH_Structure <GH_Curve> refGhCurves, GH_Structure <GH_Plane> inputPlanes, GH_Structure <GH_Plane> outputPlanes) { bool planesTopoEqualCurvesTopo = refGhCurves.TopologyDescription.Equals(inputPlanes.TopologyDescription); if (planesTopoEqualCurvesTopo) { outputPlanes = inputPlanes.Duplicate(); } else { foreach (GH_Path ghPath in refGhCurves.Paths) { for (int i = 0; i < refGhCurves.get_Branch(ghPath).Count; i++) { outputPlanes.Insert(inputPlanes.get_LastItem(true), ghPath, i); } } } return(outputPlanes); }
/// <summary> /// Match the number of values of two given data structure, modifing the one with less elements. GH_Breps => GH_Numbers /// </summary> /// <param name="inGhBreps"></param> /// <param name="inGhNums"></param> /// <param name="outGhNums"></param> /// <returns></returns> public static GH_Structure <GH_Number> NumbersDSFromBreps(GH_Structure <GH_Brep> inGhBreps, GH_Structure <GH_Number> inGhNums, GH_Structure <GH_Number> outGhNums) { bool brepTopoEqualNumsTopo = inGhNums.TopologyDescription.Equals(inGhBreps.TopologyDescription); if (brepTopoEqualNumsTopo) { outGhNums = inGhNums.Duplicate(); } else { foreach (GH_Path ghPath in inGhBreps.Paths) { for (int i = 0; i < inGhBreps.get_Branch(ghPath).Count; i++) { outGhNums.Insert(inGhNums.get_LastItem(true), ghPath, i); } } } return(outGhNums); }
/// <summary> /// Match the number of values of two given data structure, modifing the one with less elements. GH_Breps => GH_Boolean /// </summary> /// <param name="inGhBreps"></param> /// <param name="inGhBool"></param> /// <param name="outGhBool"></param> /// <returns></returns> public static GH_Structure <GH_Boolean> BoolDSFromBreps(GH_Structure <GH_Brep> inGhBreps, GH_Structure <GH_Boolean> inGhBool, GH_Structure <GH_Boolean> outGhBool) { bool brepTopologyEqualBoolTopology = inGhBool.TopologyDescription.Equals(inGhBreps.TopologyDescription); if (brepTopologyEqualBoolTopology) { outGhBool = inGhBool.Duplicate(); } else { foreach (GH_Path ghPath in inGhBreps.Paths) { for (int i = 0; i < inGhBreps.get_Branch(ghPath).Count; i++) { outGhBool.Insert(inGhBool.get_LastItem(true), ghPath, i); } } } return(outGhBool); }
/// <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 <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); int zoom = -1; DA.GetData <int>(1, ref zoom); string fileloc = ""; DA.GetData <string>(2, ref fileloc); if (!fileloc.EndsWith(@"\")) { fileloc = fileloc + @"\"; } string prefix = ""; DA.GetData <string>(3, ref prefix); if (prefix == "") { prefix = mbSource; } string URL = mbURL; //DA.GetData<string>(4, ref URL); string mbToken = ""; DA.GetData <string>(4, ref mbToken); if (mbToken == "") { string hmbToken = System.Environment.GetEnvironmentVariable("HERONMAPBOXTOKEN"); if (hmbToken != null) { mbToken = hmbToken; AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using Mapbox token stored in Environment Variable HERONMAPBOXTOKEN."); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Mapbox token is specified. Please get a valid token from mapbox.com"); return; } } bool run = false; DA.GetData <bool>("Run", ref run); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_Curve> imgFrame = new GH_Structure <GH_Curve>(); GH_Structure <GH_String> tCount = new GH_Structure <GH_String>(); GH_Structure <GH_Mesh> tMesh = new GH_Structure <GH_Mesh>(); for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); int tileTotalCount = 0; int tileDownloadedCount = 0; ///Get image frame for given boundary if (!boundary[i].GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary[i].GetBoundingBox(true); ///TODO: look into scaling boundary to get buffer tiles ///file path for final image string imgPath = fileloc + prefix + "_" + i + ".png"; //location of final image file mapList.Append(new GH_String(imgPath), path); //create cache folder for images string cacheLoc = fileloc + @"HeronCache\"; List <string> cacheFileLocs = new List <string>(); if (!Directory.Exists(cacheLoc)) { Directory.CreateDirectory(cacheLoc); } //tile bounding box array List <Point3d> boxPtList = new List <Point3d>(); //get the tile coordinates for all tiles within boundary var ranges = Convert.GetTileRange(boundaryBox, zoom); List <List <int> > tileList = new List <List <int> >(); var x_range = ranges.XRange; var y_range = ranges.YRange; if (x_range.Length > 100 || y_range.Length > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This tile range is too big (more than 100 tiles in the x or y direction). Check your units."); return; } //cycle through tiles to get bounding box for (int y = (int)y_range.Min; y <= y_range.Max; y++) { for (int x = (int)x_range.Min; x <= x_range.Max; x++) { //add bounding box of tile to list boxPtList.AddRange(Convert.GetTileAsPolygon(zoom, y, x).ToList()); cacheFileLocs.Add(cacheLoc + mbSource.Replace(" ", "") + zoom + x + y + ".png"); tileTotalCount = tileTotalCount + 1; } } tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); //bounding box of tile boundaries BoundingBox bboxPts = new BoundingBox(boxPtList); //convert bounding box to polyline List <Point3d> imageCorners = bboxPts.GetCorners().ToList(); imageCorners.Add(imageCorners[0]); imgFrame.Append(new GH_Curve(new Rhino.Geometry.Polyline(imageCorners).ToNurbsCurve()), path); //tile range as string for (de)serialization of TileCacheMeta string tileRangeString = zoom.ToString() + x_range[0].ToString() + y_range[0].ToString() + x_range[1].ToString() + y_range[1].ToString(); //check if the existing final image already covers the boundary. //if so, no need to download more or reassemble the cached tiles. ///temporarily disable until how to tag images with meta data is figured out /* * if (TileCacheMeta == tileRangeString && Convert.CheckCacheImagesExist(cacheFileLocs)) * { * if (File.Exists(imgPath)) * { * using (Bitmap imageT = new Bitmap(imgPath)) * { * //System.Drawing.Imaging.PropertyItem prop = imageT.GetPropertyItem(40092); * //string imgComment = Encoding.Unicode.GetString(prop.Value); * string imgComment = imageT.GetCommentsFromImage(); * //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, imgComment); * imageT.Dispose(); * //check to see if tilerange in comments matches current tilerange * if (imgComment == (mbSource.Replace(" ", "") + tileRangeString)) * { * AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using existing topo image."); * * Mesh eMesh = TopoMeshFromImage(imgPath, boundaryBox, zoom); * tMesh.Append(new GH_Mesh(eMesh), path); * continue; * } * * } * * } * * } */ ///Query Mapbox URL ///download all tiles within boundary ///merge tiles into one bitmap ///API to query ///string mbURL = "https://api.mapbox.com/v4/mapbox.terrain-rgb/{z}/{x}/{y}@2x.pngraw?access_token=" + mbToken; string mbURLauth = mbURL + mbToken; ///Do the work of assembling image ///setup final image container bitmap int fImageW = ((int)x_range.Length + 1) * 512; int fImageH = ((int)y_range.Length + 1) * 512; Bitmap finalImage = new Bitmap(fImageW, fImageH, System.Drawing.Imaging.PixelFormat.Format32bppArgb); int imgPosW = 0; int imgPosH = 0; if (run == true) { using (Graphics g = Graphics.FromImage(finalImage)) { g.Clear(Color.Black); for (int y = (int)y_range.Min; y <= (int)y_range.Max; y++) { for (int x = (int)x_range.Min; x <= (int)x_range.Max; x++) { //create tileCache name string tileCache = mbSource.Replace(" ", "") + zoom + x + y + ".png"; string tileCahceLoc = cacheLoc + tileCache; //check cache folder to see if tile image exists locally if (File.Exists(tileCahceLoc)) { Bitmap tmpImage = new Bitmap(Image.FromFile(tileCahceLoc)); //add tmp image to final g.DrawImage(tmpImage, imgPosW * 512, imgPosH * 512); tmpImage.Dispose(); } else { tileList.Add(new List <int> { zoom, y, x }); string urlAuth = Convert.GetZoomURL(x, y, zoom, mbURLauth); System.Net.WebClient client = new System.Net.WebClient(); client.DownloadFile(urlAuth, tileCahceLoc); Bitmap tmpImage = new Bitmap(Image.FromFile(tileCahceLoc)); client.Dispose(); //add tmp image to final g.DrawImage(tmpImage, imgPosW * 512, imgPosH * 512); tmpImage.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } //increment x insert position, goes left to right imgPosW++; } //increment y insert position, goes top to bottom imgPosH++; imgPosW = 0; } //garbage collection g.Dispose(); //add tile range meta data to image comments finalImage.AddCommentsToPNG(mbSource.Replace(" ", "") + tileRangeString); //save out assembled image finalImage.Save(imgPath, System.Drawing.Imaging.ImageFormat.Png); } } //garbage collection finalImage.Dispose(); //add to tile count total tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); Mesh nMesh = TopoMeshFromImage(imgPath, boundaryBox, zoom); //mesh.Flip(true, true, true); tMesh.Append(new GH_Mesh(nMesh), path); //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, tCount); DA.SetDataTree(3, tMesh); DA.SetDataList(4, "copyright Mapbox"); }
/// <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 INPUTS // import silkwormSettings file List<string> silkwormSettings = new List<string>(); if (!DA.GetDataList(0, silkwormSettings)) return; List<GH_ObjectWrapper> things = new List<GH_ObjectWrapper>(); if (!DA.GetDataList(1, things)) return; // import Silkworm Movement #endregion SilkwormUtility sUtil = new SilkwormUtility(); Dictionary<string, string> Settings = sUtil.convertSettings(silkwormSettings); #region Optional Variables int shell = -999; if (!DA.GetData(4, ref shell)) { } double layerheight = -999; if (!DA.GetData(3, ref layerheight)) { } //bool detect = false; //if (!DA.GetData(5, ref detect)) { } List<Plane> sliceplanes = new List<Plane>(); if (!DA.GetDataList(2, sliceplanes)) { } if (shell == -999) { shell = int.Parse(Settings["perimeters"]); } if (layerheight == -999) { layerheight = double.Parse(Settings["layer_height"]); } if (sliceplanes.Count<1) { sliceplanes.Add(Plane.WorldXY); } #endregion List<Brep> Breps = new List<Brep>(); List<Mesh> Meshes = new List<Mesh>(); SilkwormSkein skein = new SilkwormSkein(); #region Sort Types foreach (GH_ObjectWrapper obj in things) { if (obj.Value is GH_Brep) { Brep brep = null; GH_Convert.ToBrep(obj.Value, ref brep, GH_Conversion.Both); Breps.Add(brep); continue; } if (obj.Value is GH_Mesh) { Mesh mesh = null; GH_Convert.ToMesh(obj.Value, ref mesh, GH_Conversion.Both); Meshes.Add(mesh); continue; } } #endregion if (Breps.Count>0) { skein = new SilkwormSkein(Settings, Breps, sliceplanes, shell, layerheight); skein.BrepSlice(false); } if (Meshes.Count > 0) { //TODO } //Reflect Errors and Warnings foreach (string message in skein.ErrorMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, message); } foreach (string message in skein.WarningMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, message); } List<Curve>[] openregions = skein.openRegions; List<Brep>[] rRegions = skein.Regions; List<Brep>[] rPerimeterR = skein.regionPerimeter; List<Brep>[] rInfillR = skein.regionInfill; GH_Structure<GH_Brep> Regions = new GH_Structure<GH_Brep>(); GH_Structure<GH_Curve> openRegions = new GH_Structure<GH_Curve>(); #region Add Regions to GH_Structure if (rRegions.GetUpperBound(0) > 1) { for (int i = 0; i < rRegions.Length; i++) { if (rRegions[i] != null) { for (int j = 0; j < rRegions[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rRegions[i][j]); Regions.Insert(gShapes, new GH_Path(i, 0), j); } } } } if (rPerimeterR.GetUpperBound(0) > 1) { for (int i = 0; i < rPerimeterR.Length; i++) { if (rPerimeterR[i] != null) { for (int j = 0; j < rPerimeterR[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rPerimeterR[i][j]); Regions.Insert(gShapes, new GH_Path(i, 1), j); } } } } if (rInfillR.GetUpperBound(0) > 1) { for (int i = 0; i < rInfillR.Length; i++) { if (rInfillR[i] != null) { for (int j = 0; j < rInfillR[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rInfillR[i][j]); Regions.Insert(gShapes, new GH_Path(i, 2), j); } } } } if (openregions.GetUpperBound(0) > 1) { for (int i = 0; i < openregions.Length; i++) { if (openregions[i] != null) { for (int j = 0; j < openregions[i].Count; j++) { GH_Curve gShapes = new GH_Curve(openregions[i][j]); openRegions.Insert(gShapes, new GH_Path(i), j); } } } } //TODO //Add Overhang and Bridges #endregion #region Add Open Regions to GH_Structure if (openregions.GetUpperBound(0) > 1) { for (int i = 0; i < openregions.Length; i++) { for (int j = 0; j < openregions[i].Count; j++) { if (openregions[i][j] != null) { SilkwormSegment segment = new SilkwormSegment(openregions[i][j]); Curve curve = segment.Pline.ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(curve); openRegions.Insert(gShapes, new GH_Path(i), j); } } } } #endregion #region OUTPUT if (!DA.SetDataTree(0, Regions)) { return; } if (!DA.SetDataTree(1, openRegions)) { return; } #endregion }
/// <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 INPUTS // import silkwormSettings file List <string> silkwormSettings = new List <string>(); if (!DA.GetDataList(0, silkwormSettings)) { return; } List <GH_ObjectWrapper> things = new List <GH_ObjectWrapper>(); if (!DA.GetDataList(1, things)) { return; } // import Silkworm Movement #endregion SilkwormUtility sUtil = new SilkwormUtility(); Dictionary <string, string> Settings = sUtil.convertSettings(silkwormSettings); #region Optional Variables int shell = -999; if (!DA.GetData(4, ref shell)) { } double layerheight = -999; if (!DA.GetData(3, ref layerheight)) { } //bool detect = false; //if (!DA.GetData(5, ref detect)) { } List <Plane> sliceplanes = new List <Plane>(); if (!DA.GetDataList(2, sliceplanes)) { } if (shell == -999) { shell = int.Parse(Settings["perimeters"]); } if (layerheight == -999) { layerheight = double.Parse(Settings["layer_height"]); } if (sliceplanes.Count < 1) { sliceplanes.Add(Plane.WorldXY); } #endregion List <Brep> Breps = new List <Brep>(); List <Mesh> Meshes = new List <Mesh>(); SilkwormSkein skein = new SilkwormSkein(); #region Sort Types foreach (GH_ObjectWrapper obj in things) { if (obj.Value is GH_Brep) { Brep brep = null; GH_Convert.ToBrep(obj.Value, ref brep, GH_Conversion.Both); Breps.Add(brep); continue; } if (obj.Value is GH_Mesh) { Mesh mesh = null; GH_Convert.ToMesh(obj.Value, ref mesh, GH_Conversion.Both); Meshes.Add(mesh); continue; } } #endregion if (Breps.Count > 0) { skein = new SilkwormSkein(Settings, Breps, sliceplanes, shell, layerheight); skein.BrepSlice(false); } if (Meshes.Count > 0) { //TODO } //Reflect Errors and Warnings foreach (string message in skein.ErrorMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, message); } foreach (string message in skein.WarningMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, message); } List <Curve>[] openregions = skein.openRegions; List <Brep>[] rRegions = skein.Regions; List <Brep>[] rPerimeterR = skein.regionPerimeter; List <Brep>[] rInfillR = skein.regionInfill; GH_Structure <GH_Brep> Regions = new GH_Structure <GH_Brep>(); GH_Structure <GH_Curve> openRegions = new GH_Structure <GH_Curve>(); #region Add Regions to GH_Structure if (rRegions.GetUpperBound(0) > 1) { for (int i = 0; i < rRegions.Length; i++) { if (rRegions[i] != null) { for (int j = 0; j < rRegions[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rRegions[i][j]); Regions.Insert(gShapes, new GH_Path(i, 0), j); } } } } if (rPerimeterR.GetUpperBound(0) > 1) { for (int i = 0; i < rPerimeterR.Length; i++) { if (rPerimeterR[i] != null) { for (int j = 0; j < rPerimeterR[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rPerimeterR[i][j]); Regions.Insert(gShapes, new GH_Path(i, 1), j); } } } } if (rInfillR.GetUpperBound(0) > 1) { for (int i = 0; i < rInfillR.Length; i++) { if (rInfillR[i] != null) { for (int j = 0; j < rInfillR[i].Count; j++) { GH_Brep gShapes = new GH_Brep(rInfillR[i][j]); Regions.Insert(gShapes, new GH_Path(i, 2), j); } } } } if (openregions.GetUpperBound(0) > 1) { for (int i = 0; i < openregions.Length; i++) { if (openregions[i] != null) { for (int j = 0; j < openregions[i].Count; j++) { GH_Curve gShapes = new GH_Curve(openregions[i][j]); openRegions.Insert(gShapes, new GH_Path(i), j); } } } } //TODO //Add Overhang and Bridges #endregion #region Add Open Regions to GH_Structure if (openregions.GetUpperBound(0) > 1) { for (int i = 0; i < openregions.Length; i++) { for (int j = 0; j < openregions[i].Count; j++) { if (openregions[i][j] != null) { SilkwormSegment segment = new SilkwormSegment(openregions[i][j]); Curve curve = segment.Pline.ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(curve); openRegions.Insert(gShapes, new GH_Path(i), j); } } } } #endregion #region OUTPUT if (!DA.SetDataTree(0, Regions)) { return; } if (!DA.SetDataTree(1, openRegions)) { return; } #endregion }
protected override void SolveInstance(IGH_DataAccess DA) { //bool inputLock = false; string key = "Leopard(" + this.InstanceGuid + ")"; GH_Structure <IGH_GeometricGoo> inGeoTree; if (!DA.GetDataTree <IGH_GeometricGoo>(0, out inGeoTree)) { return; } //clear all stored selection if (resetStoredPath) { storedPath.Clear(); } //delete the preview baked objects if (!freezePreviewObjects) { RemovePreviewObjects(); } //generate the preview baked objects if (!inputLock && (generatePreview || !freezePreviewObjects)) { GeneratePreViewObjectsI(inGeoTree); // && !freezePreviewObjects) } //happens when unlock //if (addSelection) // SelectStoredPathObj(storedPath); GH_Structure <GH_String> pathTree = new GH_Structure <GH_String>(); //a tree that the data stored is its path for (int i = 0; i < inGeoTree.PathCount; i++) { string path = inGeoTree.Paths[i].ToString(); for (int j = 0; j < inGeoTree.Branches[i].Count; j++) { string str = path + "(" + j.ToString() + ")"; pathTree.Append(new GH_String(str)); } } List <string> pathOrder = new List <string>(); foreach (GH_String s in pathTree.AllData(false)) { pathOrder.Add(s.ToString()); } GH_Structure <GH_Integer> orderTree = new GH_Structure <GH_Integer>(); //a tree that the data is the order of each data, this tree is reference for sorting for (int i = 0; i < pathOrder.Count; i++) { string[] pathSeg; string indSeg; GH_Path.SplitPathLikeString(pathOrder[i], out pathSeg, out indSeg); int[] pInd = System.Array.ConvertAll(pathSeg, str => System.Convert.ToInt32(str)); int index = System.Convert.ToInt32(indSeg); orderTree.Insert(new GH_Integer(i), new GH_Path(pInd), index); } GH_Structure <IGH_Goo> outGeoTree = new GH_Structure <IGH_Goo>(); List <IGH_Goo> outGeoList = new List <IGH_Goo>(); GH_Structure <IGH_Goo> outPathTree = new GH_Structure <IGH_Goo>(); List <IGH_Goo> outPathList = new List <IGH_Goo>(); GH_Structure <IGH_Goo> outIndTree = new GH_Structure <IGH_Goo>(); List <IGH_Goo> outIndList = new List <IGH_Goo>(); GH_Structure <GH_Integer> outOrderTree = new GH_Structure <GH_Integer>(); List <GH_Integer> outOrderList = new List <GH_Integer>(); for (int i = 0; i < storedPath.Count; i++) { string p = pathOrder[System.Convert.ToInt32(storedPath[i])]; string[] pathSeg; string indSeg; if (GH_Path.SplitPathLikeString(p, out pathSeg, out indSeg)) { int[] pInd = System.Array.ConvertAll(pathSeg, str => System.Convert.ToInt32(str)); GH_Path path = new GH_Path(pInd); int index = System.Convert.ToInt32(indSeg); if (maintainPath) { outGeoTree.Append((IGH_GeometricGoo)inGeoTree.get_Branch(path)[index], path); outPathTree.Append(new GH_String(path.ToString()), path); outIndTree.Append(new GH_Integer(index), path); outOrderTree.Append((GH_Integer)(orderTree.get_Branch(path)[index]), path); } else { outGeoList.Add((IGH_GeometricGoo)inGeoTree.get_Branch(path)[index]); outPathList.Add(new GH_String(path.ToString())); outIndList.Add(new GH_Integer(index)); outOrderList.Add((GH_Integer)orderTree.get_Branch(path)[index]); } } } if (maintainPath) { if (this.sortByIndex) { outGeoTree = SortTreeByIndex(outGeoTree, outOrderTree); outIndTree = SortTreeByIndex(outIndTree, outOrderTree); } DA.SetDataTree(0, outGeoTree); DA.SetDataTree(1, outPathTree); DA.SetDataTree(2, outIndTree); DA.SetDataTree(3, outOrderTree); } else { if (this.sortByIndex) { List <IGH_Goo> gooCopy = outGeoList; outGeoList.Sort(new SelectCompareGoo(gooCopy, outOrderList)); gooCopy = outPathList; outPathList.Sort(new SelectCompareGoo(gooCopy, outOrderList)); gooCopy = outIndList; outIndList.Sort(new SelectCompareGoo(gooCopy, outOrderList)); } DA.SetDataList(0, outGeoList); DA.SetDataList(1, outPathList); DA.SetDataList(2, outIndList); DA.SetDataTree(3, outOrderTree); } }
/// <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 <Curve> boundary = new List <Curve>(); DA.GetDataList(0, boundary); int zoom = -1; DA.GetData(1, ref zoom); string filePath = string.Empty; DA.GetData(2, ref filePath); if (!filePath.EndsWith(@"\")) { filePath = filePath + @"\"; } string prefix = string.Empty; DA.GetData(3, ref prefix); if (prefix == string.Empty) { prefix = slippySource; } string URL = slippyURL; //DA.GetData<string>(4, ref URL); string userAgent = string.Empty; DA.GetData(4, ref userAgent); bool run = false; DA.GetData <bool>("Run", ref run); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); GH_Structure <GH_String> tCount = new GH_Structure <GH_String>(); for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); int tileTotalCount = 0; int tileDownloadedCount = 0; ///Get image frame for given boundary and make sure it's valid if (!boundary[i].GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary[i].GetBoundingBox(true); ///TODO: look into scaling boundary to get buffer tiles ///file path for final image string imgPath = filePath + prefix + "_" + i + ".jpg"; ///location of final image file mapList.Append(new GH_String(imgPath), path); ///create cache folder for images string cacheLoc = filePath + @"HeronCache\"; List <string> cachefilePaths = new List <string>(); if (!Directory.Exists(cacheLoc)) { Directory.CreateDirectory(cacheLoc); } ///tile bounding box array List <Point3d> boxPtList = new List <Point3d>(); ///get the tile coordinates for all tiles within boundary var ranges = Convert.GetTileRange(boundaryBox, zoom); List <List <int> > tileList = new List <List <int> >(); var x_range = ranges.XRange; var y_range = ranges.YRange; if (x_range.Length > 100 || y_range.Length > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This tile range is too big (more than 100 tiles in the x or y direction). Check your units."); return; } ///cycle through tiles to get bounding box for (int y = (int)y_range.Min; y <= y_range.Max; y++) { for (int x = (int)x_range.Min; x <= x_range.Max; x++) { ///add bounding box of tile to list boxPtList.AddRange(Convert.GetTileAsPolygon(zoom, y, x).ToList()); cachefilePaths.Add(cacheLoc + slippySource.Replace(" ", "") + zoom + x + y + ".jpg"); tileTotalCount = tileTotalCount + 1; } } tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); ///bounding box of tile boundaries BoundingBox bbox = new BoundingBox(boxPtList); var rect = BBoxToRect(bbox); imgFrame.Append(new GH_Rectangle(rect), path); AddPreviewItem(imgPath, boundary[i], rect); ///tile range as string for (de)serialization of TileCacheMeta string tileRangeString = zoom.ToString() + x_range[0].ToString() + y_range[0].ToString() + x_range[1].ToString() + y_range[1].ToString(); ///check if the existing final image already covers the boundary. ///if so, no need to download more or reassemble the cached tiles. if ((TileCacheMeta == tileRangeString) && Convert.CheckCacheImagesExist(cachefilePaths)) { if (File.Exists(imgPath)) { using (Bitmap imageT = new Bitmap(imgPath)) { ///getting commments currently only working for JPG ///TODO: get this to work for any image type or ///find another way to check if the cached image covers the boundary. string imgComment = imageT.GetCommentsFromJPG(); imageT.Dispose(); ///check to see if tilerange in comments matches current tilerange if (imgComment == (slippySource.Replace(" ", "") + tileRangeString)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using existing image."); continue; } } } } ///Query Slippy URL ///download all tiles within boundary ///merge tiles into one bitmap ///API to query ///Do the work of assembling image ///setup final image container bitmap int fImageW = ((int)x_range.Length + 1) * 256; int fImageH = ((int)y_range.Length + 1) * 256; Bitmap finalImage = new Bitmap(fImageW, fImageH); int imgPosW = 0; int imgPosH = 0; if (run == true) { using (Graphics g = Graphics.FromImage(finalImage)) { g.Clear(Color.Black); for (int y = (int)y_range.Min; y <= (int)y_range.Max; y++) { for (int x = (int)x_range.Min; x <= (int)x_range.Max; x++) { //create tileCache name string tileCache = slippySource.Replace(" ", "") + zoom + x + y + ".jpg"; string tileCacheLoc = cacheLoc + tileCache; //check cache folder to see if tile image exists locally if (File.Exists(tileCacheLoc)) { Bitmap tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); ///add tmp image to final g.DrawImage(tmpImage, imgPosW * 256, imgPosH * 256); tmpImage.Dispose(); } else { tileList.Add(new List <int> { zoom, y, x }); string urlAuth = Convert.GetZoomURL(x, y, zoom, slippyURL); System.Net.WebClient client = new System.Net.WebClient(); ///insert header if required client.Headers.Add("user-agent", userAgent); client.DownloadFile(urlAuth, tileCacheLoc); Bitmap tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); client.Dispose(); //add tmp image to final g.DrawImage(tmpImage, imgPosW * 256, imgPosH * 256); tmpImage.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } //increment x insert position, goes left to right imgPosW++; } //increment y insert position, goes top to bottom imgPosH++; imgPosW = 0; } //garbage collection g.Dispose(); //add tile range meta data to image comments finalImage.AddCommentsToJPG(slippySource.Replace(" ", "") + tileRangeString); //save the image finalImage.Save(imgPath, System.Drawing.Imaging.ImageFormat.Jpeg); } } //garbage collection finalImage.Dispose(); //add to tile count total tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; } DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, tCount); ///Add copyright info here DA.SetDataList(3, ""); }
protected override void SolveInstance(IGH_DataAccess DA) { //bool inputLock = false; string key = "Leopard(" + this.InstanceGuid + ")"; GH_Structure <IGH_GeometricGoo> inGeoTree; if (!DA.GetDataTree <IGH_GeometricGoo>(0, out inGeoTree)) { return; } GH_Structure <IGH_GeometricGoo> ptsGoo = new GH_Structure <IGH_GeometricGoo>(); for (int i = 0; i < inGeoTree.PathCount; i++) { for (int j = 0; j < inGeoTree.Branches[i].Count; j++) { Mesh mesh; if (!inGeoTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { GH_Path path = inGeoTree.get_Path(i); List <int> newPath = new List <int>(); for (int p = 0; p < path.Indices.Length; p++) { newPath.Add(path.Indices[p]); } PlanktonMesh pMesh = mesh.ToPlanktonMesh(); IEnumerable <Point3d> pts = pMesh.GetPositions(); foreach (Point3d p in pts) { if (inGeoTree.PathCount == 1) { ptsGoo.Append(GH_Convert.ToGeometricGoo(p), inGeoTree.get_Path(i)); } else { ptsGoo.Append(GH_Convert.ToGeometricGoo(p), new GH_Path(newPath.ToArray())); } } } } } //ptsGoo.Simplify(GH_SimplificationMode.CollapseLeadingOverlaps); //clear all stored selection if (resetStoredPath) { storedPath.Clear(); } //delete the preview baked objects if (!freezePreviewObjects) { RemovePreviewObjects(); } //generate the preview baked objects if (!inputLock && (generatePreview || !freezePreviewObjects)) { GeneratePreViewObjectsI(ptsGoo); // && !freezePreviewObjects) } //happens when unlock //if (addSelection) // SelectStoredPathObj(storedPath); GH_Structure <GH_String> pathTree = new GH_Structure <GH_String>(); //a tree that the data stored is its path for (int i = 0; i < ptsGoo.PathCount; i++) { string path = ptsGoo.Paths[i].ToString(); for (int j = 0; j < ptsGoo.Branches[i].Count; j++) { string str = path + "(" + j.ToString() + ")"; pathTree.Append(new GH_String(str)); } } List <string> pathOrder = new List <string>(); foreach (GH_String s in pathTree.AllData(false)) { pathOrder.Add(s.ToString()); } GH_Structure <GH_Integer> orderTree = new GH_Structure <GH_Integer>(); //a tree that the data is the order of each data, this tree is reference for sorting for (int i = 0; i < pathOrder.Count; i++) { string[] pathSeg; string indSeg; GH_Path.SplitPathLikeString(pathOrder[i], out pathSeg, out indSeg); int[] pInd = System.Array.ConvertAll(pathSeg, str => System.Convert.ToInt32(str)); int index = System.Convert.ToInt32(indSeg); orderTree.Insert(new GH_Integer(i), new GH_Path(pInd), index); } GH_Structure <IGH_Goo> outGeoTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> outIndTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> outOrderTree = new GH_Structure <GH_Integer>(); for (int i = 0; i < storedPath.Count; i++) { string p = pathOrder[System.Convert.ToInt32(storedPath[i])]; string[] pathSeg; string indSeg; if (GH_Path.SplitPathLikeString(p, out pathSeg, out indSeg)) { int[] pInd = System.Array.ConvertAll(pathSeg, str => System.Convert.ToInt32(str)); GH_Path path = new GH_Path(pInd); int index = System.Convert.ToInt32(indSeg); outGeoTree.Append((IGH_GeometricGoo)ptsGoo.get_Branch(path)[index], path); outIndTree.Append(new GH_Integer(index), path); outOrderTree.Append((GH_Integer)(orderTree.get_Branch(path)[index]), path); } } if (this.sortByIndex) { outGeoTree = SortTreeByIndex(outGeoTree, outOrderTree); outIndTree = SortTreeByIndex(outIndTree, outOrderTree); } DA.SetDataTree(0, outGeoTree); DA.SetDataTree(1, outIndTree); }
public static GH_Structure <IGH_Goo> DictToGHStruct(string k, Dictionary <string, dynamic> dict) { GH_Structure <IGH_Goo> ghStructure = new GH_Structure <IGH_Goo>(); if (!(dict.Count == 0)) { if (dict.TryGetValue(k, out dynamic _dataDict)) { //if value is a dictionary .. if (_dataDict is Dictionary <string, dynamic> ) { foreach (dynamic _key in _dataDict.Keys) { foreach (dynamic _value in _dataDict[_key]) { if (int.TryParse(_key, out int _result)) { // if dictionary value is a list GH_Path p = new GH_Path(_result); if (_value is List <dynamic> ) { for (int i = 0; i < _value.Count; i++) { IGH_Goo goo = null; if (goo.CastFrom(_value[i])) { ghStructure.Insert(goo, p, i); } } } // if dictionary value is a single item else { IGH_Goo goo = null; if (goo.CastFrom(_value)) { ghStructure.Insert(goo, p, 0); } } } } } } /// if its a list else if (_dataDict is List <dynamic> ) { GH_Path p = new GH_Path(int.Parse(k)); for (int i = 0; i < _dataDict.Count; i++) { //if (GH_Goo.CastFrom(_dataDict[i])) // ghStructure.Insert(goo, p, i); } } else { GH_Path p = new GH_Path(int.Parse(k)); IGH_Goo goo = null; if (goo.CastFrom(_dataDict)) { ghStructure.Insert(goo, p, 0); } } } } return(ghStructure); }
/// <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 INPUTS // import silkwormSettings file List<string> silkwormSettings = new List<string>(); if (!DA.GetDataList(0, silkwormSettings)) return; List<Brep> things = new List<Brep>(); if (!DA.GetDataList(1, things)) return; // import Silkworm Movement SilkwormUtility sUtil = new SilkwormUtility(); Dictionary<string, string> Settings = sUtil.convertSettings(silkwormSettings); SilkwormCalculator calc = new SilkwormCalculator(Settings); #region Optional Inputs int infType = 0; if (!DA.GetData(2, ref infType)) { } List<double> spacing = new List<double>(); if (!DA.GetDataList(3, spacing)) { } List<double> infDens = new List<double>(); if (!DA.GetDataList(4, infDens)) { } List<double> infRot = new List<double>(); if (!DA.GetDataList(5, infRot)) { } #endregion if (spacing.Count<1) { spacing.Add(0.66); //TODO Calculator } if (infDens.Count < 1) { infDens.Add(double.Parse(Settings["fill_density"])); } if (infRot.Count < 1) { infRot.Add(double.Parse(Settings["fill_angle"])); } #endregion SilkwormSkein skein = new SilkwormSkein(Settings, things); //Switch depending on which infill type is selected by input if (infType == 0) { //Match length of data if (spacing.Count != things.Count) { List<double> newspacing = new List<double>(); for (int e = 0; e < things.Count; e++) { newspacing.Add(spacing[0]); } spacing = newspacing; } skein.Skinner(spacing); } if (infType == 1) { //Match length of data if (infDens.Count != things.Count) { List<double> newinfDens = new List<double>(); for (int e = 0; e < things.Count; e++) { newinfDens.Add(infDens[0]); } spacing = newinfDens; } if (infRot.Count != things.Count) { List<double> newinfRot = new List<double>(); for (int e = 0; e < things.Count; e++) { newinfRot.Add(infRot[0]); } spacing = newinfRot; } skein.Filler(infDens, infRot); } //Reflect Errors and Warnings foreach (string message in skein.ErrorMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, message); } foreach (string message in skein.WarningMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, message); } //Output Holders List<Curve>[] plPerimeter = skein.curvePerimeter; List<Curve>[] plInfill = skein.curveInfill; GH_Structure<GH_Curve> InfillRegion = new GH_Structure<GH_Curve>(); //Create GH_Structure #region Create Structure from Curves if (plPerimeter.Length > 0) { for (int i = 0; i < plPerimeter.Length; i++) { if (plPerimeter[i] != null) { for (int j = 0; j < plPerimeter[i].Count; j++) { Curve aShape = plPerimeter[i][j].ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(aShape); InfillRegion.Insert(gShapes, new GH_Path(i, 0), j); //} } } } } if (plInfill.Length > 0) { for (int i = 0; i < plInfill.Length; i++) { if (plInfill[i] != null) { for (int j = 0; j < plInfill[i].Count; j++) { Curve aShape = plInfill[i][j].ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(aShape); InfillRegion.Insert(gShapes, new GH_Path(i, 1), j); } } } } #endregion //Output if (!DA.SetDataTree(0, InfillRegion)) { return; } }
/// <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 <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); int zoom = -1; DA.GetData <int>(1, ref zoom); string folderPath = string.Empty; DA.GetData <string>(2, ref folderPath); if (!folderPath.EndsWith(@"\")) { folderPath = folderPath + @"\"; } string prefix = string.Empty; DA.GetData <string>(3, ref prefix); if (prefix == "") { prefix = mbSource; } string URL = mbURL; ///get a valid mapbox token to send along with query string mbToken = string.Empty; DA.GetData <string>(4, ref mbToken); if (mbToken == "") { string hmbToken = System.Environment.GetEnvironmentVariable("HERONMAPBOXTOKEN"); if (hmbToken != null) { mbToken = hmbToken; AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using Mapbox token stored in Environment Variable HERONMAPBOXTOKEN."); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "No Mapbox token is specified. Please get a valid token from mapbox.com"); return; } } bool run = false; DA.GetData <bool>("Run", ref run); GH_Structure <GH_String> mapList = new GH_Structure <GH_String>(); GH_Structure <GH_Rectangle> imgFrame = new GH_Structure <GH_Rectangle>(); GH_Structure <GH_String> tCount = new GH_Structure <GH_String>(); /* * ///Save for later development of warping * ///Setup for warping * RESTful.GdalConfiguration.ConfigureGdal(); * RESTful.GdalConfiguration.ConfigureOgr(); * * OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); * userSRS.SetFromUserInput("WGS84"); * * OSGeo.OSR.SpatialReference mapboxSRS = new OSGeo.OSR.SpatialReference(""); * mapboxSRS.SetFromUserInput("EPSG:3857"); * * ///Set transform from input spatial reference to Rhino spatial reference * OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); * rhinoSRS.SetWellKnownGeogCS("WGS84"); * * ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa * //Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); * Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); * Transform mapboxSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(mapboxSRS); * Transform modelToMapboxSRSTransform = Heron.Convert.GetModelToUserSRSTransform(mapboxSRS); */ for (int i = 0; i < boundary.Count; i++) { GH_Path path = new GH_Path(i); int tileTotalCount = 0; int tileDownloadedCount = 0; //Get image frame for given boundary and make sure it's valid if (!boundary[i].GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary[i].GetBoundingBox(true); ///TODO: look into scaling boundary to get buffer tiles ///file path for final image string imgPath = folderPath + prefix + "_" + i + ".jpg"; if (!tilesOut) { //location of final image file mapList.Append(new GH_String(imgPath), path); } //create cache folder for images string cacheLoc = folderPath + @"HeronCache\"; List <string> cacheFilePaths = new List <string>(); if (!Directory.Exists(cacheLoc)) { Directory.CreateDirectory(cacheLoc); } //tile bounding box array List <Point3d> boxPtList = new List <Point3d>(); //get the tile coordinates for all tiles within boundary var ranges = Convert.GetTileRange(boundaryBox, zoom); List <List <int> > tileList = new List <List <int> >(); var x_range = ranges.XRange; var y_range = ranges.YRange; if (x_range.Length > 100 || y_range.Length > 100) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "This tile range is too big (more than 100 tiles in the x or y direction). Check your units."); return; } List <Rectangle3d> tileRectangles = new List <Rectangle3d>(); //cycle through tiles to get bounding box for (int y = (int)y_range.Min; y <= y_range.Max; y++) { for (int x = (int)x_range.Min; x <= x_range.Max; x++) { //add bounding box of tile to list List <Point3d> boxPts = Convert.GetTileAsPolygon(zoom, y, x).ToList(); boxPtList.AddRange(boxPts); string cacheFilePath = cacheLoc + mbSource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".jpg"; cacheFilePaths.Add(cacheFilePath); tileTotalCount = tileTotalCount + 1; if (tilesOut) { mapList.Append(new GH_String(cacheFilePath), path); Rectangle3d tileRectangle = BBoxToRect(new BoundingBox(boxPts)); tileRectangles.Add(tileRectangle); imgFrame.Append(new GH_Rectangle(tileRectangle), path); } } } tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); //bounding box of tile boundaries BoundingBox bbox = new BoundingBox(boxPtList); var rect = BBoxToRect(bbox); if (!tilesOut) { imgFrame.Append(new GH_Rectangle(rect), path); } ///tile range as string for (de)serialization of TileCacheMeta string tileRangeString = zoom.ToString() + x_range[0].ToString() + y_range[0].ToString() + x_range[1].ToString() + y_range[1].ToString(); ///check if the existing final image already covers the boundary. ///if so, no need to download more or reassemble the cached tiles. if ((TileCacheMeta == tileRangeString) && Convert.CheckCacheImagesExist(cacheFilePaths)) { if (File.Exists(imgPath) && !tilesOut) { using (Bitmap imageT = new Bitmap(imgPath)) { ///getting commments currently only working for JPG ///TODO: get this to work for any image type or ///find another way to check if the cached image covers the boundary. string imgComment = string.Empty; ///Save for later development of warping //if (!warped) imgComment = imageT.GetCommentsFromJPG(); imageT.Dispose(); ///check to see if tilerange in comments matches current tilerange if (imgComment == (mbSource.Replace(" ", "") + tileRangeString)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Using existing image."); AddPreviewItem(imgPath, boundary[i], rect); continue; } } } if (tilesOut) { for (int t = 0; t < cacheFilePaths.Count; t++) { if (File.Exists(cacheFilePaths[t])) { AddPreviewItem(cacheFilePaths[t], tileRectangles[t].ToNurbsCurve(), tileRectangles[t]); } } continue; } } ///Query Mapbox URL ///download all tiles within boundary ///merge tiles into one bitmap ///API to query string mbURLauth = mbURL + mbToken; ///Do the work of assembling image ///setup final image container bitmap int fImageW = ((int)x_range.Length + 1) * 512; int fImageH = ((int)y_range.Length + 1) * 512; Bitmap finalImage = new Bitmap(fImageW, fImageH); int imgPosW = 0; int imgPosH = 0; /* * ///Save for later development of warping * List<GCP> gcpList = new List<GCP>(); */ using (Graphics g = Graphics.FromImage(finalImage)) { g.Clear(Color.Black); for (int y = (int)y_range.Min; y <= (int)y_range.Max; y++) { for (int x = (int)x_range.Min; x <= (int)x_range.Max; x++) { ///create tileCache name string tileCache = mbSource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".jpg"; string tileCacheLoc = cacheLoc + tileCache; /* * ///Save for later development of warping * ///Get GCPs for warping * Point3d tileCorner = Heron.Convert.GetTileAsPolygon(zoom, y, x)[3]; * var tileCorner3857 = Convert.Point3dToOgrPoint(tileCorner, modelToMapboxSRSTransform); * GCP gcp = new GCP(tileCorner3857.GetX(0), tileCorner3857.GetY(0), tileCorner3857.GetZ(0), imgPosW * 512, imgPosH * 512, tileCorner3857.ToString(), zoom + x + y + ""); * gcpList.Add(gcp); */ ///check cache folder to see if tile image exists locally if (File.Exists(tileCacheLoc)) { Bitmap tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); ///add tmp image to final g.DrawImage(tmpImage, imgPosW * 512, imgPosH * 512); tmpImage.Dispose(); } else { tileList.Add(new List <int> { zoom, y, x }); string urlAuth = Convert.GetZoomURL(x, y, zoom, mbURLauth); Bitmap tmpImage = new Bitmap(512, 512); System.Net.WebClient client = new System.Net.WebClient(); if (run == true) { try { client.DownloadFile(urlAuth, tileCacheLoc); tmpImage = new Bitmap(Image.FromFile(tileCacheLoc)); } catch (WebException e) { using (Graphics tmp = Graphics.FromImage(tmpImage)) { tmp.Clear(Color.White); } AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, e.Message); } } client.Dispose(); ///add tmp image to final g.DrawImage(tmpImage, imgPosW * 512, imgPosH * 512); tmpImage.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } ///increment x insert position, goes left to right imgPosW++; } ///increment y insert position, goes top to bottom imgPosH++; imgPosW = 0; } ///garbage collection g.Dispose(); ///add tile range meta data to image comments finalImage.AddCommentsToJPG(mbSource.Replace(" ", "") + tileRangeString); ///Save for later development of warping ///if (!warped) ///save the image finalImage.Save(imgPath, ImageFormat.Jpeg); } /* * ///Save for later development of warping * byte[] imageBuffer; * string memFilename = "/vsimem/inmemfile"; * string memTranslated = "/vsimem/inmemfileTranslated"; * string memWarped = "/vsimem/inmemfileWarped"; * using (MemoryStream stream = new MemoryStream()) * { * finalImage.Save(stream, ImageFormat.Jpeg); * imageBuffer = stream.ToArray(); * } */ //garbage collection finalImage.Dispose(); /* * ///Save for later development of warping * Gdal.FileFromMemBuffer(memFilename, imageBuffer); * Dataset gdalImage = Gdal.Open(memFilename, Access.GA_ReadOnly); * var upperLeft3857 = Convert.Point3dToOgrPoint(rect.Corner(3), modelToMapboxSRSTransform); * var lowerRight3857 = Convert.Point3dToOgrPoint(rect.Corner(1), modelToMapboxSRSTransform); * var upperLeft4326 = Convert.Point3dToOgrPoint(rect.Corner(3), modelToUserSRSTransform); * var lowerRight4326 = Convert.Point3dToOgrPoint(rect.Corner(1), modelToUserSRSTransform); * List<string> translateOptions = new List<string> { "-a_srs", "EPSG:3857", * "-r", "bilinear", * "-a_ullr", upperLeft3857.GetX(0).ToString(), upperLeft3857.GetY(0).ToString(), lowerRight3857.GetX(0).ToString(), lowerRight3857.GetY(0).ToString() }; * Dataset gdalTranslated = Gdal.wrapper_GDALTranslate(memTranslated, gdalImage, new GDALTranslateOptions(translateOptions.ToArray()), null, null); * * var wkt = gdalTranslated.GetProjection(); * //gdalTranslated.SetGCPs(gcpList.ToArray(), wkt); * * List<string> warpOptions = new List<string> { "-t_srs", "EPSG:4326", * "-r", "bilinear", * //"-multi", * //"-wo", "NUM_THREADS=6", * "-overwrite", * //"-order", "1", * //"-tps", * "-te_srs", "EPSG:3857", * "-te", upperLeft3857.GetX(0).ToString(), lowerRight3857.GetY(0).ToString(), lowerRight3857.GetX(0).ToString(), upperLeft3857.GetY(0).ToString() }; * * ///https://github.com/OSGeo/gdal/issues/813 * ///https://lists.osgeo.org/pipermail/gdal-dev/2017-February/046046.html * ///Odd way to go about setting source dataset in parameters for Warp is a known issue * * var ptr = new[] { Dataset.getCPtr(gdalTranslated).Handle }; * var gcHandle = GCHandle.Alloc(ptr, GCHandleType.Pinned); * try * { * var dss = new SWIGTYPE_p_p_GDALDatasetShadow(gcHandle.AddrOfPinnedObject(), false, null); * Dataset gdalWarped = Gdal.wrapper_GDALWarpDestName(memWarped, 1, dss, new GDALWarpAppOptions(warpOptions.ToArray()), null, null); * var driver = Gdal.GetDriverByName("JPEG"); * List<string> copyOptions = new List<string> { "QUALITY=95", "COMMENT=" + mbSource.Replace(" ", "") + tileRangeString}; * var copy = driver.CreateCopy(imgPath, gdalWarped, 0, copyOptions.ToArray(), null, null); * copy.Dispose(); * driver.Dispose(); * gdalWarped.Dispose(); * } * finally * { * if (gcHandle.IsAllocated) * gcHandle.Free(); * } * * gdalImage.Dispose(); * gdalTranslated.Dispose(); * Gdal.Unlink(memFilename); * Gdal.Unlink(memTranslated); * Gdal.Unlink(memWarped); */ if (!tilesOut) { AddPreviewItem(imgPath, boundary[i], rect); } else { for (int t = 0; t < cacheFilePaths.Count; t++) { if (File.Exists(cacheFilePaths[t])) { AddPreviewItem(cacheFilePaths[t], tileRectangles[t].ToNurbsCurve(), tileRectangles[t]); } } } //add to tile count total tCount.Insert(new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"), path, 0); //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; } List <string> mbAtts = new List <string> { "© Mapbox, © OpenStreetMap", "https://www.mapbox.com/about/maps/", "http://www.openstreetmap.org/copyright" }; DA.SetDataTree(0, mapList); DA.SetDataTree(1, imgFrame); DA.SetDataTree(2, tCount); DA.SetDataList(3, mbAtts); }
/// <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 INPUTS // import silkwormSettings file List <string> silkwormSettings = new List <string>(); if (!DA.GetDataList(0, silkwormSettings)) { return; } List <Brep> things = new List <Brep>(); if (!DA.GetDataList(1, things)) { return; } // import Silkworm Movement SilkwormUtility sUtil = new SilkwormUtility(); Dictionary <string, string> Settings = sUtil.convertSettings(silkwormSettings); SilkwormCalculator calc = new SilkwormCalculator(Settings); #region Optional Inputs int infType = 0; if (!DA.GetData(2, ref infType)) { } List <double> spacing = new List <double>(); if (!DA.GetDataList(3, spacing)) { } List <double> infDens = new List <double>(); if (!DA.GetDataList(4, infDens)) { } List <double> infRot = new List <double>(); if (!DA.GetDataList(5, infRot)) { } #endregion if (spacing.Count < 1) { spacing.Add(0.66); //TODO Calculator } if (infDens.Count < 1) { infDens.Add(double.Parse(Settings["fill_density"])); } if (infRot.Count < 1) { infRot.Add(double.Parse(Settings["fill_angle"])); } #endregion SilkwormSkein skein = new SilkwormSkein(Settings, things); //Switch depending on which infill type is selected by input if (infType == 0) { //Match length of data if (spacing.Count != things.Count) { List <double> newspacing = new List <double>(); for (int e = 0; e < things.Count; e++) { newspacing.Add(spacing[0]); } spacing = newspacing; } skein.Skinner(spacing); } if (infType == 1) { //Match length of data if (infDens.Count != things.Count) { List <double> newinfDens = new List <double>(); for (int e = 0; e < things.Count; e++) { newinfDens.Add(infDens[0]); } spacing = newinfDens; } if (infRot.Count != things.Count) { List <double> newinfRot = new List <double>(); for (int e = 0; e < things.Count; e++) { newinfRot.Add(infRot[0]); } spacing = newinfRot; } skein.Filler(infDens, infRot); } //Reflect Errors and Warnings foreach (string message in skein.ErrorMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, message); } foreach (string message in skein.WarningMessages) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, message); } //Output Holders List <Curve>[] plPerimeter = skein.curvePerimeter; List <Curve>[] plInfill = skein.curveInfill; GH_Structure <GH_Curve> InfillRegion = new GH_Structure <GH_Curve>(); //Create GH_Structure #region Create Structure from Curves if (plPerimeter.Length > 0) { for (int i = 0; i < plPerimeter.Length; i++) { if (plPerimeter[i] != null) { for (int j = 0; j < plPerimeter[i].Count; j++) { Curve aShape = plPerimeter[i][j].ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(aShape); InfillRegion.Insert(gShapes, new GH_Path(i, 0), j); //} } } } } if (plInfill.Length > 0) { for (int i = 0; i < plInfill.Length; i++) { if (plInfill[i] != null) { for (int j = 0; j < plInfill[i].Count; j++) { Curve aShape = plInfill[i][j].ToNurbsCurve(); GH_Curve gShapes = new GH_Curve(aShape); InfillRegion.Insert(gShapes, new GH_Path(i, 1), j); } } } } #endregion //Output if (!DA.SetDataTree(0, InfillRegion)) { return; } }