Визуализация при помощи RenderToImage API
Как вы возможно уже знаете API графической системы было изменено в AutoCAD 2015, как описано в статье Изменения в графике в AutoCAD 2015. В AutoCAD 2016 рендер RapidRT заменил рендер MentalRay, который использовался в предыдущих версиях. В свете этого в ObjectARX 2016 появился новый класс AcDbRapidRTRenderSettings. Все эти изменения требуют изменений в вашем коде в случае, если вы использовали метод AcGsView::RenderToImage для генерации изображения модели AutoCAD.
Следующий код должен генерировать визуализацию изображения как в AutoCAD 2016, так и в предыдущих версиях. Чтобы учесть различные изменения графической системы и средства визуализации, приведенный ниже код широко использует возможности условной компиляции.
Чтобы попробовать это, откройте чертеж и задайте направление взгляда в AutoCAD, такой как вы хотите для того чтобы генерировать визуализированное изображение. Настройте параметры визуализации и выполните визуализацию в AutoCAD. После того как вас устроят результаты, сделать настройки визуализации текущими. Это должно сохранить предустановки визуализации в качестве активных. Приведенный ниже код, получает параметры на основе активной предустановки, и используют их для создания изображении.
- static void AdskMyTestRTITest(void )
- {
- AcDbDatabase *pDb
- = acdbHostApplicationServices()->workingDatabase();
- AcGsManager *gsManager = acgsGetGsManager();
- if (!gsManager)
- return ;
- #ifdef ACAD2016 // 2016 и новее используют RapidRT рендер
- AcGsManager2 *gsManager2
- = dynamic_cast <AcGsManager2 *>(gsManager);
- if (! gsManager2)
- return ;
- AcGsKernelDescriptor descriptor;
- descriptor.addRequirement(AcGsKernelDescriptor::k3DRapidRTRendering);
- AcGsGraphicsKernel *pGraphicsKernel = AcGsManager::acquireGraphicsKernel(descriptor);
- AcGsDevice *offDevice = gsManager2->getOffScreenDevice(*pGraphicsKernel);
- if (! offDevice)
- return ;
- #elif ACAD2015
- // 2015 использует Mental Ray рендер. Учитываем изменения в GS API
- AcGsKernelDescriptor descriptor;
- descriptor.addRequirement (AcGsKernelDescriptor::k3DDrawing);
- AcGsGraphicsKernel *pGraphicsKernel = AcGsManager::acquireGraphicsKernel(descriptor);
- AcGsDevice *offDevice = pGraphicsKernel->createOffScreenDevice();
- if (! offDevice)
- return ;
- #else // 2014 и более ранние используют Mental ray рендер
- AcGsClassFactory *factory = gsManager->getGSClassFactory();
- if (! factory)
- return ;
- AcGsDevice *offDevice = factory->createOffScreenDevice();
- if (! offDevice)
- return ;
- #endif
- AcDbObjectId curVportId = AcDbObjectId::kNull;
- int width = 10, height = 10;
- Adesk::IntDbId viewportObjectId;
- LONG_PTR acadWindowId;
- LONG_PTR viewportId;
- if (pDb->tilemode())
- { // Пространство модели
- curVportId = acedActiveViewportId();
- struct resbuf rb;
- int rt = acedGetVar(_T("CVPORT" ), &rb);
- if (rt != RTNORM)
- return ;
- int vportNum = rb.resval.rint;
- AcDbObjectPointer<AcDbViewportTableRecord> curVTR (curVportId,AcDb::kForRead);
- if (curVTR.openStatus() == Acad::eOk)
- {
- curVTR.close();
- }
- int l,r,b,t;
- acgsGetViewportInfo(vportNum,l,b,r,t);
- height = t - b - 1;
- width = r - l - 1;
- viewportObjectId = curVportId.asOldId();
- acadWindowId = vportNum;
- viewportId = curVportId.asOldId();
- }
- else
- { // Пространство Листа, но находимся внутри Пространства Модели
- // Активируем видовой экран
- curVportId = acedGetCurViewportObjectId();
- AcDbObjectPointer<AcDbViewport> curVport (curVportId,AcDb::kForRead);
- if (curVport->number() < 2)
- {
- AfxMessageBox(_T("Для работы рендера Пространство Модели должно быть активно в видовом экране."));
- return ;
- }
- int l,r,b,t;
- acgsGetViewportInfo(curVport->number(),l,b,r,t);
- height = t - b - 1;
- width = r - l - 1;
- viewportObjectId = curVportId.asOldId();
- acadWindowId = curVport->number();
- viewportId = curVportId.asOldId();
- }
- offDevice->onSize(width, height);
- #ifdef ACAD2016
- AcGsClientViewInfo info;
- info.viewportId = viewportId;
- info.acadWindowId = acadWindowId;
- info.viewportObjectId = viewportObjectId;
- AcGsView* pView = gsManager2->getOffScreenView(*pGraphicsKernel, info);
- #elif ACAD2015
- AcGsView *pView = pGraphicsKernel->createView();
- if (! pView)
- return ;
- #else
- AcGsView *pView = factory->createView();
- if (! pView)
- return ;
- #endif
- acgsGetViewParameters(acadWindowId, pView);
- offDevice->setDeviceRenderer(AcGsDevice::kFullRender);
- offDevice->add(pView);
- offDevice->update();
- #if defined (ACAD2016) || defined (ACAD2015)
- AcGsModel *pModel = gsManager->createAutoCADModel(*pGraphicsKernel);
- #else
- AcGsModel *pModel = gsManager->createAutoCADModel();
- #endif
- if (! pModel)
- return ;
- // Пространство модели
- AcDbBlockTable *pBT = NULL;
- AcDbBlockTableRecord *pBTR = NULL;
- AcDbObjectId msId;
- pDb->getBlockTable(pBT, AcDb::kForRead);
- pBT->getAt(ACDB_MODEL_SPACE, msId);
- pBT->close();
- AcDbBlockTableRecordPointer spaceRec(msId, AcDb::kForRead);
- if (spaceRec.openStatus() != Acad::eOk)
- return ;
- pView->add(spaceRec, pModel);
- spaceRec.close();
- if (pView != NULL)
- {
- pView->invalidate();
- pView->update();
- }
- // Получаем имя файла для вывода
- struct resbuf *result = NULL;
- int status = acedGetFileNavDialog(
- _T("Визуализированное изображение" ),
- NULL,
- _T("jpg;png;tif;bmp" ),
- _T("RenderImageDialog" ), 1, &result);
- if (status == RTNORM)
- {
- ACHAR *pFileName = result->resval.rstring;
- if (! CreateAtilImage(pView, width, height, 32, 0, pFileName))
- AfxMessageBox(_T("Ошибка при создании изображения..." ));
- }
- // Очищаем графическую систему
- pView->eraseAll();
- offDevice->erase(pView);
- #if defined (ACAD2016)
- //pGraphicsKernel->deleteView(pView);
- pGraphicsKernel->deleteModel(pModel);
- //pGraphicsKernel->deleteDevice(offDevice);
- AcGsManager::releaseGraphicsKernel(pGraphicsKernel);
- #elif ACAD2015
- pGraphicsKernel->deleteView(pView);
- pGraphicsKernel->deleteModel(pModel);
- pGraphicsKernel->deleteDevice(offDevice);
- AcGsManager::releaseGraphicsKernel(pGraphicsKernel);
- #else
- factory->deleteView(pView);
- factory->deleteModel(pModel);
- factory->deleteDevice(offDevice);
- #endif
- }
- #ifdef ACAD2016
- static Acad::ErrorStatus GetActiveRapidRTRenderSetting (AcDbRapidRTRenderSettings *&pRenderSetting)
- {
- AcApDocument *pActiveDoc = acDocManager->mdiActiveDocument();
- AcDbDatabase *pDB = pActiveDoc->database();
- AcDbDictionary *pNODContainer = NULL;
- Acad::ErrorStatus es = pDB->getNamedObjectsDictionary
- (pNODContainer, AcDb::OpenMode::kForRead);
- AcDbObject *pMyDictObject = NULL;
- if (pNODContainer->has(
- ACRX_T("ACAD_RENDER_ACTIVE_RAPIDRT_SETTINGS" )))
- {
- es = pNODContainer->getAt(ACRX_T(
- "ACAD_RENDER_ACTIVE_RAPIDRT_SETTINGS" ),
- pMyDictObject, AcDb::OpenMode::kForRead);
- AcDbObjectId myObjectId = AcDbObjectId::kNull;
- if (es == Acad::eOk)
- {
- AcDbRapidRTRenderSettings *pRapidRTActiveSetting
- = AcDbRapidRTRenderSettings::cast(pMyDictObject);
- if (pRapidRTActiveSetting != NULL)
- {
- pRenderSetting = new AcDbRapidRTRenderSettings();
- es = pRenderSetting->copyFrom(pRapidRTActiveSetting);
- }
- es = pRapidRTActiveSetting->close();
- }
- }
- else
- {
- acutPrintf(
- ACRX_T("ACAD_RENDER_ACTIVE_RAPIDRT_SETTINGS не найдена !!" ));
- }
- pNODContainer->close();
- return Acad::eOk;
- }
- #else
- static Acad::ErrorStatus GetActiveRenderSetting (AcDbMentalRayRenderSettings *&pRenderSetting)
- {
- AcApDocument *pActiveDoc = acDocManager->mdiActiveDocument();
- AcDbDatabase *pDB = pActiveDoc->database();
- AcDbDictionary *pNODContainer = NULL;
- Acad::ErrorStatus es = pDB->getNamedObjectsDictionary
- (pNODContainer, AcDb::OpenMode::kForRead);
- AcDbObject *pMyDictObject = NULL;
- if (pNODContainer->has(ACRX_T("ACAD_RENDER_ACTIVE_SETTINGS" )))
- {
- es = pNODContainer->getAt(
- ACRX_T("ACAD_RENDER_ACTIVE_SETTINGS" ),
- pMyDictObject, AcDb::OpenMode::kForRead);
- AcDbObjectId myObjectId = AcDbObjectId::kNull;
- if (es == Acad::eOk)
- {
- AcDbMentalRayRenderSettings *pMentalRayActiveSetting =
- AcDbMentalRayRenderSettings::cast(pMyDictObject);
- if (pMentalRayActiveSetting != NULL)
- {
- pRenderSetting = new AcDbMentalRayRenderSettings();
- es = pRenderSetting->copyFrom(pMentalRayActiveSetting);
- }
- es = pMentalRayActiveSetting->close();
- }
- }
- else
- {
- acutPrintf(ACRX_T("ACAD_RENDER_ACTIVE_SETTINGS не найдена !!" ));
- }
- pNODContainer->close();
- return Acad::eOk;
- }
- #endif
- static bool CreateAtilImage(AcGsView *pView,
- int width, int height,
- int colorDepth, int paletteSize,
- ACHAR *pFileName)
- {
- bool done = false ;
- AcGsDCRect screenRect(0,width-1,0, height-1);
- // Мы хотели бы иметь глубину цвета 24 или 32 бита
- if (colorDepth < 24)
- colorDepth = 24;
- if (colorDepth > 24)
- colorDepth = 32;
- // Создаём rbgmodel 32 битную полноцветную
- Atil::RgbModel rgbModel(colorDepth);
- Atil::ImagePixel initialColor(rgbModel.pixelType());
- // Создаём Atil изображение в стеке
- Atil::Image imgSource (Atil::Size(width, height), &rgbModel, initialColor);
- bool ok = false ;
- #ifdef ACAD2016 // 2016 использует Rapid RT рендер
- AcDbRapidRTRenderSettings *pCurrentSetting = NULL;
- Acad::ErrorStatus es = GetActiveRapidRTRenderSetting(pCurrentSetting);
- if (pCurrentSetting != NULL)
- {
- ok = pView->renderToImage (&imgSource, pCurrentSetting, nullptr , screenRect);
- delete pCurrentSetting;
- }
- #else // 2015 и более ранние используют Mental Ray рендер
- AcDbMentalRayRenderSettings *pCurrentSetting = NULL;
- Acad::ErrorStatus es = GetActiveRenderSetting(pCurrentSetting);
- if (pCurrentSetting != NULL)
- {
- ok = pView->RenderToImage (&imgSource, pCurrentSetting, nullptr , screenRect);
- delete pCurrentSetting;
- }
- #endif
- if (!ok)
- {
- AfxMessageBox(_T("Ошибка при рендере изображения" ));
- return false ;
- }
- else
- {
- done = WriteImageToFile(&imgSource, pFileName);
- }
- return done;
- }
Проект этого примера и чертежа с настройками визуализации можно скачать здесь:
А это скриншот визуализированного изображения, полученный в AutoCAD 2016 при помощи рендера RapidRT:
Источник: http://adndevblog.typepad.com/autocad/2015/09/rendering-using-rendertoimage-api-.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=4265
Опубликовано 16.02.2016Отредактировано 16.02.2016 в 01:50:53