Тема: штриховка

Господа, теперь не могу к базы данных добавить штриховку. Например круг нарисовал. А теперь надо его заштриховать. Пишу что-то типа этого
    AcDbHatch *pHatch = new AcDbHatch;
    if ((es = pMS->appendAcDbEntity(pText)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД штриховки. ")) ;
        return (RSRSLT);
    };
    pHatch->close();

Re: штриховка

pMS->appendAcDbEntity(pText)

pText -> pHatch

Re: штриховка

чего-то не получается...

Re: штриховка

Вот так пишу, ну явно ошибка. Помогите пожалуйста   
AcDbHatch *pHatch = new AcDbHatch;
    AcDbCircle* pCircle = new AcDbCircle(center, AcGeVector3d::kZAxis, 50.0);
    // Добавление к БД рисунка окружности
    if ((es = pMS->appendAcDbEntity(pCircle)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД окружности. ")) ;
        return (RSRSLT);
    };
   
    pMS->appendAcDbEntity(pHatch);
    pCircle->pHatch;
    pCircle->close();

Re: штриховка

Здесь: https://www.caduser.ru/forum/topic23762.html

Re: штриховка

Александр, спасибо, но там вероятно код для поздней версии ObjectARX. Что-то не срабатывает. Окружность добавляется из немодального окна, текст в центр, даже вроде со штриховкой более ли менее понятно как ее описать. Конкретный вопрос, как эту штриховку связать с окружностью?
Спасибо.
int fUzel()
{
    AcDbObjectIdArray dbObjIds;
    ads_point pt;
    acedGetPoint(NULL,_T("\nУкажите точку"),pt);
    masUzel[countUzel].X=pt[0];
    masUzel[countUzel].Y=pt[1];
   
    // Признак ошибки (целое число)
    Acad::ErrorStatus es;
   
    // Подготовительная работа с таблицей блоков
    // Указатель на таблицу блоков (инициализируем нулем)
    AcDbBlockTable* pBlockTbl = NULL;
    // Открываем БД текущего рисунка и получаем указатель на таблицу блоков
    if ((es =
        acdbHostApplicationServices()->workingDatabase()->getBlockTable
        (pBlockTbl, AcDb::kForRead)) != Acad::eOk )
        {
            acutPrintf (_T("\nНе открыть таблицу блоков! ")) ;
            return (RSRSLT);
        }
    // Указатель на запись таблицы блоков
    AcDbBlockTableRecord *pMS = NULL;
    // Получаем указатель на пространство модели как блок ACDB_MODEL_SPACE
    //и открываем его для записи
    pBlockTbl->getAt(ACDB_MODEL_SPACE, pMS, AcDb::kForWrite);
    if (pMS == NULL)
    {
        acutPrintf (_T("\nНет доступа к блоку *Model_Space. ")) ;
        return (RSRSLT);
    }
    // Построение окружности
    //=======================
    // Создание объекта - трехмерной точки
    AcGePoint3d center(pt[0], pt[1], 0);
    // AcGeVector3d::kZAxis - стандартный вектор нормали (0, 0, 1)
    // Создание окружности по точке центра, вектору нормали и радиусу
    AcDbHatch *pHatch = new AcDbHatch;
    // Установим нормаль штриховки
    AcGeVector3d normal(0.0, 0.0, 1.0);
    // Установим уровень штриховки
    pHatch->setElevation(0.0);
    // Установим шаблон штриховки
    pHatch->setPattern(AcDbHatch::kPreDefined, _T("ANSI31"));
    // Установим ассоциативность
    pHatch->setAssociative(Adesk::kTrue);
    AcDbObjectId cirId;
    AcDbCircle* pCircle = new AcDbCircle(center, AcGeVector3d::kZAxis, 50.0);
    // Добавление к БД рисунка окружности
    if ((es = pMS->appendAcDbEntity(pCircle)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД окружности. ")) ;
        return (RSRSLT);
    };
   
    pHatch->appendLoop(AcDbHatch::kExternal, dbObjIds);
    pMS->appendAcDbEntity(pHatch);
    // Обработка контуров штриховки
    pHatch->evaluateHatch();
    AcDbObjectPointer<AcDbEntity> pEnt(cirId,AcDb::kForWrite);
    pEnt.openStatus();
    //pCircle->pHatch;
    pCircle->close();
    AcDbText* pText = new AcDbText (center,masUzel[countUzel].Name,0,10,0);
    if ((es = pMS->appendAcDbEntity(pText)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД текста. ")) ;
        return (RSRSLT);
    };
    pText->close();
    pMS->close();
    pBlockTbl->close();
    countUzel++;
    // TODO: Replace the following line by your returned value if any
    acedRetVoid () ;
    return (RSRSLT) ;
}

Re: штриховка

> Евгений
Для более поздней - это для какой? smile
Вместо:

AcDbObjectId cirId;
AcDbCircle* pCircle = new AcDbCircle(center, AcGeVector3d::kZAxis, 50.0);
// Добавление к БД рисунка окружности
if ((es = pMS->appendAcDbEntity(pCircle)) != Acad::eOk)
{
 acutPrintf (_T("\nОшибка добавления к БД окружности. ")) ;
 return (RSRSLT);
};

Должно быть:

AcDbObjectId cirId;
AcDbCircle* pCircle = new AcDbCircle(center, AcGeVector3d::kZAxis, 50.0);
// Добавление к БД рисунка окружности
if ((es = pMS->appendAcDbEntity(cirId,pCircle)) != Acad::eOk)
{
 delete pCircle;
 acutPrintf (_T("\nОшибка добавления к БД окружности. ")) ;
 return (RSRSLT);
};
pCircle->close();
dbObjIds.append(cirId);

Кроме того в случае ошибок у тебя не закрывается таблица блоков, так что развал AutoCAD тебе обеспечен.

Re: штриховка

Спасибо за совет, однако как правильно реализовать связь штриховки с объектом, например окружностью согласно выше приведенному тексту программы?

Re: штриховка

> Евгений
Еще раз внимательно прочитай то, что я тебе написал! dbObjIds должен содержать AcDbObjectId для примитивов, которые используются в качестве контура штриховки. Приведенный выше мною код именно это и делает, т.е. добавляет в этот массив AcDbObjectId для окружности. А у тебя в коде dbObjIds пустой (т.е. не содержит ни одного AcDbObjectId) и соответственно контура штриховки нет. Уже и не знаю как объяснить подробнее...

Re: штриховка

Я уже достал, но все-таки хотелось бы докопаться до истины. Постарался выполнить все Ваши рекомендации, Александр. Однако программа идет без ошибок, но штриховки нет. Привожу исходник. В нем программа рисует окружность, вставляет в нее текст, введенный из EDIT. И должна эту окружность заштриховать. Разные варианты испробовал, но только правильного не нашел - знаний маловато. Спасибо.
int AddHatch()
{
AcDbObjectIdArray dbObjIds;
    ads_point pt;
    acedGetPoint(NULL,_T("\nУкажите точку"),pt);
    masUzel[countUzel].X=pt[0];
    masUzel[countUzel].Y=pt[1];
   
    // Признак ошибки (целое число)
    Acad::ErrorStatus es;
   
    // Подготовительная работа с таблицей блоков
    // Указатель на таблицу блоков (инициализируем нулем)
    AcDbBlockTable* pBlockTbl = NULL;
    // Открываем БД текущего рисунка и получаем указатель на таблицу блоков
    if ((es =
        acdbHostApplicationServices()->workingDatabase()->getBlockTable
        (pBlockTbl, AcDb::kForRead)) != Acad::eOk )
        {
            acutPrintf (_T("\nНе открыть таблицу блоков! ")) ;
            return (RSRSLT);
        }
    // Указатель на запись таблицы блоков
    AcDbBlockTableRecord *pMS = NULL;
    // Получаем указатель на пространство модели как блок ACDB_MODEL_SPACE
    //и открываем его для записи
    pBlockTbl->getAt(ACDB_MODEL_SPACE, pMS, AcDb::kForWrite);
    if (pMS == NULL)
    {
        acutPrintf (_T("\nНет доступа к блоку *Model_Space. ")) ;
        return (RSRSLT);
    }
    // Построение окружности
    //=======================
    // Создание объекта - трехмерной точки
    AcGePoint3d center(pt[0], pt[1], 0);
    AcDbObjectId cirId;
    AcDbCircle* pCircle = new AcDbCircle(center, AcGeVector3d::kZAxis, 50.0);
   
    // Добавление к БД рисунка окружности
    if ((es = pMS->appendAcDbEntity(cirId,pCircle)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД окружности. ")) ;
        return (RSRSLT);
    };
    pCircle->close();
    dbObjIds.setLogicalLength(0);
    dbObjIds.append(cirId);
    AcDbHatch *pHatch = new AcDbHatch;
    // Установим нормаль штриховки
    AcGeVector3d normal(0.0, 0.0, 1.0);
    // Установим уровень штриховки
    pHatch->setElevation(0.0);
    // Установим шаблон штриховки
    pHatch->setPattern(AcDbHatch::kPreDefined, _T("ANSI31"));
    // Установим ассоциативность
    pHatch->setAssociative(Adesk::kTrue);
   
    AcDbObjectId HatchId;
    if ((es = pMS->appendAcDbEntity(HatchId,pHatch)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД штриховки. ")) ;
        return (RSRSLT);
    };
    pHatch->close();
    dbObjIds.append(HatchId);
// Обработка контуров штриховки
    pHatch->evaluateHatch();   
  // Добавим ассоциативность к окружности
  {
    AcDbObjectPointer<AcDbEntity> pEnt(cirId,AcDb::kForWrite);
    if ((es = pEnt.openStatus()) != Acad::eOk) {
      acutPrintf(_T("\nError open circle for write: %s"),acadErrorStatusText(es));
      return(RSRSLT);
    }
    pEnt->addPersistentReactor(HatchId);
  }
   
    AcDbText* pText = new AcDbText (center,masUzel[countUzel].Name,0,10,0);
    if ((es = pMS->appendAcDbEntity(pText)) != Acad::eOk)
    {
        acutPrintf (_T("\nОшибка добавления к БД текста. ")) ;
        return (RSRSLT);
    };
    pText->close();
    pMS->close();
    pBlockTbl->close();
    countUzel++;
    // TODO: Replace the following line by your returned value if any
    acedRetVoid () ;
    return (RSRSLT) ;
}

Re: штриховка

Повторим:

// Функция добавления примитива в базу чертежа
Acad::ErrorStatus postToDb(
    AcDbEntity* ent, AcDbObjectId& objId,
    const char *blkname = ACDB_MODEL_SPACE,
    AcDbDatabase *pDb = acdbCurDwg()
);
// Недокументированная функция для регенерации активного чертежа
void ads_regen(void);
static void AddHatch(void)
{
  Acad::ErrorStatus es;
  AcGePoint3d cenPt;
  if (acedGetPoint(NULL,_T("\nУкажите центр окружности: "),asDblArray(cenPt)) != RTNORM)
    return;
  ACHAR str[256]="";
  if (acedGetString(TRUE,_T("\nВведите текст: "),str) != RTNORM)
    return;
  AcDbCircle *pCircle = new AcDbCircle();
  pCircle->setDatabaseDefaults();
  pCircle->setNormal(AcGeVector3d::kZAxis);
  pCircle->setCenter(cenPt);
  pCircle->setRadius(50.0);
  AcDbObjectId cirId;
  postToDb(pCircle, cirId);
  // Создадим текст
  AcDbText *text = new AcDbText();
  text->setTextString(str);
  text->setDatabaseDefaults();
  text->setHorizontalMode(AcDb::kTextCenter);
  text->setVerticalMode(AcDb::kTextVertMid);
  text->setAlignmentPoint(cenPt);
  text->setHeight(10.0);
  AcDbObjectId textId;
  postToDb(text, textId);
  // Создадим штриховку
  AcDbHatch* pHatch = new AcDbHatch();
  pHatch->setDatabaseDefaults();
  // Установим нормаль штриховки
  pHatch->setNormal(AcGeVector3d::kZAxis);
  // Установим уровень штриховки
  pHatch->setElevation(0.0);
  // Установим шаблон штриховки
  pHatch->setPattern(AcDbHatch::kPreDefined, _T("ANSI31"));
  // Установим ассоциативность
  pHatch->setAssociative(Adesk::kTrue);
  AcDbObjectIdArray dbObjIds;
  dbObjIds.setLogicalLength(0); dbObjIds.append(cirId);
  pHatch->appendLoop(AcDbHatch::kExternal, dbObjIds);
  dbObjIds.setLogicalLength(0); dbObjIds.append(textId);
  pHatch->appendLoop(AcDbHatch::kDefault, dbObjIds);
  // Обработка контуров штриховки
  pHatch->evaluateHatch();
  AcDbObjectId hatchId;
  dbObjIds.setLogicalLength(0);
  pHatch->getAssocObjIds(dbObjIds);
  postToDb(pHatch, hatchId);
  // Добавим ассоциативность к окружностям
  for (int i=0; i < dbObjIds.length(); i++) {
    AcDbObjectPointer<AcDbEntity> pEnt(dbObjIds[i],AcDb::kForWrite);
    if ((es = pEnt.openStatus()) != Acad::eOk) {
      acutPrintf("\nError open circle for write: %s",acadErrorStatusText(es));
      return;
    }
    pEnt->addPersistentReactor(hatchId);
  }
  // Можно выполнить и регенерацию, хотя это необязательно
  ads_regen();
}
//////////////////////////////////////////////////////////////////////////
//          Функция добавления примитива в базу чертежа
//////////////////////////////////////////////////////////////////////////
Acad::ErrorStatus postToDb(AcDbEntity* ent, AcDbObjectId& objId, const char *blkname, AcDbDatabase *pDb)
{
  Acad::ErrorStatus es;
  if (ent==NULL) return Acad::eNullObjectPointer;
  if (pDb==NULL) return Acad::eNoDatabase;
  AcAxDocLock dblock(pDb);
  AcDbBlockTableRecordPointer pSpaceRecord(blkname,pDb,AcDb::kForWrite);
  if ((es = pSpaceRecord.openStatus()) != Acad::eOk) return es;
  if ((es = pSpaceRecord->appendAcDbEntity(objId, ent)) != Acad::eOk) {
    return es;
  }
  return ent->close();
}

Re: штриховка

Здравствуйте Александр. Большое спасибо, что хладнокровно и по порядку многократно все изложили вплото до исходника. Все получилось, но после небольшого уточнения. Тип const char нужно заменить на ACHAR. Тогда все работает! Это и тормозило меня и заставляло писать Вам вновь. Спасибо огромное!