# Def using "While"

#1

As usuall it seams to be the simplest ones that are the hardest.

End End Goal is to have more use of loop / while functions to allow itterating through list of items.

End Goal today is simply to creat a def where once can take a close poly curve, and nest a copy of itself with in it rotated by a an amount.

In a one time process this works fine. - code block text below.

PC_1 = PolyCurve.Curves(results);
pts1 = Curve.PointAtParameter(PC_1,0.2);
pts2 =List.ShiftIndices(pts1,1);
ln = Line.ByStartPointEndPoint(pts2,pts1);
PC = PolyCurve.ByJoinedCurves(ln);

and i can string these together in series to nest ever smaller shapes and given amount.

this seams like a waste of steps. So I attempted a simple def when I could loop the process to a given amount of itterations.

I receive no errors, and it appears to finish (dynamo doesnt go into a endless loop) but after much editiing and trial all that appears to return is â€śnullâ€ť

I have completed an approximation of this same defintion swaping all geometry oppertations for math and it will work. Is there a limitation to looping geomotric functions, or am i missing something else.

def test(Geom,Itt)
{
return = [Imperative]
{
//
sequence = {Geom};
i = List.Count(sequence);
while (i != Itt)
{
results = sequence[0];
PC_1 = PolyCurve.Curves(results);
pts1 = Curve.PointAtParameter(PC_1,0.2);
pts2 =List.ShiftIndices(pts1,1);
ln = Line.ByStartPointEndPoint(pts2,pts1);
PC = PolyCurve.ByJoinedCurves(ln);
i=i+1;
}
return = {i,results};
}
};

#2

What version of Dynamo is this?

#3

Dynamo Studio 1.3
Dynamo Core 1.3.1
Attempted in both studio and sandbox

#4

You have to remember that you canâ€™t use associative calls such as â€śCurve.PointAtParameterâ€ť on a list of objects in imperative blocks. Try the below version instead:

``````def recursive(Geom, Itt){
return = [Imperative]{
sequence = {Geom};
i = 0;
while (i < Itt)
{
curves = Geom.Curves();
pts1 = {};
for (j in GetKeys(curves) )
{
pts1[j] = curves[j].PointAtParameter(0.2);
}
Geom = PolyCurve.ByPoints(pts1, 1);
i = i + 1;
}
return = sequence;
}};
``````

Imperative DS functions are more trouble than theyâ€™re worth, now more than ever. If anybody is considering using them, arm yourself with a ton of patience. These few lines of code took 5+ attempts. Youâ€™ve never gotten any feedback and debugging information but now itâ€™s worse than everâ€¦

• Using class methods (like PolyCurve.Curves(x) ) failed silently
• If you have any ZT packages that use the same names as the core namespaces and classes (List, Solid, Point, Vector), they become unusable in in DS
• I had to copy/paste the function multiple times because it didnâ€™t properly detect code changes
• For some weird reason, all of a sudden the interpreter assumed that the function doesnâ€™t work with â€śRectangleâ€ť types any more and I got an error even tho Iâ€™ve never defined the argument type. I had to copy/paste the function into a new CBN yet again.
• You have to be careful with the definition of your variables. They now have a scope and if you donâ€™t define a variable at the right place, it may be inaccessible in a different part of the code.
- The performance of DS function calls has tanked compared to previous versions.

It feels to me like this functionality has really deteriorated over time.

#5

@Dimitar_Venkov thanks for finding the issue here with anticipating replication.

we should follow up to figure out how to improve the experience of using imperative blocks - are you finding performance decreases in 2.0 vs 1.3 in imperative blocks?

#6

@Michael_Kirschner2

I take that part back - I ran this by the numbers and the performance of calling custom DS functions in 1.32 and 2.0 has actually increased relative to older versions.

I imagine it has more to do with the fact that all the added tiny issues popping up over time have impacted my overall perceived experience with DS functions negatively - it definitely feels like it takes longer to get them running properly but the actual performance is indeed faster.

This goes to show that you should always measure things first, or else youâ€™ll end up eating your words

Multiple function calls are still expensive tho and you should avoid them if possible:

DS_Func_Perf_1.3.dyn (14.2 KB)

#7

Thank you all, information is invaluable.

â€śarm yourself with a ton of patience.â€ť - this is absolutely true.

Any thoughts on doing this in Python vs Codeblock?

#8

This discussion could help:

#9

@Mike_Engel1 @Dimitar_Venkov thanks for your findings. We are making changes/improvements to imperative blocks in 2.0 where we are addressing some of these issues. You can find a brief description on language changes here: http://dynamobim.org/resuming-pre-release-builds/. Regarding specific imperative language changes, there are new scoping rules, such that variables defined in an outer scope are readonly within an imperative scope and if modified within the imperative scope, will not affect values in the parent associative scope. Secondly statements like â€śPolyCurve.Curves(pc);â€ť and â€śCurve.PointAtParameter(list_of_curves, 0.2);â€ť will also work but not â€ślist_of_curves.PointAtParameter(0.2);â€ť as @Dimitar_Venkov rightly pointed out. The latter will only work within an â€śAssociativeâ€ť scope since it involves replication.

#10

Wonderful - my next thought was to test on 2.0 builds, but looks like you covered it.

#11

Here is a Python version of â€śrecursiveâ€ť, for anyone interested in a quick comparison with DesignScript :

``````import clr

from Autodesk.DesignScript.Geometry import *

Geom = IN[0]
itt = IN[1]
sequence = [Geom]
curvs = []
i = 0

while i < itt:
curvs = Geom.Curves()
pts = []
for crv in curvs:
pts.append(Curve.PointAtParameter(crv, 0.2))
Geom = PolyCurve.ByPoints(pts, 1)
sequence.append(Geom)
i = i + 1

OUT = (pts, sequence)
``````