load mupa and show fake path scene
authorDiane Trout <diane@caltech.edu>
Sat, 25 Feb 2006 02:52:22 +0000 (02:52 +0000)
committerDiane Trout <diane@caltech.edu>
Sat, 25 Feb 2006 02:52:22 +0000 (02:52 +0000)
Enable loading a mupa file.
Use the gl scene widget from the qtgl prototype to make it look
like we've done something.

mussagl.pro
qui/PathScene.cxx [new file with mode: 0644]
qui/PathScene.h [new file with mode: 0644]
qui/PathWindow.cxx
qui/PathWindow.h

index 73826dd4356e435bfcb339f794f829da53a736ef..6f8c36190145033ed4cbba150f54d67a84160185 100644 (file)
@@ -34,4 +34,4 @@ SOURCES += mussagl.cxx \
 #           test/test_mussa.cxx \
 #           test/test_nway.cxx \
 #           test/test_sequence.cxx 
-
+QT += opengl
diff --git a/qui/PathScene.cxx b/qui/PathScene.cxx
new file mode 100644 (file)
index 0000000..1ae8fd0
--- /dev/null
@@ -0,0 +1,313 @@
+#include "PathScene.h"
+
+#include <QMouseEvent>
+#include <QRubberBand>
+#include <QRect>
+#include <iostream>
+
+#include <GL/gl.h>
+
+PathScene::PathScene(int frags, int len, QWidget *parent) : 
+  QGLWidget(parent),
+  X(0),
+  clipZ(32.0),
+  zoom(0),
+  maxOrtho2d(-50.0, -50, 3000000.0, 300.0),
+  curOrtho2d(maxOrtho2d),
+  fragsize(frags),
+  length(len),
+  rubberBand(0),
+  debugBand(true),
+  drawingBand(false)
+{ 
+}
+
+QSize PathScene::sizeHint() const
+{
+  return QSize(400, 400);
+}
+
+void PathScene::setX(int newX)
+{
+  if (X != newX) {
+    X = newX;
+    update();
+  }
+}
+
+static float max(float a, float b)
+{
+  if ( a < b) 
+    return b;
+  else
+    return a;
+}
+
+static float min(float a, float b)
+{
+  if ( a < b) 
+    return a;
+  else
+    return b;
+}
+
+void PathScene::setZoom(int newZoom)
+{
+  std::cout << newZoom << " " << zoom << std::endl;
+  if (zoom != newZoom) {
+    // try to figure out where we should be now?
+
+    float width = maxOrtho2d.width();
+    std::cout << "max width " << width 
+              << " max left " << maxOrtho2d.left()
+              << " max right " << maxOrtho2d.right() << std::endl;
+    float newWidth = width / newZoom;
+    std::cout << "new width" << newWidth<< std::endl;
+    float center = curOrtho2d.width()/2 + curOrtho2d.left();
+    std::cout << "l: " << curOrtho2d.left() << " r: " << curOrtho2d.right() 
+              << " ctr: " << center << std::endl;
+    curOrtho2d.setLeft(max(center-newWidth, maxOrtho2d.left()));
+    curOrtho2d.setRight(min(center+newWidth, maxOrtho2d.right()));
+    std::cout << "nl: " << curOrtho2d.left() << " nr: " << curOrtho2d.right()
+              << std::endl;
+    zoom = newZoom;
+    update();
+  }
+}
+
+void PathScene::setClipPlane(int newZ)
+{
+  if (clipZ != (double) newZ){
+    clipZ = (double) newZ;
+    update();
+  }
+}
+
+void PathScene::initializeGL()
+{
+  glEnable(GL_DEPTH_TEST|GL_BLEND);
+  glClearColor(0.0, 0.0, 0.0, 0.0);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  glShadeModel(GL_FLAT);
+  glLoadIdentity();
+  glPushMatrix();
+}
+
+void PathScene::resizeGL(int width, int height)
+{
+  glViewport(0, 0, (GLsizei)width, (GLsizei)height);
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  // I'm abusing this as Qt and OpenGL disagree about the direction of the
+  // y axis
+  glOrtho(curOrtho2d.left(), curOrtho2d.right(), 
+          curOrtho2d.top(), curOrtho2d.bottom(), 
+          -50.0, clipZ);
+  glMatrixMode(GL_MODELVIEW);
+}
+
+void PathScene::paintGL()
+{
+  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+  glPushMatrix();
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(curOrtho2d.left(), curOrtho2d.right(), 
+          curOrtho2d.top(), curOrtho2d.bottom(), 
+          -50.0, clipZ);
+  glMatrixMode(GL_MODELVIEW);
+  if (debugBand && !drawingBand) {
+    glColor4f(0.4, 0.4, 0.4, 0.9);
+    glRectf(previousBand.x(), previousBand.y(),
+            previousBand.right(), previousBand.bottom());
+  }
+  glTranslatef(-X*1000, 0.0, 0.0);
+  mussaesque(fragsize, length);
+
+  glPopMatrix();
+  glFlush();
+}
+
+static void processHits(GLint hits, GLuint buffer[])
+{
+  GLuint names, *ptr;
+
+  std::cout << "hits = " << hits << std::endl;
+  ptr = (GLuint *) buffer;
+  for (GLint i=0; i < hits; ++i)
+  {
+    names = *ptr;
+    std::cout << " number of names for hit " << i << " " << names << std::endl;
+    ptr++;
+    std::cout << "  z1 is " << (float) *ptr/0x7fffffff << std::endl;
+    ptr++;
+    std::cout << "  z2 is " << (float) *ptr/0x7fffffff << std::endl;
+    ptr++;
+    std::cout << "  the name is ";
+    for (GLuint j=0; j < names; j++)
+    {
+      std::cout << *ptr;
+      ptr++;
+    }
+    std::cout << std::endl;
+  }
+}
+
+void PathScene::mousePressEvent( QMouseEvent *e)
+{
+  drawingBand = true;
+  std::cout << "x=" << e->x() << " y=" << e->y() << std::endl;
+
+  bandOrigin = e->pos();
+  if (!rubberBand)
+    rubberBand = new QRubberBand(QRubberBand::Rectangle, this);
+  
+  rubberBand->setGeometry(QRect(bandOrigin, QSize()));
+  rubberBand->show();
+}
+
+void PathScene::mouseMoveEvent( QMouseEvent *e)
+{
+  rubberBand->setGeometry(QRect(bandOrigin, e->pos()).normalized());
+}
+
+void dumpRect(const QRect &r)
+{
+  std::cout << "x=" << r.x() << " y=" << r.y() 
+            << " w=" << r.width() << " h=" << r.height() << std::endl;
+}
+
+void PathScene::mouseReleaseEvent( QMouseEvent *e)
+{
+  drawingBand = false;
+  rubberBand->hide();
+  QRect r = QRect(bandOrigin, e->pos()).normalized();
+  bandOrigin = r.topLeft();
+  std::cout << "band ";
+  dumpRect(r);
+
+  std::cout << "window ";
+  dumpRect(geometry());
+
+  GLfloat x_scale = curOrtho2d.width()/((float)geometry().width());
+  GLfloat y_scale = curOrtho2d.height()/((float)geometry().height());
+  GLfloat x_left = curOrtho2d.left() + (r.x()*x_scale);
+  GLfloat x_right = x_left + r.width() * x_scale;
+  // using QRectF with Y axis swapped
+  GLfloat y_top = curOrtho2d.bottom()-(r.y()*y_scale);
+  GLfloat y_bottom = y_top - r.height() * y_scale;
+  previousBand.setCoords(x_left, y_top, x_right, y_bottom);
+  std::cout << x_left << " " << x_right << " " << y_top << " " << y_bottom 
+            << std::endl;
+
+  GLuint selectBuf[512];
+  glSelectBuffer(512, selectBuf);
+  GLint hits;
+
+  (void)glRenderMode(GL_SELECT);
+  glInitNames();
+  glPushName(42);
+  glPushMatrix();
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  glOrtho(x_left, x_right, y_top, y_bottom, -50.0, 50.0);
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  mussaesque(fragsize,  length);
+  glFlush();
+
+  glPopMatrix();
+  hits = glRenderMode(GL_RENDER);
+  processHits(hits, selectBuf);
+
+  resizeGL(geometry().width(), geometry().height());
+}
+
+
+//////
+// openGl rendering code
+
+static void seq_track(long length, long height)
+{
+  glLineWidth(5);
+  glColor3f(0.9, 0.6, 0.9);
+  glBegin(GL_LINES);
+    glVertex3f(0.0, (GLfloat)height, -1.0);
+    glVertex3f((GLfloat)length, (GLfloat)height, -1.0);
+  glEnd();
+}
+
+static void tracks()
+{
+  glPushMatrix();
+  glLoadName(1);
+  seq_track(2000000, 0);
+  glLoadName(2);
+  seq_track(2500000, 100);
+  glLoadName(3);
+  seq_track(1900000, 200);
+  glPopMatrix();
+}
+
+static void draw_lines(int fragsize, int length)
+{
+  float depth = 1.0;
+
+  glColor3f(0.3, 0.9, 0.3);
+  glLineWidth(0.001);
+  GLfloat x;
+  GLfloat z;
+  const long short_sequence_len = 1800000;
+  long blocks = short_sequence_len / fragsize;
+  std::cout << "blocks " << blocks << std::endl;
+  std::cout << "line count " << blocks * length << std::endl;
+  for (long base_block=0; base_block < blocks; ++base_block)
+  {
+    for (long base_offset=0; base_offset < length; ++base_offset)
+    {
+      glBegin(GL_LINE_STRIP);
+      x = (GLfloat)(base_block * fragsize +base_offset);
+
+      depth -= 0.1;
+      if (depth < -2.0) depth = 1.0;
+
+      z = (-32.0 - (-32.0 * depth));
+
+      //std::cout << "Z: " << z << "\n";
+
+      glVertex3f(x, 0.0, z );
+      glVertex3f(x+200000.0, 100, z );
+      glVertex3f(x+100.0, 200, z );
+      glEnd();
+    }
+  }
+}
+
+static GLuint make_line_list(int fragsize, int length)
+{
+  GLuint line_list = glGenLists(1);
+  glNewList(line_list, GL_COMPILE);
+
+  draw_lines(fragsize, length);
+
+  glEndList();
+  return line_list;
+
+}
+
+void PathScene::mussaesque(int fragments, int length)
+{
+  static GLuint theLines = make_line_list(fragments, length);
+
+  glInitNames();
+  glPushName(0);
+  tracks();
+  glLoadName(10);
+  glCallList(theLines);
+  glPopName();
+  //draw_lines();
+}
+
+
diff --git a/qui/PathScene.h b/qui/PathScene.h
new file mode 100644 (file)
index 0000000..77737ab
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef _PATHSCENE_H_
+#define _PATHSCENE_H_
+
+#include <QGLWidget>
+#include <QRectF>
+#include <QPoint>
+
+class QMouseEvent;
+class QRubberBand;
+
+/*! \brief Render mussa sequences and paths 
+ */
+class PathScene: public QGLWidget
+{
+  Q_OBJECT
+
+public: 
+  PathScene(int fragsize, int length, QWidget *parent=0);
+
+  QSize sizeHint() const;
+
+public slots:
+  void setX(int x);
+  void setClipPlane(int z);
+  void setZoom(int);
+
+protected:
+  int X;
+  double clipZ;
+  int zoom;
+  QRectF maxOrtho2d;
+  QRectF curOrtho2d;
+  int fragsize;
+  int length;
+
+  void initializeGL();
+  void resizeGL(int width, int height);
+  void paintGL();
+
+  QRubberBand *rubberBand;
+  QPoint bandOrigin;
+  QRectF previousBand;
+  bool debugBand;
+  bool drawingBand;
+  void mousePressEvent(QMouseEvent *);
+  void mouseMoveEvent(QMouseEvent *);
+  void mouseReleaseEvent(QMouseEvent *);
+
+  void mussaesque(int, int);
+};
+#endif
index 82ba18901f299b36f22d7ce220e3c05010e1f413..0313496789d4a878512a7201ce3cad14365a8619 100644 (file)
@@ -1,8 +1,14 @@
 #include "qui/PathWindow.h"
-#include <QMenuBar>
+
 #include <QAction>
+#include <QDir>
+#include <QFileDialog>
+#include <QMenuBar>
 #include <QMessageBox>
 #include <QStatusBar>
+#include <QString>
+
+#include "qui/PathScene.h"
 
 PathWindow::PathWindow(QWidget *) :
   closeAction(0) // initialize one of the pointers to null as a saftey flag
@@ -10,6 +16,9 @@ PathWindow::PathWindow(QWidget *) :
   setupActions();
   setupMainMenu();
 
+  scene = new PathScene(10000, 10, this);
+  this->setCentralWidget(scene);
+
   statusBar()->showMessage("Welcome to mussa", 2000);
 }
 
@@ -41,7 +50,7 @@ void PathWindow::setupActions()
   
   loadMupaAction = new QAction(tr("Load Mussa Parameters"), this);
   connect(loadMupaAction, SIGNAL(triggered()), 
-          this, SLOT(loadMupaAction()));
+          this, SLOT(loadMupa()));
 
   loadSavedAnalysisAction = new QAction(tr("Load &Analysis"), this);
   connect(loadSavedAnalysisAction, SIGNAL(triggered()), 
@@ -102,7 +111,13 @@ void PathWindow::loadMotifList()
 
 void PathWindow::loadMupa()
 {
-  NotImplementedBox();
+  QString caption("Load a mussa parameter file");
+  QString filter("Mussa Parameters (*.mupa)");
+  QString mupa_path = QFileDialog::getOpenFileName(this,
+                                                   caption, 
+                                                   QDir::currentPath(),
+                                                   filter);
+  mussaAnalysis.load_mupa_file(mupa_path.toStdString());
 }
 
 void PathWindow::loadSavedAnalysis()
index 7ba0867571400aa6285ba8a2bc177c9534ae8cfd..c25e035b8a1aae3abd1509b83744e65b092c0c57 100644 (file)
@@ -3,13 +3,17 @@
 
 #include <QMainWindow>
 
+#include "alg/mussa_class.hh"
+
 class QAction;
+class PathScene;
 
 class PathWindow : public QMainWindow
 {
   Q_OBJECT
 
 public: 
+  Mussa mussaAnalysis;
   PathWindow(QWidget *parent=0);
 
 public slots:
@@ -36,6 +40,9 @@ public slots:
   //\@}
 
 protected:
+  // display our wonderful mussa output
+  PathScene *scene;
+  
   QAction *aboutAction;
   QAction *closeAction;
   QAction *createNewAnalysisAction;