您可能已注意到 Dynamo 中节点名称的共同主题:每个节点都使用不带空格的 “.” 语法。这是因为每个节点顶部的文本表示脚本编写的实际语法,而 “.” (或 点符号 )会将图元与我们可以调用的可能方法分开。这样可轻松地将可视化脚本编写转换为基于文本的脚本编写。
作为点符号的一般类比,我们如何在 Dynamo 中处理参数化苹果?以下是我们在决定食用苹果之前将对苹果运行的几种方法。(注意:这些不是实际的 Dynamo 方法):
人类可读 | 点符号 | 输出 |
---|---|---|
我不了解您,但是从上表中的输出来看,这看起来像一只美味的苹果。我想我会 “Apple.eat()” 它。
考虑到苹果的类比,我们来看一下 “Point.ByCoordinates”,并说明如何使用代码块创建点。
“代码块” 语法 Point.ByCoordinates(0,10);
会提供与 Dynamo 中的 “Point.ByCoordinates” 节点相同的结果,但我们能够使用一个节点创建点。这相较于将单独的节点连接到 “X” 和 Y” 更加高效。
通过在代码块中使用 “Point.ByCoordinates”,我们指定输入的顺序与现成节点 “(X,Y)” 相同。
只要节点不是特殊的 “UI”节点 (具有特殊用户接口功能的节点),即可通过代码块调用库中的任何常规节点。例如,可以调用 “Circle.ByCenterPointRadius”,但调用 “Watch 3D” 节点并没有什么意义。
常规节点(库中的大多数)通常有三种类型。您会发现库是按这些类别来组织的。在代码块内调用这三种类型的方法或节点时,它们的处理方式有所不同。
创建 - 创建(或构造)对象
操作 - 对某个对象执行操作
查询 - 获取已存在对象的特性
“创建”类别将从头开始构造几何图形。我们在代码块中从左到右输入值。这些输入与节点上从上到下的输入顺序相同。
比较 “Line.ByStartPointEndPoint” 节点和代码块中的对应语法,可得到相同的结果。
操作是对该类型的对象所执行的动作。Dynamo 使用许多编码语言通用的 “点符号”,来对某个对象应用操作。确定操作对象后,键入一个点,然后键入操作的名称。与创建类方法一样,操作类方法的输入放置在圆括号中,只是您无需在相应节点上指定所见到的第一个输入。反之,我们指定要对其执行操作的元素:
“Point.Add” 节点是操作类节点,因此语法的工作方式略有不同。
要添加给它的输入分别是 (1) 点 和 (2) 向量。在 “代码块” 中,我们已将点(对象)命名为 “pt”。要将名为*“vec”*的向量添加到 “pt”,我们会写入 “pt.Add(vec)” 或写入“: 对象、点、操作”。“添加”操作仅有一个输入,或 “Point.Add” 节点的所有输入减去第一个输入。“Point.Add” 节点的第一个输入是点本身。
查询类方法可获取对象的特性。由于对象本身是输入,因此不必再指定任何输入。无需输入圆括号。
带节点的连缀与带代码块的连缀略有不同。使用节点,用户在相应节点上单击鼠标右键并选择要执行的连缀选项。使用代码块,用户可以更好地控制如何创建数据的结构。代码块简写方法使用 “复制指南”,来设置多个一维列表应如何成对。尖括号“<>”中的数字定义所生成嵌套列表的层次结构:<1>、<2>、<3> 等。
在本例中,我们使用简写来定义两个范围(更多简写位于本章的以下部分中)。简而言之,
0..1;
等效于{0,1}
,-3..-7
等效于{-3,-4,-5,-6,-7}
。结果将生成由 2 个 X 值和 5 个 Y 值组成的列表。如果我们不对这些不匹配的列表使用复制指南,则会得到一列两点,即最短列表的长度。使用“复制指南”,我们可以找出 2 和 5 坐标的所有可能组合(或“笛卡尔积”)。使用语法 Point.ByCoordinates
(x_vals<1>,y_vals<2>);
,可以得到 两 个列表(其中,每个列表中包含 五 个项目)。使用语法 Point.ByCoordinates
(x_vals<2>,y_vals<1>);
,可以得到 五 个列表(其中,每个列表中包含 两 个项目)。
使用这种表示法,我们还可以指定哪个列表是主列表:2 个列表(每个列表 5 个项目)或 5 个列表(每个列表 2 个项目)。在该示例中,更改复制指南的顺序可在栅格中生成以下结果:一个列表(每个列表包含一行点)或一个列表(每个列表包含一列点)。
尽管上面的代码块方法可能需要一些时间来适应,但 Dynamo 中有一个名为“节点到代码”的功能,该功能可使该过程更加容易。要使用此功能,请在 Dynamo 图形中选择一组节点,在画布上单击鼠标右键并选择“节点到代码”。Dynamo 将这些节点以及所有输入和输出压缩到代码块中!这不仅是学习代码块的优秀工具,还支持您更高效地处理参数化 Dynamo 图形。我们将通过使用“节点到代码”来汇总下面的练习,因此不要错过它。
单击下面的链接下载示例文件。
可以在附录中找到示例文件的完整列表。
为了展现代码块的强大功能,我们将把现有的吸引器字段定义转换为代码块形式。使用现有定义演示代码块如何与可视化脚本编写相关联,有助于了解 DesignScript 语法。
首先,在上图中重新创建定义(或打开样例文件)。
请注意,“Point.ByCoordinates” 上的连缀已设置为 “笛卡尔积”。
在 Z 方向上,栅格中的每个点均基于其距参照点的距离进行上移。
曲面将重新创建并加厚,从而在几何图形中相对于距参照点的距离创建隆起。
从头开始,我们先定义参照点:Point.ByCoordinates
(x,y,0);
,我们使用与参照点节点顶部指定的相同 “Point.ByCoordinates” 语法。变量 “x” 和 “y” 会插入到 “代码块” 中,以便我们可以使用滑块动态地更新这些变量。
将一些 “滑块” 添加到 “代码块” 输入中(范围介于 -50 到 50 之间)。这样,我们就可以跨越默认的 Dynamo 栅格。
在 “代码块” 的第二行中,我们定义简写来替换数字序列节点:
coordsXY = (-50..50..#11);
。我们将在下一节中详细介绍此内容。现在,请注意,此简写与可视化脚本中的 “数字序列” 节点等效。
现在,我们要基于 “coordsXY” 序列创建点栅格。为此,我们要使用 “Point.ByCoordinates” 语法,但还需要采用与在可视化脚本中相同的方式初始化列表的 “笛卡尔积”。为此,我们键入以下代码行:
gridPts = Point.ByCoordinates(coordsXY<1>,coordsXY<2>,0);
。尖括号表示叉积参照。请注意,在 “Watch3D” 节点中,我们有一个点栅格穿过 Dynamo 栅格。
现在,面临的棘手情形是:我们希望根据距参照点的距离向上移动点栅格。首先,我们调用这组新的点 “transPts”。由于平移是对现有图元的操作(而不是使用
Geometry.Translate...
),因此我们使用gridPts.Translate
从画布上的实际节点读取时,我们会看到有三个输入。由于我们要对该图元执行操作(使用 “gridPts.Translate” ),因此已声明要平移的几何图形。其余两个输入将插入到函数的圆括号中:方向和 距离。
方向足够简单,我们使用
Vector.ZAxis()
来沿垂直方向移动。参照点与每个栅格点之间的距离仍需进行计算,因此我们以相同方式对该参照点执行这一计算操作:
refPt.DistanceTo(gridPts)
代码的最后一行会给出平移后的点:
transPts=gridPts.Translate(Vector.ZAxis(),refPt.DistanceTo(gridPts));
现在,我们得到具有相应数据结构的点栅格来创建 Nurbs 曲面。我们使用
srf = NurbsSurface.ByControlPoints(transPts);
构建曲面
最后,要为曲面添加一些深度,我们使用
solid = srf.Thicken(5);
构建实体;在本例中,我们使用代码将曲面加厚 5 个单位,但我们始终可以将其声明为一个变量(例如,将它命名为“thickness”),然后使用滑块控制该值。
“节点到代码”功能可自动执行我们只需单击按钮完成的整个练习。这不仅对于创建自定义定义和可重复使用的代码块来说是一项强大的功能,而且它对了解如何在 Dynamo 中编写脚本也是一个非常有用的工具:
从练习的步骤 1 开始处理现有可视化脚本。选择所有节点,在画布上单击鼠标右键,然后选择 “节点到代码”。就这么简单。
Dynamo 具有基于可视化图的版本、连缀和所有功能自动执行的文字。对可视化脚本测试此功能,然后发布该代码块的功能!
苹果是什么颜色?
Apple.color
red
苹果成熟了吗?
Apple.isRipe
true
苹果的重量是多少?
Apple.weight
6 oz.
苹果来自哪里?
Apple.parent
树
苹果创建什么?
Apple.children
种子
这个苹果是本地种植的吗?
Apple.distanceFromOrchard
60 mi.
函数可以在代码块中创建,并在 Dynamo 定义中的其他位置进行调用。这将在参数化文件中创建另一层控制,并且可以作为基于文本版本的自定义节点进行查看。在这种情况下,“父”代码块可以随时访问,并且可以位于图形上的任意位置。不需要引线!
第一行包含关键字“def”,接着是函数名称,然后是括号中的输入名称。大括号定义函数的主体。使用“return =”返回值。定义函数的代码块没有输入或输出端口,因为它们是从其他代码块调用的。
通过提供名称和相同数量的参数,调用同一文件中具有另一代码块的函数。其工作原理与库中现成的节点一样。
单击下面的链接下载示例文件。
可以在附录中找到示例文件的完整列表。
在本练习中,我们将创建一个通用定义,该定义将通过输入的点列表创建球体。这些球体的半径由每个点的 Z 特性驱动。
首先从 0 到 100 的十个值范围开始。将这些值插入到 “Point.ByCoordinates” 节点,以创建对角线。
创建 “代码块”,然后引入我们的定义。
使用以下代码行:
“inputPt” 是我们提供的名称,用于表示将驱动函数的点。目前,该函数不会执行任何操作,但我们会在后续步骤中构建此函数。
通过添加到 “代码块” 函数,我们放置注释和 “sphereRadius” 变量(该变量会查询每个点的 “Z” 位置)。请记住,“inputPt.Z” 不需要圆括号以用作方法。这是对现有图元特性的 “查询”,因此不需要输入:
现在,我们再次调用在另一个 “代码块” 中创建的函数。如果双击画布以创建新的 “代码块”,然后键入 “sphereB”,我们会注意到 Dynamo 建议使用已定义的 “sphereByZ” 函数。您的函数已添加到智能库!非常棒。
现在,我们调用相应函数并创建一个名为 “Pt” 的变量,以连接在之前步骤中创建的点:
在输出中,我们注意到所有值都为空值。这是为什么呢?在定义函数后,我们会计算 “sphereRadius” 变量,但是我们未定义函数应 “返回” 为 “输出” 的内容。可以在下一个步骤中修复该问题。
一个重要步骤是,我们需要定义函数的输出,方法是将一行代码
return = sphereRadius;
添加到 “sphereByZ” 函数。现在,我们看到“代码块”的输出为我们提供了每个点的 Z 坐标。
现在,让我们通过编辑 “父” 函数,来创建实际球体。
首先,我们使用代码行定义一个球体:
sphere=Sphere.ByCenterPointRadius(inputPt,sphereRadius);
接下来,我们将返回值更改为 “sphere”,而不是 “sphereRadius”:
return = sphere;
。这会在 Dynamo 预览中为我们提供一些巨大的球体!
1.要调整这些球体的大小,我们通过添加分隔器来更新“sphereRadius”值:
sphereRadius = inputPt.Z/20;
。现在,我们可以看到单独的球体,然后开始了解半径和 Z 值之间的关系。
在 “Point.ByCoordinates” 节点上,通过将连缀从“最短列表”更改为“叉积”,我们将创建点栅格。“sphereByZ” 函数仍然完全有效,因此所有点都会使用基于 Z 值的半径创建球体。
仅是为了测试水域,我们将原始数字列表连接到 “Point.ByCoordinates” 的 X 输入。现在,我们得到了一个球体的立方体。
注意:如果在计算机上的计算需要较长时间,请尝试将 “#10” 更改为 “#5” 之类的值。
请记住,我们创建的 “sphereByZ” 函数是一个通用函数,因此我们可以调用前一课中的螺旋,然后对其应用该函数。
最后一步:使用用户定义的参数来控制半径比。为此,我们需要为该函数创建新输入,并将 “20” 除数替换为参数。
将 “sphereByZ” 定义更新为以下内容:
通过向输入中添加“ratio”变量来更新子 “代码块”:
sphereByZ(Pt,ratio);
。将滑块插入到新创建的 “代码块” 输入中,并根据半径比改变半径大小。
代码块是 Dynamo 中的一项独特功能,可将可视化编程环境与基于文本的环境动态链接。代码块可以访问所有 Dynamo 节点,并且可以在一个节点中定义整个图形。请仔细阅读本章,因为代码块是 Dynamo 的基本构建块。
简单来说,代码块中有一些基本的简写方法,这些方法使数据管理 更加 容易。我们将详细介绍下面的基础知识,并讨论如何使用此简写来创建和查询数据。
定义范围和序列的方法可缩减为基本简写。使用下图作为“..”语法的指导,以使用代码块定义数值数据列表。在完成此标记法后,创建数值数据是一个非常有效的过程:
在本例中,数字范围会替换为定义
beginning..end..step-size;
的基本 “代码块” 语法。通过以数字表示,可以得到:0..10..1;
请注意,语法
0..10..1;
等同于0..10;
,步长 1 是简写表示法的默认值。因此,0..10;
将给出一个从 0 到 10 的序列(步长为 1)。“序列” 示例类似,除了我们使用“#”来指明我们希望列表中包含 15 个值,而不是列表中的最大值为 15。在本例中,我们将定义:
beginning..#ofSteps..step-size:
。序列的实际语法为0..#15..2
使用上一步中的_“#”,我们现在将其放置在语法的“step-size”部分中。现在,我们有一个 数字范围,从 “beginning” 到 “end”,“step-size”_ 表示法指示两者之间均匀分布多个值:
beginning..end..#ofSteps
创建高级范围后,我们即可简单地处理列表的列表。在下面的示例中,我们将隔离主要范围表示法的变量,并创建该列表的另一个范围。
1.创建嵌套范围,将带“#”的表示法与不带符号的表示法进行比较。相同逻辑在基本范围中都适用,但它稍显复杂。
2.我们可以在主范围内的任意位置处定义子范围;请注意,我们也可以有两个子范围。
3.通过控制范围中的“end”值,我们可以创建多个长度不同的的范围。
作为逻辑练习,请比较上述两个简写,并尝试解析 “subranges” 和 “#” 表示法如何驱动结果输出。
除了使用简写生成列表外,我们还可以即时创建列表。这些列表可以包含多种元素类型,也可以进行查询(请记住,列表本身就是对象)。总之,使用代码块时,可以创建列表,并从带括号的列表中查询项目(即“方括号”):
1.使用字符串快速创建列表,并使用项目索引进行查询。
2.使用变量创建列表,并使用范围简写表示法进行查询。
管理嵌套列表的过程类似。请注意列表顺序,并使用多组方括号进行调用:
1.定义一列列表。
2.使用单括号表示法查询列表。
3.使用双括号表示法查询项目。
单击下面的链接下载示例文件。
可以在附录中找到示例文件的完整列表。
在本练习中,我们将调整新的简写技能,以创建由范围和公式定义的精美蛋壳曲面。在本练习中,请注意我们如何串联使用代码块和现有 Dynamo 节点:我们将代码块用于繁重的数据提升,而 Dynamo 节点以可视方式布局来使定义清晰易读。
首先,通过连接上述节点创建曲面。请勿使用数字节点定义宽度和长度,而是双击画布并在代码块中键入 100;
通过在 “代码块” 中键入
0..1..#50
,定义一个介于 0 和 1 之间的范围(其中包含 50 个划分)。将该范围连接到 “Surface.PointAtParameter”,它会在曲面上提取介于 0 和 1 之间的 u 和 v 值。请记得通过在 “Surface.PointAtParameter” 节点上单击鼠标右键,将“连缀”更改为“叉积”。
在此步骤中,我们会使用第一个函数以在 Z 方向上向上移动点栅格。此栅格将基于底层函数驱动生成的曲面。添加新节点,如下图所示
我们不使用公式节点,而是使用内含以下代码行的 “代码块”:
(0..Math.Sin(x*360)..#50)*5;
。为了对该内容快速详细介绍,我们定义了一个内部带有公式的范围。此公式为正弦函数。在 Dynamo 中,正弦函数接收度数输入,因此为了获得完整正弦波,我们将x 值(这一范围输入介于 0 到 1 之间)乘以 360。接下来,我们希望每行都具有与控制栅格点相同数量的划分,因此我们用 #50 定义了 50 个细分。最后,乘数 5 只会增加平移幅度,因此我们可以在 Dynamo 预览中查看效果。
虽然上一个 “代码块” 正常工作,但它并非完全参数化。我们希望动态驱动其参数,因此我们会将上一步中的代码行替换为
(0..Math.Sin(x*360*cycles)..#List.Count(x))*amp;
。这使我们可以根据输入定义这些值。
通过更改滑块(范围介于 0 到 10 之间),我们会得到一些有趣的结果。
通过对数字范围执行转置,我们会反转幕墙波的方向:
transposeList = List.Transpose(sineList);
如果添加 sineList 和 tranposeList,我们会得到一个扭曲的蛋壳曲面:
eggShellList = sineList+transposeList;
我们会更改下面指定的滑块值,以“平静地控制”该算法。
最后,让我们使用“代码块”查询数据的隔离部分。要使用特定范围的点重新生成曲面,请在 “Geometry.Translate” 和 “NurbsSurface.ByPoints” 节点之间添加上述代码块。这包含以下文本行:sineStrips[0..15..1];
。这将选择前 16 行点(共 50 行)。通过重新创建曲面,可以看到我们已生成点栅格的隔离部分。
在最后一步中,为了提高此 “代码块” 的参数化,我们使用介于 0 到 1 之间的滑块来驱动查询。我们使用以下代码行来执行此操作:
sineStrips[0..((List.Count(sineStrips)-1)*u)];
。这看起来可能会令人困惑,但代码行提供的方法让我们可以快速地将列表的长度缩放为 0 到 1 之间的乘数。
滑块上的值 0.53
会创建刚好经过栅格中点的曲面。
如预期的一样,值为 1
的滑块会基于完整的栅格点创建曲面。
通过查看可视图形,我们可以亮显代码块并查看其每个函数。
1.第一个 “代码块” 替换 “Number” 节点。
2.第二个 “代码块” 替换 “Number Range” 节点。
3.第三个 “代码块” 替换 “Formula” 节点(以及 “List.Transpose” 、 “List.Count” 和 “Number Range” )。
4.第四个 “代码块” 查询一列列表,以便替换 “List.GetItemAtIndex” 节点。
代码块是深入 Dynamo 的核心编程语言 DesignScript 的窗口。从头进行构建的 DesignScript 可支持探索式设计工作流,它是一种可读且简明的语言,既可提供对少量代码的即时反馈,也可扩展到大型和复杂交互。DesignScript 还构成引擎的支柱,该引擎推动 Dynamo 的大部分方面“处于底层”。由于在 Dynamo 节点和交互中找到的几乎所有功能都与脚本语言有一对一关系,因此有独特的机会在基于节点的交互和脚本之间以流畅的方式进行移动。
对于初学者,节点可以自动转换为文本语法以帮助学习 DesignScript,或者只是缩小图形较大部分的大小。这是使用名为“节点到代码”过程完成的,将在“DesignScript 语法”部分中详细介绍该过程。有经验的用户可以使用“代码块”创建现有功能的自定义映射,并使用许多标准编码范例来创建用户编写的关系。在初学者和高级用户之间,有大量可加快设计速度的快捷方式和代码段。虽然对于非程序员来说,术语“代码块”可能有点令人畏惧,但它既易于使用又功能强大。初学者可以高效地使用代码块(最少编码),高级用户可以定义脚本化定义以在 Dynamo 定义中的其他位置重新调用。
简而言之,代码块是可视化脚本环境中的文本脚本界面。它们可以用作数字、字符串、公式和其他数据类型。代码块专为 Dynamo 设计,因此用户可以在代码块中定义任意变量,这些变量会自动添加到节点的输入:
使用代码块,用户可以灵活地确定如何指定输入。以下是通过坐标 “(10, 5, 0)” 创建基点的几种不同方法:
当您了解库中更多的可用函数时,您甚至会发现键入“Point.ByCoordinates”比在库中搜索和查找正确的节点更快。例如,当键入 “Point.” 时,Dynamo 会显示可能应用于点的函数列表。这使脚本更加直观,有助于了解如何在 Dynamo 中应用函数。
代码块位于 “核心”>“输入”>“操作”>“代码块” 中。但更快的是,只需双击画布,代码块即会显示。此节点经常被使用,因此赋予其完全双击权限。
代码块在数据类型方面也很灵活。用户可以快速定义数字、字符串和公式,且代码块将提供所需的输出。
在下图中,您可以看到“旧学校”的操作方法有点长:用户在界面中搜索预期节点、将节点添加到画布,然后输入数据。使用代码块,用户可以双击画布来调出节点,然后使用基本语法键入正确的数据类型。
数字、字符串和公式节点是三个 Dynamo 节点示例,这些节点相较于代码块无疑是过时的。
“过去”
代码块
数据类型
标准 Dynamo
等效代码块
数字
字符串
序列
范围
获取索引处的项目
创建列表
连接字符串
条件语句
节点
等效代码块
注释
任何运算符(+、&&、>=、Not 等)
+、&&、>=、! 等
请注意,“Not”变为“!”,但该节点被称为“Not”以区分“阶乘”
布尔值 True
true;
注意小写
布尔值 False
false;
注意小写