Удаление всех внешних ссылок

Автор Тема: Удаление всех внешних ссылок  (Прочитано 18426 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #15 : 28-11-2018, 15:04:55 »
опа! вот это здорово! спасибо!

второй вопрос еще актуален

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Удаление всех внешних ссылок
« Ответ #16 : 28-11-2018, 15:06:59 »
а вот если проходить по BlockTable, то мне нужно открывать по ObjectId каждый btr и проверять что это внешняя ссылка?
второй вопрос еще актуален
А какие ещё есть варианты? Вроде как, иного пути нет.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #17 : 28-11-2018, 15:16:03 »
А кто-то в теме спрашивал про слой? Как нибудь определись с тем, что тебе нужно.
мне нужно удалить то все! но если они лежат в заблокированном слое, то его нужно разблокировать сначала. а для этого узнать что за слой! так ведь?

а вот если проходить по BlockTable, то мне нужно открывать по ObjectId каждый btr и проверять что это внешняя ссылка?
Тут я бы рекомендовал запомнить состояние слоёв и все разблокировать, выполнить удаление внешних ссылок а затем восстановить состояние слоёв.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #18 : 28-11-2018, 15:17:20 »
что то не нашел у btr соответствующих свойств, кроме статуса внешней ссылки. как определить что это внешняя ссылка(любая)? неужели перебирать все статусы в условии?
можно не отвечать.. понял
« Последнее редактирование: 28-11-2018, 16:03:49 от simson43 »

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #19 : 28-11-2018, 15:27:20 »
IsFromExternalReference
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #20 : 28-11-2018, 15:33:17 »
это не то же самое?
Код - C# [Выбрать]
  1. if (btrXRef.XrefStatus != XrefStatus.NotAnXref)
« Последнее редактирование: 28-11-2018, 16:04:01 от simson43 »

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #21 : 28-11-2018, 16:26:13 »
а вот сейчас я окончательно запутался.
попробовал просто найти все BlockTableRecord внешних ссылок и удалил. без обратки слоев. и он удалил даже в заблокированном!
так и долнжо быть? изначально он так не мог.
причем без этого
соответствующей опцией forceOpenOnLockedLayer

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Re: Удаление всех внешних ссылок
« Ответ #22 : 28-11-2018, 16:36:00 »
попробовал просто найти все BlockTableRecord внешних ссылок и удалил. без обратки слоев. и он удалил даже в заблокированном!
так и долнжо быть?
Ну так удалены же были определения блоков. Это не графические объекты, они не располагаются на слоях. А до этого, наверное, удалялись вставки блоков - это уже графические объекты, которые могут располагаться на слоях. Удивительно, что удаление определения блока при наличии в чертеже вставок происходит без ошибок. Я бы расценивал это как подарок от API :)

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #23 : 28-11-2018, 16:39:58 »
я и в прошлый раз "детачил" внешние ссылки, а не удалял вставки.. но как ты напоролся на ошибку из-за слоя...
может я опять что то путаю - не исключено

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #24 : 28-11-2018, 19:56:29 »
Я проверил этот код в AutoCAD 2019:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System.Collections.Generic;
  6.  
  7. #pragma warning disable 0618
  8.  
  9. // This line is not mandatory, but improves loading performances
  10. [assembly: CommandClass(typeof(Rivilis.ScanXrefs))]
  11.  
  12. namespace Rivilis
  13. {
  14.   public class ScanXrefs
  15.   {
  16.     [CommandMethod("RemoveAllXrefs")]
  17.     public void RemoveAllXrefs()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Editor ed = doc.Editor;
  22.       Database db = doc.Database;
  23.       List<ObjectId> idsXref = new List<ObjectId>();
  24.       using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
  25.       {
  26.         foreach (ObjectId idBtr in bt)
  27.         {
  28.           using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
  29.           {
  30.             if (btr.IsFromExternalReference)
  31.               idsXref.Add(idBtr);
  32.           }
  33.         }
  34.       }
  35.       foreach (ObjectId idBtr in idsXref)
  36.         db.DetachXref(idBtr);
  37.     }
  38.   }
  39. }

Он удаляет все вставки внешних ссылок, а затем и описания блоков внешних ссылок, если вставки непосредственно в модели/листе. Но если они внутри блока, то мы видим сообщение:
Цитировать
Xref 1 has multiple references. Not detached.
Так что правильно сначала удалить все вставки внешних ссылок, а затем уже их "детачить" внешние ссылки.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #25 : 28-11-2018, 20:23:51 »
Вот так должно быть универсальнее. Потестируй:

Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System.Collections.Generic;
  6.  
  7. #pragma warning disable 0618
  8.  
  9. // This line is not mandatory, but improves loading performances
  10. [assembly: CommandClass(typeof(Rivilis.ScanXrefs))]
  11.  
  12. namespace Rivilis
  13. {
  14.   public class ScanXrefs
  15.   {
  16.     [CommandMethod("RemoveAllXrefs")]
  17.     public void RemoveAllXrefs()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Editor ed = doc.Editor;
  22.       Database db = doc.Database;
  23.       List<ObjectId> idsXref = new List<ObjectId>(); // Внешние ссылки
  24.       List<ObjectId> idsLocked = new List<ObjectId>(); // Блокированные слои
  25.       // Отбираем блокированные слои и сразу их разблокируем
  26.       using (LayerTable lt = db.LayerTableId.Open(OpenMode.ForRead) as LayerTable)
  27.       {
  28.         foreach (ObjectId idLay in lt)
  29.         {
  30.           using (LayerTableRecord ltr = idLay.Open(OpenMode.ForRead) as LayerTableRecord)
  31.           {
  32.             if (ltr.IsLocked)
  33.             {
  34.               ltr.UpgradeOpen();
  35.               ltr.IsLocked = false;
  36.               idsLocked.Add(idLay);
  37.             }
  38.           }
  39.         }
  40.       }
  41.       // Отбираем внешние ссылки
  42.       using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
  43.       {
  44.         foreach (ObjectId idBtr in bt)
  45.         {
  46.           using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
  47.           {
  48.             if (btr.IsFromExternalReference)
  49.               idsXref.Add(idBtr);
  50.           }
  51.         }
  52.       }
  53.       // Удаляем внешние ссылки
  54.       foreach (ObjectId idBtr in idsXref)
  55.       {
  56.         using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
  57.         {
  58.           // Находим все вставки внешних ссылок и удаляем их
  59.           ObjectIdCollection idsBrefs = btr.GetBlockReferenceIds(false, true);
  60.           foreach (ObjectId idBref in idsBrefs)
  61.             using (DBObject bref = idBref.Open(OpenMode.ForWrite))
  62.               bref.Erase();
  63.         }
  64.         // Удаляем саму внешнюю ссылку
  65.         db.DetachXref(idBtr);
  66.       }
  67.       // Блокируем слои, которые были заблокированы до запуска команды
  68.       // но небыли удалены при удалении внешних ссылок
  69.       foreach (ObjectId idLay in idsLocked)
  70.           if (!idLay.IsErased)
  71.           using (LayerTableRecord ltr = idLay.Open(OpenMode.ForWrite) as LayerTableRecord)
  72.             ltr.IsLocked = true;
  73.     }
  74.   }
  75. }
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #26 : 28-11-2018, 20:32:31 »
Ну и по подсказке Дмитрий Загорулькин можно сократить код на сохранение/восстановление блокировки слоёв:
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5. using System.Collections.Generic;
  6.  
  7. #pragma warning disable 0618
  8.  
  9. // This line is not mandatory, but improves loading performances
  10. [assembly: CommandClass(typeof(Rivilis.ScanXrefs))]
  11.  
  12. namespace Rivilis
  13. {
  14.   public class ScanXrefs
  15.   {
  16.     [CommandMethod("RemoveAllXrefs")]
  17.     public void RemoveAllXrefs()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       if (doc == null) return;
  21.       Editor ed = doc.Editor;
  22.       Database db = doc.Database;
  23.       List<ObjectId> idsXref = new List<ObjectId>(); // Внешние ссылки
  24.  
  25.       // Отбираем внешние ссылки
  26.       using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
  27.       {
  28.         foreach (ObjectId idBtr in bt)
  29.         {
  30.           using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
  31.           {
  32.             if (btr.IsFromExternalReference)
  33.               idsXref.Add(idBtr);
  34.           }
  35.         }
  36.       }
  37.       // Удаляем внешние ссылки
  38.       foreach (ObjectId idBtr in idsXref)
  39.       {
  40.         using (BlockTableRecord btr = idBtr.Open(OpenMode.ForRead) as BlockTableRecord)
  41.         {
  42.           // Находим все вставки внешних ссылок и удаляем их
  43.           ObjectIdCollection idsBrefs = btr.GetBlockReferenceIds(false, true);
  44.           foreach (ObjectId idBref in idsBrefs)
  45.             // Открываем с учетом возможных блокированных слоёв
  46.             using (DBObject bref = idBref.Open(OpenMode.ForWrite,false,true))
  47.               bref.Erase();
  48.         }
  49.         // Удаляем саму внешнюю ссылку
  50.         db.DetachXref(idBtr);
  51.       }
  52.     }
  53.   }
  54. }

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

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #27 : 28-11-2018, 22:20:03 »
Но если они внутри блока

Вы имеете ввиду именно блок? Не внутри другой внешней ссылки?
Если первое то не встречал такого.

Еще что примечательно, если перебирать XrefGraph, там хранятся удаленные внешние ссылки и тогда при попытке удалить вылетает исключение, при переборе BlockTable такой беды нет, поэтому я остановился на похожем на первый ваш вариант.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Удаление всех внешних ссылок
« Ответ #28 : 28-11-2018, 22:25:23 »
Вы имеете ввиду именно блок? Не внутри другой внешней ссылки?
Если первое то не встречал такого.
Именно в блоке. Запускаешь команду БЛОК (_BLOCK), выделяешь внешнюю ссылку (можешь еще что-то выбрать  - не важно). Вот у тебя вставка внешней ссылки в блоке. Вообще-то вложенность может быть любой.
Еще что примечательно, если перебирать XrefGraph, там хранятся удаленные внешние ссылки и тогда при попытке удалить вылетает исключение
Проверять нужно удалена или нет...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 411
  • Карма: 9
Re: Удаление всех внешних ссылок
« Ответ #29 : 28-11-2018, 23:36:26 »
Ну да можно и так.
 Александр Ривилис, Дмитрий Загорулькин, Спасибо за ответы!