My objective is to produce a correctly ordered and directed sequence of lines.
The input lines have draw / selection order that is random and line directions are also inconsistent. I also input the start point of the sequence of lines.
Problem: The logic works OK when stepped through with 3 lines, but the same process does not work with For / While loops in an Imperative block. It seems that syntax is wrong. Can anyone see a mistake?
The biggest benefit of design script is that you RARELY need a for or a while loop, as the tool will iterate over a list for you. The exceptions to this are situation where an action has to be performed repeatedly until a condition is met. In your case it likely could be done via a custom node without any design script. However while they are rare; they exist and a path has to be found. For this reason imperative code block statements were introduced.
However the method of authoring means many issues get completely suppressed, and you have a lot less control over output. It’s IMPERATIVE that the code returns a value, and so even if it returns ‘null’ due to a warning it’s going to continue as if it didn’t hit anything.
As a general rule when writing imperative code:
Once you start imperative code you cannot use associative methods anymore. This means no lacing or list levels will work - you have to specify the for loops directly (like I did in the Python).
Once you enter imperative code warnings will often be suppressed which means you’re going to just receive ‘null’ as an input.
To return something it has to have been defined outside of any nested loops.
Likely your Line.StartPoint(remainingLines); and remainingLines.StartPoint are both failing due to number 1 above as remainingLines is a list not a geometry and you’re in an imperative code block so it can’t be iterated over.
This definnition should perform what you want, with extra annotations to make it clear what I was thinking when:
def SortToChain(curves: DesignScript.Curve[]) //defines a new definition
//opens the defintion block
{
//defines an imperative code block called orderedLines
orderedLines = [Imperative]
//starts the imperative code, allowing for and while loops but blocking
//list levels and replication guides
{
//get the first curve from the curves list as crv
crv = curves[0];
//remove the first curve
crvs = List.DropItems(curves,1);
//define net as a list containing the first curve
net = [crv];
while (List.Count(crvs)>0) //define a loop while more than 0 curves
//start the while loop
{
//get the start and end point of the curve
start = crv.StartPoint;
end = crv.EndPoint;
//define dists as an empty list
dists = [];
//starting a for loop now as crvs.StartPOint will fail as it can't
//iterate over a loop
//define a loop for each next in the crvs list
for (next in crvs)
//start the for loop
{
//get the distance from start and end to next's start and end
sS = start.DistanceTo(next.StartPoint);
sE = start.DistanceTo(next.EndPoint);
eS = end.DistanceTo(next.StartPoint);
eE = end.DistanceTo(next.EndPoint);
//combine the distances into a single list
measures = [sS,sE,eS,eS];
//get the minimum distance found
measure = List.MinimumItem(measures);
//add the minimum distance to the list of distances
dists = List.Join([dists,measure]);
//close the for loop
}
//sort the curves list by the distances list
crvs = List.SortByKey(crvs,dists)["sortedList"];
//get the first curve from the curves list as crv
crv = crvs[0];
//remove the first item from the curves list
crvs = List.DropItems(crvs, 1);
//add the new value of crv to the net list
net = List.AddItemToEnd(crv,net);
//close the while loop
}
//return net from the orderedLines imperative code block
return net;
//close the impertative code block
}
//return orderedLines from the SortToChain definition block
return orderedLines;
//close the definition code block
};
Brilliant! The concept of [associative] and [imperative] methods is still new to me, so that really helps me. Thank you! (Tack så mycket!)
Likely your Line.StartPoint(remainingLines); and remainingLines.StartPoint are both failing due to number 1
Yes, that was causing the problem. I can that see your solution replaces them with For loops.
I ran and referenced your code. The annotations really helped. Below is the code that I will adopt. It is basically that same a yours with a small adjustment to change the line direction.