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

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Копирование объекта из внешней ссылки в текущий чертеж

LISP. Копирование объекта из внешней ссылки в текущий чертеж

Ответ
Поиск в этой теме
Непрочитано 05.09.2016, 22:05 #1
LISP. Копирование объекта из внешней ссылки в текущий чертеж
skkkk
 
Регистрация: 20.03.2008
Сообщений: 2,653

Возникла такая задача, и я, конечно, первым делом обратился к поиску. Только на англоязычном ресурсе нашел код, который копирует объект из внешней ссылки в текущий чертеж:
Код:
[Выделить все]
 (defun c:copyn (/ blk blks e i lst obj tm ss)
  (setq	blks (vla-get-blocks
	       (vla-get-activedocument (vlax-get-acad-object))
	     )
	ss   (ssadd)
  )
  (while (and (setq e (nentselp "Выберите вложенный объект для копирования из внешней ссылки: "))
	      (setq tm (caddr e))
	      (setq blk (car (cadddr e)))
	      (setq blk (vlax-ename->vla-object blk))
	      (setq i (vla-item blks (vla-get-name blk)))
	)
    (if	(= (vla-get-isxref i) :vlax-false)
      (vlax-for	be i
	(if (and (setq e (entget (vlax-vla-object->ename be)))
		(not (cdr (assoc 102 e)))
		(setq obj (entmakex e))
		(setq obj (vlax-ename->vla-object obj))
	    )
	  (progn
	    (vla-transformby obj (vlax-tmatrix tm))
	    (setq lst (cons (list obj (vla-get-color obj)) lst))
	    (vla-put-color obj 1)
	    (vla-update obj)
	  )
	  (princ (strcat "\nComplex entity not created [ "
			(cdr (assoc 0 e))
			" ]"
		)
	  )
	)
      )
      (progn
	(setq obj (vlax-ename->vla-object (entmakex (entget (car e)))))
	(vla-transformby obj (vlax-tmatrix tm))
	(setq lst (cons (list obj (vla-get-color obj)) lst))
	(vla-put-color obj 1)
	(vla-update obj)
      )
    )
  )
  (if lst
    (progn (foreach o lst
	     (vla-put-color (car o) (cadr o))
	     (setq ss (ssadd (vlax-vla-object->ename (car o)) ss))
	     (command "_.draworder"
		      (vlax-vla-object->ename (car o))
		      ""
		      "_front"
	     )
	   )
	   (sssetfirst nil ss)
    )
  )
  (princ)
)

Прошу помощи в доведении лиспа до ума.
Во-первых, если на запрос объекта выбрать блок внутри внешней ссылки, то в текущем чертеже будем иметь его в расчлененном виде. Поскольку для меня это пока не критично, я еще с этим не разбирался.
Во-вторых, лисп категорически отказывается копировать линии, тип которых отличен от "Continuous". Путем анализа и экспериментов удалось выявить, что проблема в entmakex, который почему-то возвращает nil для других типов линий. Полагал, что ошибка возникает из-за того, что entget воспринимает знак "|" в типе линии как сочетание "%0%" и entmakex его не "съедает", однако, в случае со слоем ведь все получается. Полагал также, что не хватает в чертеже нужного типа линии - добавил его принудительно (во всех трех вариантах: с "%0%", с "|" и без всего) - не помогло (думаю, это все же придется решить программно после того, как пойму в чем дело).
Буду благодарен за любые наводящие мысли.
Файлы для экспериментов прилагаю.

Добавлено: РЕШЕНИЕ В #4.

Вложения
Тип файла: dwg
DWG 2010
Тестовый чертеж.dwg (83.8 Кб, 14 просмотров)
Тип файла: dwg
DWG 2010
Внешняя ссылка.dwg (78.0 Кб, 13 просмотров)


Последний раз редактировалось skkkk, 16.04.2017 в 03:26. Причина: Добавлена ссылка на решение.
Просмотров: 7407
 
Непрочитано 05.09.2016, 22:40
#2
Кулик Алексей aka kpblc
Moderator

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


Посмотреть не могу - башка уже не варит. Поэтому ответы "насухую".
Проверяй тип линии объекта. Если он не Continuous, то предварительно загрузи тип линии. Ну или меняй список для entmakex.
По вопросу блоков - может быть, их сначала стоит создавать, например, через vla-CopyObjects?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 06.09.2016, 18:08
#3
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Забыли еще про Express Tools. Там есть команда NCOPY (Copies objects nested in an xref or a block)
Описание находится в файле TREXBLK.LSP

Еще вариант отсюда Copy nested object(s) - how to work with XRefs?
Без проверки.
Код:
[Выделить все]
(vl-load-com)
(setq doc   (vla-get-activedocument (vlax-get-acad-object))
      space (if	(eq (getvar 'CVPORT) 1)
	      (vla-get-paperspace doc)
	      (vla-get-modelspace doc)
	    )
)
(if (and
      (setq ent (nentselp "\nSelect nested curve to copy: "))
      (setq obj (vlax-ename->vla-object (car ent)))
      )
  (vla-put-Color
    (setq new
	   (car
	     (vlax-invoke
	       (vla-get-XRefDatabase
		 (vla-Item
		   (vla-get-Blocks doc)
		   (vla-get-Name
		     (vlax-ename->vla-object
		       (car (last ent))
		     )
		   )
		 )
	       )
	       'CopyObjects
	       (list obj)
	       space
	     )
	   )
    )
    3
  )
)
----- добавлено через ~4 мин. -----
*** Добавлено Еще вспомнил про Copy to Drawings
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 23.01.2017, 13:25
#4
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Прошу прощения за длительное молчание, не доходили руки доработать программу.
Цитата:
Сообщение от VVA Посмотреть сообщение
Забыли еще про Express Tools. Там есть команда NCOPY
VVA, спасибо, но я о ней знал. Она также отказывается работать с типами линий. Точнее копирует линию, но тип "Continuous" ей назначает принудительно. Мне было важно получить полную копию линии.
Цитата:
Сообщение от VVA Посмотреть сообщение
Еще вариант отсюда Copy nested object(s) - how to work with XRefs?
С типами линий тоже мимо.
В общем, добавил я в код, приведенный в первом посте, обработку типов линий при помощи функции Steal от Lee Mac (для работы кода файл StealV1-8.lsp должен быть загружен или должен находиться в путях поддержки).
Код:
[Выделить все]
 (defun C:COPYN ( / e obj lst) 
	(while (setq e (nentselp "Выберите вложенный объект для копирования из внешней ссылки: "))
		(setq obj (copyn e))
		; (vla-put-color obj 1)
	)
)
		


(defun copyn (e / adoc blks ss nobj tm blk i linetype entlist filename obj lst) 
	(setq	
		adoc (vla-get-activedocument (vlax-get-acad-object))
		blks (vla-get-blocks adoc)
		ss   (ssadd)
	)
	(setq nobj (car e))
	(setq tm (caddr e))
	(setq blk (car (cadddr e)))
	(setq blk (vlax-ename->vla-object blk))
	(setq i (vla-item blks (vla-get-name blk)))
	(if	(= (vla-get-isxref i) :vlax-false)
		(vlax-for 
			be 
			i
			(if 
				(and 
					(setq e (entget (vlax-vla-object->ename be)))
					(not (cdr (assoc 102 e)))
					(setq obj (entmakex e))
					(setq obj (vlax-ename->vla-object obj))
					; (vla-put-Linetype obj "Continuous")
				)
				(progn
					(vla-transformby obj (vlax-tmatrix tm))
					(setq lst (cons (list obj (vla-get-color obj)) lst))
					; (vla-put-color obj 1)
					(vla-update obj)
				)
				(princ (strcat "\nComplex entity not created [ "
							   (cdr (assoc 0 e))
							   " ]"
						)
				)
			)
		)
		(progn
			(setq linetype (cdr (assoc 6 (setq entlist (entget nobj)))))
			(if linetype
				(progn
					(setq linetype (vl-string-subst "" (strcat (vla-get-effectivename blk) "|") linetype))
					(setq entlist (subst (cons 6 linetype) (assoc 6 entlist) entlist))
				)
				(progn
					(setq linetype (vla-get-Linetype (vla-Item (vla-get-Layers adoc) (vla-get-Layer (vlax-ename->vla-object nobj)))))
					; (setq linetype (vl-string-subst "" (strcat (vla-get-effectivename blk) "|") linetype))
					(setq entlist (append entlist (list (cons 6 linetype))))
				)
			)
			(if (null (tblobjname "LTYPE" linetype))
				(progn
					(load "StealV1-8.lsp")
					(or (setq filename (findfile (setq filename (vla-get-path blk))))
						(setq filename (findfile (substr (vla-get-path blk) (+ 2 (vl-string-position 92 (vla-get-path blk) 1 T)))))
					)
					(Steal filename '(("Linetypes" ("*"))))
				)
			)
			(setq obj (vlax-ename->vla-object (entmakex entlist)))
			(vla-transformby obj (vlax-tmatrix tm))
			(setq lst (cons (list obj (vla-get-color obj)) lst))
			; (vla-put-color obj 1)
			(vla-update obj)
		)
	)
	obj
	; (princ)
)
Правда, не удалось мне скормить этому Steal'у тип линий в виде переменной - он принимает только строку в "явном" виде, поэтому грузятся все типы линий из указываемой внешней ссылки (если еще нет в чертеже).
Замечено, что программа вылетает при попытке скопировать примитивы типа VERTEX. Видимо, есть там с ними какая-то специфика в entmake. Поскольку пока мне они не нужны - не разбирался с ними. Равно, как и с блоками (напомню, что они попадают в текущий файл расчлененными).
skkkk вне форума  
 
Непрочитано 14.04.2017, 14:00
#5
barabaka


 
Регистрация: 02.07.2016
Сообщений: 17


^C^C_ncopy;\;\@;
А чем в этом макросе можно заменить выделенный участок, для выделения нескольких обьектов? Предварительно выбрать не возможно, так как выбирается вся внешняя ссылка
barabaka вне форума  
 
Непрочитано 14.04.2017, 14:43
#6
Кулик Алексей aka kpblc
Moderator

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


А _ncopy поддерживает множественный выбор? Я просто не в курсе...
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 14.04.2017, 14:52
#7
barabaka


 
Регистрация: 02.07.2016
Сообщений: 17


Поддерживает, но только после вызова команды и только щелчком по обекту, не рамкой.
В принципе устраивает, что б выбор был одиночным, но тогда не было запроса о базовой точке. Но макрос *^C^C_ncopy;\;@@; не работает

Последний раз редактировалось barabaka, 14.04.2017 в 15:06.
barabaka вне форума  
 
Непрочитано 14.04.2017, 18:59
#8
Profan


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


Попробуй вот так:
Код:
[Выделить все]
^C^C_ncopy;\@;
Только зачем здесь жучка?
Profan вне форума  
 
Непрочитано 14.04.2017, 20:09
#9
barabaka


 
Регистрация: 02.07.2016
Сообщений: 17


Работаю с генпланами и подкладываю подоснову внешней ссылкой. Часто надо что то с подосновы скопировать в рабочий чертеж. Эта команда хороша всем, но при указании базовой точки и второй можно случайно "уйти" с координат. Поэтому и пробую сделать макрос, что б либо выбрать несколько объектов и вставить их в базовую точку или выбирать по одному, но без запроса базовой точки как таковой.
Последний предложеный мне макрос ни одну, ни вторую функцию не выполняет
barabaka вне форума  
 
Непрочитано 15.04.2017, 09:01
#10
Profan


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


Если речь идет о моем "маккросе", то это по сути просто вызов команды "_NCOPY", поэтому и ждать от него нечего. А по сути получается, что базовая точка указывается в пределах внешней ссылки (но я в этом не уверен), а вторая точка - в пределах текущего чертежа.
Когда-то на форуме caduser.ru родился вот такой макрос выполнения команды РАСТЯНУТЬ без указания базовой точки
Код:
[Выделить все]
^C^C_stretch;_c;\\;;\;
Но там все происходит в пределах текущего чертежа...
Profan вне форума  
 
Непрочитано 15.04.2017, 09:22
#11
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от barabaka Посмотреть сообщение
или выбирать по одному, но без запроса базовой точки как таковой.
Код:
[Выделить все]
(command "_NCOPY" pause "" "0,0" "0,0")
Макрос (без проверки)
Код:
[Выделить все]
^C^C(command "_NCOPY" pause "" "0,0" "@")
или с определением своей команды в цикле (выход по ESC)
Код:
[Выделить все]
^C^C(defun C:NCOPY1 ()(while t (command "_NCOPY" pause "" "0,0" "@")));NCOPY1
__________________
Как использовать код на Лиспе читаем здесь

Последний раз редактировалось VVA, 15.04.2017 в 19:56.
VVA вне форума  
 
Непрочитано 15.04.2017, 10:35
#12
Profan


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


Вообще-то, тема далеко ушла от заявленного названия.
Кстати, VVA, вот в этой функции
Код:
[Выделить все]
(defun C:NCOPY1 ()(while t (command "_NCOPY" pause "" "0,0" "@")))
только у меня цикл прерывается по Esc?

Последний раз редактировалось Profan, 15.04.2017 в 11:05.
Profan вне форума  
 
Непрочитано 15.04.2017, 19:56
#13
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от Profan Посмотреть сообщение
только у меня цикл прерывается по Esc?
Нет, так и задумывалось. Другого способа пока в голову не пришло
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Непрочитано 15.04.2017, 22:10
#14
Profan


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


Попробовал я разобраться с файлом trexblk.lsp из ЕТ, да что-то муторно показалось. Одно уяснил, что для выбора объектов используется функция (nentsel) в цикле, да еще то, что там каким-то образом выбранные объекты обрабатываются (ssget). А дальше что-то утомился.
Profan вне форума  
 
Автор темы   Непрочитано 16.04.2017, 03:23
#15
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Цитата:
Сообщение от Profan Посмотреть сообщение
Вообще-то, тема далеко ушла от заявленного названия.
Согласен. Предлагаю продолжить обсуждение вот где:
LISP. Копирование объекта из внешней ссылки в текущий чертеж.
Тем более, похоже, что там есть нужное решение.
skkkk вне форума  
 
Непрочитано 16.04.2017, 09:57
#16
Profan


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


Хреново, что блок расчленяется. У меня есть объекты в виде мультивыноски с пользовательским блоком, атрибут которого является нумератором. Так вот, целиком вся выноска не копируется. Отдельно выносная линия в виде отрезка, отдельно пользовательский блок, который расчленяется до полилинии, а атрибут вообще как будто его и не было.
То же самое безобразие делает и _NCOPY.
В последних версиях (смотрел в 2013) команда "_NCOPY" ("КОПИРОВАТЬВЛОЖ") формируется самим AutoCAD'ом (а не берется из ET), поэтому я ковырялся с файлом trexblk.lsp из ЕТ AutoCAD 2006.

Последний раз редактировалось Profan, 16.04.2017 в 10:03.
Profan вне форума  
 
Непрочитано 17.04.2017, 10:23
#17
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
Правда, не удалось мне скормить этому Steal'у тип линий в виде переменной - он принимает только строку в "явном" виде, поэтому грузятся все типы линий из указываемой внешней ссылки (если еще нет в чертеже).
Код:
[Выделить все]
 (Steal filename '(("Linetypes" ("*"))))
Поковырялся у себя. У меня стояла задача загрузить типы линий указываемой внешней ссылки без типов линий вставленных в нее внешних ссылок. Тогда строчка будет выглядеть так
Код:
[Выделить все]
(steal dwgname (list (list "Linetypes" (list "~*|*"))))
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 17.04.2017, 19:22
#18
skkkk


 
Регистрация: 20.03.2008
Сообщений: 2,653


Profan, думал я этим заняться, но пока нужды особой не было. Для победы над блоками придется решить несколько вопросов, как организационных, так и алгоритмических.
1. Что делать, если блок уже есть в текущем чертеже? Переопределять? Или, чтобы он принимал вид того, что уже есть? Думаю, первое логичнее - ведь мы хотим несмотря ни на что получить копию блока из внешней ссылки? Тогда даже лучше не переопределять, а переименовывать копируемый блок.
2. Полагаю придется также "грабить" из ссылки ВСЕ блоки (помимо всех типов линий). Проблема отпуржить, конечно, небольшая, но вот как быть с п.1, пока неясно. Если блок такой уже есть в чертеже, выходит, его в нем надо переименовать, а из ссылки подгрузить тот? Прошу помочь определиться тех, кому интересно.
3. С обработкой атрибутов вроде бы проблем возникнуть не должно. Собираем их список из ссылки и назначаем их по этому списку в чертеже.
4. Мультивыноски (и видмимо, размеры) придется обрабатывать отдельно.
Что я еще мог забыть?
skkkk вне форума  
 
Непрочитано 17.04.2017, 19:56
#19
Profan


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


Да мне тоже как-то не обязательно.
Но тут человек про макрос для меню спрашивал на основе _NCOPY. Видимо, задача трудноразрешимая или совсем не, поскольку реально можно скопировать весьма ограниченное количество типов объектов.
Profan вне форума  
 
Непрочитано 17.04.2017, 22:00
#20
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,990
<phrase 1= Отправить сообщение для VVA с помощью Skype™


Цитата:
Сообщение от skkkk Посмотреть сообщение
Что я еще мог забыть?
Мультилинии. Наверное, придется импортировать еще стиль мультилиний.
Не знаю как поведут себя таблицы.
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > LISP. Копирование объекта из внешней ссылки в текущий чертеж

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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Lisp. Копирование объекта, шаг и повтор с добавлением в новый слой pobat LISP 9 19.10.2016 08:18
Как все слои обеденить в один автоматически при внедрение внешней ссылки kofein4ik AutoCAD 10 23.10.2015 10:10
Как можно разбить на примитивы только по контуру внешней ссылки? Иван Павлов AutoCAD 5 18.01.2013 08:52
Как программно определить путь файла внешней ссылки kp+ Программирование 3 11.08.2005 10:39
Не явный путь задания внешней ссылки Елена AutoCAD 2 05.11.2004 00:21