基于OpenCASCADE自制三维建模软件(五)鼠标模式


鼠标控制模式用于三维空间可视化导航,通过鼠标的按键及少数键盘按键的组合,可以实现对三维视图的平移、缩放、选择等操作。

一、选择导航模式

由于之前使用过Blender,其鼠标的操作方式比较好用,因此这里使用Blender导航。Blender导航参照Blender的操作。以前需要SHIFT配合鼠标才能完成视图平移. 在2016年Blender增加了一个功能改变了这一情况。要平移视图,现在可以同时按下鼠标左键和鼠标右键并在视图中拖动。

在这里插入图片描述
在三维界面头文件中加入模式枚举,及添加鼠标操作相关成员:

//c3dwidget.h
class C3DWidget : public QWidget
{
	......
protected:
    //!三维场景转换模式
    enum CurrentAction3d
    {
        CurAction3d_Nothing,
        CurAction3d_DynamicPanning, //平移
        CurAction3d_DynamicZooming, //缩放
        CurAction3d_DynamicRotation //旋转
    };
protected:
    //!覆写键盘按键按下事件
    void keyPressEvent(QKeyEvent *event);
    //!覆写键盘按键释放事件
    void keyReleaseEvent(QKeyEvent *event);
    //!覆写鼠标按键按下事件
    void mousePressEvent(QMouseEvent *event);
    //!覆写鼠标按键释放事件
    void mouseReleaseEvent(QMouseEvent *event);
    //!覆写鼠标移动事件
    void mouseMoveEvent(QMouseEvent *event);
    //!覆写鼠标滚轮事件
    void wheelEvent(QWheelEvent *event);
private:
    Standard_Integer m_x_max;    //!记录鼠标平移坐标X
    Standard_Integer m_y_max;    //!记录鼠标平移坐标Y
    CurrentAction3d m_current_mode; //!三维场景转换模式
    bool m_shift_key_pressed;   //!记录Shift键是否被按下
    ......
};

二、平移

平移的方式有两种,通过if判断当前操作是否为平移方式的其中一种。其中一种需要加上SHIFT按键,则通过m_shift_key_pressed 变量判断SHIFT键是否被按下。

void C3DWidget::mousePressEvent(QMouseEvent *event)
{
    if( ((event->buttons() & Qt::MidButton) && (QApplication::keyboardModifiers()==Qt::ShiftModifier) )  //平移方式1
        ||((event->buttons()&Qt::LeftButton)&&(event->buttons()&Qt::RightButton)))//平移方式2
    {
        m_current_mode = CurAction3d_DynamicPanning;
        m_x_max = event->pos().x(); //记录起始X位置
        m_y_max = event->pos().y(); //记录起始Y位置
    }
    ......
}
void C3DWidget::mouseReleaseEvent(QMouseEvent *)
{
    m_current_mode = CurAction3d_Nothing;
}

void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
    switch (m_current_mode)
    {
    case CurAction3d_DynamicPanning:
        //执行平移
        m_view->Pan(event->pos().x() - m_x_max, m_y_max - event->pos().y());
        m_x_max = event->pos().x();
        m_y_max = event->pos().y();
        break;
    ......
    }
}

三、缩放

缩放通过V3d_View类的Zoom方法实现,Zoom方法的设计是通过相邻两次鼠标位置判断缩小或放大,以及缩放的程度。前两个参数为第一次鼠标的位置,后两个参数为第二次鼠标的位置。而滚动鼠标滚轮会Qt的wheelEvent事件,向上滚动和向下滚动event->angleDelta().y()会返回或正或负的数值,将此值模拟第二次鼠标的位置,实现三维界面缩放功能。

void C3DWidget::wheelEvent(QWheelEvent *event)
{
    m_view->Zoom(0, 0, event->angleDelta().y(), 0); //执行缩放
}

5月9日更新:原来的程序只在固定点缩放,作以下更改后,缩放跟随鼠标的位置进行。

void C3DWidget::wheelEvent(QWheelEvent *event)
{
    m_view->StartZoomAtPoint(event->pos().x(),event->pos().y());
    m_view->ZoomAtPoint(0, 0, event->angleDelta().y(), 0); //执行缩放
}

在这里插入图片描述


四、旋转

鼠标的中键按下时,通过V3d_View类的StartRotation方法记录起始位置。鼠标发生移动后,使用Rotation方法实现三维界面旋转。

void C3DWidget::mousePressEvent(QMouseEvent *event)
{
    if(......)//平移
    {......}
    else if(event->buttons() & Qt::MidButton)  //旋转
    {
        m_current_mode = CurAction3d_DynamicRotation;
        m_view->StartRotation(event->pos().x(), event->pos().y());
    }
    ......
}
void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
    switch (m_current_mode)
    {
    ......
    case CurAction3d_DynamicRotation:
        //执行旋转
        m_view->Rotation(event->pos().x(), event->pos().y());
        break;
    ......
    }
}

五、实际效果

在这里插入图片描述

项目仓库

https://github.com/Jelatine/JellyCAD

  • 16
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
下面是一个使用 OpenCASCADE 和 Qt 开发的简单三维显示程序的示例代码: ```cpp #include <QApplication> #include <QWidget> #include <Aspect_Handle.hxx> #include <Graphic3d_GraphicDriver.hxx> #include <OpenGl_GraphicDriver.hxx> #include <V3d_Viewer.hxx> #include <V3d_View.hxx> int main(int argc, char *argv[]) { // 创建 Qt 应用程序 QApplication app(argc, argv); // 创建 Qt 窗口 QWidget window; window.resize(800, 600); window.show(); // 获取窗口的原生句柄 Aspect_Handle hWindow = reinterpret_cast<Aspect_Handle>(window.winId()); // 创建 OpenCASCADE 图形驱动程序 Handle(Graphic3d_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver(); // 创建三维视窗 Handle(V3d_Viewer) aViewer = new V3d_Viewer(aGraphicDriver); Handle(V3d_View) aView = aViewer->CreateViewFromWindow("MyView", hWindow); // 设置视窗参数 aView->SetBackgroundColor(Quantity_NOC_GRAY60); aView->MustBeResized(); aView->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_WHITE, 0.08, V3d_ZBUFFER); // 循环显示视窗,直到应用程序退出 while (!app.quitOnLastWindowClosed()) { aView->Redraw(); app.processEvents(); } return app.exec(); } ``` 这个示例代码演示了如何在一个 Qt 窗口中创建一个简单的三维视窗,并设置视窗的背景颜色和坐标轴显示。您可以根据需要自定义窗口的大小和其他参数。 要运行此代码,您需要先安装 Qt 和 OpenCASCADE 库,并将其与您的 C++ 项目链接。请确保您已正确配置 Qt 和 OpenCASCADE 的环境。 请注意,这只是一个简单的示例,用于说明如何在 Qt 中集成 OpenCASCADE 的三维显示功能。在实际开发中,您可能需要更多的代码来处理用户交互、加载模型文件、添加其他功能等。希望这个示例对您有所帮助!如果您有更多问题,请随时提问。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值