source: src/UIElements/Views/Qt4/Qt3D/GLWorldView.cpp@ 0eb7bf3

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 0eb7bf3 was f31b34, checked in by Michael Ankele <ankele@…>, 13 years ago

rearranged toolbar buttons + more sensible icons

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