Exemple #1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Structure <GH_Brep> breps   = null;
            GH_Structure <GH_Brep> cutters = null;

            //Brep brep = null;
            //List<Brep> cutters = new List<Brep>();

            if (!DA.GetDataTree("Brep", out breps))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Invalid Brep input.");
                return;
            }
            if (!DA.GetDataTree("Cutters", out cutters))
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Invalid cutter input.");
                return;
            }

            GH_Structure <GH_Brep> resTree = new GH_Structure <GH_Brep>();

            foreach (var path in breps.Paths)
            {
                resTree.EnsurePath(path);
            }

            List <string> errors = new List <string>();

            Parallel.For(0, breps.Paths.Count, index =>
            {
                GH_Path path = breps.Paths[index];
                if (cutters.PathExists(path) && breps[path].Count > 0)
                {
                    resTree[path].Add(new GH_Brep(breps[path][0].Value.Cut(
                                                      cutters[path].Select(x => x.Value))));
                }
                else if (cutters.PathCount == 1 && breps[path].Count > 0) // Handle a single list of cutters
                {
                    try
                    {
                        if (cutters[0].Count > 0 && breps[path][0] != null)
                        {
                            resTree[path].Add(new GH_Brep(breps[path][0].Value.Cut(
                                                              cutters[cutters.Paths[0]].Select(x => x.Value))));
                        }
                    }
                    catch (Exception ex)
                    {
                        errors.Add(ex.Message);
                    }
                }
                else
                {
                    resTree[path].AddRange(breps[path]);
                }
            });

            DA.SetDataTree(0, resTree);
            DA.SetDataList("Errors", errors);
        }
        public override void DoWork(Action <string, double> ReportProgress, Action Done)
        {
            Parent.Message = "Extending...";
            var path = new GH_Path(iteration);

            if (valueTree.PathExists(path))
            {
                var values = valueTree.get_Branch(path) as List <IGH_Goo>;
                // Input is a list of values. Assign them directly
                if (keys.Count != values?.Count)
                {
                    Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Key and Value lists are not the same length.");
                    Done();
                }

                AssignToObject(@base, keys, values);
            }
            else if (valueTree.Branches.Count == 1)
            {
                var values = valueTree.Branches[0];
                if (keys.Count != values.Count)
                {
                    Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Key and Value lists are not the same length.");
                    Done();
                }

                // Input is just one list, so use it.
                AssignToObject(@base, keys, values);
            }
            else
            {
                // Input is a tree, meaning it's values are either lists or trees.
                var subTree = Utilities.GetSubTree(valueTree, path);
                var index   = 0;
                keys.ForEach(key =>
                {
                    var subPath = new GH_Path(index);
                    if (subTree.PathExists(subPath))
                    {
                        // Value is a list, convert and assign.
                        var list = subTree.get_Branch(subPath) as List <IGH_Goo>;
                        if (list?.Count > 0)
                        {
                            @base[key] = list.Select(goo => Utilities.TryConvertItemToSpeckle(goo, Converter)).ToList();
                        }
                        ;
                    }
                    else
                    {
                        // TODO: Handle tree conversions
                        Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Cannot handle trees yet");
                    }

                    index++;
                });
            }

            Done();
        }
Exemple #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // Initialize local variables
            var valueTree = new GH_Structure <IGH_Goo>();
            var keys      = new List <string>();

            // Get data from inputs
            if (!DA.GetDataList(0, keys))
            {
                return;
            }
            if (!DA.GetDataTree(1, out valueTree))
            {
                return;
            }

            // Create a path from the current iteration
            var searchPath = new GH_Path(DA.Iteration);

            // Grab the corresponding subtree from the value input tree.
            var  subTree    = Utilities.GetSubTree(valueTree, searchPath);
            Base speckleObj = new Base();

            // Find the list or subtree belonging to that path
            if (valueTree.PathExists(searchPath) || valueTree.Paths.Count == 1)
            {
                var list = valueTree.Paths.Count == 1 ? valueTree.Branches[0] : valueTree.get_Branch(searchPath);
                // We got a list of values
                var ind = 0;
                keys.ForEach(key =>
                {
                    if (ind < list.Count)
                    {
                        speckleObj[key] = Utilities.TryConvertItemToSpeckle(list[ind], Converter);
                    }
                    ind++;
                });
            }
            else
            {
                // We got a tree of values

                // Create the speckle object with the specified keys
                var index = 0;
                keys.ForEach(key =>
                {
                    var itemPath = new GH_Path(index);
                    //TODO: Grab conversion methods and implement branch handling.
                    var branch = subTree.get_Branch(itemPath);
                    if (branch != null)
                    {
                        List <object> objs = new List <object>();
                        foreach (var goo in branch)
                        {
                            objs.Add(Utilities.TryConvertItemToSpeckle(goo, Converter));
                        }

                        if (objs.Count > 0)
                        {
                            speckleObj[key] = objs;
                        }
                    }

                    index++;
                });
            }

            // Set output
            DA.SetData(0, new GH_SpeckleBase {
                Value = speckleObj
            });
        }
        public Base DoWork(Base @base, List <string> keys, GH_Structure <IGH_Goo> valueTree)
        {
            try
            {
                // 👉 Checking for cancellation!
                if (CancelToken.IsCancellationRequested)
                {
                    return(null);
                }

                // Create a path from the current iteration
                var searchPath = new GH_Path(RunCount - 1);

                // Grab the corresponding subtree from the value input tree.
                var subTree = Utilities.GetSubTree(valueTree, searchPath);
                // Find the list or subtree belonging to that path
                if (valueTree.PathExists(searchPath) || valueTree.Paths.Count == 1)
                {
                    var list = valueTree.Paths.Count == 1 ? valueTree.Branches[0] : valueTree.get_Branch(searchPath);
                    // We got a list of values
                    var ind       = 0;
                    var hasErrors = false;
                    keys.ForEach(key =>
                    {
                        if (ind < list.Count)
                        {
                            try
                            {
                                if (Converter != null)
                                {
                                    @base[key] = Utilities.TryConvertItemToSpeckle(list[ind], Converter);
                                }
                                else
                                {
                                    @base[key] = list[ind];
                                }
                            }
                            catch (Exception e)
                            {
                                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
                                hasErrors = true;
                            }
                        }

                        ind++;
                    });
                    if (hasErrors)
                    {
                        @base = null;
                    }
                }
                else
                {
                    // We got a tree of values

                    // Create the speckle object with the specified keys
                    var index     = 0;
                    var hasErrors = false;
                    keys.ForEach(key =>
                    {
                        var itemPath = new GH_Path(index);

                        var branch = subTree.get_Branch(itemPath);
                        if (branch != null)
                        {
                            var objs = new List <object>();
                            foreach (var goo in branch)
                            {
                                if (Converter != null)
                                {
                                    objs.Add(Utilities.TryConvertItemToSpeckle(goo, Converter));
                                }
                                else
                                {
                                    objs.Add(goo);
                                }
                            }

                            if (objs.Count > 0)
                            {
                                try
                                {
                                    @base[key] = objs;
                                }
                                catch (Exception e)
                                {
                                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
                                    hasErrors = true;
                                }
                            }
                        }

                        index++;
                    });

                    if (hasErrors)
                    {
                        @base = null;
                    }
                }

                return(@base);
            }
            catch (Exception e)
            {
                // If we reach this, something happened that we weren't expecting...
                Log.CaptureException(e);
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went terribly wrong... " + e.Message);
                return(null);
            }
        }
Exemple #5
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>(0, boundary);

            string URL = string.Empty;

            DA.GetData <string>("REST URL", ref URL);
            if (!URL.EndsWith("/"))
            {
                URL = URL + "/";
            }

            string userSRStext = string.Empty;

            DA.GetData <string>("User Spatial Reference System", ref userSRStext);

            bool run = false;

            DA.GetData <bool>("run", ref run);

            ///GDAL setup
            RESTful.GdalConfiguration.ConfigureOgr();

            ///TODO: implement SetCRS here.
            ///Option to set CRS here to user-defined.  Needs a SetCRS global variable.

            OSGeo.OSR.SpatialReference userSRS = new OSGeo.OSR.SpatialReference("");
            userSRS.SetFromUserInput(userSRStext);
            int userSRSInt = Int16.Parse(userSRS.GetAuthorityCode(null));

            ///Set transform from input spatial reference to Rhino spatial reference
            OSGeo.OSR.SpatialReference rhinoSRS = new OSGeo.OSR.SpatialReference("");
            rhinoSRS.SetWellKnownGeogCS("WGS84");

            ///This transform moves and scales the points required in going from userSRS to XYZ and vice versa
            Transform userSRSToModelTransform = Heron.Convert.GetUserSRSToModelTransform(userSRS);
            Transform modelToUserSRSTransform = Heron.Convert.GetModelToUserSRSTransform(userSRS);

            GH_Structure <GH_String> mapquery = new GH_Structure <GH_String>();

            GH_Structure <GH_Point>         gsetUser   = new GH_Structure <GH_Point>();
            GH_Structure <IGH_GeometricGoo> gGoo       = new GH_Structure <IGH_GeometricGoo>();
            GH_Structure <GH_String>        fset       = new GH_Structure <GH_String>();
            GH_Structure <GH_String>        fieldnames = new GH_Structure <GH_String>();


            for (int i = 0; i < boundary.Count; i++)
            {
                GH_Path     cpath = new GH_Path(i);
                BoundingBox bbox  = boundary[i].GetBoundingBox(false);
                bbox.Transform(modelToUserSRSTransform);

                string restquery = URL +
                                   "query?where=&text=&objectIds=&time=&geometry=" + bbox.Min.X + "%2C" + bbox.Min.Y + "%2C" + bbox.Max.X + "%2C" + bbox.Max.Y +
                                   "&geometryType=esriGeometryEnvelope&inSR=" + userSRSInt +
                                   "&spatialRel=esriSpatialRelIntersects" +
                                   "&relationParam=&outFields=*" +
                                   "&returnGeometry=true" +
                                   "&maxAllowableOffset=" +
                                   "&geometryPrecision=" +
                                   "&outSR=" + userSRSInt +
                                   "&returnIdsOnly=false" +
                                   "&returnCountOnly=false" +
                                   "&orderByFields=" +
                                   "&groupByFieldsForStatistics=&outStatistics=" +
                                   "&returnZ=true" +
                                   "&returnM=false" +
                                   "&gdbVersion=" +
                                   "&returnDistinctValues=false" +
                                   "&f=json";

                mapquery.Append(new GH_String(restquery), cpath);

                if (run)
                {
                    //string result = Heron.Convert.HttpToJson(restquery);

                    OSGeo.OGR.DataSource dataSource = OSGeo.OGR.Ogr.Open("ESRIJSON:" + restquery, 0);

                    if (dataSource == 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.");
                    }


                    ///Loop through each layer. Likely not any layers in a REST service
                    for (int iLayer = 0; iLayer < dataSource.GetLayerCount(); iLayer++)
                    {
                        OSGeo.OGR.Layer ogrLayer = dataSource.GetLayerByIndex(iLayer);

                        if (ogrLayer == null)
                        {
                            Console.WriteLine($"Couldn't fetch advertised layer {iLayer}");
                            System.Environment.Exit(-1);
                        }

                        long count        = ogrLayer.GetFeatureCount(1);
                        int  featureCount = System.Convert.ToInt32(count);
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Layer #{iLayer} {ogrLayer.GetName()} has {featureCount} features");

                        OSGeo.OGR.FeatureDefn def = ogrLayer.GetLayerDefn();

                        ///Get the field names
                        for (int iAttr = 0; iAttr < def.GetFieldCount(); iAttr++)
                        {
                            ///TODO: Look into GetAlternativeNameRef() for field aliases (more readable) available in GDAL 3.2
                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iAttr);
                            fieldnames.Append(new GH_String(fdef.GetNameRef()), new GH_Path(i, iLayer));
                        }

                        ///Loop through geometry
                        OSGeo.OGR.Feature feat;
                        def = ogrLayer.GetLayerDefn();

                        int m = 0;
                        while ((feat = ogrLayer.GetNextFeature()) != null)
                        {
                            OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();
                            OSGeo.OGR.Geometry sub_geomUser;

                            ///reproject geometry to WGS84 and userSRS
                            ///TODO: look into using the SetCRS global variable here
                            if (geomUser.GetSpatialReference() == null)
                            {
                                geomUser.AssignSpatialReference(userSRS);
                            }

                            geomUser.TransformTo(userSRS);

                            if (feat.GetGeometryRef() != null)
                            {
                                if (!pointsOnly)
                                {
                                    ///Convert GDAL geometries to IGH_GeometricGoo
                                    gGoo.AppendRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform), new GH_Path(i, iLayer, m));

                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End get Feature Values
                                }

                                else
                                {
                                    ///Start get points if open polylines and points
                                    for (int gpc = 0; gpc < geomUser.GetPointCount(); gpc++)
                                    {
                                        ///Loop through geometry points for User SRS
                                        double[] ogrPtUser = new double[3];
                                        geomUser.GetPoint(gpc, ogrPtUser);
                                        Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                        pt3DUser.Transform(userSRSToModelTransform);

                                        gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m));
                                        ///End loop through geometry points


                                        /// Get Feature Values
                                        if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                        {
                                            fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                        }
                                        for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                        {
                                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                            if (feat.IsFieldSet(iField))
                                            {
                                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                            }
                                            else
                                            {
                                                fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                            }
                                        }
                                        ///End Get Feature Values
                                    }
                                    ///End getting points if open polylines or points


                                    ///Start getting points if closed polylines and multipolygons
                                    for (int gi = 0; gi < geomUser.GetGeometryCount(); gi++)
                                    {
                                        sub_geomUser = geomUser.GetGeometryRef(gi);
                                        OSGeo.OGR.Geometry subsub_geomUser;

                                        if (sub_geomUser.GetGeometryCount() > 0)
                                        {
                                            for (int n = 0; n < sub_geomUser.GetGeometryCount(); n++)
                                            {
                                                subsub_geomUser = sub_geomUser.GetGeometryRef(n);

                                                for (int ptnum = 0; ptnum < subsub_geomUser.GetPointCount(); ptnum++)
                                                {
                                                    ///Loop through geometry points for User SRS
                                                    double[] ogrPtUser = new double[3];
                                                    subsub_geomUser.GetPoint(ptnum, ogrPtUser);
                                                    Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                                    pt3DUser.Transform(userSRSToModelTransform);

                                                    gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi, n));
                                                    ///End loop through geometry points
                                                }
                                                subsub_geomUser.Dispose();
                                            }
                                        }

                                        else
                                        {
                                            for (int ptnum = 0; ptnum < sub_geomUser.GetPointCount(); ptnum++)
                                            {
                                                ///Loop through geometry points for User SRS
                                                double[] ogrPtUser = new double[3];
                                                sub_geomUser.GetPoint(ptnum, ogrPtUser);
                                                Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                                pt3DUser.Transform(userSRSToModelTransform);

                                                gGoo.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi));

                                                ///End loop through geometry points
                                            }
                                        }

                                        sub_geomUser.Dispose();

                                        /// Get Feature Values
                                        if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                        {
                                            fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                        }
                                        for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                        {
                                            OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                            if (feat.IsFieldSet(iField))
                                            {
                                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                            }
                                            else
                                            {
                                                fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                            }
                                        }
                                        ///End Get Feature Values
                                    } ///End closed polygons and multipolygons
                                }     ///End points only
                            }
                            m++;
                            geomUser.Dispose();
                            feat.Dispose();
                        }///end while loop through features
                    }
                    dataSource.Dispose();
                }
            }

            ///Not the most elegant way of setting outputs only on run
            if (run)
            {
                DA.SetDataList(0, fieldnames.get_Branch(0));
                DA.SetDataTree(1, fset);
                DA.SetDataTree(2, gGoo);
            }
            DA.SetDataTree(3, mapquery);
        }
Exemple #6
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>(0, boundary);

            string shpFileLoc = "";

            DA.GetData <string>("Shapefile Location", ref shpFileLoc);

            ////int SRef = 3857;
            GdalConfiguration.ConfigureOgr();
            GdalConfiguration.ConfigureGdal();

            OSGeo.OGR.Driver     drv = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource ds  = OSGeo.OGR.Ogr.Open(shpFileLoc, 0);

            List <OSGeo.OGR.Layer> layerset = new List <OSGeo.OGR.Layer>();
            List <int>             fc       = new List <int>();

            for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer);

                if (layer == null)
                {
                    Console.WriteLine("FAILURE: Couldn't fetch advertised layer " + iLayer);
                    System.Environment.Exit(-1);
                }
                long count        = layer.GetFeatureCount(1);
                int  featureCount = System.Convert.ToInt32(count);
                fc.Add(featureCount);
                layerset.Add(layer);
            }

            //Get OGR envelope of Shapefile
            OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope();
            layerset[0].GetExtent(ext, 1);
            Point3d extMin = new Point3d();
            Point3d extMax = new Point3d();

            extMin.X = ext.MinX;
            extMin.Y = ext.MinY;
            extMax.X = ext.MaxX;
            extMax.Y = ext.MaxY;

            OSGeo.OSR.SpatialReference sr = layerset[0].GetSpatialRef();

            OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference("");
            dst.SetWellKnownGeogCS("WGS84");

            //Get the spatial refernce of the input Shapefile
            string sRef;

            sr.ExportToWkt(out sRef);

            OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst);
            OSGeo.OSR.CoordinateTransformation revTransform   = new OSGeo.OSR.CoordinateTransformation(dst, sr);

            //Get bounding box of data in Shapefile
            double[] extMinPT = new double[3] {
                extMin.X, extMin.Y, extMin.Z
            };
            double[] extMaxPT = new double[3] {
                extMax.X, extMax.Y, extMax.Z
            };
            coordTransform.TransformPoint(extMinPT);
            coordTransform.TransformPoint(extMaxPT);
            Point3d     extPTmin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]);
            Point3d     extPTmax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]);
            Rectangle3d rec      = new Rectangle3d(Plane.WorldXY, Heron.Convert.ToXYZ(extPTmin), Heron.Convert.ToXYZ(extPTmax));

            //Declare trees
            GH_Structure <GH_String> fset    = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>  gset    = new GH_Structure <GH_Point>();
            GH_Structure <GH_String> layname = new GH_Structure <GH_String>();

            OSGeo.OGR.FeatureDefn def = layerset[0].GetLayerDefn();

            //Loop through input boundaries
            for (int i = 0; i < boundary.Count; i++)
            {
                if (rec.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Min) && (rec.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Max)))
                {
                    //Create bounding box for clipping geometry
                    Point3d  min   = Heron.Convert.ToWGS(boundary[i].GetBoundingBox(true).Min);
                    Point3d  max   = Heron.Convert.ToWGS(boundary[i].GetBoundingBox(true).Max);
                    double[] minpT = new double[3];
                    double[] maxpT = new double[3];

                    minpT[0] = min.X;
                    minpT[1] = min.Y;
                    minpT[2] = min.Z;
                    maxpT[0] = max.X;
                    maxpT[1] = max.Y;
                    maxpT[2] = max.Z;
                    revTransform.TransformPoint(minpT);
                    revTransform.TransformPoint(maxpT);

                    OSGeo.OGR.Geometry bbox  = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + min.X + " " + min.Y + ", " + min.X + " " + max.Y + ", " + max.X + " " + max.Y + ", " + max.X + " " + min.Y + ", " + min.X + " " + min.Y + "))");
                    OSGeo.OGR.Geometry ebbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + minpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + minpT[1] + "))");

                    //Clip Shapefile
                    //http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html
                    OSGeo.OGR.Layer clipped_layer = layerset[0];
                    clipped_layer.SetSpatialFilter(ebbox);

                    //Loop through geometry
                    OSGeo.OGR.Feature feat;
                    def = clipped_layer.GetLayerDefn();

                    int m = 0;
                    while ((feat = layerset[0].GetNextFeature()) != null)
                    {
                        if (feat.GetGeometryRef() != null)
                        {
                            //Get geometry points and field values
                            OSGeo.OGR.Geometry geom = feat.GetGeometryRef();
                            OSGeo.OGR.Geometry sub_geom;

                            //Start get points if open polylines and points
                            for (int gpc = 0; gpc < geom.GetPointCount(); gpc++)
                            { //Loop through geometry points
                                double[] pT = new double[3];
                                pT[0] = geom.GetX(gpc);
                                pT[1] = geom.GetY(gpc);
                                pT[2] = geom.GetZ(gpc);
                                if (Double.IsNaN(geom.GetZ(gpc)))
                                {
                                    pT[2] = 0;
                                }
                                coordTransform.TransformPoint(pT);

                                Point3d pt3D = new Point3d();
                                pt3D.X = pT[0];
                                pt3D.Y = pT[1];
                                pt3D.Z = pT[2];

                                gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, m));
                                //End loop through geometry points

                                // Get Feature Values
                                if (fset.PathExists(new GH_Path(i, m)))
                                {
                                    fset.get_Branch(new GH_Path(i, m)).Clear();
                                }
                                for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                {
                                    OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                    if (feat.IsFieldSet(iField))
                                    {
                                        fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, m));
                                    }
                                    else
                                    {
                                        fset.Append(new GH_String("null"), new GH_Path(i, m));
                                    }
                                }
                                //End Get Feature Values
                            }
                            //End getting points if open polylines or points

                            //Start getting points if closed polylines and multipolygons
                            for (int gi = 0; gi < geom.GetGeometryCount(); gi++)
                            {
                                sub_geom = geom.GetGeometryRef(gi);
                                List <Point3d> geom_list = new List <Point3d>();

                                for (int ptnum = 0; ptnum < sub_geom.GetPointCount(); ptnum++)
                                {
                                    //Loop through geometry points
                                    double[] pT = new double[3];
                                    pT[0] = sub_geom.GetX(ptnum);
                                    pT[1] = sub_geom.GetY(ptnum);
                                    pT[2] = sub_geom.GetZ(ptnum);
                                    coordTransform.TransformPoint(pT);

                                    Point3d pt3D = new Point3d();
                                    pt3D.X = pT[0];
                                    pt3D.Y = pT[1];
                                    pt3D.Z = pT[2];

                                    gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, m, gi));
                                    //End loop through geometry points

                                    // Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, m));
                                        }
                                    }
                                    //End Get Feature Values
                                }
                                //End getting points from closed polylines
                            }
                            m++;
                        }
                        feat.Dispose();
                    }
                }
                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the Shapefile dataset.");
                    //return;
                }
            }

            //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);
                fieldnames.Add(fdef.GetNameRef());
            }

            DA.SetData(0, def.GetName());
            DA.SetDataList(1, fc);
            DA.SetData(2, rec);
            DA.SetData(3, sRef);
            DA.SetDataList(4, fieldnames);
            DA.SetDataTree(5, fset);
            DA.SetDataTree(6, gset);
        }
Exemple #7
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);
        }
Exemple #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)
        {
            GH_Structure <GH_Point>   ptsTree  = new GH_Structure <GH_Point>();
            GH_Structure <GH_Vector>  velTree  = new GH_Structure <GH_Vector>();
            GH_Structure <GH_Number>  massTree = new GH_Structure <GH_Number>();
            GH_Structure <GH_Boolean> scTree   = new GH_Structure <GH_Boolean>();
            GH_Structure <GH_Boolean> ifTree   = new GH_Structure <GH_Boolean>();
            GH_Structure <GH_Integer> giTree   = new GH_Structure <GH_Integer>();

            DA.GetDataTree(0, out ptsTree);
            DA.GetDataTree(1, out velTree);
            DA.GetDataTree(2, out massTree);
            DA.GetDataTree(3, out scTree);
            DA.GetDataTree(4, out ifTree);
            DA.GetDataTree(5, out giTree);

            #region clean up etc
            if (!ptsTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!velTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!massTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!scTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!ifTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!giTree.IsEmpty)
            {
                ptsTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }

            if (ptsTree.Branches.Count == 1)
            {
                GH_Structure <GH_Point> pT = new GH_Structure <GH_Point>();
                pT.AppendRange(ptsTree.Branches[0], new GH_Path(0));
                ptsTree = pT;
            }
            if (velTree.Branches.Count == 1)
            {
                GH_Structure <GH_Vector> pT = new GH_Structure <GH_Vector>();
                pT.AppendRange(velTree.Branches[0], new GH_Path(0));
                velTree = pT;
            }
            if (massTree.Branches.Count == 1)
            {
                GH_Structure <GH_Number> mT = new GH_Structure <GH_Number>();
                mT.AppendRange(massTree.Branches[0], new GH_Path(0));
                massTree = mT;
            }
            if (scTree.Branches.Count == 1)
            {
                GH_Structure <GH_Boolean> mT = new GH_Structure <GH_Boolean>();
                mT.AppendRange(scTree.Branches[0], new GH_Path(0));
                scTree = mT;
            }
            if (ifTree.Branches.Count == 1)
            {
                GH_Structure <GH_Boolean> mT = new GH_Structure <GH_Boolean>();
                mT.AppendRange(ifTree.Branches[0], new GH_Path(0));
                ifTree = mT;
            }
            if (giTree.Branches.Count == 1)
            {
                GH_Structure <GH_Integer> mT = new GH_Structure <GH_Integer>();
                mT.AppendRange(giTree.Branches[0], new GH_Path(0));
                giTree = mT;
            }
            #endregion

            List <FlexParticle> parts = new List <FlexParticle>();

            for (int i = 0; i < ptsTree.PathCount; i++)
            {
                GH_Path path = new GH_Path(i);

                for (int j = 0; j < ptsTree.get_Branch(path).Count; j++)
                {
                    float[] pos = new float[3] {
                        (float)ptsTree.get_DataItem(path, j).Value.X, (float)ptsTree.get_DataItem(path, j).Value.Y, (float)ptsTree.get_DataItem(path, j).Value.Z
                    };

                    float[] vel = new float[3] {
                        0.0f, 0.0f, 0.0f
                    };
                    if (velTree.PathExists(path))
                    {
                        if (velTree.get_Branch(path).Count > j)
                        {
                            vel = new float[3] {
                                (float)velTree.get_DataItem(path, j).Value.X, (float)velTree.get_DataItem(path, j).Value.Y, (float)velTree.get_DataItem(path, j).Value.Z
                            }
                        }
                        ;
                        else
                        {
                            vel = new float[3] {
                                (float)velTree.get_DataItem(path, 0).Value.X, (float)velTree.get_DataItem(path, 0).Value.Y, (float)velTree.get_DataItem(path, 0).Value.Z
                            }
                        };
                    }

                    float iM = 1.0f;
                    if (massTree.PathExists(path))
                    {
                        if (massTree.get_Branch(path).Count > j)
                        {
                            iM = 1.0f / (float)massTree.get_DataItem(path, j).Value;
                        }
                        else
                        {
                            iM = 1.0f / (float)massTree.get_DataItem(path, 0).Value;
                        }
                    }

                    bool sc = false;
                    if (scTree.PathExists(path))
                    {
                        if (scTree.get_Branch(path).Count > j)
                        {
                            sc = scTree.get_DataItem(path, j).Value;
                        }
                        else
                        {
                            sc = scTree.get_DataItem(path, 0).Value;
                        }
                    }

                    bool isf = false;
                    if (ifTree.PathExists(path))
                    {
                        if (ifTree.get_Branch(path).Count > j)
                        {
                            isf = ifTree.get_DataItem(path, j).Value;
                        }
                        else
                        {
                            isf = ifTree.get_DataItem(path, 0).Value;
                        }
                    }

                    int gi = i;
                    if (giTree.PathExists(path))
                    {
                        if (giTree.get_Branch(path).Count > j)
                        {
                            gi = giTree.get_DataItem(path, j).Value;
                        }
                        else
                        {
                            gi = giTree.get_DataItem(path, 0).Value;
                        }
                    }

                    parts.Add(new FlexParticle(pos, vel, iM, sc, isf, gi, true));
                }
            }

            DA.SetDataList(0, parts);
        }
        public override void DoWork(Action <string, double> ReportProgress, Action Done)
        {
            try
            {
                Parent.Message = "Extending...";
                var path = new GH_Path(iteration);
                if (valueTree.PathExists(path))
                {
                    var values = valueTree.get_Branch(path) as List <IGH_Goo>;
                    // Input is a list of values. Assign them directly
                    if (keys.Count != values?.Count)
                    {
                        Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Key and Value lists are not the same length.");
                        Parent.Message = "Error";
                        return;
                    }

                    AssignToObject(@base, keys, values);
                }
                else if (valueTree.Branches.Count == 1)
                {
                    var values = valueTree.Branches[0];
                    if (keys.Count != values.Count)
                    {
                        Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Key and Value lists are not the same length.");
                        Parent.Message = "Error";
                        return;
                    }

                    // Input is just one list, so use it.
                    AssignToObject(@base, keys, values);
                }
                else
                {
                    // Input is a tree, meaning it's values are either lists or trees.
                    var subTree   = Utilities.GetSubTree(valueTree, path);
                    var index     = 0;
                    var foundTree = false;
                    keys.ForEach(key =>
                    {
                        var subPath = new GH_Path(index);
                        if (subTree.PathExists(subPath))
                        {
                            // Value is a list, convert and assign.
                            var list = subTree.get_Branch(subPath) as List <IGH_Goo>;
                            if (list?.Count > 0)
                            {
                                try
                                {
                                    @base[key] = list.Select(goo => Utilities.TryConvertItemToSpeckle(goo, Converter)).ToList();
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine(e);
                                }
                            }
                            ;
                        }
                        else
                        {
                            foundTree = true;
                        }

                        index++;
                    });

                    if (foundTree)
                    {
                        // TODO: Handle tree conversions
                        Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Cannot handle trees yet");
                        Parent.Message = "Error";
                    }
                }

                Done();
            }
            catch (Exception e)
            {
                // If we reach this, something happened that we weren't expecting...
                Log.CaptureException(e);
                Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went terribly wrong... " + e.Message);
                Parent.Message = "Error";
            }
        }
Exemple #10
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)
        {
            double anchorThreshold = 0.01;

            List <Mesh> meshes = new List <Mesh>();
            GH_Structure <GH_Vector> velTree          = new GH_Structure <GH_Vector>();
            GH_Structure <GH_Number> massTree         = new GH_Structure <GH_Number>();
            List <double>            stretchStiffness = new List <double>();
            List <double>            bendStiffness    = new List <double>();
            List <double>            preTension       = new List <double>();
            GH_Structure <IGH_Goo>   anchorTree       = new GH_Structure <IGH_Goo>();
            List <int> groupIndexList = new List <int>();

            List <Cloth> cloths = new List <Cloth>();

            DA.GetDataList(0, meshes);
            DA.GetDataTree(1, out velTree);
            DA.GetDataTree(2, out massTree);
            DA.GetDataList(3, stretchStiffness);
            DA.GetDataList(4, bendStiffness);
            DA.GetDataList(5, preTension);
            DA.GetDataTree(6, out anchorTree);
            DA.GetDataList(7, groupIndexList);

            #region simplify trees and if(branch.Count == 1) make sure everything sits in path {0}
            if (!velTree.IsEmpty)
            {
                velTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!massTree.IsEmpty)
            {
                massTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!anchorTree.IsEmpty)
            {
                anchorTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (velTree.Branches.Count == 1)
            {
                GH_Structure <GH_Vector> vT = new GH_Structure <GH_Vector>();
                vT.AppendRange(velTree.Branches[0], new GH_Path(0));
                velTree = vT;
            }
            if (massTree.Branches.Count == 1)
            {
                GH_Structure <GH_Number> mT = new GH_Structure <GH_Number>();
                mT.AppendRange(massTree.Branches[0], new GH_Path(0));
                massTree = mT;
            }
            if (anchorTree.Branches.Count == 1)
            {
                GH_Structure <IGH_Goo> aT = new GH_Structure <IGH_Goo>();
                aT.AppendRange(anchorTree.Branches[0], new GH_Path(0));
                anchorTree = aT;
            }
            #endregion

            for (int i = 0; i < meshes.Count; i++)
            {
                Mesh mesh = new Mesh();
                mesh.Vertices.AddVertices(meshes[i].Vertices);
                mesh.Faces.AddFaces(meshes[i].Faces);

                GH_Path      path       = new GH_Path(i);
                List <float> positions  = new List <float>();
                List <float> velocities = new List <float>();
                List <float> invMasses  = new List <float>();

                for (int j = 0; j < mesh.Vertices.Count; j++)
                {
                    positions.Add((float)mesh.Vertices[j].X);
                    positions.Add((float)mesh.Vertices[j].Y);
                    positions.Add((float)mesh.Vertices[j].Z);

                    Vector3d vel = new Vector3d(0.0, 0.0, 0.0);
                    if (velTree.PathExists(path))
                    {
                        if (velTree.get_Branch(path).Count == 1)
                        {
                            vel = velTree.get_DataItem(path, 0).Value;
                        }
                        else if (velTree.get_Branch(path).Count > j)
                        {
                            vel = velTree.get_DataItem(path, j).Value;
                        }
                    }
                    velocities.Add((float)vel.X);
                    velocities.Add((float)vel.Y);
                    velocities.Add((float)vel.Z);

                    float invMass = 1.0f;
                    if (massTree.PathExists(path))
                    {
                        if (massTree.get_Branch(path).Count == 1)
                        {
                            invMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value;
                        }
                        else if (massTree.get_Branch(path).Count > j)
                        {
                            invMass = 1.0f / (float)massTree.get_DataItem(path, j).Value;
                        }
                    }
                    invMasses.Add(invMass);
                }

                int[]   triangles       = new int[mesh.Faces.Count * 3];
                float[] triangleNormals = new float[mesh.Faces.Count * 3];
                mesh.UnifyNormals();
                mesh.FaceNormals.ComputeFaceNormals();

                for (int j = 0; j < triangles.Length / 3; j++)
                {
                    triangles[3 * j]           = mesh.Faces[j].A;
                    triangles[3 * j + 1]       = mesh.Faces[j].B;
                    triangles[3 * j + 2]       = mesh.Faces[j].C;
                    triangleNormals[3 * j]     = mesh.FaceNormals[j].X;
                    triangleNormals[3 * j + 1] = mesh.FaceNormals[j].Y;
                    triangleNormals[3 * j + 2] = mesh.FaceNormals[j].Z;
                }

                List <int> anchorIndices = new List <int>();
                if (anchorTree.PathExists(path))
                {
                    foreach (IGH_Goo ao in anchorTree.get_Branch(path))
                    {
                        string  aS = "";
                        int     aI = -1;
                        Point3d aP;
                        if (ao.CastTo <Point3d>(out aP))
                        {
                            for (int j = 0; j < positions.Count / 3; j++)
                            {
                                if (Util.SquareDistance(new Point3d(positions[3 * j], positions[3 * j + 1], positions[3 * j + 2]), aP) < anchorThreshold * anchorThreshold)
                                {
                                    anchorIndices.Add(j);
                                    break;
                                }
                            }
                        }
                        else if (ao.CastTo <int>(out aI))
                        {
                            anchorIndices.Add(aI);
                        }
                        else if (ao.CastTo <string>(out aS))
                        {
                            anchorIndices.Add(int.Parse(aS));
                        }
                    }
                }

                float preTens = (float)preTension[0];;
                if (preTension.Count > i)
                {
                    preTens = (float)preTension[i];
                }

                float sStiffness = (float)stretchStiffness[0];
                if (stretchStiffness.Count > i)
                {
                    sStiffness = (float)stretchStiffness[i];
                }

                float bStiffness = (float)bendStiffness[0];
                if (bendStiffness.Count > i)
                {
                    bStiffness = (float)bendStiffness[i];
                }


                Cloth cloth = new Cloth(positions.ToArray(), velocities.ToArray(), invMasses.ToArray(), triangles, triangleNormals, sStiffness, bStiffness, preTens, anchorIndices.ToArray(), groupIndexList[i]);
                cloth.Mesh = mesh;
                cloths.Add(cloth);
            }

            DA.SetDataList(0, cloths);
        }
Exemple #11
0
        public override void DoWork(Action <string, double> ReportProgress, Action Done)
        {
            // 👉 Checking for cancellation!
            if (CancellationToken.IsCancellationRequested)
            {
                return;
            }
            Parent.Message = "Creating...";
            // Create a path from the current iteration
            var searchPath = new GH_Path(iteration);

            // Grab the corresponding subtree from the value input tree.
            var subTree = Utilities.GetSubTree(valueTree, searchPath);

            speckleObj = new Base();
            // Find the list or subtree belonging to that path
            if (valueTree.PathExists(searchPath) || valueTree.Paths.Count == 1)
            {
                var list = valueTree.Paths.Count == 1 ? valueTree.Branches[0] : valueTree.get_Branch(searchPath);
                // We got a list of values
                var ind = 0;
                keys.ForEach(key =>
                {
                    if (ind < list.Count)
                    {
                        speckleObj[key] = Utilities.TryConvertItemToSpeckle(list[ind], Converter);
                    }
                    ind++;
                });
            }
            else
            {
                // We got a tree of values

                // Create the speckle object with the specified keys
                var index = 0;
                keys.ForEach(key =>
                {
                    var itemPath = new GH_Path(index);

                    var branch = subTree.get_Branch(itemPath);
                    if (branch != null)
                    {
                        var objs = new List <object>();
                        foreach (var goo in branch)
                        {
                            objs.Add(Utilities.TryConvertItemToSpeckle(goo, Converter));
                        }

                        if (objs.Count > 0)
                        {
                            speckleObj[key] = objs;
                        }
                    }

                    index++;
                });
            }
            // --> Report progress if necessary
            // ReportProgress(Id, percentage);

            // Call Done() to signal it's finished.
            Done();
        }
Exemple #12
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)
        {
            GH_Structure <GH_Curve> crvs = new GH_Structure <GH_Curve>();

            DA.GetDataTree <GH_Curve>(0, out crvs);

            GH_Structure <GH_Number> height = new GH_Structure <GH_Number>();

            DA.GetDataTree <GH_Number>(1, out height);

            double tol = DocumentTolerance();

            //reserve one processor for GUI

            //create a dictionary that works in parallel
            var mPatchTree = new System.Collections.Concurrent.ConcurrentDictionary <GH_Path, GH_Mesh>();

            //Multi-threading the loop
            System.Threading.Tasks.Parallel.ForEach(crvs.Paths,
                                                    new System.Threading.Tasks.ParallelOptions {
                MaxDegreeOfParallelism = totalMaxConcurrancy
            },
                                                    pth =>
            {
                List <Curve> branchCrvs = new List <Curve>();
                double offset           = 0;
                if (crvs.get_Branch(pth).Count > 0)
                {
                    foreach (var ghCrv in crvs.get_Branch(pth))
                    {
                        Curve c = null;
                        GH_Convert.ToCurve(ghCrv, ref c, 0);

                        if (extrudeDir == "Extrude Z")
                        {
                            ///Ensure boundary winds clockwise
                            if (c.ClosedCurveOrientation(Vector3d.ZAxis) < 0)
                            {
                                c.Reverse();
                            }
                        }

                        branchCrvs.Add(c);
                    }

                    ///Convert first curve in branch to polyline
                    ///Don't know why the boundary parameter can't be a Curve if the holes are allowed to be Curves
                    Polyline pL = null;
                    branchCrvs[0].TryGetPolyline(out pL);
                    branchCrvs.RemoveAt(0);
                    if (!pL.IsClosed)
                    {
                        pL.Add(pL[0]);
                    }

                    ///Check validity of pL
                    if (!pL.IsValid)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Outer boundary curve could not be converted to polyline or is invalid");
                    }

                    ///The magic found here:
                    ///https://discourse.mcneel.com/t/mesh-with-holes-from-polylines-in-rhinowip-to-c/45589
                    Mesh mPatch = Mesh.CreatePatch(pL, tol, null, branchCrvs, null, null, true, 1);
                    mPatch.Ngons.AddPlanarNgons(tol);
                    //mPatch.UnifyNormals();
                    mPatch.FaceNormals.ComputeFaceNormals();
                    mPatch.Normals.ComputeNormals();
                    mPatch.Compact();

                    if (height.PathExists(pth))
                    {
                        if (height.get_Branch(pth).Count > 0)
                        {
                            GH_Convert.ToDouble(height.get_Branch(pth)[0], out offset, 0);
                            if (extrudeDir == "Extrude Z")
                            {
                                mPatch = mPatch.Offset(offset, true, Vector3d.ZAxis);
                            }
                            else
                            {
                                mPatch.Flip(true, true, true);
                                mPatch = mPatch.Offset(offset, true);
                            }
                        }
                    }
                    else if (height.get_FirstItem(true) != null)
                    {
                        GH_Convert.ToDouble(height.get_FirstItem(true), out offset, 0);
                        if (extrudeDir == "Extrude Z")
                        {
                            mPatch = mPatch.Offset(offset, true, Vector3d.ZAxis);
                        }
                        else
                        {
                            mPatch.Flip(true, true, true);
                            mPatch = mPatch.Offset(offset, true);
                        }
                    }
                    else
                    {
                    }

                    if (mPatch != null)
                    {
                        if (mPatch.SolidOrientation() < 0)
                        {
                            mPatch.Flip(true, true, true);
                        }
                    }

                    mPatchTree[pth] = new GH_Mesh(mPatch);
                }
            });
            ///End of multi-threaded loop


            ///Convert dictionary to regular old data tree
            GH_Structure <GH_Mesh> mTree = new GH_Structure <GH_Mesh>();

            foreach (KeyValuePair <GH_Path, GH_Mesh> m in mPatchTree)
            {
                mTree.Append(m.Value, m.Key);
            }

            DA.SetDataTree(0, mTree);
        }
Exemple #13
0
        public override void DoWork(Action <string, double> ReportProgress, Action Done)
        {
            try
            {
                // 👉 Checking for cancellation!
                if (CancellationToken.IsCancellationRequested)
                {
                    return;
                }
                Parent.Message = "Creating...";
                // Create a path from the current iteration
                var searchPath = new GH_Path(iteration);

                // Grab the corresponding subtree from the value input tree.
                var subTree = Utilities.GetSubTree(valueTree, searchPath);
                speckleObj = new Base();
                // Find the list or subtree belonging to that path
                if (valueTree.PathExists(searchPath) || valueTree.Paths.Count == 1)
                {
                    var list = valueTree.Paths.Count == 1 ? valueTree.Branches[0] : valueTree.get_Branch(searchPath);
                    // We got a list of values
                    var ind       = 0;
                    var hasErrors = false;
                    keys.ForEach(key =>
                    {
                        if (ind < list.Count)
                        {
                            try
                            {
                                speckleObj[key] = Utilities.TryConvertItemToSpeckle(list[ind], Converter);
                            }
                            catch (Exception e)
                            {
                                Console.WriteLine(e);
                                Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
                                Parent.Message = "Error";
                                hasErrors      = true;
                            }
                        }

                        ind++;
                    });
                    if (hasErrors)
                    {
                        return;
                    }
                }
                else
                {
                    // We got a tree of values

                    // Create the speckle object with the specified keys
                    var index = 0;
                    keys.ForEach(key =>
                    {
                        var itemPath = new GH_Path(index);

                        var branch = subTree.get_Branch(itemPath);
                        if (branch != null)
                        {
                            var objs = new List <object>();
                            foreach (var goo in branch)
                            {
                                objs.Add(Utilities.TryConvertItemToSpeckle(goo, Converter));
                            }

                            if (objs.Count > 0)
                            {
                                try
                                {
                                    speckleObj[key] = objs;
                                }
                                catch (Exception e)
                                {
                                    Console.WriteLine(e);
                                    Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, e.Message);
                                    return;
                                }
                            }
                        }

                        index++;
                    });
                }
                // --> Report progress if necessary
                // ReportProgress(Id, percentage);

                // Call Done() to signal it's finished.
                Done();
            }
            catch (Exception e)
            {
                // If we reach this, something happened that we weren't expecting...
                Log.CaptureException(e);
                Parent.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Something went terribly wrong... " + e.Message);
                Parent.Message = "Error";
            }
        }
Exemple #14
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)
        {
            double anchorThreshold         = 0.01;
            double pointDuplicateThreshold = 0.01;
            bool   isSheetMesh             = false;


            GH_Structure <IGH_Goo>   springTree          = new GH_Structure <IGH_Goo>();
            GH_Structure <GH_Vector> velTree             = new GH_Structure <GH_Vector>();
            GH_Structure <GH_Number> massTree            = new GH_Structure <GH_Number>();
            GH_Structure <GH_Number> lengthTree          = new GH_Structure <GH_Number>();
            GH_Structure <GH_Number> stiffnessTree       = new GH_Structure <GH_Number>();
            List <double>            sheetStiffeningList = new List <double>();
            GH_Structure <IGH_Goo>   anchorTree          = new GH_Structure <IGH_Goo>();
            List <bool> selfCollisionList = new List <bool>();
            List <int>  groupIndexList    = new List <int>();

            List <SpringSystem> springSystems = new List <SpringSystem>();

            DA.GetDataTree(0, out springTree);
            DA.GetDataTree(1, out velTree);
            DA.GetDataTree(2, out massTree);
            DA.GetDataTree(3, out lengthTree);
            DA.GetDataTree(4, out stiffnessTree);
            DA.GetDataList(5, sheetStiffeningList);
            DA.GetDataList(6, selfCollisionList);
            DA.GetDataTree(7, out anchorTree);
            DA.GetDataList(8, groupIndexList);

            #region simplify trees and if(branch.Count == 1) make sure everything sits in path {0}
            if (!springTree.IsEmpty)
            {
                springTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!velTree.IsEmpty)
            {
                velTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!massTree.IsEmpty)
            {
                massTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!lengthTree.IsEmpty)
            {
                lengthTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!stiffnessTree.IsEmpty)
            {
                stiffnessTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }
            if (!anchorTree.IsEmpty)
            {
                anchorTree.Simplify(GH_SimplificationMode.CollapseAllOverlaps);
            }

            if (springTree.Branches.Count != groupIndexList.Count || springTree.Branches.Count != selfCollisionList.Count)
            {
                throw new Exception("Line tree doesn't fit either groupIndices count or selfCollision count!");
            }

            if (springTree.Branches.Count == 1)
            {
                GH_Structure <IGH_Goo> lT = new GH_Structure <IGH_Goo>();
                lT.AppendRange(springTree.Branches[0], new GH_Path(0));
                springTree = lT;
            }
            if (velTree.Branches.Count == 1)
            {
                GH_Structure <GH_Vector> vT = new GH_Structure <GH_Vector>();
                vT.AppendRange(velTree.Branches[0], new GH_Path(0));
                velTree = vT;
            }
            if (massTree.Branches.Count == 1)
            {
                GH_Structure <GH_Number> mT = new GH_Structure <GH_Number>();
                mT.AppendRange(massTree.Branches[0], new GH_Path(0));
                massTree = mT;
            }
            if (lengthTree.Branches.Count == 1)
            {
                GH_Structure <GH_Number> leT = new GH_Structure <GH_Number>();
                leT.AppendRange(lengthTree.Branches[0], new GH_Path(0));
                lengthTree = leT;
            }
            if (stiffnessTree.Branches.Count == 1)
            {
                GH_Structure <GH_Number> sT = new GH_Structure <GH_Number>();
                sT.AppendRange(stiffnessTree.Branches[0], new GH_Path(0));
                stiffnessTree = sT;
            }
            if (anchorTree.Branches.Count == 1)
            {
                GH_Structure <IGH_Goo> aT = new GH_Structure <IGH_Goo>();
                aT.AppendRange(anchorTree.Branches[0], new GH_Path(0));
                anchorTree = aT;
            }
            #endregion

            for (int branchIndex = 0; branchIndex < springTree.Branches.Count; branchIndex++)
            {
                List <float> positions         = new List <float>();
                List <float> velocities        = new List <float>();
                List <float> invMasses         = new List <float>();
                List <int>   springPairIndices = new List <int>();
                List <float> targetLengths     = new List <float>();
                List <float> stiffnesses       = new List <float>();
                List <int>   anchorIndices     = new List <int>();
                List <float> initialLengths    = new List <float>(); //just for info

                GH_Path path = new GH_Path(branchIndex);

                List <Line> lines = new List <Line>();
                Curve       c;
                Line        l;
                Mesh        mesh = new Mesh();
                foreach (IGH_Goo springObject in springTree.get_Branch(path))
                {
                    if (springObject.CastTo <Mesh>(out mesh))
                    {
                        break;
                    }
                    else if (springObject.CastTo <Curve>(out c))
                    {
                        if (c.IsPolyline())
                        {
                            Polyline pl;
                            c.TryGetPolyline(out pl);
                            for (int i = 0; i < pl.SegmentCount; i++)
                            {
                                lines.Add(pl.SegmentAt(i));
                            }
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Polyline in branch " + branchIndex + " was split into its segments!");
                        }
                        else
                        {
                            lines.Add(new Line(c.PointAtStart, c.PointAtEnd));
                        }
                    }
                    else if (springObject.CastTo <Line>(out l))
                    {
                        lines.Add(l);
                    }
                }

                #region isMesh
                if (mesh != null && mesh.IsValid)
                {
                    mesh.Vertices.CombineIdentical(true, true);
                    mesh.Weld(Math.PI);
                    mesh.UnifyNormals();

                    Rhino.Geometry.Collections.MeshTopologyVertexList mv = mesh.TopologyVertices;
                    Rhino.Geometry.Collections.MeshTopologyEdgeList   me = mesh.TopologyEdges;

                    //Add everything related to particles
                    for (int i = 0; i < mv.Count; i++)
                    {
                        //add position
                        positions.Add(mv[i].X);
                        positions.Add(mv[i].Y);
                        positions.Add(mv[i].Z);

                        //add velocity
                        Vector3d vel = new Vector3d(0.0, 0.0, 0.0);
                        if (velTree.PathExists(path))
                        {
                            if (velTree.get_Branch(path).Count > i)
                            {
                                vel = velTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                vel = velTree.get_DataItem(path, 0).Value;
                            }
                        }
                        velocities.Add((float)vel.X);
                        velocities.Add((float)vel.Y);
                        velocities.Add((float)vel.Z);

                        //add inverse mass
                        float invMass = 1.0f;
                        if (massTree.PathExists(path))
                        {
                            if (massTree.get_Branch(path).Count > i)
                            {
                                invMass = 1.0f / (float)massTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                invMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value;
                            }
                        }
                        invMasses.Add(invMass);
                    }

                    //Add everything related to spring lines
                    for (int i = 0; i < me.Count; i++)
                    {
                        springPairIndices.Add(me.GetTopologyVertices(i).I);
                        springPairIndices.Add(me.GetTopologyVertices(i).J);

                        //add length
                        float length = (float)me.EdgeLine(i).Length;
                        initialLengths.Add(length);
                        if (lengthTree.PathExists(path))
                        {
                            float temp = 0.0f;
                            if (lengthTree.get_Branch(path).Count > i)
                            {
                                temp = (float)lengthTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                temp = (float)lengthTree.get_DataItem(path, 0).Value;
                            }

                            if (temp < 0.0)
                            {
                                length *= -temp;
                            }
                            else
                            {
                                length = temp;
                            }
                        }
                        targetLengths.Add(length);

                        //add stiffness
                        float stiffness = 1.0f;
                        if (stiffnessTree.PathExists(path))
                        {
                            if (stiffnessTree.get_Branch(path).Count > i)
                            {
                                stiffness = (float)stiffnessTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value;
                            }
                        }
                        stiffnesses.Add(stiffness);


                        List <Line> f = new List <Line>();
                        if (sheetStiffeningList.Count > branchIndex && sheetStiffeningList[branchIndex] > 0.0)
                        {
                            isSheetMesh = true;
                            int[] adjFaceInd = me.GetConnectedFaces(i);
                            if (adjFaceInd.Length == 2)
                            {
                                f.Add(me.EdgeLine(i));
                                MeshFace faceA = mesh.Faces[adjFaceInd[0]];
                                MeshFace faceB = mesh.Faces[adjFaceInd[1]];
                                if (faceA.IsTriangle && faceB.IsTriangle)
                                {
                                    List <int> allInds = new List <int> {
                                        faceA.A, faceA.B, faceA.C, faceB.A, faceB.B, faceB.C
                                    };
                                    int[] uniques = new int[6] {
                                        0, 0, 0, 0, 0, 0
                                    };
                                    for (int h = 0; h < 6; h++)
                                    {
                                        for (int g = 0; g < 6; g++)
                                        {
                                            if (allInds[h] == allInds[g])
                                            {
                                                uniques[h]++;
                                            }
                                        }
                                    }
                                    for (int h = 0; h < 6; h++)
                                    {
                                        if (uniques[h] == 1)
                                        {
                                            springPairIndices.Add(mv.TopologyVertexIndex(allInds[h]));
                                            stiffnesses.Add((float)(stiffness * sheetStiffeningList[branchIndex]));
                                        }
                                    }
                                    float le = (float)mv[springPairIndices[springPairIndices.Count - 2]].DistanceTo(mv[springPairIndices[springPairIndices.Count - 1]]);
                                    targetLengths.Add(le);
                                    initialLengths.Add(le);
                                    f.Add(new Line(mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 1])], mesh.Vertices[mv.TopologyVertexIndex(springPairIndices[springPairIndices.Count - 2])]));
                                }
                            }
                        }
                    }
                }
                #endregion

                #region isLines
                else if (lines.Count != 0)
                {
                    List <Line> cleanLineList    = new List <Line>();
                    double      ptDuplThrSquared = pointDuplicateThreshold * pointDuplicateThreshold;

                    #region clean up line list
                    List <Line> lHist = new List <Line>();
                    for (int j = 0; j < lines.Count; j++)
                    {
                        //Clean list from duplicate lines
                        Line    lCand             = lines[j];
                        Point3d ptCandA           = lCand.From;
                        Point3d ptCandB           = lCand.To;
                        bool    lineExistsAlready = false;
                        foreach (Line lh in lHist)
                        {
                            Line tempL = new Line(lCand.From, lCand.To);
                            if ((Util.SquareDistance(tempL.From, lh.From) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.To) < ptDuplThrSquared) ||
                                (Util.SquareDistance(tempL.From, lh.To) < ptDuplThrSquared && Util.SquareDistance(tempL.To, lh.From) < ptDuplThrSquared))
                            {
                                lineExistsAlready = true;
                            }
                        }

                        //Clean list from too short lines
                        if (!(Util.SquareDistance(ptCandA, ptCandB) < ptDuplThrSquared || lineExistsAlready))
                        {
                            lHist.Add(lCand);
                            cleanLineList.Add(lCand);
                        }
                        else
                        {
                            AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Spring nr. " + j + " in branch " + branchIndex + " is either invalid (too short) or appeared for the second time. It is ignored.");
                        }
                    }
                    #endregion


                    //get velocity and mass for this branch (no mass / velo per particle allowed)
                    List <float> branchDefaultVelocity = new List <float>()
                    {
                        0.0f, 0.0f, 0.0f
                    };
                    if (velTree.PathExists(path))
                    {
                        branchDefaultVelocity = new List <float> {
                            (float)velTree.get_DataItem(path, 0).Value.X, (float)velTree.get_DataItem(path, 0).Value.Y, (float)velTree.get_DataItem(path, 0).Value.Z
                        }
                    }
                    ;

                    float branchDefaultInvMass = 1.0f;
                    if (massTree.PathExists(path))
                    {
                        branchDefaultInvMass = 1.0f / (float)massTree.get_DataItem(path, 0).Value;
                    }

                    //find unique line start indices
                    List <int> springStartIndices = new List <int>();
                    int        advance            = 0;
                    for (int item = 0; item < cleanLineList.Count; item++)
                    {
                        Point3d ptCand          = cleanLineList[item].From;
                        int     alreadyExistsAs = -1;
                        for (int k = 0; k < positions.Count / 3; k++)
                        {
                            //simple squared distance
                            if (Util.SquareDistance(new Point3d(positions[k * 3], positions[k * 3 + 1], positions[k * 3 + 2]), ptCand) < ptDuplThrSquared)
                            {
                                alreadyExistsAs = k;
                                springStartIndices.Add(alreadyExistsAs);
                                break;
                            }
                        }
                        if (alreadyExistsAs == -1)
                        {
                            positions.Add((float)ptCand.X);
                            positions.Add((float)ptCand.Y);
                            positions.Add((float)ptCand.Z);

                            velocities.AddRange(branchDefaultVelocity);
                            invMasses.Add(branchDefaultInvMass);

                            springStartIndices.Add(advance);
                            advance++;
                        }
                    }

                    //find unique line end indices
                    List <int> springEndIndices = new List <int>();
                    for (int item = 0; item < cleanLineList.Count; item++)
                    {
                        Point3d ptCand          = cleanLineList[item].To;
                        int     alreadyExistsAs = -1;
                        for (int k = 0; k < positions.Count / 3; k++)
                        {
                            if (Util.SquareDistance(new Point3d(positions[3 * k], positions[3 * k + 1], positions[3 * k + 2]), ptCand) < ptDuplThrSquared)
                            {
                                alreadyExistsAs = k;
                                springEndIndices.Add(alreadyExistsAs);
                                break;
                            }
                        }
                        if (alreadyExistsAs == -1)
                        {
                            positions.Add((float)ptCand.X);
                            positions.Add((float)ptCand.Y);
                            positions.Add((float)ptCand.Z);

                            velocities.AddRange(branchDefaultVelocity);
                            invMasses.Add(branchDefaultInvMass);

                            springEndIndices.Add(advance);
                            advance++;
                        }
                    }

                    //weave spring start indices and spring end indices together
                    for (int w = 0; w < springStartIndices.Count; w++)
                    {
                        springPairIndices.Add(springStartIndices[w]);
                        springPairIndices.Add(springEndIndices[w]);
                    }

                    //Add everything spring line related...
                    for (int i = 0; i < cleanLineList.Count; i++)
                    {
                        //add length
                        float length = (float)cleanLineList[i].Length;
                        initialLengths.Add(length);
                        if (lengthTree.PathExists(path))
                        {
                            float temp = 0.0f;
                            if (lengthTree.get_Branch(path).Count > i)
                            {
                                temp = (float)lengthTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                temp = (float)lengthTree.get_DataItem(path, 0).Value;
                            }

                            if (temp < 0.0)
                            {
                                length *= -temp;
                            }
                            else
                            {
                                length = temp;
                            }
                        }
                        targetLengths.Add(length);

                        //add stiffness
                        float stiffness = 1.0f;
                        if (stiffnessTree.PathExists(path))
                        {
                            if (stiffnessTree.get_Branch(path).Count > i)
                            {
                                stiffness = (float)stiffnessTree.get_DataItem(path, i).Value;
                            }
                            else
                            {
                                stiffness = (float)stiffnessTree.get_DataItem(path, 0).Value;
                            }
                        }
                        stiffnesses.Add(stiffness);
                    }
                }
                #endregion
                else
                {
                    throw new Exception("No valid spring input found in branch " + branchIndex);
                }


                //Add anchors
                if (anchorTree.PathExists(path))
                {
                    foreach (IGH_Goo anchorObj in anchorTree.get_Branch(path))
                    {
                        string  ass = "";
                        int     ai  = 0;
                        Point3d ap  = new Point3d(0.0, 0.0, 0.0);
                        if (anchorObj.CastTo <string>(out ass))
                        {
                            anchorIndices.Add(int.Parse(ass));
                        }
                        else if (anchorObj.CastTo <int>(out ai))
                        {
                            anchorIndices.Add(ai);
                        }
                        else if (anchorObj.CastTo <Point3d>(out ap))
                        {
                            for (int i = 0; i < positions.Count / 3; i++)
                            {
                                if ((anchorThreshold * anchorThreshold) > Math.Pow((positions[3 * i] - ap.X), 2) + Math.Pow((positions[3 * i + 1] - ap.Y), 2) + Math.Pow((positions[3 * i + 2] - ap.Z), 2))
                                {
                                    anchorIndices.Add(i);
                                }
                            }
                        }
                    }
                }

                SpringSystem ss = new SpringSystem(positions.ToArray(), velocities.ToArray(), invMasses.ToArray(), springPairIndices.ToArray(), targetLengths.ToArray(), stiffnesses.ToArray(), selfCollisionList[branchIndex], anchorIndices.ToArray(), groupIndexList[branchIndex]);
                ss.Mesh           = mesh;
                ss.IsSheetMesh    = isSheetMesh;
                ss.InitialLengths = initialLengths.ToArray();
                springSystems.Add(ss);
            }
            DA.SetDataList(0, springSystems);
        }
Exemple #15
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
Exemple #16
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ///Gather GHA inputs
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>("Boundary", boundary);

            string shpFilePath = string.Empty;

            DA.GetData <string>("Vector Data Location", ref shpFilePath);

            bool cropIt = true;

            DA.GetData <Boolean>("Crop file", ref cropIt);

            string userSRStext = "WGS84";

            DA.GetData <string>(2, ref userSRStext);


            ///GDAL setup
            ///Some preliminary testing has been done to read SHP, GeoJSON, OSM, KML, MVT, GML and GDB
            ///It can be spotty with KML, MVT and GML and doesn't throw informative errors.  Likely has to do with getting a valid CRS and
            ///TODO: resolve errors with reading KML, MVT, GML.

            DataSource   dataSource = CreateDataSource(shpFilePath);
            List <Layer> layerSet   = GetLayers(dataSource);

            ///Declare trees
            GH_Structure <GH_Rectangle> recs = new GH_Structure <GH_Rectangle>();
            GH_Structure <GH_String>    spatialReferences = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fnames            = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fset = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>     gset = new GH_Structure <GH_Point>();

            GH_Structure <GH_Point>     gsetUser = new GH_Structure <GH_Point>();
            GH_Structure <GH_Rectangle> recsUser = new GH_Structure <GH_Rectangle>();

            GH_Structure <GH_String>        gtype = new GH_Structure <GH_String>();
            GH_Structure <IGH_GeometricGoo> gGoo  = new GH_Structure <IGH_GeometricGoo>();


            ///Loop through each layer. Layers usually occur in Geodatabase GDB format. SHP usually has only one layer.
            for (int iLayer = 0; iLayer < dataSource.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = dataSource.GetLayerByIndex(iLayer);

                if (layer == null)
                {
                    Console.WriteLine($"Couldn't fetch advertised layer {iLayer}");
                    System.Environment.Exit(-1);
                }

                long count        = layer.GetFeatureCount(1);
                int  featureCount = System.Convert.ToInt32(count);



                AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Layer #{iLayer} {layer.GetName()} has {featureCount} features");

                ///Get the spatial reference of the input vector file and set to WGS84 if not known
                ///
                OSGeo.OSR.SpatialReference sourceSRS = new SpatialReference(Osr.SRS_WKT_WGS84);
                string spatialReference = GetSpatialReference(layer, iLayer, dataSource, sourceSRS);
                spatialReferences.Append(new GH_String(spatialReference), new GH_Path(iLayer));


                ///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);

                ///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);

                ///Get OGR envelope of the data in the layer in the sourceSRS
                OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope();
                layer.GetExtent(ext, 1);

                OSGeo.OGR.Geometry extMinSourceOgr = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPoint);
                extMinSourceOgr.AddPoint(ext.MinX, ext.MinY, 0.0);
                extMinSourceOgr.AssignSpatialReference(sourceSRS);

                OSGeo.OGR.Geometry extMaxSourceOgr = new OSGeo.OGR.Geometry(wkbGeometryType.wkbPoint);
                extMaxSourceOgr.AddPoint(ext.MaxX, ext.MaxY, 0.0);
                extMaxSourceOgr.AssignSpatialReference(sourceSRS);

                ///Get extents in Rhino SRS
                Point3d extPTmin = Heron.Convert.OgrPointToPoint3d(extMinSourceOgr, sourceToModelSRSTransform);
                Point3d extPTmax = Heron.Convert.OgrPointToPoint3d(extMaxSourceOgr, sourceToModelSRSTransform);

                Rectangle3d rec = new Rectangle3d(Plane.WorldXY, extPTmin, extPTmax);
                recs.Append(new GH_Rectangle(rec), new GH_Path(iLayer));

                ///Get extents in userSRS
                ///Can give odd results if crosses 180 longitude
                extMinSourceOgr.TransformTo(userSRS);
                extMaxSourceOgr.TransformTo(userSRS);

                Point3d extPTminUser = Heron.Convert.OgrPointToPoint3d(extMinSourceOgr, userSRSToModelTransform);
                Point3d extPTmaxUser = Heron.Convert.OgrPointToPoint3d(extMaxSourceOgr, userSRSToModelTransform);

                Rectangle3d recUser = new Rectangle3d(Plane.WorldXY, extPTminUser, extPTmaxUser);
                recsUser.Append(new GH_Rectangle(recUser), new GH_Path(iLayer));


                if (boundary.Count == 0 && cropIt == true)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Define a boundary or set cropIt to False");
                }

                else if (boundary.Count == 0 && cropIt == false)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Clipping boundary has not been defined. File extents will be used instead");
                    boundary.Add(rec.ToNurbsCurve());
                }



                ///Loop through input boundaries
                for (int i = 0; i < boundary.Count; i++)
                {
                    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(i, iLayer));
                    }

                    ///Check if boundary is contained in extent
                    if (!rec.IsValid || ((rec.Height == 0) && (rec.Width == 0)))
                    {
                        ///Get field data if even if no geometry is present in the layer
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more vector datasource bounds are not valid.");
                        OSGeo.OGR.Feature feat;
                        int m = 0;

                        while ((feat = layer.GetNextFeature()) != null)
                        {
                            ///Loop through field values
                            for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                            {
                                OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                fdef.Dispose();
                            }
                            m++;
                            feat.Dispose();
                        }
                    }

                    else if (boundary[i] == null)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + " not set.");
                    }

                    else if (!boundary[i].IsValid)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + "  is not valid.");
                    }

                    else if (rec.IsValid && Curve.PlanarClosedCurveRelationship(rec.ToNurbsCurve(), boundary[i], Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == RegionContainment.Disjoint)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more clipping boundaries may be outside the bounds of the vector datasource.");
                    }

                    else
                    {
                        ///Create bounding box for clipping geometry
                        Point3d min = boundary[i].GetBoundingBox(true).Min;
                        Point3d max = boundary[i].GetBoundingBox(true).Max;
                        min.Transform(modelToSourceSRSTransform);
                        max.Transform(modelToSourceSRSTransform);
                        double[] minpT = new double[3];
                        double[] maxpT = new double[3];

                        minpT[0] = min.X;
                        minpT[1] = min.Y;
                        minpT[2] = min.Z;
                        maxpT[0] = max.X;
                        maxpT[1] = max.Y;
                        maxpT[2] = max.Z;


                        OSGeo.OGR.Geometry ebbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + minpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + minpT[1] + "))");

                        ///Create bounding box for clipping geometry
                        ///Not working on MVT type files
                        //boundary[i].Transform(modelToSourceSRSTransform);
                        //OSGeo.OGR.Geometry ebbox = Heron.Convert.CurveToOgrPolygon(boundary[i]);


                        ///Clip Shapefile
                        ///http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html
                        OSGeo.OGR.Layer clipped_layer = layer;

                        if (cropIt)
                        {
                            clipped_layer.SetSpatialFilter(ebbox);
                        }

                        ///Loop through geometry
                        OSGeo.OGR.Feature feat;
                        def = clipped_layer.GetLayerDefn();

                        int m = 0;
                        while ((feat = clipped_layer.GetNextFeature()) != null)
                        {
                            OSGeo.OGR.Geometry geom = feat.GetGeometryRef();
                            OSGeo.OGR.Geometry sub_geom;

                            OSGeo.OGR.Geometry geomUser = feat.GetGeometryRef().Clone();
                            OSGeo.OGR.Geometry sub_geomUser;

                            ///reproject geometry to WGS84 and userSRS
                            ///TODO: look into using the SetCRS global variable here
                            if (geom.GetSpatialReference() == null)
                            {
                                geom.AssignSpatialReference(sourceSRS);
                            }
                            if (geomUser.GetSpatialReference() == null)
                            {
                                geomUser.AssignSpatialReference(sourceSRS);
                            }

                            geom.TransformTo(rhinoSRS);
                            geomUser.TransformTo(userSRS);
                            gtype.Append(new GH_String(geom.GetGeometryName()), new GH_Path(i, iLayer, m));

                            if (feat.GetGeometryRef() != null)
                            {
                                ///Convert GDAL geometries to IGH_GeometricGoo
                                gGoo.AppendRange(Heron.Convert.OgrGeomToGHGoo(geomUser, userSRSToModelTransform), new GH_Path(i, iLayer, m));

                                /// Get Feature Values
                                if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                {
                                    fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                }
                                for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                {
                                    OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                    if (feat.IsFieldSet(iField))
                                    {
                                        fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                    }
                                    else
                                    {
                                        fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                    }
                                }
                                ///End get Feature Values


                                ///Start get points if open polylines and points
                                for (int gpc = 0; gpc < geom.GetPointCount(); gpc++)
                                {
                                    ///Loop through geometry points for Rhino SRS
                                    double[] ogrPt = new double[3];
                                    geom.GetPoint(gpc, ogrPt);
                                    Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]);
                                    pt3D.Transform(Heron.Convert.WGSToXYZTransform());

                                    gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m));

                                    ///Loop through geometry points for User SRS
                                    double[] ogrPtUser = new double[3];
                                    geomUser.GetPoint(gpc, ogrPtUser);
                                    Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                    pt3DUser.Transform(userSRSToModelTransform);

                                    gsetUser.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m));

                                    ///End loop through geometry points


                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End Get Feature Values
                                }
                                ///End getting points if open polylines or points


                                ///Start getting points if closed polylines and multipolygons
                                for (int gi = 0; gi < geom.GetGeometryCount(); gi++)
                                {
                                    sub_geom = geom.GetGeometryRef(gi);
                                    OSGeo.OGR.Geometry subsub_geom;

                                    sub_geomUser = geomUser.GetGeometryRef(gi);
                                    OSGeo.OGR.Geometry subsub_geomUser;

                                    if (sub_geom.GetGeometryCount() > 0)
                                    {
                                        for (int n = 0; n < sub_geom.GetGeometryCount(); n++)
                                        {
                                            subsub_geom     = sub_geom.GetGeometryRef(n);
                                            subsub_geomUser = sub_geomUser.GetGeometryRef(n);

                                            for (int ptnum = 0; ptnum < subsub_geom.GetPointCount(); ptnum++)
                                            {
                                                ///Loop through geometry points
                                                double[] ogrPt = new double[3];
                                                subsub_geom.GetPoint(ptnum, ogrPt);
                                                Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]);
                                                pt3D.Transform(Heron.Convert.WGSToXYZTransform());

                                                gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m, gi, n));

                                                ///Loop through geometry points for User SRS
                                                double[] ogrPtUser = new double[3];
                                                subsub_geomUser.GetPoint(ptnum, ogrPtUser);
                                                Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                                pt3DUser.Transform(userSRSToModelTransform);

                                                gsetUser.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi, n));

                                                ///End loop through geometry points
                                            }
                                            subsub_geom.Dispose();
                                            subsub_geomUser.Dispose();
                                        }
                                    }

                                    else
                                    {
                                        for (int ptnum = 0; ptnum < sub_geom.GetPointCount(); ptnum++)
                                        {
                                            ///Loop through geometry points
                                            double[] ogrPt = new double[3];
                                            sub_geom.GetPoint(ptnum, ogrPt);
                                            Point3d pt3D = new Point3d(ogrPt[0], ogrPt[1], ogrPt[2]);
                                            pt3D.Transform(Heron.Convert.WGSToXYZTransform());

                                            gset.Append(new GH_Point(pt3D), new GH_Path(i, iLayer, m, gi));

                                            ///Loop through geometry points for User SRS
                                            double[] ogrPtUser = new double[3];
                                            sub_geomUser.GetPoint(ptnum, ogrPtUser);
                                            Point3d pt3DUser = new Point3d(ogrPtUser[0], ogrPtUser[1], ogrPtUser[2]);
                                            pt3DUser.Transform(userSRSToModelTransform);

                                            gsetUser.Append(new GH_Point(pt3DUser), new GH_Path(i, iLayer, m, gi));

                                            ///End loop through geometry points
                                        }
                                    }

                                    sub_geom.Dispose();
                                    sub_geomUser.Dispose();


                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End Get Feature Values
                                }


                                //m++;
                            }
                            m++;
                            geom.Dispose();
                            geomUser.Dispose();
                            feat.Dispose();
                        } ///end while loop through features
                    }     ///end clipped layer else statement
                }         ///end loop through boundaries

                layer.Dispose();
            }///end loop through layers

            dataSource.Dispose();

            DA.SetDataTree(0, recs);
            DA.SetDataTree(1, spatialReferences);
            DA.SetDataTree(2, fnames);
            DA.SetDataTree(3, fset);
            DA.SetDataTree(4, gset);

            DA.SetDataTree(5, gsetUser);
            DA.SetDataTree(6, recsUser);

            DA.SetDataTree(7, gGoo);
            DA.SetDataTree(8, gtype);
        }
Exemple #17
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> boundary = new List <Curve>();

            DA.GetDataList <Curve>(0, boundary);

            string shpFileLoc = "";

            DA.GetData <string>("Vector Data Location", ref shpFileLoc);

            ///GDAL setup
            ///Some preliminary testing has been done to read SHP, GeoJSON, OSM, KML, MVT, GML and GDB
            ///It can be spotty with KML, MVT and GML and doesn't throw informative errors.  Likely has to do with getting a valid CRS and
            ///TODO: resolve errors with reading KML, MVT, GML.

            RESTful.GdalConfiguration.ConfigureOgr();
            OSGeo.OGR.Ogr.RegisterAll();
            OSGeo.OGR.Driver     drv = OSGeo.OGR.Ogr.GetDriverByName("ESRI Shapefile");
            OSGeo.OGR.DataSource ds  = OSGeo.OGR.Ogr.Open(shpFileLoc, 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;
            }

            List <OSGeo.OGR.Layer> layerset = new List <OSGeo.OGR.Layer>();
            List <int>             fc       = new List <int>();

            for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer);

                if (layer == null)
                {
                    Console.WriteLine("Couldn't fetch advertised layer " + iLayer);
                    System.Environment.Exit(-1);
                }
                else
                {
                    layerset.Add(layer);
                }
            }

            ///Declare trees
            GH_Structure <GH_String>    layname = new GH_Structure <GH_String>();
            GH_Structure <GH_Integer>   fcs     = new GH_Structure <GH_Integer>();
            GH_Structure <GH_Rectangle> recs    = new GH_Structure <GH_Rectangle>();
            GH_Structure <GH_String>    sRefs   = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fnames  = new GH_Structure <GH_String>();
            GH_Structure <GH_String>    fset    = new GH_Structure <GH_String>();
            GH_Structure <GH_Point>     gset    = new GH_Structure <GH_Point>();


            ///Loop through each layer. Layers usually occur in Geodatabase GDB format. SHP usually has only one layer.
            for (int iLayer = 0; iLayer < ds.GetLayerCount(); iLayer++)
            {
                OSGeo.OGR.Layer layer = ds.GetLayerByIndex(iLayer);

                if (layer == null)
                {
                    Console.WriteLine("Couldn't fetch advertised layer " + iLayer);
                    System.Environment.Exit(-1);
                }

                long count        = layer.GetFeatureCount(1);
                int  featureCount = System.Convert.ToInt32(count);
                fcs.Append(new GH_Integer(featureCount), new GH_Path(iLayer));

                layname.Append(new GH_String(layer.GetName()), new GH_Path(iLayer));


                ///Get OGR envelope of the data in the layer
                OSGeo.OGR.Envelope ext = new OSGeo.OGR.Envelope();
                layer.GetExtent(ext, 1);
                Point3d extMin = new Point3d();
                Point3d extMax = new Point3d();
                extMin.X = ext.MinX;
                extMin.Y = ext.MinY;
                extMax.X = ext.MaxX;
                extMax.Y = ext.MaxY;


                ///Get the spatial reference of the input vector file and set to WGS84 if not known
                OSGeo.OSR.SpatialReference sr = new SpatialReference(Osr.SRS_WKT_WGS84);
                string sRef = "";

                if (layer.GetSpatialRef() == null)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is missing.  CRS set automatically set to WGS84.");
                    sr.ImportFromXML(shpFileLoc);
                    string pretty = "";
                    sr.ExportToPrettyWkt(out pretty, 0);
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, pretty);
                    sr.SetWellKnownGeogCS("WGS84");
                    sRef = "Coordinate Reference System (CRS) is missing.  CRS set automatically set to WGS84.";
                    //sr.ImportFromEPSG(2263);
                }
                else
                {
                    if (layer.GetSpatialRef().Validate() != 0)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported.  CRS set automatically set to WGS84.");
                        sr.SetWellKnownGeogCS("WGS84");
                        sRef = "Coordinate Reference System (CRS) is unknown or unsupported.  SRS set automatically set to WGS84.";
                    }
                    else
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) set from layer" + iLayer + ".");
                        sr = layer.GetSpatialRef();
                        sr.ExportToWkt(out sRef);
                    }
                }

                sRefs.Append(new GH_String(sRef), new GH_Path(iLayer));


                ///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 dst = new OSGeo.OSR.SpatialReference("");
                dst.SetWellKnownGeogCS("WGS84");
                OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst);
                OSGeo.OSR.CoordinateTransformation revTransform   = new OSGeo.OSR.CoordinateTransformation(dst, sr);


                ///Get bounding box of data in layer
                double[] extMinPT = new double[3] {
                    extMin.X, extMin.Y, extMin.Z
                };
                double[] extMaxPT = new double[3] {
                    extMax.X, extMax.Y, extMax.Z
                };
                coordTransform.TransformPoint(extMinPT);
                coordTransform.TransformPoint(extMaxPT);
                Point3d     extPTmin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]);
                Point3d     extPTmax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]);
                Rectangle3d rec      = new Rectangle3d(Plane.WorldXY, Heron.Convert.ToXYZ(extPTmin), Heron.Convert.ToXYZ(extPTmax));
                recs.Append(new GH_Rectangle(rec), new GH_Path(iLayer));


                ///Loop through input boundaries
                for (int i = 0; i < boundary.Count; i++)
                {
                    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(i, iLayer));
                    }

                    ///Check if boundary is contained in extent
                    if (!rec.IsValid || ((rec.Height == 0) && (rec.Width == 0)))
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more vector datasource bounds are not valid.");
                        OSGeo.OGR.Feature feat;
                        int m = 0;

                        while ((feat = layer.GetNextFeature()) != null)
                        {
                            ///Loop through field values
                            for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                            {
                                OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                fdef.Dispose();
                            }
                            m++;
                            feat.Dispose();
                        }
                    }

                    else if (boundary[i] == null)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + " not set.");
                    }

                    else if (!boundary[i].IsValid)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Clipping boundary " + i + "  is not valid.");
                    }

                    else if (rec.IsValid && Curve.PlanarClosedCurveRelationship(rec.ToNurbsCurve(), boundary[i], Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == RegionContainment.Disjoint)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the vector datasource.");
                    }

                    else
                    {
                        ///Create bounding box for clipping geometry
                        Point3d  min   = Heron.Convert.ToWGS(boundary[i].GetBoundingBox(true).Min);
                        Point3d  max   = Heron.Convert.ToWGS(boundary[i].GetBoundingBox(true).Max);
                        double[] minpT = new double[3];
                        double[] maxpT = new double[3];

                        minpT[0] = min.X;
                        minpT[1] = min.Y;
                        minpT[2] = min.Z;
                        maxpT[0] = max.X;
                        maxpT[1] = max.Y;
                        maxpT[2] = max.Z;
                        revTransform.TransformPoint(minpT);
                        revTransform.TransformPoint(maxpT);

                        ///Convert to OGR geometry
                        ///TODO: add conversion from GH geometry to OGR to Convert class
                        OSGeo.OGR.Geometry ebbox = OSGeo.OGR.Geometry.CreateFromWkt("POLYGON((" + minpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + maxpT[1] + ", " + maxpT[0] + " " + minpT[1] + ", " + minpT[0] + " " + minpT[1] + "))");

                        ///Clip Shapefile
                        ///http://pcjericks.github.io/py-gdalogr-cookbook/vector_layers.html
                        ///TODO: allow for polyline/curve as clipper, not just bounding box
                        OSGeo.OGR.Layer clipped_layer = layer;
                        clipped_layer.SetSpatialFilter(ebbox);

                        ///Loop through geometry
                        OSGeo.OGR.Feature feat;
                        def = clipped_layer.GetLayerDefn();

                        int m = 0;
                        while ((feat = clipped_layer.GetNextFeature()) != null)
                        {
                            OSGeo.OGR.Geometry geom = feat.GetGeometryRef();
                            OSGeo.OGR.Geometry sub_geom;

                            ///reproject geometry to WGS84
                            ///TODO: look into using the SetCRS global variable here
                            geom.Transform(coordTransform);

                            if (feat.GetGeometryRef() != null)
                            {
                                ///Start get points if open polylines and points
                                for (int gpc = 0; gpc < geom.GetPointCount(); gpc++)
                                {
                                    ///Loop through geometry points
                                    double[] pT = new double[3];
                                    pT[0] = geom.GetX(gpc);
                                    pT[1] = geom.GetY(gpc);
                                    pT[2] = geom.GetZ(gpc);
                                    if (Double.IsNaN(geom.GetZ(gpc)))
                                    {
                                        pT[2] = 0;
                                    }
                                    //coordTransform.TransformPoint(pT);

                                    Point3d pt3D = new Point3d();
                                    pt3D.X = pT[0];
                                    pt3D.Y = pT[1];
                                    pt3D.Z = pT[2];

                                    gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, iLayer, m));
                                    ///End loop through geometry points

                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End Get Feature Values
                                }
                                ///End getting points if open polylines or points



                                ///Start getting points if closed polylines and multipolygons
                                for (int gi = 0; gi < geom.GetGeometryCount(); gi++)
                                {
                                    sub_geom = geom.GetGeometryRef(gi);
                                    OSGeo.OGR.Geometry subsub_geom;
                                    List <Point3d>     geom_list = new List <Point3d>();

                                    ///trouble getting all points.  this is a troubleshoot
                                    ///gset.Append(new GH_Point(new Point3d(0, 0, sub_geom.GetGeometryCount())), new GH_Path(i, iLayer, m, gi));

                                    if (sub_geom.GetGeometryCount() > 0)
                                    {
                                        for (int n = 0; n < sub_geom.GetGeometryCount(); n++)
                                        {
                                            subsub_geom = sub_geom.GetGeometryRef(n);
                                            for (int ptnum = 0; ptnum < subsub_geom.GetPointCount(); ptnum++)
                                            {
                                                ///Loop through geometry points
                                                double[] pT = new double[3];
                                                pT[0] = subsub_geom.GetX(ptnum);
                                                pT[1] = subsub_geom.GetY(ptnum);
                                                pT[2] = subsub_geom.GetZ(ptnum);

                                                Point3d pt3D = new Point3d();
                                                pt3D.X = pT[0];
                                                pt3D.Y = pT[1];
                                                pt3D.Z = pT[2];

                                                gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi, n));
                                                ///End loop through geometry points
                                            }
                                            subsub_geom.Dispose();
                                        }
                                    }

                                    else
                                    {
                                        for (int ptnum = 0; ptnum < sub_geom.GetPointCount(); ptnum++)
                                        {
                                            ///Loop through geometry points
                                            double[] pT = new double[3];
                                            pT[0] = sub_geom.GetX(ptnum);
                                            pT[1] = sub_geom.GetY(ptnum);
                                            pT[2] = sub_geom.GetZ(ptnum);

                                            Point3d pt3D = new Point3d();
                                            pt3D.X = pT[0];
                                            pt3D.Y = pT[1];
                                            pt3D.Z = pT[2];

                                            gset.Append(new GH_Point(Heron.Convert.ToXYZ(pt3D)), new GH_Path(i, iLayer, m, gi));
                                            ///End loop through geometry points
                                        }
                                    }

                                    sub_geom.Dispose();

                                    /// Get Feature Values
                                    if (fset.PathExists(new GH_Path(i, iLayer, m)))
                                    {
                                        fset.get_Branch(new GH_Path(i, iLayer, m)).Clear();
                                    }
                                    for (int iField = 0; iField < feat.GetFieldCount(); iField++)
                                    {
                                        OSGeo.OGR.FieldDefn fdef = def.GetFieldDefn(iField);
                                        if (feat.IsFieldSet(iField))
                                        {
                                            fset.Append(new GH_String(feat.GetFieldAsString(iField)), new GH_Path(i, iLayer, m));
                                        }
                                        else
                                        {
                                            fset.Append(new GH_String("null"), new GH_Path(i, iLayer, m));
                                        }
                                    }
                                    ///End Get Feature Values
                                }
                                //m++;
                            }
                            m++;
                            feat.Dispose();
                        } ///end while loop through features
                    }
                }         //end loop through boundaries

                layer.Dispose();
            }///end loop through layers

            ds.Dispose();

            DA.SetDataTree(0, layname);
            DA.SetDataTree(1, fcs);
            DA.SetDataTree(2, recs);
            DA.SetDataTree(3, sRefs);
            DA.SetDataTree(4, fnames);
            DA.SetDataTree(5, fset);
            DA.SetDataTree(6, gset);
        }