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

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 Candidate_v1.7.0 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 859a00 was 859a00, checked in by Michael Ankele <ankele@…>, 13 years ago

added selection modes to toolbar

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