Как создать вложенный блок?

Автор Тема: Как создать вложенный блок?  (Прочитано 3873 раз)

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

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
День добрый,
Есть блок или несколько блоков. Задача: создать блок, в который вложены эти блоки. Именно вложены, а не объединены (статью, https://adn-cis.org/obedinenie-blokov-autocad-s-ispolzovaniem-.net-api.html я читал). Ощущение такое, что решение должно быть очевидным, но найти не удается...
Заранее благодарен.

Отмечено как Решение Балиев 09-04-2022, 17:19:34

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #1 : 09-04-2022, 16:27:27 »
Описание блока (BlockTableRecord) должно содержать вставки этих блоков (BlockReference). Возможно нужно будет поиграться с точками вставки этих блоков.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #2 : 09-04-2022, 17:19:30 »
Описание блока (BlockTableRecord) должно содержать вставки этих блоков (BlockReference). Возможно нужно будет поиграться с точками вставки этих блоков.

Спасибо, все заработало!

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #3 : 22-04-2022, 18:02:35 »
Заработало, но только для случая, когда я создаю блоки внутри объединяющего блока. А если у меня уже существуют блоки вставленные в чертеж и я хочу их объединить в блок? Как мне действовать в этом случае?
Я попробовал вытащить через GetBlockReferenceIds ссылки на существующие блоки и затем записать их в BlockTableRecord объединяющего блока, но так не получилось
Код - C# [Выбрать]
  1.         public void CreatingABlock()
  2.         {
  3.              Database acCurDb;
  4.             acCurDb = Application.DocumentManager.MdiActiveDocument.Database;
  5.  
  6.             using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
  7.             {
  8.                 BlockTable acBlkTbl;
  9.                 acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
  10.  
  11.                 if (!acBlkTbl.Has("CircleBlock"))
  12.                 {
  13.                     using (BlockTableRecord acBlkTblRec = new BlockTableRecord())
  14.                     {
  15.                         acBlkTblRec.Name = "CircleBlock";
  16.  
  17.                         acBlkTblRec.Origin = new Point3d(0, 0, 0);
  18.  
  19.                         using (Circle acCirc = new Circle())
  20.                         {
  21.                             acCirc.Center = new Point3d(0, 0, 0);
  22.                             acCirc.Radius = 100;
  23.  
  24.                             acBlkTblRec.AppendEntity(acCirc);
  25.  
  26.                             acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite);
  27.                             acBlkTbl.Add(acBlkTblRec);
  28.                             acTrans.AddNewlyCreatedDBObject(acBlkTblRec, true);
  29.                         }
  30.                     }
  31.                 }
  32.                 else
  33.                 {
  34.                     using (BlockTableRecord acBlkTblRec1 = new BlockTableRecord())
  35.                     {
  36.                         acBlkTblRec1.Name = "CircleBlock1";
  37.  
  38.                         acBlkTblRec1.Origin = new Point3d(100, 0, 0);
  39.  
  40.                         BlockTableRecord block = (BlockTableRecord)acTrans.GetObject(acBlkTbl["CircleBlock"], OpenMode.ForRead);
  41.                         ObjectIdCollection ids = block.GetBlockReferenceIds(true, true);
  42.  
  43.                         // поскольку в коллекции д.б. всего одна запись
  44.                       BlockReference br =(BlockReference)acTrans.GetObject(ids[0], OpenMode.ForRead);
  45.  
  46.                         acBlkTblRec1.AppendEntity(br);  // ЗДесь все сломалось...
  47.  
  48.                         acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForWrite);
  49.                         acBlkTbl.Add(acBlkTblRec1);
  50.                         acTrans.AddNewlyCreatedDBObject(acBlkTblRec1, true);
  51.                     }
  52.                 }
  53.  
  54.                 acTrans.Commit();
  55.             }
  56.         }
  57.  
.

Заранее благодарен.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #4 : 22-04-2022, 18:07:47 »
Я попробовал вытащить через GetBlockReferenceIds ссылки на существующие блоки и затем записать их в BlockTableRecord объединяющего блока, но так не получилось
И не должно было. Нужно копировать при помощи метода Database.DeepCloneObjects. Первым параметром этого метода ты передаешь коллекцию ObjectId примитивов, которые будут скопированы в объединенный блок. В коллекции могут быть как ObjectId отдельных примитивов, так и ObjectId для вставок нужных тебе блоков (BlockReference). Второй параметр - это ObjectId нового владельца. В данном случае это будет ObjectId для BlockTableRecord твоего блока.
« Последнее редактирование: 22-04-2022, 18:49:16 от Александр Ривилис »
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #5 : 26-04-2022, 18:55:13 »
Да, так и есть. Спасибо.

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Что не так?
« Ответ #6 : 29-07-2022, 19:42:11 »
Есть два блока: blockPanel и blockPillar. Хочу создать из них новый блок "block". Вот кусок кода:
Код - C# [Выбрать]
  1. BlockTableRecord block = new BlockTableRecord();
  2.  
  3. try
  4. {
  5.         using (Transaction tr = db.TransactionManager.StartTransaction())
  6.         {
  7.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  8.                 BlockTableRecord blockPanel = (BlockTableRecord)tr.GetObject(bt[blockName + "WP"], OpenMode.ForWrite);
  9.  
  10.                 BlockTableRecord blockPillar = (BlockTableRecord)tr.GetObject(bt["pillar300"], OpenMode.ForWrite);
  11.                 blockPillar.Origin = new Point3d(-lBlock, 0.0, 0.0);
  12.  
  13.                 bt.Add(block);
  14.                 tr.AddNewlyCreatedDBObject(block, true);
  15.                 ObjectId idBtr = block.ObjectId;
  16.  
  17.                 ObjectIdCollection ids = new ObjectIdCollection();
  18.                 ids.Add(blockPanel.ObjectId);
  19.                 ids.Add(blockPillar.ObjectId);
  20.  
  21.                 IdMapping mapping = new IdMapping();
  22.                 acCurDb.DeepCloneObjects(ids, idBtr, mapping, false);
  23.                
  24.                 .............
  25.                
  26.                 tr.Commit();
  27.         }
  28. }      
  29.  
  30.  
Ломается на 22 строке. Выбрасывает исключение: "eIllegalEntityType". Что не так?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #7 : 29-07-2022, 20:16:26 »
Балиев,
Перечитай внимательно то, что я написал в своем предыдущем сообщении.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #8 : 29-07-2022, 20:48:03 »
Балиев,
Перечитай внимательно то, что я написал в своем предыдущем сообщении.
Если я правильно тебя понял, то ты имеешь в виду, что там должна быть коллекция не ObjectId, а ObjectId as BlockReference. Но проблема в том, что у меня есть только определения входящих блоков, а не ссылки на них. Мне нужно из определения двух входящих блоков создать определение третьего блока. Или это невозможно?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #9 : 29-07-2022, 20:54:44 »
Балиев,

Понял совершенно неправильно. Это должна быть коллекция ObjectId примитивов, входящих в BlockTableRecord одного и второго блоков. И копировать можно только в BlockTableRecord у которого ObjectId не равен null, т.е. он уже добавлен в BlockTable. У тебя это не так.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #10 : 29-07-2022, 21:07:43 »
Это должна быть коллекция ObjectId примитивов, входящих в BlockTableRecord одного и второго блоков.
Т.е. ObjectId  самого блока использовать нельзя, я правильно понимаю?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #11 : 29-07-2022, 21:14:36 »
Т.е. ObjectId  самого блока использовать нельзя, я правильно понимаю?
Нельзя!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #12 : 29-07-2022, 21:27:10 »
Нельзя!
ОК, но в этом случае во вновь создаваемый блок будут входить не сами блоки, а примитивы в них входящие. А, если нужно, чтобы входили сами блоки?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #13 : 29-07-2022, 22:43:42 »
Нельзя!
ОК, но в этом случае во вновь создаваемый блок будут входить не сами блоки, а примитивы в них входящие. А, если нужно, чтобы входили сами блоки?
Тогда совсем всё просто и DeepCloneObjects не нужен.
1. Создаешь BlockTableRecord нового блока и добавляешь её к BlockTable.
2. Создаешь BlockReference для первого блока и BlockReference для второго блока.
3. Добавляешь оба BlockReference из п.2 к BlockTableRecord из п.1
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Как создать вложенный блок?
« Ответ #14 : 29-07-2022, 22:44:56 »
Балиев,
В BlockTableRecord могут входить только BlockReference, но не BlockTableRecord!!!
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн БалиевАвтор темы

  • ADN Club
  • ***
  • Сообщений: 188
  • Карма: 2
Re: Как создать вложенный блок?
« Ответ #15 : 30-07-2022, 14:42:54 »
1. Создаешь BlockTableRecord нового блока и добавляешь её к BlockTable.
2. Создаешь BlockReference для первого блока и BlockReference для второго блока.
3. Добавляешь оба BlockReference из п.2 к BlockTableRecord из п.1
Все работает, спасибо! Люблю четкие инструкции!))