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

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 30cd0d was 30cd0d, checked in by Michael Ankele <ankele@…>, 13 years ago

GLWorldScene handles IndexChanged message from atoms

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