Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
如果要查找有关如何为 Dynamo 开发的示例,请查看以下资源:
这些样例是 Visual Studio 模板,可用于启动您自己的项目:
ZeroTouchEssentials: 用于基本 ZeroTouch 节点的模板。
HelloDynamo: 用于基本 NodeModel 节点和视图自定义的模板。
基本 NodeModel 模板:HelloNodeModel.cs
基本 NodeModel 视图自定义模板:HelloGui.cs、HelloGuiNodeView.cs、Slider.xaml、Slider.xaml.cs
DynamoSamples: 用于 ZeroTouch、自定义 UI、测试和视图扩展的模板。
创建基本的自定义 UI 节点:CustomNodeModel.cs
创建下拉菜单:DropDown.cs
ZeroTouch 测试:HelloDynamoZeroTouchTests.cs
ZeroTouch 节点示例,包括实现 IGraphicItem
以影响几何图形渲染的节点:BasicExample.cs
使用 IRenderPackage
为几何图形着色的 ZeroTouch 节点示例:ColorExample.cs
视图扩展示例:一个 IViewExtension 实现,在单击其 MenuItem 时显示一个无模式窗口。
NodeModelsEssentials: 用于使用 NodeModel 进行高级 Dynamo 软件包开发的模板。
DynaText: 一个用于在 Dynamo 中创建文字的 ZeroTouch 库。
第三方开发人员已为该平台做出了令人兴奋的重大贡献,其中许多也是开源的。以下项目是可以使用 Dynamo 实现的特例。
Ladybug 是一个 Python 库,可用于加载、分析和修改 EneregyPlus Weather 文件 (epw)。
https://github.com/ladybug-tools/ladybug
Honeybee 是一个 Python 库,可用于创建、运行和可视化日光 (RADIANCE) 和能量分析 (EnergyPlus/OpenStudio) 的结果。
https://github.com/ladybug-tools/honeybee
Bumblebee 是用于 Excel 和 Dynamo 互操作性 (GPL) 的插件。
https://github.com/ksobon/Bumblebee
Clockwork 是一组自定义节点,用于 Revit 相关活动以及其他用途,例如列表管理、数学运算、字符串操作、几何操作(主要是边界框、网格、平面、点、曲面、UV 和向量)和嵌板。
本部分包含有关将图形、软件包和库移植到 Dynamo 3.x 时可能所遇到问题的信息。
Dynamo 3.0 是一个主版本,一些 API 已更改或已删除。对于作为 Dynamo 3.x 的开发人员或用户的您而言,可能产生影响的最大变化是迁移到 .NET8。
Dotnet/.NET 是运行时,支持 Dynamo 编写所用的 C# 语言。我们已将此运行时以及 Autodesk 生态系统的其余部分一起更新到现代版本。
可以在我们的博客贴子中了解详细信息。
由于 Dynamo 3.x 现在基于 .NET8 运行时运行,因此并不能保证为 Dynamo 2.x(使用 .NET48)构建的软件包能够在 Dynamo 3.x 中工作。尝试在 Dynamo 3.x 中下载从 Dynamo 版本低于 3.0 发布的软件包时,您会收到一条警告,指出该软件包来自较旧版本的 Dynamo。
这并不意味着软件包将不工作。这只是一个警告,指出可能存在兼容性问题;通常,最好检查是否有专为 Dynamo 3.x 构建的较新版本。
在加载软件包时,您还可能会在 Dynamo 日志文件中注意到此类警告。如果一切正常,可以忽略它。
为 Dynamo 3.x(使用 .Net8)构建的软件包不太可能基于 Dynamo 2.x 运行。如果您正在使用较旧版本的 Dynamo,则下载为更高版本的 Dynamo 构建的软件包时,还会看到警告。
Dynamo 扩展可以像常规 Dynamo 节点库一样展开到软件包管理器。如果安装的软件包包含视图扩展,则会在 Dynamo 载入时的运行时载入扩展。可以查看 Dynamo 控制台,以确认扩展是否已正确载入。
扩展包的结构与普通软件包相同,其中包含...
假定您已构建扩展,您将(至少)有一个 .NET 程序集和一个清单文件。该程序集应包含实现 IViewExtension
或 IExtension
的类。清单 .XML 文件会告知 Dynamo 要实例化哪个类才能启动扩展。为了使软件包管理器能够正确定位扩展,清单文件应准确对应于程序集位置和命名。
将任何程序集文件放置在 bin
文件夹中,并将清单文件放置在 extra
文件夹中。任何其他资源也可以放置在此文件夹中。
清单 .XML 文件示例:
在您有包含上述子目录的文件夹后,即可将其推送(上传)到软件包管理器。需要注意的一点是,您当前无法从 Dynamo 沙箱发布软件包。这意味着您需要使用 Dynamo Revit。在进入 Dynamo Revit 后,导航到“软件包”=>“发布新软件包”。这将提示用户登录到其要与软件包关联的 Autodesk 帐户。
此时,您应该位于常规发布软件包窗口,在该窗口中将输入有关软件包/扩展的所有必填字段。还有一个非常重要的附加步骤,要求您确保没有任何程序集文件标记为节点库。为此,请在已输入的文件(在上面创建的软件包文件夹)上单击鼠标右键。一个上下文菜单即会显示,让您可以选中(或取消选中)此选项。应取消选中所有扩展程序集。
在公开发布之前,应始终在本地发布,以确保一切正常。在确认一切正常后,即可通过选择“发布”来联机发布。
要确认软件包是否已成功上传,您应该能够根据在发布步骤中指定的命名和关键字搜索到相应软件包。最后,请务必注意,相同的扩展需要重新启动 Dynamo,然后才能正常运行。通常,这些扩展需要在 Dynamo 启动时指定的参数。
DynamoRevit 源文件也托管在 DynamoDS GitHub 上,可供开发人员参与修改并构建 Beta 版。从源代码构建 DynamoRevit 通常遵循与 Dynamo 相同的过程,但一些重要细节除外:
DynamoRevit 会参照 Dynamo 程序集,因此应使用匹配的 NuGet 软件包构建这些程序集。例如,DynamoRevit 2.x 不会载入到 Dynamo 1.3 中。
DynamoRevit 特定于 Revit 版本,例如:DynamoRevit 2018 分支应在 Revit 2018 上运行。
在本手册中,我们将使用以下内容:
Revit 2023
基于分支 Revit2023
的最新 DynamoRevit 构建
最新 Dynamo 构建
为了确保构建成功,我们将克隆并构建要在本漫游中使用的 Dynamo 和 DynamoRevit 存储库。
注意:仅当构建 Dynamo 1.x 和 DynamoRevit 1.x 时,才需要在 Dynamo 之前手动构建 Dynamo - 较新版本的 DynamoRevit 存储库依赖 NuGet 软件包管理器来构建所需的 Dynamo 依存关系。虽然 DynamoRevit 2.x 的构建不需要手动拉取 Dynamo,但仍需要在其他地方使用核心 dlls
来实际运行 DynamoRevit addin
- 因此,无论如何,拉取和构建 Dynamo 都是值得的。详见下文: 使用 Visual Studio 构建存储库
DynamoRevit 项目的代码位于 GitHub 上独立于核心 Dynamo 源代码的存储库中。此存储库包含 Revit 特定节点的源文件和载入 Dynamo 的 Revit 附加模块。针对不同版本的 Revit(例如,2016、2017 或 2018)的 DynamoRevit 构建会在存储库中组织为分支。
DynamoRevit 的源代码托管在此处:https://github.com/DynamoDS/DynamoRevit
克隆或下载存储库
DynamoRevit 的分支参照 Revit 版本
在与拉取 Dynamo 存储库类似的过程中,我们将使用 git 克隆命令来克隆 DynamoRevit 并指定与我们的 Revit 版本匹配的分支。首先,我们将打开命令行界面,然后将当前目录设置为要将文件克隆到的位置。
cd C:\Users\username\Documents\GitHub
更改当前目录
将
username
替换为您的用户名
现在,我们可以将存储库克隆到此目录中。尽管我们需要指定存储库的分支,但可以在克隆后切换到该分支。
git clone https://github.com/DynamoDS/DynamoRevit.git
从远程 URL 克隆存储库,然后默认切换到主分支。
在存储库克隆完成后,将当前目录更改为存储库文件夹,然后切换到与已安装版本的 Revit 匹配的分支。在本例中,我们使用的是 Revit RC2.13.1_Revit2023。可以在 GitHub 页面上的“分支”下拉菜单中查看所有远程分支。
cd C:\Users\username\Documents\GitHub\DynamoRevit
将目录更改为 DynamoRevit。
git checkout RC2.13.1_Revit2023
将当前分支设置为 RC2.13.1_Revit2023
。
git branch
确认我们所在的分支,并显示本地存在的其他分支。
带星号的分支是当前已检出的分支。
Revit2018
分支之所以显示,是因为我们之前已将其检出,所以它存在于本地。
请务必选择存储库的正确分支,以确保在 Visual Studio 中构建项目时,它将参照 Revit 安装目录的正确版本中的程序集,尤其是 RevitAPI.dll
和 RevitAPIUI.dll
。
在构建存储库之前,我们需要使用 src
文件夹中的 restorepackages.bat
文件恢复 NuGet 软件包。该 bat 文件会使用 NuGet 软件包管理器来拉取 DynamoRevit 所需的 Dynamo 核心的已构建二进制文件。但如果您仅对 DynamoRevit 进行更改,而不是对 Dynamo 核心进行更改,也可以选择手动构建这些文件。这样可以更快地开始运行。确保以管理员身份运行此文件。
在
restorepackages.bat
上单击鼠标右键,然后选择Run as administrator
如果软件包已成功恢复,则 packages
文件夹将添加到 src
文件夹(包含最新 Beta 版 NuGet 软件包)中。
最新 Beta 版 Dynamo NuGet 软件包
在软件包恢复后,打开 src
中的 DynamoRevit.All.sln
Visual Studio 解决方案文件,然后构建解决方案。该构建最初可能难以找到 AssemblySharedInfo.cs
。如果是这样,则重新运行构建即会解决该问题。
选择
Build > Build Solution
在“输出”窗口中确认构建是否已成功。消息应为
===== Build: 13 succeeded, 0 failed, 0 up-to-date, 0 skipped =====
。
Revit 需要一个附加模块文件来识别 DynamoRevit,安装程序会自动创建该文件。在开发过程中,我们需要手动创建一个指向我们要使用的 DynamoRevit 构建的附加模块文件,尤其是 DynamoRevitDS.dll
程序集。我们还需要将 DynamoRevit 指向 Dynamo 的构建。
在 Revit 的附加模块文件夹(位于 C:\ProgramData\Autodesk\Revit\Addins\2023
中)中创建 Dynamo.addin
文件。我们已安装了一个版本的 DynamoRevit,因此我们只需编辑现有文件以指向新构建。
在 <Assembly>...</Assembly>
内,指定 DynamoRevitDS.dll
的文件路径。
或者,我们可以让附加模块载入版本选择器,而不是特定的程序集。
将 <Assembly>...</Assembly>
文件路径设置为 DynamoRevitVersionSelector.dll
<FullClassName>...</FullClassName>
指定哪些类要从我们使用上述程序集元素路径指向的程序集实例化。此类将成为我们附加模块的入口点。
此外,我们还需要删除 Revit 附带的现有 Dynamo。要执行此操作,请转到 C:\\Program Files\Autodesk\Revit 2023\AddIns
并删除包含 “Dynamo” 的两个文件夹:DynamoForRevit
和 DynamoPlayerForRevit
。如果需要恢复原始 Dynamo for Revit,可以删除它们,也可以将它们备份在单独的文件夹中。
第二步是将 Dynamo 核心程序集的文件路径添加到 DynamoRevit 的 bin
文件夹中的 Dynamo.config
文件。当附加模块在 Revit 中打开时,DynamoRevit 将载入这些文件。通过此配置文件,可以将 DynamoRevit 附加模块指向不同版本的 Dynamo 核心,以在核心和 DynamoRevit 中开发和测试更改。
代码应如下所示:
将 bin
文件夹的目录路径添加到 <add key/>
我们在此漫游之前就已克隆并构建了 Dynamo,以确保它能够与 DynamoRevit 一起正常工作。目录路径指向此构建。
现在,当我们打开 Revit 时,“管理”选项卡中应该有一个 Dynamo 附加模块。
选择
Manage
单击 Dynamo 附加模块图标
一个 DynamoRevit 的实例
如果出现一个错误对话框窗口(其中显示缺少的程序集),则很可能是您构建的 DynamoCore 版本与运行时载入的版本不匹配。例如,如果您尝试使用 Dynamo 1.3 dll 启动 DynamoRevit(其中包含 DynamoCore 的最新 2.0 Beta 版软件包),则它将无法工作。请确保两个存储库的版本相同,并且 DynamoRevit 拉取的是版本匹配的 NuGet 依存关系。在 DynamoRevit 存储库的 package.json
文件中定义这些依存关系。
在上一节(从源代码构建 Dynamo)中,我们简要介绍了在 Visual Studio 中调试以及如何将 Visual Studio 附着到进程。以 Wall.ByCurveAndHeight 节点中的异常为例,我们将介绍如何附着到进程、设置断点、单步调试代码,以及使用调用堆栈来确定异常的来源。这些调试工具通常适用于 .net 开发工作流,值得在本手册之外进行探索。
“附着到进程” 会将正在运行的应用程序链接到 Visual Studio,以进行调试。如果我们要调试 DynamoRevit 构建中发生的行为,则我们可以在 Visual Studio 中打开 DynamoRevit 源文件,然后附着 Revit.exe
进程,该进程是 DynamoRevit 附加模块的父进程。Visual Studio 使用符号文件 (.pbd
),以在 DynamoRevit 正在执行的程序集和源代码之间建立连接。
“断点” 会在源代码中建立应用程序将在执行之前暂停的代码行。如果某个节点导致 DynamoRevit 崩溃或返回意外结果,则我们可以向节点的源代码添加断点以暂停该过程、单步执行代码并检查变量的实时值,直到找到问题的根源。
“单步调试代码” 会逐行遍历源代码。我们可以逐个运行函数、单步执行函数调用,或跳出当前正在执行的函数。
“调用堆栈” 会相对于涉及此函数调用的以前函数调用,显示进程当前正在运行的函数。Visual Studio 有一个“调用堆栈”窗口来显示此内容。例如,如果我们在源代码之外遇到异常,则我们可以在调用堆栈中查看调用代码的路径。
2,000 Things You Should Know About C# 对调用堆栈进行了更深入的说明。
当给定 PolyCurve 作为 “Wall.ByCurveAndHeight” 节点的曲线输入时,该节点会抛出异常,并显示消息:“未实现 BSPlineCurve”。通过调试,我们可以弄清楚节点不会接受此几何图形类型作为曲线参数的输入的确切原因。在本例中,我们假定 DynamoRevit 已成功构建,并可以作为 Revit 的附加模块运行。
Wall.ByCurveAndHeight 节点抛出异常
首先打开 DynamoRevit.All.sln
解决方案文件、启动 Revit,然后启动 DynamoRevit 附加模块。然后,使用 Attach to Process
窗口将 Visual Studio 附着到 Revit 进程。
Revit 和 DynamoRevit 需要运行才能显示为可用进程
通过选择
Debug > Attach to Process...
来打开Attach to Process
窗口将
Transport
设置为Default
选择
Revit.exe
选择
Attach
在将 Visual Studio 附着到 Revit 后,打开 Wall.cs
中的 Wall.ByCurveAndHeight 源代码。我们可以在“解决方案资源管理器”的 Libraries > RevitNodes > Elements
下的文件的 Public static constructors
区域中找到此内容。在墙类型的构造函数中设置断点,以便在 Dynamo 中执行节点时,该进程会中断,然后我们可以分别单步调试每行代码。通常,Dynamo Zero Touch 类型构造函数以 By<parameters>
开头。
具有 Wall.ByCurveAndHeight 构造函数的类文件
设置断点,方法是单击行号的左侧,或者在代码行上单击鼠标右键并选择
Breakpoint > Insert Breakpoint
。
在设置断点后,我们需要该进程运行穿过 Wall.ByCurveAndHeight 函数。通过将导线重新连接到 Dynamo 的一个端口(这将强制节点重新执行),可以在 Dynamo 中再次执行该函数。断点将在 Visual Studio 中命中。
断点图标会在断点命中后发生变化
显示下一个方法的“调用堆栈”窗口
现在,单步执行构造函数中的每一行,直到我们遇到异常。以黄色亮显的代码是要运行的下一条语句。
用于导航代码的调试工具
按
Step Over
以运行亮显的代码,然后在函数返回后暂停执行要运行的下一条语句由黄色亮显和箭头指示
如果我们继续单步调试该功能,我们将遇到在 DynamoRevit 窗口中显示的异常。在“调用堆栈”窗口中,我们可以看到异常最初抛出自名为 Autodesk.Revit.CurveAPIUtils.CreateNurbsCurve
的方法。值得庆幸的是,异常在此处得到处理,因此 Dynamo 未崩溃。调试过程通过将我们引入到源代码中的其他方法,来为问题提供上下文。
由于这不是一个开源库,因此我们无法在此处进行更改 - 由于我们有详细信息,因此我们可以通过填写 GitHub 问题来报告问题以及更多上下文,也可以针对此问题提出解决方案,以进行拉取请求。
当我们在
Walls.cs
中遇到导致异常的语句时,调试过程使我们尽可能接近ProtoToRevitCurve.cs
中用户代码中问题的根源在
ProtoToRevitCurve.cs
中导致异常的语句在调用堆栈中,我们可以看到异常来自非用户代码
一个为我们提供有关异常的信息的弹出窗口
此过程可应用于我们正在处理的任何源文件。如果我们正在为 Dynamo Studio 开发一个 Zero-Touch 节点库,则我们可以打开该库的源代码,然后附着一个 Dynamo 进程来调试节点库。即使一切正常,调试也是探索代码和了解工作原理的绝佳方法。
此过程与为 Dynamo 拉取更改几乎相同,但我们需要确保位于正确的分支上。使用 DynamoRevit 存储库中的 git branch
命令,可查看哪些分支在本地可用以及哪些分支当前已检出。
cd C:\Users\username\Documents\GitHub\DynamoRevit
将当前目录设置为 DynamoRevit 存储库。
git branch
确认我们位于正确的分支上,RC2.13.1_Revit2023
.
git pull origin RC2.13.1_Revit2023
从远程来源 RC2.13.1_Revit2023
分支拉取更改。
来源仅指向我们克隆的原始 URL。
例如,我们需要注意当前位于哪个分支上,以及要从哪个分支拉取,从而避免将更改从
RC2.13.1_Revit2023
拉取到Revit2018
中。
如从源代码构建 Dynamo 中所述,当我们准备好向 DynamoRevit 存储库提交更改时,我们可以按照 Dynamo 团队在“拉取请求”部分中提供的准则来创建拉取请求。
在 Visual Studio 项目启动并运行后,我们将介绍如何构建一个自定义节点来创建一个单元的矩形网格。尽管我们可以使用多个标准节点创建该矩形网格,但它是一个非常有用的工具,可轻松包含在 Zero-Touch 节点中。与网格线不同,单元可以围绕其中心点进行单元、查询其角顶点,或将其构建到面中。
本例将介绍创建 Zero-Touch 节点时需要注意的一些功能和概念。在我们构建自定义节点并将其添加到 Dynamo 中后,请确保查看“进一步了解 Zero-Touch”页面,以更深入地了解默认输入值、返回多个值、文档、对象、使用 Dynamo 几何类型和移植。
要开始构建网格节点,请创建一个新的 Visual Studio 类库项目。有关如何设置项目的深入介绍,请参见“快速入门”页面。
选择
Class Library
作为项目类型将项目命名为
CustomNodes
由于我们将要创建几何图形,因此我们需要参照相应的 NuGet 软件包。通过 Nuget 软件包管理器安装 ZeroTouchLibrary 软件包。对于 using Autodesk.DesignScript.Geometry;
语句而言,此软件包是必需的。
浏览 ZeroTouchLibrary 软件包
我们将要在 Dynamo Studio 的当前版本(即 1.3)中使用此节点。选择与此版本匹配的软件包版本。
请注意,我们还将类文件重命名为
Grids.cs
接下来,我们需要建立 RectangularGrid 方法将在其中运行的名称空间和类。在 Dynamo 中,该节点将根据方法和类名进行命名。我们尚不需要将该节点复制到 Visual Studio 中。
Autodesk.DesignScript.Geometry;
将参照创建列表时所需的 ZeroTouchLibrary 软件包System.Collections.Generic
中的 ProtoGeometry.dll
现在,我们可以添加用于绘制矩形的方法。类文件应如下所示,并可以复制到 Visual Studio 中。
如果项目看起来与此类似,请继续并尝试构建 .dll
。
选择“构建”>“构建解决方案”
检查项目的 bin
文件夹以查找 .dll
。在构建成功后,我们可以将 .dll
添加到 Dynamo 中。
Dynamo 库中的自定义 RectangularGrids 节点
画布上的自定义节点
用于将
.dll
添加到 Dynamo 中的“添加”按钮
在上例中,我们创建了一个非常简单的节点,该节点未定义 RectangularGrids
方法之外的太多其他内容。但是,我们可能要为输入端口创建工具提示,或者像标准 Dynamo 节点一样为该节点提供摘要。将这些功能添加到自定义节点会使其更易于使用,尤其是当用户要在库中搜索这些节点时。
默认输入值
xCount 输入的工具提示
RectangularGrid 节点需要其中的一些基本功能。在下面的代码中,我们添加了输入和输出端口描述、摘要和默认输入值。
通过为方法参数赋值,来为输入提供默认值:RectangularGrid(int xCount = 10, int yCount = 10)
创建输入和输出工具提示、搜索关键字以及前面带有 ///
的 XML 文档摘要。
要添加工具提示,我们需要在项目目录中有一个 xml 文件。通过启用该选项,.xml
可以由 Visual Studio 自动生成。
在此处启用 XML 文档文件,然后指定文件路径。这将生成一个 XML 文件。
大功告成!我们已创建了一个包含多个标准功能的新节点。以下“Zero-Touch 基础知识”章节将更详细地介绍 Zero-Touch 节点开发以及需要注意的问题。
在开始开发之前,请务必为新项目打下坚实基础。Dynamo 开发人员社区中的多个项目模板是绝佳的起点,但了解如何从头开始构建项目更有价值。通过从头开始构建项目,将能够更深入地了解开发过程。
Visual Studio 是一个功能强大的 IDE,我们可以在其中创建项目、添加参照、构建 .dlls
和调试。在创建新项目时,Visual Studio 还会创建一个解决方案,即用于组织项目的结构。多个项目可以存在于一个解决方案中,并可以一起构建。要创建 ZeroTouch 节点,我们需要开始一个新的 Visual Studio 项目,我们将在该项目中编写一个 C# 类库并构建一个 .dll
。
Visual Studio 中的“新建项目”窗口
首先打开 Visual Studio 并创建一个新项目:
File > New > Project
选择
Class Library
项目模板为项目命名(我们已将项目命名为“MyCustomNode”)
设置项目的文件路径。在本例中,我们将其保留在默认位置
选择
Ok
Visual Studio 将自动创建并打开一个 C# 文件。我们应为其指定一个合适名称、设置工作空间,并将默认代码替换为以下乘法方法。
从
View
打开“解决方案资源管理器”和“输出”窗口。在右侧的“解决方案资源管理器”中,将
Class1.cs
文件重命名为SampleFunctions.cs
。为乘法函数添加上述代码。我们稍后会介绍 Dynamo 将如何读取您的 C# 类的详情。
解决方案资源管理器:该资源管理器使您能够访问项目中的所有内容。
“输出”窗口:我们稍后会需要使用该窗口来查看构建是否已成功。
下一步是构建项目,但在构建之前,我们需要检查一些设置。首先,确保已选择 Any CPU
或 x64
作为平台目标,并确保在“项目特性”中未选中 Prefer 32-bit
。
通过选择
Project > "ProjectName" Properties
打开项目特性选择
Build
页面从下拉菜单中选择
Any CPU
或x64
确保未选中
Prefer 32-bit
现在,我们可以构建项目以创建 .dll
。要执行此操作,请从 Build
菜单中选择 Build Solution
,或使用快捷键 CTRL+SHIFT+B
。
选择
Build > Build Solution
可以通过检查“输出”窗口来确定您的项目是否已成功构建
如果项目已成功构建,则项目的 bin
文件夹中会有一个名为 MyCustomNode
的 .dll
。在本例中,我们已将项目的文件路径保留为 Visual Studio 的默认路径:c:\users\username\documents\visual studio 2015\Projects
。让我们来看一下项目的文件结构。
bin
文件夹包含从 Visual Studio 构建的.dll
。Visual Studio 项目文件。
类文件。
由于我们的解决方案配置已设置为
Debug
,因此将在bin\Debug
中创建.dll
。
现在,我们可以打开 Dynamo 并输入 .dll
。使用“添加”功能时,导航到项目的 bin
位置,然后选择要打开的 .dll
。
选择“添加”按钮以输入
.dll
浏览到项目位置。我们的项目位于 Visual Studio 的默认文件路径:
C:\Users\username\Documents\Visual Studio 2015\Projects\MyCustomNode
选择要输入的
MyCustomNode.dll
单击
Open
以载入.dll
如果在名为 MyCustomNode
的库中创建了一个类别,则表示 .dll 已成功输入!但是,Dynamo 创建了两个节点,而我们希望这两个节点成为单个节点。在下一节中,我们将解释发生这种情况的原因,以及 Dynamo 读取 .dll 的方式。
Dynamo 库中的 MyCustomNode。“库”类别由
.dll
名称确定。画布上的 SampleFunctions.MultiplyByTwo。
在 Dynamo 载入 .dll 后,它会将所有公有静态方法显示为节点。构造函数、方法和特性将分别转换为 Create、Action 和 Query 节点。在我们的乘法示例中,MultiplyByTwo()
方法会在 Dynamo 中成为 Action 节点。这是因为节点已根据其方法和类进行命名。
根据方法的参数名称,输入命名为
inputNumber
。输出默认命名为
double
,因为这是要返回的数据类型。节点命名为
SampleFunctions.MultiplyByTwo
,因为这些是类和方法名称。
在上面的示例中,创建了额外的 SampleFunctions
Create 节点,因为我们没有显式地提供构造函数,因此自动创建了一个构造函数。我们可以通过在 SampleFunctions
类中创建一个空的私有构造函数,来避免出现这种情况。
Dynamo 已将我们的方法输入为 Create 节点
乘法节点非常简单,不需要参照 Dynamo。例如,如果我们要访问 Dynamo 的任何功能来创建几何图形,则我们需要参照 Dynamo NuGet 软件包。
ZeroTouchLibrary - 用于为 Dynamo 构建 Zero Touch 节点库的软件包,其中包含以下库:DynamoUnits.dll、ProtoGeometry.dll
WpfUILibrary - 用于为在 WPF 中有自定义 UI 的 Dynamo 构建节点库的软件包,其中包含以下库:DynamoCoreWpf.dll、CoreNodeModels.dll、CoreNodeModelWpf.dll
DynamoServices - Dynamo 的 DynamoServices 库
核心 - Dynamo 的单位和系统测试基础结构,其中包含以下库:DSIronPython.dll、DynamoApplications.dll、DynamoCore.dll、DynamoInstallDetective.dll、DynamoShapeManager.dll、DynamoUtilities.dll、ProtoCore.dll、VMDataBridge.dll
测试 - Dynamo 的单位和系统测试基础结构,其中包含以下库:DynamoCoreTests.dll、SystemTestServices.dll、TestServices.dll
DynamoCoreNodes - 用于为 Dynamo 构建核心节点的软件包,其中包含以下库:Analysis.dll、GeometryColor.dll、DSCoreNodes.dll
要在 Visual Studio 项目中参照这些软件包,请通过上述链接从 NuGet 中下载软件包并手动参照 .dll,或者在 Visual Studio 中使用 NuGet 软件包管理器。首先,我们可以漫游如何在 Visual Studio 中使用 NuGet 安装它们。
通过选择
Tools > NuGet Package Manager > Manage NuGet Packages for Solution...
来打开 NuGet 软件包管理器
这是 NuGet 软件包管理器。此窗口会显示已为项目安装的软件包,并允许用户浏览其他软件包。如果发布了新版本的 DynamoServices 软件包,则可以从此处更新软件包或将其恢复为早期版本。
选择“浏览并搜索 DynamoVisualProgramming”以显示 Dynamo 软件包。
Dynamo 软件包。选择一个软件包即会显示其当前版本,以及内部内容的描述。
选择所需的软件包版本,然后单击“安装”。这将为您要处理的特定项目安装一个软件包。由于我们使用的是 Dynamo 的最新稳定版本 1.3,因此请选择相应的软件包版本。
要手动添加从浏览器下载的软件包,请从“解决方案资源管理器”打开“参照管理器”,然后浏览到该软件包。
在
References
上单击鼠标右键,然后选择Add Reference
。选择
Browse
以导航到软件包位置。
现在,Visual Studio 已正确配置,并且我们已成功将 .dll
添加到 Dynamo,这样我们就为后续概念奠定了坚实基础。这仅仅是一个开始,因此请继续学习,以详细了解如何创建自定义节点。
本手册的目的是帮助您了解 Dynamo 的 C# 开发可能性范围,从如何创建 Zero-Touch 节点到构建扩展。
GitHub 上的 Dynamo 源代码
Dynamo:下载 Dynamo 的最新稳定内部版和每日内部版
Dynamo GitHub:Dynamo 是 GitHub 上的开源开发项目。
https://github.com/DynamoDS/Dynamo
Dynamo GitHub WiKi:这一直是开发人员文档的主要资源。
https://github.com/DynamoDS/Dynamo/wiki
“节点命名标准” 提供了在 Dynamo 中命名类别、节点以及输入和输出端口的标准和准则。
https://github.com/DynamoDS/Dynamo/wiki/Naming-Standards
Dynamo 语言/API 手册:Dynamo 的 API 文档目前涵盖了核心功能
https://dynamods.github.io/DynamoAPI/
“DynamoBIM” 获取其他信息、学习内容和论坛的最佳来源是 DynamoBIM 网站。
“Dynamo 字典” 所有 Dynamo 节点的可搜索数据库
https://dictionary.dynamobim.com/
“DesignScript 语言手册” 编写 DesignScript 的 PDF 手册
本文档可以吸纳建议。可以直接在 GitHub 中通过创建更改请求,来实现这些更改。
Dynamo 的源代码托管在 GitHub 上,可供任何人克隆并参与修改。在这一章中,我们将漫游如何使用 git 克隆存储库、使用 Visual Studio 编译源文件、运行和调试本地构建,以及从 GitHub 中拉取任何新更改。
GitHub 是一种基于 Git 的托管服务,它是一个版本控制系统,可用于跟踪更改并协调用户之间的工作。Git 是一种工具,我们可以利用它来下载 Dynamo 的源文件,并可以通过几条命令来保持更新这些源文件。通过使用此方法,将避免每次更新时下载和手动替换源文件这一不必要的固有混乱工作。Git 版本控制系统将跟踪本地和远程代码存储库之间的任何差异。
Dynamo 的源代码托管在 DynamoDS GitHub 上的以下存储库中:https://github.com/DynamoDS/Dynamo
Dynamo 源文件。
克隆或下载整个存储库
查看其他 DynamoDS 存储库
Dynamo 的源文件
Git 特定文件
在可以克隆存储库之前,我们需要先安装 Git。请跟随此简短手册来了解安装步骤,以及如何设置 gihub 用户名和电子邮件地址。在本例中,我们将在命令行中使用 Git。本手册假定您将使用的是 Windows,但也可以在 Mac 或 Linux 中使用 Git 来克隆 Dynamo 源代码。
我们需要一个 Dynamo 存储库的 URL,以通过其进行克隆。这可以在存储库页面上的“克隆或下载”按钮中找到。复制要粘贴到命令提示中的 URL。
选择“Clone or download”
复制 URL
在完成安装 Git 后,我们就可以克隆 Dynamo 库。首先打开命令提示。然后,使用更改目录命令 cd
,以导航到要将源文件克隆到的目标文件夹。在本例中,我们在 Documents
中已创建了一个名为 Github
的文件夹。
cd C:\Users\username\Documents\GitHub
将“username”替换为您的用户名
在下一步中,我们将运行一个 git 命令,以将 Dynamo 存储库克隆到我们指定的位置。通过单击 GitHub 上的“克隆或下载”按钮,可获取命令中的 URL。在命令终端中运行此命令。请注意,这将克隆 Dynamo 存储库主分支(它是 Dynamo 的最新代码),并将包含到最新版本的 Dynamo 代码。此分支每天都会发生变化。
git clone https://github.com/DynamoDS/Dynamo.git
如果克隆操作成功完成,则我们知道 Git 工作正常。在文件资源管理器中,导航到克隆的目录以查看源文件。目录结构看起来应与 GitHub 上 Dynamo 存储库的主分支相同。
Dynamo 的源文件
Git 文件
在源文件现已克隆到我们的本地计算机后,我们可以为 Dynamo 构建可执行文件。为此,我们需要设置 Visual Studio IDE,并确保已安装 .NET Framework 和 DirectX。
下载并安装 Microsoft Visual Studio Community 2015,这是一个功能齐全的免费 IDE(集成开发环境 - 更高版本也可以使用)
下载并安装 Microsoft .NET Framework 4.5 或更高版本
从本地 Dynamo 存储库 (Dynamo\tools\install\Extra\DirectX\DXSETUP.exe
) 安装 Microsoft DirectX
可能已安装 .NET 和 DirectX。
在完成所有安装后,我们就可以启动 Visual Studio,然后打开位于 Dynamo\src
中的 Dynamo.All.sln
解决方案。
选择
File > Open > Project/Solution
浏览到 Dynamo 库并打开
src
文件夹选择
Dynamo.All.sln
解决方案文件选择
Open
在可以构建解决方案之前,应先指定一些设置。我们应该先构建调试版本的 Dynamo,以便 Visual Studio 可以在调试期间收集更多信息来帮助我们开发,并且我们希望以 AnyCPU 为目标。
这些将成为
bin
文件夹内的文件夹
在本例中,我们选择
Debug
作为解决方案配置将解决方案平台设置为
Any CPU
在项目打开后,我们可以构建解决方案。此过程将创建一个我们可以运行的 DynamoSandbox.exe 文件。
通过构建项目,将恢复 NuGet 依存关系。
选择
Build > Build Solution
在“输出”窗口中确认构建是否已成功,其内容应类似于
==== Build: 69 succeeded, 0 failed, 0 up-to-date, 0 skipped ====
如果 Dynamo 构建成功,则会在 Dynamo 存储库中创建一个 bin
文件夹,其中包含 DynamoSandbox.exe 文件。在我们的案例中,我们使用“调试”选项进行构建,因此可执行文件位于 bin\AnyCPU\Debug
中。运行此文件会打开 Dynamo 的本地构建。
我们刚刚构建的 DynamoSandbox 可执行文件。运行此文件以启动 Dynamo。
现在,我们几乎已完全准备好开始为 Dynamo 开发。
有关为其他平台(例如,Linux 或 OS X)构建 Dynamo 的说明,请访问此 Wiki 页面。
调试是一个识别、隔离和更正错误或问题的过程。在从源代码成功构建 Dynamo 后,我们可以使用 Visual Studio 中的多款工具来调试正在运行的应用程序(例如,DynamoRevit 附加模块)。我们可以分析它的源代码来查找问题的根源,也可以观察当前正在执行的代码。有关如何在 Visual Studio 中调试和导览代码的更详细说明,请参见 Visual Studio 文档。
对于单机版 Dynamo 应用程序 DynamoSandbox,我们会介绍两个用于调试的选项:
直接从 Visual Studio 构建并启动 Dynamo
将 Visual Studio 附加到正在运行的 Dynamo 进程
如果需要,从 Visual Studio 启动 Dynamo 会为每个调试会话重新构建解决方案;因此,如果我们对源代码进行更改,则在调试时将合并这些更改。在 Dynamo.All.sln
解决方案仍打开的情况下,从下拉菜单中选择 Debug
、AnyCPU
和 DynamoSandbox
,然后单击 Start
。这将构建 Dynamo 并启动一个新进程 (DynamoSandbox.exe),然后将 Visual Studio 的调试器附加到该进程。
直接从 Visual Studio 构建和启动应用程序
将配置设置为
Debug
将平台设置为
Any CPU
将启动项目设置为
DynamoSandbox
单击
Start
以开始调试过程
或者,我们可能希望调试已在运行的 Dynamo 进程,以解决特定图形打开或打包的问题。为此,我们将在 Visual Studio 中打开项目的源文件,然后使用 Attach to Process
调试菜单项附加到正在运行的 Dynamo 进程。
将正在运行的进程附加到 Visual Studio
选择
Debug > Attach to Process...
选择
DynamoSandbox.exe
选择
Attach
在这两种情况下,我们都会将调试器附加到要调试的进程。我们可以在启动调试器之前或之后在代码中设置断点,这将导致进程在执行该行代码之前立即暂停。如果在调试期间引发未捕获的异常,则 Visual Studio 会跳转到源代码中发生异常的位置。这是一种用于查找简单崩溃、未处理的异常以及了解应用程序执行流的有效方法。
在调试 DynamoSandbox 期间,我们在 Color.ByARGB 节点的构造函数中设置一个断点,这会导致 Dynamo 进程在节点实例化时暂停。如果此节点抛出异常或导致 Dynamo 崩溃,则我们可以单步调试构造函数中的每一行,以查找出现问题的位置。
断点
显示当前正在执行的函数和以前的函数调用的调用堆栈。
在下一节(从源代码构建 DynamoRevit)中,我们将漫游一个特定的调试示例,并说明如何设置断点、单步调试代码和读取调用堆栈。
由于 Dynamo 源代码托管在 GitHub 上,因此保持更新本地源文件的最简单方法是使用 Git 命令拉取更改。
使用命令行,将当前目录设置为 Dynamo 存储库:
cd C:\Users\username\Documents\GitHub\Dynamo
将
"username"
替换为您的用户名
使用以下命令,可拉取最新更改:
git pull origin master
在此处,我们可以看到本地存储库已使用远程存储库中的更改进行了更新。
除了拉取更新外,还有四个 Git 工作流需要熟悉。
分叉 Dynamo 存储库,以创建一个独立于原始存储库的副本。此处所做的任何更改都不会影响原始存储库,并且可以使用拉取请求来获取或提交更新。分叉不是一个 Git 命令,而是 GitHub 添加的一个工作流 - 分叉、拉取请求模型是用于在线参与开源项目的最常见工作流之一。如果您要参与 Dynamo,它是值得学习的。
分支 - 与分支中的其他工作隔离的实验工作或新功能。这使发送拉取请求更容易。
在完成一个工作单元之后和在可能需要撤消的更改之后,经常进行提交。提交会记录对存储库的更改,并将在向主 Dynamo 存储库发出拉取请求时可见。
当更改准备好正式提交给主 Dynamo 存储库时,创建拉取请求。
Dynamo 团队会提供有关创建拉取请求的具体说明。请参见本文档中的“拉取请求”部分,以了解要解决的更详细项目。
有关 Git 命令的参照列表,请参见此文档页面。
无论用户的经验水平如何,Dynamo 平台是专为所有用户设计的,旨在使他们都能够成为参与者。有多个针对不同能力和技能水平的开发选项,每个选项都有其优势和劣势,具体取决于目标。下面,我们将概述不同的选项以及如何选择其中一个。
三种开发环境:Visual Studio、Python 编辑器和代码块 DesignScript
Dynamo 的开发选项主要分为两类:for(面向)Dynamo 与 in(使用)Dynamo。可以将这两个类别视为如下所述:“in”Dynamo 表示使用 Dynamo IDE 创建要在 Dynamo 中使用的内容,而“for”Dynamo 表示使用外部工具创建要输入到 Dynamo 中以供使用的内容。尽管本手册重点介绍 for Dynamo 开发,但下面介绍了适用于所有过程的资源。
这些节点允许最高程度的自定义。许多软件包都是使用此方法构建的,它对于参与 Dynamo 的源代码而言必不可少。本手册将介绍构建这些软件包的过程。
Zero-Touch 节点
NodeModel 派生节点
扩展
本 Primer 提供了有关输入 Zero-Touch 库的指南。
在下面的讨论中,Visual Studio 将用作 Zero-Touch 和 NodeModel 节点的开发环境。
我们将要开发的项目的 Visual Studio 界面
尽管这些过程存在于可视化编程工作空间中并且相对简单,但它们都是用于自定义 Dynamo 的可行选项。本 Primer 涵盖了这些内容,并在脚本编写策略一章中提供了脚本编写技巧和最佳实践。
代码块会在可视化编程环境中显示 DesignScript,从而支持灵活的文本脚本和节点工作流。代码块中的函数可由工作空间中的任何对象调用。
下载代码块示例(单击鼠标右键,然后单击“另存为”),或在 Primer 中查看详细漫游。
自定义节点是节点集合甚至整个图形的容器。它们是收集常用例程并与社区共享这些例程的有效方式。
下载自定义节点示例(单击鼠标右键,然后单击“另存为”),或在 Primer 中查看详细漫游。
Python 节点是可视化编程工作空间中的脚本接口,类似于代码块。Autodesk.DesignScript 库使用与 DesignScript 类似的点表示法。
下载 Python 节点示例(单击鼠标右键,然后单击“另存为”),或在 Primer 中查看详细漫游。
在 Dynamo 工作空间中开发是获得即时反馈的强大工具。
在 Dynamo 工作空间中使用 Python 节点开发
Dynamo 的开发选项旨在解决自定义需求的复杂性。无论目标是在 Python 中编写递归脚本还是构建完全自定义的节点 UI,都有一些选项可用于实现仅涉及启动和运行所需内容的代码。
Dynamo 中的代码块、Python 节点和自定义节点
这些都是用于在 Dynamo 可视化编程环境中编写代码的简单选项。通过 Dynamo 可视化编程工作空间,可访问 Python、DesignScript,还可以在自定义节点内包含多个节点。
使用这些方法,我们可以:
开始编写 Python 或 DesignScript,而几乎无需设置。
将 Python 库输入到 Dynamo 中。
将代码块、Python 节点和自定义节点作为软件包的一部分与 Dynamo 社区共享。
Zero-Touch 节点
“Zero-Touch”是指一种用于输入 C# 库的简单点击方法。Dynamo 将读取 .dll
的公有方法,并将这些方法转换为 Dynamo 节点。可以使用 Zero-Touch 来开发您自己的自定义节点和软件包。
使用此方法,我们可以:
输入一个不一定是为 Dynamo 开发的库,并自动创建一组新节点(如本 Primer 中的 A-Forge 示例)
编写 C# 方法,并在 Dynamo 中轻松将这些方法用作节点
通过软件包将 C# 库作为节点与 Dynamo 社区共享
NodeModel 派生节点
通过这些节点,可以更深入地了解 Dynamo 的结构。它们基于 NodeModel
类,并使用 C# 编写。尽管此方法提供了最大的灵活性和强大功能,但节点的大多数方面都必须明确定义,并且函数需要位于单独的程序集中。
使用此方法,我们可以:
使用滑块、图像、颜色等创建完全可自定义的节点 UI(例如 ColorRange 节点)
访问并影响 Dynamo 画布中发生的情况
自定义连缀
作为软件包载入到 Dynamo 中
由于 Dynamo 会定期更新,因此可能会对软件包使用的 API 的一部分进行更改。跟踪这些更改对于确保现有软件包继续正常工作而言非常重要。
API 更改是在 Dynamo Github Wiki 上进行跟踪的。这包括对 DynamoCore、库和工作空间的更改。
举例来说,2.0 版中即将发生的重大更改是从 XML 文件格式转换为 JSON 文件格式。NodeModel 派生节点现在需要 JSON 构造函数,否则它们将无法在 Dynamo 2.0 中打开。
Dynamo 的 API 文档目前涵盖了核心功能:http://dynamods.github.io/DynamoAPI
请注意,.dll 包含在要上传到软件包管理器的软件包中。如果软件包作者未创建 .dll,则他们必须有权共享它。
如果软件包包含二进制文件,则在下载时必须提示用户该软件包包含二进制文件。
如果您愿意使用 Python 编写脚本,并希望从标准 Dynamo Python 节点中获取更多功能,我们可以使用 Zero-Touch 创建自己的节点。让我们从一个简单示例开始,它允许我们将 Python 脚本作为字符串传递给 Zero-Touch 节点,在该节点中执行脚本并返回结果。本案例研究将建立在“快速入门”部分中的漫游和示例的基础上;如果您对创建 Zero-Touch 节点完全不熟悉,请参见这些漫游和示例。
将执行 Python 脚本字符串的 Zero-Touch 节点
此节点依赖于 IronPython 脚本引擎的实例。为此,我们需要参照一些其他程序集。按照以下步骤操作,以在 Visual Studio 中设置基本模板:
创建新的 Visual Studio 类项目
添加对 C:\Program Files (x86)\IronPython 2.7\IronPython.dll
中 IronPython.dll
的参照
添加对 C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\Microsoft.Scripting.dll
中 Microsoft.Scripting.dll
的参照
在类中包含 IronPython.Hosting
和 Microsoft.Scripting.Hosting
using
语句
添加一个私有的空构造函数,以防止将其他节点随软件包一起添加到 Dynamo 库中
创建一个将单个字符串作为输入参数的新方法
在此方法中,我们将实例化一个新的 Python 引擎,并创建一个空的脚本作用域。可以将此作用域想象为 Python 解释器实例中的全局变量
接下来,在引擎上调用 Execute
,以将输入字符串和作用域作为参数传递
最后,通过在作用域上调用 GetVariable
并传递 Python 脚本中包含要返回的值的变量的名称,来检索并返回脚本的结果。(有关更多详细信息,请参见下面的示例)
以下代码提供了上述步骤的示例。构建解决方案将在项目的 bin 文件夹中创建一个新的 .dll
。现在,此 .dll
可以作为软件包的一部分或通过导航到 File < Import Library...
以输入到 Dynamo 中
Python 脚本将返回变量 output
,这意味着我们在 Python 脚本中需要一个 output
变量。使用此样例脚本以在 Dynamo 中测试节点。如果您曾在 Dynamo 中使用过 Python 节点,则以下内容应该很熟悉。有关详细信息,请查看入门手册的 Python 部分。
标准 Python 节点的一个限制是它们只有一个输出端口;因此,如果我们要返回多个对象,我们必须构造一个列表并检索其中的每个对象。如果我们修改上面的示例以返回字典,则我们可以根据需要添加许多输出端口。有关字典的更多详细信息,请参见“进一步了解 Zero-Touch”中的“返回多个值”部分。
此节点允许我们返回立方体的体积及其质心。
让我们通过以下步骤来修改前面的示例:
通过 NuGet 软件包管理器添加对 DynamoServices.dll
的参照
除了以前的程序集外,还包括 System.Collections.Generic
和 Autodesk.DesignScript.Runtime
修改我们方法的返回类型以返回一个包含我们输出的字典
必须从作用域中单独检索每个输出(考虑为较大的输出集设置一个简单的循环)
我们还向样例 Python 脚本添加了一个额外输出变量 (output2
)。请记住,这些变量可以使用任何合法的 Python 命名约定;为了清晰起见,在本例中已严格使用输出。
软件包是一种用于存储节点并与 Dynamo 社区共享节点的便捷方式。软件包可以包含从在 Dynamo 工作空间中创建的自定义节点到 NodeModel 派生节点等的所有内容。发布和安装软件包使用的是软件包管理器。除了此页面,Primer 还提供了有关软件包的常规手册。
Dynamo Package Manager 是一个软件注册表(类似于 npm),可以从 Dynamo 或 Web 浏览器中访问。软件包管理器包括安装、发布、更新和查看软件包。与 npm 一样,它会维护不同版本的软件包。它还有助于管理项目的依赖关系。
在浏览器中,搜索软件包并查看统计信息:https://dynamopackages.com/
在 Dynamo 中,软件包管理器包括安装、发布和更新软件包。
联机搜索软件包:
Packages > Search for a Package...
查看/编辑已安装的软件包:
Packages > Manage Packages...
发布新软件包:
Packages > Publish New Package...
软件包是从 Dynamo 内的软件包管理器发布的。建议的过程是本地发布、测试软件包,然后联机发布以与社区共享。通过使用 NodeModel 案例研究,我们将完成本地发布 RectangularGrid 节点为软件包和联机发布的必要步骤。
启动 Dynamo,然后选择 Packages > Publish New Package...
以打开 Publish a Package
窗口。
选择
Add file...
以浏览要添加到软件包的文件从 NodeModel 案例研究中选择两个
.dll
文件选择
Ok
在将文件添加到软件包内容中后,为软件包指定名称、描述和版本。使用 Dynamo 发布软件包会自动创建 pkg.json
文件。
准备好发布的软件包。
提供所需的名称、描述和版本信息。
通过单击“本地发布”进行发布,然后选择 Dynamo 的软件包文件夹“
AppData\Roaming\Dynamo\Dynamo Core\1.3\packages
”以使节点在核心中可用。始终本地发布,直到软件包准备好共享。
发布软件包后,节点将在 Dynamo 库中的 CustomNodeModel
类别下可用。
我们刚刚在 Dynamo 库中创建的软件包
在软件包准备好联机发布后,打开软件包管理器、选择 Publish
,然后选择 Publish Online
。
要查看 Dynamo 如何设置软件包的格式,请单击“CustomNodeModel”右侧的三个垂直点,然后选择“显示根目录”
在“发布 Dynamo 软件包”窗口中,选择
Publish
,然后选择Publish Online
。要删除软件包,请选择
Delete
。
更新软件包的过程与发布过程类似。打开软件包管理器、在需要更新的软件包上选择 Publish Version...
,然后输入更高版本。
选择
Publish Version
以使用根目录中的新文件更新现有软件包,然后选择它应本地发布还是联机发布。
软件包管理器 Web 客户端专用于搜索和查看软件包数据,例如版本控制和下载统计信息。
可以通过以下链接访问软件包管理器 Web 客户端:https://dynamopackages.com/
如果要开发要发布为 Dynamo 软件包的程序集,可以将项目配置为对所有必需资源进行分组,并将其放置在与软件包兼容的目录结构中。这将使项目能够作为软件包快速进行测试,并模拟用户体验。
在 Visual Studio 中构建软件包有两种方法:
通过“项目设置”对话框,添加使用 xcopy 或 Python 脚本复制必需文件的构建后事件
在 .csproj
文件中,使用“AfterBuild”构建目标来创建文件和目录复制任务
由于“AfterBuild”不依赖于可能在构建计算机上不可用的文件复制操作,因此“AfterBuild”是这些类型操作(以及本手册中介绍的操作)的首选方法。
在储存库中设置目录结构,以使源文件与软件包文件分开。使用 CustomNodeModel 案例研究时,将 Visual Studio 项目和所有关联文件放置到新的 src
文件夹中。您会将项目生成的所有软件包都存储在此文件夹中。文件夹结构现在应如下所示:
将项目文件移动到新的
src
文件夹
由于源文件位于单独的文件夹中,因此在 Visual Studio 中将 AfterBuild
目标添加到 CustomNodeModel.csproj
文件。这应该会将必需文件复制到新的软件包文件夹中。在文本编辑器(我们使用的是 Atom)中,打开 CustomNodeModel.csproj
文件,然后在结束标记 </Project>
之前放置构建目标。此 AfterBuild 目标会将所有 .dll、.pbd、.xml 和 .config 文件复制到新的 bin 文件夹中,并创建 dyf 文件夹和 extra 文件夹。
我们需要确保目标已添加到
CustomNodeModel.csproj
文件(而非其他项目文件)中,并确保项目没有任何现有的“构建后”设置。
将 AfterBuild 目标放置在结束标记
</Project>
之前。
在 <ItemGroup>
部分中,定义了许多变量来表示特定的文件类型。例如,Dll
变量表示输出目录中扩展名为 .dll
的所有文件。
Copy
任务是将所有 .dll
文件复制到某个目录,尤其是我们要构建到的软件包文件夹。
Dynamo 软件包通常有 dyf
和 extra
文件夹,用于 Dynamo 自定义节点和其他资源(如图像)。要创建这些文件夹,我们需要使用 MakeDir
任务。如果某个文件夹不存在,则此任务会创建该文件夹。可以手动将文件添加到此文件夹。
如果您构建项目,则项目文件夹现在应该有 packages
文件夹以及之前创建的 src
文件夹。packages
目录内是一个文件夹,其中包含软件包所需的所有内容。我们还需要将 pkg.json
文件复制到软件包文件夹中,以使 Dynamo 知道要载入软件包。
AfterBuild 目标创建的新软件包文件夹
项目的现有 src 文件夹
从 AfterBuild 目标创建的
dyf
和extra
文件夹手动复制
pkg.json
文件。
现在,可以使用 Dynamo 的软件包管理器发布软件包,也可以直接将软件包复制到 Dynamo 的软件包目录:<user>\AppData\Roaming\Dynamo\1.3\packages
。
在了解如何创建 Zero-Touch 项目后,我们可以通过浏览 Dynamo Github 中的 ZeroTouchEssentials 示例,来更深入地了解创建节点的具体细节。
Dynamo 的许多标准节点本质上都是 Zero-Touch 节点,就像上面的大多数 Math、Color 和 DateTime 节点一样。
首先,从以下位置下载 ZeroTouchEssentials 项目:https://github.com/DynamoDS/ZeroTouchEssentials
在 Visual Studio 中,打开 ZeroTouchEssentials.sln
解决方案文件并构建解决方案。
ZeroTouchEssentials.cs
文件包含我们将要输入到 Dynamo 中的所有方法。
打开 Dynamo 并输入 ZeroTouchEssentials.dll
,以获取我们将要在以下示例中参照的节点。
代码示例拉取自 ZeroTouchEssentials.cs,通常与之匹配。为了保持简洁,已删除 XML 文档;每个代码示例都会在其上方的图像中创建节点。
Dynamo 支持为节点上的输入端口定义默认值。如果端口没有连接,则这些默认值会提供给节点。默认值是使用《C# 编程手册》中指定可选参数的 C# 机制来表示的。通过以下方式指定默认值:
将方法参数设置为默认值:inputNumber = 2.0
将光标悬停在节点输入端口上方时,即会显示默认值
返回多个值比创建多个输入要复杂得多,并且需要使用字典返回。字典的条目会成为节点输出端的端口。通过以下方式创建多个返回端口:
添加 using System.Collections.Generic;
以使用 Dictionary<>
。
添加 using Autodesk.DesignScript.Runtime;
以使用 MultiReturn
属性。这会参照 DynamoServices NuGet 软件包中的“DynamoServices.dll”。
将 [MultiReturn(new[] { "string1", "string2", ... more strings here })]
属性添加到方法。这些字符串会引用字典中的键,并会成为输出端口名称。
从函数返回 Dictionary<>
,其中包含与属性中的参数名称匹配的键:return new Dictionary<string, object>
请参见 ZeroTouchEssentials.cs 中的此代码示例
返回多个输出的节点。
请注意,现在有两个输出端口,它们是根据我们为字典的键输入的字符串命名的。
最佳做法是向 Dynamo 节点添加描述节点的功能、输入、输出、搜索标记等的文档。这是通过 XML 文档标记实现的。通过以下方式创建 XML 文档:
任何前面带有三个正斜杠的注释文字都会被视为文档
例如:/// Documentation text and XML goes here
在三个斜杠之后,在 Dynamo 输入 .dll 时将读取的方法上方创建 XML 标记
例如:/// <summary>...</summary>
在 Visual Studio 中,通过选择 Project > Project Properties > Build
并选中 XML documentation file
来启用 XML 文档
Visual Studio 将在指定位置处生成 XML 文件
标记的类型如下所示:
/// <summary>...</summary>
是节点的主文档,将在左侧搜索栏中作为工具提示显示在节点上方
/// <param name="inputName">...</param>
将为特定输入参数创建文档
/// <returns>...</returns>
将为输出参数创建文档
/// <returns name = "outputName">...</returns>
将为多个输出参数创建文档
/// <search>...</search>
将根据逗号分隔的列表将您的节点与搜索结果匹配。例如,如果我们创建一个细分网格的节点,则我们可能需要添加诸如“mesh”、“subdivision”和“catmull-clark”之类的标记。
以下是一个示例节点,其中包含输入和输出描述,以及将在库中显示的摘要。
请参见 ZeroTouchEssentials.cs 中的此代码示例
请注意,此示例节点的代码包含:
节点摘要
输入描述
输出描述
Dynamo 没有 new
关键字,因此需要使用静态构造方法来构造对象。通过以下方式构造对象:
除非另有要求,否则使构造函数成为内部构造函数 internal ZeroTouchEssentials()
使用静态方法构造对象,例如 public static ZeroTouchEssentials ByTwoDoubles(a, b)
注意:Dynamo 使用“By”前缀来指示静态方法是构造函数;尽管这是可选方法,但使用“By”将帮助您的库更好地适应现有 Dynamo 样式。
请参见 ZeroTouchEssentials.cs 中的此代码示例
在已输入 ZeroTouchEssentials dll 后,库中会有一个 ZeroTouchEssentials 节点。可以使用 ByTwoDoubles
节点创建此对象。
Dynamo 库可以使用原生 Dynamo 几何图形类型作为输入,并创建新的几何图形作为输出。通过以下方式创建几何图形类型:
通过在 C# 文件顶部包含 using Autodesk.DesignScript.Geometry;
并将 ZeroTouchLibrary NuGet 软件包添加到项目中,可参照项目中的“ProtoGeometry.dll”。
重要信息: 管理未从函数中返回的几何图形资源,请参见下面的 Dispose/using 语句部分。
注意:Dynamo 几何图形对象与传递给函数的任何其他对象一样使用。
请参见 ZeroTouchEssentials.cs 中的此代码示例
获取曲线长度并使其加倍的节点。
此节点接受曲线几何图形类型作为输入。
除非您使用的是 Dynamo 2.5 版或更高版本,否则不会从函数中返回的几何图形资源需要进行手动管理。在 Dynamo 2.5 及更高版本中,几何图形资源由系统进行内部处理;但是,如果您有复杂的用例,或者您必须在确定时间减少内存,则可能仍需要手动处理几何图形。Dynamo 引擎将处理从函数中返回的任何几何图形资源。可以通过以下方式手动处理未返回的几何图形资源:
使用手动 Dispose 调用:
发布库的较新版本时,节点名称可能会更改。可以在移植文件中指定名称更改,以便在完成更新后,基于库的以前版本构建的图形可以继续正常使用。通过以下方式实现移植:
在与 .dll
所在的同一个文件夹中创建 .xml
文件,其格式如下所示:"BaseDLLName".Migrations.xml
在 .xml
中,创建单个 <migrations>...</migrations>
元素
在移植元素内,为每个名称更改创建 <priorNameHint>...</priorNameHint>
元素
对于每个名称更改,请提供 <oldName>...</oldName>
和 <newName>...</newName>
元素
单击鼠标右键,然后选择
Add > New Item
选择
XML File
对于此项目,我们会将移植文件命名为
ZeroTouchEssentials.Migrations.xml
此示例代码会告知 Dynamo,任何名为 GetClosestPoint
的节点现在都已命名为 ClosestPointTo
。
请参见 ProtoGeometry.Migrations.xml 中的此代码示例
Zero-Touch 当前不支持使用泛型。可以使用这些泛型,但无法在直接输入且未设置类型的代码中使用它们。不能公开属于泛型且未设置类型的方法、特性或类。
在下面的示例中,将不会输入类型为 T
的 Zero-Touch 节点。如果库的其余部分输入到 Dynamo 中,则会出现丢失的类型异常。
使用在本例中所设置类型的泛型类型将输入到 Dynamo 中。
Dynamo 2.0 是一个主要版本,一些 API 已更改或已删除。将影响节点和软件包作者的最大更改之一是我们转为使用 JSON 文件格式。
通常,Zero Touch 节点作者几乎无需进行任何操作,即可在 2.0 中运行其软件包。
UI 节点和直接从 NodeModel 派生的节点需要进行更多操作才能在 2.x 中运行。
扩展作者可能还要进行一些潜在更改,具体取决于他们在其扩展中使用的 Dynamo 核心 API 数量。
请勿将 Dynamo 或 Dynamo Revit .dll 与软件包捆绑在一起。这些 dll 会由 Dynamo 进行载入。如果捆绑的版本不同于用户已载入的版本 (即,您分发 Dynamo Core 1.3,但用户运行的是基于 Dynamo 2.0 的软件包),则会发生意外运行时错误。这包括诸如 DynamoCore.dll
、DynamoServices.dll
、DSCodeNodes.dll
、ProtoGeometry.dll
之类的 dll
如果可以避免,请勿将 newtonsoft.json.net
与软件包捆绑在一起并分发。此 dll 也将由 Dynamo 2.x 载入。可能会出现与上述相同的问题。
如果可以避免,请勿将 CEFSharp
与软件包捆绑在一起并分发。此 dll 也将由 Dynamo 2.x 载入。可能会出现与上述相同的问题。
通常,如果需要控制依存关系的版本,请避免将该依存关系与 Dynamo 或 Revit 共享。
1) 打开图形时,一些节点有多个同名端口,但图形在保存时看起来正常。此问题可能有几个原因。
常见的根本原因是,节点是使用重新创建端口的构造函数创建的。反之,应使用已载入端口的构造函数。这些构造函数通常标记为 [JsonConstructor]
参见下文以了解示例
这可能是因为:
根本没有匹配的 [JsonConstructor]
,或者未通过 JSON .dyn 给它传递 Inports
和 Outports
。
有两个版本的 JSON.net 同时载入到同一进程中导致 .net 运行时失败,因此无法正确使用 [JsonConstructor]
属性来标记构造函数。
版本不同于当前 Dynamo 版本的 DynamoServices.dll 已与软件包捆绑在一起,并会导致 .net 运行时无法识别 [MultiReturn]
属性,因此标记有各种属性的 Zero Touch 节点将无法应用它们。您可能会发现,一个节点返回一个字典输出,而不是多个端口。
2) 在将存在一些错误的图形载入控制台后,节点会完全丢失。
如果反序列化因某种原因而失败,则可能会发生这种情况。最好仅序列化所需的特性。我们可以对不需要载入或保存的复杂特性使用 [JsonIgnore]
来忽略它们。诸如 function pointer, delegate, action,
或 event
之类的特性。由于这些特性通常无法反序列化并导致出现运行时错误,因此不应该对它们序列化。
已知问题:
在 librarie.js 中,同一级别上的自定义节点名称和类别名称重名会导致出现意外行为。QNTM-3653 - 避免为类别和节点使用相同的名称。
注释将转换为块注释,而不是行注释。
短类型名称将替换为完整名称。例如,如果再次载入自定义节点时未指定类型,则您会看到 var[]..[]
- 因为这是默认类型。
在 Dynamo 2.0 中,“列表”和“字典”类型已拆分,并且用于创建列表和字典的语法已更改。列表将使用 []
初始化,而字典使用 {}
。
如果以前使用 DefaultArgument
属性标记 Zero Touch 节点上的参数,并将列表语法默认用于特定列表(如 someFunc([DefaultArgument("{0,1,2}")])
),则此语法将不再有效,需要修改 DesignScript 代码段以对列表使用新的初始化语法。
如上所述,请勿将 Dynamo DLL 与软件包一起分发。(DynamoCore
、DynamoServices
等)。
节点模型节点需要做大量操作才能更新到 Dynamo 2.x。在较高级别上,除了用于实例化节点类型的新实例的常规 nodeModel 构造函数外,还需要实现将仅用于从 json 载入节点的构造函数。为了区分这些构造函数,请使用 [JsonConstructor]
(来自 newtonsoft.Json.net 的属性)来标记载入时间构造函数。
构造函数中参数的名称通常应与 JSON 特性的名称相匹配 - 尽管覆盖使用 [JsonProperty] 属性序列化的名称时,此映射会变得更复杂。 有关详细信息,请参见 Json.net 文档。
更新派生自 NodeModel
基类(或其他 Dynamo 核心基类,即 DSDropDownBase
)的节点所需的最常见更改是需要将 JSON 构造函数添加到您的类中。
原始无参数构造函数仍将对在 Dynamo 中创建的新节点处理初始化(例如,通过库)。要初始化从保存的 .dyn 或 .dyf 文件反序列化 (载入) 的节点,需要使用 JSON 构造函数。
JSON 构造函数与基础构造函数的不同之处在于,它将 PortModel
参数用于 inPorts
和 outPorts
,这些参数由 JSON 载入逻辑提供。由于数据存在于 .dyn 文件中,此处不需要调用来注册节点的端口。JSON 构造函数的示例如下所示:
using Newtonsoft.Json; //New dependency for Json
………
[JsonConstructor] //Attribute required to identity the Json constructor
//Minimum constructor implementation. Note that the base method invocation must also be present.
FooNode(IEnumerable<PortModel> inPorts, IEnumerable<PortModel> outPorts) : base(inPorts, outPorts) { }
此语法 :base(Inports,outPorts){}
会调用基础 nodeModel
构造函数,并将反序列化端口传递给它。
类构造函数中存在的任何涉及初始化已序列化到 .dyn 文件中的特定数据的特殊逻辑 (例如,设置端口注册、连缀策略等) 都不需要在此构造函数中重复,因为这些值可以从 JSON 中读取。
这是 nodeModel 的 JSON 构造函数和非 JSON 构造函数之间的主要区别。JSON 构造函数在从文件载入时被调用,并被传递载入的数据。但是,必须在 JSON 构造函数中复制其他用户逻辑 (例如,为节点初始化事件处理程序或附加)。
可以在此处的 DynamoSamples 存储库 -> ButtonCustomNodeModel、DropDown 或 SliderCustomNodeModel 中找到示例
以前,开发人员可以通过 SerializeCore
和 DeserializeCore
方法将特定模型数据序列化和反序列化到 xml 文档。这些方法仍存在于 API 中,但将在将来版本的 Dynamo 中弃用(可以在此处找到示例)。现在,通过 JSON.NET 实现,NodeModel 派生类上的 public
特性可以直接序列化到 .dyn 文件。JSON.Net 提供了多个属性来控制如何序列化该特性。
指定 PropertyName
的此示例可以在此处的 Dynamo 存储库中找到。
[JsonProperty(PropertyName = "InputValue")]
public DSColor DsColor {...
注意
如果您创建自己的 JSON.net 转换器类,则 Dynamo 目前没有一种机制可以让您将其注入到载入和保存方法中;因此,即使您使用 [JsonConverter]
属性标记您的类,它也不可能被使用 - 可以改为直接在 setter 或 getter 中调用您的转换器。//TODO 需要确认这一限制。欢迎提供任何证据。
指定序列化方法以将该特性转换为字符串的示例可以在此处的 Dynamo 存储库中找到。
[JsonProperty("MeasurementType"), JsonConverter(typeof(StringEnumConverter))]
public ConversionMetricUnit SelectedMetricConversion{...
不用于序列化的 public
特性需要添加 [JsonIgnore]
属性。当将节点保存到 .dyn 文件时,这将确保序列化机制会忽略此数据,并且再次打开图形时不会导致出现意外结果。此情况的示例可以在此处的 Dynamo 存储库中找到。
如上所述,过去使用 SerializeCore
和 DeserializeCore
方法是为了将节点保存和载入到 xml .dyn 文件中。此外,它们还用于保存和载入节点状态以进行撤消/重做, **现在仍然如此!**如果要为 nodeModel UI 节点实现复杂的撤消/重做功能,则需要实现这些方法并将其序列化到作为这些方法的参数提供的 XML 文档对象中。除了复杂的 UI 节点之外,这应该是一个罕见用例。
受 2.0 API 更改影响的 nodeModel 节点中常见的一种情况是节点构造函数中的端口注册。查看 Dynamo 或 DynamoSamples 存储库中的示例,您会发现以前使用 InPortData.Add()
或 OutPortData.Add()
方法。以前,在 Dynamo API 中,InPortData
和 OutPortData
公有特性标记为已弃用。在 2.0 中,这些特性已删除。现在,开发人员应使用 InPorts.Add()
和 OutPorts.Add()
方法。此外,这两种 Add()
方法的签名略有不同:
InPortData.Add(new PortData("Port Name", "Port Description")); //Old version valid in 1.3 but now deprecated
与
InPorts.Add(new PortModel(PortType.Input, this, new PortData("Port Name", "Port Description"))); //Recommended 2.0
可以在此处的 Dynamo 存储库 -> DynamoConvert.cs 或 FileSystem.cs 中找到已转换代码的示例
受 2.0 API 更改影响的另一个常见用例与 BuildAst()
方法中的常用方法有关,可根据是否存在端口连接器来确定节点行为。以前,使用 HasConnectedInput(index)
来验证已连接端口的状态。现在,开发人员应使用 InPorts[0].IsConnected
特性来检查端口连接状态。可以在 Dynamo 存储库中的 ColorRange.cs 中找到此情况的示例。
让我们来逐步介绍如何将 1.3 UI 节点升级到 Dynamo 2.x。
为了在 2.0 中正确载入和保存该 nodeModel
类,我们所需要做的就是添加一个 jsonConstructor 来处理端口的载入。我们只需在基础构造函数中传递端口,而这个实现是空的。
注意:请勿在 JsonConstructor 中调用 RegisterPorts()
或其某些变体 - 这将使用节点类中的输入和输出参数属性来构造新端口!由于我们希望使用传递给您的构造函数的已载入端口,因此我们不希望这样。
本例尽可能添加最小的载入 JSON 构造函数。但是,如果我们需要执行一些更复杂的构造逻辑(例如,在构造函数中设置一些用于事件处理的侦听器),该怎么办。从
DynamoSamples 存储库获取的下一个样例的链接位于本文档的 JsonConstructors Section
中的上方。
以下是 UI 节点的更复杂构造函数:
当我们添加用于从文件载入此节点的 JSON 构造函数时,我们必须重新创建该逻辑的一部分;但请注意,我们不会包括创建端口、设置连缀或设置特性的默认值(可以从文件载入)的代码。
请注意,已序列化到 JSON 中的其他公有特性(如 ButtonText
和 WindowText
)将不会作为显式参数添加到构造函数中 - JSON.net 会使用这些特性的 setter 自动设置它们。
相较于 Zero-Touch 节点,基于 NodeModel 的节点提供了更大的灵活性和更强大的功能。在本例中,我们将通过添加一个随机化矩形大小的集成滑块,来将 Zero-Touch 网格节点提升到下一个级别。
滑块会相对于单元大小缩放单元,因此用户不必为滑块提供正确的范围。
Dynamo 基于 model-view-viewmodel (MVVM) 软件体系结构模式,以使 UI 与后端保持分离。当创建 ZeroTouch 节点时,Dynamo 会在节点的数据与其 UI 之间绑定数据。要创建自定义 UI,我们必须添加数据绑定逻辑。
在较高级别上,在 Dynamo 中建立模型-视图关系有两个部分:
NodeModel
类用于建立节点的核心逻辑(“模型”)
INodeViewCustomization
类用于自定义如何查看 NodeModel
(“视图”)
NodeModel 对象已有关联的视图-模型 (NodeViewModel),因此我们可以仅关注自定义 UI 的模型和视图。
NodeModel 节点与 Zero-Touch 节点有几个明显差异,我们将在本例中介绍这些差异。在我们进入 UI 自定义之前,让我们先构建 NodeModel 逻辑。
1.创建项目结构:
NodeModel 节点只能调用函数,因此我们需要将 NodeModel 和函数分离到不同的库中。对 Dynamo 软件包执行此操作的标准方法是为每个软件包创建单独的项目。先创建一个新的解决方案来包含项目。
选择
File > New > Project
选择
Other Project Types
以显示“解决方案”选项选择
Blank Solution
将解决方案命名为
CustomNodeModel
选择
Ok
在解决方案中创建两个 C# 类库项目:一个用于函数,一个用于实现 NodeModel 接口。
在解决方案上单击鼠标右键,然后选择
Add > New Project
选择类库
将它命名为
CustomNodeModel
单击
Ok
重复该过程以添加另一个名为
CustomNodeModelFunctions
的项目
接下来,我们需要重命名自动创建的类库,然后将其添加到 CustomNodeModel
项目中。类 GridNodeModel
实现抽象的 NodeModel 类、GridNodeView
用于自定义视图,GridFunction
包含我们需要调用的任何函数。
添加另一个类,方法是在
CustomNodeModel
项目上单击鼠标右键、选择Add > New Item...
,然后选择Class
。在
CustomNodeModel
项目中,我们需要GridNodeModel.cs
和GridNodeView.cs
类在
CustomNodeModelFunction
项目中,我们需要GridFunctions.cs
类
在我们将任何代码添加到类之前,请为此项目添加必需的软件包。CustomNodeModel
将需要 ZeroTouchLibrary 和 WpfUILibrary,CustomNodeModelFunction
将仅需要 ZeroTouchLibrary。WpfUILibrary 将用于我们稍后进行操作的 UI 自定义,ZeroTouchLibrary 将用于创建几何图形。可以为项目单独添加软件包。由于这些软件包具有依存关系,因此将自动安装 Core 和 DynamoServices。
在项目上单击鼠标右键,然后选择
Manage NuGet Packages
仅安装该项目所需的软件包
Visual Studio 会将我们参照的 NuGet 软件包复制到构建目录中。这可以设置为 false,这样一来软件包中就不会存在任何不必要的文件。
选择 Dynamo NuGet 软件包
将
Copy Local
设置为 false
2.继承 NodeModel 类
如前所述,使 NodeModel 节点与 ZeroTouch 节点不同的主要方面是其对 NodeModel
类的实现。NodeModel 节点需要此类中的多个函数,我们可以通过在类名后添加 :NodeModel
来获取这些函数。
将以下代码复制到 GridNodeModel.cs
中。
这不同于 Zero-Touch 节点。让我们了解一下每个部分的作用。
指定节点属性,如名称、类别、InPort/OutPort 名称、InPort/OutPort 类型、描述。
public class GridNodeModel : NodeModel
是一个从 Dynamo.Graph.Nodes
中继承 NodeModel
类的类。
public GridNodeModel() { RegisterAllPorts(); }
是一个注册节点输入和输出的构造函数。
BuildOutputAst()
返回 AST(抽象语法树),这是从 NodeModel 节点返回数据所需的结构。
AstFactory.BuildFunctionCall()
调用 GridFunctions.cs
中的 RectangularGrid 函数。
new Func<int, int, double, List<Rectangle>>(GridFunction.RectangularGrid)
指定函数及其参数。
new List<AssociativeNode> { inputAstNodes[0], inputAstNodes[1], sliderValue });
将节点输入映射到函数参数。
如果输入端口未连接,则 AstFactory.BuildNullNode()
会构建空节点。这是为了避免在节点上显示警告。
RaisePropertyChanged("SliderValue")
会在滑块值发生更改时通知 UI
var sliderValue = AstFactory.BuildDoubleNode(SliderValue)
在 AST 中构建表示滑块值的节点
将输入更改为 functionCall 变量 new List<AssociativeNode> { inputAstNodes[0], sliderValue });
中的 sliderValue
变量
3.调用函数
CustomNodeModelFunction
项目将构建到 CustomNodeModel
中的单独程序集,以便可以调用它。
将以下代码复制到 GridFunction.cs
中。
此函数类与 Zero-Touch 网格案例研究非常相似,但有一点不同:
由于已从 CustomNodeModel
调用函数,因此 [IsVisibleInDynamoLibrary(false)]
会阻止 Dynamo“看到”以下方法和类。
正如我们为 NuGet 软件包添加参照一样,CustomNodeModel
需要参照 CustomNodeModelFunction
才能调用函数。
在我们参照函数之前,CustomNodeModel 的 using 语句将处于不活动状态
在
CustomNodeModel
上单击鼠标右键,然后选择Add > Reference
选择
Projects > Solution
选中
CustomNodeModelFunction
单击
Ok
4.自定义视图
要创建滑块,我们需要通过实现 INodeViewCustomization
接口来自定义 UI。
将以下代码复制到 GridNodeView.cs
中
public class CustomNodeModelView : INodeViewCustomization<GridNodeModel>
定义自定义 UI 所需的功能。
在完成设置项目结构后,使用 Visual Studio 的设计环境构建用户控件并在 .xaml
文件中定义其参数。通过工具箱,将滑块添加到 <Grid>...</Grid>
。
在
CustomNodeModel
上单击鼠标右键,然后选择Add > New Item
选择
WPF
将用户控件命名为
Slider
单击
Add
将以下代码复制到 Slider.xaml
中
在 .xaml
文件中定义滑块控件的参数。Minimum 和 Maximum 属性定义此滑块的数值范围。
在 <Grid>...</Grid>
中,我们可以通过 Visual Studio 工具箱放置不同的用户控件
当创建 Slider.xaml
文件时,Visual Studio 会自动创建一个名为 Slider.xaml.cs
的 C# 文件,用于初始化滑块。更改此文件中的名称空间。
该名称空间应为 CustomNodeModel.CustomNodeModel
GridNodeModel.cs
定义滑块计算逻辑。
5.配置为软件包
在我们构建项目之前,最后一步是添加一个 pkg.json
文件,以便 Dynamo 可以读取软件包。
在
CustomNodeModel
上单击鼠标右键,然后选择Add > New Item
选择
Web
选择
JSON File
将该文件命名为
pkg.json
单击
Add
将以下代码复制到 pkg.json
中
"name":
确定软件包的名称及其在 Dynamo 库中的分组
"keywords":
提供用于搜索 Dynamo 库的搜索词
"node_libraries": []
指示与软件包关联的库
最后一步是构建解决方案并发布为 Dynamo 软件包。请参见“软件包展开”一章,以了解如何在联机发布之前创建本地软件包以及如何直接从 Visual Studio 构建软件包。
扩展是 Dynamo 生态系统中一款功能强大的开发工具。它们允许开发人员基于 Dynamo 交互和逻辑来派生自定义功能。扩展可以分为两大类:扩展和视图扩展。顾名思义,视图扩展框架允许您通过注册自定义菜单项来扩展 Dynamo UI。除了 UI 之外,常规扩展的运行方式非常相似。例如。我们可以构建一个将特定信息记录到 Dynamo 控制台的扩展。此场景不需要自定义 UI,因此也可以使用扩展完成。
按照 DynamoSamples Github 存储库中的 SampleViewExtension 示例,我们将逐步介绍创建一个实时显示图形中活动节点的简单无模式窗口所需的步骤。视图扩展要求我们为窗口创建 UI,并将值绑定到视图模型。
视图扩展窗口是按照 Github 存储库中的 SampleViewExtension 示例开发的。
尽管我们将从头开始构建示例,但您也可以下载并构建 DynamoSamples 存储库以用作参照。
此漫游将专门参照位于
DynamoSamples/src/
中名为 SampleViewExtension 的项目。
视图扩展有三个基本部分:
一个程序集,包含实现 IViewExtension
的类以及创建视图模型的类
一个 .xml
文件,告知 Dynamo 在运行时应在何处查找此程序集以及扩展类型
一个 .xaml
文件,将数据绑定到图形显示并确定窗口外观
1.创建项目结构
首先,创建一个名为 SampleViewExtension
的 Class Library
新项目。
通过选择
File > New > Project
来创建新项目选择
Class Library
将项目命名为
SampleViewExtension
选择
Ok
在此项目中,我们需要两个类。一个类将实现 IViewExtension
,另一个类将实现 NotificationObject.
。IViewExtension
将包含有关如何展开、载入、参照和处理我们扩展的所有信息。NotificationObject
将为 Dynamo 和 IDisposable
中的更改提供通知;当发生更改时,计数将随之更新。
一个名为
SampleViewExtension.cs
的类文件,将实现IViewExtension
一个名为
SampleWindowViewMode.cs
的类文件,将实现NotificationObject
要使用 IViewExtension
,我们需要 WpfUILibrary NuGet 软件包。安装此软件包将自动安装 Core、Services 和 ZeroTouchLibrary 软件包。
选择 WpfUILibrary
选择
Install
以安装所有相关软件包
2.实现 IViewExtension 类
在 IViewExtension
类中,我们将确定 Dynamo 启动、载入扩展以及 Dynamo 关闭时会出现的情况。在 SampleViewExtension.cs
类文件中,添加以下代码:
SampleViewExtension
类创建用于打开窗口的可单击菜单项,并将其连接到视图模型和窗口。
public class SampleViewExtension : IViewExtension
SampleViewExtension
继承自 IViewExtension
接口,提供我们创建菜单项所需的一切。
sampleMenuItem = new MenuItem { Header = "Show View Extension Sample Window" };
创建 MenuItem 并将其添加到 View
菜单。
菜单项
sampleMenuItem.Click += (sender, args)
会触发在单击菜单项时将打开一个新窗口的事件
MainGrid = { DataContext = viewModel }
会为窗口中的主网格设置数据上下文,参考我们将创建的 .xaml
文件中的 Main Grid
Owner = p.DynamoWindow
会将我们弹出窗口的所有者设置为 Dynamo。这意味着新窗口依赖于 Dynamo,因此最小化、最大化和恢复 Dynamo 等操作将导致新窗口遵循此相同行为
window.Show();
会显示已设置其他窗口特性的窗口
3.实现视图模型
现在,我们已经建立了窗口的一些基本参数,我们将添加用于响应各种 Dynamo 相关事件的逻辑,并指示 UI 根据这些事件进行更新。将以下代码复制到 SampleWindowViewModel.cs
类文件:
视图模型类的此实现会侦听 CurrentWorkspaceModel
,并会在工作空间添加或删除节点时触发事件。这将引发特性更改,通知 UI 或绑定图元:数据已更改并需要更新。ActiveNodeTypes
getter 会被调用,它将在内部调用一个附加辅助函数 getNodeTypes()
。此函数会遍历画布上的所有活动节点、填充包含这些节点名称的字符串,并将此字符串返回给 .xaml 文件中要在弹出窗口中显示的绑定。
在定义扩展的核心逻辑后,我们现在将使用 .xaml
文件指定窗口的外观详细信息。我们所需要的只是一个简单的窗口,它将通过 TextBlock
Text
中的 ActiveNodeTypes
特性绑定来显示字符串。
在项目上单击鼠标右键,然后选择
Add > New Item...
选择我们将对其进行更改以创建窗口的“用户控制”模板
将新文件命名为
SampleWindow.xaml
选择
Add
在 .xaml
窗口代码中,我们需要将 SelectedNodesText
绑定到文本块。将以下代码添加到 SampleWindow.xaml
:
Text="{Binding ActiveNodeTypes}"
会将 SampleWindowViewModel.cs
中的 ActiveNodeTypes
特性值绑定到窗口中的 TextBlock
Text
值。
现在,我们将初始化 .xaml C# 备份文件 SampleWindow.xaml.cs
中的样例窗口。将以下代码添加到 SampleWindow.xaml
:
视图扩展现在已准备好构建并添加到 Dynamo 中。Dynamo 需要一个 xml
文件,才能将我们的输出 .dll
注册为扩展。
在项目上单击鼠标右键,然后选择
Add > New Item...
选择 XML 文件
将文件命名为
SampleViewExtension_ViewExtensionDefinition.xml
选择
Add
文件名遵循 Dynamo 标准,以便参照扩展程序集,如下所示:"extensionName"_ViewExtensionDefinition.xml
在 xml
文件中,添加以下代码以告知 Dynamo 要在何处查找扩展程序集:
在此示例中,我们已将程序集构建到默认的 Visual Studio 项目文件夹。将 <AssemblyPath>...</AssemblyPath>
目标替换为程序集的位置。
最后一步是将 SampleViewExtension_ViewExtensionDefinition.xml
文件复制到 Dynamo 的视图扩展文件夹,该文件夹位于 Dynamo Core 安装目录 C:\Program Files\Dynamo\Dynamo Core\1.3\viewExtensions
中。请务必注意,extensions
和 viewExtensions
有单独的文件夹。将 xml
文件放置在不正确的文件夹中可能会导致在运行时无法正确载入。
我们已复制到 Dynamo 的视图扩展文件夹中的
.xml
文件
这是对视图扩展的基本介绍。有关更复杂的案例研究,请参见 DynaShape 软件包,它是 Github 上的开源项目。该软件包使用支持在 Dynamo 模型视图中实时编辑的视图扩展。
Dynamo 依赖于其社区的创造力和活跃度,Dynamo 团队会鼓励参与者探索各种可能性、测试创意以及加入社区以提供反馈。尽管鼓励创新,但仅当变更会使 Dynamo 更易于使用并满足本文档中定义的准则时,才会合并这些变更。将不会合并好处狭隘的变更。
Dynamo 团队要求拉取请求遵循以下准则:
遵循我们的和
添加新功能时包括单位测试
修复错误时,添加将亮显如何终止当前行为的单位测试
使讨论集中于一个问题。如果出现新主题或相关主题,则创建新问题。
以及一些有关禁止行为的准则:
大量拉取请求让我们大吃一惊。反之,请提出问题并发起讨论,以便我们能够在您投入大量时间之前就方向达成共识。
提交您未写入的代码。如果您发现您认为非常适合添加到 Dynamo 的代码,请提出问题并发起讨论,然后再继续操作。
提交将更改许可相关文件或标头的 PR。如果您认为它们有问题,请提出问题,我们很乐意讨论。
生成 API 附加功能,而无需先提出问题并与我们讨论。
提交拉取请求时,请使用。在提交您的 PR 之前,请确保清楚地描述了目的,并且所有声明均可断言为真:
代码库在此 PR 之后的状态更佳
根据进行记录
此 PR 包含的测试级别是合适的
面向用户的字符串(如果有)将提取到 *.resx
文件中
所有测试都使用自助服务 CI 通过
UI 更改的快照(如果有)
对 API 的更改遵循,并记录在 文档中。
Dynamo 团队将为您的拉取请求指定合适的审阅者。
提交拉取请求后,您可能需要在审阅过程中继续参与。请注意以下审阅标准:
Dynamo 团队每月召开一次会议,以审阅从最旧到最新的拉取请求。
如果审阅后的拉取请求需要所有者进行更改,则 PR 的所有者有 30 天的时间做出响应。如果 PR 在下一次会议之前未看到有任何活动,则它将由团队关闭,或者根据其效用由团队中的某人接管。
拉取请求应使用 Dynamo 的默认 PR 模板
将不会审阅未完全填写 Dynamo PR 模板且所有声明均已满足的拉取请求。
由于市面上提供有多个版本的 Revit,因此您可能需要将所做更改精选给特定的 DynamoRevit 发行分支机构,以便其他版本的 Revit 可以拾取新功能。在审阅过程中,参与者会负责将其已审阅的提交精选给 Dynamo 团队指定的其他 DynamoRevit 分支机构。
DynamoSamples 存储库:
DynaShape 的软件包安装程序可以从 Dynamo 论坛下载:
源代码可以从 Github 克隆: