Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

vuTransferCanvas.cpp

Go to the documentation of this file.
00001 #include "vuTransferCanvas.h"
00002 #include "vuTransferDialog.h"
00003 #include <GL/gl.h>
00004 #include <GL/glu.h>
00005 #include <math.h>
00006 
00007 #include "vuColourRGBa.h"
00008 
00009 BEGIN_EVENT_TABLE(vuTransferCanvas, vuGLCanvas)
00010     EVT_MOUSE_EVENTS(vuTransferCanvas::OnMouse)
00011 END_EVENT_TABLE()
00012 
00013 //----------------------------------------------------------------------------
00014 //------------------------- The constructor ----------------------------------
00015 //----------------------------------------------------------------------------
00016 
00017 vuTransferCanvas::vuTransferCanvas(vuTFDesign &tf, wxWindow *parent,wxWindowID id,bool edit)
00018   : vuGLCanvas(parent,id,wxDefaultPosition,wxDefaultSize,0,"vuTransferCanvas",NULL)
00019     , m_TFunc(tf), m_Edit(edit),m_xMin(0),m_xMax(255),m_yMin(0),m_yMax(1) 
00020 {
00021     m_Opacity = m_Colour = (dword) -1;
00022 
00023     m_xScreenMin = m_xMin;
00024     m_xScreenMax = m_xMax;
00025     m_yScreenMin = m_yMin;
00026     m_yScreenMax = m_yMax;
00027 
00028     m_DoSpectral = (tf.getNComponents() != 4);
00029 }
00030 
00031 //----------------------------------------------------------------------------
00032 //------------------------- The destructor -----------------------------------
00033 //----------------------------------------------------------------------------
00034 
00035 vuTransferCanvas::~vuTransferCanvas()
00036 {
00037 }
00038 
00039 //----------------------------------------------------------------------------
00040 //------------------------- public: getTransferFunc() ------------------------
00041 //----------------------------------------------------------------------------
00042 
00043 vuTFDesign& vuTransferCanvas::getTransferFunc()
00044 {
00045     return m_TFunc;
00046 }
00047 
00048 //----------------------------------------------------------------------------
00049 //------------------------- public: setTransferFunc() ------------------------
00050 //----------------------------------------------------------------------------
00051 
00052 void vuTransferCanvas::setTransferFunc(const vuTFDesign& tf)
00053 {
00054     m_TFunc = tf;
00055     redraw();
00056 }
00057 
00058 //----------------------------------------------------------------------------
00059 //------------------------- public: setOpacitiesmoothing() -------------------
00060 //----------------------------------------------------------------------------
00061 
00062 void vuTransferCanvas::setSmoothing(float opacity, float colour)
00063 {
00064     m_TFunc.setOpacitySmoothing(opacity);
00065     m_TFunc.setColourSmoothing(colour);
00066     m_TFunc.generateFunction();
00067     redraw();
00068 }
00069 
00070 //----------------------------------------------------------------------------
00071 //------------------------- public: getActiveOpacity() -----------------------
00072 //----------------------------------------------------------------------------
00073 
00074 const vuTFDesign::OpacityNode *vuTransferCanvas::getActiveOpacity() const
00075 {
00076     if (m_Opacity==(dword)-1)
00077         return 0;
00078     else
00079         return &m_TFunc.getOpacity(m_Opacity);
00080 }
00081 
00082 //----------------------------------------------------------------------------
00083 //------------------------- public: setActiveOpacity() -----------------------
00084 //----------------------------------------------------------------------------
00085 
00086 void vuTransferCanvas::setActiveOpacity(const vuTFDesign::OpacityNode *cn)
00087 {
00088     if (m_Opacity!=(dword)-1)
00089     {
00090         m_TFunc.removeOpacity(m_Opacity);
00091         m_Opacity = m_TFunc.addOpacity(cn->intensity,cn->opacity);
00092 
00093         m_TFunc.generateFunction();
00094         redraw();
00095     }
00096 }
00097 
00098 //----------------------------------------------------------------------------
00099 //------------------------- public: getActiveColour() ------------------------
00100 //----------------------------------------------------------------------------
00101 
00102 const vuTFDesign::ColourNode *vuTransferCanvas::getActiveColour() const
00103 {
00104     if (m_Colour==(dword)-1)
00105         return 0;
00106     else
00107         return &m_TFunc.getColour(m_Colour);
00108 }
00109 
00110 //----------------------------------------------------------------------------
00111 //------------------------- public: setActiveColour() ------------------------
00112 //----------------------------------------------------------------------------
00113 
00114 void vuTransferCanvas::setActiveColour(const vuTFDesign::ColourNode *cn)
00115 {
00116     if (m_Colour!=(dword)-1)
00117     {
00118         m_TFunc.removeColour(m_Colour);
00119         m_Colour = m_TFunc.addColour(cn->intensity,cn->col);
00120 
00121         m_TFunc.generateFunction();
00122         redraw();
00123     }
00124 }
00125 
00126 //----------------------------------------------------------------------------
00127 //------------------------- protected: glInit() ------------------------------
00128 //----------------------------------------------------------------------------
00129 
00130 bool vuTransferCanvas::glInit(void)
00131 {
00132     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00133 
00134     //Set up the coordinate system.
00135     glMatrixMode(GL_MODELVIEW);
00136     glLoadIdentity();
00137     glMatrixMode(GL_PROJECTION);
00138     glLoadIdentity();
00139     gluOrtho2D(m_xScreenMin,m_xScreenMax,m_yScreenMin,m_yScreenMax);
00140 
00141     return true;
00142 };
00143 
00144 //----------------------------------------------------------------------------
00145 //------------------------- protected: resize() ------------------------------
00146 //----------------------------------------------------------------------------
00147 
00148 void vuTransferCanvas::resize()
00149 {
00150     glViewport(0, 0, (GLint)getWidth(),(GLint)getHeight());
00151 
00152     //Recalculate the grid values
00153     m_dx = float(m_xMax-m_xMin) / getWidth();
00154     m_dy = float(m_yMax-m_yMin) / getHeight();
00155 
00156     if (m_Edit)
00157     {
00158         //Fix the coordinate system.
00159         m_xScreenMin = m_xMin-10*m_dx;
00160         m_xScreenMax = m_xMax+10*m_dx;
00161         m_yScreenMin = m_yMin-30*m_dy;
00162         m_yScreenMax = m_yMax+10*m_dy;
00163 
00164         glMatrixMode(GL_MODELVIEW);
00165         glLoadIdentity();
00166         glMatrixMode(GL_PROJECTION);
00167         glLoadIdentity();
00168         gluOrtho2D(m_xScreenMin,m_xScreenMax,m_yScreenMin,m_yScreenMax);
00169     }
00170 }
00171 
00172 //----------------------------------------------------------------------------
00173 //------------------------- protected: render() ------------------------------
00174 //----------------------------------------------------------------------------
00175 
00176 void vuTransferCanvas::render()
00177 {
00178     glClear(GL_COLOR_BUFFER_BIT);
00179 
00180     //First fill in the graph.
00181     //Draw the colour regions
00182     glBegin(GL_QUADS);
00183     for (dword i = m_xMin; i <= m_xMax; i++)
00184     {
00185         vuColourRGBa rgba;
00186         m_TFunc.getRGBa(i,rgba);
00187 
00188         glColor3fv(rgba.getData());
00189         glVertex2f(i-0.5,-20*m_dy);
00190         glVertex2f(i+0.5,-20*m_dy);
00191         glVertex2f(i+0.5,m_TFunc.getOpacityAtPos(i+1));
00192         glVertex2f(i-0.5,m_TFunc.getOpacityAtPos(i));
00193     }
00194     glEnd();
00195 
00196     //When editing, draw all the helper lines
00197     if (m_Edit)
00198     {
00199         //Draw the surrounding box
00200         glBegin(GL_LINE_LOOP);
00201         glColor3f(1,1,1);
00202         glVertex2f(m_xMin,m_yMin-20*m_dy);
00203         glVertex2f(m_xMax,m_yMin-20*m_dy);
00204         glVertex2f(m_xMax,m_yMax);
00205         glVertex2f(m_xMin,m_yMax);
00206         glEnd();
00207 
00208         //Draw the polyline opacity function.
00209         glBegin(GL_LINE_STRIP);
00210         glColor3f(1,1,1);
00211         dword numOpacities = m_TFunc.getNumOpacities();
00212         for (dword i = 0; i < numOpacities; i++)
00213         {
00214             vuTFDesign::OpacityNode cp = m_TFunc.getOpacity(i);
00215             glVertex2f(cp.intensity,cp.opacity);
00216         }
00217         glEnd();
00218 
00219         //Draw the opacity control nodes.
00220         for (dword i = 0; i < numOpacities; i++)
00221         {
00222             if (i == m_Opacity)
00223                 glColor4f(1,0.5,0.5,0.01);
00224             else
00225                 glColor4f(1,1,1,0.01);
00226 
00227             vuTFDesign::OpacityNode cp = m_TFunc.getOpacity(i);
00228 
00229             glBegin(GL_LINE_LOOP);
00230             glVertex2f(cp.intensity-3*m_dx,cp.opacity-3*m_dy);
00231             glVertex2f(cp.intensity+3*m_dx,cp.opacity-3*m_dy);
00232             glVertex2f(cp.intensity+3*m_dx,cp.opacity+3*m_dy);
00233             glVertex2f(cp.intensity-3*m_dx,cp.opacity+3*m_dy);
00234             glEnd();
00235         }
00236 
00237         //Draw the colour control nodes.
00238         dword numColours = m_TFunc.getNumColours();
00239         for (dword i = 0; i < numColours; i++)
00240         {
00241             if (i == m_Colour)
00242                 glColor4f(1,0.5,0.5,0.01);
00243             else
00244                 glColor4f(1,1,1,0.01);
00245 
00246             vuTFDesign::ColourNode cp = m_TFunc.getColour(i);
00247 
00248             glBegin(GL_LINE_LOOP);
00249             glVertex2f(cp.intensity-3*m_dx,-23*m_dy);
00250             glVertex2f(cp.intensity+3*m_dx,-23*m_dy);
00251             glVertex2f(cp.intensity+3*m_dx,-17*m_dy);
00252             glVertex2f(cp.intensity-3*m_dx,-17*m_dy);
00253             glEnd();
00254         }
00255     }
00256 };
00257 
00258 //----------------------------------------------------------------------------
00259 //------------------------- protected: OnMouse() -----------------------------
00260 //----------------------------------------------------------------------------
00261 
00262 void vuTransferCanvas::OnMouse(wxMouseEvent &ev)
00263 {
00264     if (ev.ButtonDClick() && !m_Edit)
00265     {
00266         //Pop up dialog Canvas that lets you edit
00267         vuTransferDialog dlg(this,m_TFunc);
00268 
00269         if (dlg.ShowModal() == wxID_OK)
00270         {
00271             m_TFunc = dlg.getTransferFunc();
00272 
00273             postEvent(vuEVT_TRANSFER_CHANGE);
00274             redraw();
00275         }
00276     }
00277     else if (ev.LeftDown() && m_Edit) //Select the clicked control Node
00278     {
00279         //Translate into graph coordinates
00280         float x = (float(ev.GetX()) / getWidth()) * float(m_xScreenMax - m_xScreenMin) + m_xScreenMin;
00281         float y = (float(getHeight() - ev.GetY()) / getHeight()) * float(m_yScreenMax - m_yScreenMin) + m_yScreenMin;
00282 
00283         m_Opacity = m_Colour = (dword)-1;
00284 
00285         //Find out if there is an associated Opacity Node and store it
00286         for (dword i = 0; i < m_TFunc.getNumOpacities(); i++)
00287         {
00288             const vuTFDesign::OpacityNode &cp = m_TFunc.getOpacity(i);
00289             if ((fabs(cp.intensity-x) < 4*m_dx) && (fabs(cp.opacity-y) < 4*m_dy))
00290             {
00291                 m_Opacity = i;
00292                 break;
00293             }
00294         }
00295 
00296         //Find out if there is an associated colour Node and store it
00297         for (dword i = 0; i < m_TFunc.getNumColours(); i++)
00298         {
00299             const vuTFDesign::ColourNode &cp = m_TFunc.getColour(i);
00300             if ((fabs(cp.intensity-x) < 4*m_dx) && (fabs(-m_dy*20-y) < 4*m_dy))
00301             {
00302                 m_Colour = i;
00303                 break;
00304             }
00305         }
00306 
00307         postEvent(vuEVT_TRANSFER_NODE_SELECT);
00308         redraw();
00309     }
00310     else if (ev.LeftDClick() && m_Edit) //Create and/or open up control Node
00311     {
00312         //Translate click into graph coordinates
00313         float x = (float(ev.GetX()) / getWidth()) * float(m_xScreenMax - m_xScreenMin) + m_xScreenMin;
00314         float y = (float(getHeight() - ev.GetY()) / getHeight()) * float(m_yScreenMax - m_yScreenMin) + m_yScreenMin;
00315 
00316         //If in the graph range, open the clicked Opacity node, or add a new one
00317         if ((m_Opacity != (dword)-1) && 
00318             (fabs(m_TFunc.getOpacity(m_Opacity).intensity-x) < 4*m_dx) &&
00319             (fabs(m_TFunc.getOpacity(m_Opacity).opacity - y) < 4*m_dy))
00320         {
00321             postEvent(vuEVT_TRANSFER_NODE_OPEN);
00322         }
00323         else if (( x >= m_xMin && x <= m_xMax) && (y >= m_yMin && y <= m_yMax))
00324         {
00325             m_Opacity = m_TFunc.addOpacity((byte)x,y);
00326             m_Colour = (dword)-1;
00327 
00328             m_TFunc.generateFunction();
00329             postEvent(vuEVT_TRANSFER_CHANGE);
00330             postEvent(vuEVT_TRANSFER_NODE_OPEN);
00331             redraw();
00332         }
00333 
00334         //If in the colour range, open the clicked colour node, or add a new one
00335         if ((m_Colour != (dword)-1) && 
00336             (fabs(m_TFunc.getColour(m_Colour).intensity-x) < 4*m_dx) &&
00337             (-20*m_dy - y < 4*m_dy))
00338         {
00339             postEvent(vuEVT_TRANSFER_NODE_OPEN);
00340         }
00341         else if (( x >= m_xMin && x <= m_xMax) && (fabs(-20*m_dy-y) < 4*m_dy))
00342         {
00343           if(m_DoSpectral) {
00344             // This has to be changed!
00345             m_Colour = m_TFunc.addColour((byte)x,vuColourRGBa(0.f));
00346           } else {
00347             m_Colour = m_TFunc.addColour((byte)x,vuColourRGBa(0.f));
00348           }
00349             m_Opacity = (dword)-1;
00350             
00351             m_TFunc.generateFunction();
00352             postEvent(vuEVT_TRANSFER_CHANGE);    
00353             postEvent(vuEVT_TRANSFER_NODE_OPEN);
00354             redraw();
00355         }
00356     }
00357     else if (ev.RightDClick() && m_Edit) //Remove control Node
00358     {
00359         //Translate click into graph coordinates
00360         float x = (float(ev.GetX()) / getWidth()) * float(m_xScreenMax - m_xScreenMin) + m_xScreenMin;
00361         float y = (float(getHeight() - ev.GetY()) / getHeight()) * float(m_yScreenMax - m_yScreenMin) + m_yScreenMin;
00362 
00363         //Find out if there is an associated Opacity Node and remove it
00364         for (dword i = 0; i < m_TFunc.getNumOpacities(); i++)
00365         {
00366             const vuTFDesign::OpacityNode &cp = m_TFunc.getOpacity(i);
00367             if ((fabs(cp.intensity-x) < 4*m_dx) && (fabs(cp.opacity-y) < 4*m_dy))
00368             {
00369                 m_TFunc.removeOpacity(i);
00370                 if (i==m_Opacity) m_Opacity = (dword)-1;
00371                 
00372                 m_TFunc.generateFunction();
00373                 postEvent(vuEVT_TRANSFER_CHANGE);
00374                 redraw();
00375             }
00376         }
00377 
00378         //Find out if there is an associated colour Node and remove it
00379         for (dword i = 0; i < m_TFunc.getNumColours(); i++)
00380         {
00381             const vuTFDesign::ColourNode &cp = m_TFunc.getColour(i);
00382             if ((fabs(cp.intensity-x) < 4*m_dx) && (fabs(-20*m_dy-y) < 4*m_dy))
00383             {
00384                 m_TFunc.removeColour(i);
00385                 if (i==m_Colour) m_Colour = (dword)-1;
00386 
00387                 m_TFunc.generateFunction();
00388                 postEvent(vuEVT_TRANSFER_CHANGE);
00389                 redraw();
00390             }
00391         }
00392     }
00393     else if (ev.LeftIsDown() && ev.Dragging() && m_Edit) //Drag the selected control node
00394     {
00395         //Translate into graph coordinates
00396         float x = (float(ev.GetX()) / getWidth()) * float(m_xScreenMax - m_xScreenMin) + m_xScreenMin;
00397         float y = (float(getHeight() - ev.GetY()) / getHeight()) * float(m_yScreenMax - m_yScreenMin) + m_yScreenMin;
00398 
00399         //Update the dragged Opacity Node, if any.
00400         if ((m_Opacity != (dword)-1) && 
00401             (x >= m_xMin) && (x <= m_xMax) && (y >= m_yMin) && (y <= m_yMax) && 
00402             (m_Opacity == 0 || (byte)x > m_TFunc.getOpacity(m_Opacity-1).intensity) && 
00403             (m_Opacity == m_TFunc.getNumOpacities()-1 || (byte)x < m_TFunc.getOpacity(m_Opacity+1).intensity))
00404         {
00405             if (m_Opacity == 0)
00406                 m_TFunc.addOpacity(m_xMin,y);
00407             else if (m_Opacity == m_TFunc.getNumOpacities()-1)
00408                 m_TFunc.addOpacity(m_xMax,y);
00409             else
00410             {
00411                 m_TFunc.removeOpacity(m_Opacity);
00412                 m_TFunc.addOpacity((byte)x,y);
00413             }
00414            
00415             m_TFunc.generateFunction();
00416             postEvent(vuEVT_TRANSFER_CHANGE);
00417             redraw();
00418         }
00419 
00420         //Update the dragged colour Node, if any.
00421         if ((m_Colour != (dword)-1) && (m_Colour != m_TFunc.getNumColours() - 1) &&
00422             (x >= m_xMin) && (x <= m_xMax) && 
00423             (m_Colour == 0 || (byte)x > m_TFunc.getColour(m_Colour-1).intensity) && 
00424             ((byte)x < m_TFunc.getColour(m_Colour+1).intensity))
00425         {
00426             vuTFDesign::ColourNode cp = m_TFunc.getColour(m_Colour);
00427             m_TFunc.removeColour(m_Colour);
00428             m_TFunc.addColour((byte)x, cp.col);
00429             
00430             m_TFunc.generateFunction();
00431             postEvent(vuEVT_TRANSFER_CHANGE);
00432             redraw();
00433         }
00434     }
00435 }
00436 
00437 //----------------------------------------------------------------------------
00438 //------------------------- protected: postEvent() ---------------------------
00439 //----------------------------------------------------------------------------
00440 
00441 void vuTransferCanvas::postEvent(wxEventType ev)
00442 {
00443      wxCommandEvent commandEvent(ev, GetId());
00444      commandEvent.SetEventObject( this );
00445      commandEvent.SetClientData(&m_TFunc);
00446      GetEventHandler()->ProcessEvent(commandEvent);   
00447 }

Generated on Wed Dec 15 21:20:38 2004 for vuVolume by  doxygen 1.3.9.1