Параметры блока по BlockTableRecord

Автор Тема: Параметры блока по BlockTableRecord  (Прочитано 6752 раз)

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

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

  • ADN Club
  • *****
  • Сообщений: 828
  • Карма: 168
    • Мои плагины к Автокаду
Задался целью составить список всех атрибутов и параметров блока. Чисто для удобства пользователя в настройке моего плагина. Причем на входе имею BlockTableRecord. С атрибутами проблем нет: в btr хранятся AttributeDefinition. А вот с параметрами динамических блоков глушняк - не могу даже найти такого типа объекта "Определение Параметра". По BlockReference могу найти все параметры т.к. у него есть DynamicBlockReferencePropertyCollection. Но проблема в том, что блок может быть еще не использован в чертеже, BlockReference может не существовать. Хотя даже если блок использован, то  я ее не вижу в списке btr.GetBlockReferenceIds(false, false), что в общем-то понятно, вставлен не сам блок а его безымянные вариации с разными значениями параметров.
Уже нашел инфу, что динамические блоки вообще не возможно создавать из API... Но создавать-то мне и не надо.
Может параметры где-то отдельно хранятся? В своем каком-то словаре? Излазил всю базу данных чертежа - вижу только кучу странных xData. В xData нашел AcDbDynamicBlockGUID. Но к какому месту его приложить...

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

  • Administrator
  • *****
  • Сообщений: 13894
  • Карма: 1789
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры блока по BlockTableRecord
« Ответ #1 : 23-11-2017, 15:18:14 »
Если тебя устраивает DynamicBlockReferencePropertyCollection, то сам сделай вставку блока и из него получи DynamicBlockReferencePropertyCollection.
Документированных средств получения информации о свойствах в BlockTableRecord нет. Более того даже в ObjectARX нет (публичных) классов для работы со свойствами, а в AutoCAD .NET API и подавно...
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • Administrator
  • *****
  • Сообщений: 13894
  • Карма: 1789
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры блока по BlockTableRecord
« Ответ #2 : 23-11-2017, 15:36:03 »
А чтобы понять где это всё находится - смотри картинки:



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN Club
  • *****
  • Сообщений: 828
  • Карма: 168
    • Мои плагины к Автокаду
Re: Параметры блока по BlockTableRecord
« Ответ #3 : 23-11-2017, 17:37:08 »
Намек понял. AcDbBlockLinearParameter все-таки существует :) Но имя параметра я так и не нашел. Пожалуй все это слишком сложно для меня, овчинка выделки не стоит :)
Но все равно спасибо

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

  • Administrator
  • *****
  • Сообщений: 13894
  • Карма: 1789
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: Параметры блока по BlockTableRecord
« Ответ #4 : 23-11-2017, 17:58:42 »
Если всё-таки надумаешь разбираться, то посмотри на эту картинку (там вроде и имя параметра есть):



Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Оффлайн Дмитрий Загорулькин

  • ADN
  • *
  • Сообщений: 2531
  • Карма: 738
Re: Параметры блока по BlockTableRecord
« Ответ #5 : 24-11-2017, 13:38:00 »
У меня была похожая задача - мне нужно было найти названия состояний для параметра отражения блока. В сети нашёл решение: читать словарь ACAD_ENCHANCEDBLOCK (как раз то, что Александр Наумович указал выше). Давно это было, уже не помню где нашёл пример кода. Вся сложность была в том, что к объектам этого словаря нет доступа из .NET (не было, может сейчас уже есть). Выход из этой ситуации - использовать acdbEntGet из ObjectARX через P/Invoke.
Вот, как пример, код для получения данных о свойствах параметра отражения:
Код - C# [Выбрать]
  1. // Пробуем получить словарь имен для состояний параметров отражения
  2. Dictionary<string, FlipStateNames> flipNamesDict = new Dictionary<string, FlipStateNames>();
  3. AcDb.BlockTableRecord dynBlkTableRec = tr.GetObject(blkReference.DynamicBlockTableRecord, AcDb.OpenMode.ForRead) as AcDb.BlockTableRecord;
  4. if (dynBlkTableRec.ExtensionDictionary != null)
  5. {
  6.     AcDb.DBDictionary refDict = tr.GetObject(dynBlkTableRec.ExtensionDictionary, AcDb.OpenMode.ForRead) as AcDb.DBDictionary;
  7.     if (refDict.Contains("ACAD_ENHANCEDBLOCK"))
  8.     {
  9.         AcDb.ObjectId graphId = refDict.GetAt("ACAD_ENHANCEDBLOCK");
  10.         List<object> parameterIds = InvokeMethods.acdbEntGetObjects(graphId, 360);
  11.  
  12.         List<AcDb.ObjectId> flipParamsIds = parameterIds.Cast<AcDb.ObjectId>().Where
  13.             (item => item.ObjectClass.Name == "AcDbBlockFlipParameter").ToList();
  14.  
  15.         foreach (AcDb.ObjectId id in flipParamsIds)
  16.         {
  17.             List<AcDb.TypedValue> flipParam = InvokeMethods.acdbEntGetTypedVals(id);
  18.  
  19.             flipNamesDict.Add(
  20.                 flipParam.Single(item => item.TypeCode == 305).Value.ToString(),
  21.                 new FlipStateNames()
  22.                 {
  23.                     NotFlipped = flipParam.Single(item => item.TypeCode == 307)
  24.                     .Value.ToString(),
  25.                     Flipped = flipParam.Single(item => item.TypeCode == 308)
  26.                     .Value.ToString()
  27.                 });
  28.         }
  29.     }
  30. }
  31.  
Вспомогательные методы и объекты:
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Получение списка значений с заданным DXF кодом
  3. /// </summary>
  4. /// <param name="id">Id объекта</param>
  5. /// <param name="dxfCode">DXF код для значений</param>
  6. /// <returns></returns>
  7. public static List<object> acdbEntGetObjects(ObjectId id, short dxfCode)
  8. {
  9.     List<object> result = new List<object>();
  10.  
  11.     AdsName name = new AdsName();
  12.  
  13.     int res = AcdbGetAdsName(ref name, id);
  14.  
  15.     ResultBuffer rb = new ResultBuffer();
  16.  
  17.     Autodesk.AutoCAD.Runtime.Interop.AttachUnmanagedObject(rb, AcdbEntGet(ref name), true);
  18.  
  19.     ResultBufferEnumerator iter = rb.GetEnumerator();
  20.  
  21.     while (iter.MoveNext())
  22.     {
  23.         TypedValue typedValue = (TypedValue)iter.Current;
  24.  
  25.         if (typedValue.TypeCode == dxfCode)
  26.         {
  27.             result.Add(typedValue.Value);
  28.         }
  29.     }
  30.  
  31.     return result;
  32. }
  33.  
Код - C# [Выбрать]
  1. /// <summary>
  2. /// Метод EntGet
  3. /// </summary>
  4. /// <param name="ename"></param>
  5. /// <returns></returns>
  6. [DllImport("accore.dll", CharSet = CharSet.Ansi,
  7.     CallingConvention = CallingConvention.Cdecl, EntryPoint = "acdbEntGet")]
  8. private static extern IntPtr AcdbEntGet(ref AdsName ename);
  9.  
AdsName:
Код - C# [Выбрать]
  1. private struct AdsName
  2. {
  3.     IntPtr a;
  4.     IntPtr b;
  5. }
  6.  
P.S. Вот, вроде бы, пример, который я адаптировал под свои нужды: http://adndevblog.typepad.com/autocad/2012/05/accessing-visible-entities-in-a-dynamic-block.html
P.P.S Ещё один метод забыл:
Код - C# [Выбрать]
  1. public static List<TypedValue> acdbEntGetTypedVals(ObjectId id)
  2. {
  3.     List<TypedValue> result = new List<TypedValue>();
  4.  
  5.     AdsName name = new AdsName();
  6.  
  7.     int res = AcdbGetAdsName(ref name, id);
  8.  
  9.     ResultBuffer rb = new ResultBuffer();
  10.  
  11.     Autodesk.AutoCAD.Runtime.Interop.AttachUnmanagedObject(
  12.         rb, AcdbEntGet(ref name), true);
  13.  
  14.     ResultBufferEnumerator iter = rb.GetEnumerator();
  15.  
  16.     while (iter.MoveNext())
  17.     {
  18.         result.Add((TypedValue)iter.Current);
  19.     }
  20.  
  21.     return result;
  22. }
  23.