跳转到主要内容

参数与表达式

当草图的尺寸由命名值而不是硬编码的数字驱动时,草图才真正成为参数化草图。本页介绍完整的工作流程:创建参数、通过表达式用参数驱动几何图形,以及在主窗口中分配每个实例的值。同时还介绍了文本框中的模板表达式。

添加和编辑参数

每个草图都有自己的参数列表,显示在草图编辑器左侧的 Sketch Parameters 面板中。点击 Add Parameter 可以创建一个新参数,可在整数、浮点数、滑块或单行文本之间选择。

草图编辑器中的 Sketch Parameters 面板

每个参数都是一个可展开的行。点击该行可显示其定义字段:

  • Label —— 在列表中显示的易读名称。
  • Key —— 表达式引用的标识符(除非手动输入,否则自动从标签派生)。保持它为有效的 Python 标识符,例如 widthwall_thickness
  • Description —— 行下方显示的可选说明。
  • Default Value —— 参数的初始值。
  • Minimum / Maximum Value —— 可选的范围限制(启用对应的开关即可)。滑块参数始终具有有限范围。

对于壁厚可变的盒子,一个典型的设置是两个参数:widththickness。此时还没有任何东西约束几何图形;在表达式使用它们之前,参数只是数字的名称。

在表达式中使用参数

双击一个尺寸约束(参见约束),输入一个表达式而不是纯数字:

width / 2

约束的值就成为该表达式的结果,并在草图每次求解时重新计算。在下面的示例中,左边缘被约束为 width / 2——其标记和标签以橙色绘制,表示它由表达式驱动——而顶边缘保持纯数字尺寸:

由表达式驱动的尺寸约束

更改 width 参数,受约束的几何图形就会随之更新——现在一次编辑就能更新所有引用它的尺寸。

表达式可以将参数与算术运算和标准 Python 数学函数组合使用:

width - 2 * thickness
sqrt(area) / 2
2 * pi * radius

sqrtsincostan 这样的函数,以及像 pi 这样的常量,都来自 Python 的 math 模块——这个模块加上参数本身,正是约束表达式所能引用的全部内容。字符串参数也可以被引用,这主要用于文本框。

在主窗口中分配值

在草图中定义的参数作为其边界值的默认值。当草图放置在文档中时,每个工件都拥有自己的参数值副本,右侧属性面板中的 Sketch Parameters 组允许你为每个实例覆盖它们——同一个草图可以在板材上以多种尺寸使用,每个实例都有自己的 widththickness

在主窗口中选择草图工件,该组就会出现在属性面板中,每行一个参数,每行显示该实例使用的值。输入或调整新值;零件会立即重新生成。

在主窗口中分配参数值

编辑参数定义(添加参数、更改默认值或重命名键)在草图编辑器中进行,如上所述。主窗口面板仅调整所选实例的——它始终反映草图的参数集,新实例在覆盖之前使用草图的默认值。

文本框中的模板表达式

文本框会在求解时解析花括号括起来的表达式,因此标签和雕刻文本会显示实时值:

W = {width}, H = {height}

任何参数都可以按名称替换,结果可以用冒号后的 Python 格式说明符进行格式化:

  • {width} — 参数 width 的当前值
  • {name} — 字符串类型参数的值
  • {width:.1f} — 一位小数
  • {timestamp():.0f} — 函数结果无小数

这里同样可以使用数学运算,既可以写成 {width * 2} 这样的表达式,也可以通过 {sqrt(area):.2f} 这样的函数使用。与约束表达式相比,文本模板拥有更丰富的工具箱:除了数学模块之外,它们还暴露下方的内置函数,并且可以为它们注册自定义函数(见下文)。

内置模板函数

函数返回类型描述
{today()}date当前 UTC 日期(如 2026-08-26
{date()}datetoday() 的别名
{now()}datetime当前 UTC 日期和时间
{time()}time当前 UTC 时间(如 15:30:00.123456+00:00
{timestamp()}floatUnix 时间戳(自纪元以来的秒数)
{uuid4()}str8 字符十六进制字符串(如 a1b2c3d4
{uuid8()}struuid4() 的别名
{uuid()}str完整 UUID v4 字符串(36 字符)

典型用途包括每次求解生成唯一序列号(零件 #{uuid4()})、实时尺寸标签(宽={width:.1f} 高={height:.1f})、日期戳(日期:{today()})、生产计数器({name} - {count:.0f}个),或用于生产日志的 Unix 时间戳({timestamp():.0f})。

自定义模板函数

你可以注册自己的函数,在文本框模板中使用。这对于从数据库获取序列号、读取外部数据或生成自定义标签非常有用。

编写注册脚本

创建一个 Python 文件(如 ~/.config/rayforge/my_functions.py):

"""Register custom template functions for text box expressions."""
import sqlite3

from sketcher.core.template_functions import register_template_function

DB_PATH = "/home/you/production.db"


def next_serial() -> str:
"""Fetch and reserve the next serial number from the database."""
conn = sqlite3.connect(DB_PATH)
try:
cur = conn.execute(
"UPDATE counters SET value = value + 1 "
"WHERE name = 'serial' RETURNING value"
)
row = cur.fetchone()
conn.commit()
return f"SN-{row[0]:06d}"
finally:
conn.close()

register_template_function("next_serial", next_serial)

对每个函数调用 register_template_function(name, callable)。函数可以做任何 Python 能做的事——打开文件、连接数据库、调用 API——并且它在 每次渲染时都会被调用,所以应该很快(如果底层数据在渲染之间不会变化,可以使用缓存)。如果你的 callable 是线程安全的,函数就是线程安全的。

运行带有脚本的 Rayforge

使用 --script 标志在窗口打开之前加载你的函数:

rayforge --script ~/.config/rayforge/my_functions.py mydoc.ryp

这会在启动早期运行你的脚本——在加载插件之前、在创建主窗口之前——因此函数在草图首次求解时就已可用。

在文本框中使用函数

在草图绘制器中,创建一个内容如下的文本框:

{next_serial()}

格式说明符也可以使用:

{next_serial():>20}

编程式注册函数

如果你正在编写插件或可重用库,可以从任何在草图求解之前运行的 Python 代码中调用 register_template_function

from sketcher.core.template_functions import register_template_function

register_template_function("part_number", lambda: f"P-{hash('x') % 10000:04d}")

内置函数不能被删除

内置函数(todaynowuuid 等)不能被注销。如果需要改变它们的行为,请用不同的名称注册一个函数。