4 #include <vtkRenderWindow.h>     5 #include <vtkRenderWindowInteractor.h>     6 #include <vtkInteractorStyleTrackballCamera.h>     7 #include <vtkWindowToImageFilter.h>     8 #include <vtkPNGWriter.h>     9 #include <vtkCommand.h>    10 #include <vtkProperty.h>    11 #include <vtkProperty2D.h>    12 #include <vtkObjectBase.h>    13 #include <vtkPropCollection.h>    14 #include <vtkContextScene.h>    34         for (
auto & subframe: frame.second->subframes)
    35           subframe.renderer->RemoveAllViewProps();
    36         frame.second->window->Finalize();
    55       char* port_string= getenv(
"VTKFIG_PORT_NUMBER");
    56       char* wtime_string=getenv(
"VTKFIG_WAIT_SECONDS");
    57       char *debug_string=getenv(
"VTKFIG_DEBUG");
    58       char *multi_string=getenv(
"VTKFIG_MULTITHREADED");
    59       char *dbuff_string=getenv(
"VTKFIG_DOUBLEBUFFER");
    69       if (multi_string!=0 && atoi(multi_string))
    72           cout << 
"overriding multithreading default (off) on APPLE" << endl;
    77       if (multi_string!=0 && !atoi(multi_string))
    80           cout << 
"overriding multithreading default (on) on" << endl;
    89         wtime=atoi(wtime_string);
    94         int port=atoi(port_string);
    96           throw std::runtime_error(
"Invalid port number for server");
   107           cout << sc<< 
" try running multithreaded" << endl;
   109           cout << sc<<
" try running single threaded" << endl;
   118       cout << 
"Server start listening on port "<< port << endl;
   124         cout << 
"Server connected" << endl;
   127         cout << 
"Nobody is listening ... giving up" << endl;
   128         throw std::runtime_error(
"Server connection failed");
   137         cout << 
" ~mt"  << endl;
   140         std::this_thread::sleep_for(std::chrono::milliseconds(10));
   142         std::this_thread::sleep_for(std::chrono::milliseconds(10));
   163       frame->mainthread=
this;
   195       assert(frame==
framemap[frame->number_in_frame_list]);
   197       frame->number_in_frame_list=-1;
   214         std::this_thread::sleep_for (std::chrono::milliseconds(10));
   226         cout << 
"mt " << from << 
" " << number_in_frame_list << endl;
   230       this->
iframe=number_in_frame_list;
   233         std::unique_lock<std::mutex> lock(this->
mutex);
   254       std::vector<Figure*>edited_figures;
   257       bool edit_mode =
false;
   260       bool left_button_down=
false;
   291         for (
auto & figure: frame->figures)
   293           for (
auto & actor: figure->ctxactors) 
   294             actor->GetScene()->SetDirty(
true);
   296         vtkInteractorStyleTrackballCamera::OnConfigure();        
   308           this->left_button_down=
true;
   309           lastx=this->Interactor->GetEventPosition()[0];
   310           lasty=this->Interactor->GetEventPosition()[1];
   313           vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
   319         for (
auto &figure: frame->figures)
   322           if (frame->subframes[figure->framepos].renderer==this->CurrentRenderer)
   323             figure->RTShowActive();
   325             figure->RTShowInActive();
   326           frame->window->Render();
   330         if (this->left_button_down)
   331           this->left_button_down=
false;
   333           vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
   342         if (this->left_button_down)
   346           int thisx=this->Interactor->GetEventPosition()[0];
   347           int thisy=this->Interactor->GetEventPosition()[1];
   352           for (
auto figure:this->edited_figures) 
   353             figure->RTProcessMove(dx,dy);
   356           this->Interactor->Render();
   363           vtkInteractorStyleTrackballCamera::OnMouseMove();
   370         std::string key = this->Interactor->GetKeySym();
   386           for (
auto & subframe: this->frame->subframes)
   388             if (subframe.renderer==this->CurrentRenderer)
   390               frame->RTResetCamera(subframe);
   393           this->Interactor->Render();
   399           for (
auto &figure: this->frame->figures)
   400             if (this->frame->subframes[figure->framepos].renderer==this->CurrentRenderer)
   402               figure->state.wireframe=!figure->state.wireframe;
   403               if (figure->state.wireframe)
   404                 for (
auto & actor: figure->actors)  actor->GetProperty()->SetRepresentationToWireframe();
   406                 for (
auto&  actor: figure->actors)  actor->GetProperty()->SetRepresentationToSurface();
   407               this->Interactor->Render();
   417           auto now = std::chrono::system_clock::now();
   418           auto time = std::chrono::system_clock::to_time_t(now);
   419           std::tm * ttm = localtime(&time);
   420           char time_str[] = 
"yyyy-mm-ddTHH:MM:SS ";
   421           strftime(time_str, strlen(time_str), 
"%Y-%m-%dT%H:%M:%S", ttm);
   422           auto fname=frame->parameter.wintitle+
"-"+time_str+
".png";
   424           auto imgfilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
   425           imgfilter->SetInput(frame->window);
   428           auto pngwriter = vtkSmartPointer<vtkPNGWriter>::New();
   429           pngwriter->SetInputConnection(imgfilter->GetOutputPort());
   430           pngwriter->SetFileName(fname.c_str());
   432           this->Interactor->Render();
   435           cout << 
"Frame written to "<< fname << endl;
   439         else if (key == 
"x" || key== 
"y" || key== 
"z" || key== 
"l" || key== 
"a")
   441           if (!this->edit_mode)
   444             this->edit_mode=
true;
   448             for (
auto &figure: frame->figures)
   452                 frame->subframes[figure->framepos].renderer==this->CurrentRenderer
   465                 this->edited_figures.push_back(figure);
   470           for (
auto figure : this->edited_figures)
   471             figure->RTProcessKey(key);
   472           this->Interactor->Render();
   477         else if(key == 
"Left" || key== 
"Down")
   481             for (
auto figure : this->edited_figures)
   482               figure->RTProcessMove(-1,-1);
   483             this->Interactor->Render();
   488         else if(key == 
"Right" || key== 
"Up")
   492             for (
auto figure : this->edited_figures)
   493               figure->RTProcessMove(1,1);
   494             this->Interactor->Render();
   499         else if(key == 
"Return" || key==
"Delete")
   503             for (
auto figure : this->edited_figures)
   504               figure->RTProcessKey(key);
   505             this->Interactor->Render();
   510         else if(key == 
"Escape")
   512           this->edit_mode=
false;
   513           for (
auto figure : this->edited_figures)
   515             figure->RTProcessKey(key);
   516             figure->RTMessage(
"");
   518           this->Interactor->Render();
   519           this->edited_figures.resize(0);
   520           this->Interactor->Render();
   524         else if(key == 
"I" || key== 
"L" || key == 
"E" || key == 
"S" || key == 
"slash" || key == 
"B" || key == 
"C" || key == 
"O"|| key == 
"A")
   526           for (
auto &figure: frame->figures)
   527             if (frame->subframes[figure->framepos].renderer==this->CurrentRenderer)
   528               figure->RTProcessKey(key);
   530           this->Interactor->Render();
   534         else if (key==
"space")
   536           frame->mainthread->communication_blocked=!frame->mainthread->communication_blocked;
   537           if(frame->mainthread->communication_blocked)
   538             frame->title_actor->SetText(6,
"-|-");
   540             frame->title_actor->SetText(6,
"---");
   541           frame->title_actor->Modified();
   542           frame->window->Render();
   546         else if (key==
"BackSpace")
   548           frame->mainthread->communication_blocked=!frame->mainthread->communication_blocked;
   549           if (!frame->mainthread->communication_blocked)
   550             frame->step_number=std::max(frame->step_number-2,0);
   554         else if (key==
"asterisk")
   556           if (!frame->single_subframe_view)
   557             for(
int i=0;i<this->frame->subframes.size();i++)
   559               if (this->frame->subframes[i].renderer==this->CurrentRenderer)
   560                 this->frame->active_subframe=i;
   563           frame->single_subframe_view=!frame->single_subframe_view;
   564           frame->RTSetSingleView(frame->single_subframe_view);
   565           this->Interactor->Render();
   569         else if (frame->single_subframe_view && key==
"Next")
   571           frame->RTSetActiveSubFrame(frame->active_subframe-1,
true);
   572           this->Interactor->Render();
   575         else if (frame->single_subframe_view && key==
"Prior")
   577           frame->RTSetActiveSubFrame(frame->active_subframe+1,
true);
   578           this->Interactor->Render();
   584         else if(key == 
"h" or key == 
"question")
   592           vtkInteractorStyleTrackballCamera::OnChar();
   608       vtkSmartPointer<vtkRenderWindowInteractor> Interactor=0;
   614         vtkObject *vtkNotUsed(caller),
   615         unsigned long eventId,
   616         void *vtkNotUsed(callData)
   627           vtkCommand::TimerEvent == eventId  
   635             std::unique_lock<std::mutex> lock(this->mainthread->
mutex);
   638           switch(mainthread->
cmd)
   653             for (
auto & subframe: frame->subframes)
   654               subframe.renderer->RemoveAllViewProps();
   656             frame->window->Finalize();
   658             mainthread->
framemap.erase(frame->number_in_frame_list);
   668             for (
auto & framepair: mainthread->
framemap)
   669               framepair.second->RTAddFigures();
   673             for (
auto & framepair: mainthread->
framemap)
   675               auto frame=framepair.second;
   677               if(frame->mainthread->communication_blocked)
   678                 frame->title_actor->SetText(6,
"-|-");
   680                 frame->title_actor->SetText(6,
"---");
   682               frame->title_actor->Modified();
   686               frame->window->Render();
   687               if (frame->videowriter && ! frame->mainthread->communication_blocked)
   689                 this->Interactor->Render();
   690                 auto imgfilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
   691                 imgfilter->SetInput(frame->window);
   693                 frame->videowriter->SetInputConnection(imgfilter->GetOutputPort());
   694                 this->Interactor->Render();
   695                 frame->videowriter->Write();
   706             auto imgfilter = vtkSmartPointer<vtkWindowToImageFilter>::New();
   707             auto pngwriter = vtkSmartPointer<vtkPNGWriter>::New();
   709             pngwriter->SetInputConnection(imgfilter->GetOutputPort());
   710             pngwriter->SetFileName(frame->parameter.filename.c_str());
   712             imgfilter->SetInput(frame->window);
   715             this->Interactor->Render();
   725             frame->videowriter =  vtkSmartPointer<vtkOggTheoraWriter>::New();
   726             frame->videowriter->SetFileName(frame->parameter.filename.c_str());
   727             frame->videowriter->Start();
   734             frame->videowriter->End();
   735             frame->videowriter=0;
   742             frame->RTRemoveFigure(frame->parameter.current_figure);
   750             frame->RTSetLayout(frame->parameter.nvpx,frame->parameter.nvpy); 
   751             frame->RTResetRenderers(
false);
   758             frame->window->SetSize(frame->parameter.winsize_x, frame->parameter.winsize_y);
   766             frame->RTSetActiveSubFrame(frame->parameter.active_subframe,
false);
   774             auto& subframe=frame->subframes[frame->parameter.active_subframe];
   775             frame->RTSetActiveSubFrameCameraViewAngle(subframe,frame->parameter.camera_view_angle);
   783             auto& subframe=frame->subframes[frame->parameter.active_subframe];
   784             frame->RTSetActiveSubFrameCameraPosition(subframe,frame->parameter.camera_position);
   792             auto& subframe=frame->subframes[frame->parameter.active_subframe];
   793             frame->RTSetActiveSubFrameCameraFocalPoint(subframe,frame->parameter.camera_focal_point);
   800             frame->RTSetSingleView(frame->parameter.single_subframe_view);
   810             frame->window->SetPosition(frame->parameter.winposition_x, frame->parameter.winposition_y);
   819             frame->title_actor->SetText(7,frame->parameter.frametitle.c_str());
   820             frame->title_actor->Modified();
   829             frame->window->SetWindowName(frame->parameter.wintitle.c_str());
   837             auto renderer=mainthread->
framemap[mainthread->
iframe]->subframes[frame->parameter.camlinkthisframepos].renderer;
   838             auto lrenderer=mainthread->
framemap[frame->parameter.camlinkframenum]->subframes[frame->parameter.camlinkframepos].renderer;
   839             renderer->SetActiveCamera(lrenderer->GetActiveCamera());
   847             for (
auto & framepair: mainthread->
framemap)
   848               framepair.second->window->Finalize();
   852             this->Interactor->TerminateApp();
   885       frame->window = vtkSmartPointer<vtkRenderWindow>::New();
   886       frame->window->SetWindowName(
"vtkfig");
   889         frame->window->DoubleBufferOn();
   891         frame->window->DoubleBufferOff();
   893       frame->window->SetSize(frame->parameter.winsize_x, frame->parameter.winsize_y);
   894       frame->window->SetPosition(frame->parameter.winposition_x, frame->parameter.winposition_y);
   896       frame->RTResetRenderers(
true);
   899       frame->title_subframe.renderer->AddActor(frame->title_actor);
   900       frame->title_actor->SetText(6,
"---");
   901       frame->title_actor->SetText(7,frame->parameter.frametitle.c_str());
   910       mainthread->
interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
   911       auto style =  vtkSmartPointer<MyInteractorStyle>::New();
   912       style->SetFrame(frame);
   913       mainthread->
interactor->SetInteractorStyle(style);
   915       mainthread->
interactor->SetRenderWindow(frame->window);
   917       auto callback =  vtkSmartPointer<MyTimerCallback>::New();
   920       mainthread->
interactor->AddObserver(vtkCommand::TimerEvent,callback);
   953         std::this_thread::sleep_for (std::chrono::milliseconds(10));
   974           std::unique_lock<std::mutex> lock(mainthread->
mutex);
   977           cout << 
"s cmd: " << 
static_cast<int>(mainthread->
cmd) << 
" frame: " <<mainthread->
iframe<< endl;
   983         switch(mainthread->
cmd)
   995           mainthread->
communicator->SendInt(frame->parameter.nvpx);
   996           mainthread->
communicator->SendInt(frame->parameter.nvpy);
   997           frame->nvpx=frame->parameter.nvpx;
   998           frame->nvpy=frame->parameter.nvpy;
  1005           mainthread->
communicator->SendInt(frame->parameter.active_subframe);
  1017           for (
auto framepair: mainthread->
framemap)
  1018             for (
auto & figure: framepair.second->figures)
  1030           mainthread->
communicator->SendString(frame->parameter.filename);
  1037           mainthread->
communicator->SendInt(frame->parameter.winsize_x);
  1038           mainthread->
communicator->SendInt(frame->parameter.winsize_y);
  1045           mainthread->
communicator->SendInt(frame->parameter.winposition_x);
  1046           mainthread->
communicator->SendInt(frame->parameter.winposition_y);
  1053           mainthread->
communicator->SendString(frame->parameter.frametitle);
  1061           mainthread->
communicator->SendString(frame->parameter.wintitle);
  1069           mainthread->
communicator->SendString(frame->parameter.current_figure->SubClassName());
  1070           mainthread->
communicator->SendInt(frame->parameter.current_figure->framepos);
  1077           mainthread->
communicator->SendString(frame->parameter.current_figure->SubClassName());
  1078           mainthread->
communicator->SendInt(frame->parameter.current_figure->framepos);
  1086           mainthread->
communicator->SendInt(frame->parameter.camlinkthisframepos);
  1087           mainthread->
communicator->SendInt(frame->parameter.camlinkframenum);
  1088           mainthread->
communicator->SendInt(frame->parameter.camlinkframepos);
  1108             cout << 
"s term" << endl;
  1119           cout << 
"s cmd: " << 
static_cast<int>(mainthread->
cmd) << endl;
  1120           throw std::runtime_error(
"wrong command on server");
  1142         std::this_thread::sleep_for (std::chrono::milliseconds(5));
 
void Terminate(void)
Terminate thread. 
 
vtkSmartPointer< Communicator > communicator
Communicator object for communication with cliend. 
 
int lastframenum
Number of last frame created. 
 
virtual void OnChar()
Overwrite keyboard callback. 
 
bool communication_blocked
space down state ? 
 
static MainThread * CreateMainThread()
Start thread. 
 
double timer_interval
Timer interval for timer callback. 
 
static MyTimerCallback * New()
 
static MainThread * mainthread
"This" thread 
 
void Show()
Show all frames aka nonblocking event loop. 
 
vtkSmartPointer< vtkRenderWindowInteractor > interactor
 
void OpenConnection(int port, int wtime)
Open connection to client. 
 
virtual void OnConfigure()
 
void Start()
Spawn parallel thread for rendering or communication. 
 
Communicator::Command cmd
Communication command. 
 
std::condition_variable condition_variable
Condition variable signalizing finished command. 
 
std::mutex mutex
Mutex to organize communication. 
 
static void PrepareCommunicatorThread(MainThread *)
Prepare comm thread before start. 
 
void Update()
Update all figures in all frames. 
 
std::shared_ptr< std::thread > thread
std::thread which runs rendering resp. communication 
 
bool double_buffering
Use of double buffering. 
 
bool connection_open
State of connection to client. 
 
friend class MyInteractorStyle
 
static void PrepareRenderThread(MainThread *)
Prepare render thread before start. 
 
virtual void OnMouseMove()
Overwrite mouse move. 
 
Timer callback handling communication with render thread. 
 
int debug_level
Debug level for client communication. 
 
friend class MyTimerCallback
 
virtual void Execute(vtkObject *vtkNotUsed(caller), unsigned long eventId, void *vtkNotUsed(callData))
 
virtual void OnLeftButtonUp()
Overwrite left button up. 
 
void Interact()
Blocking event loop demanding user interaction unblocked by space key. 
 
void AddFrame(Frame *frame)
Add frame to be handeled by thread. 
 
static void RenderThread(MainThread *)
Callback function for render thread. 
 
Main communication thread. 
 
bool try_running_multithreaded
Toggle multithreaded/single (at startup) 
 
static MyInteractorStyle * New()
 
void RemoveFrame(Frame *frame)
Remove frame from thread. 
 
Provide a framework wrapping window+interactor+renderers from vtk. 
 
static void DeleteMainThread()
Kill the thread. 
 
virtual void OnLeftButtonDown()
Overwrite left button down. 
 
void SendCommand(int iframe, const std::string from, Communicator::Command cmd)
Communication with render thread. 
 
static void CommunicatorThread(MainThread *)
Callback function for communicator thread. 
 
std::map< int, Frame * > framemap
Map of all frames handeled by thread. 
 
bool running_multithreaded
Thread state. 
 
int iframe
Frame number as parameter during communication. 
 
Define Frame class providing a window for rendering. 
 
static void CommunicatorThreadCallback(MainThread *)
Callback function for communicator thread if multithreading is off. 
 
vtkfig specific keybord and mouse interaction 
 
static void RTAddFrame(MainThread *mt, int iframe)
Add frame, to be called from render thread. 
 
static constexpr const char * KeyboardHelp
Help string printed when pressing "h"/"?".