[Примечание: перечитав это перед отправкой, я понял, что этот вопрос стал чем-то вроде эпоса.Спасибо, что потворствовали моему длинному объяснению причин этого преследования.Я чувствую, что если бы я был в состоянии помочь другому предпринять аналогичный проект, я бы с большей вероятностью оказался на борту, если бы знал причину вопроса.]
Я попал в Структура Synth Микаэль Хвидтфельдт Кристенсен в последнее время.Это инструмент для генерации трехмерной геометрии из (в основном) контекстно-свободной грамматики, называемой Eisenscript.Структура Synth сама по себе вдохновлена Context Free Art.Контекстно-свободные грамматики могут создавать потрясающие результаты из удивительно простых наборов правил.
Мой текущий рабочий процесс Structure Synth включает в себя экспорт файла OBJ из Structure Synth, импорт его в Blender, настройку источников света, материалов и т. Д., А затем рендеринг с помощью Luxrender.,К сожалению, импорт этих OBJ-файлов часто приводит к остановке Blender, поскольку могут существовать тысячи объектов с довольно сложной геометрией.Я говорю «честно», потому что Structure Synth генерирует только базовые формы, но сфера, представленная треугольниками, все еще имеет много граней.
Таким образом, генерация структур непосредственно в Blender была бы предпочтительнее текущего процесса (глубокая поддержка Blender дляСценарии Python должны сделать это возможным).Интеллектуальная библиотека Python может использовать возможности экземпляров Blender, чтобы использовать одну сетку для создания множества объектов, тем самым экономя память.Plus Blender - это полнофункциональный 3D-пакет, и его способность интерпретировать CFDG обеспечит творческие возможности, намного превосходящие возможности Structure Synth.
И поэтому мой вопрос заключается в том, как лучше всего перевести грамматику Eisenscript в Python DSL.,Вот как выглядит простой Eisenscript:
set maxdepth 2000
{ a 0.9 hue 30 } R1
rule R1 {
{ x 1 rz 3 ry 5 } R1
{ s 1 1 0.1 sat 0.9 } box
}
rule R1 {
{ x 1 rz -3 ry 5 } R1
{ s 1 1 0.1 } box
}
Чтобы объяснить, первый вызов R1 (строка 2) будет случайным образом вызывать одно из двух определений R1.Каждое определение R1 рекурсивно вызывает R1 (случайным образом вызывая одно из двух определений), а также создает блок.Первая строка убивает поколение после того, как рекурсия прошла 2000 уровней.
Джереми Ашкенас (из известности CoffeeScript) успешно реализовал контекстно-независимый DSL в Ruby , используя блоки.Внутренне он работает путем создания ключа хеш-функции для каждого «имени» правила и сохраняет блоки для каждого определения этого правила в массиве, который выбирается случайным образом при вызове правила.
Предыдущее правило Eisenscriptопределения будут переводиться в Ruby DSL следующим образом:
rule :r1 do
r1 :x => 1, :rz => 3, :ry => 5
box :s => [1, 1, 0.1], :sat => 0.9
end
rule :r1 do
r1 :x => 1, :rz => -3, :ry => 5
box :s => [1, 1, 0.1]
end
Я начинающий пользователь Python и поэтому провёл некоторое исследование возможностей функционального программирования Python.Кажется, что лямбда слишком ограничена, чтобы создавать что-то похожее на Ruby DSL Джереми, и, насколько я могу судить, лямбда - единственный вариант для анонимных функций?
Как опытный Pythonista может подойти к дизайну?