(изменено: teem0n, 10 октября 2011г. 10:18:34)

Тема: Динамические блоки

Здравствуйте!

Возник вопрос по динамическим блокам. Есть блок с ручкой, за которую его можно растягивать (параметр длины, соответственно double).
Хочется растягивать его программно.

Теоретический вопрос: динамические блоки - это блоки с ручками, ведь так?:)

Для определения свойств использую такой код (чуть изменил пример Александра Ривилиса):

static void FpmSimpleLine_DynBlockTest(void)
    {
      ads_name en; ads_point p;
      if (acedEntSel(_T("\nPick dynamic block: "),en,p) == RTNORM) 
      {
        AcDbObjectId eId; acdbGetObjectId(eId,en);
        AcDbObjectPointer<AcDbBlockReference> pBlkRef(eId,AcDb::kForRead);
        if (pBlkRef.openStatus() == Acad::eOk) 
        {
          AcDbObjectId idBlkTblRec = pBlkRef->blockTableRecord();
          if (AcDbDynBlockReference::isDynamicBlock(idBlkTblRec)) 
          {
            AcDbDynBlockReference dynBlk(eId);
            AcDbDynBlockReferencePropertyArray aProps;
            dynBlk.getBlockProperties(aProps);
            if (aProps.length() > 0) 
            {
                AcDbDynBlockReferenceProperty prop;
              for (int i=0; i < aProps.length(); i++) 
              {
                prop = aProps[i];
                AcDbEvalVariant Var = prop.value();
               acutPrintf(L"Property %d name: %s, value: %lg\n",i+1,prop.propertyName().kTCharPtr(),Var.resval.rreal);
                }
            }
          } else {
            acutPrintf(_T("\nSelected block is not dynamic!"));
          }
        } else {
          acutPrintf(_T("\nError: %s"),acadErrorStatusText(pBlkRef.openStatus()));
        }
      }
    }

Почему-то если выбрать блок без ручек, он не пишет "Selected block is not dynamic!", т е попадает в if.

Еще у меня не получается записывать атрибуты...

Re: Динамические блоки

teem0n пишет:

Почему-то если выбрать блок без ручек, он не пишет "Selected block is not dynamic!", т е попадает в if.

Ты про какие ручки? Есть ручки обычные, а есть ручки для динамических блоков.

Re: Динамические блоки

Ручки, например, линейного параметра блока (с которым связана операция растяжения).

Нашел вот такой пример: http://forums.autodesk.com/t5/Autodesk- … -p/2500361 (ссылки на сторонние ресурсы разрешены?)

Но он у меня
1) не компилировался, сделал AcArray<TCHAR*> visNames;
2) не меняет параметр (хотя вот это visNames.at(1) должно, как я понимаю, устанавливать второй параметр)

Re: Динамические блоки

Еще хотелось бы понять следующий момент: если я делаю так:

AcDbObjectPointer<AcDbBlockReference> pBlkRef(eId,AcDb::kForWrite);

То aProps не заполняются (проверка "isDynamicBlock" проходится, дальше не идет).

Что не так?

Re: Динамические блоки

Через транзакции получилось:

static void FpmSimpleLine_DDynBlockTest(void)
    {
        ads_name en; ads_point p;
        AcTransaction* pTrans = actrTransactionManager->startTransaction();

        if (acedEntSel(_T("\nPick dynamic block: "),en,p) == RTNORM) 
        {
            AcDbObjectId eId;

            AcDbBlockReference *pBlkRef;//
            acdbGetObjectId(eId,en);
            

            if (pTrans->getObject( (AcDbObject*&)pBlkRef,eId,AcDb::kForWrite) == Acad::eOk) 
            {

                AcDbObjectId idBlkTblRec = pBlkRef->blockTableRecord();
                if (AcDbDynBlockReference::isDynamicBlock(idBlkTblRec)) 
                {
                    acutPrintf(L"Dynamic block!\n");
                    AcDbDynBlockReference dynBlk(eId);
                    AcDbDynBlockReferencePropertyArray aProps;
                    dynBlk.getBlockProperties(aProps);
                    if (aProps.length() > 0) 
                    {
                        acutPrintf(L"There are some properties!\n");
                        AcDbDynBlockReferenceProperty prop;
                        AcDbEvalVariant Var;
                        int i;
                        for (i=0; i < aProps.length(); i++) 
                        {
                            prop = aProps[i];
                            Var = prop.value();
                            acutPrintf(L"Property %d name: %s, value: %lg, readonly:%s\n",i+1,prop.propertyName().kTCharPtr(),Var.resval.rreal,prop.readOnly()?L"TRUE":L"FALSE");
                        }
                        
                        prop=aProps[0];
                        if(prop.setValue(500.0)!=Acad::eOk)
                            acutPrintf(_T("\nError setting property: %s"),acadErrorStatusText(prop.setValue(500.0)));
                        
                    }
                } 
                else 
                {
                    acutPrintf(_T("\nSelected block is not dynamic!"));
                }
                pBlkRef->close();
            } 
            else 
            {
                acutPrintf(_T("\nError: %s"),pTrans->getObject( (AcDbObject*&)pBlkRef,eId,AcDb::kForWrite));

            }
        }
        
        actrTransactionManager->endTransaction();
    }

Осталась одна проблема - я что-то где-то не закрываю, повторно функцию к данному блоку применить нельзя. Буду благодарен, если укажете.

Re: Динамические блоки

teem0n пишет:

То aProps не заполняются (проверка "isDynamicBlock" проходится, дальше не идет).

Очень может быть, т.к. функция косвенно пытается открыть AcDbBlockReference для чтения, а он уже открыт для записи. Так что нужно сначала открыть для чтения, получить всю нужную информацию, а перед модификацией вызвать метод upgradeOpen()

Re: Динамические блоки

teem0n пишет:

pBlkRef->close();

Это лишнее. Завершение транзакции закроет его.

Re: Динамические блоки

teem0n пишет:

else{ acutPrintf(_T("\nError: %s"),pTrans->getObject( (AcDbObject*&)pBlkRef,eId,AcDb::kForWrite));

}

А это совсем бред.

Re: Динамические блоки

Александр Ривилис пишет:
teem0n пишет:

else{ acutPrintf(_T("\nError: %s"),pTrans->getObject( (AcDbObject*&amp;)pBlkRef,eId,AcDb::kForWrite));



}

А это совсем бред.

Это уже исправил. Копипаста виновата :(

pBlkRef->close(); тоже убрал, пробовал... А где еще может быть ошибка? Вылезает "Selected block is not dynamic!"

Re: Динамические блоки

Александр, а по поводу ошибки можете чем-нибудь помочь? Вроде ничего лишнего не открываю...

(изменено: Александр Ривилис, 12 октября 2011г. 14:43:42)

Re: Динамические блоки

static void ChangeDynValue(void)
{
  // Add your code for command TestDynBlk.ChangeDynValue here
  ads_name en; ads_point p;
  if (acedEntSel(_T("\nУкажите динамический блок: "), en,p) != RTNORM) return;
  AcDbObjectId idBR; acdbGetObjectId(idBR,en);
  AcDbObjectPointer<AcDbBlockReference> pBR(idBR,AcDb::kForRead);
  Acad::ErrorStatus es = pBR.openStatus();
  if (es == Acad::eWrongObjectType) { acutPrintf(_T("\nЭто не блок!")); return; }
  if (es != Acad::eOk) {  acutPrintf(_T("\nНе могу открыть блок!")); return; }

  AcDbDynBlockReference* pDynBlkRef = new AcDbDynBlockReference(idBR);
  pBR->close();
  if (!pDynBlkRef || !pDynBlkRef->isDynamicBlock()) {
    acutPrintf(_T("\nЭто не динамический блок!"));
    delete pDynBlkRef;
    return;
  }

  ACHAR propName[512] = _T("");
  if (acedGetString(TRUE,_T("\nУкажите имя динамического свойства (тип - действительное число): "), propName) != RTNORM) return;
  double propValue = 0;
  if (acedGetReal(_T("\nУкажите значение динамического свойства - действительное число: "), &propValue) != RTNORM) return;

  AcDbDynBlockReferencePropertyArray blkPropAry;  pDynBlkRef->getBlockProperties(blkPropAry);
  AcDbDynBlockReferenceProperty blkProp;
  bool isFindPropName = false;
  for(long i=0 ; i < blkPropAry.length() ; i++) {
    blkProp = blkPropAry[i];
    if (wcsicmp(blkProp.propertyName().kACharPtr(), propName) != 0) continue;
    isFindPropName = true;
    if (blkProp.readOnly()) {
      acutPrintf(_T("\nСвойство <%s> только для чтения!"), propName); continue;
    }
    if ((es = blkProp.setValue(propValue)) != Acad::eOk) {
      acutPrintf(_T("\nНельзя установить свойству <%s> значение %g! Ошибка: %s"), 
        propName, propValue,acadErrorStatusText(es));
      continue;
    }
  }
  delete pDynBlkRef;
  if (!isFindPropName) {
    acutPrintf(_T("\nСвойство <%s> не найдено!"), propName);
  }
}

Re: Динамические блоки

Спасибо огромное! Буду разбираться, где у меня фигня. :oops:

Еще маленький вопрос: это код зачисляет в динамические блоки блоки с текстовыми параметрами. Оно так и должно быть? Свойств, разумеется, у них нету, но тем не менее...

Re: Динамические блоки

teem0n пишет:

Еще маленький вопрос: это код зачисляет в динамические блоки блоки с текстовыми параметрами.

Чего? Этот код изменяет динамические параметры по имени параметра. Какие текстовые параметры???
Динамические параметры представляют из себя пару: {ключ значение}. ключ - это имя динамического параметра (всегда строка), значение - это значение (может быть строкой, действительным числом и т.д.)

Re: Динамические блоки

Я понимаю, что такое динамические параметры. Но если выбрать обычный блок (у которого есть пара текстовых параметров, но нет динамических), то сообщение "Это не динамический блок!" не появляется.

Почему?

Re: Динамические блоки

teem0n пишет:

то сообщение "Это не динамический блок!" не появляется.
Почему?

Изменил код. К тому что ты называешь "текстовыми параметрами", и которые, как я могу только догадываться, или просто тексты или атрибуты блока, это никакого отношения не имеет. И возьми наконец-то в руки книгу по AutoCAD и почитай её, разберись с терминами, иначе буду игнорировать твои вопросы. У меня нет времени разгадывать ребусы.

Re: Динамические блоки

Понял, исправлюсь...

Я имел ввиду, что для функции нет разницы между статическими (обычными, без ручек) и динамическими блоками.

Re: Динамические блоки

teem0n пишет:

Я имел ввиду, что для функции нет разницы между статическими (обычными, без ручек) и динамическими блоками.

Теперь будет различать.

(изменено: teem0n, 12 октября 2011г. 23:28:38)

Re: Динамические блоки

У меня почему-то не различает... Могу файл .dwg прислать :) Но, в общем, это не сильно важно. Спасибо большое за помощь!

Re: Динамические блоки

teem0n пишет:

Могу файл .dwg прислать

Пришли, а еще лучше выложи куда-нибудь и сюда ссылку. Только убедись, что использовал последнюю версию версию программы из #11

(изменено: teem0n, 13 октября 2011г. 10:02:00)

Re: Динамические блоки

Только что убедился. Надеюсь, что я не напутал с определениями блоков :oops:

Ссылка: http://narod.ru/disk/28252648001/%D0%91 … 0.dwg.html

На обоих работает.

Re: Динамические блоки

Ты снова всё перепутал. Оба блока динамические:
Динамические блоки
Динамические блоки
Красным обведено то, что делает блок динамическим. Еще раз повторяю - читай книжки, документацию по AutoCAD!