Как обновить атрибуты блока после изменения свойств (слой, цвет)

Автор Тема: Как обновить атрибуты блока после изменения свойств (слой, цвет)  (Прочитано 4179 раз)

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

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Если я меняю в описании блока, атрибутам блока свойства: слой, или цвет на по слою..
В атрибутах вхождений блоков на чертеже эти изменения не отобразятся (исключение если явно указать цвет атрибута, то обновится сразу)
Собственно вопрос.. как это сделать из кода: обновить вид атрибутов (цвет, слой)?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Собственно вопрос.. как это сделать из кода: обновить вид атрибутов (цвет, слой)?
Ответ очевиден - изменить свойства атрибутам вхождений (AttributeReference) эти свойства (цвет, слой). Т.е. для каждой вставки блока (BlockReference) находим его коллекцию атрибутов (BlockReference.AttributeCollection), ну и каждому из них (или избранным) меняем свойства.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
изменить свойства атрибутам вхождений (AttributeReference) эти свойства (цвет, слой). Т.е. для каждой вставки блока (BlockReference) находим его коллекцию атрибутов (BlockReference.AttributeCollection), ну и каждому из них (или избранным) меняем свойства.
т.е. изменить свойства атрибутов в определении блока в этом случае недостаточно?
в принципе этот код https://adn-cis.org/izmenenie-czveta-vlozhennyix-primitivov-autocad-s-pomoshhyu-.net.html именно это и делает, но
если я зайду в редактор блоков и изменю слой атрибутам, с другим цветом (для наглядности и что бы вхождения не соответствовали описанию)
то приведенный код меняет цвет блока и атрибутов в любой цвет кроме  256(по слою), цвет атрибутов по слою не становится.
Или же есть разница менять свойство как примитиву или как атрибуту?

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
т.е. в приложенном файле я ввожу код цвета от 0 по блоку до 255 цвет и атрибут прекрасно меняет свой цвет,
но код цвета 256 (по слою) игнорирует,
если обновить атрибуты (атробновить) все работает адекватно.
Собственно, как сделать этот атробновить блокам программно? Ведь до этого я все референсы прошел, и все должно быть обновлено?

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Блин, атрибуты референсов слой не сменили.. поэтому по слою, цвет старого слоя..
Спасибо.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
doctorRAZ,
Команда _ATTSYNC позволяет обновить атрибуты блокам, но тот алгоритм, который я описал выше делает тоже самое.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
тот алгоритм, который я описал выше делает тоже самое.
спасибо!

Код - C# [Выбрать]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. #if NC
  6. using Teigha.DatabaseServices;
  7. using Teigha.Runtime;
  8. using Teigha.Geometry;
  9. using HostMgd.ApplicationServices;
  10. using HostMgd.EditorInput;
  11. using Trtm = Teigha.Runtime;
  12. using Platform = HostMgd;
  13. using PlatformDb = Teigha;
  14. using Teigha.Colors;
  15.  
  16. //using Autodesk.AutoCAD.ApplicationServices;
  17. //using Autodesk.AutoCAD.DatabaseServices;
  18. //using Autodesk.AutoCAD.EditorInput;
  19. //using Autodesk.AutoCAD.Runtime;
  20. //using Autodesk.AutoCAD.Colors;
  21.  
  22. #else
  23. using Autodesk.AutoCAD.ApplicationServices;
  24. using Autodesk.AutoCAD.DatabaseServices;
  25. using Autodesk.AutoCAD.EditorInput;
  26. using Autodesk.AutoCAD.Geometry;
  27. using Autodesk.AutoCAD.Runtime;
  28. using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
  29. using Trtm = Autodesk.AutoCAD.Runtime;
  30. using Platform = Autodesk.AutoCAD;
  31. using PlatformDb = Autodesk.AutoCAD;
  32. #endif
  33. namespace drz
  34. /*подготовка подосновы
  35.  *
  36.  */
  37. {
  38.     public class NormalizedBlock : IExtensionApplication
  39.     {
  40.         [CommandMethod("drz-BlcNorm", CommandFlags.Modal)]
  41.         public void BlockNormalized()
  42.         /* Слой примитивов блока в Zero
  43.          * Цвет примитивов блока по слою
  44.          */
  45.         {
  46.  
  47.             Document doc = Application.DocumentManager.MdiActiveDocument;
  48.             Database db = doc.Database;
  49.             Editor ed = doc.Editor;
  50.  
  51.             int count = 0;
  52.             short newColorIndex = 256;
  53.             string newLayer = "0";
  54.             using (Transaction tr = db.TransactionManager.StartTransaction())
  55.             {
  56.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
  57.                 foreach (ObjectId btrId in bt)
  58.                 {
  59.                     BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  60.                     if (!btr.IsFromExternalReference)
  61.                     {
  62.                         if (btr.IsLayout)//проходим по всем Space для обновления вида атрибутов
  63.                         {
  64.                             count += BlockNormalizedAttRef(btrId, newColorIndex, newLayer);
  65.                         }
  66.                         else //вне чертежа, меняем примитивы в описаниях блоков
  67.                         {
  68.                             foreach (ObjectId id in btr)
  69.                             {
  70.                                 Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;//может быстрее будет открывать сразу на запись?
  71.                                 if (ent != null)
  72.                                 {
  73.                                     if (ent.Layer != newLayer)// может быстрее не делать проверку, сразу переписывать?
  74.                                     {
  75.                                         ent.UpgradeOpen();
  76.                                         ent.Layer = newLayer;
  77.                                         ent.DowngradeOpen();
  78.                                     }
  79.                                     if (ent.ColorIndex != newColorIndex)
  80.                                     {
  81.                                         ent.UpgradeOpen();
  82.                                         ent.ColorIndex = newColorIndex;
  83.                                         ent.DowngradeOpen();
  84.                                     }
  85.  
  86.                                 }
  87.  
  88.                             }
  89.                         }
  90.                     }
  91.                 }
  92.                 tr.Commit();
  93.             }
  94.             ed.Regen();
  95.             ed.WriteMessage(
  96.                  "\nИзменено {0} атрибут{1} в цвет {2} на слое {3}.",
  97.                  count,
  98.                  count == 1 ? "" : "ов",
  99.                  newColorIndex,
  100.                  newLayer
  101.                  );
  102.         }
  103.         //--------------------------
  104.         private int BlockNormalizedAttRef(ObjectId btrId, short colorIndex, string layerName)
  105.         {
  106.             int changedCount = 0;
  107.             Document doc = Application.DocumentManager.MdiActiveDocument;
  108.             Database db = doc.Database;
  109.             Editor ed = doc.Editor;
  110.             Transaction tr = db.TransactionManager.StartTransaction();
  111.             using (tr)
  112.             {
  113.                 BlockTableRecord btr = (BlockTableRecord)tr.GetObject(btrId, OpenMode.ForRead);
  114.                 foreach (ObjectId entId in btr)
  115.                 {
  116.                     BlockReference br = tr.GetObject(entId, OpenMode.ForRead) as BlockReference;
  117.                     if (br != null)
  118.                     {
  119.                             //----------------------
  120.                             foreach (ObjectId attId in br.AttributeCollection)
  121.                             {
  122.                                 AttributeReference att = tr.GetObject(attId, OpenMode.ForRead, false, true) as AttributeReference;
  123.                                 if (att != null)
  124.                                 {
  125.                                     bool bCount = false;
  126.                                     if (att.ColorIndex != colorIndex)
  127.                                     {
  128.                                         bCount = true;
  129.                                         att.UpgradeOpen();
  130.                                         att.ColorIndex = colorIndex;
  131.                                         att.DowngradeOpen();
  132.                                     }
  133.                                     if (att.Layer != layerName)
  134.                                     {
  135.                                         bCount = true;
  136.                                         att.UpgradeOpen();
  137.                                         att.Layer = layerName;
  138.                                         att.DowngradeOpen();
  139.                                     }
  140.                                     if (bCount) changedCount++;
  141.                                 }
  142.                             }
  143.                         //-----------------------
  144.                         // Рекурсивно для вложенных блоков
  145.                         changedCount += BlockNormalizedAttRef(br.BlockTableRecord, colorIndex, layerName);
  146.                     }
  147.                 }
  148.                 tr.Commit();
  149.             }
  150.             return changedCount;
  151.         }
  152.         //-----------------------------
  153.         public void Initialize()
  154.         {
  155.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  156.             ed.WriteMessage("\"drz\" загружен");
  157.         }
  158.         public void Terminate()
  159.         {
  160.         }
  161.     }
  162. }
  163.  

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
Атрибуты обновил
Внешние ссылки вроде отсек... но..
Примитивы в блоках внешних ссылок переопределил(((
Как блоки в ссылках различать, чтобы не трогать их?

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Ты когда находишь BlockReference внутри BlockTableRecord, то не проверяешь его собственный BlockTableRecord. А её тоже нужно проверить на IsFromExternalReference.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 42
  • Карма: 0
  • Skype: doctorraz
её тоже нужно проверить на IsFromExternalReference.
С вложенными вроде разобрался.
Спасибо.
Код - C# [Выбрать]
  1. //................
  2.         foreach (ObjectId id in btr)
  3.         {
  4.                 //проверка на вложенную ссылку
  5.                 BlockReference btrr = tr.GetObject(id,
  6.         OpenMode.ForRead) as BlockReference;
  7.                 if (btrr != null)
  8.                 {
  9.                         BlockTableRecord btxr = tr.GetObject(btrr.BlockTableRecord,
  10.                                                                  OpenMode.ForRead) as BlockTableRecord;
  11.                         if (btxr != null)
  12.                         {
  13.                                 if (btxr.IsFromExternalReference)
  14.                                 {
  15.                                         continue;//пропускаем
  16.                                 }
  17.                         }
  18.                 }
  19.                 Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;//может быстрее будет открывать сразу на запись?
  20.                 if (ent != null)
  21.                 {
  22.                         if (ent.Layer != newLayer)// может быстрее не делать проверку, сразу переписывать?
  23.                         {
  24.                                 ent.UpgradeOpen();
  25.                                 ent.Layer = newLayer;
  26.                                 ent.DowngradeOpen();
  27.                         }
  28.                         if (ent.ColorIndex != newColorIndex)
  29.                         {
  30.                                 ent.UpgradeOpen();
  31.                                 ent.ColorIndex = newColorIndex;
  32.                                 ent.DowngradeOpen();
  33.                         }
  34.                         Wipeout wpt = ent as Wipeout;
  35.                         if (wpt != null)//если маскировка
  36.                         {
  37.                                 // получаем таблицу порядка отрисовки блока
  38.                                 DrawOrderTable drawOrder =
  39.                                                                          tr.GetObject(btr.DrawOrderTableId,
  40.                                                                         OpenMode.ForWrite) as DrawOrderTable;
  41.                                 ObjectIdCollection ids = new ObjectIdCollection();
  42.                                 ids.Add(wpt.ObjectId);
  43.                                 drawOrder.MoveToBottom(ids);//топим маскировку
  44.                         }
  45.                 }
  46.         }
  47.  
  48.  
но когда прохожу по BlockTableRecord не в space (по описаниям блоков), то из xref прилетают описания блоков
с именем вида ссылка|имя блока
IsFromExternalReference у них false, вопрос как их отловить , что бы пропустить?
тут же на форуме нашел ответ
Код - C# [Выбрать]
  1. if (!btr.IsFromExternalReference && !btr.IsDependent)// not xref and xref|block
« Последнее редактирование: 03-08-2021, 13:54:30 от doctorRAZ »

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
тут же на форуме нашел ответ
У нас почти всегда так. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение