Revit Dynamo中Catmull/Linear日期插值Python脚本报错求助
解决Revit Dynamo中日期插值脚本的两类错误
作为经常在Dynamo里折腾Python脚本的人,我帮你拆解下这两个错误的根源和解决办法:
一、Catmull插值的TypeError: can't multiply sequence by non-int of type 'float'
这个错误本质是你试图对非数值类型的序列做浮点运算,大概率是日期数据的格式没处理对:
- 你输入的日期
D可能是字符串格式(比如"2024-05-20"),而不是可以进行数值计算的日期对象或数值。字符串序列没法和IN[0]里的float数值相乘,自然报错。 - 少数情况是
IN[0]的t参数被当成了字符串列表,但你给出的IN[0]是数值,这个可能性较低。
解决步骤:
- 把日期转成可计算的数值:先将日期字符串转换成
datetime对象,再转成从某个基准日(比如1970-01-01)开始的天数/秒数,变成纯数值。 - 完成插值后转回日期:插值计算得到的是数值,再把它转换回
datetime对象,才能在Dynamo里正常使用。
举个简化的示例代码:
import datetime from scipy.interpolate import interp1d # 假设IN[0]是t参数列表,IN[1]是你的日期输入(字符串列表) t_values = [float(val) for val in IN[0]] date_strings = IN[1] # 转换日期为数值(以1970-01-01为基准的天数) date_nums = [] for d_str in date_strings: dt = datetime.datetime.strptime(d_str, "%Y-%m-%d") # 这里要匹配你的日期格式 delta = dt - datetime.datetime(1970, 1, 1) date_nums.append(delta.days) # 执行Catmull-Rom插值(kind='cubic'对应Catmull插值) interpolator = interp1d(t_values, date_nums, kind='cubic') # 假设你要插值的目标t值是target_t,替换成你的实际需求 target_t = 0.5 interpolated_num = interpolator(target_t) # 转回日期对象 interpolated_date = datetime.datetime(1970, 1, 1) + datetime.timedelta(days=interpolated_num) OUT = interpolated_date
二、Linear插值的Unexpected Token "v3"错误
这个是Python语法错误,和插值逻辑无关,大概率是脚本里的拼写或语法问题:
- 你写的线性插值代码里出现了未定义的变量
v3,可能是手滑打错了变量名(比如本来是v2或者某个已定义的变量)。 - 也可能是代码结构有问题:比如括号不匹配、引号没闭合,或者不小心输入了多余的字符(比如复制粘贴时带了奇怪的符号)。
- 另外,Dynamo用的是IronPython,部分Python 3的语法(比如f-string、walrus运算符)不支持,如果你的代码里用了这些,也可能触发奇怪的语法错误。
解决步骤:
- 直接搜索你的线性插值脚本里的
v3,检查这个变量是否被定义,或者是不是拼写错误。比如如果你的线性插值公式是result = start_val + (end_val - start_val) * (target_t - start_t)/(end_t - start_t),那根本不需要v3,删掉它就行。 - 检查整个脚本的语法:比如所有括号是否成对,字符串是否用引号闭合,有没有使用IronPython不支持的语法。
举个正确的线性插值示例(处理日期的版本):
import datetime # 假设IN[0]是t参数列表,IN[1]是日期字符串列表,IN[2]是要插值的目标t值 t_values = [float(val) for val in IN[0]] date_strings = IN[1] target_t = float(IN[2]) # 转换日期为数值 date_nums = [] for d_str in date_strings: dt = datetime.datetime.strptime(d_str, "%Y-%m-%d") delta = dt - datetime.datetime(1970, 1, 1) date_nums.append(delta.days) # 找到目标t所在的区间 for i in range(len(t_values)-1): if t_values[i] <= target_t <= t_values[i+1]: t1, t2 = t_values[i], t_values[i+1] d1, d2 = date_nums[i], date_nums[i+1] # 线性插值计算 interpolated_num = d1 + (d2 - d1) * (target_t - t1)/(t2 - t1) # 转回日期 interpolated_date = datetime.datetime(1970, 1, 1) + datetime.timedelta(days=interpolated_num) OUT = interpolated_date break
内容的提问来源于stack exchange,提问作者P.Kapoor
相关产品推荐
相关产品推荐

