Update of QT samples for problems: 1. Mouse selection issue is repeatable 2. Display...
[occt.git] / samples / qt / voxeldemo / src / Viewer.cpp
1 #include "Viewer.h"
2 #include "Timer.h"
3
4 #include <QApplication.h>
5 #include <QCursor.h>
6 #include <QMessagebox.h>
7
8 #include <QMouseEvent>
9
10 #include <WNT_Window.hxx>
11 #include <Graphic3d_WNTGraphicDevice.hxx>
12
13 #include <Voxel_Prs.hxx>
14 #include <AIS_ListOfInteractive.hxx>
15 #include <AIS_ListIteratorOfListOfInteractive.hxx>
16
17 static Handle(Graphic3d_WNTGraphicDevice) device;
18
19 Viewer::Viewer(QWidget* parent):QWidget(parent)
20 {
21     if(device.IsNull())
22         device = new Graphic3d_WNTGraphicDevice();
23     
24                 Handle(V3d_Viewer) aViewer = new V3d_Viewer(device, TCollection_ExtendedString("Visu3D").ToExtString(), "",
25                                                 1000, V3d_XposYnegZpos,
26                                                 Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT,
27                                                 true, true, V3d_TEX_NONE);
28     aViewer->Init();
29
30         aViewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
31
32     myView = aViewer->CreateView();
33     myIC = new AIS_InteractiveContext(aViewer);
34     myIC->SetDeviationCoefficient(1.e-3);
35
36     int       windowHandle = (int) winId();
37     short     hi, lo;
38
39     lo = (short) windowHandle;
40     hi = (short) (windowHandle >> 16);
41     Handle(WNT_Window) hWnd =
42         new WNT_Window(Handle(Graphic3d_WNTGraphicDevice)::DownCast(aViewer->Device()), (int) hi, (int) lo);
43
44     myView->SetWindow(hWnd);
45     if(!hWnd->IsMapped())
46         hWnd->Map();
47
48     myView->MustBeResized();
49     myView->SetSurfaceDetail(V3d_TEX_NONE);
50     myView->SetTransparency(Standard_True);
51     myView->SetSize(10000.0);
52     myView->SetZSize(10000.0);
53     myView->SetViewMappingDefault();
54
55     myZoom = false;
56     myPan = false;
57     myRotate = false;
58     setMouseTracking(true);
59
60     setMinimumSize(400, 200);
61     
62     myView->ZBufferTriedronSetup();
63     myView->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_BLACK, 0.1, V3d_ZBUFFER);
64
65     mySelector.Init(myView);
66
67         setBackgroundRole( QPalette::NoRole );//NoBackground );
68         // set focus policy to threat QContextMenuEvent from keyboard  
69         setFocusPolicy( Qt::StrongFocus );
70         setAttribute( Qt::WA_PaintOnScreen );
71         setAttribute( Qt::WA_NoSystemBackground );
72 }
73
74 Viewer::~Viewer()
75 {
76
77 }
78
79 void Viewer::paintEvent(QPaintEvent * pEvent)
80 {
81     if (!myView.IsNull())
82         myView->Redraw();
83 }
84
85
86 /*!
87   Get paint engine for the OpenGL viewer. [ virtual public ]
88 */
89 QPaintEngine* Viewer::paintEngine() const
90 {
91   return 0;
92 }
93
94 void Viewer::resizeEvent(QResizeEvent * e)
95 {
96     if (!myView.IsNull())
97     {
98         myView->MustBeResized();
99     }
100 }
101
102 void Viewer::mousePressEvent(QMouseEvent * mpEvent)
103 {
104     // Memorize start point
105     myStartPnt.setX(mpEvent->x());
106     myStartPnt.setY(mpEvent->y());
107     
108     // Inform IC that the mouse cursor is at the point
109     myIC->MoveTo(myStartPnt.x(), myStartPnt.y(), myView);
110
111     // In case of rotation, define the start rotation point
112     if ((mpEvent->modifiers() & Qt::ControlModifier) && (mpEvent->buttons() & Qt::RightButton))
113     {
114         myView->StartRotation(myStartPnt.x(), myStartPnt.y());
115     }
116
117     // Start degenerate mode
118     setDegenerateMode(true);
119
120     emit mousePressed(mpEvent->modifiers(), mpEvent->x(), mpEvent->y());
121 }
122
123 void Viewer::mouseMoveEvent(QMouseEvent * mmEvent)
124 {
125     QPoint currentPnt(mmEvent->x(), mmEvent->y());
126
127     if (mmEvent->modifiers() & Qt::ControlModifier)
128     {
129         if (mmEvent->buttons() & Qt::LeftButton)
130         {
131             myView->Zoom(myStartPnt.x(), myStartPnt.y(), currentPnt.x(), currentPnt.y());
132             myStartPnt = currentPnt;
133         }
134         else if (mmEvent->buttons() & Qt::MidButton)
135         {
136             myView->Pan(currentPnt.x() - myStartPnt.x(), myStartPnt.y() - currentPnt.y());
137             myStartPnt = currentPnt;
138         }
139         else if (mmEvent->buttons() & Qt::RightButton)
140         {
141             myView->Rotation(currentPnt.x(), currentPnt.y());
142         }
143     }
144     else
145     {
146         myIC->MoveTo(currentPnt.x(), currentPnt.y(), myView);
147     }
148
149     emit mouseMoved(mmEvent->modifiers(), currentPnt.x(), currentPnt.y());
150 }
151
152 void Viewer::mouseReleaseEvent(QMouseEvent * mrEvent)
153 {
154     if(mrEvent->button() == Qt::LeftButton)
155     {
156         if(!myZoom && !myPan && !myRotate)
157         {
158             if(mrEvent->modifiers() & Qt::ShiftModifier)
159                 myIC->ShiftSelect();
160             else
161                 myIC->Select();
162
163             // Select a voxel
164             int ix = -1, iy = -1, iz = -1;
165             bool detected = mySelector.Detect(mrEvent->x(), mrEvent->y(), ix, iy, iz);
166             if (detected)
167             {
168                 cout<<"("<<ix<<", "<<iy<<", "<<iz<<")"<<endl;
169             }
170             if (!myPrs.IsNull())
171                 myPrs->Highlight(ix, iy, iz);
172         }
173     }
174     else if(mrEvent->button() == Qt::RightButton)
175     {
176         // Popup menu:
177
178     
179         }
180
181     // Finish degenerate mode
182     setDegenerateMode(false);
183     
184     emit mouseReleased(mrEvent->modifiers(), mrEvent->x(), mrEvent->y());
185 }
186
187 void Viewer::mouseDoubleClickEvent(QMouseEvent * mdcEvent)
188 {
189     emit mouseDoubleClick(mdcEvent->modifiers(), mdcEvent->x(), mdcEvent->y());
190 }
191
192 void Viewer::setDegenerateMode(const bool on)
193 {
194     AIS_ListOfInteractive displayed;
195     myIC->DisplayedObjects(displayed);
196     AIS_ListIteratorOfListOfInteractive itri(displayed);
197     for (; itri.More(); itri.Next())
198     {
199         if (itri.Value()->DynamicType() == STANDARD_TYPE(Voxel_Prs))
200         {
201             Handle(Voxel_Prs) prs = Handle(Voxel_Prs)::DownCast(itri.Value());
202             prs->SetDegenerateMode(on);
203             myView->Redraw();
204             break;
205         }
206     }
207 }