ObjectARX, AutoCAD. Среда программирования библиотеки C++

Функции Данных Примитива


Некоторые функции работают на данных примитива и могут использоваться, чтобы изменить базу данных текущего рисунка. AcdbEntDel () функция удаляет указанный примитив. Примитив не очищен от базы данных, пока Вы не оставляете текущий рисунок.

Так, если приложение вызывает acdbEntDel () второй раз в течение того сеанса и определяет тот же самый примитив, примитив восстановлен. (Вы можете использовать acdbHandEnt () чтобы восстановить{*отыскать*} названия{*имена*} удаленных примитивов.)

ОБРАТИТЕ ВНИМАНИЕ На использование acdbEntDel (), атрибуты, и вершина ломаной линии не может быть удалена независимо от их родительских примитивов; acdbEntDel () работает только на основных примитивах. Чтобы удалять атрибут или вершину, используйте acedCommand () или acedCmd () чтобы вызвать AutoCAD ATTEDIT или команды PEDIT, используйте acdbEntMod () чтобы переопределить примитив без нежелательных подпримитивов, или откройте вершину, или припишите, и используйте ее стирание () метод стереть это.

AcdbEntGet () функция возвращает данные определения указанного примитива.

Данные возвращены как список связей буферов результатов. Тип каждого элемента (буфер) в списке определен кодом группы DXF. Первый элемент в списке содержит текущее имя примитива (restype == -1).

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

void getlast()

{

struct resbuf *ebuf, *eb;

ads_name ent1;

acdbEntLast(ent1);

ebuf = acdbEntGet(ent1);

eb = ebuf;



acutPrintf("\nResults of entgetting last entity\n");

// Print items in the list.

for (eb = ebuf; eb != NULL; eb = eb->rbnext)

printdxf(eb);

// Release the acdbEntGet() list.

acutRelRb(ebuf);

}

int printdxf(eb)

struct resbuf *eb;

{

int rt;

if (eb == NULL)

return RTNONE;

if ((eb->restype >= 0) && (eb->restype <= 9))

rt = RTSTR ;

else if ((eb->restype >= 10) && (eb->restype <= 19))


rt = RT3DPOINT;

else if ((eb->restype >= 38) && (eb->restype <= 59))

rt = RTREAL ;

else if ((eb->restype >= 60) && (eb->restype <= 79))

rt = RTSHORT ;

else if ((eb->restype >= 210) && (eb->restype <= 239))

rt = RT3DPOINT ;

else if (eb->restype < 0)

// Entity name (or other sentinel)

rt = eb->restype;

else

rt = RTNONE;

switch (rt) {

case RTSHORT:

acutPrintf("(%d . %d)\n", eb->restype,

eb->resval.rint);

break;

case RTREAL:

acutPrintf("(%d . %0.3f)\n", eb->restype,

eb->resval.rreal);

break;

case RTSTR:

acutPrintf("(%d . \"%s\")\n", eb->restype,

eb->resval.rstring);

break;

case RT3DPOINT:

acutPrintf("(%d . %0.3f %0.3f %0.3f)\n",

eb->restype,

eb->resval.rpoint[X], eb->resval.rpoint[Y],

eb->resval.rpoint[Z]);

break;

case RTNONE:

acutPrintf("(%d . Unknown type)\n", eb->restype);

break;

case -1:

case -2:

// First block entity

acutPrintf("(%d . <Entity name: %8lx>)\n", eb->restype, eb->resval.rlname[0]);

}

return eb->restype;

}

В следующем примере, следующие (заданные по умолчанию) условия{*состояния*} обращаются к текущему рисунку.

§         текущий уровень - 0

§         linetype - НЕПРЕРЫВЕН

§         текущее повышение - 0

§         маркеры примитива заблокированы

Также, пользователь рисовал линию со следующей последовательностью команд:

Command: line

From point: 1,2

To point: 6,6

To point: ENTER

Тогда запрос к getlast () печатал бы следующий (значение имени изменится).

Результат выполнения acdbEntGet () для последнего примитива:

(-1 . <Entity name: 60000014>)

(0 . "LINE")

(8 . "0")

(10 1.0 2.0 0.0)

(11 6.0 6.0 0.0)

(210 0.0 0.0 1.0)



ОБРАТИТЕ ВНИМАНИЕ На printdxf () функция печатает вывод в формате ассоциативного списка AutoLISP, но элементы сохранены в списке связей буферов результатов.

Буфер результатов в начале списка (с -1 кодом стража) содержит имя примитива, который этот список представляет. AcdbEntMod () функциональные использования это, чтобы идентифицировать примитив, который нужно изменить.

Коды для компонентов примитива (сохраненный в restype поле) - используемые DXF. Как с DXF, элементы заголовка примитива возвращены только, если они имеют значения другие чем значение по умолчанию. В отличие от DXF, необязательные поля определения примитива возвращены независимо от того, равняются ли они их значениям по умолчанию. Это упрощает обработку; приложение может всегда предполагать, что эти поля присутствуют. Также в отличие от DXF, связанного X, Y, и координат Z возвращены как одиночная переменная точки (resval.rpoint), не как отдельный X (10), Y (20), и Z (30) групп. Значение restype содержит номер группы координаты X (в диапазоне 10-19).

Чтобы находить группу с определенным кодом, приложение может пересекать список. Entitem () функция, показанная здесь ищет список буфера результата группу указанного типа.

static struct resbuf *entitem(rchain, gcode)

struct resbuf *rchain;

int gcode;

{

while ((rchain != NULL) && (rchain->restype != gcode))

rchain = rchain->rbnext;

return rchain;

}

Если код группы DXF, указанный gcode параметром - не подарок{*настоящее*} в списке (или если gcode - не,  правильная{*допустимая*} группа DXF), entitem () “ уменьшается конец ” и возвращает NULL. Обратите внимание, что entitem () эквивалентен функции AutoLISP (assoc).

AcdbEntMod () функция изменяет примитив. Это передает список, который имеет тот же самый формат как список, возвращенный acdbEntGet (), но с некоторыми из значений группы примитива (возможно) изменяемых приложением. Эти функциональные дополнения acdbEntGet (); первичные средства,  которыми ObjectARX-приложение модифицирует базу данных - восстанавливая{*отыскивая*} примитив с acdbEntGet (), изменяя его список примитива, и затем пропуская список назад к базе данных с acdbEntMod ().



ОБРАТИТЕ ВНИМАНИЕ, чтобы восстановить значение по умолчанию цвета примитива или linetype, использовать acdbEntMod () чтобы установить цвет в 256, который является BYLAYER, или linetype к BYLAYER.

Следующий кодовый фрагмент отыскивает данные определения первого примитива в рисунке, и изменяет его свойство уровня к MYLAYER.

ads_name en;

struct resbuf *ed, *cb;

char *nl = "MYLAYER";

if (acdbEntNext(NULL, en) != RTNORM)

return BAD; // Error status

ed = acdbEntGet(en); // Retrieve entity data.

for (cb = ed; cb != NULL; cb = cb->rbnext)

if (cb->restype == 8) { // DXF code for Layer

// Check to make sure string buffer is long enough.

if (strlen(cb->resval.rstring) < (strlen(nl)))

// Allocate a new string buffer.

cb->resval.rstring = realloc(cb->resval.rstring,

strlen(nl) + 1);

strcpy(cb->resval.rstring, nl);

if (acdbEntMod(ed) != RTNORM) {

acutRelRb(ed);

return BAD; // Error

}

break; // From the for loop

}

acutRelRb(ed); // Release result buffer.

Управление памятью - ответственность ObjectARX-приложения.

Код в примере гарантирует, что строковый буфер - правильный размер, и это выпускает буфер результатов, возвращенный acdbEntGet () (и прошло к acdbEntMod ()) как только операция закончена, действительно ли запрос к acdbEntMod () преуспевает.

ОБРАТИТЕ ВНИМАНИЕ, используете ли Вы acdbEntMod () чтобы изменить примитив на блочном определении, это воздействует на всю ВСТАВКУ или XREF к тому блоку; также, примитивы на блочных определениях не могут быть удалены acdbEntDel ().

Приложение может также добавлять примитив к базе данных рисунка,  вызывая acdbEntMake () функция. Подобно acdbEntMod (), параметр к acdbEntMake () - список буфера результата, чей формат подобен таковому списка, возвращенного acdbEntGet (). (AcdbEntMake () запрос игнорирует поле имени примитива [-1], если это присутствует.) новый примитив добавлен в конец к базе данных рисунка (это становится последним{*прошлым*} примитивом в рисунке). Если примитив - сложный примитив (ломаная линия или блок), это не добавлено в конец к базе данных, пока это не закончено.



Следующий типовой кодовый фрагмент создает круг на уровне MYLAYER.

int status;

struct resbuf *entlist;

ads_point center = {5.0, 7.0, 0.0};

char *layer = "MYLAYER";

entlist = acutBuildList(RTDXF0, "CIRCLE",// Entity type

8, layer, // Layer name

10, center, // Center point

40, 1.0, // Radius

0 );

if (entlist == NULL) {

acdbFail("Unable to create result buffer list\n");

return BAD;

}

status = acdbEntMake(entlist);

acutRelRb(entlist); // Release acdbEntMake buffer.

if (status == RTERROR) {

acdbFail("Unable to make circle entity\n");

return BAD;

}

И acdbEntMod () и acdbEntMake () исполняют,  те же самые проверки последовательности на данных примитива прошли к ним, поскольку команда DXFIN AutoCAD исполняет при чтении DXF файлы. Они терпят неудачу, если они не могут создавать правильные{*допустимые*} примитивы рисунка.


Содержание раздела