Accessing Element information - GC

Afternoon,

i'm trying to access the element information via GC and then export the information to excel in a structured way.

does anyone know how to get the element information?

Thanks 

Parents
  • All output properties that are available on a GC node can be written to Excel using the ExcelRange node. The ExcelRange node is available after loading the Bentley Product Assembly Bentley.GenerativeComponents.Office.dll.

       

  • thanks for that, i'm aware that this allows me to read/write data to excel however i'm struggling to get the information out of the element specifically the Element ID and Cell name. do you know what cell i can use to access this information? Thanks in advance
  • Then I may need a better description of what you are trying to do. It seems you have a DGN file containing DGN elements (not GC nodes), some of which are cells. Of those cells you want to know the Element ID and the names of the Cells.

    How do you identify those elements/cells? (Or how should GC identify them?)

       

  • ok.

    I have a GC graph that places specific cells at a location along a curve. this works perfect...

    what I now need to do is report the Element ID of the placed cells back to the Excel that originally placed them. I'm struggling to find a node that will allow me to get to that information out of the Cell.

    hope this helps
  • Im still trying to figure this out as well..
  • Hi L,

    In the current versions of GenerativeComponents, there is no ready-made functionality to achieve what you are looking for.  However, utilizing GC's extensibility, the development team suggests the following solution:

    Using the example solution that is delivered with GenerativeComponents, a couple of functions can be added to the ScriptFunctions.cs file.

    Here are the steps:

    (1)

    At the top of ScriptFunctions.cs add:

    using Bentley.GenerativeComponents;
    using Bentley.GenerativeComponents.Features;
    using Bentley.GenerativeComponents.MicroStationElements;

    (2)

    In the Load method, add this statement:

    nameCatalog.AddNamespaceLevelFunction("GetElementID", "long function(Node node)", GetElementID);

    There are already two similar statements.  Just add this one below those two.

    (3)

    Below the Load method, add these two functions:

    /// <summary> Returns the element ID of a node. If the node does not have a corresponding geometric element, returns 0. </summary>
    static private void GetElementID(CallFrame callFrame)
    {
       IGCObject result = Boxer.Box(0);
       INode node = callFrame.UnboxArgument<INode>(0);
       Feature feature = node as Feature;
       if (feature != null)
          result = GetElementID(feature);
       callFrame.SetFunctionResult(result);
    }

    static IGCObject GetElementID( Feature feature)  
    {
       if (feature.ContainsReplicatedChildFeatures())
       {
          GCList result = new GCList();
          foreach (Feature child in feature.ReplicatedChildFeatures())
             result.Add(GetElementID(child)); // Recursive call.
          return result;
       }
       else
       {
          long elementID = feature.Element.SafeID64();
          return Boxer.Box(elementID);
       }
    }

    (4)

    Compile the sample project and load the DLL into GenerativeComponents.  In the list of functions you will see GetElementID.

    (5)

    Drag GetElementID into the Graph (will create a FunctionCall node) and hook the Cell node as input to the "node" input port.

    (6)

    The result of that function call is a single long integer for non-nested geometric nodes, a list of long integers for geometric nodes containing child nodes, etc. (there is a recursive call in GetElementID that will return the element IDs in whichever nesting the elements are contained in the top level node.)

       

Reply
  • Hi L,

    In the current versions of GenerativeComponents, there is no ready-made functionality to achieve what you are looking for.  However, utilizing GC's extensibility, the development team suggests the following solution:

    Using the example solution that is delivered with GenerativeComponents, a couple of functions can be added to the ScriptFunctions.cs file.

    Here are the steps:

    (1)

    At the top of ScriptFunctions.cs add:

    using Bentley.GenerativeComponents;
    using Bentley.GenerativeComponents.Features;
    using Bentley.GenerativeComponents.MicroStationElements;

    (2)

    In the Load method, add this statement:

    nameCatalog.AddNamespaceLevelFunction("GetElementID", "long function(Node node)", GetElementID);

    There are already two similar statements.  Just add this one below those two.

    (3)

    Below the Load method, add these two functions:

    /// <summary> Returns the element ID of a node. If the node does not have a corresponding geometric element, returns 0. </summary>
    static private void GetElementID(CallFrame callFrame)
    {
       IGCObject result = Boxer.Box(0);
       INode node = callFrame.UnboxArgument<INode>(0);
       Feature feature = node as Feature;
       if (feature != null)
          result = GetElementID(feature);
       callFrame.SetFunctionResult(result);
    }

    static IGCObject GetElementID( Feature feature)  
    {
       if (feature.ContainsReplicatedChildFeatures())
       {
          GCList result = new GCList();
          foreach (Feature child in feature.ReplicatedChildFeatures())
             result.Add(GetElementID(child)); // Recursive call.
          return result;
       }
       else
       {
          long elementID = feature.Element.SafeID64();
          return Boxer.Box(elementID);
       }
    }

    (4)

    Compile the sample project and load the DLL into GenerativeComponents.  In the list of functions you will see GetElementID.

    (5)

    Drag GetElementID into the Graph (will create a FunctionCall node) and hook the Cell node as input to the "node" input port.

    (6)

    The result of that function call is a single long integer for non-nested geometric nodes, a list of long integers for geometric nodes containing child nodes, etc. (there is a recursive call in GetElementID that will return the element IDs in whichever nesting the elements are contained in the top level node.)

       

Children
  • I seem to be getting two errors, do you know why ?

  • Sorry, you ran up against a formatting error that I overlooked in the HTML version of the code. The last statement was missing the space between return and Boxer.Box. This should remove the two errors that you are showing in the screen capture. I have inserted that missing space in my previous response.

       

  • Wow! What else can you do by accessing the assemblies provided by GC?
  • With appropriate hyperbole: anything is possible!

    By design, the extensibility of GenerativeComponents is one of its intended strengths. There are so many things that can be done that even I cannot comprehensively enumerate them all.

    Here is a list of how extensibility in GC works:
    By modeling assemblies of nodes and encapsulating them as Generated Node Types (GNT). No coding required. Note that these assemblies of nodes may include nodes using the ByFunction technique.
    By using expressions in input properties of nodes (e.g. Length entry for line02.ByStartPointDirectionLength could be "line01.Length + 5.0"). Minimal "coding" from basic math expressions and calling built-in or scripted functions to more advanced one-line logical, search, and lambda expressions.
    By writing Script Transactions using C-language control flow (if, while, for, foreach, etc.). A step up in scripting/coding.
    By writing/scripting functions (C/C# syntax) and adding them to the available built-in functions. Another step up in scripting/coding.
    By using those or anonymous functions to generate nodes using their ByFunction technique.
    Any coding/scripting is supported by GC's built-in development environment, the Script Editor, with Statement Builder and auto-completion lowering the coding threshold.

    Access to assemblies that do not expose function libraries to GC's list of functions is available by unpacking the sample solution (C#) and then coding extensions to GenerativeComponents using a bona fide development environment, e.g. Visual Studio. Note that assemblies' APIs may need proper wrapping as shown in the coding example in order to expose them to GC application users.

    I hope I did not miss something...

       

  • Unknown said:
    Here is a list of how extensibility in GC works:
    1. By modeling assemblies of nodes and encapsulating them as Generated Node Types (GNT). No coding required. Note that these assemblies of nodes may include nodes using the ByFunction technique.
    2. By using expressions in input properties of nodes (e.g. Length entry for line02.ByStartPointDirectionLength could be "line01.Length + 5.0"). Minimal "coding" from basic math expressions and calling built-in or scripted functions to more advanced one-line logical, search, and lambda expressions.
    3. By writing Script Transactions using C-language control flow (if, while, for, foreach, etc.). A step up in scripting/coding.
    4. By writing/scripting functions (C/C# syntax) and adding them to the available built-in functions. Another step up in scripting/coding.
    5. By using those or anonymous functions to generate nodes using their ByFunction technique.


    Any coding/scripting is supported by GC's built-in development environment, the Script Editor, with Statement Builder and auto-completion lowering the coding threshold.

    Unknown said:
    Access to assemblies that do not expose function libraries to GC's list of functions is available by unpacking the sample solution (C#) and then coding extensions to GenerativeComponents using a bona fide development environment, e.g. Visual Studio. Note that assemblies' APIs may need proper wrapping as shown in the coding example in order to expose them to GC application users.

    Not sure what you mean here... do you mean that say if Mstn or ABD has dotNET dll's in their Assemblies folders, the user can use Visual Studio to access the functions in them? When you say 'coding extensions' is this the same as 'writing wrappers'?

    It would be good to see some examples of how this can be done... in the GC CE SDK?

    Also, it would be good to be able to access Mstn and ABD tools, like Dynamo can directly access Revit elements.

    1. Selection- A node that selects all Elements at a specified level, of a Category, Element type (ABD Wall, Beam, Slab etc), by Name, bounding box, Item , Element Template info or vertical-specific info like ABD's Datagroup / Family and Parts info... sub-element entities like vertex, edge, face etc using Mstn/ABD's inbuilt scanning tools.

    2. Access and use Mstn and ABD commands, functions. So, after selecting say a bunch of ABD Walls, GC should be able to use ABD's tools to make modifications to the geometry (not just the attached DGS or F+P info.

    Once GC has access to the 'raw' or foreign element's info, it can use its own extensive tools to generate geometric info and insert the information back into the foreign element. In this example, the Revit element's vertex info was extracted and passed to the Dynamo node, when then passed to a Curve.Offset technique to generate a second curve, whose vertex info was re-inserted into the Revit element.

    Mstn and I assume ABD eventually will have published schemas. Will this information be used to help the 'extension' or 'wrapper' writing process easier?

    3. What about accessing and modifiying Mstn's Sheet Index or Saved View names? This is a standard Dynamo party trick. I suppose a lot of the methods are now exposed in the new NET API in Connect? Hopefully, no wrappers or whatever in Visual Studio is not required. Hopefully, ABD will follow suit with its Floor Manager and Grid tools.