• Nenhum resultado encontrado

Comparação entre Symbol Tables e Dictionaries

No documento ObjectARX.pdf (páginas 42-52)

Funções das entidades setam os valores de suas coordenadas usando World Coordinate System . Tem- se como exceção o caso da classe AcDb2dPolylineVextex, que usa o valor da Entity Coordinate System.

VII.

Objetos Container

Essa sessão descreve os objetos container usados no banco de dados do AutoCAD: symbol tables, dictionaries, groups e xrecords. Mostra também como utilizá-los , interagi-los e como criá-los.

Comparação entre Symbol Tables e Dictionaries

Symbol tables e dictionaries executam essencialmente a mesma função; eles contem entradas que

são objetos de banco de dados que são acessados utilizando-se uma string chave. Pode-se adicionar outras entradas a esses objetos e também usar iterators para percorrer passos a passo as entradas e conteúdos.

O AutoCAD contem um conjunto fixo de nove symbol tables, que não podem ser criados ou deletados. O que pode ser feito é acrescentar ou mudar as entradas em um symbol tables (records). Sendo que cada symbol table contem somente um tipo particular de objetos.

Os dictionaries fornecem um mecanismo similar para armazenamento e recuperação de objetos com nomes chaves. O AutoCAD cria o named object dictionary sempre que cria um novo desenho, e a partir desse pode se criar outro objetos e adicioná-los no mesmo. Contudo, o mais prático seria adicionar um único objeto no named object dictionary e a partir dele adicionar outros dictionaries. Tipicamente, o objeto possuído é uma classe container assim como um dictionary. O dictionary, por default, contém dois dictionaries: ACAD_GROUP e ACAD_MLINESTYLE.

A classe hierárquica para symbol tables, symbol tables records, dictionaries e iterators é a seguinte: AcRxObject AcDbObject AcDbDictionary AcDbDictionaryIterator (AcRxObject) (AcDbObject)

AcDbSymbolTable AcDbBlockTable AcDbDimStyleTable AcDbLayerTable AcDbLinetypeTable AcDbRegAppTable AcDbTextStyleTable AcDbUCSTable AcDbAbstractViewTable AcDbViewportTable AcDbViewTable AcDbSymbolTableRecord AcDbBlockTableRecord AcDbDimStyleTableRecord AcDbLayerTableRecord AcDbLinetypeTableRecord AcDbRegAppTableRecord AcDbTextStyleTableRecord AcDbUCSTableRecord AcDbAbstractViewTableRecord AcDbViewportTableRecord AcDbViewTableRecord AcDbSymbolTableIterator AcDbBlockTableIterator AcDbBlockTableRecordIterator AcDbDimStyleTableIterator AcDbLayerTableIterator

AcDbLinetypeTableIterator AcDbRegAppTableIterator AcDbTextStyleTableIterator AcDbUCSTableIterator AcDbAbstractViewTableIterator AcDbViewTableIterator AcDbViewportTableIterator

Symbol Tables

O banco de dados do AutoCAD contem as seguintes symbol tables:

 Block table (AcDbBlockTable; BLOCK)

 Layer table (AcDbLayerTable; LAYER)

 Text style table (AcDbTextStyleTable; STYLE)

 Linetype table (AcDbLinetypeTable; LTYPE)

 View table (AcDbViewTable; VIEW)

 UCS table (AcDbUCSTable; UCS)

 Viewport table (AcDbViewportTable; VPORT)

 Registered applications table (AcDbRegAppTable)

 Dimension styles table (AcDbDimStyleTable; DIMSTYLE)

Cada classe symbol table fornece uma função getAt( ) para procurar o record especificado pelo nome. Para sobrecarregar essa função tem-se:

Acad::ErrorStatus

AcDb##BASE_NAME##Table::getAt(const char* pEntryName, AcDb::OpenMode mode,

AcDb##BASE_NAME##TableRecord*& pRecord,

Adesk::Boolean openErasedRecord = Adesk::kFalse) const; Acad::ErrorStatus

AcDb##BASE_NAME##Table::getAt(const char* pEntryName, AcDbObjectId& recordId,

Adesk::Boolean getErasedRecord = Adesk::kFalse) const;

Outra funções pra o symbol tables são: Adesk::Boolean

AcDb##BASE_NAME##Table::has(const char* pName) const; Acad::ErrorStatus

AcDb##BASE_NAME##Table::add(AcDb##BASE_NAME##TableRecord* pRecord);

Acad::ErrorStatus

AcDb##BASE_NAME##Table::add(AcDbObjectId& record Id, AcDb##BASE_NAME##TableRecord*

pRecord);

Block Table

Entidades no banco de dados pertencem ao block table record. O block table contem dois records como default, MODEL_SPACE e PAPER_SPACE, que correspondem a dois espaços de edição.

Layer Table

O layer table contem um layer, layer 0, por default. O usuário pode adicionar outros através do comando LAYER.

Propriedades do Layer

A classe AcDbLayerTableRecord contem funções membro para especificar o número de propriedades que afetaram a entidade.

Frozen/Thawed void AcDbLayerTableRecord::setIsFrozen(Adesk::Boolean); Adesk::Boolean AcDbLayerTableRecord::isFrozen() const; On/Off void AcDbLayerTableRecord::setIsOff(Adesk::Boolean); Adesk::Boolean AcDbLayerTableRecord::isOff() const; Viewport void AcDbLayerTableRecord::setVPDFLT(Adesk::Boolean);

Adesk::Boolean AcDbLayerTableRecord::VPDFLT() const; Locked/Unlocked void AcDbLayerTableRecord::setIsLocked(Adesk::Boolean); Adesk::Boolean AcDbLayerTableRecord::isLocked() const; Color

void AcDbLayerTableRecord::setColor(const AcCmColor &color); AcCmColor AcDbLayerTableRecord::color() const; Linetype void AcDbLayerTableRecord::setLinetypeObjectId(AcDbObjectId); AcDbObjectId AcDbLayerTableRecord::linetypeObjectId() const;

Criando e Modificando um Layer Table Record

O exemplo mostra como criar um novo layer table record(AcDbLayerTableRecord) e setar certos atributos do layer.

void addLayer() { AcDbLayerTable *pLayerTbl; acdbCurDwg()->getLayerTable(pLayerTbl, AcDb::kForWrite); if (!pLayerTbl->has("testlayer")) { AcDbLayerTableRecord *pLayerTblRcd = new AcDbLayerTableRecord; pLayerTblRcd->setName("ASDK_TESTLAYER"); pLayerTblRcd->setIsFrozen(0); // layer para THAWED pLayerTblRcd->setIsOff(0); // layer para ON

pLayerTblRcd->setVPDFLT(0); // viewport default pLayerTblRcd->setIsLocked(0); // un-locked

AcCmColor color;

color.setColorIndex(1); // seta a cor para vermelho pLayerTblRcd->setColor(color);

// Para linetype é necessário fornecer o object id da // linetype record AcDbObjectId ltId; acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); if ((pLinetypeTbl->getAt("DASHED", ltId)) != Acad::eOk) {

ads_printf("\nUnable to find DASHED" " linetype. Using CONTINUOUS"); pLinetypeTbl->getAt("CONTINUOUS", ltId); } pLinetypeTbl->close(); pLayerTblRcd->setLinetypeObjectId(ltId); pLayerTbl->add(pLayerTblRcd); pLayerTblRcd->close(); pLayerTbl->close(); } else {

ads_printf("\nlayer already exists"); }

}

Cada symbol table tem um iterator correspondente que pode ser criado com a função AcDb##BASE_NAME::newIterator( ). AcDb##BASE_NAME##Table::newIterator() function. Acad::ErrorStatus AcDb##BASE_NAME##Table::newIterator( AcDb##BASE_NAME##TableIterator*& pIterator, Adesk::Boolean atBeginning = Adesk::kTrue, Adesk::Boolean skipErased = Adesk::kTrue) const;

A função newIterator( ) cria um objeto que pode ser usado para percorrer através do conteúdo da

table e estabelecer pIterator para apontar para o objeto iterator. É possível se criar um novo iterator, mas não se pode esquecer de deletá-lo antes de fechar o symbol table. A classe AcDbBlockTableRecord retorna um objeto da classe AcDbBlockTableRecordIterator , que permite

percorrer através das entidades contidas no block table record.

Interagindo sobre Tables

O exemplo cria um iterator que percorre pelo symbol table record na linetype table. void

iterateLinetypes()

{

AcDbLinetypeTable *pLinetypeTbl;

acdbCurDwg()->getLinetypeTable(pLinetypeTbl, AcDb::kForRead); // Cria um novo iterator.

AcDbLinetypeTableIterator *pLtIterator; pLinetypeTbl->newIterator(pLtIterator); // Percorre a table

char *pLtName;

for (; !pLtIterator->done(); pLtIterator->step()) {

pLtIterator->getRecord(pLtTableRcd, AcDb::kForRead); pLtTableRcd->getName(pLtName);

pLtTableRcd->close();

ads_printf("\nLinetype name is: %s", pLtName); free(pLtName); } delete pLtIterator; pLinetypeTbl->close(); }

Dictionaries

Para criar um novo dictionary, é necessário criar uma instancia do AcDbDictionary, adicionar no banco de dados e registrar com o objeto. Quando isso acontece o dictionary automaticamente anexa um reactor para a entrada. Com a função setAt( ) adiciona objetos para o dictionary e o banco de dados.

Acad::ErrorStatus

AcDbDictionary::setAt(const char* pSrchKey, AcDbObject* pNewValue,

AcDbObjectId& retObjId);

Groups e o Group Dictionary

Um Group é um objeto container que mantem uma coleção ordenada de entidades no banco de dados, porem ele não tem um ownership link para as entidades que contem. Quando uma entidade é apagada , os groups que a contem são automaticamente removidos. Se a mesma entidade for desapagada, os groups são novamente inseridos.

Algumas funções podem ser usadas para os Groups e não é necessário setar cada elemento, por exemplo: setColor(), setLayer(), setLinetype(), setVisibility(), and setHighlight(). Os Groups devem ser armazenados no GROUP dictionary, que pode ser obtido da seguinte forma:

AcDbDictionary* pGrpDict = acdbCurDwg()->getGroupDictionary( pGroupDict, AcDb::kForWrite);

Criando um Dictionary

O exemplo cria um dictionary(ASDK_DICT) e adiciona para o named object dictionary. Então ele cria dois novos objetos da classe customizada AsdkMyClass e adiciona no dictionary.

void

createDictionary() {

AcDbDictionary *pNamedobj;

acdbCurDwg()->getNamedObjectsDictionary(pNamedobj, AcDb::kForWrite); // Checa a existencia do dictionary

AcDbDictionary *pDict;

if (pNamedobj->getAt("ASDK_DICT", (AcDbObject*&) pDict, AcDb::kForWrite) == Acad::eKeyNotFound)

{

pDict = new AcDbDictionary; AcDbObjectId DictId;

pNamedobj->setAt("ASDK_DICT", pDict, DictId); }

pNamedobj->close(); if (pDict) {

// Cria novos objects para adicionar para o novo dictionary, AsdkMyClass *pObj1 = new AsdkMyClass(1);

AsdkMyClass *pObj2 = new AsdkMyClass(2); AcDbObjectId rId1, rId2;

pDict->setAt("OBJ1", pObj1, rId1); pDict->setAt("OBJ2", pObj2, rId2); pObj1->close();

pObj2->close(); pDict->close();

}

Interagindo sobre Entradas do Dictionary

A classe iterator para dictionaries é AcDbDictionaryIterator. O exemplo a seguir obtem um

dictionary (ASDK_DICT) do named object dictionary e usa um iterador para percorrer as entradas

do dictionary. void iterateDictionary() { AcDbDictionary *pNamedobj; acdbCurDwg()->getNamedObjectsDictionary(pNamedobj, AcDb::kForRead); // Dá o ponteiro para ASDK_DICT dictionary

AcDbDictionary *pDict;

pNamedobj->getAt("ASDK_DICT", (AcDbObject*&)pDict, AcDb::kForRead); pNamedobj->close();

// Dá o iterador para ASDK_DICT dictionary

AcDbDictionaryIterator* pDictIter= pDict->newIterator(); AsdkMyClass *pMyCl;

Adesk::Int16 val;

for (; !pDictIter->done(); pDictIter->next()) { // Dá o corrente record, o abre para ler

pDictIter->getObject((AcDbObject*&)pMyCl, AcDb::kForRead); pMyCl->getData(val);

pMyCl->close();

ads_printf("\nintval is: %d", val); }

delete pDictIter; pDict->close();

}

Xrecords

Xrecords permite a adição de dados específicos de forma arbitrária e limitada. Essa é uma forma

alternativa de guardar dados mais utilizada em ADS ou AutoLISP.

Definindo Novas Classes

No documento ObjectARX.pdf (páginas 42-52)

Documentos relacionados