Author Topic: Create custom blocks  (Read 440 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7486
  • AKA Daniel
Create custom blocks
« on: October 13, 2022, 07:23:12 PM »
Just a concept.

Query SQL server for a ‘master block’, or just create new.
Query SQL server for the sub components to insert into the block;
SQL, could have a in basepoint or even a matrix.
wblock the sub components into the master block.
Insert master block.

Code - C: [Select]
  1.     static CString generateTempFilePath()
  2.     {
  3.         TCHAR tempPath[MAX_PATH];
  4.         TCHAR lpTempPathBuffer[MAX_PATH];
  5.         GetTempPath(MAX_PATH, lpTempPathBuffer);
  6.         GetTempFileName(lpTempPathBuffer, nullptr, 0, tempPath);
  7.         return CString{ tempPath };
  8.     }
  9.  
  10.     static bool writeBufferToFile(const CLongBinary& buf, const CString& path)
  11.     {
  12.         bool flag = false;
  13.         LPBYTE pLock = static_cast<LPBYTE>(::GlobalLock(buf.m_hData));
  14.         if (pLock != nullptr)
  15.         {
  16.             CFile fileS;
  17.             CFileException e;
  18.             if (fileS.Open(path, CFile::modeWrite | CFile::modeCreate, &e))
  19.             {
  20.                 fileS.Write(pLock, buf.m_dwDataLength);
  21.                 fileS.Flush();
  22.                 fileS.Close();
  23.                 flag = true;
  24.             }
  25.             GlobalUnlock(buf.m_hData);
  26.         }
  27.         return flag;
  28.     }
  29.  
  30.     static bool downloadFile(const ODBCDwgFileInfo& info)
  31.     {
  32.         try
  33.         {
  34.             CString statment;
  35.             statment.Format(_T("SELECT BlockFile FROM Blocks WHERE Name = %ls"), info.name);
  36.  
  37.             CDatabase db;
  38.             if (db.Open(info.dsn))
  39.             {
  40.                 CRecordset rs(&db);
  41.                 if (rs.Open(CRecordset::forwardOnly, statment, CRecordset::readOnly | CRecordset::executeDirect) == TRUE)
  42.                 {
  43.                     while (!rs.IsEOF())
  44.                     {
  45.                         const auto numFields = rs.GetODBCFieldCount();
  46.                         for (auto item = 0; item < numFields; item++)
  47.                         {
  48.                             CODBCFieldInfo fieldInfo;
  49.                             rs.GetODBCFieldInfo(item, fieldInfo);
  50.                             auto oldType = fieldInfo.m_nSQLType;
  51.                             switch (fieldInfo.m_nSQLType)
  52.                             {
  53.                                 case SQL_BINARY:
  54.                                 case SQL_VARBINARY:
  55.                                 case SQL_LONGVARBINARY:
  56.                                     rs.m_rgODBCFieldInfos[item].m_nSQLType = SQL_LONGVARBINARY;//<< hackola!
  57.                                     break;
  58.                                 default:
  59.                                     break;
  60.                             }
  61.                             CDBVariant var;
  62.                             rs.GetFieldValue(item, var);
  63.                             if (var.m_dwType == DBVT_BINARY && var.m_pbinary != nullptr)
  64.                             {
  65.                                 writeBufferToFile(*var.m_pbinary, info.path);
  66.                             }
  67.                         }
  68.                         rs.MoveNext();
  69.                     }
  70.                     rs.Close();
  71.                 }
  72.             }
  73.         }
  74.         catch (...)
  75.         {
  76.             acutPrintf(_T("\nDOH Your coding sucks!"));
  77.         }
  78.         return std::filesystem::exists((const TCHAR*)info.path);
  79.     }
  80.  
  81.     static void ArxTest_doit2(void)
  82.     {
  83.         ODBCDwgFileInfo info1;
  84.         info1.dsn = _T("ODBC_FIELD");
  85.         info1.name = _T("6036");
  86.         info1.path = generateTempFilePath();
  87.  
  88.         ODBCDwgFileInfo info2;
  89.         info2.dsn = _T("ODBC_FIELD");
  90.         info2.name = _T("6236");
  91.         info2.path = generateTempFilePath();
  92.  
  93.         if (!downloadFile(info1))
  94.             return;
  95.         if (!downloadFile(info2))
  96.             return;
  97.         AcDbDatabase* pDb = acdbHostApplicationServices()->workingDatabase();
  98.         {
  99.             Acad::ErrorStatus es = eOk;
  100.             std::unique_ptr<AcDbDatabase> dwg1(new AcDbDatabase(false, true));
  101.             if (es = dwg1->readDwgFile(info1.path); es != eOk)
  102.                 return;
  103.  
  104.             std::unique_ptr<AcDbDatabase> dwg2(new AcDbDatabase(false, true));
  105.             if (es = dwg2->readDwgFile(info2.path); es != eOk)
  106.                 return;
  107.  
  108.             AcGePoint3d pt;
  109.             AcDbObjectIdArray ids;
  110.             AcDbBlockTableRecordPointer pDwg2Mspace(acdbSymUtil()->blockModelSpaceId(dwg2.get()));
  111.             if (pDwg2Mspace.openStatus() != eOk)
  112.                 return;
  113.  
  114.             for (auto [es, pIter] = makeBlockTableRecordIterator(*pDwg2Mspace); !pIter->done(); pIter->step())
  115.             {
  116.                 AcDbObjectId id;
  117.                 es = pIter->getEntityId(id);
  118.                 ids.append(id);
  119.             }
  120.  
  121.             if (es = dwg2->wblock(dwg1.get(), ids, pt, AcDb::kDrcReplace); es != eOk)
  122.                 return;
  123.  
  124.             AcDbObjectId id;
  125.             es = pDb->insert(id, info1.name, dwg1.get(), false);
  126.         }
  127.         DeleteFile(info1.path);
  128.         DeleteFile(info2.path);
  129.     }
  130.  
Retired

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7486
  • AKA Daniel
Re: Create custom blocks
« Reply #1 on: October 13, 2022, 07:29:41 PM »
readDwgFile really should accept a memory file, just say'n
Retired

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 7486
  • AKA Daniel
Re: Create custom blocks
« Reply #2 on: October 14, 2022, 09:15:54 PM »
Well, that's kinda cool, a lot of work to build a block though.
I guess once you get some data in, it's easier

Code - C: [Select]
  1.  static void ArxBrxTest_test01(void)
  2.     {
  3.         const CString blockName = _T("DWR4BASESEC");
  4.  
  5.         CDatabase db;
  6.         if (db.Open(_T("ODBC_FIELD"),FALSE,TRUE, passwd))
  7.         {
  8.             CString componentQuery;
  9.             componentQuery.Format(_T("SELECT TableName, BlockName, X, Y, Z, R, S FROM [%ls]"), (const TCHAR*)blockName);
  10.  
  11.             ComponentDataArray componentDataArray;
  12.             ODBCConnector::getComponentData(db, componentQuery, componentDataArray);
  13.  
  14.             for (auto& item : componentDataArray)
  15.             {
  16.                 CString subBomponentQuery;
  17.                 subBomponentQuery.Format(_T("SELECT BlockFile FROM %ls WHERE BlockName='%ls'"), (const TCHAR*)item.TableName, (const TCHAR*)item.BlockName);
  18.                 ODBCConnector::downloadFile(db, subBomponentQuery, item);
  19.  
  20.             }
  21.             CadDatabaseMgr::get().createAndInsertBlock(blockName, componentDataArray);
  22.         }
  23.  
  24.     }
  25.  

Retired