Can a Custom Node (C#) control the lacing Mode?

HI,
I was feeding a list of lists to my custom node, where i loop through every item and perform my task. But for the live of me i could not figure out why my inner loop count was always one. So it was treating my inner list to have a count of 1, even though it had more.
So after many attempts i figured out that i have forgotten about the lacing on my node, which was at default/shortest. (Rookie mistake) so once i modified that to longest, my code was able to loop thru every element.

So now i am curious if there is a way to force the lacing from within my custom Node. I would have diffidently defined it and not have to rely on the the user to set it properly.
is there a way to do force lacing mode?

Any takers, any ideas on this please.

Lacing is pointless in the custom node context. It sounds like you’re not defining your methods input parameters correctly so Dynamo is modifying the data structure before your loop executes which may explain the unexpected behaviour. Share your code if you want a solution.

2 Likes

Hi Thomas,

Here is the code and a snapshot of the Dynamo nodes:
With Lacing set to “Auto” on createXL, it works fine. with lacing set to “Shortest”, rc_data[r] has a count of 1, instead of 15.

        private static void WriteExcelFile(SpreadsheetDocument Doc, List<List<object>> rc_data)
        {
                for (int r = 0; r < rc_data.Count; r++)
                {
                    for (int c = 0; c < rc_data[r].Count; c++)  // This evaluates to 1 instead of 15 in lacing = "Shortest"
                    {
                        // Insert Values in Cells
                    }
                }
        }


![image|690x351](upload://swoJjCynjLAwFoceSejQqXRNTi1.png)

i just noticed that the image did not upload… here it is showing the list of lists that i am feeding my custom node.

Can you take a look at my code and see if i am defining the input parameter correctly?

thanks

Your code is fine although your screenshot shows many more inputs so…?
The problem is just Dynamos replication behaviour: it iterates over collections for single inputs. Since your node inputs (in your screenshot not the useless code snippet you provided) have both single instance and list inputs you will get unexpected behaviour should you decide to provide a list of values into one of the single input ports and fail to promote the rank of the input passed into the list of lists input port.

This is because of data matching (lacing) - each value from a list of values passed into a single instance input port will be paired with corresponding values from any other list passed into the other input ports. So if you pass in a list of say column indexes each of these values will be paired with the inner value of your list of lists inputs and thats why your are seeing unexpected behaviour. You would need to make your list of lists 3D (rank 3) to preserve the expected behaviour and also ensure all your other inputs are promoted too. Trying to solve this internally in your node simply won’t work as it’s too late by the time it’s executing, you have to prepare the data correctly before running the node. Your best option is to simply disable the lacing functionality so users are forced to provide the inputs as designed or better still, write a macro or Revit add-in which is a much more appropriate approach given that your method returns nothing.

Hi Thomas,
Thank for your response…

The code is attached below
XLTM-XLSM-Overwrite.txt (16.8 KB)

I thought you wanted to see how i defined my input parameters and that’s what i provided, without the other clutter that i was still debugging.

You suggested 3 things:
1- Change the Rank of the list to 3D… I do not understand what that means. i googled around to understand that concept. but nothing came up. can you point me in the right direction here?

2- Disable Lacing… I did not know i could do that, and thus my question to this forum. So how do i do that?

3- Create Macro… That is not an option for me in this particular case, because i want the user to make few choices that will affect the content and Size of the “list of Lists” before exporting to excel later.

Finally, the tone of this: “(in your screenshot not the useless code snippet you provided)” was not really necessary for the purpose of this forum. It just put me in a bad mood.

You need to provide all your code otherwise the answer to your problem could be a wild goose chase - your code snippet initially was quite useless to address your problem, I’m sorry, it just was! Thanks for publishing the full code since.

  1. A rank 3 / 3D list is a list of list of lists. Promotion typically means to increase rank by 1, so a single instance would be moved to a list, a list will become a list of lists, a lists of lists becomes a list of list of lists and so on.
  2. You can disable lacing using the IsLacingDisabled attribute - just decorate a nodes method or property with it. The node will then only use Dynamos default replication behaviour and the user can’t override it (see below).
  3. A macro can launch a UI (but really you might as well develop a full blown app if you were to do this) and can include all the input controls you need. Its naturally going to be way more flexible than any node and you can design it in such a way that it can adapt to your list structure just be careful as your requirement may be a warning that your approach is wrong and to redesign your object model so its more consistent and predicable - guide the user, don’t let the user guide your data structure otherwise you could end up in a situation when your problem morphs into ‘how long is a piece of string?’.
        [IsLacingDisabled]
        public ImportInstanceReport(IDocumentAttributes documentAttributes, RevitImportInstance importInstance)
1 Like

Hi Thomas,

Sorry for the late reply,
So for:
1- Does increasing the rank, cheats the node to look at its input as a single entry, when in fact that single entry happens to be a list, so it is only used once in lacing? This has worked for me.

2- I think this should be the answer for my question, since it does give the developer (some) control over the Lacing mode of his custom node. However, it did not work for me. I have added it before my method as below, but i was still able to change the lacing within dynamo in debug mode. And my node created multiple files based on my lacing selection. Any ideas?

3- i hear what you are saying, and that’s why i wrote this in C#, just in case i wanted to move the whole thing to a macro. but for now i am still convinced it is a better route as a custom node.

        [Autodesk.DesignScript.Runtime.MultiReturn(new[] { "filePath", "sheetName", "startRow", "startCol", "rc_data" })]
        [IsLacingDisabled]
        public static Dictionary<string, object> createXL(string filePath, string sheetName, int startRow, int startCol, List<List<object>> rc_data)
        {

Hi @fawzimasri7137

  1. Its not so much ‘cheating the node’ rather this is simply the mechanism (replication) by which Dynamo executes a node if a list is passed into an input which only expects a single value (or any other rank promotion). This is also the reason why its too late to do anything about it by the time the data is received by your method as Dynamo marshals the data beforehand and you cant intercept it. One other thing I didn’t mention is to avoid object in your input parameters (or anywhere else unless you are writing an event handler). Dynamo does really weird boxing with object inputs and I suspect this is masking an exception that would occur (and that you actually want) should the list structure not be input in the required structure and this also applies when promotion occurs. Its most probably masking the exception - use a specific type like string and stick to best practice in C#. If you need to use generics then Dynamo does support this. Plus if you are exporting to excel then everything should be a string - you can always cast or convert to a different value type internally (double, date, currency etc).

  2. I’m not sure why the attribute doesn’t work - you should see a node without the lacing option on it or replication guides. I’m using Dynamo 2.12 and tested the attribute and it works for me so maybe you’re using a different build of Dynamo and its not supported or perhaps you are running an older version of your library without realising and are not seeing your latest changes - just make sure when you build your solution you either automate the copying of the new library file to your package install location or copy it over manually if you don’t know how to do this.

  3. I would encourage you to venture into full-blown app development with WPF. You’ll notice a number of benefits. In BimorphNodes for example Sheet.Duplicate is way more appropriate built as a Revit add-in with a rich UI vs a node that only can offer very rudimentary inputs.

1 Like

I am using Dynamo versions:
Dynamo Core: 2.3.1.11775
Dynamo Revit: 2.3.1.11830

i am using Revit 2020…

Here it shows that lacing does exist and i can make choices. Choosing long or cross, will produce many excel files, as expected. unless i up the Rank for the data to 3.

here is the code again:

        
        [Autodesk.DesignScript.Runtime.MultiReturn(new[] { "filePath", "sheetName", "startRow", "startCol", "rc_data" })]
        [IsLacingDisabled]
        public static Dictionary<string, object> createXL(string filePath, string sheetName, int startRow, int startCol, List<List<object>> rc_data)
        {
            #region // Check if FilePath Exists if not open filedialog for user to choose a template file
            if (File.Exists(filePath))
            {

i will do some more debugging on it.