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

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

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

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #15 : 26-02-2015, 17:34:13 »
Цитировать
я у себя на чертеже перед этим удалял все(!) мультилинии. Но тем не менее, не могу понять, почему повторная загрузка стилей(через инвок, без удаления) работала, а потмо перестала о_О.
Ну-ну... Пробовал после этого войти в редактор стилей мультилиний? :)

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

Вот подправленный твой код (собственно, от "твоего" там почти ничего и не осталось):
Код - 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.           doc.Database.Purge(new Db.ObjectIdCollection(objects.ToArray()));
  37.  
  38.           foreach (var item in objects) {
  39.             var mlstyle = (Db.MlineStyle)trans.GetObject(item,
  40.               Db.OpenMode.ForWrite);
  41.             mlstyle.Erase(true);
  42.           }
  43.           trans.Commit();
  44.         }
  45.       }
  46.     }
  47.   }
  48. }
Андрей, Вы наверное не так поняли меня. Во-первых, ни шаблон, ни чертёж не сохранялся, поэтому ничего "коцанного" нет.
Во-вторых, на  счёт "сомнительно". Я пробовал БЕЗ УДАЛЕНИЯ(!) старых стилей подгружать ПОВЕРХ(!) стили из файлов. Именно в таком(!) виде оно работало. Не сочтите за офтоп конечно, но я задавая вопросы здесь, стараюсь вникнуть в суть проблемы, каждый раз подчерпывая для себя информацию о том, как устроен внутри Автокад. Поэтому и указал этот странный момент в своём сообщении, стараясь указать как можно больше информации, чтобы получить конкретный ответ.
За помощь спасибо:)

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #16 : 26-02-2015, 17:35:52 »
юзингов-то в своём коде ты понатыкал... я поубирал лишние.
Разве получая объект по транзакции неправильно диспоузить его?

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

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

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

  • ADN OPEN
  • Сообщений: 39
  • Карма: 0
Re: Обновить стили мультилиний
« Ответ #18 : 27-02-2015, 07:01:10 »
Андрей, пробовал с Вашим вариантом удаления, но потерпел неудачу. Вот код

Код - C# [Выбрать]
  1. public static void AppendAllMultilineType(Document doc, string scale, string appDir)
  2.                 {
  3.                         using (doc.LockDocument())
  4.                         using (var trans = doc.Database.TransactionManager.StartTransaction())
  5.                         using (var styles = (DBDictionary)trans.GetObject(doc.Database.MLStyleDictionaryId, OpenMode.ForWrite))
  6.                         {
  7.                                 var objects = new List<ObjectId>();
  8.                                 foreach (var style in styles)
  9.                                 {
  10.                                         if (style.Key.Equals("STANDARD", StringComparison.CurrentCultureIgnoreCase) || style.Value == doc.Database.CmlstyleID)
  11.                                                 continue;
  12.  
  13.                                         objects.Add(style.Value);
  14.                                 }
  15.  
  16.                                 if (objects.Any())
  17.                                         doc.Database.Purge(new ObjectIdCollection(objects.ToArray()));
  18.  
  19.                                 foreach (var style in objects)
  20.                                 {
  21.                                         var mlstyle = (MlineStyle)trans.GetObject(style, OpenMode.ForWrite);
  22.                                         mlstyle.Erase(true);
  23.                                 }
  24.  
  25.                                 trans.Commit();
  26.                         }
  27.  
  28.                         using (doc.Database.MLStyleDictionaryId.GetObject(OpenMode.ForWrite))
  29.                         {
  30.                                 var files = Directory.GetFiles(appDir, String.Format("*{0}.mln", scale));
  31.  
  32.                                 foreach (var file in files)
  33.                                 {
  34.                                         var styleName = file.Substring(file.LastIndexOf('\\') + 1);
  35.                                         styleName = styleName.Remove(styleName.IndexOf('_'));
  36.                                         try
  37.                                         {
  38.                                                 doc.Database.LoadMlineStyleFile(styleName, file);
  39.                                         }
  40.                                         catch
  41.                                         {
  42.                                         }
  43.                                 }
  44.                         }
  45.                 }
  46.  

Опять при назначении стиля мультилинии возникает исключение ошибка eWasErased. Подгрузку пробовал переносить и над trans.Commit() - результат тот же.

При попытке переименовать, а потом следом подгрузить стили из файлов тоже безуспешны. Переименовываются норм, а вот подгрузка происходит "мимо", стили не появляются. Более того, если следом попытаться назначить стиль для мультилинии со старым названием, то никаких исключения не генерируется. А в словаре далее в плагине мы находим без проблем все стили по старым именам(как до изменения). Это при том, что в окне MLSTYLE имена меняются, а в словаре нет.

Код - C# [Выбрать]
  1.                 public static void AppendAllMultilineType(Document doc, string scale, string appDir)
  2.                 {
  3.                         using (doc.LockDocument())
  4.                         using (var trans = doc.Database.TransactionManager.StartTransaction())
  5.                         using (var styles = (DBDictionary)trans.GetObject(doc.Database.MLStyleDictionaryId, OpenMode.ForWrite))
  6.                         {
  7.                                 foreach (var style in styles)
  8.                                 {
  9.                                         if (style.Key.Equals("STANDARD", StringComparison.CurrentCultureIgnoreCase) || style.Value == doc.Database.CmlstyleID)
  10.                                                 continue;
  11.                                         var mlstyle = (MlineStyle)trans.GetObject(style.Value, OpenMode.ForWrite);
  12.                                         mlstyle.Name += "_";
  13.  
  14.                                 }
  15.  
  16.                                 trans.Commit();
  17.                         }
  18.  
  19.                         using (doc.Database.MLStyleDictionaryId.GetObject(OpenMode.ForWrite))
  20.                         {
  21.                                 var files = Directory.GetFiles(appDir, String.Format("*{0}.mln", scale));
  22.  
  23.                                 foreach (var file in files)
  24.                                 {
  25.                                         var styleName = file.Substring(file.LastIndexOf('\\') + 1);
  26.                                         styleName = styleName.Remove(styleName.IndexOf('_'));
  27.                                         try
  28.                                         {
  29.                                                 doc.Database.LoadMlineStyleFile(styleName, file);
  30.                                         }
  31.                                         catch
  32.                                         {
  33.                                         }
  34.                                 }
  35.                         }
  36.                 }
  37.  
« Последнее редактирование: 27-02-2015, 21:55:11 от Александр Ривилис »

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #19 : 27-02-2015, 10:08:08 »
Цитировать
пробовал с Вашим вариантом удаления, но потерпел неудачу. Вот код
То, что ты показываешь - это однозначно не мой код.

Выложи DWG файл, на котором запускал код.

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

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Обновить стили мультилиний
« Ответ #20 : 27-02-2015, 10:44:16 »
Цитировать
пробовал с Вашим вариантом удаления, но потерпел неудачу
Согласен, нужно добавить проверку на наличие элементов в списке objects, прежде чем вызывать Purge, иначе получаем ошибку, если удалять нечего. Добавил выше эту проверку в коде (см. строку 36).

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #21 : 27-02-2015, 22:02:39 »
MikhailTAP
1) Мне начинает надоедать форматировать твой код. Прочитай мою подпись и в дальнейшем придерживайся правил форматирования на форуме.
2) Если нужна помощь - выкладывай чертеж, mln-файлы и тестовый проект, который у тебя не работает.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Обновить стили мультилиний
« Ответ #22 : 27-02-2015, 22:05:31 »
Для переименования насколько я помню следует использовать метод DBDictionary.SetName(string oldName, string newName);
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение