Инструменты пользователя

Инструменты сайта


developers:references:tlc:example_linear:start

Пример TLC-скрипта линейного объекта


Раздел на модерации

Рассмотрим создание конструкции линейного объекта на примере раскладки пролётных строений вдоль трассы подобъекта. Предусмотрим два вида пролётного строения:

1. Односкатное с уклоном 40‰ и возможностью выбора стороны наклона

2. Двускатное с уклоном 20‰

Так же предусмотрим:

  • Изменение длины основной плиты;
  • Изменение высоты балок на которых лежит основная плита пролётного строения;
  • Деформационный шов изменяемой величины;

Скрипты компонентов основной плиты и балки

Основную плиту и балку опишем отдельными компонентами и разместим их код в разных tlc-скриптах, которые будут импортироваться в теле основного скрипта. Эти компоненты будут обладать свойствами, но у них не будет геометрии. Определение геометрии будет производиться в теле основного скрипта, основываясь на значениях свойств компонентов основной плиты и балки.

Компонент основной плиты будет содержать три свойства:

  • Вид
  • Сторона
  • Уклон

Скрипт компонента основной плиты будет иметь следующий вид:

Bridge_Span_Deck.tlc
(setq
  ; Словарь видов пролётного строения
  bridge_deck_views (dict
                      "single" "Односкатное"
                      "double" "Двускатное"
                    )
  ; Словарь сторон наклона
  ;односкатного пролётного строения
  bridge_deck_leans (dict
                      "left" "Влево"
                      "right" "Вправо"
                    )
)
 
; Определение компонента основной плиты пролётного строения
(defcomponent "Основная плита" "SmdxElement"
  (v-properties
    ; Свойство вида пролётного строения
    (defproperty bridge_deck_view "single" "Вид"
      (v-property-enum bridge_deck_views))
    ; Если пролётное строение односкатное то добавляем свойство Наклона
    (if (eql bridge_deck_view "single")
      (defproperty bridge_deck_lean "left" "Сторона"
        (v-property-enum bridge_deck_leans))
    )
    ; Свойство уклона пролётного строения
    ; с неизменяемым (readonly) значением.
    ; Значение определяется по виду
    ; и стороне наклона пролётного строения
    (setproperty bridge_deck_incline
      (if (eql bridge_deck_view "single")
        (if (eql bridge_deck_lean "left")
          40
          -40
        )
        -20
      )
      "Уклон, ‰"
    )
  )
)

Скрипт компонента балки будет иметь следующий вид:

Bridge_Span_Girder.tlc
; Определение конструкции балки пролётного строения
(defcomponent "Балка пролётного строения" "SmdxElement"
  (v-properties
    ; Свойство ширины с неизменяемым (readonly) значением
    (setproperty bridge_girder_width 1.4 "Ширина")
    ; Свойство высоты балки
    (defproperty bridge_girder_height 2.0 "Высота"
      (v-property-double "m" 0.01 100.0))
  )
)

Основной скрипт

Компоненты основной плиты и балки потребуются для определения профиля пролётного строения, поэтому сразу импортируем их.

Последняя функция основного скрипта должна возвращать компонент, поэтому блок defcomponent должен быть расположен в конце файла.

В теле основного скрипта опишем сам компонент и функции определяющие его геометрию:

               Функция                Описание
get-bridge-span-profile Определение профиля пролётного строения
get-road-bed-profile Определение профиля проезжей части
insert-bridge-span Расположение пролетных строений на кривой

Выбор линейного объекта при вставке конструкции на план, осуществляется с помощью свойства axis_curve типа объект информационной модели с предустановленным smdx-типом SmdxPolyline.

Импортированные компоненты основной плиты и балки применяются в качестве значения по умолчанию для свойств bridge_deck_element (основная плита) и bridge_girder_element (балка). Эти свойства имеют тип свойства объект информационной модели, таким образом нам станут доступны свойства этих компонентов в окне инспектора свойств.

Также предусмотрим следующие свойства свойства:

  • Длина плиты
  • Деформационный шов
  • Смещение от начала
  • Смещение от конца
  • Количество плит (Свойство с неизменяемым значением (readonly). Считаются только плиты полной длины.)

На основе указанных значений свойств формируются профиль пролётного строения. Путём вытягивания профиля сформируются 3D-тела и рассчитается их расположение вдоль линейного объекта.

Файл основного скрипта будет иметь следующий вид:

"Bridge_Span.tlc"
; Подгрузка конструкции балки и определение возможных типа пролётного строения
(setq bridge_girder (import "Bridge_Span_Girder.tlc")
      bridge_deck (import "Bridge_Span_Deck.tlc")
)
 
; Определение профиля пролётного строения
(defun get-bridge-span-profile (deck girder)
  (let
    ; Объявление переменных
    (central_width central_height side_width
    incline left_incline right_incline
    girder_step girder_width girder_height girder_profile
    road_bed_height left_bed_height right_bed_height
    road_bed_width left_profile right_profile deck_view)
    ; Инициализация переменных
    (setq 
      central_width 2.0
      central_height 1.0
      side_width 3.0
      girder_step 6.375
      incline (* (getproperty deck 'bridge_deck_incline) 0.001)
      deck_view (getproperty deck 'bridge_deck_view)
      girder_width (getproperty girder 'bridge_girder_width)
      girder_height (getproperty girder 'bridge_girder_height)
      girder_profile  (v-profile-translate 
                        (v-profile-rect girder_width girder_height)
                        (vec 0.0 (* -0.5 girder_height))
                      )
      left_profile  (v-profile-shape
                      (vec (* 0.5 side_width) 0.5)
                      (vec (* -0.5 side_width) 0.6)
                      (vec (* -0.5 side_width) 0.6)
                      (vec (* -0.5 side_width) -0.5)
                      (vec (* -0.5 side_width) -0.5)
                      (vec (* 0.5 side_width) -0.5)
                      (vec (* 0.5 side_width) -0.5)
                      (vec (* 0.5 side_width) 0.5))
      right_profile (v-profile-mirror left_profile (vec 0 0 1))
      road_bed_width (- (* 2 girder_step) (* 0.5 side_width) (* 0.5 central_width))
      road_bed_height (* incline road_bed_width)
      left_incline  (cond
                      ((eql deck_view "single") (* -1 incline))
                      ((eql deck_view "double") incline)
                    )
      right_incline incline
      left_bed_height (cond
                        ((eql deck_view "single") (* -1 road_bed_height))
                        ((eql deck_view "double") road_bed_height)
                      )
      right_bed_height road_bed_height
    )
    ; Определение профиля пролётного строения
    ; Профиль изначально строим как есть и в последствии отзеркаливаем
    ; потому что при выдавливании
    ; профиль располагается плоскостью к вектору выдавливания,
    ; что приводит к эффекту разворота профиля
    (v-profile-mirror
      (v-profile-compound
        ; Середина
        (v-profile-rect central_width central_height)
        (v-profile-translate girder_profile  (vec 0 (* central_height -0.5)))
 
        ; Правая сторона
        (v-profile-translate right_profile (vec (* 2 girder_step) right_bed_height))
        (get-road-bed-profile
          central_width side_width girder_step girder_width right_incline nil)
        (v-profile-translate girder_profile
          (vec girder_step
            (- (* right_incline (- girder_step (* 0.5 central_width ))) 0.5)))
        (v-profile-translate girder_profile
          (vec (* 2 girder_step) (- (* right_incline road_bed_width) 0.5)))        
 
        ; Левая сторона
        (v-profile-translate left_profile (vec (* -2 girder_step) left_bed_height))
        (get-road-bed-profile central_width side_width
          girder_step girder_width left_incline t)
        (v-profile-translate girder_profile  
          (vec (* -1 girder_step)
            (- (* left_incline (- girder_step (* 0.5 central_width ))) 0.5)))
        (v-profile-translate girder_profile
          (vec (* -2 girder_step) (- (* left_incline road_bed_width) 0.5)))
      )
      (vec 0.0 0.0 1.0)
    )
  )
)
 
; Определение профиля проезжей части
(defun get-road-bed-profile
  (central_width side_width girder_step girder_width incline to_mirror)
  (let (length profile)
    (setq 
      length (- (* 2 girder_step) (* 0.5 (+ central_width side_width)))
      profile (v-profile-shape
                (vec (* 0.5 central_width) 0.0)
                (vec (+ (* 0.5 central_width) length) (* incline length))
                (vec (+ (* 0.5 central_width) length) (* incline length))
                (vec (+ (* 0.5 central_width) length) (- (* incline length) 0.5))
                (vec (+ (* 0.5 central_width) length) (- (* incline length) 0.5))
                (vec (+ girder_step (* 0.5 girder_width))
                  (- (* incline (- girder_step (* 0.5 central_width ))) 0.5))
                (vec (+ girder_step (* 0.5 girder_width))
                  (- (* incline (- girder_step (* 0.5 central_width ))) 0.5))
                (vec (- girder_step (* 0.5 girder_width))
                  (- (* incline (- girder_step (* 0.5 central_width ))) 0.5))
                (vec (- girder_step (* 0.5 girder_width))
                  (- (* incline (- girder_step (* 0.5 central_width ))) 0.5))
                (vec (* 0.5 central_width) -0.5)
                (vec (* 0.5 central_width) -0.5)
                (vec (* 0.5 central_width) 0.0)
              )
    )
    (if to_mirror
      (v-profile-mirror profile (vec 0.0 0.0 1.0))
      profile
    )
  )
)
 
; Вставка пролетного строения на кривой
(defun insert-bridge-span (profile curve s_param e_param)
  (let
    (start_point end_point ox oy oz)
    (setq
      start_point (v-curve-d0 curve s_param)
      end_point (v-curve-d0 curve e_param)
      length (vec-len (vec-sub end_point start_point ))
      ox (vec-normalize (vec-sub start_point end_point))
      oy (vec-normalize (vec-cross (vec 0 0 1) ox))
      oz (vec-cross ox oy)
    )
    (v-align
      start_point oz oy
      (v-extrude profile (vec 0.0 length))
    )
  )
)
 
; Определение конструкции пролётного строения
(defcomponent "Пролётное строение" "SmdxElement"
  ; Определение блока свойств конструкции
  (v-properties
    (defproperty axis_curve nil "Ось" (v-property-typed "SmdxPolyline"))
    (defproperty bridge_deck_element bridge_deck "Основная плита"
      (v-property-typed "SmdxElement"))
    (defproperty bridge_girder_element bridge_girder "Балка"
      (v-property-typed "SmdxElement"))
    (defproperty bridge_span_length 5.0 "Длина плиты"
      (v-property-double "m" 0.01 100.0))
    (defproperty bridge_span_joint_length 0.05 "Деформационный шов"
      (v-property-double "m" 0.001 1.0))
    (defproperty bridge_span_start_offset 0.0 "Смещение от начала"
      (v-property-double "m" 0.01 100.0))
    (defproperty bridge_span_end_offset 0.0 "Смещение от конца"
      (v-property-double "m" 0.01 100.0))
  )
 
  (setq bridge_span_counter 0)
 
  (defgeometry
    (if axis_curve
      (let 
        ; Объявление переменных
        (
          span_profile axis_length cur_param end_param
          finish_param span_param_increment joint_param_increment params
        )
        ; Инициализация переменных
        (setq
          axis_length (v-curve-length axis_curve)
          span_param_increment (/ bridge_span_length axis_length)
          joint_param_increment (/ bridge_span_joint_length axis_length)
          cur_param (/ bridge_span_start_offset axis_length)
          finish_param (- 1.0 (/ bridge_span_end_offset axis_length))
          params (list)
          span_profile (get-bridge-span-profile bridge_deck_element
                         bridge_girder_element)
        )
        ; Расчёт параметров вставки пролётных строений на кривой 
        (while (< cur_param finish_param)
          (let (start_param end_param start_point end_point ox oy oz)
            (setq start_param cur_param
                  end_param (+ cur_param span_param_increment)
            )
            (if (> end_param finish_param)
              (setq end_param finish_param)
              (setq bridge_span_counter (+ bridge_span_counter 1))
            )
            (setq params (cons (list start_param end_param) params)
                  cur_param (+ end_param joint_param_increment)
            )
          )
        )
        ; Вставка пролётных строений по кривой
        (v-compound
          (v-for
            (item params)
            (let (start_param end_param start_point end_point ox oy oz)
              (setq start_param (car item)
                    end_param (cadr item)
              )
              (insert-bridge-span span_profile axis_curve start_param end_param)
            )
          )
        )
      )
    )
  )
  ; Добавление readonly свойства количества 
  (setproperty bridge_span_count bridge_span_counter "Количество плит")
)

Проделайте следующие действия:

  1. Сохраните файлы Bridge_Span.tlc, Bridge_Span_Deck.tlc и Bridge_Span_Girder.tlc так чтобы они находились в одной директории вашего накопителя;
  2. Выберите пункт меню «Задачи» → «Визуализация» → «Добавить 3D-сборку»;
  3. В открывшемся диалоговом окне укажите путь к сохранённому файлу. Bridge_Span.tlc;
  4. Программа предложит вам указать ось. Вы можете указать координаты оси курсором на плане или нажать на клавиатуре стрелку вниз «↓», после чего откроются другие доступные варианты. Если требуется выбрать существующий линейный объект, выберите пункт «По линейному объекту»

Результатом действий станет размещение пролётных строений вдоль линейного объекта:

developers/references/tlc/example_linear/start.txt · Последние изменения: 2023/08/06 16:27 — proxor