Тема: Точка вставки атрибута блока, вложенного в др-й блок?

Добрый день!
Проблема следующая:
Если у блока есть атрибут, точка вставки этого атрибута легко находится через
(cdr (assoc 10 (entget ob)))
либо
(vlax-get obj "InsertionPoint")
а как быть, если этот блок ВЛОЖЕН в другой блок?
Вышеприведенные варианты не дают правильные координаты,
хотя
(cdr (assoc 10 (entget (car (nentsel)))))
возвращает то, что нужно.
Как получить "правильную" точку вставки атрибута блока, если
блок вложен в другой блок?

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Что-то желающих поделиться мыслями нет...
Может вопрос поставлен непонятно?

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Самый топорный вариант:
заметить entlast;
сделать копию "большого" блока;
подорвать ее;
найти в груде обломков "маленький" блок c нужным атрибутом и сделать с ним все, что надо;
убрать мусор.
Может быть, гуру предложат что-то лучше

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Не, не пойдёт.
А если блок вложен "глубже", чем один раз?
Всё рвать?
Каким-то образом (entget (car (nentsel))) правильно видит координаты, значит должен быть способ, чтобы до них добраться... Только как?

Re: Точка вставки атрибута блока, вложенного в др-й блок?

А вообще с помощью Vlisp это возможно? Хоть в какую сторону копать, кто-нибудь, толкните...

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Что-то странное молчание по поводу моей проблемы...
Собственно атрибуты вообще не использую, но "товарищи по оружию" - кто во что горазд. Попадаются файлы просто с невообразимой структурой (для меня, по крайней мере). Написал себе лисп, который объекты адаптирует к моему видению черчения на ACAD. Вот пытаюсь бороться с атрибутами в блоках, которые в свою очередь могут быть вложены в другие блоки ещё глубже (и не один раз). Нужна "их" InsertionPoint...
Ну может кто-то поделится идеей (сказал он почти обречённо)...

Re: Точка вставки атрибута блока, вложенного в др-й блок?

А как ты добираешься до указателя на атрибут? (пока вопрос "а зачем надо получать координаты атрибутов" оставим в стороне)

Re: Точка вставки атрибута блока, вложенного в др-й блок?

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

  (setq ss (ssget "_X" '((0 . "INSERT"))))
  (if ss (progn
    ;; получить список имён блоков в наборе
    (setq LstBlock
      (mapcar
        (function vlax-ename->vla-object)
        (vl-remove-if (function listp)(mapcar (function cadr)(ssnamex ss)))
      )
    )
    ;; составить список блоков с атрибутами
    (setq LstBlockAtt
      (vl-remove-if-not
        (function (lambda (x)(vlax-invoke x 'GetAttributes)))
        LstBlock
      )
    )
    ;; подфункция для поиска атрибутов внутри блоков
    (defun *subblock* (OBJ*)
      (vl-catch-all-apply (function (lambda ()
        ;; для каждого объекта, вложенного в блок, снова запускать функцию
        (if (= (vla-get-objectname OBJ*) "AcDbBlockReference")
          (vlax-for i
            (vla-item
              (vla-get-Blocks (vla-get-activedocument (vlax-get-acad-object)))
              (vla-get-Name OBJ*)
            )
            (if (vlax-invoke i 'GetAttributes)
              ;; дополнять список из блоков с атрибутами
              (setq LstBlockAtt (cons  i LstBlockAtt))
            )
            (*subblock* i)
          )
        )
      )))
    ) ;;...defun
    ;; проверить все блоки, в том числе и вложенные
    (mapcar
      (function (lambda (x)(*subblock* x)))
      LstBlock
    )
    ;; список всех возможных атрибутов
    (setq AttLst
      (apply (function append)(mapcar
        (function (lambda (x)
          (vlax-safearray->list (vlax-variant-value (vla-GetAttributes x)))
        ))
        LstBlockAtt
      ))
    )
  )) ;;...if ss progn

Re: Точка вставки атрибута блока, вложенного в др-й блок?

> Re:] Kosarev
Для одиночного выбора можно наверно так:

(defun test (/ ent ins-point-atr lst-point-atr)
  (defun ins-point-atr (Obj)
    (if    (= (strcase (vla-get-objectname Obj) t)
       "acdbblockreference"
    ) ;_ end of =
      (progn
    (setq lst-point-atr
           (append
         lst-point-atr
         (mapcar '(lambda (x)
                (vlax-safearray->list
                  (vlax-variant-value (vla-get-InsertionPoint x))
                ) ;_ end of vlax-safearray->list
              ) ;_ end of lambda
             (vlax-invoke Obj 'GetAttributes)
         ) ;_ end of mapcar
           ) ;_ end of append
    ) ;_ end of setq
    (vlax-for ent
          (vla-item
            (vla-get-blocks
              (vla-get-activedocument (vlax-get-acad-object))
            ) ;_ end of vla-get-blocks
            (vla-get-name Obj)
          ) ;_ end of vla-item
      (if (= (strcase (vla-get-objectname ent) t)
         "acdbblockreference"
          ) ;_ end of =
        (ins-point-atr ent)
      ) ;_ end of if
    ) ;_ end of vlax-for
      ) ;_ end of progn
    ) ;_ end of if
  ) ;_ end of defun
  (if (setq ent (car (entsel "\nУкажите блок: \n")))
    (ins-point-atr
      (vlax-ename->vla-object ent)
    ) ;_ end of ins-point-atr
  ) ;_ end of if
  lst-point-atr
) ;_ end of defun

Для множественного выбора блоков я думаю сложностей не составит...

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Уважаемый CB, спасибо за отклик и отличный лисп,
но он не решает моей проблемы. Т.е. не годится для блоков с атрибутами, которые ВЛОЖЕНЫ в другие блоки (возможно несколько раз). По крайней мере у меня это не получилось. Ваш лисп в случае выбора ТАКОГО блока возвращает точки с каким-то странным смещением. Причём перенос блока в другое место никак не влияет на возвращаемые координаты. Они всегда остаются одинаковыми:(

Re: Точка вставки атрибута блока, вложенного в др-й блок?

> [Re:] Kosarev
Вообще то я ориентировался на вашу фразу

хотя
(cdr (assoc 10 (entget (car (nentsel)))))
возвращает то, что нужно.

А то что обрабатываются вложенные блоки - так это точно. Какой же результат все же нужно получить? Если можно поподробней...

Re: Точка вставки атрибута блока, вложенного в др-й блок?

В моей фразе, на которую Вы ориентировались, ключевая функция (nentsel) а не (entsel), и она при указании на атрибут в блоке возвращает "правильные" координаты его, атрибута, точки вставки, независимо от уровня вложенности этого блока в другие блоки.
Сам понимаю, что объяснение проблемы, мягко говоря, туповатое, поэтому попробую как-то отвлечённо:
1) создадим некий блок с атрибутом,
2) скопируем его несколько раз (для наглядности),
3) объединим все копии в новый суперблок,
4) скопируем этот суперблок ещё несколько раз,
5) выберем все образовавшиеся блоки через
   (setq ss (ssget "_X" '((0 . "INSERT"))))
6) для всех атрибутов получим указатели и в точках "InsertionPoint"
   атрибутов нарисуем маленькие кружочки
7) если с помощъю Вашей функции рисовать кружочки для п.1 или п.2, то всё
   нормально если для п.4 - нет.
"Нарисовать кружочки" - это не конкретная цель, которую я преследую, просто дальше для меня будет всё ясно.

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Kosarev пишет:

ключевая функция (nentsel) а не (entsel), и она при указании на атрибут в блоке возвращает "правильные" координаты его, атрибута, точки вставки, независимо от уровня вложенности этого блока в другие блоки

не может быть. как у вас версия автокада?

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Да, вот это я "залип"...
Vovka прав на все 100, (nentsel) действительно бесполезен. Чем там я смотрел, когда тему создавал - уж и не знаю, хотя даже очки пока не ношу. Прошу прощения у участников форума за то, что ввёл в заблуждение. Честное слово, даже уши покраснели.
Но вопрос не снимаю, раз уж влез (хоть как и медведь в посудную лавку).
Может кто-то и поможет...

Re: Точка вставки атрибута блока, вложенного в др-й блок?

> [Re:] Kosarev
Наконец-то нашлось время вернуться к этому вопросу. Попробуйте этот лисп:

(defun test1 (/ ins-point-atr lst-point-atr VLA-OBJECT-BLOCK NAME-BLOCK)
  (defun ins-point-atr (Obj temp)
    (vlax-for ent
          (vla-item
            (vla-get-blocks
              (vla-get-activedocument (vlax-get-acad-object))
            ) ;_ end of vla-get-blocks
            (vla-get-name Obj)
          ) ;_ end of vla-item
      (cond
    ((= (strcase (vla-get-objectname ent) t)
        "acdbattributedefinition"
     ) ;_ end of =
     (setq lst-point-atr
        (cons
          (append
            (list
              (vlax-safearray->list
            (vlax-variant-value
              (vla-get-InsertionPoint ent)
            ) ;_ end of vlax-variant-value
              ) ;_ end of vlax-safearray->list
            ) ;_ end of list
            temp
          ) ;_ end of append
          lst-point-atr
        ) ;_ end of cons
     ) ;_ end of setq
    )
    ((= (strcase (vla-get-objectname ent) t)
        "acdbblockreference"
     ) ;_ end of =
     (ins-point-atr
       ent
       (append
         (list
           (vlax-safearray->list
         (vlax-variant-value
           (vla-get-InsertionPoint ent)
         ) ;_ end of vlax-variant-value
           ) ;_ end of vlax-safearray->list
         ) ;_ end of list
         temp
       ) ;_ end of append
     ) ;_ end of ins-point-atr
    )
      ) ;_ end of cond
    ) ;_ end of vlax-for
  ) ;_ end of defun
  (if (and
    (setq NAME-BLOCK (car (entsel "\nУкажите блок: \n")))
    (setq VLA-OBJECT-BLOCK (vlax-ename->vla-object NAME-BLOCK))
    (= (strcase (vla-get-objectname VLA-OBJECT-BLOCK) t)
       "acdbblockreference"
    ) ;_ end of =
      ) ;_ end of and
    (progn
      (ins-point-atr
    VLA-OBJECT-BLOCK
    (list (vlax-safearray->list
        (vlax-variant-value
          (vla-get-InsertionPoint VLA-OBJECT-BLOCK)
        ) ;_ end of vlax-variant-value
          ) ;_ end of vlax-safearray->list
    ) ;_ end of list
      ) ;_ end of ins-point-atr
      (mapcar '(lambda (x)
         (apply 'mapcar (cons '+ x))
           ) ;_ end of lambda
          lst-point-atr
      ) ;_ end of mapcar
    ) ;_ end of progn
  ) ;_ end of if
) ;_ end of defun

Re: Точка вставки атрибута блока, вложенного в др-й блок?

моя версия
непонятна ситуация с 3d
не работает с блоками nonuniform scale

(vl-load-com)
(defun vk_Trans    (Point Offset Rotation Scale)
  (mapcar '+
      (polar '(0 0 0)
         (+ (angle '(0 0 0) Point) Rotation)
         (* (distance '(0 0 0) Point) Scale)
      )
      Offset
  )
)
(defun test (CollectionObj Offset Rotation Scale / ObjName OutList)
  (vlax-for Obj    CollectionObj
    (setq ObjName (vla-get-ObjectName Obj))
    (if    (= ObjName "AcDbBlockReference")
      (progn (if (= (vla-get-HasAttributes Obj) :vlax-true)
           (foreach    Att
            (vlax-safearray->list (vlax-variant-value (vla-GetAttributes Obj)))
         (setq
           OutList (cons (cons (vla-get-TextString Att)
                       (vlax-safearray->list
                     (vlax-variant-value (vla-get-InsertionPoint Att))
                       )
                 )
                 OutList
               )
         )
           )
         )
         (setq
           OutList (append
             OutList
             (test
               (vla-Item
                 (vla-get-Blocks (vla-get-ActiveDocument (vlax-get-acad-object)))
                 (vla-get-Name Obj)
               )
               (vlax-safearray->list
                 (vlax-variant-value (vla-get-InsertionPoint Obj))
               )
               (vla-get-Rotation Obj)
               (vla-get-XScaleFactor Obj)
             )
               )
         )
      )
    )
  )
  (mapcar (function
        (lambda (a) (cons (car a) (vk_Trans (cdr a) Offset Rotation Scale)))
      )
      OutList
  )
)
;;;проверка
;|
(mapcar    (function
      (lambda (a)
        (entmake
          (list (cons 0 "POINT") (cons 10 (cdr a)))
        )
      )
    )
    (test (vla-get-ModelSpace (vla-get-ActiveDocument (vlax-get-acad-object)))
          '(0 0 0)
          0.0
          1.0
    )
)
|;

Re: Точка вставки атрибута блока, вложенного в др-й блок?

Огромное спасибо СВ и Vovk-e за участие.
Оба варианта меня полностью удовлетворяют и даже более того (есть чему поучиться).
Проблема решена!