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

ADN Club => AutoCAD .NET API => Тема начата: Luca от 29-01-2020, 11:01:19

Название: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 11:01:19
Здравствуйте.
Как получить доступ к MText внутри блока?
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Дмитрий Загорулькин от 29-01-2020, 11:08:01
Выбрать вставку блока на чертеже
Открыть его на чтение
Получить данные об описании блока
Открыть описание блока на чтение или запись

После всего этого появится доступ к объектам любого типа внутри блока, в том числе и к MText'ам.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 11:11:58
Выбрать вставку блока на чертеже
выбрал
Открыть его на чтение
открыл
на запись, в данном случае
Получить данные об описании блока
?
Открыть описание блока на чтение или запись
?
можно попросить ссылку на код, который реализует что-то подобное
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 11:13:40
Luca,
Добавлю к тому, что написал Дмитрий Загорулькин.
1. К описанию блока BlockTableRecord можно обратится и по имени (впрочем если это одно из состояний динамического блока, то это будет не просто).
2. Если тебе нужно изменить MText внутри блока, то после модификации потребуется регенерация чертежа и изменение MText отобразится во всех вставках этого блока.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 11:14:52
на запись, в данном случае
На запись BlockReference открывать в данном случае не нужно - ты собираешься менять не BlockReference, а его BlockTableRecord.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 11:17:00
можно пример кода, который меняет текст внутри блока. блок состоит из MText внутри и всё.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Дмитрий Загорулькин от 29-01-2020, 11:17:35
Выбрать вставку блока на чертеже
выбрал
Открыть его на чтение
открыл
на запись, в данном случае
Получить данные об описании блока
?
Открыть описание блока на чтение или запись
?
можно попросить ссылку на код, который реализует что-то подобное
Как получить данные об описании блока (объект BlockTableRecord): http://help.autodesk.com/view/OARX/2018/ENU/?guid=OREFNET-Autodesk_AutoCAD_DatabaseServices_BlockReference_BlockTableRecord
Т.к. получаем ObjectId, я думаю, не должно быть проблем с его дальнейшим открытием?
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 11:18:23
Цитата: Дмитрий Загорулькин от 29-01-2020, 10:08:01

    Получить данные об описании блока

?
Код - C# [Выбрать]
  1. BlockReference br; // Ты его уже раньше получил.
  2. ObjectId idBtr = br.BlockTableRecord; // Это ObjectId описания блока
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 11:19:12
можно пример кода, который меняет текст внутри блока. блок состоит из MText внутри и всё.
Это будет неинтересно и не педагогично.
P.S.: Публикуй сразу код, который у тебя на данный момент получится. Будем дальше подсказывать.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 12:20:53
Это будет неинтересно и не педагогично.
тратить время в пустую - точно ...
Берем оф документацию (в которой просто ни одного примера нет. где найти пошаговую, связанную информацию с примерами я так и не понял - всё какими-то кусками):
Код - C# [Выбрать]
  1. public ObjectId BlockTableRecord;
  2.  
Код - C# [Выбрать]
  1. public class BlockTableRecord : SymbolTableRecord, IEnumerable;
  2.  
замечательно - мы наследуем от SymbolTableRecord и можем его итерировать...
смотрим свойства BlockTableRecord:
https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-__MEMBERTYPE_Properties_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord (https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-__MEMBERTYPE_Properties_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord)
смотрим методы BlockTableRecord:
https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-__MEMBERTYPE_Methods_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord (https://help.autodesk.com/view/OARX/2019/ENU/?guid=OREFNET-__MEMBERTYPE_Methods_Autodesk_AutoCAD_DatabaseServices_BlockTableRecord)
и как имея всё это богатство получить доступ к MText (например) внутри блока так и осталось загадкой
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Дмитрий Загорулькин от 29-01-2020, 12:35:57
замечательно - мы наследуем от SymbolTableRecord и можем его итерировать...
Таки итерируйте, и будет Вам счастье ;)
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 12:56:01
Ладно. Поступлю непедагогично.



Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. [assembly: CommandClass(typeof(ChgMTextInBlock.MyCommands))]
  7.  
  8. namespace ChgMTextInBlock
  9. {
  10.   public class MyCommands
  11.   {
  12.     [CommandMethod("ChgMTextInBlock")]
  13.     public void ChgMTextInBlockHandler()
  14.     {
  15.       Document doc = Application.DocumentManager.MdiActiveDocument;
  16.       if (doc == null) return;
  17.       Editor ed = doc.Editor;
  18.       Database db = doc.Database;
  19.       PromptEntityOptions prOpt =
  20.         new PromptEntityOptions("Выберите блок с MText: ");
  21.       prOpt.SetRejectMessage("Это не блок!");
  22.       prOpt.AddAllowedClass(typeof(BlockReference), true);
  23.       PromptEntityResult prRes = ed.GetEntity(prOpt);
  24.       if (prRes.Status != PromptStatus.OK) return;
  25.       using (Transaction tr = doc.TransactionManager.StartTransaction())
  26.       {
  27.         BlockReference br =
  28.           tr.GetObject(prRes.ObjectId, OpenMode.ForRead) as BlockReference;
  29.         if (br != null)
  30.         {
  31.           BlockTableRecord btr =
  32.             tr.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  33.           if (btr != null)
  34.           {
  35.             foreach (ObjectId id in btr)
  36.             {
  37.               if (id.ObjectClass == RXClass.GetClass(typeof(MText)))
  38.               {
  39.                 MText mt = tr.GetObject(id, OpenMode.ForWrite) as MText;
  40.                 // Меняем цвет MText
  41.                 if (mt != null)
  42.                 {
  43.                   mt.ColorIndex = (mt.ColorIndex + 1) % 255;
  44.                 }
  45.               }
  46.             }
  47.           }
  48.         }
  49.         tr.Commit();
  50.       }
  51.       ed.Regen(); // Чтобы отобразились изменения в блоке.
  52.     }
  53.   }
  54. }
  55.  
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 12:58:24
хотел уточнить один момент:
BlockReference - это что?
описание типа
Цитировать
This .NET class wraps the AcDbBlockReference ObjectARX class.
"много о чём говорит"...
идём в ObjectARX
constructor
Код - C++ [Выбрать]
  1. AcDbBlockReference(
  2.     const AcGePoint3d& position,
  3.     AcDbObjectId blockTableRec
  4. );
  5.  
получается, что BlockReference - это ссылка на blockTableRec и где оно вставляется, а
blockTableRecord - это
Цитировать
BTR содержит коллекцию объектов, на которые могут ссылаться несколько вставок, чтобы сэкономить место на чертеже, сэкономить время при создании чертежа и гарантировать, что все вставки будут выглядеть одинаково (за исключением, возможно, цвета и типа линии).
те если проитерировать BTR и проверить is MText или не принадлежность тому или иному слою, то мы получим искомое. Верно?
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 13:01:09
хотел уточнить один момент:
BlockReference - это что?
Вставка блока. Так понятнее???
те если проитерировать BTR и проверить is MText или не принадлежность тому или иному слою, то мы получим искомое.
Слой тут причем? В постановке задачи про слой не было ни слова. Код мой посмотри и разбери детально.
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Luca от 29-01-2020, 13:07:30
Слой тут причем? В постановке задачи про слой не было ни слова. Код мой посмотри и разбери детально.
я имел в виду способ идентификации содержимого блока, те, если там MText не один, а два, например, то различать одинаковые по типу сущности можно по слою, например
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 13:08:47
Luca,
Код посмотрел? Всё понятно?
Название: Re: Как получить доступ к MText внутри блока?
Отправлено: Александр Ривилис от 29-01-2020, 13:23:36
Вот еще один вариант с непосредственным указанием MTEXT (не важно в блоке ли он или отдельный):

Код - C# [Выбрать]
  1. [CommandMethod("ChgMText")]
  2. public void ChgMText()
  3. {
  4.   Document doc = Application.DocumentManager.MdiActiveDocument;
  5.   if (doc == null) return;
  6.   Editor ed = doc.Editor;
  7.   Database db = doc.Database;
  8.   PromptNestedEntityOptions prOpt =
  9.     new PromptNestedEntityOptions("Выберите  MText: ");
  10.   PromptNestedEntityResult prRes = ed.GetNestedEntity(prOpt);
  11.   if (prRes.Status != PromptStatus.OK) return;
  12.   if (prRes.ObjectId.ObjectClass != RXClass.GetClass(typeof(MText)))
  13.   {
  14.     ed.WriteMessage("\nЭто не MTEXT!!!");
  15.     return;
  16.   }
  17.   using (Transaction tr = doc.TransactionManager.StartTransaction())
  18.   {
  19.     MText mt = tr.GetObject(prRes.ObjectId, OpenMode.ForWrite) as MText;
  20.     // Меняем цвет MText
  21.     if (mt != null)
  22.     {
  23.       mt.ColorIndex = (mt.ColorIndex + 1) % 255;
  24.     }
  25.     tr.Commit();
  26.   }
  27.   // Чтобы отобразились изменения в блоке (если MTEXT в блоке).
  28.   if (prRes.GetContainers().Length > 0) ed.Regen();
  29. }