source: src/UIElements/Views/Qt4/Qt3D/GLWorldView.cpp@ 8e7dd9

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 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 8e7dd9 was 8e7dd9, checked in by Michael Ankele <ankele@…>, 12 years ago

GLWorldView: added stereo modes

  • Property mode set to 100644
File size: 55.1 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * GLWorldView.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 "GLWorldView.hpp"
21
22#include <Qt/qevent.h>
23#include <Qt/qaction.h>
24#include <QtGui/QMenu>
25#include <QtGui/QToolBar>
26#include <QtGui/QToolButton>
27#include <Qt/qtimer.h>
28#include <Qt/qsettings.h>
29#include <Qt3D/qglbuilder.h>
30#include <Qt3D/qglscenenode.h>
31#include <Qt3D/qglsphere.h>
32#include <Qt3D/qglcylinder.h>
33#include <Qt3D/qglcube.h>
34
35#include "GLWorldScene.hpp"
36
37#include "CodePatterns/MemDebug.hpp"
38
39#include "Atom/AtomObserver.hpp"
40#include "Atom/atom_observable.hpp"
41#include "CodePatterns/Log.hpp"
42#include "CodePatterns/Observer/Notification.hpp"
43#include "World.hpp"
44#include "Box.hpp"
45
46GLWorldView::GLWorldView(QWidget *parent)
47 : QGLView(parent), Observer("GLWorldView"), worldscene(NULL), changesPresent(false), needsRedraw(false)
48{
49 worldscene = new GLWorldScene(this);
50
51 setOption(QGLView::ObjectPicking, true);
52 setOption(QGLView::CameraNavigation, false);
53 setCameraControlMode(Rotate);
54 defaultEyeSeparation = 4.0;
55
56 createDomainBox();
57 createDreiBein();
58 //changeMaterials(false);
59
60 connect(worldscene, SIGNAL(changeOccured()), this, SLOT(changeSignalled()));
61 connect(worldscene, SIGNAL(changed()), this, SIGNAL(changed()));
62 connect(worldscene, SIGNAL(hoverChanged(const atom *)), this, SLOT(sceneHoverSignalled(const atom *)));
63 connect(this, SIGNAL(atomInserted(const atom *)), worldscene, SLOT(atomInserted(const atom *)));
64 connect(this, SIGNAL(atomRemoved(const atom *)), worldscene, SLOT(atomRemoved(const atom *)));
65 connect(this, SIGNAL(worldSelectionChanged()), worldscene, SLOT(worldSelectionChanged()));
66 connect(this, SIGNAL(moleculeRemoved(const molecule *)), worldscene, SLOT(moleculeRemoved(const molecule *)));
67 //connect(this, SIGNAL(moleculeInserted(const molecule *)), worldscene, SLOT(moleculeInserted(const molecule *)));
68 //connect(this, SIGNAL(changed()), this, SLOT(updateGL()));
69 connect(this, SIGNAL(changed()), this, SLOT(sceneChangeSignalled()));
70
71 // sign on to changes in the world
72 World::getInstance().signOn(this);
73 World::getInstance().signOn(this, World::AtomInserted);
74 World::getInstance().signOn(this, World::AtomRemoved);
75 World::getInstance().signOn(this, World::MoleculeInserted);
76 World::getInstance().signOn(this, World::MoleculeRemoved);
77 World::getInstance().signOn(this, World::SelectionChanged);
78 AtomObserver::getInstance().signOn(this, AtomObservable::PositionChanged);
79
80 redrawTimer = new QTimer(this);
81}
82
83GLWorldView::~GLWorldView()
84{
85 World::getInstance().signOff(this);
86 World::getInstance().signOff(this, World::AtomInserted);
87 World::getInstance().signOff(this, World::AtomRemoved);
88 World::getInstance().signOff(this, World::MoleculeInserted);
89 World::getInstance().signOff(this, World::MoleculeRemoved);
90 World::getInstance().signOff(this, World::SelectionChanged);
91 AtomObserver::getInstance().signOff(this, AtomObservable::PositionChanged);
92 delete worldscene;
93
94 delete(domainBoxMaterial);
95 for (int i=0;i<3;i++)
96 delete(dreiBeinMaterial[i]);
97}
98
99
100/**
101 * Add some widget specific actions to the toolbar:
102 * - camera rotation/translation mode
103 * - camera fit to domain
104 */
105void GLWorldView::addToolBarActions(QToolBar *toolbar)
106{
107 toolbar->addSeparator();
108 QAction *transAction = new QAction(QIcon::fromTheme("forward"), tr("camera translation mode"), this);
109 connect(transAction, SIGNAL(triggered()), this, SLOT(setCameraControlModeTranslation()));
110 toolbar->addAction(transAction);
111 QAction *rotAction = new QAction(QIcon::fromTheme("object-rotate-left"), tr("camera rotation mode"), this);
112 connect(rotAction, SIGNAL(triggered()), this, SLOT(setCameraControlModeRotation()));
113 toolbar->addAction(rotAction);
114 QAction *fitAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("camera fit to domain"), this);
115 connect(fitAction, SIGNAL(triggered()), this, SLOT(fitCameraToDomain()));
116 toolbar->addAction(fitAction);
117 toolbar->addSeparator();
118 QAction *selAtomAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("select atom by clicking"), this);
119 connect(selAtomAction, SIGNAL(triggered()), worldscene, SLOT(setSelectionModeAtom()));
120 toolbar->addAction(selAtomAction);
121 QAction *selMolAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("select molecule by clicking"), this);
122 connect(selMolAction, SIGNAL(triggered()), worldscene, SLOT(setSelectionModeMolecule()));
123 toolbar->addAction(selMolAction);
124
125 QToolButton *stereoButton = new QToolButton(toolbar);
126 QMenu *stereoMenu = new QMenu();
127 QAction *stereoHardwareAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("hardware"), this);
128 connect(stereoHardwareAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeHardware()));
129 stereoMenu->addAction(stereoHardwareAction);
130 QAction *stereoLeftRightAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("left right"), this);
131 connect(stereoLeftRightAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeLeftRight()));
132 stereoMenu->addAction(stereoLeftRightAction);
133 QAction *stereoRightLeftAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("right left"), this);
134 connect(stereoRightLeftAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeRightLeft()));
135 stereoMenu->addAction(stereoRightLeftAction);
136 QAction *stereoTopBottomAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("top bottom"), this);
137 connect(stereoTopBottomAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeTopBottom()));
138 stereoMenu->addAction(stereoTopBottomAction);
139 QAction *stereoBottomTopAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("bottom top"), this);
140 connect(stereoBottomTopAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeBottomTop()));
141 stereoMenu->addAction(stereoBottomTopAction);
142 QAction *stereoAnaglyphAction = new QAction(QIcon::fromTheme("zoom-best-fit"), tr("anaglyph"), this);
143 connect(stereoAnaglyphAction, SIGNAL(triggered()), this, SLOT(setCameraStereoModeAnaglyph()));
144 stereoMenu->addAction(stereoAnaglyphAction);
145 stereoButton->setMenu(stereoMenu);
146 stereoButton->setPopupMode(QToolButton::InstantPopup);
147 toolbar->addWidget(stereoButton);
148}
149
150void GLWorldView::createDomainBox()
151{
152 QSettings settings;
153 settings.beginGroup("WorldView");
154 QColor colorFrame = settings.value("domainBoxColorFrame", QColor(150,160,200,255)).value<QColor>();
155 QColor colorAmbient = settings.value("domainBoxColorAmbient", QColor(50,60,100,255)).value<QColor>();
156 QColor colorDiffuse = settings.value("domainBoxColorDiffuse", QColor(150,160,200,180)).value<QColor>();
157 settings.setValue("domainBoxColorFrame", colorFrame);
158 settings.setValue("domainBoxColorAmbient", colorAmbient);
159 settings.setValue("domainBoxColorDiffuse", colorDiffuse);
160 settings.endGroup();
161
162 domainBoxMaterial = new QGLMaterial;
163 domainBoxMaterial->setAmbientColor(QColor(0,0,0,255));
164 domainBoxMaterial->setDiffuseColor(QColor(0,0,0,255));
165 domainBoxMaterial->setEmittedLight(colorFrame);
166
167
168 QGLMaterial *material = new QGLMaterial;
169 material->setAmbientColor(colorAmbient);
170 material->setDiffuseColor(colorDiffuse);
171
172 QGLBuilder builder;
173 builder << QGL::Faceted;
174 builder << QGLCube(-1.0); // "inverted" => inside faces are used as front.
175 meshDomainBox = builder.finalizedSceneNode();
176 QMatrix4x4 mat;
177 mat.translate(0.5f, 0.5f, 0.5f);
178 meshDomainBox->setLocalTransform(mat);
179 meshDomainBox->setMaterial(material);
180}
181
182void GLWorldView::createDreiBein()
183{
184 QSettings settings;
185 settings.beginGroup("WorldView");
186 QColor colorX = settings.value("dreiBeinColorX", QColor(255,50,50,255)).value<QColor>();
187 QColor colorY = settings.value("dreiBeinColorY", QColor(50,255,50,255)).value<QColor>();
188 QColor colorZ = settings.value("dreiBeinColorZ", QColor(50,50,255,255)).value<QColor>();
189 settings.setValue("dreiBeinColorX", colorX);
190 settings.setValue("dreiBeinColorY", colorY);
191 settings.setValue("dreiBeinColorZ", colorZ);
192 settings.setValue("dreiBeinEnabled", true);
193 settings.endGroup();
194
195 // Create 3 color for the 3 axes.
196 dreiBeinMaterial[0] = new QGLMaterial;
197 dreiBeinMaterial[0]->setColor(colorX);
198 dreiBeinMaterial[1] = new QGLMaterial;
199 dreiBeinMaterial[1]->setColor(colorY);
200 dreiBeinMaterial[2] = new QGLMaterial;
201 dreiBeinMaterial[2]->setColor(colorZ);
202
203 // Create the basic meshes (cylinder and cone).
204 QGLBuilder builderCyl;
205 builderCyl << QGLCylinder(.15,.15,1.0,16);
206 QGLSceneNode *cyl = builderCyl.finalizedSceneNode();
207
208 QGLBuilder builderCone;
209 builderCone << QGLCylinder(0,.4,0.4,16);
210 QGLSceneNode *cone = builderCone.finalizedSceneNode();
211 {
212 QMatrix4x4 mat;
213 mat.translate(0.0f, 0.0f, 1.0f);
214 cone->setLocalTransform(mat);
215 }
216
217 // Create a scene node from the 3 axes.
218 meshDreiBein = new QGLSceneNode(this);
219
220 // X-direction
221 QGLSceneNode *node = new QGLSceneNode(meshDreiBein);
222 node->setMaterial(dreiBeinMaterial[0]);
223 node->addNode(cyl);
224 node->addNode(cone);
225 {
226 QMatrix4x4 mat;
227 mat.rotate(90, 0.0f, 1.0f, 0.0f);
228 node->setLocalTransform(mat);
229 }
230
231 // Y-direction
232 node = new QGLSceneNode(meshDreiBein);
233 node->setMaterial(dreiBeinMaterial[1]);
234 node->addNode(cyl);
235 node->addNode(cone);
236 {
237 QMatrix4x4 mat;
238 mat.rotate(-90, 1.0f, 0.0f, 0.0f);
239 node->setLocalTransform(mat);
240 }
241
242 // Z-direction
243 node = new QGLSceneNode(meshDreiBein);
244 node->setMaterial(dreiBeinMaterial[2]);
245 node->addNode(cyl);
246 node->addNode(cone);
247}
248
249/**
250 * Update operation which can be invoked by the observable (which should be the
251 * change tracker here).
252 */
253void GLWorldView::update(Observable *publisher)
254{
255 emit changed();
256}
257
258/**
259 * The observable can tell when it dies.
260 */
261void GLWorldView::subjectKilled(Observable *publisher) {}
262
263/** Listen to specific changes to the world.
264 *
265 * @param publisher ref to observable.
266 * @param notification type of notification
267 */
268void GLWorldView::recieveNotification(Observable *publisher, Notification_ptr notification)
269{
270 if (static_cast<World *>(publisher) == World::getPointer()) {
271 switch (notification->getChannelNo()) {
272 case World::AtomInserted:
273 {
274 const atom *_atom = World::getInstance().lastChanged<atom>();
275 #ifdef LOG_OBSERVER
276 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that atom "+toString(_atom->getId())+" has been inserted.";
277 #endif
278 emit atomInserted(_atom);
279 break;
280 }
281 case World::AtomRemoved:
282 {
283 const atom *_atom = World::getInstance().lastChanged<atom>();
284 #ifdef LOG_OBSERVER
285 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that atom "+toString(_atom->getId())+" has been removed.";
286 #endif
287 emit atomRemoved(_atom);
288 break;
289 }
290 case World::SelectionChanged:
291 {
292 #ifdef LOG_OBSERVER
293 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that selection has changed.";
294 #endif
295 emit worldSelectionChanged();
296 break;
297 }
298 case World::MoleculeInserted:
299 {
300 const molecule *_molecule = World::getInstance().lastChanged<molecule>();
301 #ifdef LOG_OBSERVER
302 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that molecule "+toString(_molecule->getId())+" has been removed.";
303 #endif
304 emit moleculeInserted(_molecule);
305 break;
306 }
307 case World::MoleculeRemoved:
308 {
309 const molecule *_molecule = World::getInstance().lastChanged<molecule>();
310 #ifdef LOG_OBSERVER
311 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that molecule "+toString(_molecule->getId())+" has been removed.";
312 #endif
313 emit moleculeRemoved(_molecule);
314 break;
315 }
316 default:
317 ASSERT(0, "GLWorldView::recieveNotification() - we cannot get here.");
318 break;
319 }
320 } else if (dynamic_cast<AtomObservable *>(publisher) != NULL) {
321 switch (notification->getChannelNo()) {
322 case AtomObservable::PositionChanged:
323 {
324 const atom *_atom = dynamic_cast<const atom *>(publisher);
325 #ifdef LOG_OBSERVER
326 observerLog().addMessage() << "++ Observer " << observerLog().getName(this) << " received notification that atom "+toString(_atom->getId())+" has changed its position.";
327 #endif
328 emit changed();
329 break;
330 }
331 default:
332 ASSERT(0, "GLWorldView::recieveNotification() - we cannot get here.");
333 break;
334 }
335 } else
336 ASSERT(0, "GLWorldView::recieveNotification() - received notification from unknown source.");
337}
338
339void GLWorldView::checkChanges()
340{
341 updateGL();
342 needsRedraw = false;
343}
344
345void GLWorldView::sceneChangeSignalled()
346{
347 if (!needsRedraw){
348 redrawTimer->singleShot(0, this, SLOT(checkChanges()));
349 needsRedraw = true;
350 redrawTimer->start();
351 }
352}
353
354void GLWorldView::initializeGL(QGLPainter *painter)
355{
356 worldscene->initialize(this, painter);
357 changesPresent = false;
358}
359
360void GLWorldView::paintGL(QGLPainter *painter)
361{
362 if (changesPresent) {
363 initializeGL(painter);
364 changesPresent = false;
365 }
366 worldscene->draw(painter);
367
368 drawDreiBein(painter);
369
370 // Domain box has to be last because of its transparency.
371 drawDomainBox(painter);
372}
373
374void GLWorldView::keyPressEvent(QKeyEvent *e)
375{
376 if (e->key() == Qt::Key_Tab) {
377 // The Tab key turns the ShowPicking option on and off,
378 // which helps show what the pick buffer looks like.
379 setOption(QGLView::ShowPicking, ((options() & QGLView::ShowPicking) == 0));
380 updateGL();
381 }
382 QGLView::keyPressEvent(e);
383}
384
385void GLWorldView::changeSignalled()
386{
387 changesPresent = true;
388}
389
390
391/**
392 * Set the current camera control mode.
393 */
394void GLWorldView::setCameraControlMode(GLWorldView::CameraControlModeType mode)
395{
396 cameraControlMode = mode;
397}
398
399void GLWorldView::setCameraControlModeRotation()
400{
401 setCameraControlMode(Rotate);
402}
403
404void GLWorldView::setCameraControlModeTranslation()
405{
406 setCameraControlMode(Translate);
407}
408
409/**
410 * Returns the current camera control mode.
411 * This needs to be invertable (rotation - translation), if the shift key is pressed.
412 */
413GLWorldView::CameraControlModeType GLWorldView::getCameraControlMode(bool inverted)
414{
415 if (inverted){
416 if (cameraControlMode == Rotate)
417 return Translate;
418 if (cameraControlMode == Translate)
419 return Rotate;
420 return Rotate;
421 }else
422 return cameraControlMode;
423}
424
425/**
426 * Set the camera so it can oversee the whole domain.
427 */
428void GLWorldView::fitCameraToDomain()
429{
430 // Move the camera focus point to the center of the domain box.
431 Vector v = World::getInstance().getDomain().translateIn(Vector(0.5, 0.5, 0.5));
432 camera()->setCenter(QVector3D(v[0], v[1], v[2]));
433
434 // Guess some eye distance.
435 double dist = v.Norm() * 3;
436 camera()->setEye(QVector3D(v[0], v[1], v[2] + dist));
437 camera()->setUpVector(QVector3D(0, 1, 0));
438}
439
440void GLWorldView::setCameraStereoModeDisable()
441{
442 setStereoType(QGLView::Hardware);
443 camera()->setEyeSeparation(0.0);
444 updateGL();
445}
446
447void GLWorldView::setCameraStereoModeHardware()
448{
449 setStereoType(QGLView::Hardware);
450 camera()->setEyeSeparation(defaultEyeSeparation);
451 updateGL();
452}
453
454void GLWorldView::setCameraStereoModeLeftRight()
455{
456 setStereoType(QGLView::LeftRight);
457 camera()->setEyeSeparation(defaultEyeSeparation);
458 updateGL();
459}
460
461void GLWorldView::setCameraStereoModeRightLeft()
462{
463 setStereoType(QGLView::RightLeft);
464 camera()->setEyeSeparation(defaultEyeSeparation);
465 updateGL();
466}
467
468void GLWorldView::setCameraStereoModeTopBottom()
469{
470 setStereoType(QGLView::TopBottom);
471 camera()->setEyeSeparation(defaultEyeSeparation);
472 updateGL();
473}
474
475void GLWorldView::setCameraStereoModeBottomTop()
476{
477 setStereoType(QGLView::BottomTop);
478 camera()->setEyeSeparation(defaultEyeSeparation);
479 updateGL();
480}
481
482void GLWorldView::setCameraStereoModeAnaglyph()
483{
484 setStereoType(QGLView::RedCyanAnaglyph);
485 camera()->setEyeSeparation(defaultEyeSeparation);
486 updateGL();
487}
488
489void GLWorldView::mousePressEvent(QMouseEvent *event)
490{
491 QGLView::mousePressEvent(event);
492
493 // Reset the saved mouse position.
494 lastMousePos = event->posF();
495}
496
497/**
498 * Handle a mouse move event.
499 * This is used to control the camera (rotation and translation) when the left button is being pressed.
500 */
501void GLWorldView::mouseMoveEvent(QMouseEvent *event)
502{
503 if (event->buttons() & Qt::LeftButton){
504 // Find the mouse distance since the last event.
505 QPointF d = event->posF() - lastMousePos;
506 lastMousePos = event->posF();
507
508 // Rotate or translate? (inverted by shift key)
509 CameraControlModeType mode = getCameraControlMode(event->modifiers() & Qt::ShiftModifier);
510
511 if (mode == Rotate){
512 // Rotate the camera.
513 d *= 0.3;
514 camera()->tiltPanRollCenter(- d.y(), - d.x(), 0);
515 }else if (mode == Translate){
516 // Translate the camera.
517 d *= 0.02;
518 camera()->translateCenter(- d.x(), d.y(), 0);
519 camera()->translateEye(- d.x(), d.y(), 0);
520 }
521 }else{
522 // Without this Qt would not test for hover events (i.e. mouse over an atom).
523 QGLView::mouseMoveEvent(event);
524 }
525}
526
527/**
528 * When the mouse wheel is used, zoom in or out.
529 */
530void GLWorldView::wheelEvent(QWheelEvent *event)
531{
532 // Find the distance between the eye and focus point.
533 QVector3D d = camera()->eye() - camera()->center();
534
535 // Scale the distance.
536 if (event->delta() < 0)
537 d *= 1.2;
538 else if (event->delta() > 0)
539 d /= 1.2;
540
541 // Set new eye position.
542 camera()->setEye(camera()->center() + d);
543}
544
545/**
546 * Draw a transparent cube representing the domain.
547 */
548void GLWorldView::drawDomainBox(QGLPainter *painter) const
549{
550 // Apply the domain matrix.
551 RealSpaceMatrix m = World::getInstance().getDomain().getM();
552 painter->modelViewMatrix().push();
553 painter->modelViewMatrix() *= QMatrix4x4(m.at(0,0), m.at(0,1), m.at(0,2), 0.0,
554 m.at(1,0), m.at(1,1), m.at(1,2), 0.0,
555 m.at(2,0), m.at(2,1), m.at(2,2), 0.0,
556 0.0, 0.0, 0.0, 1.0);
557
558 // Draw the transparent cube.
559 painter->setStandardEffect(QGL::LitMaterial);
560 glCullFace(GL_BACK);
561 glEnable(GL_CULL_FACE);
562 glEnable(GL_BLEND);
563 glDepthMask(0);
564 //glDisable(GL_DEPTH_TEST);
565 meshDomainBox->draw(painter);
566 //glEnable(GL_DEPTH_TEST);
567 glDepthMask(1);
568 glDisable(GL_BLEND);
569 glDisable(GL_CULL_FACE);
570
571 // Draw the outlines.
572 painter->setFaceMaterial(QGL::AllFaces, domainBoxMaterial);
573 //glEnable(GL_LINE_SMOOTH);
574 QVector3DArray array;
575 array.append(0, 0, 0); array.append(1, 0, 0);
576 array.append(1, 0, 0); array.append(1, 1, 0);
577 array.append(1, 1, 0); array.append(0, 1, 0);
578 array.append(0, 1, 0); array.append(0, 0, 0);
579
580 array.append(0, 0, 1); array.append(1, 0, 1);
581 array.append(1, 0, 1); array.append(1, 1, 1);
582 array.append(1, 1, 1); array.append(0, 1, 1);
583 array.append(0, 1, 1); array.append(0, 0, 1);
584
585 array.append(0, 0, 0); array.append(0, 0, 1);
586 array.append(1, 0, 0); array.append(1, 0, 1);
587 array.append(0, 1, 0); array.append(0, 1, 1);
588 array.append(1, 1, 0); array.append(1, 1, 1);
589 painter->clearAttributes();
590 painter->setVertexAttribute(QGL::Position, array);
591 painter->draw(QGL::Lines, 24);
592
593 painter->modelViewMatrix().pop();
594}
595
596void GLWorldView::drawDreiBein(QGLPainter *painter)
597{
598 painter->modelViewMatrix().push();
599 painter->modelViewMatrix().translate(camera()->center());
600 painter->setStandardEffect(QGL::LitMaterial);
601 painter->setFaceMaterial(QGL::FrontFaces, NULL);
602 meshDreiBein->draw(painter);
603 painter->modelViewMatrix().pop();
604}
605
606void GLWorldView::sceneHoverSignalled(const atom *_atom)
607{
608 emit hoverChanged(_atom);
609}
610
611
612//#include <GL/glu.h>
613//#include <QtGui/qslider.h>
614//#include <QtGui/qevent.h>
615//
616//#include "ui_dialoglight.h"
617//
618//#include "CodePatterns/MemDebug.hpp"
619//
620//#include <iostream>
621//#include <boost/shared_ptr.hpp>
622//
623//#include "LinearAlgebra/Line.hpp"
624//#include "Atom/atom.hpp"
625//#include "Bond/bond.hpp"
626//#include "Element/element.hpp"
627//#include "molecule.hpp"
628//#include "Element/periodentafel.hpp"
629//#include "World.hpp"
630//
631//#if defined(Q_CC_MSVC)
632//#pragma warning(disable:4305) // init: truncation from const double to float
633//#endif
634//
635//
636//GLMoleculeView::GLMoleculeView(QWidget *parent) :
637// QGLWidget(parent), Observer("GLMoleculeView"), X(Vector(1,0,0)), Y(Vector(0,1,0)), Z(Vector(0,0,1))
638//{
639// xRot = yRot = zRot = 0.0; // default object rotation
640// scale = 5.; // default object scale
641// object = 0;
642// LightPosition[0] = 0.0f;
643// LightPosition[1] = 2.0f;
644// LightPosition[2] = 2.0f;
645// LightPosition[3] = 0.0f;
646// LightDiffuse[0] = 0.5f;
647// LightDiffuse[1] = 0.5f;
648// LightDiffuse[2] = 0.5f;
649// LightDiffuse[3] = 0.0f;
650// LightAmbient[0] = 0.0f;
651// LightAmbient[1] = 0.0f;
652// LightAmbient[2] = 0.0f;
653// LightAmbient[3] = 0.0f;
654//
655// SelectionColor[0] = 0;
656// SelectionColor[1] = 128;
657// SelectionColor[2] = 128;
658//
659// MultiViewEnabled = true;
660//
661// isSignaller = false;
662//
663// World::getInstance().signOn(this);
664//}
665//
666///** Destructor of GLMoleculeView.
667// * Free's the CallList.
668// */
669//GLMoleculeView::~GLMoleculeView()
670//{
671// makeCurrent();
672// glDeleteLists( object, 1 );
673//
674// World::getInstance().signOff(this);
675//}
676//
677///** Paints the conents of the OpenGL window.
678// * Clears the GL buffers, enables lighting and depth.
679// * Window is either quartered (if GLMoleculeView::MultiViewEnabled) and xy, xz, yz planar views
680// * are added. Uses the CallList, constructed during InitializeGL().
681// */
682//void GLMoleculeView::paintGL()
683//{
684// Vector spot;
685//
686// glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
687// glShadeModel(GL_SMOOTH); // Enable Smooth Shading
688// glEnable(GL_LIGHTING); // Enable Light One
689// glEnable(GL_DEPTH_TEST); // Enables Depth Testing
690// glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
691// glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
692//
693// // 3d viewport
694// if (MultiViewEnabled)
695// glViewport( 0, 0, (GLint)width/2, (GLint)height/2 );
696// else
697// glViewport( 0, 0, (GLint)width, (GLint)height );
698// glMatrixMode( GL_PROJECTION );
699// glLoadIdentity();
700// glFrustum( -1.0, 1.0, -1.0, 1.0, 1.0, 50.0 );
701// glMatrixMode( GL_MODELVIEW );
702// glLoadIdentity();
703//
704// // calculate point of view and direction
705// glTranslated(position[0],position[1],position[2]);
706// glTranslated(0.0, 0.0, -scale);
707// glRotated(xRot, 1.0, 0.0, 0.0);
708// glRotated(yRot, 0.0, 1.0, 0.0);
709// glRotated(zRot, 0.0, 0.0, 1.0);
710//
711// // render scene
712// glCallList(object);
713//
714// // enable light
715// glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
716// glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
717// glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
718// glEnable(GL_LIGHT1); // Enable Light One
719//
720// if (MultiViewEnabled) {
721// // xy view port
722// glViewport( (GLint)width/2, 0, (GLint)width/2, (GLint)height/2 );
723// glMatrixMode( GL_PROJECTION );
724// glLoadIdentity();
725// glScalef(1./scale, 1./scale,1./scale);
726// glOrtho(0, width/2, 0, height/2, 0,0);
727// glMatrixMode( GL_MODELVIEW );
728// glLoadIdentity();
729//
730// // calculate point of view and direction
731// view = position;
732// spot = Vector(0.,0.,scale);
733// top = Vector(0.,1.,0.);
734// gluLookAt(
735// spot[0], spot[1], spot[2],
736// view[0], view[1], view[2],
737// top[0], top[1], top[2]);
738//
739// // enable light
740// glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
741// glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
742// glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
743// glEnable(GL_LIGHT1); // Enable Light One
744//
745// // render scene
746// glCallList(object);
747//
748// // xz viewport
749// glViewport( 0, (GLint)height/2, (GLint)width/2, (GLint)height/2 );
750// glMatrixMode( GL_PROJECTION );
751// glLoadIdentity();
752// glScalef(1./scale, 1./scale,1./scale);
753// glOrtho(0, width/2, 0, height/2, 0,0);
754// glMatrixMode( GL_MODELVIEW );
755// glLoadIdentity();
756//
757// // calculate point of view and direction
758// view = position;
759// spot = Vector(0.,scale,0.);
760// top = Vector(1.,0.,0.);
761// gluLookAt(
762// spot[0], spot[1], spot[2],
763// view[0], view[1], view[2],
764// top[0], top[1], top[2]);
765//
766// // enable light
767// glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
768// glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
769// glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
770// glEnable(GL_LIGHT1); // Enable Light One
771//
772// // render scene
773// glCallList(object);
774//
775// //yz viewport
776// glViewport( (GLint)width/2, (GLint)height/2, (GLint)width/2, (GLint)height/2 );
777// glMatrixMode( GL_PROJECTION );
778// glLoadIdentity();
779// glScalef(1./scale, 1./scale,1./scale);
780// glOrtho(0, width/2, 0, height/2, 0,0);
781// glMatrixMode( GL_MODELVIEW );
782// glLoadIdentity();
783//
784// // calculate point of view and direction
785// view= position;
786// spot = Vector(scale,0.,0.);
787// top = Vector(0.,1.,0.);
788// gluLookAt(
789// spot[0], spot[1], spot[2],
790// view[0], view[1], view[2],
791// top[0], top[1], top[2]);
792//
793// // enable light
794// glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
795// glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); // Setup The Diffuse Light
796// glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
797// glEnable(GL_LIGHT1); // Enable Light One
798//
799// // render scene
800// glCallList(object);
801// }
802// //CoordinatesBar->setText( QString ("X: %1, Y: %2, Z: %3").arg(position[0]).arg(position[1]).arg(position[2]) );
803//}
804//
805////void polarView{GLdouble distance, GLdouble twist,
806//// GLdouble elevation, GLdouble azimuth)
807////{
808//// glTranslated(0.0, 0.0, -distance);
809//// glRotated(-twist, 0.0, 0.0, 1.0);
810//// glRotated(-elevation, 1.0, 0.0, 0.0);
811//// glRotated(azimuth, 0.0, 0.0, 1.0);
812////}
813//
814///** Make a sphere.
815// * \param x position
816// * \param radius radius
817// * \param color[3] color rgb values
818// */
819//void GLMoleculeView::makeSphere(const Vector &x, double radius, const unsigned char color[3])
820//{
821// 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
822// GLUquadricObj* q = gluNewQuadric ();
823// gluQuadricOrientation(q, GLU_OUTSIDE);
824//
825// std::cout << "Setting sphere at " << x << " with color r"
826// << (int)color[0] << ",g" << (int)color[1] << ",b" << (int)color[2] << "." << endl;
827//
828// glPushMatrix();
829// glTranslatef( x[0], x[1], x[2]);
830//// glRotatef( xRot, 1.0, 0.0, 0.0);
831//// glRotatef( yRot, 0.0, 1.0, 0.0);
832//// glRotatef( zRot, 0.0, 0.0, 1.0);
833// glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blueMaterial);
834// gluSphere (q, (GLdouble)radius, 10, 10);
835// glPopMatrix();
836//}
837//
838///** Make a cylinder.
839// * \param x origin
840// * \param y direction
841// * \param radius thickness
842// * \param height length
843// * \color[3] color rgb values
844// */
845//void GLMoleculeView::makeCylinder(const Vector &x, const Vector &y, double radius, double height, const unsigned char color[3])
846//{
847// float blueMaterial[] = { 255./(float)color[0], 255./(float)color[1], 255./(float)color[2], 1 };
848// GLUquadricObj* q = gluNewQuadric ();
849// gluQuadricOrientation(q, GLU_OUTSIDE);
850// Vector a,b;
851// Vector OtherAxis;
852// double alpha;
853// a = x - y;
854// // construct rotation axis
855// b = a;
856// b.VectorProduct(Z);
857// Line axis(zeroVec, b);
858// // calculate rotation angle
859// alpha = a.Angle(Z);
860// // construct other axis to check right-hand rule
861// OtherAxis = b;
862// OtherAxis.VectorProduct(Z);
863// // assure right-hand rule for the rotation
864// if (a.ScalarProduct(OtherAxis) < MYEPSILON)
865// alpha = M_PI-alpha;
866// // check
867// Vector a_rotated = axis.rotateVector(a, alpha);
868// std::cout << "Setting cylinder from "// << x << " to " << y
869// << a << " to " << a_rotated << " around " << b << " by " << alpha/M_PI*180. << ", respectively, "
870// << " with color r"
871// << (int)color[0] << ",g" << (int)color[1] << ",b" << (int)color[2] << "." << endl;
872//
873// glPushMatrix();
874// glTranslatef( x[0], x[1], x[2]);
875// glRotatef( alpha/M_PI*180., b[0], b[1], b[2]);
876// glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, blueMaterial);
877// gluCylinder (q, (GLdouble)radius, (GLdouble)radius, (GLdouble)height, 10, 10);
878// glPopMatrix();
879//}
880//
881///** Defines the display CallList.
882// * Goes through all molecules and their atoms and adds spheres for atoms and cylinders
883// * for bonds. Heeds GLMoleculeView::SelectedAtom and GLMoleculeView::SelectedMolecule.
884// */
885//void GLMoleculeView::initializeGL()
886//{
887// double x[3] = {-1, 0, -10};
888// unsigned char white[3] = {255,255,255};
889// Vector Position, OtherPosition;
890// QSize window = size();
891// width = window.width();
892// height = window.height();
893// std::cout << "Setting width to " << width << " and height to " << height << std::endl;
894// GLfloat shininess[] = { 0.0 };
895// GLfloat specular[] = { 0, 0, 0, 1 };
896// glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Let OpenGL clear to black
897// object = glGenLists(1);
898// glNewList( object, GL_COMPILE );
899// glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular);
900// glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
901//
902// const std::vector<molecule*> &molecules = World::getInstance().getAllMolecules();
903//
904// if (molecules.size() > 0) {
905// for (std::vector<molecule*>::const_iterator Runner = molecules.begin();
906// Runner != molecules.end();
907// Runner++) {
908// for (molecule::const_iterator atomiter = (*Runner)->begin();
909// atomiter != (*Runner)->end();
910// ++atomiter) {
911// // create atom
912// const element *ptr = (*atomiter)->getType();
913// boost::shared_ptr<Vector> MolCenter((*Runner)->DetermineCenterOfGravity());
914// Position = (*atomiter)->getPosition() - *MolCenter;
915// const unsigned char* color = NULL;
916// if ((World::getInstance().isSelected(*atomiter)) || (World::getInstance().isSelected((*Runner))))
917// color = SelectionColor;
918// else
919// color = ptr->getColor();
920// makeSphere(Position, ptr->getVanDerWaalsRadius()*0.25, color);
921//
922// // create bonds
923// const BondList &bonds = (*atomiter)->getListOfBonds();
924// for (BondList::const_iterator bonditer = bonds.begin();
925// bonditer != bonds.end();
926// ++bonditer) {
927// if ((*bonditer)->leftatom->getId() == (*atomiter)->getId()) {
928// Position = (*bonditer)->leftatom->getPosition() - *MolCenter;
929// OtherPosition = (*bonditer)->rightatom->getPosition() - *MolCenter;
930// const double distance = sqrt(Position.DistanceSquared(OtherPosition))/2.;
931// const unsigned char *color1 = (*bonditer)->leftatom->getType()->getColor();
932// const unsigned char *color2 = (*bonditer)->rightatom->getType()->getColor();
933// makeCylinder(Position, OtherPosition, 0.1, distance, color1);
934// makeCylinder(OtherPosition, Position, 0.1, distance, color2);
935// }
936// }
937// }
938// }
939// } else {
940// makeSphere( x,1, white);
941// }
942// glEndList();
943//}
944//
945//
946///* ================================== SLOTS ============================== */
947//
948///** Initializes some public variables.
949// * \param *ptr pointer to QLabel statusbar
950// */
951//void GLMoleculeView::init(QLabel *ptr)
952//{
953// StatusBar = ptr;
954//}
955//
956///** Initializes the viewport statusbar.
957// * \param *ptr pointer to QLabel for showing view pointcoordinates.
958// */
959//void GLMoleculeView::initCoordinates(QLabel *ptr)
960//{
961// CoordinatesBar = ptr;
962//}
963//
964///** Slot to be called when to initialize GLMoleculeView::MolData.
965// */
966//void GLMoleculeView::createView( )
967//{
968// initializeGL();
969// updateGL();
970//}
971//
972///** Slot of window is resized.
973// * Copies new width and height to GLMoleculeView::width and GLMoleculeView::height and calls updateGL().
974// * \param w new width of window
975// * \param h new height of window
976// */
977//void GLMoleculeView::resizeGL( int w, int h )
978//{
979// width = w;
980// height = h;
981// updateGL();
982//}
983//
984///** Sets x rotation angle.
985// * sets GLMoleculeView::xRot and calls updateGL().
986// * \param degrees new rotation angle in degrees
987// */
988//void GLMoleculeView::setXRotation( int degrees )
989//{
990// xRot = (GLfloat)(degrees % 360);
991// updateGL();
992//}
993//
994//
995///** Sets y rotation angle.
996// * sets GLMoleculeView::yRot and calls updateGL().
997// * \param degrees new rotation angle in degrees
998// */
999//void GLMoleculeView::setYRotation( int degrees )
1000//{
1001// yRot = (GLfloat)(degrees % 360);
1002// updateGL();
1003//}
1004//
1005//
1006///** Sets z rotation angle.
1007// * sets GLMoleculeView::zRot and calls updateGL().
1008// * \param degrees new rotation angle in degrees
1009// */
1010//void GLMoleculeView::setZRotation( int degrees )
1011//{
1012// zRot = (GLfloat)(degrees % 360);
1013// updateGL();
1014//}
1015//
1016///** Sets the scale of the scene.
1017// * sets GLMoleculeView::scale and calls updateGL().
1018// * \param distance distance divided by 100 is the new scale
1019// */
1020//void GLMoleculeView::setScale( int distance )
1021//{
1022// scale = (GLfloat)(distance / 100.);
1023// updateGL();
1024//}
1025//
1026///** Update the ambient light.
1027// * \param light[4] light strength per axis and position (w)
1028// */
1029//void GLMoleculeView::setLightAmbient( int *light )
1030//{
1031// for(int i=0;i<4;i++)
1032// LightAmbient[i] = light[i];
1033// updateGL();
1034//}
1035//
1036///** Update the diffuse light.
1037// * \param light[4] light strength per axis and position (w)
1038// */
1039//void GLMoleculeView::setLightDiffuse( int *light )
1040//{
1041// for(int i=0;i<4;i++)
1042// LightDiffuse[i] = light[i];
1043// updateGL();
1044//}
1045//
1046///** Update the position of light.
1047// * \param light[4] light strength per axis and position (w)
1048// */
1049//void GLMoleculeView::setLightPosition( int *light )
1050//{
1051// for(int i=0;i<4;i++)
1052// LightPosition[i] = light[i];
1053// updateGL();
1054//}
1055//
1056///** Toggles the boolean GLMoleculeView::MultiViewEnabled.
1057// * Flips the boolean and calls updateGL().
1058// */
1059//void GLMoleculeView::toggleMultiViewEnabled ( )
1060//{
1061// MultiViewEnabled = !MultiViewEnabled;
1062// cout << "Setting MultiView to " << MultiViewEnabled << "." << endl;
1063// updateGL();
1064//}
1065//
1066///** Launch a dialog to configure the lights.
1067// */
1068//void GLMoleculeView::createDialogLight()
1069//{
1070//// Ui_DialogLight *Lights = new Ui_DialogLight();
1071//// if (Lights == NULL)
1072//// return;
1073//// // Set up the dynamic dialog here
1074//// QLineEdit *Field = NULL;
1075//// Field = Lights->findChild<QLineEdit *>("LightPositionX");
1076//// if (Field) Field->setText( QString("%1").arg(LightPosition[0]) );
1077//// Field = Lights->findChild<QLineEdit *>("LightPositionY");
1078//// if (Field) Field->setText( QString("%1").arg(LightPosition[1]) );
1079//// Field = Lights->findChild<QLineEdit *>("LightPositionZ");
1080//// if (Field) Field->setText( QString("%1").arg(LightPosition[2]) );
1081//// Field = Lights->findChild<QLineEdit *>("LightPositionW");
1082//// if (Field) Field->setText( QString("%1").arg(LightPosition[3]) );
1083////
1084//// Field = Lights->findChild<QLineEdit *>("LightDiffuseX");
1085//// if (Field) Field->setText( QString("%1").arg(LightDiffuse[0]) );
1086//// Field = Lights->findChild<QLineEdit *>("LightDiffuseY");
1087//// if (Field) Field->setText( QString("%1").arg(LightDiffuse[1]) );
1088//// Field = Lights->findChild<QLineEdit *>("LightDiffuseZ");
1089//// if (Field) Field->setText( QString("%1").arg(LightDiffuse[2]) );
1090//// Field = Lights->findChild<QLineEdit *>("LightDiffuseW");
1091//// if (Field) Field->setText( QString("%1").arg(LightDiffuse[3]) );
1092////
1093//// Field = Lights->findChild<QLineEdit *>("LightAmbientX");
1094//// if (Field) Field->setText( QString("%1").arg(LightAmbient[0]) );
1095//// Field = Lights->findChild<QLineEdit *>("LightAmbientY");
1096//// if (Field) Field->setText( QString("%1").arg(LightAmbient[1]) );
1097//// Field = Lights->findChild<QLineEdit *>("LightAmbientZ");
1098//// if (Field) Field->setText( QString("%1").arg(LightAmbient[2]) );
1099//// Field = Lights->findChild<QLineEdit *>("LightAmbientW");
1100//// if (Field) Field->setText( QString("%1").arg(LightAmbient[3]) );
1101////
1102//// if ( Lights->exec() ) {
1103//// //cout << "User accepted.\n";
1104//// // The user accepted, act accordingly
1105//// Field = Lights->findChild<QLineEdit *>("LightPositionX");
1106//// if (Field) LightPosition[0] = Field->text().toDouble();
1107//// Field = Lights->findChild<QLineEdit *>("LightPositionY");
1108//// if (Field) LightPosition[1] = Field->text().toDouble();
1109//// Field = Lights->findChild<QLineEdit *>("LightPositionZ");
1110//// if (Field) LightPosition[2] = Field->text().toDouble();
1111//// Field = Lights->findChild<QLineEdit *>("LightPositionW");
1112//// if (Field) LightPosition[3] = Field->text().toDouble();
1113////
1114//// Field = Lights->findChild<QLineEdit *>("LightDiffuseX");
1115//// if (Field) LightDiffuse[0] = Field->text().toDouble();
1116//// Field = Lights->findChild<QLineEdit *>("LightDiffuseY");
1117//// if (Field) LightDiffuse[1] = Field->text().toDouble();
1118//// Field = Lights->findChild<QLineEdit *>("LightDiffuseZ");
1119//// if (Field) LightDiffuse[2] = Field->text().toDouble();
1120//// Field = Lights->findChild<QLineEdit *>("LightDiffuseW");
1121//// if (Field) LightDiffuse[3] = Field->text().toDouble();
1122////
1123//// Field = Lights->findChild<QLineEdit *>("LightAmbientX");
1124//// if (Field) LightAmbient[0] = Field->text().toDouble();
1125//// Field = Lights->findChild<QLineEdit *>("LightAmbientY");
1126//// if (Field) LightAmbient[1] = Field->text().toDouble();
1127//// Field = Lights->findChild<QLineEdit *>("LightAmbientZ");
1128//// if (Field) LightAmbient[2] = Field->text().toDouble();
1129//// Field = Lights->findChild<QLineEdit *>("LightAmbientW");
1130//// if (Field) LightAmbient[3] = Field->text().toDouble();
1131//// updateGL();
1132//// } else {
1133//// //cout << "User reclined.\n";
1134//// }
1135//// delete(Lights);
1136//}
1137//
1138///** Slot for event of pressed mouse button.
1139// * Switch discerns between buttons and stores position of event in GLMoleculeView::LeftButtonPos,
1140// * GLMoleculeView::MiddleButtonPos or GLMoleculeView::RightButtonPos.
1141// * \param *event structure containing information of the event
1142// */
1143//void GLMoleculeView::mousePressEvent(QMouseEvent *event)
1144//{
1145// std::cout << "MousePressEvent." << endl;
1146// QPoint *pos = NULL;
1147// switch (event->button()) { // get the right array
1148// case Qt::LeftButton:
1149// pos = &LeftButtonPos;
1150// std::cout << "Left Button" << endl;
1151// break;
1152// case Qt::MidButton:
1153// pos = &MiddleButtonPos;
1154// std::cout << "Middle Button" << endl;
1155// break;
1156// case Qt::RightButton:
1157// pos = &RightButtonPos;
1158// std::cout << "Right Button" << endl;
1159// break;
1160// default:
1161// break;
1162// }
1163// if (pos) { // store the position
1164// pos->setX(event->pos().x());
1165// pos->setY(event->pos().y());
1166// std::cout << "Stored src position is (" << pos->x() << "," << pos->y() << ")." << endl;
1167// } else {
1168// std::cout << "pos is NULL." << endl;
1169// }
1170//}
1171//
1172///** Slot for event of pressed mouse button.
1173// * Switch discerns between buttons:
1174// * -# Left Button: Rotates the view of the GLMoleculeView, relative to GLMoleculeView::LeftButtonPos.
1175// * -# Middle Button: nothing
1176// * -# Right Button: Shifts the selected molecule or atom, relative to GLMoleculeView::RightButtonPos.
1177// * \param *event structure containing information of the event
1178// */
1179//void GLMoleculeView::mouseReleaseEvent(QMouseEvent *event)
1180//{
1181// std::cout << "MouseReleaseEvent." << endl;
1182// QPoint *srcpos = NULL;
1183// QPoint destpos = event->pos();
1184// int Width = (MultiViewEnabled) ? width/2 : width;
1185// int Height = (MultiViewEnabled) ? height/2 : height;
1186// std::cout << "Received dest position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
1187// switch (event->button()) { // get the right array
1188// case Qt::LeftButton: // LeftButton rotates the view
1189// srcpos = &LeftButtonPos;
1190// std::cout << "Left Button" << endl;
1191// if (srcpos) { // subtract the position and act
1192// std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
1193// destpos -= *srcpos;
1194// std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
1195// std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
1196//
1197// int pos = (int)floor((double)srcpos->x()/(double)Width) + ((int)floor((double)srcpos->y()/(double)Height))*2;
1198// if ((MultiViewEnabled) && (pos != 2)) { // means four regions, and we are in a shifting one
1199// // switch between three regions
1200// // decide into which of the four screens the initial click has been made
1201// std::cout << "Position is " << pos << "." << endl;
1202// switch(pos) {
1203// case 0: // lower left = xz
1204// position[0] += -destpos.y()/100.;
1205// position[2] += destpos.x()/100.;
1206// break;
1207// case 1: // lower right = yz
1208// position[1] += -destpos.y()/100.;
1209// position[2] += -destpos.x()/100.;
1210// break;
1211// case 2: // upper left = projected
1212// std::cout << "This is impossible: Shifting in the projected region, we should rotate!." << endl;
1213// break;
1214// case 3: // upper right = xy
1215// position[0] += destpos.x()/100.;
1216// position[1] += -destpos.y()/100.;
1217// break;
1218// default:
1219// std::cout << "click was not in any of the four regions." << endl;
1220// break;
1221// }
1222// updateGL();
1223// } else { // we are in rotation region
1224// QWidget *Parent = parentWidget();
1225// QSlider *sliderX = Parent->findChild<QSlider *>("sliderX");
1226// QSlider *sliderY = Parent->findChild<QSlider *>("sliderY");
1227// std::cout << sliderX << " and " << sliderY << endl;
1228// if (sliderX) {
1229// int xrange = sliderX->maximum() - sliderX->minimum();
1230// double xValue = ((destpos.x() + Width) % Width);
1231// xValue *= (double)xrange/(double)Width;
1232// xValue += sliderX->value();
1233// int xvalue = (int) xValue % xrange;
1234// std::cout << "Setting x to " << xvalue << " within range " << xrange << "." << endl;
1235// setXRotation(xvalue);
1236// sliderX->setValue(xvalue);
1237// } else {
1238// std::cout << "sliderX is NULL." << endl;
1239// }
1240// if (sliderY) {
1241// int yrange = sliderY->maximum() - sliderY->minimum();
1242// double yValue = ((destpos.y() + Height) % Height);
1243// yValue *= (double)yrange/(double)Height;
1244// yValue += sliderY->value();
1245// int yvalue = (int) yValue % yrange;
1246// std::cout << "Setting y to " << yvalue << " within range " << yrange << "." << endl;
1247// setYRotation(yvalue);
1248// sliderY->setValue(yvalue);
1249// } else {
1250// std::cout << "sliderY is NULL." << endl;
1251// }
1252// }
1253// } else {
1254// std::cout << "srcpos is NULL." << endl;
1255// }
1256// break;
1257//
1258// case Qt::MidButton: // MiddleButton has no function so far
1259// srcpos = &MiddleButtonPos;
1260// std::cout << "Middle Button" << endl;
1261// if (srcpos) { // subtract the position and act
1262// QWidget *Parent = parentWidget();
1263// QSlider *sliderZ = Parent->findChild<QSlider *>("sliderZ");
1264// QSlider *sliderScale = Parent->findChild<QSlider *>("sliderScale");
1265// std::cout << sliderZ << " and " << sliderScale << endl;
1266// std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
1267// destpos -= *srcpos;
1268// std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
1269// std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
1270// if (sliderZ) {
1271// int xrange = sliderZ->maximum() - sliderZ->minimum();
1272// double xValue = ((destpos.x() + Width) % Width);
1273// xValue *= (double)xrange/(double)Width;
1274// xValue += sliderZ->value();
1275// int xvalue = (int) xValue % xrange;
1276// std::cout << "Setting x to " << xvalue << " within range " << xrange << "." << endl;
1277// setZRotation(xvalue);
1278// sliderZ->setValue(xvalue);
1279// } else {
1280// std::cout << "sliderZ is NULL." << endl;
1281// }
1282// if (sliderScale) {
1283// int yrange = sliderScale->maximum() - sliderScale->minimum();
1284// double yValue = ((destpos.y() + Height) % Height);
1285// yValue *= (double)yrange/(double)Height;
1286// yValue += sliderScale->value();
1287// int yvalue = (int) yValue % yrange;
1288// std::cout << "Setting y to " << yvalue << " within range " << yrange << "." << endl;
1289// setScale(yvalue);
1290// sliderScale->setValue(yvalue);
1291// } else {
1292// std::cout << "sliderScale is NULL." << endl;
1293// }
1294// } else {
1295// std::cout << "srcpos is NULL." << endl;
1296// }
1297// break;
1298// break;
1299//
1300// case Qt::RightButton: // RightButton moves eitstdher the selected molecule or atom
1301// srcpos = &RightButtonPos;
1302// std::cout << "Right Button" << endl;
1303// if (srcpos) { // subtract the position and act
1304// std::cout << "Stored src position is (" << srcpos->x() << "," << srcpos->y() << ")." << endl;
1305// destpos -= *srcpos;
1306// std::cout << "Resulting diff position is (" << destpos.x() << "," << destpos.y() << ")." << endl;
1307// std::cout << "Width and Height are " << Width << "," << Height << "." << endl;
1308// if (MultiViewEnabled) {
1309// // which vector to change
1310// Vector SelectedPosition;
1311// const std::vector<atom*> &SelectedAtoms = World::getInstance().getSelectedAtoms();
1312// const std::vector<molecule*> &SelectedMolecules = World::getInstance().getSelectedMolecules();
1313// if (SelectedMolecules.size()) {
1314// if (SelectedAtoms.size())
1315// SelectedPosition = (*SelectedAtoms.begin())->getPosition();
1316// else
1317// SelectedPosition = (*(*SelectedMolecules.begin())->begin())->getPosition();
1318// }
1319// // decide into which of the four screens the initial click has been made
1320// int pos = (int)floor((double)srcpos->x()/(double)Width) + ((int)floor((double)srcpos->y()/(double)Height))*2;
1321// if (!SelectedPosition.IsZero()) {
1322// std::cout << "Position is " << pos << "." << endl;
1323// switch(pos) {
1324// case 0: // lower left = xz
1325// SelectedPosition[0] += -destpos.y()/100.;
1326// SelectedPosition[2] += destpos.x()/100.;
1327// break;
1328// case 1: // lower right = yz
1329// SelectedPosition[1] += -destpos.y()/100.;
1330// SelectedPosition[2] += -destpos.x()/100.;
1331// break;
1332// case 2: // upper left = projected
1333// SelectedPosition[0] += destpos.x()/100.;
1334// SelectedPosition[1] += destpos.y()/100.;
1335// SelectedPosition[2] += destpos.y()/100.;
1336// break;
1337// case 3: // upper right = xy
1338// SelectedPosition[0] += destpos.x()/100.;
1339// SelectedPosition[1] += -destpos.y()/100.;
1340// break;
1341// default:
1342// std::cout << "click was not in any of the four regions." << endl;
1343// break;
1344// }
1345// } else {
1346// std::cout << "Nothing selected." << endl;
1347// }
1348// // update Tables
1349// if (SelectedMolecules.size()) {
1350// isSignaller = true;
1351// if (SelectedAtoms.size())
1352// emit notifyAtomChanged( (*SelectedMolecules.begin()), (*SelectedAtoms.begin()), AtomPosition);
1353// else
1354// emit notifyMoleculeChanged( (*SelectedMolecules.begin()), MoleculePosition );
1355// }
1356// // update graphic
1357// initializeGL();
1358// updateGL();
1359// } else {
1360// cout << "MultiView is not enabled." << endl;
1361// }
1362// } else {
1363// cout << "srcpos is NULL." << endl;
1364// }
1365// break;
1366//
1367// default:
1368// break;
1369// }
1370//}
1371//
1372///* ======================================== SLOTS ================================ */
1373//
1374///** Hear announcement of selected molecule.
1375// * \param *mol pointer to selected molecule
1376// */
1377//void GLMoleculeView::hearMoleculeSelected(molecule *mol)
1378//{
1379// if (isSignaller) { // if we emitted the signal, return
1380// isSignaller = false;
1381// return;
1382// }
1383// initializeGL();
1384// updateGL();
1385//};
1386//
1387///** Hear announcement of selected atom.
1388// * \param *mol pointer to molecule containing atom
1389// * \param *Walker pointer to selected atom
1390// */
1391//void GLMoleculeView::hearAtomSelected(molecule *mol, atom *Walker)
1392//{
1393// if (isSignaller) { // if we emitted the signal, return
1394// isSignaller = false;
1395// return;
1396// }
1397// initializeGL();
1398// updateGL();
1399//};
1400//
1401///** Hear announcement of changed molecule.
1402// * \param *mol pointer to changed molecule
1403// * \param type of change
1404// */
1405//void GLMoleculeView::hearMoleculeChanged(molecule *mol, enum ChangesinMolecule type)
1406//{
1407// if (isSignaller) { // if we emitted the signal, return
1408// isSignaller = false;
1409// return;
1410// }
1411// initializeGL();
1412// updateGL();
1413//};
1414//
1415///** Hear announcement of changed atom.
1416// * \param *mol pointer to molecule containing atom
1417// * \param *Walker pointer to changed atom
1418// * \param type type of change
1419// */
1420//void GLMoleculeView::hearAtomChanged(molecule *mol, atom *Walker, enum ChangesinAtom type)
1421//{
1422// if (isSignaller) { // if we emitted the signal, return
1423// isSignaller = false;
1424// return;
1425// }
1426// initializeGL();
1427// updateGL();
1428//};
1429//
1430///** Hear announcement of changed element.
1431// * \param *Runner pointer to changed element
1432// * \param type of change
1433// */
1434//void GLMoleculeView::hearElementChanged(element *Runner, enum ChangesinElement type)
1435//{
1436// if (isSignaller) { // if we emitted the signal, return
1437// isSignaller = false;
1438// return;
1439// }
1440// switch(type) {
1441// default:
1442// case ElementName:
1443// case ElementSymbol:
1444// case ElementMass:
1445// case ElementValence:
1446// case ElementZ:
1447// break;
1448// case ElementCovalent:
1449// case ElementVanderWaals:
1450// initializeGL();
1451// updateGL();
1452// break;
1453// }
1454//};
1455//
1456///** Hear announcement of added molecule.
1457// * \param *mol pointer to added molecule
1458// */
1459//void GLMoleculeView::hearMoleculeAdded(molecule *mol)
1460//{
1461// if (isSignaller) { // if we emitted the signal, return
1462// isSignaller = false;
1463// return;
1464// }
1465// initializeGL();
1466// updateGL();
1467//};
1468//
1469///** Hear announcement of added atom.
1470// * \param *mol pointer to molecule containing atom
1471// * \param *Walker pointer to added atom
1472// */
1473//void GLMoleculeView::hearAtomAdded(molecule *mol, atom *Walker)
1474//{
1475// if (isSignaller) { // if we emitted the signal, return
1476// isSignaller = false;
1477// return;
1478// }
1479// initializeGL();
1480// updateGL();
1481//};
1482//
1483///** Hear announcement of removed molecule.
1484// * \param *mol pointer to removed molecule
1485// */
1486//void GLMoleculeView::hearMoleculeRemoved(molecule *mol)
1487//{
1488// if (isSignaller) { // if we emitted the signal, return
1489// isSignaller = false;
1490// return;
1491// }
1492// initializeGL();
1493// updateGL();
1494//};
1495//
1496///** Hear announcement of removed atom.
1497// * \param *mol pointer to molecule containing atom
1498// * \param *Walker pointer to removed atom
1499// */
1500//void GLMoleculeView::hearAtomRemoved(molecule *mol, atom *Walker)
1501//{
1502// if (isSignaller) { // if we emitted the signal, return
1503// isSignaller = false;
1504// return;
1505// }
1506// initializeGL();
1507// updateGL();
1508//};
1509//
1510//void GLMoleculeView::update(Observable *publisher)
1511//{
1512// initializeGL();
1513// updateGL();
1514//}
1515//
1516///**
1517// * This method is called when a special named change
1518// * of the Observable occured
1519// */
1520//void GLMoleculeView::recieveNotification(Observable *publisher, Notification_ptr notification)
1521//{
1522// initializeGL();
1523// updateGL();
1524//}
1525//
1526///**
1527// * This method is called when the observed object is destroyed.
1528// */
1529//void GLMoleculeView::subjectKilled(Observable *publisher)
1530//{
1531//
1532//}
1533//
1534//
1535//// new stuff
1536//
1537///** Returns the ref to the Material for element No \a from the map.
1538// *
1539// * \note We create a new one if the element is missing.
1540// *
1541// * @param no element no
1542// * @return ref to QGLMaterial
1543// */
1544//QGLMaterial* GLMoleculeView::getMaterial(size_t no)
1545//{
1546// if (ElementNoMaterialMap.find(no) != ElementNoMaterialMap.end()){
1547// // get present one
1548//
1549// } else {
1550// ASSERT( (no >= 0) && (no < MAX_ELEMENTS),
1551// "GLMoleculeView::getMaterial() - Element no "+toString(no)+" is invalid.");
1552// // create new one
1553// LOG(1, "Creating new material for element "+toString(no)+".");
1554// QGLMaterial *newmaterial = new QGLMaterial(this);
1555// periodentafel *periode = World::getInstance().getPeriode();
1556// element *desiredelement = periode->FindElement(no);
1557// ASSERT(desiredelement != NULL,
1558// "GLMoleculeView::getMaterial() - desired element "+toString(no)+" not present in periodentafel.");
1559// const unsigned char* color = desiredelement->getColor();
1560// newmaterial->setAmbientColor( QColor(color[0], color[1], color[2]) );
1561// newmaterial->setSpecularColor( QColor(60, 60, 60) );
1562// newmaterial->setShininess( QColor(128) );
1563// ElementNoMaterialMap.insert( no, newmaterial);
1564// }
1565//}
1566//
1567//QGLSceneNode* GLMoleculeView::getAtom(size_t no)
1568//{
1569// // first some sensibility checks
1570// ASSERT(World::getInstance().getAtom(AtomById(no)) != NULL,
1571// "GLMoleculeView::getAtom() - desired atom "
1572// +toString(no)+" not present in the World.");
1573// ASSERT(AtomsinSceneMap.find(no) != AtomsinSceneMap.end(),
1574// "GLMoleculeView::getAtom() - desired atom "
1575// +toString(no)+" not present in the AtomsinSceneMap.");
1576//
1577// return AtomsinSceneMap[no];
1578//}
1579//
1580//QGLSceneNode* GLMoleculeView::getBond(size_t leftno, size_t rightno)
1581//{
1582// // first some sensibility checks
1583// ASSERT(World::getInstance().getAtom(AtomById(leftno)) != NULL,
1584// "GLMoleculeView::getAtom() - desired atom "
1585// +toString(leftno)+" of bond not present in the World.");
1586// ASSERT(World::getInstance().getAtom(AtomById(rightno)) != NULL,
1587// "GLMoleculeView::getAtom() - desired atom "
1588// +toString(rightno)+" of bond not present in the World.");
1589// ASSERT(AtomsinSceneMap.find(leftno) != AtomsinSceneMap.end(),
1590// "GLMoleculeView::getAtom() - desired atom "
1591// +toString(leftno)+" of bond not present in the AtomsinSceneMap.");
1592// ASSERT(AtomsinSceneMap.find(rightno) != AtomsinSceneMap.end(),
1593// "GLMoleculeView::getAtom() - desired atom "
1594// +toString(rightno)+" of bond not present in the AtomsinSceneMap.");
1595// ASSERT(leftno == rightno,
1596// "GLMoleculeView::getAtom() - bond must not be between the same atom: "
1597// +toString(leftno)+" == "+toString(rightno)+".");
1598//
1599// // then return with smaller index first
1600// if (leftno > rightno)
1601// return AtomsinSceneMap[ make_pair(rightno, leftno) ];
1602// else
1603// return AtomsinSceneMap[ make_pair(leftno, rightno) ];
1604//}
1605//
Note: See TracBrowser for help on using the repository browser.