Top
Работа

Искусство, процедурность, перфорация, печать

Алик Кадум подробно рассказал о трех методах процедурной модификации поверхности объектов для SLS-печати, которые он применил, работая над проектом австрийского скульптора Oliver Laric.

Вступление

Привет. Начну со знакомства. Меня зовут Алик Кадум. Жил и живу в Одессе, Украина. Занимаюсь 3D-графикой уже более семи лет. Никогда не мог выбрать для себя какую-то одну узкую специализацию: было интересно все. Ну, кроме дизайна интерьера. Так что я своего рода швея-гитаристка. Начал интересоваться графикой на первом курсе академии, когда учился на архитектуре (тут место для ваших шуток про дизайн интерьеров и диванчики со стоков). Я немного умел рисовать, но академическому рисунку, композиции и живописи я научился уже в академии. Не могу сказать, что я любил играть в видеоигры, однако, мне было жутко интересно смотреть дневники разработчиков или же фильмы о фильмах. Меня невероятно увлекал процесс создания чего-либо.

И вот однажды, мой хороший друг программист пригласил меня в игровую инди-студию. Оказалось, что одними лишь программистами игру не сделаешь и им нужен был concept artist и дизайнер шрифтов (как удачно, что в академии, помимо прочего, мы делали шрифты вручную). Знакомство непосредственно с компьютерной графикой началось с создания текстур для моделей средневековых доспехов, шлемов, оружия… Делал олдскульную покраску в Photoshop. После, переделывал эти модели в 3Ds Max.

Позже, я познакомился с ZBrush, который полюбил навсегда, а с ним появился и первый графический планшет, что равносильно первой любви. Со своими будущими коллегами я встретился по странной случайности. Они пришли консультировать нас по вопросам motion capture и съемки. Я заинтересовался и перешел к ним. Так я и попал в компанию Pixelated Realities, в которой работаю по сей день.

Основная наша деятельность напрямую связана с фотограмметрией и 3D-сканированием. Мы работаем во многих сферах: игры, кино, AR/VR. Сейчас большая часть времени уходит на цифровое производство опять-таки на базе отснятого материала. За последние 5–6 лет 80% моей работы связано с обработкой сырых сканов, в основном памятников культуры и архитектуры.
Но хватит об этом. Перейдем к делу.

Начало

Почти каждому художнику рано или поздно приходится пробовать фриланс на вкус. То же случилось и со мной. Было тяжело и долго мониторить разные платформы в поисках клиентов. Но однажды я увидел заказ, в котором необходимо было модифицировать поверхность объектов с паттерном, приведенным ниже, а также определенным диаметром отверстий и расстоянием между ними, и все это под SLS-печать в промышленных размерах.

Внезапно оказалось, что клиентом был скульптор Oliver Laric, создатель сайта threedscans.com. Это проект, которым я восхищался в первые месяцы знакомства с фотограмметрией. На сайте собрано и выложено в свободный доступ множество известнейших сканов скульптур со всего мира. Настоятельно рекомендую ознакомиться с сайтом, там вы сможете увидеть много моделей, знакомых вам из туториалов, статей и клипов. И как интересно вышло, что мне нужно работать со сканами известных памятников культуры!
Кстати, после этого проекта, коллеги прозвали меня «профессор-перфоратор». Думаю, вы догадываетесь почему)

Мой пайплайн достаточно сильно менялся и меняется до сих пор. Расскажу о нем по порядку. Даже скорее о его эволюции. Далеко не все тут является единственно верным или супер правильным, но, возможно, какие-то приемы смогут помочь кому-нибудь в решении своих задач. Начнем!

I

Первый пайплайн был основан на использовании текстуры с необходимым соотношением диаметра отверстий к расстоянию между ними. Основная проблема была в том, чтобы сохранить возможность печати для такого сложного объекта. Поэтому первая идея сделать отверстия на внешней поверхности и просто добавить ей толщину сразу отпала.

Да и кривизна поверхности не позволяет максимально равномерно распределить паттерн, как бы я сделал в любом CAD’е. Я принял решение делать Boolean цилиндров из уже готовой под производство модели. Для этого вначале необходимо подготовить модель, не разрушая уже сделанных конструктивных решений. Сначала необходимо было оставить лишь внешнюю поверхность, отделив от нее толщину и конструктивные пазы. После чего для удобства и легкости, я решил сделать ремеш в ZBrush.

Позже необходимо развернуть модель с минимальной дисторсией, чтобы текстура была без растяжений, ведь дальше мы будем пытаться делать из нее геометрию. Избавиться от дисторсии мне помог RizomUV. За последнее время – это лучший, на мой взгляд, инструмент для создания разверток.

Ранее у меня был интересный кейс, где необходимо было развернуть купол одного исторического памятника для научной документации, с целью расчета площадей поверхности и переноса их в чертежи. Так что развернуть модель настоящего физического объекта мне не составило труда. Прошу заметить, что мои методы достаточно сильно отличаются от методов геймдева или кино, когда речь идет о каком-либо производстве, несмотря на использование одних и тех же, казалось бы, инструментов.

Я создал текстуру в Photoshop с необходимыми пропорциями и применил ее на модель.

Результат был приблизительно вот такой:

Теперь дело было интереснее: надо было понять, как же мне превратить это все в геометрию. Да, для меня Modo – прекрасный инструмент, но я не смог придумать, как это реализовать тут. ZBrush же на удивление сразу подсказал мне вариант использовать Noise по UV, а потом маску из него. Да, не идеально, но уже что-то. Конечно, тут не угадаешь с масштабом, пришлось делать «костыль»: я создал три цилиндра нужного диаметра и расстояния между ними, свободно на глаз вставил их перпендикулярно модели и скейлил Noise до тех пор, пока не попал в масштаб. Предварительно сделал несколько уровней сабдивайда. Важно поставить на ноль значения следующих параметров: Noise Scale, Magnify by Mask и Mix Basic Noise. Так как мы хотим получить чистую маску.

После нескольких манипуляций я получил нужный масштаб:

Далее жмем Mask by Noise:

Получаем следующее:

Несложно догадаться, что делать далее. Добавляем замаскированные области в одну полигруппу и удаляем то, что нам не нужно. Получаем интересную поверхность, которая еще далека от финальной:

Как мы видим, вроде и круги, а вроде и нет. Да, можно было бы сделать Polish by Groups, но недостаток этого метода в том, что он не позволяет корректно сохранить ориентацию этих кругов, да и радиус у всех может стать разным.

Поэтому дальше я перехожу в Modo, чтобы обработать их инструментом Radial Align Tool. Перед этим удалив все внутренние эджи, кроме контура, чтобы получился N-gon. Удобство в том, что этим инструментом можно выставить радиус окружностей, где я уже буду достаточно близок к желаемому. Также можно указать количество сторон кругов, если это необходимо. Когда диаметр отверстия был 2 мм, то 12 сторон вполне хватало. При радиусе же в 3 мм, я увеличиваю кол-во сторон до 16. Тогда после SLS-печати не видно угловатости.

Далее уже все очевидно, делаем Extrude на необходимое расстояние, чтобы получить цилиндры и возвращаемся в ZBrush. Для предпросмотра использую прекрасную вещь Live Boolean, если необходимо, возвращаюсь в Modo, чтобы поправить или повернуть какой-то цилиндр и обратно в ZBrush. Когда все исправлено, то делаю финальный Boolean, а если нужно,  накидываю сверху Decimate.

Экспортируем в формате .stl и все готово!

II

Первый метод вроде бы дал нужный результат, но мой внутренний перфекционист горел в огне. Ужасно раздражала зависимость от плотности сетки, кривая геометрия, никакой закономерности, много ручных правок. Да и сами процессы на картинках выглядят быстрыми, а на деле приходилось работать с мешами под 20–40 миллионов полигонов, чтобы получить более точные результаты, а это, поверьте, тягомотина. Так как моделей было несколько десятков, я понял, что здесь нужен какой-то процедурный подход. Но Houdini я на тот момент даже ни разу в жизни не открывал. 

Я решил попробовать сделать инструмент для создания паттерна с возможностью задавать радиус и расстояние, когда мне захочется. Сразу начал думать о том, как сделать non-destructive схему, не создавая перемещение руками, так как это поможет в будущем менять диаметр. Я залез в Modo Schematic, и, используя тригонометрию, которую учил в школе, базовыми нодами выстроил перемещение. Постараюсь объяснить, что мы имеем из тригонометрии. По факту наш паттерн – это обыкновенные соты. В каждую соту вписана окружность. Вот как-то так это выглядит:

А теперь простыми словами: 3 соприкасающихся шестиугольника, в каждый вписана окружность, соответственно, центр каждого шестиугольника и каждой окружности совпадают; расстояние между центрами известно из задачи, то есть 3 радиуса окружности; имеем равносторонний треугольник ABC, чья высота h (CD) является смещением окружности по оси Y, а половина расстояния между точками A и B – смещением по оси X.

Заодно зацените этот сайт. Он помог мне очень многое осознать.

Так как мы еще имеем прямоугольный треугольник ADC, по определению синуса, мы можем вычислить необходимое нам смещение по Y, то есть sin 60 x 3R, а по оси X – 1.5 x R.

Далее я создал процедурный цилиндр со значением 0 по Z, чтобы получилась окружность, радиус по Y и X я залинковал. Позже добавил оператор Clone, из Tool Pipe вытащил Linear Generator и добавил его на Schematic. Посыпаем элементарной математической операцией умножения, заправляем синусом 60-и градусов, и ставим в значения Offset X и Y до полной готовности. Получается следующее:

А во вьюпорте мы увидим это:

Ура!  У нас почти готов паттерн. Осталось добавить Array, скормить ему значения для Offset по X и Y. В X добавляем 3 радиуса, в Y – 2 высоты, которые мы получили из первых расчётов. Выходит так:

Можно добавить пару хэндлов для удобства, но это уже косметика. После всех этих манипуляций мой инструмент выглядит как-то так:

Теперь необходимо его применить на модель, каким-то образом. В голову пришло только сделать UV-развертку и спроецировать полученный паттерн. В Modo есть прекрасный инструмент UV Transform. О нем сейчас по порядку.

Новая модель у нас намного менее очевидная. Ее кривизна поверхности невероятно сложная. Тут уже придется делать швы, так как на один UV-island развернуть не получится.

Предварительно я изолировал внешнюю поверхность, так же, как и в первом пайплайне. Ее я развернул в RizomUV Real Space, который как раз предназначен для реальных объектов – производства или лазерной резки. Как вы можете видеть, дисторсия присутствует, но я посчитал, что дисторсия на лице лучше, чем шов вокруг носа. Я старался делать швы в местах окклюзии и на пиках кривизны. Получилось так:

Возвращаемся в Modo, импортируем наш меш с разверткой. Дальше Texture / Convert UVs To Mesh. Это мы делаем для того, чтобы видеть наши границы.

После этого достаем созданный ранее нами генератор, и с помощью Array Count X и Y создаем паттерн, который покроет с запасом всю нашу развертку. За масштаб можем не переживать, так как Rizom RS сделал нам развертку в реальных физических размерах.

Я уменьшил кол-во сторон окружности до 6, исключительно из соображений оптимизации и производительности. Они нужны нам только для координат, а не выдавливания.

Далее выбираем наши круги, перед этим заморозив их (Right Click / Freeze Operations / Freeze), добавляем оператор UV Transform, как Target Mesh выбираем наш меш с UV-разверткой, а как Target UV Map – его развертку, которая по дефолту называется Texture. Жмем ОК и ждем.

Получается такой результат:

Да, возникли небольшие артефакты, которые я решил превратить в интересный арт-объект, но это лишь мелочи, их несложно убрать руками. Наилучший способ избежать появления артефактов – обрезать круги по UV с небольшим оффсетом внутрь, перед тем, как делать UV Transform. Но времени не было, ручками вышло быстрее, да и понятнее. Я понял, что без правок тут не обойтись, но ковыряться в геометрии будет очень тяжело, да и все круги сами по себе не очень ровные вышли, из-за кривизны поверхности.

Теперь создаем цилиндр, я сделал его процедурно, с радиусом 1мм, а высотой – такой, какая нужна, чтобы пройти оригинальную модель насквозь. Кидаю цилиндр в Schematic, полученную после UV Transform геометрию кидаю туда же. Добавляем оператор Replicator, в параметре Instancing выбираем Use Polygons, чтобы цилиндры создавались не по точкам, а по нашим н-гонам. Цилиндр подключаем в Prototypes, а кружочки в Particle Source. Вот так:

Во избежание слишком очевидных пересечений на внутренней поверхности я добавил второй цилиндр, а точнее усеченный конус (по факту кружок с экструдом и бевелом). Тут важно чтобы внутренний радиус был не сильно маленьким, чтобы не возникало ошибок печати, ведь она очень дорогая. В моем случае я сделал внутренний радиус 0.7мм. Ниже решил не делать. Сделал второй репликатор, второй меш-контейнер для кружков и еще один контейнер для уже будущих цилиндров. Все это вставил в ноду Merge Meshes.

Теперь можно править швы (да-да, ручками) и в особо кривых или узких местах немного повернуть цилиндры или заменить их на усеченные конусы. Вот, что вышло по итогу:

Вышло неплохо, теперь делаем Freeze, экспортируем и идем в ZBrush для предпросмотра. Если что-то нужно исправить, возвращаемся и исправляем. По финалу выходит так:

III

Теперь перейдем к крайнему (не последнему) пайплайну, до которого я смог дойти. На данный момент для меня он самый оптимальный, быстрый и наиболее естественный. Я много советовался на форумах, в чатах и в комментариях на YouTube. Чаще всего я слышал мнение: «Это точно можно сделать в Houdini, я его не знаю, но точно можно!!!».

Я боялся долго, но несколько добрых людей в интернете смогли меня переубедить, за что им отдельная благодарность. Я сел за Houdini, в попытках изучить интерфейс или какие-то базовые его вещи, философию. Но, когда у тебя сроки горят, все горит, ты в огне и надо срочно работать, тогда не до обучения. Крутить вьюпорт научился, значит, работать можно, погнали. Тем более, что существует негласное правило: «Если это нельзя сделать в Houdini, это нельзя сделать больше нигде».

Проштудировал терабайты Ютуба, десятки статей, много задавал вопросов, и все же нашел вроде бы подходящий инструмент для своих задач. Первое, что мне пришлось принять как архитектору и художнику, это Платоновы тела. Возьмем, к примеру, стандартный футбольный мяч из шестиугольников, с черными лоскутами. Это не что иное, как усеченный икосаэдр. Даже у такой, казалось бы, элементарной формы как сфера не получается обрасти только лишь шестиугольниками — геометрия будет против.

Это важно для внутреннего перфекциониста. Просто. Смириться. С этим.

А вот невероятно полезное видео, объясняющее природу Платоновых Тел:

Не будем вникать в основы Houdini, сразу перейдем к магии. На входе имеем еще более комплексную модель:

Уже по известному нам принципу отделяем внешнюю поверхность от всего остального. Я бы мог сделать это процедурно, сгруппировав по углу, нормали и т. д., но, к сожалению, модели бывают разные и не всегда это работает так, как нужно. Часто намного быстрее и легче бывает отделить это руками.

Диаметр отверстий в этой модели – 3мм, расстояние между отверстиями 1 радиус – 1.5мм. Пропорции такие же. К сожалению, я не нашел удобного метода указания расстояния между отверстиями: пришлось думать с другой стороны.

Сначала давайте сделаем небольшой тест, который раскроет все тайны и объяснит идею. Возьмем простую ноду Sphere c параметром Primitive Type — Polygon и Frequency со значением около 6. Попробуем сделать паттерн на этой сфере. Кидаем ноду Scatter со значениям 0 в параметре Relax Iterations. Мы увидим 1000 точек, рандомно расположенных на поверхности сферы. Вот в чем трюк: чем дальше мы задираем Relax Iterations, тем регулярнее становится позиция точек. Логично, что единственный метод релакса точек  – это отдалить соседние точки на равное расстояние. То есть может получится только 6 равноудаленных точек вокруг одной. А если проще, то: если мы возьмем минимальное кол-во точек, которые могут создать плоскость и которые могут быть равноудалены, а именно 3, то мы получим равносторонний треугольник. И, к счастью, шестиугольник состоит из шести равносторонних треугольников.

Давайте посмотрим нагляднее. Берем ноду Circle и Copy to Points. Подключим Scatter и Circle в Copy to Points. О чудо! Прекрасный паттерн без швов. Представьте, как бы это пришлось делать, используя предыдущий пайплайн…

После этого мне пришла в голову идея, что параметр Force Total Count в ноде Scatter сможет мне помочь разобраться с расстояниями между точками. Значит нужно узнать, как получить это количество.

Я исходил из площадей. А точнее площади поверхности, которую нужно покрыть, и площади шестиугольника, в который нужно вписать окружность. Если соотнести площадь поверхности к площади одного шестиугольника, то мы получим кол-во этих шестиугольников, то есть кол-во отверстий.
Вернемся к нашей тригонометрии:

Имеем все тот же шестиугольник. Чтобы его построить, необходимо понять его зависимость от отверстия. Высоту h мы уже знаем из предыдущих вычислений. Все по тому же определению синуса, находим необходимую нам длину OM, которая и является радиусом самого хекса.

Построим в гудини окружность и этот шестиугольник. Берем две ноды Circle, в первой задаем нужный нам радиус и параметр Divisions на 12. Чтобы залинковать радиус по X и по Y, на параметре радиуса по X делаем Right Click / Copy Parameter, а в параметре Y – Right Click / Paste Relative Reference:

После этого во второй ноде Circle делаем то же самое, только параметр Divisions на 6. Но теперь надо каким-то образом вставить наши вычисления в значение радиуса X. Копируем параметр радиуса нашей окружности, умножаем на 1.5 и делим на sin (60), все это в строке значения. Получаем следующее:

Получили ровно то, что хотели. Отлично, двигаемся дальше. Теперь нам бы получить площадь. Это делается одной нодой Measure. Она по дефолту считает площадь. Очень важно не забыть поставить галочку Total Attribute Name. Тогда создается атрибут площади, к которому мы будем обращаться позже.

Вернемся к нашей модели. Мне пришлось подрезать ее на 2.5 мм с открытых сторон, так как я хотел оставить 1 мм условной рамки, а еще 1.5 мм – это наш радиус. Сейчас вы поймете, почему.

По образу и подобию берем ноду Measure, с той же галочкой, так как именно эти атрибуты мы и будем сравнивать.

Добавляем нашу главную ноду Scatter. Параметр Generate – By Density. Теперь будем задавать количество точек на модели в параметре Force Total Count. Нам нужно обратиться к атрибуту площади поверхности скульптуры и поделить его на площадь поверхности шестиугольника. Обращаться к ним нужно таким образом: attrType(«../nodeName»,»attrName»,0).

Вставляем площадь поверхности скульптуры, ставим знак деления и вставляем площадь шестиугольника. Параметр Relax Iterations у меня обычно колеблется от 1000 до 10000. На всякий случай отключаю Randomize Point Order (а вдруг с ним придется работать), параметры Scale Radii By и Max Relax Radius всегда меняются в зависимости от модели. В 60% случаев я оставляю их по дефолту.

Вот, какой замечательный узор у нас выходит. Где это возможно, одну точку окружают 6 равноудаленных точек, а где необходимо – 5 или же 7. Вспоминаем наш усеченный икосаэдр.

Подрезал я модель с той целью, чтобы круги не выходили за границы скульптуры, а даже имели отступ в 1 мм от краев, так как Scatter генерирует точки четко по границам поверхности (тут уже не подрезанная модель, а оригинальная):

Дело за малым. Берем ноду Copy to Points, скармливаем ей во вход Target Point to Copy to наш Scatter полученный, а во вход Geometry to Copy – созданную нами в первых шагах окружность. И всё это дружно экспортируем:

Часто я создаю цилиндр рядом с нужным радиусом и высотой, добавляю ноду Boolean и сразу в Houdini имею превью того, что получу на выходе. Но все равно мне ZBrush милее.

Теперь импортирую все в Modo, использую тот же Replicator на полученных окружностях и вручную правлю какие-то проблемные области, если таковые имеются. Как было описано в части II. Прыг-скок в Zbrush и обратно, как и раньше. И вуа-ля:

Данный метод мне кажется более естественным с точки зрения баланса между затраченным временем и результатом. Никаких тебе швов, никаких UV, края узора красивые и сохраненная процедурность. Да, возможно, он не самый точный из всех, но мы тут решаем вопросы искусства с помощью математики, а не решаем математические задачи в ущерб искусству.

Теперь представлю вашему вниманию те скульптуры, которые уже были произведены и выставлены. Спасибо вам большое за потраченное на прочтение время, и надеюсь, что кто-то найдет полезными какие-то методы из моей практики!


Подписывайтесь на нас в Facebook, Telegram, Vkontakte, Pinterest.

+1
2
+1
6
+1
1
+1
0
+1
1
+1
0
+1
0
Поделиться: