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
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
00033
00034
00035 vuTransferCanvas::~vuTransferCanvas()
00036 {
00037 }
00038
00039
00040
00041
00042
00043 vuTFDesign& vuTransferCanvas::getTransferFunc()
00044 {
00045 return m_TFunc;
00046 }
00047
00048
00049
00050
00051
00052 void vuTransferCanvas::setTransferFunc(const vuTFDesign& tf)
00053 {
00054 m_TFunc = tf;
00055 redraw();
00056 }
00057
00058
00059
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
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
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
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
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
00128
00129
00130 bool vuTransferCanvas::glInit(void)
00131 {
00132 glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
00133
00134
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
00146
00147
00148 void vuTransferCanvas::resize()
00149 {
00150 glViewport(0, 0, (GLint)getWidth(),(GLint)getHeight());
00151
00152
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
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
00174
00175
00176 void vuTransferCanvas::render()
00177 {
00178 glClear(GL_COLOR_BUFFER_BIT);
00179
00180
00181
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
00197 if (m_Edit)
00198 {
00199
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
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
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
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
00260
00261
00262 void vuTransferCanvas::OnMouse(wxMouseEvent &ev)
00263 {
00264 if (ev.ButtonDClick() && !m_Edit)
00265 {
00266
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)
00278 {
00279
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
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
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)
00311 {
00312
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
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
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
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)
00358 {
00359
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
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
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)
00394 {
00395
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
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
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
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 }