| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > AutoCAD > Изменить точку вставки блока

Изменить точку вставки блока

Ответ
Поиск в этой теме
Непрочитано 04.10.2007, 15:10 #1
Изменить точку вставки блока
Apelsinov
 
Проектировщик ВК. LISP-любитель.
 
Москва
Регистрация: 15.12.2003
Сообщений: 1,166

Есть блок, есть множество вставок этого блока в чертеже.
Необходимо изменить расположение точки вставки блока, но так, чтобы расположение примитивов вставок блока относительно чертежа осталось прежним, то есть - вставки не "уехали" вслед за измененной точкой вставки.

Есть ли способ сделать это иначе, кроме как исправлением точки вставки блока (например - расположение параметра точки вставки в блокэдиторе), и последующим перемещением вставок соответственно смещению точки вставки?
__________________
apel.fas
Просмотров: 33342
 
Непрочитано 04.10.2007, 15:45
#2
Profan


 
Регистрация: 25.12.2005
Москва
Сообщений: 13,663


Вот тут
http://www.autocad.ru/cgi-bin/f1/board.cgi?t=38163rN
я глупо бился над этой проблемой.
Пришел к выводу, что без программирования не обойтись.
Profan вне форума  
 
Непрочитано 04.10.2007, 15:50
#3
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,843


А какая цель преследуется? Если надо существующий блок "вставлять за другое место" - (без приколов пожалуста) - то можно просто добавить параметр выравнивания, а если для чего-то другого :?: то напиши для чего.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 04.10.2007, 15:58
#4
TheBuTeK

преподавание
 
Регистрация: 28.09.2005
Москваград
Сообщений: 131
<phrase 1=


А в редакторе блоков поменять местоположение параметра "базовая точка" не то, что требуется?
Упс, виноват, не дочитал...
__________________
Добрым словом и пистолетом можно добиться гораздо большего, чем одним добрым словом.
TheBuTeK вне форума  
 
Автор темы   Непрочитано 04.10.2007, 16:51
#5
Apelsinov

Проектировщик ВК. LISP-любитель.
 
Регистрация: 15.12.2003
Москва
Сообщений: 1,166
<phrase 1=


Цитата:
Сообщение от Дима_
А какая цель преследуется? Если надо существующий блок "вставлять за другое место" - (без приколов пожалуста) - то можно просто добавить параметр выравнивания, а если для чего-то другого :?: то напиши для чего.
В основном нужно для исправления криворукосделаных чертежей, где точки вставки блоков находятся чертигде, но только не в пределах габаритов самих этих блоков. С такими чертежами тяжело работать.
__________________
apel.fas
Apelsinov вне форума  
 
Непрочитано 04.10.2007, 20:41
#6
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,843


С такими образцами надо бороться решительно и навсегда - переделывать их нафиг целиком - ибо если их за основу брать наверняка еще куча неизвестно-чего вылезет, ищи потом какую он там переменную настроил - лучше день помучаться, а потом за 5 минут долететь.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 04.10.2007, 22:18
#7
T-Yoke

Артиллерист - вертолётчик. Дипломированный инженер-механик. Technologist
 
Регистрация: 29.11.2004
Где-то около Москвы
Сообщений: 16,125
Отправить сообщение для T-Yoke с помощью Skype™


Цитата:
Сообщение от Apelsinov
Цитата:
Сообщение от Дима_
А какая цель преследуется?...
...В основном нужно для исправления криворукосделаных чертежей, где точки вставки блоков находятся чертигде, но только не в пределах габаритов самих этих блоков. С такими чертежами тяжело работать.
Вот всегда так! Вместо того чтобы, пару раз лишить премии или устроить "темную" криворукому автору. Решаем как его творчество улучшать. Мой вам совет, "Не надо бороться со следствием, боритесь с причиной"
__________________
«Артиллерия не токмо грохот, но и наука!» Пётр I
T-Yoke вне форума  
 
Непрочитано 04.10.2007, 23:32
#8
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 38,690


Если бы была гарантия того, что все блоки вставлены в мировой системе координат, что текущая система координат мировая, не изменена base, insbase, что блоки имеют масштабы по осям, равные 1, еще можно было бы попытаться что-то изобразить. А так... Голову сломаешь.
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 05.10.2007, 10:39
#9
cheeppy

Инженер
 
Регистрация: 22.01.2006
Краснодар
Сообщений: 16


Я сумел только тупо сделать это
Цитата:
изменить расположение точки вставки блока, но так, чтобы расположение примитивов вставок блока относительно чертежа осталось прежним, то есть - вставки не "уехали" вслед за измененной точкой вставки
программно, переопределяя блок с новой точкой вставки и перемещая блоки чертежа соответственно, с учетом угла поворота и масштаба.
Но результат иногда(правда редко), в зависимости от единиц вставки блока, сиситемы координат вставки и т.п., не радует. Ну и динамические блоки, мультивставки - не воспринимает вообще.
Если еще нужно, могу выложить лиспик "как есть"(типа работает и ладно)
__________________
То, чего нельзя сделать в Acade, не существует.
cheeppy вне форума  
 
Непрочитано 05.10.2007, 13:27
#10
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


Когда-то подобное делал для 3D моделей - пробовал через матрицы трансформации, через синусы-косинусы - чуть не свихнулся! и всё равно не всегда правильно получалось с углами поворота!!!
А потом плюнул на всё и сделал "по тупому" - работает идеално в моих условиях. Код примерно такой:

Код:
[Выделить все]
;|
xyz - координата новой базы в системе координат блока, можно список (x y z) или variant
name - имя этого блока
пример вызова:    (ad-move-basa-block '(0 0 -1596) "beton-1")
|;

(defun ad-move-basa-block (xyz name / adoc blocks temp_name temp_block item xyz000 block bl)
  (vl-load-com)
  (if (= (type xyz) 'list)
    (setq xyz (vlax-3d-point xyz))
    ) ;_ end if
  (setq adoc       (vla-get-activedocument (vlax-get-acad-object))
        blocks     (vla-get-blocks adoc)
        xyz000     (vlax-3d-point 0.0 0.0 0.0)
        temp_name  (strcat "ad-temp_" (itoa (fix (getvar "date"))))
        block      (vla-item blocks name)
        temp_block (vla-add blocks xyz000 temp_name)
        insert     (vla-insertblock temp_block xyz000 Name 1.0 1.0 1.0 0.0)
        ) ;_ end setq
  (vla-put-Explodable block :vlax-true)
  (vla-put-Explodable temp_block :vlax-true)
  (vla-move insert xyz xyz000)
  (vla-explode insert)
  (vla-delete insert)
  (vlax-for item block (vla-delete item))
  (vla-insertblock block xyz temp_name 1.0 1.0 1.0 0.0)
  (vlax-for bl blocks
    (vlax-for item bl
      (and (= (vla-get-objectname item) "AcDbBlockReference")
           (= (vla-get-name item) name)
           ;|####  Можно через  (vl-cmdf "_.explode"), см. описание в конце  ###|;
           (not (vl-catch-all-error-p
                  (vl-catch-all-apply 'vla-explode (list item))
                  ) ;_ end vl-catch-all-error-p
                ) ;_ end not
           (vla-delete item) ;|####  .....  ###|;
           ) ;_ end and
      ) ;_ end vlax-for
    ) ;_ end vlax-for
  (vla-delete block)
  (vla-put-name temp_block name)
  (princ)
  ) ;_ end defun
Идея простая, но надёжная, все слои должны быть разблокированы. Ограничения только на масштабы вставок - должны быть равны по модулю на всех осях (это ограничение для vla-explode). Если и это важно. то можно использовать (vl-cmdf "_.explode"), но она работает только в активном пространстве, позтому для вложеных блоков придётся повозиться немного (я не хочу).
Евгений А. вне форума  
 
Непрочитано 19.10.2007, 22:54
#11
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Условия: Куча копий блока в разных местах и с разными углами поворота. Точки вставки светятся как звезды на небе, но не на самих блоках.
Надо: Чтобы точки вставки были на графике, но чтобы графика осталась на месте.

Решения: Их два. Первое попроще, но ручное, второе посложнее и для макроса.
Первое решение:
1. Переименовываем блок. Делаем ему имя "Технический" (к примеру). Все блоки теперь - "Технический". И обязательно purge - удаляем из таблицы блок с первоначальным именем. (хотя там их не должно быть)
2. Копируем в буфер любую из копий и открываем второй чистый файл (теперь открыто два файла первый - с моделью и второй чистый)
3. Вставляем из буфера в чистый файл блок.
4. Возвращаем ему его первоначальное имя.
5. Открываем его редактором и наводим порядок с положением точки вставки
6. Выходим из редактора и копируем отремонтированный блок в буфер
7. Возвращаемся в файл с моделью.
8. Открываем редактором блок "Технический"
9. Вставляем из буфера на место графики блок с первоначальным именем и правильной точкой вставки. Я с начала линию подвожу к месту куда точка вставки должна стать, затем убиваю графику и вставляю из буфера блок. Он сволочь, вставляется не туда, куда я показываю, а в 0,0 и приходится его перетаскивать к линии. После чего сношу линию. Если рядом с графикой атрибуты есть - снести.
10. Выходим из редактора, включаем ручки у всех копий блока "Технический" (ну макросом естественно) и взрываем.
После взрыва блока, его начинка остается на своем месте а она является блоком с первоначальным именем.
Если сравнить порядок расположения вхождений блока "Технический" и порядок вновь появившегося блока, то они по идее совпадут. не проверял. А это значит, что перед всеми этими манипуляциями можно сохранить значения динамических свойств, а потом эти значения прописать новичкам.

Второй вариант:
1. Создаем блок "Точка" с точкой внутри на месте точки вставки. Короче все в одной точке.
2. Заходим в редактор блока и ставим эту точку на графику в то место, куда потом станет точка вставки.
3. Выходим из редактора и программно делаем следующее:
3.1. Создаем набор из всех вхождений этого блока
3.2. К каждому элементу набора применяем следующую последовательность действий
3.2.1. Записать метку блока (любые ориентиры на вхождение)
3.2.2. Взорвать блок
3.2.3. Включить через моделспейс ручку у блока "Точка"
3.2.4. Записать ее координаты в моделе и привязать к метке блока
3.2.5. Вернуть Undo-й блок в целостное состояние
4. Открываем редактором блока наш блок и ставим графику на место. В модели все блоки разлетаются кто куда.
5. Программно переносим каждое вхождение блока по координатам привязанным к его метке.
Все. Пригодно даже для динамических блоков, даже если при перемещении графики внутри блока заново переопределяешь привяку к элементам.
Supermax вне форума  
 
Непрочитано 20.10.2007, 15:53
#12
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


-> Supermax
Собственно код выше примерно так и работает (всё даже немного проще)
Евгений А. вне форума  
 
Непрочитано 20.10.2007, 16:48
#13
Supermax

Руководитель фирмы
 
Регистрация: 28.03.2007
Москва
Сообщений: 1,831
Отправить сообщение для Supermax с помощью Skype™


Отлично!
Как побочный эффект - восстановилась видимость выключенных деталей. Надо набирать лисп выражение - грусть. А так - супер.
Надо запускать редактор через commands просить указать точку и сваливать. Загруженный и запущенный лисп продолжает работать пока не закончится. Смело можно ползать по файлам и пространствам.

Да, к сожалению, динамические блоки разваливаются.

У динамических блоков перенос графики может разрушить динамические свойства. Но я двигал по Z и все остается работоспособным. А X и Y можно просто точку вставки с 0,0,0 перенести.

Открываем прямо из под лиспа редактор блоков, просим указать новую точку вставки, запоминаем X, Y, Z двигаем графику только по Z, а потом
(Command "_BParameter" "B" "872.2095,997.3218") и вываливаемся.

Последний раз редактировалось Supermax, 20.10.2007 в 17:15.
Supermax вне форума  
 
Непрочитано 20.10.2007, 19:30
#14
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


Попробуй мой готовый вариант (он работает немного по другому), правда попробовал динамические блоки - результат странный: вставки и грипса (якобы базовая точка!) остаются на прежнем месте, а у новых блоков грипса базы уже там где надо.

Программа лежит здесь http://ad-cad.narod.ru/Help-Paper.htm команда "AD" (недокументированная) в списке выбираешь "изменить базовые точки у блоков" - будет цикл по всем блокам модели, надо будет указывать новую базу или "esc", чтобы пропустить.
Евгений А. вне форума  
 
Непрочитано 20.10.2007, 21:32
#15
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 38,690


Исходников, я так понимаю, не будет?
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 20.10.2007, 23:49
#16
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Исходников, я так понимаю, не будет?
Да можно, если устраивает результат
Код:
[Выделить все]
(defun ad-move-basa-block (xyz name / adoc blocks temp_name temp_block item xyz000 block
                           bl vlo)
  (vl-load-com)
  (if (= (type xyz) 'list)
    (setq xyz (vlax-3d-point xyz))
    ) ;_ end if
  (setq adoc       (vla-get-activedocument (vlax-get-acad-object))
        blocks     (vla-get-blocks adoc)
        xyz000     (vlax-3d-point 0.0 0.0 0.0)
        temp_name  (strcat "ad-temp_" (itoa (fix (getvar "date"))))
        block      (vla-item blocks name)
        temp_block (vla-add blocks xyz000 temp_name)
        insert     (vla-insertblock temp_block xyz Name 1.0 1.0 1.0 0.0)
        ) ;_ end setq
  (vlax-for vlo block (vla-move vlo xyz xyz000)) 
  (vla-put-Explodable temp_block :vlax-true)
  (vlax-for bl blocks
    (if (not (equal temp_block bl))
      (vlax-for item bl
        (and (= (vla-get-objectname item) "AcDbBlockReference")
             (= (vla-get-name item) name)
             (null (vla-put-name item temp_name))
             (not (vl-catch-all-error-p
                    (vl-catch-all-apply 'vla-explode (list item))
                    ) ;_ end vl-catch-all-error-p
                  ) ;_ end not
             (vla-delete item) ;|####  .....  ###|;
             ) ;_ end and
        ) ;_ end vlax-for
      ) ;_ end if
    ) ;_ end vlax-for
  (vl-catch-all-apply 'vla-delete (list temp_block))
  ) ;_ end defun
Евгений А. вне форума  
 
Непрочитано 21.10.2007, 00:04
#17
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 38,690


вариант, на котором код не срабатывает ожидаемым образом - во вложении (форматы файлов 2007 и 2004). Ошибка при выполнении последней строки; перемещение примитивов блока выполняется неверно; вхождения блока теряют собственные настройки. Код слеганца переделал:
Код:
[Выделить все]
(defun ad-move-basa-block (xyz      name     /        adoc     blocks
                           temp_name         temp_block        item
                           xyz000   block    bl       vlo
                           )

                          ;|
*    Пример вызова:
(ad-move-basa-block (getpoint "\nНовая базовая точка ") (cdr (assoc 2 (entget (car (entsel))))))
|;

  (defun *error* (msg)
    (vla-endundomark adoc)
    (princ msg)
    (princ)
    ) ;_ end of defun

  (vl-load-com)
  (if (= (type xyz) 'list)
    (setq xyz (vlax-3d-point xyz))
    ) ;_ end if
  (vla-startundomark
    (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
    ) ;_ end of vla-startundomark
  (setq blocks     (vla-get-blocks adoc)
        xyz000     (vlax-3d-point 0.0 0.0 0.0)
        temp_name  (strcat "ad-temp_" (itoa (fix (getvar "date"))))
        block      (vla-item blocks name)
        temp_block (vla-add blocks xyz000 temp_name)
        insert     (vla-insertblock temp_block xyz name 1.0 1.0 1.0 0.0)
        ) ;_ end setq
  (vlax-for vlo block (vla-move vlo xyz xyz000))
  (vla-put-explodable temp_block :vlax-true)
  (vlax-for bl blocks
    (if (not (equal temp_block bl))
      (vlax-for item bl
        (and (= (vla-get-objectname item) "AcDbBlockReference")
             (= (vla-get-name item) name)
             (null (vla-put-name item temp_name))
             (not (vl-catch-all-error-p
                    (vl-catch-all-apply 'vla-explode (list item))
                    ) ;_ end vl-catch-all-error-p
                  ) ;_ end not
             (vla-delete item) ;|####  .....  ###|;
             ) ;_ end and
        ) ;_ end vlax-for
      ) ;_ end if
    ) ;_ end vlax-for
  (vl-catch-all-apply 'vla-delete (list temp_block))
  (vla-regen adoc acallviewports)
  (vla-endundomark adoc)
  (princ)
  ) ;_ end defun
И это на простых блоках, без динамики.
Вложения
Тип файла: dwg
DWG 2007
block_move.dwg (44.2 Кб, 5892 просмотров)
Тип файла: dwg
DWG 2004
block_move2k4.dwg (31.5 Кб, 5868 просмотров)
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.10.2007, 01:47
#18
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


"вхождения блока теряют собственные настройки" - с этим согласен (у себя исправил + добавил проверку слоёв), а в остальном - ты не прав по условию (читай пост №10 - там я говорил про масштабы и про vla-explode, и там же читай вторую строку листинга про xyz - это далеко не (getpoint "\nНовая базовая точка ")
Я делал это под себя для работы с твёрдотельной моделью, когда все масштабы по осям равны 1 (!!!), зато есть повороты,координаты вставок и главное - глубокая вложенность блоков.
Остальные варианты мне не очень интересны, хотя и их сделать не трудно...

Последний раз редактировалось Евгений А., 21.10.2007 в 02:09.
Евгений А. вне форума  
 
Непрочитано 21.10.2007, 02:17
#19
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 38,690


Я проводил тестирование, указав левый верхний блок в качестве основного. А там и масштабы, и угол поворота - все "по правилам".
Читаю то, что сказано в
Код:
[Выделить все]
  (if (= (type xyz) 'list)
    (setq xyz (vlax-3d-point xyz))
    ) ;_ end if
Исходя из этого, я могу указать точку как мне угодно, лишь бы не вызвало падения кода. А если так, то кто мешает точку указывать как (getpoint)? Все равно ж возвращается список из 3 вещественных чисел, которые потом благополучно преобразовываются в variant.
В остальном я подошел с точки зрения юзера, которому надо "ткнуть и указать". Потому что выполнить "передвижку" примитивов внутри блока можно и без подобных операций "разбить-собрать": vla-move и вперед. Примерно так (сейчас acad на переустановке, пишу "по памяти" и для версий от 2006 и выше:
Код:
[Выделить все]
(defun _move-in-block(name pt / def)
;|
*    name - имя блока. Для дин.блоков указывать EffectiveName
*    pt     - то же, что и xyz
|;
(vlax-for subent (setq def (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) name))
(vla-move subent (vla-get-origin def) (cond ((=(type pt) 'list) (vlax-3d-point pt)) (t pt)))
)
)
Основная трудность именно в удовлетворении достаточно предсказуемого (и обоснованного) желания "ткнуть" и получить результат. И вдобавок сделать такой код, чтобы он работал всегда.
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.10.2007, 02:50
#20
Евгений А.

Армспорт
 
Регистрация: 18.07.2006
Ейск
Сообщений: 355


Вообще-то я показал только функцию , а не готовую программу, только чтобы подкинуть идею. Адрес на программу я указывал...
Цитирую из №10:
xyz - координата новой базы в системе координат блока... , а не в модели - это важно!
Про ошибку: База смещается в описании блока, в этот момент ВСЕ вхождения на этот блок смещаются тоже, в зависимости от нормали, угла поворота и масштабов (будь они не ладны), и чтобы всё поставить на место, надо что-то делать (сместить куда надо очку вставки) со ВСЕМИ вхождениями на этот блок (а не только то, которое выбрано через (entsel)), поэтому программа всё равно пытается расчленить вхождения с разными масштабами - вот тут и ошибка, а потом ест-но ошибка при удалении временного блока.
Евгений А. вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > AutoCAD > Изменить точку вставки блока

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск