forked from Kitware/VTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BasicVTKView.mm
129 lines (110 loc) · 4.08 KB
/
BasicVTKView.mm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#import "BasicVTKView.h"
#import "vtkCocoaRenderWindow.h"
#import "vtkCocoaRenderWindowInteractor.h"
#import "vtkRenderWindow.h"
#import "vtkRenderWindowInteractor.h"
#import "vtkRenderer.h"
@implementation BasicVTKView
// ----------------------------------------------------------------------------
// Designated initializer
- (instancetype)initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
// nothing to do... add something if you need to
}
return self;
}
// ----------------------------------------------------------------------------
// Designated initializer
- (nullable instancetype)initWithCoder:(NSCoder*)coder
{
self = [super initWithCoder:coder];
if (self)
{
// nothing to do... add something if you need to
}
return self;
}
// ----------------------------------------------------------------------------
// We are going to override the super class here to do some last minute
// setups. We need to do this because if we initialize in the constructor or
// even later, in say an NSDocument's windowControllerDidLoadNib, then
// we will get a warning about "Invalid Drawable" because the OpenGL Context
// is trying to be set and rendered into an NSView that most likely is not
// on screen yet. This is a way to defer that initialization until the NSWindow
// that contains our NSView subclass is actually on screen and ready to be drawn.
- (void)drawRect:(NSRect)theRect
{
// Check for a valid vtkWindowInteractor and then initialize it. Technically we
// do not need to do this, but what happens is that the window that contains
// this object will not immediately render it so you end up with a big empty
// space in your gui where this NSView subclass should be. This may or may
// not be what is wanted. If you allow this code then what you end up with is the
// typical empty black OpenGL view which seems more 'correct' or at least is
// more soothing to the eye.
vtkRenderWindowInteractor* renWinInt = [self getInteractor];
if (renWinInt && (renWinInt->GetInitialized() == NO))
{
renWinInt->Initialize();
}
// Let the vtkCocoaGLView do its regular drawing
[super drawRect:theRect];
}
// ----------------------------------------------------------------------------
- (void)initializeVTKSupport
{
// The usual vtk object creation.
vtkRenderer* ren = vtkRenderer::New();
vtkRenderWindow* renWin = vtkRenderWindow::New();
vtkRenderWindowInteractor* renWinInt = vtkRenderWindowInteractor::New();
// The cast should never fail, but we do it anyway, as
// it's more correct to do so.
vtkCocoaRenderWindow* cocoaRenWin = vtkCocoaRenderWindow::SafeDownCast(renWin);
if (ren && cocoaRenWin && renWinInt)
{
// This is special to our usage of vtk. To prevent vtk
// from creating an NSWindow and NSView automatically (its
// default behaviour) we tell vtk that they exist already.
// The APIs names are a bit misleading, due to the cross
// platform nature of vtk, but this usage is correct.
NSWindow* parentWindow = [self window];
assert(parentWindow);
cocoaRenWin->SetRootWindow((__bridge void*)parentWindow);
cocoaRenWin->SetWindowId((__bridge void*)self);
// The usual vtk connections.
cocoaRenWin->AddRenderer(ren);
renWinInt->SetRenderWindow(cocoaRenWin);
// This is special to our usage of vtk. vtkCocoaGLView
// keeps track of the renderWindow, and has a get
// accessor if you ever need it.
[self setVTKRenderWindow:cocoaRenWin];
// Likewise, BasicVTKView keeps track of the renderer.
[self setRenderer:ren];
}
}
// ----------------------------------------------------------------------------
- (void)cleanUpVTKSupport
{
vtkRenderer* ren = [self getRenderer];
vtkRenderWindow* renWin = [self getVTKRenderWindow];
vtkRenderWindowInteractor* renWinInt = [self getInteractor];
if (ren)
{
ren->Delete();
}
if (renWin)
{
renWin->Delete();
}
if (renWinInt)
{
renWinInt->Delete();
}
[self setRenderer:nil];
[self setVTKRenderWindow:nil];
// There is no setter accessor for the render window
// interactor, that's ok.
}
@end