Изменить файл не открывая AutoCAD

Автор Тема: Изменить файл не открывая AutoCAD  (Прочитано 10447 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Всем доброго времени суток.
Мне достался файл с множеством динамических блоков с двумя линейными параметрами и 4-мя атрибутами.
Вобщем, блоки несложные, но что с ними не знаю:
при непрограммном (руками) изменении какого -либо динамического параметра AutoCAD тормозит ужасно и часто fatal error выскакивает даже если всего 50 блоков изменяешь.

Моя задача, грубо говоря, поменять все блоки с длиной  равной 500 на длину равную 400.
Мысль сделать это программно не открывая AutoCAD.
Это возможно?
Сам код, думаю, я смогу написать, но как получить документ?
то есть что написать вместо строчки:
Код - C# [Выбрать]
  1. Document doc = AcadApp.DocumentManager.MdiActiveDocument;
???

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #1 : 21-09-2017, 15:12:11 »
Мысль сделать это программно не открывая AutoCAD.
Это как? Вообще не запуская AutoCAD? Тогда или accoreconsole.exe (это бесплатно) или RealDWG (это платно и стоит очень прилично).
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #2 : 21-09-2017, 15:17:50 »
Или имеется в виду не загружая чертеж в редактор AutoCAD? Тогда можно через Database.ReadDwgFile(...)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #3 : 21-09-2017, 15:23:08 »
Да, AutoCAD на компьютере установлен, если Вы об этом, но не нужно его запускать.
А Database.ReadDwgFile(...) - это
Код - C# [Выбрать]
  1. Document doc = Database.ReadDwgFile(filePath);
где filePath - путь к файлу?


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #4 : 21-09-2017, 15:45:30 »
Да, AutoCAD на компьютере установлен, если Вы об этом, но не нужно его запускать.
Без запуска AutoCAD у тебя ничего не получится.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Serg34 22-09-2017, 10:51:10

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #5 : 21-09-2017, 15:54:47 »
А Database.ReadDwgFile(...) - это
Код - C# [Выбрать]

    Document doc = Database.ReadDwgFile(filePath);

где filePath - путь к файлу?

Это бред. Пример использования Database.ReadDwgFile: http://adn-cis.org/izmenenie-putej-k-vneshnim-ssyilkam-iz-absolyutnyix-v-otnositelnyie.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #6 : 21-09-2017, 16:21:57 »
Спасибо, дома попробую!

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #7 : 22-09-2017, 11:05:33 »
Все работает, но тут следующая проблема:
при изменении длины блока штриховка не меняет габарита и вылезает за габариты блока

При открытом файле все нормально проходит, хотя код, вроде, такой же за одним исключением:
Для закрытого файла я убрал строчку: ed.Regen();
Код могу привести, но он у меня по разным классам разнесен.
Может, без моего кода сможете подсказать в чем может быть дело?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #8 : 22-09-2017, 11:24:52 »
1. Не все, что можно сделать с файлом в редакторе AutoCAD можно сделать без редактора (т.е. имея Document)
2. Попробуйте переключить рабочую базу на ту, что редактируете, а по окончании редактирования верните назад. Иногда такое помогает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #9 : 22-09-2017, 11:47:02 »
Не совсем пойму.
Вот код (на всякий случай поясню, это метод-итератор, который принимает метод-обработчик в качестве аргумента и при выполнении условий применяет этот метод-обработчик к блоку):
Код - C# [Выбрать]
  1. private static void AccessGlobalFromFile(
  2.         GlobalBlocksAccessor action, // метод обработки блока
  3.         string blockName = "",
  4.         string autoCADFilePath = "",
  5.         bool manyblocks = true,
  6.         bool dynamicOnly = false,
  7.         bool attributesAndParametrsMust = false)
  8. {
  9.         Document doc = Application.DocumentManager.MdiActiveDocument;
  10.         if (doc == null) return;
  11.  
  12.         Editor ed = doc.Editor;
  13.         using (Database db = new Database(false, true))
  14.         {
  15.                 db.ReadDwgFile(autoCADFilePath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  16.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  17.                 {
  18.                         BlockTable blocktable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); // получаем таблицу блоков и проходим по всем записям таблицы блоков
  19.                         foreach (ObjectId btrId in blocktable)
  20.                         {
  21.                                 BlockTableRecord blockTableRecord = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);// получаем запись таблицы блоков и смотрим анонимная ли она
  22.                                 if (!dynamicOnly || blockTableRecord.IsDynamicBlock)
  23.                                         if (string.IsNullOrWhiteSpace(blockName) || blockTableRecord.Name == blockName)
  24.                                         {
  25.                                                 ObjectIdCollection anonymousIds = blockTableRecord.GetAnonymousBlockIds();// получаем все анонимные блоки динамического блока
  26.                                                 foreach (ObjectId anonymousBtrId in anonymousIds)
  27.                                                 {
  28.                                                         BlockTableRecord anonymousBtr = (BlockTableRecord)tr.GetObject(anonymousBtrId, OpenMode.ForRead);// получаем анонимный блок
  29.                                                         ObjectIdCollection blocksCollection = anonymousBtr.GetBlockReferenceIds(true, true);// получаем все вставки этого блока
  30.  
  31.                                                         var attributeRefCollection = new List<AttributeReference>();
  32.                                                         DynamicBlockReferencePropertyCollection parametrsRefCollection = null;
  33.                                                         BlockReference blockReference = null;
  34.  
  35.                                                         if (attributesAndParametrsMust)
  36.                                                         {
  37.                                                                 foreach (ObjectId entId in blocksCollection)
  38.                                                                 {
  39.                                                                         if (tr.GetObject(entId, OpenMode.ForRead) is Entity ent)
  40.                                                                         {
  41.                                                                                 blockReference = ent as BlockReference;
  42.                                                                                 if (blockReference != null)
  43.                                                                                 {
  44.                                                                                         BlockTableRecord bd = (BlockTableRecord)tr.GetObject(blockReference.BlockTableRecord, OpenMode.ForRead);
  45.                                                                                         foreach (ObjectId arId in blockReference.AttributeCollection)// ... to see whether it's a block with the name we're after
  46.                                                                                         {
  47.                                                                                                 DBObject obj = tr.GetObject(arId, OpenMode.ForRead);
  48.                                                                                                 if (obj is AttributeReference ar)
  49.                                                                                                         attributeRefCollection.Add(ar);
  50.                                                                                         }
  51.                                                                                         parametrsRefCollection = blockReference.DynamicBlockReferencePropertyCollection;
  52.                                                                                         if (!manyblocks) break; // получили атрибуты и параметры. Если нужен только один блок, то выходим из перечисления вставок блока
  53.                                                                                 }
  54.                                                                         }
  55.                                                                 }
  56.                                                         }
  57.                                                         action(blockTableRecord, blocksCollection, blockReference, attributeRefCollection, parametrsRefCollection); // непосредственно обработка блока при помощи передаваемого метода
  58.                                                         if (!manyblocks) break;// получили все параметры. Если нужен только один блок, то выходим из перечисления типов блоков
  59.                                                 }
  60.                                         }
  61.                         }
  62.                         tr.Commit();
  63.                 }
  64.                 if (manyblocks) db.SaveAs(db.OriginalFileName, true, db.OriginalFileVersion, db.SecurityParameters);
  65.         }
  66. }

Где тут рабочая база?
И в какой строчке нужно менять базу?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #10 : 22-09-2017, 11:53:24 »
Где тут рабочая база?
HostApplicationServices.WorkingDatabase - это рабочая база. Сразу после создания db переключаешься на неё, а перед удалением базы (после сохранения) переключаешься обратно.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #11 : 22-09-2017, 12:04:05 »
Можно пример?

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #12 : 22-09-2017, 12:12:59 »
Со смартфона тяжело. Посмотри это: http://adn-cis.org/forum/index.php?topic=831.msg3438#msg3438
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 18
  • Карма: 1
Re: Изменить файл не открывая AutoCAD
« Ответ #13 : 22-09-2017, 12:24:11 »
Спасибо большое.
По примеру сделал так:
Код - C# [Выбрать]
  1. private static void AccessGlobalFromFile(...)
  2. {
  3.         Document doc = Application.DocumentManager.MdiActiveDocument;
  4.         if (doc == null) return;
  5.  
  6.         Editor ed = doc.Editor;
  7.         using (Database db = new Database(false, true))
  8.         {
  9.                 db.ReadDwgFile(autoCADFilePath, FileOpenMode.OpenForReadAndWriteNoShare, false, "");
  10.                 Database prevDb = HostApplicationServices.WorkingDatabase;
  11.                 HostApplicationServices.WorkingDatabase = db;
  12.  
  13.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  14.                 {
  15.                         ...
  16.                         tr.Commit();
  17.                 }
  18.                 HostApplicationServices.WorkingDatabase = prevDb;
  19.                 db.SaveAs(db.OriginalFileName, true, db.OriginalFileVersion, db.SecurityParameters);
  20.         }
  21. }
Эффект тот же(
Попробую еще с открытым файлом - может, если программно блоки редактировать, то не будет fatal error

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Изменить файл не открывая AutoCAD
« Ответ #14 : 22-09-2017, 22:18:18 »
Ну возможно еще в коде обновления что-то не то. Например, я обратил внимание, что BlockTable открыт для чтения, а изменение параметров динамического блока приводит к созданию нового анонимного блока, BlockTableRecord которого должен записаться в BlockTable.
Короче говоря поиграйся с заменой OpenMode.ForRead на OpenMode.ForWrite в разных местах у себя. А может стоит заменить обычную транзакцию на эмуляцию транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение