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

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

Проблемы с перемещением блоков в новой ПСК

Ответ
Поиск в этой теме
Непрочитано 16.09.2023, 21:32 #1
Проблемы с перемещением блоков в новой ПСК
Станислав_
 
Регистрация: 05.08.2023
Сообщений: 27

Здравствуйте всем! Пишу прогу по расстановке блоков на плане с привязкой к определённым точкам и с совмещением по линейному объекту. Нюанс программы в том, что после установки блока в точку вставки и совмещения его, например, с линейным участком ломаной линии, отрезком или стороной прямоугольника (все эти объекты могут быть развёрнуты относительно МСК на некоторый угол) нужно сдвинуть блок относительно точки вставки по координатам Х и У в системе координат блока на определённые расстояния. После перемещения уже повёрнутого блока в точку вставки и установки ПСК по блоку пытался выполнить этот сдвиг через команду (command _.move ...), через (vla-move obj ...) и даже попытался подвинуть блок изменением точки вставки через (vla-put-InsertionPoint obj ...). Итог следующий: по координате Х блок передвигается на нужное расстояние, а по координате У перемещается на какую-то произвольную величину! Также заметил, что все действия по перемещению происходят не в СК блока или СК объекта, по которому выравнивается блок, а в МСК! Возможно проблема кроется в значении какой-то системной переменной, про которую я и не догадываюсь... Прицепил картинки, которые иллюстрируют работу программы. Подскажите пожалуйста, как правильно программно организовать этот сдвиг. Заранее всех благодарю за ответы!

Миниатюры
Нажмите на изображение для увеличения
Название: Ситуация до.PNG
Просмотров: 39
Размер:	24.7 Кб
ID:	258756  Нажмите на изображение для увеличения
Название: Ситуация после совмещения.PNG
Просмотров: 42
Размер:	22.2 Кб
ID:	258758  Нажмите на изображение для увеличения
Название: Ситуация после совмещения и смещения блока по координатам.PNG
Просмотров: 36
Размер:	29.5 Кб
ID:	258759  

Просмотров: 1045
 
Непрочитано 16.09.2023, 21:34
#2
Кулик Алексей aka kpblc
Moderator

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


trans ?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 16.09.2023, 21:38
#3
Станислав_


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


Да, и конечно же мой инструмент: AutoCAD 2021 rus.
А также, предупреждая разного рода вопросы про мою несознательность: форум пошерстил, в инете погуглил, у Полещука не нашёл.

----- добавлено через ~6 мин. -----
trans, возможно очень полезная функция, но я не понимаю, как ей пользоваться. Честно пытался с ней разобраться, экспериментировал, но безрезультатно. Те результаты, которые выдаёт данная функция для меня не понятны...
Станислав_ вне форума  
 
Непрочитано 16.09.2023, 22:07
#4
Кулик Алексей aka kpblc
Moderator

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


Я про то, что (может быть) стоит изначально вычислить корректную точку вставки блока, потом ее транспонировать в новую ПСК, и после этого уже собственно вставлять блок, предварительно сменив ему нормаль.
ПыСы АКАД сейчас от меня очень далеко, пишу "на попробовать"
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 16.09.2023, 22:23
#5
Станислав_


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


Не совсем понял про нормаль. Блоки двумерные, расставляются на двумерных планах...
Станислав_ вне форума  
 
Непрочитано 17.09.2023, 08:12
#6
Кулик Алексей aka kpblc
Moderator

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


Тогда откуда "смещение от МСК"? И вообще, базовая точка блока где находится?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.09.2023, 09:59
#7
Станислав_


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


На второй картинке блок установлен своей базовой точкой в правый верхний угол прямоугольника. Затем нужно произвести смещение блока на расстояния X и Y.
Станислав_ вне форума  
 
Непрочитано 17.09.2023, 11:15
#8
Кулик Алексей aka kpblc
Moderator

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


Так, может, базовую точку привести в нормальное состояние? И вообще, скинь чертеж и код - попробую посмотреть
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.09.2023, 11:55
#9
Станислав_


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


Скину, но только вечером, ща не у компа...
Станислав_ вне форума  
 
Автор темы   Непрочитано 17.09.2023, 19:49
#10
Станислав_


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


Итак, выкладываю код:
Код:
[Выделить все]
 (defun AttrRotateAndMove (
		          /
		          obj            ;выбранный объект (блок)
		          trgg           ;триггер выхода из цикла while
		          att_lst        ;список значений атрибутов блока
		          blc_nm         ;значение атрибута блока
			  att_obj_lst    ;список атрибуто, представляющих vla-объекты
			  att_obj        ;атрибут (vla-объект)
		          modLeft        ;маркер, принимает значение Т, если значение атрибута соответствует шаблону левой модификации блока
		          modRght        ;маркер, принимает значение Т, если значение атрибута соответствует шаблону правой модификации блока
		          pt1            ;координаты первой точки
		          pt2            ;координаты второй точки
		          pt3            ;координаты третьей точки
			  ins_pt         ;точка вставки блока
			  ang            ;угол поворота блока
			  dx_            ;смещение блока по оси X при его позиционировании
			  dy_            ;смещение блока по оси Y при его позиционировании
		         )
  (setq adoc (vla-get-activedocument (vlax-get-acad-object))) ;запись в глобальную переменную указателя на документ
  (vla-StartUndoMark adoc) ;установка начальной метки отката
  (while (not trgg)
    (if (VL-CATCH-ALL-ERROR-P (setq obj (VL-CATCH-ALL-APPLY 'entsel)))  ;выбор блока с проверкой на нажание клавиши Esc
      (setq trgg T)  ;присвоение переменной trgg значения nil для выхода из цикла while
      (if obj
	(progn
          (setq obj (vlax-ename->vla-object (car obj)))  ;переопределение выбранного объекта в VLA-объект
          (cond
            ((eq :vlax-false (vla-get-HasAttributes obj)) ;проверка на наличие у выбранного объекта атрибутов
             (alert "Объект не имеет атрибутов!")  ;сообщение об ошибке
	    )
	    (T
	     (setq att_obj_lst (vlax-safearray->list (vlax-variant-value (vla-GetAttributes obj))))  ;получение списка атрибутов блоков в виде VLA-объектов
             (mapcar '(lambda (x) (if (or (setq modLeft (wcmatch (vla-get-tagstring x) "*.##Л*")) (setq modRght (wcmatch (vla-get-tagstring x) "*.##П*")))  (setq att_obj x))) att_obj_lst)  ;получение значений маркеров modLeft и modRght в зависимости от соответствия наименования блока шаблону с одновременным определением атрибута с наименованием блока из списка атрибутов
	     (setq blc_nm (vla-get-tagstring att_obj))  ;определение имени блока (в дальнейшем имя блока определяет наименование файла, в котором хранится данный блок)
	    )
          )
	  (setq pt1 (getpoint))  ;указание первой точки
	  (setq pt2 (getpoint))  ;указание второй точки
	  (setq pt3 (getpoint))  ;указание третьей точки
	  (cond
	    (modLeft (setq ang (- (angle pt1 pt2) pi)))  ;вычисление угла поворота блока в зависимости от модификации блока ЛЕВЫЙ
	    (modRght (setq ang (angle pt1 pt2)))  ;вычисление угла поворота блока в зависимости от модификации блока ПРАВЫЙ
	  )
	  ;определение смещений блока по значениям атрибутов:
          (mapcar '(lambda (x) (if (wcmatch (vla-get-tagstring x) "DX")  ;условие: если имя атрибута равно значению "DX"
				 (setq dx_ (vla-get-TextString x))       ;присвоение переменной dx значения атрибута с именем "DX"
			       )
		               (if (wcmatch (vla-get-tagstring x) "DY")  ;условие: если имя атрибута равно значению "DY"
				 (setq dy_ (vla-get-TextString x))       ;присвоение переменной dy значения атрибута с именем "DY"
			       )
		   )
	           att_obj_lst)
	  (setq ins_pt (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint obj))))  ;точка вставки блока
	  (vla-put-Rotation att_obj (* ang -1)) ;поворот атрибута блока с наименованием блока на обратный вычисленный угол
	  (vla-put-Rotation obj ang)  ;поворот блока на вычисленный угол
	  ;позиционирование блока на месте вставки:
	  (vla-move obj (vlax-3d-point ins_pt) (vlax-3d-point pt1))  ;перемещение блока в точку установки блока на КП
	  (command "_UCS" "_obj" (vlax-vla-object->ename obj))
;;;	  (command "_UCS" "_new" pt1)  ;перемещение СК в точку pt1
;;;	  (command "_UCS" "z" (/ (* ang 180) pi))  ;поворот СК на угол ang с переводом радиан в градусы
	  
;;;	  (setq ins_pt (vlax-safearray->list (vlax-variant-value (vla-get-InsertionPoint obj))))  ;точка вставки блока
;;;	  (setq ins_pt (mapcar '- ins_pt (list (atoi dx_) (atoi dy_) 0)))
;;;	  (vla-put-InsertionPoint obj (vlax-3d-point ins_pt))
	  
;;;	  (command "_.move" (vlax-vla-object->ename obj) "" (list 0 0 0) (list (atoi dx_) 0 0))  ;перемещиние блока с позиционированием его по линии установки со смещением от края отверстия на заданное расстояние
;;;	  (command "_.move" (vlax-vla-object->ename obj) "" (list 0 0 0) (list 0 (atoi dy_) 0))

;;;	  (command "_UCS" "_w")  ;установка МСК
	  (setq trgg T)  ;присвоение переменной начального значения
        )
      )
    )
  )
  (vla-EndUndoMark adoc) ;установка конечной метки отката
  (princ)
)
Пояснения: в начале работы программы нужно выбрать блок, затем три точки на прямоугольнике, на котором нужно спозиционировать блок, две точки по углам длинной стороны прямоугольника, одна на углу короткой стороны. Закомментированные строки в моей процедуре - это мои попытки сместить блок после его позиционирования в прямоугольнике. Не доделал проверку на нажатие кнопки Esc при выборе точек. Также прикладываю файл с блоками и прямоугольниками.
Вложения
Тип файла: dwg
DWG 2013
Расстановка блоков на плане.dwg (5.27 Мб, 8 просмотров)
Станислав_ вне форума  
 
Непрочитано 17.09.2023, 21:27
1 | #11
Кулик Алексей aka kpblc
Moderator

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


Ну вот что по-быстрому получилось:
Код:
[Выделить все]
 (defun test ()
  (while (and
           (=
             (type (setq blk_ref (vl-catch-all-apply
                                   (function
                                     (lambda ()
                                       (vlax-ename->vla-object (ssname (ssget "_:S" '((0 . "INSERT") (66 . 1))) 0))
                                     ) ;_ end of lambda
                                   ) ;_ end of function
                                 ) ;_ end of vl-catch-all-apply
                   ) ;_ end of setq
             ) ;_ end of type
             'vla-object
           ) ;_ end of =
           (= (type (setq point1 (vl-catch-all-apply
                                   (function
                                     (lambda ()
                                       (getpoint "\nFirst point <Cancel> : ")
                                     ) ;_ end of lambda
                                   ) ;_ end of function
                                 ) ;_ end of vl-catch-all-apply
                    ) ;_ end of setq
              ) ;_ end of type
              'list
           ) ;_ end of =
           point1
           (= (type (setq point2 (vl-catch-all-apply
                                   (function
                                     (lambda ()
                                       (getpoint point1 "\nSecond point <Cancel> : ")
                                     ) ;_ end of lambda
                                   ) ;_ end of function
                                 ) ;_ end of vl-catch-all-apply
                    ) ;_ end of setq
              ) ;_ end of type
              'list
           ) ;_ end of =
           point2
;           (= (type (setq point3 (vl-catch-all-apply
;                                   (function
;                                     (lambda ()
;                                       (getpoint point1 "\nSecond point <Cancel> : ")
;                                     ) ;_ end of lambda
;                                   ) ;_ end of function
;                                 ) ;_ end of vl-catch-all-apply
;                    ) ;_ end of setq
;              ) ;_ end of type
;              'list
;           ) ;_ end of =
;           point3
         ) ;_ end of and
    (vla-insertblock
      (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))
      (vlax-3d-point point2)
      (vla-get-effectivename blk_ref)
      1.
      1.
      1.
      (angle point1 point2)
    ) ;_ end of vla-InsertBlock
  ) ;_ end of while
) ;_ end of defun
Назначение 3-й точки пока непонятно, так что закомментировал. На ACAD2021 все работает вполне корректно
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.09.2023, 21:50
#12
Станислав_


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


Алексей, спасибо огромное! Завтра буду тестировать.

----- добавлено через ~3 мин. -----
А третья точка введена на перспективу образмерить область вставки блока для наглядности плана с размещёнными блоками.
Станислав_ вне форума  
 
Непрочитано 17.09.2023, 21:56
#13
Кулик Алексей aka kpblc
Moderator

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


Цитата:
Сообщение от Станислав_ Посмотреть сообщение
А третья точка введена на перспективу образмерить область вставки блока для наглядности плана с размещёнными блоками.
Я бы подумал на предмет "вынести это в отдельную функцию". Т.е. вставка - отдельно, образмеривание - отдельно. Ибо нефих!
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 17.09.2023, 22:31
1 | #14
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,817


как понял, без проверок) но видится использование динамики в блоке, а именно выравнивания и использование видимости для правого и левого положений блока.
Код:
[Выделить все]
 
;****************************************************************************************************************************************************************************************

(defun _fix (number)
	(atoi (rtos number 2 0))	  
)

;****************************************************************************************************************************************************************************************

(defun c:move_block (/ insert corner_vertex pline corner_vertex_param corner_vertex+1 corner_vertex-1 insert_rotation_x_axis_angle y_axis_angle dx dy angle_correction) 
	(setq insert (vlax-ename->vla-object (car (entsel "\nБлок: ")))
	      corner_vertex (getpoint "\nУгловая реперная вершина полилинии для вставки блока: ")
	      pline (car (nentselp corner_vertex))
	      corner_vertex (trans corner_vertex 1 0)
	      corner_vertex_param (_fix (vlax-curve-getparamatpoint pline corner_vertex))
	      corner_vertex (vlax-curve-getpointatparam pline corner_vertex_param) 
	      corner_vertex+1 (vlax-curve-getpointatparam pline (if (= (_fix (vlax-curve-getendparam pline)) corner_vertex_param) 1 (1+ corner_vertex_param)))
	      corner_vertex-1 (vlax-curve-getpointatparam pline (if (zerop corner_vertex_param) (vlax-curve-getendparam pline) (1- corner_vertex_param)))
	      insert_rotation_x_axis_angle (angle corner_vertex (if (> (distance corner_vertex corner_vertex+1) (distance corner_vertex corner_vertex-1)) corner_vertex+1 corner_vertex-1))
	      y_axis_angle (angle corner_vertex (if (< (distance corner_vertex corner_vertex+1) (distance corner_vertex corner_vertex-1)) corner_vertex+1 corner_vertex-1)) 
	)
	(mapcar '(lambda (attribute) (cond
					 	(
							(= "DX" (vla-get-tagstring attribute))
						 		(setq dx (abs (atof (vla-get-textstring attribute))))
						)
						(
							(= "DY" (vla-get-tagstring attribute))
						 		(setq dy (abs (atof (vla-get-textstring attribute))))
						)
						(
						 	(and (= "NAME" (vla-get-tagstring attribute)))
						 		(cond
								  	(
							         		(wcmatch (vla-get-textstring attribute) "*_Л_")
						 	         			(setq angle_correction pi)
									)
							    		(
							         		(wcmatch (vla-get-textstring attribute) "*_П_")
						 	         			(setq angle_correction 0)
								 	)
								)
						)
						(t)
					)
		   )
		   (vlax-invoke insert 'getattributes)
	)
	(vla-move insert (vla-get-insertionpoint insert) (vlax-3d-point (polar (polar corner_vertex insert_rotation_x_axis_angle dx) y_axis_angle dy)))
	(vla-put-rotation insert (+ insert_rotation_x_axis_angle angle_correction))
  	(princ)
)
;****************************************************************************************************************************************************************************************
__________________
K Lisp

Последний раз редактировалось koMon, 21.09.2023 в 09:50.
koMon вне форума  
 
Автор темы   Непрочитано 18.09.2023, 19:46
#15
Станислав_


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


Добрый вечер всем! Попробовал выполнить код. Всё прекрасно работает, блок выравнивается по объекту. Но остаётся вопрос, как сделать смещение блока после его позиционирования по объекту? Мой код работает ровно до этого же момента! Я так понимаю, что без функции trans не обойтись... Также предполагаю, что можно обойтись одной-двумя строчками кода с использованием этой функции. Только не соображу как правильно составить эту строчку, поэтому в очередной раз прошу помощи у спецов!
Станислав_ вне форума  
 
Непрочитано 18.09.2023, 20:01
#16
Кулик Алексей aka kpblc
Moderator

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


ИМХО при таких раскладах будет значительно проще изначально высчитать точку вставки. Тем же polar
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 19.09.2023, 07:55
#17
Станислав_


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


koMon, программа выдаёт ошибку на строке:
Код:
[Выделить все]
 corner_vertex_param (fix (vlax-curve-getparamatpoint pline corner_vertex))
Попытался исправить, чёт не получилось...
Станислав_ вне форума  
 
Непрочитано 19.09.2023, 10:59
#18
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,817


что за ошибка в консоли?
д.б. как-то так
Нажмите на изображение для увеличения
Название: MB.gif
Просмотров: 13
Размер:	811.8 Кб
ID:	258787
__________________
K Lisp

Последний раз редактировалось koMon, 19.09.2023 в 11:09.
koMon вне форума  
 
Автор темы   Непрочитано 19.09.2023, 20:59
#19
Станислав_


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


После выбора блока, указываю первую точку на полилинии и вылетает ошибка. Скрин в прикреплении.

----- добавлено через ~15 мин. -----
Странным образом заработало после того, как раза два перезагрузил Автокад!
Алексей и koMon ОГРОМНОЕ спасибо за участие! Буду обращаться...
Миниатюры
Нажмите на изображение для увеличения
Название: Сообщение об ошибке в консоли.PNG
Просмотров: 10
Размер:	7.7 Кб
ID:	258791  Нажмите на изображение для увеличения
Название: Строка с ошибкой.PNG
Просмотров: 10
Размер:	22.8 Кб
ID:	258792  
Станислав_ вне форума  
 
Непрочитано 20.09.2023, 11:24
#20
koMon


 
Блог
 
Регистрация: 26.09.2017
Сообщений: 1,817


Цитата:
Сообщение от Станислав_ Посмотреть сообщение
После выбора блока, указываю первую точку на полилинии и вылетает ошибка. Скрин в прикреплении.
могло быть из-за выставленной пск.
__________________
K Lisp
koMon вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Проблемы с перемещением блоков в новой ПСК



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с редактированием блоков Ohripshiy AutoCAD 11 28.10.2015 11:27
Lisp. Как вставить описания всех блоков библиотеки блоков? Kirill_Ja LISP 5 11.04.2013 10:22
Проблема с редактированием определения блоков densoul AutoCAD 9 21.02.2012 13:45
Как избавиться от проблемы "конфликт имени блока в рабочем наборе" при вставке нескольких идеинтичных блоков в другой блок? igor130566 Динамические блоки 9 02.06.2011 11:25
Стены из блоков ФБС высотой 5,4м? Vertex Конструкции зданий и сооружений 11 28.03.2011 14:14