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

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 4f7f0bf was 407638e, checked in by Michael Ankele <ankele@…>, 13 years ago

GL: Qt signals rewired

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