如何在E3上调用图龙图形库进行图形生成模块开发

之前大家应该都有听说E3也是一款功能强大的参数化设计工具,今天这个案例带大家上手E3的图形功能。

案例辅助文件在此【建议跟帖从零开始练习,如遇到问题可借助此文件差错】
图龙001.zip (24.8 KB)

新建一个E3项目,在package.toml文件中复制下面这串代码,这是E3在每个项目中调用不同运算功能模组的操作方式(这部分工作未来会给大家更新一个简易版,目前是专业版的)

platform = "net8.0"

[dependencies]
"E3.Core" = "nuget:1.2.4"
"Tulo.Clipper" = "1.3.1"
"Tulo.Geometry" = "1.3.4"
"Tulo.Intersects" = "1.3.1"
"Tulo.Triangulation" = "1.3.2"

编辑完的结果注意Ctrl+S保存。然后关闭项目重新打开。这个过程是未来让我们的项目正式加载这些运算功能模组。

重新进入文件后,能够看到模块菜单中新增加的Tulo(图龙图形库)

这样项目开发的环境文件就配置好了,下面我们正式开始

/
/
/

让我们先来学习如何创建一个点,双击面板调出模块菜单,键入point,找到Geomoetry–Point3–[Constructor]Point3(float,float,float),这个功能卡的名字也代表了这个运算模块的功能,这部分我们后续单独开帖为大家深入剖析。【这里重点是如果名字太长,大家看不到名字后面内容时,注意面板最下方有个拉棒可以往后拉,把名字看全】

调出的功能模块是用三个坐标绘制一个点,接下来我们用三个input float,给这三点点分别赋予三个数值



此时我们点击模型窗口并没有看到这个点,这是因为程序还没有运行,同时我们也还没有告诉程序这个点是否要显示出来,或者以何种方式显示。

下一步我们调出display和print两个模块,分别对点的信息进行显示。

然后点击程序运行,查看运行结果,注意右上方【屏幕】按钮打开模型窗口,右下角【!】按钮打开信息打印窗口,此时我们看到这个点已经生成了。

/
/
/

接下来我们来看怎么来画多个点:
在图龙最基础的图形库中并不存在像Grasshopper中的等差数列运算器那样可以一次性的给我们提供一个数列。但作为一个强大的研发工具,我们可以通过最基础的程序运算快速的还原这个功能。用到核心功能就是这个叫for的功能模块:这个模块可以被理解成为一个计数器,它并不是每次运算都给我们生成一串数列,而是通过建立循环算法,一次又一次的为我们提供变化的单个数据。比如目前的设置,start【0】stop【10】step【1】意思是从0离开时到10结束,中间每次循环递增数值为【1】。所以这个功能卡片会被触发10次循环运算,每次计算输出的数值都在递增,且都是单一数据。(注意生成的数据没有0,因为第一次循环的计算就能就是star+step即0+1,输出的结果是1)

让我们尝试把这个生成的递增数值提供给x,用它来生成之前的点。此时我们能看到一共我们生成了10个点,同时我们能在打印记录之中看到这些点是依次生成的。

这个时候如果我们把点数调成非常多,比如10000个,我们会看到这些点并不是一次性被生成出来的,而是有先后的顺序,它们被计算并显示的过程就像一个动画。
image

这是因为我们通过for创建了一个最建议的循环程序,这个程序在这个循环里被跑了一万次,并且每次都经历了for【1回】–display【1回】–print【1回】–for【2回】–display【2回】–print【2回】–for【3回】–display【3回】–print【3回】–for【4回】–display【4回】–print【4回】……
这样的一个过程。我们看到的点的增长动画,就是在着一万次循环中,分别生成的。

在这个过程中,我们能清晰的感受到流程线的意义:这个循环是从for的loop端发的,进入到display去显示点,然后去print打印这个点的信息,在print之后流程结束了,自动回到for的loop进入下一次循环,一直到for的循环结束,运算流程可以从for的Done输出端继续链接后续的程序。

ok,解析来继续用这个方法制作一个二维点阵**【注意先把for里的stop值改到100,先生成1万个点,数据量过大程序会卡】**,在第一个for和display之间再追加一个for,将第二个for的i值比配给点的y坐标。因为第一个for建立了10个循环,每次给x坐标提供一个值,这里创建第二个for意思是在上一级循环中,每次循环里再次创建第二级内部循环。相当于有十次大循环,生成了不同的x值,然后每个大循环里又出了十次小循环,给每个x值匹配10个不同的y值。

这次我们生成的效果是这样的。
point2

相信已经熟练掌握了GH的朋友第一次接触用这种方式创建点阵会很奇怪:为什么不能一个功能模块就直接创建一个点阵呢?其实这个问题也好理解,那就是E3的本质是算法研发工具,这个案例为大家展示的即是编写一个点阵生成算法的底层过程。也可以说我们可以基于E3开发一个类似GH的参数化设计工具出来。

从另一个方面讲,GH和其他编程软件相比,还是更容易上手一些,这其中的原由之一就是上述的运算过程已经被GH电池高度封装,让使用者不被感知到。这个过程虽然对萌新友好,但是也限制了程序的底床,使其程序编写能力被局限在了一个范围内,同时也让模型生成程序变得更加笨重,GH里大家很少感受到循环的存在就是一个例子。而我们最熟悉的树形数据,其实也是对GH中无法实现循环套循环这类算法的一种补偿规则。

这里我还是要肯定GH1的,毕竟我个人也用了十五年,还为它编写过书籍教材。想强调E3和GH是无缝链接的,两者可以协同跑,这是我们对GH和参数化设计师的最大认同和福利。同时既然要重新定义国人自己的参数化设计平台,我们就得打破过去的限制,直击程序的本质。我们正在闭合的RPA扩展包都将是一些非常便于操作的集成模块。而作为这些智能程序的载体,E3平台的使命是为广大的算法程序开发者们提供一个更自由、更灵活的无代码开发平台,这也是E3的创造者KavinD最初的理念。

/
/
/

回到这个案例,目前这么写其实很占用资源,原因是display和print都在循环内部,被触发了1w次,这是为什么出现动画效果以及1w个点也会运算卡的原因。接下来我们把它优化一下。方法就是我们先来创建一个点的列表,把这1w个点都放进列表中,然后一次性显示和打印。

创建一个变量,类型设置成point,名字取名为【点阵A】

注意这个变量是在循环开始之前创建的,一定不要放在循环里,否则会被执行1w次……

然后找到另一个核心功能模块:list下面的Append,它是用来往变量里装数据的。

在每次循环结束时,我们要把新生成的点装到【点阵A】这个变量里,生成一个新的数据列表。

然后从第一级for的Done输出端,连出来display和print,把变量也关联好。此时我们在运行就能够看到运算时长从之前的4s动画编程了106ms,其实这个计算时间还包含了一次网络请求,如果扣去网速的延迟,这个计算速度会更快。

/
/
/

到这里一个基本的矩形点阵算法就写好了,最好一步也是最重要的一步,让我们把它封装成一个功能卡片。

双击程序起始端这个功能卡,打开程序的参数创建面板,增加程序的输入端和输出端。输入参数面板打开后点击【+】按钮可以创建变量。

点击新建的参数,可以设置参数的名字、数据类型(点、数值、字符)、数据形式(单个、列表、字典)、以及是否为必填参数

这里我们创建三个输入参数,x、y、S。均为小数、单个数据、不必填

输出端创建一个P。设置point3,数据列表。创建好之后不用保存,直接点【x】关掉即可。

回到编辑面板,调出core下的return模块,这个模块是程序的结束,我们可以看到刚才设置好的出口已经出现在了return上。

让我们把对应的数据相互之间关联上,去掉不必要的display和print,这样一个新模块就封装好了。

此时我们尝试运行一下,系统会提示有错误无法运行,因为目前我们还没有给这个算法配置它的输入参数。

接下来,我们新建一个ncf文件

此时我们看到main.ncf这个文件在新文件中已经可以作为一个模块被调用

最后我们用input给它输入参数,后面连上display显示这些点。然后运行程序~~~


自此恭喜各位已经开发了一个新的点阵功能模块~enjoy it

补充一下,如果大家想给卡片名字命名,直接修改ncf名字,然后重新调出就可以了

增加一节内容,在这个案例基础之上,继续带大家体验E3的参数化建模能力:

在上一版模块的基础上,我们再增加一个z方向的数值参数,并把它赋予给point的z坐标。这样就可以在外部直接控制这套xy点阵的z轴。

保存后直接拖拽左侧的ncf文件,就可以调用这个新的模块,注意每次修改完的ncf,需要重新保存,且需要重新调用才能得到更新,旧的已被调用的模块将继续延续旧的版本,不会受到新的影响。

让我们试着重复调用两个新的矩形点阵模块,xys赋予相同的值,z轴赋予不同的值。然后运行一下~
这样我们就得到两个上下不同层的点阵。

接下来,我们要尝试将这两组点一一对应去连线,双击面板,键入line,调出[Constructor] Line (Point3、Ponit3)这个模块,功能是两点间连线。

此时我们需要注意一个问题,那就是我们创建的案例中ncf的输出端是list(列表、多个数据),而两点连线模块的输入端是item(单项、单个数据),两者因为数据容器的类型不同,无法直连。这就需要我们在这里新建立一个循环,由一个分发数据的模块将两个列表中的点,分别一对一对的分发出来,交给line,每次循环只分发两个需要之间连线的点。

这个问题虽然听起来复杂,但是操作起来也简单,只需要我们调用一个模块叫MutilEach。每个模块可以触发循环算法,左侧连入多个不同的列表,右侧在每次循环中会根据输入列表的排序依次输出一个数据。这样就可以通过它来创建一个列表与列表之间、数据根据排序一一对应计算的运算效果。讲到这输入grasshoppper的朋友应该能有所体会,真正是我们最熟悉的longestlist列表运算法则,而MultiEach也遵循longestlist法则或者Shortestlist法则。

接下来,我们将程序流程线和数据传递的连线如图链接好,再次运行,注意生成的line数据也需要DIsplay才能被程序显示出来。连好后点击运行~

如果我们不希望在每次的连线循环中都触发一次display(这样占据运算资源)就可以和上面讲述的方法一样,通过Create list 创建一个放line的变量,然后用Append在每次循环里存储这个变量。最好在循环结束时,统一显示所有的连线。

我们也可以将这套操作重新创建一个点阵连线的ncf模块。让它变成我们开发的一个功能包。

/
/
/

此外,在E3中,程序流程设计的方式非常自由,我们可以用不同的程序流生成完全一样的结果,像这样的改动,我们就可以通过一个Sequence模块对流程进行拆解,在这个模块中程序运行会被拆解成为若干个步骤,先执行S1,然后S2、S3……最后执行SE,这样拆解后的步骤会使得流程更加清晰。像演示文件中的改动,意思就是我们先绘制这些数据,最好用一个类型为any、名字为VarA的变量,将所有要显示的数据装进去,然后再Display。

/
/
/

1 个赞

分享E3参数化建模新手集合

练习01 随机彩色圆柱

总体生成思路

程序从 “E3 图龙 003” 模块开始,通过双重循环(For Loop)控制生成圆柱体的数量和布局。在循环内部,利用多个Random模块生成随机数,来确定圆柱体在平面上的位置(X、Y 坐标)、高度(Z 坐标)、半径以及颜色。接着,依据这些随机参数,通过Point3模块创建三维点,结合GET Vector3.ZAxis获取的 Z 轴向量,利用Plane模块创建平面,再使用CreatePolygon模块在平面上创建多边形(近似圆形底面),随后通过CreateExtrude模块将多边形拉伸成圆柱体。最后,利用RGBColor模块生成随机颜色,由Display模块将所有生成的圆柱体进行可视化展示。

模块用途

模块名称 用途
E3 图龙 003 作为程序的起始模块,用于触发整个流程或者提供初始的全局参数等,是整个程序运行的起点。
For Loop(第一个) 设置外层循环,起始值为 0,步长为 2,循环到 30 结束。用于控制生成圆柱体在 x 维度上的布局数量和迭代次数。
For Loop(第二个) 设置内层循环,起始值为 0,步长为 2,循环到 30 结束。与第一个For Loop配合,在内层进一步细化布局,控制生成圆柱体在 y 维度上的数量和迭代情况。
Random(X、Y 坐标相关) 生成范围在 -1 到 1 的随机数,用于确定圆柱体在平面上 X、Y 方向的随机位置。
Random(Z 坐标相关) 生成范围在 0.2 到 0.8 的随机数,用来确定圆柱体的随机高度。
Random(半径相关) 生成范围在 0.5 到 0.8 的随机数,用于设定圆柱体底面半径大小。
Random(颜色相关) 生成范围在 50 到 255 的随机数,用于确定圆柱体颜色的分量。
Point3 根据传入的 X、Y、Z 坐标值创建三维空间中的点,为后续创建平面和几何体提供位置信息。
GET Vector3.ZAxis 获取三维空间中 Z 轴的方向向量,用于确定平面的法向量方向等与方向相关的操作。
Plane 根据传入的原点坐标(origin)和法向量(normal,此处使用GET Vector3.ZAxis获取的 Z 轴向量 )创建一个平面,作为后续创建多边形的基础平面。
CreatePolygon 在指定平面(plane)上,按照给定的半径(radius)和分段数(segments,这里为 48 )创建一个多边形,近似于圆形,作为圆柱体的底面。
CreateExtrude CreatePolygon创建的多边形(边界boundary ),沿着指定方向(direction,此处用 Z 轴方向 )拉伸,生成三维的圆柱体。
RGBColor 根据传入的红(r)、绿(g)、蓝(b)分量值创建颜色对象,这里绿色和蓝色分量固定为 0,红色分量由随机数确定,用于设置圆柱体的颜色。
Display 将生成的所有圆柱体对象(objects)进行可视化展示,可设置是否清除之前内容(clear )以及显示颜色(color )等属性。

/
/
/

练习02 动态螺旋点阵

002

总体生成思路

程序从“图龙新手练习”模块触发起始信号,通过“For 循环”模块设定从0到100、步长为1的循环迭代过程。在每次循环中,利用“MathHelper求正弦值”和“MathHelper求余弦值”模块对循环计数等数值进行数学运算,再结合乘法模块进一步处理数值。通过这些运算结果,使用“Point3”模块创建三维点坐标,进而确定“Circle”模块所定义圆的中心点位置及相关参数。循环过程中,通过“暂停执行”模块控制每轮迭代的时间间隔为100毫秒,最后利用“Display”模块将创建的圆等对象进行可视化展示。

运算模块及解释说明

模块名称 用途 参数说明
图龙新手练习 作为程序的起始模块,触发整个流程
For 循环 设置循环,控制迭代次数。起始值为0,停止值为100,步长为1 start:循环起始值,取值0;stop:循环停止值,取值100;step:循环步长,取值1
Sleep 暂停执行 暂停程序执行,控制执行节奏,暂停时间为100毫秒 ms:暂停时间,取值100
Display 可视化展示对象,可设置是否清除之前对象及显示颜色 objects:要展示的对象;clear:是否清除之前对象,默认false;color:显示颜色,可设置
Circle 根据中心点和半径创建圆 center:圆的中心点(三维点);radius:圆的半径
Point3 根据x、y、z坐标值创建三维空间中的点 x:x坐标值;y:y坐标值;z:z坐标值
乘法模块(多个) 对输入数值进行乘法运算,用于数据处理 输入数值1、输入数值2等,具体根据连接的输入数据而定
MathHelper求正弦值 对输入值求正弦值,用于数学计算 val:输入数值
MathHelper求余弦值 对输入值求余弦值,用于数学计算 val:输入数值
> input(数值比较模块) 将输入值与5进行比较,输出布尔值结果 input:输入数值,本程序中取值5

002-2.gif

升级版 总体生成思路

main2 模块启动流程,核心靠双重循环驱动动态动画:外层 For 循环作为 “帧控制器”,每轮迭代对应动画一 “帧”,迭代时先通过 “清空列表” 模块删掉上一帧数据,保证画面不叠加;内层 For 循环在每帧内运行,利用数学运算、点创建等模块生成该帧所需图形元素(如点、圆 )。

每帧元素生成后,“暂停执行” 模块控制帧间间隔(类似 sleep 定速),接着 Display 模块渲染当前帧画面。如此循环,外层循环逐帧切换、内层循环填充单帧内容、清空旧帧 + 暂停控速 + 实时渲染,让图像实现 “一帧一更新” 的动态变化效果,替代上一版元素叠加模式,达成画面动态更替。

相关项目文件:
图龙新手练习.zip (28.3 KB)

发一个图形模块开发中的项目实例

目前开放的图龙运算模块允许我们调用非常底层的图形定义算法,我们可以在次基础上,构架各种算法编程模式和应用体系。

举个例子,如果我们希望在E3平台模仿GH的操作逻辑去定义一套电池出来也是可行的。

相信这样一版图形建模的操作逻辑老参数化设计师应该很容易看懂,先一个模块创建矩形方阵,然后每个格子随机offset偏移一下。简单清晰不绕脑~

让我们来接着这个项目看看这样的模块开发是如何实现的:

首先来看目前这个正在运行的文件是main.ncf。这个文件调用了一个开发模块叫Square.Box2,这个模块并不是E3目前的自带模块,而是我们在这个研发项目里机遇底层图龙图形库二次开发的成果。

它的开发文件对应这另一个叫做Square.Box2.ncf(生成矩形网格)的算法模块文件。

而在这个文件中又包含了Square.ncf(生成矩形点阵)和DataMatching.ncf(用行列值查找点)两个自定义开发模块。

给大家展示一下Square.ncf和DataMatching.ncf这两个文件的算法逻辑内容。


最后在Square里还有一个内置的模块是Serise.ncf(生成等差数列)


是的,大家可以体会到,在E3中的编程更强调.ncf文件之间的嵌套关系,先这个案例就呈现出下图这样的结构。

在这个层面上,算法模块的功能和进出参数都是可以被重新设计和定义的。不同的打包思路和参数设计能够决定这些模块未来不同的功能领域和使用习惯。所以这里大家能体会到为什么我们说E3是一款开发工具,在它的基床上可以开发出各种类型的整体应用算法、拼装应用算法的工具,以及开发工具的工具。

这里分别举例子说明【整体应用算法】对应着我们在gh上写了一个建筑方案项目的一键生成程序;【拼装应用算法的工具】可以理解为我们诺亚一直在宣传的第五代RPA模块,它们是用来快速开发自定义绘图逻辑的模块;而【开发工具的工具】可以理解为grasshopper平台这个层级。这三个层级开发目标并不一样,对产品的属性要求也截然不同。未来我们再找机会去聊开发目标面向哪个层级产品的问题。这里主要是想给大家展示一下E3的开发环境,便于大家理解定位我们学习也好、开发也好,目前处于哪个阶段。

项目文件公开出来,仅供参考:

main-250903.zip (41.2 KB)

/

/

/

补充说明:有朋友尝试自己重写这个模块,遇到一个新版本Frist无法兼容空集列表的问题,可以用以下方式讲Frist替换成Foreach。则可以正确运行(原理是Foreach遇到空集就不会触发loop循环)

新增加一个三角形随机偏移闪动的案例
三角随机偏移


项目文件:
三角形随机偏移闪动.zip (50.5 KB)

/

/

/

补充说明:版本更新导致Frist遇到空集会拦截报错,建议自学的朋友将First替换成Foreach

新整一个分组随机移动的例子包含个体随机、行随机、列随机



项目文件:
分组随机移动.zip (43.1 KB)

矩阵递增旋转



项目文件:矩阵递变旋转.zip (42.0 KB)

曲面动态网架
动态网架2.gif


项目文件:
动态曲面网架.zip (51.5 KB)

扩展1:尝试过程(不提供文件)


扩展2:尝试过程(不提供文件)

扩展3:尝试过程(不提供文件)

扩展4:曲面网架(提供文件)

项目文件:
动态曲面网架.zip (90.3 KB)


跟到这里的时候出现的问题

@leungHB 这个bug还没修复,目前work round是,避免在done或者if里return,在前面加sequence来组织,如下:

好的 OKOK:ok_hand: :ok_hand:

Sequence 是分步骤导流的模块,执行后,先执行S1流程,再执行S2流程,最后执行SE流程,目前所有的双流程出口的模块(并不对)在应用时都难免存在分流后程序搭建不完整的问题,如果A分支流程中创建的变量,在B分支流程里想读取,或是默写程序必要的模块被放置在分支流程中(有可能触发不到)这个报错指的就是类似得问题(我理解属于程序编程领域的常见问题)。这个bug是报错系统谨慎拦截了,近期会修复。实际开发过程中用Sequence好一些

好习惯1:S1里优先创建全局用的变量
好习惯2:SE里放置Return和Display、Print这些生成结论
好习惯3:遇到喜欢或分叉独立一个S,不和其他步骤产生流程性的交集

好的,清泉说你憋大招呢 :grinning_face:

本章总结:

过去两周断断续续的持续尝试用E3开发,总体体会是:

如果能规避一些常见的编程错误,也就是运行前会报错的情况,E3的体验还是很给力的。我也在尝试总结一些避免常见错误的应用习惯,KavinD也计划让报错机制表达的更加清晰。这部分感受相信会越来越丝滑~

在这段自学的时间里,是我试图在E3上复现一些gh电池的功能,希望在E3上能够复现一套类似GH操作习惯的模块组。一方面这和我个人过往的使用习惯比较贴合,另一方也希望众多的GH玩家在上手E3的时候能够无缝衔接。于是我在第一阶段用大概三周的时间做了这些升级包



说明文档:Tulo.LSO.zip (29.1 KB)

说说核心的感悟,我新写的这些包,主要是在把E3一些底层的面向【Item】变量容器编程的功能块,通过内置打包【创建变量】和【循环计算】的方法升级成了面向【List】变量容器编程的功能块

有了这些包我们就可以丝滑的做一些“算法唱片”了~

说明:文中的【Item】和【List】指代的是一系列配套的输入端为Item或List的运算模块,它们因为输入数据容器类型的不同,导致了在实际使用过程中,建模思维方式存在较大的变化。所以文中【Item】和【List】也寓意了不同的编程思维“流派”。

在实际操作的感受中,面向【Item】和【List】不同的变量容器,图形的编程逻辑思维也是不一样的。面向【Item】的编程思维更像是利用循环套循环的方式逐一处理程序中的单个元素。其思维方式和写代码编程很接近。更加关注编程相关的知识点和编程经验。面向【List】的编程思维则省去了对底层程序思维频繁的思考,能够直接把编程人员的注意力集中在几何逻辑上,也就是更纯净的思考点线面的空间逻辑。

那么如此说来参数化设计师是不是就只掌握面向【List】的工具流就可以了呢?
很遗憾,我实际体验完之后【List】是有局限的,它是被降维后的或者说阉割版的编程,为了更容易使用,强加了一些辅助规则,形成了一定的应用局限。所以现在在诺亚开发团队中,除了我以外是没人面向【List】开发的,都是面向【Item】。

GH是不是面向【LIst】?还不完全是。 GH其实是一套面向【Tree】来编程的思维逻辑,Tree就想当于多维度的【List】。多个List之间通过path被巧妙的组合了起来,并赋予一定定制化的计算规则(如Longestlist法则)。我猜测这也是David看到了【LIst】的局限后再一次给工具流的操作能力升维的思考。

那么【Tree】是不是就是最好的?我不这么认为。 大家知道国内我是第一个总结讲解【Tree】的人,我脑海中的参数化建模思维和Tree是深度绑定的。都就在过去的几周里,给了开发丰富【List】,我对【Item】越来越熟悉,也发现【List】的升维方法可以有很多种,【Tree】只是其中一种选择。所以这样一看,每种可能性都能够开发出一整套的参数化设计软件,它们的应用思维本质一样,但驱动它们的建模思路可能各不相同。面对可预见到的各种应用体系及思维分支,我更提倡接受最本质的,最底层的【Item】工具流。

从产品推广的角度讲,应用越简洁越好,但简洁也意味着局限。 产品的推敲就是在某一个特定的维度上反复拿捏局限和简洁的平衡点。而这个平衡点也会随着应用生态的进步动态位移。

所以我决定会为大家持续的更新这套【List】工具流,让它在处理几何逻辑的时候更加丝滑。同时也会开源其内部文件,让大家可以以此学习如何用【Item】工具流去实现等效的开发。
这套工具我会另行开贴与大家分享:E3开发实例开源:Tulo.LSO(List工作流模块组)

补充几点干货:
1、除了【Item】、【List】、【Tree】以外,还有一个重要的变量容器是【Dictionary】,它是信息模型的基础。【Dictionary】的工具流也是独立成套的,而诺亚第五代开发思想,强调直接对【信息模型】进行几何编辑。其中的信息模型就是一种类似【Dictionary】的【Type】;
2、比较几种工具流操作思维,【List】最容易学,【Dictionary】次之。【Item】和【Tree】学习难度差不多都很绕脑子。【Item】和【Dictionary】组合的体系可以把智能化设计赛道打通关,不需要【List】和【Tree】;
3、所以如果诸位想搞图形算法开发的话,可以用【List】先过渡一下,学起来快,然后就可以直奔【Item】了。

哈哈哈,大招不能老憋,有保质期 :sweat_smile:

后续案例:
三角面破碎


项目文件:三角形破碎-250724.zip (77.8 KB)

第一张图 看着有点像GH的逻辑了 :grinning_face:

嗯,这套工具流我计划一直更新



项目文件:
六边形转立方体凹凸-250806.zip (132.5 KB)



项目文件:
拼图随机旋转B-250808.zip (157.7 KB)