ADN Club > ObjectARX
вставка блоков
Николай Горлов:
даже не знаю в чем дело. короче говоря, ситуация такая (упрощенно :) )
есть окошко с кнопочками. за каждой кнопочкой закреплена вставка соответствующего блока (блок может быть динамическим).
сами блоки находятся в файле, например, c:\aaa\data.dwg, ну и естественно имеют уникальные имена.
по нажатию на кнопочку отрабатывает функция
--- Код: ---drawSign(_T("динблок1"),_T("C:\\aaa\\data.dwg"),0.2); //динблок1 - имя блока, C:\\aaa\\data.dwg - в каком файле искать блок, 0.2 - масштаб
--- Конец кода ---
за этой функцией скрывается следующее:
--- Код - C++ [Выбрать] ---AcDbObjectId importBlockToCurDWGDatabase(const ACHAR *pBlockName, const ACHAR *pFileName){ Acad::ErrorStatus es=Acad::eOk; AcDbObjectId idImported; // ID нашего нового блока AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDatabase(); AcAxDocLock docLock(pWorkDatabase); AcDbDatabase* pBlockDatabase = new AcDbDatabase(false,true); es = pBlockDatabase->readDwgFile(pFileName); if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} try { AcDbBlockTable* pBlockTable; es=pBlockDatabase->getSymbolTable(pBlockTable,AcDb::kForRead); if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} AcDbObjectId idInsRecord; es=pBlockTable->getAt(pBlockName,idInsRecord); pBlockTable->close(); if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // нет такого блока AcDbDatabase* pTempDB; es=pBlockDatabase->wblock(pTempDB,idInsRecord); if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не скопировался блок в пустую базу es=pWorkDatabase->insert(idImported,pBlockName,pTempDB); delete pTempDB; if(es!=Acad::eOk){delete pBlockDatabase;return NULL;} // не вставилась пустая база с блоком в нашу текущую базу }catch(...){delete pBlockDatabase;return NULL;} delete pBlockDatabase; return idImported;} void drawSign(CString blockName, CString blockFilePath, double scale){ AcDbObjectId newBlockTableId; AcGePoint3d insPnt; acdbHostApplicationServices()->enableMessageDisplay(false); newBlockTableId = importBlockToCurDWGDatabase(blockName.GetString(),blockFilePath.GetString()); acdbHostApplicationServices()->enableMessageDisplay(true); if (newBlockTableId.isNull()) { acedAlert(_T("Данный блок не найден")); return; } acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_off"),0); // значек СК acedCommand (RTSTR, _T("_ucs"),RTSTR,_T("_v"),0); AcDbDatabase* pWorkDatabase = acdbHostApplicationServices()->workingDatabase(); AcAxDocLock docLock(pWorkDatabase); int osnap = acdbHostApplicationServices()->workingAppSysvars()->osmode(); acdbHostApplicationServices()->workingAppSysvars()->setOsmode(64 + 512); if(acedGetPoint(NULL,_T("\nТочка вставки: "),asDblArray (insPnt))!=RTNORM) { acdbHostApplicationServices()->workingAppSysvars()->setOsmode(osnap); acedCommand(RTSTR,_T("_ucs"),RTSTR,_T("_p"),0); acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_on"),0); return; } AcDbBlockReference *blockReference = new AcDbBlockReference(insPnt,newBlockTableId); blockReference->setRotation(0.0); blockReference->setNormal (AcGeVector3d (0.0, 0.0, 1.0)) ; blockReference->setScaleFactors(AcGeScale3d(scale)); AcGeMatrix3d matUcs; acedGetCurrentUCS(matUcs); blockReference->transformBy(matUcs); postToDb(blockReference); // запись экзкмпляра блока в БД чертежа acdbHostApplicationServices()->workingAppSysvars()->setOsmode(osnap); acedCommand(RTSTR,_T("_ucs"),RTSTR,_T("_p"),0); acedCommand(RTSTR,_T("_ucsicon"),RTSTR,_T("_on"),0); acedPostCommandPrompt();}
если вставлять блоки в чертеж через drawSign (т.е. нажимать кнопочку), то вставляются всегда хорошо, но пользователи люди ... и им намного "проще" найти нужный блок в одном из их чертежей, а не клацнуть на кнопочку. после того как они его находят в куче своих чертежей, они Ctrl+C\Ctrl+V блок в новый чертеж. и, о чудо, у некоторых блоков умирает порядок прорисовки и после вставки вместо правильно начерченного блока получается мешанина отрезков и штриховок.
пробовал повторить сам ручками. картина та же. при вставке с кнопочки всегда все ok, а вот при копировании (причем без разницы в новый чертеж или в тот же) порядок прорисовки игнорируется.
может что-то не так с моим кодом? дело в том, что если ручками открыть файл C:\aaa\data.dwg, вставить туда этот блок (вставка->блок. блоков в самом чертеже нет. они только в БД чертежа), а потом скопировать его в буфер, то в другие чертежи (если там еще не было вхождения такого блока) всё вставляется правильно.
Александр Ривилис:
Проверь копируется ли у тебя связанная с AcDbBlockTableRecord AcDbSortentsTable (отвечает за порядок прорисовки). Она содержится в ExtDictionary у AcDbBlockTableRecord с ключом "ACAD_SORTENTS". Если нет, то тебе придётся её самостоятельно скопировать.
Николай Горлов:
пробежался arxdbg. взял правильно отрисованный блок и неправильно. результаты одинаковые
- на самом ВСТАВЛЕННОМ блоке (Entity Info) в Extension dictionary только AcDbBlockRepresentation
- в database \ BlockTable \ имя_блока в Extension dictionary есть ACAD_SORTENTS, ACAD_ENHANCEDBLOCK и AcDbDynamicBlockRoundTripPurgePrevent
Александр Ривилис:
--- Цитата: Николай Горлов от 04-12-2013, 14:15:40 ---результаты одинаковые
--- Конец цитаты ---
1) Одинаково и содержимое AcDbSortentsTable?
2) Такое происходит только с динамическими блоками?
3) Такое происходит в трёх последних версиях AutoCAD?
Если удастся всё это формально записать с минимальным примером кода (проект) и dwg-файла с блоками - будем трясти ADN DevHelp
Николай Горлов:
1. ну в пределах допустимого. блоки то разные ), так что handle, owner и entity name - разные
2. за простые ничего сказать не могу (простых почти нет :), а на те что есть никто не жаловался). так что будем считать, что только динамические.
3. начиная с 2010 акада по 2014. чтоб все работало начиная с 2010 автокада, версия файла с блоками - 2010.
4. еще иногда слетает динамика после копирования. допустим есть столбики, которые идут массивом при растяжке. вставили через "кнопочку", потянули, все ок. скопировали, вставили рядом через Ctrl+C\Ctrl+V. потянули, а остается только первый столбик, хотя точка растяжки уходит туда, куда клацнул (у меня dwg файлика нет. нада скататься взять. но видел собственными глазами). и самое интересное, происходит это ТОЛЬКО с редактируемым экземпляром блока. столбики в остальных экземпляров блока находятся там где и должны и после регенерации. а вот если начать растягивать и другие подобные блоки, то такой же косяк происходит и на них.
PS: а проектик подготовлю, это не проблема. только на следующей неделе. сейчас весь в разъездах )))
--- Цитировать ---будем трясти ADN DevHelp
--- Конец цитаты ---
ну да, ток исправлять то ЭТО в 2010 автокаде никто не будет, если это баг. а пользуются уже сейчас. эх, опять заплатки делать ))). так что ооочень сильно надеюсь, что это я что-то намудрил
а пока что dwg с блоком. можете попробовать его скопировать в новый чертеж средствами автокада. у меня штриховка всегда идет на передний план. хотя про копировании внутри одного чертежа все ок.
http://yadi.sk/d/9vhcJ2BaDnjKE
Навигация
Перейти к полной версии