Перебор всех объектов

Автор Тема: Перебор всех объектов  (Прочитано 11606 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Перебор всех объектов
« : 10-10-2018, 14:28:44 »
Добрый день!

выполняю перебор всех объектов чертежа. в чертеже есть внешние ссылки.
когда она проверяется и натыкается на эту строчку
Код - C# [Выбрать]
  1. if (myTransaction.GetObject(objId, OpenMode.ForWrite) is MText mt)
выскакивает ошибка
видимо потому что ее нельзя получить внешнюю ссылку для записи. получать два раза как то не хочется: для проверки а потом для изменения
как быть?
Спасибо

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #1 : 10-10-2018, 14:51:56 »
Открывать все подряд объекты на запись - плохая практика. Если есть сомнения, что объект надо будет редактировать, то открывайте на чтение. А прямо перед модификацией вызывайте UpgradeOpen

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #2 : 10-10-2018, 14:53:51 »
ну да логично.
Спасибо.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #3 : 10-10-2018, 15:01:32 »
а если мне нужно изменить атрибут блока?
правильно я делаю, что блок открываю для чтения, а атрибут для записи?

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #4 : 10-10-2018, 15:02:42 »
да

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #5 : 10-10-2018, 15:10:18 »
Спасибо большое!

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #6 : 10-10-2018, 15:28:36 »
simson43, если я правильно понял, то Ваш код проверяет, методом открытия и приведения объекта, является ли он MText
Попробуйте использовать вот этот код:
Код - C# [Выбрать]
  1. if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
он не открывает объект (если я правильно помню) и работает несколько быстрей, да и транзакция не нужна...

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #7 : 10-10-2018, 15:59:57 »
Владимир Шу, cудя по тому что оператор is объявляет переменную mt - я бы предположил, что она где-то дальше используется. Вот если не используется, тогда да - однозначно надо проверять тип объекта по ObjectId.

Отмечено как Решение simson43 10-10-2018, 20:27:50

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #8 : 10-10-2018, 16:12:05 »
avc, конечно используется, иначе какой смысл создавать эту перемененную.
Я просто имел ввиду, что более правильно сначала определить класс объекта, а потом, если он подходит, его открывать...
Код - C# [Выбрать]
  1. if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
  2. {
  3.   MText mt = myTransaction.GetObject(objId, OpenMode.ForWrite) as MText;
  4.   //и далее какой-то код
  5.  }

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #9 : 10-10-2018, 18:44:38 »
Открывать все подряд объекты на запись - плохая практика. Если есть сомнения, что объект надо будет редактировать, то открывайте на чтение. А прямо перед модификацией вызывайте UpgradeOpen
Всё так, кроме того, что вместо UpgradeOpen нужно снова вызвать повторно Transaction.GetObject(...), но с OpenMode.ForWrite. UpgradeOpen - это для Open/Close (или OpenCloseTransaction) и может конфликтовать с обычной транзакцией.
« Последнее редактирование: 10-10-2018, 19:45:42 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #10 : 10-10-2018, 18:54:47 »
моджет конфликтовать с обычной транзакцией
Да что вы?! Точно? Я всегда так делаю и в куче примеров видел и у объекта IsWriteEnabled становится true... Неужели я столько лет косячил... шок...

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #11 : 10-10-2018, 19:00:06 »
Полез на блог Kean Walmsley - во всех примерах он берет объекты через транзакции, и потом вызывает UpgradeOpen. Вот от него я и набрался. Вот например тут http://www.keanw.com/2010/01/creating-an-autocad-block-using-net.html
Код - C# [Выбрать]
  1. BlockTable bt =
  2.           (BlockTable)tr.GetObject(
  3.             db.BlockTableId,
  4.             OpenMode.ForRead
  5.           );

и следом

Код - C# [Выбрать]
  1.         bt.UpgradeOpen();
  2.         ObjectId btrId = bt.Add(btr);
  3.         tr.AddNewlyCreatedDBObject(btr, true);

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #12 : 10-10-2018, 19:35:24 »
моджет конфликтовать с обычной транзакцией
Да что вы?! Точно? Я всегда так делаю и в куче примеров видел и у объекта IsWriteEnabled становится true... Неужели я столько лет косячил... шок...
Ты был не один. И я тоже такие примеры приводил с использованием UpgradeOpen. Но один старший товарищ (Art Cooney - один из руководителей разработки AutoCAD) объяснил мне, что я не прав. Это вылезло в одном из обновлений AutoCAD 2018. Тут подробности: https://forums.autodesk.com/t5/net/api-bug-2018-1-causes-crash-using-upgradeopen-on-dependent/m-p/7272262/highlight/true#M54471
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #13 : 10-10-2018, 20:13:15 »
т е или заменить обычную транзакция на openclosetransaction или еще раз получать объект для записи?

а как же вот с оф сайта пример?
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-CC5CC229-B122-4897-A8DA-5C5ADADB0F38-htm.html?_ga=2.51307242.2126543432.1539105496-1602586928.1535484681

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #14 : 10-10-2018, 20:21:18 »
т е или заменить обычную транзакция на openclosetransaction или еще раз получать объект для записи?
Менять ничего не надо. Просто вместо UpgradeOpen вызываешь снова myTransaction.GetObject, но уже с OpenMode.ForWrite.

а как же вот с оф сайта пример?
https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2015/ENU/AutoCAD-NET/files/GUID-CC5CC229-B122-4897-A8DA-5C5ADADB0F38-htm.html?_ga=2.51307242.2126543432.1539105496-1602586928.1535484681
Он ошибочен. И по той ссылке, которую я дал выше, это обсуждается.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #15 : 10-10-2018, 20:23:05 »
а openclosetransaction чем хуже?
или вначале предложенный способ проверки типа объекта не открывая его?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #16 : 10-10-2018, 20:25:45 »
а openclosetransaction чем хуже?
Ничем не хуже. Он просто другой и требует большей внимательности от программиста.
или вначале предложенный способ проверки типа объекта не открывая его?
В данном случае это вообще идеальный вариант, если пишешь под AutoCAD не старее 2009-го. В AutoCAD 2008 такого метода не было.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #17 : 10-10-2018, 20:27:34 »
Значит отмечаю его как правильный.
Всем спасибо! в этот раз не я один узнал что-то новое)

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #18 : 10-10-2018, 21:25:50 »
Он ошибочен. И по той ссылке, которую я дал выше, это обсуждается.
Вот же ж.. Только что перелопатил весь код, убирал TopTransaction, а на завтра опять тотальный рефакторинг - убирать UpgradeOpen... 

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #19 : 10-10-2018, 22:07:57 »
а с toptransaction что?

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #20 : 10-10-2018, 22:23:54 »
а с toptransaction что?
А я внезапно понял, что toptransaction  - это вовсе не обязательно МОЯ последняя транзакция. Мы ж в многопоточной среде! И регулярные сбои Автокада на диспозе объектов запросто могут быть из-за путаницы в транзакциях. Экономил на копейках (лишние параметры у методов не красивыми считал, раз тарнзакцию можно вроде как и не передавать), а проиграл сурово: переписывал горы кода - где транзакция длинная - заводил отдельную, где мелочевка - передаю теперь свыше в параметрах или полях классов.

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #21 : 10-10-2018, 22:26:19 »
недавно как раз впервые встал перед выбором передать или вложить транзакцию - счел слишком сложным вкладывать. передавать как то приятнее мне показалось)

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #22 : 10-10-2018, 22:53:16 »
if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
{
  MText mt = myTransaction.GetObject(objId, OpenMode.ForWrite) as MText;
  //и далее какой-то код
 }
а есть ли разница между IsDerivedFrom, Equals и, например, == в данном случае?

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #23 : 10-10-2018, 23:09:59 »
а есть ли разница между IsDerivedFrom, Equals и, например, == в данном случае?
IsDerivedFrom - это сам класс (в данном случае MText) и его наследники. В самом AutoCAD наследников для MText нет, но теоретически можно создать Custom Entity унаследованный от AcDbMText и для него создать .NET-обертку - наследник от MText (с именем например MyMText). Ну и тогда возникнет вопрос - обрабатывать только MText или MyMText тоже. Равенство вернет только MText, а IsDerivedFrom - оба класса.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #24 : 10-10-2018, 23:23:54 »
последние два одинаковы? или есть разница в их работе?
IsDerivedFrom, Equals и, например, ==

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #25 : 10-10-2018, 23:27:59 »
последние два одинаковы? или есть разница в их работе?
IsDerivedFrom, Equals и, например, ==

Надо смотреть внутрь класса RXClass. Но я бы наверное (для точного сравнения) сравнивал бы на равенство строки objId.ObjectClass.Name и RXObject.GetClass(typeof(MText)).Name
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #26 : 10-10-2018, 23:31:48 »
Даже так..
Хорошо, спасибо!

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Перебор всех объектов
« Ответ #27 : 12-10-2018, 23:23:31 »
Вот же ж.. Только что перелопатил весь код, убирал TopTransaction, а на завтра опять тотальный рефакторинг - убирать UpgradeOpen...
На очереди ещё один рефакторинг - отказ от транзакций в пользу ObjectId.Open  8)

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #28 : 12-10-2018, 23:58:08 »
На очереди ещё один рефакторинг - отказ от транзакций в пользу ObjectId.Open  8)
В ForRead - однозначно. А вот с ForWrite я бы сначала потестировал. Насколько я помню транзакции (я про обычные) для ForWrite лучше (быстрее).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #29 : 13-10-2018, 11:18:19 »
отказ от транзакций в пользу ObjectId.Open
Ни-ни. Моя СУБДшная натура категорически против отказа от транзакций, там где они возможны. А слухи, про их тормознутость сильно преувеличены. Я проверял. :)

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Перебор всех объектов
« Ответ #30 : 13-10-2018, 15:38:54 »
Моя СУБДшная натура категорически против отказа от транзакций, там где они возможны.
Я так понимаю, что это не те транзакции, что в СУБД. Общее у них только название. А по факту, получился инструмент, который на начальных этапах освоения API сильно упрощает жизнь, а в дальнейшем - может её сильно испортить.
где транзакция длинная - заводил отдельную, где мелочевка - передаю теперь свыше в параметрах или полях классов.
В том-то и дело. Я так понимаю, что есть некоторые вспомогательные методы, которые выполняют обработку переданных данных. Пока они вызываются из командных методов, всё работает вроде как надо. Но впоследствии эти же методы возможно понадобится вызывать из различных событий, из методов Overrule и тд и тп, то есть, в тех случаях, когда транзакция может испортить работу AutoCAD, приводя к Fatal Error. Отлавливание таких ошибок - очень непростое дело.
Я для себя пришёл к такому решению: если пишется "библиотечный" метод, лучше, чтобы в нём не было транзакций. Либо передаю уже открытый объект(на чтение, на запись), либо открываю внутри метода объект с помощью ObjectId.Open или OpenCloseTransaction.GetObject.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #31 : 13-10-2018, 16:31:01 »
это не те транзакции, что в СУБД
Почему же не те - принцип как раз тот: изоляция изменений до коммита транзакции, откат всех изменений целиком. На ранних этапах (да и теперь) они конечно сильно УСЛОЖНЯЮТ жизнь, удлиняют код. В сравнении со всякими VBA. Но повышают дуракоустойчивость кода. В обработчиках событий транзакции у меня живут прекрасно и им там самое место. ИМХО. Нельзя сказать наверняка, но похоже больше фаталов от смешивания подходов - часть методов безтранзакционные, часть используют toptransaction не явно и влетают на чужие транзакции, которые внезапно комитятся, а открытые объекты остаются в вашем коде... и гуд-бай Автокад... API позволяет намешать такой винегрет, что мама не горюй. А примеры, понадерганные из форумов, этому только способствуют. И, как тут только что выяснилось, примеры с принципиальными ошибками пишут даже гуру. 

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Перебор всех объектов
« Ответ #32 : 13-10-2018, 17:14:34 »
Как один из недавних примеров: http://adn-cis.org/forum/index.php?topic=7829.0
Цитировать
Казалось бы, никакой проблемы - используем транзакцию и радуемся. Но! При обработке больших чертежей, в какой-то случайный момент вываливается исключение System.AccessViolationException без указания места, в котором это исключение возникло. Без транзакции исключений не возникает
Если поискать по форуму, можно найти ещё несколько тем, где обсуждается необходимость отказа от транзакций в определённых случаях.

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #33 : 13-10-2018, 17:27:48 »
Вроде как раз примеры того, как не надо смешивать транзакции и доступ к БД без транзакций. К тем же записям! Уж если где-то получаете объекты без транзакций, то делайте так везде и будет все хорошо. Если, конечно, справитесь с тем, чтоб все вовремя даунгрейдить и диспозить. Другое дело, что никто так не делает, у всех в коде каша. Тотально у всех, у меня тоже. А потом делается вывод, что это транзакции виноваты. Не верю! Если б MS SQL такое позволял, он бы тоже падал когда попало как Автокад.

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 735
Re: Перебор всех объектов
« Ответ #34 : 13-10-2018, 17:32:19 »
Не верю!
Ну ок. Я поделился своим опытом. Перенимать его или нет - дело хозяйское.  ;)

Оффлайн avc

  • ADN Club
  • *****
  • Сообщений: 805
  • Карма: 166
    • Мои плагины к Автокаду
Re: Перебор всех объектов
« Ответ #35 : 13-10-2018, 17:33:52 »
Не могу не согласиться. Случаи бывают разные. А истина всегда ускользает. Продолжаем оптимизировать код.... Каждый по своему....

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #36 : 13-10-2018, 22:01:40 »
Попробуйте использовать вот этот код:
Код - C# [Выбрать]
if (objId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(MText))))
Проблема!
внешняя ссылка для него это блок и он залазит в нее (если я ищу блоки).

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #37 : 14-10-2018, 02:06:56 »
Проблема!
внешняя ссылка для него это блок и он залазит в нее (если я ищу блоки).
Кто куда залазит???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #38 : 14-10-2018, 08:43:21 »
Проблема!
внешняя ссылка для него это блок и он залазит в нее (если я ищу блоки).
Почему проблема? Внешняя ссылка и есть блок, внутри автокада очень многое можно привести к блоку (таблицы, размеры, выноски и т.д.).
Если Вам не нужны XRef, то и фильтруйте их: BlockTableRecord.IsFromExternalReference

Все еще не понимаю где проблема...

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #39 : 14-10-2018, 08:57:47 »
Я просто не знал что так много всего подходит под определение блока. Придется фильтровать все что не нужно.
Спасибо

Оффлайн simson43Автор темы

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Перебор всех объектов
« Ответ #40 : 14-10-2018, 12:24:04 »
Если Вам не нужны XRef, то и фильтруйте их: BlockTableRecord.IsFromExternalReference
т е для проверки придется открыть блок через транзакцию и дополнительно получать так же через транзакцию BlockTableRecord полученного блока?
« Последнее редактирование: 14-10-2018, 14:25:15 от simson43 »

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #41 : 14-10-2018, 16:44:06 »
Если Вам не нужны XRef, то и фильтруйте их: BlockTableRecord.IsFromExternalReference
т е для проверки придется открыть блок через транзакцию и дополнительно получать так же через транзакцию BlockTableRecord полученного блока?
Угу.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Владимир Шу

  • ADN Club
  • *****
  • Сообщений: 611
  • Карма: 155
    • ПГСу Бложик
Re: Перебор всех объектов
« Ответ #42 : 15-10-2018, 07:41:06 »
т е для проверки придется открыть блок через транзакцию и дополнительно получать так же через транзакцию BlockTableRecord полученного блока?
Можно и так, но ИМХО, проще написать метод расширения для ObjectId и проверять сразу в условии.

Что то вроде:
Код - C# [Выбрать]
  1.     public static class BlockReferenceHelper
  2.     {
  3.         public static bool IsXRef(this Db.ObjectId id)
  4.         {
  5.             bool ret = false;
  6.             if (id.ObjectClass.IsDerivedFrom(Rtm.RXClass.GetClass(typeof(Db.BlockReference))))
  7.             {
  8.                 Db.BlockReference br = id.Open(Db.OpenMode.ForRead) as Db.BlockReference;
  9.                 Db.BlockTableRecord btr = br.BlockTableRecord.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord;
  10.                 ret = btr.IsFromExternalReference;
  11.  
  12.                 br.Close();
  13.                 br.Dispose();
  14.  
  15.                 btr.Close();
  16.                 btr.Dispose();
  17.             }
  18.             return ret;
  19.         }
  20.     }

И далее уже в своем коде:
Код - C# [Выбрать]
  1. if (Id.IsXRef())
  2. {
  3.  // тут какой то свой код
  4. }

PS.
За код, особо сильно не пинайте, "чукча не писатель, чукча читатель"

Оффлайн Александр Ривилис

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Перебор всех объектов
« Ответ #43 : 17-10-2018, 17:04:18 »
PS.
За код, особо сильно не пинайте, "чукча не писатель, чукча читатель"
Всё-таки слегка "пну" по поводу Close и Dispose. Если !ObjectId.IsNull (а это наш случай), то Dispose вызывает Close. Так что вызывать и Close и Dispose не следует. Если ObjectId.IsNull то Close вызвать нельзя.
Лучше всего в этом коде использовать using:
Код - C# [Выбрать]
  1. using (Db.BlockReference br = id.Open(Db.OpenMode.ForRead) as Db.BlockReference)
  2. using (Db.BlockTableRecord btr = br.BlockTableRecord.Open(Db.OpenMode.ForRead) as Db.BlockTableRecord)
  3. {
  4.     ret = btr.IsFromExternalReference;
  5. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение