2011-02-09

3D view navigation: mouse wheel support and more

With recently released CAD Exchanger 2.1 Beta, which adds some GUI improvements, I thought to share some experience about that.
Default OCC viewer suggests some conventions based on using the Ctrl button and mouse buttons:
- Ctrl + MB1 (left button) – zoom;
- Ctrl + MB2 (middle button) – pan;
- Ctrl + MB3 (right button) – rotate.
This seems to be not only inconsistent with typical conventions in CAD systems but also challenging for user experience. For instance, MB3 is normally expected to open a context menu.
So following CAD Exchanger users’ feedback, I had to implement different navigation based on Solidworks and other conventions. They are based on using MB2:
- MB2 – rotate
- Shift + MB2 – zoom
- Ctrl + MB2 – pan.


In addition, support for mouse wheel (to zoom in/out), which is a commonly used convention, has been added. For Qt-based viewer it appeared to be quite easy:

void QOOcc_View3d::wheelEvent (QWheelEvent* theEvent)
{
if (theEvent->orientation() == Qt::Vertical) {
int numDegrees = theEvent->delta() / 8; //number of degrees the wheel rotated by
//let 100 degrees be approximately 2x zoom (see V3d_View::Zoom())
int numSteps = numDegrees;

myView->Zoom (0, 0, numSteps, 0);
theEvent->accept();
}
}

Apparently, QtOCC project by Peter Dolby already implemented that (though I did not notice). But Peter used V3d_View::SetScale(). Either should work anyway.

Perhaps, wheel support could be added into default OCC viewers and default OCC conventions could be revisited to better align with industrial ones.

3 comments:

  1. Hello Roman,

    To preventing a program crash, my proposal is to use
    something like:

    Standard_Integer minLevel=0, maxLevel=1700000000;
    if (e->orientation() == Qt::Vertical)
    {
    minLevel = myView->Scale();
    if (minLevel < maxLevel)
    {
    int numDegrees = e->delta() / 8;
    int numSteps = numDegrees;
    myView->Zoom(0, 0, numSteps, 0);
    }
    else
    {
    e->ignore();
    myView->FitAll();
    }
    }

    I have not checked CAD Exchanger 2.2, but version 2.1 crashes at this point.

    Best Regards,

    ReplyDelete
  2. Hi Goran,
    Sorry for a long response - it sank in email box too quickly.
    Thanks for the catch - indeed, the crash may happen on some large models when reaching a large scale coefficient. Instead of using some hard-coded values I've ended up with try/catch as follows:
    try {
    //exception is thrown from Visual3d_ViewMapping::SetWindowLimit() when reaching too large scale factor
    myView->Zoom (0, 0, numSteps, 0);
    } catch (const Visual3d_ViewMappingDefinitionError&) {
    //ignore
    }
    Hope this helps.
    Roman

    ReplyDelete
  3. Hello, I am new in OPenCascade.

    I am not able to display a 3d solid ( say a cube, for example) , showing the edges in other colours.

    In other word, I would like display a solid like yours http://2.bp.blogspot.com/-O4r3nZ2V_dk/TdF201bDAOI/AAAAAAAAAOI/_k3MJ1UxXJM/s1600/logo.png

    ( I am not referring to logo display, but I referring to the fact that the face of the solid are gray and the edge dark gray( black) colour.

    Can I get a fragment of code in C++.

    Many thanks in advance.

    Mauro

    ReplyDelete