QVTKWidget.cxx 20.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    QVTKWidget.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
Clinton Stimpson's avatar
 
Clinton Stimpson committed
15
16
17
18
19
20
21
22
23
24
25
/*
 * Copyright 2004 Sandia Corporation.
 * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
 * license for use of this work by or on behalf of the
 * U.S. Government. Redistribution and use in source and binary forms, with
 * or without modification, are permitted provided that this Notice and any
 * statement of authorship are reproduced on all copies.
 */

/*========================================================================
 For general information about using VTK and Qt, see:
26
 http://www.vtk.org/Wiki/VTK/Examples/Cxx#Qt
Clinton Stimpson's avatar
 
Clinton Stimpson committed
27
28
=========================================================================*/

29
30
31
32
33
34
#ifdef _MSC_VER
// Disable warnings that Qt headers give.
#pragma warning(disable:4127)
#pragma warning(disable:4512)
#endif

Clinton Stimpson's avatar
 
Clinton Stimpson committed
35
36
#include "QVTKWidget.h"

37
38
#include "QVTKPaintEngine.h"
#include "QVTKInteractorAdapter.h"
39
#include "QVTKInteractor.h"
Clinton Stimpson's avatar
   
Clinton Stimpson committed
40

Clinton Stimpson's avatar
 
Clinton Stimpson committed
41
42
43
#include "qevent.h"
#include "qapplication.h"
#include "qpainter.h"
Clinton Stimpson's avatar
   
Clinton Stimpson committed
44
45
#include "qsignalmapper.h"
#include "qtimer.h"
46
#include "vtkRenderingOpenGLConfigure.h"
47
#if defined(Q_WS_X11)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
48
49
50
#include "qx11info_x11.h"
#endif

51
#if defined(Q_OS_WIN)
52
# include <windows.h>
53
# include <QSysInfo>
54
55
#endif

Clinton Stimpson's avatar
 
Clinton Stimpson committed
56
57
58
59
60
61
62
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkRenderWindow.h"
#include "vtkCommand.h"
#include "vtkOStrStreamWrapper.h"
#include "vtkObjectFactory.h"
#include "vtkCallbackCommand.h"
#include "vtkConfigure.h"
Clinton Stimpson's avatar
   
Clinton Stimpson committed
63
#include "vtkUnsignedCharArray.h"
64
65
#include "vtkImageData.h"
#include "vtkPointData.h"
66
67
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
Clinton Stimpson's avatar
 
Clinton Stimpson committed
68

69
70
71
72
#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
# include "vtkTDxUnixDevice.h"
#endif

Clinton Stimpson's avatar
 
Clinton Stimpson committed
73
/*! constructor */
74
QVTKWidget::QVTKWidget(QWidget* p, Qt::WindowFlags f)
75
76
  : QWidget(p, f | Qt::MSWindowsOwnDC), mRenWin(NULL),
    cachedImageCleanFlag(false),
77
78
    automaticImageCache(false), maxImageCacheRenderRate(1.0),
    renderEventCallbackObserverId(0)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
79
{
80
  this->UseTDx=false;
Clinton Stimpson's avatar
 
Clinton Stimpson committed
81
  // no background
Clinton Stimpson's avatar
   
Clinton Stimpson committed
82
83
  this->setAttribute(Qt::WA_NoBackground);
  // no double buffering
Clinton Stimpson's avatar
   
Clinton Stimpson committed
84
  this->setAttribute(Qt::WA_PaintOnScreen);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
85

86
  // default to strong focus
Clinton Stimpson's avatar
 
Clinton Stimpson committed
87
88
89
90
  this->setFocusPolicy(Qt::StrongFocus);

  // default to enable mouse events when a mouse button isn't down
  // so we can send enter/leave events to VTK
91
92
  this->setMouseTracking(true);

Clinton Stimpson's avatar
 
Clinton Stimpson committed
93
  // set expanding to take up space for better default layouts
94
  this->setSizePolicy(
95
96
    QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding )
    );
97

Clinton Stimpson's avatar
   
Clinton Stimpson committed
98
99
  mPaintEngine = new QVTKPaintEngine;

100
101
102
  this->mCachedImage = vtkImageData::New();
  this->mCachedImage->SetOrigin(0,0,0);
  this->mCachedImage->SetSpacing(1,1,1);
Clinton Stimpson's avatar
   
Clinton Stimpson committed
103

104
105
  mIrenAdapter = new QVTKInteractorAdapter(this);

Clinton Stimpson's avatar
 
Clinton Stimpson committed
106
107
108
109
110
111
112
113
}

/*! destructor */

QVTKWidget::~QVTKWidget()
{
  // get rid of the VTK window
  this->SetRenderWindow(NULL);
114

115
  this->mCachedImage->Delete();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
116

117
  delete mPaintEngine;
Clinton Stimpson's avatar
 
Clinton Stimpson committed
118
119
}

120
121
122
123
124
// ----------------------------------------------------------------------------
void QVTKWidget::SetUseTDx(bool useTDx)
{
  if(useTDx!=this->UseTDx)
    {
125
    this->UseTDx=useTDx;
126

127
128
129
    if(this->UseTDx)
      {
#if defined(VTK_USE_TDX) && defined(Q_WS_X11)
130
131
132
133
134
135
136
137
138
139
140
141
142
       QByteArray theSignal=
         QMetaObject::normalizedSignature("CreateDevice(vtkTDxDevice *)");
      if(QApplication::instance()->metaObject()->indexOfSignal(theSignal)!=-1)
        {
        QObject::connect(QApplication::instance(),
                         SIGNAL(CreateDevice(vtkTDxDevice *)),
                         this,
                         SLOT(setDevice(vtkTDxDevice *)));
        }
      else
        {
        vtkGenericWarningMacro("Missing signal CreateDevice on QApplication. 3DConnexion device will not work. Define it or derive your QApplication from QVTKApplication.");
        }
143
144
#endif
      }
145
146
147
148
149
150
151
152
153
    }
}

// ----------------------------------------------------------------------------
bool QVTKWidget::GetUseTDx() const
{
  return this->UseTDx;
}

Clinton Stimpson's avatar
 
Clinton Stimpson committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*! get the render window
 */
vtkRenderWindow* QVTKWidget::GetRenderWindow()
{
  if (!this->mRenWin)
    {
    // create a default vtk window
    vtkRenderWindow* win = vtkRenderWindow::New();
    this->SetRenderWindow(win);
    win->Delete();
    }

  return this->mRenWin;
}

/*! set the render window
170
171
  this will bind a VTK window with the Qt window
  it'll also replace an existing VTK window
Clinton Stimpson's avatar
 
Clinton Stimpson committed
172
*/
Clinton Stimpson's avatar
   
Clinton Stimpson committed
173
void QVTKWidget::SetRenderWindow(vtkRenderWindow* w)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
174
175
{
  // do nothing if we don't have to
Clinton Stimpson's avatar
   
Clinton Stimpson committed
176
  if(w == this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
177
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
178
    return;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
179
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
180
181
182

  // unregister previous window
  if(this->mRenWin)
183
    {
184
185
186
187
188
    if (this->renderEventCallbackObserverId)
      {
      this->mRenWin->RemoveObserver(this->renderEventCallbackObserverId);
      this->renderEventCallbackObserverId = 0;
      }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
189
    //clean up window as one could remap it
Clinton Stimpson's avatar
   
Clinton Stimpson committed
190
    if(this->mRenWin->GetMapped())
Clinton Stimpson's avatar
   
Clinton Stimpson committed
191
      {
Clinton Stimpson's avatar
   
Clinton Stimpson committed
192
      this->mRenWin->Finalize();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
193
      }
194
#ifdef Q_WS_X11
Clinton Stimpson's avatar
   
Clinton Stimpson committed
195
    this->mRenWin->SetDisplayId(NULL);
196
#endif
Clinton Stimpson's avatar
   
Clinton Stimpson committed
197
    this->mRenWin->SetWindowId(NULL);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
198
    this->mRenWin->UnRegister(NULL);
199
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
200
201

  // now set the window
Clinton Stimpson's avatar
   
Clinton Stimpson committed
202
  this->mRenWin = w;
Clinton Stimpson's avatar
 
Clinton Stimpson committed
203
204

  if(this->mRenWin)
205
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
206
207
    // register new window
    this->mRenWin->Register(NULL);
208

Clinton Stimpson's avatar
   
Clinton Stimpson committed
209
210
    // if it is mapped somewhere else, unmap it
    if(this->mRenWin->GetMapped())
Clinton Stimpson's avatar
   
Clinton Stimpson committed
211
      {
Clinton Stimpson's avatar
   
Clinton Stimpson committed
212
      this->mRenWin->Finalize();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
213
      }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
214
215
216
217
218
219
220
221

#ifdef Q_WS_X11
    // give the qt display id to the vtk window
    this->mRenWin->SetDisplayId(QX11Info::display());
#endif

    // special x11 setup
    x11_setup_window();
222

Clinton Stimpson's avatar
   
Clinton Stimpson committed
223
224
    // give the qt window id to the vtk window
    this->mRenWin->SetWindowId( reinterpret_cast<void*>(this->winId()));
225

Clinton Stimpson's avatar
 
Clinton Stimpson committed
226
227
228
    // tell the vtk window what the size of this window is
    this->mRenWin->vtkRenderWindow::SetSize(this->width(), this->height());
    this->mRenWin->vtkRenderWindow::SetPosition(this->x(), this->y());
229

Clinton Stimpson's avatar
 
Clinton Stimpson committed
230
    // have VTK start this window and create the necessary graphics resources
Clinton Stimpson's avatar
   
Clinton Stimpson committed
231
232
233
234
    if(isVisible())
      {
      this->mRenWin->Start();
      }
235

Clinton Stimpson's avatar
 
Clinton Stimpson committed
236
237
    // if an interactor wasn't provided, we'll make one by default
    if(!this->mRenWin->GetInteractor())
238
      {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
239
240
      // create a default interactor
      QVTKInteractor* iren = QVTKInteractor::New();
241
      iren->SetUseTDx(this->UseTDx);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
242
243
      this->mRenWin->SetInteractor(iren);
      iren->Initialize();
244

Clinton Stimpson's avatar
 
Clinton Stimpson committed
245
      // now set the default style
Clinton Stimpson's avatar
   
Clinton Stimpson committed
246
247
      vtkInteractorStyle* s = vtkInteractorStyleTrackballCamera::New();
      iren->SetInteractorStyle(s);
248

Clinton Stimpson's avatar
 
Clinton Stimpson committed
249
      iren->Delete();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
250
      s->Delete();
251
      }
252

Clinton Stimpson's avatar
 
Clinton Stimpson committed
253
254
    // tell the interactor the size of this window
    this->mRenWin->GetInteractor()->SetSize(this->width(), this->height());
255

Clinton Stimpson's avatar
 
Clinton Stimpson committed
256
257
258
    // Add an observer to monitor when the image changes.  Should work most
    // of the time.  The application will have to call
    // markCachedImageAsDirty for any other case.
259
260
261
    this->renderEventCallbackObserverId =
      this->mRenWin->AddObserver(vtkCommand::RenderEvent,
        this, &QVTKWidget::renderEventCallback);
262
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
263
264
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
265

Clinton Stimpson's avatar
 
Clinton Stimpson committed
266
267

/*! get the Qt/VTK interactor
268
 */
Clinton Stimpson's avatar
 
Clinton Stimpson committed
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
QVTKInteractor* QVTKWidget::GetInteractor()
{
  return QVTKInteractor
    ::SafeDownCast(this->GetRenderWindow()->GetInteractor());
}

void QVTKWidget::markCachedImageAsDirty()
{
  if (this->cachedImageCleanFlag)
    {
    this->cachedImageCleanFlag = false;
    emit cachedImageDirty();
    }
}

void QVTKWidget::saveImageToCache()
{
286
  if (this->cachedImageCleanFlag)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
287
288
289
    {
    return;
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
290

291
292
  int w = this->width();
  int h = this->height();
293
  this->mCachedImage->SetExtent(0, w-1, 0, h-1, 0, 0);
294
  this->mCachedImage->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
295
296
  vtkUnsignedCharArray* array = vtkUnsignedCharArray::SafeDownCast(
    this->mCachedImage->GetPointData()->GetScalars());
297
  // We use back-buffer if
298
  this->mRenWin->GetPixelData(0, 0, this->width()-1, this->height()-1,
299
    this->mRenWin->GetDoubleBuffer()? 0 /*back*/ : 1 /*front*/, array);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
300
301
302
303
304
305
306
  this->cachedImageCleanFlag = true;
  emit cachedImageClean();
}

void QVTKWidget::setAutomaticImageCacheEnabled(bool flag)
{
  this->automaticImageCache = flag;
307
  if (!flag)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
308
    {
309
    this->mCachedImage->Initialize();
310
311
    this->mCachedImage->SetOrigin(0,0,0);
    this->mCachedImage->SetSpacing(1,1,1);
312
    this->markCachedImageAsDirty();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
313
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
}
bool QVTKWidget::isAutomaticImageCacheEnabled() const
{
  return this->automaticImageCache;
}

void QVTKWidget::setMaxRenderRateForImageCache(double rate)
{
  this->maxImageCacheRenderRate = rate;
}
double QVTKWidget::maxRenderRateForImageCache() const
{
  return this->maxImageCacheRenderRate;
}

329
vtkImageData* QVTKWidget::cachedImage()
Clinton Stimpson's avatar
 
Clinton Stimpson committed
330
331
332
333
334
{
  // Make sure image is up to date.
  this->paintEvent(NULL);
  this->saveImageToCache();

Clinton Stimpson's avatar
   
Clinton Stimpson committed
335
  return this->mCachedImage;
Clinton Stimpson's avatar
 
Clinton Stimpson committed
336
337
338
}

/*! overloaded Qt's event handler to capture additional keys that Qt has
339
  default behavior for (for example the Tab and Shift-Tab key)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
340
341
342
*/
bool QVTKWidget::event(QEvent* e)
{
Clinton Stimpson's avatar
   
Clinton Stimpson committed
343
344
345
346
347
348
349
350
  if(e->type() == QEvent::ParentAboutToChange)
    {
    this->markCachedImageAsDirty();
    if (this->mRenWin)
      {
      // Finalize the window to remove graphics resources associated with
      // this window
      if(this->mRenWin->GetMapped())
351
        {
Clinton Stimpson's avatar
   
Clinton Stimpson committed
352
        this->mRenWin->Finalize();
353
        }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
354
355
356
357
      }
    }
  else if(e->type() == QEvent::ParentChange)
    {
Clinton Stimpson's avatar
   
Clinton Stimpson committed
358
359
360
361
362
    if(this->mRenWin)
      {
      x11_setup_window();
      // connect to new window
      this->mRenWin->SetWindowId( reinterpret_cast<void*>(this->winId()));
Clinton Stimpson's avatar
   
Clinton Stimpson committed
363

Clinton Stimpson's avatar
   
Clinton Stimpson committed
364
365
      // start up the window to create graphics resources for this window
      if(isVisible())
366
        {
Clinton Stimpson's avatar
   
Clinton Stimpson committed
367
        this->mRenWin->Start();
368
        }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
369
      }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
370
    }
371
372
373
374
375
376
377
378
379
380
381
382
383
  else if(e->type() == QEvent::TouchBegin ||
          e->type() == QEvent::TouchUpdate ||
          e->type() == QEvent::TouchEnd)
    {
    if(this->mRenWin)
      {
      mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
      if (e->isAccepted())
        {
        return true;
        }
      }
    }
384

Clinton Stimpson's avatar
   
Clinton Stimpson committed
385
  if(QObject::event(e))
Clinton Stimpson's avatar
   
Clinton Stimpson committed
386
    {
387
    return true;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
388
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
389

Clinton Stimpson's avatar
 
Clinton Stimpson committed
390
  if(e->type() == QEvent::KeyPress)
391
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
392
    QKeyEvent* ke = static_cast<QKeyEvent*>(e);
393
    this->keyPressEvent(ke);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
394
    return ke->isAccepted();
395
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
396
397
398
399
400
401
402

  return QWidget::event(e);
}


/*! handle resize event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
403
void QVTKWidget::resizeEvent(QResizeEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
404
{
Clinton Stimpson's avatar
   
Clinton Stimpson committed
405
  QWidget::resizeEvent(e);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
406
407

  if(!this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
408
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
409
    return;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
410
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
411

412
413
414
  // Don't set size on subclass of vtkRenderWindow or it triggers recursion.
  // Getting this event in the first place means the window was already
  // resized and we're updating the sizes in VTK.
Clinton Stimpson's avatar
 
Clinton Stimpson committed
415
  this->mRenWin->vtkRenderWindow::SetSize(this->width(), this->height());
416
417

  // and update the interactor
Clinton Stimpson's avatar
 
Clinton Stimpson committed
418
  if(this->mRenWin->GetInteractor())
Clinton Stimpson's avatar
   
Clinton Stimpson committed
419
    {
420
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
421
    }
422

Clinton Stimpson's avatar
 
Clinton Stimpson committed
423
424
425
  this->markCachedImageAsDirty();
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
426
void QVTKWidget::moveEvent(QMoveEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
427
{
Clinton Stimpson's avatar
   
Clinton Stimpson committed
428
  QWidget::moveEvent(e);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
429
430

  if(!this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
431
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
432
    return;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
433
    }
434

435
436
437
  // Don't set size on subclass of vtkRenderWindow or it triggers recursion.
  // Getting this event in the first place means the window was already
  // resized and we're updating the sizes in VTK.
Clinton Stimpson's avatar
 
Clinton Stimpson committed
438
439
440
441
442
443
444
445
446
  this->mRenWin->vtkRenderWindow::SetPosition(this->x(), this->y());
}

/*! handle paint event
 */
void QVTKWidget::paintEvent(QPaintEvent* )
{
  vtkRenderWindowInteractor* iren = NULL;
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
447
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
448
    iren = this->mRenWin->GetInteractor();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
449
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
450
451

  if(!iren || !iren->GetEnabled())
Clinton Stimpson's avatar
   
Clinton Stimpson committed
452
    {
Clinton Stimpson's avatar
 
Clinton Stimpson committed
453
    return;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
454
    }
455

456
  // if we have a saved image, use it
457
  if (this->paintCachedImage())
458
459
460
461
462
    {
    return;
    }

  iren->Render();
463

Clinton Stimpson's avatar
   
Clinton Stimpson committed
464
465
  // In Qt 4.1+ let's support redirected painting
  // if redirected, let's grab the image from VTK, and paint it to the device
Clinton Stimpson's avatar
   
Clinton Stimpson committed
466
467
  QPaintDevice* device = QPainter::redirected(this);
  if(device != NULL && device != this)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
468
469
470
    {
    int w = this->width();
    int h = this->height();
471
    QImage img(w, h, QImage::Format_RGB32);
Clinton Stimpson's avatar
   
Clinton Stimpson committed
472
473
474
475
476
    vtkUnsignedCharArray* pixels = vtkUnsignedCharArray::New();
    pixels->SetArray(img.bits(), w*h*4, 1);
    this->mRenWin->GetRGBACharPixelData(0, 0, w-1, h-1, 1, pixels);
    pixels->Delete();
    img = img.rgbSwapped();
Clinton Stimpson's avatar
   
Clinton Stimpson committed
477
    img = img.mirrored();
478

Clinton Stimpson's avatar
   
Clinton Stimpson committed
479
480
481
482
    QPainter painter(this);
    painter.drawImage(QPointF(0.0,0.0), img);
    return;
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
483
484
485
486
}

/*! handle mouse press event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
487
void QVTKWidget::mousePressEvent(QMouseEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
488
489
490
{

  // Emit a mouse press event for anyone who might be interested
Clinton Stimpson's avatar
   
Clinton Stimpson committed
491
  emit mouseEvent(e);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
492
493

  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
494
    {
495
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
496
    }
497

Clinton Stimpson's avatar
 
Clinton Stimpson committed
498
499
500
501
}

/*! handle mouse move event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
502
void QVTKWidget::mouseMoveEvent(QMouseEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
503
504
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
505
    {
506
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
507
508
509

    // Emit a mouse press event for anyone who might be interested
    emit mouseEvent(e);
Clinton Stimpson's avatar
   
Clinton Stimpson committed
510
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
511
512
513
514
515
}


/*! handle enter event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
516
void QVTKWidget::enterEvent(QEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
517
518
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
519
    {
520
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
521
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
522
523
524
525
}

/*! handle leave event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
526
void QVTKWidget::leaveEvent(QEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
527
528
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
529
    {
530
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
531
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
532
533
534
535
}

/*! handle mouse release event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
536
void QVTKWidget::mouseReleaseEvent(QMouseEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
537
538
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
539
    {
540
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
541
542
543

    // Emit a mouse press event for anyone who might be interested
    emit mouseEvent(e);
544
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
545
546
547
548
}

/*! handle key press event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
549
void QVTKWidget::keyPressEvent(QKeyEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
550
551
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
552
    {
553
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
554
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
555
556
557
558
}

/*! handle key release event
 */
Clinton Stimpson's avatar
   
Clinton Stimpson committed
559
void QVTKWidget::keyReleaseEvent(QKeyEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
560
561
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
562
    {
563
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
564
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
565
566
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
567
void QVTKWidget::wheelEvent(QWheelEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
568
569
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
570
    {
571
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
572
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
573
574
}

575
void QVTKWidget::focusInEvent(QFocusEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
576
{
577
  // These prevent updates when the window
578
  // gains or loses focus.  By default, Qt
579
  // does an update because the color group's
580
581
  // active status changes.  We don't even use
  // color groups so we do nothing here.
582

583
584
  // also pass to interactor
  mIrenAdapter->ProcessEvent(e, this->GetInteractor());
Clinton Stimpson's avatar
 
Clinton Stimpson committed
585
586
}

587
void QVTKWidget::focusOutEvent(QFocusEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
588
{
589
  // These prevent updates when the window
590
  // gains or loses focus.  By default, Qt
591
  // does an update because the color group's
592
593
  // active status changes.  We don't even use
  // color groups so we do nothing here.
594

595
596
  // also pass to interactor
  mIrenAdapter->ProcessEvent(e, this->GetInteractor());
Clinton Stimpson's avatar
 
Clinton Stimpson committed
597
598
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
599

Clinton Stimpson's avatar
   
Clinton Stimpson committed
600
void QVTKWidget::contextMenuEvent(QContextMenuEvent* e)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
601
602
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
603
    {
604
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
605
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
606
607
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
608
void QVTKWidget::dragEnterEvent(QDragEnterEvent* e)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
609
610
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
611
    {
612
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
613
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
614
615
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
616
void QVTKWidget::dragMoveEvent(QDragMoveEvent* e)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
617
618
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
619
    {
620
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
621
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
622
623
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
624
void QVTKWidget::dragLeaveEvent(QDragLeaveEvent* e)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
625
626
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
627
    {
628
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
629
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
630
631
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
632
void QVTKWidget::dropEvent(QDropEvent* e)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
633
634
{
  if(this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
635
    {
636
    mIrenAdapter->ProcessEvent(e, this->mRenWin->GetInteractor());
Clinton Stimpson's avatar
   
Clinton Stimpson committed
637
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
638
639
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
640
void QVTKWidget::showEvent(QShowEvent* e)
Clinton Stimpson's avatar
 
Clinton Stimpson committed
641
642
643
{
  this->markCachedImageAsDirty();

Clinton Stimpson's avatar
   
Clinton Stimpson committed
644
  QWidget::showEvent(e);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
645
646
}

Clinton Stimpson's avatar
   
Clinton Stimpson committed
647
648
QPaintEngine* QVTKWidget::paintEngine() const
{
Clinton Stimpson's avatar
   
Clinton Stimpson committed
649
  return mPaintEngine;
Clinton Stimpson's avatar
   
Clinton Stimpson committed
650
651
}

652
653
654
655
656
657
658
659
660
661

// X11 stuff near the bottom of the file
// to prevent namespace collisions with Qt headers

#if defined Q_WS_X11
#if defined(VTK_USE_OPENGL_LIBRARY)
#include "vtkXOpenGLRenderWindow.h"
#endif
#endif

662
#ifdef VTK_USE_TDX
663
664
665
666
// Description:
// Receive notification of the creation of the TDxDevice
void QVTKWidget::setDevice(vtkTDxDevice *device)
{
667
#ifdef Q_WS_X11
668
669
670
671
672
673
674
675
  if(this->GetInteractor()->GetDevice()!=device)
    {
    this->GetInteractor()->SetDevice(device);
    }
#else
  (void)device; // to avoid warnings.
#endif
}
676
#endif
677
678

void QVTKWidget::x11_setup_window()
Clinton Stimpson's avatar
   
Clinton Stimpson committed
679
{
680
681
682
683
684
685
686
687
688
689
690
691
692
#if defined Q_WS_X11

  // this whole function is to allow this window to have a
  // different colormap and visual than the rest of the Qt application
  // this is very important if Qt's default visual and colormap is
  // not enough to get a decent graphics window


  // save widget states
  bool tracking = this->hasMouseTracking();
  Qt::FocusPolicy focus_policy = focusPolicy();
  bool visible = isVisible();
  if(visible)
693
    {
694
    hide();
695
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
696

Clinton Stimpson's avatar
 
Clinton Stimpson committed
697

698
699
700
701
  // get visual and colormap from VTK
  XVisualInfo* vi = 0;
  Colormap cmap = 0;
  Display* display = reinterpret_cast<Display*>(mRenWin->GetGenericDisplayId());
702

703
704
705
706
707
708
709
710
  // check ogl and mesa and get information we need to create a decent window
#if defined(VTK_USE_OPENGL_LIBRARY)
  vtkXOpenGLRenderWindow* ogl_win = vtkXOpenGLRenderWindow::SafeDownCast(mRenWin);
  if(ogl_win)
    {
    vi = ogl_win->GetDesiredVisualInfo();
    cmap = ogl_win->GetDesiredColormap();
    }
711
#endif
712
713
714
715

  // can't get visual, oh well.
  // continue with Qt's default visual as it usually works
  if(!vi)
716
    {
717
    if(visible)
718
      {
719
      show();
720
      }
721
    return;
722
    }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
723

724
725
726
727
728
  // create the X window based on information VTK gave us
  XSetWindowAttributes attrib;
  attrib.colormap = cmap;
  attrib.border_pixel = 0;
  attrib.background_pixel = 0;
Clinton Stimpson's avatar
 
Clinton Stimpson committed
729

730
731
732
733
734
  Window p = RootWindow(display, DefaultScreen(display));
  if(parentWidget())
    {
    p = parentWidget()->winId();
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
735

736
737
  XWindowAttributes a;
  XGetWindowAttributes(display, this->winId(), &a);
Clinton Stimpson's avatar
 
Clinton Stimpson committed
738

739
740
741
742
743
744
745
746
747
  Window win = XCreateWindow(display, p, a.x, a.y, a.width, a.height,
                             0, vi->depth, InputOutput, vi->visual,
                             CWBackPixel|CWBorderPixel|CWColormap, &attrib);

  // backup colormap stuff
  Window *cmw;
  Window *cmwret;
  int count;
  if ( XGetWMColormapWindows(display, topLevelWidget()->winId(), &cmwret, &count) )
748
    {
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
    cmw = new Window[count+1];
    memcpy( (char *)cmw, (char *)cmwret, sizeof(Window)*count );
    XFree( (char *)cmwret );
    int i;
    for ( i=0; i<count; i++ )
      {
      if ( cmw[i] == winId() )
        {
        cmw[i] = win;
        break;
        }
      }
    if ( i >= count )
      {
      cmw[count++] = win;
      }
765
    }
766
  else
767
    {
768
769
770
    count = 1;
    cmw = new Window[count];
    cmw[0] = win;
771
    }
772

773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790

  // tell Qt to initialize anything it needs to for this window
  create(win);

  // restore colormaps
  XSetWMColormapWindows( display, topLevelWidget()->winId(), cmw, count );

  delete [] cmw;
  XFree(vi);

  XFlush(display);

  // restore widget states
  this->setMouseTracking(tracking);
  this->setAttribute(Qt::WA_NoBackground);
  this->setAttribute(Qt::WA_PaintOnScreen);
  this->setFocusPolicy(focus_policy);
  if(visible)
791
    {
792
    show();
793
    }
794

795
#endif
796
797
}

798
#if defined(Q_OS_WIN)
799
800
bool QVTKWidget::winEvent(MSG* msg, long*)
{
801
802
803
804
805
  // Starting with Windows Vista, Microsoft introduced WDDM.
  // We need to call InvalidateRect() to work with WDDM correctly,
  // especially when AERO is off.
  if(msg->message == WM_PAINT &&
    QSysInfo::windowsVersion() >= QSysInfo::WV_VISTA)
806
    {
807
    InvalidateRect((HWND)this->winId(), NULL, FALSE);
808
809
810
    }
  return false;
}
811
812
813
814
815
816
817
818
819
820
821

#if QT_VERSION >= 0x050000
bool QVTKWidget::nativeEvent(const QByteArray& eventType, void* message, long* result)
{
  if (eventType == "windows_generic_MSG")
    {
    winEvent((MSG*)message, result);
    }
  return false;
}
#endif
822
823
#endif

824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
//-----------------------------------------------------------------------------
bool QVTKWidget::paintCachedImage()
{
  // if we have a saved image, use it
  if (this->cachedImageCleanFlag)
    {
    vtkUnsignedCharArray* array = vtkUnsignedCharArray::SafeDownCast(
      this->mCachedImage->GetPointData()->GetScalars());
    // put cached image into back buffer if we can
    this->mRenWin->SetPixelData(0, 0, this->width()-1, this->height()-1,
                                array, !this->mRenWin->GetDoubleBuffer());
    // swap buffers, if double buffering
    this->mRenWin->Frame();
    // or should we just put it on the front buffer?
    return true;
    }
  return false;
}

//-----------------------------------------------------------------------------
844
void QVTKWidget::renderEventCallback()
Clinton Stimpson's avatar
 
Clinton Stimpson committed
845
{
846
  if (this->mRenWin)
Clinton Stimpson's avatar
   
Clinton Stimpson committed
847
    {
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
    // prevent capturing the selection buffer as the cached image. to do this
    // we iterate through each renderer in the view and check if they have an
    // active selector object. if so we return without saving the image
    vtkRendererCollection *renderers = this->mRenWin->GetRenderers();
    if(renderers)
      {
      renderers->InitTraversal();

      while(vtkRenderer *renderer = renderers->GetNextItem())
        {
        if(renderer->GetSelector() != NULL)
          {
          return;
          }
        }
      }

865
866
867
    this->markCachedImageAsDirty();
    if (this->isAutomaticImageCacheEnabled() &&
      (this->mRenWin->GetDesiredUpdateRate() < this->maxRenderRateForImageCache()))
868
      {
869
      this->saveImageToCache();
870
      }
Clinton Stimpson's avatar
   
Clinton Stimpson committed
871
    }
Clinton Stimpson's avatar
 
Clinton Stimpson committed
872
}