О пользе ename-представлений

Привык я как-то к тому, что через ActiveX можно сделать все или почти все. Привык, что тут поделать... Но вот попалась задачка, решить которую средствами только ActiveX оказалось невозможно.

Задача проста до невозможности: необходимо изменить базовую точку штриховки. При этом условия - как в пансионате: все происходит в одном и том же пространстве, только в мировой системе координат, штриховка имеет тоже мировую систему координат. Пробуем достаточно простой код:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
(vl-load-com)

(defun c:chh (/ adoc hatch base)
  (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
  (if (and (= (type (setq hantch (vl-catch-all-apply
                                   (function
                                     (lambda ()
                                       (ssname (ssget "_+.:S:E:L" '((0 . "HATCH"))) 0)
                                       ) ;_ end of lambda
                                     ) ;_ end of function
                                   ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'ename
              ) ;_ end of =
           (= (type (setq base (vl-catch-all-apply
                                 (function
                                   (lambda ()
                                     (getpoint "\nSelect new base point <Cancel> : ")
                                     ) ;_ end of lambda
                                   ) ;_ end of function
                                 ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'list
              ) ;_ end of =
           base
           ) ;_ end of and
    (progn
      (vla-put-origin (vlax-ename->vla-object hantch)
                      (vlax-make-variant
                        (vlax-safearray-fill
                          (vlax-make-safearray vlax-vbdouble '(0 . 1))
                          (list (car base) (cadr base))
                          ) ;_ end of vlax-safearray-fill
                        ) ;_ end of vlax-make-variant
                      ) ;_ end of vla-put-Origin
      (redraw)
      ) ;_ end of progn
    ) ;_ end of if
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun

И получаем полноценный латвийский праздник "Обломайтэс". То есть базовая точка, скорее всего, меняется, а вот вид штриховки - фигушки.
Ну, раз так, то лезем в DXF Reference и находим, что для штриховки есть отдельный "раздел" dxf-ключей: pattern data. И там есть две группы:
43 Pattern line base point, X component
44 Pattern line base point, Y component
Отлично! Тогда их менять и будем:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
(vl-load-com)

(defun c:chh (/ adoc hatch elist base)
  (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object))))
  (if (and (= (type (setq hantch (vl-catch-all-apply
                                   (function
                                     (lambda ()
                                       (ssname (ssget "_+.:S:E:L" '((0 . "HATCH"))) 0)
                                       ) ;_ end of lambda
                                     ) ;_ end of function
                                   ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'ename
              ) ;_ end of =
           (= (type (setq base (vl-catch-all-apply
                                 (function
                                   (lambda ()
                                     (getpoint "\nSelect new base point <Cancel> : ")
                                     ) ;_ end of lambda
                                   ) ;_ end of function
                                 ) ;_ end of vl-catch-all-apply
                          ) ;_ end of setq
                    ) ;_ end of type
              'list
              ) ;_ end of =
           base
           ) ;_ end of and
    (progn
      (setq elist (entget hantch))
      (foreach item (list (cons 43 (car base))
                          (cons 44 (cadr base))
                          ) ;_ end of list
        (setq elist (subst item
                           (assoc (car item) elist)
                           elist
                           ) ;_ end of subst
              ) ;_ end of setq
        ) ;_ end of foreach
      (entmod elist)
      (entupd hantch)
      ) ;_ end of progn
    ) ;_ end of if
  (vla-endundomark adoc)
  (princ)
  ) ;_ end of defun

Логика такова: после получения указателей на штриховку и новой базовой точки выполняется "дамп" объекта штриховки, в этом "дампе" меняются 43 и 44 группы, а потом уже модифицированное ename-представление обновляется (entmod) и регенерируется (entupd).
Мораль проста: ActiveX, конечно, вещь, но не всемогущая. Про ename тоже забывать не след.
---
P.S. lisp-код можно взять здесь: chh.lsp

Размещено в Код LISP, Новости, Функции LISP · Метки:



Комментарии

Есть 9 коммент. к “О пользе ename-представлений”
  1. Кулик Алексей aka kpblc пишет:

    Только что позвонил Евгений Елпанов, и сказал, что для штриховок есть отдельный метод, который позволяет (по крайней мере теоретически) получить изменения сразу. Таки да, есть метод Evaluate, но даже его применение для уже существующей штриховки не дало видимого эффекта на AutoCAD 2011 64 bit.
    То есть базовая точка для штриховки меняется (это видно по дампу объекта), но визуально изменения штриховки не касаются - надо лезьть в панель свойств, там менять, к примеру, масштаб - вот тогда все становится здорово и круто.
    Каково будет поведение для варианта добавления элементов в контур - не знаю, не проверял.
    P.S. За компанию код для vla-обновления штриховки. Если кому-то интересно, погоняйте, проверьте. Вдруг это у меня на машине глюк.
    chh-vla.lsp

  2. Gontarski пишет:

    Скажите, а какой физический смысл всех этих "(vl-catch-all-apply" в вашем коде? Спасибо.

  3. Кулик Алексей aka kpblc пишет:

    Элементарный - отлов ошибок. Подробнее см. Код без ошибок – возможно ли?

  4. Gontarski пишет:

    Спасибо за ответ. :)

    >Элементарный – отлов ошибок.
    Я в курсе функционала. Я намекал, что в конкретно взятом примере их применение не имеет никакого смысла, а только лишь убивает читабельность кода (вы ведь для новичков здесь код выкладываете, так?). Это же можно сказать о применении здесь foreach.

    всё тоже самое можно выразить например вот так:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    (defun c:chh3 ( / adoc elist base)

        ;укажем исходные данные
        (while (= (setq ss (ssget ":S" '((0 . "HATCH")))) nil) (prompt "\nНеобходимо указать штриховку!!"))
      (while (= (setq base (getpoint "\nУкажите новую базовую точку для штриховки: ")) nil))

        ;dxf список штриховки
        (setq elist (entget (ssname ss 0)))
     
      ;изменим координаты базовой точки в списке
        (setq elist (subst (cons 43 (car base)) (assoc 43 elist) elist))
        (setq elist (subst (cons 44 (cadr base)) (assoc 44 elist) elist))

        (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object)))) ;для обеспечения корректной отмены наших действий
     
        (entmod elist) ;изменим штриховку в соответствии с новым списком
        (entupd (ssname ss 0)) ;обновим отображение штриховки
     
      (vla-endundomark adoc) ;для обеспечения корректной отмены наших действий
        (princ)
    );defun
  5. Gontarski пишет:

    что-то таг не сработал, извините.

    (defun c:chh3 ( / adoc elist base)

    ;укажем исходные данные
    (while (= (setq ss (ssget ":S" '((0 . "HATCH")))) nil) (prompt "\nНеобходимо указать штриховку!!"))
    (while (= (setq base (getpoint "\nУкажите новую базовую точку для штриховки: ")) nil))

    ;dxf список штриховки
    (setq elist (entget (ssname ss 0)))

    ;изменим координаты базовой точки в списке
    (setq elist (subst (cons 43 (car base)) (assoc 43 elist) elist))
    (setq elist (subst (cons 44 (cadr base)) (assoc 44 elist) elist))

    (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object)))) ;для обеспечения корректной отмены наших действий

    (entmod elist) ;изменим штриховку в соответствии с новым списком
    (entupd (ssname ss 0)) ;обновим отображение штриховки

    (vla-endundomark adoc) ;для обеспечения корректной отмены наших действий
    (princ)
    );defun

  6. Gontarski пишет:

    что-то тэг лисп-кода не сработал :(

    (defun c:chh3 ( / adoc elist base)

    ;укажем исходные данные
    (while (= (setq ss (ssget ":S" '((0 . "HATCH")))) nil) (prompt "\nНеобходимо указать штриховку!!"))
    (while (= (setq base (getpoint "\nУкажите новую базовую точку для штриховки: ")) nil))

    ;dxf список штриховки
    (setq elist (entget (ssname ss 0)))

    ;изменим координаты базовой точки в списке
    (setq elist (subst (cons 43 (car base)) (assoc 43 elist) elist))
    (setq elist (subst (cons 44 (cadr base)) (assoc 44 elist) elist))

    (vla-startundomark (setq adoc (vla-get-activedocument (vlax-get-acad-object)))) ;для обеспечения корректной отмены наших действий

    (entmod elist) ;изменим штриховку в соответствии с новым списком
    (entupd (ssname ss 0)) ;обновим отображение штриховки

    (vla-endundomark adoc) ;для обеспечения корректной отмены наших действий
    (princ)
    );defun

  7. Кулик Алексей aka kpblc пишет:

    В конкретно взятом примере отлов ошибок имеет прямое значение: а если я в момент запроса штриховки нажму Esc? Или в момент запроса точки?
    Я стараюсь показывать не столько коды для начинающих, сколько гарантированно работающие и более-менее правильно написанные коды :)

  8. Gontarski пишет:

    >а если я в момент запроса штриховки нажму Esc? Или в момент запроса точки?

    В смысле в приведенном мной коде? Нормально всё отработает. Будет выдано сообщение об отмене команды, всего-то делов. Так-же как и в Вашем коде. Об том и речь - при той же функциональности разница в коде очевидна. Ну по крайней мере мне. :)

    Ну да и ладно, чой-та я полез в чужой монастырь со своими молитвами. Спасибо за плодотворную беседу, Ваш сайт на самом деле очень полезен, честно. Хорошая работа! ;)

    ЗЫ: Но насчет прозрачности и компактности кода рекомендую таки задуматься. ;)

  9. Кулик Алексей aka kpblc пишет:

    Все дело в том, что ошибки обрабатываются по-разному: Код без ошибок

Поделитесь своим мнением


Я не робот.