Мульти вставка блоков

Автор Тема: Мульти вставка блоков  (Прочитано 22234 раз)

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

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Мульти вставка блоков
« : 07-02-2020, 18:17:46 »
Приветствую всех.
Я пытаюсь сделать так, чтобы в чертёж вставлялось несколько блоков, их можно было интерактивно перемещать, но при этом, в конце всех манипуляция с перемещением они так и остались отдельными блоками. Для этого я использую DrawJig. Сначала вставляю блоки в чертёж, составляю их список (list<>), потом этот список передаю в DrawJig. Всё нормально, но можно ли отключить показ старого положения объектов, во время перемещения объектов в чертеже?

Отмечено как Решение Lemieux 08-02-2020, 23:47:15

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #1 : 07-02-2020, 18:19:55 »
Lemieux,
Теоретически, установив исходным вставкам свойство Visible в false можно скрыть оригиналы.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #2 : 07-02-2020, 18:24:42 »
Lemieux,
Теоретически, установив исходным вставкам свойство Visible в false можно скрыть оригиналы.
Интересное решение, сейчас поэкспериментирую :)

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #3 : 07-02-2020, 18:26:05 »
Lemieux,
Теоретически, установив исходным вставкам свойство Visible в false можно скрыть оригиналы.
Интересное решение, сейчас поэкспериментирую :)
Но DrawJig нужно передавать, не сами вставки с Visiable == false, а их клоны с Visible == true
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #4 : 07-02-2020, 23:11:31 »
Lemieux,
Теоретически, установив исходным вставкам свойство Visible в false можно скрыть оригиналы.
Интересное решение, сейчас поэкспериментирую :)
Но DrawJig нужно передавать, не сами вставки с Visiable == false, а их клоны с Visible == true
Что-то не получается у меня. Что интересно, что в любом месте кода, когда делаю вставки блока visiable = false, то исчезают не изначальные объекты, а те, что перемещаются за курсором.

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #5 : 08-02-2020, 00:11:57 »
Что-то не получается у меня. Что интересно, что в любом месте кода, когда делаю вставки блока visiable = false, то исчезают не изначальные объекты, а те, что перемещаются за курсором.
Будем гадать на кофейной гуще или предоставишь нормальный тестовый проект?
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #6 : 08-02-2020, 10:07:15 »
Что-то не получается у меня. Что интересно, что в любом месте кода, когда делаю вставки блока visiable = false, то исчезают не изначальные объекты, а те, что перемещаются за курсором.
Будем гадать на кофейной гуще или предоставишь нормальный тестовый проект?
Не будем гадать :) Сразу скажу, что это не моё произведение, а части кода собраны из источников интернета и адаптированы друг для друга. И, иногда, возникает проблема, что атрибуты блоков, по координате Х, остаются в нуле. Но я так и не понял закономерность этого явления.

Код - C# [Выбрать]
  1. using System.Collections.Generic;
  2.  
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.Runtime;
  6. using Autodesk.AutoCAD.EditorInput;
  7. using Autodesk.AutoCAD.Geometry;
  8. using Autodesk.AutoCAD.GraphicsInterface;
  9.  
  10. namespace Multiply_Insert
  11. {
  12.     public class Commands
  13.     {
  14.         [CommandMethod("LMXMULTIPLYINSERT")]
  15.         public void lmxInsertBlock()
  16.         {
  17.             Document lxDocument = Application.DocumentManager.MdiActiveDocument;
  18.             Database lxDatabase = Application.DocumentManager.MdiActiveDocument.Database;
  19.             Editor lxEditor = Application.DocumentManager.MdiActiveDocument.Editor;
  20.             ObjectId lxBlockID;
  21.  
  22.             string FullPath = "D:\\test.dwg";
  23.             System.IO.FileInfo lxFile = new System.IO.FileInfo(FullPath);
  24.             string BlockName = lxFile.Name;
  25.             double lx = 0;
  26.             Point3d lxBlockInsertPoint = new Point3d(lx, 0, 0);
  27.             List<BlockReference> lxBlockReferenceCollect = new List<BlockReference>();
  28.  
  29.             int i = 0;
  30.             while(i < 6)
  31.             {
  32.                 using (Transaction lxTransaction = lxDatabase.TransactionManager.StartTransaction())
  33.                 {
  34.                     using (Database lxTempDatabase = new Database(false, true))
  35.                     {
  36.                         BlockTable lxBlockTable = lxTransaction.GetObject(lxDatabase.BlockTableId, OpenMode.ForWrite, false) as BlockTable;
  37.                         if (!lxBlockTable.Has(BlockName))
  38.                         {
  39.                             lxTempDatabase.ReadDwgFile(FullPath, System.IO.FileShare.Read, true, null);
  40.                             lxBlockID = lxDatabase.Insert(BlockName, lxTempDatabase, true);
  41.                         }
  42.                         else
  43.                         {
  44.                             lxBlockID = lxBlockTable[BlockName];
  45.                         }
  46.                     }
  47.  
  48.                     lxTransaction.Commit();
  49.                 }
  50.  
  51.                 using (Transaction lxTransaction = lxDatabase.TransactionManager.StartTransaction())
  52.                 {
  53.                     BlockTable lxBlockTable = lxTransaction.GetObject(lxDatabase.BlockTableId, OpenMode.ForRead) as BlockTable;
  54.                     BlockTableRecord lxBlock = lxBlockTable[BlockName].GetObject(OpenMode.ForRead) as BlockTableRecord;
  55.                     BlockReference lxBlockReference = new BlockReference(lxBlockInsertPoint, lxBlockID);
  56.                     BlockTableRecord lxBlockTableRecord = lxTransaction.GetObject(lxBlockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  57.                     lxBlockTableRecord.AppendEntity(lxBlockReference);
  58.                     lxTransaction.AddNewlyCreatedDBObject(lxBlockReference, true);
  59.  
  60.                     foreach (ObjectId lxID in lxBlock)
  61.                     {
  62.                         DBObject lxObject = lxID.GetObject(OpenMode.ForRead);
  63.                         AttributeDefinition lxAttributeDefenition = lxObject as AttributeDefinition;
  64.                         if ((lxAttributeDefenition != null) && (!lxAttributeDefenition.Constant))
  65.                         {
  66.                             using (AttributeReference lxAttributeReference = new AttributeReference())
  67.                             {
  68.                                 lxAttributeReference.SetAttributeFromBlock(lxAttributeDefenition, lxBlockReference.BlockTransform);
  69.                                 lxBlockReference.AttributeCollection.AppendAttribute(lxAttributeReference);
  70.                                 lxTransaction.AddNewlyCreatedDBObject(lxAttributeReference, true);
  71.                             }
  72.                         }
  73.                     }
  74.  
  75.                     lxBlockReferenceCollect.Add(lxBlockReference);
  76.                     lxTransaction.Commit();
  77.                 }
  78.                 lx = lx + 5;
  79.                 i++;
  80.                 lxBlockInsertPoint = new Point3d(lx, 0, 0);
  81.             }
  82.  
  83.             try
  84.             {
  85.                 lmxDrawJig lxJig = new lmxDrawJig(new Point3d(0, 0, 0));
  86.                 using (Transaction lxTrasaction = lxDatabase.TransactionManager.StartTransaction())
  87.                 {
  88.                     foreach (BlockReference lxObject in lxBlockReferenceCollect)
  89.                     {
  90.                         BlockReference lxBlockReference = lxTrasaction.GetObject(lxObject.ObjectId, OpenMode.ForWrite) as BlockReference;
  91.                         lxJig.AddEntity(lxBlockReference);
  92.                     }
  93.  
  94.                     PromptResult lxPromptResult = Application.DocumentManager.MdiActiveDocument.Editor.Drag(lxJig);
  95.                     if (lxPromptResult.Status == PromptStatus.OK)
  96.                     {
  97.                         lxJig.TransformEntities();
  98.                         lxTrasaction.Commit();
  99.                     }
  100.                     else
  101.                         lxTrasaction.Abort();
  102.                 }
  103.             }
  104.             catch (System.Exception ex)
  105.             {
  106.                 Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(ex.ToString());
  107.             }
  108.         }
  109.  
  110.         class lmxDrawJig : DrawJig
  111.         {
  112.             private Point3d lxOriginPoint;
  113.             private Point3d lxNewPoint;
  114.             List<BlockReference> lxReferenceCollect;
  115.  
  116.             public lmxDrawJig(Point3d basePt)
  117.             {
  118.                 lxOriginPoint = basePt.TransformBy(UCS);
  119.                 lxReferenceCollect = new List<BlockReference>();
  120.             }
  121.  
  122.             public Point3d Base
  123.             {
  124.                 get { return lxNewPoint; }
  125.                 set { lxNewPoint = value; }
  126.             }
  127.  
  128.             public Point3d Location
  129.             {
  130.                 get { return lxNewPoint; }
  131.                 set { lxNewPoint = value; }
  132.             }
  133.  
  134.             public Matrix3d UCS
  135.             {
  136.                 get
  137.                 {
  138.                     return Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
  139.                 }
  140.             }
  141.  
  142.             public void AddEntity(BlockReference lxRef)
  143.             {
  144.                 lxReferenceCollect.Add(lxRef);
  145.             }
  146.  
  147.             public void TransformEntities()
  148.             {
  149.                 Matrix3d lxMatrix = Matrix3d.Displacement(lxOriginPoint.GetVectorTo(lxNewPoint));
  150.  
  151.                 foreach (BlockReference lxObject in lxReferenceCollect)
  152.                 {
  153.                     lxObject.TransformBy(lxMatrix);
  154.                 }
  155.             }
  156.  
  157.             protected override bool WorldDraw(WorldDraw lxDraw)
  158.             {
  159.                 Matrix3d lxMatrix = Matrix3d.Displacement(lxOriginPoint.GetVectorTo(lxNewPoint));
  160.  
  161.                 WorldGeometry lxGeometry = lxDraw.Geometry;
  162.                 if (lxGeometry != null)
  163.                 {
  164.                     lxGeometry.PushModelTransform(lxMatrix);
  165.                     foreach (BlockReference ent in lxReferenceCollect)
  166.                     {
  167.                         ent.Visible = true;
  168.                         lxGeometry.Draw(ent);
  169.                     }
  170.                     lxGeometry.PopModelTransform();
  171.                 }
  172.                 return true;
  173.             }
  174.  
  175.             protected override SamplerStatus Sampler(JigPrompts lxPrompts)
  176.             {
  177.                 JigPromptPointOptions lxPPO = new JigPromptPointOptions("\nNew location:");
  178.                 lxPPO.UseBasePoint = false;
  179.  
  180.                 PromptPointResult lxPointResult = lxPrompts.AcquirePoint(lxPPO);
  181.                 if (lxPointResult.Status == PromptStatus.Cancel || lxPointResult.Status == PromptStatus.Error)
  182.                     return SamplerStatus.Cancel;
  183.  
  184.                 if (!lxNewPoint.IsEqualTo(lxPointResult.Value, new Tolerance(10e-10, 10e-10)))
  185.                 {
  186.                     lxNewPoint = lxPointResult.Value;
  187.                     return SamplerStatus.OK;
  188.                 }
  189.                 else return SamplerStatus.NoChange;
  190.             }
  191.         }
  192.     }
  193. }

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #7 : 08-02-2020, 13:36:02 »
Lemieux,
Я же сказал что нужно в Jig передавать не сами объекты, а их клоны. И еще ты пытаешься работать с объектами, открытыми в транзакции, после того как транзакция завершена. Это недопустимо. Fatal Error тебе обеспечено.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #8 : 08-02-2020, 18:46:01 »
Я же сказал что нужно в Jig передавать не сами объекты, а их клоны.
Как это сделать?
И еще ты пытаешься работать с объектами, открытыми в транзакции, после того как транзакция завершена.
Работает код нормально, без фатала. А в каком месте я так работаю?

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #9 : 08-02-2020, 21:07:27 »
А в каком месте я так работаю?
Строка 75 кода. После lxTrasaction.Commit() все BlockReference в lxBlockReferenceCollect становятся недействительными. Поэтому используй не
List<BlockReference>, а List<ObjectId>.
Как это сделать?
Если с строке 91 заменить lxBlockReference на lxBlockReference.Clone() то будет то, что я имел в виду.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #10 : 08-02-2020, 23:47:06 »
Строка 75 кода. После lxTrasaction.Commit() все BlockReference в lxBlockReferenceCollect становятся недействительными.
Понял. Но каким-то образом я беру их id в следующей транзакции.
Если с строке 91 заменить lxBlockReference на lxBlockReference.Clone() то будет то, что я имел в виду.
Всё сделал, но когда указываю точку вставки, то что двигалось за курсором исчезает.

Я решил так. После строки 75 добавил
Код - C# [Выбрать]
  1. lxBlockReference.Visible = false;
а после строки 166 добавил
Код - C# [Выбрать]
  1. ent.Visible = true;
клонировать не стал, оставил как есть
Код - C# [Выбрать]
  1. lxJig.AddEntity(lxBlockReference);

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #11 : 09-02-2020, 00:16:33 »
клонировать не стал, оставил как есть
Это очень плохо. Еще раз. Нельзя пользоваться объектами, открытыми в транзакции, вне этой транзакции. Это аксиома.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #12 : 09-02-2020, 00:21:18 »
Это очень плохо. Еще раз. Нельзя пользоваться объектами, открытыми в транзакции, вне этой транзакции. Это аксиома.
Так если я клонирую, то не работает.

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

  • Administrator
  • *****
  • Сообщений: 13923
  • Карма: 1793
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Мульти вставка блоков
« Ответ #13 : 09-02-2020, 00:22:16 »
Всё сделал, но когда указываю точку вставки, то что двигалось за курсором исчезает.
Конечно исчезнет. Клоны не содержатся в чертеже. После указания точки вставки ты должен их вставить в чертеж, т.е.  lxBlockTableRecord.AppendEntity(lxBlockReference), а затем lxBlockReference.Close()), а оригиналы стереть (метод Erase)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • ****
  • Сообщений: 394
  • Карма: 21
Re: Мульти вставка блоков
« Ответ #14 : 09-02-2020, 09:58:19 »
lxBlockReference.Close()
VS studio пишет, что "Use transaction instead", хотя в хелпе я ничего не нашёл про эту фичу.

lxBlockTableRecord.AppendEntity(lxBlockReference)
AutoCAD пишет, что объект уже существует.