1 //---------------------------------------------------------------------------
2 #include <vcl.h>
3 #pragma hdrstop
4
5 #include <vcl\Sysutils.hpp>
6
7 #include "vtkBorlandRenderWindow.h"
8
9 #include "vtkInteractorStyleSwitch.h"
10 #include "vtkInteractorStyleFlight.h"
11 #include "vtkInteractorStyleImage.h"
12 #include "vtkInteractorStyleUser.h"
13
14 #pragma package(smart_init)
15
16 //---------------------------------------------------------------------------
17 // ValidCtrCheck is used to assure that the components created do not have
18 // any pure virtual functions.
19 //
ValidCtrCheck(TvtkBorlandRenderWindow *)20 static inline void ValidCtrCheck(TvtkBorlandRenderWindow *)
21 {
22 new TvtkBorlandRenderWindow(NULL);
23 }
24
25 //---------------------------------------------------------------------------
26 namespace Vtkborlandrenderwindow
27 {
Register()28 void __fastcall PACKAGE Register()
29 {
30 TComponentClass classes[1] = {__classid(TvtkBorlandRenderWindow)};
31 RegisterComponents("Samples", classes, 0);
32 }
33 }
34
35 //---------------------------------------------------------------------------
TvtkBorlandRenderWindow(TComponent * Owner)36 __fastcall TvtkBorlandRenderWindow::TvtkBorlandRenderWindow(TComponent* Owner)
37 : inherited(Owner)
38 {
39 // Do want these
40 ControlStyle << csCaptureMouse << csClickEvents << csOpaque << csDoubleClicks;
41 // Don't want these
42 ControlStyle >> csAcceptsControls >> csSetCaption;
43
44 FUsevtkInteractor = true;
45 FInteractorMode = IM_TrackballCamera;
46 FInteractor = 0;
47 FOnVtkClose = 0;
48 FRenderWindow = 0;
49 FRenderer = 0;
50 FAbortCallback = vtkAbortCallback::New();
51 }
52
53 //---------------------------------------------------------------------------
~TvtkBorlandRenderWindow()54 __fastcall TvtkBorlandRenderWindow::~TvtkBorlandRenderWindow()
55 {
56 // Delete this first because Renderwindow has a hold on it too
57 if ( FInteractor )
58 {
59 FInteractor->Delete();
60 FInteractor = 0;
61 }
62 if ( FRenderer )
63 {
64 FRenderer->GetViewProps()->RemoveAllItems();
65 FRenderWindow->RemoveRenderer(FRenderer);
66 FRenderer->Delete();
67 FRenderer = 0;
68 }
69 if ( FRenderWindow )
70 {
71 FRenderWindow->RemoveObserver(FAbortCallback);
72 FRenderWindow->Delete();
73 FRenderWindow = 0;
74 }
75 FAbortCallback->Delete();
76 }
77
78 //---------------------------------------------------------------------------
GetRenderWindow(void)79 vtkWin32OpenGLRenderWindow * __fastcall TvtkBorlandRenderWindow::GetRenderWindow(void)
80 {
81 if ( ! FRenderWindow )
82 {
83 // Stuff the renderwindow into our window
84 FRenderWindow = vtkWin32OpenGLRenderWindow::New();
85 FRenderWindow->AddObserver( vtkCommand::AbortCheckEvent, FAbortCallback);
86 FRenderWindow->SetParentId(Parent->Handle);
87 FRenderWindow->SetWindowId(Handle);
88 FRenderWindow->DoubleBufferOn();
89 FRenderWindow->SwapBuffersOn();
90 // Frame to avoid unsightly garbage during initial
91 // display which may be long when a complex scene is first rendered
92 FRenderWindow->Frame();
93 Invalidate();
94 }
95 // We create the interactor here because it makes maintenance better
96 if (!FInteractor)
97 {
98 FInteractor = vtkWin32RenderWindowInteractor::New();
99 FInteractor->SetRenderWindow(FRenderWindow);
100 FInteractor->SetInstallMessageProc(false);
101 SetInteractorMode(FInteractorMode);
102 FInteractor->UpdateSize(Width,Height);
103 FInteractor->Initialize();
104 }
105 return FRenderWindow;
106 }
107
108 //---------------------------------------------------------------------------
GetInteractor(void)109 vtkWin32RenderWindowInteractor * __fastcall TvtkBorlandRenderWindow::GetInteractor(void)
110 {
111 if (FRenderWindow)
112 {
113 if (!FInteractor)
114 {
115 throw Exception("Window exists but no Interactor, this shouldn't happen");
116 }
117 }
118 else
119 {
120 this->GetRenderWindow();
121 }
122 return FInteractor;
123 }
124
125 //---------------------------------------------------------------------------
GetRenderer(void)126 vtkRenderer * __fastcall TvtkBorlandRenderWindow::GetRenderer(void)
127 {
128 if (!FRenderer)
129 {
130 FRenderer = vtkRenderer::New();
131 GetRenderWindow()->AddRenderer(FRenderer);
132 FRenderer->ResetCamera();
133 DWORD L = ColorToRGB(Color);
134 double rgb[3] = { GetRValue(L)/255.0, GetGValue(L)/255.0, GetBValue(L)/255.0 };
135 FRenderer->SetBackground(rgb);
136 }
137 return FRenderer;
138 }
139
140 //---------------------------------------------------------------------------
SetInteractorMode(const vtkBorlandInteractorMode & im)141 void __fastcall TvtkBorlandRenderWindow::SetInteractorMode(const vtkBorlandInteractorMode& im)
142 {
143 if ( im <= IM_TrackballActor && im >= IM_JoystickCamera )
144 {
145 vtkInteractorStyleSwitch *iass = vtkInteractorStyleSwitch::SafeDownCast(FInteractor->GetInteractorStyle());
146 if (!iass)
147 {
148 iass = vtkInteractorStyleSwitch::New();
149 FInteractor->SetInteractorStyle(iass);
150 iass->Delete();
151 }
152
153 switch ( im )
154 {
155 case IM_JoystickCamera: iass->SetCurrentStyleToJoystickCamera(); break;
156 case IM_JoystickActor: iass->SetCurrentStyleToJoystickActor(); break;
157 case IM_TrackballCamera: iass->SetCurrentStyleToTrackballCamera(); break;
158 case IM_TrackballActor: iass->SetCurrentStyleToTrackballActor(); break;
159 default: break;
160 }
161 FInteractorMode = im;
162 }
163 else if (im==IM_Flight)
164 {
165 vtkInteractorStyleFlight *iafl = vtkInteractorStyleFlight::SafeDownCast(FInteractor->GetInteractorStyle());
166 if (!iafl)
167 {
168 iafl = vtkInteractorStyleFlight::New();
169 FInteractor->SetInteractorStyle(iafl);
170 iafl->Delete();
171 }
172 FInteractorMode = IM_Flight;
173 }
174 else if (im==IM_Image)
175 {
176 vtkInteractorStyleImage *iasi = vtkInteractorStyleImage::SafeDownCast(FInteractor->GetInteractorStyle());
177 if (!iasi)
178 {
179 iasi = vtkInteractorStyleImage::New();
180 FInteractor->SetInteractorStyle(iasi);
181 iasi->Delete();
182 }
183 FInteractorMode = IM_Image;
184 }
185 else if (im==IM_User)
186 {
187 vtkInteractorStyleUser *iasu = vtkInteractorStyleUser::SafeDownCast(FInteractor->GetInteractorStyle());
188 if (!iasu)
189 {
190 iasu = vtkInteractorStyleUser::New();
191 FInteractor->SetInteractorStyle(iasu);
192 iasu->Delete();
193 }
194 FInteractorMode = IM_User;
195 }
196 else
197 {
198 return;
199 }
200 }
201
202 //---------------------------------------------------------------------------
203 // Paint
204 //---------------------------------------------------------------------------
Paint(void)205 void __fastcall TvtkBorlandRenderWindow::Paint(void)
206 {
207 if (FRenderWindow)
208 {
209 try
210 {
211 FRenderWindow->Render();
212 }
213 catch (...)
214 {
215 // Some error trap should occurr here
216 ShowMessage("An exception occurred whilst rendering");
217 }
218 }
219 else
220 { // Design time or before RenderWindow creation
221 inherited::Paint();
222 }
223 }
224
225 //---------------------------------------------------------------------------
226 // Event handlers
227 //---------------------------------------------------------------------------
WMEraseBkgnd(TWMEraseBkgnd & Message)228 void __fastcall TvtkBorlandRenderWindow::WMEraseBkgnd(TWMEraseBkgnd &Message)
229 {
230 if (!FRenderWindow)
231 {
232 inherited::Dispatch(&Message);
233 }
234 else
235 {
236 Message.Result = 1; // No, but thanks for asking.
237 }
238 }
239
240 //---------------------------------------------------------------------------
WMGetDlgCode(TMessage & Message)241 void __fastcall TvtkBorlandRenderWindow::WMGetDlgCode(TMessage &Message)
242 {
243 Message.Result = DLGC_WANTARROWS;
244 }
245
246 //---------------------------------------------------------------------------
WMChar(TWMKey & Message)247 void __fastcall TvtkBorlandRenderWindow::WMChar(TWMKey &Message)
248 {
249 switch (Message.CharCode)
250 {
251 case 'e':
252 case 'E':
253 case 'q':
254 case 'Q': if (!FOnVtkClose || (FOnVtkClose && FOnVtkClose(this)))
255 {
256 FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
257 }
258 break;
259 default: FInteractor->OnChar(Handle,Message.CharCode, 0, 0);
260 }
261 }
262
263 //---------------------------------------------------------------------------
WMKeyDown(TWMKey & Message)264 void __fastcall TvtkBorlandRenderWindow::WMKeyDown(TWMKey &Message)
265 {
266 FInteractor->OnKeyDown(Handle,Message.CharCode, 0, 0);
267 }
268
269 //---------------------------------------------------------------------------
WMKeyUp(TWMKey & Message)270 void __fastcall TvtkBorlandRenderWindow::WMKeyUp(TWMKey &Message)
271 {
272 FInteractor->OnKeyUp(Handle,Message.CharCode, 0, 0);
273 }
274
275 //---------------------------------------------------------------------------
MouseMove(TShiftState shift,int x,int y)276 void __fastcall TvtkBorlandRenderWindow::MouseMove(TShiftState shift, int x, int y )
277 {
278 if(this->OnMouseMove && shift.Contains(ssCtrl))
279 {
280 this->OnMouseMove(this,shift,x,y);
281 return;
282 }
283
284 if (FInteractor && FUsevtkInteractor)
285 {
286 int flags = 0;
287 if (shift.Contains(ssShift)) flags += MK_SHIFT;
288 if (shift.Contains(ssCtrl)) flags += MK_CONTROL;
289 FInteractor->OnMouseMove(Handle, flags, x, y );
290 }
291 }
292
293 //---------------------------------------------------------------------------
MouseDown(TMouseButton button,TShiftState shift,int x,int y)294 void __fastcall TvtkBorlandRenderWindow::MouseDown(TMouseButton button, TShiftState shift, int x, int y )
295 {
296 if (::GetFocus()!=Handle) SetFocus();
297
298 if(this->OnMouseDown && shift.Contains(ssCtrl))
299 {
300 this->OnMouseDown(this,button,shift,x,y);
301 return;
302 }
303
304 if (FInteractor && FUsevtkInteractor)
305 {
306 int flags = 0;
307 if (shift.Contains(ssShift)) flags += MK_SHIFT;
308 if (shift.Contains(ssCtrl)) flags += MK_CONTROL;
309 switch (button)
310 {
311 case mbLeft: FInteractor->OnLButtonDown(Handle, flags, x,y); break;
312 case mbRight: FInteractor->OnRButtonDown(Handle, flags, x,y); break;
313 case mbMiddle: FInteractor->OnMButtonDown(Handle, flags, x,y); break;
314 }
315 }
316 }
317
318 //---------------------------------------------------------------------------
MouseUp(TMouseButton button,TShiftState shift,int x,int y)319 void __fastcall TvtkBorlandRenderWindow::MouseUp(TMouseButton button, TShiftState shift, int x, int y )
320 {
321 if(this->OnMouseUp && shift.Contains(ssCtrl))
322 {
323 this->OnMouseUp(this,button,shift,x,y);
324 return;
325 }
326
327 if (FInteractor && FUsevtkInteractor)
328 {
329 int flags = 0;
330 if (shift.Contains(ssShift)) flags += MK_SHIFT;
331 if (shift.Contains(ssCtrl)) flags += MK_CONTROL;
332 switch (button)
333 {
334 case mbLeft: FInteractor->OnLButtonUp(Handle, flags, x,y); break;
335 case mbRight: FInteractor->OnRButtonUp(Handle, flags, x,y); break;
336 case mbMiddle: FInteractor->OnMButtonUp(Handle, flags, x,y); break;
337 }
338 }
339 }
340
341 //---------------------------------------------------------------------------
Resize(void)342 void __fastcall TvtkBorlandRenderWindow::Resize(void)
343 {
344 if (FInteractor)
345 {
346 FInteractor->OnSize(this->Handle, 0, this->Width, this->Height);
347 }
348 }
349
350 //---------------------------------------------------------------------------
WMTimer(TWMTimer & Message)351 void __fastcall TvtkBorlandRenderWindow::WMTimer(TWMTimer &Message)
352 {
353 if (FInteractor)
354 {
355 FInteractor->OnTimer(Handle,Message.TimerID);
356 }
357 }
358
359 //---------------------------------------------------------------------------
DoMouseWheelDown(TShiftState Shift,const TPoint & MousePos)360 bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelDown(TShiftState Shift, const TPoint &MousePos)
361 {
362 bool result;
363 if (this->OnMouseWheelDown && Shift.Contains(ssCtrl))
364 {
365 this->OnMouseWheelDown(this,Shift,MousePos,result);
366 return result;
367 }
368
369 if (FInteractor && FUsevtkInteractor)
370 {
371 int flags = 0;
372 if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
373 if (Shift.Contains(ssCtrl)) { flags += MK_CONTROL; }
374 FInteractor->OnMouseWheelBackward(Handle, flags, MousePos.x,MousePos.y);
375 result = true;
376 }
377 return result;
378 }
379
380 //---------------------------------------------------------------------------
DoMouseWheelUp(TShiftState Shift,const TPoint & MousePos)381 bool __fastcall TvtkBorlandRenderWindow::DoMouseWheelUp(TShiftState Shift, const TPoint &MousePos)
382 {
383 bool result;
384 if (this->OnMouseWheelUp && Shift.Contains(ssCtrl))
385 {
386 this->OnMouseWheelUp(this,Shift,MousePos,result);
387 return result;
388 }
389
390 if (FInteractor && FUsevtkInteractor)
391 {
392 int flags = 0;
393 if (Shift.Contains(ssShift)) { flags += MK_SHIFT; }
394 if (Shift.Contains(ssCtrl)) { flags += MK_CONTROL; }
395 FInteractor->OnMouseWheelForward(Handle, flags, MousePos.x,MousePos.y);
396 result = true;
397 }
398 return result;
399 }
400
401
402
403
404