24/11/2014
Сохранение порядка отрисовки примитивов при операции клонирования блоков
WblockClone API не гарантирует сохранение порядка отрисовки примитивов (DrawOrder) при клонировании блоков, т.к. операция WblockClone – это очень низкоуровневая операция, которая только копирует примитивы. Так что программисту придется самому позаботится о сохранении порядка отрисовки примитивов в блоке при его клонировании.
Эти картинки показывают правильный и неправильный порядок отрисовки примитивов в блоке в случае клонирования блока. Чтобы сохранить порядок отрисовки нам нужно воспользоваться DrawOrderTable API для сортировки примитивов в блоке.
C++ код :
Код - C++: [Выделить]
- static void ADSKMyGroupWTEST()
- {
- Acad::ErrorStatus es;
- TCHAR fullpath[_MAX_PATH];
- int ret = acedFindFile(_T("C:\\VESSELBLOCKS.dwg"), fullpath );
- if ( ret != RTNORM )
- return;
- AcDbDatabase *pSrcDb = new AcDbDatabase( false, false );
- es = pSrcDb->readDwgFile( fullpath, _SH_DENYNO );
- if ( es != Acad::eOk )
- {
- acutPrintf( _T("\nНе могу открыть файл.") );
- delete pSrcDb;
- return;
- }
- AcApDocument *pActiveDoc = acDocManager->mdiActiveDocument();
- AcDbDatabase *pDestDb = pActiveDoc->database();
- AcDbObjectIdArray objIds2Copy;
- AcDbBlockTable *pBlockTable,*pBlockTable2;
- es = pSrcDb->getSymbolTable(pBlockTable, AcDb::kForRead);
- AcDbObjectId recordId = AcDbObjectId::kNull;
- es = pBlockTable->getAt(ACRX_T("CP_STERN_SY"), recordId, AcDb::kForRead);
- objIds2Copy.append(recordId);
- es = pBlockTable->close();
- AcDbIdMapping idMap;
- es = pSrcDb->wblockCloneObjects(objIds2Copy,
- acdbSymUtil()->blockModelSpaceId(pDestDb),
- idMap, AcDb::kDrcReplace);
- if (es == Acad::eOk)
- {
- acutPrintf( _T("\nКлонируем блок в текущий чертеж.") );
- AcDbObjectId targetBlockId = AcDbObjectId::kNull;
- es = pDestDb->getSymbolTable(pBlockTable2, AcDb::kForRead);
- es = pBlockTable2->getAt(ACRX_T("CP_STERN_SY"), targetBlockId, AcDb::kForRead);
- SetBlockDrawOrder(recordId,targetBlockId,idMap);
- es = pBlockTable2->close();
- }
- else
- {
- acutPrintf(_T("\nОшибка при клонировании блока текущий чертеж."));
- }
- delete pSrcDb;
- }
- static void SetBlockDrawOrder(AcDbObjectId srcBlockId,
- AcDbObjectId targetBlockId,
- AcDbIdMapping& idMap)
- {
- AcDbBlockTableRecord *pSrcBlock = NULL;
- acdbOpenObject(pSrcBlock, srcBlockId, AcDb::kForRead);
- AcDbSortentsTable *pSortTab1 = NULL;
- pSrcBlock->getSortentsTable(pSortTab1, AcDb::kForRead, true);
- AcDbObjectIdArray oids;
- pSortTab1->getFullDrawOrder(oids);
- pSortTab1->close();
- pSrcBlock->close();
- AcDbBlockTableRecord *pTargetBlock = NULL;
- acdbOpenObject(pTargetBlock, targetBlockId, AcDb::kForRead);
- AcDbSortentsTable *pSortTab2 = NULL;
- pTargetBlock->getSortentsTable(pSortTab2, AcDb::kForWrite, true);
- AcDbObjectIdArray targetIds;
- int len = oids.length();
- for(int cnt = 0; cnt < len; cnt++)
- {
- AcDbIdPair idPair(oids.at(cnt), AcDbObjectId::kNull, true);
- if (idMap.compute (idPair)) targetIds.append(idPair.value());
- }
- pSortTab2->setRelativeDrawOrder(targetIds);
- pSortTab2->close();
- pTargetBlock->close();
- }
.NET код :
Код - C#: [Выделить]
- [CommandMethod("WTEST")]
- public void MyWTEST()
- {
- string blockName = "CP_STERN_SY";
- string pathDWG = "C:\\VESSELBLOCKS.dwg";
- var doc = Application.DocumentManager.MdiActiveDocument;
- using (Database OpenDb = new Database(false, false))
- {
- OpenDb.ReadDwgFile(pathDWG, System.IO.FileShare.ReadWrite, true, "");
- ObjectIdCollection ids = new ObjectIdCollection();
- BlockTable bt;
- ObjectId sourceBlockId = ObjectId.Null;
- using (Transaction tr = OpenDb.TransactionManager.StartTransaction())
- {
- bt = (BlockTable)tr.GetObject(OpenDb.BlockTableId, OpenMode.ForRead);
- if (bt.Has(blockName))
- {
- ids.Add(bt[blockName]);
- sourceBlockId = bt[blockName];
- }
- if (ids.Count != 0)
- {
- Database destdb = doc.Database;
- IdMapping iMap = new IdMapping();
- OpenDb.WblockCloneObjects(ids, destdb.BlockTableId,
- iMap, DuplicateRecordCloning.Replace, false);
- using (Transaction t = destdb.TransactionManager.StartTransaction())
- {
- ObjectId targetBlockId = ObjectId.Null;
- BlockTable b = (BlockTable)t.GetObject(destdb.BlockTableId, OpenMode.ForRead);
- if (b.Has(blockName))
- {
- targetBlockId = b[blockName];
- }
- SetBlockDrawOrder(sourceBlockId, targetBlockId, iMap);
- t.Commit();
- }
- }
- tr.Commit();
- }
- }
- }
- public void SetBlockDrawOrder(ObjectId sourceBlockId,
- ObjectId targetBlockId,
- IdMapping iMap)
- {
- Database db = HostApplicationServices.WorkingDatabase;
- using (Transaction t = db.TransactionManager.StartTransaction())
- {
- var sourceBTR = (BlockTableRecord)t.GetObject(sourceBlockId, OpenMode.ForRead);
- var dotSource = (DrawOrderTable)t.GetObject(sourceBTR.DrawOrderTableId, OpenMode.ForRead, true);
- ObjectIdCollection srcDotIds = new ObjectIdCollection();
- srcDotIds = dotSource.GetFullDrawOrder(0);
- var targetBTR = (BlockTableRecord)t.GetObject(targetBlockId, OpenMode.ForRead);
- var dotTarget = (DrawOrderTable)t.GetObject(targetBTR.DrawOrderTableId, OpenMode.ForWrite, true);
- ObjectIdCollection trgDotIds = new ObjectIdCollection();
- foreach (ObjectId oId in srcDotIds)
- {
- if (iMap.Contains(oId))
- {
- IdPair idPair = iMap.Lookup(oId);
- trgDotIds.Add(idPair.Value);
- }
- }
- dotTarget.SetRelativeDrawOrder(trgDotIds);
- t.Commit();
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=1103
Опубликовано 24.11.2014