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

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 a8fc70 was a8fc70, checked in by Frederik Heber <heber@…>, 12 years ago

FIX: Added disable to stereo-viewing options.

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