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

ADN Club => AutoCAD .NET API => Тема начата: Алексей Кузин от 23-03-2016, 17:04:15

Название: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 23-03-2016, 17:04:15
Возможно тема уже была, но ничего подходящего не нашел.
Многие сталкивались с ситуацией появления дисконнектов при работе с объектами. в частности Duct и DuctFitting.
Дисконнекты убирал так:

Код - C# [Выбрать]
  1. currentDocument.SendStringToExecute("REGEN\n", true, false, false);
  2.             currentDocument.Editor.Regen();

ситуация такая, что документа нет, есть только Database. документ открывать/закрывать не хотелось бы.

Код - C# [Выбрать]
  1. using(Database xdb = new Database(false, true))
  2. {
  3.     xdb.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndAllShare, true, "");
  4.     xdb.CloseInput(true);
  5.  
  6.     //действия с базой, приводящие к появлению дисконнектов
  7.  
  8.     xdb.SaveAs(filePath, DwgVersion.Current);
  9. }

Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 23-03-2016, 17:07:56
Прочитай у мня в подписи как правильно форматировать код для форума и исправь своё сообщение.
При открытии чертежа выполняется его регенерация, так что я не понимаю зачем нужны дополнительные действия при работе вне редактора AutoCAD.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 23-03-2016, 17:23:03
при последующем открытии дисконнекты остаются.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 23-03-2016, 17:26:23
Ситуация - нужно работать с дровингом, не открывая документ.
Вот этот метод приводит к появлению дисконнектов:

Код - C# [Выбрать]
  1.  Autodesk.Aec.Building.ApplicationServices.PartManager.ModifyPartViaRecord(exTable, recordCol[0], member);
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 23-03-2016, 17:29:16
В любом случае нет аналога команды REGEN для неоткрытого в редакторе чертежа. Так что если в твоём случае помогает только эта команда, то сделай реактор на открытие документа и из него запускай эту команду.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 24-03-2016, 11:17:36
Спасибо, но реактор на открытие не вариант. Попробую разобраться в причинах появления дисконнектов.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 25-03-2016, 09:47:31
Попробую разобраться в причинах появления дисконнектов.
Ну если выложишь кусок кода, который к ним приводит может чего и подскажу.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 28-03-2016, 18:07:53
В DuctFitting определяем новое поле "MyPropety". Оно не влияет на геометрические размеры DuctFitting, но влияет на уникальность FittingDefinition. То есть изменяю значения этого поля, мы можем задать для DuctFitting уникальный FittingDefinition.

Далее представлен примерный код того, как подменить DuctFitting, не открывая документ.
Проблема в том, что возникают дисконекты между подмененным DuctFitting и его соседями.

Код - C# [Выбрать]
  1. [CommandMethod("myTestCommand")]
  2.         public void myTestCommand()
  3.         {
  4.             Document doc = AcadApp.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.  
  8.             PromptSaveFileOptions opts = new PromptSaveFileOptions("Select location drawing file");
  9.             opts.Filter = "Drawing (*.dwg)|*.dwg";
  10.             PromptFileNameResult pr = ed.GetFileNameForSave(opts);
  11.  
  12.             string filePath = pr.StringResult;
  13.  
  14.             Database xdb = null;
  15.             try
  16.             {
  17.                 xdb = new Database(false, false);
  18.                 xdb.ReadDwgFile(filePath, FileOpenMode.OpenForReadAndAllShare, true, "");
  19.                 xdb.CloseInput(true);
  20.  
  21.  
  22.                 using (Transaction tr = xdb.TransactionManager.StartTransaction())
  23.                 {
  24.  
  25.                     ObjectIdCollection ids = new ObjectIdCollection();
  26.                     using (BlockTable table = tr.GetObject(xdb.BlockTableId, OpenMode.ForWrite) as BlockTable)
  27.                     using (BlockTableRecord btr = (BlockTableRecord)tr.GetObject(table[BlockTableRecord.ModelSpace], OpenMode.ForRead, false))
  28.                         foreach (ObjectId id in btr)
  29.                         {
  30.                             if (id.ObjectClass.Name != Constants.AecbDbDuctFitting)
  31.                                 continue;
  32.  
  33.                             using (DuctFitting ductFitting = (DuctFitting)tr.GetObject(id, OpenMode.ForRead))
  34.                             {
  35.                                 string partGuid = PartManager.GetPartGuid(ductFitting);
  36.                                 DataExpandedTable exTable = getExTableFromCatalog(ductFitting, partGuid);
  37.                                 if (exTable == null)
  38.                                     continue;
  39.  
  40.                                 DataRecordCollection recordCol = exTable.DataRecords;
  41.  
  42.                                 ductFitting.UpgradeOpen();
  43.                                 //метод которые вызывает подмену и появления дисконектов
  44.                                 Autodesk.Aec.Building.ApplicationServices.PartManager.ModifyPartViaRecord(exTable, recordCol[0], ductFitting);
  45.                                 if (exTable != null)
  46.                                     exTable.Dispose();
  47.                             }
  48.                         }
  49.  
  50.  
  51.                     tr.Commit();
  52.                 }
  53.  
  54.             xdb.SaveAs(filePath, DwgVersion.Current);
  55.             }
  56.             catch (System.Exception e)
  57.             {
  58.                 ed.WriteMessage("Fittings draw error: " + e.Message);
  59.             }
  60.             finally
  61.             {
  62.                 if (xdb != null)
  63.                     xdb.Dispose();
  64.             }
  65.         }
  66.  
  67.         private DataExpandedTable getExTableFromCatalog(DuctFitting ductFitting, string partGuid)
  68.         {
  69.             DataQuery query = new DataQuery();
  70.             query.Domain = Domain.DuctComponent;
  71.             query.PartGuid = partGuid;
  72.  
  73.             //добавляем параметры, размеры которые нам необходимы.
  74.             //для примера возьмем размеры самого фиттинга
  75.             //с заменой одного параметра "MyPropety"
  76.             using(DataRecord dataRecord =  Autodesk.Aec.Building.ApplicationServices.PartManager.GetPartData(ductFitting))
  77.                 foreach (DataField df in dataRecord.DataFields)
  78.             {
  79.                 //заполняем только основными значениями. чтобы геометрия оставалась на прежнем месте.
  80.                 if (df.RawDataSource != DataSource.ConstantLists)
  81.                     continue;
  82.  
  83.                 if (df.Name == "MyProperty")
  84.                 {
  85.                     query.AddSizeParameter(df.Context, df.Index, "myValue");
  86.                     continue;
  87.                 }
  88.  
  89.                 if (df.Type == CatalogDataType.Bool)
  90.                     query.AddSizeParameter(df.Context, df.Index, df.ValueBoolean);
  91.                 if (df.Type == CatalogDataType.Double)
  92.                     query.AddSizeParameter(df.Context, df.Index, df.ValueDouble);
  93.                 if (df.Type == CatalogDataType.Int)
  94.                     query.AddSizeParameter(df.Context, df.Index, df.ValueInteger);
  95.                 if (df.Type == CatalogDataType.String)
  96.                     query.AddSizeParameter(df.Context, df.Index, df.ValueString);
  97.             }
  98.  
  99.             DataExpandedTable exTable = null;
  100.             try
  101.             {
  102.                 exTable = Autodesk.Aec.Building.ApplicationServices.PartManager.GetPartTableIncludeCustomSize(query, 1);
  103.             }
  104.             catch
  105.             {
  106.             }
  107.  
  108.             if (query != null)
  109.                 query.Dispose();
  110.  
  111.             return exTable;
  112.         }
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 28-03-2016, 20:55:12
Пока из общих соображений могу предложить:
1) Переключать HostApplicationServices.WorkingDatabase на открытую базу на время работы с ней.
2) Разбить транзакцию на две. В первой получить список ObjectId для всех DuctFitting в пространстве модели. А во второй уже выполнять подмену.
Меня смущает то, что у тебя в этот момент открыта и таблица блоков и пространство модели.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 29-03-2016, 12:30:59
Предложенные решения не сработали.  :(
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 29-03-2016, 19:54:31
Предложенные решения не сработали.  :(
Сам я проверить не могу. Я так понимаю, что это MEP? Если это одна из последних трёх версий (более ранние можно не рассматривать), то можно задать вопрос в ADN DevHelp. Но тебе придётся для этой цели потрудится и предоставить:
1) Полный тестовый проект (в архиве). Желательно с английскими комментариями.
2) Минимальный dwg-файл с DuctFitting'гами, и другие требуемые для воспроизведения проблемы дисконнектов файлы.
3) Записать видео (при помощи Autodesk Screencast, как у меня написано в подписи на форуме) с проблемой дисконнектов.
Если не поленишься и сделаешь, то отправлю в ADN DevHelp.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 31-03-2016, 15:58:54
Да, MEP. версии - 2014, 2015, 2016
Хорошо. Как будет время попробую наваять.
Временное решение: после свои изменений открываю документ, делаю реген, сохраняю.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Александр Ривилис от 31-03-2016, 16:01:42
Временное решение: после свои изменений открываю документ, делаю реген, сохраняю.
Не понял. Ты же писал, что:
Спасибо, но реактор на открытие не вариант.
Я так понимал, что регенерация для такого чертежа уже не помогала и поэтому ты отказался от реактора.
Название: Re: убрать дисконнекты, не открывая документ.
Отправлено: Алексей Кузин от 04-04-2016, 12:08:05
Реактор на открытие не вариант - так как чертеж может быть открыт потом в автокаде без плагина и дисконекты останутся. Поэтому необходимо от них избавиться сразу.

Doc.SendStringToExecute("regen\n", false, false, false); - помогает это сделать, но для её запуска необходим документ. Поэтому приходится открывать документ делать реген и закрывать, но это решение временное...