opencascade4解析

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;}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/699992.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【动态规划】【状态压缩】LCP04 覆盖

作者推荐 【广度优先搜索】【网格】【割点】【 推荐】1263. 推箱子 本文涉及知识点 动态规划汇总 LCP04 覆盖 你有一块棋盘&#xff0c;棋盘上有一些格子已经坏掉了。你还有无穷块大小为1 * 2的多米诺骨牌&#xff0c;你想把这些骨牌不重叠地覆盖在完好的格子上&#xff0…

maven3旧版本的下载地址(含新版本)

因为现有的3.8版本与IDEA不兼容&#xff0c;我需要下载3.6版本&#xff0c;但是官网的位置非常隐蔽&#xff0c;找了很多资料才看到。故记录一下。 第一步 进入网址&#xff0c;选择需要的版本 Index of /dist/maven/maven-3 第二步 选择binaries 第三步 选择zip文件下载就可…

Django内置模型查询讲解

Django框架的核心特性之一是它的对象关系映射&#xff08;ORM&#xff09;系统&#xff0c;它允许开发者使用Python代码与数据库进行交互&#xff0c;而无需编写原始的SQL查询。Django的ORM提供了丰富的API来执行复杂的数据库查询。在这篇博客中&#xff0c;我们将详细讲解Djan…

【Java程序设计】【C00285】基于Springboot的游戏分享网站(有论文)

基于Springboot的游戏分享网站&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的游戏分享网站 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xff1a;在网站首页可以查看首页、游戏…

uniapp-提现功能(demo)

页面布局 提现页面 有一个输入框 一个提现按钮 一段提现全部的文字 首先用v-model 和data内的数据双向绑定 输入框逻辑分析 输入框的逻辑 为了符合日常输出 所以要对输入框加一些条件限制 因为是提现 所以对输入的字符做筛选,只允许出现小数点和数字 这里用正则实现的 小数点…

IDEA生成Java Doc帮助文档

使用场景 使用IDEA&#xff08;本次使用2020.3版&#xff09;将自己写的常用的工具类打成jar包&#xff0c;安装到maven本地仓库&#xff0c;最后生成对应的doc参考文档。 操作流程 方法一 选中项目 右键 show in Explor&#xff0c;如下图&#xff1a; 选中地址栏 cmd 输入…

无公网IP情况下如何远程查看本地群晖NAS存储的文件资源

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…

Unity 获取文件夹引用并读取文件夹路径

准备 编辑器中的文件夹属于DefaultAssets类型的资源EditorGUILayout.ObjectField 可以获取对象的引用AssetDatabase.GetAssetPath可通过对象的实例id获取资源路径DirectoryInfo 可获取目录内文件信息Path.GetFileNameWithoutExtension 可获取无后缀的文件名 示例1 弹出窗口 …

Optional.ofNullable()方法

空指针异常 public static void main(String[] args) {List<String> list null;list.forEach(x -> System.out.println(x)); }优雅判空 public static void main(String[] args) {List<String> list null;List<String> newList Optional.ofNullable(…

Java的编程之旅27——继承

1.继承的简介 继承是面向对象编程中的一个重要概念&#xff0c;指的是一个类可以继承另一个类的属性和方法。被继承的类称为父类或基类&#xff0c;继承这个父类的类称为子类或派生类。 通过继承&#xff0c;子类可以继承父类的属性和方法&#xff0c;使得子类具有相似的行为…

掌握BeautifulSoup4:爬虫解析器的基础与实战【第91篇—BeautifulSoup4】

掌握BeautifulSoup4&#xff1a;爬虫解析器的基础与实战 网络上的信息浩如烟海&#xff0c;而爬虫技术正是帮助我们从中获取有用信息的重要工具。在爬虫过程中&#xff0c;解析HTML页面是一个关键步骤&#xff0c;而BeautifulSoup4正是一款功能强大的解析器&#xff0c;能够轻…

2024年度中国5G随身WiFi品牌排行榜

【中国品牌网中国3C质量评测中心权威榜单联合发布】 第一名&#xff1a;格行 优势&#xff1a;作为随身WiFi行业的佼佼者&#xff0c;格行凭借其15年的物联网行业经验&#xff0c;在技术研发、产品创新及客户服务上均享有盛誉。其5G随身WiFi产品网络稳定&#xff0c;客户满意度…

行为树入门:ROS2 BehaviorTree.CPP Groot2安装与简单使用(有例程)

ROS2安装与学习及其topic学习 BehaviorTree.CPP编译与安装 和 Groot2安装 注意&#xff1a;《ROS2行为树&#xff08;C行为树&#xff09;BehaviorTree.CPP完全图形化开发&#xff0c;完美支持ROS2话题通信》这个例程实现的前提需要建一个sentry_interfaces::msg::RobotHP的m…

基本代码讲解

1. 引用不能指向另一个对象 在Java中&#xff0c;对象是基于类定义创建的实例。每个对象都有自己的状态&#xff08;属性&#xff09;和行为&#xff08;方法&#xff09;。当我们在代码中创建一个对象时&#xff0c;我们通常会使用一个引用变量来持有这个对象的内存地址&…

Spring Boot 笔记 029 用户模块

1.1 用户信息需要在多个链接使用&#xff0c;所以需要用pinia持久化 1.1.1 定义store import {defineStore} from pinia import {ref} from vue const useUserInfoStore defineStore(userInfo,()>{//定义状态相关的内容const info ref({})const setInfo (newInfo)>{i…

“IT行业职业发展的黄金之路:哪些证书能为你增光添彩?“

文章目录 每日一句正能量前言1、浙大计算机程序设计能力考试证书&#xff08;PAT&#xff09;2、全国计算机等级考试证书(NCRE)3、计算机技术与软件专业资格考试证书&#xff08;软考&#xff09;4、通信专业技术人员职业水平证书5、全国计算机应用水平考试证书&#xff08;NIT…

MySQL学习Day19——索引的数据结构

一、为什么使用索引: 索引是存储引擎用于快速找到数据记录的一种数据结构&#xff0c;就好比一本教课书的目录部分&#xff0c;通过目录中找到对应文章的页码&#xff0c;便可快速定位到需要的文章。MySQL中也是一样的道理&#xff0c;进行数据査找时&#xff0c;首先查看查询…

【深蓝学院】移动机器人运动规划--第6章 模型预测控制(MPC)与运动规划--笔记

0. Outline 1. Reactive Control&#xff08;反应式控制&#xff09; 控制学中的 “Reactive Control” 通常指的是一种控制策略&#xff0c;它依赖于系统对特定事件或变化的即时反应&#xff0c;而不是按照预定的计划或策略行动。这种控制往往是基于当前的传感器输入来做出决…

爬虫项目(1)

1.节点 想要获取网页中的数据&#xff0c;首先要获取网页 HTML 代码&#xff0c;再把数据从中提取出来。 我们要向网页的服务器发送请求&#xff0c;服务器返回的响应就是网页 HTML 代码 节点 &#xff08;1&#xff09;文档节点&#xff1a;就是文档的内容&#xff1b; &a…

Mac 上游玩QQ飞车详细教程,IPA砸壳包资源下载安装

最近经过一番折腾终于在 MAC 上成功安装运行了 QQ 飞车&#xff0c;上图&#xff1a; 最后总结下来安装过程其实蛮简单的&#xff0c;但其中有很多卡点和坑所以浪费了很多的时间&#xff0c;特意整理本篇教程供大家参考 大体思路是这样的&#xff0c;先安装 playCover,该软件可…