source: src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp@ 47f0e4

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 47f0e4 was 15c8a9, checked in by Frederik Heber <heber@…>, 9 years ago

Added QtInstanceInformationBoard that handles ObservedValues through the QtGui interface.

  • this is meant as a instantiator of all ObservedValue's needed by QtGui for representing information from the World. The ObservedValue's are instantiated separately w.r.t. to the instance for the visual representation. This is light-weight and can be performed in the same thread, while the visual representation's instantiation can be done elsewhere and there we just need to access the ready ObservedValue's that exist as long as they are needed by the QtGui.
  • Property mode set to 100644
File size: 22.6 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 * Copyright (C) 2013 Frederik Heber. All rights reserved.
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/>.
22 */
23
24/*
25 * GLWorldScene.cpp
26 *
27 * This is based on the Qt3D example "teaservice", specifically parts of teaservice.cpp.
28 *
29 * Created on: Aug 17, 2011
30 * Author: heber
31 */
32
33// include config.h
34#ifdef HAVE_CONFIG_H
35#include <config.h>
36#endif
37
38#include "GLWorldScene.hpp"
39#include <Qt3D/qglview.h>
40#include <Qt3D/qglbuilder.h>
41#include <Qt3D/qglscenenode.h>
42#include <Qt3D/qglsphere.h>
43#include <Qt3D/qglcylinder.h>
44
45#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject.hpp"
46#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp"
47#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp"
48#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp"
49#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_shape.hpp"
50
51#include "UIElements/Views/Qt4/QtInstanceInformationBoard.hpp"
52#include "UIElements/Views/Qt4/QtSelectionChangedAgent.hpp"
53
54#include "CodePatterns/MemDebug.hpp"
55
56#include "CodePatterns/Log.hpp"
57
58#include "Actions/SelectionAction/Atoms/AtomByIdAction.hpp"
59#include "Actions/SelectionAction/Atoms/NotAtomByIdAction.hpp"
60#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
61#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
62#include "Atom/atom.hpp"
63#include "Bond/bond.hpp"
64#include "Descriptors/AtomIdDescriptor.hpp"
65#include "Descriptors/MoleculeIdDescriptor.hpp"
66#include "Helpers/helpers.hpp"
67#include "Shapes/ShapeRegistry.hpp"
68#include "molecule.hpp"
69#include "World.hpp"
70
71#include <iostream>
72
73using namespace MoleCuilder;
74
75GLWorldScene::GLWorldScene(
76 QtInstanceInformationBoard * _board,
77 QObject *parent) :
78 QObject(parent),
79 selectionMode(SelectAtom),
80 board(_board)
81{
82 int sphereDetails[] = {5, 3, 2, 0};
83 int cylinderDetails[] = {16, 8, 6, 3};
84 for (int i=0;i<GLMoleculeObject::DETAILTYPES_MAX;i++){
85 QGLBuilder emptyBuilder;
86 GLMoleculeObject::meshEmpty[i] = emptyBuilder.finalizedSceneNode();
87 QGLBuilder sphereBuilder;
88 sphereBuilder << QGLSphere(2.0, sphereDetails[i]);
89 GLMoleculeObject::meshSphere[i] = sphereBuilder.finalizedSceneNode();
90 GLMoleculeObject::meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
91 QGLBuilder cylinderBuilder;
92 cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
93 GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
94 GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
95 }
96 connect(board, SIGNAL(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)),
97 this, SLOT(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)));
98 connect(board, SIGNAL(moleculeInserted(const moleculeId_t)),
99 this, SLOT(moleculeInserted(const moleculeId_t)));
100 connect(board, SIGNAL(moleculeRemoved(const moleculeId_t)),
101 this, SLOT(moleculeRemoved(const moleculeId_t)));
102 connect(board, SIGNAL(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)),
103 this, SLOT(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)));
104
105// connect(this, SIGNAL(updated()), this, SLOT(update()));
106}
107
108GLWorldScene::~GLWorldScene()
109{
110 // remove all elements
111 GLMoleculeObject::cleanMaterialMap();
112}
113
114///** Update the WorldScene with molecules and atomsfrom World.
115// *
116// * This function should be called after e.g. WorldTime::TimeChanged was
117// * received or after another molecule has been loaded.
118// *
119// */
120//void GLWorldScene::update()
121//{
122// const std::vector<const molecule *> &molecules =
123// const_cast<const World &>(World::getInstance()).getAllMolecules();
124//
125// for (std::vector<const molecule*>::const_iterator moliter = molecules.begin();
126// moliter != molecules.end();
127// moliter++) {
128// boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
129// // check whether molecule already exists
130// const moleculeId_t molid = (*moliter)->getId();
131// const bool mol_present = MoleculesinSceneMap.count(molid);
132// if (!mol_present)
133// moleculeInserted((*moliter)->getId());
134// }
135//
136// boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
137// MoleculeNodeMap::iterator iter = MoleculesinSceneMap.begin();
138// for (;iter != MoleculesinSceneMap.end();) {
139// const moleculeId_t molid = iter->first;
140// const molecule * const mol = const_cast<const World &>(World::getInstance()).
141// getMolecule(MoleculeById(molid));
142// const bool mol_absent = (mol == NULL);
143// // step on to next molecule before possibly removing entry and invalidating iter
144// ++iter;
145// if (mol_absent)
146// moleculeRemoved(molid);
147// }
148//
149//}
150
151void GLWorldScene::atomClicked(atomId_t no)
152{
153 LOG(3, "INFO: GLMoleculeObject_molecule - atom " << no << " has been clicked.");
154 const atom * const Walker = const_cast<const World &>(World::getInstance()).
155 getAtom(AtomById(no));
156 ASSERT( Walker != NULL,
157 "GLWorldScene::atomClicked() - clicked atom has disappeared.");
158 if (selectionMode == SelectAtom){
159 if (!World::getInstance().isSelected(Walker))
160 SelectionAtomById(std::vector<atomId_t>(1,no));
161 else
162 SelectionNotAtomById(std::vector<atomId_t>(1,no));
163 }else if (selectionMode == SelectMolecule){
164 const molecule *mol = Walker->getMolecule();
165 ASSERT(mol, "Atom without molecule has been clicked.");
166 molids_t ids(1, mol->getId());
167 if (!World::getInstance().isSelected(mol))
168 SelectionMoleculeById(ids);
169 else
170 SelectionNotMoleculeById(ids);
171 }
172 emit clicked(no);
173}
174
175void GLWorldScene::moleculeClicked(moleculeId_t no)
176{
177 LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
178 const molecule * const mol= const_cast<const World &>(World::getInstance()).
179 getMolecule(MoleculeById(no));
180 ASSERT(mol, "Atom without molecule has been clicked.");
181 molids_t ids(1, mol->getId());
182 if (!World::getInstance().isSelected(mol))
183 SelectionMoleculeById(ids);
184 else
185 SelectionNotMoleculeById(ids);
186 emit clicked(no);
187}
188
189/** Inserts an atom into the scene before molecule is present.
190 *
191 * @param _molid molecule to insert atom for
192 * @param _atomid atom to insert
193 */
194void GLWorldScene::atomInserted(const moleculeId_t _molid, const atomId_t _atomid)
195{
196 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
197
198 LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_atomid)+".");
199
200 // check of molecule is already present
201 if (MoleculesinSceneMap.count(_molid) != 0) {
202 // pass signal through
203 } else {
204 // store signal for when it is instantiated
205 if (MoleculeMissedStateMap.count(_molid) == 0)
206 MoleculeMissedStateMap.insert( std::make_pair(_molid ,StateChangeMap_t()) );
207 MoleculeMissedStateMap[_molid].insert( std::make_pair(_atomid, atomInsertedState) );
208 }
209}
210
211/** Removes an atom into the scene before molecule is present.
212 *
213 * @param _molid molecule to insert atom for
214 * @param _atomid atom to insert
215 */
216void GLWorldScene::atomRemoved(const moleculeId_t _molid, const atomId_t _atomid)
217{
218 LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_atomid)+".");
219
220 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
221
222 // check of molecule is already present
223 if (MoleculesinSceneMap.count(_molid) != 0) {
224 // pass signal through
225 } else {
226 // store signal for when it is instantiated
227 if (MoleculeMissedStateMap.count(_molid) == 0)
228 MoleculeMissedStateMap.insert( std::make_pair(_molid ,StateChangeMap_t()) );
229 MoleculeMissedStateMap[_molid].insert( std::make_pair(_atomid, atomRemovedState) );
230 }
231}
232
233/** Inserts a molecule into the scene.
234 *
235 * @param _mol molecule to insert
236 */
237void GLWorldScene::moleculeInserted(const moleculeId_t _id)
238{
239 LOG(3, "INFO: GLWorldScene: Received signal moleculeInserted for molecule "+toString(_id)+".");
240
241 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
242
243 MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(_id);
244 ASSERT( iter == MoleculesinSceneMap.end(),
245 "GLWorldScene::moleculeInserted() - molecule's id "+toString(_id)+" already present.");
246
247 // check whether molecule is still present
248 if (RemovalMolecules.count(_id) != 0) {
249 RemovalMolecules.erase(_id);
250 return;
251 }
252 if (const_cast<const World &>(World::getInstance()).getMolecule(MoleculeById(_id)) == NULL) {
253 ELOG(2, "Molecule with id " << _id << " has disappeared.");
254 return;
255 }
256
257 // add new object
258 LOG(1, "DEBUG: Adding GLMoleculeObject_molecule to id " << _id);
259 GLMoleculeObject_molecule *molObject =
260 new GLMoleculeObject_molecule(
261 GLMoleculeObject::meshEmpty, this, _id);
262 ASSERT( molObject != NULL,
263 "GLWorldScene::moleculeInserted - could not create molecule object for "+toString(_id));
264 MoleculesinSceneMap.insert( make_pair(_id, molObject) );
265
266 // now handle all state changes that came up before the instantiation
267 while (MoleculeMissedStateMap.count(_id) != 0) {
268 ASSERT( !MoleculeMissedStateMap[_id].empty(),
269 "GLWorldScene::moleculeInserted() - we have an empty state change map for molecule with id "
270 +toString(_id));
271 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
272 for (StateChangeMap_t::iterator iter = MoleculeMissedStateMap[_id].begin();
273 !MoleculeMissedStateMap[_id].empty();
274 iter = MoleculeMissedStateMap[_id].begin()) {
275 std::pair<StateChangeMap_t::iterator, StateChangeMap_t::iterator> rangeiter =
276 MoleculeMissedStateMap[_id].equal_range(iter->first);
277 const size_t StateCounts = std::distance(rangeiter.first, rangeiter.second);
278 if (StateCounts > 1) {
279 // more than one state change, have to combine
280 typedef std::map<StateChangeType, size_t> StateChangeAmounts_t;
281 StateChangeAmounts_t StateChangeAmounts;
282 for (StateChangeMap_t::const_iterator stateiter = rangeiter.first;
283 stateiter != rangeiter.second; ++stateiter)
284 ++StateChangeAmounts[stateiter->second];
285 ASSERT( StateChangeAmounts[atomInsertedState] >= StateChangeAmounts[atomRemovedState],
286 "GLWorldScene::moleculeInserted() - more atomRemoved states than atomInserted for atom "
287 +toString(iter->first));
288 if (StateChangeAmounts[atomInsertedState] > StateChangeAmounts[atomRemovedState]) {
289 LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
290 QMetaObject::invokeMethod(molObject, // pointer to a QObject
291 "atomInserted", // member name (no parameters here)
292 Qt::DirectConnection, // connection type
293 Q_ARG(const atomId_t, iter->first)); // parameters
294 } else {
295 LOG(1, "INFO: Atom " << iter->first << " has been inserted and removed already.");
296 }
297 } else {
298 // can only be an insertion
299 switch (rangeiter.first->second) {
300 case atomRemovedState:
301 ASSERT( 0,
302 "GLWorldScene::moleculeInserted() - atomRemoved state without atomInserted for atom "
303 +toString(iter->first));
304 break;
305 case atomInsertedState:
306 LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
307 QMetaObject::invokeMethod(molObject, // pointer to a QObject
308 "atomInserted", // member name (no parameters here)
309 Qt::DirectConnection, // connection type
310 Q_ARG(const atomId_t, iter->first)); // parameters
311 break;
312 default:
313 ASSERT( 0,
314 "GLWorldScene::moleculeInserted() - there are unknown change states.");
315 break;
316 }
317 }
318 // removed state changes for this atom
319 MoleculeMissedStateMap[_id].erase(iter);
320 }
321 // remove state change map for the molecule
322 MoleculeMissedStateMap.erase(_id);
323 }
324
325 // now let the molObject sign on to molecule
326 molObject->activateObserver();
327
328 connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
329 connect (molObject, SIGNAL(changeOccured()), this, SIGNAL(changeOccured()));
330 connect (molObject, SIGNAL(atomClicked(atomId_t)), this, SLOT(atomClicked(atomId_t)));
331 connect (molObject, SIGNAL(moleculeClicked(moleculeId_t)), this, SLOT(moleculeClicked(moleculeId_t)));
332 connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
333 connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
334 connect (molObject, SIGNAL(hoverChanged(const atomId_t)), this, SIGNAL(hoverChanged(const atomId_t)));
335 connect (molObject, SIGNAL(hoverChanged(const moleculeId_t, int)), this, SIGNAL(hoverChanged(const moleculeId_t, int)));
336 connect (molObject, SIGNAL(hoverChanged(const moleculeId_t, int)), this, SIGNAL(hoverChanged(const moleculeId_t, int)));
337
338 emit changed();
339 emit changeOccured();
340}
341
342/** Removes a molecule from the scene.
343 *
344 * @param _id id of molecule to remove
345 */
346void GLWorldScene::moleculeRemoved(const moleculeId_t _id)
347{
348 LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_id)+".");
349
350 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
351
352 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
353 if ( iter == MoleculesinSceneMap.end()) {
354 RemovalMolecules.insert(_id);
355 } else {
356 LOG(1, "DEBUG: Removing GLMoleculeObject_molecule to id " << _id);
357 GLMoleculeObject_molecule *molObject = iter->second;
358 molObject->disconnect();
359 MoleculesinSceneMap.erase(iter);
360 delete molObject;
361 }
362
363 // remove any possible state changes left
364 {
365 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
366 MoleculeMissedStateMap.erase(_id);
367 }
368
369 emit changed();
370 emit changeOccured();
371}
372
373void GLWorldScene::moleculeIndexChanged(const moleculeId_t _oldid, const moleculeId_t _newid)
374{
375 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_oldid);
376 if ( iter == MoleculesinSceneMap.end()) {
377 RemovalMolecule_t::iterator removeiter =
378 RemovalMolecules.find(_oldid);
379 ASSERT( removeiter != RemovalMolecules.end(),
380 "GLWorldScene::moleculeIndexChanged() - cannot find id "+toString(_oldid)+" in any map.");
381 RemovalMolecules.erase(removeiter);
382 RemovalMolecules.insert(_newid);
383 } else {
384 LOG(1, "DEBUG: Changing GLMoleculeObject_molecule from " << _oldid << " to id " << _newid);
385 GLMoleculeObject_molecule* molObject = iter->second;
386 MoleculesinSceneMap.erase(iter);
387 MoleculesinSceneMap.insert(
388 std::make_pair( _newid, molObject) );
389 }
390}
391
392void GLWorldScene::moleculesVisibilityChanged(const moleculeId_t _id, bool _visible)
393{
394 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
395 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
396 ASSERT( iter != MoleculesinSceneMap.end(),
397 "GLWorldScene::moleculeInserted() - molecule's id "+toString(_id)+" is unknown.");
398
399 GLMoleculeObject_molecule *molObject = iter->second;
400 molObject->setVisible(_visible);
401
402 emit changed();
403 emit changeOccured();
404}
405
406/** Adds a shape to the scene.
407 *
408 */
409void GLWorldScene::addShape(const std::string &_name)
410{
411 Shape * const shape = ShapeRegistry::getInstance().getByName(_name);
412 if (shape != NULL) {
413 GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(*shape, this);
414 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
415 ASSERT(iter == ShapesinSceneMap.end(),
416 "GLWorldScene::addShape() - same shape "+_name+" added again.");
417 ShapesinSceneMap.insert( make_pair(_name, shapeObject) );
418 } else
419 ELOG(2, "GLWorldScene::addShape() - shape disappeared before we could draw it.");
420
421 emit changed();
422}
423
424void GLWorldScene::removeShape(const std::string &_name)
425{
426 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
427 ASSERT(iter != ShapesinSceneMap.end(),
428 "GLWorldScene::removeShape() - shape "+_name+" not in scene.");
429 ShapesinSceneMap.erase(iter);
430 delete(iter->second);
431
432 emit changed();
433}
434
435void GLWorldScene::updateSelectedShapes()
436{
437 foreach (QObject *obj, children()) {
438 GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
439 if (shapeobj){
440 shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
441 }
442 }
443
444 emit changed();
445}
446
447void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
448{
449 // Initialize all of the mesh objects that we have as children.
450 foreach (QObject *obj, children()) {
451 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
452 if (meshobj)
453 meshobj->initialize(view, painter);
454 }
455}
456
457void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
458{
459 // Draw all of the mesh objects that we have as children.
460 foreach (QObject *obj, children()) {
461 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
462 if (meshobj)
463 meshobj->draw(painter, cameraPlane);
464 }
465}
466
467void GLWorldScene::setSelectionMode(SelectionModeType mode)
468{
469 selectionMode = mode;
470 // TODO send update to toolbar
471}
472
473void GLWorldScene::setSelectionChangedAgent(QtSelectionChangedAgent *agent)
474{
475 connect(agent, SIGNAL(atomSelected(const moleculeId_t, const atomId_t)),
476 this, SLOT(AtomSelected(const moleculeId_t, const atomId_t)));
477 connect(agent, SIGNAL(atomUnselected(const moleculeId_t, const atomId_t)),
478 this, SLOT(AtomUnselected(const moleculeId_t, const atomId_t)));
479
480 connect(agent, SIGNAL(moleculeSelected(const moleculeId_t)),
481 this, SLOT(MoleculeSelected(const moleculeId_t)));
482 connect(agent, SIGNAL(moleculeUnselected(const moleculeId_t)),
483 this, SLOT(MoleculeUnselected(const moleculeId_t)));
484}
485
486void GLWorldScene::setSelectionModeAtom()
487{
488 setSelectionMode(SelectAtom);
489}
490
491void GLWorldScene::setSelectionModeMolecule()
492{
493 setSelectionMode(SelectMolecule);
494}
495
496void GLWorldScene::changeMoleculeId(
497 GLMoleculeObject_molecule *ob,
498 const moleculeId_t oldId,
499 const moleculeId_t newId)
500{
501 LOG(3, "INFO: GLWorldScene - change molecule id " << oldId << " to " << newId << ".");
502
503 {
504 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
505 // Remove from map.
506 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(oldId);
507 ASSERT(iter != MoleculesinSceneMap.end(),
508 "GLWorldScene::changeMoleculeId() - molecule with old id "+toString(oldId)+" not on display.");
509 ASSERT(iter->second == ob,
510 "GLWorldScene::changeMoleculeId() - molecule with id "
511 +toString(oldId)+" does not match with object in MoleculesinSceneMap.");
512 MoleculesinSceneMap.erase(iter);
513
514 // Reinsert with new id.
515 {
516 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(newId);
517 ASSERT(iter == MoleculesinSceneMap.end(),
518 "GLWorldScene::changeMoleculeId() - moleculewith new id "+toString(newId)+" already known.");
519 }
520 MoleculesinSceneMap.insert( make_pair(newId, ob) );
521 }
522
523 {
524 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
525 // Remove and re-insert from map if present.
526 MoleculeMissedStateMap_t::iterator iter = MoleculeMissedStateMap.find(oldId);
527 if (iter != MoleculeMissedStateMap.end()) {
528 StateChangeMap_t changemap = iter->second;
529 MoleculeMissedStateMap.erase(iter);
530 MoleculeMissedStateMap.insert( std::make_pair(newId, changemap) );
531 }
532 }
533}
534
535void GLWorldScene::AtomSelected(const moleculeId_t _molid, const atomId_t _id)
536{
537 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
538 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
539 // use direct connection as it's lightweight and we avoid index change troubles
540 if (iter != MoleculesinSceneMap.end())
541 QMetaObject::invokeMethod(iter->second, // pointer to a QObject
542 "AtomSelected", // member name (no parameters here)
543 Qt::DirectConnection, // connection type
544 Q_ARG(const atomId_t, _id)); // parameters
545 else
546 ELOG(2, "DEBUG: GLWorldScene::AtomSelected() - molecule " <<
547 _molid << " unknown to GLWorldScene.");
548}
549
550void GLWorldScene::AtomUnselected(const moleculeId_t _molid, const atomId_t _id)
551{
552 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
553 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
554 // use direct connection as it's lightweight and we avoid index change troubles
555 if (iter != MoleculesinSceneMap.end())
556 QMetaObject::invokeMethod(iter->second, // pointer to a QObject
557 "AtomUnselected", // member name (no parameters here)
558 Qt::DirectConnection, // connection type
559 Q_ARG(const atomId_t, _id)); // parameters
560 else
561 ELOG(2, "GLWorldScene::AtomUnselected() - molecule "
562 << _molid << " unknown to GLWorldScene.");
563}
564
565void GLWorldScene::MoleculeSelected(const moleculeId_t _molid)
566{
567 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
568MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
569 if (iter != MoleculesinSceneMap.end())
570 QMetaObject::invokeMethod(iter->second, // pointer to a QObject
571 "Selected", // member name (no parameters here)
572 Qt::QueuedConnection); // connection type
573 else
574 ELOG(2, "GLWorldScene::MoleculeSelected() - molecule "
575 << _molid << " unknown to GLWorldScene.");
576}
577
578void GLWorldScene::MoleculeUnselected(const moleculeId_t _molid)
579{
580 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
581 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
582 if (iter != MoleculesinSceneMap.end())
583 QMetaObject::invokeMethod(iter->second, // pointer to a QObject
584 "Unselected", // member name (no parameters here)
585 Qt::QueuedConnection); // connection type
586 else
587 ELOG(2, "GLWorldScene::MoleculeUnselected() - molecule "
588 << _molid << " unknown to GLWorldScene.");
589}
Note: See TracBrowser for help on using the repository browser.