Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: Anton от 29-04-2014, 11:07:17

Название: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 29-04-2014, 11:07:17
Друзья!

Столкнулся с небольшой проблемой при решении одной задачки:
Дано Есть файлы dwg с блоками, эти блоки вставлены в модель с определенными масштабами.
Надо получить масштабы этих вхождений блоков, имена я их знаю. И проделать определенные манипуляции в текущем чертеже на основе этой информации (это я тоже знаю как сделать). Главное прочитать из внешних файлов масштабы блоков.
Задачка усложняется еще и тем, что это многовидовые блоки AutoCAD Architecture.
Мне хотя бы найти образец решения по обычным блокам, а с многовидовыми я как-нибудь по аналогии.
Есть такая хорошая команда - clonehelper, но к сожалению она клонирует только определения блоков, а мне еще надод считать масштабы вхождения экземпляра этого блока в пространстве модели.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 29-04-2014, 11:13:42
BlockReference.ScaleFactors
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 29-04-2014, 11:25:38
Спасибо Андрей!

Еще такой вопросик в продолжении этой темы - я прочитал Database нужного мне внешнего чертежа, достать оттуда определение блока (сам блок) я могу, а вот как достать вхождение этого блока в модель, т.е. его экземпляр - он в моем случае один, который вставлен в чертеж, желательно по имени этого блока? Ну а дальше вроде как понятно как действовать.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 29-04-2014, 11:34:23
BlockTableRecord.GetBlockReferenceIds

Если блок динамический (BlockTableRecord.IsDynamicBlock), то его вхождения, по факту, зачастую будут вхождениями анонимных блоков (имена начинаются со "звёздочки"). Т.о. тебе нужно будет воспользоваться BlockTableRecord.GetAnonymousBlockIds и уже для каждого из них, в свою очередь, проверять BlockTableRecord.GetBlockReferenceIds .
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 29-04-2014, 11:49:55
Блок, многовидовой в терминологии AutoCAD Architecture - MultiViewBlock - состоит из нескольких обычных блоков, которые связаны с видовыми представлениями. Ну типа вид в плане - условное изображение, в 3D - объемное, на разрезе - третье и т.п. Клонировать я их научился. Сейчас вот сижу и разбираюсь почему у меня в BlockTableRecord нет метода GetBlockReferencesIds.
Полное название - Autodesk.AutoCAD.DatabaseServices.BlockTableRecord?
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 29-04-2014, 11:53:43
Полное название - Autodesk.AutoCAD.DatabaseServices.BlockTableRecord?
да
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 29-04-2014, 11:58:42
Цитировать
Сейчас вот сижу и разбираюсь почему у меня в BlockTableRecord нет метода GetBlockReferencesIds
Происки тёмных сил :)

На всякий случай поясняю: это экземплярные методы, а не статические.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 29-04-2014, 12:22:36
Ну да, конечно, затупил немного как-то, отвлекают постоянно, вот и все мысли в кучу сбились, я ее вытаскиваю tr.getObject ну а дальше - дело техники.
В принципе все получилось, прочитал масштаб, осталось только разобраться в идентификации MultiviewBlockReference по стилю DictionaryMultiViewBlockDefinition. Как вернусь выложу сюда код того, чего получилось, может кому и пригодится.
Код - C# [Выбрать]
  1.         public Scale3d getMVBScale(string MVBblockName)
  2.         {
  3.             Scale3d RetValue = new Scale3d();
  4.            
  5.             if (SourceDirectoryDWGPath == null)
  6.             {
  7.                 // Source path empty
  8.  
  9.                 return RetValue;
  10.             }
  11.             try
  12.             {
  13.                 // Путь к файлу
  14.                 string SourcePath = SourceDirectoryDWGPath + "\\" + MVBblockName + ".DWG";
  15.                 Autodesk.AutoCAD.DatabaseServices.Database dbSource = new Database(false, true);
  16.                 dbSource.ReadDwgFile(SourcePath, System.IO.FileShare.Read, true, "");
  17.                 Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = dbSource.TransactionManager;
  18.                 Transaction t = tm.StartTransaction();
  19.                 BlockTable bt = tm.GetObject(dbSource.BlockTableId, OpenMode.ForRead, false) as BlockTable;
  20.                 BlockTableRecord btr = tm.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite, false) as BlockTableRecord;
  21.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId id in btr)
  22.                 {
  23.                     try
  24.                     {
  25.                         Entity ent1 = tm.GetObject(id, OpenMode.ForRead) as Entity;
  26.                         string entType = ent1.GetType().ToString();
  27.  
  28.                         if(entType == "Autodesk.Aec.DatabaseServices.MultiViewBlockReference")
  29.                         {
  30.                             MultiViewBlockReference MVBRef = tm.GetObject(id, OpenMode.ForRead) as MultiViewBlockReference;
  31.                             RetValue = MVBRef.Scale;
  32.                         }
  33.                     }
  34.                     catch (Autodesk.AutoCAD.Runtime.Exception ex)
  35.                     {
  36.                         MessageBox.Show("Ошибка" + ex.Message);
  37.                     }
  38.                 }
  39.  
  40.                 t.Commit();
  41.                
  42.             }
  43.             catch (Autodesk.AutoCAD.Runtime.Exception ex)
  44.             {
  45.                 MessageBox.Show("Ошибка" + ex.Message);
  46.                 return RetValue;
  47.             }
  48.  
  49.             return RetValue;
  50.         }
  51.  
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Александр Ривилис от 29-04-2014, 18:17:24
А если вместо:
Код - C# [Выбрать]
  1. Entity ent1 = tm.GetObject(id, OpenMode.ForRead) as Entity;
  2. string entType = ent1.GetType().ToString();
  3.  
  4. if(entType == "Autodesk.Aec.DatabaseServices.MultiViewBlockReference")
  5. {
  6.     MultiViewBlockReference MVBRef = tm.GetObject(id, OpenMode.ForRead) as MultiViewBlockReference;
  7.     RetValue = MVBRef.Scale;
  8. }
  9.  
написать:
Код - C# [Выбрать]
  1. MultiViewBlockReference MVBRef = tm.GetObject(id, OpenMode.ForRead) as MultiViewBlockReference;
  2. if(MVBRef != null) RetValue = MVBRef.Scale;
  3.  
то будет и красивее и правильнее (ты дважды открываешь один и тот же примитив).

А еще я не увидел t.Dispose();
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 29-04-2014, 19:09:22
AutoCAD 2014 С таким кодом падает.
Код - C# [Выбрать]
  1. MultiViewBlockReference MVBRef = tm.GetObject(id, OpenMode.ForRead) as MultiViewBlockReference;
  2. if(MVBRef != null) RetValue = MVBRef.Scale;
  3.  
Вот и пришлось извращаться. Про t.Dispose(); забыл, спасибо за подсказку.

Единственное, что у меня пока не получается это Jigging с уже заданным масштабом MVBlock'а. В этой теме http://adn-cis.org/forum/index.php?topic=274.0 (http://adn-cis.org/forum/index.php?topic=274.0) я нашел как сделать Jig, только не могу понять как сделать его сразу же с заданным масштабом. Чтобы он уже масштабированным таскался за курсором перед вставкой.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Александр Ривилис от 30-04-2014, 01:05:14
AutoCAD 2014 С таким кодом падает.
Так быть не должно. Как падает? Какие сообщения?
По второму вопросу в той теме.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 30-04-2014, 12:48:51
Падало из-за отсутствия в цикле t.Commit(); теперь не падает. В процессе "извращения кода" по всей видимости я просто добавил t.Commit() и падать перестало. А мне почему-то показалось что падало из-за другого.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 30-04-2014, 12:50:53
Падало из-за отсутствия в цикле t.Commit();
Сомневаюсь. В этом случае происходит откат транзакции.
Цитировать
В процессе "извращения кода"
Скорее всего ты внёс исправление в ходе этого процесса.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Александр Ривилис от 30-04-2014, 13:03:57
Андрей Бушман.
Думаю, что Антон ошибся и имел в виду отсутствие t.Dispose(), а не t.Commit()
Впрочем возможно еще что-то...
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 30-04-2014, 13:13:18
да конечно t.Dispose(), транзакция откатывается если нет t.Commit, просто отвлекают постоянно, вот и мешается все в голове.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 30-04-2014, 13:25:52
да конечно t.Dispose()
Дабы не наступать на подобные грабли, лучше выполнять инициализацию в блоке using. В этом случае Dispose будет вызван даже в случае возникновения необработанного исключения (чего как раз и не случится в обозначенном выше коде).
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 30-04-2014, 13:30:06
Цитировать
Падало из-за отсутствия в цикле t.Commit(); теперь не падает.
Кстати, Commit можно вызывать только один раз. Если мне не изменяет память, то последующие вызовы приводят к Fatal Error или др. неприятным моментам.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 30-04-2014, 13:35:50
Спасибо за помощь и советы, исправил инициализацию на using. Скорее всего вылетало тогда из-за цикла и из-за commit в одном месте, а в другом из-за отсутствия dispose. В общем все причесал, все теперь не падает и выглядит нормально.
Почитал еще статьи на этом сайте, в частности статья про типовые ошибки при использовании транзакций помогла причесать код, как следует и позволила избежать некоторых потенциальных ошибок.
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Андрей Бушман от 30-04-2014, 13:39:50
в частности статья про типовые ошибки при использовании транзакций помогла причесать код, как следует и позволила избежать некоторых потенциальных ошибок.
возможно будет интересно:
тынц 1 (http://bushman-andrey.blogspot.ru/2013/01/database-autocad.html)
тынц 2 (http://bushman-andrey.blogspot.ru/2014/03/autocad-net-api-idisposable.html)
Название: Re: Получить масштаб Block refernces из другого файла
Отправлено: Anton от 30-04-2014, 19:37:05
Очень полезные статьи и полезный блог!
Спасибо Александр и Андрей за Ваш труд.