Тема: Как подгрузить блоки из другого файла?
Как можно в текущий открытый файл подгрузить блоки из другого файла?
Информационный портал для профессионалов в области САПР
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Форумы CADUser → Программирование → ObjectARX → Как подгрузить блоки из другого файла?
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Как можно в текущий открытый файл подгрузить блоки из другого файла?
Это функция переносит блок с данным именем из pBlockDatabase в pWorkDatabase. pBlockDatabase открывается таким вот образом:
AcDbDatabase* pBlockDatabase=new AcDbDatabase(false,true); pBlockDatabase->readDwgFile(strFileName); BOOL ImportBlock(AcDbDatabase* pBlockDatabase,AcDbDatabase* pWorkDatabase,LPCSTR pszBlockName,AcDbObjectId& idImported) { BOOL bRes=TRUE; Acad::ErrorStatus es=Acad::eOk; try { AcDbBlockTable* pBlockTable; es=pBlockDatabase->getSymbolTable(pBlockTable,AcDb::kForRead); if(es!=Acad::eOk)throw es; AcDbObjectId idInsRecord; es=pBlockTable->getAt(pszBlockName,idInsRecord); pBlockTable->close(); if(es!=Acad::eOk)throw es; AcDbDatabase* pTempDB; es=pBlockDatabase->wblock(pTempDB,idInsRecord); if(es!=Acad::eOk)throw es; es=pWorkDatabase->insert(idImported,pszBlockName,pTempDB); delete pTempDB; if(es!=Acad::eOk)throw es; }catch(Acad::ErrorStatus) { bRes=FALSE; } return bRes; }
Со вставкой блока, думаю, сложностей не возникнет. Если надо перенести все блоки, можно изменить функцию так, чтобы использовать итератор.
Аналогично примеру (см. выше) делаю следующее:
CString sBlockName = "MyBlock" CString sFileName = "c:\mydwg.dwg" Acad::ErrorStatus err; try { AcDbDatabase *pDB = new AcDbDatabase(Adesk::kFalse); err = pDB->readDwgFile(sFileName,_SH_DENYRW); if (err!=Acad::eOk) throw err; AcDbBlockTable* pBlockTable; err = pDB->getSymbolTable(pBlockTable,AcDb::kForRead); if (err!=Acad::eOk) throw err; AcDbObjectId idInsRecord; err = pBlockTable->getAt(sBlockName,idInsRecord); if (err!=Acad::eOk) throw err; AcDbDatabase* pTempDB; err = pDB->wblock(pTempDB,idInsRecord); if (err!=Acad::eOk) throw err; pBlockTable->close(); pBlockTable->close(); err = acdbHostApplicationServices()->workingDatabase()->insert(idInsRecord,sBlockName,pTempDB); if (err!=Acad::eOk) throw err; delete pTempDB; delete pDB; } catch(Acad::ErrorStatus) { acutPrintf("Error loading %s from %s!\n",sBlockName,sFileName); fCurBlockOk = false; } }
Но после
err = pDB->wblock(pTempDB,idInsRecord);
В pTempDB попадает почему-то не только нужный мне блок, но и др. блоки, присутствующие в mydwg.dwg
Может кто-то сможет пояснить причину?
Может быть, это из-за того, что wblock() использует механизм wblockClone, который, например, может скопировать в новую базу что-то лишнее из-за наличия "Hard" ссылок между объектами?
Каким образом тогда нужно корректно решать задачу:
Есть название файла и имя блока.
Нужно добавить определение этого блока в таблицу блоков текущего чертежа.
?
(чтобы исключить возможность добавления "лишних" блоков)
err = pBlockTable->getAt(sBlockName,idInsRecord);
err == eKeyNotFound
Подскажите пож. в чем грабли?
> Lanter
Дык нету blockTableRecord-а с указанным именем.
> Exhumer
- спасибо, бывает :)
Может кому понадобится код (по названию темы) - можно сразу вставлять в проект:
AcDbObjectId id; AcDbObjectIdArray list; AcDbDatabase extDatabase( Adesk::kFalse ); char * dwgName = NULL; struct resbuf *rb; rb = acutNewRb(RTSTR); acedGetFileD("Pick a drawing", NULL, "dwg", 0, rb); dwgName = (char*)acad_malloc(strlen(rb->resval.rstring) + 1); strcpy(dwgName, rb->resval.rstring); acutRelRb(rb); if (Acad::eOk != extDatabase.readDwgFile(dwgName )) { acedAlert( "Error reading DWG!" ); return; } AcDbBlockTable* pBT; if (Acad::eOk != extDatabase.getSymbolTable( pBT, AcDb::kForRead )) { acedAlert( "Error getting BlockTable of DWG" ); return; } AcDbBlockTableRecord* pBTR; Acad::ErrorStatus es = pBT->getAt( ACDB_MODEL_SPACE, pBTR, AcDb::kForRead ); pBT->close(); if (Acad::eOk != es) { acedAlert( "Error getting model space of DWG" ); return; } AcDbBlockTableRecordIterator* pIT; if (Acad::eOk != pBTR->newIterator( pIT )) { acedAlert( "Error iterating model space of DWG" ); pBTR->close(); return; } for ( ; !pIT->done(); pIT->step()) { if (Acad::eOk == pIT->getEntityId( id )) { list.append( id ); AcDbEntity *pEnt; if ( Acad::eOk == pIT->getEntity(pEnt, AcDb::kForRead)) { AcDbObjectId obj; if ((obj = pEnt->extensionDictionary()) != AcDbObjectId::kNull) { AcDbDictionary *pDict = NULL; acdbOpenObject(pDict, obj, AcDb::kForWrite); if (pDict) { pDict->setTreatElementsAsHard(Adesk::kTrue); pDict->close(); } } pEnt->close(); } } } delete pIT; pBTR->close(); if (list.isEmpty()) { acedAlert( "No entities found in model space of DWG" ); return; } AcDbDatabase *pTempDb; if (Acad::eOk != extDatabase.wblock( pTempDb, list, AcGePoint3d::kOrigin )) { acedAlert( "wblock failed!" ); return; } if (Acad::eOk != acdbHostApplicationServices()->workingDatabase() ->insert( AcGeMatrix3d::kIdentity, pTempDb )) acedAlert( "insert failed!" ); delete pTempDb;
Нужно вставить содержимое файла как блок в текущий файл (аналог INSERT+BROWSE...). Имя файла известно. Файл находится на путях поддержки, однако точный путь к нему неизвестен.
Как открыть этот файл?
Метод AcDbDatabase::readDwgFile(name) не проводит поиск по путям поддержки, о чем написано в справочнике ObjectArx 2005. Во всех примерах форума точный путь к файлу известен, у меня - нет. Как заставить автокад искать внешнюю AcDbDatabase по имени файла без указания папки по всем путям поддержки (support path)?
> Зигмус
extern "C" int acedFindFile(const ACHAR * fname, ACHAR * result);
В продолжение вопроса - что-то вставка блока осуществляется очень медленно.
Т.е. на вставку 100 разных блоков уходит 5-20 секунд в зависимости от размера блоков.
Самая "тягомотная" операция - это
es=pWorkDatabase->insert(idImported,pszBlockName,pTempDB);
Почему то даже быстрее открывается чертеж, из которого надо скопировать, и делается pDB->wblock(pTempDB,idInsRecord);
Я вот даже не знаю что делать. Мне надо вставлять из разных файлов блоки. Много и разных. И даже приличный ПК висит по 15-30 секунд... хотя вставить 200 блоков - казалось бы это - "пшик"...
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Форумы CADUser → Программирование → ObjectARX → Как подгрузить блоки из другого файла?
Форум работает на PunBB, при поддержке Informer Technologies, Inc