예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        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 _));
        }
예제 #4
0
        /*******************************************/

        public static bool CastToGoo(object value, ref IGH_GeometricGoo target)
        {
            try
            {
                target = GH_Convert.ToGeometricGoo(value);
                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #5
0
        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);
        }
예제 #6
0
        /// <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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        /// <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
예제 #9
0
        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);
        }
예제 #10
0
        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);
        }
예제 #11
0
        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);



        }
예제 #12
0
        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);
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
파일: GH_Support.cs 프로젝트: tudo-tk/Eagle
        /// <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);
        }
예제 #15
0
        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);
             */
        }
예제 #16
0
        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);
        }
예제 #17
0
        /// <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
예제 #18
0
        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);
        }
예제 #19
0
        /// <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);
            }
        }
예제 #20
0
        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);
        }