Копирование COGOPOINT из внешних ссылок.

Автор Тема: Копирование COGOPOINT из внешних ссылок.  (Прочитано 18320 раз)

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

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Добрый день. У меня имеется чертеж, в котором вставлена внешняя ссылка. Ссылка представляет собой набор линий и copopoint'ов. У меня написан метод, который позволяет копировать объекты из внешних ссылок. Проблема заключается в том, что после копировании cogopoint'ов они становятся невидимыми на чертеже, хотя в базу данных чертежа  они успешно добавляются. Линии при этом копируются и отображаются нормально.  Не могу разобраться, в чем тут проблема.
ПО проверяется на  Civil 3D 2015.
Ниже привожу скриншоты чертежа и код методов копирования объектов.
1. Состояния чертежа до копирования объектов из внешних ссылок.


2. Состояние чертежа после копирования объектов из внешних ссылок.

На рис. 2 видно, что cogopoint'ы (зеленые крестики) не видны на чертеже.

3.Методы осуществляющий копирование объектов из внешних ссылок.

Код - C# [Выбрать]
  1.                  /// <summary>
  2.                 /// Запуск копирования объектов из внешней ссылки.
  3.                 /// </summary>
  4.                 public void Execute()
  5.                 {
  6.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  7.                         _db = doc.Database;
  8.                         var layers = new List<string>();
  9.  
  10.                         var isSucsess = true;
  11.  
  12.                         _formProgress = new FormProgressBar(null) { Text = @"Копирование объектов" };
  13.                         System.Windows.Forms.Application.DoEvents();
  14.                         Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(_formProgress);
  15.                         System.Windows.Forms.Application.DoEvents();
  16.  
  17.                         using (_trans = _db.TransactionManager.StartTransaction())
  18.                         using (var bt = (BlockTable)_trans.GetObject(_db.BlockTableId, OpenMode.ForWrite))
  19.                         using (_btr = (BlockTableRecord)_trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
  20.                         {
  21.                                 // Получаем наименование всех слоев.
  22.                                 var layerTable = (LayerTable)_trans.GetObject(doc.Database.LayerTableId, OpenMode.ForWrite);
  23.                                 foreach (var layerObjId in layerTable)
  24.                                 {
  25.                                         using (var layer = (LayerTableRecord)_trans.GetObject(layerObjId, OpenMode.ForRead))
  26.                                         {
  27.                                                 if (!layer.IsFrozen && !layer.IsOff)
  28.                                                 {
  29.                                                         layers.Add(layer.Name);
  30.                                                 }
  31.                                         }
  32.                                 }
  33.  
  34.                                 // Вытягиваем внешние ссылки.
  35.                                 var acadReferenceTree = Tap.CADGIS.AutoCAD.Utils.AcadReferenceTree.Create(doc);
  36.                                 acadReferenceTree.Build();
  37.                                 var nodes = acadReferenceTree.Nodes.Where(n => n.Type == AcadReferenceType.DRAWING && n.Database != null).ToList();
  38.                                 if (nodes.Count == 0)
  39.                                 {
  40.                                         MessageBox.Show("Документ не содержит внешних ссылок", "Внимание", MessageBoxButton.OK, MessageBoxImage.Warning);
  41.                                         _formProgress.Dispose();
  42.                                         return;
  43.                                 }
  44.  
  45.                                 layers.AddRange(nodes.Select(p => p.Name + "|0"));
  46.                                 foreach (var objId in _btr)
  47.                                 {
  48.                                         using (var ent = (Entity)_trans.GetObject(objId, OpenMode.ForWrite))
  49.                                         {
  50.  
  51.                                                 // Проверка элемента по игнор-листу
  52.                                                 if (ent.IsErased || ent is ProxyEntity || !ent.Visible || ent.GetType().ToString().Contains("Site"))
  53.                                                         continue;
  54.                                                 try
  55.                                                 {
  56.                                                         // Если объект блок референс
  57.                                                         var bref = ent as BlockReference;
  58.                                                         if (bref != null)
  59.                                                         {
  60.                                                                 // является ли объект внешней ссылкой
  61.                                                                 var isExternalRef = nodes.Any(p => p.Name.Equals(bref.Name));
  62.  
  63.                                                                 if (isExternalRef && !layers.Contains(bref.Layer))
  64.                                                                         continue;
  65.  
  66.                                                                 // Получаем объекты из внешних ссылок
  67.                                                                 var bferEntities = Tap.CADGIS.AutoCAD.Instruments.AcadEntityInstruments.GetEntityFromBlockReference(bref, layers);
  68.  
  69.                                                                 // Добавляем объекты в базу
  70.                                                                 AddEntitiesToBTR(bferEntities, isExternalRef, layers);
  71.  
  72.                                                                 // Скрываем внеш. ссылку.
  73.                                                                 bref.Visible = false;
  74.                                                                 //bref.Erase(true);
  75.                                                         }
  76.                                                 }
  77.                                                 catch
  78.                                                 {
  79.                                                         isSucsess = false;
  80.                                                 }
  81.                                         }
  82.                                 }
  83.  
  84.                                 _formProgress.SetMessage(100, string.Empty);
  85.                                 if (!isSucsess)
  86.                                         MessageBox.Show("Копирование объектов произошло с ошибкой", "Копирование", MessageBoxButton.OK, MessageBoxImage.Error);
  87.                                 else
  88.                                 {
  89.                                         doc.Editor.Regen();
  90.                                         _trans.Commit();
  91.                                         MessageBox.Show("Объекты успешно скопированы", "Копирование", MessageBoxButton.OK, MessageBoxImage.Information);
  92.                                 }
  93.  
  94.                                 if (_formProgress != null && !_formProgress.IsDisposed)
  95.                                 {
  96.                                         _formProgress.Dispose();
  97.                                 }
  98.                         }
  99.                 }
  100.  
  101.                 /// <summary>
  102.                 /// Добавление объектов в бд чертежа.
  103.                 /// </summary>
  104.                 /// <param name="bferEntities"></param>
  105.                 /// <param name="isExternalRef"></param>
  106.                 /// <param name="layers"></param>
  107.                 private void AddEntitiesToBTR(List<Entity> bferEntities, bool isExternalRef, List<string> layers)
  108.                 {
  109.                         var oldPercent = 0;
  110.                         var i = 0;
  111.  
  112.                         foreach (var brefEntity in bferEntities)
  113.                         {
  114.                                 if (brefEntity.Database == null)
  115.                                         brefEntity.SetDatabaseDefaults(_db);
  116.  
  117.                                 if (brefEntity is MLeader && brefEntity.Database == null)
  118.                                         continue;
  119.  
  120.                                 if (isExternalRef && !layers.Contains(brefEntity.Layer))
  121.                                         continue;
  122.  
  123.                                 if (!layers.Contains(brefEntity.Layer))
  124.                                         continue;
  125.  
  126.                                 // обновляем прогресс бар
  127.                                 if (++i * 100 / bferEntities.Count != oldPercent)
  128.                                 {
  129.                                         oldPercent = ++i * 100 / bferEntities.Count;
  130.                                         _formProgress.SetMessage(oldPercent, string.Empty);
  131.                                 }
  132.  
  133.                                 _btr.AppendEntity(brefEntity);
  134.                                 _trans.AddNewlyCreatedDBObject(brefEntity, true);
  135.                         }
  136.                 }
  137.  

4. Скриншоты при обнаружении cogopoint в коде.





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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
1. Что происходит если этот чертеж сохранить, закрыть и снова открыть?
2. Функции копирования неудачные. Для полного копирования объектов (и всего, что с ними связано) между чертежами следует использовать метод Database.WblockCloneObjects.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Насколько я помню Civil, то там есть группы точек и стили отображения. Может ваши точки нормально копируются, просто в самом чертеже не настроено их отображение?

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
1. Что происходит если этот чертеж сохранить, закрыть и снова открыть?
2. Функции копирования неудачные. Для полного копирования объектов (и всего, что с ними связано) между чертежами следует использовать метод Database.WblockCloneObjects.
Хорошо, сейчас попробую предложенные вами способы и отпишусь.

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
1. При закрытии и открытии документа стилизованные линии тоже не отображаются.
2. Переписал метод с использованием Database.WblockCloneObjects.
Код - C# [Выбрать]
  1.                  /// <summary>
  2.                 /// Запуск инструмента.
  3.                 /// </summary>
  4.                 [CommandMethod(Constants.CommandNames.ExtractObjects, CommandFlags.Modal)]
  5.                 public void Execute()
  6.                 {
  7.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  8.                         _db = doc.Database;
  9.                         var layers = new List<string>();
  10.  
  11.                         var isSucsess = true;
  12.  
  13.                         _formProgress = new FormProgressBar(null) { Text = @"Копирование объектов" };
  14.                         System.Windows.Forms.Application.DoEvents();
  15.                         Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(_formProgress);
  16.                         System.Windows.Forms.Application.DoEvents();
  17.  
  18.                         using (_trans = _db.TransactionManager.StartTransaction())
  19.                         using (var bt = (BlockTable)_trans.GetObject(_db.BlockTableId, OpenMode.ForWrite))
  20.                         using (_btr = (BlockTableRecord)_trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
  21.                         {
  22.                                 // Получаем наименование всех слоев.
  23.                                 var layerTable = (LayerTable)_trans.GetObject(doc.Database.LayerTableId, OpenMode.ForWrite);
  24.                                 foreach (var layerObjId in layerTable)
  25.                                 {
  26.                                         using (var layer = (LayerTableRecord)_trans.GetObject(layerObjId, OpenMode.ForRead))
  27.                                         {
  28.                                                 if (!layer.IsFrozen && !layer.IsOff)
  29.                                                 {
  30.                                                         layers.Add(layer.Name);
  31.                                                 }
  32.                                         }
  33.                                 }
  34.  
  35.                                 // Вытягиваем внешние ссылки.
  36.                                 var acadReferenceTree = Tap.CADGIS.AutoCAD.Utils.AcadReferenceTree.Create(doc);
  37.                                 acadReferenceTree.Build();
  38.                                 var nodes = acadReferenceTree.Nodes.Where(n => n.Type == AcadReferenceType.DRAWING && n.Database != null).ToList();
  39.                                 if (nodes.Count == 0)
  40.                                 {
  41.                                         MessageBox.Show("Документ не содержит внешних ссылок", "Внимание", MessageBoxButton.OK, MessageBoxImage.Warning);
  42.                                         _formProgress.Dispose();
  43.                                         return;
  44.                                 }
  45.  
  46.                                 layers.AddRange(nodes.Select(p => p.Name + "|0"));
  47.                                 foreach (var objId in _btr)
  48.                                 {
  49.                                         using (var ent = (Entity)_trans.GetObject(objId, OpenMode.ForWrite))
  50.                                         {
  51.                                                 // Проверка элемента по игнор-листу
  52.                                                 if (ent.IsErased || ent is ProxyEntity || !ent.Visible || ent.GetType().ToString().Contains("Site"))
  53.                                                         continue;
  54.                                                 try
  55.                                                 {
  56.                                                         // Если объект блок референс
  57.                                                         var bref = ent as BlockReference;
  58.                                                         if (bref != null)
  59.                                                         {
  60.                                                                 // является ли объект внешней ссылкой
  61.                                                                 var isExternalRef = nodes.Any(p => p.Name.Equals(bref.Name));
  62.  
  63.                                                                 if (isExternalRef && !layers.Contains(bref.Layer))
  64.                                                                         continue;
  65.  
  66.                                                                 // Получаем объекты из внешних ссылок
  67.                                                                 //var bferEntities = Tap.CADGIS.AutoCAD.Instruments.AcadEntityInstruments.GetEntityFromBlockReference(bref, layers);
  68.  
  69.                                                                 var objIds = new ObjectIdCollection { bref.ObjectId };
  70.  
  71.                                                                 _trans.TransactionManager.QueueForGraphicsFlush();
  72.                                                                 bref.Database.WblockCloneObjects(objIds, _db.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Ignore, false);
  73.  
  74.                                                                 // Добавляем объекты в базу
  75.                                                                 //AddEntitiesToBTR(bferEntities, isExternalRef, layers);
  76.  
  77.                                                                 // Скрываем внеш. ссылку.
  78.                                                                 bref.Visible = false;
  79.                                                                 //bref.Erase(true);
  80.                                                         }
  81.                                                 }
  82.                                                 catch
  83.                                                 {
  84.                                                         isSucsess = false;
  85.                                                 }
  86.                                         }
  87.                                 }
  88.  
  89.                                 _formProgress.SetMessage(100, string.Empty);
  90.                                 if (!isSucsess)
  91.                                         MessageBox.Show("Копирование объектов произошло с ошибкой", "Копирование", MessageBoxButton.OK, MessageBoxImage.Error);
  92.                                 else
  93.                                 {
  94.                                         _trans.Commit();
  95.                                         doc.Editor.Regen();
  96.                                         MessageBox.Show("Объекты успешно скопированы", "Копирование", MessageBoxButton.OK, MessageBoxImage.Information);
  97.                                 }
  98.  
  99.                                 if (_formProgress != null && !_formProgress.IsDisposed)
  100.                                 {
  101.                                         _formProgress.Dispose();
  102.                                 }
  103.                         }
  104.                 }
  105.  

Результат работы метода.


Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А если так:
Код - C# [Выбрать]
  1. _db.WblockCloneObjects(objIds, _db.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Ignore, false);

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
А если так:
Код - C# [Выбрать]
  1. _db.WblockCloneObjects(objIds, _db.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Ignore, false);

Что все-равно не получается


Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Вот нашел по теме - http://adn-cis.org/pri-ispolzovanii-wblockcloneobjects-skopirovannyie-v-prostranstvo-modeli-primitivyi-ischezayut-v-tekushhem-chertezhe.html
Еще интересное замечание нашел - нельзя прям в методе писать new IdMapping(). Нужно обязательно сначала создать переменную!

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Вот нашел по теме - http://adn-cis.org/pri-ispolzovanii-wblockcloneobjects-skopirovannyie-v-prostranstvo-modeli-primitivyi-ischezayut-v-tekushhem-chertezhe.html
Еще интересное замечание нашел - нельзя прям в методе писать new IdMapping(). Нужно обязательно сначала создать переменную!
Хорошо, сейчас попробую все.

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

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Все равно выскакивает ошибка WrongDatabase. Документ залочен.
1.

2.

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
Добавлю еще.
1. Не следует вызвать WblockCloneObjects внутри транзакции.
2. Если не модифицируешь объект, то не нужно открывать его ForWrite.
3. Из кода я не понял из какой базы bref.

3. bref берется  из базы текущего чертежа.

Сейчас закрою транзакции и попробую снова.

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

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

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

  • ADN OPEN
  • Сообщений: 19
  • Карма: 0
3. bref берется  из базы текущего чертежа.
Не понял. Совсем не понял.

Код - C# [Выбрать]
  1. var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  2. _db = doc.Database;
  3. .....
  4. using (var docLock = doc.LockDocument())
  5. using (_trans = _db.TransactionManager.StartTransaction())
  6. using (var bt = (BlockTable)_trans.GetObject(_db.BlockTableId, OpenMode.ForWrite))
  7. using (_btr = (BlockTableRecord)_trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
  8. {
  9. .......
  10.      foreach (var objId in _btr)
  11.     {
  12.         using (var ent = (Entity)_trans.GetObject(objId, OpenMode.ForWrite))
  13.        {
  14.             var bref = ent as BlockReference;
  15.             ......................
  16.        }
  17.  
  18.     }
  19. }
  20.  

Оффлайн Александр Пекшев aka Modis

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А может стоит тогда попробовать DeepCloneObjects?
По логике, получается, что не происходит обращения к БД источника внешней ссылки. Хотя, могу и ошибаться