source: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.cpp@ f7c7cf

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

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

  • GNU Scientific Library is used at every place in the code, especially the sub-package LinearAlgebra is based on it which in turn is used really everywhere in the remainder of MoleCuilder. Hence, we have to use the GPL license for the whole of MoleCuilder. In effect, GPL's COPYING was present all along and stated the terms of the GPL v2 license.
  • Hence, I added the default GPL v2 disclaimer to every source file and removed the note about a (actually missing) LICENSE file.
  • also, I added a help-redistribute action which again gives the disclaimer of the GPL v2.
  • also, I changed in the disclaimer that is printed at every program start in builder_init.cpp.
  • TEST: Added check on GPL statement present in every module to test CodeChecks project-disclaimer.
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 *
6 *
7 * This file is part of MoleCuilder.
8 *
9 * MoleCuilder is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * MoleCuilder is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with MoleCuilder. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23/*
24 * GLMoleculeObject.cpp
25 *
26 * This is based on the Qt3D example "teaservice", specifically meshobject.cpp.
27 *
28 * Created on: Aug 17, 2011
29 * Author: heber
30 */
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "GLMoleculeObject.hpp"
38
39#include <Qt3D/qglview.h>
40#include <Qt3D/qglscenenode.h>
41#include <Qt3D/qglpainter.h>
42#include <Qt3D/qglmaterial.h>
43
44#include "CodePatterns/MemDebug.hpp"
45
46#include "CodePatterns/Assert.hpp"
47#include "CodePatterns/Log.hpp"
48
49#include "Helpers/defs.hpp"
50#include "Element/element.hpp"
51#include "Element/periodentafel.hpp"
52#include "World.hpp"
53
54GLMoleculeObject::ElementMaterialMap GLMoleculeObject::ElementNoMaterialMap;
55
56
57#include "CodePatterns/MemDebug.hpp"
58
59QGLMaterial *GLMoleculeObject::m_hoverMaterial = NULL;
60QGLMaterial *GLMoleculeObject::m_selectionMaterial = NULL;
61QGLMaterial *GLMoleculeObject::m_selectionBoxMaterial = NULL;
62
63
64double GLMoleculeObject::detailMinDistance[GLMoleculeObject::DETAILTYPES_MAX] = {0, 15, 30, 42};
65
66GLMoleculeObject::GLMoleculeObject(QGLSceneNode *mesh[], QObject *parent)
67 : QObject(parent)
68{
69 //mesh->setParent(this);
70 for (int i=0;i<DETAILTYPES_MAX;i++)
71 m_mesh[i] = mesh[i];
72 m_scale = 1.0f;
73 m_scaleZ = 1.0f;
74 m_rotationAngle = 0.0f;
75 m_effect = 0;
76 m_objectId = -1;
77 m_hovering = false;
78 m_selected = false;
79 m_material = 0;
80 initStaticMaterials();
81}
82
83GLMoleculeObject::GLMoleculeObject(QGLAbstractScene *scene, QObject *parent)
84 : QObject(parent)
85{
86 scene->setParent(this);
87 m_mesh[0] = scene->mainNode();
88 m_mesh[1] = scene->mainNode();
89 m_mesh[2] = scene->mainNode();
90 m_scale = 1.0f;
91 m_scaleZ = 1.0f;
92 m_rotationAngle = 0.0f;
93 m_effect = 0;
94 m_objectId = -1;
95 m_hovering = false;
96 m_selected = false;
97 m_material = 0;
98 initStaticMaterials();
99}
100
101GLMoleculeObject::~GLMoleculeObject()
102{
103}
104
105void GLMoleculeObject::initialize(QGLView *view, QGLPainter *painter)
106{
107 Q_UNUSED(painter);
108 if (m_objectId != -1)
109 view->registerObject(m_objectId, this);
110}
111
112
113/** Draws a box around the mesh.
114 *
115 */
116void GLMoleculeObject::drawSelectionBox(QGLPainter *painter)
117{
118 painter->setFaceMaterial(QGL::AllFaces, m_selectionBoxMaterial);
119 QVector3DArray array;
120 qreal radius = 1.0;
121 array.append(-radius, -radius, -radius); array.append( radius, -radius, -radius);
122 array.append( radius, -radius, -radius); array.append( radius, radius, -radius);
123 array.append( radius, radius, -radius); array.append(-radius, radius, -radius);
124 array.append(-radius, radius, -radius); array.append(-radius, -radius, -radius);
125
126 array.append(-radius, -radius, radius); array.append( radius, -radius, radius);
127 array.append( radius, -radius, radius); array.append( radius, radius, radius);
128 array.append( radius, radius, radius); array.append(-radius, radius, radius);
129 array.append(-radius, radius, radius); array.append(-radius, -radius, radius);
130
131 array.append(-radius, -radius, -radius); array.append(-radius, -radius, radius);
132 array.append( radius, -radius, -radius); array.append( radius, -radius, radius);
133 array.append(-radius, radius, -radius); array.append(-radius, radius, radius);
134 array.append( radius, radius, -radius); array.append( radius, radius, radius);
135 painter->clearAttributes();
136 painter->setVertexAttribute(QGL::Position, array);
137 painter->draw(QGL::Lines, 24);
138}
139
140void GLMoleculeObject::draw(QGLPainter *painter, const QVector4D &cameraPlane)
141{
142 // Position the model at its designated position, scale, and orientation.
143 painter->modelViewMatrix().push();
144 painter->modelViewMatrix().translate(m_position);
145 if (m_scale != 1.0f)
146 painter->modelViewMatrix().scale(m_scale);
147 if (m_rotationAngle != 0.0f)
148 painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
149 if (m_scaleZ != 1.0f)
150 painter->modelViewMatrix().scale(1.0f, 1.0f, m_scaleZ);
151
152 // Apply the material and effect to the painter.
153 QGLMaterial *material;
154 if (m_hovering)
155 material = m_hoverMaterial;
156 else if (m_selected)
157 material = m_selectionMaterial;
158 else
159 material = m_material;
160
161 ASSERT(material, "GLMoleculeObject::draw: chosen material is NULL");
162
163 painter->setColor(material->diffuseColor());
164 painter->setFaceMaterial(QGL::AllFaces, material);
165 if (m_effect)
166 painter->setUserEffect(m_effect);
167 else
168 painter->setStandardEffect(QGL::LitMaterial);
169
170 // Mark the object for object picking purposes.
171 int prevObjectId = painter->objectPickId();
172 if (m_objectId != -1)
173 painter->setObjectPickId(m_objectId);
174
175 // Draw the geometry mesh.
176 QVector4D pos4d(m_position, -1);
177 qreal distance = QVector4D::dotProduct(cameraPlane, pos4d);
178
179 if (distance > detailMinDistance[DETAIL_LOW])
180 m_mesh[DETAIL_LOW]->draw(painter);
181 else if (distance > detailMinDistance[DETAIL_MEDIUM])
182 m_mesh[DETAIL_MEDIUM]->draw(painter);
183 else if (distance > detailMinDistance[DETAIL_HIGH])
184 m_mesh[DETAIL_HIGH]->draw(painter);
185 else if (distance > detailMinDistance[DETAIL_HIGHEST])
186 m_mesh[DETAIL_HIGHEST]->draw(painter);
187
188 // Draw a box around the mesh, if selected.
189 if (m_selected)
190 drawSelectionBox(painter);
191
192 // Turn off the user effect, if present.
193 if (m_effect)
194 painter->setStandardEffect(QGL::LitMaterial);
195
196 // Revert to the previous object identifier.
197 painter->setObjectPickId(prevObjectId);
198
199 // Restore the modelview matrix.
200 painter->modelViewMatrix().pop();
201}
202
203bool GLMoleculeObject::event(QEvent *e)
204{
205 // Convert the raw event into a signal representing the user's action.
206 if (e->type() == QEvent::MouseButtonPress) {
207 QMouseEvent *me = (QMouseEvent *)e;
208 if (me->button() == Qt::LeftButton)
209 emit pressed();
210 } else if (e->type() == QEvent::MouseButtonRelease) {
211 QMouseEvent *me = (QMouseEvent *)e;
212 if (me->button() == Qt::LeftButton) {
213 emit released();
214 if (me->x() >= 0) // Positive: inside object, Negative: outside.
215 emit clicked();
216 }
217 } else if (e->type() == QEvent::MouseButtonDblClick) {
218 emit doubleClicked();
219 } else if (e->type() == QEvent::Enter) {
220 m_hovering = true;
221 emit hoverChanged(this);
222 } else if (e->type() == QEvent::Leave) {
223 m_hovering = false;
224 emit hoverChanged(NULL);
225 }
226 return QObject::event(e);
227}
228
229/** Returns the ref to the Material for element No \a from the map.
230 *
231 * \note We create a new one if the element is missing.
232 *
233 * @param no element no
234 * @return ref to QGLMaterial
235 */
236QGLMaterial* GLMoleculeObject::getMaterial(size_t no)
237{
238 ASSERT( (no > 0) && (no < MAX_ELEMENTS),
239 "GLMoleculeView::getMaterial() - Element no "+toString(no)+" is invalid.");
240 if (ElementNoMaterialMap.find(no) != ElementNoMaterialMap.end()){
241 // get present one
242 return ElementNoMaterialMap[no];
243 } else {
244 // create new one
245 LOG(1, "Creating new material for element "+toString(no)+".");
246 QGLMaterial *newmaterial = new QGLMaterial(NULL);
247
248 // create material for element
249 periodentafel *periode = World::getInstance().getPeriode();
250 const element *desiredelement = periode->FindElement(no);
251 ASSERT(desiredelement != NULL,
252 "GLMoleculeView::getMaterial() - desired element "+toString(no)+" not present in periodentafel.");
253 const unsigned char* color = desiredelement->getColor();
254 LOG(1, "Creating new material with color " << (int)color[0] << "," << (int)color[1] << "," << (int)color[2] << ".");
255 newmaterial->setAmbientColor( QColor((int)color[0], (int)color[1], (int)color[2]) );
256 newmaterial->setSpecularColor( QColor(60, 60, 60) );
257 newmaterial->setShininess( 128 );
258 ElementNoMaterialMap.insert( make_pair(no, newmaterial) );
259
260 return newmaterial;
261 }
262}
263
264/** Create the 3 materials shared by all objects.
265 *
266 */
267void GLMoleculeObject::initStaticMaterials()
268{
269 if (!m_hoverMaterial){
270 m_hoverMaterial = new QGLMaterial(NULL);
271 m_hoverMaterial->setAmbientColor( QColor(0, 128, 128) );
272 m_hoverMaterial->setSpecularColor( QColor(60, 60, 60) );
273 m_hoverMaterial->setShininess( 128 );
274 }
275 if (!m_selectionMaterial){
276 m_selectionMaterial = new QGLMaterial(NULL);
277 m_selectionMaterial->setAmbientColor( QColor(255, 50, 50) );
278 m_selectionMaterial->setSpecularColor( QColor(60, 60, 60) );
279 m_selectionMaterial->setShininess( 128 );
280 }
281 if (!m_selectionBoxMaterial){
282 m_selectionBoxMaterial = new QGLMaterial(NULL);
283 m_selectionBoxMaterial->setAmbientColor( QColor(0, 0, 0) );
284 m_selectionBoxMaterial->setDiffuseColor( QColor(0, 0, 0) );
285 m_selectionBoxMaterial->setEmittedLight( QColor(155, 50, 50) );
286 }
287}
288
289/** Static function to be called when Materials have to be removed.
290 *
291 */
292void GLMoleculeObject::cleanMaterialMap()
293{
294 for (ElementMaterialMap::iterator iter = ElementNoMaterialMap.begin();
295 !ElementNoMaterialMap.empty();
296 iter = ElementNoMaterialMap.begin()) {
297 delete iter->second;
298 ElementNoMaterialMap.erase(iter);
299 }
300}
301
302
303void GLMoleculeObject::setSelected(bool value)
304{
305 if (value != m_selected){
306 m_selected = value;
307 emit selectionChanged();
308 }
309}
Note: See TracBrowser for help on using the repository browser.