his comes in the form of an HTML page with links to every component, so you will need to view it in your web browser. (I use Chrome and it doesn't seem to be working correctly, but when opened in IE its fine.)
2) Included in each help topic for each component is the Inputs and Outputs descriptions and data types.
3) You supply the data. What you supply and how you supply it is for you to decide. There are umpteen different ways. Are you asking for a list of those ways for each input?
4) Points can either be Rhino objects or 3D co-ordinates. To create a point you can use any of these methods, but it mostly comes down to user preference. I like using Panels as this displays outside of the component.
5) Because of the nature of vectors they represent magnitude and direction but they don't have an independent location, so there is a component that will display vectors in Rhino.
6) The user.
7) There is a Primer on the front page. Here you find the Basics, but because GH is ever evolving in its current beta state you might find things that aren't relevant any more or simply don't work the same. And here is the reason why nobody is writing an update because it could be soon out of date.
8) Importing images by either dragging them from explorer onto the canvas or right click context menu Image...
9) Single line = Single Item of Data. Double line = Multiple items of data on the same Branch. Dashed Double Line = Multiple Data on Multiple Branches.
10) User preference
11) Toolbar management is probably the bane of David's life. Most things are logically placed. For example the Curve Tab, Primitives are any simple curve types that you are creating from scratch. Similarly Splines is for more complex curve types created from scratch. Analysis is where you find components that are finding answers supplied by curves, control points, curvature, parameters, end points etc. Division is a subset of this category but has a group of its own. And Utilities is where you find curve related actions that you want to perform, offsetting, rebuilding projecting, exploding etc.
12) I would image it would have been the Point On Curve component in Curve>Analysis. Why that group? You are not putting a point on a curve you are analysing a curve for the location of a point based on some parameters that you are supplying. For example "what is the mid point?"
I hope this goes some way towards answering you questions. No doubt this will have generated more so don't be afraid to ask, it took me several releases of Explicit History (aka Grasshopper) before I realised what the egg did, it never occurred to me that I could put my objects into Rhino when I was finished. Or the fact that I could use panels to 'see' data outputs.
Al the best,
Danny…
Added by Danny Boyes at 3:48am on December 9, 2010
should follow the instruction which mostapha has wrote in https://github.com/mostaphaRoudsari/ladybug/blob/master/resources/I...
Instructions for Installing Ladybug + Honeybee: (Follow steps 1-6 for basic functionality and 1-11 for full functionality) 0. If you have an old version of LB+HB, download the file here (https://app.box.com/s/ds96em9l6stxpcw8kgtf) and open it in Grasshopper to remove your old Ladybug and Honeybee version. 1. Make sure that you have a working copy of both Rhino and Grasshopper installed. 2. Open Rhino and type "Grasshopper" into the command line (without quotations). Wait for grasshopper to load. 3. Install GHPython by downloading the file at this link (http://www.food4rhino.com/project/ghpython?ufh) and drag the .gha file onto the Grasshopper canvas. 4. Select and drag all of the files in the "userObjects" folder (downloaded with this instructions file) onto your Grasshopper canvas. You should see Ladybug and Honeybee appear as tabs on the grasshopper tool bar. (If you are reading this instruction on github you can download them from http://www.food4rhino.com/project/ladybug-honeybee) 5. Download the files at this link (https://app.box.com/s/bh9sbpgajdtmmystv3n4), unzip them and copy the contents to both C:\ladybug and C:\Users\[yourUsername]\AppData\Roaming\Ladybug. 6. Restart Rhino and Grasshopper. You now have a fully-functioning Ladybug. For Honeybee, continue to the following: 7. Install Radiance to C:\Radiance by downloading it from this link (https://github.com/NREL/Radiance/releases/download/4.2.2/radiance-4...) and running the exe. 6. Install Daysim to C:\DAYSIM by downloading it at this link (http://daysim.ning.com/page/download) and running the exe. 8. Install Energy Plus 8.1 to C:\EnergyPlusV8-1-0 by going to the DOE website (http://apps1.eere.energy.gov/buildings/energyplus/energyplus_downlo...), making an account, going to "download older versions of EnergyPlus, selecting 8.1 and running the exe. 9. Copy falsecolor2.exe (http://pyrat.googlecode.com/files/falsecolor2.exe) and evalglare.exe (http://www.ise.fraunhofer.de/en/downloads-englisch/software/evalgla...) to C:\Radiance\bin 10. Download the OpenStudio Libraries (https://app.box.com/s/y2sx16k98g1lfd3r47zi) and unzip them to C:\ladybug\OpenStudio. 11. You now have a fully-working version of Ladybug + Honeybee. Get started visualizing weather data with these video tutorials (https://www.youtube.com/playlist?list=PLruLh1AdY-Sj_XGz3kzHUoWmpWDX...).
It works for me..
Agus…
long as the component runs, the list gets generated (screenshot below). It's based on a process explained by James Ramsden here.
However, the list is only generated after all inputs are defined, so for components that have certain inputs without default values, the user has to set these inputs before the list gets generated. Is there any way to force the component to generate the list even before the component has been given all input values? Here is sample code for the issue; the list is only generated after input1 has been defined:
using System; using System.Collections.Generic; using Grasshopper.Kernel; using Rhino.Geometry; using System.Drawing; namespace IntraLattice { public class MyComponent1 : GH_Component { GH_Document GrasshopperDocument; IGH_Component Component; public MyComponent1() : base("MyComponent1", "Nickname", "Description", "Category", "Subcategory") { } protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddLineParameter("Input1", "Input1", "An input", GH_ParamAccess.list); pManager.AddIntegerParameter("Input2", "Input2", "The list selection input", GH_ParamAccess.item, 0); } protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddLineParameter("Output", "Output", "Dummy output", GH_ParamAccess.item); } protected override void SolveInstance(IGH_DataAccess DA) { // 0. Generate input menu list Component = this; GrasshopperDocument = this.OnPingDocument(); if (Component.Params.Input[1].SourceCount == 0) TopoSelect(ref Component, ref GrasshopperDocument, 1, 11); // 1. Retrieve/validate input var input1 = new List<Line>(); int input2 = 0; if (!DA.GetDataList(0, input1)) { return; } if (!DA.GetData(1, ref input2)) { return; } var nodes = new List<Point3d>(); var lines = new List<Line>(); // Some dummy code, that will set the output depending on the value selection list // create first point Point3d pt1 = new Point3d(0, 0, 0); Point3d pt2; // set output depending on value list selection if (input2 == 0) pt2 = new Point3d(5, 0, 0); else pt2 = new Point3d(0, 5, 0); // create pt2 Line line = new Line(pt1, pt2); DA.SetData(0, line); } /// The 'index' input represents the input index (first input is index 0) /// The 'offset' parameter is the vertical offset of the menu, to help with positioning /// </summary> public static void TopoSelect(ref IGH_Component Component, ref GH_Document GrasshopperDocument, int index, float offset) { //instantiate new value list var vallist = new Grasshopper.Kernel.Special.GH_ValueList(); vallist.ListMode = Grasshopper.Kernel.Special.GH_ValueListMode.Cycle; vallist.CreateAttributes(); //customise value list position float xCoord = (float)Component.Attributes.Pivot.X - 200; float yCoord = (float)Component.Attributes.Pivot.Y + index * 40 - offset; PointF cornerPt = new PointF(xCoord, yCoord); vallist.Attributes.Pivot = cornerPt; //populate value list with our own data vallist.ListItems.Clear(); var items = new List<Grasshopper.Kernel.Special.GH_ValueListItem>(); items.Add(new Grasshopper.Kernel.Special.GH_ValueListItem("Choice 0", "0")); items.Add(new Grasshopper.Kernel.Special.GH_ValueListItem("Choice 1", "1")); vallist.ListItems.AddRange(items); // Until now, the slider is a hypothetical object. // This command makes it 'real' and adds it to the canvas. GrasshopperDocument.AddObject(vallist, false); //Connect the new slider to this component Component.Params.Input[index].AddSource(vallist); Component.Params.Input[index].CollectData(); } protected override System.Drawing.Bitmap Icon { get { return null; } } public override Guid ComponentGuid { get { return new Guid("{ebc17377-4900-4e14-b33e-0b1c66ef2ade}"); } } } }
Thanks in advance…
on the division points (see rhino screenshot below, left side is what I'm describing. there is also a note in the screenshot of the GH file)
Unfortunately it doesn't work for multiple cell inputs.
I've also tried flattening the points into one big list and re-creating the polylines with sublists but with no luck. The points are not ordered the way it would need to be to use sublists from domains created by 2 series of numbers. So this is problematic becuase each cell has a different number of vertices. That method would work if I can create unevenly spaced intervals that match the number of vertices on a given input, but I'm not sure how to do that.
Like would it be possible to create a series of numbers whos step size varies with each step? e.g. series that starts at 0, steps up in size 5, then 7, then 11, etc. ant there are x amount of values in the series?
Any ideas how to get this working? Either with this definition or a different method?
Thanks,
Brian…
Added by Brian Harms at 5:40pm on October 15, 2011
8.3.0 ************* IDF Context for following error/warning message: ************* Note -- lines truncated at 300 characters, if necessary... ************* 829 Construction, ************* indicated Name=PELLE001 ************* Only last 10 lines before error line shown.....
************* 832 AIR WALL2, !- - Layer 2 ************* 833 X-LAM, !- - Layer 3 ************* 834 POLYSTYRENE2, !- - Layer 4 ************* 835 PANNELLO VIP, !- - Layer 5 ************* 836 POLYSTYRENE2, !- - Layer 6 ************* 837 X-LAM, !- - Layer 7 ************* 838 LANA DI ROCCIAS, !- - Layer 8 ************* 839 VANO IMPIANTI, !- - Layer 9 ************* 840 LANA DI ROCCIAS, !- - Layer 10 ************* 841 LASTRA IN GESSOFIBRA, !- - Layer 11 ** Severe ** IP: IDF line~841 Error detected for Object=CONSTRUCTION ** ~~~ ** Maximum arguments reached for this object, trying to process ->LASTRA IN GESSOFIBRA<- ************* IDF Context for following error/warning message: ************* Note -- lines truncated at 300 characters, if necessary... ************* 985 Construction, ************* indicated Name=ROOF001 ************* Only last 10 lines before error line shown..... ************* 988 TRAVETTI, !- - Layer 2 ************* 989 TAVOLATO, !- - Layer 3 ************* 990 POLYSTYRENE2, !- - Layer 4 ************* 991 PANNELLO VIP, !- - Layer 5 ************* 992 POLYSTYRENE2, !- - Layer 6 ************* 993 X-LAM, !- - Layer 7 ************* 994 LANA DI ROCCIAS, !- - Layer 8 ************* 995 VANO IMPIANTI, !- - Layer 9 ************* 996 LANA DI ROCCIAS, !- - Layer 10 ************* 997 LASTRA IN GESSOFIBRA, !- - Layer 11 ** Severe ** IP: IDF line~997 Error detected for Object=CONSTRUCTION ** ~~~ ** Maximum arguments reached for this object, trying to process ->LASTRA IN GESSOFIBRA<- ** Warning ** IP: Note -- Some missing fields have been filled with defaults. See the audit output file for details. ** Severe ** IP: Possible incorrect IDD File ** ~~~ ** IDD Version:"IDD_Version 8.3.0" ** ~~~ ** Version in IDF="8.3" not the same as expected="8.3" ** ~~~ ** Possible Invalid Numerics or other problems ** Fatal ** IP: Errors occurred on processing IDF file. Preceding condition(s) cause termination. ...Summary of Errors that led to program termination: ..... Reference severe error count=3 ..... Last severe error=IP: Possible incorrect IDD File ************* Warning: Node connection errors not checked - most system input has not been read (see previous warning). ************* Fatal error -- final processing. Program exited before simulations began. See previous error messages. ************* EnergyPlus Warmup Error Summary. During Warmup: 0 Warning; 0 Severe Errors. ************* EnergyPlus Sizing Error Summary. During Sizing: 0 Warning; 0 Severe Errors. ************* EnergyPlus Terminated--Fatal Error Detected. 1 Warning; 3 Severe Errors; Elapsed Time=00hr 00min 0.34sec
My question is how i can fix it ??? and why it tell me that:
** Severe ** IP: Possible incorrect IDD File** ~~~ ** IDD Version:"IDD_Version 8.3.0"** ~~~ ** Version in IDF="8.3" not the same as expected="8.3"** ~~~ ** Possible Invalid Numerics or other problems** Fatal ** IP: Errors occurred on processing IDF file. Preceding condition(s) cause termination....Summary of Errors that led to program termination:
Help me pleaseeeeeeee
Happy new year!!!!!…
8.3.0************* IDF Context for following error/warning message:************* Note -- lines truncated at 300 characters, if necessary...************* 829 Construction,************* indicated Name=PELLE001************* Only last 10 lines before error line shown.....
************* 832 AIR WALL2, !- - Layer 2************* 833 X-LAM, !- - Layer 3************* 834 POLYSTYRENE2, !- - Layer 4************* 835 PANNELLO VIP, !- - Layer 5************* 836 POLYSTYRENE2, !- - Layer 6************* 837 X-LAM, !- - Layer 7************* 838 LANA DI ROCCIAS, !- - Layer 8************* 839 VANO IMPIANTI, !- - Layer 9************* 840 LANA DI ROCCIAS, !- - Layer 10************* 841 LASTRA IN GESSOFIBRA, !- - Layer 11** Severe ** IP: IDF line~841 Error detected for Object=CONSTRUCTION** ~~~ ** Maximum arguments reached for this object, trying to process ->LASTRA IN GESSOFIBRA<-************* IDF Context for following error/warning message:************* Note -- lines truncated at 300 characters, if necessary...************* 985 Construction,************* indicated Name=ROOF001************* Only last 10 lines before error line shown.....************* 988 TRAVETTI, !- - Layer 2************* 989 TAVOLATO, !- - Layer 3************* 990 POLYSTYRENE2, !- - Layer 4************* 991 PANNELLO VIP, !- - Layer 5************* 992 POLYSTYRENE2, !- - Layer 6************* 993 X-LAM, !- - Layer 7************* 994 LANA DI ROCCIAS, !- - Layer 8************* 995 VANO IMPIANTI, !- - Layer 9************* 996 LANA DI ROCCIAS, !- - Layer 10************* 997 LASTRA IN GESSOFIBRA, !- - Layer 11** Severe ** IP: IDF line~997 Error detected for Object=CONSTRUCTION** ~~~ ** Maximum arguments reached for this object, trying to process ->LASTRA IN GESSOFIBRA<-** Warning ** IP: Note -- Some missing fields have been filled with defaults. See the audit output file for details.** Severe ** IP: Possible incorrect IDD File** ~~~ ** IDD Version:"IDD_Version 8.3.0"** ~~~ ** Version in IDF="8.3" not the same as expected="8.3"** ~~~ ** Possible Invalid Numerics or other problems** Fatal ** IP: Errors occurred on processing IDF file. Preceding condition(s) cause termination....Summary of Errors that led to program termination:..... Reference severe error count=3..... Last severe error=IP: Possible incorrect IDD File************* Warning: Node connection errors not checked - most system input has not been read (see previous warning).************* Fatal error -- final processing. Program exited before simulations began. See previous error messages.************* EnergyPlus Warmup Error Summary. During Warmup: 0 Warning; 0 Severe Errors.************* EnergyPlus Sizing Error Summary. During Sizing: 0 Warning; 0 Severe Errors.************* EnergyPlus Terminated--Fatal Error Detected. 1 Warning; 3 Severe Errors; Elapsed Time=00hr 00min 0.34sec
My question is how i can fix it ??? and why it tell me that:
** Severe ** IP: Possible incorrect IDD File** ~~~ ** IDD Version:"IDD_Version 8.3.0"** ~~~ ** Version in IDF="8.3" not the same as expected="8.3"** ~~~ ** Possible Invalid Numerics or other problems** Fatal ** IP: Errors occurred on processing IDF file. Preceding condition(s) cause termination....Summary of Errors that led to program termination:
Help me pleaseeeeeeee
Thanks and Happy new year!!!!!…
he resulting STL file has no problems. I was going to make a 3D print of it but I thought I could make it even more interesting.
When I make a duplicate piece of geometry with reversed curve rotation values and combine the 2 together I get this interesting result:
However, after baking this geometry the exported STL file has a huge number of errors - there are literally thousands of flipped normals, multiple mesh parts, and disconnected triangles.
I have tried lots of things to resolve this and none of them worked: converting to meshes in GH, GH mesh smooth, Rhino Solid Union, Mesh Repair, Align Normals, etc. I use 3D Builder to correct STL problems, but it can't fix this one.
An even more interesting shape happens when I twist the above shape in one direction, and then add it to another that is twisted in the opposite direction:
Of course the STL file for this one is even worse because it just compounds the previous problems.
Is there any way to resolve these problems? My GH file is somewhat messy and perhaps a bit obscure, but I'd be happy to clean it up and share it with anyone who thinks there is a way to get this puppy working.
…
Added by Birk Binnard at 11:56am on September 22, 2016
cs/numpy-for-iron-python-wit... ) also fails to allow numpy import:
Numpy and Scipy are in directories here:
C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\
This is all a sad joke, taking a full day so far. Rhino just sort of sucks for serious work. There's no way I can offer any Numpy/Scipy scripts to clients this way, just impossible. Rhino/Grasshopper Python should come with this stuff, dear developers, or have a simple installer that just works. It comes with math already doesn't it? So why not Numpy and Scipy for serious users?
Upon restarting Rhino, it totally changes behavior and spits out a crazy error upon importing Numpy:
Message: The type initializer for 'NumpyDotNet.NpyCoreApi' threw an exception.Traceback: line 11, in <module>, "C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\numpy\core\multiarray.py" line 6, in <module>, "C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\numpy\core\__init__.py" line 155, in <module>, "C:\Program Files (x86)\IronPython 2.7\Lib\site-packages\numpy\__init__.py" line 1, in <module>, "C:\Users\Nik\AppData\Local\Temp\TempScript.py"
The Grasshopper Python node editor gives the same error. Perhaps I can only import parts of Numpy using "from Numpy import XXXX"?…
Added by Nik Willmore at 3:32pm on October 11, 2015
.
Things have been working swimmingly in many areas of the plugin, but one particular problem has been tough to solve. I have two components that are trying to read/write to the same memory at the same time, causing Rhino exceptions and crashes.
The conflicts appear to be happening between two components -- one is a "Layer Events Listener" that reports essentially what type of layer event just happened. The other is a "Set Layer Visibility" component that toggles the visibility of a list of layers.
The code:
public class LayerTools_LayerEventsListener : GH_Component { /// <summary> /// Initializes a new instance of the LayerTools_LayerListener class. /// </summary> public LayerTools_LayerEventsListener() : base("Layer Events Listener", "Layer Listener", "Get granular information about the layer events happening in the Rhino document.", "Squirrel", "Layer Tools") { }
/// <summary> /// Registers all the input parameters for this component. /// </summary> protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddBooleanParameter("Active", "A", "Set to true to listen to layer events in the Rhino document.", GH_ParamAccess.item, false); pManager.AddTextParameter("Exclusions", "E", "Provide a list of exclusions to stop reading specific events (Added, Deleted, Moved, Renamed, Locked, Visibility, Color, Active).", GH_ParamAccess.list); pManager[1].Optional = true; }
/// <summary> /// Registers all the output parameters for this component. /// </summary> protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddBooleanParameter("Initialized", "I", "Whether the listener changed from passive to active.", GH_ParamAccess.item); pManager.AddTextParameter("Document Name", "doc", "Name of the Rhino document that is changing.", GH_ParamAccess.item); pManager.AddTextParameter("Layer Path", "path", "Path of the modifed layer.", GH_ParamAccess.item); pManager.AddIntegerParameter("Layer Index", "ID", "Index of the modified layer.", GH_ParamAccess.item); pManager.AddIntegerParameter("Sort Index", "SID", "Sort index of the modified layer.", GH_ParamAccess.item); pManager.AddTextParameter("Event Type", "T", "Type of the modification.", GH_ParamAccess.item); pManager.AddBooleanParameter("Added", "A", "If the layer has been added.", GH_ParamAccess.item); pManager.AddBooleanParameter("Deleted", "D", "If the layer has been deleted.", GH_ParamAccess.item); pManager.AddBooleanParameter("Moved", "M", "If the layer has been moved.", GH_ParamAccess.item); pManager.AddBooleanParameter("Renamed", "R", "If the layer has been renamed.", GH_ParamAccess.item); pManager.AddBooleanParameter("Locked", "L", "If the layer locked setting has changed.", GH_ParamAccess.item); pManager.AddBooleanParameter("Visibility", "V", "If the layer's visibility has changed.", GH_ParamAccess.item); pManager.AddBooleanParameter("Color", "C", "If the layer's color has changed.", GH_ParamAccess.item); pManager.AddBooleanParameter("Active", "Act", "If the active layer has changed.", GH_ParamAccess.item); }
/// <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) { bool active = false; List<string> exclusions = new List<string>();
DA.GetData(0, ref active); DA.GetDataList(1, exclusions);
RhinoDoc thisDoc = null;
bool initialize = false;
string dName = null; string activePath = null; int layerIndex = -1; int sortIndex = -1; string eventType = null; bool added = false; bool deleted = false; bool moved = false; bool renamed = false; bool locked = false; bool visibility = false; bool color = false; bool current = false;
if (active) { thisDoc = RhinoDoc.ActiveDoc;
initialize = (!previouslyActive) ? true : false;
RhinoDoc.LayerTableEvent -= RhinoDoc_LayerTableEvent; RhinoDoc.LayerTableEvent += RhinoDoc_LayerTableEvent; previouslyActive = true;
} else {
RhinoDoc.LayerTableEvent -= RhinoDoc_LayerTableEvent; previouslyActive = false; }
if (ev != null) { dName = ev.Document.Name; layerIndex = ev.LayerIndex; eventType = ev.EventType.ToString();
if (!exclusions.Contains("Active")) { if (ev.EventType.ToString() == "Current") { // active layer has just been changed current = true; }
}
if (!exclusions.Contains("Moved")) { if (ev.EventType.ToString() == "Sorted") { // active layer has just been changed moved = true; }
}
if (!exclusions.Contains("Added")) { if (ev.EventType.ToString() == "Added") { // layer has just been added activePath = ev.NewState.FullPath; added = true; }
}
if (!exclusions.Contains("Active")) { if (ev.EventType.ToString() == "Deleted") { // layer has just been added
deleted = true; } }
if (ev.EventType.ToString() == "Modified") { // layer has been modified activePath = ev.NewState.FullPath;
//skip sortindex eventType = ev.EventType.ToString();
if (ev.OldState != null && ev.NewState != null) { if (!exclusions.Contains("Locked")) { if (ev.OldState.IsLocked != ev.NewState.IsLocked) locked = true;
} if (!exclusions.Contains("Visibility")) { if (ev.OldState.IsVisible != ev.NewState.IsVisible) visibility = true; }
if (!exclusions.Contains("Moved")) { if (ev.OldState.ParentLayerId != ev.NewState.ParentLayerId) moved = true; }
//if (ev.OldState.SortIndex != ev.NewState.SortIndex) moved = true; if (!exclusions.Contains("Renamed")) { if (ev.OldState.Name != ev.NewState.Name) renamed = true; }
if (!exclusions.Contains("Color")) { if (ev.OldState.Color != ev.NewState.Color) color = true; } }
} }
DA.SetData(0, initialize); DA.SetData(1, dName); DA.SetData(2, activePath); DA.SetData(3, layerIndex); DA.SetData(4, sortIndex); DA.SetData(5, eventType); DA.SetData(6, added); DA.SetData(7, deleted); DA.SetData(8, moved); DA.SetData(9, renamed); DA.SetData(10, locked); DA.SetData(11, visibility); DA.SetData(12, color); DA.SetData(13, current);
}
static bool previouslyActive = false; Rhino.DocObjects.Tables.LayerTableEventArgs ev = null;
void RhinoDoc_LayerTableEvent(object sender, Rhino.DocObjects.Tables.LayerTableEventArgs e) { ev = e;this.ExpireSolution(true); }
And for the layer visibility component:
public LayerTools_SetActiveLayer() : base("Set Active Layer", "SetActiveLayer", "Set the active layer in the Rhino document.", "Squirrel", "Layer Tools") { }
/// <summary> /// Registers all the input parameters for this component. /// </summary> protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { pManager.AddBooleanParameter("Active", "A", "Set to true to change the active layer in Rhino.", GH_ParamAccess.item, false); pManager.AddTextParameter("Path", "P", "Full path of the layer to be activated.", GH_ParamAccess.item); }
/// <summary> /// Registers all the output parameters for this component. /// </summary> protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { pManager.AddIntegerParameter("Layer ID", "ID", "Index of layer that has been activated.", GH_ParamAccess.item); pManager.AddBooleanParameter("Status", "St", "True when the layer has been activated.", GH_ParamAccess.item); }
/// <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) { bool active = false; string path = "";
if (!DA.GetData(0, ref active)) return; if (!DA.GetData(1, ref path)) return;
int layer_index = -1; bool status = false;
if (path != null) {
Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc; Rhino.DocObjects.Tables.LayerTable layertable = doc.Layers;
layer_index = layertable.FindByFullPath(path, true);
if (layer_index > 0) { // if exists RhinoDoc.ActiveDoc.Layers.SetCurrentLayerIndex(layer_index, true); status = true; } }
DA.SetData(0, layer_index); DA.SetData(1, status); }
Now originally I was getting exceptions when changing multiple layers' visibility properties, which would cause the Event Listener to fire and try to read the Visibility property before the memory has been released by the Set Layer Visibility component. That led me to add an "Exceptions" input, that would allow me to disable the reading of Visibility events at the source in the Layer Events listener. That helped me manage about 95% of the crashes I was getting, but I still get strange crashes in other event properties, even when that property shouldn't be affected. For instance, I am getting a crash here on the Name property in the event from the delegate function, even though I am only changing Visibility at any one time:
I have a few ideas but they all seem pretty hacky. One is to try to set a flag that is readable by any component in the plugin -- so that the event listener can see if a "set" component is currently running and abort before causing an exception. The other is creating a delay in the event listener, somthing like 200ms, to allow any set components to finish what they are doing before reading the event. Neither seems super ideal.
Any ideas?
Thanks,
Marc
…