Рассмотрим создание конструкции точечного объекта на примере опоры ЛЭП. Конструкция будет содержать в себе каталог шифров возможных вариантов опор различных материалов и типоразмеров. Так же пользователю будет доступна возможность задать свои размеры отличающиеся от предложенных в сортаменте.
На основе сортамента необходимо предусмотреть шесть различных конструкций опоры ЛЭП:
Таблицу сортамента представим в виде словаря, в котором каждая комбинация параметров опоры будет задана парой ключ/значение, где ключ - это строка с именем шифра, а значение - это упорядоченный список параметров опоры соответствующий данному шифру. Так же создадим словари для всех параметров с конечным набором значений (материал, тип, вид).
Так как словари содержат большое количество информации, их удобно держать в отдельном файле и импортировать его в основной скрипт конструкции. Так же в этом файле расположим второстепенные вспомогательные функции:
Функция | Описание |
---|---|
gen-cipher-tag | Генерация уникального символа для опор различной конструкции. Уникальные символы будут использоваться в качестве идентификатора свойства шифра. Свойство шифра имеет тип "Перечисление" и содержит определённый набор шифров из сортамента, соответствующий конструкции опоры. Если не менять идентификатор свойства, то мы столкнёмся с ситуацией, когда предыдущее значение свойства не будет найдено в устанавливаемом перечне шифров и в инспекторе свойств будет указано, что значение свойства Шифр не задано. Подробнее смотри раздел Применение функций «defproperty», «setproperty» и «v-property» |
gen-type-tag | Генерация уникального символа соответствующего материалу опоры. Аналогично gen-cipher-tag , символ будет использоваться в качестве идентификатора свойства типа опоры |
gen-material-color | Получение RGB компонента (цвета) соответствующего материалу опоры |
get-pillar-ciphers | Получение словаря шифров доступных для соответствующей конструкции опоры. Для любой конструкции опоры добавляем в словарь шифр «Пользовательский» |
get-pillar-types | Получение словаря типов опоры соответствующего материалу опоры |
get-first-dict-element | Получение первого элемента словаря |
degrees_to_radians | Преобразование градусов в радианы |
hypotenuse_length | Расчёт длины гипотенузы по катету и прилежащему углу |
Файл вспомогательного скрипта будет иметь следующий вид:
(setq ; Словарь таблицы сортамента lep_pillar_sortament (dict ; Шифр Материал Вид Тип L1 L2 d/B L3/W ; Дерево "П10 С7.75х1" '("Дерево" "Промежуточная" "Простая" 6.0 1.5 0.19 ) "П10 С8х1" '("Дерево" "Промежуточная" "Простая" 6.0 2.0 0.20 ) "П10 С8.5х1" '("Дерево" "Промежуточная" "Простая" 6.5 2.0 0.225 ) "П10-1 С9.7х2" '("Дерево" "Промежуточная" "Составная" 8.0 1.7 0.19 3.0 ) "П10 С10.8х2" '("Дерево" "Промежуточная" "Составная" 9.0 1.8 0.20 3.0 ) "П10 С12х2" '("Дерево" "Промежуточная" "Составная" 10.0 2.0 0.225 3.0 ) "УП10 С7.75х1" '("Дерево" "Угловая" "Простая" 6.0 1.5 0.19 ) "УП10 С8х1" '("Дерево" "Угловая" "Простая" 6.0 2.0 0.20 ) "УП10 С8.5х1" '("Дерево" "Угловая" "Простая" 6.5 2.0 0.225 ) "УП10 С9.7х2" '("Дерево" "Угловая" "Составная" 8.0 1.7 0.19 3.0 ) "УП10 С10.8х2" '("Дерево" "Угловая" "Составная" 9.0 1.8 0.20 3.0 ) "УП10 С12х2" '("Дерево" "Угловая" "Составная" 10.0 2.0 0.225 3.0 ) "К10 С7.75х1" '("Дерево" "Концевая" "Простая" 6.0 1.5 0.19 ) "К10 С8х1" '("Дерево" "Концевая" "Простая" 6.0 2.0 0.20 ) "К10 С8.5х1" '("Дерево" "Концевая" "Простая" 6.5 2.0 0.225 ) "К10 С9.7х2" '("Дерево" "Концевая" "Составная" 8.0 1.7 0.19 3.0 ) "К10 С10.8х2" '("Дерево" "Концевая" "Составная" 9.0 1.8 0.20 3.0 ) "К10 С12х2" '("Дерево" "Концевая" "Составная" 10.0 2.0 0.225 3.0 ) ; ЖБ "П10-СВ 105" '("ЖБ" "Промежуточная" "Одностоечная" 8.5 2.0 0.28 0.2 ) "П10-СВ 113" '("ЖБ" "Промежуточная" "Одностоечная" 9.5 1.8 0.28 0.165) "П10-СВ 145" '("ЖБ" "Промежуточная" "Одностоечная" 12.5 2.0 0.28 0.19 ) "УП10-СВ 105" '("ЖБ" "Угловая" "Одностоечная" 8.5 2.0 0.28 0.2 ) "УП10-СВ 113" '("ЖБ" "Угловая" "Одностоечная" 9.5 1.8 0.28 0.2 ) "УП10-СВ 145" '("ЖБ" "Угловая" "Одностоечная" 12.5 2.0 0.28 0.19 ) "К10-СВ 105" '("ЖБ" "Концевая" "Одностоечная" 8.5 2.0 0.28 0.2 ) "К10-СВ 113" '("ЖБ" "Концевая" "Одностоечная" 9.5 1.8 0.28 0.2 ) "К10-СВ 145" '("ЖБ" "Концевая" "Одностоечная" 12.5 2.0 0.28 0.19 ) ) ; Словарь материалов lep_pillar_materials (dict "ЖБ" "ЖБ" "Дерево" "Дерево" ) ; Словарь видов опор lep_pillar_views (dict "Промежуточная" "Промежуточная" "Угловая" "Угловая" "Концевая" "Концевая" ) ; Словарь типов для ЖБ опор lep_pillar_types_concrete (dict "Одностоечная" "Одностоечная" ) ; Словарь типов для деревянных опор lep_pillar_types_wood (dict "Простая" "Простая" "Составная" "Составная" ) ) ; Генерация уникального символа для опор различной конструкции (defun gen-cipher-tag (material view type) (let (m v t) (setq m (cond ((eql material "ЖБ") "c") ;concrete ((eql material "Дерево") "w") ;wood (t "u")) ;unknown v (cond ((eql view "Промежуточная") "i") ;intermediate ((eql view "Угловая") "c") ;corner ((eql view "Концевая") "e") ;end (t "u")) ;unknown t (cond ((eql type "Простая") "s") ;simple ((eql type "Составная") "c") ;composite ((eql type "Одностоечная") "o") ;one (t "u")) ;unknown ) (make-symbol (format "pillar_cipher_{0}{1}{2}" m v t)) ) ) ; Генерация уникального символа соответствующего материалу опоры (defun gen-type-tag (material) (let (m) (setq m (cond ((eql material "ЖБ") "c") ;concrete ((eql material "Дерево") "w") ;wood (t "u")) ;unknown ) (make-symbol (format "pillar_construction_type_{0}" m)) ) ) ; Получение RGB компонента (цвета) соответствующего материалу опоры (defun gen-material-color (material) (cond ((eql material "ЖБ") (vec 0.8 0.8 0.79)) ;gray ((eql material "Дерево") (vec 0.62 0.49 0.22)) ;brown (t (vec)) ;default ) ) ; Получение словаря шифров доступных для соответствующей конструкции опоры (defun get-pillar-ciphers (material view type) (let (ciphers) (setq ciphers (dict)) ; Выборка шифров по установленным параметрам опоры (v-for (key (dict-keys lep_pillar_sortament)) (setq data (dict-get lep_pillar_sortament key)) (if (and (eql material (car data)) (eql view (cadr data)) (eql type (caddr data))) (dict-set ciphers key key) ) ) (dict-set ciphers "custom" "Пользовательский") ciphers ) ) ; Получение словаря типов опоры соответствующего материалу опоры (defun get-pillar-types (material) (let (types) (setq types (cond ((eql material "ЖБ") lep_pillar_types_concrete) ;concrete ((eql material "Дерево") lep_pillar_types_wood) ;wood (t (dict))) ;unknown ) ) ) ; Получение первого элемента словаря (defun get-first-dict-element (dic) (let (enum first) (setq enum (enum-get (dict-keys dic))) (enum-next enum) (setq first (enum-current enum)) (enum-reset enum) first ) ) ; Преобразование градусов в радианы (defun degrees_to_radians (degrees) (* PI (/ degrees 180.0)) ) ; Расчёт длины гипотенузы по катету и прилежащему углу (defun hypotenuse_length (cathetus degrees) (/ cathetus (cos (degrees_to_radians 20.0))) )
Функции и переменные вспомогательного скрипта нам потребуются для определения свойств компонента, поэтому сразу импортируем его.
defcomponent
должен быть расположен в конце файла.
В теле основного скрипта опишем сам компонент и функции определяющие его геометрию:
Функция | Описание |
---|---|
pillar | Определение 3D-тел всех элементов опоры соответствующих её конструкции |
standoff | Определение 3D-тел упора опоры |
simple_standoff | Определение 3D-тел упора простой или одностоечной опоры |
composite_standoff | Определение 3D-тел упора составной опоры |
simple_pillar | Определение 3D-тел простой или одностоечной опоры |
composite_pillar | Определение 3D-тел составной опоры |
crossbar | Определение 3D-тел перекладины крепления проводов ЛЭП |
Для удобства работы с конечной моделью, свойства компонента сгруппируем:
Группа свойств | Описание |
---|---|
Подпись | Свойства подписи опоры на плане |
Опора | Свойства конструкции опоры |
Размеры | Свойства размеров опоры |
Вставка | Свойства вставляемого элемента ИМ |
Взаимодействие свойств опоры организовано следующим образом:
На основе указанных значений свойств формируются 3D-тела соответствующей формы и цвета. Полученные 3D-тела помещаются в блок определения геометрии defgeometry
. Так же в этом блоке предусмотрим вставку дополнительного элемента из библиотеки 3D-моделей.
При составлении топографических планов, точечные объекты, как правило, обозначаются точечными условными знаками, поэтому автоматически генерируемый вид конструкции сверху (план), в нашем случае, будет избыточным. Сформируем уникальный вид конструкции на плане в блоке defview
. Разместим на этом виде сечение опоры в натуральную величину, а так же добавим подпись с именем опоры с привязкой к свойствам из группы «Подпись», чтобы положение подписи можно было изменить.
Файл основного скрипта будет иметь следующий вид:
; Импорт вспомогательного скрипта (import "PowerLine_Pillar_Lib.tlc") ; Определение 3D-тел всех элементов опоры соответствующей её конструкции (defun pillar (type view profile length deepening front side bottom) (let ( ; Величина нахлёста секций составных опор (overlap 1.0) ; Вектор горизонтального смещения секций ; составных опор в зависимости от вида опоры (h_offset (if (eql view "Концевая") (vec 0.0 (* -1 side) 0.0) (vec (* -1 front) 0.0 0.0))) ) (v-compound ; Определение 3D-тел опоры (if (eql type "Составная") ; Для составной (composite_pillar profile length deepening front side bottom overlap h_offset) ; Для простой или одностоечной (simple_pillar profile length deepening front side) ) ; Определение 3D-тел упора если опора угловая или концевая (if (or (eql view "Угловая") (eql view "Концевая")) (standoff view type profile length deepening front side bottom overlap h_offset) ) ) ) ) ; Определение 3D-тел упора опоры (defun standoff (view type profile length deepening front side bottom overlap h_offset) (let (incline v_offset direction radians translation rotation) (setq ; Уклон упора в градусах incline 20.0 ; Вертикальный отступ от верха опоры v_offset 2.0 ; Доворот 3D-модели в момент наклона ; Использоуется в функции (v-align) direction (if (eql view "Угловая") 90 0) ; Уклон упора в радианах radians (degrees_to_radians incline) ; Вектор переноса упора translation (if (eql view "Угловая") (vec (* (+ front (* front (cos radians))) 0.5) 0.0 (- length v_offset)) (vec 0.0 (* (+ side (* side (cos radians))) 0.5) (- length v_offset)) ) ; Вектор поворота упора rotation (if (eql view "Угловая") (vec (* -1 (sin radians)) 0.0 (cos radians)) (vec 0.0 (* -1 (sin radians)) (cos radians)) ) ) (if (eql type "Составная") ; Если опора составная (let ( ; Длина верхней секции составного упора (top_standoff_section_length (hypotenuse_length (+ (- length bottom v_offset) overlap) incline)) ; Длина нижней секции составного упора (bottom_standoff_section_length (hypotenuse_length (+ bottom deepening) incline)) ; Длина нахлёста секций составного упора (overlap_standoff_section_length (hypotenuse_length overlap incline)) ; Приращение высоты смещения нижней секции составного упора ; с учётом его наклона. ; (Для того чтобы нахлёсты находились на одном уровне) (bottom_translation_increment (if (eql view "Угловая") (* front (sin radians)) (* side (sin radians)))) ) ; Определение 3D-тел упора составной опоры (composite_standoff profile top_standoff_section_length bottom_standoff_section_length overlap_standoff_section_length bottom_translation_increment translation rotation direction h_offset) ) ; В остальных случаях (let ; Длина упора ((standoff_length (hypotenuse_length (- (+ length deepening) v_offset) incline))) ;Определение 3D-тел простой или одностоечной опоры (simple_standoff profile standoff_length translation rotation direction) ) ) ) ) ; Определение 3D-тел простой или одностоечной опоры (defun simple_standoff (profile standoff_length translation rotation direction) (v-translate translation (v-align (vec) rotation direction (v-extrude profile (vec 0.0 0.0 (* standoff_length -1))) ) ) ) ; Определение 3D-тел упора составной опоры (defun composite_standoff (profile top_section_length bottom_section_length overlap_section_length translation_increment translation rotation direction h_offset) (v-translate translation (v-align (vec) rotation direction (v-compound (v-extrude profile (vec 0.0 0.0 (* top_section_length -1))) (v-translate (vec 0.0 0.0 (* (- top_section_length (+ overlap_section_length translation_increment)) -1 ) ) (v-translate h_offset (v-extrude profile (vec 0.0 0.0 (* bottom_section_length -1))) ) ) ) ) ) ) ; Определение 3D-тел простой или одностоечной опоры (defun simple_pillar (profile length deepening front side) (v-compound (v-extrude profile (vec 0.0 0.0 length)) (v-extrude profile (vec 0.0 0.0 (* deepening -1))) ) ) ; Определение 3D-тел составной опоры (defun composite_pillar (profile length deepening front side bottom overlap h_offset) (v-compound (v-translate h_offset (v-extrude profile (vec 0.0 0.0 bottom)) (v-extrude profile (vec 0.0 0.0 (* -1 deepening))) ) (v-translate (vec 0.0 0.0 (- bottom overlap)) (v-extrude profile (vec 0.0 0.0 (+ (- length bottom) overlap))) ) ) ) ; Определение 3D-тел перекладины крепления проводов ЛЭП (defun crossbar (length side) (let ((width 0.15) (thickness 0.005) (offset 0.3)) (v-translate (vec -1.0 (+ (* side 0.5) (* width 0.5)) (- length offset)) (v-extrude (v-profile-rotate (v-profile-g thickness width) 270) (vec 2.0 0.0 0.0) ) ) ) ) ; Определение компонента (defcomponent "Опора ЛЭП" "SmdxElement" (v-properties ; Группа свойств "Подпись" (defproperty pillar_name "Имя" "Подпись|Имя опоры" (v-property-string)) (defproperty pillar_name_attachment_point (v-object-typed "SmdxPoint" (defproperty x 1.0 "X" (v-property-length-m)) (defproperty y 0.0 "Y" (v-property-length-m)) (defproperty z 0.0 "Z" (v-property-length-m)) ) "Подпись|Положение" (v-property-typed "SmdxPoint") ) (defproperty pillar_name_rotation 0 "Подпись|Угол поворота" (v-property-double "deg" 0 360) ) ; Группа свойств "Опора" (defproperty pillar_material "Дерево" "Опора|Материал" (v-property-enum lep_pillar_materials)) (defproperty pillar_view "Промежуточная" "Опора|Вид" (v-property-enum lep_pillar_views)) ; Определение свойства типа (setq pillar_type_prop_tag (gen-type-tag pillar_material)) (let (selected_lep_types) (setq selected_lep_types (get-pillar-types pillar_material)) (v-property t (symbol-name pillar_type_prop_tag) (get-first-dict-element selected_lep_types) "Опора|Тип конструкции" (v-property-enum selected_lep_types)) ) ; Определение свойства шифра (setq pillar_cipher_prop_tag (gen-cipher-tag pillar_material pillar_view (getproperty pillar_type_prop_tag) )) (let (selected_lep_ciphers) (setq selected_lep_ciphers (get-pillar-ciphers pillar_material pillar_view (getproperty pillar_type_prop_tag) )) (v-property t (symbol-name pillar_cipher_prop_tag) (get-first-dict-element selected_lep_ciphers) "Опора|Шифр" (v-property-enum selected_lep_ciphers)) ) ; Группа свойств "Размеры" (if (eql (getproperty pillar_cipher_prop_tag) "custom") ; В случае с пользовательским шифром добавляются свойства ; с возможностью указывать пользовательские значения (v-properties (defproperty pillar_length 6.0 "Размеры|Длина" (v-property-double "m" 3.0 100.0) ) (defproperty pillar_deepening 2.0 "Размеры|Заглубление" (v-property-double "m" 0.001 10.0) ) (if (eql pillar_material "ЖБ") ; Для ЖБ опор добавляем свойства Ширины и Толщины (v-properties (defproperty pillar_width 0.2 "Размеры|Ширина" (v-property-double "m" 0.001 1.0) ) (defproperty pillar_thickness 0.28 "Размеры|Толщина" (v-property-double "m" 0.001 1.0) ) ) ; Для деревянных опор добавляем свойсто Диаметр (defproperty pillar_diameter 0.20 "Размеры|Диаметр" (v-property-double "m" 0.001 1.0) ) ) ; Для составных опор добавляем свойство длины нижней секции (if (eql (getproperty pillar_type_prop_tag) "Составная") (defproperty pillar_bottom_length 3.0 "Размеры|Длина нижней секции" (v-property-double "m" 1.0 10.0) ) ) ) ; Для шифра из сортамента получаем набор характеристик из словаря ; И обавляем те же свойства, что и для пользовательского шифра, ; но с соответствующими значениями и без возможности их изменять (let ((data (dict-get lep_pillar_sortament (getproperty pillar_cipher_prop_tag)))) (v-properties (setproperty pillar_length (cadddr data) "Размеры|Длина") (setproperty pillar_deepening (caddddr data) "Размеры|Заглубление") (if (eql pillar_material "ЖБ") ; ЖБ (v-properties (setproperty pillar_thickness (cadddddr data) "Размеры|Толщина") (setproperty pillar_width (caddddddr data) "Размеры|Ширина") ) ; Дерево (setproperty pillar_diameter (cadddddr data) "Размеры|Диаметр") ) (if (eql (getproperty pillar_type_prop_tag) "Составная") (setproperty pillar_bottom_length (caddddddr data) "Размеры|Длина нижней секции") ) ) ) ) ; Свойство вставки дополнительного элемента (defproperty pillar_slot_element nil "Вставка|Элемент" (v-property-typed "SmdxElement") ) ; Свойство вставки дополнительного элемента (defproperty pillar_element_elevation 4.5 "Вставка|Высота вставки элемента" (v-property-double "m" 1.0 pillar_length) ) ) ; Определение геометрии опоры ЛЭП (defgeometry (let ( ; Профиль сечения опоры (profile (if (eql pillar_material "ЖБ") (v-profile-rect pillar_width pillar_thickness) (v-profile-round pillar_diameter))) ; Ширина опоры спереди (front_size (if (eql pillar_material "ЖБ") pillar_width pillar_diameter)) ; Ширина опоры сбоку (side_size (if (eql pillar_material "ЖБ") pillar_thickness pillar_diameter)) ; Длина нижней секции составной опоры (bottom_length (if (eql (getproperty pillar_type_prop_tag) "Составная") pillar_bottom_length 0.0)) ; Смещение вставки элемента относительно высоты опоры (element_offset 1.0) (color (gen-material-color pillar_material)) ) (v-compound ; Определение 3D-тел опоры ЛЭП (v-styled (v-phong "Цвет" color) (pillar (getproperty pillar_type_prop_tag) pillar_view profile pillar_length pillar_deepening front_size side_size bottom_length) ) ; Определение 3D-тел перекладины крпеления проводов ЛЭП (crossbar pillar_length side_size) ; Вставка элемента из библиотеки 3D-моделей (if pillar_slot_element (v-translate (vec (* -1 (* 0.5 front_size)) 0.0 pillar_element_elevation) (v-align (vec) (vec 0 0 1) 270 (setelement "Элемент" pillar_slot_element)) ) ) ) ) ) ; Определение вида на плане (defview (v-top) ; Отрисовка сечения опоры (if (eql pillar_material "ЖБ") (v-translate (vec (* -1 (* 0.5 pillar_width)) (* -1 (* 0.5 pillar_thickness))) (v-compound (v-entity-line (vec) (vec pillar_width 0.0)) (v-entity-line (vec pillar_width 0.0) (vec pillar_width pillar_thickness)) (v-entity-line (vec pillar_width pillar_thickness) (vec 0.0 pillar_thickness)) (v-entity-line (vec 0.0 pillar_thickness) (vec)) ) ) (v-entity-circle pillar_diameter) ) ; Отрисовка подписи опоры (if (eql (eql pillar_name "") false) (let (width) (setq width (if (eql pillar_material "ЖБ") (* 0.5 pillar_width) (* 0.5 pillar_diameter)) text_offset (+ 0.5 (* 0.5 width))) (v-align (vec (getproperty pillar_name_attachment_point "x") (getproperty pillar_name_attachment_point "y") 0.0) (vec 0 0 1) pillar_name_rotation (v-entity-text pillar_name (* mapscale 1.6) 9 "pillar_name" "Имя опоры") ) ) ) ) )
Проделайте следующие действия:
Результатом действий станет размещение опоры ЛЭП на плане: