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

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

FIX: As we use GSL internally, we are as of now required to use GPL v2 license.

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