Обновить стили мультилиний

Автор Тема: Обновить стили мультилиний  (Прочитано 16421 раз)

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

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Добрый день!
Есть плагин, который использует мультилинии. Их стили содержатся в шаблонах(для создаваемых документов), и в файлах *.mln(для обновления уже существующих чертежей). От версии к версии необходимо обновить стили мультилиний в соответствии с актуальными файлами *.mln, в которых стили называются также но имеют другие настройки. При подгрузке через метод Database.LoadMlineStyleFile, или аналог через P/Invoke ничего не обновляется. Стили не меняют настройки. Пробовал сначала вырезать все мультилинии на чертеже, потом удалить все стили линий, и подгрузить их заново указанными выше методами, однако получаю eWasErased при создании мультилиний (указывая им свои стили, которые были подгружены). И стили в окне MLSTYLE не меняются.

Код - C# [Выбрать]
  1.                         using (doc.LockDocument())
  2.                         using (var trans = doc.Database.TransactionManager.StartTransaction())
  3.                         using (var styles = (DBDictionary)trans.GetObject(doc.Database.MLStyleDictionaryId, OpenMode.ForRead))
  4.                         {
  5.                                 var objects = new List<ObjectId>();
  6.                                 foreach (var style in styles)
  7.                                 {
  8.                                         using (var mlstyle = (MlineStyle)trans.GetObject(style.Value, OpenMode.ForWrite))
  9.                                         {
  10.                                                 //mlstyle.Name = mlstyle.Name + "___";
  11.                                                 objects.Add(style.Value);
  12.                                                 mlstyle.Erase(true);
  13.                                         }
  14.                                 }
  15.  
  16.                                 doc.Database.Purge(new ObjectIdCollection(objects.ToArray()));
  17.  
  18.                                 trans.Commit();
  19.                         }
  20.  

Есть ли вариант как-то обновить стили?

Спасибо.
« Последнее редактирование: 26-02-2015, 14:58:42 от Александр Ривилис »

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #1 : 26-02-2015, 14:23:18 »
Как вариант: можно программно сравнить исходный и целевой стили между собой (каждую опцию настроек) и в случае необходимости внести соответствующие корректировки в целевой. Поскольку свойств не так уж и много, то трудностей это представлять не должно. Пример программной настройки стиля мультилинии можно глянуть здесь.

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #2 : 26-02-2015, 14:25:08 »
Я тоже об этом подумал, однако проблема в том, что стили в файлах mln. А как из них получить объект стиля мультилинии?

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #3 : 26-02-2015, 14:33:23 »
проблема в том, что стили в файлах mln. А как из них получить объект стиля мультилинии?
это обычные текстовые файлы, так что читать\редактировать их не должно представлять каких-либо трудностей. :)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #4 : 26-02-2015, 15:15:24 »
Думаю, что нужно:
1) Переименовать те стили в чертеже, которые ты хочешь обновить
2) Загрузить Database.LoadMlineStyleFile
3) Задать новые стили.
4) Старые стили удалить.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #5 : 26-02-2015, 16:20:04 »
Думаю, что нужно:
1) Переименовать те стили в чертеже, которые ты хочешь обновить
2) Загрузить Database.LoadMlineStyleFile
3) Задать новые стили.
4) Старые стили удалить.

Проверить полностью весь порядок смогу только завтра, но могу сказать что пробовал переименовывать стили мультилиний в чертеже, и следом загружать стили из файлов mln, вызывая правда функцию через P/Invoke, однако переименовываются стили нормально, но не подгружаются, в окне MLSTYLE стили не появляются.
Однако, немного предыстории, почему я вообще стал звать функцию загрузки из либы. Я изначально пытался загружать "поверх" стили методом Database.LoadMlineStyleFile, однако если стиль уже присутствовал в чертеже, генерировалось исключение, а если удалить вручную стили мультилиний из чертежа, сохранить, а потом открыть снова(для надежности так сказать), то этот метод сыпал исключение xxxAccessFilexxx(точно не вспомню). Погуглив это исключение, я наткнулся на Ваш пост, Александр:) На нём вы посоветовали использовать функцию из либы.
Я воспользовался этим советом, и стал звать функцию из либы. И бьюсь об заклад, что при подгрузке "поверх" стилей, они обновлялись как надо. Но на следующий день метод перестал работать. Откуда такое поведение - непонятно.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #6 : 26-02-2015, 16:22:31 »
На нём вы посоветовали использовать функцию из либы.
Переведи. Желательно с ссылкой на то, что я писал.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #7 : 26-02-2015, 16:29:52 »
Александр, вот ссылка http://forums.autodesk.com/t5/net/error-loading-a-multiline-style/td-p/1678971 старый пост (аж 2006 год:)). Вообще насколько я понял, eFileAccessErr по заявлению саппорта Автодеска за 2013 г может появляться при использовании метода Database.LoadMlineStyleFile если файл стиля расположен не в системной директории. Хотя в моём случае, путь до директории где лежали стили, был прописан в настройках автокада.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #8 : 26-02-2015, 16:31:30 »
Ну, во первых, нельзя удалять все стили. Должен присутствовать как минимум стиль standard, а ты пытаешься и его удалить.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #9 : 26-02-2015, 16:35:14 »
Должен присутствовать как минимум стиль standard, а ты пытаешься и его удалить.
Нельзя удалять также и текущий стиль и все используемые в чертеже стили. Ты же их сначала удаляешь, а затем уже проверяешь можно ли их удалить. В чем смысл?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #10 : 26-02-2015, 16:41:18 »
Да, согласен, изменять/удалять системные объекты - плохое дело, но тем не менее, я у себя на чертеже перед этим удалял все(!) мультилинии. Но тем не менее, не могу понять, почему повторная загрузка стилей(через инвок, без удаления) работала, а потмо перестала о_О.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #11 : 26-02-2015, 16:46:22 »
Ну тут как минимум нужно смотреть на твой код. Как минимум MLStyleDictionary должна быть доступна для записи в момент когда ты выполняешь загрузку *.mln-файлов. И вообще желательно, чтобы это действие было вне транзакции.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #12 : 26-02-2015, 16:53:57 »
Цитировать
я у себя на чертеже перед этим удалял все(!) мультилинии. Но тем не менее, не могу понять, почему повторная загрузка стилей(через инвок, без удаления) работала, а потмо перестала о_О.
Ну-ну... Пробовал после этого войти в редактор стилей мультилиний? :)

Не занимайся ерундой. Тебе сказали, что нельзя удалять стандартные и текущие стили. То, что у тебя там "что-то работало, а потом перестало" - весьма сомнительно. В любом случае это "что-то" покоцало базу данных твоего чертежа и рано или поздно это всё равно вылезло бы. Кстати, возможно, что в свой шаблон ты как раз коцанный чертёж и вогнал. Соответственно всё, созданное на его основе так же криво.

Вот подправленный твой код (собственно, от "твоего" там почти ничего и не осталось):
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. #if AUTOCAD
  6. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  7. using Ap = Autodesk.AutoCAD.ApplicationServices;
  8. using Db = Autodesk.AutoCAD.DatabaseServices;
  9. using Ed = Autodesk.AutoCAD.EditorInput;
  10. using Rt = Autodesk.AutoCAD.Runtime;
  11. using Gm = Autodesk.AutoCAD.Geometry;
  12. using Hs = Autodesk.AutoCAD.DatabaseServices.HostApplicationServices;
  13. using Us = Autodesk.AutoCAD.DatabaseServices.SymbolUtilityServices;
  14. #endif
  15.  
  16. namespace cad_sandbox {
  17.   public class Class1 {
  18.     [Rt.CommandMethod("test")]
  19.     public void Test() {
  20.       Ap.Document doc = cad.DocumentManager.MdiActiveDocument;
  21.       Ed.Editor ed = doc.Editor;
  22.       Db.Database db = doc.Database;
  23.  
  24.       using (doc.LockDocument()) {
  25.         using (var trans = doc.Database.TransactionManager.StartTransaction()) {
  26.           Db.DBDictionary styles = trans.GetObject(db.MLStyleDictionaryId,
  27.             Db.OpenMode.ForRead) as Db.DBDictionary;
  28.           List<Db.ObjectId> objects = new List<Db.ObjectId>();
  29.           foreach (var style in styles) {
  30.             if (db.CmlstyleID != style.Value &&
  31.               style.Key.ToLower() != "standard") {
  32.               objects.Add(style.Value);
  33.             }
  34.           }
  35.  
  36.           if (objects.Count > 0) {
  37.             doc.Database.Purge(new Db.ObjectIdCollection(objects.ToArray()));
  38.           }
  39.  
  40.           foreach (var item in objects) {
  41.             var mlstyle = (Db.MlineStyle)trans.GetObject(item,
  42.               Db.OpenMode.ForWrite);
  43.             mlstyle.Erase(true);
  44.           }
  45.           trans.Commit();
  46.         }
  47.       }
  48.     }
  49.   }
  50. }
« Последнее редактирование: 27-02-2015, 10:41:33 от Андрей Бушман »

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #13 : 26-02-2015, 16:57:52 »
Спасибо за помощь, завтра попробую.

Оффлайн Андрей Бушман

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #14 : 26-02-2015, 17:30:06 »
юзингов-то в своём коде ты понатыкал... я поубирал лишние.