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

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

Получить блок программно, не используя функцию entsel

Ответ
Поиск в этой теме
Непрочитано 03.12.2010, 11:27 #1
Получить блок программно, не используя функцию entsel
Nextk
 
Регистрация: 02.12.2010
Сообщений: 7

Здравствуйте.
Я использую функцию, взятую с этого форума.
Наверное, она вам известна. Она получает атрибуты.
Например так
Код:
[Выделить все]
(get-all-atts (car(entsel "\nSelect block:")))
а мне нужно получить атрибуты этой же функцией, но не по выделению мышкой, а по знанию того, что блок называется "testname", например. Как это сделать?
Спасибо за внимание, буду очень благодарен советам.
Просмотров: 5504
 
Непрочитано 03.12.2010, 11:54
1 | #2
Лиспер


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


По имени блока можно получить определения атрибутов и их "начальные" значения. Конкретные значения можно получить только из вхождения.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 03.12.2010, 12:06
1 | #3
Sleekka

-
 
Регистрация: 24.07.2005
Москва
Сообщений: 1,335


Код:
[Выделить все]
(setq ss2 (ssget "_A" '((2 . "ымя блоха") )))
(vl-remove-if 'listp (mapcar 'cadr (ssnamex ss2)))
Ну как-то так - если есть динамика то уже сложнее - придется тебе самому поискать по форуму, если никто не сжалится.
Sleekka вне форума  
 
Автор темы   Непрочитано 03.12.2010, 12:21
#4
Nextk


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


Динамики нет, задача просто открыть чертеж, прочитать значения, сделать некие выводы и закрыть
Скоро проверю эти варианты, спасибо за помощь.
Nextk вне форума  
 
Автор темы   Непрочитано 06.12.2010, 09:26
#5
Nextk


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


К сожалению, этот метод
Код:
[Выделить все]
(setq ss2 (ssget "_A" '((2 . "имя блоха") )))
возвращает nil..
Как получить значения атрибутов по имени блока?
Nextk вне форума  
 
Непрочитано 06.12.2010, 09:34
1 | #6
Лиспер


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


1. Вместо "имя блока" подставил имя искомого блока (в кавычках)?
2. Смотри #2
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Автор темы   Непрочитано 06.12.2010, 09:45
#7
Nextk


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


Да, само собой подставил, в кавычках. А что значит #2?
Nextk вне форума  
 
Непрочитано 06.12.2010, 09:48
1 | #8
Лиспер


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


Пост номер 2 этой темы. Для получения значений атрибутов конкретного блока необходимо получить указатель на вхождение этого блока.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Автор темы   Непрочитано 06.12.2010, 10:00
#9
Nextk


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


А как получить указатель на вхождение блока? Среди каких функций мне искать?
"Функции доступа к примитивам AutoCAD"? или "Функции ввода данных и указания объектов"?
Я пока малокомпетентен, к сожалению :/
Nextk вне форума  
 
Непрочитано 06.12.2010, 10:11
1 | #10
NEDIS

Инженер СКС
 
Регистрация: 21.08.2009
г. Домодедово МО
Сообщений: 72


лови
Код:
[Выделить все]
(vl-load-com)
(setq
    pt1 (getpoint "\nВыделите фрагмент в рамках которого будет выполняться поиск")
    pt2 (getcorner pt1)
)
;находим все вхождения блоков
(setq
    selset (ssget "_W" pt1 pt2 '((0 . "INSERT")))
    n1 0
)
;извлекаем блоки из набора
(while
    (setq BlkRef1 (ssname selset n1))
    (setq BlkRef1 (vlax-ename->vla-object BlkRef1))
    (if
        ;проверяем имя блока, если оно то считываем атрибуты
        (= (vla-get-EffectiveName BlkRef1) "ИМЯ-блока")
        (progn
            ;Составление списка атрибутов блока ИМЯ-блока 
            (setq lst_temp1 
                (vlax-safearray->list
                    (vlax-variant-value (vla-GetAttributes BlkRef1))
                )
            )
            ;Считываем название атрибута и значения
            (foreach item1 lst_temp1
                (setq
                    Name-atr (vla-get-TagString item1)
                    Value-atr (vla-get-TextString item1)
                )
                (princ (strcat "\n " Name-atr " - " Value-atr))
            )
        )
        
    )
    (setq n1 (1+ n1))
    (princ "\n========================")
)
NEDIS вне форума  
 
Автор темы   Непрочитано 08.12.2010, 13:34
#11
Nextk


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


NEDIS, Спасибо огромное! Это работает
Теперь ищу ответ на вопрос - как найти координаты этого самого блока
Nextk вне форума  
 
Непрочитано 08.12.2010, 13:46
#12
Лиспер


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


1, Код не обязательно будет работать корректно, если часть окна попала за пределы отображаемой графики.
2. Забыли про постоянные атрибуты
3. Все равно выполняется выбор блока.
4. Что значит "координаты"? Координаты точки вставки? Так это либо INsertionPoint, либо 10-я группа DXF-представления. Ну и не надо забывать про немировые системы координат...
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Автор темы   Непрочитано 08.12.2010, 14:06
#13
Nextk


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


Лиспер, нужные мне атрибуты он читает, а что значит постоянные? какие сейчас тогда читаются? о_О
Выбор блока я переопределил, чтобы он брал большой прямоугольник и в нем искал.
Координаты это левая верхняя и правая нижняя точка границы блока, есть ведь такие?
Нужно всё это в итоге для печати.
Я так понял что мне и надо использовать десятую группу, вроде бы.
Nextk вне форума  
 
Непрочитано 08.12.2010, 14:11
1 | #14
Лиспер


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


Nextk, что такое "постоянное"? Правильно, неизменяемое. Можешь поверить, можешь проверить - такие атрибуты существуют.
Цитата:
Сообщение от Nextk Посмотреть сообщение
левая верхняя и правая нижняя точка границы блока, есть ведь такие?
Конечно есть. Получаются через метод vla-GetBoundingBox. Метод не без подводных камней, на форуме это дело кто-то разбирал (по-моему, VVA).
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 14.12.2010, 15:40
#15
NEDIS

Инженер СКС
 
Регистрация: 21.08.2009
г. Домодедово МО
Сообщений: 72


Цитата:
Сообщение от Лиспер Посмотреть сообщение
1, Код не обязательно будет работать корректно, если часть окна попала за пределы отображаемой графики.
2. Забыли про постоянные атрибуты
3. Все равно выполняется выбор блока.
4. Что значит "координаты"? Координаты точки вставки? Так это либо INsertionPoint, либо 10-я группа DXF-представления. Ну и не надо забывать про немировые системы координат...
По поводу пункта 1 столкнулся с такой проблемой, как решить?

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

Код:
[Выделить все]
(defun repole-marker ( / )
	;===== Формируем набор selset всех примитивов, находящихся на этом чертеже =====;
	(setq
		selset (ssget "_X" '((0 . "INSERT")))
		n 0
	)
	;== Извлекаем примитивы из набора selset ==;
	(if
		(/= selset nil)
		(while 
			(setq BlkRef (ssname selset n))
			(setq BlkRef (vlax-ename->vla-object BlkRef))
;-----------------------------------------------------------------------------------------------------------
			(if
				(= (vla-get-EffectiveName BlkRef) "SCS_kab_marker")
				;====== Составление списка атрибутов блока =======;
				(progn
					(setq
						lst_temp 
							(vlax-safearray->list
								(vlax-variant-value (vla-GetAttributes BlkRef))
							)
						n1 0
					)
					(while
						(<= n1 (- (length lst_temp) 1))
						(if
							(and 
								(= (vla-get-TagString (nth n1 lst_temp)) "СЛОЙ1")
								(/= (vla-get-TextString (nth n1 lst_temp)) "")
							)
							(progn
								(setq
									sloy1 (vla-get-TextString (nth n1 lst_temp))
								)
								;====== Вот здесь понеслась: необходимо считать базовую точку блока, =======;
								;====== из точки сделать небольшую рамку, и посчитать все линейные примитивы на указанном слое =======;
								;====== количество пимитивов засунуть в МАРКЕР1 =======;
								(setq
									tocka-vstavki-bloka (cdr (assoc 10 (entget (ssname selset n))))
									X1 (nth 0 tocka-vstavki-bloka) Y1 (nth 1 tocka-vstavki-bloka) Z1 (nth 2 tocka-vstavki-bloka)
									p1 (list (- X1 2) (+ Y1 2))
									p2 (list (+ X1 2) (- Y1 2))
									selset_marker (ssget "_C" p1 p2 '((0 . "*POLYLINE")))
									n2 0
									s4et4ik 0
								)
								(if
									(/= selset_marker nil)
									(while
										(setq primitiv-list (ssname selset_marker n2))
										(if
											(= (cdr (assoc 8 (entget primitiv-list))) sloy1)
											(setq s4et4ik (+ s4et4ik 1))
										)
									(setq n2 (+ n2 1)))
								)
								(foreach item lst_temp
									(if
										(= (vla-get-TagString item) "МАРКЕР1")
										(vla-put-TextString item s4et4ik)
									)
								)
							)
						)
					(setq n1 (+ n1 1)))
				)
			)
(setq n (+ n 1)))
	)
)
NEDIS вне форума  
 
Непрочитано 14.12.2010, 16:15
#16
Лиспер


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


А блок гарантированно находится в видимой области экрана? А если блоков несколько?
В общем, в качестве одного из вариантов (поскольку образца файла нет, код не тестировал вообще)
Вложения
Тип файла: lsp repole-mark.LSP (5.6 Кб, 43 просмотров)
__________________
(/= RegDate StartReadDate)

Последний раз редактировалось Лиспер, 16.12.2010 в 11:50.
Лиспер вне форума  
 
Непрочитано 16.12.2010, 11:26
#17
NEDIS

Инженер СКС
 
Регистрация: 21.08.2009
г. Домодедово МО
Сообщений: 72


Цитата:
Сообщение от Лиспер Посмотреть сообщение
А блок гарантированно находится в видимой области экрана? А если блоков несколько?
В общем, в качестве одного из вариантов (поскольку образца файла нет, код не тестировал вообще)
не обновляются как раз те блоки которые не попали в видимую часть экрана
код не фурычит. выкладываю пример
Вложения
Тип файла: dwg
DWG 2007
Пример на форум.dwg (118.6 Кб, 823 просмотров)
NEDIS вне форума  
 
Непрочитано 16.12.2010, 11:50
#18
Лиспер


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


#16 изменил, проверяй. На примере сработало.
Кстати, слои должны быть разблокированы и разморожены, я это дело не обрабатывал.
__________________
(/= RegDate StartReadDate)
Лиспер вне форума  
 
Непрочитано 16.12.2010, 12:36
#19
NEDIS

Инженер СКС
 
Регистрация: 21.08.2009
г. Домодедово МО
Сообщений: 72


Цитата:
Сообщение от Лиспер Посмотреть сообщение
#16 изменил, проверяй. На примере сработало.
Кстати, слои должны быть разблокированы и разморожены, я это дело не обрабатывал.
Обработку 200 блоков я подустал ждать на моей косячной функции за пару секунд обрабатывалось
NEDIS вне форума  
 
Непрочитано 16.12.2010, 12:46
#20
Лиспер


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


Пример обработало примерно за секунду (AutoCAD 2008).
---
Добавлено: давай файл с 200 / 2 000 / 20 000 блоками, попробую погонять. Если время найдется.
---
Добавлено 2: Ради интересу можно добавить в файл "мусора" - сторонних блоков, которые вообще никакого отношения к задаче не имеют. И попробовать уже с ними.
__________________
(/= RegDate StartReadDate)

Последний раз редактировалось Лиспер, 16.12.2010 в 12:53.
Лиспер вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Получить блок программно, не используя функцию entsel



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Болеем за наших на Олимпиаде T-Yoke Разное 472 28.04.2009 17:40
ADT. Программно получить значение храктеристики. игорёк Программирование 10 25.08.2008 10:39
Как получить значение атрибута используя Diesel-выражение? mental Программирование 1 12.04.2007 10:16