occview.cpp新注释

#include <OpenGl_GraphicDriver.hxx>

#include "view.h"

#include <QMenu>
#include <QMouseEvent>
#include <QRubberBand>
#include <QStyleFactory>

#include <V3d_View.hxx>

#include <Aspect_Handle.hxx>
#include <Aspect_DisplayConnection.hxx>

#ifdef WNT//判断你的系统并做出相应处理
  #include <WNT_Window.hxx>
#elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
  #include <Cocoa_Window.hxx>
#else
  #undef Bool
  #undef None
  #undef KeyPress
  #undef KeyRelease
  #undef FocusOut
  #undef FontChange
  #include <Xw_Window.hxx>
#endif


static Handle(Graphic3d_GraphicDriver)& GetGraphicDriver()//Graphic3d_GraphicDriver是一个3D图形驱动程序,用于在计算机上渲染和操作三维图形。它是连接3D图形应用程序和计算机图形硬件的桥梁,允许开发者利用计算机图形硬件的能力进行高效的3D渲染。
//Graphic3d_GraphicDriver通常与3D图形库或引擎一起使用,例如OpenGL、DirectX或Unity等。开发者可以使用这些库或引擎来创建和管理3D图形应用程序,并通过Graphic3d_GraphicDriver与计算机图形硬件进行交互,以实现高效的3D渲染。
{
    static Handle(Graphic3d_GraphicDriver) aGraphicDriver;
    return aGraphicDriver;
}

OccView::OccView(QWidget* parent)
    : QWidget(parent),
    myXmin(0),//相当于int myxmin=0;注释掉了也没有影响,修改也不影响啥
    myYmin(0),
    myXmax(0),
    myYmax(0),
    myCurrentMode(CurAction3d_DynamicRotation),//CurAction3d_DynamicRotation是一个动作捕捉相关的功能,用于实现3D动态旋转。即使你不使用旋转的那个命令也一样能旋转图形
    myDegenerateModeIsOn(Standard_True),//和上面一个都是currentaction3d的枚举,都有各自的3d作用,Standard_True就相当于true。注释掉好像也不影响
    myRectBand(NULL)//来自于一个qt类,它提供了一种方便的方法来在图形界面中显示橡皮筋效果。注释掉后也没有啥影响
{
    // No Background
    setBackgroundRole(QPalette::NoRole);//setBackgroundRole是Qt中的一个函数,其作用是设置qbrush部件的背景颜色。注释掉好像也不影响

    // set focus policy to threat QContextMenuEvent from keyboard  
    setFocusPolicy(Qt::StrongFocus);//setFocusPolicy函数在Qt中用于设置部件获得焦点的方式。部件获得焦点的作用主要是接收用户的键盘输入。
    //当一个部件获得焦点时,它会成为键盘输入的主要接收者。例如,如果一个文本框获得焦点,用户就可以在其中输入文本。类似地,如果一个按钮获得焦点,用户可以通过按下空格键或回车键来触发该按钮的操作,这与使用鼠标点击该按钮是相同的效果。
    //    在图形用户界面中,通过键盘操作可以大大提高用户的效率。因此,合理地设置和管理部件的焦点是非常重要的。注释掉后也不影响。
    //Qt中有以下几种获得焦点的方式:
    //    Qt::TabFocus:通过Tab键获得焦点。
    //    Qt::ClickFocus:通过被单击获得焦点。
    //    Qt::StrongFocus:可通过以上两种方式获得焦点。
    //    Qt::NoFocus:不能通过以上两种方式获得焦点。
    setAttribute(Qt::WA_PaintOnScreen);
    setAttribute(Qt::WA_NoSystemBackground);
    //在Qt中,setAttribute函数用于设置窗口部件的属性。Qt::WA_PaintOnScreen和Qt::WA_NoSystemBackground是Qt中预定义的窗口部件属性。

  /*  setAttribute(Qt::WA_PaintOnScreen); 这个属性的作用是关闭窗口部件的双缓冲绘图。通常情况下,Qt的所有窗口部件默认都使用双缓冲进行绘图,这样可以减轻绘制的闪烁感。但在某些情况下,用户可能需要关闭双缓冲,自己管理绘图。关闭双缓冲后,所有的绘图操作将直接在屏幕上进行。

        setAttribute(Qt::WA_NoSystemBackground); 这个属性的作用是禁止窗口部件使用系统背景。默认情况下,窗口部件会使用系统的背景颜色和样式。但如果你希望窗口部件有一个自定义的背景,或者根本不想让它有背景,就可以设置这个属性。

        请注意,这两个属性是互斥的,也就是说,如果一个窗口部件同时设置了这两个属性,那么Qt::WA_PaintOnScreen将覆盖Qt::WA_NoSystemBackground,窗口部件将不会有背景。*/

    // Enable the mouse tracking, by default the mouse tracking is disabled.
    setMouseTracking(true);//注释掉好像也不影响
    //在 PyQt5 中,setMouseTracking() 是 QWidget 类中的一个方法,用于设置一个组件是否跟踪鼠标移动事件。具体作用如下:

  /*  当一个组件启用了鼠标移动跟踪,它会在鼠标移动时接收 mouseMoveEvent() 事件,并能够响应这些事件。
        如果一个组件没有启用鼠标移动跟踪,它只有在鼠标按钮按下或释放时才会接收鼠标事件。
        默认情况下,QWidget 类中的组件都没有启用鼠标移动跟踪,这意味着它们只有在鼠标按钮按下或释放时才会接收鼠标事件。
        如果你想在鼠标移动时接收鼠标事件,可以使用 setMouseTracking(True) 方法来启用鼠标移动跟踪。然后,可以通过重写 mouseMoveEvent() 方法,在鼠标移动时输出鼠标的坐标信息。
        总的来说,setMouseTracking(true) 可以让程序在鼠标移动时实时接收并处理鼠标事件。*/

    init();
}

void OccView::init()//成员函数可以在类外面定义
{
    // Create Aspect_DisplayConnection
    Handle(Aspect_DisplayConnection) aDisplayConnection = new Aspect_DisplayConnection();
    //Aspect_DisplayConnection是Qt中的一个类,用于表示窗口部件和显示设备之间的连接。它的主要作用是在窗口部件和显示设备之间建立一个桥梁,使得窗口部件能够在正确的显示设备上绘制自己。

    //在Qt中,窗口部件并不知道自己将在哪个显示设备上绘制,也不知道显示设备的分辨率和其他属性。而Aspect_DisplayConnection类则封装了这些信息,使得窗口部件可以通过它与显示设备进行交互。

    //    Aspect_DisplayConnection类还提供了一些方法,用于获取显示设备的属性,如分辨率、色彩深度等。此外,它还可以处理窗口部件和显示设备之间的缩放和旋转等操作,以保证窗口部件在不同的显示设备上都能够正确地显示。

    //    总的来说,Aspect_DisplayConnection类在Qt的窗口系统中扮演着一个非常重要的角色,它使得窗口部件能够在不同的显示设备上正确地绘制自己,并且处理各种显示设备的属性。


    // Get graphic driver if it exists, otherwise initialise it
    if (GetGraphicDriver().IsNull())
    {
        GetGraphicDriver() = new OpenGl_GraphicDriver(aDisplayConnection);//OpenGl_GraphicDriver是一个图形驱动程序,用于在计算机上渲染和操作三维图形。
    }

    // Get window handle. This returns something suitable for all platforms.
    WId window_handle = (WId)winId();//总的来说,这行代码的目的是获取一个 Qt 窗口部件的本地窗口句柄,并将其存储在一个变量中以备后用。后面的代码根据不同的平台(Windows、macOS、其他)使用这个句柄来创建相应的窗口对象。

    // Create appropriate window for platform
    #ifdef WNT 根据不同的平台创建不同的窗口对象,这里使用了条件编译 
    Handle(WNT_Window) wind = new WNT_Window((Aspect_Handle)window_handle);
    #elif defined(__APPLE__) && !defined(MACOSX_USE_GLX)
    Handle(Cocoa_Window) wind = new Cocoa_Window((NSView*)window_handle);
    #else
    Handle(Xw_Window) wind = new Xw_Window(aDisplayConnection, (Window)window_handle);
    #endif

    // Create V3dViewer and V3d_View
    myViewer = new V3d_Viewer(GetGraphicDriver());//注释会报错,但不是语法错误

    myView = myViewer->CreateView();//CreateView() 方法在 OpenCASCADE Technology 中用于创建一个新的三维视图对象,以便在应用程序中显示和操作三维模型。
    //使用 myViewer 对象的 CreateView() 方法创建一个 V3d_View 对象,并将其赋值给 myView 变量 
    myView->SetWindow(wind);//SetWindow() 方法通常用于激活视图类中与屏幕建立映射的窗口。这个方法是在 V3d_View 类中定义的,该类用于管理和渲染三维场景。
    if (!wind->IsMapped()) wind->Map();//IsMapped()是Qt库中的一个函数,主要用于判断窗口部件(QWidget)是否已经被映射到屏幕上。如果没有映射,这里会让你再映射,所以按道理来说,把它注释掉也可以运行

    // Create AISInteractiveContext
    myContext = new AIS_InteractiveContext(myViewer);
//AIS_InteractiveContext是OpenCASCADECommunity(OCC)中的一种交互式场景,用于管理和显示3D场景中的对象。在AIS_InteractiveContext中,shiftselect是一种特殊的多选模式,它允许用户选择多个实体。当用户按住Shift键并单击多个实体时,AIS_InteractiveContext会将这些实体添加到当前选择集中,而不是替换当前选择集中的实体。这意味着,如果需要选择多个实体来执行操作(例如剪切、移动或旋转),则可以使用shiftselect。
    //此外,AIS_InteractiveContext还有一个函数DisplayNoSelection,其主要作用是在绘图上下文中显示一个不可选择的交互对象。
    
    // Set up lights etc
    myViewer->SetDefaultLights();
    myViewer->SetLightOn();

    myView->SetBackgroundColor(Quantity_NOC_BLACK);//绘图界面的背景颜色
    myView->MustBeResized();//MustBeResized()是OpenCASCADE Technology(OCCT)中的一个方法,通常用于判断3D视图是否需要重新调整大小。这个方法是在V3d_View类中定义的,该类用于管理和渲染三维场景。
    myView->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_ZBUFFER);//坐标系的显示

    myContext->SetDisplayMode(AIS_Shaded, Standard_True);
}

const Handle(AIS_InteractiveContext)& OccView::getContext() const
{
    return myContext;
}

/*!
Get paint engine for the OpenGL viewer. [ virtual public ]
*/
QPaintEngine* OccView::paintEngine() const
{
    return 0;
}

void OccView::paintEvent(QPaintEvent* /*theEvent*/)
{
    myView->Redraw();// 调用 myView 的 Redraw 方法,重绘视图内容
}

void OccView::resizeEvent(QResizeEvent* /*theEvent*/)// 重写 QWidget 类的 resizeEvent 函数,当窗口大小被改变时,该函数会被调用。
{
    if (!myView.IsNull())
    {
        myView->MustBeResized();
    }
}
// 函数 fitAll,将视图中的所有内容完全适应窗口,并重绘视图 
void OccView::fitAll(void)//注释掉后,没法直接fitall了。对应lzzcad里的槽函数
{
    myView->FitAll();
    myView->ZFitAll();
    myView->Redraw();
}

void OccView::reset(void)//注释掉后,没法直接reset了。对应lzzcad里的槽函数
{
    myView->Reset();
}

void OccView::pan(void)//注释掉后,没法直接pan了。对应lzzcad里的槽函数
{
    myCurrentMode = CurAction3d_DynamicPanning;
}

void OccView::zoom(void)//注释掉后,没法直接zoom了。对应lzzcad里的槽函数
{
    myCurrentMode = CurAction3d_DynamicZooming;
}

void OccView::rotate(void)//注释掉后,没法直接rotate了。对应lzzcad里的槽函数
{
    myCurrentMode = CurAction3d_DynamicRotation;
}

void OccView::mousePressEvent(QMouseEvent* theEvent)//按压鼠标的判定
{
    if (theEvent->button() == Qt::LeftButton)// 检查点击的鼠标按钮是否为左键 
    {
        onLButtonDown((theEvent->buttons() | theEvent->modifiers()), theEvent->pos());//buttons()这个函数似乎是为了提供一个方法来检索鼠标按钮的当前状态。modifiers()这个函数似乎是为了提供一个方法来检索键盘修饰符的当前状态
    }//pos()这个函数似乎是为了提供一个方法来检索某个图形对象(如线段或矩形)的起始点或位置
    else if (theEvent->button() == Qt::MidButton)// 检查点击的鼠标按钮是否为中键 
    {
        onMButtonDown((theEvent->buttons() | theEvent->modifiers()), theEvent->pos());
    }
    else if (theEvent->button() == Qt::RightButton)// 检查点击的鼠标按钮是否为右键 
    {
        onRButtonDown((theEvent->buttons() | theEvent->modifiers()), theEvent->pos());
    }
}

void OccView::mouseReleaseEvent(QMouseEvent* theEvent)//松开鼠标的判定
{
    if (theEvent->button() == Qt::LeftButton)
    {
        onLButtonUp(theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
    }
    else if (theEvent->button() == Qt::MidButton)
    {
        onMButtonUp(theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
    }
    else if (theEvent->button() == Qt::RightButton)
    {
        onRButtonUp(theEvent->buttons() | theEvent->modifiers(), theEvent->pos());
    }
}

void OccView::mouseMoveEvent(QMouseEvent* theEvent)//鼠标移动。这段代码的作用是在鼠标移动时调用自定义的 onMouseMove 函数,并将鼠标按钮状态和位置作为参数传递,以便执行特定的操作或响应。
{
    onMouseMove(theEvent->buttons(), theEvent->pos());
}

void OccView::wheelEvent(QWheelEvent* theEvent)//这个函数似乎是为了处理鼠标滚轮事件。当用户在OccView对象上滚动鼠标滚轮时,它会调用onMouseWheel函数,并传递鼠标按钮状态、滚动量和鼠标位置作为参数。
{
    onMouseWheel(theEvent->buttons(), theEvent->delta(), theEvent->pos());
}


//下面开始是具体函数的方法
void OccView::onLButtonDown(const int /*theFlags*/, const QPoint thePoint)//这段代码是 Qt 框架中的一个鼠标左键按下事件处理函数。注释掉好像也不影响,因为这里没什么左键操作的东西
{//注释掉还是有影响的,在你选中东西后鼠标离开,标记就消失了
    // Save the current mouse coordinate in min.
    myXmin = thePoint.x();
    myYmin = thePoint.y();
    myXmax = thePoint.x();
    myYmax = thePoint.y();

}

void OccView::onMButtonDown(const int /*theFlags*/, const QPoint thePoint)//这段代码是 Qt 框架中的一个鼠标中键按下事件处理函数。注释掉会影响,每次旋转的时候位置会改变
{
    // Save the current mouse coordinate in min.
    myXmin = thePoint.x();
    myYmin = thePoint.y();
    myXmax = thePoint.x();
    myYmax = thePoint.y();

    if (myCurrentMode == CurAction3d_DynamicRotation)// 检查当前模式是否为动态旋转模式 
    {
        myView->StartRotation(thePoint.x(), thePoint.y()); // 如果是,则开始旋转操作,传入当前鼠标的 x 和 y 坐标 
    }
}

void OccView::onRButtonDown(const int /*theFlags*/, const QPoint /*thePoint*/)//这段代码是 Qt 框架中的一个鼠标右键按下事件处理函数,感觉没什么用,也可以加上跟左键一样的东西
{
 //这意味着,虽然函数可以接受这些参数,但在函数体内无法直接使用它们。这可能是为了避免编译错误或警告,或者是因为这个函数尚未实现或暂时不需要使用这些参数。
}

void OccView::onMouseWheel(const int /*theFlags*/, const int theDelta, const QPoint thePoint)//一个鼠标滚轮事件处理函数,注释后没法用滚轮放大缩小了
{//theDelta表示滚轮滚动的数量和方向
    Standard_Integer aFactor = 16;//Standard_Integer相当于int

    Standard_Integer aX = thePoint.x();
    Standard_Integer aY = thePoint.y();

    if (theDelta > 0)
    {
        aX += aFactor;
        aY += aFactor;
    }
    else
    {
        aX -= aFactor;
        aY -= aFactor;
    }

    myView->Zoom(thePoint.x(), thePoint.y(), aX, aY); // 调用myView对象的Zoom方法,对指定位置进行缩放操作。方法四个参数分别为:原始鼠标点击位置的x和y坐标,以及经过滚轮滚动操作后的鼠标点击位置的x和y坐标 
}

void OccView::addItemInPopup(QMenu* /*theMenu*/)//这段代码是 Qt 框架中的一个函数,用于向弹出菜单(上下文菜单)中添加项。
{
}

void OccView::popup(const int /*x*/, const int /*y*/)//定义一个名为OccView的类中的弹出菜单处理函数
{
}

void OccView::onLButtonUp(const int theFlags, const QPoint thePoint)//是一个处理鼠标左键释放事件的函数
{
    // Hide the QRubberBand
    if (myRectBand)
    {
        myRectBand->hide();
    }

    // Ctrl for multi selection.
    if (thePoint.x() == myXmin && thePoint.y() == myYmin)
    {
        if (theFlags & Qt::ControlModifier)
        {
            multiInputEvent(thePoint.x(), thePoint.y());//按了crtl就可以多选,否则就是单选,注释掉就永远是单选了
        }
        else
        {
            inputEvent(thePoint.x(), thePoint.y());
        }
    }

}

void OccView::onMButtonUp(const int /*theFlags*/, const QPoint thePoint)//是一个处理鼠标中键释放事件的函数
{
    if (thePoint.x() == myXmin && thePoint.y() == myYmin)
    {
        panByMiddleButton(thePoint);
    }
}

void OccView::onRButtonUp(const int /*theFlags*/, const QPoint thePoint)//是一个处理鼠标右键释放事件的函数
{
    popup(thePoint.x(), thePoint.y());
}

void OccView::onMouseMove(const int theFlags, const QPoint thePoint)//是一个处理鼠标移动事件的函数
{
    // Draw the rubber band.
    if (theFlags & Qt::LeftButton)//在函数体内,theFlags参数被用来检查鼠标按键的状态,以便执行相应的操作。
    {
        drawRubberBand(myXmin, myYmin, thePoint.x(), thePoint.y());

        dragEvent(thePoint.x(), thePoint.y());
    }

    // Ctrl for multi selection.
    if (theFlags & Qt::ControlModifier)
    {
        multiMoveEvent(thePoint.x(), thePoint.y());
    }
    else
    {
        moveEvent(thePoint.x(), thePoint.y());
    }

    // Middle button.
    if (theFlags & Qt::MidButton)
    {
        switch (myCurrentMode)
        {
        case CurAction3d_DynamicRotation:
            myView->Rotation(thePoint.x(), thePoint.y());
            break;

        case CurAction3d_DynamicZooming:
            myView->Zoom(myXmin, myYmin, thePoint.x(), thePoint.y());
            break;

        case CurAction3d_DynamicPanning:
            myView->Pan(thePoint.x() - myXmax, myYmax - thePoint.y());
            myXmax = thePoint.x();
            myYmax = thePoint.y();
            break;

        default:
            break;
        }
    }

}

void OccView::dragEvent(const int x, const int y)//一个处理拖动事件的函数
{
    myContext->Select(myXmin, myYmin, x, y, myView, Standard_True);

    emit selectionChanged();//selectionChanged函数的作用是在选择发生改变时激活OccView对象的指定信号。这通常用于触发一些响应选择改变的操作或更新界面状态。
}

void OccView::multiDragEvent(const int x, const int y)//一个处理多重拖动事件的函数
{
    myContext->ShiftSelect(myXmin, myYmin, x, y, myView, Standard_True);

    emit selectionChanged();

}

void OccView::inputEvent(const int x, const int y)//是一个处理输入事件的函数,注释掉也不影响
{
    Q_UNUSED(x);
    Q_UNUSED(y);

    myContext->Select(Standard_True);

    emit selectionChanged();
}

void OccView::multiInputEvent(const int x, const int y)//是一个处理多重输入事件的函数,注释掉也不影响
{
    Q_UNUSED(x);
    Q_UNUSED(y);

    myContext->ShiftSelect(Standard_True);

    emit selectionChanged();
}

void OccView::moveEvent(const int x, const int y)//是一个处理移动事件的函数
{
    myContext->MoveTo(x, y, myView, Standard_True);
}

void OccView::multiMoveEvent(const int x, const int y)//是一个处理多重移动事件的函数
{
    myContext->MoveTo(x, y, myView, Standard_True);
}

void OccView::drawRubberBand(const int minX, const int minY, const int maxX, const int maxY)//是一个绘制橡皮筋线的函数,注释掉也不影响
{
    QRect aRect;

    // Set the rectangle correctly.
    (minX < maxX) ? (aRect.setX(minX)) : (aRect.setX(maxX));
    (minY < maxY) ? (aRect.setY(minY)) : (aRect.setY(maxY));

    aRect.setWidth(abs(maxX - minX));
    aRect.setHeight(abs(maxY - minY));

    if (!myRectBand)
    {
        myRectBand = new QRubberBand(QRubberBand::Rectangle, this);

        // setStyle is important, set to windows style will just draw
        // rectangle frame, otherwise will draw a solid rectangle.
        myRectBand->setStyle(QStyleFactory::create("windows"));
    }

    myRectBand->setGeometry(aRect);
    myRectBand->show();
}

void OccView::panByMiddleButton(const QPoint& thePoint)//是一个处理鼠标中键按下事件的函数,用于平移视图。注释掉好像也不影响
{
    Standard_Integer aCenterX = 0;
    Standard_Integer aCenterY = 0;

    QSize aSize = size();

    aCenterX = aSize.width() / 2;
    aCenterY = aSize.height() / 2;

    myView->Pan(aCenterX - thePoint.x(), thePoint.y() - aCenterY);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值