source: src/UIElements/Views/Qt4/Qt3D/GLWorldView.cpp@ 72a4c1

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

GL: using multiple levels of detail for the meshes

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