Ускорение вставки кучи динамических блоков

Автор Тема: Ускорение вставки кучи динамических блоков  (Прочитано 10560 раз)

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

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Доброго времени суток всем!

Наблюдаются тормоза при вставке динамических блоков у которых нужно менять дин параметры.
Вот такой тестовый пример:
Код - C# [Выбрать]
  1. [CommandMethod("TestInsertManyDynBl")]
  2.       public static void TestInsertManyDynBl()
  3.       {
  4.          Random rnd = new Random();  
  5.          Database db = HostApplicationServices.WorkingDatabase;
  6.          using (var t = db.TransactionManager.StartTransaction())
  7.          {            
  8.             var bt = t.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  9.             var ms = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  10.             var btrDynBl = t.GetObject(bt["Test"], OpenMode.ForRead) as BlockTableRecord;
  11.             ObjectId idBtr = btrDynBl.Id;
  12.             Point3d pos = Point3d.Origin;
  13.  
  14.             // Вставка 1000 дин блоков с изменение дин параметров.
  15.             for (int i = 0; i < 1000; i++)            
  16.             {              
  17.                var blRef = new BlockReference(new Point3d(rnd.Next(10000), rnd.Next(10000), 0), idBtr);              
  18.                ms.AppendEntity(blRef);
  19.                t.AddNewlyCreatedDBObject(blRef, true);
  20.                setDynParam(blRef);
  21.             }
  22.             t.Commit();
  23.          }
  24.       }
  25.  
  26.       private static void setDynParam(BlockReference blRefcolorAreaSpot)
  27.       {
  28.          foreach (DynamicBlockReferenceProperty item in blRefcolorAreaSpot.DynamicBlockReferencePropertyCollection)
  29.          {
  30.             if (string.Equals(item.PropertyName, "Длина", StringComparison.InvariantCultureIgnoreCase))
  31.                item.Value = 300d;
  32.             else if (string.Equals(item.PropertyName, "Высота", StringComparison.InvariantCultureIgnoreCase))
  33.                item.Value = 100d;
  34.          }
  35.       }
Всем блокам выставляются одни и те же дин параметры с одинаковыми значениями. Т.е. можно сделать один блок шаблона и его копировать в нужные места. Но, не нашел подходящего метода - Clone не подходит, т.к. он копирует анонимный блок.
Если просто вставлять блоки, не изменяя дин параметров, то все происходит мгновенно.

Отмечено как Решение Александр Ривилис 04-10-2015, 22:12:46

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Получилось через deepCloneObjects
Код - C# [Выбрать]
  1. // Вставка 1000 дин блоков с изменение дин параметров.
  2.             for (int i = 0; i < 1000; i++)            
  3.             {
  4.                IdMapping map = new IdMapping();
  5.                db.DeepCloneObjects(colCopy, ms.Id, map, false);
  6.                var blRef = t.GetObject(map[idBlRefTemplate].Value, OpenMode.ForWrite) as BlockReference;
  7.                blRef.Position = new Point3d(rnd.Next(10000), rnd.Next(10000), 0);              
  8.             }
  9.             t.Commit();
в colCopy добавил один id блока шаблона

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
в colCopy добавил один id блока шаблона
Я правильно понимаю, что одну вставку блока ты сделал как обычно, настроил в ней динамические параметры, а потом уже копируешь его?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82

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

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 737
Интересно, а при копировании блока через DeepCloneObjects его атрибуты тоже копируются, или их нужно отдельно обрабатывать? Не проверяли?

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Интересно, а при копировании блока через DeepCloneObjects его атрибуты тоже копируются, или их нужно отдельно обрабатывать? Не проверяли?
У меня пока такой задачи не было.
Попробовал - работает.
Код - C# [Выбрать]
  1. [CommandMethod("TestInsertManyDynBl")]
  2.       public static void TestInsertManyDynBl()
  3.       {        
  4.          Random rnd = new Random();
  5.          Document doc = Application.DocumentManager.MdiActiveDocument;
  6.          using (var ld = doc.LockDocument())
  7.          {
  8.             Database db = doc.Database;                        
  9.             using (var t = db.TransactionManager.StartTransaction())
  10.             {
  11.                var bt = t.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  12.                var ms = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;              
  13.                var btrDynBl = t.GetObject(bt["Test"], OpenMode.ForRead) as BlockTableRecord;              
  14.  
  15.                ObjectId idBlRefTemplate;
  16.                // Шаблон дин блока с атрибутами
  17.                using (var blRefTemplate = new BlockReference(Point3d.Origin, btrDynBl.Id))
  18.                {
  19.                   ms.AppendEntity(blRefTemplate);
  20.                   t.AddNewlyCreatedDBObject(blRefTemplate, true);
  21.                   // установка дин параметров
  22.                   setDynParam(blRefTemplate);
  23.                   // добавление атрибутов и задание им значений
  24.                   setAttr(blRefTemplate, btrDynBl);
  25.                   idBlRefTemplate = blRefTemplate.Id;
  26.                   ms.DowngradeOpen();
  27.                }
  28.                var colCopy = new ObjectIdCollection();
  29.                // добавление блока шабллона
  30.                colCopy.Add(idBlRefTemplate);
  31.            
  32.                // Вставка 1000 дин блоков с изменение дин параметров.
  33.                for (int i = 0; i < 1000; i++)
  34.                {
  35.                   IdMapping map = new IdMapping();
  36.                   // копирование блока шаблона
  37.                   db.DeepCloneObjects(colCopy, ms.Id, map, false);
  38.                   var blRef = t.GetObject(map[idBlRefTemplate].Value, OpenMode.ForWrite) as BlockReference;                  
  39.                   var newPt = new Point3d(rnd.Next(10000), rnd.Next(10000), 0);
  40.                   // перенос скопированного блока внужное место
  41.                   blRef.TransformBy(Matrix3d.Displacement(blRef.Position.GetVectorTo(newPt)));
  42.                }
  43.                t.Commit();
  44.             }
  45.          }
  46.       }
  47.  
  48.       private static void setDynParam(BlockReference blRef)
  49.       {
  50.          foreach (DynamicBlockReferenceProperty item in blRef.DynamicBlockReferencePropertyCollection)
  51.          {
  52.             if (string.Equals(item.PropertyName, "Длина", StringComparison.InvariantCultureIgnoreCase))
  53.                item.Value = 300d;
  54.             else if (string.Equals(item.PropertyName, "Высота", StringComparison.InvariantCultureIgnoreCase))
  55.                item.Value = 100d;
  56.          }
  57.       }      
  58.  
  59.       private static void setAttr (BlockReference blRef, BlockTableRecord btr)
  60.       {
  61.          foreach (ObjectId idEnt in btr)
  62.          {
  63.             if (idEnt.ObjectClass.Name == "AcDbAttributeDefinition")
  64.             {
  65.                var atrDef = idEnt.GetObject(OpenMode.ForRead) as AttributeDefinition;
  66.                if (!atrDef.Constant)
  67.                {
  68.                   using (var atrRef = new AttributeReference())
  69.                   {
  70.                      atrRef.SetAttributeFromBlock(atrDef, blRef.BlockTransform);
  71.                      blRef.AttributeCollection.AppendAttribute(atrRef);
  72.                      if (string.Equals(atrRef.Tag, "Test1", StringComparison.InvariantCultureIgnoreCase))
  73.                      {
  74.                         atrRef.TextString = "test string 1";
  75.                      }
  76.                      else if (string.Equals(atrRef.Tag, "Test2", StringComparison.InvariantCultureIgnoreCase))
  77.                      {
  78.                         atrRef.TextString = "test string 2";
  79.                      }
  80.                   }
  81.                }
  82.             }
  83.          }        
  84.       }      


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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
Попробовал - работает.
Всё правильно, т.к. атрибуты вставки блока связаны с ним Hard References, которые копируются методом DeepCloneObjects. 
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Есть метод для отключения прорисовки объектов или еще что-то, чтобы ускорить DeepCloneObjects?

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

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

P.S.: Сама тема обсуждалась здесь: http://adn-cis.org/forum/index.php?topic=1719.0
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн ВильдарАвтор темы

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Спасибо