taxplot3d_pane.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:19k
- /*
- * ===========================================================================
- * PRODUCTION $Log: taxplot3d_pane.cpp,v $
- * PRODUCTION Revision 1000.1 2004/06/01 21:13:45 gouriano
- * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
- * PRODUCTION
- * ===========================================================================
- */
- /* $Id: taxplot3d_pane.cpp,v 1000.1 2004/06/01 21:13:45 gouriano Exp $
- * ===========================================================================
- *
- * PUBLIC DOMAIN NOTICE
- * National Center for Biotechnology Information
- *
- * This software/database is a "United States Government Work" under the
- * terms of the United States Copyright Act. It was written as part of
- * the author's official duties as a United States Government employee and
- * thus cannot be copyrighted. This software/database is freely available
- * to the public for use. The National Library of Medicine and the U.S.
- * Government have not placed any restriction on its use or reproduction.
- *
- * Although all reasonable efforts have been taken to ensure the accuracy
- * and reliability of the software and data, the NLM and the U.S.
- * Government do not and cannot warrant the performance or results that
- * may be obtained by using this software or data. The NLM and the U.S.
- * Government disclaim all warranties, express or implied, including
- * warranties of performance, merchantability or fitness for any particular
- * purpose.
- *
- * Please cite the author in any work or product based on this material.
- *
- * ===========================================================================
- *
- * Authors: Vladimir Tereshkov
- *
- * File Description:
- * A child of CGlCanvas3d, this pane implements all basic 3d drawing functionality
- */
- #include <ncbi_pch.hpp>
- #include "taxplot3d_pane.hpp"
- #include <gui/opengl/gldlist.hpp>
- #include <gui/opengl/glutils.hpp>
- #include <FL/glut.H>
- BEGIN_NCBI_SCOPE
- CTaxplot3dPanel::CTaxplot3dPanel(int x, int y, int w, int h, const char* label)
- : CGlCanvas3d(x, y, w, h, label),
- m_Transform(CVect3<float>(0.0f, 0.0f, 0.0f), 2.0f),
- m_Pivot(0,0,0),
- m_Font_Bitmap8x13(CGlBitmapFont::eBitmap8x13)
- {
- m_Transform.Resolution(w, h);
-
- m_Data = NULL;
- m_Handler = NULL;
- m_ViewMode = eCamera;
- m_PivotPoint = eFloating;
- m_PrimitiveShape = eSphere;
- m_State = eNormal;
-
- m_bAxes = true;
- m_bGrid = true;
- m_bArrows = true;
- m_bLabels = true;
- m_bScale = true;
- m_bPvAttach = true;
-
- m_Tooltip.EnableActiveMode(static_cast<ITooltipClient*>(this));
- m_Tooltip.SetMode(CTooltip::eHideOnMove);
- }
- void CTaxplot3dPanel::draw()
- {
- x_DrawBackground(0.3f, 0.3f, 0.3f);
- x_SetupView();
-
- static GLfloat spec[] = {0.5f, 0.5f ,0.5f ,1.0}; //sets specular highlight of spheres
- static GLfloat posl[] = {2,4,3,1}; //position of ligth source
- static GLfloat amb[] = {0.7f, 0.7f, 0.7f ,1.0f}; //global ambient
- static GLfloat amb2[] = {0.3f, 0.3f, 0.3f ,1.0f}; //ambient of lightsource
- static float df = 5.0;
- glClearDepth(1.0f); // Depth Buffer Setup
- glEnable(GL_DEPTH_TEST); // Enables Depth Testing
- glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
- glShadeModel(GL_SMOOTH);
- glEnable(GL_CULL_FACE);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LINE_SMOOTH);
- glMaterialfv(GL_FRONT,GL_SPECULAR,spec);
- glMaterialfv(GL_FRONT,GL_SHININESS,&df);
- glEnable(GL_LIGHTING);
- glLightfv(GL_LIGHT0,GL_POSITION,posl);
- glLightfv(GL_LIGHT0,GL_AMBIENT,amb2);
- glEnable(GL_LIGHT0);
- glLightModelfv(GL_LIGHT_MODEL_AMBIENT,amb);
- glEnable(GL_COLOR_MATERIAL);
- glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- // move us out of center
- glTranslatef(0,0,-3);
- // scale
- if (m_bScale) drawScale();
-
- // apply transformations
- transformView();
-
- if (m_Dlist.IsValid()) {
- m_Dlist.Call();
- } else {
- CGlDisplayListCompile COMPILE(m_Dlist, CGlDisplayList::eCompileAndExecute);
-
- // bad name, not only axes
- drawAxes();
- // draw something real
- if (m_Data){
- for (unsigned int i=0; i<m_Data->getData().size(); i++){
- glPushMatrix();
-
- CVect3<float> point(m_Data->getVertexAt(i).getXYZ());
- CVect3<float> color(m_Data->getVertexAt(i).getRGB());
- glTranslatef(point.X(), point.Y(), point.Z());
- if (m_Data->getVertexAt(i).isSelected()) glColor4f(1,0.0f,0.0f,0.7f);
- else glColor4f(color.X(), color.Y(), color.Z(), 0.7f);
- drawPrimitive();
- glPopMatrix();
- }
- }
- }
- //CGlUtils::CheckGlError(); // on x-server it fails, need to trace this
- }
- // resize event handler
- void CTaxplot3dPanel::resize(int x, int y, int w, int h)
- {
- m_Transform.Resolution(w, h);
- CGlCanvas3d::resize(x, y, w, h);
- }
- // keyboard/mouse handlers
- int CTaxplot3dPanel::handle(int event)
- {
- // pass events to the tooltip object
- m_Tooltip.Handle(event);
- switch (event) {
- case FL_PUSH:
- if (Fl::event_button() == 1) {
- if (Fl::event_shift()) {
- m_Transform.Switch2Zoom();
- m_State = eZoom;
- } else if (Fl::event_ctrl()) {
- m_Transform.Switch2Pan();
- m_State = ePan;
- } else {
- m_Transform.Switch2Rotate();
- m_State = eRotate;
- }
- m_Transform.Update(Fl::event_x(), Fl::event_y());
- m_Transform.BeginDrag();
- draw(); // restoring current matrix, for synchronization purposes - good place for improvement
- checkSelection(Fl::event_x(), Fl::event_y());
- }
- break;
- case FL_DRAG:
- m_Transform.Update(Fl::event_x(), Fl::event_y());
- redraw();
- break;
- case FL_RELEASE:
- m_Transform.Update(Fl::event_x(), Fl::event_y());
- m_Transform.EndDrag();
- m_State = eNormal;
- break;
- default:
- // let it go
- return CGlCanvas3d::handle(event);
- }
-
- return 1; // event handled
- }
- // one point drawing
- void CTaxplot3dPanel::drawPrimitive()
- {
- switch (m_PrimitiveShape){
- case eCube:{
- glScalef(0.005f, 0.005f, 0.005f);
- GLfloat n[6][3] = { /* Normals for the 6 faces of a cube. */
- {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
- {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0, -1.0} };
- GLint faces[6][4] = { /* Vertex indices for the 6 faces of a cube. */
- {0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
- {4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3} };
- GLfloat v[8][3]; /* Will be filled in with X,Y,Z vertexes. */
- v[0][0] = v[1][0] = v[2][0] = v[3][0] = -1;
- v[4][0] = v[5][0] = v[6][0] = v[7][0] = 1;
- v[0][1] = v[1][1] = v[4][1] = v[5][1] = -1;
- v[2][1] = v[3][1] = v[6][1] = v[7][1] = 1;
- v[0][2] = v[3][2] = v[4][2] = v[7][2] = 1;
- v[1][2] = v[2][2] = v[5][2] = v[6][2] = -1;
- for (int i = 0; i < 6; i++) {
- glBegin(GL_QUADS);
- glNormal3fv(&n[i][0]);
- glVertex3fv(&v[faces[i][0]][0]);
- glVertex3fv(&v[faces[i][1]][0]);
- glVertex3fv(&v[faces[i][2]][0]);
- glVertex3fv(&v[faces[i][3]][0]);
- glEnd();
- }
- break;
- }
- case eSphere:{
- static GLUquadricObj *pObj = gluNewQuadric();
- gluSphere(pObj, 0.005, 10,10);
- break;
- }
- case eCross:
- glScalef(0.005f, 0.005f, 0.005f);
- glBegin(GL_LINES);
- glVertex3f( 0.0f, -1.0f, 0.0f);
- glVertex3f( 0.0f, 1.0f, 0.0f);
- glVertex3f( -1.0f, 0.0f, 0.0f);
- glVertex3f( 1.0f, 0.0f, 0.0f);
- glVertex3f( 0.0f, 0.0f, -1.0f);
- glVertex3f( 0.0f, 0.0f, 1.0f);
- glEnd();
- break;
- }
- }
- // update of data source
- void CTaxplot3dPanel::SetDataSource(CTaxplot3dDataSource * ds)
- {
- m_Data = ds;
- slowRedraw();
- }
- // drawing axes, labels, grid...
- void CTaxplot3dPanel::drawAxes()
- {
- glPushMatrix();
- glColor3f(1.0f,1.0f,1.0f);
- GLUquadricObj *pObj = gluNewQuadric();
- if (m_bAxes){
- glBegin(GL_LINES);
- glVertex3f( 0.0f, 0.0f, 0.0f);
- glVertex3f( 0.0f, 1.0f, 0.0f);
- glVertex3f( 0.0f, 0.0f, 0.0f);
- glVertex3f( 1.0f, 0.0f, 0.0f);
- glVertex3f( 0.0f, 0.0f, 0.0f);
- glVertex3f( 0.0f, 0.0f, 1.0f);
- glEnd();
- }
-
- if (m_bGrid){
- // step selection
- double step_n = GetBestStep(true);
-
- for (int i=1; (step_n * i) <= 1; i++){
- glColor4f(1.0f,1.0f,1.0f, (i%2)?0.05f:0.3f);
- glBegin(GL_LINES);
- glVertex3f( step_n * i, 0, 0.0f);
- glVertex3f( step_n * i, 1, 0.0f);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f( step_n * i, 0, 0.0f);
- glVertex3f( step_n * i, 0, 1.0f);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(0, step_n * i, 0.0f);
- glVertex3f(1, step_n * i, 0.0f);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(0, 0.0f, step_n * i);
- glVertex3f(1, 0.0f, step_n * i);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(0, 0.0f, step_n * i);
- glVertex3f(0, 1.0f, step_n * i);
- glEnd();
- glBegin(GL_LINES);
- glVertex3f(0, step_n * i, 0.0f);
- glVertex3f(0, step_n * i, 1.0f);
- glEnd();
-
- }
- }
- glPopMatrix();
- // labels
- if (m_Data && m_bLabels){
- glColor3f(1.0f,1.0f,1.0f);
- if (m_ViewMode!=eViewY) m_Font_Bitmap8x13.TextOut(0.0f, 1.07f, m_Data->yLabel().c_str());
- if (m_ViewMode!=eViewX) m_Font_Bitmap8x13.TextOut(1.07f, 0.0f, m_Data->xLabel().c_str());
- if (m_ViewMode!=eViewZ){
- glPushMatrix();
- glRotatef(90,1.0f,0.0f,0.0f);
- glColor3f(1.0f,1.0f,1.0f);
- m_Font_Bitmap8x13.TextOut(0.0f, 1.07f, m_Data->zLabel().c_str());
- glPopMatrix();
- }
- }
- // arrows
- if (m_bArrows){
- if (m_ViewMode!=eViewZ){
- glPushMatrix();
- glColor3f(1.0f,1.0f,1.0f);
- glTranslatef(0.0f,0.0f, 1.0f);
- gluQuadricDrawStyle(pObj, GLU_FILL);
- gluCylinder(pObj, 0.01, 0, 0.05, 20, 20);
- glPopMatrix();
- }
- if (m_ViewMode!=eViewY){
- glPushMatrix();
- glColor3f(1.0f,1.0f,1.0f);
- glRotatef(90,-1.0f,0.0f,0.0f);
- glTranslatef(0.0f,0.0f, 1.0f);
- gluQuadricDrawStyle(pObj, GLU_FILL);
- gluCylinder(pObj, 0.01, 0, 0.05, 20, 20);
- glPopMatrix();
- }
- if (m_ViewMode!=eViewX){
- glPushMatrix();
- glColor3f(1.0f,1.0f,1.0f);
- glRotatef(90,0.0f,1.0f,0.0f);
- glTranslatef(0.0f,0.0f, 1.0f);
- gluQuadricDrawStyle(pObj, GLU_FILL);
- gluCylinder(pObj, 0.01, 0, 0.05, 20, 20);
- glPopMatrix();
- }
- }
- }
- CVect3<float> CTaxplot3dPanel::GetOGLPos(int x, int y)
- {
- GLint viewport[4];
- GLdouble modelview[16];
- GLdouble projection[16];
- GLfloat winX, winY, winZ;
- GLdouble posX, posY, posZ;
- glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
- glGetDoublev( GL_PROJECTION_MATRIX, projection );
- glGetIntegerv( GL_VIEWPORT, viewport );
- winX = (float)x;
- winY = (float)viewport[3] - (float)y;
- glReadPixels( x, int(winY), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ );
- gluUnProject( winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ);
- return CVect3<float>(posX, posY, posZ);
- }
- // object lookup in 3D scene
- int CTaxplot3dPanel::findObject(int x, int y)
- {
- int foundIndex = -1;
- float delta = 0.006f;
- CVect3<float> pos = GetOGLPos(x, y);
- if (m_Data){
- for (unsigned int i=0; i<m_Data->getData().size(); i++){
- CVect3<float> point(m_Data->getVertexAt(i).getXYZ());
- if ((pos.X()>(point.X()-delta)) && (pos.X()<(point.X()+delta)) &&
- (pos.Y()>(point.Y()-delta)) && (pos.Y()<(point.Y()+delta)) &&
- (pos.Z()>(point.Z()-delta)) && (pos.Z()<(point.Z()+delta))) {
- foundIndex = i;
- break;
- }
- }
- }
- return foundIndex;
- }
- void CTaxplot3dPanel::checkSelection(int x, int y)
- {
- if (m_Data){
- m_Data->dropSelection();
- int curObject = findObject(x, y);
- if (curObject>=0){
- CVect3<float> point(m_Data->getVertexAt(curObject).getXYZ());
- m_Pivot = point;
- m_Data->getVertexAt(curObject).doSelect(true);
- if (m_Handler) m_Handler->fireEvent(this, ITaxplot3dCP::eSelection);
- slowRedraw();
- }
- }
- }
- // all view transformations for ortho and perspective projections
- void CTaxplot3dPanel::transformView(void)
- {
- switch (m_ViewMode){
- case eCamera:
- m_Camera.SetLayout(CGlCamera::ePerspective);
- m_Camera.MakeCurrent();
-
- switch (m_PivotPoint){
- case eFloating:
- m_Transform.ApplyGL(CGlMTransform::eZoom);
- m_Transform.ApplyGL(CGlMTransform::ePan);
- m_Transform.ApplyGL(CGlMTransform::eRotate);
- break;
- case eFixed:
- m_Transform.ApplyGL(CGlMTransform::eZoom);
- m_Transform.ApplyGL(CGlMTransform::eRotate);
- m_Transform.ApplyGL(CGlMTransform::ePan);
- }
- glRotatef(45, 1,0,0); glRotatef(45, 0,-1,0);
- if (m_bPvAttach) glTranslatef(-m_Pivot.X(), -m_Pivot.Y(), -m_Pivot.Z());
- break;
- case eViewX:
- switch2ortho();
- m_Transform.ApplyGL(CGlMTransform::eTranslate);
- gluLookAt(0,0,0,-1,0,0,0,0,1);
- break;
- case eViewY:
- switch2ortho();
- m_Transform.ApplyGL(CGlMTransform::eTranslate);
- gluLookAt(0,0,0,0,-1,0,1,0,0);
- break;
- case eViewZ:
- switch2ortho();
- m_Transform.ApplyGL(CGlMTransform::eTranslate);
- gluLookAt(0,0,0,0,0,-1,0,1,0);
- break;
- }
- }
- void CTaxplot3dPanel::switch2ortho(void)
- {
- GLfloat ratio = (m_Transform.GetTranslation().Z())/2 - 0.8;
- m_Camera.SetLayout(CGlCamera::eOrtho);
- m_Camera.SetLeftPlane(ratio); m_Camera.SetRightPlane(-ratio);
- m_Camera.SetTopPlane(-ratio); m_Camera.SetBottomPlane(ratio);
- m_Camera.MakeCurrent();
- glTranslatef(-0.6f, -0.6f, 0);
- }
- void CTaxplot3dPanel::slowRedraw(void)
- {
- m_Dlist.Invalidate();
- redraw();
- }
- void CTaxplot3dPanel::drawScale(void)
- {
- float scaleSize = 0.07f;
- m_Camera.SetLayout(CGlCamera::eOrtho);
- m_Camera.SetLeftPlane(-1); m_Camera.SetRightPlane(1);
- m_Camera.SetTopPlane(1); m_Camera.SetBottomPlane(-1);
- m_Camera.MakeCurrent();
- glColor4f(0.0f,1.0f,0.5f,0.3f);
- // graph label
- string strViewMode = "Undefined";
- switch (m_ViewMode){
- case eViewX: strViewMode = "Ortho YZ"; break;
- case eViewY: strViewMode = "Ortho XZ"; break;
- case eViewZ: strViewMode = "Ortho XY"; break;
- case eCamera: strViewMode = "Perspective"; break;
- }
- m_Font_Bitmap8x13.TextOut(-0.9f, 0.9f, strViewMode.c_str());
- string strScale = NStr::DoubleToString(GetBestStep()*2) + " x " + NStr::DoubleToString(GetBestStep()*2);
- m_Font_Bitmap8x13.TextOut(-0.9f + scaleSize*2, 0.8f, strScale.c_str());
- glColor4f(1.0f,1.0f,1.0f, 0.3f);
- glBegin(GL_LINE_LOOP);
- glVertex3f(-0.9f, 0.8f, 0);
- glVertex3f(-0.9f + scaleSize, 0.8f, 0);
- glVertex3f(-0.9f + scaleSize, 0.8f + scaleSize, 0);
- glVertex3f(-0.9f, 0.8f + scaleSize, 0);
- glEnd();
- glColor4f(1.0f,1.0f,1.0f, 0.05f);
- glBegin(GL_LINES);
- glVertex3f(-0.9f + scaleSize/2, 0.8f, 0);
- glVertex3f(-0.9f + scaleSize/2, 0.8f+scaleSize, 0);
- glVertex3f(-0.9f, 0.8f + scaleSize/2, 0);
- glVertex3f(-0.9f + scaleSize, 0.8f + scaleSize/2, 0);
- glEnd();
-
- m_Camera.ReleaseCurrent();
- }
- double CTaxplot3dPanel::GetBestStep(bool bNorm)
- {
- int maxTicks = 20;
- int minTicks = 10;
- // step selection
- double scale = m_Data?m_Data->getScale():1;
- double log = ceil(log10(scale));
- double step = pow((double)10, log)/maxTicks;
- double step_n = step / scale;
- // minimum 10 ticks
- while (step_n > (1.0 / minTicks)) {step/=2; step_n/=2;}
- return bNorm?step_n:step;
- }
- // tooltips implementation
- bool CTaxplot3dPanel::TC_NeedTooltip(int x, int y)
- {
- return findObject(x, y) >= 0;
- }
- string CTaxplot3dPanel::TC_GetTooltip(int& x, int& y, int& w, int& h)
- {
- string toolTip = "";
- int currIndex = findObject(x, y);
- double scale = m_Data?m_Data->getScale():1;
- if (currIndex >= 0) {
- toolTip = "gi: " + NStr::IntToString(m_Data->getVertexAt(currIndex).getGi());
- toolTip += "nScores:";
- toolTip += ("n" + m_Data->xLabel() + ": " + NStr::IntToString(m_Data->getVertexAt(currIndex).getXYZ().X()*scale));
- toolTip += ("n" + m_Data->yLabel() + ": " + NStr::IntToString(m_Data->getVertexAt(currIndex).getXYZ().Y()*scale));
- toolTip += ("n" + m_Data->zLabel() + ": " + NStr::IntToString(m_Data->getVertexAt(currIndex).getXYZ().Z()*scale));
- }
- return toolTip;
- }
- END_NCBI_SCOPE
- /*
- * ===========================================================================
- * $Log: taxplot3d_pane.cpp,v $
- * Revision 1000.1 2004/06/01 21:13:45 gouriano
- * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.4
- *
- * Revision 1.4 2004/05/21 22:27:55 gorelenk
- * Added PCH ncbi_pch.hpp
- *
- * Revision 1.3 2004/01/28 15:56:29 tereshko
- * UI additions - scale, tooltips
- *
- * Revision 1.2 2004/01/14 16:39:22 tereshko
- * Minor changes due to integration with Taxplot viewer
- *
- * Revision 1.1 2004/01/05 16:20:49 tereshko
- * Initial revision
- *
- * ===========================================================================
- */