教程大纲
- 什么是 Seamless Factory?
- 核心思想与价值
- 传统 Houdini Python vs. Seamless Factory
- 环境准备
- 安装 Houdini 版本要求
- 如何启用 Seamless Factory
- 核心概念:Nodes, Graphs, and Arguments
Node: 代表一个 SOP/DOP/ROP 节点Graph: 代表一个网络,如/objArguments: 节点的输入和参数- Cooking (计算): 何时以及如何触发计算
- 实战教程:从零开始构建一个自动化流程
- 教程目标: 创建一个工具,一键生成带有随机大小和位置的球体,并将其打包成 Alembic 文件。
- 步骤 1: 创建和连接节点
- 步骤 2: 设置节点参数
- 步骤 3: 获取和设置节点数据
- 步骤 4: 控制节点的计算
- 步骤 5: 完整代码与讲解
- 进阶概念与技巧
- 错误处理: 使用
try...except - 性能优化: 避免不必要的计算
- 与 UI 交互: 在 Python 中修改 UI 参数
- 使用 Presets: 加载和保存节点预设
- 错误处理: 使用
- 总结与资源
什么是 Seamless Factory?
核心思想与价值
Seamless Factory 的核心思想是 “声明式” (Declarative) 和 “无状态” (Stateless)。

- 传统方式 (命令式): 你告诉 Houdini 如何一步步操作。
create a node,set its parameter,connect node A to node B,cook node B,你需要手动管理节点的创建、连接、计算顺序等状态。 - Seamless Factory 方式: 你告诉 Houdini 你想要什么结果,你描述一个最终的“工厂”或“蓝图”,其中包含了哪些节点、它们之间如何连接、以及每个节点的参数是什么,Seamless Factory 负责处理所有底层的实现细节,如创建节点、建立连接、并以正确的顺序计算它们。
价值:
- 代码更简洁: 代码量通常比传统 Python API 减少 80% 以上。
- 可读性更高: 代码结构清晰地反映了最终的节点网络布局。
- 性能更好: 它内部进行了大量优化,可以智能地管理计算,避免重复计算。
- 更健壮: 减少了因手动管理节点状态(如路径错误、连接失效)而导致的脚本崩溃。
传统 Houdini Python vs. Seamless Factory
假设我们要创建一个 Sphere 节点并设置其半径。
传统方式:
import hou
# 获取当前网络
obj = hou.node("/obj")
# 创建节点
sphere = obj.createNode("sphere", "my_sphere")
# 设置参数
sphere.parm("radius").set(2.0)
# 连接到另一个节点 (例如一个 Null)
null_node = obj.createNode("null", "my_null")
sphere.setNextInput(null_node)
Seamless Factory 方式:

from sops import factories
# 直接描述节点网络
sphere = factories.node("/obj/my_sphere", type="sphere", radius=2.0)
看,代码从 7 行减少到了 1 行,并且意图更加明确。
环境准备
安装 Houdini 版本要求
Seamless Factory 是从 Houdini 19.5 开始引入的,你需要确保你使用的是 Houdini 19.5 或更高版本。
如何启用 Seamless Factory
Seamless Factory 通常作为 Houdini 的一部分预装,你只需要在 Python 环境中导入它即可,它不需要单独的安装步骤。
在 Python Shell 或脚本的顶部,这样导入:

from sops import factories
如果导入成功,说明你的环境已经准备就绪。
核心概念:Nodes, Graphs, and Arguments
Node (节点)
在 Seamless Factory 中,一个 Node 对象代表 Houdini 中的一个节点,你可以通过其路径来引用它:
# 获取一个已经存在的节点
my_sphere = factories.node("/obj/geo1/sphere1")
# 创建一个新节点 (如果路径不存在)
new_box = factories.node("/obj/geo1/my_new_box", type="box")
Graph (图/网络)
一个 Graph 代表一个网络,/obj, /out, (根网络),你可以通过 factories.graph() 来获取一个图对象,然后在上面创建节点。
# 获取 /obj 图
obj_graph = factories.graph("/obj")
# 在图上创建节点
geo = obj_graph.createNode("geo", "my_geo")
Arguments (参数)
这是 Seamless Factory 最强大的部分,你可以在创建节点或设置参数时,直接传递一个字典来定义所有需要的参数。
-
创建时设置参数:
# 创建一个带有初始参数的节点 noise = factories.node("/obj/noise1", type="noise", freq=10.0, roughness=0.2) -
设置已有节点的参数:
# 获取节点并设置参数 my_node = factories.node("/obj/my_node") my_node.set_parms({"tx": 5.0, "ty": 0.0, "tz": -3.0}) # 注意:是 set_parms (带s),不是 set_parm
Cooking (计算)
在传统 Houdini 中,你可能需要手动调用 node.cook(),在 Seamless Factory 中,它会自动处理:
- 延迟计算: 当你只读取节点信息(如
node.geometry())时,它不会立即计算整个网络。 - 按需计算: 只有当你需要某个节点的最终结果时,它才会计算该节点及其所有必要的上游节点。
- 自动缓存: 计算结果会被缓存,避免重复计算。
实战教程:一键生成 Alembic 文件
教程目标
创建一个 Python 脚本,执行以下操作:
- 在
/obj下创建一个geo节点。 - 在
geo节点内,创建一个Sphere节点,并设置其半径和位置为随机值。 - 在
geo节点内,创建一个RBD Packed Object节点,将Sphere作为输入。 - 在
/out下创建一个Rop Alembic Output节点。 - 将
RBD Packed Object连接到Rop Alembic Output。 - 设置 Alembic 节点的路径和帧范围。
- 执行整个网络,生成 Alembic 文件。
步骤 1 & 2: 创建和连接节点,并设置参数
我们将一次性创建所有节点,并设置它们的初始参数和连接关系。
from sops import factories
import random
# --- 1. 创建 SOP 网络部分 ---
# 在 /obj 下创建一个 geo 网络
geo_node = factories.node("/obj/my_alembic_geo", type="geo")
# 在 geo 网络内创建一个球体,并随机设置其位置和半径
sphere_node = factories.node("/obj/my_alembic_geo/sphere",
type="sphere",
tx=random.uniform(-5, 5),
ty=random.uniform(-5, 5),
tz=random.uniform(-5, 5),
radius=random.uniform(0.5, 2.0))
# 在 geo 网络内创建一个 RBD Packed Object 节点
# 它会自动将 sphere_node 作为输入
packed_node = factories.node("/obj/my_alembic_geo/rbd_packed",
type="rbdpackedobject",
# inputindex0=sphere_node # 通常不需要显式写,SF会处理
)
# --- 2. 创建 ROP 网络部分 ---
# 在 /out 下创建一个 Alembic Output 节点
alembic_node = factories.node("/out/my_alembic_output",
type="rop_alembic",
# 将 packed_node 连接到 Alembic � 