Zero-Touch MultiReturn adds new level to OUT list

zerotouch
revit
#1

Hi All,

I’ve created a zero-touch node that multiplies each number of the incoming list of lists by 2.
The resulting list has an extra rank (even if the rank node says it doesn’t)

any ideas why? how do I output a list of lists similar to the flatten node one?
I’m using the MultiReturn so I can change the name of the output port (unless there is another way)

[MultiReturn(new[] { "out" })]
public static Dictionary<string, object> test (List<List<double>> data)
{

foreach (var lst in data)
{
for (int i = 0; i < lst.Count; i++)
{
lst[i] *= 2;
}
			
}

return new Dictionary<string, object>
{
{"out", data }
};

}
#2

hi @salvatoredragotta, try this way;

First, create a new list for your return value and another list for sub-list.

// return result
var myData = new List<List<double>>();
foreach (var lst in data)
{ 
    // sub-list for inner list
    var subList = new List<dobule>();

    for (int i = 0; i < lst.Count; i++)
    {
           double res = lst[i] * 2;
           subList.Add(res);
    }
    myData.Add(subList);
}
return myData;

*Note: your method statement (public …) still need to write, of course.

#3

@jean you are not using the [MultiReturn(new[] { "out" })] in your code.

I tried this but it doesn’t work

		[MultiReturn(new[] { "out" })]
		public static Dictionary<string, object> test3(List<List<double>> data)
		{

			var myData = new List<List<double>>();
			foreach (var lst in data)
			{
				// sub-list for inner list
				var subList = new List<double>();

				for (int i = 0; i < lst.Count; i++)
				{
					double res = lst[i] * 2;
					subList.Add(res);
				}
				myData.Add(subList);
			}
			return new Dictionary<string, object>
			{
				{"out", myData }
			};
		}

how to keep the structure of original list of lists.For Example, look at the List.Replace node in the orchid package

#4

@salvatoredragotta you dont need to use a dictionary to return a single output. It explains why you are seeing the additional rank; dictionaries are key value pairs, so if you use them to output your values, the extra rank is needed to store these pairs.

Just return your list and change your methods return type accordingly:

	public static List<List<double>> test3(List<List<double>> data)
	{

		var myData = new List<List<double>>();
		foreach (var lst in data)
		{
			// sub-list for inner list
			var subList = new List<double>();

			for (int i = 0; i < lst.Count; i++)
			{
				double res = lst[i] * 2;
				subList.Add(res);
			}
			myData.Add(subList);
		}
		return myData;
	}

Edit: looks like @jean already gave you the answer!

1 Like
#5

@Thomas_Mahon I want to have a control on the name of the single output port. is there another way?

#6

Do you mean the label of the output port of the node, or the key name in the pop-up watch window from below the node?

#7

@Thomas_Mahon

#8

Multireturn works like this, this is from my node Element.Flipped in the Orchid package

    /// <summary>
    /// Get the element flip condition, output as element
    /// </summary>
    /// <param name="element">List of elements</param>
    /// <returns name="true">List of flipped elements</returns>
    /// <returns name="false">List of not flipped elements</returns>
    [NodeCategory("Query")]
    [MultiReturn(new[] { "true", "false" })]
    public static IDictionary Flipped(IList element)
    {
        var output = Orchid.Elements.Element.Flipped(element);

        return new Dictionary<string, object>
        {
            {"true", output[0]},
            {"false", output[1]}
        };
    }

please note that all UI (look and feel) is coded in a project for that, while all what I compute is coded in another project. The above is from the UI project.

You can see the structure I use in my DynamoSamples

1 Like
#9

@salvatoredragotta you simply need to add an XML documentation file to your build output. In VS click Project > Properties, click the Build tab then check the XML Documentation File setting.

Now add the XML tags above any public class members. If you triple forward slash above the member, you will automatically generate the necessary tags. To rename your output ports, use the returns name tag:

@erfajo method to name output ports will only work if you develop nodes using Dynamo’s NodeModel, whereas Zero Touch uses XML tags.

4 Likes
Override Node name and Description ZT
#10

Thanks @erfajo! I managed to achieve what I wanted following your examples. Thank you for sharing!

#11

@Thomas_Mahon I’ve already done that. The issue is getting the correct data structure with [MultiReturn(new[] { "out" })] with just one output port. is it achievable or @erfajo suggestion is the only solution?