Jump to content

быстрая пакетная работа с DWG


Recommended Posts

Вопрос "за 1000")

Как МАКСИМАЛЬНО БЫСТРО читать информацию с dwg?

условно. есть 5000 чертежей dwg. надо прочитать кол-во блоков в каждом из них.
какие подходы вообщем применимы для такой задачи?

не обязательно в рамках nanoCAD а вообще.

операции только на чтение.
понятно что можно открывать в CAD и читать через API информацию - но это капец долго.
также интересно для формата IFC.

Link to comment
Share on other sites

Два пути только: 

1. Через API.

2. Читать DXF файлы.

Можно ускорить процесс, через запуск нескольких NC, а там, смотря сколько ядер у процессора, и сколько может дать файловая система.

Link to comment
Share on other sites

По мне так цифра 5000 не шибко страшная. Я правда не несколько тысяч, но несколько сотен документов обрабатывал, выполняя в них довольно тяжелую команду.

Link to comment
Share on other sites

1 час назад, Robink сказал:

Два пути только: 

1. Через API.

2. Читать DXF файлы.

Можно ускорить процесс, через запуск нескольких NC, а там, смотря сколько ядер у процессора, и сколько может дать файловая система.

перебор файлов через конкретный CAD  связан с кучей накладных проблем (открытие, отрисовка графики, че то пошло не так  и т.д. и т.п.) и блин долго.

dxf как бэ - фиг знает что там пропало по пути из dwg.

а вот библиотеки  ODA (понятно что они платные и я их не куплю) они позволяют организовать некий без интерфейсный доступ к файлу на уровне прямых запросов к DWG как к БД? или все ж таки файл по факту будет прочитан весь(читай открыт) и на это уйдет основное время?

Link to comment
Share on other sites

Как я понимаю, DWG - это все-таки файл, а не база данных. Поэтому никаких запросов, а открыть, разместить в памяти, отфильтровать объекты, перебрать их и найти нужный тип блоков. Но может разработчики и поправят меня...

Link to comment
Share on other sites

Доступ к DWG - файлам , естественно, возможен только через библиотеки (та же тайга), либо самому нужно будет писать парсер со всем сопутствующим накладняком - скудная документация, версионность, отсутствие стандарта на формат и т.д..

Более перспективным видится все-таки работа через приложение с использованием API: пара ночей и 5к файлов будет перелопачено

Link to comment
Share on other sites

13 часов назад, Ivanco сказал:

перебор файлов через конкретный CAD  связан с кучей накладных проблем (открытие, отрисовка графики, че то пошло не так  и т.д. и т.п.) и блин долго.

dxf как бэ - фиг знает что там пропало по пути из dwg.

а вот библиотеки  ODA (понятно что они платные и я их не куплю) они позволяют организовать некий без интерфейсный доступ к файлу на уровне прямых запросов к DWG как к БД? или все ж таки файл по факту будет прочитан весь(читай открыт) и на это уйдет основное время?

Вообщем можно читать БД без открытия документа и без графики, через API NC.

 

Database db2 = new Database(false, true);
db2.ReadDwgFile(PathToFile, System.IO.FileShare.Read, true, "");

Edited by Robink
  • Like 2
Link to comment
Share on other sites

4 часа назад, Robink сказал:

Вообщем можно читать БД без открытия документа и без графики, через API NC.

 

Database db2 = new Database(false, true);
db2.ReadDwgFile(PathToFile, System.IO.FileShare.Read, true, "");

спасибо буду пробовать.

Link to comment
Share on other sites

В примере находятся вхождения блока и удаляются и еще определение блока убирается из документа.

 

using (Transaction tr = db.TransactionManager.StartTransaction()) 
{    
    BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
    
    if (bt.Has(type1 + "_" + GetLegal(brand1) + "_" + GetLegal(model1) + "_РАМКИ_ВИДОВ")) 
    {    
        ObjectId BtrId = bt[type1 + "_" + GetLegal(brand1) + "_" + GetLegal(model1) + "_РАМКИ_ВИДОВ"];
    
         BlockTableRecord Btr = (BlockTableRecord)tr.GetObject(BtrId, OpenMode.ForWrite);
    
         foreach (ObjectId BrId2 in Btr.GetBlockReferenceIds(true, true)) 
         {    
             BlockReference Br = (BlockReference)tr.GetObject(BrId2, OpenMode.ForWrite);
             Br.Erase(true);    
          }
    
          Btr.Erase(true);    
   }
    
   tr.Commit();

}

Edited by Robink
Link to comment
Share on other sites

49 минут назад, Robink сказал:

В примере находятся вхождения блока и удаляются и еще определение блока убирается из документа.

да спасибо за изначальную подсказку, в принципе скорость приемлимая.

некая свалка из 500 dwg обрабатывалась 14 минут.

мне примерно такое надо :

Спойлер

Database db = new Database(false, true);
Dictionary<string,int> allNames = new Dictionary<string, int>();
int badFiles = 0;

foreach (string oneDwgPath in allDwgPaths)
{
  try
  {
    db.ReadDwgFile(oneDwgPath, System.IO.FileShare.Read, true, "");
  }
  catch (System.Exception)
  {
    badFiles++;
    continue;
  }

  using (Transaction tr = db.TransactionManager.StartTransaction())
  {
    BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
    IEnumerable<BlockTableRecord> blockTableRecords = bt.Cast<ObjectId>()
      .Select(id => tr.GetObject(id, OpenMode.ForWrite) as BlockTableRecord)
      .Where(btr => btr != null)
      .Where(btr => btr.IsLayout == false);

    foreach (BlockTableRecord block in blockTableRecords)
    {
      if (!allNames.ContainsKey(block.Name))
      {
        allNames.Add(block.Name, 1);
      }
      else
      {
        allNames[block.Name] = allNames[block.Name] + 1;
      }
    }

  }

}

 

 

Link to comment
Share on other sites

52 минуты назад, Robink сказал:

Есть утечка памяти? db.Dispose() наверное еще нужен в конце.

насколько я понимаю использование using , Dispose() должен сам вызываться по  умолчанию. или не?

хотя во многих примерах кода по акад, Dispose() используется явно.

Цитата с доков:

Использование инструкции using обеспечивает вызов Dispose (или DisposeAsync), даже если в блоке using возникает исключение.

https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/keywords/using-statement

Edited by Ivanco
Link to comment
Share on other sites

Я про db она же объявлена и получается вне using.

 

using (Database db = new Database(false, true))
{

}

Edited by Robink
Link to comment
Share on other sites

В 13.09.2020 в 02:17, Robink сказал:

Я про db она же объявлена и получается вне using.

 

using (Database db = new Database(false, true))
{

}

да так скорее всего  правильней. в моем коде объект db насколько понимаю просто уберется GC 'ом в конце.

 

2 часа назад, Robink сказал:

По работе с IFC наверное нужно пробовать что то типа https://www.nuget.org/packages/Ifc.NET

насколько понимаю этих IFC 10 штук разных еще,  с IFC толком не ковырялся пока.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Tell a friend

    Love Официальный форум компании Нанософт? Tell a friend!
×
×
  • Create New...