блоки и атрибуты

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

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

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

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

  • ADN OPEN
  • Сообщений: 40
  • Карма: 1
блоки и атрибуты
« : 12-02-2019, 10:01:30 »
Добрый день!
Вопрос к этому коду уважаемого Александра Наумовича насчет блоков:
Код - C++ [Выбрать]
  1. static void BlockRefIterate(void)
  2. {
  3.   ads_name en;
  4.   ads_point p;
  5.   Acad::ErrorStatus es;
  6.   if (acedEntSel("\nУкажите блок для получения информации: ",en,p) == RTNORM) {
  7.     AcDbObjectId objId; acdbGetObjectId(objId,en);
  8.     AcDbObjectPointer<AcDbBlockReference> pEnt(objId,AcDb::kForRead);
  9.     if ((es = pEnt.openStatus()) == Acad::eOk) {
  10.       AcDbObjectId objBTRId = pEnt->blockTableRecord();
  11.       AcDbObjectPointer<AcDbBlockTableRecord> pBTR(objBTRId,AcDb::kForRead);
  12.       if ((es = pBTR.openStatus()) == Acad::eOk) {
  13.         AcDbBlockTableRecordIterator *pIterBTR = NULL;
  14.         if ((es = pBTR->newIterator(pIterBTR)) == Acad::eOk) {
  15.           for (;!pIterBTR->done();pIterBTR->step()) {
  16.             AcDbObjectId objSubId;
  17.             if ((es = pIterBTR->getEntityId(objSubId)) == Acad::eOk) {
  18.               AcDbObjectPointer<AcDbEntity> pSubEnt(objSubId,AcDb::kForRead);
  19.               if ((es = pSubEnt.openStatus()) == Acad::eOk) {
  20.                 //
  21.                 // Здесь можно работать с примитивами в блоке
  22.                 //
  23.                 acutPrintf("\nПримитив: %s",pSubEnt->isA()->name());
  24.                 AcDbAttributeDefinition *pAttdef = AcDbAttributeDefinition::cast(pSubEnt.object());
  25.                 //
  26.                 // Если это определение атрибута сделаем отдельную обработку
  27.                 //
  28.                 if (pAttdef) {
  29.                   acutPrintf("-> Tag=%s Value=%s IsConst=%s IsPreset=%s IsInvisible=%s isVerifiable=%s",
  30.                               pAttdef->tagConst(), pAttdef->textStringConst(),
  31.                               (pAttdef->isConstant()?"Yes":"No"),
  32.                               (pAttdef->isPreset()?"Yes":"No"),
  33.                               (pAttdef->isInvisible()?"Yes":"No"),
  34.                               (pAttdef->isVerifiable()?"Yes":"No")
  35.                   );
  36.                 }
  37.               } else {
  38.                 acutPrintf("\nНе удалось открыть примитив в блоке! Ошибка: %s",
  39.                            acadErrorStatusText(es));
  40.               }
  41.             } else {
  42.               acutPrintf("\nНе удалось получить AcDbObjectId примитва в блоке! Ошибка: %s",
  43.                          acadErrorStatusText(es));
  44.             }
  45.           }
  46.         } else {
  47.           acutPrintf("\nНе удалось создать итератор для записи таблицы блоков! Ошибка: %s", acadErrorStatusText(es));
  48.         }
  49.       } else {
  50.         acutPrintf("\nНе удалось открыть запись таблицы блоков! Ошибка: %s", acadErrorStatusText(es));
  51.       }
  52.       //
  53.       //  Получаем информацию о неконстантных атрибутах в блоке
  54.       //
  55.       AcDbObjectIterator *pAttrIter = pEnt->attributeIterator();
  56.       if (pAttrIter) {
  57.         for (pAttrIter->start();!pAttrIter->done();pAttrIter->step()) {
  58.           AcDbObjectId objAttrId = pAttrIter->objectId();
  59.           AcDbObjectPointer<AcDbAttribute> pAttr(objAttrId,AcDb::kForRead);
  60.           if ((es = pAttr.openStatus()) == Acad::eOk) {
  61.             //
  62.             // Здесь можно получить информацию об атрибуте
  63.             //
  64.             acutPrintf("\nАтрибут: Tag=%s Value=%s IsConst=%s IsPreset=%s IsInvisible=%s isVerifiable=%s",
  65.                        pAttr->tagConst(), pAttr->textStringConst(),
  66.                       (pAttr->isConstant()?"Yes":"No"),
  67.                       (pAttr->isPreset()?"Yes":"No"),
  68.                       (pAttr->isInvisible()?"Yes":"No"),
  69.                       (pAttr->isVerifiable()?"Yes":"No")
  70.             );
  71.           } else {
  72.             acutPrintf("\nНе удалось открыть атрибут блока! Ошибка: %s", acadErrorStatusText(es));
  73.           }
  74.         }
  75.       }
  76.     } else if (es == Acad::eNotThatKindOfClass) {
  77.       acutPrintf("\nЭто не блок!");
  78.     } else {
  79.       acutPrintf("\nНе удалось открыть блок! Ошибка: %s", acadErrorStatusText(es));
  80.     }
  81.   }
  82. }

Когда блок выбирается в чертеже (по коду) все хорошо. Когда заранее блок с атрибутом програмно внесен в чертеж,
и есть его AcDbObjectId, вторая часть кода не выполняется, ниже этого:
Цитировать
Получаем информацию о неконстантных атрибутах в блоке
То есть сюда не заxодит
Цитировать
for (pAttrIter->start();!pAttrIter->done();pAttrIter->step())
Так и должно быть или я что-то напортачил? Спасибо заранее.

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: блоки и атрибуты
« Ответ #1 : 12-02-2019, 18:04:00 »
Когда заранее блок с атрибутом програмно внесен в чертеж,
и есть его AcDbObjectId, вторая часть кода не выполняется, ниже этого:
Похоже вы не создали атрибуты когда "программно вносили блок" в чертеж. :)
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 40
  • Карма: 1
Re: блоки и атрибуты
« Ответ #2 : 12-02-2019, 19:16:23 »
Был создан блок с атрибутами, я его внес в чертеж из другого файла. Но он может быть и без заполненных атрибутов. Проблема что итератор их не видит...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: блоки и атрибуты
« Ответ #3 : 12-02-2019, 19:51:22 »
Был создан блок с атрибутами, я его внес в чертеж из другого файла. Но он может быть и без заполненных атрибутов. Проблема что итератор их не видит...
Похоже путаешь AcDbBlockTableRecord и AcDbBlockReference. После создания AcDbBlockReference и добавления его к базе данных к нему необходимо добавить атрибуты (AcDbAttribute) при помощи метода AcDbBlockReference::appendAttribute
Как пример: https://knowledge.autodesk.com/search-result/caas/CloudHelp/cloudhelp/2019/ENU/OARX-DevGuide/files/GUID-0C509F32-0BCE-4373-9FF4-6962B6E1F677-htm.html
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 40
  • Карма: 1
Re: блоки и атрибуты
« Ответ #4 : 12-02-2019, 20:39:03 »
У меня задача не создать блок с атрибутом, а внести в чертеж готовый блок и исправить затем в нем атрибуты. Когда мы вносим блок в базу данных, он сохраняет свои атрибуты? Может быть причина почему в AcDbBlockTableRecord итератор не видит атрибуты?
вставляю блок так :
Код - C++ [Выбрать]
  1. AcDbObjectId insertBlockRef(AcDbObjectId idBtr, AcGePoint3d pt)
  2. {
  3.         AcDbBlockTableRecordPointer pSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
  4.         if (pSpace.openStatus() != Acad::eOk)
  5.                 return;
  6.         AcDbBlockReference *pRef = new AcDbBlockReference(pt, idBtr);
  7.         pRef->setDatabaseDefaults(acdbCurDwg());
  8. AcDbObjectId id;
  9.         pSpace->appendAcDbEntity(id, pRef);
  10.         pRef->close();
  11.         return id;
  12. }
Все вставляется прекрасно, только потом атрибутов не видно итератором...

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: блоки и атрибуты
« Ответ #5 : 12-02-2019, 20:40:56 »
Все вставляется прекрасно, только потом атрибутов не видно итератором...
Ты ничего не понял из того, что я тебе написал. Перечитай еще раз и сделай как я сказал.
После создания AcDbBlockReference и добавления его к базе данных к нему необходимо добавить атрибуты (AcDbAttribute) при помощи метода AcDbBlockReference::appendAttribute
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

Отмечено как Решение alsh 13-02-2019, 10:20:40

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

  • Administrator
  • *****
  • Сообщений: 13829
  • Карма: 1784
  • Рыцарь ObjectARX
  • Skype: rivilis
Re: блоки и атрибуты
« Ответ #6 : 12-02-2019, 22:52:05 »
alsh,
В первом приближении твоя функция по созданию вставки блока должна выглядеть так:
Код - C++ [Выбрать]
  1. AcDbObjectId insertBlockRef(AcDbObjectId idBtr, AcGePoint3d pt)
  2. {
  3.   AcDbBlockTableRecordPointer pSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
  4.   if (pSpace.openStatus() != Acad::eOk)
  5.           return;
  6.   AcDbBlockReference *pRef = new AcDbBlockReference(pt, idBtr);
  7.   pRef->setDatabaseDefaults(acdbCurDwg());
  8.   AcDbObjectId id;
  9.   pSpace->appendAcDbEntity(id, pRef);
  10.   // Нужно не забыть про атрибуты блока
  11.   AcDbBlockTableRecordPointer pBlockDef(idBtr, AcDb::kForRead);
  12.   Acad::ErrorStatus es = pBlockDef.openStatus();
  13.   AcDbBlockTableRecordIterator *pIterator = NULL;
  14.   pBlockDef->newIterator(pIterator);
  15.   for (pIterator->start(); !pIterator->done(); pIterator->step())
  16.   {
  17.     AcDbObjectId idAttDef;
  18.     pIterator->getEntityId(idAttDef);
  19.     AcDbObjectPointer<AcDbAttributeDefinition> pAttdef(idAttDef, AcDb::kForRead);
  20.     // Только неконстантные атрибуты
  21.     if (pAttdef.openStatus() == Acad::eOk && !pAttdef->isConstant())
  22.     {
  23.       AcDbObjectPointer<AcDbAttribute> pAtt; pAtt.create();
  24.       pAtt->setAttributeFromBlock(pAttdef,AcGeMatrix3d::kIdentity);
  25.       // Переносим дополнительно своства определения атрибута в атрибут
  26.       pAtt->setInvisible(attdef->isInvisible());
  27.       pAtt->setFieldLength(attdef->fieldLength());
  28.  
  29.       pAtt->setThickness(attdef->thickness());
  30.       pAtt->setOblique(attdef->oblique());
  31.       pAtt->setRotation(attdef->rotation());
  32.       pAtt->setHeight(attdef->height());
  33.       pAtt->setTextStyle(attdef->textStyle());
  34.       pAtt->mirrorInX(attdef->isMirroredInX());
  35.       pAtt->mirrorInY(attdef->isMirroredInY());
  36.       pAtt->setHorizontalMode(attdef->horizontalMode());
  37.       pAtt->setVerticalMode(attdef->verticalMode());
  38.       pAtt->setPosition(attdef->position());
  39.       pAtt->setAlignmentPoint(attdef->alignmentPoint());
  40.       pAtt->setTag(attdef->tagConst());
  41.       pAtt->setTextString(attdef->textStringConst());
  42.      
  43.       pAtt->transformBy(pBlkRef->blockTransform());
  44.       AcDbObjectId attId;
  45.       pBlkRef->appendpAttute(attId, pAtt);
  46.     }
  47.   }
  48.   delete pIterator;
  49.   pRef->close();
  50.   return id;
  51. }

P.S.: По техническим причинам я не компилировал и не тестировал код. Надеюсь, что нигде нет опечаток.
Не забывайте про правильное Форматирование кода на форуме
Создание и добавление Autodesk Screencast видео в сообщение на форуме
Если Вы задали вопрос и на форуме появился правильный ответ, то не забудьте про кнопку Решение

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

  • ADN OPEN
  • Сообщений: 40
  • Карма: 1
Re: блоки и атрибуты
« Ответ #7 : 13-02-2019, 10:13:58 »
Cпасибо огромное Александр!!