Добавим еще больше уровней в иерархию и углубимся в нашу кроличью нору. Структура данных может быть гораздо более объемной, чем простой двумерный список списков. Поскольку списки являются самостоятельными элементами в Dynamo, мы можем создать данные с практически неограниченным количеством измерений.
Это похоже на матрешку. Каждый список можно рассматривать как один контейнер, который содержит несколько элементов. Каждый список обладает собственными свойствами и рассматривается как отдельный объект.
Набор матрешек (фотография предоставлена Zeta) является аналогией многомерных списков. Каждый слой представляет список, и каждый список содержит элементы. В Dynamo каждый контейнер может содержать несколько контейнеров (представляющих элементы каждого списка).
Многомерные списки сложно объяснить визуально, но в данном разделе есть несколько упражнений, которые помогут вам разобраться в работе со списками, число измерений которых превышает два.
Сопоставление — возможно, самый сложный аспект управления данными в Dynamo, особенно когда речь идет о сложных иерархических структурах, состоящих из списков. В рамках приведенных ниже упражнений мы рассмотрим случаи, в которых следует использовать сопоставление и комбинации при работе с многомерными данными.
Основные сведения по работе с узлами List.Map и List.Combine можно найти в предыдущем разделе. Эти узлы будут использованы для работы со сложной структурой данных в последнем из приведенных ниже упражнений.
Скачайте файл с примером, щелкнув ссылку ниже.
Полный список файлов с примерами можно найти в приложении.
Это первое из трех упражнений, направленных на работу с импортированной геометрией. От упражнения к упражнению структура данных будет усложняться.
Начнем с файла SAT, расположенного в папке с файлами для упражнения. Добавим его в приложение с помощью узла File Path.
Узел Geometry.ImportFromSAT импортирует геометрию в Dynamo и отображает ее в виде двух поверхностей.
Для простоты в этом упражнении вы будете работать только с одной поверхностью.
Чтобы выбрать верхнюю поверхность, задайте индекс 1. Для этого добавьте узел List.GetItemAtIndex.
Отключите предварительный просмотр геометрии в области предварительного просмотра Geometry.ImportFromSAT.
Теперь нужно преобразовать поверхность в сетку точек.
1. С помощью узла Code Block вставьте две следующие строки кода:
0..1..#10;
0..1..#5;
.2. Используя узел Surface.PointAtParameter, соедините два значения Code Block с входными параметрами «u» и v. Задайте для параметра Переплетение этого узла значение Векторное произведение.
3. Полученная структура данных отображается в области предварительного просмотра Dynamo.
Затем используйте точки из последнего шага для создания десяти кривых вдоль поверхности.
Чтобы отобразить структуру данных, соедините узел NurbsCurve.ByPoints с портом вывода узла Surface.PointAtParameter.
Для получения более четкого результата можно отключить предварительный просмотр в узле List.GetItemAtIndex.
Базовый узел List.Transpose позволяет поменять местами столбцы и строки в списке списков.
При соединении порта вывода узла List.Transpose с узлом NurbsCurve.ByPoints вы получите пять кривых, идущих горизонтально вдоль поверхности.
Для получения того же результата можно отключить предварительный просмотр в узле NurbsCurve.ByPoints на предыдущем шаге.
Усложним задачу. Предположим, что нам нужно выполнить определенное действие с кривыми, которые мы получили в предыдущем упражнении. Например, нужно связать эти кривые с другой поверхностью и выполнить лофтинг между ними По сути, логика остается прежней, но задача требует более внимательной работы со структурой данных.
Начнем с операции, уже знакомой вам по предыдущему упражнению. Изолируйте верхнюю поверхность импортированной геометрии с помощью узла List.GetItemAtIndex.
Используя узел Surface.Offset, задайте значение 10, чтобы сместить поверхность.
Как и в предыдущем упражнении, добавьте узел Code Block с двумя следующими строками кода:
0..1..#10;
0..1..#5;
.Соедините порты вывода этого узла с двумя узлами Surface.PointAtParameter и задайте для параметра Переплетение каждого из них значение Векторное произведение. Один из этих узлов соединен с исходной поверхностью, а второй — с поверхностью смещения.
Отключите предварительный просмотр этих поверхностей.
Как и в предыдущем упражнении, соедините порты вывода с двумя узлами NurbsCurve.ByPoints. В результате отображаются кривые, соответствующие двум поверхностям.
С помощью узла List.Create можно объединить два набора кривых в один список списков.
В результате создаются два списка с десятью элементами, каждый из которых представляет собой связанный набор NURBS-кривых.
С помощью узла Surface.ByLoft можно создать визуальное представление этой структуры данных. Узел выполняет лофтинг для всех кривых в каждом списке.
Отключите предварительный просмотр узла Surface.ByLoft на предыдущем шаге.
Как вы помните, узел List.Transpose позволяет поменять местами столбцы и строки в списке списков. В результате использования этого узла два списка из десяти кривых каждый преобразуются в десять списков из двух кривых каждый. Теперь каждая NURBS-кривая связана с соседней кривой на другой поверхности.
С помощью узла Surface.ByLoft мы получили реберную конструкцию.
Далее демонстрируется альтернативный процесс получения этого результата
Перед началом отключите предварительный просмотр Surface.ByLoft во избежание путаницы.
Вместо узла List.Transpose можно использовать узел List.Combine. Он выполняет роль «комбинатора» для каждого вложенного списка.
В данном случае мы используем List.Create в качестве «комбинатора» для создания списка по каждому элементу во вложенных списках.
Добавив узел Surface.ByLoft, мы получаем те же поверхности, что и на предыдущем шаге. В данном случае узел Transpose является более простым вариантом, но при работе с еще более сложной структурой данных надежнее будет использовать узел List.Combine.
Вернемся на несколько шагов назад. Если вы хотите изменить ориентацию кривых в реберной конструкции, узел List.Transpose следует применить до соединения с узлом NurbsCurve.ByPoints. В результате столбцы и строки поменяются местами, и мы получим пять горизонтальных ребер.
Продолжаем усложнять задачи. В этом упражнении мы используем обе импортированные поверхности, чтобы создать сложную иерархическую структуру данных. По сути, вам предстоит выполнить то же самое действие, пользуясь той же самой логикой, что и ранее.
Вернемся к файлу, импортированному в предыдущем упражнении.
Как и в предыдущем упражнении, используйте узел Surface.Offset, чтобы задать значение смещения, равное 10.
Обратите внимание, что добавление узла смещения привело к созданию двух поверхностей.
Как и в предыдущем упражнении, добавьте узел Code Block с двумя следующими строками кода:
0..1..#20;
0..1..#20;
.Соедините порты вывода этого узла с двумя узлами Surface.PointAtParameter и задайте для параметра «Переплетение» каждого из них значение Векторное произведение. Один из этих узлов соединен с исходными поверхностями, а второй — с поверхностями смещения.
Как и в предыдущем упражнении, соедините порты вывода с двумя узлами NurbsCurve.ByPoints.
Посмотрите на выходные данные узла NurbsCurve.ByPoints и обратите внимание, что они представляют собой список, состоящий из двух списков, что является более сложной структурой, чем в предыдущем упражнении. Данные упорядочиваются по базовой поверхности, поэтому в структуру данных добавлен еще один уровень.
Обратите внимание, что структура данных в узле Surface.PointAtParameter стала более сложной. В нем представлен список, состоящий из списков списков.
Перед продолжением отключите предварительный просмотр существующих поверхностей.
С помощью узла List.Create объедините NURBS-кривые в одну структуру данных, чтобы создать список, состоящий из списков списков.
При подключении узла Surface.ByLoft мы получаем новую версию исходных поверхностей, так как они остаются в собственном списке в соответствии с исходной структурой данных.
В предыдущем упражнении мы использовали узел List.Transpose для создания реберной конструкции. В этом случае данная функция не подходит. Перенос следует использовать с двумерными списками, но мы имеем дело с трехмерным списком, поэтому перестановка столбцов и строк не сработает. Поскольку списки являются объектами, то узел List.Transpose выполнит перестановку между списками с вложенными списками, но она не затронет NURBS-кривые в списках на уровень ниже.
В этом случае List.Combine является более подходящим инструментом. При работе с более сложными структурами данных используются узлы List.Map и List.Combine.
Используя List.Create в качестве «комбинатора», создайте структуру данных, которая лучше подойдет для ваших целей.
Структуру данных все еще требуется перенести на один уровень вниз по иерархии. Для этого используйте узел List.Map. Его работа аналогична узлу List.Combine, однако в нем используется только один список входных данных, а не два или больше.
К узлу List.Map будет применена функция List.Transpose, которая меняет местами столбцы и строки вложенных списков в главном списке.
Наконец, выполните лофтинг между NURBS-кривыми с использованием соответствующей иерархии данных, чтобы получить реберную конструкцию.
Добавим глубину геометрии с помощью узла Surface.Thicken с входными параметрами, как показано на изображении.
Будет полезно добавить поверхность, поддерживающую конструкцию, поэтому добавьте еще один узел Surface.ByLoft и используйте в качестве входного параметра первый вывод узла NurbsCurve.ByPoints из предыдущего шага.
Чтобы не перегружать экран, отключите предварительный просмотр этих узлов. Щелкните узел правой кнопкой мыши и снимите флажок «Предварительный просмотр», чтобы лучше рассмотреть результат.
Теперь увеличьте толщину выбранных поверхностей.
В результате мы получили нечто, похожее на слегка неустойчивое кресло-качалку. Зато сколько данных ушло на его создание!
Наконец, изменим направление бороздок. Для этого выполните процедуру, аналогичную преобразованию, которое вы уже использовали ранее.
Чтобы заполнить еще один уровень иерархии, используйте узел List.Map с функцией List.Tranpose, чтобы изменить направление NURBS-кривых.
Если требуется увеличить количество канавок, то данные узла Code Block можно изменить на следующие:
0..1..#20;
0..1..#30;
.
Если первая версия кресла-качалки была обтекаемой, то вторая получилась более похожей на колесо внедорожника.