Аннотативность блока, и обновление атрибутов

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

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

Тема содержит сообщение с Решением. Нажмите здесь чтобы посмотреть его.

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
Здравствуйте, уважаемые форумчане! Если допускается правилами форума, то у меня 2 вопроса:
1) как называется метод для обновления атрибута?(AttributeDefinition.???)
2) как называется метод для сброса блока? Изначально пытался включить аннотативность и сразу же её отключить для определения блока, но аннотативные масштабы не сбросились




 
Код - C# [Выбрать]
  1. public void reset_block_atribut(string blockName)
  2.         {              
  3.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  4.             Database db = doc.Database;
  5.             Editor ed = doc.Editor;
  6.                        
  7.             Transaction tr = db.TransactionManager.StartTransaction();
  8.             using (tr)
  9.             {              
  10.                 BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
  11.  
  12.                 if (!bt.Has(blockName))
  13.                 {
  14.                     ed.WriteMessage("Отсутствует определение блока в данном чертеже!");
  15.                     return;
  16.                 }
  17.                 else
  18.                 {
  19.                    BlockTableRecord btr = tr.GetObject(bt[blockName], OpenMode.ForWrite) as BlockTableRecord;
  20.                    
  21.                          foreach (ObjectId id in btr)
  22.                     {                        
  23.                         DBObject obj = tr.GetObject(id, OpenMode.ForRead);                        
  24.                         if (obj.GetType() == typeof(AttributeDefinition))
  25.                         {
  26.                             obj.UpgradeOpen();
  27.  
  28.  ?????                           (obj as AttributeDefinition).??????
  29.  
  30.                         }
  31.                     }
  32.  
  33.  
  34.  ?????                   btr.Annotative = AnnotativeStates.False;
  35.  ?????                  btr.Annotative = AnnotativeStates.True;
  36.  
  37.  
  38.                     // фиксируем транзакцию
  39.                     tr.Commit();
  40.                 }
  41.             }
  42.         }

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
1) как называется метод для обновления атрибута?(AttributeDefinition.???)
??? Что такое обновление атрибута? Объясни очень (!!!) подробно что тебе нужно.
2) как называется метод для сброса блока? Изначально пытался включить аннотативность и сразу же её отключить для определения блока, но аннотативные масштабы не сбросились
Что ты понимаешь под сбросом блока? И вообще имеешь ли ты в виду определение блока (BLockTableRecord) или вставку блока (BlockRefrerence). Для вставки блока есть метод BlockReference.ResetBlock, но аннототивность этим методом сбрасываться не должна.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
1) про обновление атрибута



имеется блок, "отметка уровня" с атрибутом. когда начинаешь менять (аннотативный масштаб, сдвигать атрибут) - и так по несколько раз, то атрибут начинает уже "тормозить", уже при Новых аннотативных масштабах атрибут находится в "слетевшем" состоянии.
ситуацию частично спасает обновление атрибута из команды _Battman



но к сожалению только для текущей видимости(текущего аннотативного масштаба). стоит повторно сменить на новый аннотативный масштаб, то снова атрибут слетел

2) про сброс блока понимал именно: выделить вхождение блока - правая км - Сброс блока
и правда, даже ручное применение команды не лечит данный блок

Пока что единственный адекватный вариант, который позволит при Новых аннотативных масштабах видеть атрибут на исходных позициях - это физическое удаление всех аннотативных машстабов

или есть более оптимальный вариант?


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

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

Отмечено как Решение bert 10-10-2017, 12:23:58

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Посмотри эту статью: http://adn-cis.org/ustanovka-polozheniya-mtext-dlya-kazhdogo-iz-masshtabov-annotaczij.html
Думаю что она применима и к атрибутам блока.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
Имеем блок с подвижным атрибутом
вставив его в модель имеем один аннотативный масштаб 1:1



сдвинем атрибут в сторону и переместим блок вместе с атрибутом



добавим аннотативный масштаб 1:2



Также, сдвинем атрибут + переместим целиком блок + снова добавим новый аннотативный масштаб( 1:4)
и получаем



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

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

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
На сколько я понял данный алгоритм находит координаты базовой точки в текущем аннотативном масштабе и устанавливает по остальным аннотативным масштабам такие же координаты базовой точки (правда не понял зачем прибавляется данный кусок умноженный на 3 (Vector3d.XAxis * 3 + Vector3d.YAxis * 3))

ньюанс следующий

если человеку видит слетевший атрибут - и применит алгоритм то по всем остальным масштабам координаты базовой точки будут также слетевшими

попробую найти "правильные координаты" и применить данную функцию

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
В общем благодарю, Александр, понял в каком направлении двигаться, но всё-таки хочется пойти по пути наименьшего сопротивления и уточнить: имеется ли команда которая обновляет атрибут как в _battman?

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

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

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
Александр, в продолжении темы. долго мучился чтобы изменить вообще координаты атрибута
пробовал и
Код - C# [Выбрать]
  1. atr_ref.Position = Point3d.Origin;
и
Код - C# [Выбрать]
  1. atr_ref.MTextAttribute.Location = Point3d.Origin;
и добавлять вконце
Код - C# [Выбрать]
  1. atr_ref.UpdateMTextAttribute();
в итоге заработало только
Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = Point3d.Origin;

Увидел в одном из ваших сообщений команду которую регулярно используете

Код - C# [Выбрать]
  1. ar.Position = _attPos[ar.Tag].TransformBy(br.BlockTransform);
  2.  

-_attPos[ar.Tag] - я так понимаю это координаты атрибута в определении блока?

почему тогда не используют AttribiteDefinition.position?

AttribiteDefinition.TransformBy(br.BlockTransform);
- я правильно понимаю что мы берем координаты атрибута в определении блока AttribiteDefinition, и используя размеры(в виде координат) вхождения блока br.BlockTransform получаем точные координаты атрибута в модели? независимо от масштаба аннотации


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

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

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
найдем определение атрибута

Код - C# [Выбрать]
  1.  
  2. AttributeDefinition atr_def= new AttributeDefinition();
  3. foreach (var idEnt in btr)
  4.                 {
  5.                     Entity en = tr.GetObject(idEnt, OpenMode.ForRead) as Entity;
  6.  
  7.                     if (en.GetType() == typeof(AttributeDefinition))
  8.                     {
  9.                         AttributeDefinition atr = tr.GetObject(idEnt, OpenMode.ForWrite, false, true) as AttributeDefinition;
  10.                         atr_def = atr;
  11.                     }
  12.  
  13.                 }

другими словами
можно ли заменить строку

Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = AttribiteDefinition.TransformBy(br.BlockTransform);
  2.  
на

Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = br.Position + Vector3d.XAxis*atr_def.AlignmentPoint.X+ Vector3d.YAxis*atr_def.AlignmentPoint.Y;


я в принципе уже сделал на первоначальный вопрос
мне просто интересен принцип работы методов TransformBy и BlockTransform

на мой взгляд

Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = br.Position + Vector3d.XAxis*atr_def.AlignmentPoint.X * на делитель масштаба аннотации+ Vector3d.YAxis*atr_def.AlignmentPoint.Y * на делитель масштаба аннотации; -

лично для меня более наглядна из-за незнания данных методов

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
можно ли заменить строку

Код - C# [Выбрать]

    atr_ref.AlignmentPoint = AttribiteDefinition.TransformBy(br.BlockTransform);
     

на

Код - C# [Выбрать]

    atr_ref.AlignmentPoint = br.Position + Vector3d.XAxis*atr_def.AlignmentPoint.X+ Vector3d.YAxis*atr_def.AlignmentPoint.Y;


Нет. Во-первых, не

Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = AttribiteDefinition.TransformBy(br.BlockTransform);

а

Код - C# [Выбрать]
  1. atr_ref.AlignmentPoint = atr_def.AlignmentPoint.TransformBy(br.BlockTransform);

Во-вторых, во втором коде не учитывается поворот и масштабирование.
В-третьих, точка вставки определения блока может не совпадать с (0,0,0).
Короче говоря использование br.BlockTransform наиболее правильный метод.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 32
  • Карма: 1
В итоге получился вот такой код

Код - C# [Выбрать]
  1.         [CommandMethod("vost_otm_ur")]
  2.         public void ustanov_mashtab()
  3.         {
  4.             Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  5.             Database db = doc.Database;
  6.             Editor ed = doc.Editor;
  7.                        
  8.             TypedValue[] filterlist = new TypedValue[1];            
  9.             filterlist[0] = new TypedValue(0, "INSERT");
  10.             //filterlist[1] = new TypedValue(2, "отметка уровня");          
  11.             SelectionFilter filter = new SelectionFilter(filterlist);            
  12.             PromptSelectionResult selRes = ed.SelectAll(filter);
  13.  
  14.             // если произошла ошибка - сообщаем о ней
  15.             if (selRes.Status != PromptStatus.OK)
  16.             {
  17.                 ed.WriteMessage("\nОшибка!\n");
  18.                 return;
  19.             }
  20.  
  21.          
  22.             ObjectId[] ids = selRes.Value.GetObjectIds();            
  23.  
  24.             using (DocumentLock docLock = doc.LockDocument())
  25.             {
  26.                 using (Transaction tr = db.TransactionManager.StartTransaction())
  27.                 {
  28.                     ObjectContextManager ocm = db.ObjectContextManager;
  29.                     ObjectContextCollection occ = ocm.GetContextCollection("ACDB_ANNOTATIONSCALES");
  30.  
  31.                     if (ocm == null)
  32.                         return;
  33.  
  34.                     /////////////
  35.                     foreach (ObjectId id in ids)
  36.                     {
  37.                         Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
  38.  
  39.  
  40.                         if(ent.GetType() == typeof(BlockReference))
  41.                         {
  42.                             BlockReference brr = (BlockReference)ent;
  43.                             BlockTableRecord btrr = tr.GetObject(brr.DynamicBlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  44.  
  45.                             if (btrr.Name == "отметка уровня")                            
  46.                             {
  47.  
  48.                                 BlockReference br = (BlockReference)tr.GetObject(id, OpenMode.ForWrite);
  49.                                 BlockTableRecord btr = tr.GetObject(br.BlockTableRecord, OpenMode.ForRead) as BlockTableRecord;
  50.                                 AttributeDefinition atr_def = new AttributeDefinition();
  51.  
  52.                                 if (!br.HasContext(occ.GetContext("1:1")))
  53.                                 {
  54.                                     br.AddContext(occ.GetContext("1:1"));
  55.                                 }
  56.  
  57.                                 foreach (var idEnt in btr)
  58.                                 {
  59.                                     Entity en = tr.GetObject(idEnt, OpenMode.ForRead) as Entity;
  60.                                     if (en.GetType() == typeof(AttributeDefinition))
  61.                                     {
  62.                                         AttributeDefinition atr = tr.GetObject(idEnt, OpenMode.ForWrite, false, true) as AttributeDefinition;
  63.                                         atr_def = atr;
  64.                                     }
  65.                                 }
  66.  
  67.                                 AnnotationScale currentScale = db.Cannoscale;
  68.                                 foreach (ObjectContext oc in occ)
  69.                                 {
  70.                                     if (br.HasContext(oc))
  71.                                     {
  72.                                         AnnotationScale annoScale = oc as AnnotationScale;
  73.                                         db.Cannoscale = annoScale;
  74.  
  75.                                         foreach (ObjectId idAtrRef in br.AttributeCollection)
  76.                                         {
  77.                                             AttributeReference atr_ref = tr.GetObject(idAtrRef, OpenMode.ForWrite) as AttributeReference;
  78.  
  79.                                             if (atr_ref.AlignmentPoint != null)
  80.                                             {
  81.                                                 atr_ref.AlignmentPoint = atr_def.AlignmentPoint.TransformBy(br.BlockTransform);
  82.                                             }
  83.                                             if (atr_ref.IsMTextAttribute)
  84.                                             {
  85.                                                 atr_ref.UpdateMTextAttribute();
  86.                                             }
  87.                                         }
  88.                                     }
  89.                                 }
  90.                                 db.Cannoscale = currentScale;
  91.  
  92.                             }                            
  93.                         }
  94.  
  95.                 }
  96.                     tr.Commit();
  97.                 }
  98.             }
  99.  
  100.  
  101.             MessageBox.Show("Выполнено!");
  102.  
  103.         }  //public void ustanov_mashtab()

думает правда долго на тяжелых чертежах(около минуты)...жалко что фильтр не работает с динамическими блоками из-за смены имени на "U..."