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

ADN Club => AutoCAD .NET API => Тема начата: bert от 09-10-2017, 13:58:28

Название: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 09-10-2017, 13:58:28
Здравствуйте, уважаемые форумчане! Если допускается правилами форума, то у меня 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.         }
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 09-10-2017, 16:30:52
1) как называется метод для обновления атрибута?(AttributeDefinition.???)
??? Что такое обновление атрибута? Объясни очень (!!!) подробно что тебе нужно.
2) как называется метод для сброса блока? Изначально пытался включить аннотативность и сразу же её отключить для определения блока, но аннотативные масштабы не сбросились
Что ты понимаешь под сбросом блока? И вообще имеешь ли ты в виду определение блока (BLockTableRecord) или вставку блока (BlockRefrerence). Для вставки блока есть метод BlockReference.ResetBlock, но аннототивность этим методом сбрасываться не должна.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 10-10-2017, 06:56:55
1) про обновление атрибута

(https://s1.postimg.org/5356ibriu3/image.jpg) (https://postimg.org/image/5356ibriu3/)

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

(https://s1.postimg.org/31ewmm8ixn/image.jpg) (https://postimg.org/image/31ewmm8ixn/)

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

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

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

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

Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 10-10-2017, 08:03:37
атрибут находится в "слетевшем" состоянии.
Это как? У него неправильное положение?
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 10-10-2017, 08:06:38
Посмотри эту статью: http://adn-cis.org/ustanovka-polozheniya-mtext-dlya-kazhdogo-iz-masshtabov-annotaczij.html
Думаю что она применима и к атрибутам блока.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 10-10-2017, 08:18:21
Имеем блок с подвижным атрибутом
вставив его в модель имеем один аннотативный масштаб 1:1

(https://s1.postimg.org/14h15lsnmj/image.jpg) (https://postimg.org/image/14h15lsnmj/)

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

(https://s1.postimg.org/1n9d0ozmh7/image.jpg) (https://postimg.org/image/1n9d0ozmh7/)

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

(https://s1.postimg.org/4yeb8757kb/image.jpg) (https://postimg.org/image/4yeb8757kb/)

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

(https://s1.postimg.org/6c0uc8iu6j/image.jpg) (https://postimg.org/image/6c0uc8iu6j/)
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 10-10-2017, 09:14:48
bert,
Статью посмотрел? Попробовал?
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 10-10-2017, 09:38:37
На сколько я понял данный алгоритм находит координаты базовой точки в текущем аннотативном масштабе и устанавливает по остальным аннотативным масштабам такие же координаты базовой точки (правда не понял зачем прибавляется данный кусок умноженный на 3 (Vector3d.XAxis * 3 + Vector3d.YAxis * 3))

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

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

попробую найти "правильные координаты" и применить данную функцию
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 10-10-2017, 11:35:03
В общем благодарю, Александр, понял в каком направлении двигаться, но всё-таки хочется пойти по пути наименьшего сопротивления и уточнить: имеется ли команда которая обновляет атрибут как в _battman?
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 10-10-2017, 12:12:00
имеется ли команда которая обновляет атрибут как в _battman?
Нет. Во всяком случае мне она не знакома.
попробую найти "правильные координаты" и применить данную функцию
Именно так и следует поступить. Если ты хочешь поставить атрибут (AttributeReference) на место относительно полки, то должен получить смещение соответствующего AttribiteDefinition относительно полки в BlockTableRecord и поставить AttributeReference по этому же смещению (возможно с учетом масштабирования и поворота). Как-то так.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 16-10-2017, 12:12:48
Александр, в продолжении темы. долго мучился чтобы изменить вообще координаты атрибута
пробовал и
Код - 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 получаем точные координаты атрибута в модели? независимо от масштаба аннотации

Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 16-10-2017, 12:53:44
AttribiteDefinition.TransformBy(br.BlockTransform);
Это лишь преобразование по матрице преобразования самого определения атрибута. А нам нужна вставка атрибута.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 16-10-2017, 13:06:27
найдем определение атрибута

Код - 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 * на делитель масштаба аннотации; -

лично для меня более наглядна из-за незнания данных методов
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 16-10-2017, 13:20:27
можно ли заменить строку

Код - 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 наиболее правильный метод.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: bert от 17-10-2017, 08:15:28
В итоге получился вот такой код

Код - 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..."
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Дмитрий Загорулькин от 18-10-2017, 20:18:37
думает правда долго на тяжелых чертежах(около минуты)...жалко что фильтр не работает с динамическими блоками из-за смены имени на "U..."
Так это потому, что не надо так делать. Не надо использовать SelectAll, если можно просто найти нужное описание блока в таблице блоков и из него получить все вставки блока в чертеже, включая анонимные.
Название: Re: Аннотативность блока, и обновление атрибутов
Отправлено: Александр Ривилис от 18-10-2017, 20:23:00
думает правда долго на тяжелых чертежах(около минуты)...жалко что фильтр не работает с динамическими блоками из-за смены имени на "U..."
Так это потому, что не надо так делать. Не надо использовать SelectAll, если можно просто найти нужное описание блока в таблице блоков и из него получить все вставки блока в чертеже, включая анонимные.
Именно!
bert
Читаем: Как найти все вставки динамического блока (http://adn-cis.org/kak-najti-vse-vstavki-dinamicheskogo-bloka.html)