ADN Open CIS
Сообщество программистов Autodesk в СНГ

19/08/2016

Значение координаты Z в строку текста

Поступила мне тут просьба - в файле dwg есть большое (около 1000) объектов TEXT и MTEXT, у которых изменена точка вставки по оси 0z. В эти объекты надо "вбить" значение их высоты с точностью до 2 знаков после запятой.

Недолгие расспросы определили практически тепличные условия:

  1. Все объекты созданы в мировой системе координат
  2. Текушая система координат - мировая
  3. Результат должен быть именно в текущей (мировой) системе координат

Поскольку я лентяй, я нарисовал достаточно простую программку:

Код - Auto/Visual LISP: [Выделить]
  1.  
  2. (vl-load-com)
  3.  
  4. (defun c:h2str (/ adoc selset err err_lst)
  5.   (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
  6.   (if (= (type (setq selset (vl-catch-all-apply (function (lambda () (ssget "_:L" '((0 . "*TEXT"))))))))
  7.          'pickset
  8.          ) ;_ end of =
  9.     (progn
  10.       (foreach ent (mapcar (function vlax-ename->vla-object)
  11.                            ((lambda (/ item tab)
  12.                               (repeat (setq tab  nil
  13.                                             item (sslength selset)
  14.                                             ) ;_ end setq
  15.                                 (setq tab (cons (ssname selset (setq item (1- item))) tab))
  16.                                 ) ;_ end of repeat
  17.                               ) ;_ end of lambda
  18.                             )
  19.                            ) ;_ end of mapcar
  20.         (if (vl-catch-all-error-p
  21.               (setq err (vl-catch-all-apply
  22.                           (function
  23.                             (lambda (/ z)
  24.                               (setq z (* 0.01 (* 100 (caddr (vlax-safearray->list (vlax-variant-value (vla-get-insertionpoint ent))))))
  25.                                     z (if (= (rem (fix (* 10 (- (* (abs z) 100) (fix (* (abs z) 100))))) 5) 0)
  26.                                         (rtos (* 0.01 (fix (* z 100))) 2 2)
  27.                                         (rtos z 2 2)
  28.                                         ) ;_ end of if
  29.                                     ) ;_ end of setq
  30.                               (if (not (vl-string-search "." z))
  31.                                 (setq z (strcat z ".00"))
  32.                                 (while (< (strlen (substr z (+ 2 (vl-string-search "." "55.6")))) 2) (setq z (strcat z "0")))
  33.                                 ) ;_ end of if
  34.                               (vla-put-textstring ent z)
  35.                               ) ;_ end of lambda
  36.                             ) ;_ end of function
  37.                           ) ;_ end of vl-catch-all-apply
  38.                     ) ;_ end of setq
  39.               ) ;_ end of vl-catch-all-error-p
  40.           (setq err_lst (cons (vl-catch-all-error-message err) err_lst))
  41.           ) ;_ end of if
  42.         ) ;_ end of foreach
  43.       ) ;_ end of progn
  44.     ) ;_ end of if
  45.   (foreach item err_lst (princ (strcat "\nОшибка назначения высоты для текста : " item)))
  46.   (vla-endundomark adoc)
  47.   (princ)
  48.   ) ;_ end of defun
  49.  

Принцип работы прост: запрашиваем объекты, не лежащие на заблокированных слоях, и проходим по ним. Для каждого объекта получаем координаты его точки вставки (свойство InsertionPoint есть и у однострочного, и у многострочного текста), забираем координату Z, и приводим ее к строке с двумя знаками после запятой. Разделителем целой и дробной части принята точка (по условиям, которые мне выставили конечные потребители программки).

Работа кода проверена на AutoCAD 2002-2016, особых нареканий пока не выявлено.

Понятно, что как только в задачу вмешаются немировые системы координат, код быстро дополнится многочисленными trans. Но мне было легче ;)

Автор: Алексей Кулик

Обсуждение: http://adn-cis.org/forum/index.php?topic=

Опубликовано 19.08.2016