protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); GH_Structure <IGH_GeometricGoo> oDualMeshTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <IGH_GeometricGoo> oDualMeshCurveTree = new GH_Structure <IGH_GeometricGoo>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { oDualMeshTree.Append( GH_Convert.ToGeometricGoo(mesh.ToPlanktonMesh().Dual(0).ToRhinoMesh()), path); } } } DA.SetDataTree(0, oDualMeshTree); }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); GH_Structure <IGH_Goo> oVerticesTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oNormalsTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oNakedVerticesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oNakedIndicesTree = new GH_Structure <GH_Integer>(); GH_Structure <IGH_Goo> oClosedVerticesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oClosedIndicesTree = new GH_Structure <GH_Integer>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); PlanktonXYZ[] xyz = pMesh.Vertices.GetPositions(); PlanktonXYZ[] normals = pMesh.Vertices.GetNormals(); for (int v = 0; v < xyz.Length; v++) { oVerticesTree.Append(GH_Convert.ToGeometricGoo(xyz[v].ToPoint3d()), path); oNormalsTree.Append(GH_Convert.ToGeometricGoo(normals[v].ToVector3f()), path); if (pMesh.Vertices.IsBoundary(v)) { oNakedVerticesTree.Append(GH_Convert.ToGeometricGoo(xyz[v].ToPoint3d()), path); oNakedIndicesTree.Append(new GH_Integer(v), path); } else { oClosedVerticesTree.Append(GH_Convert.ToGeometricGoo(xyz[v].ToPoint3d()), path); oClosedIndicesTree.Append(new GH_Integer(v), path); } } } } } DA.SetDataTree(0, oVerticesTree); DA.SetDataTree(1, oNormalsTree); DA.SetDataTree(2, oNakedVerticesTree); DA.SetDataTree(3, oNakedIndicesTree); DA.SetDataTree(4, oClosedVerticesTree); DA.SetDataTree(5, oClosedIndicesTree); }
public static Mesh ParseToJoinedMesh(List <Brep> breps) { List <IGH_GeometricGoo> geometricGoos = new List <IGH_GeometricGoo>(); for (int i = 0; i < breps.Count; i++) { geometricGoos.Add(GH_Convert.ToGeometricGoo(new GH_Brep(breps[i]))); } return(ParseToJoinedMesh(geometricGoos, out _)); }
/*******************************************/ public static bool CastToGoo(object value, ref IGH_GeometricGoo target) { try { target = GH_Convert.ToGeometricGoo(value); return(true); } catch { return(false); } }
private ConcurrentQueue <Tuple <int, ConcurrentQueue <IGH_GeometricGoo>, FileTypes> > GetGeometricData(string path) { ConcurrentQueue <Tuple <int, ConcurrentQueue <IGH_GeometricGoo>, FileTypes> > data = new ConcurrentQueue <Tuple <int, ConcurrentQueue <IGH_GeometricGoo>, FileTypes> >(); ConcurrentQueue <string> filepaths; int gh_Path = 0; System.Globalization.CultureInfo EnglishCulture = new System.Globalization.CultureInfo("en-EN"); if (recursive) { filepaths = new ConcurrentQueue <string>(Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories)); } else { filepaths = new ConcurrentQueue <string>(Directory.EnumerateFiles(path, "*.*", SearchOption.TopDirectoryOnly)); } Parallel.ForEach(filepaths, file => { FileTypes extension = (FileTypes)Enum.Parse(typeof(FileTypes), Path.GetExtension(file).TrimStart('.').ToUpper()); switch (extension) { case FileTypes.XYZ: ConcurrentQueue <IGH_GeometricGoo> goo = new ConcurrentQueue <IGH_GeometricGoo>(); Parallel.ForEach(File.ReadLines(file), (line, _, lineNumber) => { string[] linedata = line.Split(','); if (linedata.Length == 3) { GH_Point p = new GH_Point(new Point3d(Convert.ToDouble(linedata[0], EnglishCulture), Convert.ToDouble(linedata[1], EnglishCulture), Convert.ToDouble(linedata[2], EnglishCulture))); goo.Enqueue(GH_Convert.ToGeometricGoo(p)); } }); data.Enqueue(new Tuple <int, ConcurrentQueue <IGH_GeometricGoo>, FileTypes>(gh_Path, goo, FileTypes.XYZ)); break; default: this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "File '" + file + "' - File type not supported"); break; } gh_Path++; }); return(data); }
/// <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) { Curve boundary = null; DA.GetData <Curve>(0, ref boundary); int zoom = -1; DA.GetData <int>(1, ref zoom); string filePath = string.Empty; DA.GetData <string>(2, ref filePath); if (!filePath.EndsWith(@"\")) { filePath = filePath + @"\"; } string prefix = string.Empty; DA.GetData <string>(3, ref prefix); if (prefix == "") { prefix = mbSource; } string URL = mbURL; 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); ///GDAL setup RESTful.GdalConfiguration.ConfigureOgr(); OSGeo.OGR.Ogr.RegisterAll(); RESTful.GdalConfiguration.ConfigureGdal(); GH_Curve imgFrame; GH_String tCount; GH_Structure <GH_String> fnames = new GH_Structure <GH_String>(); GH_Structure <GH_String> fvalues = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> gGoo = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_String> gtype = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> gGooBuildings = new GH_Structure <IGH_GeometricGoo>(); int tileTotalCount = 0; int tileDownloadedCount = 0; ///Get image frame for given boundary if (!boundary.GetBoundingBox(true).IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Boundary is not valid."); return; } BoundingBox boundaryBox = boundary.GetBoundingBox(true); //create cache folder for vector tiles 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); 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 List <Polyline> tileExtents = new List <Polyline>(); List <double> tileHeight = new List <double>(); List <double> tileWidth = new List <double>(); 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 for translation Polyline tileExtent = Heron.Convert.GetTileAsPolygon(zoom, y, x); tileExtents.Add(tileExtent); tileWidth.Add(tileExtent[0].DistanceTo(tileExtent[1])); tileHeight.Add(tileExtent[1].DistanceTo(tileExtent[2])); boxPtList.AddRange(tileExtent.ToList()); cachefilePaths.Add(cacheLoc + mbSource.Replace(" ", "") + zoom + "-" + x + "-" + y + ".mvt"); tileTotalCount = tileTotalCount + 1; } } tCount = new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"); ///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 = new GH_Curve(new Rhino.Geometry.Polyline(imageCorners).ToNurbsCurve()); ///tile range as string for (de)serialization of TileCacheMeta string tileRangeString = "Tile range for zoom " + zoom.ToString() + ": " + x_range[0].ToString() + "-" + y_range[0].ToString() + " to " + x_range[1].ToString() + "-" + y_range[1].ToString(); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, tileRangeString); ///Query Mapbox URL ///download all tiles within boundary ///API to query string mbURLauth = mbURL + mbToken; if (run == true) { 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 + ".mvt"; string tileCacheLoc = cacheLoc + tileCache; //check cache folder to see if tile image exists locally if (File.Exists(tileCacheLoc)) { } else { string urlAuth = Heron.Convert.GetZoomURL(x, y, zoom, mbURLauth); System.Net.WebClient client = new System.Net.WebClient(); client.DownloadFile(urlAuth, tileCacheLoc); client.Dispose(); ///https://gdal.org/development/rfc/rfc59.1_utilities_as_a_library.html ///http://osgeo-org.1560.x6.nabble.com/gdal-dev-How-to-convert-shapefile-to-geojson-using-c-bindings-td5390953.html#a5391028 ///ogr2ogr is slow //OSGeo.GDAL.Dataset httpDS = OSGeo.GDAL.Gdal.OpenEx("MVT:"+urlAuth,4,null,null,null); //var transOptions = new OSGeo.GDAL.GDALVectorTranslateOptions(new[] { "-s_srs","EPSG:3857", "-t_srs", "EPSG:4326","-skipfailures" }); //var transDS = OSGeo.GDAL.Gdal.wrapper_GDALVectorTranslateDestName(mvtLoc + zoom + "-" + x + "-" + y , httpDS, transOptions, null, null); //httpDS.Dispose(); //transDS.Dispose(); tileDownloadedCount = tileDownloadedCount + 1; } } } } //add to tile count total tCount = new GH_String(tileTotalCount + " tiles (" + tileDownloadedCount + " downloaded / " + (tileTotalCount - tileDownloadedCount) + " cached)"); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, tCount.ToString()); ///Build a VRT file ///https://stackoverflow.com/questions/55386597/gdal-c-sharp-wrapper-for-vrt-doesnt-write-a-vrt-file //string vrtFile = cacheLoc + "mapboxvector.vrt"; //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, vrtFile); //var vrtOptions = new OSGeo.GDAL.GDALBuildVRTOptions(new[] { "-overwrite" }); //var vrtDataset = OSGeo.GDAL.Gdal.wrapper_GDALBuildVRT_names(vrtFile, cachefilePaths.ToArray(), vrtOptions, null, null); //vrtDataset.Dispose(); ///Set transform from input spatial reference to Rhino spatial reference ///TODO: look into adding a step for transforming to CRS set in SetCRS OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference(""); rhinoSRS.SetWellKnownGeogCS("WGS84"); ///TODO: verify the userSRS is valid ///TODO: use this as override of global SetSRS OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference(""); //userSRS.SetFromUserInput(userSRStext); userSRS.SetFromUserInput("WGS84"); OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(""); sourceSRS.SetFromUserInput("EPSG:3857"); ///These transforms move and scale in order to go from userSRS to XYZ and vice versa Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS); Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS); Transform sourceToModelSRSTransform = Heron.Convert.GetUserSRSToModelTransform(sourceSRS); Transform modelToSourceSRSTransform = Heron.Convert.GetModelToUserSRSTransform(sourceSRS); //OSGeo.GDAL.Driver gdalOGR = OSGeo.GDAL.Gdal.GetDriverByName("VRT"); //var ds = OSGeo.GDAL.Gdal.OpenEx(vrtFile, 4, ["VRT","MVT"], null, null); int t = 0; foreach (string mvtTile in cachefilePaths)// cachefilePaths) { OSGeo.OGR.Driver drv = OSGeo.OGR.Ogr.GetDriverByName("MVT"); OSGeo.OGR.DataSource ds = OSGeo.OGR.Ogr.Open("MVT:" + mvtTile, 0); string[] mvtOptions = new[] { "CLIP", "NO" }; //OSGeo.OGR.DataSource ds = drv.Open(mvtTile, 0); if (ds == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The vector datasource was unreadable by this component. It may not a valid file type for this component or otherwise null/empty."); return; } ///Morph raw mapbox tile points to geolocated tile Vector3d moveDir = tileExtents[t].ElementAt(0) - new Point3d(0, 0, 0); Transform move = Transform.Translation(moveDir); Transform scale = Transform.Scale(Plane.WorldXY, tileWidth[t] / 4096, tileHeight[t] / 4096, 1); Transform scaleMove = Transform.Multiply(move, scale); for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++) { OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer); long count = layer.GetFeatureCount(1); int featureCount = System.Convert.ToInt32(count); AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Layer #" + iLayer + " " + layer.GetName() + " has " + featureCount + " features"); //if (layer.GetName() == "admin" || layer.GetName() == "building") //{ OSGeo.OGR.FeatureDefn def = layer.GetLayerDefn(); ///Get the field names List <string> fieldnames = new List <string>(); for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr); fnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(iLayer, t)); } ///Loop through geometry OSGeo.OGR.Feature feat; int m = 0; ///error "Self-intersection at or near point..." when zoom gets below 12 for water ///this is an issue with the way mvt simplifies geometries at lower zoom levels and is a known problem ///TODO: look into how to fix invalid geom and return to the typical while loop iterating method //while ((feat = layer.GetNextFeature()) != null) while (true) { try { feat = layer.GetNextFeature(); } catch { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Some features had invalid geometry and were skipped."); continue; } if (feat == null) { break; } OSGeo.OGR.Geometry geom = feat.GetGeometryRef(); ///reproject geometry to WGS84 and userSRS ///TODO: look into using the SetCRS global variable here gtype.Append(new GH_String(geom.GetGeometryName()), new GH_Path(iLayer, t, m)); Transform tr = scaleMove; // new Transform(1); if (feat.GetGeometryRef() != null) { ///Convert GDAL geometries to IGH_GeometricGoo foreach (IGH_GeometricGoo gMorphed in Heron.Convert.OgrGeomToGHGoo(geom, tr)) { //gMorphed.Morph(morph); gGoo.Append(gMorphed, new GH_Path(iLayer, t, m)); } if (layer.GetName() == "building") { if (feat.GetFieldAsString(def.GetFieldIndex("extrude")) == "true") { double unitsConversion = Rhino.RhinoMath.UnitScale(Rhino.RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters); double height = System.Convert.ToDouble(feat.GetFieldAsString(def.GetFieldIndex("height"))) / unitsConversion; double min_height = System.Convert.ToDouble(feat.GetFieldAsString(def.GetFieldIndex("min_height"))) / unitsConversion; bool underground = System.Convert.ToBoolean(feat.GetFieldAsString(def.GetFieldIndex("underground"))); if (geom.GetGeometryType() == wkbGeometryType.wkbPolygon) { Extrusion bldg = Heron.Convert.OgrPolygonToExtrusion(geom, tr, height, min_height, underground); IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(bldg); gGooBuildings.Append(bldgGoo, new GH_Path(iLayer, t, m)); } if (geom.GetGeometryType() == wkbGeometryType.wkbMultiPolygon) { List <Extrusion> bldgs = Heron.Convert.OgrMultiPolyToExtrusions(geom, tr, height, min_height, underground); foreach (Extrusion bldg in bldgs) { IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(bldg); gGooBuildings.Append(bldgGoo, new GH_Path(iLayer, t, m)); } } } } /// Get Feature Values if (fvalues.PathExists(new GH_Path(iLayer, t, m))) { //fvalues.get_Branch(new GH_Path(iLayer, t, m)).Clear(); } for (int iField = 0; iField < feat.GetFieldCount(); iField++) { OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField); if (feat.IsFieldSet(iField)) { fvalues.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(iLayer, t, m)); } else { fvalues.Append(new GH_String("null"), new GH_Path(iLayer, t, m)); } } } m++; geom.Dispose(); feat.Dispose(); }///end while loop through features //}///end layer by name layer.Dispose(); }///end loop through layers ds.Dispose(); t++; }///end loop through mvt tiles //write out new tile range metadata for serialization TileCacheMeta = tileRangeString; DA.SetData(0, imgFrame); DA.SetDataTree(1, fnames); DA.SetDataTree(2, fvalues); DA.SetDataTree(3, gGoo); DA.SetDataList(4, "copyright Mapbox"); DA.SetDataTree(5, gtype); DA.SetDataTree(6, gGooBuildings); DA.SetDataList(7, tileExtents); }
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); }
/// <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) { ///Gather GHA inputs Curve boundary = null; DA.GetData <Curve>(0, ref boundary); string osmFilePath = string.Empty; DA.GetData <string>("OSM Data Location", ref osmFilePath); //string userSRStext = "WGS84"; //DA.GetData<string>(2, ref userSRStext); List <string> filterWords = new List <string>(); DA.GetDataList <string>(2, filterWords); List <string> filterKeyValue = new List <string>(); DA.GetDataList <string>(3, filterKeyValue); Transform xformToMetric = new Transform(scaleToMetric); Transform xformFromMetric = new Transform(scaleFromMetric); ///Declare trees Rectangle3d recs = new Rectangle3d(); GH_Structure <GH_String> fieldNames = new GH_Structure <GH_String>(); GH_Structure <GH_String> fieldValues = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> geometryGoo = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <IGH_GeometricGoo> buildingGoo = new GH_Structure <IGH_GeometricGoo>(); Point3d max = new Point3d(); Point3d min = new Point3d(); if (boundary != null) { Point3d maxM = boundary.GetBoundingBox(true).Corner(true, false, true); max = Heron.Convert.XYZToWGS(maxM); Point3d minM = boundary.GetBoundingBox(true).Corner(false, true, true); min = Heron.Convert.XYZToWGS(minM); } /// get extents (why is this not part of OsmSharp?) System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Load(osmFilePath); if (xdoc.Root.Element("bounds") != null) { double minlat = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlat").Value); double minlon = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlon").Value); double maxlat = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlat").Value); double maxlon = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlon").Value); Point3d boundsMin = Heron.Convert.WGSToXYZ(new Point3d(minlon, minlat, 0)); Point3d boundsMax = Heron.Convert.WGSToXYZ(new Point3d(maxlon, maxlat, 0)); recs = new Rectangle3d(Plane.WorldXY, boundsMin, boundsMax); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cannot determine the extents of the OSM file. A 'bounds' element may not be present in the file. " + "Try turning off clipping in this component's menu."); } using (var fileStreamSource = File.OpenRead(osmFilePath)) { /// create a source. OsmSharp.Streams.XmlOsmStreamSource source = new OsmSharp.Streams.XmlOsmStreamSource(fileStreamSource); /// filter by bounding box OsmSharp.Streams.OsmStreamSource sourceClipped = source; if (clipped) { sourceClipped = source.FilterBox((float)max.X, (float)max.Y, (float)min.X, (float)min.Y, true); } /// create a dictionary of elements OsmSharp.Db.Impl.MemorySnapshotDb sourceMem = new OsmSharp.Db.Impl.MemorySnapshotDb(sourceClipped); /// filter the source var filtered = from osmGeos in sourceClipped where osmGeos.Tags != null select osmGeos; if (filterWords.Any()) { filtered = from osmGeos in filtered where osmGeos.Tags.ContainsAnyKey(filterWords) select osmGeos; } if (filterKeyValue.Any()) { List <Tag> tags = new List <Tag>(); foreach (string term in filterKeyValue) { string[] kv = term.Split(','); Tag tag = new Tag(kv[0], kv[1]); tags.Add(tag); } filtered = from osmGeos in filtered where osmGeos.Tags.Intersect(tags).Any() select osmGeos; } source.Dispose(); /// loop over all objects and count them. int nodes = 0, ways = 0, relations = 0; Dictionary <PolylineCurve, GH_Path> bldgOutlines = new Dictionary <PolylineCurve, GH_Path>(); List <BuildingPart> buildingParts = new List <BuildingPart>(); foreach (OsmSharp.OsmGeo osmGeo in filtered) { //NODES if (osmGeo.Type == OsmGeoType.Node) { OsmSharp.Node n = (OsmSharp.Node)osmGeo; GH_Path nodesPath = new GH_Path(0, nodes); //populate Fields and Values for each node fieldNames.AppendRange(GetKeys(osmGeo), nodesPath); fieldValues.AppendRange(GetValues(osmGeo), nodesPath); //get geometry for node Point3d nPoint = Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0)); geometryGoo.Append(new GH_Point(nPoint), nodesPath); //increment nodes nodes++; } //////////////////////////////////////////////////////////// //WAYS if (osmGeo.Type == OsmGeoType.Way) { OsmSharp.Way w = (OsmSharp.Way)osmGeo; GH_Path waysPath = new GH_Path(1, ways); //populate Fields and Values for each way fieldNames.AppendRange(GetKeys(osmGeo), waysPath); fieldValues.AppendRange(GetValues(osmGeo), waysPath); //get polyline geometry for way List <Point3d> wayNodes = new List <Point3d>(); foreach (long j in w.Nodes) { OsmSharp.Node n = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, j); wayNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0))); } PolylineCurve pL = new PolylineCurve(wayNodes); if (pL.IsClosed) { //create base surface Brep[] breps = Brep.CreatePlanarBreps(pL, DocumentTolerance()); geometryGoo.Append(new GH_Brep(breps[0]), waysPath); } else { geometryGoo.Append(new GH_Curve(pL), waysPath); } //building massing if ((w.Tags.ContainsKey("building") || w.Tags.ContainsKey("building:part")))// && !w.Tags.ContainsKey("construction")) { if (pL.IsClosed) { ///Populate dictionary for sorting building parts later if (w.Tags.ContainsKey("building")) { bldgOutlines.Add(pL, waysPath); } CurveOrientation orient = pL.ClosedCurveOrientation(Plane.WorldXY); if (orient != CurveOrientation.CounterClockwise) { pL.Reverse(); } ///Move polylines to min height double minHeightWay = GetMinBldgHeight(osmGeo); Vector3d minVec = new Vector3d(0, 0, minHeightWay); //minVec.Transform(xformFromMetric); if (minHeightWay > 0.0) { var minHeightTranslate = Transform.Translation(minVec); pL.Transform(minHeightTranslate); } Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo) - minHeightWay); //hVec.Transform(xformFromMetric); Extrusion ex = Extrusion.Create(pL, hVec.Z, true); IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(ex); ///Save building parts for sorting later and remove part from geometry goo tree if (w.Tags.ContainsKey("building:part")) { BuildingPart bldgPart = new BuildingPart(pL, bldgGoo, fieldNames[waysPath], fieldValues[waysPath], osmGeo); buildingParts.Add(bldgPart); fieldNames.RemovePath(waysPath); fieldValues.RemovePath(waysPath); geometryGoo.RemovePath(waysPath); ways = ways - 1; } else { buildingGoo.Append(bldgGoo, waysPath); } } } //increment ways ways++; } /////////////////////////////////////////////////////////// //RELATIONS if (osmGeo.Type == OsmGeoType.Relation) { OsmSharp.Relation r = (OsmSharp.Relation)osmGeo; GH_Path relationPath = new GH_Path(2, relations); //populate Fields and Values for each relation fieldNames.AppendRange(GetKeys(osmGeo), relationPath); fieldValues.AppendRange(GetValues(osmGeo), relationPath); List <Curve> pLines = new List <Curve>(); // start members loop for (int mem = 0; mem < r.Members.Length; mem++) { GH_Path memberPath = new GH_Path(2, relations, mem); OsmSharp.RelationMember rMem = r.Members[mem]; OsmSharp.OsmGeo rMemGeo = sourceMem.Get(rMem.Type, rMem.Id); if (rMemGeo != null) { //get geometry for node if (rMemGeo.Type == OsmGeoType.Node) { long memNodeId = rMem.Id; OsmSharp.Node memN = (OsmSharp.Node)sourceMem.Get(rMem.Type, rMem.Id); Point3d memPoint = Heron.Convert.WGSToXYZ(new Point3d((double)memN.Longitude, (double)memN.Latitude, 0)); geometryGoo.Append(new GH_Point(memPoint), memberPath); } //get geometry for way if (rMem.Type == OsmGeoType.Way) { long memWayId = rMem.Id; OsmSharp.Way memWay = (OsmSharp.Way)rMemGeo; //get polyline geometry for way List <Point3d> memNodes = new List <Point3d>(); foreach (long memNodeId in memWay.Nodes) { OsmSharp.Node memNode = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, memNodeId); memNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)memNode.Longitude, (double)memNode.Latitude, 0))); } PolylineCurve memPolyline = new PolylineCurve(memNodes); geometryGoo.Append(new GH_Curve(memPolyline.ToNurbsCurve()), memberPath); CurveOrientation orient = memPolyline.ClosedCurveOrientation(Plane.WorldXY); if (orient != CurveOrientation.CounterClockwise) { memPolyline.Reverse(); } pLines.Add(memPolyline.ToNurbsCurve()); } //get nested relations if (rMem.Type == OsmGeoType.Relation) { ///not sure if this is needed } } } //end members loop bool allClosed = true; foreach (Curve pc in pLines) { if (!pc.IsClosed) { allClosed = false; } } if (pLines.Count > 0 && allClosed) { ///Move polylines to min height double minHeight = GetMinBldgHeight(osmGeo); if (minHeight > 0.0) { Vector3d minVec = new Vector3d(0, 0, minHeight); //minVec.Transform(xformFromMetric); var minHeightTranslate = Transform.Translation(minVec); for (int i = 0; i < pLines.Count; i++) { pLines[i].Transform(minHeightTranslate); } } ///Create base surface Brep[] breps = Brep.CreatePlanarBreps(pLines, DocumentTolerance()); geometryGoo.RemovePath(relationPath); foreach (Brep b in breps) { geometryGoo.Append(new GH_Brep(b), relationPath); ///Building massing if (r.Tags.ContainsKey("building") || r.Tags.ContainsKey("building:part")) { Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo) - minHeight); //hVec.Transform(xformFromMetric); ///Create extrusion from base surface buildingGoo.Append(new GH_Brep(Brep.CreateFromOffsetFace(b.Faces[0], hVec.Z, DocumentTolerance(), false, true)), relationPath); } } } ///Increment relations relations++; } ///End relation loop } ///End filtered loop ///Add building parts to sub-branches under main building for (int partIndex = 0; partIndex < buildingParts.Count; partIndex++) { BuildingPart bldgPart = buildingParts[partIndex]; Point3d partPoint = bldgPart.PartFootprint.PointAtStart; partPoint.Z = 0; bool replaceBuidingMass = false; GH_Path mainBuildingMassPath = new GH_Path(); PolylineCurve massOutline = new PolylineCurve(); bool isRoof = bldgPart.PartOsmGeo.Tags.TryGetValue("roof:shape", out string isRoofString); if (isRoof) { bldgPart.PartGoo = BldgPartToRoof(bldgPart); } foreach (KeyValuePair <PolylineCurve, GH_Path> pair in bldgOutlines) { PointContainment pc = pair.Key.Contains(partPoint, Plane.WorldXY, DocumentTolerance()); if (pc != PointContainment.Outside) { ///Create new sub-branch int numSubBranches = 0; GH_Path partPath = pair.Value.AppendElement(numSubBranches); while (buildingGoo.PathExists(partPath)) { numSubBranches++; partPath = pair.Value.AppendElement(numSubBranches); } ///Add data to sub-branch fieldNames.AppendRange(bldgPart.PartFieldNames, partPath); fieldValues.AppendRange(bldgPart.PartFieldValues, partPath); buildingGoo.Append(bldgPart.PartGoo, partPath); ///Remove the main building mass replaceBuidingMass = true; mainBuildingMassPath = pair.Value; massOutline = pair.Key; } } ///Remove the main building mass if (replaceBuidingMass) { buildingGoo.RemovePath(mainBuildingMassPath); buildingGoo.Append(new GH_Curve(massOutline), mainBuildingMassPath); } else { GH_Path extrasPath = new GH_Path(3, partIndex); buildingGoo.Append(bldgPart.PartGoo, extrasPath); fieldNames.AppendRange(bldgPart.PartFieldNames, extrasPath); fieldValues.AppendRange(bldgPart.PartFieldValues, extrasPath); } } } ///end osm source loop if (recs.IsValid) { DA.SetData(0, recs); } DA.SetDataTree(1, fieldNames); DA.SetDataTree(2, fieldValues); DA.SetDataTree(3, geometryGoo); DA.SetDataTree(4, buildingGoo); } ///end SolveInstance
public static IGH_GeometricGoo BldgPartToRoof(BuildingPart bldgPart) { IGH_GeometricGoo roof = bldgPart.PartGoo; PolylineCurve pL = bldgPart.PartFootprint; ///Already at min height bldgPart.PartOsmGeo.Tags.TryGetValue("roof:shape", out string roofShape); bldgPart.PartOsmGeo.Tags.TryGetValue("height", out string heightString); double height = GetHeightDimensioned(heightString); bldgPart.PartOsmGeo.Tags.TryGetValue("min_height", out string minHeightString); double min_height = GetHeightDimensioned(minHeightString); bldgPart.PartOsmGeo.Tags.TryGetValue("roof:height", out string roofHeightString); double roofHeight = GetHeightDimensioned(roofHeightString); double facadeHeight = height - roofHeight; ///Make sure there's a minium facade height for SF Transamerica Pyramid case if (facadeHeight <= 0) { facadeHeight = 2 * DocumentTolerance(); } bldgPart.PartOsmGeo.Tags.TryGetValue("roof:orientation", out string roofOrientationString); bldgPart.PartOsmGeo.Tags.TryGetValue("roof:direction", out string roofDirectionString); double roofDirection = System.Convert.ToDouble(roofDirectionString); Vector3d roofDirectionVector = Plane.WorldXY.YAxis; roofDirectionVector.Rotate(RhinoMath.ToRadians(-roofDirection), Plane.WorldXY.ZAxis); Line[] edges = pL.ToPolyline().GetSegments(); Point3d centroid = AreaMassProperties.Compute(pL).Centroid; switch (roofShape) { case "pyramidal": centroid.Z = height; pL.TryGetPolyline(out Polyline pLPolyline); Line[] pLLines = pLPolyline.GetSegments(); List <Brep> pyramidBrepList = Brep.CreatePlanarBreps(pL, DocumentTolerance()).ToList(); if (!string.IsNullOrEmpty(roofHeightString)) { Plane facadeHeightPlane = Plane.WorldXY; facadeHeightPlane.Translate(new Vector3d(0, 0, facadeHeight)); pLPolyline.Transform(Transform.PlanarProjection(facadeHeightPlane)); ///Creating individual faces seems to work better/cleaner than lofting curves for (int i = 0; i < pLLines.Count(); i++) { Line bottomEdge = pLLines[i]; Line topEdge = bottomEdge; topEdge.Transform(Transform.PlanarProjection(facadeHeightPlane)); pyramidBrepList.Add(Brep.CreateFromCornerPoints(bottomEdge.PointAt(0), bottomEdge.PointAt(1), topEdge.PointAt(1), topEdge.PointAt(0), DocumentTolerance())); } } foreach (Line edge in pLPolyline.GetSegments()) { pyramidBrepList.Add(Brep.CreateFromCornerPoints(edge.PointAt(0), centroid, edge.PointAt(1), DocumentTolerance())); } Brep[] pyramidBrep = Brep.CreateSolid(pyramidBrepList, DocumentTolerance()); if (pyramidBrep[0].IsSolid) { roof = GH_Convert.ToGeometricGoo(pyramidBrep[0]); } break; case "skillion": Line frontEdge = new Line(); Line backEdge = new Line(); double frontAngleMin = RhinoMath.ToRadians(90); double backAngleMin = RhinoMath.ToRadians(90); foreach (Line edge in edges) { Point3d closestPt = edge.ClosestPoint(centroid, true); Vector3d perpVector = closestPt - centroid; double angleDifference = Vector3d.VectorAngle(roofDirectionVector, perpVector); if (angleDifference < frontAngleMin) { frontEdge = edge; frontAngleMin = angleDifference; } if (angleDifference > backAngleMin) { backEdge = edge; backAngleMin = angleDifference; } } Point3d backEdgeFrom = backEdge.From; backEdgeFrom.Z = height; Point3d backEdgeTo = backEdge.To; backEdgeTo.Z = height; Point3d frontEdgeFrom = frontEdge.From; frontEdgeFrom.Z = facadeHeight; Point3d frontEdgeTo = frontEdge.To; frontEdgeTo.Z = facadeHeight; List <Point3d> basePtList = new List <Point3d> { backEdge.From, backEdge.To, frontEdge.From, frontEdge.To, backEdge.From }; Polyline basePolyline = new Polyline(basePtList); List <Point3d> topPtList = new List <Point3d> { backEdgeFrom, backEdgeTo, frontEdgeFrom, frontEdgeTo, backEdgeFrom }; Polyline topPolyline = new Polyline(topPtList); ///Creating individual faces seems to work better/cleaner than lofting curves List <Brep> skillionBreps = new List <Brep>(); Line[] baseLines = basePolyline.GetSegments(); Line[] topLines = topPolyline.GetSegments(); for (int i = 0; i < baseLines.Count(); i++) { Line bottomEdge = baseLines[i]; Line topEdge = topLines[i]; skillionBreps.Add(Brep.CreateFromCornerPoints(bottomEdge.PointAt(0), bottomEdge.PointAt(1), topEdge.PointAt(1), topEdge.PointAt(0), DocumentTolerance())); } Brep baseSkillion = Brep.CreateFromCornerPoints(backEdge.From, backEdge.To, frontEdge.From, frontEdge.To, DocumentTolerance()); Brep topSkillion = Brep.CreateFromCornerPoints(backEdgeFrom, backEdgeTo, frontEdgeFrom, frontEdgeTo, DocumentTolerance()); skillionBreps.Add(baseSkillion); skillionBreps.Add(topSkillion); Brep[] skillion = Brep.CreateSolid(skillionBreps, DocumentTolerance()); if (skillion.Count() > 0) { roof = GH_Convert.ToGeometricGoo(skillion[0]); } break; case "gabled": ///TODO: Look into getting oriented bbox using front edge as orientation plane, ///extrude gable roof profile from face of bbox, trim roof geo from footprint, ///loft between footprint and trimmed roof edges and join everything. ///Need to simply polylines with colinear segments. Angle tolerance based on Notre-Dame de Paris case //pL.Simplify(CurveSimplifyOptions.All, 0, RhinoMath.ToRadians(2)).TryGetPolyline(out Polyline pLSimplified); Polyline pLSimplified = pL.ToPolyline(); pLSimplified.MergeColinearSegments(DocumentAngleTolerance() * 5, true); Line[] edgesSimplified = pLSimplified.GetSegments(); if (edgesSimplified.Count() != 4) { break; } Line ridge = new Line(); Line eaveOne = new Line(); Line eaveTwo = new Line(); Polyline topGablePolyline = new Polyline(); List <Brep> gableBreps = new List <Brep>(); if ((edgesSimplified[0].Length > edgesSimplified[1].Length && roofOrientationString != "across") || ((edgesSimplified[0].Length < edgesSimplified[1].Length && roofOrientationString == "across"))) { ridge = new Line(edgesSimplified[3].PointAt(0.5), edgesSimplified[1].PointAt(0.5)); ridge.FromZ = height; ridge.ToZ = height; eaveOne = edgesSimplified[0]; eaveOne.FromZ = facadeHeight; eaveOne.ToZ = facadeHeight; eaveTwo = edgesSimplified[2]; eaveTwo.Flip(); eaveTwo.FromZ = facadeHeight; eaveTwo.ToZ = facadeHeight; topGablePolyline = new Polyline { eaveOne.From, eaveOne.To, ridge.To, eaveTwo.To, eaveTwo.From, ridge.From, eaveOne.From }; Brep[] gableRoof = Brep.CreateFromLoft(new List <Curve> { eaveOne.ToNurbsCurve(), ridge.ToNurbsCurve(), eaveTwo.ToNurbsCurve() }, Point3d.Unset, Point3d.Unset, LoftType.Straight, false); gableRoof[0].Faces.SplitKinkyFaces(); gableBreps.Add(gableRoof[0]); } if ((edgesSimplified[0].Length > edgesSimplified[1].Length && roofOrientationString == "across") || (edgesSimplified[0].Length < edgesSimplified[1].Length && roofOrientationString != "across")) { ridge = new Line(edgesSimplified[0].PointAt(0.5), edgesSimplified[2].PointAt(0.5)); ridge.FromZ = height; ridge.ToZ = height; eaveOne = edgesSimplified[1]; eaveOne.FromZ = facadeHeight; eaveOne.ToZ = facadeHeight; eaveTwo = edgesSimplified[3]; eaveTwo.Flip(); eaveTwo.FromZ = facadeHeight; eaveTwo.ToZ = facadeHeight; topGablePolyline = new Polyline { eaveTwo.From, ridge.From, eaveOne.From, eaveOne.To, ridge.To, eaveTwo.To, eaveTwo.From }; Brep[] gableRoof = Brep.CreateFromLoft(new List <Curve> { eaveOne.ToNurbsCurve(), ridge.ToNurbsCurve(), eaveTwo.ToNurbsCurve() }, Point3d.Unset, Point3d.Unset, LoftType.Straight, false); gableRoof[0].Faces.SplitKinkyFaces(); gableBreps.Add(gableRoof[0]); } Brep[] gablewalls = Brep.CreateFromLoft(new List <Curve> { pLSimplified.ToPolylineCurve(), topGablePolyline.ToPolylineCurve() }, Point3d.Unset, Point3d.Unset, LoftType.Straight, false); gablewalls[0].Faces.SplitKinkyFaces(); gablewalls[0].MergeCoplanarFaces(DocumentTolerance()); gableBreps.Add(gablewalls[0]); Brep baseGable = Brep.CreateFromCornerPoints(edgesSimplified[0].From, edgesSimplified[0].To, edgesSimplified[2].From, edgesSimplified[2].To, DocumentTolerance()); gableBreps.Add(baseGable); Brep[] gable = Brep.JoinBreps(gableBreps, DocumentTolerance()); if (gable[0].IsValid) { roof = GH_Convert.ToGeometricGoo(gable[0]); } break; default: break; } return(roof); }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); GH_Structure <IGH_Goo> oFaceCentersTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oFaceBoundarysTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oNakedFacesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oNakedIndicesTree = new GH_Structure <GH_Integer>(); GH_Structure <IGH_Goo> oClosedFacesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oClosedIndicesTree = new GH_Structure <GH_Integer>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); for (int f = 0; f < pMesh.Faces.Count; f++) { // get face centers PlanktonXYZ center = pMesh.Faces.GetFaceCenter(f); oFaceCentersTree.Append(GH_Convert.ToGeometricGoo(center.ToPoint3d()), path); } // get face boundarys Polyline[] boundaryCurves = pMesh.ToPolylines(); for (int p = 0; p < boundaryCurves.Length; p++) { oFaceBoundarysTree.Append(GH_Convert.ToGeometricGoo(boundaryCurves[p]), path); if (pMesh.Faces.NakedEdgeCount(p) > 0) { oNakedFacesTree.Append(GH_Convert.ToGeometricGoo(boundaryCurves[p]), path); oNakedIndicesTree.Append(new GH_Integer(p), path); } else { oClosedFacesTree.Append(GH_Convert.ToGeometricGoo(boundaryCurves[p]), path); oClosedIndicesTree.Append(new GH_Integer(p), path); } } //for (int e = 0; e < pMesh.Halfedges.Count; e++) //{ // if (pMesh.Halfedges.GetPairHalfedge(e) > e) continue; // int[] vts = pMesh.Halfedges.GetVertices(e); // oEdgesTree.Append( // GH_Convert.ToGeometricGoo(new LineCurve( // pMesh.Vertices[vts[0]].ToPoint3d(), // pMesh.Vertices[vts[1]].ToPoint3d())), path); // if (pMesh.Halfedges.IsBoundary(e)) // { // oNakedEdgesTree.Append( // GH_Convert.ToGeometricGoo(new LineCurve( // pMesh.Vertices[vts[0]].ToPoint3d(), // pMesh.Vertices[vts[1]].ToPoint3d())), path); // oNakedIndicesTree.Append(new GH_Integer(e / 2), path); // } // else // { // oClosedEdgesTree.Append( // GH_Convert.ToGeometricGoo(new LineCurve( // pMesh.Vertices[vts[0]].ToPoint3d(), // pMesh.Vertices[vts[1]].ToPoint3d())), path); // oClosedIndicesTree.Append(new GH_Integer(e / 2), path); // } //} } } } DA.SetDataTree(0, oFaceCentersTree); DA.SetDataTree(1, oFaceBoundarysTree); DA.SetDataTree(2, oNakedFacesTree); DA.SetDataTree(3, oNakedIndicesTree); DA.SetDataTree(4, oClosedFacesTree); DA.SetDataTree(5, oClosedIndicesTree); //DA.GetData<Mesh>("Mesh", ref iMesh); //pMesh = iMesh.ToPlanktonMesh(); //for (int i = 0; i < pMesh.Faces.Count; i++) //{ // // get face centers // PlanktonXYZ center = pMesh.Faces.GetFaceCenter(i); // oFaceCenters.Add(center.ToPoint3d()); //} //// get face boundarys //Polyline[] boundaryCurves = pMesh.ToPolylines(); //for (int p = 0; p < boundaryCurves.Length; p++) //{ // oFaceBoundarys.Add(boundaryCurves[p]); // if (pMesh.Faces.NakedEdgeCount(p) > 0) // oNakedFaces.Add(boundaryCurves[p]); // else // oClosedFaces.Add(boundaryCurves[p]); //} //DA.SetDataList("Face Centers", oFaceCenters); //DA.SetDataList("Face Boundary Curves", oFaceBoundarys); //DA.SetDataList("Face Naked", oNakedFaces); //DA.SetDataList("Face Closed", oClosedFaces); }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure<IGH_GeometricGoo> iMeshTree = new GH_Structure<IGH_GeometricGoo>(); GH_Structure<GH_Integer> iFaceIndices = new GH_Structure<GH_Integer>(); DA.GetDataTree<IGH_GeometricGoo>(0, out iMeshTree); DA.GetDataTree<GH_Integer>(1, out iFaceIndices); GH_Structure<IGH_GeometricGoo> oFaceTree = new GH_Structure<IGH_GeometricGoo>(); GH_Structure<IGH_Goo> oFaceVerticesTree = new GH_Structure<IGH_Goo>(); GH_Structure<IGH_Goo> oFacesEdgesTree = new GH_Structure<IGH_Goo>(); GH_Structure<IGH_Goo> oVertexNFTree = new GH_Structure<IGH_Goo>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo<Mesh>(out mesh)) continue; else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); Polyline[] polyFaces = pMesh.ToPolylines(); for (int vi = 0; vi < iFaceIndices.PathCount; vi++) { int id; GH_Path pathFaces = iFaceIndices.get_Path(vi); if (path != pathFaces) continue; for (int vj = 0; vj < iFaceIndices.Branches[vi].Count; vj++) { iFaceIndices.Branches[vi][vj].CastTo<int>(out id); // getting neighbouring vertices oFaceTree.Append( GH_Convert.ToGeometricGoo(polyFaces[id]), path); List<int> newPath = new List<int>(); for (int p = 0; p < path.Indices.Length; p++) newPath.Add(path.Indices[p]); newPath.Add(vj); GH_Path vertexPath = new GH_Path(newPath.ToArray()); //vertices on face foreach (int fv in pMesh.Faces.GetFaceVertices(id)) oFaceVerticesTree.Append(GH_Convert.ToGeometricGoo(pMesh.Vertices[fv].ToPoint3d()), vertexPath); //edges on face and neighbour face of face foreach (int fe in pMesh.Faces.GetHalfedges(id)) { if (pMesh.Halfedges.IsBoundary(fe)) continue; int fae = pMesh.Halfedges.GetPairHalfedge(fe); if (fae != -1) { int[] vts = pMesh.Halfedges.GetVertices(fae); oFacesEdgesTree.Append(GH_Convert.ToGeometricGoo( new LineCurve(pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d())), path); int f = pMesh.Halfedges[fae].AdjacentFace; Polyline facePoly = Leopard.MeshEdit.getFacePolyline(pMesh, f); oVertexNFTree.Append(GH_Convert.ToGeometricGoo(facePoly), vertexPath); } } } } } } } DA.SetDataTree(0, oFaceTree); DA.SetDataTree(1, oFaceVerticesTree); DA.SetDataTree(2, oFacesEdgesTree); DA.SetDataTree(3, oVertexNFTree); }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_Integer> iVertexIndices = new GH_Structure <GH_Integer>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); DA.GetDataTree <GH_Integer>(1, out iVertexIndices); GH_Structure <IGH_GeometricGoo> oVertexTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <IGH_Goo> oVertexNVTree = new GH_Structure <IGH_Goo>(); // neighbouring vertices GH_Structure <IGH_Goo> oVertexNETree = new GH_Structure <IGH_Goo>(); // neighbouring edges GH_Structure <IGH_Goo> oVertexNFTree = new GH_Structure <IGH_Goo>(); // this was polyline GH_Structure <IGH_Goo> oVertexNFCTree = new GH_Structure <IGH_Goo>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); for (int vi = 0; vi < iVertexIndices.PathCount; vi++) { int id; GH_Path pathVertices = iVertexIndices.get_Path(vi); if (path != pathVertices) { continue; } for (int vj = 0; vj < iVertexIndices.Branches[vi].Count; vj++) { iVertexIndices.Branches[vi][vj].CastTo <int>(out id); // getting neighbouring vertices oVertexTree.Append(GH_Convert.ToGeometricGoo(pMesh.Vertices[id].ToPoint3d()), path); List <int> newPath = new List <int>(); for (int p = 0; p < path.Indices.Length; p++) { newPath.Add(path.Indices[p]); } newPath.Add(vj); GH_Path vertexPath = new GH_Path(newPath.ToArray()); // getting neighbouring vertices int[] vertexNV = pMesh.Vertices.GetVertexNeighbours(id); foreach (int v in vertexNV) { if (v != -1) { oVertexNVTree.Append(GH_Convert.ToGeometricGoo(pMesh.Vertices[v].ToPoint3d()), vertexPath); } } // getting neighbouring edges int[] vertexNE = pMesh.Vertices.GetHalfedges(id); foreach (int e in vertexNE) { if (e != -1) { int[] edgeVerticesAB = pMesh.Halfedges.GetVertices(e); oVertexNETree.Append( GH_Convert.ToGeometricGoo( new Line( pMesh.Vertices[edgeVerticesAB[0]].ToPoint3d(), pMesh.Vertices[edgeVerticesAB[1]].ToPoint3d() )), vertexPath); } } // getting neighbouring faces int[] vertexNFC = pMesh.Vertices.GetVertexFaces(id); foreach (int fc in vertexNFC) { if (fc != -1) { int[] vertexFace = pMesh.Faces.GetFaceVertices(fc); Polyline facePoly = new Polyline(); for (int f = 0; f <= vertexFace.Length; f++) { var v = pMesh.Vertices[vertexFace[f % vertexFace.Length]]; facePoly.Add(v.X, v.Y, v.Z); } oVertexNFTree.Append(GH_Convert.ToGeometricGoo(facePoly), vertexPath); oVertexNFCTree.Append(GH_Convert.ToGeometricGoo(pMesh.Faces.GetFaceCenter(fc).ToPoint3d()), vertexPath); } } } } } } } DA.SetDataTree(0, oVertexTree); DA.SetDataTree(1, oVertexNVTree); DA.SetDataTree(2, oVertexNETree); DA.SetDataTree(3, oVertexNFTree); DA.SetDataTree(4, oVertexNFCTree); }
/// <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) { Mesh topoMesh = new Mesh(); DA.GetData <Mesh>("Topography Mesh", ref topoMesh); GH_Structure <IGH_GeometricGoo> featureGoo = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>("Feature Geometry", out featureGoo); ///Reserve one processor for GUI totalMaxConcurrancy = System.Environment.ProcessorCount - 1; ///Tells us how many threads were using //Message = totalMaxConcurrancy + " threads"; ///Get Rtree of points and flat mesh for processing in detailed feature mesh projection Mesh topoFlat = new Mesh(); Point3d[] topoFlatPoints = null; RTree rTree = new RTree(); if (!fast) { topoFlat = topoMesh.DuplicateMesh(); for (int i = 0; i < topoFlat.Vertices.Count; i++) { Point3f v = topoFlat.Vertices[i]; v.Z = 0; topoFlat.Vertices.SetVertex(i, v); } topoFlatPoints = topoFlat.Vertices.ToPoint3dArray(); rTree = RTree.CreateFromPointArray(topoFlatPoints); } ///Create a dictionary that works in parallel var gooTree = new System.Collections.Concurrent.ConcurrentDictionary <GH_Path, List <IGH_GeometricGoo> >(); ///Multi-threading the loop System.Threading.Tasks.Parallel.ForEach(featureGoo.Paths, new System.Threading.Tasks.ParallelOptions { MaxDegreeOfParallelism = totalMaxConcurrancy }, pth => { ///Create containers for translating from GH Goo Point3d pt = new Point3d(); Polyline pLine = null; PolylineCurve pLineCurve = null; Curve curve = null; Mesh mesh = new Mesh(); Surface surface = null; Brep brep = new Brep(); ///Output container list List <IGH_GeometricGoo> gGooList = new List <IGH_GeometricGoo>(); List <IGH_GeometricGoo> fGooList = new List <IGH_GeometricGoo>(); var branchFeatures = featureGoo.get_Branch(pth); BoundingBox branchBox = new BoundingBox(); if (branchFeatures.Count > 0) { foreach (var bGoo in branchFeatures) { ///Get geometry type(s) in branch string geomType = string.Empty; IGH_GeometricGoo fGoo = GH_Convert.ToGeometricGoo(bGoo); if (fGoo != null && fGoo.IsValid) { if (grouped) { ///Need to duplicate geometry or else move vector piles on similar to the following ///https://www.grasshopper3d.com/forum/topics/c-component-refresh-problem fGooList.Add(fGoo.DuplicateGeometry()); branchBox.Union(fGoo.Boundingbox); } geomType = fGoo.TypeName; switch (geomType) { case "Point": fGoo.CastTo <Point3d>(out pt); gGooList.Add(ProjectPointToTopo(topoMesh, pt)); break; case "Line": case "Polyline": fGoo.CastTo <Polyline>(out pLine); if (fast) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine)); } else { ///Lock topoMesh so it's not accessed by mutliple threads at once in a "deadlock" ///https://docs.microsoft.com/en-us/dotnet/standard/threading/managed-threading-best-practices lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLine.ToNurbsCurve())); } } break; case "PolylineCurve": fGoo.CastTo <PolylineCurve>(out pLineCurve); if (fast) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLineCurve.ToPolyline())); } else { lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, pLineCurve.ToNurbsCurve())); } } break; case "Curve": fGoo.CastTo <Curve>(out curve); if (fast) { if (curve.TryGetPolyline(out pLine)) { gGooList.Add(ProjectPolylineToTopo(topoMesh, pLine)); } else { gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve)); } } else { lock (topoMesh) { gGooList.AddRange(ProjectCurveToTopo(topoMesh, curve)); } } break; case "Mesh": fGoo.CastTo <Mesh>(out mesh); if (mesh.IsClosed) { gGooList.Add(ProjectSolidMeshToTopo(topoMesh, mesh)); } else { if (fast) { gGooList.Add(ProjectMeshToTopoFast(topoMesh, mesh)); } else { lock (topoMesh) { gGooList.Add(ProjectMeshToTopoSlow(topoMesh, topoFlat, topoFlatPoints, rTree, mesh)); } } } break; case "Surface": fGoo.CastTo <Surface>(out surface); gGooList.Add(ProjectSurfaceToTopoFast(topoMesh, surface)); break; case "Brep": fGoo.CastTo <Brep>(out brep); gGooList.Add(ProjectBrepToTopo(topoMesh, brep)); break; default: AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not able to move " + geomType + " geometry to mesh" + ". Geometry must be a Point, Curve, Mesh, Surface or Brep."); break; } } else { } } ///Move objects in branch a minimum distance if grouped selected ///If only one feature in a branch, not need to group if (grouped && gGooList.Count > 1) { ///Get the minimum move vector Point3d lowestPoint = new Point3d(); double minDistance = double.MaxValue; Vector3d minimumVec = new Vector3d(); foreach (var gi in gGooList) { if (gi != null) { Point3d gGooMin = gi.Boundingbox.Min; Vector3d distVector = gGooMin - branchBox.Min; if (distVector.Length < minDistance && distVector.Length > 0 && distVector.IsValid) { lowestPoint = gGooMin; minDistance = distVector.Length; minimumVec = new Vector3d(0, 0, distVector.Z); } } } ///Move orignal feature geometry the minimum move vector if (minDistance != double.MaxValue) { Transform transform = Transform.Translation(minimumVec); for (int f = 0; f < fGooList.Count; f++) { fGooList[f].Transform(transform); } gooTree[pth] = fGooList; } } else { gooTree[pth] = gGooList; } } }); ///End of multi-threaded loop ///Convert dictionary to regular old data tree GH_Structure <IGH_GeometricGoo> gTree = new GH_Structure <IGH_GeometricGoo>(); foreach (KeyValuePair <GH_Path, List <IGH_GeometricGoo> > g in gooTree) { gTree.AppendRange(g.Value, g.Key); } topoFlat.Dispose(); topoMesh.Dispose(); DA.SetDataTree(0, gTree); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <IGH_GeometricGoo> geo = new List <IGH_GeometricGoo>(); if (!DA.GetDataList(0, geo)) { return; } if (!DA.GetData(1, ref constraint_X)) { return; } if (!DA.GetData(2, ref constraint_Y)) { return; } if (!DA.GetData(3, ref constraint_Z)) { return; } if (!DA.GetData(4, ref constraint_RX)) { return; } if (!DA.GetData(5, ref constraint_RY)) { return; } if (!DA.GetData(6, ref constraint_RZ)) { return; } DA.GetData(7, ref scale); DataTree <IGH_GeometricGoo> symbols = new DataTree <IGH_GeometricGoo>(); for (int i = 0; i < geo.Count; i++) { Point3d p = new Point3d(); if (geo[i] is Point3d) { if (!GH_Convert.ToPoint3d(geo[i], ref p, GH_Conversion.Both)) { return; } } else if (geo[i] is GH_Point) { GH_Point ghP = new GH_Point(); if (GH_Convert.ToGHPoint(geo[i], GH_Conversion.Both, ref ghP)) { p = ghP.Value; } else { return; } } double radius = scale / 8.0; Sphere s1 = new Sphere(p, radius); double pX = radius * Math.Sin(Math.PI / 4) * Math.Cos(Math.PI / 4); double pY = radius * Math.Sin(Math.PI / 4) * Math.Sin(Math.PI / 4); double pZ = radius * Math.Cos(Math.PI / 4); double pX0 = radius * Math.Sin(Math.PI / 4) * Math.Cos(0); double pY0 = radius * Math.Sin(0) * Math.Sin(Math.PI / 4); Point3d p01 = new Point3d(p.X - pX0, p.Y - pY0, p.Z - pZ); Point3d p02 = new Point3d(p.X + pX0, p.Y - pY0, p.Z - pZ); Point3d p03 = new Point3d(p.X + pX0, p.Y + pY0, p.Z - pZ); Point3d p04 = new Point3d(p.X - pX0, p.Y + pY0, p.Z - pZ); Point3d p11 = new Point3d(p.X - pX, p.Y - pY, p.Z - pZ); Point3d p12 = new Point3d(p.X + pX, p.Y - pY, p.Z - pZ); Point3d p13 = new Point3d(p.X + pX, p.Y + pY, p.Z - pZ); Point3d p14 = new Point3d(p.X - pX, p.Y + pY, p.Z - pZ); Point3d p21 = new Point3d(p.X - scale / 2.0, p.Y - scale / 2.0, p.Z - scale / 2.0); Point3d p22 = new Point3d(p.X + scale / 2.0, p.Y - scale / 2.0, p.Z - scale / 2.0); Point3d p23 = new Point3d(p.X + scale / 2.0, p.Y + scale / 2.0, p.Z - scale / 2.0); Point3d p24 = new Point3d(p.X - scale / 2.0, p.Y + scale / 2.0, p.Z - scale / 2.0); Line l1 = new Line(p11, p21); Line l2 = new Line(p12, p22); Line l3 = new Line(p13, p23); Line l4 = new Line(p14, p24); Line l5 = new Line(p21, p22); Line l6 = new Line(p22, p23); Line l7 = new Line(p23, p24); Line l8 = new Line(p24, p21); Arc a1 = new Arc(p11, p01, p12); Arc a2 = new Arc(p12, p02, p13); Arc a3 = new Arc(p13, p03, p14); Arc a4 = new Arc(p14, p04, p11); List <Curve> c1 = new List <Curve>() { l1.ToNurbsCurve(), l2.ToNurbsCurve(), l5.ToNurbsCurve(), a3.ToNurbsCurve() }; List <Curve> c2 = new List <Curve>() { l2.ToNurbsCurve(), l3.ToNurbsCurve(), l6.ToNurbsCurve(), a2.ToNurbsCurve() }; List <Curve> c3 = new List <Curve>() { l3.ToNurbsCurve(), l4.ToNurbsCurve(), l7.ToNurbsCurve(), a1.ToNurbsCurve() }; List <Curve> c4 = new List <Curve>() { l4.ToNurbsCurve(), l1.ToNurbsCurve(), l8.ToNurbsCurve(), a4.ToNurbsCurve() }; Brep b1 = Brep.CreateEdgeSurface(c1); Brep b2 = Brep.CreateEdgeSurface(c2); Brep b3 = Brep.CreateEdgeSurface(c3); Brep b4 = Brep.CreateEdgeSurface(c4); symbols.Add(GH_Convert.ToGeometricGoo(s1), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l1), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l2), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l3), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l4), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l5), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l6), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l7), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(l8), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(b1), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(b2), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(b3), new GH_Path(i)); symbols.Add(GH_Convert.ToGeometricGoo(b4), new GH_Path(i)); } DA.SetDataTree(0, symbols); }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_Integer> iEdgeIndices = new GH_Structure <GH_Integer>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); DA.GetDataTree <GH_Integer>(1, out iEdgeIndices); GH_Structure <IGH_GeometricGoo> oEdgeTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <IGH_Goo> oEdgeEndsTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oEdgeFacesTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oEdgeFaceCentersTree = new GH_Structure <IGH_Goo>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); for (int vi = 0; vi < iEdgeIndices.PathCount; vi++) { int id; GH_Path pathEdges = iEdgeIndices.get_Path(vi); if (path != pathEdges) { continue; } for (int vj = 0; vj < iEdgeIndices.Branches[vi].Count; vj++) { iEdgeIndices.Branches[vi][vj].CastTo <int>(out id); id *= 2; // getting neighbouring vertices int pairIndex = pMesh.Halfedges.GetPairHalfedge(id); if (pairIndex < id) { int temp = id; id = pairIndex; pairIndex = temp; } int[] vts = pMesh.Halfedges.GetVertices(id); // edge line output oEdgeTree.Append(GH_Convert.ToGeometricGoo( new LineCurve(pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d())), path); List <int> newPath = new List <int>(); for (int p = 0; p < path.Indices.Length; p++) { newPath.Add(path.Indices[p]); } newPath.Add(vj); GH_Path vertexPath = new GH_Path(newPath.ToArray()); // edge end points output oEdgeEndsTree.Append(GH_Convert.ToGeometricGoo(pMesh.Vertices[vts[0]].ToPoint3d()), vertexPath); oEdgeEndsTree.Append(GH_Convert.ToGeometricGoo(pMesh.Vertices[vts[1]].ToPoint3d()), vertexPath); // edge faces int fA = pMesh.Halfedges[id].AdjacentFace; int fB = pMesh.Halfedges[pairIndex].AdjacentFace; Polyline facePolyA = new Polyline(); Polyline facePolyB = new Polyline(); if (fA != -1) { int[] vsA = pMesh.Faces.GetFaceVertices(fA); for (int f = 0; f <= vsA.Length; f++) { var v = pMesh.Vertices[vsA[f % vsA.Length]]; facePolyA.Add(v.X, v.Y, v.Z); } oEdgeFacesTree.Append(GH_Convert.ToGeometricGoo(facePolyA), vertexPath); oEdgeFaceCentersTree.Append( GH_Convert.ToGeometricGoo(pMesh.Faces.GetFaceCenter(fA).ToPoint3d()), vertexPath); } if (fB != -1) { int[] vsB = pMesh.Faces.GetFaceVertices(fB); for (int f = 0; f <= vsB.Length; f++) { var v = pMesh.Vertices[vsB[f % vsB.Length]]; facePolyB.Add(v.X, v.Y, v.Z); } oEdgeFacesTree.Append(GH_Convert.ToGeometricGoo(facePolyB), vertexPath); oEdgeFaceCentersTree.Append( GH_Convert.ToGeometricGoo(pMesh.Faces.GetFaceCenter(fB).ToPoint3d()), vertexPath); } } } } } } DA.SetDataTree(0, oEdgeTree); DA.SetDataTree(1, oEdgeEndsTree); DA.SetDataTree(2, oEdgeFacesTree); DA.SetDataTree(3, oEdgeFaceCentersTree); /* * pMesh = iMesh.ToPlanktonMesh(); * * iEdgeIndex *= 2; * * int pairIndex = pMesh.Halfedges.GetPairHalfedge(iEdgeIndex); * if (pairIndex < iEdgeIndex) { int temp = iEdgeIndex; iEdgeIndex = pairIndex; pairIndex = temp;} * * int[] vts = pMesh.Halfedges.GetVertices(iEdgeIndex); * * // edge line output * oEdge = new LineCurve(pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d()); * * // edge end points output * oEdgeEnds.Add(pMesh.Vertices[vts[0]].ToPoint3d()); * oEdgeEnds.Add(pMesh.Vertices[vts[1]].ToPoint3d()); * * // edge faces * int fA = pMesh.Halfedges[iEdgeIndex].AdjacentFace; * int fB = pMesh.Halfedges[pairIndex].AdjacentFace; * * Polyline facePolyA = new Polyline(); * Polyline facePolyB = new Polyline(); * if (fA != -1) * { * int[] vsA = pMesh.Faces.GetFaceVertices(fA); * * for (int j = 0; j <= vsA.Length; j++) * { * var v = pMesh.Vertices[vsA[j % vsA.Length]]; * facePolyA.Add(v.X, v.Y, v.Z); * } * oEdgeFaces.Add(facePolyA); * oEdgeFaceCenters.Add(pMesh.Faces.GetFaceCenter(fA).ToPoint3d()); * } * if (fB != -1) * { * int[] vsB = pMesh.Faces.GetFaceVertices(fB); * for (int j = 0; j <= vsB.Length; j++) * { * var v = pMesh.Vertices[vsB[j % vsB.Length]]; * facePolyB.Add(v.X, v.Y, v.Z); * } * oEdgeFaces.Add(facePolyB); * oEdgeFaceCenters.Add(pMesh.Faces.GetFaceCenter(fB).ToPoint3d()); * } * * * DA.SetData("This Edge", oEdge); * DA.SetDataList("Edge Vertices", oEdgeEnds); * DA.SetDataList("Edge Faces", oEdgeFaces); * DA.SetDataList("Edge Faces Center", oEdgeFaceCenters); */ }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_Integer> ilevelsTree = new GH_Structure <GH_Integer>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); DA.GetDataTree <GH_Integer>(1, out ilevelsTree); GH_Structure <IGH_GeometricGoo> SubdivideMesh = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_Integer> selectVertices = new GH_Structure <GH_Integer>(); GH_Structure <GH_Integer> selectEdges = new GH_Structure <GH_Integer>(); GH_Structure <GH_Integer> selectFaces = new GH_Structure <GH_Integer>(); #region input parameters switch (_mode) { case FoldMode.SimpleSubdivision: break; case FoldMode.Vertices: DA.GetDataTree(2, out selectVertices); break; case FoldMode.Edges: DA.GetDataTree(2, out selectEdges); break; case FoldMode.Faces: DA.GetDataTree(2, out selectFaces); break; case FoldMode.VerticesAndEdges: DA.GetDataTree(2, out selectVertices); DA.GetDataTree(3, out selectEdges); break; case FoldMode.VerticesAndFaces: DA.GetDataTree(2, out selectVertices); DA.GetDataTree(3, out selectFaces); break; case FoldMode.EdgesAndFace: DA.GetDataTree(2, out selectEdges); DA.GetDataTree(3, out selectFaces); break; case FoldMode.AllSelect: DA.GetDataTree(2, out selectVertices); DA.GetDataTree(3, out selectEdges); DA.GetDataTree(4, out selectFaces); break; default: throw new ArgumentOutOfRangeException(); } #endregion for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { List <int> verticesIndices = new List <int>(); List <int> edgesIndices = new List <int>(); List <int> facesIndices = new List <int>(); #region select vertices for (int vi = 0; vi < selectVertices.PathCount; vi++) { if (path != selectVertices.get_Path(vi)) { continue; } else { foreach (var sv in selectVertices[vi].ToList()) { int number; sv.CastTo <int>(out number); verticesIndices.Add(number); } } } #endregion #region select edges for (int vi = 0; vi < selectEdges.PathCount; vi++) { if (path != selectEdges.get_Path(vi)) { continue; } else { foreach (var sv in selectEdges[vi].ToList()) { int number; sv.CastTo <int>(out number); edgesIndices.Add(number); } } } #endregion #region select faces for (int vi = 0; vi < selectFaces.PathCount; vi++) { if (path != selectFaces.get_Path(vi)) { continue; } else { foreach (var sv in selectFaces[vi].ToList()) { int number; sv.CastTo <int>(out number); facesIndices.Add(number); } } } #endregion #region level for (int l = 0; l < ilevelsTree.PathCount; l++) { int level; GH_Path pathLevel = ilevelsTree.get_Path(l); if (ilevelsTree.Count() == 1) { ilevelsTree.Branches[l][0].CastTo <int>(out level); SubdivideMesh.Append( GH_Convert.ToGeometricGoo( mesh.ToPlanktonMesh().CatmullClark( level, verticesIndices, edgesIndices, facesIndices).ToRhinoMesh()), path); break; } else if (path != pathLevel) { continue; } else { for (int vj = 0; vj < ilevelsTree.Branches[l].Count; vj++) { ilevelsTree.Branches[l][vj].CastTo <int>(out level); SubdivideMesh.Append( GH_Convert.ToGeometricGoo( mesh.ToPlanktonMesh().CatmullClark( level, verticesIndices, edgesIndices, facesIndices).ToRhinoMesh()), path); } } } #endregion } } } DA.SetDataTree(0, SubdivideMesh); }
/// <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) { ///Gather GHA inputs Curve boundary = null; DA.GetData <Curve>(0, ref boundary); string osmFilePath = string.Empty; DA.GetData <string>("OSM Data Location", ref osmFilePath); //string userSRStext = "WGS84"; //DA.GetData<string>(2, ref userSRStext); List <string> filterWords = new List <string>(); DA.GetDataList <string>(2, filterWords); List <string> filterKeyValue = new List <string>(); DA.GetDataList <string>(3, filterKeyValue); Transform xformToMetric = new Transform(Rhino.RhinoMath.UnitScale(RhinoDoc.ActiveDoc.ModelUnitSystem, Rhino.UnitSystem.Meters)); Transform xformFromMetric = new Transform(Rhino.RhinoMath.UnitScale(Rhino.UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem)); ///Declare trees Rectangle3d recs = new Rectangle3d(); GH_Structure <GH_String> fieldNames = new GH_Structure <GH_String>(); GH_Structure <GH_String> fieldValues = new GH_Structure <GH_String>(); GH_Structure <IGH_GeometricGoo> geometryGoo = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <IGH_GeometricGoo> buildingGoo = new GH_Structure <IGH_GeometricGoo>(); Point3d max = new Point3d(); Point3d min = new Point3d(); if (boundary != null) { Point3d maxM = boundary.GetBoundingBox(true).Corner(true, false, true); max = Heron.Convert.XYZToWGS(maxM); Point3d minM = boundary.GetBoundingBox(true).Corner(false, true, true); min = Heron.Convert.XYZToWGS(minM); } /// get extents (why is this not part of OsmSharp?) System.Xml.Linq.XDocument xdoc = System.Xml.Linq.XDocument.Load(osmFilePath); if (xdoc.Root.Element("bounds") != null) { double minlat = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlat").Value); double minlon = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("minlon").Value); double maxlat = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlat").Value); double maxlon = System.Convert.ToDouble(xdoc.Root.Element("bounds").Attribute("maxlon").Value); Point3d boundsMin = Heron.Convert.WGSToXYZ(new Point3d(minlon, minlat, 0)); Point3d boundsMax = Heron.Convert.WGSToXYZ(new Point3d(maxlon, maxlat, 0)); recs = new Rectangle3d(Plane.WorldXY, boundsMin, boundsMax); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Cannot determine the extents of the OSM file. A 'bounds' element may not be present in the file."); } using (var fileStreamSource = File.OpenRead(osmFilePath)) { /// create a source. OsmSharp.Streams.XmlOsmStreamSource source = new OsmSharp.Streams.XmlOsmStreamSource(fileStreamSource); /// filter by bounding box OsmSharp.Streams.OsmStreamSource sourceClipped = source; if (clipped) { sourceClipped = source.FilterBox((float)max.X, (float)max.Y, (float)min.X, (float)min.Y, true); } /// create a dictionary of elements OsmSharp.Db.Impl.MemorySnapshotDb sourceMem = new OsmSharp.Db.Impl.MemorySnapshotDb(sourceClipped); /// filter the source var filtered = from osmGeos in sourceClipped where osmGeos.Tags != null select osmGeos; if (filterWords.Any()) { filtered = from osmGeos in filtered where osmGeos.Tags.ContainsAnyKey(filterWords) select osmGeos; } if (filterKeyValue.Any()) { List <Tag> tags = new List <Tag>(); foreach (string term in filterKeyValue) { string[] kv = term.Split(','); Tag tag = new Tag(kv[0], kv[1]); tags.Add(tag); } filtered = from osmGeos in filtered where osmGeos.Tags.Intersect(tags).Any() select osmGeos; } source.Dispose(); /// loop over all objects and count them. int nodes = 0, ways = 0, relations = 0; foreach (OsmSharp.OsmGeo osmGeo in filtered) { //NODES if (osmGeo.Type == OsmGeoType.Node) { OsmSharp.Node n = (OsmSharp.Node)osmGeo; GH_Path nodesPath = new GH_Path(0, nodes); //populate Fields and Values for each node fieldNames.AppendRange(GetKeys(osmGeo), nodesPath); fieldValues.AppendRange(GetValues(osmGeo), nodesPath); //get geometry for node Point3d nPoint = Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0)); geometryGoo.Append(new GH_Point(nPoint), nodesPath); //increment nodes nodes++; } //////////////////////////////////////////////////////////// //WAYS if (osmGeo.Type == OsmGeoType.Way) { OsmSharp.Way w = (OsmSharp.Way)osmGeo; GH_Path waysPath = new GH_Path(1, ways); //populate Fields and Values for each way fieldNames.AppendRange(GetKeys(osmGeo), waysPath); fieldValues.AppendRange(GetValues(osmGeo), waysPath); //get polyline geometry for way List <Point3d> wayNodes = new List <Point3d>(); foreach (long j in w.Nodes) { OsmSharp.Node n = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, j); wayNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)n.Longitude, (double)n.Latitude, 0))); } PolylineCurve pL = new PolylineCurve(wayNodes); if (pL.IsClosed) { //create base surface Brep[] breps = Brep.CreatePlanarBreps(pL, DocumentTolerance()); geometryGoo.Append(new GH_Brep(breps[0]), waysPath); } else { geometryGoo.Append(new GH_Curve(pL), waysPath); } //building massing if (w.Tags.ContainsKey("building") || w.Tags.ContainsKey("building:part")) { if (pL.IsClosed) { CurveOrientation orient = pL.ClosedCurveOrientation(Plane.WorldXY); if (orient != CurveOrientation.CounterClockwise) { pL.Reverse(); } Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo)); hVec.Transform(xformFromMetric); Extrusion ex = Extrusion.Create(pL, hVec.Z, true); IGH_GeometricGoo bldgGoo = GH_Convert.ToGeometricGoo(ex); buildingGoo.Append(bldgGoo, waysPath); } } //increment ways ways++; } /////////////////////////////////////////////////////////// //RELATIONS if (osmGeo.Type == OsmGeoType.Relation) { OsmSharp.Relation r = (OsmSharp.Relation)osmGeo; GH_Path relationPath = new GH_Path(2, relations); //populate Fields and Values for each relation fieldNames.AppendRange(GetKeys(osmGeo), relationPath); fieldValues.AppendRange(GetValues(osmGeo), relationPath); List <Curve> pLines = new List <Curve>(); // start members loop for (int mem = 0; mem < r.Members.Length; mem++) { GH_Path memberPath = new GH_Path(2, relations, mem); OsmSharp.RelationMember rMem = r.Members[mem]; OsmSharp.OsmGeo rMemGeo = sourceMem.Get(rMem.Type, rMem.Id); if (rMemGeo != null) { //get geometry for node if (rMemGeo.Type == OsmGeoType.Node) { long memNodeId = rMem.Id; OsmSharp.Node memN = (OsmSharp.Node)sourceMem.Get(rMem.Type, rMem.Id); Point3d memPoint = Heron.Convert.WGSToXYZ(new Point3d((double)memN.Longitude, (double)memN.Latitude, 0)); geometryGoo.Append(new GH_Point(memPoint), memberPath); } //get geometry for way if (rMem.Type == OsmGeoType.Way) { long memWayId = rMem.Id; OsmSharp.Way memWay = (OsmSharp.Way)rMemGeo; //get polyline geometry for way List <Point3d> memNodes = new List <Point3d>(); foreach (long memNodeId in memWay.Nodes) { OsmSharp.Node memNode = (OsmSharp.Node)sourceMem.Get(OsmGeoType.Node, memNodeId); memNodes.Add(Heron.Convert.WGSToXYZ(new Point3d((double)memNode.Longitude, (double)memNode.Latitude, 0))); } PolylineCurve memPolyline = new PolylineCurve(memNodes); geometryGoo.Append(new GH_Curve(memPolyline.ToNurbsCurve()), memberPath); CurveOrientation orient = memPolyline.ClosedCurveOrientation(Plane.WorldXY); if (orient != CurveOrientation.CounterClockwise) { memPolyline.Reverse(); } pLines.Add(memPolyline.ToNurbsCurve()); } //get nested relations if (rMem.Type == OsmGeoType.Relation) { ///not sure if this is needed } } } //end members loop bool allClosed = true; foreach (Curve pc in pLines) { if (!pc.IsClosed) { allClosed = false; } } if (pLines.Count > 0 && allClosed) { //create base surface Brep[] breps = Brep.CreatePlanarBreps(pLines, DocumentTolerance()); geometryGoo.RemovePath(relationPath); foreach (Brep b in breps) { geometryGoo.Append(new GH_Brep(b), relationPath); //building massing if (r.Tags.ContainsKey("building") || r.Tags.ContainsKey("building:part")) { Vector3d hVec = new Vector3d(0, 0, GetBldgHeight(osmGeo)); hVec.Transform(xformFromMetric); //create extrusion from base surface buildingGoo.Append(new GH_Brep(Brep.CreateFromOffsetFace(b.Faces[0], hVec.Z, DocumentTolerance(), false, true)), relationPath); } } } //increment relations relations++; } ///end relation loop } ///end filtered loop } ///end osm source loop if (recs.IsValid) { DA.SetData(0, recs); } DA.SetDataTree(1, fieldNames); DA.SetDataTree(2, fieldValues); DA.SetDataTree(3, geometryGoo); DA.SetDataTree(4, buildingGoo); } ///end SolveInstance
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); GH_Structure <GH_Integer> iFaceIndices = new GH_Structure <GH_Integer>(); GH_Structure <GH_Number> iThicknesses = new GH_Structure <GH_Number>(); GH_Structure <GH_Number> iExtrudes = new GH_Structure <GH_Number>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); DA.GetDataTree <GH_Integer>(1, out iFaceIndices); DA.GetDataTree <GH_Number>(2, out iThicknesses); DA.GetDataTree <GH_Number>(3, out iExtrudes); GH_Structure <IGH_GeometricGoo> oNewMeshTree = new GH_Structure <IGH_GeometricGoo>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path pathMesh = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); PlanktonMesh pSMesh = new PlanktonMesh(); List <Point3d[]> faceOffset = new List <Point3d[]>(); List <int> facesIDs = new List <int>(); List <double> thicks = new List <double>(); List <double> offsets = new List <double>(); #region value initial for (int vi = 0; vi < iFaceIndices.PathCount; vi++) { if (pathMesh != iFaceIndices.get_Path(vi)) { continue; } else { foreach (var sv in iFaceIndices[vi].ToList()) { int number; sv.CastTo <int>(out number); facesIDs.Add(number); } } } for (int vi = 0; vi < iThicknesses.PathCount; vi++) { if (pathMesh != iThicknesses.get_Path(vi)) { continue; } else { foreach (var sv in iThicknesses[vi].ToList()) { double number; sv.CastTo <double>(out number); thicks.Add(number); } } } for (int vi = 0; vi < iExtrudes.PathCount; vi++) { if (pathMesh != iExtrudes.get_Path(vi)) { continue; } else { foreach (var sv in iExtrudes[vi].ToList()) { double number; sv.CastTo <double>(out number); offsets.Add(number); } } } #endregion #region Create windows vertices for (int k = 0; k < pMesh.Faces.Count; k++) { if (!facesIDs.Contains(k)) { continue; } int id = facesIDs.IndexOf(k); Point3d center = pMesh.Faces.GetFaceCenter(k).ToPoint3d(); int[] fVertices = pMesh.Faces.GetFaceVertices(k); Point3d[] centerVertices = new Point3d[fVertices.Length]; //Vector3d normal = pMesh.Faces.GetFaceNormal(k).ToVector3d(); //!!!!!!!!!!!!!!!!! plankton vertices normal have bugs!!!!!!! for (int fv = 0; fv < fVertices.Length; fv++) { Point3d v = pMesh.Vertices[fVertices[fv]].ToPoint3d(); Vector3d vec = center - v; Point3d v2 = new Point3d(); if (fv == fVertices.Length - 1) { v2 = pMesh.Vertices[fVertices[0]].ToPoint3d(); } else { v2 = pMesh.Vertices[fVertices[fv + 1]].ToPoint3d(); } int thickID = (id >= thicks.Count) ? thicks.Count - 1 : id; int offsetID = (id >= offsets.Count) ? offsets.Count - 1 : id; Vector3d normal = Vector3d.CrossProduct(vec, v - v2); normal.Unitize(); centerVertices[fv] = v + vec * thicks[thickID] + normal * offsets[offsetID]; } faceOffset.Add(centerVertices); } #endregion // add vertices #region add Vertices foreach (PlanktonVertex v in pMesh.Vertices) { pSMesh.Vertices.Add(v.ToPoint3d()); } #endregion #region add frame vertices // add offset vertices foreach (Point3d[] pts in faceOffset) { foreach (Point3d p in pts) { pSMesh.Vertices.Add(p); } } #endregion // add mesh int vc = 0; // vertice counter for (int k = 0; k < pMesh.Faces.Count; k++) { if (!facesIDs.Contains(k)) { int[] fVertices = pMesh.Faces.GetFaceVertices(k); if (fVertices.Length == 3) { pSMesh.Faces.AddFace(fVertices[0], fVertices[1], fVertices[2]); } else { pSMesh.Faces.AddFace(fVertices[0], fVertices[1], fVertices[2], fVertices[3]); } } else { int[] fVertices = pMesh.Faces.GetFaceVertices(k); if (fVertices.Length == 3) { pSMesh.Faces.AddFace(fVertices[0], fVertices[1], pMesh.Vertices.Count + vc + 1, pMesh.Vertices.Count + vc + 0); pSMesh.Faces.AddFace(fVertices[1], fVertices[2], pMesh.Vertices.Count + vc + 2, pMesh.Vertices.Count + vc + 1); pSMesh.Faces.AddFace(fVertices[2], fVertices[0], pMesh.Vertices.Count + vc + 0, pMesh.Vertices.Count + vc + 2); if (m_cap) { pSMesh.Faces.AddFace(pMesh.Vertices.Count + vc + 0, pMesh.Vertices.Count + vc + 1, pMesh.Vertices.Count + vc + 2); } vc += 3; } else { pSMesh.Faces.AddFace(fVertices[0], fVertices[1], pMesh.Vertices.Count + vc + 1, pMesh.Vertices.Count + vc + 0); pSMesh.Faces.AddFace(fVertices[1], fVertices[2], pMesh.Vertices.Count + vc + 2, pMesh.Vertices.Count + vc + 1); pSMesh.Faces.AddFace(fVertices[2], fVertices[3], pMesh.Vertices.Count + vc + 3, pMesh.Vertices.Count + vc + 2); pSMesh.Faces.AddFace(fVertices[3], fVertices[0], pMesh.Vertices.Count + vc + 0, pMesh.Vertices.Count + vc + 3); if (m_cap) { pSMesh.Faces.AddFace(pMesh.Vertices.Count + vc + 0, pMesh.Vertices.Count + vc + 1, pMesh.Vertices.Count + vc + 2, pMesh.Vertices.Count + vc + 3); } vc += 4; } } } oNewMeshTree.Append( GH_Convert.ToGeometricGoo(pSMesh.ToRhinoMesh()), pathMesh); } } } DA.SetDataTree(0, oNewMeshTree); }
/// <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) { string path = ""; int lineSkip = 1; if (!DA.GetData(0, ref path)) { return; } DA.GetData(1, ref recursive); DA.GetData(2, ref asMesh); DA.GetData(3, ref lineSkip); if (lineSkip < 1) { lineSkip = 1; } try { if (oldPath != path) { oldPath = path; geometry = GetGeometricData(path); } DataTree <IGH_GeometricGoo> geo = new DataTree <IGH_GeometricGoo>(); foreach (Tuple <int, ConcurrentQueue <IGH_GeometricGoo>, FileTypes> tuple in geometry) { switch (tuple.Item3) { case FileTypes.XYZ: if (asMesh) { ConcurrentQueue <Point3d> pp = new ConcurrentQueue <Point3d>(); Parallel.ForEach(tuple.Item2, (item, _, iNum) => { if (iNum % lineSkip == 0) { GH_Point p = new GH_Point(); if (GH_Convert.ToGHPoint(item, GH_Conversion.Both, ref p)) { pp.Enqueue(p.Value); } } }); Mesh mesh = new Mesh(); mesh.Vertices.AddVertices(pp); try { Node2List nodes = new Node2List(pp); List <Face> faces = Solver.Solve_Faces(nodes, 1); IEnumerable <MeshFace> meshFaces = faces.Select(x => new MeshFace(x.A, x.B, x.C)); mesh.Faces.AddFaces(meshFaces); ConcurrentQueue <IGH_GeometricGoo> goo = new ConcurrentQueue <IGH_GeometricGoo>(); goo.Enqueue(GH_Convert.ToGeometricGoo(mesh)); geo.AddRange(goo, new GH_Path(tuple.Item1)); } catch (Exception e) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message); } } else { ConcurrentQueue <IGH_GeometricGoo> goo = new ConcurrentQueue <IGH_GeometricGoo>(); Parallel.ForEach(tuple.Item2, (item, _, iNum) => { if (iNum % lineSkip == 0) { goo.Enqueue(item); } }); geo.AddRange(goo, new GH_Path(tuple.Item1)); } break; } } DA.SetDataTree(0, geo); } catch (Exception e) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message); } }
protected override void SolveInstance(IGH_DataAccess DA) { GH_Structure <IGH_GeometricGoo> iMeshTree = new GH_Structure <IGH_GeometricGoo>(); DA.GetDataTree <IGH_GeometricGoo>(0, out iMeshTree); GH_Structure <IGH_Goo> oEdgesTree = new GH_Structure <IGH_Goo>(); GH_Structure <IGH_Goo> oNakedEdgesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oNakedIndicesTree = new GH_Structure <GH_Integer>(); GH_Structure <IGH_Goo> oClosedEdgesTree = new GH_Structure <IGH_Goo>(); GH_Structure <GH_Integer> oClosedIndicesTree = new GH_Structure <GH_Integer>(); for (int i = 0; i < iMeshTree.PathCount; i++) { GH_Path path = iMeshTree.get_Path(i); for (int j = 0; j < iMeshTree.Branches[i].Count; j++) { Mesh mesh; if (!iMeshTree.Branches[i][j].CastTo <Mesh>(out mesh)) { continue; } else { PlanktonMesh pMesh = mesh.ToPlanktonMesh(); for (int e = 0; e < pMesh.Halfedges.Count; e++) { if (pMesh.Halfedges.GetPairHalfedge(e) > e) { continue; } int[] vts = pMesh.Halfedges.GetVertices(e); oEdgesTree.Append( GH_Convert.ToGeometricGoo(new LineCurve( pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d())), path); if (pMesh.Halfedges.IsBoundary(e)) { oNakedEdgesTree.Append( GH_Convert.ToGeometricGoo(new LineCurve( pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d())), path); oNakedIndicesTree.Append(new GH_Integer(e / 2), path); } else { oClosedEdgesTree.Append( GH_Convert.ToGeometricGoo(new LineCurve( pMesh.Vertices[vts[0]].ToPoint3d(), pMesh.Vertices[vts[1]].ToPoint3d())), path); oClosedIndicesTree.Append(new GH_Integer(e / 2), path); } } } } } DA.SetDataTree(0, oEdgesTree); DA.SetDataTree(1, oNakedEdgesTree); DA.SetDataTree(2, oNakedIndicesTree); DA.SetDataTree(3, oClosedEdgesTree); DA.SetDataTree(4, oClosedIndicesTree); }