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

ADN Club => AutoCAD .NET API => Тема начата: Poty от 03-02-2020, 15:02:50

Название: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Poty от 03-02-2020, 15:02:50
Добрый день!
Помогите найти простой пример вставки блока в модель.Есть имя блока , надо по указным координатам вставить в чертеж , взорвать блок , и удалить блок из чертежа.
Пример копирования блока из стороннего чертежа нашел.Подтолкните в нужном направлении, пожалуйста.
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 15:04:20
Помогите найти простой пример вставки блока в модель
Блок (точнее его описание) уже в этом чертеже?
Тогда вот пример: https://adn-cis.org/kak-vstavit-blok-s-atributami-v-prostranstvo-modeli.html
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Poty от 03-02-2020, 15:12:10
Так я копирую блок "5". 

Код - C# [Выбрать]
  1. public void InsertBlock() // This method can have any name
  2.         {
  3.  
  4.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.  
  6.             using (Database OpenDb = new Database(false, true))
  7.             {
  8.  
  9.                 OpenDb.ReadDwgFile("C:\\AutoCAD_prilozhenie\\prokat\\Sveler.dwg",
  10.  
  11.                     System.IO.FileShare.ReadWrite, true, "");
  12.  
  13.  
  14.  
  15.                 ObjectIdCollection ids = new ObjectIdCollection();
  16.  
  17.                 using (Transaction tr =
  18.  
  19.                         OpenDb.TransactionManager.StartTransaction())
  20.                 {
  21.  
  22.                     //For example, Get the block by name "TEST"
  23.  
  24.                     BlockTable bt;
  25.  
  26.                     bt = (BlockTable)tr.GetObject(OpenDb.BlockTableId
  27.  
  28.                                                    , OpenMode.ForRead);
  29.  
  30.  
  31.  
  32.                     if (bt.Has("5"))
  33.                     {
  34.  
  35.                         ids.Add(bt["5"]);
  36.  
  37.                     }
  38.  
  39.                     tr.Commit();
  40.  
  41.                 }
  42.  
  43.  
  44.  
  45.                 //if found, add the block
  46.  
  47.                 if (ids.Count != 0)
  48.                 {
  49.  
  50.                     //get the current drawing database
  51.  
  52.                     Database destdb = doc.Database;
  53.  
  54.  
  55.  
  56.                     IdMapping iMap = new IdMapping();
  57.  
  58.                     destdb.WblockCloneObjects(ids, destdb.BlockTableId
  59.  
  60.                            , iMap, DuplicateRecordCloning.Ignore, false);
  61.  
  62.                 }
  63.  
  64.             }
  65.  
  66.         }
  67.  
Затем мне нужно вставить его в чертеж , взорвать, и удалить из базы.
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 15:13:28
Poty,
Внимательно прочитай у меня в подписи правило форматирования кода на форуме и соблюдай его!
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 15:18:05
Затем мне нужно вставить его в чертеж , взорвать, и удалить из базы.
Ну а дальше используя этот код вставляешь блок: https://adn-cis.org/kak-vstavit-blok-s-atributami-v-prostranstvo-modeli.html
Чтобы расчленить блок лучше всего использовать метод BlockReference.ExplodeToOwnerSpace и затем удалить сам BlockReference. Вопрос нужен ли тебе затем его BlockTableRecord? Если нет, то и его можно удалить.
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Poty от 03-02-2020, 16:09:59
Спасибо большое все получилось. Только не могу удалить BlockTableRecord через erase autocad вылетает.
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 16:18:02
Спасибо большое все получилось. Только не могу удалить BlockTableRecord через erase autocad вылетает.
Ну если приведёшь полный код, то постараюсь помочь.
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Poty от 03-02-2020, 16:25:29
 
Код - C# [Выбрать]
  1. public void AddBlockTest()
  2.         {
  3.             Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;
  4.             using (Transaction myT = db.TransactionManager.StartTransaction())
  5.             {
  6.                 // Получаем определение блока "Check".
  7.                 string blockName = "55";
  8.                 BlockTable bt =
  9.                     db.BlockTableId.GetObject(OpenMode.ForRead) as BlockTable;
  10.                 BlockTableRecord blockDef =
  11.                   bt[blockName].GetObject(OpenMode.ForRead) as BlockTableRecord;
  12.                 // Открываем пространство модели – мы добавляем наш BlockReference к нему
  13.                 BlockTableRecord ms =
  14.                   bt[BlockTableRecord.ModelSpace].GetObject(OpenMode.ForWrite)
  15.                                                           as BlockTableRecord;
  16.                 // Создаём BlockReference и связываем его с определением блока
  17.                 Point3d point = new Point3d(2.0, 4.0, 6.0);
  18.                 using (BlockReference blockRef =
  19.                         new BlockReference(point, blockDef.ObjectId))
  20.                 {
  21.                     // Добавляем вставку блока к пространству модели
  22.                     ms.AppendEntity(blockRef);
  23.                     myT.AddNewlyCreatedDBObject(blockRef, true);
  24.  
  25.                     blockRef.ExplodeToOwnerSpace();
  26.                     blockRef.Erase();
  27.  
  28.                     blockDef.Erase(); // Здесь autocad вылетает.
  29.                 }
  30.                
  31.                 myT.Commit();
  32.             }
  33.         }
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 16:29:53
Poty,
1. blockDef открыт ForRead, а чтобы его удалить его нужно открывать ForWrite
2. Удалять blockDef лучше в отдельной транзакции, т.е. завершить эту транзакцию, сохранив его ObjectId, запустить новую транзакцию, в ней открыть blockDef и вызвать blockDef.Erase();
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Александр Ривилис от 03-02-2020, 18:29:08
Poty,
Вот так я слегка модифицировал этот тестовый пример:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Geometry;
  6. using Autodesk.AutoCAD.EditorInput;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(InsertExplodeErase.MyCommands))]
  10.  
  11. namespace InsertExplodeErase
  12. {
  13.  
  14.   public class MyCommands
  15.   {
  16.     [CommandMethod("AddBlockTest")]
  17.     public void AddBlockTest()
  18.     {
  19.       Document doc = Application.DocumentManager.MdiActiveDocument;
  20.       Database db = doc.Database;
  21.  
  22.       string blockName = "55";
  23.  
  24.       using (Database sourceDb = new Database(false, true))
  25.       {
  26.         sourceDb.ReadDwgFile("C:\\AutoCAD_prilozhenie\\prokat\\Sveler.dwg",
  27.             System.IO.FileShare.ReadWrite, true, "");
  28.  
  29.         ObjectIdCollection ids = new ObjectIdCollection();
  30.         using (Transaction tr = sourceDb.TransactionManager.StartTransaction())
  31.         {
  32.           BlockTable bt =
  33.             (BlockTable)tr.GetObject(sourceDb.BlockTableId, OpenMode.ForRead);
  34.           if (bt.Has(blockName))
  35.           {
  36.             ids.Add(bt[blockName]);
  37.           }
  38.           tr.Commit();
  39.         }
  40.  
  41.         if (ids.Count != 0)
  42.         {
  43.           Database destdb = doc.Database;
  44.           IdMapping iMap = new IdMapping();
  45.           destdb.WblockCloneObjects(ids, destdb.BlockTableId, iMap,
  46.           DuplicateRecordCloning.Ignore, false);
  47.         }
  48.         else return;
  49.       }
  50.  
  51.       ObjectId blockId;
  52.  
  53.       using (Transaction tr = db.TransactionManager.StartTransaction())
  54.       {
  55.         BlockTable bt =
  56.             tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
  57.         BlockTableRecord blockDef =
  58.             tr.GetObject(bt[blockName], OpenMode.ForRead) as BlockTableRecord;
  59.         blockId = blockDef.ObjectId;
  60.         // Открываем пространство модели – мы добавляем наш BlockReference к нему
  61.         BlockTableRecord ms =
  62.           tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  63.         // Создаём BlockReference и связываем его с определением блока
  64.         Point3d point = new Point3d(2.0, 4.0, 6.0);
  65.         BlockReference blockRef =
  66.                 new BlockReference(point, blockDef.ObjectId);
  67.         // Добавляем вставку блока к пространству модели
  68.         ms.AppendEntity(blockRef);
  69.         tr.AddNewlyCreatedDBObject(blockRef, true);
  70.         blockRef.ExplodeToOwnerSpace();
  71.         blockRef.Erase();
  72.         tr.Commit();
  73.       }
  74.       // Удаляем описание этого блока
  75.       if (!blockId.IsNull)
  76.       {
  77.         using (Transaction tr = db.TransactionManager.StartTransaction())
  78.         {
  79.           BlockTableRecord blockDef =
  80.               tr.GetObject(blockId, OpenMode.ForWrite) as BlockTableRecord;
  81.           // Только если нет вставок этого блока
  82.           ObjectIdCollection ids =
  83.               new ObjectIdCollection() { blockId };
  84.           db.Purge(ids);
  85.           if (ids.Count == 1)
  86.           {
  87.             blockDef.Erase();
  88.           }
  89.           tr.Commit();
  90.         }
  91.       }
  92.     }
  93.   }
  94. }
Название: Re: Как вставить блок по имени по указанным координатам в C#?
Отправлено: Poty от 04-02-2020, 07:29:27
Спасибо, огромное все получилось.