Сохранение собственных значений на уровне dwg-файла
Вопрос:
Есть необходимость хранить в чертеже (dwg-файле) информацию, относящуюся ко всему чертежу. Формат информации – целые или вещественные числа, строки и координаты точек. Необходимо обеспечить соответствие имени переменной (например, Scale) и его значению (например, 1.0). Как это проще и удобнее всего сделать.
Ответ:
Для таких целей удобнее всего использовать Named Object Dictionary (NOD):
Для этой цели в корневом словаре мы создаем дочерний словарь с именем заданным переменной appName и внутри него для каждой из созданных переменных с именем varName будем хранить их значения varValue в примитиве XRecord.
Ниже приведен код, для удобства в виде lisp-функций для записи и чтения значений переменных:
- //-----------------------------------------------------------------------------
- //----- acrxEntryPoint.cpp
- //-----------------------------------------------------------------------------
- #include "StdAfx.h"
- #include "resource.h"
- //-----------------------------------------------------------------------------
- #define szRDS _RXST("")
- //-----------------------------------------------------------------------------
- //----- ObjectARX EntryPoint
- class CDWGVariablesApp : public AcRxArxApp {
- public:
- CDWGVariablesApp () : AcRxArxApp () {}
- virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
- AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg (pkt) ;
- return (retCode) ;
- }
- virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
- AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg (pkt) ;
- return (retCode) ;
- }
- virtual void RegisterServerComponents () {
- }
- static AcDbObjectId GetOrCreateVariableXrecordId(ACHAR *appName, ACHAR *varName, AcDbDatabase *db = NULL)
- {
- AcDbObjectId idXrec, id;
- if (!db) db = acdbCurDwg();
- AcDbObjectId idNOD = db->namedObjectsDictionaryId();
- AcDbObjectPointer<AcDbDictionary> pNOD(idNOD,AcDb::kForRead);
- if (pNOD.openStatus() == Acad::eOk) {
- AcDbObjectPointer<AcDbDictionary> pDict;
- AcDbObjectPointer<AcDbXrecord> pXrec;
- if (pNOD->has(appName)) {
- if (pNOD->getAt(appName, id) == Acad::eOk) {
- if (pDict.open(id,AcDb::kForWrite) == Acad::eOk) {
- if (pDict->has(varName)) {
- pDict->getAt(varName, idXrec);
- } else {
- pXrec.create(); pDict->setAt(varName, pXrec, idXrec);
- }
- }
- }
- } else {
- pDict.create();
- if (pNOD->upgradeOpen() == Acad::eOk && pNOD->setAt(appName, pDict, id) == Acad::eOk) {
- pXrec.create(); pDict->setAt(varName, pXrec, idXrec);
- }
- }
- }
- return idXrec;
- }
- static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, int n, AcDbDatabase *db = NULL)
- {
- AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
- if (idXrecord.isNull()) return Acad::eInvalidObjectId;
- AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
- if (pXrec.openStatus() == Acad::eOk) {
- resbuf *rb = acutBuildList(AcDb::kDxfInt16, n, 0);
- Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
- acutRelRb(rb);
- return es;
- }
- return Acad::eNullHandle;
- }
- static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, double d, AcDbDatabase *db = NULL)
- {
- AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
- if (idXrecord.isNull()) return Acad::eInvalidObjectId;
- AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
- if (pXrec.openStatus() == Acad::eOk) {
- resbuf *rb = acutBuildList(AcDb::kDxfReal, d, 0);
- Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
- acutRelRb(rb);
- return es;
- }
- return Acad::eNullHandle;
- }
- static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, ACHAR *str, AcDbDatabase *db = NULL)
- {
- AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
- if (idXrecord.isNull()) return Acad::eInvalidObjectId;
- AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
- if (pXrec.openStatus() == Acad::eOk) {
- resbuf *rb = acutBuildList(AcDb::kDxfText, str, 0);
- Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
- acutRelRb(rb);
- return es;
- }
- return Acad::eNullHandle;
- }
- static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, ads_point p, AcDbDatabase *db = NULL)
- {
- AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
- if (idXrecord.isNull()) return Acad::eInvalidObjectId;
- AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
- if (pXrec.openStatus() == Acad::eOk) {
- resbuf *rb = acutBuildList(AcDb::kDxfXCoord, p, 0);
- Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
- acutRelRb(rb);
- return es;
- }
- return Acad::eNullHandle;
- }
- static resbuf *GetVariable(ACHAR *appName, ACHAR *varName, AcDbDatabase *db = NULL)
- {
- resbuf *rb = NULL;
- AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
- if (idXrecord.isNull()) return rb;
- AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
- if (pXrec.openStatus() == Acad::eOk) {
- pXrec->rbChain(&rb);
- }
- return rb;
- }
- //////////////////////////////////////////////////////////////////////////
- // Lisp-функция:
- // (setdwgvariable "appname" "varname" varvalue)
- // Например:
- // (setdwgvariable "RivilisVars" "ScaleFactor" 1.0)
- //////////////////////////////////////////////////////////////////////////
- static int ads_setdwgvariable () {
- ACHAR *appName = NULL, *varName = NULL;
- resbuf *args = acedGetArgs (), *rb = args;
- if (rb && rb->restype == RTSTR) {
- appName = rb->resval.rstring;
- rb = rb->rbnext;
- } else {
- acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'appName'"));
- return RSRSLT ;
- }
- if (rb && rb->restype == RTSTR) {
- varName = rb->resval.rstring;
- rb = rb->rbnext;
- } else {
- acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varName'"));
- return RSRSLT ;
- }
- if (rb) {
- switch (rb->restype)
- {
- case RTSHORT:
- SetVariable(appName,varName,rb->resval.rint);
- break;
- case RTREAL:
- SetVariable(appName,varName,rb->resval.rreal);
- break;
- case RTSTR:
- SetVariable(appName,varName,rb->resval.rstring);
- break;
- case RT3DPOINT:
- case RTPOINT:
- SetVariable(appName,varName,rb->resval.rpoint);
- break;
- }
- } else {
- acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varValue'"));
- return RSRSLT ;
- }
- return RSRSLT ;
- }
- //////////////////////////////////////////////////////////////////////////
- // Lisp-функция:
- // (getdwgvariable "appname" "varname")
- // Например:
- // (getdwgvariable "RivilisVars" "ScaleFactor")
- //////////////////////////////////////////////////////////////////////////
- static int ads_getdwgvariable () {
- ACHAR *appName = NULL, *varName = NULL;
- resbuf *args = acedGetArgs (), *rb = args;
- acedRetNil();
- if (rb && rb->restype == RTSTR) {
- appName = rb->resval.rstring;
- rb = rb->rbnext;
- } else {
- acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'appName'"));
- return RSRSLT ;
- }
- if (rb && rb->restype == RTSTR) {
- varName = rb->resval.rstring;
- rb = rb->rbnext;
- } else {
- acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varName'"));
- return RSRSLT ;
- }
- rb = GetVariable(appName,varName);
- if (rb) {
- switch (rb->restype)
- {
- case AcDb::kDxfInt16:
- acedRetInt(rb->resval.rint);
- break;
- case AcDb::kDxfReal:
- acedRetReal(rb->resval.rreal);
- break;
- case AcDb::kDxfText:
- acedRetStr(rb->resval.rstring);
- break;
- case AcDb::kDxfXCoord:
- acedRetPoint(rb->resval.rpoint);
- break;
- }
- }
- return RSRSLT ;
- }
- } ;
- //-----------------------------------------------------------------------------
- IMPLEMENT_ARX_ENTRYPOINT(CDWGVariablesApp)
- ACED_ADSSYMBOL_ENTRY_AUTO(CDWGVariablesApp, setdwgvariable, true)
- ACED_ADSSYMBOL_ENTRY_AUTO(CDWGVariablesApp, getdwgvariable, true)
Автор перевода: Александр Ривилис
Обсуждение: http://adn-cis.org/forum/index.php?topic=505
Опубликовано 04.02.2014