source: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.cpp@ 8819d2

Candidate_v1.6.1 ChemicalSpaceEvaluator Gui_displays_atomic_force_velocity PythonUI_with_named_parameters TremoloParser_IncreasedPrecision
Last change on this file since 8819d2 was 897a01, checked in by Frederik Heber <frederik.heber@…>, 7 years ago

Arrows display velocity and force of each atom.

  • Property mode set to 100644
File size: 7.3 KB
RevLine 
[907636]1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
[0aa122]4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
[5aaa43]5 * Copyright (C) 2013 Frederik Heber. All rights reserved.
[94d5ac6]6 *
7 *
8 * This file is part of MoleCuilder.
9 *
10 * MoleCuilder is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * MoleCuilder is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
[907636]22 */
23
24/*
25 * GLMoleculeObject_atom.cpp
26 *
27 * Created on: Aug 17, 2011
28 * Author: heber
29 */
30
31// include config.h
32#ifdef HAVE_CONFIG_H
33#include <config.h>
34#endif
35
36#include "GLMoleculeObject_atom.hpp"
37
38#include <Qt3D/qglscenenode.h>
39
[9eb71b3]40//#include "CodePatterns/MemDebug.hpp"
[907636]41
42#include "CodePatterns/Assert.hpp"
[7188b1]43#include "CodePatterns/Log.hpp"
[02ce36]44#include "CodePatterns/Observer/Notification.hpp"
[907636]45
[534374]46#include <algorithm>
47
[2ad1ec]48#include "Atom/atom.hpp"
49#include "Bond/bond.hpp"
[3bdb6d]50#include "Element/element.hpp"
[534374]51#include "Element/periodentafel.hpp"
[897a01]52#include "LinearAlgebra/Line.hpp"
[907636]53#include "LinearAlgebra/Vector.hpp"
[8d5fbf1]54#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp"
[2f7988]55#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
[7188b1]56#include "World.hpp"
[534374]57
[026bef]58GLMoleculeObject_atom::GLMoleculeObject_atom(
59 QGLSceneNode *mesh[],
[897a01]60 QGLSceneNode *mesharrow[],
[026bef]61 QObject *parent,
[1b07b1]62 QtObservedAtom::ptr &_ObservedAtom) :
[026bef]63 GLMoleculeObject(mesh, parent),
[897a01]64 GLMoleculeObjectVelocity(mesharrow, this),
65 GLMoleculeObjectForce(mesharrow, this),
[65c323]66 ObservedAtom(_ObservedAtom)
[026bef]67{
[65c323]68 init(ObservedAtom->getAtomIndex());
[026bef]69}
70
71void GLMoleculeObject_atom::init(const atomId_t _id)
72{
[534374]73 setObjectId(_id);
74 resetPosition();
[897a01]75 resetVelocity();
76 resetForce();
[534374]77 resetElement();
[7188b1]78
[897a01]79 GLMoleculeObjectVelocity.setMaterial(GLMoleculeObject::m_velocityMaterial);
80 GLMoleculeObjectForce.setMaterial(GLMoleculeObject::m_forceMaterial);
81
[d16a06]82 m_selected = ObservedAtom->getAtomSelected();
[a39d72]83
[7188b1]84 connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
[522c45]85 connect( ObservedAtom.get(), SIGNAL(indexChanged()), this, SLOT(resetIndex()));
[65c323]86 connect( ObservedAtom.get(), SIGNAL(elementChanged()), this, SLOT(resetElement()));
87 connect( ObservedAtom.get(), SIGNAL(positionChanged()), this, SLOT(resetPosition()));
[897a01]88 connect( ObservedAtom.get(), SIGNAL(velocityChanged()), this, SLOT(resetVelocity()));
89 connect( ObservedAtom.get(), SIGNAL(forceChanged()), this, SLOT(resetForce()));
[5cd3a33]90 connect( ObservedAtom.get(), SIGNAL(selectedChanged()), this, SLOT(resetSelected()));
[7188b1]91}
92
[534374]93GLMoleculeObject_atom::~GLMoleculeObject_atom()
[65c323]94{}
[534374]95
[522c45]96void GLMoleculeObject_atom::resetIndex()
[534374]97{
[65c323]98 const atomId_t newId = ObservedAtom->getAtomIndex();
[534374]99 const size_t oldId = objectId();
100 ASSERT( newId != oldId,
101 "GLMoleculeObject_atom::updateIndex() - index "+toString(newId)+" did not change.");
102 LOG(4, "INFO: GLMoleculeObject_atom::resetIndex() - new index is "+toString(newId)+".");
103 setObjectId(newId);
[494478]104
105 emit indexChanged(this, oldId, newId);
[7188b1]106}
107
[897a01]108static void setArrow(
109 const Vector &_position,
110 const Vector &_arrow,
111 const double _offset,
112 GLMoleculeObject &_obj)
113{
114 // set position (cylinder offset is in its barymetric center)
115 Vector OneFourth(_position + (_offset/_arrow.Norm()+.75) * _arrow);
116 _obj.setPosition(QVector3D(OneFourth[0], OneFourth[1], OneFourth[2]));
117}
118
[7188b1]119void GLMoleculeObject_atom::resetPosition()
[907636]120{
[65c323]121 const Vector Position = ObservedAtom->getAtomPosition();
[96f14a]122 LOG(4, "INFO: GLMoleculeObject_atom::resetPosition() - new position is "+toString(Position)+".");
[534374]123 setPosition(QVector3D(Position[0], Position[1], Position[2]));
[897a01]124 setArrow(Position, 10.*ObservedAtom->getAtomVelocity(), scaleX(), GLMoleculeObjectVelocity);
125 setArrow(Position, 10.*ObservedAtom->getAtomForce(), scaleX(), GLMoleculeObjectForce);
126}
127
128static void alignArrow(
129 const Vector &_arrow,
130 GLMoleculeObject &_obj)
131{
132 if (_arrow.IsZero()) {
133 _obj.setScaleZ(0.);
134 return;
135 }
136 // calculate position
137 Vector Z(unitVec[2]); // cylinder are initially aligned along the Z axis
138 Vector b;
139 Vector OtherAxis;
140 double alpha;
141 // construct rotation axis
142 b = -1.*_arrow;
143 b.VectorProduct(Z);
144 Line axis(zeroVec, b);
145 // calculate rotation angle
146 alpha = _arrow.Angle(Z);
147 // construct other axis to check right-hand rule
148 OtherAxis = b;
149 OtherAxis.VectorProduct(Z);
150 // assure right-hand rule for the rotation
151 if (_arrow.ScalarProduct(OtherAxis) < MYEPSILON)
152 alpha = M_PI-alpha;
153 // check
154 Vector a_rotated = axis.rotateVector(_arrow, alpha);
155 LOG(5, "DEBUG: Aligning arrow " << _arrow << " to " << a_rotated
156 << " around " << b << " by " << alpha/M_PI*180. << ".");
157
158 _obj.setScaleZ(10.*_arrow.Norm());
159 _obj.setRotationVector(QVector3D(b[0], b[1], b[2]));
160 _obj.setRotationAngle(alpha/M_PI*180.);
161}
162
163void GLMoleculeObject_atom::resetVelocity()
164{
165 const Vector Velocity = ObservedAtom->getAtomVelocity();
166 LOG(4, "INFO: GLMoleculeObject_atom::resetVelocity() - new velocity is "+toString(Velocity)+".");
167 alignArrow(Velocity, GLMoleculeObjectVelocity);
168// GLMoleculeObjectForce.setScaleZ(Velocity.Norm());
169}
170
171void GLMoleculeObject_atom::resetForce()
172{
173 const Vector Force = ObservedAtom->getAtomForce();
174 LOG(4, "INFO: GLMoleculeObject_atom::resetForce() - new force is "+toString(Force)+".");
175 alignArrow(Force, GLMoleculeObjectForce);
176// GLMoleculeObjectForce.setScaleZ(Force.Norm());
[7188b1]177}
178
179void GLMoleculeObject_atom::resetElement()
180{
181 size_t elementno = 0;
[534374]182 const element * const _type = World::getInstance().
[65c323]183 getPeriode()->FindElement(ObservedAtom->getAtomElement());
[c60665]184 if (_type != NULL) {
185 elementno = _type->getAtomicNumber();
186 } else { // if no element yet, set to hydrogen
187 elementno = 1;
188 }
[96f14a]189 LOG(4, "INFO: GLMoleculeObject_atom::resetElement() - new element number is "+toString(elementno)+".");
[c60665]190
191 // set materials
192 QGLMaterial *elementmaterial = getMaterial(elementno);
193 ASSERT(elementmaterial != NULL,
[96f14a]194 "GLMoleculeObject_atom::resetElement() - QGLMaterial ref from getter function is NULL.");
[c60665]195 setMaterial(elementmaterial);
196
197 // set scale
198 double radius = 0.;
199 if (_type != NULL) {
200 radius = _type->getVanDerWaalsRadius();
201 } else {
202 radius = 0.5;
203 }
204 setScale( radius / 4. );
[534374]205}
[f115cc]206
[5cd3a33]207void GLMoleculeObject_atom::resetSelected()
[015f8c]208{
[03e69e]209 // we ascertain check that selection state changed as the Qt signal might be executed
210 // at a later stage when the state has changed yet again
[5cd3a33]211 const bool new_selected = ObservedAtom->getAtomSelected();
212 m_selected = new_selected;
[015f8c]213
214 emit changed();
215}
216
[534374]217void GLMoleculeObject_atom::draw(QGLPainter *painter, const QVector4D &cameraPlane)
218{
219 // call old hook to do the actual paining
220 GLMoleculeObject::draw(painter, cameraPlane);
[897a01]221 GLMoleculeObjectVelocity.draw(painter, cameraPlane);
222 GLMoleculeObjectForce.draw(painter, cameraPlane);
[7188b1]223}
224
[534374]225void GLMoleculeObject_atom::wasClicked()
[7188b1]226{
[65c323]227 LOG(4, "INFO: GLMoleculeObject_atom: atom "
228 << ObservedAtom->getAtomIndex() << " has been clicked");
229 emit clicked(ObservedAtom->getAtomIndex());
[7c7c4a]230}
Note: See TracBrowser for help on using the repository browser.