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

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

DWG -> Трёхмерная таблица

Ответ
Поиск в этой теме
Непрочитано 11.07.2010, 00:19 #1
DWG -> Трёхмерная таблица
Lazerus
 
Регистрация: 11.07.2010
Сообщений: 24

Добрый вечер!

Ситуация следующая:

Необходимо привести DWG файл к трёхмерной таблице цветов, чтобы была возможность проходя по осям X, Y и Z считать цвет трёхмерной точки и, следовательно, понимать, что данная точка заполнена чем либо.

Скачал ARX для AutoCAD 2011, но разобраться так и не смог.
Пытался оттолкнуться от типа AcDbDatabase, но без результатно.
Просмотров: 13442
 
Непрочитано 11.07.2010, 11:39
#2
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Необходимо привести DWG файл к трёхмерной таблице цветов, чтобы была возможность проходя по осям X, Y и Z считать цвет трёхмерной точки и, следовательно, понимать, что данная точка заполнена чем либо.
Не знаю как другие, но лично я не смог понять что за "трёхмерная таблица цветов" (цвета всех пикселов в плоскости XY для каждого уровня Z что-ли...) и зачем такое может понадобиться.
hwd вне форума  
 
Автор темы   Непрочитано 11.07.2010, 11:54
#3
Lazerus


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


Цитата:
Сообщение от hwd Посмотреть сообщение
Не знаю как другие, но лично я не смог понять что за "трёхмерная таблица цветов" (цвета всех пикселов в плоскости XY для каждого уровня Z что-ли...) и зачем такое может понадобиться.
Да. Хоть даже если в списке параметров каждого пункта ( или точки ) будет не только цвет.

Грубо говоря, необходимо обойти все точки по осям X, Y, Z, собрав их информацию.
Lazerus вне форума  
 
Непрочитано 11.07.2010, 12:22
#4
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Да. Хоть даже если в списке параметров каждого пункта ( или точки ) будет не только цвет.

Грубо говоря, необходимо обойти все точки по осям X, Y, Z, собрав их информацию.
и зачем это нужно? информация какого рода?
hwd вне форума  
 
Непрочитано 11.07.2010, 12:27
#5
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Так подойдет? Это эскиз, так что можно развить идею...
Код:
[Выделить все]
(defun c:test ( / dummy ss i tmp result)
  (vl-load-com)
  (if (setq ss (ssget "_X" (list '(0 . "POINT"))))
	(setq
	  i 0 result '() dummy
	  (repeat (sslength ss)
		(setq
		  result
		  (cons
			(cons
			  (vla-get-Coordinates (setq tmp (vlax-ename->vla-object (ssname ss i))))
			  (vla-get-Color tmp)
			)
			result
		  )
		  i (1+ i)
		)
	  )
	)
  )
  result
)
gomer вне форума  
 
Автор темы   Непрочитано 11.07.2010, 12:57
#6
Lazerus


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


Цитата:
Сообщение от hwd Посмотреть сообщение
и зачем это нужно? информация какого рода?
Для рассчёта теплообмена здания, и учётом объектов внутри здания. Главная проблема с обходом DWG файла по осям.

Цитата:
Сообщение от hwd Посмотреть сообщение
Так подойдет? Это эскиз, так что можно развить идею...
Ой, я вобще новичёк в AutoCAD, но постараюсь разобраться. Дело в том, что я ещё не разобрался как такие скрипты запускать. Насколько я понял, Вы написали макрос для AutoCAD.

Последний раз редактировалось Lazerus, 11.07.2010 в 13:05.
Lazerus вне форума  
 
Непрочитано 11.07.2010, 13:40
#7
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


>Lazerus: В таком случае читайте справку, чтоб различать, что такое скрипт(сценарий), программа на autolisp или макрос VBA... и как этим пользоваться!
в данном случае скопируйте код в командную строку, затем в ней же наберите: test... если в рисунке есть точки различных цветов, то получите список точек и их цветов!
gomer вне форума  
 
Непрочитано 11.07.2010, 13:43
#8
Кулик Алексей aka kpblc
Moderator

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


Раздел публикации -> как использовать лисп, опубликованный на форуме
__________________
Моя библиотека lisp-функций
---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 11.07.2010, 21:54
#9
lene-caress


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


я бы решала Вашу задачу примерно так (ObjectARX):

1. определить какие объекты нужно подвергнуть преобразованию (выделение)

2. определить границы (диапозоны координат по каждой из осей) трехмерной области

3. определить разрешающую способность результирующей таблицы
ТЕ какой объем векторного пространства будет отображатся на одну ячейку таблицы-результата.
чем больше ячейка - тем проще считать, но хуже детализация,
чем меньше ячейки - тем больше операций счета и памяти требуется, но детализация лучше.

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

4. а вот самое интересное тут.
нужно пройти по списку объектов полученных в пункте 1,
найти ячейки таблицы которые содержат этот объект и вычислить "влияние"
объекта на эти ячейки.
ТЕ если стена дома имеет "цвет" C1 и занимает половину объема ячейки,
то добавляем в аккомулятор ячейки значения цвета и долю объема, в данном случае 0.1
-
подробности этого пункта зависят от того какие типы объектов Вы используете,
и других подробностей.
здесь потребуется привлечь достаточно много математики.

5. по окончании сканирования объектов
в ячейках будут данные о влиянии объектов на них,
можно вычислить средне-весовое этих данных
и сохранить массив данных в любом

по информации:

как получить список объектов, как получить доступ к ним:
http://arxdummies.blogspot.com/2005/...tion-sets.html

метод луча, для определения принадлежности точки многоугольнику (может помочь с пунктом 4):
http://ru.wikipedia.org/wiki/%D0%90%...B8.D1.82.D0.BC
lene-caress вне форума  
 
Автор темы   Непрочитано 11.07.2010, 22:05
#10
Lazerus


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


Цитата:
Сообщение от gomer Посмотреть сообщение
>Lazerus: В таком случае читайте справку, чтоб различать, что такое скрипт(сценарий), программа на autolisp или макрос VBA... и как этим пользоваться!
в данном случае скопируйте код в командную строку, затем в ней же наберите: test... если в рисунке есть точки различных цветов, то получите список точек и их цветов!
Разукрасил материалами, но результат лисп скрипта - nil.

lene-caress, спасибо! Я так понимаю, что невозможно просто пройтись по осям и узнать значения каждой точки через Object ARX. Впринципе, мне без разницы что использовать: ARX или что-либо ещё. В любом случае, постораюсь разобраться по предоставленному Вами плану.

Последний раз редактировалось Lazerus, 11.07.2010 в 22:13.
Lazerus вне форума  
 
Непрочитано 11.07.2010, 22:17
#11
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


хватит стебаться... автор, пример в студию
gomer вне форума  
 
Непрочитано 11.07.2010, 22:46
#12
lene-caress


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


Цитата:
Сообщение от Lazerus Посмотреть сообщение
lene-caress, спасибо! Я так понимаю, что невозможно просто пройтись по осям и узнать значения каждой точки через Object ARX. Впринципе, мне без разницы что использовать: ARX или что-либо ещё. В любом случае, постораюсь разобраться по предоставленному Вами плану.
да - невозможно
дело, однако, не в ObjectARX а в том, что acad оперирует векторными данными, в то время как Вам требуются данные по структуре похожие на растр, только трехмерные.
lene-caress вне форума  
 
Автор темы   Непрочитано 11.07.2010, 23:10
#13
Lazerus


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


Цитата:
Сообщение от lene-caress Посмотреть сообщение
да - невозможно
дело, однако, не в ObjectARX а в том, что acad оперирует векторными данными, в то время как Вам требуются данные по структуре похожие на растр, только трехмерные.
А Вы занимаетесь с ARX? Если "Да", то не моглибы привести пример? Конкретно интересуют координаты объекта, размер, расположение. Я в любом случае буду пытаться разобраться сам, но всёже при наличии примера былобы быстрее.
Lazerus вне форума  
 
Непрочитано 11.07.2010, 23:21
#14
hwd

C, C++, C#
 
Регистрация: 07.10.2009
С-Пб.
Сообщений: 2,762
Отправить сообщение для hwd с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
моглибы... всёже... былобы...
Offtop: Чем-то напоминает манеру письма Павла Лукьянченко...
hwd вне форума  
 
Автор темы   Непрочитано 11.07.2010, 23:27
#15
Lazerus


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


Цитата:
Сообщение от hwd Посмотреть сообщение
Offtop: Чем-то напоминает манеру письма Павла Лукьянченко...
Понравилась фраза "Лучше день потерять за то за пол часа долететь". Но я не он. Хотя возможно, не понял соль фразы.
Lazerus вне форума  
 
Непрочитано 12.07.2010, 02:18
#16
lene-caress


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


как я уже говорила, вот тут описан способ получения списка объектов.
http://arxdummies.blogspot.com/2005/...tion-sets.html

в самом конце заметки дан исходный код, который по полученному ads_name
получает сначала AcDbObjectId, а потом получает сам объект (AcDbEntity*) с помощью функции acdbOpenAcDbEntity

если проводить аналогии (немного кривые) AcDbObjectId похож на первичный ключ (primary key) в реляционных СУБД.
а функция acdbOpenAcDbEntity позволяет получить доступ к объекту идентифицируемому ключем.

полученный AcDbEntity можно преобразовать к нужному типу объекта,
но поскольку тип зарание не известен, то получается:
* либо пробовать преобразовать для каждого обрабатываемого нашей программой типа,
* либо как-то идентифировать что за объект у нас есть.

в предках AcDbEntity есть класс AcRxObject у него есть метод desc()
этот метод возвращает AcRxClass, у него есть метод name(),
который возвращает строковый идентификатор типа объекта
для объекта AcDbLine это будет строчка "AcDbLine"

в любом случае, если нам нужно попробовать привести AcDbEntity к типу пригодному для обработки.

пусть наш объект в переменной:
AcDbEntity *ent ...


либо воспользовавшись данными ent->desc()->name() либо методом "квазинаучного тыка"
пробуем преобразовать объект к типу AcDbLine:
Код:
[Выделить все]
AcDbLine *line = AcDbLine::cast( ent );
if ( line != NULL )
	{
	// если у нас это получилось
	// значит наш ent совместим (является или унаследован) с AcDbLine
	// значит мы можем чтото делать, например получить координаты начальной точки:
	// line->startPoint(); // тип результата AcGePoint3d
	}
аналогично для других типов...

что касается функций из AcDb* здесь проблем быть не должно
они описаны в документации (ObjectARX Reference) и достаточно понятны.

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

Последний раз редактировалось Кулик Алексей aka kpblc, 12.07.2010 в 07:01.
lene-caress вне форума  
 
Автор темы   Непрочитано 12.07.2010, 09:03
#17
Lazerus


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


lene-caress, спасибо! Кстати, а что нужно будет делать, если рёбра объекта деформированны, где хранитмя информация о деформации? Не знаю, можно ли так сделать, но уверен, что AutoCAD представляет такую возможность.
Lazerus вне форума  
 
Непрочитано 12.07.2010, 12:21
#18
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Вы говорили, что все затевается для "рассчёта теплообмена здания, и учётом объектов внутри здания."
Может имеет смысл рассказать вкратце, что за программа будет делать этот расчет и какие входные данные её требуются?
Просто невозможно просмотреть все точки трехмерного пространства в принципе, поскольку их бесконечное множество. Тут дискретизация требуется ( о чем говорила lene-caress). Но можно ведь и по другому подойти. Собрать все объекты в набор и проанализировать каждый из них. Ведь получить сведения о характерных точках, ребрах и гранях можно непосредственно из объектов не сканируя вдоль и поперек трехмерное пространство. Есть шанс, что вам предложат иной подход к решению, если будет достаточно информации о входных требованиях программы теплового расчета.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Автор темы   Непрочитано 12.07.2010, 23:40
#19
Lazerus


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


Цитата:
Сообщение от Pastor Посмотреть сообщение
Вы говорили, что все затевается для "рассчёта теплообмена здания, и учётом объектов внутри здания."
Может имеет смысл рассказать вкратце, что за программа будет делать этот расчет и какие входные данные её требуются?
Просто невозможно просмотреть все точки трехмерного пространства в принципе, поскольку их бесконечное множество. Тут дискретизация требуется ( о чем говорила lene-caress). Но можно ведь и по другому подойти. Собрать все объекты в набор и проанализировать каждый из них. Ведь получить сведения о характерных точках, ребрах и гранях можно непосредственно из объектов не сканируя вдоль и поперек трехмерное пространство. Есть шанс, что вам предложат иной подход к решению, если будет достаточно информации о входных требованиях программы теплового расчета.
Главное знать все заполненные материалом пункты и сам материал. Если не возможно пробежаться по осям всей системы координат, тогда буду рассматривать каждый объект отдельно и заносить инфу в свой трёхмерный массив; но тогда возникает проблема реализации, которую я пытаюсь решить. Я никогда ARX не использовал, ровным счётом, как и AutoCAD.
Lazerus вне форума  
 
Непрочитано 13.07.2010, 00:35
#20
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Цитата:
Я никогда ARX не использовал, ровным счётом, как и AutoCAD.
Ну тогда нужно научиться работе в AutoCAD и программированию в нем одним из трех способов - LISP, ObjectARX или .NET. Причем, научиться программировать, не имея навыков обычного пользователя, не получится.
Научится работать - это книжка страниц на 800 (какая нибудь "библия").
Научиться программировать на LISP - книжка Н.Н.Полещука (~ 500 стр.) + форум на этом сайте.
Научитья ObjectARX - это учебник по языку С++ и год жизни (если с учебником повезет) + справка по ObjectARX и ещё год жизни (если умеете читать по английски) + форум по ObjectARX на сайте caduser.ru.
И, наконец, .NET программирование в AutuCAD - требует знаний языка С# (или VB.NET) и самой платформы .NET, знаний классического ObjectARX (поскольку является оболочкой вокруг ObjectARX) и железных нервов, поскольку отвратительно документирована.
Вот такие перспективы. С наскоку не решить.
Можно ещё нанять программиста...
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Непрочитано 13.07.2010, 00:39
#21
zamtmn

КИПиА
 
Регистрация: 21.03.2005
Tyumen
Сообщений: 1,352
<phrase 1=


Эта тема стеб?
zamtmn вне форума  
 
Непрочитано 13.07.2010, 00:42
#22
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Не стебее других тем.
'Как жарить шашлык в центре Москвы' чем лучше?
__________________
...в шее моей жилы железные, и лоб мой - медный...

Последний раз редактировалось Pastor, 13.07.2010 в 00:48.
Pastor вне форума  
 
Автор темы   Непрочитано 13.07.2010, 15:53
#23
Lazerus


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


Вцелом, ясно; но это не значит, что не нужно искать пути реализации.

И не стебайтесь. Раз не могу сделать - нужно искать и спрашивать!
Lazerus вне форума  
 
Непрочитано 13.07.2010, 17:07
#24
kp+

идущий по граблям
 
Регистрация: 26.05.2005
Сообщений: 5,194


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Добрый вечер!

Ситуация следующая:

Необходимо привести DWG файл к трёхмерной таблице цветов, чтобы была возможность проходя по осям X, Y и Z считать цвет трёхмерной точки и, следовательно, понимать, что данная точка заполнена чем либо.

Скачал ARX для AutoCAD 2011, но разобраться так и не смог.
Пытался оттолкнуться от типа AcDbDatabase, но без результатно.
Я так понимаю, надо определенным образом обработать dwg-файл, сгенерированный сторонней прогой?
Тогда неплохо бы пример исходного материала увидеть...

Последний раз редактировалось kp+, 13.07.2010 в 17:24.
kp+ вне форума  
 
Автор темы   Непрочитано 14.07.2010, 10:56
#25
Lazerus


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


Цитата:
Сообщение от kp+ Посмотреть сообщение
Я так понимаю, надо определенным образом обработать dwg-файл, сгенерированный сторонней прогой?
Тогда неплохо бы пример исходного материала увидеть...
Любой DWG с любыми фигурами. А, вцелом, интересует здание, построенное в DWG, оно также будет состоять из фигур.
Lazerus вне форума  
 
Непрочитано 14.07.2010, 18:40
#26
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Фигура понятие плоское... а здание - объемное... к слову... Как вы хотите найти точки разных цветов на одной "фигуре"?
gomer вне форума  
 
Автор темы   Непрочитано 14.07.2010, 18:49
#27
Lazerus


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


На данный момент мне помогли с кодом.Я смотрю, как он работает. Осталось узнать координаты всех точек из массива, но я не уверен, что этот код сделает то, что мне необходимо. Вобщем, я это сейчас проверяю.
Код:
[Выделить все]
 
#include <axlock.h> // add this header file
 
...
 
AcDbDatabase* pDatabase=new AcDbDatabase(false,false);
 
AcAxDocLock docLock(pDatabase);
 
if ( Acad::eOk != pDatabase->readDwgFile(_T("c:\\Drawing1.dwg") ) ) return;
 
Acad::ErrorStatus es;
 
AcDbEntity * entObj; 
AcDbBlockTable *pBlockTbl;
AcDbBlockTableRecord *pBlockTableRecord;
AcDbBlockTableRecordIterator *pBlockIterator;
pDatabase->getBlockTable(pBlockTbl, AcDb::kForRead);
pBlockTbl->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead);
pBlockTbl->close();
pBlockTableRecord->newIterator(pBlockIterator);
AcGeIntArray osnapModes,geomIds;
AcGePoint3dArray gripPoints; // your 3d points will be here
 
for (; !pBlockIterator->done(); pBlockIterator->step())
{
es = pBlockIterator->getEntity(entObj,AcDb::kForRead);
 
geomIds.removeAll();
 
osnapModes.removeAll();
 
gripPoints.removeAll();
 
ACHAR * myBuf; // your material
entObj->material(myBuf); //... do something with myBuf
AcDbObjectId eId = entObj->materialId(); // material objectId. If you want you can get all data opening material with such objectId
entObj->getGripPoints(gripPoints,osnapModes,geomId​s);
 
entObj->close();
 
/*
so, here you have:
"gripPoints" - it contains all grip points of current entity
"myBuf" - contains name of entity's material. don't forget to use acutDelString to free memory
"eId" - contains ObjectId of material "entity". If you want you can open it and get much more data about material
you may fill your data vector here with variables, described above.
*/
 
acutDelString(myBuf); // don't forget to free memory
 
}
pBlockTableRecord->close();
delete pBlockIterator;
delete pDatabase;
На сколько я понимаю, теперь у меня есть массив grip точек объекта. Кстати, как правильно переводится grip points?

Как оказалось, это не совсе то, что мне нужно. Этот код даёт массив спец точек объекта. Для параллелипипеда - 8 точек ( углы ), для конуса - одна ( вершина ). Поиски продолжаются...

Последний раз редактировалось Lazerus, 15.07.2010 в 08:35.
Lazerus вне форума  
 
Непрочитано 15.07.2010, 12:53
#28
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Каждый из AutoCAD'овских типов примитивов имеет свои характерные точки. Поэтому нужно понимать какие именно типы примитивов должны обрабатываться. Судя по последнему сообщению речь идет о твердых телах (3DSOLID - класс AcDb3dSolid). Для получения геометрии 3DSOLID следует использовать BREP - смотри пример ObjectARX 20XX\utils\brep\
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 17.07.2010, 12:21
#29
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Каждый из AutoCAD'овских типов примитивов имеет свои характерные точки. Поэтому нужно понимать какие именно типы примитивов должны обрабатываться. Судя по последнему сообщению речь идет о твердых телах (3DSOLID - класс AcDb3dSolid). Для получения геометрии 3DSOLID следует использовать BREP - смотри пример ObjectARX 20XX\utils\brep\
Хорошо. Буду разбираться, хоть там и много разных файлов и каждая функция и процедура из них мне в новинку.
Lazerus вне форума  
 
Непрочитано 17.07.2010, 20:45
#30
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


AcBrEntity::getPointContainment должна помочь
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 17.07.2010, 23:27
#31
Lazerus


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


А как тогда пройтись по всем Entity в виде AcBrEntity? Или как можно скопировать AcDbEntity в AcBrEntity?
Lazerus вне форума  
 
Непрочитано 18.07.2010, 01:10
#32
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Используя BREP можно узнать находится ли конкретная точка внутри конкретного твердого тела (AcDb3dSolid). Смотри ObjectARX 20XX\utils\brep\samples\brepsamp\brptcnt.cpp, функцию pointContainment. Она использует метод AcBrEntity::getPointContainment для получения этой информации.
Для всех AcDbEntity это не работает - только для AcDb3dSolid и AcDbRegion
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 18.07.2010, 11:32
#33
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Используя BREP можно узнать находится ли конкретная точка внутри конкретного твердого тела (AcDb3dSolid). Смотри ObjectARX 20XX\utils\brep\samples\brepsamp\brptcnt.cpp, функцию pointContainment. Она использует метод AcBrEntity::getPointContainment для получения этой информации.
Для всех AcDbEntity это не работает - только для AcDb3dSolid и AcDbRegion
Вы не поняли вопрос. Как мне пройтись по всем элементам DWG файла, чтобы запустить pointContainment для каждого элемента?
Lazerus вне форума  
 
Непрочитано 18.07.2010, 12:57
#34
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Вы не поняли вопрос.
Вопрос я как раз понял. Как пройтись по всем элементам чертежа у тебя (более-менее) есть в http://forum.dwg.ru/showpost.php?p=597586&postcount=27
А как получить AcBrEntity из AcDbEntity можно глянуть здесь: http://www.caduser.ru/forum/index.ph...#message125793
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 18.07.2010, 13:54
#35
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Вопрос я как раз понял. Как пройтись по всем элементам чертежа у тебя (более-менее) есть в http://forum.dwg.ru/showpost.php?p=597586&postcount=27
А как получить AcBrEntity из AcDbEntity можно глянуть здесь: http://www.caduser.ru/forum/index.ph...#message125793
Спасибо! Такой вопрос, этот метод внутренних точек подойдёт для фигур нестандартной формы? Если нет, то какой способ подойдёт?
Lazerus вне форума  
 
Непрочитано 18.07.2010, 16:42
#36
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Такой вопрос, этот метод внутренних точек подойдёт для фигур нестандартной формы?
Этот метод должен работать для любых 3DSOLID.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 18.07.2010, 23:13
#37
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Вопрос я как раз понял. Как пройтись по всем элементам чертежа у тебя (более-менее) есть в http://forum.dwg.ru/showpost.php?p=597586&postcount=27
А как получить AcBrEntity из AcDbEntity можно глянуть здесь: http://www.caduser.ru/forum/index.ph...#message125793
Не получается получить AcBrEntity. Выдаёт ошибки.

Код:
[Выделить все]
AcBr::ErrorStatus ebr;
ads_name en;
ads_point pt;
AcDbObjectPointer <AcDbCurve> pline(entObj->objectId(),AcDb::kForRead) ;
AcDbVoidPtrArray ar, regions;
ar.append(pline.object());
AcDbRegion reg; 
reg.copyFrom((AcDbRegion *)regions[0]);
for (int i=0; i<regions.length();i++) 
	delete regions[i];
AcBrBrep brEnt;
ebr = brEnt.set(reg);
Lazerus вне форума  
 
Непрочитано 18.07.2010, 23:46
#38
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Извини, но я дал уже такое количество подсказок и ссылок, что можно было бы уже самостоятельно решить поставленную задачу.
В коде написана полная ерунда - какой-то бессвязный набор.
Александр Ривилис вне форума  
 
Непрочитано 19.07.2010, 15:08
#39
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Цитата:
В коде написана полная ерунда - какой-то бессвязный набор.
А ничего другого и быть не может. См. пост №19. Человек первый раз видит автокад и, тем более, ObjectARX.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Автор темы   Непрочитано 19.07.2010, 17:15
#40
Lazerus


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


Думаю, что этот код должен выполняться, но выдаёт ошибку:
Код:
[Выделить все]
AcDbEntity *entObj;
//Далее доступ ко всем Entity по уже известному алгоритму.
AcBrEntity *pEnt;
((AcBrBrep*)pEnt)->set((const AcDbEntity&)*entObj);




На данный момент вот, что вышло:
Код:
[Выделить все]
AcBrEntity* pBrEnt = new AcBrBrep();
AcDbObjectIdArray objIdList;
AcDb::SubentType subType = AcDb::kNullSubentType;
AcDbFullSubentPath subPath;
AcDb3dSolid* pSolid = NULL;
AcBr::ErrorStatus returnValue = AcBr::eOk;
objIdList.append(entObj->objectId());
if ((pSolid = AcDb3dSolid::cast(entObj)) != NULL) 
{
subPath = kNullSubent;
subPath.objectIds() = objIdList;
} 
returnValue = ((AcBrBrep*)pBrEnt)->set(subPath);
if (returnValue != AcBr::eOk) 
{
acutPrintf(ACRX_T("\n Error in AcBrEntity::set:"));
acutPrintf(ACRX_T(" AutoCAD Error Code: %d\n"), returnValue);
delete pBrEnt;
//return false;
}

Класс тёмного объекта AcDbSubDMesh, он был солидом, но я сгладил его. Если пытаюсь вбить его в pBrEnt возникает ошибка.

Последний раз редактировалось Lazerus, 19.07.2010 в 17:38.
Lazerus вне форума  
 
Непрочитано 19.07.2010, 18:21
#41
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Думаю, что этот код должен выполняться, но выдаёт ошибку:
Не должен. Кто память под pEnt выделять будет?
Должно быть как минимум:
Код:
[Выделить все]
AcBrEntity *pEnt = new AcBrep();
Цитата:
Сообщение от Lazerus Посмотреть сообщение
Класс тёмного объекта AcDbSubDMesh, он был солидом, но я сгладил его. Если пытаюсь вбить его в pBrEnt возникает ошибка.
Ну это и понятно, т.к. я уже несколько раз писал, что только AcDb3dSolid, AcDbRegion и AcDbBody можно "подсовывать" BREP.
С AcDbSubDMesh я не работал, но заметил что у него есть метод AcDbSubDMesh::convertToSolid. Так что получи сначала AcDb3dSolid, а потом уже натравливай на него BREP.

Последний раз редактировалось Александр Ривилис, 19.07.2010 в 18:30.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 12:23
#42
Lazerus


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


Вот, что я сделал вчера:
Код:
[Выделить все]
        AcBr::ErrorStatus err;
        AcGe::PointContainment ppp;
        AcGePoint3d pt3;
        int countIN  = 0;
        int countOUT = 0;
        int countON  = 0;
        int countERR = 0;
        for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
                {
                    pt3.x = x;
                    pt3.y = y;
                    pt3.z = z;
                    err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
                    switch(ppp)
                    {
                        case AcGe::kOutside   : countOUT++; break;
                        case AcGe::kInside    : countIN++ ; break;
                        case AcGe::kOnBoundary: countON++ ; break;
                        default: countERR++;
                    }
 
                }
 
        acutPrintf(_T("CountIN  = %d\n"),countIN );
        acutPrintf(_T("CountON  = %d\n"),countON );
        acutPrintf(_T("CountOUT = %d\n"),countOUT);
        acutPrintf(_T("CountERR = %d\n"),countERR);
Проблема вот в чём. При задании областей x, y, z вылетает ошибка. Насколько я нопимаю, функция getPointContainment влияет на объект через указатель pBrEnt. Что нужно сделать?
Lazerus вне форума  
 
Непрочитано 20.07.2010, 12:35
#43
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Что нужно сделать?
Для начала изучить C++. Что это такое?
Код:
[Выделить все]
for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
Когда пишешь, что возникает ошибка, будь добр ее приводить полностью.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 12:52
#44
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Для начала изучить C++. Что это такое?
Код:
[Выделить все]
for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 0; z++)
Когда пишешь, что возникает ошибка, будь добр ее приводить полностью.
Если я задам область, скажем, x от 0 до чего-либо, возникает ошибка:
Lazerus вне форума  
 
Непрочитано 20.07.2010, 12:54
#45
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Приведи код полностью. И вставь чертеж (dwg-файл), на котором ставишь эксперименты.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 13:07
#46
Lazerus


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


Цитата:
Сообщение от Александр Ривилис Посмотреть сообщение
Приведи код полностью. И вставь чертеж (dwg-файл), на котором ставишь эксперименты.
В файле brsample.cpp
Код:
[Выделить все]
#include"brsample_pch.h"//precompiled header
#ifdefined(_DEBUG) && !defined(AC_FULL_DEBUG)
#error _DEBUG should not be defined except in internal Adesk debug builds
#endif
#include"rxregsvc.h"
#include"aced.h"
#include"dbsymtb.h"
#include"adslib.h"
#include"dbents.h"
#include"tchar.h"
#include<axlock.h>
#include<dbobjptr.h>
#include<dbSubD.h>
 
 
void
readDwg()
{
    AcDbDatabase* pDatabase=new AcDbDatabase(false,false);
    AcAxDocLock docLock(pDatabase);
    if ( Acad::eOk != pDatabase->readDwgFile(_T("c:\\Drawing1.dwg") ) )
        return;
    Acad::ErrorStatus es;
 
    AcDbEntity *entObj; 
    AcDbBlockTable *pBlockTbl;
    AcDbBlockTableRecord *pBlockTableRecord;
    AcDbBlockTableRecordIterator *pBlockIterator;
    pDatabase->getBlockTable(pBlockTbl, AcDb::kForRead);
    pBlockTbl->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,AcDb::kForRead);
    pBlockTbl->close();
    pBlockTableRecord->newIterator(pBlockIterator);
    AcGeIntArray osnapModes,geomIds;
    AcGePoint3dArray gripPoints; // your 3d points will be here
 
    for (; !pBlockIterator->done(); pBlockIterator->step())
    {
        es = pBlockIterator->getEntity(entObj,AcDb::kForRead);
        geomIds.removeAll();
        osnapModes.removeAll();
        gripPoints.removeAll();
        entObj->getGripPoints(gripPoints,osnapModes,geomIds);
 
        AcBrEntity* pBrEnt = new AcBrBrep();
        AcDbObjectIdArray objIdList;
        AcDb::SubentType subType = AcDb::kNullSubentType;
        AcDbFullSubentPath subPath;
        AcDb3dSolid  *pSolid = NULL;
        AcDbSubDMesh *sSolid = NULL;
        AcBr::ErrorStatus returnValue = AcBr::eOk;
        objIdList.append(entObj->objectId());
        if ((pSolid = AcDb3dSolid::cast(entObj)) != NULL) 
        {
            subPath = kNullSubent;
            subPath.objectIds() = objIdList;
        }
        else
            if ((sSolid = AcDbSubDMesh::cast(entObj)) != NULL) 
            {
                subPath = kNullSubent;
                subPath.objectIds() = objIdList;
                sSolid->convertToSolid(false,false,pSolid);
            }
        returnValue = ((AcBrBrep*)pBrEnt)->set((const AcDbEntity&)*pSolid);
        if (returnValue != AcBr::eOk) 
        {
            acutPrintf(ACRX_T("\n Error in AcBrEntity::set:"));
            acutPrintf(ACRX_T(" AutoCAD Error Code: %d\n"), returnValue);
            delete pBrEnt;
            //return false;
        }
 
        AcBr::ErrorStatus err;
        AcGe::PointContainment ppp;
        AcGePoint3d pt3;
        int countIN  = 0;
        int countOUT = 0;
        int countON  = 0;
        int countERR = 0;
        for (int x = 0; x <= 0; x++)
            for (int y = 0; y <= 0; y++)
                for (int z = 0; z <= 1; z++)
                {
                    pt3.x = x;
                    pt3.y = y;
                    pt3.z = z;
                    err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
                    switch(ppp)
                    {
                        case AcGe::kOutside   : countOUT++; break;
                        case AcGe::kInside    : countIN++ ; break;
                        case AcGe::kOnBoundary: countON++ ; break;
                        default: countERR++;
                    }
 
                }
 
        acutPrintf(_T("CountIN  = %d\n"),countIN );
        acutPrintf(_T("CountON  = %d\n"),countON );
        acutPrintf(_T("CountOUT = %d\n"),countOUT);
        acutPrintf(_T("CountERR = %d\n"),countERR);
 
        acutPrintf(_T("classname: %s\n"),
            (entObj->isA())->name());
        acutPrintf(_T("END\n"));
        entObj->close();
    }
    pBlockTableRecord->close();
    delete pBlockIterator;
    delete pDatabase;
}
Вложения
Тип файла: dwg
DWG 2010
Drawing1.dwg (413.7 Кб, 864 просмотров)

Последний раз редактировалось Lazerus, 20.07.2010 в 13:19.
Lazerus вне форума  
 
Непрочитано 20.07.2010, 14:19
#47
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Замени
Код:
[Выделить все]
err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,pBrEnt);
на
Код:
[Выделить все]
AcBrEntity* container = NULL;
err = ((AcBrBrep*)pBrEnt)->getPointContainment(pt3,ppp,container);
И попробуй это:
Код:
[Выделить все]
  static void TestBrepTESTBREP(void)
  {
    ads_name en; ads_point p;
    if (acedEntSel(L"\nВыберите 3DSOLID: ", en, p) != RTNORM) return;
    AcDbObjectId eId; acdbGetObjectId(eId,en);
    AcDbObjectPointer<AcDb3dSolid> p3dsolid(eId,AcDb::kForRead);
    if (p3dsolid.openStatus() == Acad::eNotThatKindOfClass) {
      acutPrintf(L"\nВыбран не 3DSOLID!!!"); return;
    } else if (p3dsolid.openStatus() != Acad::eOk) {
      acutPrintf(L"\nОшибка AcDbObjectPointer<AcDb3dSolid> p3dsolid(eId,AcDb::kForRead)"); return;
    }
    AcBr::ErrorStatus ebs;
    AcBrBrep* pBrEnt = new AcBrBrep();
    ebs = pBrEnt->set(*(p3dsolid.object()));
    if (ebs != AcBr::eOk) {
      acutPrintf(L"\nОшибка pBrEnt->set(p3dsolid.object()) = %d",ebs);
      delete pBrEnt;
      return;
    }
    AcBrEntity* container = NULL;
    int countIN  = 0, countOUT = 0, countON  = 0, countERR = 0;
    AcGeBoundBlock3d bb; 
    // Получаем габаритный параллелепипед
    ebs = pBrEnt->getBoundBlock(bb); 
    if (ebs != AcBr::eOk) {
      acutPrintf(L"\nОшибка pBrEnt->getBoundBlock(bb) = %d",ebs);
      delete pBrEnt;
      return;
    }
    for (int x = 0; x <= 100; ++x) {
       for (int y = 0; y <= 100; ++y) {     
          for (int z = 0; z <= 100; ++z) {     
            AcGe::PointContainment pc;
            AcGePoint3d p(x,y,z);
            if (bb.contains(p)) {
              ebs = pBrEnt->getPointContainment(p,pc,container);
              if (ebs != AcBr::eOk) {
                ++countERR;
              } else {
                countIN  += (pc == AcGe::kInside);
                countOUT += (pc == AcGe::kOutside);
                countON  += (pc == AcGe::kOnBoundary);
              }
            } else {
              ++countOUT;
            }
          }
       }
    }
    acutPrintf(L"\nCountIN  = %d",countIN );
    acutPrintf(L"\nCountON  = %d",countON );
    acutPrintf(L"\nCountOUT = %d",countOUT);
    acutPrintf(L"\nCountERR = %d",countERR);
    delete pBrEnt;
  }

Последний раз редактировалось Александр Ривилис, 20.07.2010 в 14:56.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 15:14
#48
Lazerus


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


Огромное спасибо! Сейчас тестирую что получается при замене строки на Ваши две.

Чуть позже посмотрю, что делает предложенный Вами код.
Lazerus вне форума  
 
Непрочитано 20.07.2010, 15:30
#49
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
Чуть позже посмотрю, что делает предложенный Вами код.
Главная мысль моего кода - это предварительное получение габаритного параллелепипеда, и проверка в цикле точки на попадание в него. Если точка вне параллелепипеда, то нет смысла проверять getPointContainment, так как точка точно снаружи твердого тела. Операция по проверке находится ли точка внутри габаритного параллелепипеда на несколько порядков быстрее, чем getPointContainment.
Александр Ривилис вне форума  
 
Автор темы   Непрочитано 20.07.2010, 16:33
#50
Lazerus


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


А если фигура является конусом или имеет другую форму?
Lazerus вне форума  
 
Непрочитано 20.07.2010, 16:40
#51
Александр Ривилис

программист, рыцарь ObjectARX
 
Регистрация: 09.05.2005
Киев
Сообщений: 2,413
Отправить сообщение для Александр Ривилис с помощью Skype™


Цитата:
Сообщение от Lazerus Посмотреть сообщение
А если фигура является конусом или имеет другую форму?
Это совершенно неважно. Самое главное, что BoundingBox всегда охватывает объект целиком и поэтому если точка не попадает в BoundingBox, то она гарантировано не попадает в объект. Обратное утверждение неверно.
Александр Ривилис вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > DWG -> Трёхмерная таблица

Опции темы Поиск в этой теме
Поиск в этой теме:

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
формат Corel'a -> dxf или dwg. Как? the_sun Прочее. Программное обеспечение 15 07.02.2013 15:10
Сконвертируйте пожалуйста CDW (версию не знаю) -> DWG 2006 vama Прочее. Программное обеспечение 1 22.10.2009 12:50
Пакетный перегон dxf -> dwg возможно ли ? bdfy AutoCAD 4 15.11.2006 21:41
Хороший конвертер DWG -> JPG solegs AutoCAD 15 09.12.2004 18:24
dwg 2005 -> dwg 2002. нужна программа Torero AutoCAD 5 22.09.2004 14:20