00001
00002
00003
00004
00005
00006
00007
00008
00010
00011 #ifdef __GNUG__
00012 #pragma implementation "VtkInteractorEventRecorder.h"
00013 #endif
00014
00015 #include <wxGuiTest/VtkGuiTesting/VtkInteractorEventRecorder.h>
00016
00017 #include <vtkCallbackCommand.h>
00018 #include <vtkObjectFactory.h>
00019 #include <vtkRenderWindowInteractor.h>
00020
00021 #include <vtkCamera.h>
00022 #include <vtkRenderWindow.h>
00023 #include <vtkRendererCollection.h>
00024
00025 #include <stack>
00026 #include <string>
00027 #include <sstream>
00028 #include <cstdio>
00029
00030 #include <wx/window.h>
00031
00032 #include <wxVTKRenderWindowInteractor.h>
00033
00034 namespace wxTst {
00035
00036
00037 vtkCxxRevisionMacro(WxVtkInteractorEventRecorder, "$Revision: 1.5 $");
00038 vtkStandardNewMacro(WxVtkInteractorEventRecorder);
00039
00040 float WxVtkInteractorEventRecorder::StreamVersion = 2.0;
00041
00042
00043 WxVtkInteractorEventRecorder::WxVtkInteractorEventRecorder ()
00044 {
00045
00046 this->KeyPressCallbackCommand->SetCallback (
00047 WxVtkInteractorEventRecorder::ProcessCharEvent);
00048
00049 this->Priority = VTK_LARGE_FLOAT;
00050 this->EventCallbackCommand->SetCallback (
00051 WxVtkInteractorEventRecorder::ProcessEvents);
00052
00053 this->FileName = NULL;
00054
00055 this->State = WxVtkInteractorEventRecorder::Start;
00056 this->InputStream = NULL;
00057 this->OutputStream = NULL;
00058
00059 this->ReadFromInputString = 0;
00060 this->InputString = NULL;
00061 }
00062
00063
00064 WxVtkInteractorEventRecorder::~WxVtkInteractorEventRecorder ()
00065 {
00066 this->ClearInteractors ();
00067
00068 if (this->FileName) {
00069
00070 delete [] this->FileName;
00071 }
00072
00073 if (this->InputStream) {
00074
00075 delete this->InputStream;
00076 this->InputStream = NULL;
00077 }
00078
00079 if (this->OutputStream) {
00080
00081 delete this->OutputStream;
00082 this->OutputStream = NULL;
00083 }
00084
00085 if (this->InputString) {
00086
00087 delete [] this->InputString;
00088 this->InputString = NULL;
00089 }
00090
00091
00092 WxVtkMap::iterator it;
00093 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00094
00095 if ((*it).second->camera != NULL) {
00096
00097 (*it).second->camera->Delete ();
00098 (*it).second->camera = NULL;
00099 }
00100
00101 (*it).second->wxVtkRwi = NULL;
00102 delete (*it).second;
00103 }
00104 m_wxVtkMap.clear ();
00105 }
00106
00107
00108 void WxVtkInteractorEventRecorder::SetEnabled (int enabling)
00109 {
00110 if (m_wxVtkMap.empty ()) {
00111
00112 vtkErrorMacro (<< "Interactors must be set prior to enabling/disabling widget");
00113 return;
00114 }
00115
00116 if (enabling)
00117 {
00118
00119 vtkDebugMacro(<< "Enabling widget");
00120
00121 if (this->Enabled) {
00122
00123 return;
00124 }
00125
00126 this->Enabled = 1;
00127
00128
00129 WxVtkMap::iterator it;
00130 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00131
00132 (*it).second->wxVtkRwi->AddObserver (vtkCommand::AnyEvent,
00133 this->EventCallbackCommand, this->Priority);
00134 }
00135
00136 this->InvokeEvent (vtkCommand::EnableEvent, NULL);
00137
00138 } else {
00139
00140 vtkDebugMacro (<< "Disabling widget");
00141
00142 if (!this->Enabled) {
00143
00144 return;
00145 }
00146
00147 this->Enabled = 0;
00148
00149
00150 WxVtkMap::iterator it;
00151 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00152
00153 (*it).second->wxVtkRwi->RemoveObserver (this->EventCallbackCommand);
00154 }
00155
00156 this->InvokeEvent (vtkCommand::DisableEvent, NULL);
00157 }
00158 }
00159
00160
00161 void WxVtkInteractorEventRecorder::Record()
00162 {
00163 if (this->State == WxVtkInteractorEventRecorder::Start) {
00164
00165 if (!this->OutputStream) {
00166
00167 this->OutputStream = new ofstream (this->FileName, ios::out);
00168 if (this->OutputStream->fail ()) {
00169
00170 vtkErrorMacro (<< "Unable to open file: " << this->FileName);
00171 delete this->OutputStream;
00172 this->OutputStream = NULL;
00173 return;
00174 }
00175 *this->OutputStream << "# StreamVersion " <<
00176 WxVtkInteractorEventRecorder::StreamVersion << "\n";
00177 }
00178
00179 vtkDebugMacro (<< "Recording");
00180 this->State = WxVtkInteractorEventRecorder::Recording;
00181
00182
00183
00184 WxVtkMap::iterator it;
00185 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00186
00187 if ((*it).second->camera != NULL) {
00188
00189 (*it).second->camera->Delete ();
00190 (*it).second->camera = NULL;
00191 }
00192
00193 wxWindow *interactorWdw = (*it).second->wxVtkRwi;
00194
00195 wxWindow *wdw = interactorWdw;
00196 (*it).second->sizeList.push_front (wdw->GetSize ());
00197 while (wdw->GetParent () != NULL) {
00198
00199 wdw = wdw->GetParent ();
00200 (*it).second->sizeList.push_front (wdw->GetSize ());
00201 }
00202
00203 (*it).second->position = wdw->GetPosition ();
00204
00205 vtkRenderWindow *renderWdw = (*it).second->wxVtkRwi->GetRenderWindow ();
00206 vtkRendererCollection *renderers = renderWdw->GetRenderers ();
00207 wxASSERT_MSG (renderers->GetNumberOfItems () > 0,
00208 _T("At least one renderer must exist in each render window; and only the first one is fully supported."));
00209 if (renderers->GetNumberOfItems () != 1) {
00210
00211 ::wxLogTrace (_T("VtkWxwxGuiTest"),
00212 _T("Currently only one renderer per render window interactor is supported"));
00213 }
00214 vtkRenderer *renderer = renderers->GetFirstRenderer ();
00215 vtkCamera *activeCamera = renderer->GetActiveCamera ();
00216 (*it).second->camera = vtkCamera::New ();
00217 (*it).second->camera->SetParallelScale (activeCamera->GetParallelScale ());
00218 (*it).second->camera->SetViewAngle (activeCamera->GetViewAngle ());
00219 (*it).second->camera->SetClippingRange (activeCamera->GetClippingRange ());
00220 (*it).second->camera->SetFocalPoint (activeCamera->GetFocalPoint ());
00221 (*it).second->camera->SetPosition (activeCamera->GetPosition ());
00222 (*it).second->camera->SetViewUp (activeCamera->GetViewUp ());
00223 }
00224
00225 }
00226 }
00227
00228
00229 void WxVtkInteractorEventRecorder::RestoreWxVtkSettings ()
00230 {
00231 WxVtkMap::iterator it;
00232 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00233
00234 wxASSERT ((*it).second->camera != NULL);
00235
00236 wxWindow *interactorWdw = (*it).second->wxVtkRwi;
00237
00238 std::stack< wxWindow *, std::list< wxWindow * > > wdwStack;
00239
00240 wxWindow *wdw = interactorWdw;
00241 wdwStack.push (wdw);
00242 while (wdw->GetParent () != NULL) {
00243
00244 wdw = wdw->GetParent ();
00245 wdwStack.push (wdw);
00246 }
00247
00248 wdw->SetPosition ((*it).second->position);
00249
00250
00251 SizeList::const_iterator sizeIt = (*it).second->sizeList.begin ();
00252 while ((!wdwStack.empty ()) &&
00253 (sizeIt != (*it).second->sizeList.end ())) {
00254
00255 wdwStack.top ()->SetSize (*sizeIt);
00256 wdwStack.pop ();
00257 sizeIt++;
00258 }
00259
00260 vtkRenderWindow *renderWdw = (*it).second->wxVtkRwi->GetRenderWindow ();
00261 vtkRendererCollection *renderers = renderWdw->GetRenderers ();
00262 wxASSERT_MSG (renderers->GetNumberOfItems () > 0,
00263 _T("At least one renderer must exist in each render window; and only the first one is fully supported."));
00264 if (renderers->GetNumberOfItems () != 1) {
00265
00266 ::wxLogTrace (_T("VtkWxwxGuiTest"),
00267 _T("Currently only one renderer per render window interactor is supported"));
00268 }
00269 vtkRenderer *renderer = renderers->GetFirstRenderer ();
00270 vtkCamera *activeCamera = renderer->GetActiveCamera ();
00271 activeCamera->SetParallelScale ((*it).second->camera->GetParallelScale ());
00272 activeCamera->SetViewAngle ((*it).second->camera->GetViewAngle ());
00273 activeCamera->SetClippingRange ((*it).second->camera->GetClippingRange ());
00274 activeCamera->SetFocalPoint ((*it).second->camera->GetFocalPoint ());
00275 activeCamera->SetPosition ((*it).second->camera->GetPosition ());
00276 activeCamera->SetViewUp ((*it).second->camera->GetViewUp ());
00277 }
00278 }
00279
00280
00281 const WxVtkInteractorEventRecorder::WxVtkMap &
00282 WxVtkInteractorEventRecorder::GetWxVtkMap () const
00283 {
00284 return m_wxVtkMap;
00285 }
00286
00287
00288 void WxVtkInteractorEventRecorder::Play ()
00289 {
00290 if (this->State == WxVtkInteractorEventRecorder::Start) {
00291
00292 if (this->ReadFromInputString) {
00293
00294 vtkDebugMacro (<< "Reading from InputString");
00295 int len;
00296 if ((this->InputString == NULL) ||
00297 (len = strlen (this->InputString) <= 0)) {
00298
00299 vtkErrorMacro (<< "No input string specified");
00300 return;
00301 }
00302 this->InputStream = new istrstream (this->InputString, len);
00303 if (this->InputStream->fail ()) {
00304
00305 vtkErrorMacro (<< "Unable to read from string");
00306 delete this->InputStream;
00307 this->InputStream = NULL;
00308 return;
00309 }
00310
00311 } else {
00312
00313 if (!this->InputStream) {
00314
00315 this->InputStream = new ifstream (this->FileName, ios::in);
00316 if (this->InputStream->fail ()) {
00317
00318 vtkErrorMacro (<< "Unable to open file: "<< this->FileName);
00319 delete this->InputStream;
00320 this->InputStream = NULL;
00321 return;
00322 }
00323 }
00324 }
00325
00326
00327
00328
00329 vtkDebugMacro (<< "Playing");
00330 this->State = WxVtkInteractorEventRecorder::Playing;
00331
00332
00333 char event[128], keySym[64], buffer[512], wxVtkId[60];
00334 int pos[2], ctrlKey, shiftKey, keyCode, repeatCount;
00335 float stream_version = 0.0, tempf;
00336
00337 while (!this->InputStream->eof ()) {
00338
00339 this->InputStream->width (256);
00340 *this->InputStream >> event;
00341
00342
00343 if (*event == '#') {
00344
00345 this->InputStream->getline (buffer, 512);
00346
00347
00348 if ((strlen (buffer) > 15) &&
00349 (!strncmp (buffer, " StreamVersion ", 15))) {
00350
00351 int res = sscanf (buffer + 15, "%f", &tempf);
00352 if (res && res != EOF) {
00353
00354 stream_version = tempf;
00355 }
00356 }
00357
00358 } else {
00359
00360 unsigned long ievent = vtkCommand::GetEventIdFromString (event);
00361 if (ievent == vtkCommand::NoEvent) {
00362
00363 this->InputStream->ignore (512, '\n');
00364
00365 } else {
00366
00367 if (stream_version >= 1.1) {
00368
00369
00370 }
00371 *this->InputStream >> pos[0];
00372 *this->InputStream >> pos[1];
00373 *this->InputStream >> ctrlKey;
00374 *this->InputStream >> shiftKey;
00375 *this->InputStream >> keyCode;
00376 *this->InputStream >> repeatCount;
00377 *this->InputStream >> keySym;
00378 *this->InputStream >> wxVtkId;
00379
00380 wxVTKRenderWindowInteractor *wxVtkRwi =
00381 WxVtkInteractorEventRecorder::GetInteractor (
00382 wxString (wxVtkId, *wxConvCurrent));
00383 wxASSERT (wxVtkRwi != NULL);
00384
00385 wxVtkRwi->SetEventPosition (pos);
00386 wxVtkRwi->SetControlKey (ctrlKey);
00387 wxVtkRwi->SetShiftKey (shiftKey);
00388 wxVtkRwi->SetKeyCode (keyCode);
00389 wxVtkRwi->SetRepeatCount (repeatCount);
00390 wxVtkRwi->SetKeySym (keySym);
00391
00392 wxVtkRwi->InvokeEvent (ievent, NULL);
00393 }
00394 }
00395 }
00396 }
00397
00398 this->State = WxVtkInteractorEventRecorder::Start;
00399 }
00400
00401
00402 void WxVtkInteractorEventRecorder::Stop()
00403 {
00404 this->State = WxVtkInteractorEventRecorder::Start;
00405 this->Modified ();
00406 }
00407
00408
00409 void WxVtkInteractorEventRecorder::Rewind()
00410 {
00411 if (!this->InputStream) {
00412
00413 vtkGenericWarningMacro (<< "No input file opened to rewind...");
00414 }
00415 this->InputStream->clear ();
00416 this->InputStream->seekg (0);
00417 }
00418
00419
00420
00421 void WxVtkInteractorEventRecorder::SetInteractor (vtkRenderWindowInteractor *i)
00422 {
00423 wxFAIL_MSG (_T("Change of class interface: use AddInteractor() method instead!"));
00424
00425 if (i == this->Interactor)
00426 {
00427 return;
00428 }
00429
00430
00431 if (this->Interactor)
00432 {
00433 this->SetEnabled(0);
00434 this->Interactor->RemoveObserver(this->KeyPressCallbackCommand);
00435 }
00436
00437 this->Interactor = i;
00438
00439
00440 if (i)
00441 {
00442 i->AddObserver(vtkCommand::CharEvent,
00443 this->KeyPressCallbackCommand, this->Priority);
00444 i->AddObserver(vtkCommand::DeleteEvent,
00445 this->KeyPressCallbackCommand, this->Priority);
00446 }
00447
00448 this->Modified();
00449 }
00450
00451
00452 void WxVtkInteractorEventRecorder::AddInteractor (const wxString &wxVtkId,
00453 wxVTKRenderWindowInteractor *wxVtkRwi)
00454 {
00455 WxVtkMap::const_iterator it;
00456
00457 it = m_wxVtkMap.find (wxVtkId);
00458 wxASSERT (it == m_wxVtkMap.end ());
00459
00460 WxVtk *wxVtk = new WxVtk ();
00461 wxVtk->wxVtkRwi = wxVtkRwi;
00462 wxVtk->camera = NULL;
00463 m_wxVtkMap[wxVtkId] = wxVtk;
00464
00465
00466
00467 wxVtkRwi->AddObserver (vtkCommand::CharEvent,
00468 this->KeyPressCallbackCommand, this->Priority);
00469 wxVtkRwi->AddObserver (vtkCommand::DeleteEvent,
00470 this->KeyPressCallbackCommand, this->Priority);
00471
00472 this->Modified();
00473 }
00474
00475
00476 wxVTKRenderWindowInteractor * WxVtkInteractorEventRecorder::GetInteractor (
00477 const wxString &wxVtkId) const
00478 {
00479 WxVtkMap::const_iterator it = m_wxVtkMap.find (wxVtkId);
00480
00481 return (it == m_wxVtkMap.end () ? NULL : (*it).second->wxVtkRwi);
00482 }
00483
00484
00485 wxString WxVtkInteractorEventRecorder::GetInteractorId (
00486 wxVTKRenderWindowInteractor *wxVtkRwi) const
00487 {
00488 bool found = false;
00489 WxVtkMap::const_iterator it = m_wxVtkMap.begin ();
00490 while ((!found) && (it != m_wxVtkMap.end ())) {
00491
00492 if ((*it).second->wxVtkRwi == wxVtkRwi) {
00493
00494 found = true;
00495
00496 } else {
00497
00498 it++;
00499 }
00500 }
00501
00502 return (it == m_wxVtkMap.end () ? _T("") : (*it).first);
00503 }
00504
00505
00506 void WxVtkInteractorEventRecorder::ClearInteractors ()
00507 {
00508 this->SetEnabled (0);
00509
00510 WxVtkMap::iterator it;
00511 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00512
00513 if ((*it).second->camera != NULL) {
00514
00515 (*it).second->camera->Delete ();
00516 (*it).second->camera = NULL;
00517 }
00518 if ((*it).second->wxVtkRwi != NULL) {
00519
00520 (*it).second->wxVtkRwi->RemoveObserver (this->KeyPressCallbackCommand);
00521 (*it).second->wxVtkRwi = NULL;
00522 }
00523 delete (*it).second;
00524 }
00525 m_wxVtkMap.clear ();
00526
00527 this->Modified();
00528 }
00529
00530
00531 void WxVtkInteractorEventRecorder::ProcessCharEvent (vtkObject *object,
00532 unsigned long event, void* clientData, void* vtkNotUsed(callData))
00533 {
00534 WxVtkInteractorEventRecorder *self =
00535 reinterpret_cast< WxVtkInteractorEventRecorder * >(clientData);
00536 vtkRenderWindowInteractor *rwi =
00537 static_cast< vtkRenderWindowInteractor * >(object);
00538
00539 switch (event) {
00540
00541 case vtkCommand::DeleteEvent:
00542
00543
00544 self->ClearInteractors ();
00545 break;
00546
00547 case vtkCommand::CharEvent:
00548 if (self->KeyPressActivation) {
00549
00550 if (rwi->GetKeyCode () == self->KeyPressActivationValue) {
00551
00552 if (!self->Enabled) {
00553
00554 self->On ();
00555
00556 } else {
00557
00558 self->Off();
00559 }
00560 }
00561 }
00562 }
00563 }
00564
00565
00566 void WxVtkInteractorEventRecorder::ProcessEvents (vtkObject *object,
00567 unsigned long event, void *clientData, void *vtkNotUsed(callData))
00568 {
00569 WxVtkInteractorEventRecorder * self =
00570 reinterpret_cast< WxVtkInteractorEventRecorder * >(clientData);
00571 wxVTKRenderWindowInteractor * wxVtkRwi =
00572 dynamic_cast< wxVTKRenderWindowInteractor * >(object);
00573 wxString wxVtkId = self->GetInteractorId (wxVtkRwi);
00574
00575
00576 if (self->State == WxVtkInteractorEventRecorder::Recording) {
00577
00578 switch (event) {
00579
00580 case vtkCommand::ModifiedEvent:
00581 break;
00582
00583 default:
00584 self->WriteEvent (vtkCommand::GetStringFromEventId (event),
00585 wxVtkRwi->GetEventPosition (), wxVtkRwi->GetControlKey (),
00586 wxVtkRwi->GetShiftKey (), wxVtkRwi->GetKeyCode (),
00587 wxVtkRwi->GetRepeatCount (), wxVtkRwi->GetKeySym (),
00588 wxConvCurrent->cWX2MB(wxVtkId));
00589 }
00590 self->OutputStream->flush ();
00591 }
00592 }
00593
00594
00595 void WxVtkInteractorEventRecorder::WriteEvent (const char *event, int pos[2],
00596 int ctrlKey, int shiftKey, int keyCode, int repeatCount, char *keySym,
00597 const char *wxVtkId)
00598 {
00599 if (keySym == NULL) {
00600
00601 keySym = "i";
00602 }
00603
00604 *this->OutputStream << event << " " << pos[0] << " " << pos[1] << " "
00605 << ctrlKey << " " << shiftKey << " "
00606 << keyCode << " " << repeatCount << " "
00607 << keySym << " " << wxVtkId << "\n";
00608 }
00609
00610
00611 void WxVtkInteractorEventRecorder::ReadEvent ()
00612 {
00613
00614 }
00615
00616
00617 void WxVtkInteractorEventRecorder::PrintSelf (ostream &os, vtkIndent indent)
00618 {
00619 this->Superclass::PrintSelf (os,indent);
00620
00621 if (this->FileName) {
00622
00623 os << indent << "File Name: " << this->FileName << "\n";
00624 }
00625
00626 os << indent << "ReadFromInputString: " <<
00627 (this->ReadFromInputString ? "On\n" : "Off\n");
00628
00629 if (this->InputString) {
00630
00631 os << indent << "Input String: " << this->InputString << "\n";
00632
00633 } else {
00634
00635 os << indent << "Input String: (None)\n";
00636 }
00637 }
00638
00639
00640 bool WxVtkInteractorEventRecorder::HasInputStream () const
00641 {
00642 return (this->InputStream != NULL);
00643 }
00644
00645
00646 bool WxVtkInteractorEventRecorder::IsEmptyRecording () const
00647 {
00648 return (!::wxFileExists (wxString(this->FileName, *wxConvCurrent)));
00649 }
00650
00651
00652 wxString WxVtkInteractorEventRecorder::GetRecordingAsEmitString (
00653 const wxString &tab) const
00654 {
00655 std::string line;
00656 wxString fileContent;
00657
00658 std::ifstream *inStr = new std::ifstream (this->FileName, ios::in);
00659 wxASSERT (!inStr->fail ());
00660
00661 while (std::getline (*inStr, line)) {
00662
00663 fileContent << tab << tab << tab << _T("\"") <<
00664 wxString (line.c_str (), *wxConvCurrent) << _T("\\n\"\n");
00665 }
00666 inStr->close ();
00667
00668 return fileContent;
00669 }
00670
00671
00672 void WxVtkInteractorEventRecorder::ResetRecording ()
00673 {
00674 if (this->OutputStream) {
00675
00676 delete this->OutputStream;
00677 this->OutputStream = NULL;
00678 }
00679 if (this->InputStream) {
00680
00681 delete this->InputStream;
00682 this->InputStream = NULL;
00683 }
00684 if (::wxFileExists (wxString (this->FileName, *wxConvCurrent))) {
00685
00686 int ret = remove (this->FileName);
00687 wxASSERT (ret == 0);
00688 }
00689
00690 WxVtkMap::iterator it;
00691 for (it = m_wxVtkMap.begin (); it != m_wxVtkMap.end (); it++) {
00692
00693 if ((*it).second->camera != NULL) {
00694
00695 (*it).second->camera->Delete ();
00696 (*it).second->camera = NULL;
00697 }
00698 (*it).second->sizeList.clear ();
00699 }
00700 }
00701
00702 }