注    册
密 码 忘记密码
保存密码         取消
注    册
密 码 忘记密码
保存密码         取消

我的日志

vtk与gtk

分类:VTK
2007.3.30 10:53 作者:天行健 | 评论:0 | 阅读:0
可以基于gtkglext自行封装形成GtkWidget.
下面是封装的头文件以及其实现文件,最后是其示例。

vtkGtkRenderWindowInteractor.h

/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkGtkRenderWindowInteractor.cxx,v $
  Language:  C++
  Date:      $Date: 2002/11/22 16:25:58 $
  Version:   $Revision: 0.1 $

  Based on wvXRenderWindowInteractor and wxVTKRenderWindowInteractor.

  Copyright (c) 2004 Dov Grobgeld <dov.grobgeld@weizmann.ac.il>

  Based on code copyright by: 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.

=========================================================================*/
#ifndef __vtkGtkRenderWindowInteractor_h
#define __vtkGtkRenderWindowInteractor_h

//===========================================================
// now we define the C++ class

#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "gtk/gtk.h"

class VTK_RENDERING_EXPORT vtkGtkRenderWindowInteractor : public vtkRenderWindowInteractor
{
public:
  // Constructor
  vtkGtkRenderWindowInteractor();

  // Destructor
  ~vtkGtkRenderWindowInteractor();

  // Object factory. TBD.
  static vtkGtkRenderWindowInteractor *New();

  // vtkRenderWindowInteractor overrides
  void Initialize();
  void Enable();
  void Disable();
  void Start();
  void UpdateSize(int x, int y);
  int CreateTimer(int timertype);
  int DestroyTimer();
  void TerminateApp() {};
  void Render();

  // accessor function for drawing area used for gl interaction
  GtkWidget *get_drawing_area() { return drawing_area; }

  // Make all callback friends
  friend void     cb_realize   (GtkWidget*, gpointer user_data);
  friend gboolean cb_configure (GtkWidget *widget,
                GdkEventConfigure *event,
                gpointer user_data);
  friend gboolean cb_expose    (GtkWidget *widget,
                GdkEventExpose *event,
                gpointer user_data);
  friend gboolean cb_key_press_event(GtkWidget *widget,
                    GdkEventKey *event,
                gpointer user_data);
  friend gboolean cb_key_release_event(GtkWidget *widget,
                    GdkEventKey *event,
                gpointer user_data);
  friend gboolean cb_button_press_event(GtkWidget *widget,
                        GdkEventButton *event,
                gpointer user_data);
  friend gboolean cb_button_release_event(GtkWidget *widget,
                    GdkEventButton *event,
                gpointer user_data);
  friend gboolean cb_motion_notify_event(GtkWidget *widget,
                        GdkEventMotion *event,
                gpointer user_data);

  // Dov - timeout callback - will have to cast the user_data...
  friend gboolean vtkGtkRenderWindowInteractorTimer(gpointer user_data);

 protected:
  int ActiveButton;
  int RenderAllowed;
  long GetHandle();
  int Stereo;

 private:
  long Handle;
  bool Created;
  int RenderWhenDisabled;
  int UseCaptureMouse;
  GtkWidget *drawing_area;
  gint last_xpos, last_ypos, last_key_state;
  // Flag used to break timer loop
  bool do_break_timer;

  void update_mouse_pos();
};

#endif


vtkGtkRenderWindowInteractor.cxx
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkGtkRenderWindowInteractor.cxx,v $
  Language:  C++
  Date:      $Date: 2002/11/22 16:25:58 $
  Version:   $Revision: 0.1 $

  Based on wvXRenderWindowInteractor and wxVTKRenderWindowInteractor.

  Copyright (c) 2004 Dov Grobgeld <dov.grobgeld@weizmann.ac.il>

  Based on code copyright by: 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.

=========================================================================*/
#include "vtkGtkRenderWindowInteractor.h"
#include "vtkCommand.h"
#include <gtk/gtk.h>
#include <gtk/gtkgl.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include <gdk/gdkprivate.h>

// Construct an instance so that the light follows the camera motion.
vtkGtkRenderWindowInteractor::vtkGtkRenderWindowInteractor()
  : vtkRenderWindowInteractor()
  , RenderAllowed(false)
  , RenderWhenDisabled(true)
  , Created(true)
  , UseCaptureMouse(false)
  , Handle(0)
  , Stereo(0)
  , ActiveButton(0)
  , last_xpos(0)
  , last_ypos(0)
  , last_key_state(0)
  , do_break_timer(false)
{
  GdkGLConfig *glconfig;

  drawing_area = gtk_drawing_area_new();
  GTK_WIDGET_SET_FLAGS (drawing_area, GTK_CAN_FOCUS);

  gtk_widget_set_events(GTK_WIDGET(drawing_area),
            GDK_EXPOSURE_MASK
            | GDK_STRUCTURE_MASK
            | GDK_PROPERTY_CHANGE_MASK
            | GDK_POINTER_MOTION_MASK
            | GDK_POINTER_MOTION_HINT_MASK
            | GDK_BUTTON_PRESS_MASK
            | GDK_BUTTON_RELEASE_MASK
            | GDK_KEY_PRESS_MASK
            | GDK_KEY_RELEASE_MASK
            | GDK_LEAVE_NOTIFY_MASK
            | GDK_ENTER_NOTIFY_MASK
            );
 
  glconfig = gdk_gl_config_new_by_mode (GdkGLConfigMode(GDK_GL_MODE_RGB    |
                            GDK_GL_MODE_DEPTH  |
                            GDK_GL_MODE_DOUBLE));

  /* Set OpenGL-capability to the widget. */
  gtk_widget_set_gl_capability (drawing_area,
                                glconfig,
                                NULL,
                                TRUE,
                                GDK_GL_RGBA_TYPE);

  gtk_widget_set_double_buffered(drawing_area,
                                 FALSE);
 
  g_signal_connect(drawing_area, "realize",
           G_CALLBACK(&cb_realize),
           (gpointer)this);
  g_signal_connect(drawing_area, "configure_event",
           G_CALLBACK(&cb_configure),
           (gpointer)this);
  g_signal_connect(drawing_area, "expose_event",
           G_CALLBACK(&cb_expose),
           (gpointer)this);
  g_signal_connect(drawing_area, "key_press_event",
           G_CALLBACK(&cb_key_press_event),
           (gpointer)this);
  g_signal_connect(drawing_area, "key_release_event",
           G_CALLBACK(&cb_key_release_event),
           (gpointer)this);
  g_signal_connect(drawing_area, "button_press_event",
           G_CALLBACK(&cb_button_press_event),
           (gpointer)this);
  g_signal_connect(drawing_area, "button_release_event",
           G_CALLBACK(&cb_button_release_event),
           (gpointer)this);
  g_signal_connect(drawing_area, "motion_notify_event",
           G_CALLBACK(&cb_motion_notify_event),
           (gpointer)this);

  // Copied from wxVTKRenderWindowInteractor... What is it for?
  vtkRenderWindowInteractor::SetRenderWindow(vtkRenderWindow::New());
  RenderWindow->Delete();
}

vtkGtkRenderWindowInteractor * vtkGtkRenderWindowInteractor::New()
{
  // we are not registered in the objectfactor
  return new vtkGtkRenderWindowInteractor;
}

// Todo constructor with more options...

vtkGtkRenderWindowInteractor::~vtkGtkRenderWindowInteractor()
{
  gtk_widget_destroy(drawing_area);
}

// Initializes the event handlers using a parent widget that you have
// provided.  This assumes that you want to own the event loop.
void vtkGtkRenderWindowInteractor::Initialize()
{
  Enable();
  RenderWindow->Start();

  Initialized = 1;
}

void vtkGtkRenderWindowInteractor::Enable()
{
  if (Enabled)
    return;

  Enabled = true;
  Modified();
}

void vtkGtkRenderWindowInteractor::Disable()
{
  if (!Enabled)
    return;

  Enabled = false;
  Modified();
}

void vtkGtkRenderWindowInteractor::Start()
{
  fprintf(stderr, "Interactor cannot control event loop!\n");
}

void vtkGtkRenderWindowInteractor::UpdateSize(int x,int y)
{
  // if the size changed send this on to the RenderWindow
  if ((x != this->Size[0]) || (y != this->Size[1]))
  {
    this->Size[0] = x;
    this->Size[1] = y;
    this->RenderWindow->SetSize(x,y);
  }
}

int vtkGtkRenderWindowInteractor::CreateTimer(int timertype)
{
 
  if (timertype == VTKI_TIMER_FIRST)
  {
    // We use a repeating timer? Do we need to keep an id for it?
    g_timeout_add(10, vtkGtkRenderWindowInteractorTimer, (gpointer)(this));
    this->do_break_timer = false;
  }

  return 1;
}

int vtkGtkRenderWindowInteractor::DestroyTimer()
{
  this->do_break_timer = true;
  return 1;
}

long vtkGtkRenderWindowInteractor::GetHandle()
{
  return (long)GDK_WINDOW_XWINDOW(drawing_area->window);
}

void vtkGtkRenderWindowInteractor::Render()
{
  RenderAllowed = 1;
  if (!RenderWhenDisabled)
  {
    // tbd - check if parent is enabled
  }

  if (RenderAllowed)
  {
    if (Handle && (Handle == GetHandle()) )
    {
      RenderWindow->Render();
    }

    // TBD for reparenting
  }
}

void vtkGtkRenderWindowInteractor::update_mouse_pos()
{
  GdkModifierType mask;
  gdk_window_get_pointer(drawing_area->window,
             &last_xpos,
             &last_ypos,
             &mask);
  last_key_state = mask;
}

gboolean vtkGtkRenderWindowInteractorTimer(gpointer client_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)client_data;

  if (rwi->do_break_timer) {
    return FALSE;
  }
 
  if (rwi->Enabled)
  {
    rwi->InvokeEvent(vtkCommand::TimerEvent,NULL);
  }

  return TRUE;
}

void cb_realize(GtkWidget*,
        gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
 
  if (!rwi->Handle)
  {
    rwi->Handle = rwi->GetHandle();
    rwi->RenderWindow->SetWindowId((void*)rwi->Handle);
  }

  // get vtk to render to the drawing area
  //  rwi->Render();
}

gboolean cb_configure(GtkWidget *widget,
          GdkEventConfigure *event,
          gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;

  rwi->UpdateSize(event->width, event->height);

  if (!rwi->Enabled)
  {
    return TRUE;
  }

  rwi->InvokeEvent(vtkCommand::ConfigureEvent, NULL);
 
  // get vtk to render to the drawing area
  rwi->Render();

  return TRUE;
}

// I'm rendering everytime I'm getting an expose event. Perhaps this
// is a waist of time...
gboolean cb_expose(GtkWidget *widget,
           GdkEventExpose *event,
           gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
  rwi->Render();
  return TRUE;
}

gboolean
cb_key_press_event(GtkWidget *widget,
           GdkEventKey *event,
           gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
  gint keyval = event->keyval;
  char key = 0;

  if (keyval < 256)
  {
    // Todo: Unicode in non-Unicode mode??
    key = (char)keyval;
  }

  rwi->update_mouse_pos();

  rwi->SetEventInformationFlipY(rwi->last_xpos,
                rwi->last_ypos,
                event->state & GDK_CONTROL_MASK,
                event->state & GDK_SHIFT_MASK,
                key,
                0,
                NULL);

  rwi->last_key_state = event->state;
 
  rwi->InvokeEvent(vtkCommand::KeyPressEvent, NULL);
  rwi->InvokeEvent(vtkCommand::CharEvent, NULL);

  return true;
}

gboolean
cb_key_release_event(GtkWidget *widget,
             GdkEventKey *event,
             gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
  gint keyval = event->keyval;
  char key = 0;

  if (keyval < 256)
  {
    // Todo: Unicode in non-Unicode mode??
    key = (char)keyval;
  }

  rwi->update_mouse_pos();
  rwi->SetEventInformationFlipY(rwi->last_xpos,
                rwi->last_ypos,
                event->state & GDK_CONTROL_MASK,
                event->state & GDK_SHIFT_MASK,
                key,
                0,
                NULL);

  rwi->last_key_state = event->state;
 
  rwi->InvokeEvent(vtkCommand::KeyReleaseEvent, NULL);

  return TRUE;
}


gboolean
cb_button_press_event(GtkWidget *widget,
              GdkEventButton *event,
              gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
  gint button = event->button;
 
  if (!rwi->Enabled || rwi->ActiveButton != 0)
    return true;

  rwi->update_mouse_pos();
  rwi->SetEventInformationFlipY(rwi->last_xpos,
                rwi->last_ypos,
                rwi->last_key_state & GDK_CONTROL_MASK,
                rwi->last_key_state & GDK_SHIFT_MASK,
                '\0',
                0,
                NULL);
 
  rwi->ActiveButton = button;

  switch (button) {
  case 1:
    rwi->InvokeEvent(vtkCommand::LeftButtonPressEvent, NULL);
    break;
  case 2:
    rwi->InvokeEvent(vtkCommand::MiddleButtonPressEvent, NULL);
    break;
  case 3:
    rwi->InvokeEvent(vtkCommand::RightButtonPressEvent, NULL);
    break;
  default:
    // Ignore other buttons at the moment
    break;
  }

  // Do we need to worry about capturing the mouse
  return TRUE;
}

gboolean
cb_button_release_event(GtkWidget *widget,
            GdkEventButton *event,
            gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;
  gint button = event->button;

  // is this right?
  if (!rwi->Enabled || rwi->ActiveButton != button)
    return true;

  rwi->update_mouse_pos();
  rwi->SetEventInformationFlipY(rwi->last_xpos,
                rwi->last_ypos,
                rwi->last_key_state & GDK_CONTROL_MASK,
                rwi->last_key_state & GDK_SHIFT_MASK,
                '\0',
                0,
                NULL);
  switch (button) {
  case 1:
    rwi->InvokeEvent(vtkCommand::LeftButtonReleaseEvent, NULL);
    break;
  case 2:
    rwi->InvokeEvent(vtkCommand::MiddleButtonReleaseEvent, NULL);
    break;
  case 3:
    rwi->InvokeEvent(vtkCommand::RightButtonReleaseEvent, NULL);
    break;
  default:
    // Ignore other buttons at the moment
    break;
  }

  rwi->ActiveButton = 0;
}

gboolean
cb_motion_notify_event(GtkWidget *widget,
               GdkEventMotion *event,
               gpointer user_data)
{
  vtkGtkRenderWindowInteractor *rwi = (vtkGtkRenderWindowInteractor *)user_data;

  rwi->update_mouse_pos();
  rwi->SetEventInformationFlipY(rwi->last_xpos,
                rwi->last_ypos,
                rwi->last_key_state & GDK_CONTROL_MASK,
                rwi->last_key_state & GDK_SHIFT_MASK,
                '\0',
                0,
                NULL);

  rwi->InvokeEvent(vtkCommand::MouseMoveEvent, NULL);

  return true;
}

example.cc
//======================================================================
//  An example file showing how to use the vtkGtkRenderWindowInteractor.
//
//  Dov Grobgeld <dov.grobgeld@weizmann.ac.il>
//  2004-10-17
//----------------------------------------------------------------------
#include "vtkSphereSource.h"
#include "vtkCubeSource.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkGtkRenderWindowInteractor.h"
#include "vtkInteractorStyleFlight.h"
#include "gtk/gtkgl.h"

// Creates a scene consisting of a sphere and a 3D block
vtkRenderer *create_scene()
{
  // create sphere geometry
  vtkSphereSource *sphere = vtkSphereSource::New();
  sphere->SetRadius(1.0);
  sphere->SetThetaResolution(50);
  sphere->SetPhiResolution(50);

  // map to graphics library
  vtkPolyDataMapper *sphere_map = vtkPolyDataMapper::New();
  sphere_map->SetInput(sphere->GetOutput());

  // actor coordinates geometry, properties, transformation
  vtkActor *sphere_actor = vtkActor::New();
  sphere_actor->SetMapper(sphere_map);
  sphere_actor->GetProperty()->SetColor(0,0,1); // sphere color blue

  // cube
  vtkCubeSource *cube = vtkCubeSource::New();
  cube->SetXLength(1.5);
  cube->SetYLength(1.0);
  cube->SetZLength(0.5);

  // map to graphics library
  vtkPolyDataMapper *cube_map = vtkPolyDataMapper::New();
  cube_map->SetInput(cube->GetOutput());

  // actor coordinates geometry, properties, transformation
  vtkActor *cube_actor = vtkActor::New();
  cube_actor->SetMapper(cube_map);
  cube_actor->SetPosition(2.5,0,0);
  cube_actor->GetProperty()->SetColor(1,0,0); // cube color is red

  // a renderer and and place the objects in it render window
  vtkRenderer *ren1 = vtkRenderer::New();
  ren1->AddActor(sphere_actor);
  ren1->AddActor(cube_actor);
  ren1->SetBackground(1,1,1); // Background color white

  return ren1;
}

// Create's the gui and incorpotes the drawing area widget of
// the renderer.
void build_gui(GtkWidget *vtk_area)
{
  // Build gui
  GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
  GtkWidget *vbox = gtk_vbox_new(0,0);

  gtk_window_set_policy(GTK_WINDOW(window), TRUE, TRUE, TRUE);

  gtk_container_add (GTK_CONTAINER (window),
             vbox);
  gtk_box_pack_start (GTK_BOX (vbox),
              vtk_area, 1,1,0);
  gtk_widget_set_size_request(vtk_area, 400,400);
  GtkWidget *button = gtk_button_new_with_label("Quit");
  g_signal_connect(G_OBJECT(button), "clicked",
           G_CALLBACK(gtk_main_quit), NULL);
  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE,FALSE,0);
 
  gtk_widget_show_all (window);

}

int main(int argc, char *argv[])
{
  gtk_init(&argc, &argv);
  gtk_gl_init(&argc, &argv);

  // Create the gtk vtk interactor. This also creates the gtk widget.
  vtkGtkRenderWindowInteractor *iren = vtkGtkRenderWindowInteractor::New();

  // Connect the renderer to the gtk vtk rendering window
  vtkRenderer *scene = create_scene();
  iren->GetRenderWindow()->AddRenderer(scene);

  build_gui(iren->get_drawing_area());

  gtk_main();
}

你可以通过这个链接引用该篇文章:http://shenaodong.bokee.com/viewdiary.15499235.html

            X射线基础 上一篇 | 下一篇 VTK学习笔记1

我的搜索

文章评论

添加评论

马上抢占沙发,进行评论
昵  称:  主  页: (选填)
验证码: