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

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

FIX: Fixed new copyright line since start of 2013 in CodeChecks test.

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