Hi, I have been working with the C# node to drive Rhino.Inside, specifically trying to use Rhino.Inside to create railings. I am trying to avoid using the EnqueueAction method, because I want to return a list of IDs for the created objects.
I have a C# node that works to open a new transaction and create a wall using the DB.Wall.Create method. It commits successfully. However, when I try to swap out the Wall.Create with a DB.Architecture.Railing.Create method, it triggers some Revit errors. These errors pop up one at a time, each with their own little window which needs to be dismissed, one per component iteration (see attached screenshot). The errors don’t provide any information about what went wrong, and the exception from the C# component also does not provide much info.
I’ve included a working version of the script that uses the EnqueueAction method to generate valid railings (with the same inputs) so I don’t think all of the arguments in the Railing.Create method should be working.
I’m wondering if anyone has tips on:
Getting a better (ie more descriptive) error message/ exception message
Grouping the error messages together ideally or hiding them in Revit and instead displaying them on the GH component, so it runs without the user having to click through each popup.
How to make the Railing.Create method work inside a transaction and/or advice on why it might not!
GH file is attached, with the C# nodes. I’m using RIR with Revit 2020, and obviously the .dll files need to be added through the Manage Assemblies feature.
The script now accomplishes a few of the previously stated goals:
1- I found the right settings to capture the warnings and errors, and output them on the component, (then deletes them so they don’t need to be dismissed individually one at a time by the user).
2- It casts the exception to its more specific type, and extracts more info.
However, in the exception, the HR type is HResult: -2146233088… aka 0x80004005 aka E_FAIL, which is just a generic failure.
Wondering if anyone has any thoughts on this. The function succeeds with the same inputs if I use the RIR built in EnqueueAction (but then I can’t get IDs for the created objects…). Am I missing something?
There is a conflict with Revit MFC context and Rhino MFC context.
We are working to fix this in Rhino.
But meanwhile there is a method called RhinoInside.Revit.Rhinoceros.InvokeInHostContext that should help here.
As EnqueueActionInvokeInHostContext is a temporary workaround. EnqueAction was there when RiR was unable to keep the Revit API context, now is no more needed and will be removed. Same will happen to InvokeInHostContext once we address this.
public class Script_Instance : GH_ScriptInstance
{
private void RunScript(Curve Curve, object Type, object Level, ref object Railing)
{
if(Curve == null || Type == null || Level == null)
return;
Railing = RhinoInside.Revit.Rhinoceros.InvokeInHostContext
(
() => CreateRailing(Revit.ActiveDBDocument, Curve.ToCurveLoop(), Type as DB.ElementType, Level as DB.Level)
);
}
private DB.Architecture.Railing CreateRailing(DB.Document doc, DB.CurveLoop curveLoop, DB.ElementType type, DB.Level level)
{
DB.Architecture.Railing result = null;
using(var transaction = new DB.Transaction(doc, Component.Name))
{
transaction.Start();
result = DB.Architecture.Railing.Create(doc, curveLoop, type.Id, level.Id);
transaction.Commit();
}
return result;
}
}
Here RiR-CreateRailing.gh (26.4 KB) the Grasshopper definition with a sample on using this method.