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

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

Вставка таблицы внутри анонимного блока

Ответ
Поиск в этой теме
Непрочитано 20.06.2006, 17:21 #1
Вставка таблицы внутри анонимного блока
Кулик Алексей aka kpblc
Moderator
 
LISP, C# (ACAD 200[9,12,13,14])
 
С.-Петербург
Регистрация: 25.08.2003
Сообщений: 39,833

Проблема тут нарисовалась. Если сделать блок, внутри которого лежит единственный примитив - таблица, и потом попробовать вставлять его программно по аналогии с ru-block-multi-insert-scaled-rotated-or-angleask (там этот блок вставляется в анонимный, и потом работа идет уже с анонимным блоком), то возникает ошибка разбития (vla-explode) анонимного блока. Т.е. блок вставляется "не там, где указано".
Поскольку таблицы фактически являются блоками с именами аналогичными *T123, то логично предположить, что это в общем-то является аналогом безымянного блока. Как бороться, пока не представляю - не прописывать же стили полностью...
Уважаемые программеры, есть идеи? Или мне все же для работы с таблицами надо переделывать логику?
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Просмотров: 4863
 
Непрочитано 21.06.2006, 09:51
#2
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Мне кажется, что таблицы здесь не причем. Поскольку опытным путем установлено, что с анонимными блокам возникают описаные проблемы и без присутствия таблиц.

Вобщем vla-explode -

дает ошибку на:
разномасштабных анонимных и именованных блоках;

некорректно обрабатывает (смещает):
повернутые анонимные блоки;

корректно обрабатывает:
блоки кроме перечисленных.

зы если чего напутал просьба одернуть :)
AY вне форума  
 
Непрочитано 21.06.2006, 11:10
#3
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Поскольку у тебя после vla-explode объект смещается предположу, что блок вставляется с одинаковыми масшабами, но повертутым. С другой стороны именованый блок для таких параметров обрабатывается корректно, так что может быть отказаться от анонимного блока в пользу именованнго. Тем более что можно случайное имя сгенерировать. Ведь, наверное, такой блок нужен в служебных целях для однократной вставки с последующим explode и удалением из базы?
AY вне форума  
 
Автор темы   Непрочитано 21.06.2006, 11:23
#4
Кулик Алексей aka kpblc
Moderator

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


Код вставки:
Код:
[Выделить все]
;|=============================================================================
*    Функция возвращает текущий "масштаб рисования". Сделано только для этого
* примера, потому как масса вещей только захламят код
=============================================================================|;
(defun kpblc-get-scale ()
  100.	  ; масштаб: 1:100
  ) ;_ end of defun

;|=============================================================================
*    Функция вставки блока в указанную точку с указанными масштабами и
* указанным углом. Возвращает vla-указатель на вставленный блок. Снята проверка
* безошибочности выполнения для упрощения кода.
*    Параметры вызова:
*	block-name	имя блока
*	ins-point	точка вставки блока. nil -> запрос пользователя
*	x-scale		масштаб по x
*	y-scale		масштаб по у
*	z-scale		масштаб по z
*	rotation	угол поворота. nil -> Запрос пользователя.
=============================================================================|;
(defun _kpblc-block-insert-obj (block-name   ins-point	  x-scale
				y-scale	     z-scale	  rotation
				)
  (vla-insertblock
    (_kpblc-get-active-space-obj)
    (vlax-3d-point ins-point) ; (trans ins-point 1 0))
    block-name
    x-scale
    y-scale
    z-scale
    rotation
    ) ;_ end of vla-insertblock
  ) ;_ end of defun

;|=============================================================================
*    Функция возвращает активное пространство (лист / модель). Для листа
* возвращается nil. Для модели - T
*    Параметры вызова:
*	Нет
*    Примеры вызова:
(_kpblc-get-active-space)
===========================================================================|;
(defun _kpblc-get-active-space ()
  (or (= (getvar "tilemode") 1)
      (/= (getvar "cvport") 1)
      ) ;_ end of or
  ) ;_ end of defun

;|=============================================================================
*    Функция возвращает vla-активное пространство (лист / модель). 
*    Параметры вызова:
*	Нет
*    Примеры вызова:
(_kpblc-get-active-space-obj)
=============================================================================|;
(defun _kpblc-get-active-space-obj ()
  (if (and (zerop (vla-get-activespace *kpblc-activedoc*))
	   (= :vlax-false (vla-get-mspace *kpblc-activedoc*))
	   ) ;_ end of and
    (vla-get-paperspace *kpblc-activedoc*)
    (vla-get-modelspace *kpblc-activedoc*)
    ) ;_ end of if
  ) ;_ end of defun

;|=============================================================================
*    Возвращает точку, гарантированно лежащую за пределами текущего экрана.
* Используется в функциях вставки блоков. От идеи использовать LowerLeftCorner
* или UpperRightCorner пришлось отказаться в силу непонятного возвращаемого
* значения при условии работы в пространстве модели.
=============================================================================|;
(defun _kpblc-get-point-offscreen (/ cur_scale)
  (setq cur_scale (kpblc-get-scale))
  (list
    (- (car (getvar "VSMIN")) (* 2 cur_scale))
    (- (cadr (getvar "VSMIN")) (* 2 cur_scale))
    0.0
    ) ;_ end of list
  ) ;_ end of defun

;|=============================================================================
*    Честно сперто с ruCAD'a с определенными переделками "под себя" (пока не
* работаю не в мировой системе, в , поэтому проверку снял).
*    Универсальная функция вставки блока в чертеж. Изображение блока "висит" на
* курсоре в момент вставки.
*    Параметры вызова:
*	msg		приглашение. nil -> "укажите точку вставки"
*	block-name	имя блока. Блок с таким именем уже должен быть в файле
*	x-scale		масштаб по оси х
*	y-scale		то же, y. Если nil, то принимается x-scale
*	z-scale		то же, z. nil -> x-scale
*	block-angle	угол поворота блока. nil -> запрашивается у
*			пользователя
*	multi		выполнять многократную (t) или однократную (nil) вставку
*    Вставка производится на активный слой, с активными настройками текстового
* стиля, типа, веса и цвета линии. Изменения содержимого блока не выполняется.
*    Возвращает список vla-указателей на вставленные блоки.
*    Примеры вызова:
(_kpblc-block-insert-ask-multi-scale-angle "Укажите точку вставки" Block-name (kpblc-get-scale) (kpblc-get-scale) 1.0 0.0 t)
=============================================================================|;
(defun _kpblc-block-insert-ask-multi-scale-angle (msg	       block-name
						  x-scale      y-scale
						  z-scale      block-angle
						  multi	       /
						  do_insert    ins_point
						  tmp_angle    tmp_block
						  tmp_block_ent
						  cur_layer    sub_ent
						  is_attrib    unnamed_block
						  put_point    exp_block
						  result       selset
						  purge_res
						  )
  (setq	do_insert t
	ins_point (_kpblc-get-point-offscreen)
	tmp_angle (if block-angle
		    block-angle
		    0.0
		    ) ;_ end of if
	cur_layer (vla-get-name (vla-get-activelayer *kpblc-activedoc*))
	) ;_ end of setq
  (if msg
    (if	(/= msg "")
      (setq msg	(strcat	"\n"
			(vl-string-trim " :\n\t" msg)
			" <Отмена> : "
			) ;_ end of strcat
	    ) ;_ end of setq
      ) ;_ end of if
    (setq msg "\nУкажите точку вставки <Отмена> : ")
    ) ;_ end of if
  (if (setq tmp_block (_kpblc-block-insert-obj
			block-name ins_point x-scale y-scale z-scale tmp_angle) ;_ end of _kpblc-block-insert-obj
	    ) ;_ end of setq
    (progn
      (setq unnamed_block
	     (vla-add (vla-get-blocks *kpblc-activedoc*)
		      (vlax-3d-point '(0. 0. 0.))
		      "*U"
		      ) ;_ end of vla-add
	    ) ;_ end of setq
      (vla-insertblock
	unnamed_block
	(vlax-3d-point '(0. 0. 0.))
	(vla-get-name tmp_block)
	x-scale
	y-scale
	z-scale
	tmp_angle
	) ;_ end of vla-InsertBlock
      (if (= (vla-get-hasattributes tmp_block) :vlax-true)
	(setq is_attrib t)
	) ;_ end of if
      (vla-erase tmp_block)
      ) ;_ end of progn
    (setq do_insert nil)
    ) ;_ end of if
  (while do_insert
    (setq tmp_block (handent (vla-get-handle
			       (_kpblc-block-insert-obj
				 (vla-get-name unnamed_block)
				 ins_point
				 1.0
				 1.0
				 1.0
				 0.0
				 ) ;_ end of _kpblc-block-insert-obj
			       ) ;_ end of vla-get-handle
			     ) ;_ end of handent
	  ) ;_ end of setq
    (princ msg)
    (vl-cmdf "_.change" tmp_block "" "" pause "")
    (setq put_point (cdr (assoc 10 (entget tmp_block)))
	  do_insert (not (equal ins_point put_point 1e-6))
	  ) ;_ end of setq
    (if	(equal ins_point put_point 1e-6)
      (setq do_insert nil)
      (progn
	(if (not block-angle)
	  (progn
	    (princ "\nУгол поворота <0.0> : ")
	    (vl-cmdf "_.change" tmp_block "" "" "" pause)
	    ) ;_ end of progn
	  ) ;_ end of if
	(if do_insert
	  (progn
	    (setq exp_block (car (vlax-safearray->list
				   (vlax-variant-value
				     (vla-explode
				       (vlax-ename->vla-object
					 tmp_block
					 ) ;_ end of vlax-ename->vla-object
				       ) ;_ end of vla-explode
				     ) ;_ end of vlax-variant-value
				   ) ;_ end of vlax-safearray->list
				 ) ;_ end of car
		  ) ;_ end of setq
	    (if	(and (= (getvar "attreq") 1)
		     is_attrib
		     ) ;_ end of and
	      (command "_.ddatte" (entlast))
	      ) ;_ end of if
	    (vla-put-insertionpoint exp_block (vlax-3d-point put_point))
	    (setq
	      result (append result (list (vlax-ename->vla-object (entlast))))
	      ) ;_ end of setq
	    (princ result)
	    ) ;_ end of progn
	  ) ;_ end of progn
	) ;_ end of if
      ) ;_ end of if
    (entdel tmp_block)
    (if	(not multi)
      (setq do_insert nil)
      ) ;_ end of if
    ) ;_ end of while
  result
  ) ;_ end of defun
Вроде как все вложенные функции присоединил, если чего упустил, прошу сильно не бить - намекните, выложу. А теперь эксперимент:
- рисуем прямоугольник, к примеру. Из него - блок (имя - qwer1). Запускаем функцию
Код:
[Выделить все]
(_kpblc-block-insert-ask-multi-scale-angle "Точка вставки : " "qwer1" (kpblc-get-scale) (kpblc-get-scale) (kpblc-get-scale) 0.0 t)
- делаем таблицу (любую, стиль роли не играет). В блок qwer2.
Код:
[Выделить все]
(_kpblc-block-insert-ask-multi-scale-angle "Точка вставки" "qwer2" (kpblc-get-scale) (kpblc-get-scale) (kpblc-get-scale) 0.0 t)
И провернуть _zoom _e
Для полной гарантии перед вставкой добавить прямоугольник, например, (0.0 0.0) - (60000.0 3000.0) и вставлять в его вершины.
Как ощущения? Я проверял на 2005 и 2006 кадах.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 21.06.2006, 11:43
#5
Кулик Алексей aka kpblc
Moderator

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


Совсем упустил из виду (спасибо Эдуарду, подсказал)- упустил указатель на активный документ: в самом начале проверки сделать
Код:
[Выделить все]
(setq *kpblc-activedoc* (vla-get-ActiveDocument (vlax-get-acad-object)))
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.06.2006, 14:21
#6
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Следут признать фигня получается. А именно после применения комманды таблица внутри блока улетает в космос относительно своего первоночального положения. Я это объяснить не могу. Но, как показывает опыт, таблица после каждого применения команды улетает в новый космос. Я даже провел дерзкий эксперимент поместил в один блок и квадрат и таблицу :))) результат - квадрат при вставке на месте, а таблицу раз от раза "колбасит" по чертежу.

Поскольку программа навороченная, спасибо авторам, снаскоку определить место где происходит "улет" не получатеся поэтому предлагаю крысу написать отладочную функцию проверки положения таблицы в блоке с выводом сообщения с комстроку и повставлять ее куда только можно и думать думать думать . . .

ps еще одна неточность в 4-ом посте - в первом вызове функции вставки лишний аргумент
AY вне форума  
 
Автор темы   Непрочитано 21.06.2006, 14:43
#7
Кулик Алексей aka kpblc
Moderator

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


Эдуард вроде как нашел решение, только я проверить его не могу - кад, зараза, слетел напрочь. Из разговора по аське:
Цитата:
Эдуард (12:48:50 21/06/2006)
Когда ты определяешь блок qwer ты берешь уже вставленный экземпляр таблицы который имеет какую-то точку
вставки. Когда блок kwer определен эти координаты становятся относительными (относительно его qwer точки вставки).
Для того чтобы таблица встала на место нужно точку вставки таблицы определить как 0,0,0
К сожалению появляется какой-то другой глюк.- таблицу становится сложно выбрать.Похоже что-то нужно делать с блоком *T
Эдуард (13:25:08 21/06/2006)
Команда чендж похоже стирает старые вставки и вставляет новые.(т.е. висение блока на курсоре это резултат используемой команды INSERT
Вот решение:
После команды change выполняем:
(vla-put-InsertionPoint(vla-item(vla-item(vla-get-blocks(vla-get-ActiveDocument(vlax-get-acad-object)))"qwer")0)(vlax-3d-point '(0 0 0))) ;-изменяем точку вставки
(mapcar 'vla-update(mapcar 'vlax-ename->vla-object(vl-remove-if 'listp (mapcar 'cadr (ssnamex (ssget "x")))))) ;- обновляем инсерты
Пост подправил.
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 21.06.2006, 15:05
#8
AY

webcad.pro
 
Регистрация: 06.01.2005
Московская обл.
Сообщений: 501


Поробовал - работает!

Мне тоже казалось, что проблемы с относительным и абсолютным положением блоков. Однако, когда для проверки создал блок из другого блока, то при вставке все происходило нормально. И потом, положение таблицы в блоке меняется каждый раз, а не один как этого следовало бы ожидать.

Чё-то я не догоняю :(
AY вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Вставка таблицы внутри анонимного блока

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

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