写写关于Dynamo参数赋值
为单个对象赋单个参数值
最容易理解,SetParameterByName需要输入三个参数,元素对象(数据类型:Element),参数名称(数据类型:String),参数值(数据类型:None/Integer/Double/String/Element)
注意,输入的参数值的数据类型需要与指向的参数相符,例如指向的参数需要输入布尔值,如果输入了字符串则会报错
为单个对象赋多个参数值
两种方法,第一种是直接在后面加SetParameterByName节点,如果只是修改两个参数,这样操作最快,复制改改输入就好
如果修改的参数多,可以给SetParameterByName输入参数列表及值列表,要注意列表项要一一对应
为多个对象各赋单个参数值
当多个对象的参数值都是一样的时候,实现很简单,直接往SetParameterByName传入element列表就好
如果多个对象的参数值有可能不一样,可将参数值作为列表输入
为多个对象各赋多个参数值
这种情况列表结构开始复杂,但也是业务中最常碰到的场景
使用Python Script节点实现
也可以用python自定义一个节点,那样不管哪种情况拿起直接用就好
核心方法就是将参数与参数值的输入都处理成二维列表,然后用统一的遍历逻辑进行参数写入
下面代码
# 导入所需的模块
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager# 获取Dynamo中的Revit文档
doc = DocumentManager.Instance.CurrentDBDocument# 元素
elements = UnwrapElement(IN[0]) if isinstance(IN[0], list) else [UnwrapElement(IN[0])]# 参数
input_parameters = IN[1]# 值
input_values = IN[2]# 统一输入
def process_input(input_data, elements_count):dimensions = get_list_dimensions(input_data)if not dimensions: # 非列表情况,将元素包含到一个二维列表中return [[input_data] for _ in range(elements_count)]elif len(dimensions) == 1: # 一维列表情况,重复一维列表成为二维列表return [input_data] * elements_countelif len(dimensions) == 2: # 二维列表情况return input_dataelse:raise ValueError("检查输入数据的维度")# 修改参数
def modify_parameter(element, parameter, value):param = element.LookupParameter(parameter)if param:try:TransactionManager.Instance.EnsureInTransaction(doc)param.Set(value)TransactionManager.Instance.TransactionTaskDone()return elementexcept Exception as e:TransactionManager.Instance.TransactionTaskDone()return Noneelse:return None# 获取列表的维度
def get_list_dimensions(ls):if isinstance(ls, list):return [len(ls)] + get_list_dimensions(ls[0])else:return []# 检查参数与参数值数量是否一致
def check_matching_lengths(parameters, values):flattened_parameters = [item for sublist in parameters for item in sublist]flattened_values = [item for sublist in values for item in sublist]if len(flattened_parameters) != len(flattened_values):raise ValueError("参数与参数值的数量未对应")output = []
modified_elements = set()
try:parameters = process_input(input_parameters, len(elements)) # 1) 处理参数输入values = process_input(input_values, len(elements)) # 2) 处理值输入check_matching_lengths(parameters, values) # 3) 检查数量是否一致for element, element_params, element_values in zip(elements, parameters, values):#4) 修改for parameter, value in zip(element_params, element_values):modified_element = modify_parameter(element, parameter, value)if modified_element and modified_element not in modified_elements:output.append(modified_element)modified_elements.add(modified_element)
except ValueError as ve:output.append(str(ve))OUT = output
为实例对象的类型参数赋值
见过很多次初学者都提出过的赋值问题,由于对实例和类型理解得不深刻,不知道如何为类型赋值
逻辑很简单,获取到实例后,先由实例获取到类型,然后再对类型的参数做修改
注意,修改类型参数会将修改影响到所有相关的实例
遇过的一些坑
重复名称的参数
一些情况下,一个实例可能出现名称一样的两个参数,仅通过参数名称,可能会指向错误的参数
对于这种情况,通常需要增加更多的判断条件,例如是否软件自带参数,是否共享参数,甚至直接使用固定的ID等,才可以指向准确的参数
错误的参数类型
基础却又容易忽略的问题,当需要修改的参数很多的时候,时常会忽略了参数的类型
有一次跑脚本发现一直抱错,排除半天才发现居然忽略了这个基础问题
而有时一些参数的命名又容易让人产生误导,例如一个命名为“长度”的自定义参数,输入实际上被设置为字符串(有意或无意),而调试时容易将其理解为数值,导致输入错误
所以还是要注意输入的参数类型
不要在生产项目中调试数据
关于数据的写入,如果出现了错误,有时会非常隐蔽,
常见的情况是调试的时候往A参数写了数据,后续可能又将脚本修改调整到了其他参数,但此时A参数上的数据并没有被清除或回撤,如果这个是生产项目,而A参数后续又会被用到其他地方,则可能带来一些不可预料的影响
所以在编写及调试脚本的时候,不要直接在生产项目中进行)