Как удалить параметрику из блоков / вхождений блоков

Автор Тема: Как удалить параметрику из блоков / вхождений блоков  (Прочитано 25618 раз)

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

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
На всякий случай я отправил запрос в ADN DevHelp. Возможно мы что-то не учитываем и есть альтернативные методы как удалить зависимости и не допустить появления этого надоедливого окошка.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Спасибо, будем ждать.
Алексей

Отмечено как Решение Александр Ривилис 09-10-2018, 11:44:30

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Спасибо, будем ждать.
Они предложили использовать хуки если ничего лучшего не придумают. Я настоятельно попросить что-нибудь придумать. :)
Пока они будут думать я реализовал хуки. Можешь попробовать:

Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.EditorInput;
  9. using AcRx = Autodesk.AutoCAD.Runtime;
  10. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  11. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  12. using AcGe = Autodesk.AutoCAD.Geometry;
  13. using AcEd = Autodesk.AutoCAD.EditorInput;
  14. using Microsoft.Win32;
  15.  
  16. [assembly: CommandClass(typeof(Rivilis.RemoveConsAssoc))]
  17.  
  18. namespace Rivilis
  19. {
  20.   public class RemoveConsAssoc
  21.   {
  22.     // Заголовки диалогового окна в русском и английском AutoCAD,
  23.     // от которого мы хотим избавится.
  24.     const string rusTitle = "Размерные зависимости — неассоциативный размер";
  25.     const string engTitle = "Dimensional Constraints - Non Associative Dimension";
  26.    
  27.     const uint WM_CLOSE = 0x0010;
  28.  
  29.     static LocalCbtHook hook = new LocalCbtHook();
  30.     static void WinActivated(object sender, CbtEventArgs e)
  31.     {
  32.       if (e.Title.CompareTo(rusTitle) == 0 || e.Title.CompareTo(engTitle) == 0)
  33.       {
  34.         // Сразу закрываем окно
  35.         LocalCbtHook.SendMessage(e.Handle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
  36.       }
  37.     }
  38.     [CommandMethod("RemConsAssoc", CommandFlags.Modal)]
  39.     public void RemConsAssoc()
  40.     {
  41.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  42.       AcDb.Database db = doc.Database;
  43.       AcEd.Editor ed = doc.Editor;
  44.       ed.WriteMessage("\nВыберите примитивы для удаления зависимостей");
  45.       AcEd.PromptSelectionOptions prSel = new AcEd.PromptSelectionOptions();
  46.       AcEd.PromptSelectionResult resSel = ed.GetSelection(prSel);
  47.       if (resSel.Status != AcEd.PromptStatus.OK)
  48.       {
  49.         ed.WriteMessage("\nНичего не выбрано!");
  50.         return;
  51.       }
  52.       if (!hook.IsInstalled)
  53.       {
  54.         hook.WindowActivated += WinActivated;
  55.         hook.Install();
  56.       }
  57.       foreach (ObjectId id in resSel.Value.GetObjectIds())
  58.       {
  59.         DeleteAllConstraintsOnEntity(id);
  60.       }
  61.     }
  62.     public void DeleteAllConstraintsOnEntity(ObjectId id)
  63.     {
  64.       using (AcDb.DBObject obj = id.Open(AcDb.OpenMode.ForWrite))
  65.       {
  66.         ObjectIdCollection idsAct = AcDb.AssocAction.GetActionsDependentOnObject(obj, true, true);
  67.         ObjectIdCollection idsDep = AcDb.AssocDependency.GetDependenciesOnObject(obj, true, true);
  68.         for (int i = 0; i < idsAct.Count; i++)
  69.         {
  70.           using (AcDb.Assoc2dConstraintGroup objAct =
  71.             idsAct[i].Open(AcDb.OpenMode.ForWrite) as AcDb.Assoc2dConstraintGroup)
  72.           {
  73.             if (objAct != null)
  74.             {
  75.               for (int j = 0; j < idsDep.Count; j++)
  76.                 objAct.DeleteConstrainedGeometry(idsDep[j]);
  77.             }
  78.           }
  79.         }
  80.       }
  81.     }
  82.   }
  83. }
  84.  

Остальное я взял и чуть-чуть модифицировал отсюда: http://www.codeproject.com/Articles/5038/Using-Hooks-from-C
Выкладываю готовый проект для тестирования.
P.S.: К сожалению универсальный (не зависящий от языка локализации) код не получился, т.к. кроме заголовка окна ничего универсального в этих окнах я не нашел. Так что если тебе придётся работать с другими локализациями AutoCAD (немецкая, французская, китайская, и т.д.), то придется вставить дополнительные проверки.

Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дима_

  • ADN Club
  • ****
  • Сообщений: 473
  • Карма: 66
Я так и не понял зачем городить такие костыли - когда можно, как я уже писал, сделать "чистую" копию, а оригинал просто удалить - ведь на удалении примитива, в отличие от его "очистки" никакого окна не выскакивает.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Дима_
Не всё так просто, как тебе кажется:
1) Как ты собираешься копировать (метод: Clone, DeepClone, DeepCloneObjects)?
2) Что при этом произойдёт с Xdata и Extension Dictionary у скопированных примитивов?
3) К чему приведет потеря XData и Extension Dictionary или их сохранение, но при этом ссылки будут "в молоко"?
4) Как потом обеспечить взаимосвязь ObjectId с полями, если при таком копировании они поменяются?
5) Нужно будет найти все вставки старого блока в чертеже и заменить его на новый - это самое простое из поднятых вопросов.
6) ...
В действительности этот метод может оказаться значительно более сложным, чем показанный мной хук.
 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
bargool
Судя по тому, что ты отметил моё сообщение как Решение, тест прошел успешно?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • ***
  • Сообщений: 111
  • Карма: 6
Прошу прощения, поторопился. Поверить смогу только завтра (в смысле сегодня, но на работе)
Алексей

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
На всякий случай уточню, что я тестировал только в AutoCAD 2014 SP1 x64 Russian и English и в AutoCAD 2015 SP2 x64 Russian и English
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
1) Как ты собираешься копировать (метод: Clone, DeepClone, DeepCloneObjects)?
2) Что при этом произойдёт с Xdata и Extension Dictionary у скопированных примитивов?
3) К чему приведет потеря XData и Extension Dictionary или их сохранение, но при этом ссылки будут "в молоко"?
4) Как потом обеспечить взаимосвязь ObjectId с полями, если при таком копировании они поменяются?
5) Нужно будет найти все вставки старого блока в чертеже и заменить его на новый - это самое простое из поднятых вопросов.
6) ...
В действительности этот метод может оказаться значительно более сложным, чем показанный мной хук.
Можно попробовать создать новый объект, перенести в него свойства из старого и воспользоваться методом DBObject.SwapIdWith.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
перенести в него свойства из старого
Тут тоже нужно отслеживать какие свойства переносить, а какие нет. Думаю что и здесь проблем возникнет куча.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Интересное решение предложили в ADN DevHelp. Но у него есть два недостатка:
1) В указанном виде работает только внутри редактора блоков (BLOCKEDITOR)
2) Использует недокументированные вещи.
И всё-же я приведу код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Reflection;
  4. using Autodesk.AutoCAD.Runtime;
  5. using Autodesk.AutoCAD.ApplicationServices;
  6. using Autodesk.AutoCAD.DatabaseServices;
  7. using Autodesk.AutoCAD.Internal.DatabaseServices;
  8. using Autodesk.AutoCAD.Geometry;
  9. using Autodesk.AutoCAD.EditorInput;
  10. using AcRx = Autodesk.AutoCAD.Runtime;
  11. using AcAp = Autodesk.AutoCAD.ApplicationServices;
  12. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  13. using AcDbInt = Autodesk.AutoCAD.Internal.DatabaseServices;
  14. using AcGe = Autodesk.AutoCAD.Geometry;
  15. using AcEd = Autodesk.AutoCAD.EditorInput;
  16.  
  17. [assembly: CommandClass(typeof(Rivilis.RemoveConsAssoc))]
  18.  
  19. namespace Rivilis
  20. {
  21.   public class RemoveConsAssoc
  22.   {
  23.     [CommandMethod("RemConsAssoc", CommandFlags.Modal)]
  24.     public void RemConsAssoc()
  25.     {
  26.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  27.       AcDb.Database db = doc.Database;
  28.       AcEd.Editor ed = doc.Editor;
  29.       ed.WriteMessage("\nВыберите примитивы для удаления зависимостей");
  30.       AcEd.PromptSelectionOptions prSel = new AcEd.PromptSelectionOptions();
  31.       AcEd.PromptSelectionResult resSel = ed.GetSelection(prSel);
  32.       if (resSel.Status != AcEd.PromptStatus.OK) {
  33.         ed.WriteMessage("\nНичего не выбрано!");
  34.         return;
  35.       }
  36.       foreach (ObjectId id in resSel.Value.GetObjectIds()) {
  37.         if (id.ObjectClass.IsDerivedFrom(RXClass.GetClass(typeof(AcDbInt.BlockElementEntity)))) {
  38.           using (AcDb.DBObject obj = id.Open(AcDb.OpenMode.ForWrite)) {
  39.             obj.Erase();
  40.           }
  41.         } else {
  42.           DeleteAllConstraintsOnEntity(id);
  43.         }
  44.       }
  45.     }
  46.  
  47.     public void DeleteAllConstraintsOnEntity(ObjectId id)
  48.     {
  49.       using (AcDb.DBObject obj = id.Open(AcDb.OpenMode.ForWrite))
  50.       {
  51.         ObjectIdCollection idsAct = AcDb.AssocAction.GetActionsDependentOnObject(obj, true, true);
  52.         ObjectIdCollection idsDep = AcDb.AssocDependency.GetDependenciesOnObject(obj, true, true);
  53.         for (int i = 0; i < idsAct.Count; i++)
  54.         {
  55.           using (AcDb.Assoc2dConstraintGroup objAct =
  56.             idsAct[i].Open(AcDb.OpenMode.ForWrite) as AcDb.Assoc2dConstraintGroup)
  57.           {
  58.             if (objAct != null)
  59.             {
  60.               for (int j = 0; j < idsDep.Count; j++)
  61.                 objAct.DeleteConstrainedGeometry(idsDep[j]);
  62.             }
  63.           }
  64.         }
  65.       }
  66.     }
  67.   }
  68. }
  69.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Итак. Окончательный ответ от ADN DevHelp - хук хоть и не лучший, но единственно доступный вариант при такой постановке задачи.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение