本参考页面扩展了脚本编写策略中涵盖的最佳实践,并对代码库、标签和样式进行了更加详细的介绍。我们将使用 Python 说明下面的概念,但相同原则在 Python 和 C#(Zerotouch) 中适用,语法却不同。
标准库位于 Dynamo 外部,并以编程语言 Python 和 C# (Zerotouch) 呈现。Dynamo 还有自己的库集,这些库直接对应于其节点层次结构,使用户能够使用代码构建可以由节点和线生成的任何内容。下面介绍了每个 Dynamo 库对哪些内容提供访问以及何时使用标准库。
标准库和 Dynamo 库
Python 和 C# 的标准库可用于在 Dynamo 环境中构建高级数据和流结构。
Dynamo 库直接对应于节点层次结构,用于创建几何图形和其他 Dynamo 对象。
Dynamo 库
ProtoGeometry*
功能:圆弧、边界框、圆、圆锥体、坐标系、立方体、曲线、圆柱体、边、椭圆、椭圆弧、面、几何图形、螺旋、索引组、线、网格、Nurbs 曲线、Nurbs 曲面、平面、点、多边形、矩形、实体、球体、曲面、拓扑、T 样条曲线、UV、向量、顶点。
如何输入:import Autodesk.DesignScript.Geometry
``
DSCoreNodes
功能:颜色、二维颜色范围、日期时间、时间跨度、IO、公式、逻辑、列表、数学、四元树、字符串、线程。
如何输入:import DSCore
细分
功能:凸面外壳、Delaunay、Voronoi。
如何输入:import Tessellation
DSOffice
功能:Excel。
如何输入:import DSOffice
*注意:通过 Python 或 C# 使用 “ProtoGeometry” 时,正在创建的是非托管对象,这些对象需要手动对其内存进行管理 - 请参见以下部分:“非托管对象” 以了解详细信息。
在编写脚本时,我们会不断使用标识符来表示诸如变量、类型、函数和其他实体等内容。通过这种符号表示法,在构建算法时,我们可以通过标签(通常由字符序列组成)方便地引用信息。在编写易于他人以及您自己将来轻松阅读和理解的代码方面,命名内容也发挥着重要作用!以下是在脚本中命名内容时要牢记的一些技巧:
可以使用缩写,但要用注释说明缩写:
避免重复标记:
对变量名称使用正逻辑,而不是负逻辑:
首选“反转符号”:
从结构角度来说,这显得更合理。
别名应用于缩短过长且经常重复的链:
使用别名可能会快速导致出现令人困惑且非标准程序。
仅使用必要字词:
“一切应尽可能简单,但不能为了简单而简单。”– Albert Einstein
一般来说,几乎所有内容都有一种以上的编程方法,因此您“个人风格”的脚本编写是您一路上选择做出(或不做出)无数小决定的结果。也就是说,您代码的可读性和可维护性直接源于其内部一致性以及其对常规样式约定的遵循。一般来说,在两个位置看起来相同的代码的作用也应该相同。下面是用于编写清晰且一致代码的一些技巧。
命名约定:(为代码中每类实体选择以下约定之一并坚持使用!)
变量、函数、方法、软件包、模块:
lower_case_with_underscores
类和例外:
CapWords
受保护的方法和内部函数:
_single_leading_underscore(self, ...)
私有方法:
__double_leading_underscore(self, ...)
常数:
ALL_CAPS_WITH_UNDERSCORES
技巧:避免使用单字母变量(尤其是 l、O、I),但在非常短的块中,当其含义从即时上下文中清晰可见时除外。
使用空行:
在顶级函数和类定义周围加上两个空行。
类内部的方法定义周围加上一个空行。
可以使用(谨慎)额外的空行分隔多组相关函数。
避免使用多余空格:
紧挨在圆括号、方括号或大括号内:
逗号、分号或冒号之前:
在开始函数调用的参数列表的左括号之前:
在开始索引或切片的左括号之前:
始终在这些二进制运算符周围的任一侧使用一个空格:
观察行长度:
请勿对其强加超过约 79 个字符。
限制所需的编辑器窗口宽度可以并排打开多个文件,并且使用在相邻列中显示两个版本的代码审核工具时也可以正常工作。
通过将表达式括在括号中,可以将较长行分成多行:
避免出现明显多余的注释:
有时,注释越少,代码越可读。尤其是当它强制您改用有意义的符号名称时。
采用良好的编码习惯可减少对注释的依赖:
技巧:注释告诉您原因,而代码告诉您方法。
检出开源代码:
开源项目建立在众多开发人员的协作基础之上。这些项目需要保持高水平的代码可读性,以便团队可以尽可能高效地协同工作。因此,最好浏览这些项目的源代码,以观察这些开发人员正在进行的工作。
改善您的约定:
询问每个约定是否符合当前的需求。
功能/效率是否受到影响?
查看这些 Wiki 页面,以了解有关为 Zerotouch 编写 C# 以及参与 Dynamo 的指南:
此 Wiki 介绍了一些用于记录和测试代码的常规编码标准:https://github.com/DynamoDS/Dynamo/wiki/Coding-Standards
此 Wiki 专门介绍了用于库、类别、节点名称、端口名称和缩写的命名标准:https://github.com/DynamoDS/Dynamo/wiki/Naming-Standards
非托管对象:
从创建的 Python 或 C# 几何图形对象使用 Dynamo 的几何图形库 (ProtoGeometry) 时将不由虚拟机进行托管,并且将需要手动清理其中许多对象的内存。要清理本地对象或非托管对象,可以使用 “Dispose” 方法 或 “using” 关键字。请参见此 Wiki 条目以了解概述:https://github.com/DynamoDS/Dynamo/wiki/Zero-Touch-Plugin-Development#dispose--using-statement。
只需处理不返回到图形或存储对其参照的非托管资源。在本部分的其余部分中,我们将这些对象称为 “中间几何图形”。在下面的代码示例中,可以看到此类对象的示例。此 Zerotouch C# 函数 “singleCube” 会返回单个立方体,但在其执行期间会额外创建 10000 个立方体。我们可以假定该其他几何图形用作一些中间构造几何图形。
此 Zerotouch 函数最有可能导致 Dynamo 崩溃。 由于我们创建了 10000 个实体,但仅存储其中的一个,并仅返回该实体。我们应该改为处理所有中间立方体,但要返回的立方体除外。我们不希望对返回的内容进行处理,因为它将传播到图形中并由其他节点使用。
修复的代码将如下所示:
通常,只需处理几何图形,如 Surfaces
、Curves
和 Solids
。但是,为了安全起见,可以处理所有几何图形类型(Vectors
、Points
、CoordinateSystems
)。
本入门的此部分是由“最佳实践”的日志构成的。它阐明了我们通过经验和研究所学的几大策略,从而最大程度地利用良好的参数化工作流。作为设计师和编程人员,我们的质量指标主要关注工具的可维护性、可靠性、可用性和效率。尽管这些最佳实践还针对基于视觉或文本的脚本编写提供了特定示例,但原理适用于所有编程环境,可用于指导许多计算工作流。
在可视化编程过程中工作可能是一项强大的创意活动,但是程序流和关键用户输入很快可能会被工作空间的复杂性和/或布局所掩盖。让我们来了解一些管理程序的最佳实践。
在向工作空间添加了多个节点后,我们可能需要为了清晰显示而重新组织节点的布局。通过选择多个节点并在工作空间上单击鼠标右键,弹出窗口会包括 “对齐当前选择” 菜单,其中包含 X 和 Y 方向的对正和分布选项。
选择多个节点
在工作空间中单击鼠标右键
使用 “对齐当前选择” 选项
有了一些经验后,我们可以通过查看节点名称并遵循程序流来“读取”可视化程序。对于所有经验级别的用户来说,最好还要包括纯语言标签和描述。Dynamo 有一个 “Notes” 节点,该节点有可编辑的文本字段来执行此操作。我们可以通过两种方式向工作空间添加注释:
浏览到菜单“编辑”>“创建注释”
使用键盘快捷键 Ctrl+W
将注释添加到工作空间后,将弹出一个文本字段,允许我们编辑注释中的文本。创建注释后,我们可以通过双击或在注释节点上单击鼠标右键来编辑注释。
当可视化程序变得非常大时,确定要执行的较大步骤会很有帮助。我们可以使用 “组” 亮显较大的节点集合,以在背景中使用彩色矩形和标题标记它们。有三种方法可以使包含多个节点的组处于选中状态:
浏览到菜单“编辑”>“创建组”
使用键盘快捷键 Ctrl+G
在工作空间上单击鼠标右键,然后选择“创建组”
在创建组后,我们可以编辑其设置,例如标题和颜色。
提示:使用“注释”和“组”是注释文件并提高可读性的有效方法。
以下是添加了“注释”和“组”的程序示例:
注释:“栅格参数”
注释:“栅格点”
组:“创建点栅格”
组:“创建吸引器点”
注释:“校准距离值”
注释:“圆的可变栅格”
在本章之前,入门手册介绍了如何实现 Dynamo 的强大可视化脚本编写功能。充分了解这些功能是构建健壮可视化程序的坚实基础和第一步。我们在现场使用可视化程序、与同事共享这些程序、排除错误或测试限制时,我们还要处理其他问题。如果其他人将使用您的程序,或者您希望从现在开始六个月内打开它,则它需要具有直观的图形和清晰的逻辑。Dynamo 有许多工具可用于管理程序的复杂性,本章会提供有关何时使用它们的指南。
在开发 Dynamo 图形和测试想法时,它的大小和复杂性会迅速增加。尽管创建一个正常运行的程序很重要,但使其尽可能简单也同样重要。您的图形不但将运行得更快且更可预测,而且您和其他用户将在以后了解其逻辑。以下是几种可以帮助您阐明图形逻辑的方法。
组使您在构建程序时可以创建功能上不同的各部分
组使您可以移动程序的大部分内容,同时保持模块化和对齐
可以更改组的颜色以区分各组的功能(输入与函数)
可以使用组来开始组织图形以简化“自定义节点”创建
本程序中的颜色标识了每个组的用途。此策略可用于在您开发的任何图形标准或模板中创建层次结构。
“函数”组(蓝色)
“输入”组(橙色)
“脚本”组(绿色)
有关如何使用组的信息,请参见管理程序。
有时,可以使用代码块键入数字或节点方法,速度比搜索快(Point.ByCoordinates、Number、String、Formula)
代码块在您要在 DesignScript 中定义自定义函数以减少图形中的节点数量时非常有用
1 和 2 执行相同的函数。与分别搜索并添加每个节点相比,编写几行代码要快得多。代码块也更加简洁。
以代码块形式编写的设计脚本
节点中的等效程序
有关如何使用代码块的信息,请参见什么是代码块。
可以通过使用“节点到代码”降低图形的复杂性,这将采用一组简单节点并将其相应 DesignScript 写入单个代码块
“节点到代码”可以压缩代码而不会消除程序的清晰度
以下是使用“节点到代码”的优点:
轻松将代码压缩到一个仍可编辑的组件中
可以简化图形的重要部分
在“迷你程序”不经常被编辑时非常有用
对于合并其他代码块功能(如函数)非常有用
以下是使用“节点到代码”的缺点:
通用命名会降低易读性
其他用户难以理解
无法轻松返回到可视化编程版本
现有程序
基于“节点到代码”创建的代码块
有关如何使用“节点到代码”的信息,请参见设计脚本语法。
使用 List@Level,可以通过替换 List.Map 和 List.Combine 节点降低图形的复杂性,这可能会占用大量画布空间
List@Level 通过允许从节点的输入端口访问列表中任何级别的数据,从而为您提供了一种快于 List.Map/List.Combine 的方法来构建节点逻辑
我们可以通过为 CountTrue 的“列表”输入激活 List@Level,来验证 BoundingBox.Contains 返回的 True 值数以及具体列表。List@Level 允许用户确定输入从哪个级别获取数据。与其他涉及 List.Map 和 List.Combine 的方法相比,使用 List@Level 灵活、高效并且强烈建议采用。
计算列表级别 2 的 True 值
计算列表级别 3 的 True 值
有关如何使用 List@Level 的信息,请参见列表的列表。
除了使图形尽可能简单且高效之外,还要努力实现图形清晰。尽管您极力通过逻辑分组使图形直观,但关系可能并不容易显现。在组内简单注释或重命名滑块可以让您或其他用户不必经历不必要的混淆或无需在图形上平移。以下是几种可以帮助您在图形内和图形之间应用图形一致性的方法。
为了在完成构建图形后减少工作量,应尝试通过经常并在构建时对齐节点来确保节点布局清晰可辩
如果其他人将要使用您的图形,则应确保“节点-线”布局在发布之前轻松流动
为了帮助您进行对齐,请使用“清理节点布局”功能自动对齐您的图形,尽管不如您自己做的精确
未组织的图形
对齐的图形
有关如何使用“节点对齐”的信息,请参见管理程序。
重命名输入有助于其他人轻松了解您的图形,尤其是当他们插入的内容将离屏时
请谨慎重命名输入以外的节点。 除此之外,还可以基于节点群集创建自定义节点并重命名该节点;显而易见,它包含其他内容
曲面操纵的输入
建筑参数的输入
排水模拟脚本的输入
要重命名某个节点,请在其名称上单击鼠标右键并选择“重命名节点...”。
如果图形中的某些内容需要节点无法表达的简单语言说明,则应添加注释
如果一个节点集或一个组太大或太复杂且无法轻松理解,则应添加注释
描述程序中返回原始平移距离的部分的注释
描述将这些值映射到正弦波的代码的注释
有关如何添加注释的信息,请参见管理程序。
构建可视化脚本时,请务必验证返回的内容是否符合您的预期。并非所有错误或问题都会导致程序立即停止运行,尤其是可能影响远距下游内容的 Null 值或零值。在脚本编写策略中的文本脚本编写上下文中也讨论了此策略。以下练习有助于确保获得预期的效果。
构建程序时使用“观察”或“预览”气泡,来验证关键输出是否返回预期内容
“Watch”节点用于比较:
原始平移距离
通过正弦方程传递的值
有关如何使用“Watch”的信息,请参见库。
很可能会有其他人在某个时候打开您的程序,即使您独立工作也无法避免。他们应该能够通过程序的输入和输出,快速了解该程序所需的内容和生成的结果。在开发要与 Dynamo 社区共享并用于其他人的程序的自定义节点时,这一点尤为重要。这些练习有助于生成健壮的可重用程序和节点。
为了确保可读性和可扩展性,应尝试尽可能最大程度地减少输入和输出
在即使将一个节点添加到画布之前,也应尝试为将如何构建逻辑制定策略,方法是先创建逻辑可能如何工作的粗略概要。在开发粗略概要时,应跟踪脚本中将出现哪些输入和输出。
如果有要嵌入到图形中的特定选项或条件,则应使用预设进行快速访问
还可以使用预设来通过缓存特定滑块值降低复杂性(在时间运行较长的图形中)
有关如何使用预设的信息,请参见使用预设管理数据。
如果程序可以收集到单个容器中,则应使用自定义节点
当图形的某一部分将经常在其他程序中重复使用时,应使用自定义节点
如果要与 Dynamo 社区共享功能,则应使用自定义节点
将点平移程序收集到自定义节点,会使健壮的独特程序可移植且更易于理解。命名良好的输入端口将有助于其他用户了解如何使用该节点。请记住为每个输入添加描述和所需的数据类型。
现有吸引器程序
收集此程序的自定义节点 PointGrid
有关如何使用自定义节点的信息,请参见自定义节点简介。
可以构建模板以在整个可视化图形中建立图形标准,以确保协作者能够以标准化方式了解图形
构建模板时,可以标准化组颜色和字体大小,以对工作流或数据操作的类型进行分类。
构建模板时,甚至可以标准化您希望如何对图形中前端和后端工作流之间的差异进行标注、上色或设计样式。
程序的 UI 或前端包括项目名称、输入滑块和输入几何图形。
程序的后端。
分组颜色类别(常规设计、输入、Python 脚本、输入的几何图形)。
单击下面的链接下载示例文件。
可以在附录中找到示例文件的完整列表。
现在,我们已经建立了几种最佳实践,让我们将它们应用于快速组合在一起的程序中。尽管该程序成功生成了屋顶,但图形的状态是作者的“思维导图”。它缺少任何组织或使用说明。我们将通过最佳实践来组织、描述和分析该程序,以便其他用户可以了解如何使用它。
程序运行正常,但图形混乱。
让我们先确定程序返回的数据和几何图形。
了解何时对数据进行重大更改对于建立逻辑划分或模块化至关重要。尝试使用“Watch”节点检查程序的其余部分,以查看在继续进行下一步之前是否可以确定组。
此带有数学方程的 “代码块” 看起来像是程序的关键部分。“Watch” 节点显示它正在返回平移距离列表。
该区域的用途并不明显。来自 “BoundingBox.Contains” 的列表级别 L2 的 True 值排列以及 “List.FilterByBoolMask” 的存在表明,我们要对点栅格的一部分进行采样。
在了解程序的基本部分后,让我们将它们放入组中。
组允许用户直观地区分程序的各个部分。
输入三维场地模型
基于正弦方程平移点栅格
点栅格的采样部分
创建建筑屋顶曲面
创建玻璃幕墙
建立组后,对齐节点以在整个图上创建视觉连续性。
视觉连续性有助于用户查看程序流和节点之间的隐式关系。
通过添加另一图形改进层,使程序更易于访问。添加注释以描述程序的特定区域如何工作、为输入提供自定义名称以及为不同类型的组指定颜色。
这些图形改进会告诉用户有关程序正在执行的操作的更多信息。不同的组颜色有助于区分输入和函数。
说明
带有描述性名称的输入
在开始压缩程序之前,让我们找到一个战略位置来介绍 Python 脚本排水模拟器。将第一个缩放屋顶曲面的输出插入相应的脚本输入。
我们选择此时将脚本集成到程序中,以便可以在原始的单屋顶曲面上运行排水模拟。该特定曲面不会被预览,但它让我们无需选择倒角的 Polysurface 的顶面。
脚本输入的源几何图形
Python 节点
输入滑块
开/关“开关”
现在一切就绪,让我们简化图形。
使用“节点到代码”和“自定义节点”压缩我们的程序,大大减小了图形的大小。创建屋顶曲面和墙的组已转换为代码,因为它们非常特定于此程序。点平移组包含在自定义节点中,因为它用于其他程序。在示例文件中,基于平移点组创建您自己的自定义节点。
“自定义节点”用于包含“平移点栅格”组
“节点到代码”用于压缩“创建建筑屋顶曲面和幕墙”组
最后一步,为示例性屋顶成型创建预设。
这些输入是屋顶成型的主要驱动力,将帮助用户发现程序的潜力。
我们的程序具有两个预设的视图。
屋顶排水模式为用户提供了各个预设的分析视图。
可视化脚本编写环境中基于文本的脚本编写支持使用 DesignScript、Python 和 ZeroTouch (C#) 实现功能强大的可视化关系。用户可以显示输入滑块等图元,将大型操作压缩为 DesignScript,以及通过 Python 或 C# 访问功能强大的工具和库,所有这些操作都可在同一工作空间内进行。在有效管理的情况下,结合使用这些策略可以将大量自定义、清晰和高效提供给整个程序。以下是一组准则,可帮助您使用文本脚本来增强可视化脚本。
文本脚本编写可建立比可视化编程复杂度更高的关系,但其功能也会明显重叠。这很有意义,因为节点实际上是预打包的代码,我们可能会采用 DesignScript 或 Python 编写整个 Dynamo 程序。但是,我们使用可视化脚本编写,因为节点和线的接口会创建直观的图形信息流。了解文本脚本编写的功能在哪些方面超出可视化脚本编写,这将向您提供应在何时使用它的重大提示,从而不会放弃节点和线的直觉本质。以下是有关何时编写脚本以及要使用哪种语言的准则。
文本脚本编写用于:
循环
递归
访问外部库
选择语言:
有关每个 Dynamo 库所提供访问内容的列表,请参见脚本编写参考。
在不可避免的参数化环境 Dynamo 中编写脚本时,明智的做法是相对于将要驻留的节点和线框架来构建代码。考虑使用包含文本脚本的节点,就像它是程序中具有几个特定输入、函数和预期输出的任何其他节点一样。这会立即为节点内的代码提供一小组在其中起作用的变量(这是干净参数系统的关键)。以下是一些将代码更好地集成到可视化程序中的准则。
标识外部变量:
尝试确定设计问题中的给定参数,以便可以构造直接基于该数据构建的模型。
编写代码之前,请标识变量:
最少的一组输入
预期输出
常数
编写代码之前已建立多个变量。
我们将模拟降雨所基于的曲面。
我们想要的雨滴(代理)数。
我们想让雨滴跑多远。
在降低最陡路径与遍历曲面之间切换。
具有相应数量输入的 Python 节点。
用于使返回的曲线呈现蓝色的代码块。
设计内部关系:
参数化允许编辑某些参数或变量,以便操纵或改变表达式或系统的最终结果。
只要脚本中的实体在逻辑上相关,就应将它们定义为彼此的函数。这样,当修改一个实体时,另一个实体可以相应更新。
通过仅显示关键参数来最大程度减少输入数量:
如果可以从更多父参数派生一组参数,则仅将父参数公开为脚本输入。通过降低脚本接口的复杂性,从而提高脚本的可用性。
Python 节点中的示例代码“模块”。
输入。
脚本内部变量。
使用这些输入和变量执行其函数的循环。
提示:像重视解决方案一样重视过程。
当有多种方法可用于在脚本中表达同一内容时,有时重复的表示会无法进行同步,这可能导致维护困难、分解不良和内部矛盾。
DRY 原则表述为“系统中的每条知识都必须具有单一、明确、权威的表示形式”:
成功应用该原则后,脚本中的所有相关图元都会以可预测的方式统一更改,并且所有不相关的图元彼此之间不会产生逻辑上的后果。
提示:在脚本中复制实体(如上例中的常量)之前,请先问问自己是否可以改为链接到源。
随着代码变得越来越长,越来越复杂,“大创意”或总体算法变得越来越难以辨认。此外,在跟踪具体内容发生的情况(和地点)、在出错时发现 Bug、集成其他代码以及分配开发任务方面也变得更加困难。为了避免出现这些麻烦,明智的做法是以模块形式编写代码,这是一种根据代码所执行任务将代码分解的组织策略。以下是一些通过模块化方式使脚本更易于管理的技巧。
以模块形式编写代码:
“模块”是执行特定任务的一组代码,类似于工作空间中的“Dynamo 节点”。
这可以是应与相邻代码(函数、类、一组输入或要输入的库)在视觉上分开的任何内容。
以模块形式开发代码可利用节点的可视化直观质量以及只有文本脚本编写才能实现的复杂关系。
这些循环调用我们将在练习中开发的名为“agent”的类。
定义每个代理的起点的代码模块。
更新代理的代码模块。
为代理的路径绘制轨迹的代码模块。
发现代码重用:
如果发现代码在多个位置执行相同(或非常相似)的操作,则想方设法将该代码聚类为可调用的函数。
“Manager”函数控制程序流,并且主要包含对处理底层细节(如在结构之间移动数据)的“Worker”函数的调用。
本例将根据中心点的 Z 值创建具有半径和颜色的球体。
两个“worker”父函数:根据中心点的 Z 值创建具有半径和颜色颜色的球体。
合并两个“worker”函数的“manager”父函数。调用此函数会调用其中的两个函数。
仅显示需要查看的内容:
模块接口表示该模块所提供和需要的图元。
在已定义单元之间的接口后,可分别对每个单元进行详细设计。
可分离性/可替换性:
模块之间互不通信。
模块化的常规形式:
代码分组:
函数:
类:
在 Dynamo 中开发文本脚本时,明智的做法是不断确保实际创建的内容符合您的预期。这将确保不可预见的事件(语法错误、逻辑差异、值不准确、异常输出等)在出现时即被迅速发现并进行处理,而不是在结束时立即全部处理。由于文本脚本位于画布上的节点内,因此它们已集成到可视化程序的数据流中。这使得对脚本的连续监视变得很简单,只需指定要输出的数据、运行程序以及使用“观察节点”评估从脚本流出的内容。以下是一些在构建脚本时不断检查脚本的技巧。
随手测试:
每当完成一组功能时:
返回并检查代码。
非常重要。协作者是否能够了解这样做的目的?我需要这样做吗?是否可以更高效地执行此函数?我是否在创建不必要的重复项或从属关系?
快速测试以确保返回的数据“有意义”。
将正在脚本中使用的最新数据指定为输出,以便在脚本更新时节点始终输出相关数据:
检查实体的所有边是否都将作为曲线返回,以围绕其创建边界框。
检查“Count”输入是否成功转换为“Ranges”。
检查坐标系是否已在此循环中正确转换和旋转。
预测“边缘情况”:
在编写脚本时,将输入参数故意指定为其分配域的最小值和最大值,以检查程序在极端条件下是否仍能正常运行。
即使程序在其极端条件下正常运行,也应检查它是否会返回意外的 Null 值/空值/零值。
有时,暴露脚本的一些潜在问题的 Bug 和错误仅在这些边缘情况下才会出现。
了解导致出现错误的原因,然后确定是需要进行内部修复还是需要重新定义参数域,来避免出现该问题。
提示:始终假定用户将使用已呈现给他/她的每个输入值的每种组合。这将有助于消除意外情况。
调试是从脚本中消除“Bug”的过程。Bug 可能是错误、效率低下、不准确或任何意外结果。解决 Bug 可能非常简单,只需更正拼写错误的变量名即可解决脚本中普遍存在的结构性问题。理想情况下,在构建脚本时对其进行调整将有助于及早发现这些潜在问题,尽管不能保证该脚本中没有 Bug。以下是对上述几种最佳实践的回顾,以帮助您系统地解决 Bug。
使用观察气泡:
通过将它指定给 OUT 变量(类似于调整程序的概念),来检查代码中不同位置返回的数据。
编写有意义的注释:
如果清楚地描述了代码模块的预期结果,则可以更加轻松地进行调试。
通常,这会造成过多的注释行和空行,但在调试时,它有助于将内容分解为可管理的各部分。
利用代码的模块化:
问题的根源可以隔离到特定模块。
确定故障模块后,修复问题相当简单。
当必须修改程序时,则以模块形式开发的代码将更容易更改:
可以将新模块或已调试模块插入到现有程序中,同时确保程序的其余部分不会更改。
调试 Python 节点中的示例文件。
正如我们可以通过将 xDist 和 yDist 指定给 OUT 后所看到的结果,输入几何图元返回的边界框大于自身的大小。
输入几何图元的边曲线返回一个适当的边界框,该边界框具有 xDist 和 yDist 的正确距离。
我们插入的“模块”代码可解决 xDist 和 yDist 的值问题。
单击下面的链接下载示例文件。
可以在附录中找到示例文件的完整列表。
考虑到我们的文本脚本编写的最佳实践,让我们来编写一个下雨模拟脚本。尽管我们能够以“图形策略”将最佳实践应用于杂乱无章的可视化编程,但使用文本脚本编写更难以做到这一点。采用文本脚本编写建立的逻辑关系不太明显,并且几乎不可能在杂乱的代码中解开。借助文本脚本编写的强大功能,可以采用组织形式承担更大责任。我们将逐步完成每个步骤,并沿用最佳实践。
我们的脚本已应用于吸引器变形的曲面。
首先,我们需要输入必要的 Dynamo 库。首先执行此操作将在 Python 中提供对 Dynamo 功能的全局访问。
我们打算使用的所有库都需要在此处输入。
接下来,我们需要定义脚本的输入和输出,这些将在节点上显示为输入端口。这些外部输入是脚本的基础,也是建立参数化环境的关键。
我们需要定义与 Python 脚本中的变量对应的输入,并确定所需的输出:
我们要漫游的曲面。
我们要走的代理数。
允许代理采取的最大步数。
沿曲面走最短路径或对其进行遍历的选项。
具有与脚本中的输入相对应的输入标识符(IN[0]、IN[1])的 Python 节点。
可以用不同颜色显示的输出曲线。
现在,让我们采用模块化的做法,并创建脚本的主体。对于多个起点,沿曲面模拟最短路径是一项艰巨任务,这需要多个函数。与其在整个脚本中调用不同的函数,不如通过将这些函数收集到一个类(即我们的代理)中来对代码进行模块化。此类或“模块”的不同函数可以使用不同变量调用,甚至可以在其他脚本中重用。
我们需要为代理定义一个类或蓝图,以便代理每走一步时都选择沿尽可能陡峭的方向行进,从而漫游曲面:
名称。
所有代理共享的全局属性。
每个代理特有的实例属性。
用于执行步骤的函数。
用于将每步的位置分类到轨迹列表的函数。
让我们通过定义代理的起始位置来初始化代理。这是调整脚本并确保代理类正常工作的好机会。
我们需要实例化要观察漫游曲面的所有代理,并定义其初始属性:
一个新的空轨迹列表。
它们将在曲面上开始其旅程的位置。
我们已将代理列表指定为输出,以检查脚本在此处返回的内容。返回的代理数目正确,但是稍后我们需要再次调整脚本以验证其返回的几何图元。
每一步都更新每个代理。然后,我们需要进入一个嵌套循环,在该循环中,针对每个代理和每一步,我们更新其位置并记录到其轨迹列表中。在每一步,我们还将确保代理尚未到达曲面上无法采取其他步骤(即允许代理下降)的点。如果满足该条件,我们将结束该代理的行程。
现在,我们的代理已完全更新,让我们返回代表它们的几何图元。在所有代理达到其下降限制或最大步数后,我们将创建一条贯穿其轨迹列表中点的复合线并输出复合线轨迹。
我们的脚本用于查找最陡路径。
预设在基础曲面上模拟降雨。
可以切换代理以遍历基础曲面,而不是查找最陡路径。
完整的 Python 文本脚本。
循环
递归
压缩节点
外部库
简写
DesignScript
是
是
是
否
是
Python
是
是
部分
是
否
ZeroTouch (C#)
否
否
否
是
否