source: src/UIElements/Views/Qt4/GLMoleculeView.cpp@ 29daad

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 Candidate_v1.7.0 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 29daad was 29daad, checked in by Frederik Heber <heber@…>, 14 years ago

Added rudimentarily working GlMoleculeView (class was empty before).

  • We took over the code from (ancient) branch MolecuilderGUI and adapated it to the current standards. Atoms are drawn, bonds in some so far wrong direction as well.
  • Note that the guz has trouble showing dialogs for all Actions. This should be some minor bug.
  • Property mode set to 100644
File size: 30.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * GLMoleculeView.cpp
10 *
11 * Created on: Aug 1, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "GLMoleculeView.hpp"
21#include <GL/glu.h>
22#include <QtGui/qslider.h>
23#include <QtGui/qevent.h>
24
25#include "ui_dialoglight.h"
26
27#include "CodePatterns/MemDebug.hpp"
28
29#include <iostream>
30
31#include "LinearAlgebra/Line.hpp"
32#include "atom.hpp"
33#include "Bond/bond.hpp"
34#include "element.hpp"
35#include "molecule.hpp"
36#include "periodentafel.hpp"
37#include "World.hpp"
38
39#if defined(Q_CC_MSVC)
40#pragma warning(disable:4305) // init: truncation from const double to float
41#endif
42
43
44GLMoleculeView::GLMoleculeView(QWidget *parent) :
45 QGLWidget(parent), Observer("GLMoleculeView"), X(Vector(1,0,0)), Y(Vector(0,1,0)), Z(Vector(0,0,1))
46{
47 xRot = yRot = zRot = 0.0; // default object rotation
48 scale = 5.; // default object scale
49 object = 0;
50 LightPosition[0] = 0.0f;
51 LightPosition[1] = 2.0f;
52 LightPosition[2] = 2.0f;
53 LightPosition[3] = 0.0f;
54 LightDiffuse[0] = 0.5f;
55 LightDiffuse[1] = 0.5f;
56 LightDiffuse[2] = 0.5f;
57 LightDiffuse[3] = 0.0f;
58 LightAmbient[0] = 0.0f;
59 LightAmbient[1] = 0.0f;
60 LightAmbient[2] = 0.0f;
61 LightAmbient[3] = 0.0f;
62
63 SelectionColor[0] = 0;
64 SelectionColor[1] = 128;
65 SelectionColor[2] = 128;
66
67 MultiViewEnabled = true;
68
69 isSignaller = false;
70
71 World::getInstance().signOn(this);
72}
73
74/** Destructor of GLMoleculeView.
75 * Free's the CallList.
76 */
77GLMoleculeView::~GLMoleculeView()
78{
79 makeCurrent();
80 glDeleteLists( object, 1 );
81
82 World::getInstance().signOff(this);
83}
84
85/** Paints the conents of the OpenGL window.
86 * Clears the GL buffers, enables lighting and depth.
87 * Window is either quartered (if GLMoleculeView::MultiViewEnabled) and xy, xz, yz planar views
88 * are added. Uses the CallList, constructed during InitializeGL().
89 */
90void GLMoleculeView::paintGL()
91{
92 Vector spot;
93
94 glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
95 glShadeModel(GL_SMOOTH); // Enable Smooth Shading
96 glEnable(GL_LIGHTING); // Enable Light One
97 glEnable(GL_DEPTH_TEST); // Enables Depth Testing
98 glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
99 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
100
101 // 3d viewport
102 if (MultiViewEnabled)
103 glViewport( 0, 0, (GLint)width/2, (GLint)height/2 );
104 else
105 glViewport( 0, 0, (GLint)width, (GLint)height );
106 glMatrixMode( GL_PROJECTION );
107 glLoadIdentity();
108 glFrustum( -1.0, 1.0, -1.0, 1.0, 1.0, 50.0 );
109 glMatrixMode( GL_MODELVIEW );
110 glLoadIdentity();
111
112 // calculate point of view and direction
113 glTranslated(position[0],position[1],position[2]);
114 glTranslated(0.0, 0.0, -scale);
115 glRotated(xRot, 1.0, 0.0, 0.0);
116 glRotated(yRot, 0.0, 1.0, 0.0);
117 glRotated(zRot, 0.0, 0.0, 1.0);
118
119 // render scene
120 glCallList(object);
121
122 // enable light
123 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
124 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
125 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
126 glEnable(GL_LIGHT1); // Enable Light One
127
128 if (MultiViewEnabled) {
129 // xy view port
130 glViewport( (GLint)width/2, 0, (GLint)width/2, (GLint)height/2 );
131 glMatrixMode( GL_PROJECTION );
132 glLoadIdentity();
133 glScalef(1./scale, 1./scale,1./scale);
134 glOrtho(0, width/2, 0, height/2, 0,0);
135 glMatrixMode( GL_MODELVIEW );
136 glLoadIdentity();
137
138 // calculate point of view and direction
139 view = position;
140 spot = Vector(0.,0.,scale);
141 top = Vector(0.,1.,0.);
142 gluLookAt(
143 spot[0], spot[1], spot[2],
144 view[0], view[1], view[2],
145 top[0], top[1], top[2]);
146
147 // enable light
148 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
149 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
150 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
151 glEnable(GL_LIGHT1); // Enable Light One
152
153 // render scene
154 glCallList(object);
155
156 // xz viewport
157 glViewport( 0, (GLint)height/2, (GLint)width/2, (GLint)height/2 );
158 glMatrixMode( GL_PROJECTION );
159 glLoadIdentity();
160 glScalef(1./scale, 1./scale,1./scale);
161 glOrtho(0, width/2, 0, height/2, 0,0);
162 glMatrixMode( GL_MODELVIEW );
163 glLoadIdentity();
164
165 // calculate point of view and direction
166 view = position;
167 spot = Vector(0.,scale,0.);
168 top = Vector(1.,0.,0.);
169 gluLookAt(
170 spot[0], spot[1], spot[2],
171 view[0], view[1], view[2],
172 top[0], top[1], top[2]);
173
174 // enable light
175 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
176 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
177 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
178 glEnable(GL_LIGHT1); // Enable Light One
179
180 // render scene
181 glCallList(object);
182
183 //yz viewport
184 glViewport( (GLint)width/2, (GLint)height/2, (GLint)width/2, (GLint)height/2 );
185 glMatrixMode( GL_PROJECTION );
186 glLoadIdentity();
187 glScalef(1./scale, 1./scale,1./scale);
188 glOrtho(0, width/2, 0, height/2, 0,0);
189 glMatrixMode( GL_MODELVIEW );
190 glLoadIdentity();
191
192 // calculate point of view and direction
193 view= position;
194 spot = Vector(scale,0.,0.);
195 top = Vector(0.,1.,0.);
196 gluLookAt(
197 spot[0], spot[1], spot[2],
198 view[0], view[1], view[2],
199 top[0], top[1], top[2]);
200
201 // enable light
202 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
203 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
204 glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
205 glEnable(GL_LIGHT1); // Enable Light One
206
207 // render scene
208 glCallList(object);
209 }
210 //CoordinatesBar->setText( QString ("X: %1, Y: %2, Z: %3").arg(position[0]).arg(position[1]).arg(position[2]) );
211}
212
213//void polarView{GLdouble distance, GLdouble twist,
214// GLdouble elevation, GLdouble azimuth)
215//{
216// glTranslated(0.0, 0.0, -distance);
217// glRotated(-twist, 0.0, 0.0, 1.0);
218// glRotated(-elevation, 1.0, 0.0, 0.0);
219// glRotated(azimuth, 0.0, 0.0, 1.0);
220//}
221
222/** Make a sphere.
223 * \param x position
224 * \param radius radius
225 * \param color[3] color rgb values
226 */
227void GLMoleculeView::makeSphere(const Vector &x, double radius, const unsigned char color[3])
228{
229 float blueMaterial[] = { 255./(float)color[0], 255./(float)color[1], 255./(float)color[2], 1 }; // need to recast from [0,255] with integers into [0,1] with floats
230 GLUquadricObj* q = gluNewQuadric ();
231
232 std::cout << "Setting sphere at " << x << " with color r"
233 << (int)color[0] << ",g" << (int)color[1] << ",b" << (int)color[2] << "." << endl;
234
235 glPushMatrix();
236 glTranslatef( x[0], x[1], x[2]);
237// glRotatef( xRot, 1.0, 0.0, 0.0);
238// glRotatef( yRot, 0.0, 1.0, 0.0);
239// glRotatef( zRot, 0.0, 0.0, 1.0);
240 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blueMaterial);
241 gluSphere (q, (GLdouble)radius, 10, 10);
242 glPopMatrix();
243}
244
245/** Make a cylinder.
246 * \param x origin
247 * \param y direction
248 * \param radius thickness
249 * \param height length
250 * \color[3] color rgb values
251 */
252void GLMoleculeView::makeCylinder(const Vector &x, const Vector &y, double radius, double height, const unsigned char color[3])
253{
254 float blueMaterial[] = { 255./(float)color[0], 255./(float)color[1], 255./(float)color[2], 1 };
255 GLUquadricObj* q = gluNewQuadric ();
256 Vector a,b;
257 double alpha;
258 a = x - b;
259 b.GetOneNormalVector(a);
260 b.MakeNormalTo(Z);
261 alpha = a.Angle(Z);
262 if (fabs(a[2]) > MYEPSILON) // I have no idea why I need to check this, but this fixes the sign problem of the rotation angle
263 alpha = M_PI-alpha;
264 Line axis(zeroVec, b);
265 a = axis.rotateVector(a, alpha);
266 std::cout << "Setting cylinder from " << x << " to " << a << " with color r"
267 << (int)color[0] << ",g" << (int)color[1] << ",b" << (int)color[2] << "." << endl;
268
269 glPushMatrix();
270 glTranslatef( x[0], x[1], x[2]);
271 glRotatef( alpha/M_PI*180., b[0], b[1], b[2]);
272 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blueMaterial);
273 gluCylinder (q, (GLdouble)radius, (GLdouble)radius, (GLdouble)height, 10, 10);
274 glPopMatrix();
275}
276
277/** Defines the display CallList.
278 * Goes through all molecules and their atoms and adds spheres for atoms and cylinders
279 * for bonds. Heeds GLMoleculeView::SelectedAtom and GLMoleculeView::SelectedMolecule.
280 */
281void GLMoleculeView::initializeGL()
282{
283 double x[3] = {-1, 0, -10};
284 unsigned char white[3] = {255,255,255};
285 Vector Position, OtherPosition;
286 QSize window = size();
287 width = window.width();
288 height = window.height();
289 std::cout << "Setting width to " << width << " and height to " << height << std::endl;
290 GLfloat shininess[] = { 0.0 };
291 GLfloat specular[] = { 0, 0, 0, 1 };
292 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Let OpenGL clear to black
293 object = glGenLists(1);
294 glNewList( object, GL_COMPILE );
295 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
296 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
297
298 const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
299
300 if (molecules.size() > 0) {
301 for (std::vector<molecule*>::const_iterator Runner = molecules.begin();
302 Runner != molecules.end();
303 Runner++) {
304 for (molecule::const_iterator atomiter = (*Runner)->begin();
305 atomiter != (*Runner)->end();
306 ++atomiter) {
307 // create atom
308 const element *ptr = (*atomiter)->getType();
309 molecule::const_iterator moliter = (*Runner)->begin();
310 Position = (*atomiter)->getPosition() - (*moliter)->getPosition();
311 const unsigned char* color = NULL;
312 if ((World::getInstance().isSelected(*atomiter)) || (World::getInstance().isSelected((*Runner))))
313 color = SelectionColor;
314 else
315 color = ptr->getColor();
316 makeSphere(Position, ptr->getVanDerWaalsRadius()*0.25, color);
317
318 // create bonds
319 const BondList &bonds = (*atomiter)->getListOfBonds();
320 for (BondList::const_iterator bonditer = bonds.begin();
321 bonditer != bonds.end();
322 ++bonditer) {
323 if ((*bonditer)->leftatom->getId() == (*atomiter)->getId()) {
324 Position = (*bonditer)->leftatom->getPosition() - (*moliter)->getPosition();
325 OtherPosition = (*bonditer)->rightatom->getPosition() - (*moliter)->getPosition();
326 const double distance = sqrt(Position.DistanceSquared(OtherPosition))/2.;
327 const unsigned char *color1 = (*bonditer)->leftatom->getType()->getColor();
328 const unsigned char *color2 = (*bonditer)->rightatom->getType()->getColor();
329 makeCylinder(Position, OtherPosition, 0.1, distance, color1);
330 makeCylinder(OtherPosition, Position, 0.1, distance, color2);
331 }
332 }
333 }
334 }
335 } else {
336 makeSphere( x,1, white);
337 }
338 glEndList();
339}
340
341
342/* ================================== SLOTS ============================== */
343
344/** Initializes some public variables.
345 * \param *ptr pointer to QLabel statusbar
346 */
347void GLMoleculeView::init(QLabel *ptr)
348{
349 StatusBar = ptr;
350}
351
352/** Initializes the viewport statusbar.
353 * \param *ptr pointer to QLabel for showing view pointcoordinates.
354 */
355void GLMoleculeView::initCoordinates(QLabel *ptr)
356{
357 CoordinatesBar = ptr;
358}
359
360/** Slot to be called when to initialize GLMoleculeView::MolData.
361 */
362void GLMoleculeView::createView( )
363{
364 initializeGL();
365 updateGL();
366}
367
368/** Slot of window is resized.
369 * Copies new width and height to GLMoleculeView::width and GLMoleculeView::height and calls updateGL().
370 * \param w new width of window
371 * \param h new height of window
372 */
373void GLMoleculeView::resizeGL( int w, int h )
374{
375 width = w;
376 height = h;
377 updateGL();
378}
379
380/** Sets x rotation angle.
381 * sets GLMoleculeView::xRot and calls updateGL().
382 * \param degrees new rotation angle in degrees
383 */
384void GLMoleculeView::setXRotation( int degrees )
385{
386 xRot = (GLfloat)(degrees % 360);
387 updateGL();
388}
389
390
391/** Sets y rotation angle.
392 * sets GLMoleculeView::yRot and calls updateGL().
393 * \param degrees new rotation angle in degrees
394 */
395void GLMoleculeView::setYRotation( int degrees )
396{
397 yRot = (GLfloat)(degrees % 360);
398 updateGL();
399}
400
401
402/** Sets z rotation angle.
403 * sets GLMoleculeView::zRot and calls updateGL().
404 * \param degrees new rotation angle in degrees
405 */
406void GLMoleculeView::setZRotation( int degrees )
407{
408 zRot = (GLfloat)(degrees % 360);
409 updateGL();
410}
411
412/** Sets the scale of the scene.
413 * sets GLMoleculeView::scale and calls updateGL().
414 * \param distance distance divided by 100 is the new scale
415 */
416void GLMoleculeView::setScale( int distance )
417{
418 scale = (GLfloat)(distance / 100.);
419 updateGL();
420}
421
422/** Update the ambient light.
423 * \param light[4] light strength per axis and position (w)
424 */
425void GLMoleculeView::setLightAmbient( int *light )
426{
427 for(int i=0;i<4;i++)
428 LightAmbient[i] = light[i];
429 updateGL();
430}
431
432/** Update the diffuse light.
433 * \param light[4] light strength per axis and position (w)
434 */
435void GLMoleculeView::setLightDiffuse( int *light )
436{
437 for(int i=0;i<4;i++)
438 LightDiffuse[i] = light[i];
439 updateGL();
440}
441
442/** Update the position of light.
443 * \param light[4] light strength per axis and position (w)
444 */
445void GLMoleculeView::setLightPosition( int *light )
446{
447 for(int i=0;i<4;i++)
448 LightPosition[i] = light[i];
449 updateGL();
450}
451
452/** Toggles the boolean GLMoleculeView::MultiViewEnabled.
453 * Flips the boolean and calls updateGL().
454 */
455void GLMoleculeView::toggleMultiViewEnabled ( )
456{
457 MultiViewEnabled = !MultiViewEnabled;
458 cout << "Setting MultiView to " << MultiViewEnabled << "." << endl;
459 updateGL();
460}
461
462/** Launch a dialog to configure the lights.
463 */
464void GLMoleculeView::createDialogLight()
465{
466// Ui_DialogLight *Lights = new Ui_DialogLight();
467// if (Lights == NULL)
468// return;
469// // Set up the dynamic dialog here
470// QLineEdit *Field = NULL;
471// Field = Lights->findChild<QLineEdit *>("LightPositionX");
472// if (Field) Field->setText( QString("%1").arg(LightPosition[0]) );
473// Field = Lights->findChild<QLineEdit *>("LightPositionY");
474// if (Field) Field->setText( QString("%1").arg(LightPosition[1]) );
475// Field = Lights->findChild<QLineEdit *>("LightPositionZ");
476// if (Field) Field->setText( QString("%1").arg(LightPosition[2]) );
477// Field = Lights->findChild<QLineEdit *>("LightPositionW");
478// if (Field) Field->setText( QString("%1").arg(LightPosition[3]) );
479//
480// Field = Lights->findChild<QLineEdit *>("LightDiffuseX");
481// if (Field) Field->setText( QString("%1").arg(LightDiffuse[0]) );
482// Field = Lights->findChild<QLineEdit *>("LightDiffuseY");
483// if (Field) Field->setText( QString("%1").arg(LightDiffuse[1]) );
484// Field = Lights->findChild<QLineEdit *>("LightDiffuseZ");
485// if (Field) Field->setText( QString("%1").arg(LightDiffuse[2]) );
486// Field = Lights->findChild<QLineEdit *>("LightDiffuseW");
487// if (Field) Field->setText( QString("%1").arg(LightDiffuse[3]) );
488//
489// Field = Lights->findChild<QLineEdit *>("LightAmbientX");
490// if (Field) Field->setText( QString("%1").arg(LightAmbient[0]) );
491// Field = Lights->findChild<QLineEdit *>("LightAmbientY");
492// if (Field) Field->setText( QString("%1").arg(LightAmbient[1]) );
493// Field = Lights->findChild<QLineEdit *>("LightAmbientZ");
494// if (Field) Field->setText( QString("%1").arg(LightAmbient[2]) );
495// Field = Lights->findChild<QLineEdit *>("LightAmbientW");
496// if (Field) Field->setText( QString("%1").arg(LightAmbient[3]) );
497//
498// if ( Lights->exec() ) {
499// //cout << "User accepted.\n";
500// // The user accepted, act accordingly
501// Field = Lights->findChild<QLineEdit *>("LightPositionX");
502// if (Field) LightPosition[0] = Field->text().toDouble();
503// Field = Lights->findChild<QLineEdit *>("LightPositionY");
504// if (Field) LightPosition[1] = Field->text().toDouble();
505// Field = Lights->findChild<QLineEdit *>("LightPositionZ");
506// if (Field) LightPosition[2] = Field->text().toDouble();
507// Field = Lights->findChild<QLineEdit *>("LightPositionW");
508// if (Field) LightPosition[3] = Field->text().toDouble();
509//
510// Field = Lights->findChild<QLineEdit *>("LightDiffuseX");
511// if (Field) LightDiffuse[0] = Field->text().toDouble();
512// Field = Lights->findChild<QLineEdit *>("LightDiffuseY");
513// if (Field) LightDiffuse[1] = Field->text().toDouble();
514// Field = Lights->findChild<QLineEdit *>("LightDiffuseZ");
515// if (Field) LightDiffuse[2] = Field->text().toDouble();
516// Field = Lights->findChild<QLineEdit *>("LightDiffuseW");
517// if (Field) LightDiffuse[3] = Field->text().toDouble();
518//
519// Field = Lights->findChild<QLineEdit *>("LightAmbientX");
520// if (Field) LightAmbient[0] = Field->text().toDouble();
521// Field = Lights->findChild<QLineEdit *>("LightAmbientY");
522// if (Field) LightAmbient[1] = Field->text().toDouble();
523// Field = Lights->findChild<QLineEdit *>("LightAmbientZ");
524// if (Field) LightAmbient[2] = Field->text().toDouble();
525// Field = Lights->findChild<QLineEdit *>("LightAmbientW");
526// if (Field) LightAmbient[3] = Field->text().toDouble();
527// updateGL();
528// } else {
529// //cout << "User reclined.\n";
530// }
531// delete(Lights);
532}
533
534/** Slot for event of pressed mouse button.
535 * Switch discerns between buttons and stores position of event in GLMoleculeView::LeftButtonPos,
536 * GLMoleculeView::MiddleButtonPos or GLMoleculeView::RightButtonPos.
537 * \param *event structure containing information of the event
538 */
539void GLMoleculeView::mousePressEvent(QMouseEvent *event)
540{
541 std::cout << "MousePressEvent." << endl;
542 QPoint *pos = NULL;
543 switch (event->button()) { // get the right array
544 case Qt::LeftButton:
545 pos = &LeftButtonPos;
546 std::cout << "Left Button" << endl;
547 break;
548 case Qt::MidButton:
549 pos = &MiddleButtonPos;
550 std::cout << "Middle Button" << endl;
551 break;
552 case Qt::RightButton:
553 pos = &RightButtonPos;
554 std::cout << "Right Button" << endl;
555 break;
556 default:
557 break;
558 }
559 if (pos) { // store the position
560 pos->setX(event->pos().x());
561 pos->setY(event->pos().y());
562 std::cout << "Stored src position is (" << pos->x() << "," << pos->y() << ")." << endl;
563 } else {
564 std::cout << "pos is NULL." << endl;
565 }
566}
567
568/** Slot for event of pressed mouse button.
569 * Switch discerns between buttons:
570 * -# Left Button: Rotates the view of the GLMoleculeView, relative to GLMoleculeView::LeftButtonPos.
571 * -# Middle Button: nothing
572 * -# Right Button: Shifts the selected molecule or atom, relative to GLMoleculeView::RightButtonPos.
573 * \param *event structure containing information of the event
574 */
575void GLMoleculeView::mouseReleaseEvent(QMouseEvent *event)
576{
577 std::cout << "MouseReleaseEvent." << endl;
578 QPoint *srcpos = NULL;
579 QPoint destpos = event->pos();
580 int Width = (MultiViewEnabled) ? width/2 : width;
581 int Height = (MultiViewEnabled) ? height/2 : height;
582 std::cout << "Received dest position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
583 switch (event->button()) { // get the right array
584 case Qt::LeftButton: // LeftButton rotates the view
585 srcpos = &LeftButtonPos;
586 std::cout << "Left Button" << endl;
587 if (srcpos) { // subtract the position and act
588 std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
589 destpos -= *srcpos;
590 std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
591 std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
592
593 int pos = (int)floor((double)srcpos->x()/(double)Width) + ((int)floor((double)srcpos->y()/(double)Height))*2;
594 if ((MultiViewEnabled) && (pos != 2)) { // means four regions, and we are in a shifting one
595 // switch between three regions
596 // decide into which of the four screens the initial click has been made
597 std::cout << "Position is " << pos << "." << endl;
598 switch(pos) {
599 case 0: // lower left = xz
600 position[0] += -destpos.y()/100.;
601 position[2] += destpos.x()/100.;
602 break;
603 case 1: // lower right = yz
604 position[1] += -destpos.y()/100.;
605 position[2] += -destpos.x()/100.;
606 break;
607 case 2: // upper left = projected
608 std::cout << "This is impossible: Shifting in the projected region, we should rotate!." << endl;
609 break;
610 case 3: // upper right = xy
611 position[0] += destpos.x()/100.;
612 position[1] += -destpos.y()/100.;
613 break;
614 default:
615 std::cout << "click was not in any of the four regions." << endl;
616 break;
617 }
618 updateGL();
619 } else { // we are in rotation region
620 QWidget *Parent = parentWidget();
621 QSlider *sliderX = Parent->findChild<QSlider *>("sliderX");
622 QSlider *sliderY = Parent->findChild<QSlider *>("sliderY");
623 std::cout << sliderX << " and " << sliderY << endl;
624 if (sliderX) {
625 int xrange = sliderX->maximum() - sliderX->minimum();
626 double xValue = ((destpos.x() + Width) % Width);
627 xValue *= (double)xrange/(double)Width;
628 xValue += sliderX->value();
629 int xvalue = (int) xValue % xrange;
630 std::cout << "Setting x to " << xvalue << " within range " << xrange << "." << endl;
631 setXRotation(xvalue);
632 sliderX->setValue(xvalue);
633 } else {
634 std::cout << "sliderX is NULL." << endl;
635 }
636 if (sliderY) {
637 int yrange = sliderY->maximum() - sliderY->minimum();
638 double yValue = ((destpos.y() + Height) % Height);
639 yValue *= (double)yrange/(double)Height;
640 yValue += sliderY->value();
641 int yvalue = (int) yValue % yrange;
642 std::cout << "Setting y to " << yvalue << " within range " << yrange << "." << endl;
643 setYRotation(yvalue);
644 sliderY->setValue(yvalue);
645 } else {
646 std::cout << "sliderY is NULL." << endl;
647 }
648 }
649 } else {
650 std::cout << "srcpos is NULL." << endl;
651 }
652 break;
653
654 case Qt::MidButton: // MiddleButton has no function so far
655 srcpos = &MiddleButtonPos;
656 std::cout << "Middle Button" << endl;
657 if (srcpos) { // subtract the position and act
658 QWidget *Parent = parentWidget();
659 QSlider *sliderZ = Parent->findChild<QSlider *>("sliderZ");
660 QSlider *sliderScale = Parent->findChild<QSlider *>("sliderScale");
661 std::cout << sliderZ << " and " << sliderScale << endl;
662 std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
663 destpos -= *srcpos;
664 std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
665 std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
666 if (sliderZ) {
667 int xrange = sliderZ->maximum() - sliderZ->minimum();
668 double xValue = ((destpos.x() + Width) % Width);
669 xValue *= (double)xrange/(double)Width;
670 xValue += sliderZ->value();
671 int xvalue = (int) xValue % xrange;
672 std::cout << "Setting x to " << xvalue << " within range " << xrange << "." << endl;
673 setZRotation(xvalue);
674 sliderZ->setValue(xvalue);
675 } else {
676 std::cout << "sliderZ is NULL." << endl;
677 }
678 if (sliderScale) {
679 int yrange = sliderScale->maximum() - sliderScale->minimum();
680 double yValue = ((destpos.y() + Height) % Height);
681 yValue *= (double)yrange/(double)Height;
682 yValue += sliderScale->value();
683 int yvalue = (int) yValue % yrange;
684 std::cout << "Setting y to " << yvalue << " within range " << yrange << "." << endl;
685 setScale(yvalue);
686 sliderScale->setValue(yvalue);
687 } else {
688 std::cout << "sliderScale is NULL." << endl;
689 }
690 } else {
691 std::cout << "srcpos is NULL." << endl;
692 }
693 break;
694 break;
695
696 case Qt::RightButton: // RightButton moves eitstdher the selected molecule or atom
697 srcpos = &RightButtonPos;
698 std::cout << "Right Button" << endl;
699 if (srcpos) { // subtract the position and act
700 std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
701 destpos -= *srcpos;
702 std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
703 std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
704 if (MultiViewEnabled) {
705 // which vector to change
706 Vector SelectedPosition;
707 const std::vector<atom*> &SelectedAtoms = World::getInstance().getSelectedAtoms();
708 const std::vector<molecule*> &SelectedMolecules = World::getInstance().getSelectedMolecules();
709 if (SelectedMolecules.size()) {
710 if (SelectedAtoms.size())
711 SelectedPosition = (*SelectedAtoms.begin())->getPosition();
712 else
713 SelectedPosition = (*(*SelectedMolecules.begin())->begin())->getPosition();
714 }
715 // decide into which of the four screens the initial click has been made
716 int pos = (int)floor((double)srcpos->x()/(double)Width) + ((int)floor((double)srcpos->y()/(double)Height))*2;
717 if (!SelectedPosition.IsZero()) {
718 std::cout << "Position is " << pos << "." << endl;
719 switch(pos) {
720 case 0: // lower left = xz
721 SelectedPosition[0] += -destpos.y()/100.;
722 SelectedPosition[2] += destpos.x()/100.;
723 break;
724 case 1: // lower right = yz
725 SelectedPosition[1] += -destpos.y()/100.;
726 SelectedPosition[2] += -destpos.x()/100.;
727 break;
728 case 2: // upper left = projected
729 SelectedPosition[0] += destpos.x()/100.;
730 SelectedPosition[1] += destpos.y()/100.;
731 SelectedPosition[2] += destpos.y()/100.;
732 break;
733 case 3: // upper right = xy
734 SelectedPosition[0] += destpos.x()/100.;
735 SelectedPosition[1] += -destpos.y()/100.;
736 break;
737 default:
738 std::cout << "click was not in any of the four regions." << endl;
739 break;
740 }
741 } else {
742 std::cout << "Nothing selected." << endl;
743 }
744 // update Tables
745 if (SelectedMolecules.size()) {
746 isSignaller = true;
747 if (SelectedAtoms.size())
748 emit notifyAtomChanged( (*SelectedMolecules.begin()), (*SelectedAtoms.begin()), AtomPosition);
749 else
750 emit notifyMoleculeChanged( (*SelectedMolecules.begin()), MoleculePosition );
751 }
752 // update graphic
753 initializeGL();
754 updateGL();
755 } else {
756 cout << "MultiView is not enabled." << endl;
757 }
758 } else {
759 cout << "srcpos is NULL." << endl;
760 }
761 break;
762
763 default:
764 break;
765 }
766}
767
768/* ======================================== SLOTS ================================ */
769
770/** Hear announcement of selected molecule.
771 * \param *mol pointer to selected molecule
772 */
773void GLMoleculeView::hearMoleculeSelected(molecule *mol)
774{
775 if (isSignaller) { // if we emitted the signal, return
776 isSignaller = false;
777 return;
778 }
779 initializeGL();
780 updateGL();
781};
782
783/** Hear announcement of selected atom.
784 * \param *mol pointer to molecule containing atom
785 * \param *Walker pointer to selected atom
786 */
787void GLMoleculeView::hearAtomSelected(molecule *mol, atom *Walker)
788{
789 if (isSignaller) { // if we emitted the signal, return
790 isSignaller = false;
791 return;
792 }
793 initializeGL();
794 updateGL();
795};
796
797/** Hear announcement of changed molecule.
798 * \param *mol pointer to changed molecule
799 * \param type of change
800 */
801void GLMoleculeView::hearMoleculeChanged(molecule *mol, enum ChangesinMolecule type)
802{
803 if (isSignaller) { // if we emitted the signal, return
804 isSignaller = false;
805 return;
806 }
807 initializeGL();
808 updateGL();
809};
810
811/** Hear announcement of changed atom.
812 * \param *mol pointer to molecule containing atom
813 * \param *Walker pointer to changed atom
814 * \param type type of change
815 */
816void GLMoleculeView::hearAtomChanged(molecule *mol, atom *Walker, enum ChangesinAtom type)
817{
818 if (isSignaller) { // if we emitted the signal, return
819 isSignaller = false;
820 return;
821 }
822 initializeGL();
823 updateGL();
824};
825
826/** Hear announcement of changed element.
827 * \param *Runner pointer to changed element
828 * \param type of change
829 */
830void GLMoleculeView::hearElementChanged(element *Runner, enum ChangesinElement type)
831{
832 if (isSignaller) { // if we emitted the signal, return
833 isSignaller = false;
834 return;
835 }
836 switch(type) {
837 default:
838 case ElementName:
839 case ElementSymbol:
840 case ElementMass:
841 case ElementValence:
842 case ElementZ:
843 break;
844 case ElementCovalent:
845 case ElementVanderWaals:
846 initializeGL();
847 updateGL();
848 break;
849 }
850};
851
852/** Hear announcement of added molecule.
853 * \param *mol pointer to added molecule
854 */
855void GLMoleculeView::hearMoleculeAdded(molecule *mol)
856{
857 if (isSignaller) { // if we emitted the signal, return
858 isSignaller = false;
859 return;
860 }
861 initializeGL();
862 updateGL();
863};
864
865/** Hear announcement of added atom.
866 * \param *mol pointer to molecule containing atom
867 * \param *Walker pointer to added atom
868 */
869void GLMoleculeView::hearAtomAdded(molecule *mol, atom *Walker)
870{
871 if (isSignaller) { // if we emitted the signal, return
872 isSignaller = false;
873 return;
874 }
875 initializeGL();
876 updateGL();
877};
878
879/** Hear announcement of removed molecule.
880 * \param *mol pointer to removed molecule
881 */
882void GLMoleculeView::hearMoleculeRemoved(molecule *mol)
883{
884 if (isSignaller) { // if we emitted the signal, return
885 isSignaller = false;
886 return;
887 }
888 initializeGL();
889 updateGL();
890};
891
892/** Hear announcement of removed atom.
893 * \param *mol pointer to molecule containing atom
894 * \param *Walker pointer to removed atom
895 */
896void GLMoleculeView::hearAtomRemoved(molecule *mol, atom *Walker)
897{
898 if (isSignaller) { // if we emitted the signal, return
899 isSignaller = false;
900 return;
901 }
902 initializeGL();
903 updateGL();
904};
905
906void GLMoleculeView::update(Observable *publisher)
907{
908 initializeGL();
909 updateGL();
910}
911
912/**
913 * This method is called when a special named change
914 * of the Observable occured
915 */
916void GLMoleculeView::recieveNotification(Observable *publisher, Notification_ptr notification)
917{
918 initializeGL();
919 updateGL();
920}
921
922/**
923 * This method is called when the observed object is destroyed.
924 */
925void GLMoleculeView::subjectKilled(Observable *publisher)
926{
927
928}
929
930
Note: See TracBrowser for help on using the repository browser.