Интерактивное перемещение текста атрибута блока

Автор Тема: Интерактивное перемещение текста атрибута блока  (Прочитано 21895 раз)

0 Пользователей и 4 Гостей просматривают эту тему.

Оффлайн MacondoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Всем привет!
Интересует, как можно программно интерактивно ("на курсоре") перемещать текст атрибута блока. Если делать это вручную, вызывается команда **stretch**, причём если запустить саму команду _stretch, то она будет перемещать и атрибут, и сам блок. _Move аналогичен. Есть ли какие-то работающие варианты подобной реализации?

Отмечено как Решение Macondo 12-10-2015, 21:32:07

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть несколько вариантов:
1) Стандартная команда _-ATTEDIT
2) С использование функции (grread) считывать координаты курсора и перемещать атрибут.
3) С использованием моей утилиты dyndraw: http://www.maestrogroup.com.ua/support/dyndraw.zip
(там есть примеры не связанные с атрибутами, но идея должна быть ясна)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн MacondoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
1) Стандартная команда _-ATTEDIT
Спасибо! Неплохо справляется с задачей в виде
(vl-cmdf "_-attedit" "" "" "" "" atr "_P" pause "")Правда, без "резиновой нити" (не так важно). Кроме того, на месте первоначальной точки возникает огромное перекрестие. Может, за его отображение отвечает какая-то системная переменная?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Кроме того, на месте первоначальной точки возникает огромное перекрестие. Может, за его отображение отвечает какая-то системная переменная?
Насколько я помню возможности управлять этим перекрестьем нет.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Есть еще неотмеченный мной вариант. Сделать дубликат атрибута в виде текста (или мультитекста - зависит от многострочности атрибута) и таскать его. Например командой _MOVE или функцией (acet-ss-drag-move). После завершения "таскания" дубликат стереть, а атрибут перетащить (поменять точку вставку и точку выравнивания).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
+ к сказанному - при установленных Express Tools становится доступна лисп функция acet-ss-drag-move ...
Код - Auto/Visual Lisp [Выбрать]
  1. (acet-ss-drag-move (ssget) (getpoint "\nБазовая ") "\nДвигай... " nil 2)
p.s. ops опоздал
« Последнее редактирование: 12-10-2015, 21:49:24 от Александр Ривилис »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
+ к сказанному - при установленных Express Tools становится доступна лисп функция acet-ss-drag-move ...
А тут ты попался! :) Будет двигаться весь блок. Атрибут таким образом ты не подвинешь.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Не - не попался - я для примера как подвинуть "вися" на курсоре - понятно дело (ну мне по крайней мере), что к блоку так не пойдет - нужна предварительная работа.
Кстати у меня сейчас expressoв нету - а если в набор добавить только (entnext...) атрибута - подвинет?

Оффлайн MacondoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Сделать дубликат атрибута в виде текста (или мультитекста - зависит от многострочности атрибута) и таскать его.
Кстати, тоже хороший вариант! Я не уточнил в начале: если данное действие требуется совершать во время вставки блока с атрибутом, то, может, есть встроенные решения? Не нашёл свойства атрибута вроде "указание точки вставки" при вставке блока.
при установленных Express Tools становится доступна лисп функция
Не подойдёт, поскольку Express Tools может быть и не установлен, нужны простые решения!

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Я не уточнил в начале: если данное действие требуется совершать во время вставки блока с атрибутом, то, может, есть встроенные решения?
Это как? Если вставлять командой _INSERT, то положение атрибутов во время вставки изменить нельзя. Управлять запросом вставки атрибутов можно при помощи системных переменных ATTREQ и ATTDIA.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн MacondoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
Вариант с текстом показался самым естественным для отображения (если бы не перекрестье, то подошёл бы и первый).
Вот такой код получился (при наличии значения переменной model_space):
Код - Auto/Visual Lisp [Выбрать]
  1. (vl-catch-all-apply 'vl-cmdf (list "_-insert" block_name "_PX" block_dimension "_PY" block_dimension pause block_dimension block_dimension pause)); вставка блока
  2.         (foreach item (vlax-safearray->list (vlax-variant-value (vla-GetAttributes (vlax-ename->vla-object (entlast)))))
  3.           (if (AND (= (vla-get-tagstring item) "POZ") (eq (vla-get-textstring item) "")); ищем пустой атрибут с нужным тегом
  4.             (progn
  5.               (vla-put-textstring item position); добавление текста атрибута из переменной position
  6.               (vla-AddText model_space (vla-get-textstring item) (vla-get-InsertionPoint item) (vla-get-Height item)); создание временного текста
  7.               (setq temp_text (entlast))
  8.               (vl-catch-all-apply 'vl-cmdf (list "_move" (entlast) "" (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint item))) pause))
  9.               (vla-put-InsertionPoint item (vlax-3d-point (getvar "LASTPOINT"))); изменение положения текста атрибута
  10.               (entdel temp_text); удаление временного текста
  11.             )
  12.           )
  13.         )
  14.  
« Последнее редактирование: 14-10-2015, 13:53:14 от Macondo »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Обрати внимание на правила форматирования кодов у нас на форуме (у меня в подписи).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Алексей Кулик

  • Administrator
  • *****
  • Сообщений: 1115
  • Карма: 173
Н-да, пока я был на AURU2015, тут, оказывается, такие интересные штуки творились :)
Несколько вопросов по коду:
1. А если пользователь в ответ на запрос нажмет правую кнопку или Esc?
2. Почему создается текст, а удаляется примитив, который был перед ним? Там же может быть все что угодно...
3. Не учитывается вариант многострочного атрибута
4. Не учитывается вариант установленного выравнивания атрибута
5. Не учитываются варианты заблокированных / замороженных слоев

Я бы код писал по другим принципам:
- отдельная универсальная функция вставки блока. Используется при вставке block_name
- получение указателя на нужный атрибут
- создание анонимного блока, внутри которого только однострочный / многострочный текст
- используя ту самую универсальную функцию, вставляем анонимный блок по запросу пользователя. Если блок был вставлен, то получаем у него точку вставки
- полученному атрибуту устанавливаем точку вставки и / или выравнивания атрибута
- удаление вставки анонимного блока.
Все, что сказано - личное мнение.

Правила форума существуют не просто так!

Приводя в сообщении код, не забывайте про его форматирование!

Оффлайн MacondoАвтор темы

  • ADN OPEN
  • **
  • Сообщений: 57
  • Карма: 1
1. А если пользователь в ответ на запрос нажмет правую кнопку или Esc?
2. Почему создается текст, а удаляется примитив, который был перед ним? Там же может быть все что угодно...
3. Не учитывается вариант многострочного атрибута
4. Не учитывается вариант установленного выравнивания атрибута
5. Не учитываются варианты заблокированных / замороженных слоев
1. Если пользователь прерывает команду, атрибут останется на месте по умолчанию. Этот цикл обрамлён в другой цикл:
Код - Auto/Visual Lisp [Выбрать]
  1. (while (vl-catch-all-apply 'vl-cmdf (list "_-insert" block_name "_PX" block_dimension "_PY" block_dimension pause block_dimension block_dimension pause))
  2.   (foreach ... )
  3. )
2. Создаётся текст, затем он же заносится в переменную temp_text, а потом он удаляется через (entdel temp_text).
3,4. Атрибут будет задаваться в окне и не сможет быть многострочным или с другим выравниванием.
5. Верное замечание, нужно будет написать функцию, которая бы размораживала и разблокировала слой:
Код - Auto/Visual Lisp [Выбрать]
  1. (defun unlock-unfreeze-layers  (layer_name)
  2.   (if (= (vla-get-Freeze (vla-item (vla-get-layers actdoc) layer_name)) :vlax-true)
  3.     (vla-put-Freeze (vla-item (vla-get-layers actdoc) layer_name) :vlax-false)
  4.   )
  5.   (if (= (vla-get-Lock (vla-item (vla-get-layers actdoc) layer_name)) :vlax-true)
  6.     (vla-put-Lock (vla-item (vla-get-layers actdoc) layer_name) :vlax-false)
  7.   )
  8. )
- отдельная универсальная функция вставки блока. Используется при вставке block_name
Непосредственно для вставки блока используется одна команда (insert), тем более если она в условии цикла, а сразу после while идёт добавление слоя-цвета, то функцию применять (мне кажется) не очень удобно.
Кстати, как считаешь, можно ли в функцию-обработчик завершения программы, где идёт восстановление системных переменных, дописать PURGE all? Если идёт вставка блоков, когда каждый блок находится в отдельном файле (command "_insert" (strcat block_name ".dwg") nil), то потом во "Вставке" остаётся мусор с названиями файлов.

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
2. Создаётся текст, затем он же заносится в переменную temp_text, а потом он удаляется через (entdel temp_text).
В том виде, в котором ты выложил код, происходит совсем другое:
1) Ты сначала получаешь последний примитив, а затем создаешь новый текст:
Код - Auto/Visual Lisp [Выбрать]
  1. (setq temp_text (entlast))
  2. (vla-AddText model_space (vla-get-textstring item) (vla-get-InsertionPoint item) (vla-get-Height item)); создание временного текста
2) После выполнения работы ты удаляешь  temp_text, что не есть твой временный текст

 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение