1.main.cpp
#include "Viewer.h" // 包含自定义的 Viewer 头文件#include <BRepTools.hxx> // 包含 OpenCASCADE 中用于处理 BREP 文件的工具
#include <BRepPrimAPI_MakeBox.hxx> // 包含创建简单几何体的 APIint main(int argc, char** argv)
{// 创建 Viewer 对象,并指定窗口大小Viewer vout(100, 100, 1000, 800);// 将两个简单的立方体添加到 Viewer 中vout << BRepPrimAPI_MakeBox(10, 10, 20) // 创建一个 10x10x20 的立方体<< BRepPrimAPI_MakeBox(20, 30, 10); // 创建一个 20x30x10 的立方体if (argc > 1) // 如果命令行参数大于 1{BRep_Builder bb; // 创建 BRep 构建器TopoDS_Shape fromFile; // 定义一个从文件中读取的形状//if (!BRepTools::Read(fromFile, argv[1], bb)) // 从指定的文件中读取 BREP 形状{std::cout << "Failed to read BREP shape from file " << argv[1] << std::endl; // 如果读取失败,则输出错误消息return 1;}vout << fromFile; // 将从文件中读取的形状添加到 Viewer 中}// 创建两个立方体形状TopoDS_Shape box1 = BRepPrimAPI_MakeBox(10, 10, 20).Shape(); // 创建一个 10x10x20 的立方体形状TopoDS_Shape box2 = BRepPrimAPI_MakeBox(20, 30, 10).Shape(); // 创建一个 20x30x10 的立方体形状// 将两个立方体形状合并为一个形状BRep_Builder builder; // 创建 BRep 构建器TopoDS_Compound compound; // 定义一个组合形状builder.MakeCompound(compound); // 创建组合形状builder.Add(compound, box1); // 向组合形状中添加第一个立方体形状builder.Add(compound, box2); // 向组合形状中添加第二个立方体形状// 将合并后的形状保存为 BREP 文件BRepTools::Write(compound, "E:/CAD/output.brep"); // 将组合形状写入指定的文件中vout.StartMessageLoop(); // 启动消息循环,显示 Viewer 窗口return 0; // 返回程序执行成功
}
这段代码主要完成以下功能:
- 创建一个 Viewer 对象,用于可视化几何体。
- 如果有命令行参数,则尝试从文件中读取 BREP 形状,并将其添加到 Viewer 中。
- 创建两个立方体形状,将它们合并为一个组合形状,并将该组合形状写入 BREP 文件。
- 最后启动消息循环,显示 Viewer 窗口并等待用户操作。
2.viewer.h
#pragma once#ifdef _WIN32
#include <Windows.h> // 包含 Windows 平台特定的头文件
#endif// Local includes
#include "ViewerInteractor.h" // 包含自定义的 ViewerInteractor 头文件// OpenCascade includes
#include <TopoDS_Shape.hxx> // 包含 OpenCASCADE 中处理形状的头文件
#include <WNT_Window.hxx> // 包含 OpenCASCADE 中用于创建窗口的头文件// Standard includes
#include <vector> // 包含向量容器的头文件class V3d_Viewer; // OpenCASCADE 中的 3D 视图类
class V3d_View; // OpenCASCADE 中的 3D 视图类
class AIS_InteractiveContext; // OpenCASCADE 中的交互式上下文类
class AIS_ViewController; // OpenCASCADE 中的视图控制器类//-----------------------------------------------------------------------------//! Simple 3D viewer.
class Viewer
{
public:Viewer(const int left,const int top,const int width,const int height);public:Viewer& operator<<(const TopoDS_Shape& shape){this->AddShape(shape); // 添加形状到视图中return *this;}void AddShape(const TopoDS_Shape& shape); // 向视图中添加形状void StartMessageLoop(); // 启动消息循环,显示视图窗口并等待用户交互private:static LRESULT WINAPIwndProcProxy(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam);LRESULT CALLBACKwndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam);void init(const HANDLE& windowHandle); // 初始化窗口/* API-related things */
private:std::vector<TopoDS_Shape> m_shapes; //!< Shapes to visualize. // 待可视化的形状集合/* OpenCascade's things */
private:Handle(V3d_Viewer) m_viewer; // 3D 视图查看器Handle(V3d_View) m_view; // 3D 视图Handle(AIS_InteractiveContext) m_context; // 交互式上下文Handle(WNT_Window) m_wntWindow; // 窗口句柄Handle(ViewerInteractor) m_evtMgr; // 事件管理器/* Lower-level things */
private:HINSTANCE m_hInstance; //!< Handle to the instance of the module. // 模块实例句柄HWND m_hWnd; //!< Handle to the instance of the window. // 窗口句柄bool m_bQuit; //!< Indicates whether user want to quit from window. // 是否退出窗口的标志位};
这段代码定义了一个简单的 3D 视图器 Viewer
类,其中包含了以下内容:
- 定义了构造函数,用于初始化视图窗口的位置和大小。
- 重载了
<<
运算符,使得可以通过Viewer
对象向其中添加形状。 - 提供了向视图中添加形状和启动消息循环的方法。
- 定义了处理窗口消息的静态和非静态成员函数。
- 声明了用于存储待可视化形状的向量容器。
- 包含了 OpenCASCADE 中处理形状的相关类的句柄。
- 包含了与 API 相关的私有成员变量。
- 包含了与底层操作系统相关的私有成员变量。
3.viewer.cpp
#include "Viewer.h"// OpenCascade includes
#include <AIS_InteractiveContext.hxx> // AIS 交互式上下文
#include <AIS_Shape.hxx> // AIS 形状
#include <Aspect_DisplayConnection.hxx> // 显示连接
#include <Aspect_Handle.hxx> // 句柄
#include <OpenGl_GraphicDriver.hxx> // OpenGL 图形驱动
#include <V3d_AmbientLight.hxx> // 环境光
#include <V3d_DirectionalLight.hxx> // 方向光
#include <V3d_View.hxx> // 3D 视图
#include <V3d_Viewer.hxx> // 3D 观察者namespace {//! 调整本地选择的样式。//! \param[in] context AIS 上下文。void AdjustSelectionStyle(const Handle(AIS_InteractiveContext)& context){// 初始化子形状选择的样式。Handle(Prs3d_Drawer) selDrawer = new Prs3d_Drawer;//selDrawer->SetLink ( context->DefaultDrawer() ); // 设置链接selDrawer->SetFaceBoundaryDraw ( true ); // 设置绘制面边界selDrawer->SetDisplayMode ( 1 ); // 设置显示模式为填充selDrawer->SetTransparency ( 0.5f ); // 设置透明度selDrawer->SetZLayer ( Graphic3d_ZLayerId_Topmost ); // 设置 Z 层selDrawer->SetColor ( Quantity_NOC_GOLD ); // 设置颜色selDrawer->SetBasicFillAreaAspect ( new Graphic3d_AspectFillArea3d() ); // 设置基本填充区域属性// 调整填充区域方面。const Handle(Graphic3d_AspectFillArea3d)&fillArea = selDrawer->BasicFillAreaAspect();//fillArea->SetInteriorColor (Quantity_NOC_GOLD); // 设置内部颜色fillArea->SetBackInteriorColor (Quantity_NOC_GOLD); // 设置背面内部颜色//fillArea->ChangeFrontMaterial() .SetMaterialName(Graphic3d_NOM_NEON_GNC); // 修改前景材质fillArea->ChangeFrontMaterial() .SetTransparency(0.4f); // 设置透明度fillArea->ChangeBackMaterial() .SetMaterialName(Graphic3d_NOM_NEON_GNC); // 修改背景材质fillArea->ChangeBackMaterial() .SetTransparency(0.4f); // 设置透明度selDrawer->UnFreeBoundaryAspect()->SetWidth(1.0); // 设置边界宽度// 更新 AIS 上下文。context->SetHighlightStyle(Prs3d_TypeOfHighlight_LocalSelected, selDrawer);}
}//-----------------------------------------------------------------------------Viewer::Viewer(const int left,const int top,const int width,const int height)
: m_hWnd (NULL),m_bQuit (false)
{// 注册窗口类,只注册一次static HINSTANCE APP_INSTANCE = NULL;if ( APP_INSTANCE == NULL ){APP_INSTANCE = GetModuleHandleW(NULL);m_hInstance = APP_INSTANCE;WNDCLASSW WC;WC.cbClsExtra = 0;WC.cbWndExtra = 0;WC.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH);WC.hCursor = LoadCursor(NULL, IDC_ARROW);WC.hIcon = LoadIcon(NULL, IDI_APPLICATION);WC.hInstance = APP_INSTANCE;WC.lpfnWndProc = (WNDPROC) wndProcProxy;WC.lpszClassName = L"OpenGLClass";WC.lpszMenuName = 0;WC.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;if ( !RegisterClassW(&WC) ) // 注册窗口类{return;}}// 设置窗口的区域矩形坐标RECT Rect;SetRect(&Rect,left, top,left + width, top + height);// 调整窗口矩形AdjustWindowRect(&Rect, WS_OVERLAPPEDWINDOW, false);// 创建窗口m_hWnd = CreateWindow("OpenGLClass","Quaoar >>> 3D",WS_OVERLAPPEDWINDOW,Rect.left, Rect.top, // 调整后的 x、y 位置Rect.right - Rect.left, Rect.bottom - Rect.top, // 调整后的宽度和高度NULL, NULL,m_hInstance,this);// 检查窗口是否创建成功if ( m_hWnd == NULL ){return;}// 最终显示窗口ShowWindow(m_hWnd, TRUE);HANDLE windowHandle = (HANDLE) m_hWnd;this->init(windowHandle); // 初始化窗口
}//-----------------------------------------------------------------------------void Viewer::AddShape(const TopoDS_Shape& shape)
{m_shapes.push_back(shape); // 添加形状到形状集合中
}//-----------------------------------------------------------------------------//! 启动消息循环。
void Viewer::StartMessageLoop()
{for ( auto sh : m_shapes ){Handle(AIS_Shape) shape = new AIS_Shape(sh);m_context->Display(shape, true); // 显示形状m_context->SetDisplayMode(shape, AIS_Shaded, true); // 设置显示模式为填充// 调整选择样式。::AdjustSelectionStyle(m_context);// 激活选择模式。m_context->Activate(4, true); // 激活面m_context->Activate(2, true); // 激活边}MSG Msg;while ( !m_bQuit ){switch ( ::MsgWaitForMultipleObjectsEx(0, NULL, 12, QS_ALLINPUT, 0) ){case WAIT_OBJECT_0:{while ( ::PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) ){if ( Msg.message == WM_QUIT )m_bQuit = true;// return;::TranslateMessage(&Msg);::DispatchMessage(&Msg);}}}}
}//-----------------------------------------------------------------------------void Viewer::init(const HANDLE& windowHandle)
{static Handle(Aspect_DisplayConnection) displayConnection;//if ( displayConnection.IsNull() )displayConnection = new Aspect_DisplayConnection();HWND winHandle = (HWND) windowHandle;//if ( winHandle == NULL )return;// 创建 OCCT 观察者。Handle(OpenGl_GraphicDriver)graphicDriver = new OpenGl_GraphicDriver(displayConnection, false);m_viewer = new V3d_Viewer(graphicDriver);// 灯光。Handle(V3d_DirectionalLight) LightDir = new V3d_DirectionalLight(V3d_Zneg, Quantity_Color (Quantity_NOC_GRAY97), 1);Handle(V3d_AmbientLight) LightAmb = new V3d_AmbientLight();//LightDir->SetDirection(1.0, -2.0, -10.0);//m_viewer->AddLight(LightDir);m_viewer->AddLight(LightAmb);m_viewer->SetLightOn(LightDir);m_viewer->SetLightOn(LightAmb);// AIS 上下文。m_context = new AIS_InteractiveContext(m_viewer);// 配置一些全局属性。const Handle(Prs3d_Drawer)& contextDrawer = m_context->DefaultDrawer();//if ( !contextDrawer.IsNull() ){const Handle(Prs3d_ShadingAspect)& SA = contextDrawer->ShadingAspect();const Handle(Graphic3d_AspectFillArea3d)& FA = SA->Aspect();contextDrawer->SetFaceBoundaryDraw(true); // 绘制边界。FA->SetEdgeOff();// 将无限线的修复值从其默认值 500000 降低到 1000。contextDrawer->SetMaximalParameterValue(1000);}// 创建主视图。m_view = m_viewer->CreateView();m_view->SetImmediateUpdate(false);// 事件管理器在上下文和视图可用时构建。m_evtMgr = new ViewerInteractor(m_view, m_context);// 创建 Aspect 窗口m_wntWindow = new WNT_Window(winHandle);m_view->SetWindow(m_wntWindow, nullptr);//if ( !m_wntWindow->IsMapped() ){m_wntWindow->Map();}m_view->MustBeResized();// 视图设置。m_view->SetShadingModel(V3d_PHONG);// 配置渲染参数Graphic3d_RenderingParams& RenderParams = m_view->ChangeRenderingParams();RenderParams.IsAntialiasingEnabled = true;RenderParams.NbMsaaSamples = 8; // 多重采样抗锯齿RenderParams.IsShadowEnabled = false;RenderParams.CollectedStats = Graphic3d_RenderingParams::PerfCounters_NONE;
}//-----------------------------------------------------------------------------LRESULT WINAPI Viewer::wndProcProxy(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{if ( message == WM_CREATE ){// 保存我们的类实例的指针(在窗口创建时发送)到窗口存储中。CREATESTRUCTW* pCreateStruct = (CREATESTRUCTW*) lparam;SetWindowLongPtr(hwnd, int (GWLP_USERDATA), (LONG_PTR) pCreateStruct->lpCreateParams);}// 获取我们的类实例的指针。Viewer* pThis = (Viewer*) GetWindowLongPtr( hwnd, int (GWLP_USERDATA) );return (pThis != NULL) ? pThis->wndProc(hwnd, message, wparam, lparam): DefWindowProcW(hwnd, message, wparam, lparam);
}//-----------------------------------------------------------------------------//! 窗口过程。
LRESULT Viewer::wndProc(HWND hwnd,UINT message,WPARAM wparam,LPARAM lparam)
{if ( m_view.IsNull() )return DefWindowProc(hwnd, message, wparam, lparam);switch ( message ){case WM_PAINT:{PAINTSTRUCT aPaint;BeginPaint(m_hWnd, &aPaint);EndPaint (m_hWnd, &aPaint);m_evtMgr->ProcessExpose();break;}case WM_SIZE:{m_evtMgr->ProcessConfigure();break;}case WM_MOVE:case WM_MOVING:case WM_SIZING:{switch ( m_view->RenderingParams().StereoMode ){case Graphic3d_StereoMode_RowInterlaced:case Graphic3d_StereoMode_ColumnInterlaced:case Graphic3d_StereoMode_ChessBoard:{// 跟踪窗口移动以翻转立体成对m_view->MustBeResized();m_view->Update();break;}default:break;}break;}case WM_KEYUP:case WM_KEYDOWN:{const Aspect_VKey vkey = WNT_Window::VirtualKeyFromNative( (int) wparam );//if ( vkey != Aspect_VKey_UNKNOWN ){const double timeStamp = m_evtMgr->EventTime();if ( message == WM_KEYDOWN ){m_evtMgr->KeyDown(vkey, timeStamp);}else{m_evtMgr->KeyUp(vkey, timeStamp);}}break;}case WM_LBUTTONUP:case WM_MBUTTONUP:case WM_RBUTTONUP:case WM_LBUTTONDOWN:case WM_MBUTTONDOWN:case WM_RBUTTONDOWN:{const Graphic3d_Vec2i pos( LOWORD(lparam), HIWORD(lparam) );const Aspect_VKeyFlags flags = WNT_Window::MouseKeyFlagsFromEvent(wparam);Aspect_VKeyMouse button = Aspect_VKeyMouse_NONE;//switch ( message ){case WM_LBUTTONUP:case WM_LBUTTONDOWN:button = Aspect_VKeyMouse_LeftButton;break;case WM_MBUTTONUP:case WM_MBUTTONDOWN:button = Aspect_VKeyMouse_MiddleButton;break;case WM_RBUTTONUP:case WM_RBUTTONDOWN:button = Aspect_VKeyMouse_RightButton;break;}if ( message == WM_LBUTTONDOWN|| message == WM_MBUTTONDOWN|| message == WM_RBUTTONDOWN ){SetFocus (hwnd);SetCapture(hwnd);if ( !m_evtMgr.IsNull() )m_evtMgr->PressMouseButton(pos, button, flags, false);}else{ReleaseCapture();if ( !m_evtMgr.IsNull() )m_evtMgr->ReleaseMouseButton(pos, button, flags, false);}m_evtMgr->FlushViewEvents(m_context, m_view, true);break;}case WM_MOUSEWHEEL:{const int delta = GET_WHEEL_DELTA_WPARAM(wparam);const double deltaF = double(delta) / double(WHEEL_DELTA);//const Aspect_VKeyFlags flags = WNT_Window::MouseKeyFlagsFromEvent(wparam);//Graphic3d_Vec2i pos( int(short(LOWORD(lparam))), int(short(HIWORD(lparam))) );POINT cursorPnt = { pos.x(), pos.y() };if ( ScreenToClient(hwnd, &cursorPnt) ){pos.SetValues(cursorPnt.x, cursorPnt.y);}if ( !m_evtMgr.IsNull() ){m_evtMgr->UpdateMouseScroll( Aspect_ScrollDelta(pos, deltaF, flags) );m_evtMgr->FlushViewEvents(m_context, m_view, true);}break;}case WM_MOUSEMOVE:{Graphic3d_Vec2i pos( LOWORD(lparam), HIWORD(lparam) );Aspect_VKeyMouse buttons = WNT_Window::MouseButtonsFromEvent (wparam);Aspect_VKeyFlags flags = WNT_Window::MouseKeyFlagsFromEvent(wparam);// 不要从输入事件中创建幻灯片秀 - 获取实际鼠标光标位置CURSORINFO cursor;cursor.cbSize = sizeof(cursor);if ( ::GetCursorInfo(&cursor) != FALSE ){POINT cursorPnt = { cursor.ptScreenPos.x, cursor.ptScreenPos.y };if ( ScreenToClient(hwnd, &cursorPnt) ){// 由于我们重写了鼠标位置,因此我们也需要重写鼠标状态pos.SetValues(cursorPnt.x, cursorPnt.y);buttons = WNT_Window::MouseButtonsAsync();flags = WNT_Window::MouseKeyFlagsAsync();}}if ( m_wntWindow.IsNull() || (HWND) m_wntWindow->HWindow() != hwnd ){// 鼠标移动事件也适用于非活动窗口break;}if ( !m_evtMgr.IsNull() ){m_evtMgr->UpdateMousePosition(pos, buttons, flags, false);m_evtMgr->FlushViewEvents(m_context, m_view, true);}break;}default:{break;}case WM_DESTROY:m_bQuit = true;}return DefWindowProc(hwnd, message, wparam, lparam);
}
这段代码实现了一个简单的 3D 观察者类 Viewer
,用于显示和交互式操作 3D 形状。它使用了 OpenCascade(OCCT)库来处理和渲染 3D 形状。逐行注释已经解释了代码的功能和作用。
4.viewerinteractor.h
#pragma once// 包含 OpenCascade 头文件
#include <AIS_ViewController.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TCollection_AsciiString.hxx>// 前置声明
class AIS_InteractiveContext;
class V3d_View;//! 管理输入事件的类
class ViewerInteractor : public Standard_Transient, public AIS_ViewController
{
public:// OCCT RTTIDEFINE_STANDARD_RTTI_INLINE(ViewerInteractor, Standard_Transient)public://! 构造函数//! \param[in] view V3d 视图实例。//! \param[in] ctx 交互上下文。ViewerInteractor(const Handle(V3d_View)& view,const Handle(AIS_InteractiveContext)& ctx);//! 析构函数virtual ~ViewerInteractor();public://! 返回交互上下文。const Handle(AIS_InteractiveContext)&GetContext() const { return m_ctx; }//! 处理鼠标按钮按下/释放事件。virtual bool UpdateMouseButtons(const Graphic3d_Vec2i& thePoint,Aspect_VKeyMouse theButtons,Aspect_VKeyFlags theModifiers,bool theIsEmulated) Standard_OVERRIDE;//! 处理键盘按下事件。virtual void KeyDown(Aspect_VKey theKey,double theTime,double thePressure = 1.0) Standard_OVERRIDE;//! 处理键盘释放事件。virtual void KeyUp(Aspect_VKey theKey,double theTime) Standard_OVERRIDE;//! 在曝光事件上重新绘制视图。virtual void ProcessExpose();//! 处理重绘事件。virtual void handleViewRedraw(const Handle(AIS_InteractiveContext)& theCtx,const Handle(V3d_View)& theView) Standard_OVERRIDE;//! 调整视图大小。virtual void ProcessConfigure();//! 处理按键按下事件。void ProcessKeyPress(Aspect_VKey theKey);private:Handle(V3d_View) m_view; //!< 3D 视图。Handle(AIS_InteractiveContext) m_ctx; //!< 交互上下文。
};
这段代码定义了一个名为 ViewerInteractor
的类,用于管理输入事件并继承自 AIS_ViewController
类。这个类主要负责处理鼠标和键盘事件,以及在需要时重新绘制视图。
5.viewerinteractor.cpp
#include "ViewerInteractor.h"// OpenCascade 头文件
#include <Aspect_Grid.hxx>
#include <AIS_AnimationCamera.hxx>
#include <AIS_InteractiveContext.hxx>
#include <AIS_Shape.hxx>
#include <V3d_View.hxx>//-----------------------------------------------------------------------------// ViewerInteractor 类的构造函数
ViewerInteractor::ViewerInteractor(const Handle(V3d_View)& view,const Handle(AIS_InteractiveContext)& ctx): m_view(view),m_ctx(ctx)
{}//-----------------------------------------------------------------------------// ViewerInteractor 类的析构函数
ViewerInteractor::~ViewerInteractor()
{}//-----------------------------------------------------------------------------// 更新鼠标按钮并处理鼠标事件的方法
bool ViewerInteractor::UpdateMouseButtons(const Graphic3d_Vec2i& point,Aspect_VKeyMouse buttons,Aspect_VKeyFlags modifiers,bool isEmulated)
{return AIS_ViewController::UpdateMouseButtons(point, buttons, modifiers, isEmulated);
}//-----------------------------------------------------------------------------// 处理曝光事件的方法(重绘视图)
void ViewerInteractor::ProcessExpose()
{if (!m_view.IsNull()){m_view->Invalidate();FlushViewEvents(m_ctx, m_view, true);}
}//-----------------------------------------------------------------------------// 处理视图重绘事件的方法
void ViewerInteractor::handleViewRedraw(const Handle(AIS_InteractiveContext)& ctx,const Handle(V3d_View)& view)
{AIS_ViewController::handleViewRedraw(ctx, view);
}//-----------------------------------------------------------------------------// 处理配置事件的方法(调整视图大小)
void ViewerInteractor::ProcessConfigure()
{if (!m_view.IsNull()){m_view->MustBeResized();FlushViewEvents(m_ctx, m_view, true);}
}//-----------------------------------------------------------------------------// 处理按键按下事件的方法
void ViewerInteractor::KeyDown(Aspect_VKey key,double time,double pressure)
{AIS_ViewController::KeyDown(key, time, pressure);
}//-----------------------------------------------------------------------------// 处理按键释放事件的方法
void ViewerInteractor::KeyUp(Aspect_VKey key,double time)
{const unsigned int modifOld = myKeys.Modifiers();//AIS_ViewController::KeyUp(key, time);//const unsigned int modifNew = myKeys.Modifiers();ProcessKeyPress(key | modifNew);
}//-----------------------------------------------------------------------------// 处理按键按下后的操作
void ViewerInteractor::ProcessKeyPress(Aspect_VKey key)
{if (m_ctx.IsNull() || m_view.IsNull()){return;}switch (key){case Aspect_VKey_F:{// 适应所选对象或所有对象if (m_ctx->NbSelected() > 0){m_ctx->FitSelected(m_view);}else{m_view->FitAll();}break;}case Aspect_VKey_S:case Aspect_VKey_W:{// 设置所选对象或所有对象的显示模式为 Shaded 或 Wireframeconst int dm = (key == Aspect_VKey_S) ? AIS_Shaded : AIS_WireFrame;if (m_ctx->NbSelected() == 0){m_ctx->SetDisplayMode(dm, false);m_ctx->UpdateCurrentViewer();}else{for (m_ctx->InitSelected(); m_ctx->MoreSelected(); m_ctx->NextSelected()){m_ctx->SetDisplayMode(m_ctx->SelectedInteractive(), dm, false);}m_ctx->UpdateCurrentViewer();}break;}case Aspect_VKey_Backspace: // 正轴测投影{m_view->SetProj(V3d_XposYnegZpos);m_view->Redraw();break;}case Aspect_VKey_T:{// 设置视图投影为顶视图m_view->SetProj(V3d_TypeOfOrientation_Zup_Top);m_view->Redraw();break;}case Aspect_VKey_B:{// 设置视图投影为底视图m_view->SetProj(V3d_TypeOfOrientation_Zup_Bottom);m_view->Redraw();break;}case Aspect_VKey_L:{// 设置视图投影为左视图m_view->SetProj(V3d_TypeOfOrientation_Zup_Left);m_view->Redraw();break;}case Aspect_VKey_R:{// 设置视图投影为右视图m_view->SetProj(V3d_TypeOfOrientation_Zup_Right);m_view->Redraw();break;}default: break;}
}