source: src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp@ 8b59dd

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 8b59dd was 96e145, checked in by Frederik Heber <heber@…>, 9 years ago

AtomInserted/Removed of QtObservedMolecule sends ptr as unique key.

  • this is used to associate the atom with the right molecule. This is needed in case when the molecule is deleted and a new one with the same id is created. If signals are delayed, we need to know which atomInserted/Removed signal to associated with which GLMoleculeObject_molecule.
  • Property mode set to 100644
File size: 27.1 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/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
52
53#include "CodePatterns/MemDebug.hpp"
54
55#include "CodePatterns/Log.hpp"
56
57#include "Actions/SelectionAction/Atoms/AtomByIdAction.hpp"
58#include "Actions/SelectionAction/Atoms/NotAtomByIdAction.hpp"
59#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
60#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
61#include "Atom/atom.hpp"
62#include "Bond/bond.hpp"
63#include "Descriptors/AtomIdDescriptor.hpp"
64#include "Descriptors/MoleculeIdDescriptor.hpp"
65#include "Helpers/helpers.hpp"
66#include "Shapes/ShapeRegistry.hpp"
67#include "molecule.hpp"
68#include "World.hpp"
69
70#include <iostream>
71
72using namespace MoleCuilder;
73
74GLWorldScene::GLWorldScene(
75 QtObservedInstanceBoard * _board,
76 QObject *parent) :
77 QObject(parent),
78 selectionMode(SelectAtom),
79 board(_board)
80{
81 int sphereDetails[] = {5, 3, 2, 0};
82 int cylinderDetails[] = {16, 8, 6, 3};
83 for (int i=0;i<GLMoleculeObject::DETAILTYPES_MAX;i++){
84 QGLBuilder emptyBuilder;
85 GLMoleculeObject::meshEmpty[i] = emptyBuilder.finalizedSceneNode();
86 QGLBuilder sphereBuilder;
87 sphereBuilder << QGLSphere(2.0, sphereDetails[i]);
88 GLMoleculeObject::meshSphere[i] = sphereBuilder.finalizedSceneNode();
89 GLMoleculeObject::meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
90 QGLBuilder cylinderBuilder;
91 cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
92 GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
93 GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
94 }
95 connect(board, SIGNAL(moleculeInserted(QtObservedMolecule::ptr)),
96 this, SLOT(moleculeSignOn(QtObservedMolecule::ptr)), Qt::DirectConnection);
97 connect(board, SIGNAL(moleculeRemoved(const moleculeId_t)),
98 this, SLOT(moleculeSignOff(const moleculeId_t)), Qt::DirectConnection);
99 connect(board, SIGNAL(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)),
100 this, SLOT(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)));
101 connect(board, SIGNAL(atomInserted(QtObservedAtom::ptr)),
102 this, SLOT(atomInserted(QtObservedAtom::ptr)));
103 connect(board, SIGNAL(atomRemoved(const atomId_t)),
104 this, SLOT(atomRemoved(const atomId_t)));
105 connect(this, SIGNAL(insertMolecule(QtObservedMolecule::ptr)),
106 this, SLOT(moleculeInserted(QtObservedMolecule::ptr)) );
107 connect(this, SIGNAL(removeMolecule(const moleculeId_t)),
108 this, SLOT(moleculeRemoved(const moleculeId_t)) );
109
110// connect(this, SIGNAL(updated()), this, SLOT(update()));
111}
112
113GLWorldScene::~GLWorldScene()
114{
115 // remove all elements
116 GLMoleculeObject::cleanMaterialMap();
117}
118
119void GLWorldScene::atomClicked(atomId_t no)
120{
121 LOG(3, "INFO: GLMoleculeObject_molecule - atom " << no << " has been clicked.");
122 const atom * const Walker = const_cast<const World &>(World::getInstance()).
123 getAtom(AtomById(no));
124 ASSERT( Walker != NULL,
125 "GLWorldScene::atomClicked() - clicked atom has disappeared.");
126 if (selectionMode == SelectAtom){
127 if (!World::getInstance().isSelected(Walker))
128 SelectionAtomById(std::vector<atomId_t>(1,no));
129 else
130 SelectionNotAtomById(std::vector<atomId_t>(1,no));
131 }else if (selectionMode == SelectMolecule){
132 const molecule *mol = Walker->getMolecule();
133 ASSERT(mol, "Atom without molecule has been clicked.");
134 molids_t ids(1, mol->getId());
135 if (!World::getInstance().isSelected(mol))
136 SelectionMoleculeById(ids);
137 else
138 SelectionNotMoleculeById(ids);
139 }
140 emit clicked(no);
141}
142
143void GLWorldScene::moleculeClicked(moleculeId_t no)
144{
145 LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
146 const molecule * const mol= const_cast<const World &>(World::getInstance()).
147 getMolecule(MoleculeById(no));
148 ASSERT(mol, "Atom without molecule has been clicked.");
149 molids_t ids(1, mol->getId());
150 if (!World::getInstance().isSelected(mol))
151 SelectionMoleculeById(ids);
152 else
153 SelectionNotMoleculeById(ids);
154 emit clicked(no);
155}
156
157/** Prepares insertion of a general atom.
158 *
159 * This is called before the insertion into a molecule and thus before the
160 * insertion into the scene.
161 *
162 * @param _atom atom to insert
163 */
164void GLWorldScene::atomInserted(QtObservedAtom::ptr _atom)
165{
166 const atomId_t atomid = _atom->getAtomIndex();
167 ASSERT( QtObservedAtomMap.find(atomid) == QtObservedAtomMap.end(),
168 "GLWorldScene::AtomInserted() - atom with id "+toString(atomid)
169 +" is already present in QtObservedAtomMap.");
170 QtObservedAtomMap[atomid] = _atom;
171 connect(_atom.get(), SIGNAL(indexChanged(const atomId_t,const atomId_t)),
172 this, SLOT(atomIndexChanged(const atomId_t,const atomId_t)) );
173}
174
175/** Removes an general atom.
176 *
177 * This is called when the atom has been removed from the molecule.
178 *
179 * @param _atom atom to remove
180 */
181void GLWorldScene::atomRemoved(const atomId_t _atomid)
182{
183 const QtObservedAtomMap_t::iterator eraseiter = QtObservedAtomMap.find(_atomid);
184 ASSERT( eraseiter != QtObservedAtomMap.end(),
185 "GLWorldScene::AtomRemoved() - atom with id "+toString(_atomid)
186 +" is not present in QtObservedAtomMap.");
187 disconnect(eraseiter->second.get(), SIGNAL(indexChanged(const atomId_t,const atomId_t)),
188 this, SLOT(atomIndexChanged(const atomId_t,const atomId_t)) );
189 QtObservedAtomMap.erase(eraseiter);
190}
191
192/** Inserts an atom into the scene when molecule is present.
193 *
194 * @param _atom atom to insert
195 */
196void GLWorldScene::moleculesAtomInserted(QtObservedAtom::ptr _atom, QtObservedMolecule * _mol)
197{
198 const atomId_t atomid = _atom->getAtomIndex();
199 const atomId_t molid = _atom->getAtomMoleculeIndex();
200 LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(atomid)+".");
201
202 // check of molecule is already present
203 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
204 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
205 if (moliter != MoleculesinSceneMap.end()) {
206 // check that it is the right molecule
207 QtObservedMolecule::ptr &checkmol = moliter->second->ObservedMolecule;
208 if (checkmol.get() == _mol) {
209 LOG(3, "INFO: GLWorldScene: Sending signal moleculesAtomInserted for atom "+toString(atomid)+".");
210 QMetaObject::invokeMethod(moliter->second, // pointer to a QObject
211 "atomInserted", // member name (no parameters here)
212 Qt::QueuedConnection, // connection type
213 Q_ARG(QtObservedAtom::ptr, _atom)); // parameters
214 } else {
215 // relay atomRemoved to GLMoleculeObject_molecule in RemovedMolecules
216// LOG(3, "INFO: GLWorldScene: Sending signal moleculesAtomInserted for atom "+toString(_atomid)
217// +" to molecule in RemovedMolecules.");
218// const MoleculeNodeMap::iterator removedmoliter = RemovedMolecules.find(molid);
219// ASSERT( removedmoliter != RemovedMolecules.end(),
220// "GLWorldScene::moleculesAtomInserted() - signal from old mol "
221// +toString(molid)+", but not present in RemovedMolecules");
222// QMetaObject::invokeMethod(removedmoliter->second, // pointer to a QObject
223// "atomInserted ", // member name (no parameters here)
224// Qt::QueuedConnection, // connection type
225// Q_ARG(QtObservedAtom::ptr, _atom)); // parameters
226 ASSERT( 0,
227 "GLWorldScene::moleculesAtomInserted() - would need to send atomInserted to already removed molecule.");
228 }
229 } else {
230 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
231 // only record missed state for molecule if (still) present but not instantiated
232 if (QtObservedMoleculeMap.count(molid)) {
233 // store signal for when it is instantiated
234 if (MoleculeMissedStateMap.count(molid) == 0)
235 MoleculeMissedStateMap.insert( std::make_pair(molid ,StateChangeMap_t()) );
236 MoleculeMissedStateMap[molid].insert( std::make_pair(atomid, atomInsertedState) );
237 ASSERT( QtObservedAtomMap[atomid] == _atom,
238 "GLWorldScene::moleculesAtomInserted() - atom "+toString(atomid)
239 +" inserted in molecule "+toString(molid)
240 +" which does not match atom in QtObservedAtomMap.");
241 LOG(3, "INFO: GLWorldScene: Placing atomInserted for atom " << atomid
242 << " and molecule " << molid << " into missed state map.");
243 }
244 }
245}
246
247/** Removes an atom into the scene before molecule is present.
248 *
249 * @param _atomid atom to remove
250 */
251void GLWorldScene::moleculesAtomRemoved(const atomId_t _atomid, QtObservedMolecule * _mol)
252{
253 LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_atomid)+".");
254
255 // if atom is not in map, then GLMoleculeObject_molecule is already present anyway.
256 if (QtObservedAtomMap.count(_atomid)) {
257 const QtObservedAtom::ptr atom = QtObservedAtomMap[_atomid];
258 const moleculeId_t molid = atom->getAtomMoleculeIndex();
259 // check of molecule is already present
260 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
261 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
262 if (moliter != MoleculesinSceneMap.end()) {
263 QtObservedMolecule::ptr &checkmol = moliter->second->ObservedMolecule;
264 if (checkmol.get() == _mol) {
265 LOG(3, "INFO: GLWorldScene: Sending signal moleculesAtomRemoved for atom "+toString(_atomid)+".");
266 QMetaObject::invokeMethod(moliter->second, // pointer to a QObject
267 "atomRemoved", // member name (no parameters here)
268 Qt::QueuedConnection, // connection type
269 Q_ARG(const atomId_t, _atomid)); // parameters
270 } else {
271 // relay atomRemoved to GLMoleculeObject_molecule in RemovedMolecules
272 LOG(3, "INFO: GLWorldScene: Sending signal moleculesAtomRemoved for atom "+toString(_atomid)
273 +" to molecule in RemovedMolecules.");
274 const MoleculeNodeMap::iterator removedmoliter = RemovedMolecules.find(molid);
275 ASSERT( removedmoliter != RemovedMolecules.end(),
276 "GLWorldScene::moleculesAtomRemoved() - signal from old mol "
277 +toString(molid)+", but not present in RemovedMolecules");
278 QMetaObject::invokeMethod(removedmoliter->second, // pointer to a QObject
279 "atomRemoved", // member name (no parameters here)
280 Qt::QueuedConnection, // connection type
281 Q_ARG(const atomId_t, _atomid)); // parameters
282 }
283 } else {
284 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
285 // only record missed state for molecule if (still) present but not instantiated
286 if (QtObservedMoleculeMap.count(molid)) {
287 // store signal for when it is instantiated
288 if (MoleculeMissedStateMap.count(molid) == 0)
289 MoleculeMissedStateMap.insert( std::make_pair(molid, StateChangeMap_t()) );
290 MoleculeMissedStateMap[molid].insert( std::make_pair(_atomid, atomRemovedState) );
291 LOG(3, "INFO: GLWorldScene: Placing atomRemoved for atom " << _atomid
292 << " and molecule " << molid << " into missed state map.");
293 }
294 }
295 }
296}
297
298void GLWorldScene::moleculeSignOn(QtObservedMolecule::ptr _mol)
299{
300 // sign on to QtObservedMolecule to get atomInserted/..Removed signals from same
301 // source as GLMoleculeObject_molecule would
302 connect(_mol.get(), SIGNAL(atomInserted(QtObservedAtom::ptr, QtObservedMolecule *)),
303 this, SLOT(moleculesAtomInserted(QtObservedAtom::ptr, QtObservedMolecule *)) );
304 connect(_mol.get(), SIGNAL(atomRemoved(const atomId_t, QtObservedMolecule *)),
305 this, SLOT(moleculesAtomRemoved(const atomId_t, QtObservedMolecule *)) );
306 const moleculeId_t molid = _mol->getMolIndex();
307 ASSERT( QtObservedMoleculeMap.find(molid) == QtObservedMoleculeMap.end(),
308 "GLWorldScene::moleculeSignOn() - molecule with id "+toString(molid)
309 +" is already present in QtObservedMoleculeMap.");
310 QtObservedMoleculeMap[molid] = _mol;
311 connect(_mol.get(), SIGNAL(indexChanged(const moleculeId_t,const moleculeId_t)),
312 this, SLOT(moleculeIndexChanged(const moleculeId_t,const moleculeId_t)) );
313
314 LOG(3, "INFO: GLWorldScene: Received signal moleculeSignOn for molecule "+toString(molid)+".");
315
316 emit insertMolecule(_mol);
317}
318
319void GLWorldScene::moleculeSignOff(const moleculeId_t _id)
320{
321 const QtObservedMoleculeMap_t::iterator eraseiter = QtObservedMoleculeMap.find(_id);
322 ASSERT( eraseiter != QtObservedMoleculeMap.end(),
323 "GLWorldScene::moleculeSignOff() - cannot find id "+toString(_id)+" in map.");
324 disconnect(eraseiter->second.get(), SIGNAL(indexChanged(const moleculeId_t,const moleculeId_t)),
325 this, SLOT(moleculeIndexChanged(const moleculeId_t,const moleculeId_t)) );
326 QtObservedMoleculeMap.erase(eraseiter);
327
328 LOG(3, "INFO: GLWorldScene: Received signal moleculeSignOff for molecule "+toString(_id)+".");
329
330 emit removeMolecule(_id);
331}
332
333/** Inserts a molecule into the scene.
334 *
335 * @param _mol molecule to insert
336 */
337void GLWorldScene::moleculeInserted(QtObservedMolecule::ptr _mol)
338{
339 ASSERT (_mol,
340 "GLWorldScene::moleculeInserted() - received shared_ptr for molecule is empty?");
341 const moleculeId_t molid = _mol->getMolIndex();
342 LOG(3, "INFO: GLWorldScene: Received signal moleculeInserted for molecule "+toString(molid)+".");
343
344 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
345
346 MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(molid);
347 ASSERT( iter == MoleculesinSceneMap.end(),
348 "GLWorldScene::moleculeInserted() - molecule's id "+toString(molid)+" already present.");
349
350 // add new object
351 LOG(1, "DEBUG: Adding GLMoleculeObject_molecule to id " << molid);
352 GLMoleculeObject_molecule *molObject =
353 new GLMoleculeObject_molecule(
354 GLMoleculeObject::meshEmpty,
355 this,
356 *board,
357 _mol);
358 ASSERT( molObject != NULL,
359 "GLWorldScene::moleculeInserted - could not create molecule object for "+toString(molid));
360#ifndef NDEBUG
361 std::pair<MoleculeNodeMap::iterator, bool> inserter =
362#endif
363 MoleculesinSceneMap.insert( make_pair(molid, molObject) );
364 ASSERT(inserter.second,
365 "GLWorldScene::moleculeInserted() - molecule "+toString(molid)+" already present in scene.");
366
367 // now handle all state changes that came up before the instantiation
368 if (MoleculeMissedStateMap.count(molid) != 0) {
369// ASSERT( !MoleculeMissedStateMap[molid].empty(),
370// "GLWorldScene::moleculeInserted() - we have an empty state change map for molecule with id "
371// +toString(molid));
372 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
373 for (StateChangeMap_t::iterator iter = MoleculeMissedStateMap[molid].begin();
374 !MoleculeMissedStateMap[molid].empty();
375 iter = MoleculeMissedStateMap[molid].begin()) {
376 std::pair<StateChangeMap_t::iterator, StateChangeMap_t::iterator> rangeiter =
377 MoleculeMissedStateMap[molid].equal_range(iter->first);
378 const size_t StateCounts = std::distance(rangeiter.first, rangeiter.second);
379 if (StateCounts > 1) {
380 // more than one state change, have to combine
381 typedef std::map<StateChangeType, size_t> StateChangeAmounts_t;
382 StateChangeAmounts_t StateChangeAmounts;
383 for (StateChangeMap_t::const_iterator stateiter = rangeiter.first;
384 stateiter != rangeiter.second; ++stateiter)
385 ++StateChangeAmounts[stateiter->second];
386 ASSERT( StateChangeAmounts[atomInsertedState] >= StateChangeAmounts[atomRemovedState],
387 "GLWorldScene::moleculeInserted() - more atomRemoved states "
388 +toString(StateChangeAmounts[atomRemovedState])+" than atomInserted "
389 +toString(StateChangeAmounts[atomInsertedState])+" for atom "+toString(iter->first));
390 if (StateChangeAmounts[atomInsertedState] > StateChangeAmounts[atomRemovedState]) {
391 LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
392 QMetaObject::invokeMethod(molObject, // pointer to a QObject
393 "atomInserted", // member name (no parameters here)
394 Qt::QueuedConnection, // connection type
395 Q_ARG(QtObservedAtom::ptr, QtObservedAtomMap[iter->first])); // parameters
396 } else {
397 LOG(1, "INFO: Atom " << iter->first << " has been inserted and removed already.");
398 }
399 // removed all state changes for this atom
400 MoleculeMissedStateMap[molid].erase(rangeiter.first, rangeiter.second);
401 } else {
402 // can only be an insertion
403 switch (rangeiter.first->second) {
404 case atomRemovedState:
405 ASSERT( 0,
406 "GLWorldScene::moleculeInserted() - atomRemoved state without atomInserted for atom "
407 +toString(iter->first));
408 break;
409 case atomInsertedState:
410 {
411 LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
412 QMetaObject::invokeMethod(molObject, // pointer to a QObject
413 "atomInserted", // member name (no parameters here)
414 Qt::QueuedConnection, // connection type
415 Q_ARG(QtObservedAtom::ptr, QtObservedAtomMap[iter->first])); // parameters
416 break;
417 }
418 default:
419 ASSERT( 0,
420 "GLWorldScene::moleculeInserted() - there are unknown change states.");
421 break;
422 }
423 // removed state changes for this atom
424 MoleculeMissedStateMap[molid].erase(iter);
425 }
426 }
427 }
428
429 connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
430 connect (molObject, SIGNAL(changeOccured()), this, SIGNAL(changeOccured()));
431 connect (molObject, SIGNAL(atomClicked(atomId_t)), this, SLOT(atomClicked(atomId_t)));
432 connect (molObject, SIGNAL(moleculeClicked(moleculeId_t)), this, SLOT(moleculeClicked(moleculeId_t)));
433 connect (molObject, SIGNAL(moleculeEmptied(moleculeId_t)), this, SLOT(moleculeEmpty(moleculeId_t)));
434 connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
435 connect (molObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
436 connect (molObject, SIGNAL(hoverChanged(const atomId_t)), this, SIGNAL(hoverChanged(const atomId_t)));
437 connect (molObject, SIGNAL(hoverChanged(const moleculeId_t, int)), this, SIGNAL(hoverChanged(const moleculeId_t, int)));
438 connect (molObject, SIGNAL(hoverChanged(const moleculeId_t, int)), this, SIGNAL(hoverChanged(const moleculeId_t, int)));
439
440 emit changed();
441 emit changeOccured();
442
443 // remove state change map for the molecule
444 {
445 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
446 MoleculeMissedStateMap.erase(molid);
447 }
448}
449
450/** Removes a molecule from the scene.
451 *
452 * @param _id id of molecule to remove
453 */
454void GLWorldScene::moleculeRemoved(const moleculeId_t _id)
455{
456 LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_id)+".");
457
458 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
459
460 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
461 if ( iter != MoleculesinSceneMap.end()) {
462 LOG(1, "DEBUG: Removing GLMoleculeObject_molecule to id " << _id << " from scene.");
463 RemovedMolecules.insert( std::make_pair(_id, iter->second) );
464 MoleculesinSceneMap.erase(iter);
465 }
466
467 // remove any possible state changes left
468 {
469 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
470 MoleculeMissedStateMap.erase(_id);
471 }
472}
473
474void GLWorldScene::moleculeEmpty(const moleculeId_t _id)
475{
476 LOG(3, "INFO: GLWorldScene: Received signal moleculeEmpty for molecule "+toString(_id)+".");
477
478 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
479
480 MoleculeNodeMap::iterator iter = RemovedMolecules.find(_id);
481 if ( iter != RemovedMolecules.end()) {
482 LOG(1, "DEBUG: Deleting GLMoleculeObject_molecule to id " << _id);
483 GLMoleculeObject_molecule *molObject = iter->second;
484 RemovedMolecules.erase(iter);
485 molObject->disconnect();
486 delete molObject;
487 } else {
488 ASSERT(0,
489 "GLWorldScene::moleculeEmpty() - molecule "+toString(_id)+" is empty that is not present.");
490 }
491
492 // remove any possible state changes left
493 {
494 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
495 MoleculeMissedStateMap.erase(_id);
496 }
497
498 emit changed();
499 emit changeOccured();
500}
501
502void GLWorldScene::atomIndexChanged(const atomId_t _oldid, const atomId_t _newid)
503{
504 if (QtObservedAtomMap.count(_oldid)) {
505 const QtObservedAtom::ptr atom = QtObservedAtomMap[_oldid];
506 QtObservedAtomMap.erase(_oldid);
507 QtObservedAtomMap.insert( std::make_pair(_newid, atom) );
508 }
509}
510
511void GLWorldScene::moleculeIndexChanged(const moleculeId_t _oldid, const moleculeId_t _newid)
512{
513 {
514 QtObservedMoleculeMap_t::iterator const olditer = QtObservedMoleculeMap.find(_oldid);
515 ASSERT ( olditer != QtObservedMoleculeMap.end(),
516 "GLWorldScene::moleculeIndexChanged() - molecule "
517 +toString(_oldid)+" not present in QtObservedMoleculeMap.");
518#ifndef NDEBUG
519 QtObservedMoleculeMap_t::iterator const newiter = QtObservedMoleculeMap.find(_newid);
520 ASSERT ( newiter == QtObservedMoleculeMap.end(),
521 "GLWorldScene::moleculeIndexChanged() - molecule "
522 +toString(_newid)+" already present in QtObservedMoleculeMap.");
523#endif
524 const QtObservedMolecule::ptr mol = olditer->second;
525 QtObservedMoleculeMap.erase(olditer);
526 QtObservedMoleculeMap[_newid] = mol;
527 }
528 {
529 MoleculeNodeMap::iterator const olditer = MoleculesinSceneMap.find(_oldid);
530 if ( olditer != MoleculesinSceneMap.end()) {
531#ifndef NDEBUG
532 MoleculeNodeMap::iterator const newiter = MoleculesinSceneMap.find(_newid);
533 ASSERT ( newiter == MoleculesinSceneMap.end(),
534 "GLWorldScene::moleculeIndexChanged() - molecule "
535 +toString(_newid)+" already present in MoleculesinSceneMap.");
536#endif
537 LOG(1, "DEBUG: Changing GLMoleculeObject_molecule in MoleculesinSceneMapfrom "
538 << _oldid << " to id " << _newid);
539 GLMoleculeObject_molecule* const molObject = olditer->second;
540 MoleculesinSceneMap.erase(olditer);
541 MoleculesinSceneMap[_newid] = molObject;
542 }
543 }
544 {
545 MoleculeNodeMap::iterator const olditer = RemovedMolecules.find(_oldid);
546 if ( olditer != RemovedMolecules.end()) {
547#ifndef NDEBUG
548 MoleculeNodeMap::iterator const newiter = RemovedMolecules.find(_newid);
549 ASSERT ( newiter == RemovedMolecules.end(),
550 "GLWorldScene::moleculeIndexChanged() - molecule "
551 +toString(_newid)+" already present in RemovedMolecules.");
552#endif
553 LOG(1, "DEBUG: Changing GLMoleculeObject_molecule in RemovedMolecules from "
554 << _oldid << " to id " << _newid);
555 GLMoleculeObject_molecule* const molObject = olditer->second;
556 RemovedMolecules.erase(olditer);
557 RemovedMolecules[_newid] = molObject;
558 }
559 }
560}
561
562void GLWorldScene::moleculesVisibilityChanged(const moleculeId_t _id, bool _visible)
563{
564 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
565 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
566 ASSERT( iter != MoleculesinSceneMap.end(),
567 "GLWorldScene::moleculeInserted() - molecule's id "+toString(_id)+" is unknown.");
568
569 GLMoleculeObject_molecule *molObject = iter->second;
570 molObject->setVisible(_visible);
571
572 emit changed();
573 emit changeOccured();
574}
575
576/** Adds a shape to the scene.
577 *
578 */
579void GLWorldScene::addShape(const std::string &_name)
580{
581 Shape * const shape = ShapeRegistry::getInstance().getByName(_name);
582 if (shape != NULL) {
583 GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(*shape, this);
584 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
585 ASSERT(iter == ShapesinSceneMap.end(),
586 "GLWorldScene::addShape() - same shape "+_name+" added again.");
587 ShapesinSceneMap.insert( make_pair(_name, shapeObject) );
588 } else
589 ELOG(2, "GLWorldScene::addShape() - shape disappeared before we could draw it.");
590
591 emit changed();
592}
593
594void GLWorldScene::removeShape(const std::string &_name)
595{
596 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
597 ASSERT(iter != ShapesinSceneMap.end(),
598 "GLWorldScene::removeShape() - shape "+_name+" not in scene.");
599 ShapesinSceneMap.erase(iter);
600 delete(iter->second);
601
602 emit changed();
603}
604
605void GLWorldScene::updateSelectedShapes()
606{
607 foreach (QObject *obj, children()) {
608 GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
609 if (shapeobj){
610 shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
611 }
612 }
613
614 emit changed();
615}
616
617void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
618{
619 // Initialize all of the mesh objects that we have as children.
620 foreach (QObject *obj, children()) {
621 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
622 if (meshobj)
623 meshobj->initialize(view, painter);
624 }
625}
626
627void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
628{
629 // Draw all of the mesh objects that we have as children.
630 foreach (QObject *obj, children()) {
631 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
632 if (meshobj)
633 meshobj->draw(painter, cameraPlane);
634 }
635}
636
637void GLWorldScene::setSelectionMode(SelectionModeType mode)
638{
639 selectionMode = mode;
640 // TODO send update to toolbar
641}
642
643void GLWorldScene::setSelectionModeAtom()
644{
645 setSelectionMode(SelectAtom);
646}
647
648void GLWorldScene::setSelectionModeMolecule()
649{
650 setSelectionMode(SelectMolecule);
651}
652
Note: See TracBrowser for help on using the repository browser.