简介
使用 Teigha Publish 创建的文档中,可以轻松实现切换 3D CAD 模型视图的功能。
本文介绍了如何使用 JavaScript 切换 OdAnnotation 对象的视图。OdAnnotation 类中有两个函数:
void setCarouselButtons(const OdStringArray& button_names, const OdString& previous_button_name, const OdString& next_button_name, OdUInt16 scroll_size);
void setCarouselViews(const OdUInt32Array& indices, const OdImagePtrArray& images);
这些函数用于创建一组视图切换按钮,这些按钮占据 OdAnnotation 对象区域的下部。在本文中,我们将把自定义视图切换按钮添加到所创建文档的任意位置。
基础知识
创建 OdDocument 类的实例,添加 OdAnnotation 对象所在的页面,将 .prc 文件加载到 OdCADModel 对象中,并将其添加到 OdAnnotation:
OdFilePtr pPublisher = OdFile::createObject();
TEST_ASSERT(!pPublisher.isNull());
OdDocumentPtr pDoc = OdDocument::createObject();
pDoc->setInformation(L"Test Document", L"Author", L"Test", L"Oda Pdf Publish");
pDoc->setHostServices(pHostApp);
OdPagePtr pPage = OdPage::createObject();
pPage->setOrientation(Page::kPortrait);
pDoc->addPage(pPage);
OdString sFile = L"CORE11713\\tank.prc";
OdString sIn = pHostApp->findFile(sFile);
OdRect rect;
rect.m_min.x = 1;
rect.m_max.x = 593;
OdGePoint3d maxP = OdGePoint3d(2.0257825851440430, 1.1199963092803955, 5.8764815330505389);
OdGePoint3d minP = OdGePoint3d(-1.0000000000000002, -1.103692531585693, -2.2000000476837140);
OdGeExtents3d extPrc(minP, maxP);
OdCADModelPtr pModel = OdCADModel::createObject();
pModel->setSource(sIn);
OdAnnotationPtr pAnnot = OdAnnotation::createObject();
pAnnot->setSource(pModel);
pAnnot->setTransparentBackground(false);
pAnnot->setName(OdString().format(L"Test 3D Annotation%i", i));
pAnnot->setModelTreeVisibility(true);
pPage->addAnnotation(pAnnot, rect);
接下来,我们创建一个视图名称数组,用于执行切换:
OdStringArray view_names;
view_names.push_back(L"Default");
view_names.push_back(L"Front");
view_names.push_back(L"Back");
view_names.push_back(L"Right");
view_names.push_back(L"Left");
view_names.push_back(L"Top");
view_names.push_back(L"Bottom");
然后创建 OdArtwork 类的实例,并使用 addView 实用函数(参见 PublishTemplate* 示例)将 OdView 对象添加到其中:
OdArtworkPtr pArtwork = OdArtwork::createObject();
double field_w = 100;
double field_h = 100;
//Front
addView(pArtwork, OdGePoint3d(0, -1, 0), OdGePoint3d::kOrigin, OdGeVector3d::kZAxis, view_names[1], view_names[1], Camera::kOrthographic, field_w, field_h, extPrc);
//Back
addView(pArtwork, OdGePoint3d(0, 1, 0), OdGePoint3d::kOrigin, OdGeVector3d::kZAxis, view_names[2], view_names[2], Camera::kOrthographic, field_w, field_h, extPrc);
//Right
addView(pArtwork, OdGePoint3d(1, 0, 0), OdGePoint3d::kOrigin, OdGeVector3d::kZAxis, view_names[3], view_names[3], Camera::kOrthographic, field_w, field_h, extPrc);
//Left
addView(pArtwork, OdGePoint3d(-1, 0, 0), OdGePoint3d::kOrigin, OdGeVector3d::kZAxis, view_names[4], view_names[4], Camera::kOrthographic, field_w, field_h, extPrc);
//Top
addView(pArtwork, OdGePoint3d(0, 0, 1), OdGePoint3d::kOrigin, OdGeVector3d::kYAxis, view_names[5], view_names[5], Camera::kOrthographic, field_w, field_h, extPrc);
//Bottom
addView(pArtwork, OdGePoint3d(0, 0, -1), OdGePoint3d::kOrigin, -OdGeVector3d::kYAxis, view_names[6], view_names[6], Camera::kOrthographic, field_w, field_h, extPrc);
//Default View
OdGePoint3d defCamPos(-0.90612681748501411, -0.37532908821626582, 0.19509553088993711);
OdGeVector3d defUpVec(0.18024483319542611, 0.074659669699104828, 0.98078424427943056);
addView(pArtwork, defCamPos, OdGePoint3d::kOrigin, defUpVec, view_names[0], view_names[0], Camera::kOrthographic, field_w, field_h, extPrc, Rendering::kDefault, Lighting::kDay, true);
pAnnot->setArtwork(pArtwork);
按名称切换视图的示例
以下代码演示了如何使用视图名称创建视图切换按钮:
static const OdChar* changeViewFuncJS =
L"function ChangeViewByName(pageIndex, annot_index, view_name) \n"
L"{ \n"
L" annot = this.getAnnots3D( pageIndex )[ annot_index ]; \n"
L" if(annot != null) \n"
L" { \n"
L" annot.context3D.runtime.setView(view_name); \n"
L" } \n"
L"} \n"
L" \n";
pDoc->addJavaScript(L"changeViewFuncJS", changeViewFuncJS);
OdRect button_rect(10, 60, 5, 55);
for (OdUInt16 i = 0; i < view_names.size(); ++i)
{
OdButtonPtr pButton = OdButton::createObject();
pButton->setName(view_names[i]);
pButton->setLabel(view_names[i]);
pPage->addButton(pButton, button_rect);
button_rect.m_min.x += 70;
button_rect.m_max.x = button_rect.m_min.x + 50;
pPage->addJavaScriptActionByField(view_names[i], L"ChangeViewByName( this.pageNum, 0, \"" + view_names[i] + L"\");", Action::kButtonReleased);
}
在此代码中,OdButton 对象是根据 OdAnnotation 的预定义视图数量创建的。选择预定义视图的代码的公共部分在文档级别的单独的 ChangeViewByName 函数中完成。在 JavaScript 中,按钮的脚本仅包含调用此函数的代码,参数包括:页码、页面上的注释索引以及预定义视图的名称。结果如下所示。
要控制切换,您不仅可以使用 OdButton 按钮,还可以使用分配给 JavaScript 脚本的任何其他控件。
按索引切换视图的示例
以下代码演示了如何使用视图索引创建视图切换按钮:
static const OdChar* scrollViewFuncJS =
L"var current_view_index; \n"
L"if(!current_view_index) \n"
L" current_view_index = 0; \n"
L"function ScrollToView(pageIndex, annot_index, next) \n"
L"{ \n"
L" annot = this.getAnnots3D( pageIndex )[ annot_index ]; \n"
L" if(annot != null) \n"
L" { \n"
L" if(next) \n"
L" { \n"
L" viewCount = annot.context3D.runtime.viewCount; \n"
L" this.current_view_index += 1; \n"
L" if(this.current_view_index > (viewCount - 1)) \n"
L" this.current_view_index = viewCount - 1; \n"
L" } \n"
L" else \n"
L" { \n"
L" current_view_index = current_view_index - 1; \n"
L" if(current_view_index < 0) \n"
L" current_view_index = 0; \n"
L" } \n"
L" annot.context3D.runtime.setView(current_view_index);\n"
L" } \n"
L"} \n";
pDoc->addJavaScript(L"scrollViewFuncJS", scrollViewFuncJS);
OdButtonPtr pPrevButton = OdButton::createObject();
OdString prev_button_name = L"previous";
pPrevButton->setName(prev_button_name);
pPrevButton->setLabel(prev_button_name);
pPage->addButton(pPrevButton, OdRect(5, 50, 425, 475));
pPage->addJavaScriptActionByField(prev_button_name, L"ScrollToView( this.pageNum, 1, false);", Action::kButtonReleased);
OdButtonPtr pNextButton = OdButton::createObject();
OdString next_button_name = L"next";
pNextButton->setName(next_button_name);
pNextButton->setLabel(next_button_name);
pPage->addButton(pNextButton, OdRect(540, 590, 425, 475));
pPage->addJavaScriptActionByField(next_button_name, L"ScrollToView( this.pageNum, 1, true);", Action::kButtonReleased);
在此代码中,创建了两个按钮:上一个和下一个。这些按钮根据其索引将预定义视图切换到上一个和下一个。要存储当前视图索引,请使用全局文档级变量 current_view_index。切换脚本也在单独的函数中呈现。此代码的结果如下所示。