ADN Open CIS
Сообщество программистов Autodesk в СНГ

04/02/2014

Сохранение собственных значений на уровне dwg-файла

Вопрос:
Есть необходимость хранить в чертеже (dwg-файле) информацию, относящуюся ко всему чертежу. Формат информации – целые или вещественные числа, строки и координаты точек. Необходимо обеспечить соответствие имени переменной (например, Scale) и его значению (например, 1.0). Как это проще и удобнее всего сделать.

Ответ:
Для таких целей удобнее всего использовать Named Object Dictionary (NOD):

 

Для этой цели в корневом словаре мы создаем дочерний словарь с именем заданным переменной appName и внутри него для каждой из созданных переменных с именем varName будем хранить их значения varValue в примитиве XRecord.

Ниже приведен код, для удобства в виде lisp-функций для записи и чтения значений переменных:

Код - C++: [Выделить]
  1. //-----------------------------------------------------------------------------
  2. //----- acrxEntryPoint.cpp
  3. //-----------------------------------------------------------------------------
  4. #include "StdAfx.h"
  5. #include "resource.h"
  6.  
  7. //-----------------------------------------------------------------------------
  8. #define szRDS _RXST("")
  9. //-----------------------------------------------------------------------------
  10. //----- ObjectARX EntryPoint
  11. class CDWGVariablesApp : public AcRxArxApp {
  12. public:
  13.   CDWGVariablesApp () : AcRxArxApp () {}
  14.   virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) {
  15.     AcRx::AppRetCode retCode = AcRxArxApp::On_kInitAppMsg (pkt) ;
  16.     return (retCode) ;
  17.   }
  18.  
  19.   virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) {
  20.     AcRx::AppRetCode retCode = AcRxArxApp::On_kUnloadAppMsg (pkt) ;
  21.     return (retCode) ;
  22.   }
  23.  
  24.   virtual void RegisterServerComponents () {
  25.   }
  26.  
  27.   static AcDbObjectId GetOrCreateVariableXrecordId(ACHAR *appName, ACHAR *varName, AcDbDatabase *db = NULL)
  28.   {
  29.     AcDbObjectId idXrec, id;
  30.     if (!db) db = acdbCurDwg();
  31.     AcDbObjectId idNOD = db->namedObjectsDictionaryId();
  32.     AcDbObjectPointer<AcDbDictionary> pNOD(idNOD,AcDb::kForRead);
  33.     if (pNOD.openStatus() == Acad::eOk) {
  34.       AcDbObjectPointer<AcDbDictionary> pDict;
  35.       AcDbObjectPointer<AcDbXrecord> pXrec;
  36.       if (pNOD->has(appName)) {
  37.         if (pNOD->getAt(appName, id) == Acad::eOk) {
  38.            if (pDict.open(id,AcDb::kForWrite) == Acad::eOk) {
  39.              if (pDict->has(varName)) {
  40.                pDict->getAt(varName, idXrec);
  41.              } else {
  42.                pXrec.create(); pDict->setAt(varName, pXrec, idXrec);
  43.              }
  44.            }
  45.         }
  46.       } else {
  47.         pDict.create();
  48.         if (pNOD->upgradeOpen() == Acad::eOk && pNOD->setAt(appName, pDict, id) == Acad::eOk) {
  49.           pXrec.create(); pDict->setAt(varName, pXrec, idXrec);
  50.         }
  51.       }
  52.     }
  53.     return idXrec;
  54.   }
  55.  
  56.   static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, int n, AcDbDatabase *db = NULL)
  57.   {
  58.     AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
  59.     if (idXrecord.isNull()) return Acad::eInvalidObjectId;
  60.     AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
  61.     if (pXrec.openStatus() == Acad::eOk) {
  62.       resbuf *rb = acutBuildList(AcDb::kDxfInt16, n, 0);
  63.       Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
  64.       acutRelRb(rb);
  65.       return es;
  66.     }
  67.     return Acad::eNullHandle;
  68.   }
  69.   static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, double d, AcDbDatabase *db = NULL)
  70.   {
  71.     AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
  72.     if (idXrecord.isNull()) return Acad::eInvalidObjectId;
  73.     AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
  74.     if (pXrec.openStatus() == Acad::eOk) {
  75.       resbuf *rb = acutBuildList(AcDb::kDxfReal, d, 0);
  76.       Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
  77.       acutRelRb(rb);
  78.       return es;
  79.     }
  80.     return Acad::eNullHandle;
  81.   }
  82.   static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, ACHAR *str, AcDbDatabase *db = NULL)
  83.   {
  84.     AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
  85.     if (idXrecord.isNull()) return Acad::eInvalidObjectId;
  86.     AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
  87.     if (pXrec.openStatus() == Acad::eOk) {
  88.       resbuf *rb = acutBuildList(AcDb::kDxfText, str, 0);
  89.       Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
  90.       acutRelRb(rb);
  91.       return es;
  92.     }
  93.     return Acad::eNullHandle;
  94.   }
  95.  
  96.   static Acad::ErrorStatus SetVariable(ACHAR *appName, ACHAR *varName, ads_point p, AcDbDatabase *db = NULL)
  97.   {
  98.     AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
  99.     if (idXrecord.isNull()) return Acad::eInvalidObjectId;
  100.     AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
  101.     if (pXrec.openStatus() == Acad::eOk) {
  102.       resbuf *rb = acutBuildList(AcDb::kDxfXCoord, p, 0);
  103.       Acad::ErrorStatus es = pXrec->setFromRbChain(*rb);
  104.       acutRelRb(rb);
  105.       return es;
  106.     }
  107.     return Acad::eNullHandle;
  108.   }
  109.  
  110.   static resbuf *GetVariable(ACHAR *appName, ACHAR *varName, AcDbDatabase *db = NULL)
  111.   {
  112.     resbuf *rb = NULL;
  113.     AcDbObjectId idXrecord = GetOrCreateVariableXrecordId(appName, varName, db);
  114.     if (idXrecord.isNull()) return rb;
  115.     AcDbObjectPointer<AcDbXrecord> pXrec(idXrecord,AcDb::kForWrite);
  116.     if (pXrec.openStatus() == Acad::eOk) {
  117.       pXrec->rbChain(&rb);
  118.     }
  119.     return rb;
  120.   }
  121.  
  122.   //////////////////////////////////////////////////////////////////////////
  123.   //  Lisp-функция:
  124.   //    (setdwgvariable "appname" "varname" varvalue)
  125.   //  Например:
  126.   //    (setdwgvariable "RivilisVars" "ScaleFactor" 1.0)
  127.   //////////////////////////////////////////////////////////////////////////
  128.   static int ads_setdwgvariable () {
  129.     ACHAR *appName = NULL, *varName = NULL;
  130.     resbuf *args = acedGetArgs (), *rb = args;
  131.     if (rb && rb->restype == RTSTR) {
  132.       appName = rb->resval.rstring;
  133.       rb = rb->rbnext;
  134.     } else {
  135.       acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'appName'"));
  136.       return RSRSLT ;
  137.     }
  138.  
  139.     if (rb && rb->restype == RTSTR) {
  140.       varName = rb->resval.rstring;
  141.       rb = rb->rbnext;
  142.     } else {
  143.       acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varName'"));
  144.       return RSRSLT ;
  145.     }
  146.  
  147.     if (rb) {
  148.       switch (rb->restype)
  149.       {
  150.       case RTSHORT:
  151.         SetVariable(appName,varName,rb->resval.rint);
  152.         break;
  153.       case RTREAL:
  154.         SetVariable(appName,varName,rb->resval.rreal);
  155.         break;
  156.       case RTSTR:
  157.         SetVariable(appName,varName,rb->resval.rstring);
  158.         break;
  159.       case RT3DPOINT:
  160.       case RTPOINT:
  161.         SetVariable(appName,varName,rb->resval.rpoint);
  162.         break;
  163.       }
  164.     } else {
  165.       acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varValue'"));
  166.       return RSRSLT ;
  167.     }
  168.     return RSRSLT ;
  169.   }
  170.  
  171.   //////////////////////////////////////////////////////////////////////////
  172.   //  Lisp-функция:
  173.   //    (getdwgvariable "appname" "varname")
  174.   //  Например:
  175.   //    (getdwgvariable "RivilisVars" "ScaleFactor")
  176.   //////////////////////////////////////////////////////////////////////////
  177.   static int ads_getdwgvariable () {
  178.     ACHAR *appName = NULL, *varName = NULL;
  179.     resbuf *args = acedGetArgs (), *rb = args;
  180.     acedRetNil();
  181.     if (rb && rb->restype == RTSTR) {
  182.       appName = rb->resval.rstring;
  183.       rb = rb->rbnext;
  184.     } else {
  185.       acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'appName'"));
  186.       return RSRSLT ;
  187.     }
  188.  
  189.     if (rb && rb->restype == RTSTR) {
  190.       varName = rb->resval.rstring;
  191.       rb = rb->rbnext;
  192.     } else {
  193.       acutPrintf(_T("\nsetdwgvariable: неправильный аргумент 'varName'"));
  194.       return RSRSLT ;
  195.     }
  196.     rb = GetVariable(appName,varName);
  197.  
  198.     if (rb) {
  199.       switch (rb->restype)
  200.       {
  201.       case AcDb::kDxfInt16:
  202.         acedRetInt(rb->resval.rint);
  203.         break;
  204.       case AcDb::kDxfReal:
  205.         acedRetReal(rb->resval.rreal);
  206.         break;
  207.       case AcDb::kDxfText:
  208.         acedRetStr(rb->resval.rstring);
  209.         break;
  210.       case AcDb::kDxfXCoord:
  211.         acedRetPoint(rb->resval.rpoint);
  212.         break;
  213.       }
  214.     }
  215.     return RSRSLT ;
  216.   }
  217.  
  218. } ;
  219.  
  220. //-----------------------------------------------------------------------------
  221. IMPLEMENT_ARX_ENTRYPOINT(CDWGVariablesApp)
  222. ACED_ADSSYMBOL_ENTRY_AUTO(CDWGVariablesApp, setdwgvariable, true)
  223. ACED_ADSSYMBOL_ENTRY_AUTO(CDWGVariablesApp, getdwgvariable, true)
  224.  

Автор: Александр Ривилис
Автор перевода: Александр Ривилис

Обсуждение: http://adn-cis.org/forum/index.php?topic=505

Опубликовано 04.02.2014