I am trying to get new rebar numbers with Dynamo -Revit. The new rebar numbers are placed in that way so first the rebars are sorted first by parameter “Shape” , then by “Bar Diameter” and at the end by parameter “Bar Length” . The sorting by the parameters “Bar Diameter” and “Bar Length” are working fine , but the sorting by the parameter “Shape” is not good .
This is mine Dynamograph (1pic) for the parameter ‘‘Shape’’ .It connects to the Python script node (2pic) IN[0].Also have 2 more parameters “Bar Length” and “Bar Diameter” conected to IN[1] and IN[2]. I get new unique rebar numbers base on this code :
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
# Input rebar lists and parameters
rebars_list1 = IN[0]
rebars_list2 = IN[1]
rebars_list3 = IN[2]
parameterName = IN[3]
starting_number = IN[4]
# Helper function to safely get parameter values and convert them to comparable types
def get_parameter_value(rebar, param_name, default_value=None):
value = rebar.GetParameterValueByName(param_name)
if value is None:
return default_value
try:
# Attempt to convert to float if possible
return float(value)
except (ValueError, TypeError):
# If conversion fails, return as string
return str(value)
# Group rebars in rebars_list3 by "Bar Length" and "Bar Diameter"
length_diameter_grouped_rebars = {}
for rebar in rebars_list3:
length = get_parameter_value(rebar, "Bar Length", 0)
diameter = get_parameter_value(rebar, "Bar Diameter", 0)
key = (length, diameter)
if key not in length_diameter_grouped_rebars:
length_diameter_grouped_rebars[key] = []
length_diameter_grouped_rebars[key].append(rebar)
# Print the initial groupings for debugging
print("Initial groupings:")
for key, group in length_diameter_grouped_rebars.items():
print(f"Key: {key}, Group Size: {len(group)}")
# Flatten the grouped rebars while maintaining order within each length-diameter group
grouped_rebars_list3 = []
for key in sorted(length_diameter_grouped_rebars.keys()):
grouped_rebars_list3.extend(length_diameter_grouped_rebars[key])
# Combine all rebar lists into one in the specified order
all_rebars = rebars_list1 + rebars_list2 + grouped_rebars_list3
# Sort the combined list by "Shape" first, then "Bar Diameter", and then "Bar Length"
sorted_rebars = sorted(all_rebars, key=lambda rebar: (
get_parameter_value(rebar, "Shape", ""),
get_parameter_value(rebar, "Bar Diameter", 0),
get_parameter_value(rebar, "Bar Length", 0)
))
# Print the sorted list for debugging
print("Sorted rebars:")
for rebar in sorted_rebars:
shape = get_parameter_value(rebar, "Shape", "")
diameter = get_parameter_value(rebar, "Bar Diameter", 0)
length = get_parameter_value(rebar, "Bar Length", 0)
print(f"Shape: {shape}, Diameter: {diameter}, Length: {length}")
# Initialize parameters for numbering
numberMap = {}
current_number = starting_number
# Assign unique numbers to rebars based on length and diameter grouping
for rebar in sorted_rebars:
length = get_parameter_value(rebar, "Bar Length", 0)
diameter = get_parameter_value(rebar, "Bar Diameter", 0)
key = (length, diameter)
if key in numberMap:
rebar.SetParameterByName(parameterName, numberMap[key])
else:
numberMap[key] = current_number
rebar.SetParameterByName(parameterName, current_number)
current_number += 1
# Print debugging information
print(f"Rebar: {rebar}, Length: {length}, Diameter: {diameter}, Number: {numberMap[key]}")
# Output the last assigned number
OUT = current_number - 1
why there is no sorting based on the parameter ‘‘Shape’’?? Do I need modify code or to do new Dynamogrph with different nodes?
MOD EDIT: formatted code
can you use
for pasting your code
are you shure the code is right, you use print - in dynamo works only print.
# code </>
When sharing screenshots it’s always best to pin the node preview bubbles so we can see what your data looks like and how its structure is being handled.
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
allRebars = IN[0]
partition = IN[1]
rebars = []
for rebar in allRebars:
if rebar.GetParameterValueByName("Partition") == partition:
rebars.append(rebar)
# Assign your output to the OUT variable.
OUT = rebars
Your graph looks correct. Can you show us the sorting/grouping settings from the schedule? It certainly doesn’t look like it’s being sorted by Shape only.