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

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 v1.3.7
Last change on this file since c8f12e was 5b991a, checked in by Frederik Heber <heber@…>, 12 years ago

compile icons into the executable

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