Создание блока из выбранных объектов. Проблема с точкой вставки

Автор Тема: Создание блока из выбранных объектов. Проблема с точкой вставки  (Прочитано 7378 раз)

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

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

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

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

Нужно создать блок из выбранных объектов с указанной точкой вставки.

Тестовый пример:
Код - C# [Выбрать]
  1. [CommandMethod("Test")]
  2.       public void Test()
  3.       {
  4.          Document doc = Application.DocumentManager.MdiActiveDocument;
  5.          Editor ed = doc.Editor;
  6.          Database db = doc.Database;        
  7.          
  8.          // выбор объектов для создания блока
  9.          var selRes = ed.GetSelection();
  10.  
  11.          if (selRes.Status == PromptStatus.OK)
  12.          {
  13.             using (var t = db.TransactionManager.StartTransaction())
  14.             {
  15.                var bt = t.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
  16.                Point3d location;
  17.                ObjectId idBtr;
  18.  
  19.                // создание определения блока
  20.                using (var btr = new BlockTableRecord())
  21.                {
  22.                   btr.Name = "Test";
  23.                   location = ed.GetPoint("Точка вставки блока").Value;
  24.                   btr.Origin = location;
  25.                   idBtr = bt.Add(btr);
  26.                   t.AddNewlyCreatedDBObject(btr, true);
  27.                }
  28.  
  29.                // копирование выбранных объектов в блок
  30.                ObjectIdCollection ids = new ObjectIdCollection(selRes.Value.GetObjectIds());
  31.                IdMapping mapping = new IdMapping();
  32.                db.DeepCloneObjects(ids, idBtr, mapping, false);
  33.  
  34.                // удаление выбранных объектов
  35.                foreach (ObjectId idEnt in ids)
  36.                {
  37.                   var ent = t.GetObject(idEnt, OpenMode.ForWrite) as Entity;
  38.                   ent.Erase();
  39.                }
  40.  
  41.                // вставка блока
  42.                using (var blRef = new BlockReference(location, idBtr))
  43.                {
  44.                   blRef.SetDatabaseDefaults(db);
  45.                   var ms = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  46.                   ms.AppendEntity(blRef);
  47.                   t.AddNewlyCreatedDBObject(blRef, true);
  48.                }
  49.                t.Commit();
  50.             }
  51.          }        
  52.       }
В модели выглядит созданный блок как надо - тока вставки соответствует указанной в центре круга.
Но в редакторе точка вставки соответствует началу координат в модели.
См. картинки.

Как модифицировать код, чтобы правильно учесть точку вставки блока.

Спасибо!

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
А если подвинуть выбранные примитивы в точку 0,0,0, прежде чем добавить их в блок? Так даже правильнее, ИМХО

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

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Попробую, спасибо.
Боюсь, что при этом “полетят" ассоциативные размеры, штриховки и что-то ещё. Но, поверю

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

  • ADN Club
  • *****
  • Сообщений: 1658
  • Карма: 366
  • Отец modplus.org
    • ModPlus
Скорее всего еще есть вариант переместить начало координат в пространстве блока в нужную точку. Тоже может подойти
Ну или сейчас придет Ривилис и даст супер-совет, как всегда - сразу в точку  ;)

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

  • Administrator
  • *****
  • Сообщений: 13882
  • Карма: 1787
  • Рыцарь ObjectARX
  • Skype: rivilis
А еще не забудь преобразовать точку (location) из ПСК в МСК.
А если подвинуть выбранные примитивы в точку 0,0,0, прежде чем добавить их в блок? Так даже правильнее, ИМХО
Именно. Точнее наверное сдвинуть их на вектор Point3d.Origin - location (в МСК). А btr.Origin установить в Point3d.Origin
Боюсь, что при этом “полетят" ассоциативные размеры, штриховки и что-то ещё.
А ты не думаешь, что загоняя в блок, ты скорее нарушишь ассоциативность?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение Александр Ривилис 02-11-2015, 00:27:11

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

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
Спасибо,
получилось так
Код - C# [Выбрать]
  1. [CommandMethod("Test")]
  2.       public void Test()
  3.       {
  4.          Document doc = Application.DocumentManager.MdiActiveDocument;
  5.          Editor ed = doc.Editor;
  6.          Database db = doc.Database;        
  7.          
  8.          // выбор объектов для создания блока
  9.          var selRes = ed.GetSelection();
  10.          Point3d location = ed.GetPoint("Точка вставки блока").Value.TransformBy(ed.CurrentUserCoordinateSystem);                  
  11.  
  12.          if (selRes.Status == PromptStatus.OK)
  13.          {
  14.             using (var t = db.TransactionManager.StartTransaction())
  15.             {
  16.                var bt = t.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;              
  17.                ObjectId idBtr;
  18.  
  19.                // создание определения блока
  20.                BlockTableRecord btr;
  21.                using (btr = new BlockTableRecord())
  22.                {
  23.                   btr.Name = "Test";                  
  24.                   idBtr = bt.Add(btr);
  25.                   t.AddNewlyCreatedDBObject(btr, true);
  26.                }
  27.  
  28.                // копирование выбранных объектов в блок
  29.                ObjectIdCollection ids = new ObjectIdCollection(selRes.Value.GetObjectIds());
  30.                IdMapping mapping = new IdMapping();
  31.                db.DeepCloneObjects(ids, idBtr, mapping, false);
  32.  
  33.                // перемещение объектов в блоке
  34.                btr = t.GetObject(idBtr, OpenMode.ForRead) as BlockTableRecord;
  35.                var moveMatrix = Matrix3d.Displacement(Point3d.Origin - location);
  36.                foreach (ObjectId idEnt in btr)
  37.                {
  38.                   var ent = t.GetObject(idEnt, OpenMode.ForWrite) as Entity;
  39.                   ent.TransformBy(moveMatrix);
  40.                }
  41.  
  42.                // удаление выбранных объектов
  43.                foreach (ObjectId idEnt in ids)
  44.                {
  45.                   var ent = t.GetObject(idEnt, OpenMode.ForWrite) as Entity;
  46.                   ent.Erase();
  47.                }
  48.  
  49.                // вставка блока
  50.                using (var blRef = new BlockReference(location, idBtr))
  51.                {
  52.                   blRef.SetDatabaseDefaults(db);
  53.                   var ms = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  54.                   ms.AppendEntity(blRef);
  55.                   t.AddNewlyCreatedDBObject(blRef, true);
  56.                }
  57.                t.Commit();
  58.             }
  59.          }        
  60.       }
Все ок. Единственно тексты немного смещаются. Но они смещаются и если просто зайти в редактор текста и выйти.
Ассоциативные размеры и штриховки сохраняются при этом.

Спасибо.

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

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

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

  • ADN Club
  • ****
  • Сообщений: 409
  • Карма: 77
  • Skype: vildar82
При штатном создании блока эти тексты тоже смещаются. При любой операции над этими текстами они смещаются. Наверно потому что, шрифт для стиля текста у меня не найден )
Попробовал, так?
Код - C# [Выбрать]
  1. foreach (ObjectId idEnt in btr)
  2.                {
  3.                   var ent = t.GetObject(idEnt, OpenMode.ForWrite) as Entity;
  4.                   if (ent is DBText)
  5.                   {
  6.                      ((DBText)ent).AdjustAlignment(db);
  7.                   }
  8.                   ent.TransformBy(moveMatrix);                  
  9.                }
Не влияет никак.
Если поменять стиль текста, то тексты не смещаются.
Сори, ввел в заблуждение. Файлы такие чумовые )

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

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