GDL. Объект для моделей из "оцилиндрованного бревна"



В данной статье разобран пример создания параметрического элемента моделирующего оцилиндрованное бревно.  Начну свои GDL-экзерциссы, c довольно простого объекта. Тем не менее, отражающего основные возможности GDL. В частности то, что GDL поддерживает основные операции CSG(Constructive Solid Geometry – логические операции над объемными формами) – вычитание, объединение и др.

 Будем считать, что речь идет о версии объекта: 1.0 – Initial Version. Планирую его переписать с учетом новой спецификации (морально устарел).  
Ну что ж, в этом первом GDL-экзерциссе будут некоторые «прыжки в сторону» -  поясняющие отвлечения от основной темы элемента. Думаю это будет полезно тем, кто впервые решится на создание своего GDL-объекта. Кроме описаний интерфейса, буду по возможности касаться некоторых моментов связанных с интересным поведением GDL-компилятора, это все-таки это не полноценная IDE среда, и в некоторых случаях лично я находил «ответы» именно в постах других людей, споткнувшихся о теже «грабли» что и я. Эти вещи буду подчеркивать.  
Основные функции, которыми мы наделим элемент под названием «brevno»:
1.       Выбор количества пазов (для стыковки с бревнами поперечного направления): от 0 до 3.
2.       Возможность задавать основную геометрию: радиус бревна, радиус чашки, длина бревна.
3.       Возможность задать «получашку»  вначале и (или) конце бревна.
4.       Возможность среза под заданный угол начала и (или) конца бревна.
5.       Продольный паз (по длине бревна).
Итак,  для всех этих целей нам потребуется задать следующие параметры элемента:

Скрин 1 «Параметры»
По полю «имя» понятно назначение параметров. Скажу лишь, что каждый параметр имеет следующие «атрибуты»:
- «Показ» - будет ли параметр виден конечному пользователю в меню элемента.
- «Переменная» - имя переменной в скрипте.
- «Тип» - стандартные типы переменных показаны на скриншоте:


Скрин 2 «Типы параметров»

Здесь слева-направо, сверху-вниз, пиктограммы типов: «Линейная величина», «угловая величина», «действительное число», «целое число», «истина/ложь», «Текст», «Покрытие», «Тип линии», «Образец штриховки», «Цвет пера», «Разделитель», «Заголовок».
Судя по  значкам у параметров на скрине 1 видим, что: параметры Rb, Rc, L – линейные величины, опциональные параметры Xb,Xe – истинностные значения, что соответствует их логическому назначению – предоставить пользователю выбор «Да/Нет».
«Синие» Параметры на скрине 1 – это параметры соответствующие данному «подтипу» GDL- объекта, они создаются автоматически при выборе подтипа. В этом примере нам требуется подтип «Элемент модели» (без дальнейшей конкретизации). А вообще Арчик предлагает весьма забавную иерархию библиотечных объектов (кто и на основании чего ее составлял?!):

Скрин 3 «Подтипы объектов»

С основными исходными моментами определились, теперь надо увязать работу параметров, задать им значения. Рассмотрим скрипты объекта.

1.       СКРИПТ ПАРАМЕТРОВ. 


Скрин 4 «Скрипт параметров»
В первой строке мы задаем параметру inn  список возможных значений в соответствии с его типом (целое число), после этого в меню появляется возможность выбора значения для inn  из выпадающего списка. В случае, если скрипт параметров не скомпилируется, т.е. будет содержать ошибки, эта возможность исчезнет, вплоть до того момента пока ошибки не будут устранены. Таким образом если у вас возникла подобная проблема, даже если при нажатии на «Проверить скрипт» ошибки нет, знайте –решение такой ситуации следует искать в скрипте параметров.
Дальше в зависимости от выбранного значения inn определяем значения параметров х1,х2,х3, L. Математика здесь элементарная, тем не менее, есть «хитрости» описания, которые приходят с некоторым опытом, и которые достаточно выразительно позволяют описать требуемое поведение связки параметров. В данном случае выразительность заключается в следующем: L-длина бревна, X1,X2,X3 координаты пазов в пределах этой длины. Возьмем ситуацию когда пользователь задал 2 паза, указал их координаты Х1,Х2, в каких пределах теперь можно изменять длину? Правильно – от Х2 до требуемой. Таким образом строка:
values "L" range [x2+0.001,)
описывает например случай когда на плане был размещен объект с длиной  допустим 1,5м(L=1500), затем без всяких предупреждений пользователь зашел в меню и выставил кол-во пазов 2 и задал Х1=…, Х2=3500. Т.е. в случае отсутствия этой строки паз «2» попал бы «в пустоту», а длина осталась бы равной L=1500. Т.е. это описание исключило данную ситуацию и ситуацию «опечатки», невнимательного ввода – длина в данном случае автоматически пересчитается и объект автоматически удлинится, что нельзя будет не заметить в 3Д. Также скрипт параметров сыграет главную роль при интерактивном редактировании нашего объекта в 3Д. Об этом дальше. Здесь же еще отметим роль скобок [ ] и ( ) в описании граничных условий на значения параметров – круглые скобки описывают ситуацию когда значение перед/после скобки «не включается» в диапазон. Квадратные -наоборот(включается). Когда нужно указать диапазон от «х» до «бесконечности» используют круглую закрывающую скобку:  values "L" range [x3+0.001,)

2.       ОСНОВНОЙ СКРИПТ


Скрин 5 «Основной скрипт»

Здесь мы назначаем объекту материал в соответствии с выбранным в меню параметром g_m, команда material будет иметь значение для всех 3д команд создающих 3д тела, до момента пока не встретится очередное определение material. Стандартное поведение «команды-аттрибута».

Дальше в зависимости от кол-ва пазов указанных в меню (inn) будем инициализировать локальные переменные ix1,ix2,ix3 единицей при наличии соответствующего паза. Это нам нужно для организации интерактивного редактирования через активные хотспоты ( 2д, 3д скрипт). Назначение этих переменных будет понятно дальше.

3.       2D скрипт


Скрин 6 «2D скрипт»
По порядку:
project2 3,270,1 
- мы хотим видеть на плане(2Д скрипт отвечает за отрисовку объекта в плане) проекцию «сверху» 3D «содержимого» (Подробности команды project2 можно найти в ркуоводстве по GDL).

hotspot2 0,0,12,L,128+1
hotspot2 L,0,13,L,2
hotspot2 0,0,14,L,3 
- ставим «активный хотспот»(далее АС - активный спот), связанный с параметром L,
Который будет использоваться при редактировании длины на плане, для редактирования в 3д будет описан другой АС.
О синтаксисе описания АС расскажу в другой раз это отдельная тема. Вообще АС – это ключевой момент интерактивности взаимодействия пользователя с объектом в плане и 3д окне. Без АС GDL был бы убогим.
if ix1 then
hotspot2 0,0,1,x1,128+1
hotspot2 x1,0,2,x1,2
hotspot2 0,0,3,x1,3
endif
- при наличии паза 1 вешаем 2D АС на параметр Х1. Т.е. перетаскивая этот АС мы меняем параметр X1. Редактирование осуществляется: в плане, в соответствии со строками скрипта параметров(в зависимости от inn):
0 пазов – хотспот на плане не будет отрисован (по условию if ix1 then..)
1 паз - values "x1" range [0.001,L-0.001]
2,3 паза - values "x1" range [0.001,x2-0.001]

Далее и до if is=1 then
- аналогичные действия и логика по пазу 2 и 3. 
if is=1 then
text2 0,-0.5,"Привет Всем кто живет с Архикадом!!!По поводу этого и других *.gsm обращайтесь - ICQ 195830974, sergstd@rambler.ru.Выкл это сообщение мона в менюхе объекта."…
- иногда бывает полезно описать принцип того что делает скрипт, простым человеческим языком. Особенно когда речь идет о «наколеночном» программировании. Graphisoft не утруждает себя  мануалами по использованию GDL объектов из своих библиотек. При достаточном опыте работы с GDL объектами необходимость в мануале отпадает, все они реализуют конечный набор функций. Тем не менее, когда у объекта есть особенности, неплохо бы уведомить о них конечного пользователя. В нашем случае такая особенность описана в строке:
text2 0,-2.5,”И последнее...когда изменяете кол-во пазов в большую сторону(был 1 ставим 2) то хотспот 2-го паза нужно искать рядом с первым пазом”
здесь описывается случай аналогичный рассмотренному выше - с возможным вылетом паза за пределы бревна и автоматическим увеличением длины.



Скрин 7 «Вид элемента на плане – результат работы 2D скрипта»


4.       3D скрипт

Мысленно представим каким образом можно получить бревно с пазами. Очевидно что нужный результат - вычитание из объекта "бревно"   объектов "паз".
Так как наш объект – результат выполнения операций CSG(см ссылки в конце) опишем группы объектов которые будут операндами этих CSG-операций.

!  основная группа, бревно:
GROUP "brevno"
! повернем СК на 90 градусов вокруг оси У, это нужно чтобы цилиндр символизирующий бревно располагался горизонтально (по умолчанию ось цилиндра совпадает с осью Z, см. синтаксис GDL - ссылки в конце)
ROTY 90
! Вот он наш цилиндр-«заготовка»
CYLIND L,Rb
! завершаем описание группы «brevno», из которой будем вычитать пазы, получашки, делать срезы концов…
ENDGROUP

! 3D АС вешаем на параметр-длину нашего бревна.
hotspot 0,0,0,12,L,128+1
hotspot L,0,0,13,L,2
hotspot 0,0,0,14,L,3

! если есть паз 1 то вешаем 3D АС на параметр-координату этого паза(Х1), вдоль нашего бревна.
if ix1 then
hotspot 0,0,0,1,x1,128+1
hotspot x1,0,0,2,x1,2
hotspot 0,0,0,3,x1,3
endif

! тоже самое паз 2
if ix2 then
hotspot 0,0,0,4,x2,128+1
hotspot x2,0,0,5,x2,2
hotspot 0,0,0,6,x2,3
endif

! тоже самое паз 3
if ix3 then
hotspot 0,0,0,7,x3,128+1
hotspot x3,0,0,8,x3,2
hotspot 0,0,0,9,x3,3
endif

! Пара полезных ПС(пассивных спотов), удобно задавать при редактировании перемещения от конкретных точек элемента, также нужно за что-то и зеркалить элемент. Это немаловажный момент – дать конечному пользователю нужное количество ПС, для удобной работы с элементом.
hotspot 0,0,0
hotspot L,0,Rb

! Группа пазов которая формируется в зависимости от заданного количества пазов.
GROUP "paz"
! смещаем СК в положение где должен быть расположен «цилиндр-операнд», который будем вычитать из «brevno», по сути «стек трансформаций» содержит обычные афинные преобразования 3D, которые применяются к координатам команд-объектов (в нашем случае к «операндам-цилиндрам»).
ADDZ -2*Rb*cos(30)
ROTY 90

! если задан продольный паз - формируем цилиндр-операнд для такого вычитания
if pazz then
CYLIND L,Rb
endif
! удаляем из стека трансформаций последние две операции - ADDZ -2*Rb*cos(30) и ROTY 90
del 2

! настраиваем СК для вычитания поперечных пазов и получашек.
ADDZ -Rb
ADDY 2*Rb
ROTX 90

! создаем «цилиндр-операнд» результатом вычитания которого из бревна будет получашка вначале.
if xb then
CYLIND 500,Rc
endif

! получашка в конце
if xe then
addx L
CYLIND 500,Rc
del 1
endif

! поперечные пазы
if ix1 then
ADDX X1
CYLIND 500,Rc
del 1
endif

if ix2 then
addx X2
CYLIND 500,Rc
del 1
endif

if ix3 then
addx X3
CYLIND 500,Rc
del 1
endif

! очищаем стек преобразований.
DEL TOP
! закрываем группу «пазы»
ENDGROUP

! Вычитаем из бревна заданные пазы
result_=SUBGROUP("brevno","paz")

! если «срезы» бревна не заданы – кидаем наш результат в модель и…
if B_A=0 & B_b=0 then
PLACEGROUP result_
! шагаем к выходу
goto 1
endif

! Если задан срез в начале, то выполняем его при помощи cutplane
if B_A=1 & B_b=0 then
hotspot Rb*tan(ab),0,Rb
rotz 90
cutplane -ab
del 1
! срезать будем с результата вычитания, т.е. с «бревно-пазы», поэтому располагаем наш результат м/у cutplane-cutend.
PLACEGROUP result_
cutend
! шагаем к выходу
goto 1
endif

! тоже, срез на конце бревна
if B_A=0 & B_b=1 then
addx L
hotspot -Rb*tan(ae),0,Rb
rotz 90
cutplane ae
del 2
PLACEGROUP result_
cutend
goto 1
endif

! тоже, срез в начале и  конце бревна
if B_A=1 & B_b=1 then
hotspot Rb*tan(ab),0,Rb
rotz 90
cutplane -ab
del 1
addx L
hotspot -Rb*tan(ae),0,Rb
rotz 90
cutplane ae
del 2
PLACEGROUP result_
cutend
cutend
goto 1
endif

! результат вычитания и усечений уже размещен, необходимости в группах больше нет – удаляем их.
1:
KILLGROUP "brevno"
KILLGROUP "paz"
!Очищаем «стек преобразований»
del top



смотрим на результат.


Скрин 8  «Вид элемента в 3Д окне – результат работы 3D скрипта»

А так может выглядеть сруб «собранный из»:


Скрин 9 «На практике»
Ссылки по теме:
1.       http://en.wikipedia.org/wiki/Constructive_solid_geometry - конструктивная геометрия это...интересно.
2.       http://compgraphics.info/3D/3d_affine_transformations.php - об афинных преобразованиях (лучше один раз увидеть).
3.       http://archicad.ru/support/gdl/developer-zone.html  - здесь можно найти руководства по GDL.

Желаю  успехов в GDL!

Комментарии

  1. Спасибо большое за такое подробное изложение. Было приятно ознакомиться, жду продолжения!

    ОтветитьУдалить

Отправить комментарий

Популярные сообщения из этого блога

График функции в полярных координатах?! Легко!

Объект "Plan Marker"