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

ADN Club => AutoCAD .NET API => Тема начата: bargool от 16-02-2015, 14:24:49

Название: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 16-02-2015, 14:24:49
Добрый день.
Для вхождений динамических блоков есть прекрасный метод BlockReference.ConvertToStaticBlock, который "удаляет" динамику
У меня задача комбинированная, у меня есть вхождения динамических блоков, у которых присутствует ещё и параметрика
Как преобразовать такие вхождения блоков во вхождения статических, без параметрики и динамики (но с сохранением геометрии).
Например, вначале делаю им ConvertToStaticBlock, что потом можно сделать?
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Алексей Кулик от 16-02-2015, 16:39:32
ИМХО: потом получить указатель на описание созданного блока, пройтись по всем его подэлементам и удалять параметрические зависимости уже для них. Как это делается в .NET - не представляю (в лиспе как-то решал подобную задачу, но здесь оно вряд ли подойдет).
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 16-02-2015, 18:43:29
Удалить параметрику с примитива можно так: http://adndevblog.typepad.com/autocad/2012/07/associative-framework-how-to-delete-constraints-applied-to-a-specific-entity.html
Это ObjectARX, но думаю что по аналогии сделать на .NET можно.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 16-02-2015, 19:56:50
Вот так это выглядит на C# с использованием AutoCAD .NET API:
Код - 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.  
  15. [assembly: CommandClass(typeof(Rivilis.RemoveConsAssoc))]
  16.  
  17. namespace Rivilis
  18. {
  19.   public class RemoveConsAssoc
  20.   {
  21.     public void DeleteAllConstraintsOnEntity(ObjectId id)
  22.     {
  23.       using (AcDb.DBObject obj = id.Open(AcDb.OpenMode.ForWrite))
  24.       {
  25.         ObjectIdCollection idsAct = AcDb.AssocAction.GetActionsDependentOnObject(obj, true, true);
  26.         ObjectIdCollection idsDep = AcDb.AssocDependency.GetDependenciesOnObject(obj, true, true);
  27.         for (int i = 0; i < idsAct.Count; i++)
  28.         {
  29.           using (AcDb.Assoc2dConstraintGroup objAct =
  30.             idsAct[i].Open(AcDb.OpenMode.ForWrite) as AcDb.Assoc2dConstraintGroup)
  31.           {
  32.             if (objAct != null)
  33.             {
  34.               for (int j = 0; j < idsDep.Count; j++)
  35.                 objAct.DeleteConstrainedGeometry(idsDep[j]);
  36.             }
  37.           }
  38.         }
  39.       }
  40.     }
  41.     [CommandMethod("RemConsAssoc", CommandFlags.Modal)]
  42.     public void RemConsAssoc()
  43.     {
  44.       AcAp.Document doc = AcAp.Application.DocumentManager.MdiActiveDocument;
  45.       AcDb.Database db = doc.Database;
  46.       AcEd.Editor ed = doc.Editor;
  47.       AcEd.PromptEntityOptions prEnt =
  48.         new AcEd.PromptEntityOptions("\nВыберите примитив для удаления зависимостей: ");
  49.       AcEd.PromptEntityResult resEnt = ed.GetEntity(prEnt);
  50.       if (resEnt.Status != AcEd.PromptStatus.OK)
  51.       {
  52.         ed.WriteMessage("\nНичего не выбрали!");
  53.         return;
  54.       }
  55.       DeleteAllConstraintsOnEntity(resEnt.ObjectId);
  56.     }
  57.   }
  58. }
При желании можно использовать и транзакции.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 17-02-2015, 15:26:36
В процессе работы кода получаю сообщение (скриншот во вложении)
Судя по всему, это происходит тогда, когда удаляются геометрические ограничения, которые используются в формулах.
Попытался получать и удалять AssocVariable как у объектов описания блока, так и у самого описания блока. Не помогает.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 17-02-2015, 15:32:15
Выложи пример такого блока чтобы была возможность посмотреть.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 17-02-2015, 16:28:31
Образец блока во вложении.
Наколенный быстрый код, написанный на основе вашего, который по запросу вхождения блока должен вычищать описание блока от параметрики. Он выдаёт искомое сообщение, если выбрать вхождение блока в файле во вложении
Код - C# [Выбрать]
  1. [AcRt.CommandMethod("RemConsAssoc", AcRt.CommandFlags.Modal)]
  2. public void RemConsAssoc()
  3. {
  4.     AcAs.Document doc = AcApp.DocumentManager.MdiActiveDocument;
  5.     AcDb.Database db = doc.Database;
  6.     AcEd.Editor ed = doc.Editor;
  7.     AcEd.PromptEntityOptions prEnt = new AcEd.PromptEntityOptions("\nВыберите вхождение блока для удаления зависимостей: ");
  8.     prEnt.SetRejectMessage("Должно быть вхождение блока!");
  9.     prEnt.AddAllowedClass(typeof(BlockReference), true);
  10.     AcEd.PromptEntityResult resEnt = ed.GetEntity(prEnt);
  11.     if (resEnt.Status != AcEd.PromptStatus.OK)
  12.         return;
  13.  
  14.     DeleteAllConstraintsOnEntity(resEnt.ObjectId);
  15. }
  16.  
  17. private void DeleteAllConstraintsOnEntity(AcDb.ObjectId objectId)
  18. {
  19.     using (AcDb.Transaction tr = AcDb.HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
  20.     {
  21.         AcDb.BlockReference bref = tr.GetObject(objectId, AcDb.OpenMode.ForRead) as AcDb.BlockReference;
  22.         AcDb.BlockTableRecord btr = tr.GetObject(bref.DynamicBlockTableRecord, AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord;
  23.         foreach (DBObject dbo in btr.Cast<AcDb.ObjectId>().Select(id => tr.GetObject(id, AcDb.OpenMode.ForWrite) as AcDb.DBObject))
  24.         {
  25.             ObjectIdCollection idsAct = AssocAction.GetActionsDependentOnObject(dbo, true, true);
  26.             ObjectIdCollection idsDep = AssocDependency.GetDependenciesOnObject(dbo, true, true);
  27.             for (int i = 0; i < idsAct.Count; i++)
  28.             {
  29.                 Assoc2dConstraintGroup objAct = tr.GetObject(idsAct[i], OpenMode.ForWrite) as Assoc2dConstraintGroup;
  30.                 if (objAct != null)
  31.                 {
  32.                     for (int j = 0; j < idsDep.Count; j++)
  33.                     {
  34.                         objAct.DeleteConstrainedGeometry(idsDep[j]);
  35.                     }
  36.                 }
  37.             }
  38.         }
  39.         tr.Commit();
  40.     }
  41. }
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 17-02-2015, 17:19:01
Тоже самое сообщение возникает и при ручном (командой _DelConstraint) удалении зависимостей. Так что похоже это не лечится.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 17-02-2015, 18:00:48
Впрочем, так как тебе не нужна вообще никакая динамика и параметрика, то можно радикально удалить из ExtensionDictionary BlockTableRecord всё:
(https://adn-cis.org/forum/proxy.php?request=http%3A%2F%2Fimg-fotki.yandex.ru%2Fget%2F4914%2F7842324.3%2F0_f72f3_6a689a5c_orig.png&hash=d3fc2530b27faa6182354116968311b3)
Возможно в этом случае сообщения не будет.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 18-02-2015, 09:50:38
Сделал конвертирование в статику (что бы исключить проблемы с остальными вхождениями блока), а затем чистку и удаление ExtensionDictionary. В принципе, всё очищается без доп. уведомлений, но появляется промежуточный странный эффект, блок теряет параметрику, но автокад обновляет эту информацию только после захода в Block Editor: скринкаст, иллюстрирующий эффект (https://screencast.autodesk.com/main/details/1d8a2079-1c33-46ef-ab03-65cb6e2ca156)
Думаю, в моём случае это не проблема, т.к. блоки будут обрабатываться в базе без создания документа.
Код:
Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5.  
  6. using AcApp = Autodesk.AutoCAD.ApplicationServices.Application;
  7. using AcRt = Autodesk.AutoCAD.Runtime;
  8. using AcAs = Autodesk.AutoCAD.ApplicationServices;
  9. using AcDb = Autodesk.AutoCAD.DatabaseServices;
  10. using AcEd = Autodesk.AutoCAD.EditorInput;
  11.  
  12. [assembly: AcRt.CommandClass(typeof(Bargool.CommandClass))]
  13.  
  14. namespace Bargool
  15. {
  16.     class CommandClass
  17.     {
  18.         [AcRt.CommandMethod("RemConsAssoc", AcRt.CommandFlags.Modal)]
  19.         public void RemConsAssoc()
  20.         {
  21.             AcAs.Document doc = AcApp.DocumentManager.MdiActiveDocument;
  22.             AcDb.Database db = doc.Database;
  23.             AcEd.Editor ed = doc.Editor;
  24.             AcEd.PromptEntityOptions prEnt = new AcEd.PromptEntityOptions("\nВыберите вхождение блока для удаления зависимостей: ");
  25.             prEnt.SetRejectMessage("Должно быть вхождение блока!");
  26.             prEnt.AddAllowedClass(typeof(AcDb.BlockReference), true);
  27.             AcEd.PromptEntityResult resEnt = ed.GetEntity(prEnt);
  28.             if (resEnt.Status != AcEd.PromptStatus.OK)
  29.                 return;
  30.  
  31.             DeleteAllConstraintsOnEntity(resEnt.ObjectId);
  32.         }
  33.  
  34.         private void DeleteAllConstraintsOnEntity(AcDb.ObjectId objectId)
  35.         {
  36.             using (AcDb.Transaction tr = AcDb.HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
  37.             {
  38.                 AcDb.BlockReference bref = tr.GetObject(objectId, AcDb.OpenMode.ForRead) as AcDb.BlockReference;
  39.                 if (!bref.IsDynamicBlock)
  40.                     return;
  41.  
  42.                 // Подбираем имя для статического блока и конвертим динамику в статику
  43.                 int index = 0;
  44.                 string blocknamebase = "ExDyn";
  45.  
  46.                 AcDb.BlockTable bt = (AcDb.BlockTable)tr.GetObject(AcDb.HostApplicationServices.WorkingDatabase.BlockTableId, AcDb.OpenMode.ForRead);
  47.                 while (bt.Has(blocknamebase + index.ToString()))
  48.                     index++;
  49.  
  50.                 string blockname = blocknamebase + index.ToString();
  51.  
  52.                 bref.ConvertToStaticBlock(blockname);
  53.  
  54.                 AcDb.BlockTableRecord btr = tr.GetObject(bt[blockname], AcDb.OpenMode.ForWrite) as AcDb.BlockTableRecord;
  55.                 if (btr.ExtensionDictionary.IsNull)
  56.                     return;
  57.  
  58.                 AcDb.DBDictionary extDic = tr.GetObject(btr.ExtensionDictionary, AcDb.OpenMode.ForWrite) as AcDb.DBDictionary;
  59.                 foreach (AcDb.DBDictionaryEntry entry in extDic)
  60.                 {
  61.                     extDic.Remove(entry.Key);
  62.                 }
  63.                 btr.ReleaseExtensionDictionary();
  64.                
  65.                 tr.Commit();
  66.             }
  67.         }
  68.     }
  69. }
  70.  
Блок всё тот же, что приложен к сообщению выше
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Дима_ от 18-02-2015, 20:59:02
Первое, что мне приходило на ум - это после ConvertToStaticBlock - "пробежаться" по всем примитивам блока и "перекопировать" их в тот-же блок с удалением оригинала примитива - не знаю поможет-ли - но что-то мне подсказывает что данный способ будет более "брутален" по части непредвиденных эффектов автокада.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 19-02-2015, 10:17:33
Всё ещё веселее. При удалении extension dictionary блока при работе с базой без открытия документа геометрические ограничения не удаляются. Я заметил, что у примитивов в блоке остаются реакторы,  которые, видимо, отвечают за геометрические ограничения
Дима_, честно говоря да, сомневаюсь, что из этого что-то нормальное получится.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 19-02-2015, 13:26:04
Первый вариант кода тоже не работает? Возможно следует переключать WorkingDatabase на эту базу.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 19-02-2015, 14:12:41
WorkingDatabase переключаю. Первый вариант кода всё также выдает то самое сообщение.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 19-02-2015, 14:18:35
Первый вариант кода всё также выдает то самое сообщение
Но в остальном работает правильно и удаляет параметрику? Если да, то можно попробовать сделать хук, блокирующий появление этого окна. На c++ это совсем не сложно, а в .NET я с этим не сталкивался.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 23-02-2015, 23:42:54
На всякий случай я отправил запрос в ADN DevHelp. Возможно мы что-то не учитываем и есть альтернативные методы как удалить зависимости и не допустить появления этого надоедливого окошка.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 24-02-2015, 09:50:45
Спасибо, будем ждать.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 28-02-2015, 23:01:15
Спасибо, будем ждать.
Они предложили использовать хуки если ничего лучшего не придумают. Я настоятельно попросить что-нибудь придумать. :)
Пока они будут думать я реализовал хуки. Можешь попробовать:

Код - 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 (немецкая, французская, китайская, и т.д.), то придется вставить дополнительные проверки.

Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Дима_ от 01-03-2015, 00:18:35
Я так и не понял зачем городить такие костыли - когда можно, как я уже писал, сделать "чистую" копию, а оригинал просто удалить - ведь на удалении примитива, в отличие от его "очистки" никакого окна не выскакивает.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 01-03-2015, 01:35:06
Дима_
Не всё так просто, как тебе кажется:
1) Как ты собираешься копировать (метод: Clone, DeepClone, DeepCloneObjects)?
2) Что при этом произойдёт с Xdata и Extension Dictionary у скопированных примитивов?
3) К чему приведет потеря XData и Extension Dictionary или их сохранение, но при этом ссылки будут "в молоко"?
4) Как потом обеспечить взаимосвязь ObjectId с полями, если при таком копировании они поменяются?
5) Нужно будет найти все вставки старого блока в чертеже и заменить его на новый - это самое простое из поднятых вопросов.
6) ...
В действительности этот метод может оказаться значительно более сложным, чем показанный мной хук.
 
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 01-03-2015, 23:56:18
bargool
Судя по тому, что ты отметил моё сообщение как Решение, тест прошел успешно?
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: bargool от 02-03-2015, 01:25:02
Прошу прощения, поторопился. Поверить смогу только завтра (в смысле сегодня, но на работе)
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 02-03-2015, 01:31:32
На всякий случай уточню, что я тестировал только в AutoCAD 2014 SP1 x64 Russian и English и в AutoCAD 2015 SP2 x64 Russian и English
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Дмитрий Загорулькин от 02-03-2015, 15:49:47
1) Как ты собираешься копировать (метод: Clone, DeepClone, DeepCloneObjects)?
2) Что при этом произойдёт с Xdata и Extension Dictionary у скопированных примитивов?
3) К чему приведет потеря XData и Extension Dictionary или их сохранение, но при этом ссылки будут "в молоко"?
4) Как потом обеспечить взаимосвязь ObjectId с полями, если при таком копировании они поменяются?
5) Нужно будет найти все вставки старого блока в чертеже и заменить его на новый - это самое простое из поднятых вопросов.
6) ...
В действительности этот метод может оказаться значительно более сложным, чем показанный мной хук.
Можно попробовать создать новый объект, перенести в него свойства из старого и воспользоваться методом DBObject.SwapIdWith.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 02-03-2015, 23:08:28
перенести в него свойства из старого
Тут тоже нужно отслеживать какие свойства переносить, а какие нет. Думаю что и здесь проблем возникнет куча.
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 03-03-2015, 12:18:57
Интересное решение предложили в 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.  
Название: Re: Как удалить параметрику из блоков / вхождений блоков
Отправлено: Александр Ривилис от 03-03-2015, 15:54:16
Итак. Окончательный ответ от ADN DevHelp - хук хоть и не лучший, но единственно доступный вариант при такой постановке задачи.