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

ADN Club => Civil 3D API => Тема начата: zavor от 17-04-2017, 10:18:47

Название: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 10:18:47
Добрый день. У меня имеется чертеж, в котором вставлена внешняя ссылка. Ссылка представляет собой набор линий и copopoint'ов. У меня написан метод, который позволяет копировать объекты из внешних ссылок. Проблема заключается в том, что после копировании cogopoint'ов они становятся невидимыми на чертеже, хотя в базу данных чертежа  они успешно добавляются. Линии при этом копируются и отображаются нормально.  Не могу разобраться, в чем тут проблема.
ПО проверяется на  Civil 3D 2015.
Ниже привожу скриншоты чертежа и код методов копирования объектов.
1. Состояния чертежа до копирования объектов из внешних ссылок.
(https://s24.postimg.org/khv3ue6up/17-04-2017_13-58-25.png) (https://postimg.org/image/khv3ue6up/)

2. Состояние чертежа после копирования объектов из внешних ссылок.
(https://s11.postimg.org/tpskno8zj/17-04-2017_14-00-58.png) (https://postimg.org/image/tpskno8zj/)
На рис. 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 в коде.
(https://s24.postimg.org/muyuqc6qp/17-04-2017_14-13-19.png) (https://postimg.org/image/muyuqc6qp/)


(https://s16.postimg.org/44rqzml2p/17-04-2017_14-13-43.png) (https://postimg.org/image/44rqzml2p/)
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 10:29:17
1. Что происходит если этот чертеж сохранить, закрыть и снова открыть?
2. Функции копирования неудачные. Для полного копирования объектов (и всего, что с ними связано) между чертежами следует использовать метод Database.WblockCloneObjects.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Пекшев aka Modis от 17-04-2017, 10:30:02
Насколько я помню Civil, то там есть группы точек и стили отображения. Может ваши точки нормально копируются, просто в самом чертеже не настроено их отображение?
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 10:31:56
1. Что происходит если этот чертеж сохранить, закрыть и снова открыть?
2. Функции копирования неудачные. Для полного копирования объектов (и всего, что с ними связано) между чертежами следует использовать метод Database.WblockCloneObjects.
Хорошо, сейчас попробую предложенные вами способы и отпишусь.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:04:44
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.  

Результат работы метода.
(https://s7.postimg.org/w44txervr/17-04-2017_15-03-34.png) (https://postimg.org/image/w44txervr/)
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Пекшев aka Modis от 17-04-2017, 11:07:50
А если так:
Код - C# [Выбрать]
  1. _db.WblockCloneObjects(objIds, _db.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Ignore, false);
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:15:42
А если так:
Код - C# [Выбрать]
  1. _db.WblockCloneObjects(objIds, _db.CurrentSpaceId, new IdMapping(), DuplicateRecordCloning.Ignore, false);

Что все-равно не получается
(https://s4.postimg.org/bonfhypwp/17-04-2017_15-14-58.png) (https://postimg.org/image/bonfhypwp/)
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Пекшев aka Modis от 17-04-2017, 11:26:30
Вот нашел по теме - http://adn-cis.org/pri-ispolzovanii-wblockcloneobjects-skopirovannyie-v-prostranstvo-modeli-primitivyi-ischezayut-v-tekushhem-chertezhe.html
Еще интересное замечание нашел - нельзя прям в методе писать new IdMapping(). Нужно обязательно сначала создать переменную!
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:34:11
Вот нашел по теме - http://adn-cis.org/pri-ispolzovanii-wblockcloneobjects-skopirovannyie-v-prostranstvo-modeli-primitivyi-ischezayut-v-tekushhem-chertezhe.html
Еще интересное замечание нашел - нельзя прям в методе писать new IdMapping(). Нужно обязательно сначала создать переменную!
Хорошо, сейчас попробую все.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 11:45:51
Добавлю еще.
1. Не следует вызвать WblockCloneObjects внутри транзакции.
2. Если не модифицируешь объект, то не нужно открывать его ForWrite.
3. Из кода я не понял из какой базы bref.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:47:43
Все равно выскакивает ошибка WrongDatabase. Документ залочен.
1. (https://s29.postimg.org/ypx7870f7/17-04-2017_15-43-47.png) (https://postimg.org/image/ypx7870f7/)

2. (https://s3.postimg.org/oe6m8kidb/17-04-2017_15-46-04.png) (https://postimg.org/image/oe6m8kidb/)
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:51:10
Добавлю еще.
1. Не следует вызвать WblockCloneObjects внутри транзакции.
2. Если не модифицируешь объект, то не нужно открывать его ForWrite.
3. Из кода я не понял из какой базы bref.

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

Сейчас закрою транзакции и попробую снова.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 11:54:22
3. bref берется  из базы текущего чертежа.
Не понял. Совсем не понял. Внутри одного чертежа копировать нужно при помощи Database.DeepCloneObjects.
Но ты же вроде копируешь из внешней ссылки. Сделай тестовый проект в котором просто копируй из внешней ссылки в текущий чертеж и выкинь все свои вспомогательные функции и логику обработки слоёв и т.д. И проверь работает или нет.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 11:59:08
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.  
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Пекшев aka Modis от 17-04-2017, 12:01:35
А может стоит тогда попробовать DeepCloneObjects?
По логике, получается, что не происходит обращения к БД источника внешней ссылки. Хотя, могу и ошибаться
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 12:03:37
zavor
У тебя в коде полный бред. Понять из него куда и что ты копируешь невозможно. Упрости его до предела.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 12:06:07
Что вот это за ерунда:
Код - C# [Выбрать]
  1. using (var bt = (BlockTable)_trans.GetObject(_db.BlockTableId, OpenMode.ForWrite))
  2. using (_btr = (BlockTableRecord)_trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
???
Зачем всё открывать для записи? Ты же их не модифицируешь и при этом мешаешь работать другим методам,
которые не в состоянии открыть эти объекты для чтения, так как они уже открыты для записи.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Дмитрий Загорулькин от 17-04-2017, 12:10:50
1. А почему здесь, а не в разделе по Civil 3D?
2. Каковы условия работы приложения? Запускается в Civil 3D или в голом AutoCAD? Вставляется в чертеж AutoCAD или в чертеж Civil3D?
3. После копирования, COGO-точки физически присутствуют в базе чертежа, в который выполнялось копирование? Проверяется это не визуальным отображением, а в навигаторе.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 12:13:00
1. А почему здесь, а не в разделе по Civil 3D?
Логично. Тему переношу.

2. Каковы условия работы приложения? Запускается в Civil 3D или в голом AutoCAD? Вставляется в чертеж AutoCAD или в чертеж Civil3D?
В первом сообщении указано, что работа идёт в Civil 3D 2015.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Дмитрий Загорулькин от 17-04-2017, 12:36:39
Что вот это за ерунда:
Код - C# [Выбрать]
  1. using (var bt = (BlockTable)_trans.GetObject(_db.BlockTableId, OpenMode.ForWrite))
  2. using (_btr = (BlockTableRecord)_trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
???
Зачем всё открывать для записи? Ты же их не модифицируешь и при этом мешаешь работать другим методам,
которые не в состоянии открыть эти объекты для чтения, так как они уже открыты для записи.
+ использование using здесь лишнее, т.к. объекты открываются через транзакцию и она управляет ими.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 12:42:04
+ использование using здесь лишнее, т.к. объекты открываются через транзакцию и она управляет ими.
Полностью согласен.
zavor,
Что касается использования Database.WblockCloneObjects - следует сначала отобрать все ObjectId для объектов из одной внешней ссылки в одну ObjectIdCollection и вызвать Database.WblockCloneObjects для копирования всей этой коллекции примитивов в текущую базу данных.
Ну и выполнить такую операцию в цикле для всех баз внешних ссылок.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Дмитрий Загорулькин от 17-04-2017, 12:44:05
Я вообще бы наказывал за использование объектов Civil 3D во внешних ссылках. Внешние ссылки - это механизм AutoCAD, в Civil совместная работа выполняется через быстрые ссылки. Вы что,
 и поверхности, и трассы, и коридоры и характерные линии собираетесь перетаскивать таким образом? Сдается мне, что это очень проблемный сценарий...

/* Убрал тэг offtop, так как это очень по существу темы. Александр Ривилис */
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Дмитрий Загорулькин от 17-04-2017, 13:20:20
Александр Наумович, понял идею :) Просто я посчитал, что к коду мои размышления не относятся, поэтому запрятал их.
Немного поясню, в чем я вижу проблему такого копирования. Многие объекты Civil 3D взаимосвязаны в чертеже и очень часто являются зависимыми от других объектов. Что будет происходить с ними при копировании - неизвестно.
На примере COGO-точек: У точки есть стиль, метки. У меток тоже есть стили. Эти стили могут зависеть от параметров чертежа, от других стилей. Это все - объекты базы данных чертежа. Копируя одну точку из чертежа в чертеж вы тянете весь этот "хвост" зависимостей. Реализовано ли это в методах API для AutoCAD - большой вопрос. Я сталкивался уже с тем, что с объектами Civil 3D не всегда такие "продвинутые" методы работали корректно.
Даже если Вам удастся все это наладить и все будет нормально внедряться, в целевом чертеже Вы получите полную кашу из настроек и стилей. Часть из них останется из исходного чертежа, часть придет из внешних ссылок. Потом очень трудно будет разобраться в этом месиве.
Я бы просто пропускал все объекты Civil 3D при внедрении ссылок. Либо взрывал бы их до объектов AutoCAD. Еще, как вариант - не копировать объекты, а создавать их заново в целевом чертеже. К примеру, нашли COGO-точку во внешней ссылке, прочитали все ее параметры, создали новую точку в целевом чертеже методами Civil 3D API и задали ей все нужные свойства. Но я не понимаю смысла этого перетаскивания объектов Civil из чертежа в чертеж.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 13:30:37
Еще, как вариант - не копировать объекты, а создавать их заново в целевом чертеже. К примеру, нашли COGO-точку во внешней ссылке, прочитали все ее параметры, создали новую точку в целевом чертеже методами Civil 3D API и задали ей все нужные свойства.
Если всё это возможно средствами Civil 3D API (а я подозреваю, что это возможно), то мне это кажется оптимальным вариантом. Подозреваю, что часть ссылок SoftPointer и соответственно не будут копироваться при помощи WblockCloneObjects в другой чертеж. Как, например, не копируются группы.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 13:47:54
Постарался выкинуть все лишнее.

Код - C# [Выбрать]
  1. public void Action()
  2.                 {
  3.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  4.                         var db = doc.Database;
  5.  
  6.                         using (var trans = db.TransactionManager.StartTransaction())
  7.                         using (var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite))
  8.                         using (var btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite))
  9.                         {
  10.                                 foreach (var objId in btr)
  11.                                 {
  12.                                         using (var ent = (Entity)trans.GetObject(objId, OpenMode.ForWrite))
  13.                                         {
  14.                                                 try
  15.                                                 {
  16.                                                         var bref = ent as BlockReference;
  17.                                                         if (bref != null)
  18.                                                         {
  19.                                                                 var bferEntities = new DBObjectCollection();
  20.                                                                 bref.Explode(bferEntities);
  21.                                                                 foreach (var brefEntity in bferEntities)
  22.                                                                 {
  23.                                                                         var entity = (Entity)brefEntity;
  24.                                                                         if (entity.Database == null)
  25.                                                                                 entity.SetDatabaseDefaults(db);
  26.                                                                        
  27.                                                                 }
  28.  
  29.                                                                 bref.Visible = false;
  30.                                                         }
  31.                                                 }
  32.                                                 catch (Exception e)
  33.                                                 {
  34.                                                 }
  35.                                         }
  36.                                 }
  37.  
  38.                                 trans.Commit();
  39.                         }
  40.                 }
  41.  

У меня возникает следующий вопрос: когда я делаю
Код - C# [Выбрать]
  1. var bferEntities = new DBObjectCollection();
  2. bref.Explode(bferEntities);
  3.  
то у меня появляется набор объектов из блокреференса. Но эти объекты имеют objectid равным {0}.

(https://s11.postimg.org/va7bn9p73/17-04-2017_17-46-18.png) (https://postimg.org/image/va7bn9p73/)

Как в таком случае использовать Database.DeepCloneObjects?
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 13:59:38
Постарался выкинуть все лишнее.
Ты похоже не читаешь то, что тебе пишут. По поводу ForWrite я уже писал. По поводу using тебе писал Дмитрий.
У меня возникает следующий вопрос: когда я делаю
Код - C# [Выбрать]

    var bferEntities = new DBObjectCollection();
    bref.Explode(bferEntities);
     
то у меня появляется набор объектов из блокреференса. Но эти объекты имеют objectid равным {0}.

Как в таком случае использовать Database.DeepCloneObjects?
1. Кто-то из нас советовал делать Explode?
2. Никак ты не сможешь использовать Database.DeepCloneObjects для этих объектов.

Перечитай еще раз советы мои и Дмитрия и начни с начала.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 14:11:16
1. Для BlockReference ты должен найти его BlockTableRecord и определиться внешняя ссылка ли это или нет. Если не внешняя ссылка пропускаешь.
2. Для BlockTableRecord находишь ее базу: BlockTableRecord.GetXrefDatabase
3. Создаёшь ObjectIdCollection, проходишь по ModelSpace этой базы и отбираешь все (или нужные тебе объекты)
4. При помощи WblockCloneObjects копируешь выбранные в ObjectIdCollection объекты в ModelSpace текущего чертежа.
5. Возможно (если BlockReference.BlockTransform возвращает не единичную матрицу) придётся еще выполнить трансформацию всех скопированных объектов.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 17-04-2017, 14:13:03
Хорошо, спасибо. Выполню  и отпишусь.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Дмитрий Загорулькин от 17-04-2017, 15:59:37
Подозреваю, что часть ссылок SoftPointer и соответственно не будут копироваться при помощи WblockCloneObjects в другой чертеж. Как, например, не копируются группы.
Только сейчас понял, что Вы, скорее всего, имели в виду группы объектов AutoCAD. Я подумал (в контексте обсуждения) что Вы про группы точек, и удивлялся Вашим познаниям Civil 3D :)
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 17-04-2017, 16:03:44
подумал (в контексте обсуждения) что Вы про группы точек, и удивлялся Вашим познаниям Civil 3D :)
:D
Речь конечно шла о группах (Group) AutoCAD: https://forums.autodesk.com/t5/net/wblockcloneobjects-and-groups/td-p/4712099
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 18-04-2017, 06:54:36
Поменял код следующим образом
Код - C# [Выбрать]
  1.  public void Action()
  2.                 {
  3.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  4.                         var db = doc.Database;
  5.  
  6.                         using (var trans = db.TransactionManager.StartTransaction())
  7.                         {
  8.                                 var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  9.                                 var btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  10.                                
  11.                                 foreach (var objId in btr)
  12.                                 {
  13.                                         using (var ent = (Entity)trans.GetObject(objId, OpenMode.ForRead))
  14.                                         {
  15.                                                 try
  16.                                                 {
  17.                                                         var bref = ent as BlockReference;
  18.                                                         if (bref != null)
  19.                                                         {
  20.                                                                 //Является ли блок внешней ссылкой?
  21.                                                                 var isExternal = btr.Cast<ObjectId>().All(a => a != bref.BlockTableRecord);
  22.  
  23.                                                                 if (!isExternal)
  24.                                                                         return;
  25.  
  26.                                                                 // Получаем BlockTableRecord внешней ссылки
  27.                                                                 var btrBref = (BlockTableRecord)trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead);
  28.                                                                 var xDB = btrBref.GetXrefDatabase(false);
  29.  
  30.                                                                 // открываем транзакцию внешней был для получения объектов
  31.                                                                 using (var transRef = xDB.TransactionManager.StartTransaction())
  32.                                                                 {
  33.                                                                         // Внешняя база блока
  34.                                                                         var btBref = transRef.GetObject(xDB.BlockTableId, OpenMode.ForRead) as BlockTable;
  35.                                                                         var s = transRef.GetObject( btBref[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  36.  
  37.                                                                         // Создаем и заполняем коллекцию id'шников
  38.                                                                         var idColl = new ObjectIdCollection();
  39.                                                                         foreach (var objid in s)
  40.                                                                         {
  41.                                                                                 idColl.Add(objid);
  42.                                                                         }
  43.  
  44.                                                                         var iMap = new IdMapping();
  45.                                                                         xDB.WblockCloneObjects(idColl, db.CurrentSpaceId, iMap, DuplicateRecordCloning.Ignore, false);
  46.                                                                 }
  47.  
  48.                                                                 bref.Visible = false;
  49.                                                         }
  50.                                                 }
  51.                                                 catch (Exception e)
  52.                                                 {
  53.                                                 }
  54.                                         }
  55.                                 }
  56.  
  57.                                 trans.Commit();
  58.                         }
  59.                 }
  60.  

В итоге во время попытки выполнить WblockCloneObjects "выкидывается" экспепшн.
(https://s2.postimg.org/oh14pu3c5/18-04-2017_10-51-14.png) (https://postimg.org/image/oh14pu3c5/)


Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 18-04-2017, 09:02:34
Это связано с тем, что базы из Xref. Тут есть два варианта решения:
1. После
Код - C# [Выбрать]
  1. var xDB = btrBref.GetXrefDatabase(false);
вставляешь
Код - C# [Выбрать]
  1. xDB.RestoreOriginalXrefSymbols();
и перед
Код - C# [Выбрать]
  1. bref.Visible = false;
вставляешь
Код - C# [Выбрать]
  1. xDB.RestoreForwardingXrefSymbols();
Должно работать, но возможно медленно.
2.  Для btrBref получаешь её PathName
Создаёшь новую Database:
Код - C# [Выбрать]
  1. Database xDb = new Database(false,true);
и в неё читаешь (Database.ReadDwgFile) файл по этому пути.
Дальше работаешь с ней так, как ты работал с xDb в своём коде. Не забудь только выполнить для неё xDb.Dispose();
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 18-04-2017, 13:38:35
Спасибо, пробую.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: zavor от 19-04-2017, 07:04:06
Для первого случая ситуация следующая.
Добавил в код Ваши рекомендации.
Код - C# [Выбрать]
  1. public void Action()
  2.                 {
  3.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  4.                         var db = doc.Database;
  5.  
  6.                         using (var trans = db.TransactionManager.StartTransaction())
  7.                         {
  8.                                 var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
  9.                                 var btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
  10.                                
  11.                                 foreach (var objId in btr)
  12.                                 {
  13.                                         using (var ent = (Entity)trans.GetObject(objId, OpenMode.ForRead))
  14.                                         {
  15.                                                 try
  16.                                                 {
  17.                                                         var bref = ent as BlockReference;
  18.                                                         if (bref != null)
  19.                                                         {
  20.                                                                
  21.                                                                 // Получаем BlockTableRecord внешней ссылки
  22.                                                                 var btrBref = (BlockTableRecord)trans.GetObject(bref.BlockTableRecord, OpenMode.ForRead);
  23.  
  24.                                                                 if (!btrBref.IsFromExternalReference)
  25.                                                                 {
  26.                                                                         return;
  27.                                                                 }
  28.  
  29.                                                                 var xDB = btrBref.GetXrefDatabase(false);
  30.                                                                 xDB.RestoreOriginalXrefSymbols();
  31.  
  32.                                                                 // открываем транзакцию внешней базы для получения объектов
  33.                                                                 using (var transRef = xDB.TransactionManager.StartTransaction())
  34.                                                                 {
  35.                                                                         // Внешняя база блока
  36.                                                                         var xBT = transRef.GetObject(xDB.BlockTableId, OpenMode.ForRead) as BlockTable;
  37.                                                                         var xBTR = transRef.GetObject(xBT[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  38.  
  39.                                                                         // Создаем и заполняем коллекцию id'шников
  40.                                                                         var idColl = new ObjectIdCollection();
  41.                                                                         foreach (var objid in xBTR)
  42.                                                                         {
  43.                                                                                 idColl.Add(objid);
  44.                                                                         }
  45.  
  46.                                                                         var iMap = new IdMapping();
  47.                                                                         xDB.WblockCloneObjects(idColl, db.CurrentSpaceId, iMap, DuplicateRecordCloning.Ignore, false);
  48.                                                                 }
  49.  
  50.                                                                 xDB.RestoreForwardingXrefSymbols();
  51.                                                                 bref.Visible = false;
  52.                                                         }
  53.                                                 }
  54.                                                 catch (Exception e)
  55.                                                 {
  56.                                                 }
  57.                                         }
  58.                                 }
  59.  
  60.                                 trans.Commit();
  61.                         }
  62.                 }
  63.  

При запуске код работает без ошибок. Но объекты вообще не копируются.

(https://s17.postimg.org/n51okhh3v/19-04-2017_10-40-54.png) (https://postimg.org/image/n51okhh3v/)

Во втором случае код выглядит следующим образом.

Код - C# [Выбрать]
  1. public void Action()
  2.                 {
  3.                         var doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  4.                         var db = doc.Database;
  5.  
  6.                         using (var trans = db.TransactionManager.StartTransaction())
  7.                         {
  8.                                 var bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite);
  9.                                 var btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
  10.                                
  11.                                 foreach (var objId in btr)
  12.                                 {
  13.                                         using (var ent = (Entity)trans.GetObject(objId, OpenMode.ForWrite))
  14.                                         {
  15.                                                 try
  16.                                                 {
  17.                                                         var bref = ent as BlockReference;
  18.                                                         if (bref != null)
  19.                                                         {
  20.                                                                
  21.                                                                 // Получаем BlockTableRecord внешней ссылки
  22.                                                                 var btrBref = (BlockTableRecord)trans.GetObject(bref.BlockTableRecord, OpenMode.ForWrite);
  23.  
  24.                                                                 if (!btrBref.IsFromExternalReference)
  25.                                                                 {
  26.                                                                         return;
  27.                                                                 }
  28.  
  29.                                                                 using (var xDB = new Database(false, true))
  30.                                                                 {
  31.                                                                         xDB.ReadDwgFile(btrBref.PathName, FileShare.ReadWrite, false, null);
  32.  
  33.                                                                         // открываем транзакцию внешней базы для получения объектов
  34.                                                                         using (var transRef = xDB.TransactionManager.StartTransaction())
  35.                                                                         {
  36.                                                                                 // Внешняя база блока
  37.                                                                                 var xBT = transRef.GetObject(xDB.BlockTableId, OpenMode.ForRead) as BlockTable;
  38.                                                                                 var xBTR = transRef.GetObject(xBT[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
  39.  
  40.                                                                                 // Создаем и заполняем коллекцию id'шников
  41.                                                                                 var idColl = new ObjectIdCollection();
  42.                                                                                 foreach (var objid in xBTR)
  43.                                                                                 {
  44.                                                                                         idColl.Add(objid);
  45.                                                                                 }
  46.  
  47.                                                                                 var iMap = new IdMapping();
  48.                                                                                 xDB.WblockCloneObjects(idColl, db.CurrentSpaceId, iMap, DuplicateRecordCloning.Ignore, false);
  49.                                                                         }
  50.                                                                 }
  51.  
  52.                                                                 bref.Visible = false;
  53.                                                         }
  54.                                                 }
  55.                                                 catch (Exception e)
  56.                                                 {
  57.                                                 }
  58.                                         }
  59.                                 }
  60.  
  61.                                 trans.Commit();
  62.                         }
  63.                 }
  64.  
Пришлось открыть объекты на запись, так как вылетал эксепшн прир сокрытии блока.
Копирование объектов происходит, но без COGOPOINT'ов. Думаю, что может создание нового COGOPOINT на основе старого.
Название: Re: Копирование COGOPOINT из внешних ссылок.
Отправлено: Александр Ривилис от 19-04-2017, 08:06:09
Ты в обоих случаях не выполнил условие, что WblockCloneObjects должно вызваться вне транзакции. И кроме того во внутренних транзакциях я не увидел вызова Commit(). Впрочем, наверное Дмитрий Загорулькин был прав, говоря что так копировать нельзя и что нужно создавать объекты средствами Civil 3D.