Как осуществить объединение сетей по именам?

Автор Тема: Как осуществить объединение сетей по именам?  (Прочитано 20949 раз)

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

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Transaction.Commit()

С этим всё в порядке :)
Про Commit я не забыл :)


Цель: «Сеть 2» объединить с «Сеть 1»!

Забыл показать свой код:

Код - C# [Выбрать]
  1.         [Autodesk.AutoCAD.Runtime.CommandMethod("C3D_JOINNETWORKS")]
  2.         public void C3D_JoinNetworks()
  3.         {
  4.             Autodesk.AutoCAD.ApplicationServices.Document adoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             if (adoc == null) return;
  6.             Autodesk.AutoCAD.DatabaseServices.Database db = adoc.Database;
  7.             Autodesk.Civil.ApplicationServices.CivilDocument cdoc = Autodesk.Civil.ApplicationServices.CivilDocument.GetCivilDocument(db);
  8.             Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection netIDs = cdoc.GetPipeNetworkIds();
  9.             List<string> networksNames = new List<string>();
  10.  
  11.             Autodesk.Civil.DatabaseServices.Network fromNetwork = null;
  12.             Autodesk.Civil.DatabaseServices.Network toNetwork = null;
  13.  
  14.             using (Autodesk.AutoCAD.DatabaseServices.Transaction tr = db.TransactionManager.StartTransaction())
  15.             {
  16.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId netId in netIDs)
  17.                 {
  18.                     Autodesk.Civil.DatabaseServices.Network net = (Autodesk.Civil.DatabaseServices.Network)tr.GetObject(netId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
  19.                     networksNames.Add(net.Name);
  20.                     if (net.Name == "Сеть 1")
  21.                     {
  22.                         fromNetwork = net;
  23.                     }
  24.  
  25.                     if (net.Name == "Сеть 2")
  26.                     {
  27.                         toNetwork = net;
  28.                     }
  29.                 }
  30.  
  31.                 Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection pipesFromNetwork = fromNetwork.GetPipeIds();
  32.                 Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection structuresFromNetwork = fromNetwork.GetStructureIds();
  33.  
  34.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId OI in structuresFromNetwork)
  35.                 {
  36.                     pipesFromNetwork.Add(OI);
  37.                 }
  38.  
  39.                 fromNetwork.MoveParts(pipesFromNetwork, toNetwork.ObjectId);
  40.                 tr.Commit();
  41.             }
  42.         }

Получаю: System.ArgumentException: Part does not belong to the network.




Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Ну смотря как получены эти ObjectId.
Цитата: Пашин Евгений от 22-01-2018, 15:11:06
Может быть я их как-то неправильно построил на основе полилинии?
Может быть. Надо код смотреть.

Тут уточню: сети я построил вручную и сохранил чертёж. Сети программно я не создавал.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Код, в целом, в порядке. Но есть один момент, который может быть причиной ошибки. Та сеть, в которую перемещаются объекты, в метод передаётся по ObjectId. Значит, надо чтобы в момент запуска метода эта сеть не была открыта. А она открыта, да ещё и на запись. Вполне может быть, что это блокирует добавление в неё элементов. Надо переделать код таким образом, чтобы в момент вызова метода сеть-приёмник была закрыта.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Код, в целом, в порядке. Но есть один момент, который может быть причиной ошибки. Та сеть, в которую перемещаются объекты, в метод передаётся по ObjectId. Значит, надо чтобы в момент запуска метода эта сеть не была открыта. А она открыта, да ещё и на запись. Вполне может быть, что это блокирует добавление в неё элементов. Надо переделать код таким образом, чтобы в момент вызова метода сеть-приёмник была закрыта.

То есть одну сеть нужно открыть в транзакции на чтение, а вторую на запись. Интересно. Попробую.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Может сработает, но лучше вообще вторую сеть не открывать в момент работы метода передачи элементов.
Это можно сделать разными способами. Например - использовать две отдельные транзакции. Первая - для поиска ObjectId нужных сетей, вторая - для работы с сетью-источником.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Может сработает, но лучше вообще вторую сеть не открывать в момент работы метода передачи элементов.

Даже на чтение? Попробую.

Это можно сделать разными способами. Например - использовать две отдельные транзакции. Первая - для поиска ObjectId нужных сетей, вторая - для работы с сетью-источником.

Попробую и отпишусь.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Даже на чтение? Попробую.

Увы, пока ничего не изменилось. Всё та же ошибка.

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Хм... Можно глянуть итоговый код? Попробую у себя.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Хм... Можно глянуть итоговый код? Попробую у себя.

Да, Дмитрий.

Код - C# [Выбрать]
  1.         [Autodesk.AutoCAD.Runtime.CommandMethod("C3D_JoinNetworks")]
  2.         public void Civil_Join_Networks()
  3.         {
  4.             Autodesk.AutoCAD.ApplicationServices.Document adoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             if (adoc == null)
  6.                 return;
  7.             Autodesk.AutoCAD.DatabaseServices.Database db = adoc.Database;
  8.             Autodesk.Civil.ApplicationServices.CivilDocument cdoc = Autodesk.Civil.ApplicationServices.CivilDocument.GetCivilDocument(db);
  9.             Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection netIDs = cdoc.GetPipeNetworkIds();
  10.             List<string> networksNames = new List<string>();
  11.             Autodesk.Civil.DatabaseServices.Network fromNetwork = null;
  12.             Autodesk.Civil.DatabaseServices.Network toNetwork = null;
  13.             Autodesk.AutoCAD.DatabaseServices.ObjectId toNetworkObjectId = new Autodesk.AutoCAD.DatabaseServices.ObjectId();
  14.             Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection AllMovedPartsObjIds = null;
  15.             using (Autodesk.AutoCAD.DatabaseServices.Transaction tr = db.TransactionManager.StartTransaction())
  16.             {
  17.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId netId in netIDs)
  18.                 {
  19.                     Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr.GetObject(netId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
  20.                     networksNames.Add(net.Name);
  21.                     if (net.Name == "Сеть 1")
  22.                     {
  23.                         fromNetwork = net;
  24.                     }
  25.  
  26.                     if (net.Name == "Сеть 2")
  27.                     {
  28.                         toNetwork = net;
  29.                         toNetworkObjectId = toNetwork.ObjectId;
  30.                     }
  31.                 }
  32.  
  33.                 Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection pipesFromNetwork = fromNetwork.GetPipeIds();
  34.                 Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection structuresFromNetwork = fromNetwork.GetStructureIds();
  35.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId OI in pipesFromNetwork)
  36.                 {
  37.                     AllMovedPartsObjIds.Add(OI);
  38.                 }
  39.  
  40.                 foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId OI in structuresFromNetwork)
  41.                 {
  42.                     AllMovedPartsObjIds.Add(OI);
  43.                 }
  44.  
  45.                 tr.Commit();
  46.             }
  47.  
  48.             using (Autodesk.AutoCAD.DatabaseServices.Transaction tr2 = db.TransactionManager.StartTransaction())
  49.             {
  50.                 Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr2.GetObject(toNetworkObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
  51.                 net.MoveParts(AllMovedPartsObjIds, toNetworkObjectId);
  52.                 tr2.Commit();
  53.             }
  54.  
  55.             Autodesk.AutoCAD.EditorInput.Editor ed = adoc.Editor;
  56.             foreach (string netName in networksNames)
  57.             {
  58.                 ed.WriteMessage(netName + "; ");
  59.             }
  60.         }


Такое ощущение, что есть какая-то проблема с самими ObjectId труб и колодцев... Но я могу ошибаться. Без отладки мне трудно судить.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Пашин Евгений,
Мне кажется, что здесь какая-то глупость написана:
Код - C# [Выбрать]
  1.                 Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr2.GetObject(toNetworkObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
  2.                 net.MoveParts(AllMovedPartsObjIds, toNetworkObjectId);
Ты же должен переносить из fromNetworkObjectId в toNetworkObjectId, а у тебя фактически и там и там toNetworkObjectId. Как так???
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Ты же должен переносить из fromNetworkObjectId в toNetworkObjectId, а у тебя фактически и там и там toNetworkObjectId. Как так???

Согласен. Что-то не то. Но я пробовал и с разными ObjectId, результат был тот же.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
AllMovedPartsObjIds

Все эти объекты и есть из fromNetworkObjectId.

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
Пашин Евгений,
Мне кажется, что здесь какая-то глупость написана:
Код - C# [Выбрать]
                Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr2.GetObject(toNetworkObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite);
                net.MoveParts(AllMovedPartsObjIds, toNetworkObjectId);
Ты же должен переносить из fromNetworkObjectId в toNetworkObjectId, а у тебя фактически и там и там toNetworkObjectId. Как так???

Согласен, что это кусок кода может сам себе противоречить, но пока не нашёл иного варианта.

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Согласен, что это кусок кода может сам себе противоречить, но пока не нашёл иного варианта.
Шутишь???

Код - C# [Выбрать]
  1. [Autodesk.AutoCAD.Runtime.CommandMethod("C3D_JoinNetworks")]
  2. public void Civil_Join_Networks()
  3. {
  4.     Autodesk.AutoCAD.ApplicationServices.Document adoc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.     if (adoc == null)
  6.         return;
  7.     Autodesk.AutoCAD.DatabaseServices.Database db = adoc.Database;
  8.     Autodesk.Civil.ApplicationServices.CivilDocument cdoc = Autodesk.Civil.ApplicationServices.CivilDocument.GetCivilDocument(db);
  9.     Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection netIDs = cdoc.GetPipeNetworkIds();
  10.     List<string> networksNames = new List<string>();
  11.     Autodesk.Civil.DatabaseServices.Network fromNetwork = null;
  12.     Autodesk.Civil.DatabaseServices.Network toNetwork = null;
  13.     Autodesk.AutoCAD.DatabaseServices.ObjectId toNetworkObjectId = new Autodesk.AutoCAD.DatabaseServices.ObjectId();
  14.     Autodesk.AutoCAD.DatabaseServices.ObjectId fromNetworkObjectId = new Autodesk.AutoCAD.DatabaseServices.ObjectId();
  15.     Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection AllMovedPartsObjIds = null;
  16.     using (Autodesk.AutoCAD.DatabaseServices.Transaction tr = db.TransactionManager.StartTransaction())
  17.     {
  18.         foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId netId in netIDs)
  19.         {
  20.             Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr.GetObject(netId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
  21.             networksNames.Add(net.Name);
  22.             if (net.Name == "Сеть 1")
  23.             {
  24.                 fromNetwork = net;
  25.                 fromNetworkObjectId = net.ObjectId;
  26.             }
  27.  
  28.             if (net.Name == "Сеть 2")
  29.             {
  30.                 toNetwork = net;
  31.                 toNetworkObjectId = toNetwork.ObjectId;
  32.             }
  33.         }
  34.  
  35.         Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection pipesFromNetwork = fromNetwork.GetPipeIds();
  36.         Autodesk.AutoCAD.DatabaseServices.ObjectIdCollection structuresFromNetwork = fromNetwork.GetStructureIds();
  37.         foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId OI in pipesFromNetwork)
  38.         {
  39.             AllMovedPartsObjIds.Add(OI);
  40.         }
  41.  
  42.         foreach (Autodesk.AutoCAD.DatabaseServices.ObjectId OI in structuresFromNetwork)
  43.         {
  44.             AllMovedPartsObjIds.Add(OI);
  45.         }
  46.  
  47.         tr.Commit();
  48.     }
  49.  
  50.     using (Autodesk.AutoCAD.DatabaseServices.Transaction tr2 = db.TransactionManager.StartTransaction())
  51.     {
  52.         Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr2.GetObject(fromNetworkObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
  53.         net.MoveParts(AllMovedPartsObjIds, toNetworkObjectId);
  54.         tr2.Commit();
  55.     }
  56.  
  57.     Autodesk.AutoCAD.EditorInput.Editor ed = adoc.Editor;
  58.     foreach (string netName in networksNames)
  59.     {
  60.         ed.WriteMessage(netName + "; ");
  61.     }
  62. }

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

Оффлайн Пашин ЕвгенийАвтор темы

  • ADN PRO
  • *
  • Сообщений: 662
  • Карма: 12
  • Skype: pashin.evgeniy
    using (Autodesk.AutoCAD.DatabaseServices.Transaction tr2 = db.TransactionManager.StartTransaction())
    {
        Autodesk.Civil.DatabaseServices.Network net =(Autodesk.Civil.DatabaseServices.Network) tr2.GetObject(fromNetworkObjectId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead);
        net.MoveParts(AllMovedPartsObjIds, toNetworkObjectId);
        tr2.Commit();
    }

По моему эта конструкция у меня не сработала, но я попробую весь Ваш код. Отпишусь.