Получить относительный путь для вложенной внешней ссылки

Автор Тема: Получить относительный путь для вложенной внешней ссылки  (Прочитано 6270 раз)

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Здравствуйте!


Посмотрите, пожалуйста, на картинку. Это скриншот окна диспетчера внешних ссылок AutoCAD.
Есть внешняя ссылка, вложенная в другую внешнюю ссылку - "АД_Петров". Эта внешняя ссылка подключена по относительному пути. Мне нужно получить этот относительный путь. Внизу окна это свойство "Saved Path".
Свойство BlockTableRecord.PathName в этом случае возвращает абсолютный путь как он записан в диспетчере внешних ссылок в свойстве "Found at". Ниже пример кода для вывода путей всех вложенных внешних ссылок с помощью свойства BlockTableRecord.PathName.

Код - C# [Выбрать]
  1.         [CommandMethod( "GetRelativePathTest", CommandFlags.Modal)]
  2.         public static void GetRelativePathCommand()
  3.         {
  4.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  5.             if (adoc == null) return;
  6.  
  7.             Database db = adoc.Database;
  8.  
  9.             Editor ed = adoc.Editor;
  10.  
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 using (XrefGraph xg = db.GetHostDwgXrefGraph(false))
  14.                 {
  15.                     for (int index = 1; index < xg.NumNodes; ++index)
  16.                     {
  17.                         using (XrefGraphNode node = xg.GetXrefNode(index))
  18.                         {
  19.                             if (node.IsNested)
  20.                             {
  21.                                 BlockTableRecord btr = tr.GetObject(node.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
  22.  
  23.                                 ed.WriteMessage("\n"+btr.PathName);
  24.                             }
  25.                         }
  26.                     }
  27.                 }
  28.  
  29.  
  30.                 tr.Commit();
  31.             }
  32.         }
  33.  
  34.  

Подскажите, пожалуйста, как получить относительный путь или как определить, что внешняя ссылка подключена относительным путем?


Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Так.
Сейчас проверил на другом чертеже - возвращается относительный путь как мне и надо.
Постараюсь выяснить в чем дело.

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Разобрался.
Надо уточнить:  BlockTableRecord.PathName возвращает относительный путь, но только если текущий чертеж и  внешняя ссылка находятся в одном логическом диске. То есть относительный путь высчитывается относительно текущего чертежа, а не относительно предыдущего узла дерева внешних ссылок.

Все-таки есть ли возможность получить "Saved path", как он отображается в диспетчере внешних ссылок?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis


Код - C# [Выбрать]
  1. [CommandMethod("GetRelativePathTest", CommandFlags.Modal)]
  2. public static void GetRelativePathCommand()
  3. {
  4.   Document adoc = Application.DocumentManager.MdiActiveDocument;
  5.   if (adoc == null) return;
  6.  
  7.   Database db = adoc.Database;
  8.  
  9.   Editor ed = adoc.Editor;
  10.  
  11.   using (XrefGraph xg = db.GetHostDwgXrefGraph(false))
  12.   {
  13.     for (int index = 1; index < xg.NumNodes; ++index)
  14.     {
  15.       using (XrefGraphNode node = xg.GetXrefNode(index))
  16.       {
  17.         using (Transaction tr = db.TransactionManager.StartTransaction())
  18.         {
  19.           BlockTableRecord btr = tr.GetObject(node.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
  20.           ed.WriteMessage("\nPath: " + btr.PathName);
  21.           ed.WriteMessage("\nOriginalPath: " + btr.GetXrefDatabase(false).OriginalFileName);
  22.           tr.Commit();
  23.         }
  24.       }
  25.     }
  26.   }
  27. }
  28.  
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

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

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Спасибо большое, Александр!
 :D :D :D

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Ой, OriginalFileName это не то! Он возвращает всегда полный путь к чертежу. Я не так понял.



Еще раз посмотрите картинку. Текущий чертеж 1.dwg находится на диске C. К нему подсоединен чертеж 4.dwg по абсолютному пути с диска D. А к чертежу 4.dwg подсоединен чертеж 5.dwg по относительному пути. В диспетчере в разделе Подробности (Details) показано свойство Сохраненный путь (Saved Path).

Можно ли как-то из текущего чертежа 1.dwg получить эту строку, как она отображается в диспетчере ".\5\5.dwg"?

Отмечено как Решение Кирилл Захаров 25-09-2017, 16:40:24

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Можно ли как-то из текущего чертежа 1.dwg получить эту строку, как она отображается в диспетчере ".\5\5.dwg"?
Похоже для это нет API. Точнее для этого следует отдельно открыть базу данных Xref и из неё уже получить btr.PathName. Но это настолько громоздко, что яне вижу смысла в это лезть.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
для этого следует отдельно открыть базу данных Xref и из неё уже получить btr.PathName
Я попробую так сделать.

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5

Если я правильно вас понял, такой способ тоже не прокатывает. Привожу свой тестовый код:
Код - C# [Выбрать]
  1.         [CommandMethod( "GetRelativePathTest", CommandFlags.Modal)]
  2.         public static void GetRelativePathCommand()
  3.         {
  4.             Document adoc = Application.DocumentManager.MdiActiveDocument;
  5.             if (adoc == null) return;
  6.  
  7.             Database db = adoc.Database;
  8.  
  9.             Editor ed = adoc.Editor;
  10.  
  11.             using (Transaction tr = db.TransactionManager.StartTransaction())
  12.             {
  13.                 using (XrefGraph xg = db.GetHostDwgXrefGraph(false))
  14.                 {
  15.                     for (int index = 1; index < xg.NumNodes; ++index)
  16.                     {
  17.                         using (XrefGraphNode node = xg.GetXrefNode(index))
  18.                         {
  19.                             if (node.IsNested)
  20.                             {
  21.                                 BlockTableRecord btr = tr.GetObject(node.BlockTableRecordId, OpenMode.ForRead) as BlockTableRecord;
  22.                                 //Получить имя внешней ссылки
  23.                                 string btrName = btr.Name;
  24.  
  25.                                 //Получить базу данных внешней ссылки, в которую она вложена
  26.                                 XrefGraphNode nodeIn = (XrefGraphNode)node.In(0);
  27.                                 Database dbIn = nodeIn.Database;
  28.  
  29.                                 //Найти в этой базе соответствующий BlockTableRecord
  30.                                 using (Transaction trIn = dbIn.TransactionManager.StartTransaction())
  31.                                 {
  32.                                     BlockTable btIn = trIn.GetObject(dbIn.BlockTableId, OpenMode.ForRead) as BlockTable;
  33.  
  34.                                     BlockTableRecord btr1 = trIn.GetObject(btIn[btrName], OpenMode.ForRead) as BlockTableRecord;
  35.  
  36.                                     ed.WriteMessage("\nbtr1 Path: " + btr1.PathName);
  37.                                     ed.WriteMessage("\nbtr Path: " + btr.PathName+ "\n");//Получаются одинаковые пути
  38.  
  39.  
  40.                                     trIn.Commit();
  41.                                 }
  42.  
  43.                             }
  44.                         }
  45.                     }
  46.                 }
  47.  
  48.  
  49.                 tr.Commit();
  50.             }
  51.         }
  52.  

В итоге, как бы мы не получали соответствующий BlockTableRecord, свойство PathName остается одинаковым

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

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

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Вы имели в виду использовать метод ReadDwgFile?
Это действительно слишком громоздко

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Вы имели в виду использовать метод ReadDwgFile?
Да. Именно так. При работе с внешними ссылками ты работаешь с копиями баз данных. В них уже пути исправлены. Поэтому следует работать с оригинальными базами, т.е. читать их через ReadDwgFile.
Я вообще не понимаю зачем это всё тебе нужно. А когда я не понимаю, то мне сложно чем-то помочь...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Я вообще не понимаю зачем это всё тебе нужно
Сейчас я уже решил эту проблему по-другому.
Но желательно найти способ как определить была ли внешняя ссылка подключена относительной ссылкой или абсолютной, а сам путь уже не так важен.

Оффлайн Кирилл ЗахаровАвтор темы

  • ADN OPEN
  • ***
  • Сообщений: 119
  • Карма: 5
Там много нюансов. Трудно объяснить конкретнее...