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
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 * 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"
[d1196d]39#include <Qt3D/qglview.h>
[bca99d]40#include <Qt3D/qglbuilder.h>
41#include <Qt3D/qglscenenode.h>
42#include <Qt3D/qglsphere.h>
43#include <Qt3D/qglcylinder.h>
[907636]44
[015f8c]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
[2f7988]51#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
[907636]52
53#include "CodePatterns/MemDebug.hpp"
54
[7188b1]55#include "CodePatterns/Log.hpp"
56
[0e9ffe]57#include "Actions/SelectionAction/Atoms/AtomByIdAction.hpp"
[89643d]58#include "Actions/SelectionAction/Atoms/NotAtomByIdAction.hpp"
[6966b7]59#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
60#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
[6f0841]61#include "Atom/atom.hpp"
[7188b1]62#include "Bond/bond.hpp"
[89643d]63#include "Descriptors/AtomIdDescriptor.hpp"
[8c001a]64#include "Descriptors/MoleculeIdDescriptor.hpp"
[37b2575]65#include "Helpers/helpers.hpp"
[85c36d]66#include "Shapes/ShapeRegistry.hpp"
[907636]67#include "molecule.hpp"
68#include "World.hpp"
69
[2ad1ec]70#include <iostream>
71
[ce7fdc]72using namespace MoleCuilder;
[907636]73
[15c8a9]74GLWorldScene::GLWorldScene(
[2f7988]75 QtObservedInstanceBoard * _board,
[15c8a9]76 QObject *parent) :
77 QObject(parent),
78 selectionMode(SelectAtom),
79 board(_board)
[907636]80{
[72a4c1]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;
[8c001a]85 GLMoleculeObject::meshEmpty[i] = emptyBuilder.finalizedSceneNode();
[72a4c1]86 QGLBuilder sphereBuilder;
87 sphereBuilder << QGLSphere(2.0, sphereDetails[i]);
[8c001a]88 GLMoleculeObject::meshSphere[i] = sphereBuilder.finalizedSceneNode();
89 GLMoleculeObject::meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
[72a4c1]90 QGLBuilder cylinderBuilder;
91 cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
[8c001a]92 GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
93 GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
[72a4c1]94 }
[1b07b1]95 connect(board, SIGNAL(moleculeInserted(QtObservedMolecule::ptr)),
[59f1bc]96 this, SLOT(moleculeSignOn(QtObservedMolecule::ptr)), Qt::DirectConnection);
[15c8a9]97 connect(board, SIGNAL(moleculeRemoved(const moleculeId_t)),
[59f1bc]98 this, SLOT(moleculeSignOff(const moleculeId_t)), Qt::DirectConnection);
[15c8a9]99 connect(board, SIGNAL(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)),
100 this, SLOT(moleculeIndexChanged(const moleculeId_t, const moleculeId_t)));
[59f1bc]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)));
[8281cc]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)) );
[0a6ff9]109
[f714763]110// connect(this, SIGNAL(updated()), this, SLOT(update()));
[907636]111}
112
113GLWorldScene::~GLWorldScene()
[7188b1]114{
115 // remove all elements
116 GLMoleculeObject::cleanMaterialMap();
117}
[907636]118
[8c001a]119void GLWorldScene::atomClicked(atomId_t no)
120{
121 LOG(3, "INFO: GLMoleculeObject_molecule - atom " << no << " has been clicked.");
[f01769]122 const atom * const Walker = const_cast<const World &>(World::getInstance()).
123 getAtom(AtomById(no));
[369cb1]124 ASSERT( Walker != NULL,
125 "GLWorldScene::atomClicked() - clicked atom has disappeared.");
[8c001a]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.");
[d7cad1]134 molids_t ids(1, mol->getId());
[8c001a]135 if (!World::getInstance().isSelected(mol))
[d7cad1]136 SelectionMoleculeById(ids);
[8c001a]137 else
[d7cad1]138 SelectionNotMoleculeById(ids);
[8c001a]139 }
140 emit clicked(no);
141}
142
[9a7ef9]143void GLWorldScene::moleculeClicked(moleculeId_t no)
144{
145 LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
[63fb7a]146 const molecule * const mol= const_cast<const World &>(World::getInstance()).
147 getMolecule(MoleculeById(no));
[9a7ef9]148 ASSERT(mol, "Atom without molecule has been clicked.");
[d7cad1]149 molids_t ids(1, mol->getId());
[9a7ef9]150 if (!World::getInstance().isSelected(mol))
[d7cad1]151 SelectionMoleculeById(ids);
[9a7ef9]152 else
[d7cad1]153 SelectionNotMoleculeById(ids);
[9a7ef9]154 emit clicked(no);
155}
156
[59f1bc]157/** Prepares insertion of a general atom.
[9c259e]158 *
[59f1bc]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
[9c259e]163 */
[1b07b1]164void GLWorldScene::atomInserted(QtObservedAtom::ptr _atom)
[9c259e]165{
[59f1bc]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 */
[96e145]196void GLWorldScene::moleculesAtomInserted(QtObservedAtom::ptr _atom, QtObservedMolecule * _mol)
[59f1bc]197{
[1b07b1]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)+".");
[7c7c4a]201
[9c259e]202 // check of molecule is already present
[59f1bc]203 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
[96e145]204 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
[8d5fbf1]205 if (moliter != MoleculesinSceneMap.end()) {
[96e145]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 }
[9c259e]229 } else {
[59f1bc]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 }
[9c259e]244 }
245}
246
247/** Removes an atom into the scene before molecule is present.
248 *
[59f1bc]249 * @param _atomid atom to remove
[9c259e]250 */
[96e145]251void GLWorldScene::moleculesAtomRemoved(const atomId_t _atomid, QtObservedMolecule * _mol)
[9c259e]252{
[8281cc]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
[59f1bc]260 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
[96e145]261 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
[8281cc]262 if (moliter != MoleculesinSceneMap.end()) {
[96e145]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 }
[8281cc]283 } else {
[59f1bc]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 }
[8281cc]294 }
[9c259e]295 }
296}
297
[8281cc]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
[96e145]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 *)) );
[8281cc]306 const moleculeId_t molid = _mol->getMolIndex();
[59f1bc]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)) );
[8281cc]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{
[59f1bc]321 const QtObservedMoleculeMap_t::iterator eraseiter = QtObservedMoleculeMap.find(_id);
322 ASSERT( eraseiter != QtObservedMoleculeMap.end(),
[8281cc]323 "GLWorldScene::moleculeSignOff() - cannot find id "+toString(_id)+" in map.");
[59f1bc]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);
[8281cc]327
328 LOG(3, "INFO: GLWorldScene: Received signal moleculeSignOff for molecule "+toString(_id)+".");
329
330 emit removeMolecule(_id);
331}
332
[026bef]333/** Inserts a molecule into the scene.
[c67518]334 *
[8c001a]335 * @param _mol molecule to insert
[c67518]336 */
[1b07b1]337void GLWorldScene::moleculeInserted(QtObservedMolecule::ptr _mol)
[c67518]338{
[1b07b1]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)+".");
[7cf0eb]343
344 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
345
[1b07b1]346 MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(molid);
[8c001a]347 ASSERT( iter == MoleculesinSceneMap.end(),
[1b07b1]348 "GLWorldScene::moleculeInserted() - molecule's id "+toString(molid)+" already present.");
[8c001a]349
350 // add new object
[1b07b1]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(),
[4cac6c]370// "GLWorldScene::moleculeInserted() - we have an empty state change map for molecule with id "
[1b07b1]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 {
[73b13c]411 LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
[9c259e]412 QMetaObject::invokeMethod(molObject, // pointer to a QObject
413 "atomInserted", // member name (no parameters here)
[8d5fbf1]414 Qt::QueuedConnection, // connection type
[1b07b1]415 Q_ARG(QtObservedAtom::ptr, QtObservedAtomMap[iter->first])); // parameters
416 break;
[7ded1c]417 }
[1b07b1]418 default:
419 ASSERT( 0,
420 "GLWorldScene::moleculeInserted() - there are unknown change states.");
421 break;
[9c259e]422 }
[7ded1c]423 // removed state changes for this atom
[1b07b1]424 MoleculeMissedStateMap[molid].erase(iter);
[9c259e]425 }
426 }
427 }
428
[1b07b1]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)));
[bcf9cd]433 connect (molObject, SIGNAL(moleculeEmptied(moleculeId_t)), this, SLOT(moleculeEmpty(moleculeId_t)));
[1b07b1]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
[7ded1c]443 // remove state change map for the molecule
444 {
445 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
[1b07b1]446 MoleculeMissedStateMap.erase(molid);
[7ded1c]447 }
[c67518]448}
449
[7cf0eb]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{
[026bef]456 LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_id)+".");
[7c7c4a]457
[7cf0eb]458 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
459
460 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
[59f1bc]461 if ( iter != MoleculesinSceneMap.end()) {
[bcf9cd]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);
[7c7c4a]483 GLMoleculeObject_molecule *molObject = iter->second;
[bcf9cd]484 RemovedMolecules.erase(iter);
[7c7c4a]485 molObject->disconnect();
486 delete molObject;
[bcf9cd]487 } else {
488 ASSERT(0,
489 "GLWorldScene::moleculeEmpty() - molecule "+toString(_id)+" is empty that is not present.");
[7c7c4a]490 }
[9c259e]491
492 // remove any possible state changes left
[73b13c]493 {
494 boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
495 MoleculeMissedStateMap.erase(_id);
496 }
[9c259e]497
[7cf0eb]498 emit changed();
499 emit changeOccured();
[ce4126]500}
501
[8281cc]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
[15c8a9]511void GLWorldScene::moleculeIndexChanged(const moleculeId_t _oldid, const moleculeId_t _newid)
512{
[59f1bc]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
[bcf9cd]537 LOG(1, "DEBUG: Changing GLMoleculeObject_molecule in MoleculesinSceneMapfrom "
538 << _oldid << " to id " << _newid);
[59f1bc]539 GLMoleculeObject_molecule* const molObject = olditer->second;
540 MoleculesinSceneMap.erase(olditer);
541 MoleculesinSceneMap[_newid] = molObject;
[8281cc]542 }
[15c8a9]543 }
[bcf9cd]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 }
[15c8a9]560}
561
[739ee9]562void GLWorldScene::moleculesVisibilityChanged(const moleculeId_t _id, bool _visible)
563{
[7c7c4a]564 boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
[739ee9]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
[f75491]576/** Adds a shape to the scene.
[4d6662]577 *
[f75491]578 */
[07136a]579void GLWorldScene::addShape(const std::string &_name)
[f75491]580{
[07136a]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();
[284551]592}
593
[07136a]594void GLWorldScene::removeShape(const std::string &_name)
[85c36d]595{
[07136a]596 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
[ba6b5c]597 ASSERT(iter != ShapesinSceneMap.end(),
[07136a]598 "GLWorldScene::removeShape() - shape "+_name+" not in scene.");
[148dde0]599 ShapesinSceneMap.erase(iter);
[85c36d]600 delete(iter->second);
[07136a]601
602 emit changed();
[85c36d]603}
604
605void GLWorldScene::updateSelectedShapes()
[284551]606{
607 foreach (QObject *obj, children()) {
608 GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
[85c36d]609 if (shapeobj){
610 shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
611 }
[284551]612 }
[07136a]613
614 emit changed();
[f75491]615}
616
[7188b1]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
[72a4c1]627void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
[7188b1]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)
[72a4c1]633 meshobj->draw(painter, cameraPlane);
[7188b1]634 }
[907636]635}
[06ebf5]636
[6966b7]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}
[20f9b5]652
Note: See TracBrowser for help on using the repository browser.