Define output for a function

Hi All,

Just wondering if anyone has experience in defining additional outputs in a function.

For example I created a simple polygon array and used a polygon by function to perform an offset to those initial Polygons. During the function I created an array of points at the centroid of each polygon that I used as the point input in the offset. The result is a polygon. I would however like to also have an output from the node the array of points that were created along the way so they could be reused for anther operation.

Hopefully that makes sense. Below is the function I have, the return as you can see is the Polygon arrary MyPolyArray, I would also like to output the point array MyPointArray.

function (Polygon InputPoly, double ODistance)
{
Polygon MyPolyArray = {};
Point MyPointArray ={};
for (int i = 0; i < InputPoly.Count; ++i)
{   
    Polygon MypolyList = {};
    Point MyPointList = {};
    for (int j = 0; j < InputPoly[i].Count; ++j)
    {
    Polygon MyPoly = {};
    Point MyPoint = {};
    MyPoint = new Point().CentroidOfSet(InputPoly[i][j].Vertices);
    MyPoly = new Polygon().Offset(InputPoly[i][j], OffsetMethod.ByDistance,MyPoint, ODistance);
    MyPointList.Add(MyPoint);
    MypolyList.Add(MyPoly);   
    }
 MyPointArray.Add(MyPointList);
 MyPolyArray.Add(MypolyList);  
    
}

return MyPolyArray;
}

Below is the simple dgn file

Thanks
Wayne

Function-Output.dgn

  • There are a number of ways to do this, but probably the easiest way is to have your function return a record that comprises all the output values you want.

    For example, within your function, you would replace this statement:

    return MyPolyArray;

    With this statement:

    return {polys=MyPolyArray, points=MyPointArray};

    Then, when your function is called from another location, that call might look like this:

    record result = MyFunction(<input polygon>, <input distance>);

    And then the caller can access the returned Polygon array as 'result.polys', and the returned Point array as 'result.points'.

    Alternatively, if a caller wants only one of those values, it can simply access the relevant record field directly from the call:

    Point thePoints = MyFunction(<input polygon>, <input distance>).points;

    HTH

    Jeff

  • Hi Jeff,

    Thanks for the reply, that is exactly what I need.

    Just to confirm a bit of workflow.

    I created a new function in the function dialog, I gave it a name MyFucntion for this example.

    It required a type, so as it produces polygons and points I used the 'object' type as a general option. (leave it without a type didn't appear to work)

    I created a Polygon Node byFunction and used the following:

    function (Polygon InputPoly, double InputDistance)

    {

    record result = MyFunction(InputPoly,InputDistance);

    Polygon MyPoly = result.polys;

    return MyPoly;

    }

    This works well. However if we needed to create a series of points now I would have to write a similar function and access the result.points.

    This would run the function again which isn't desirable given the time/memory factor etc

    We would like to access the 2 results from running the function once.

    With this in mind I attempted to get it to work by creating a functionCall node with the following:

    function (Polygon InputPoly, double InputDistance)

    {

    record result = MyFunction(InputPoly,InputDistance);

    }

    Then I created a Polygon node by function with the following:

    function (FunctionCall InputData)

    {

    Polygon MyPoly = InputData.result,polys;

    return MyPoly;

    }

    Unfortunately this didn't work. 

    Just wondering if you had any pointers on getting this to approach to work?

    Thanks
    Wayne 

  • Hi Wayne,
     
    Your approach of using a FunctionCall node should work fine. Please make these adjustments:
     
    1. In the FunctionCall node, don’t define a new “wrapper” function. Instead, just specify the function name – MyFunction – directly. (Note that the Functions dialog has a toolbar command that lets you populate any new or existing FunctionCall node with the selected function.)
     
    1. In your Polygon ByFunction, change the statement “Polygon MyPoly = InputData.result,polys;” to simply “Polygon MyPoly = InputData.polys;”. (I’m assuming that InputData is the name of your FunctionCall node.) Alternatively, change that statement to “Polygon MyPoly = InputData.Value.polys;”.

     

    Jeff
     

  • HI Jeff,

    Thanks for the information, that cleared up the method of placing it into a FunctionCall node and linking to a polygon node.

    The node doesn't provide any error and it appears to pass the polygon counts etc across to the polygon node but it doesn't produce any polygons. Appears to just pass the names across but no data.

    I have attached a dgn file that might show the results.

    Thanks again for you help

    Wayne

    3240.function-output.dgn

  • For whatever reason, I'm not able to open that DGN file. Please re-submit it as a GCT (GC Transaction) file.
     
    If you don't know how to create a GCT file from a DGN file, here's how:
    1. Open the DGN file.
    2. From GC's 'Transactions' dialog, select the rightmost toolbar command: Edit this entire transaction list.
    3. Within the Editor, select the menu command: File -> Save Current Document to Transaction (GCT) File.
    4. A standard file-save dialog will appear. Navigate to the location to which you want to save the GCT file, give the file an appropriate name, and click Save.
    5. Finally, post that resultant GCT file to this forum thread.
    Also, I have no idea whether your model is large and complex, but, if it is: It would be very helpful if you could (firstly) reduce your model to the smallest essence that still demonstrates the problem.
    Thanks!
    Jeff