Тема: Разбор примера. Создание полилинии и добавление ее в БД чертежа

Перенесено из темы: Есть ли сайт с примерами программ на ObjectARX?.
/Администратор./

Нашёл в справочной системе пример:

The following example demonstrates creating a line and appending it to the model space block table record, as described in chapter 2, Database Primer.
AcDbObjectId
createLine()
{
    AcGePoint3d startPt(4.0, 2.0, 0.0);
    AcGePoint3d endPt(10.0, 7.0, 0.0);
    AcDbLine *pLine = new AcDbLine(startPt, endPt);
    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForRead);
    AcDbBlockTableRecord *pBlockTableRecord;
    pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
        AcDb::kForWrite);
    pBlockTable->close();
    AcDbObjectId lineId;
    pBlockTableRecord->appendAcDbEntity(lineId, pLine);
    pBlockTableRecord->close();
    pLine->close();
    return lineId;
}

И честно говоря у меня немного повилось удивление. Понятно что мы вычерчиваем линию задавая её координаты, но зачем потом вручную добавлять параметры этой линии в базу данных чертежа:

and appending it to the model space block table record

, это мог бы сделать сам ObjectARX вот так например:

AcDbObjectId
createLine()
{
    AcGePoint3d startPt(4.0, 2.0, 0.0);
    AcGePoint3d endPt(10.0, 7.0, 0.0);
    AcDbLine *pLine = new AcDbLine(startPt, endPt);
    pLine->close();
    return lineId;
}

Получается что надо написать в 2 или в 3 раза больше кода чтобы сделать почти тоже самое, что в VBA или это только мне кажется?

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

> Миша
1) На этом сайте принято "Новый вопрос -- новая тема". Так что прошу дальнейшие вопросы оформлять отдельными темами, чтобы не нагружать Администратора лишней работой.
2) Это сказывается твое VBA-шное прошлое. :) В действительности все очень логично. Примитив создается в памяти (в оперативной памяти). Его можно добавить в чертеж, а можно и не добавлять (например, для геометрических построений, для получения габаритов, нахождения пересечения с  существующими примитивами и многого другого).
А кода нужно писать значительно меньше. Достаточно раз и навсегда написать функцию для добавления примитива в базу (например, нижеследующую) и использовать ее:

Acad::ErrorStatus postToDwg (AcDbEntity *pEnt, AcDbDatabase *pDb=NULL, const char *requiredSpace=ACDB_MODEL_SPACE);
///////////////////////////////////////////////////////////////
// Добавление примитива в указанное пространство
// (по-умолчанию Model_Space) чертежа (по-умолчанию, в  текущий чертеж)
///////////////////////////////////////////////////////////////
Acad::ErrorStatus postToDwg (AcDbEntity *pEnt, AcDbDatabase *pDb, const char *requiredSpace)
{
  if (pDb == NULL) pDb = acdbHostApplicationServices()->workingDatabase();
  AcDbBlockTable *blockTable = NULL;
  Acad::ErrorStatus es = pDb->getBlockTable (blockTable, AcDb::kForRead);
  if (es != Acad::eOk)  return (es);
  AcDbBlockTableRecord *blockTableRecord = NULL;
  es = blockTable->getAt (requiredSpace, blockTableRecord, AcDb::kForWrite);
  blockTable->close ();
  if (es != Acad::eOk) return (es);
  es = blockTableRecord->appendAcDbEntity (pEnt);
  blockTableRecord->close();
  return (es);
}

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

P.S.: Тогда функция createLine будет выглядеть так:

createLine()
{
    AcGePoint3d startPt(4.0, 2.0, 0.0);
    AcGePoint3d endPt(10.0, 7.0, 0.0);
    AcDbLine *pLine = new AcDbLine(startPt, endPt);
    postToDwg(pLine); // <--- добавилась ровно одна строка кода
    pLine->close();
    return lineId;
}

Если необходимо получать еще и AcDbObjectId добавленого в чертеж примитива, то можно функцию postToDwg переписать, например, так:

Acad::ErrorStatus postToDwg(AcDbEntity* ent, AcDbObjectId& objId, AcDbDatabase *pDb = acdbCurDwg(), const char *blkname = ACDB_MODEL_SPACE);
//////////////////////////////////////////////////////////////////////////
//          Функция добавления примитива в базу чертежа
//////////////////////////////////////////////////////////////////////////
Acad::ErrorStatus postToDwg(AcDbEntity* ent, AcDbObjectId& objId, , AcDbDatabase *pDb, const char *blkname)
{
  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: Разбор примера. Создание полилинии и добавление ее в БД чертежа

Спасибо большое! Но для меня очень много непонятного в этом коде, каие-то стрелки ->, затем повторяющиеся двоеточия :: и выражение != мне не понятно. Зачем например два раза подряд использовать знак ==? Надо ещё в этом очень долго разбираться и надо надеяться, что когда-нибудь я что-нибудь пойму из этого.

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

Миша пишет:

Надо ещё в этом очень долго разбираться и надо надеяться, что когда-нибудь я что-нибудь пойму из этого.

Все что тебе здесь непонятно - это синтаксис языка C++. Без его знания увы написать ни одну программу с использованием ObjectARX не получится.

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

> Миша
Стоит сначала изучить С++ и Объектно-Ориентированный подход.
!= - это "не равно", "==" - "равно"... Остальное узнаете изучив ООП.

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

А в чем прелесть ручного создания объекта AcDbLine, перед acedCommand("...LINE...."); ??

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

> supremum
1) код работает быстрее;
2) не нужно задумываться о привязках и других системных переменых;
3) можно создавать в контексте приложения;
4) можно работать в тех контекстах, в которых acedCommand() не работает;
5) можно добавить отрезок в чертеж, который не только не является текущим, но и не загружен в редактор AutoCAD;
6) и т.д.
Достаточно?

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

Действительно весомые аргументы..

4) можно работать в тех контекстах, в которых acedCommand() не работает;

К примеру ?
И вообще, что подразумевается под контекстом ?
К примеру, в ObjectARX Commands есть ключ Context, принимающий значения либо Application, либо Document. What is it ? )))

Re: Разбор примера. Создание полилинии и добавление ее в БД чертежа

> supremum
Почитай документацию: ObjectARX Developer's Guide->Advanced Topics->Application Execution Context