source: src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp@ 2fe4a5

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_StructOpt_integration_tests 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_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 FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks 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 2fe4a5 was 9d1a78, checked in by Frederik Heber <heber@…>, 9 years ago

FIX: GLWorldScene used iterator also in NDEBUG, connect still outside mutex.

  • Property mode set to 100644
File size: 34.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
[f1b5ca]57#include <boost/assign.hpp>
58
[0e9ffe]59#include "Actions/SelectionAction/Atoms/AtomByIdAction.hpp"
[89643d]60#include "Actions/SelectionAction/Atoms/NotAtomByIdAction.hpp"
[6966b7]61#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
62#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
[6f0841]63#include "Atom/atom.hpp"
[7188b1]64#include "Bond/bond.hpp"
[89643d]65#include "Descriptors/AtomIdDescriptor.hpp"
[8c001a]66#include "Descriptors/MoleculeIdDescriptor.hpp"
[37b2575]67#include "Helpers/helpers.hpp"
[85c36d]68#include "Shapes/ShapeRegistry.hpp"
[907636]69#include "molecule.hpp"
70#include "World.hpp"
71
[2ad1ec]72#include <iostream>
73
[ce7fdc]74using namespace MoleCuilder;
[907636]75
[efeeb7]76// static functions
77
78static void eraseBondNodeParents(
79 std::vector<GLWorldScene::BondNodeParentMap_t> &_BondNodeParentMaps,
80 const ObservedValue_Index_t &_bondid)
81{
82 const size_t left_erased = _BondNodeParentMaps[0].left.erase(_bondid);
83 const size_t right_erased = _BondNodeParentMaps[1].left.erase(_bondid);
84 ASSERT( (left_erased == 1) && (right_erased == 1),
85 "eraseBondNodeParents() - could not erase both parents of "+toString(_bondid)+"?");
86}
87
88/** Checks whether both parents of the bond are set to GLWorldScene and the
89 * bondRemoved() signals was received for this bond.
90 *
91 * \param _BondNodeParent_Maps - map containing parents
92 * \param _ToBeRemovedNodes - set with all bonds that are to be removed
93 * \param _bondid id of bond
94 * \return true - both parents are assigned to GLWorldScene, false - else
95 */
96static bool checkBondRemoval(
97 const std::vector<GLWorldScene::BondNodeParentMap_t> &_BondNodeParentMaps,
98 const GLWorldScene::ToBeRemovedNodes_t &_ToBeRemovedNodes,
99 const ObservedValue_Index_t &_bondid)
100{
101 GLWorldScene::BondNodeParentMap_t::left_const_iterator leftiter =
102 _BondNodeParentMaps[0].left.find(_bondid);
103 GLWorldScene::BondNodeParentMap_t::left_const_iterator rightiter =
104 _BondNodeParentMaps[1].left.find(_bondid);
105 ASSERT( leftiter != _BondNodeParentMaps[0].left.end(),
106 "checkBondRemoval() - left parent to index "+toString(_bondid)+" missing?");
107 ASSERT( rightiter != _BondNodeParentMaps[1].left.end(),
108 "checkBondRemoval() - right parent to index "+toString(_bondid)+" missing?");
109 return ((leftiter->second == (ObservedValue_Index_t)NULL)
110 && (rightiter->second == (ObservedValue_Index_t)NULL)
111 && (_ToBeRemovedNodes.count(_bondid)));
112}
113
114void removeBondFromScene(
115 GLWorldScene::BondNodeMap &_BondsinSceneMap,
116 const ObservedValue_Index_t &_bondid)
117{
118 std::pair<GLWorldScene::BondNodeMap::iterator, GLWorldScene::BondNodeMap::iterator> iters =
119 _BondsinSceneMap.equal_range(_bondid);
120 ASSERT( iters.first != iters.second,
121 "removeBondFromScene() - could not find bond to id "+toString(_bondid));
122 for (GLWorldScene::BondNodeMap::iterator iter = iters.first; iter != iters.second; ++iter) {
123 GLMoleculeObject_bond *bondObject = iter->second;
124 delete bondObject; // is done by signal from bond itself
125 //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
126 }
127 _BondsinSceneMap.erase(_bondid);
128}
129
130static bool checkAtomRemoval(
131 const GLWorldScene::AtomNodeParentMap_t &_AtomNodeParentMap,
132 const GLWorldScene::ToBeRemovedNodes_t &_ToBeRemovedNodes,
133 const ObservedValue_Index_t &_atomid)
134{
135 GLWorldScene::AtomNodeParentMap_t::left_const_iterator iter = _AtomNodeParentMap.left.find(_atomid);
136 ASSERT( iter != _AtomNodeParentMap.left.end(),
137 "checkAtomRemoval() - missing parent entry for "+toString(_atomid));
138 return ((iter->second == (ObservedValue_Index_t)NULL) && (_ToBeRemovedNodes.count(_atomid)));
139}
140
141// class definitions
142
[15c8a9]143GLWorldScene::GLWorldScene(
[2f7988]144 QtObservedInstanceBoard * _board,
[15c8a9]145 QObject *parent) :
146 QObject(parent),
[a13f2b]147 BondNodeParentMaps(std::vector<BondNodeParentMap_t>(2)),
[15c8a9]148 selectionMode(SelectAtom),
149 board(_board)
[907636]150{
[f1b5ca]151 qRegisterMetaType<atomId_t>("atomId_t");
152 qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
153
[72a4c1]154 int sphereDetails[] = {5, 3, 2, 0};
155 int cylinderDetails[] = {16, 8, 6, 3};
156 for (int i=0;i<GLMoleculeObject::DETAILTYPES_MAX;i++){
157 QGLBuilder emptyBuilder;
[8c001a]158 GLMoleculeObject::meshEmpty[i] = emptyBuilder.finalizedSceneNode();
[72a4c1]159 QGLBuilder sphereBuilder;
160 sphereBuilder << QGLSphere(2.0, sphereDetails[i]);
[8c001a]161 GLMoleculeObject::meshSphere[i] = sphereBuilder.finalizedSceneNode();
162 GLMoleculeObject::meshSphere[i]->setOption(QGLSceneNode::CullBoundingBox, true);
[72a4c1]163 QGLBuilder cylinderBuilder;
164 cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
[8c001a]165 GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
166 GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
[72a4c1]167 }
[1b07b1]168 connect(board, SIGNAL(moleculeInserted(QtObservedMolecule::ptr)),
[bd6768]169 this, SLOT(insertMolecule(QtObservedMolecule::ptr)));
[f91ef6]170 connect(board, SIGNAL(moleculeRemoved(ObservedValue_Index_t)),
[bd6768]171 this, SLOT(removeMolecule(ObservedValue_Index_t)));
172
[59f1bc]173 connect(board, SIGNAL(atomInserted(QtObservedAtom::ptr)),
[bd6768]174 this, SLOT(connectAtom(QtObservedAtom::ptr)), Qt::DirectConnection);
175 connect(this, SIGNAL(atomConnected(QtObservedAtom::ptr)),
176 this, SLOT(insertAtom(QtObservedAtom::ptr)));
[f91ef6]177 connect(board, SIGNAL(atomRemoved(ObservedValue_Index_t)),
[bd6768]178 this, SLOT(removeAtom(ObservedValue_Index_t)));
179
[96f14a]180 connect(board, SIGNAL(bondInserted(QtObservedBond::ptr)),
[bd6768]181 this, SLOT(connectBond(QtObservedBond::ptr)), Qt::DirectConnection);
182 connect(this, SIGNAL(bondConnected(QtObservedBond::ptr)),
183 this, SLOT(insertBond(QtObservedBond::ptr)));
[96f14a]184 connect(board, SIGNAL(bondRemoved(ObservedValue_Index_t)),
[bd6768]185 this, SLOT(removeBond(ObservedValue_Index_t)));
[0a6ff9]186
[f714763]187// connect(this, SIGNAL(updated()), this, SLOT(update()));
[907636]188}
189
190GLWorldScene::~GLWorldScene()
[7188b1]191{
192 // remove all elements
193 GLMoleculeObject::cleanMaterialMap();
194}
[907636]195
[bd6768]196void GLWorldScene::clickAtom(atomId_t no)
[8c001a]197{
[bd6768]198 LOG(3, "INFO: GLWorldScene - atom " << no << " has been clicked.");
[f01769]199 const atom * const Walker = const_cast<const World &>(World::getInstance()).
200 getAtom(AtomById(no));
[369cb1]201 ASSERT( Walker != NULL,
[bd6768]202 "GLWorldScene::clickAtom() - clicked atom has disappeared.");
[8c001a]203 if (selectionMode == SelectAtom){
204 if (!World::getInstance().isSelected(Walker))
205 SelectionAtomById(std::vector<atomId_t>(1,no));
206 else
207 SelectionNotAtomById(std::vector<atomId_t>(1,no));
208 }else if (selectionMode == SelectMolecule){
209 const molecule *mol = Walker->getMolecule();
210 ASSERT(mol, "Atom without molecule has been clicked.");
[d7cad1]211 molids_t ids(1, mol->getId());
[8c001a]212 if (!World::getInstance().isSelected(mol))
[d7cad1]213 SelectionMoleculeById(ids);
[8c001a]214 else
[d7cad1]215 SelectionNotMoleculeById(ids);
[8c001a]216 }
217 emit clicked(no);
218}
219
[bd6768]220/** Prepares adding an atom to the scene
221 *
222 * We need to listen to moleculeChanged() in order to properly re-parent()
223 * this QObject
224 *
225 * @param _atom atom to connect
226 */
227void GLWorldScene::connectAtom(QtObservedAtom::ptr _atom)
228{
[1eba7c]229 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
230
[9d1a78]231 connect(_atom.get(), SIGNAL(moleculeChanged()), this, SLOT(reparentAtom()));
232
[136842]233 // store the object, as we need it on reparenting
[1eba7c]234 const ObservedValue_Index_t atomid = _atom->getIndex();
[136842]235#ifndef NDEBUG
[1eba7c]236 std::pair< ObservedAtoms_t::iterator, bool > inserter =
[136842]237#endif
[1eba7c]238 ObservedAtoms.insert( std::make_pair(_atom.get(), _atom) );
239 ASSERT( inserter.second,
240 "GLWorldScene::connectAtom() - observed atom "+toString(_atom)+" already stored?");
[649f59]241#ifndef NDEBUG
[1eba7c]242 std::pair< ObservedValueIndexLookup_t::iterator, bool > indexinserter =
[649f59]243#endif
[ea7926]244 ObservedAtomIndexLookup.insert( std::make_pair(atomid, _atom.get()) );
[1eba7c]245 ASSERT( indexinserter.second,
246 "GLWorldScene::connectAtom() - observed atom's index "
247 +toString(atomid)+" already stored?");
248
249 // and create entry in the parent map
250 AtomNodeParentMap.left.insert( std::make_pair(atomid, (ObservedValue_Index_t)NULL) );
[bd6768]251
252 emit atomConnected(_atom);
253}
254
[f1b5ca]255/** Adds an atom to the scene.
[59f1bc]256 *
[f1b5ca]257 * @param _atom atom to add
[9c259e]258 */
[bd6768]259void GLWorldScene::insertAtom(QtObservedAtom::ptr _atom)
[9c259e]260{
[f1b5ca]261 LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "
262 << _atom->getAtomIndex());
[1eba7c]263 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[f1b5ca]264
[f91ef6]265 const ObservedValue_Index_t atomid = _atom->getIndex();
[bd6768]266 QObject *parent = static_cast<QObject *>(this);
267 GLMoleculeObject_atom *atomObject = NULL;
268 {
[a13f2b]269 AtomNodeParentMap_t::left_iterator parentiter = AtomNodeParentMap.left.find(atomid);
270 ASSERT (parentiter != AtomNodeParentMap.left.end(),
[502614]271 "GLWorldScene::insertAtom() - parent to atom id "+toString(atomid)+" unknown?");
272 const ObservedValue_Index_t parentindex = parentiter->second;
273 if (parentindex != (ObservedValue_Index_t)NULL) {
274 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(parentindex);
275 if (moliter != MoleculesinSceneMap.end())
276 parent = moliter->second;
277 }
[bd6768]278
279 atomObject = new GLMoleculeObject_atom(
280 GLMoleculeObject::meshSphere,
281 parent,
282 _atom);
283 ASSERT( atomObject != NULL,
284 "GLWorldScene::atomInserted - could not create atom object for "
285 +toString(_atom->getAtomIndex()));
286 }
[9d1a78]287#ifndef NDEBUG
288 const AtomNodeMap::iterator iter = AtomsinSceneMap.find(atomid);
289#endif
[f1b5ca]290 ASSERT(iter == AtomsinSceneMap.end(),
[bd6768]291 "GLWorldScene::insertAtom - same atom with id "
[f1b5ca]292 +toString(_atom->getAtomIndex())+" added again.");
293 AtomsinSceneMap.insert( make_pair(atomid, atomObject) );
294
[bd6768]295 connect (atomObject, SIGNAL(clicked(atomId_t)), this, SLOT(clickAtom(atomId_t)));
[f1b5ca]296 connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
297 connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
298 connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
299
300 emit changed();
301 emit changeOccured();
[59f1bc]302}
303
[649f59]304template <class T>
305void removeStoredObservedValue(
306 GLWorldScene::ObservedValueIndexLookup_t &_ObservedValueIndexLookup,
307 T &_ObservedValues,
[efeeb7]308 const ObservedValue_Index_t &_id)
[649f59]309{
310 // get QObject* from lookup
311 const GLWorldScene::ObservedValueIndexLookup_t::iterator iter =
312 _ObservedValueIndexLookup.find(_id);
313 ASSERT( iter != _ObservedValueIndexLookup.end(),
[efeeb7]314 "removeStoredObservedValue() - could not find index "+toString(_id)
[649f59]315 +" to stored observed value.");
316 QObject * sender = iter->second;
317 const size_t erased = _ObservedValues.erase(sender);
318 ASSERT( erased == 1,
[efeeb7]319 "removeStoredObservedValue() - could not erase stored observed value "
[649f59]320 +toString(_id));
321 _ObservedValueIndexLookup.erase(iter);
322}
323
[efeeb7]324void removeAtomFromScene(
325 GLWorldScene::AtomNodeMap &_AtomsinSceneMap,
326 const ObservedValue_Index_t &_atomid)
327{
328 GLWorldScene::AtomNodeMap::iterator iter = _AtomsinSceneMap.find(_atomid);
329 ASSERT(iter != _AtomsinSceneMap.end(),
330 "removeAtomFromScene() - atom "+toString(_atomid)+" not on display.");
331 GLMoleculeObject_atom *atomObject = iter->second;
332 _AtomsinSceneMap.erase(iter);
333 delete atomObject;
334}
335
336void GLWorldScene::checkAndRemoveAtom(const ObservedValue_Index_t &_atomid)
337{
[1eba7c]338 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[efeeb7]339
340 if (checkAtomRemoval(AtomNodeParentMap, ToBeRemovedNodes, _atomid)) {
341 LOG(4, "DEBUG: Found parent of to be removed atom as GLWorldScene, removing.");
342 removeAtomFromScene(AtomsinSceneMap, _atomid);
343 AtomNodeParentMap.left.erase(_atomid);
344 ToBeRemovedNodes.erase(_atomid);
[ea7926]345 removeStoredObservedValue(ObservedAtomIndexLookup, ObservedAtoms, _atomid);
[efeeb7]346 }
347}
348
[f1b5ca]349/** Removes an atom.
[59f1bc]350 *
[f1b5ca]351 * @param _atomid index of the atom that is removed
[59f1bc]352 */
[bd6768]353void GLWorldScene::removeAtom(ObservedValue_Index_t _atomid)
[59f1bc]354{
[f1b5ca]355 LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_atomid)+".");
356 // bonds are removed by signal coming from ~bond
[1eba7c]357 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[f1b5ca]358
[efeeb7]359 ASSERT( ToBeRemovedNodes.count(_atomid) == 0,
360 "GLWorldScene::removeAtom() - removedAtom signal for id "+toString(_atomid)
361 +" came in twice?");
362 ToBeRemovedNodes.insert( _atomid );
363
[f1b5ca]364 // remove atoms
[efeeb7]365 checkAndRemoveAtom( _atomid );
[649f59]366
[f1b5ca]367 emit changed();
368 emit changeOccured();
[59f1bc]369}
370
[bd6768]371/** Prepares adding a bond to the scene
372 *
373 * We need to listen to moleculeChanged() in order to properly re-parent()
374 * this QObject
375 *
376 * @param _bond bond to connect
377 */
378void GLWorldScene::connectBond(QtObservedBond::ptr _bond)
379{
[efeeb7]380 LOG(3, "INFO: GLWorldScene::connectBond() - connecting to bonds " << _bond->getBondIndex());
381
382 connect(_bond.get(), SIGNAL(leftmoleculeChanged()), this, SLOT(reparentBondLeft()), Qt::QueuedConnection);
383 connect(_bond.get(), SIGNAL(rightmoleculeChanged()), this, SLOT(reparentBondRight()), Qt::QueuedConnection);
[bd6768]384
[1eba7c]385 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
386
[136842]387 // store the object, as we need it on reparenting
[1eba7c]388 const ObservedValue_Index_t bondid = _bond->getIndex();
[649f59]389 {
[136842]390#ifndef NDEBUG
[649f59]391 std::pair< ObservedBonds_t::iterator, bool > inserter =
[136842]392#endif
[649f59]393 ObservedBonds.insert( std::make_pair(_bond.get(), _bond) );
394 ASSERT( inserter.second,
395 "GLWorldScene::connectBond() - observed bond "+toString(_bond)+" already stored?");
396#ifndef NDEBUG
397 std::pair< ObservedValueIndexLookup_t::iterator, bool > indexinserter =
398#endif
[ea7926]399 ObservedBondIndexLookup.insert( std::make_pair(bondid, _bond.get()) );
[649f59]400 ASSERT( indexinserter.second,
401 "GLWorldScene::connectBond() - observed bond's index "
[1eba7c]402 +toString(bondid)+" already stored?");
[649f59]403 }
[bd6768]404 {
[502614]405 if ((_bond->getLeftAtom() != NULL) && (_bond->getLeftAtom()->getMoleculeRef() != NULL))
[a13f2b]406 BondNodeParentMaps[0].left.insert(
407 std::make_pair(bondid, _bond->getLeftAtom()->getMoleculeRef()->getIndex()) );
408 else
409 BondNodeParentMaps[0].left.insert(
410 std::make_pair(bondid, (ObservedValue_Index_t)NULL) );
[502614]411 if ((_bond->getRightAtom() != NULL) && (_bond->getRightAtom()->getMoleculeRef() != NULL))
[a13f2b]412 BondNodeParentMaps[1].left.insert(
413 std::make_pair(bondid, _bond->getRightAtom()->getMoleculeRef()->getIndex()) );
414 else
415 BondNodeParentMaps[1].left.insert(
416 std::make_pair(bondid, (ObservedValue_Index_t)NULL) );
[bd6768]417 }
418
419 emit bondConnected(_bond);
420}
421
[f1b5ca]422/** Adds a bond to the scene.
[96f14a]423 *
[f1b5ca]424 * @param _bond bond to add
[96f14a]425 */
[bd6768]426void GLWorldScene::insertBond(QtObservedBond::ptr _bond)
[96f14a]427{
[1eba7c]428 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
429
430 const std::vector< GLMoleculeObject_bond::SideOfBond > bondsides =
[f1b5ca]431 boost::assign::list_of<GLMoleculeObject_bond::SideOfBond>
432 (GLMoleculeObject_bond::left)
433 (GLMoleculeObject_bond::right);
[bd6768]434 LOG(3, "INFO: GLWorldScene::insertBond() - Adding bonds " << _bond->getBondIndex());
[f1b5ca]435
[96f14a]436 const ObservedValue_Index_t bondid = _bond->getIndex();
[a13f2b]437#ifdef NDEBUG
438 BondNodeMap::iterator iter = BondsinSceneMap.find(bondid);
439 ASSERT( iter == BondsinSceneMap.end(),
440 "GLWorldScene::insertBond() - bond "+toString(bondid)+" is already known.");
441#endif
[bd6768]442 {
[a13f2b]443 for (size_t i=0;i<2;++i) {
444 BondNodeParentMap_t::left_iterator parentiter = BondNodeParentMaps[i].left.find(bondid);
445 ASSERT (parentiter != BondNodeParentMaps[i].left.end(),
446 "GLWorldScene::insertBond() - parent to bond id "+toString(bondid)+" unknown?");
447 QObject *parent = this;
448 if (parentiter->second != (ObservedValue_Index_t)NULL) {
449 const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(parentiter->second);
[502614]450 if (moliter != MoleculesinSceneMap.end())
[a13f2b]451 parent = moliter->second;
[502614]452 }
[bd6768]453
454 GLMoleculeObject_bond *bondObject = new GLMoleculeObject_bond(
455 GLMoleculeObject::meshCylinder,
[a13f2b]456 parent,
[bd6768]457 _bond,
458 bondsides[i]);
459 connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
460 BondsinSceneMap.insert( std::make_pair(bondid, bondObject) );
461 }
[96f14a]462 }
463
[f1b5ca]464 emit changed();
465 emit changeOccured();
[96f14a]466}
467
[efeeb7]468void GLWorldScene::checkAndRemoveBond(const ObservedValue_Index_t &_bondid)
469{
[1eba7c]470 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
471
[efeeb7]472 if (checkBondRemoval(BondNodeParentMaps, ToBeRemovedNodes, _bondid)) {
473 LOG(3, "DEBUG: Found both parents of to be removed bond " << _bondid << " as GLWorldScene, removing.");
474 removeBondFromScene(BondsinSceneMap, _bondid);
[ea7926]475 removeStoredObservedValue(ObservedBondIndexLookup, ObservedBonds, _bondid);
[efeeb7]476 eraseBondNodeParents(BondNodeParentMaps, _bondid);
477 ToBeRemovedNodes.erase(_bondid);
478 }
479}
480
[f1b5ca]481/** Removes a bond.
[96f14a]482 *
[f1b5ca]483 * @param _bondid id of bond to remove
[96f14a]484 */
[bd6768]485void GLWorldScene::removeBond(ObservedValue_Index_t _bondid)
[96f14a]486{
[1eba7c]487 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
[efeeb7]488 LOG(3, "INFO: GLWorldScene::removedBond() - got bondRemoved signal from board for id " << _bondid);
[9c259e]489
[30b134]490 // check current state of associated molecules: We won't receive any
491 // moleculeChanged() here anymore, as this QtObservedBond is already
492 // disconnected from its bond object
493 {
494 const ObservedValueIndexLookup_t::const_iterator objiter = ObservedBondIndexLookup.find(_bondid);
495 ASSERT( objiter != ObservedBondIndexLookup.end(),
496 "GLWorldScene::removeBond() - bond's index "+toString(_bondid)
497 +" to be removed not stored yet?");
498 QObject *obj = objiter->second;
499 const ObservedBonds_t::const_iterator observediter = ObservedBonds.find(obj);
500 ASSERT( observediter != ObservedBonds.end(),
501 "GLWorldScene::removeBond() - bond "+toString(_bondid)
502 +" to be removed not stored yet??");
503 const QtObservedBond::ptr &_bond = observediter->second;
504 if (_bond->getLeftMoleculeIndex() != (moleculeId_t)-1) {
505 BondNodeParentMaps[0].left.erase(_bondid);
506 BondNodeParentMaps[0].left.insert( std::make_pair( _bondid, (ObservedValue_Index_t)NULL) );
507 resetParent(getBondInScene(_bondid, GLMoleculeObject_bond::left), NULL);
508 }
509 if (_bond->getRightMoleculeIndex() != (moleculeId_t)-1) {
510 BondNodeParentMaps[1].left.erase(_bondid);
511 BondNodeParentMaps[1].left.insert( std::make_pair( _bondid, (ObservedValue_Index_t)NULL) );
512 resetParent(getBondInScene(_bondid, GLMoleculeObject_bond::right), NULL);
513 }
514 }
515
[efeeb7]516 ASSERT( ToBeRemovedNodes.find(_bondid) == ToBeRemovedNodes.end(),
517 "GLWorldScene::removeBond() - bondRemoved for "+toString(_bondid)+" obtained twice?");
518 ToBeRemovedNodes.insert( _bondid );
519
520 // check whether node has still non-NULL parents, otherwise remove completely
521 checkAndRemoveBond( _bondid );
[8281cc]522
[f1b5ca]523 emit changed();
524 emit changeOccured();
[9c259e]525}
526
[f1b5ca]527void GLWorldScene::hoverChangedSignalled(GLMoleculeObject *ob)
[96f14a]528{
[1eba7c]529 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[f1b5ca]530 // Find the atom, ob corresponds to.
531 hoverAtomId = -1;
532 GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
533 if (atomObject){
534 for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
535 if (iter->second == atomObject)
536 hoverAtomId = iter->second->objectId();
[96f14a]537 }
538
[f1b5ca]539 // Propagate signal.
540 emit hoverChanged(hoverAtomId);
[96f14a]541 } else {
[f1b5ca]542 // Find the atom, ob corresponds to.
543 GLMoleculeObject_molecule *moleculeObject = dynamic_cast<GLMoleculeObject_molecule *>(ob);
544 if (moleculeObject){
545 // Propagate signal.
546 emit hoverChanged(moleculeObject->objectId(), 0);
[96f14a]547 }
548 }
549}
550
[bd6768]551void GLWorldScene::clickMolecule(moleculeId_t no)
[8281cc]552{
[f1b5ca]553 LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
554 const molecule * const mol= const_cast<const World &>(World::getInstance()).
555 getMolecule(MoleculeById(no));
556 ASSERT(mol, "Atom without molecule has been clicked.");
557 molids_t ids(1, mol->getId());
558 if (!World::getInstance().isSelected(mol))
559 SelectionMoleculeById(ids);
560 else
561 SelectionNotMoleculeById(ids);
562 emit clicked(no);
[8281cc]563}
564
[026bef]565/** Inserts a molecule into the scene.
[c67518]566 *
[8c001a]567 * @param _mol molecule to insert
[c67518]568 */
[bd6768]569void GLWorldScene::insertMolecule(QtObservedMolecule::ptr _mol)
[c67518]570{
[f91ef6]571 const ObservedValue_Index_t molid = _mol->getIndex();
572 LOG(3, "INFO: GLWorldScene: Received signal moleculeInserted for molecule "
573 << _mol->getMolIndex());
[7cf0eb]574
[1b07b1]575 MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(molid);
[8c001a]576 ASSERT( iter == MoleculesinSceneMap.end(),
[a13f2b]577 "GLWorldScene::insertMolecule() - molecule's id "+toString(molid)
[f91ef6]578 +" already present.");
[8c001a]579
580 // add new object
[a13f2b]581 LOG(1, "DEBUG: Adding GLMoleculeObject_molecule to id " << molid);
[1b07b1]582 GLMoleculeObject_molecule *molObject =
583 new GLMoleculeObject_molecule(
584 GLMoleculeObject::meshEmpty,
585 this,
586 _mol);
587 ASSERT( molObject != NULL,
[bd6768]588 "GLWorldScene::insertMolecule - could not create molecule object for "
[a13f2b]589 +toString(molid));
[6c4b69]590#ifndef NDEBUG
591 foreach (QObject *obj, molObject->children()) {
592 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
593 ASSERT( meshobj == NULL,
594 "GLWorldScene::insertMolecule() - there are already atoms or bonds attached to a to molecule.");
595 }
596#endif
[a13f2b]597
598 // check all atoms for not yet assigned parents
599 {
[1eba7c]600 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[a13f2b]601 std::pair<AtomNodeParentMap_t::right_const_iterator, AtomNodeParentMap_t::right_const_iterator> iters =
602 AtomNodeParentMap.right.equal_range(molid);
603 for (AtomNodeParentMap_t::right_const_iterator iter = iters.first;
604 iter != iters.second; ++iter) {
605 AtomNodeMap::const_iterator atomiter = AtomsinSceneMap.find(iter->second);
606 if (atomiter != AtomsinSceneMap.end())
607 resetParent(atomiter->second, molObject);
608 }
609 }
610 // check all bonds for not yet assigned parents
611 {
[1eba7c]612 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
[a13f2b]613 for (size_t i=0;i<2;++i) {
614 std::pair<BondNodeParentMap_t::right_const_iterator, BondNodeParentMap_t::right_const_iterator> iters =
615 BondNodeParentMaps[i].right.equal_range(molid);
616 for (BondNodeParentMap_t::right_const_iterator iter = iters.first;
617 iter != iters.second; ++iter) {
618 BondNodeMap::const_iterator bonditer = BondsinSceneMap.find(iter->second);
619 if (bonditer != BondsinSceneMap.end())
620 resetParent(bonditer->second, molObject);
621 }
622 }
623 }
624
[1b07b1]625#ifndef NDEBUG
626 std::pair<MoleculeNodeMap::iterator, bool> inserter =
627#endif
628 MoleculesinSceneMap.insert( make_pair(molid, molObject) );
629 ASSERT(inserter.second,
[bd6768]630 "GLWorldScene::insertMolecule() - molecule "+toString(_mol->getMolIndex())
[f91ef6]631 +" already present in scene.");
[1b07b1]632
633 connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
634 connect (molObject, SIGNAL(changeOccured()), this, SIGNAL(changeOccured()));
635
636 emit changed();
637 emit changeOccured();
[c67518]638}
639
[7cf0eb]640/** Removes a molecule from the scene.
641 *
[f1b5ca]642 * @param _molid index of the molecule to remove
[7cf0eb]643 */
[bd6768]644void GLWorldScene::removeMolecule(ObservedValue_Index_t _molid)
[7cf0eb]645{
[f1b5ca]646 LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_molid)+".");
[7c7c4a]647
[f1b5ca]648 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
[4a187d]649 ASSERT ( iter != MoleculesinSceneMap.end(),
[bd6768]650 "GLWorldScene::removeMolecule() - to be removed molecule "+toString(_molid)
[4a187d]651 +" is already gone.");
[f1b5ca]652 GLMoleculeObject_molecule *molObject = iter->second;
[6c4b69]653 // check for any atoms and bonds still attached to it
654#ifndef NDEBUG
655 foreach (QObject *obj, molObject->children()) {
656 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
657 ASSERT( meshobj == NULL,
658 "GLWorldScene::removeMolecule() - there are still atoms or bonds attached to a to molecule.");
659 }
660#endif
661 // finally, remove molecule
[f1b5ca]662 delete molObject;
[4a187d]663 MoleculesinSceneMap.erase(iter);
[bcf9cd]664
[f1b5ca]665 emit changed();
666 emit changeOccured();
[ce4126]667}
668
[f91ef6]669void GLWorldScene::moleculesVisibilityChanged(ObservedValue_Index_t _id, bool _visible)
[739ee9]670{
671 MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
672 ASSERT( iter != MoleculesinSceneMap.end(),
[f91ef6]673 "GLWorldScene::moleculeInserted() - molecule's id "
674 +toString(board->getMoleculeIdToIndex(_id))+" is unknown.");
[739ee9]675
676 GLMoleculeObject_molecule *molObject = iter->second;
677 molObject->setVisible(_visible);
678
679 emit changed();
680 emit changeOccured();
681}
682
[a13f2b]683/** This converts safely index into a GLMoleculeObject_molecule.
684 *
685 * \param _MoleculesinSceneMap all present molecules
686 * \param _molid index to look for
687 * \return MolObject or NULL when not found
688 */
689GLMoleculeObject_molecule *GLWorldScene::getMoleculeObject(
690 const ObservedValue_Index_t _molid) const
691{
692 const MoleculeNodeMap::const_iterator moliter = MoleculesinSceneMap.find(_molid);
693 if (moliter != MoleculesinSceneMap.end())
694 return moliter->second;
695 else
696 return NULL;
697}
698
[bd6768]699/** Changes the parent of an object in the scene.
700 *
701 * \param _id index of the object whose parent to change
702 * \param _ob new parent
703 */
704void GLWorldScene::reparentAtom()
705{
[1eba7c]706 boost::recursive_mutex::scoped_lock lock(Atom_mutex);
[649f59]707 QObject * origin = sender();
[efeeb7]708 if (origin == NULL) {
709 ELOG(1, "Got reparentAtom() with sender being NULL.");
710 return;
711 }
[649f59]712 ObservedAtoms_t::const_iterator iter = ObservedAtoms.find(origin);
713 ASSERT( iter != ObservedAtoms.end(),
714 "GLWorldScene::reparentAtom() - atom's "+toString(origin)+" is no longer stored?");
715 QtObservedAtom::ptr walker = iter->second;
[bd6768]716 const ObservedValue_Index_t walkerid = walker->getIndex();
[6c4b69]717 LOG(4, "DEBUG: GLWorldScene: Received signal moleculeChanged for atom "+toString(walkerid)+".");
[a13f2b]718 AtomNodeParentMap_t::left_iterator parentiter = AtomNodeParentMap.left.find(walkerid);
719 ASSERT( parentiter != AtomNodeParentMap.left.end(),
[bd6768]720 "GLWorldScene::reparentAtom() - could not find object to id "+toString(walkerid));
[502614]721
722 // change parent entry
[a13f2b]723 AtomNodeParentMap.left.erase(parentiter);
[502614]724 if (walker->getMoleculeRef() != NULL)
[a13f2b]725 AtomNodeParentMap.left.insert( std::make_pair(walkerid, walker->getMoleculeRef()->getIndex()) );
[502614]726 else
[a13f2b]727 AtomNodeParentMap.left.insert( std::make_pair(walkerid, (ObservedValue_Index_t)NULL) );
728 parentiter = AtomNodeParentMap.left.find(walkerid);
[502614]729
[a13f2b]730 const AtomNodeMap::iterator atomiter = AtomsinSceneMap.find(walkerid);
731 if (atomiter != AtomsinSceneMap.end())
732 resetParent(atomiter->second, getMoleculeObject(parentiter->second));
733 // else atom does not yet exist
[649f59]734
[efeeb7]735 // check whether node is still shown, otherwise remove completely
736 checkAndRemoveAtom( walkerid );
[bd6768]737}
738
[502614]739/** Changes the parent of an left-side bond in the scene.
[bd6768]740 *
741 */
742void GLWorldScene::reparentBondLeft()
743{
[1eba7c]744 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
[649f59]745 QObject * origin = sender();
[efeeb7]746 if (origin == NULL) {
747 ELOG(1, "Got reparentBondLeft() with sender being NULL.");
748 return;
749 }
[649f59]750 ObservedBonds_t::const_iterator iter = ObservedBonds.find(origin);
751 ASSERT( iter != ObservedBonds.end(),
752 "GLWorldScene::reparentBondLeft() - bond "+toString(origin)+" is no longer stored?");
753 QtObservedBond::ptr bond = iter->second;
[efeeb7]754 LOG(3, "INFO: GLWorldScene::reparentBondLeft() - Reparenting left side of bond "
755 << bond->getBondIndex() << ".");
[502614]756 reparentBond(bond, bond->getLeftAtom(), GLMoleculeObject_bond::left);
[649f59]757
[efeeb7]758 // check whether node is still shown, otherwise remove completely
759 checkAndRemoveBond( bond->getIndex() );
[502614]760}
761
762/** Changes the parent of an right-side bond in the scene.
763 *
764 */
765void GLWorldScene::reparentBondRight()
766{
[1eba7c]767 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
[649f59]768 QObject * origin = sender();
[efeeb7]769 if (origin == NULL) {
770 ELOG(1, "Got reparentBondRight() with sender being NULL.");
771 return;
772 }
[649f59]773 ObservedBonds_t::const_iterator iter = ObservedBonds.find(origin);
774 ASSERT( iter != ObservedBonds.end(),
775 "GLWorldScene::reparentBondRight() - bond "+toString(origin)+" is no longer stored?");
776 QtObservedBond::ptr bond = iter->second;
[efeeb7]777 LOG(3, "INFO: GLWorldScene::reparentBondRight() - Reparenting right side of bond "
778 << bond->getBondIndex() << ".");
[502614]779 reparentBond(bond, bond->getRightAtom(), GLMoleculeObject_bond::right);
[649f59]780
[efeeb7]781 // check whether node is still shown, otherwise remove completely
782 checkAndRemoveBond( bond->getIndex() );
[502614]783}
784
785GLMoleculeObject_bond *GLWorldScene::getBondInScene(
786 const ObservedValue_Index_t _bondid,
787 GLMoleculeObject_bond::SideOfBond _side) const
788{
789 std::pair<GLWorldScene::BondNodeMap::const_iterator, GLWorldScene::BondNodeMap::const_iterator> iters =
790 BondsinSceneMap.equal_range(_bondid);
[efeeb7]791 ASSERT( std::distance(iters.first, iters.second) >= 1,
792 "GLWorldScene::getBondInScene() - not at least one bond of id "
[502614]793 +toString(_bondid)+" present in scene.");
794 for (GLWorldScene::BondNodeMap::const_iterator bonditer = iters.first;
795 bonditer != iters.second; ++bonditer) {
796 if (bonditer->second->BondSide == _side)
797 return bonditer->second;
[bd6768]798 }
[502614]799 return NULL;
[bd6768]800}
801
802/** Changes the parent of an object in the scene.
803 *
[502614]804 * \param _atom atom of bond whose molecule we are associated to
805 * \param _side side of bond
[bd6768]806 */
[502614]807void GLWorldScene::reparentBond(
[649f59]808 const QtObservedBond::ptr _bond,
[507f3c]809 const QtObservedAtom::ptr _atom,
[502614]810 const GLMoleculeObject_bond::SideOfBond _side)
[bd6768]811{
[1eba7c]812 boost::recursive_mutex::scoped_lock lock(Bond_mutex);
[a13f2b]813 const size_t dim = (_side == GLMoleculeObject_bond::left) ? 0 : 1;
[502614]814 const ObservedValue_Index_t bondid = _bond->getIndex();
[a13f2b]815 BondNodeParentMap_t::left_iterator parentiter = BondNodeParentMaps[dim].left.find(bondid);
816 ASSERT( parentiter != BondNodeParentMaps[dim].left.end(),
[502614]817 "GLWorldScene::reparentBond() - could not find object to id "+toString(bondid));
818
819 // change parent entry
[a13f2b]820 BondNodeParentMaps[dim].left.erase(bondid);
[502614]821 if ((_atom != NULL) && (_atom->getMoleculeRef() != NULL))
[a13f2b]822 BondNodeParentMaps[dim].left.insert( std::make_pair( bondid, _atom->getMoleculeRef()->getIndex()));
[502614]823 else
[a13f2b]824 BondNodeParentMaps[dim].left.insert( std::make_pair( bondid, (ObservedValue_Index_t)NULL) );
825 parentiter = BondNodeParentMaps[dim].left.find(bondid);
[efeeb7]826 LOG(3, "INFO: GLWorldScene::reparentBond() - Reparented bond "
827 << _bond->getBondIndex() << " to " << parentiter->second);
[502614]828
829 // reset parent
[a13f2b]830 resetParent(getBondInScene(bondid, _side), getMoleculeObject(parentiter->second));
831}
832
833/** Resets the parent of an GLMoleculeObject.
834 *
835 * \param _obj object to reparent
836 * \param _molid index of parent molecule
837 */
838void GLWorldScene::resetParent(
839 GLMoleculeObject *_obj,
840 GLMoleculeObject_molecule *_molobj)
841{
842 if (_obj != NULL) {
[0bddd1e]843 if (_molobj != NULL) {
844 LOG(5, "DEBUG: Resetting parent of " << _obj << " to " << _molobj);
845 _obj->setParent(_molobj);
846 ASSERT( _obj->parent() == _molobj,
847 "GLWorldScene::resetParent() - new parent "+toString(_molobj)+" was not set.");
848 } else {
849 LOG(5, "DEBUG: Resetting parent of " << _obj << " to " << this);
850 _obj->setParent(this);
851 ASSERT( _obj->parent() == this,
852 "GLWorldScene::resetParent() - new parent "+toString(this)+" was not set.");
853 }
[6c4b69]854 } else
855 ELOG(1, "Object to reparent was NULL.");
[a13f2b]856 // else object does not yet exist
[bd6768]857}
858
[f75491]859/** Adds a shape to the scene.
[4d6662]860 *
[f75491]861 */
[07136a]862void GLWorldScene::addShape(const std::string &_name)
[f75491]863{
[07136a]864 Shape * const shape = ShapeRegistry::getInstance().getByName(_name);
865 if (shape != NULL) {
866 GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(*shape, this);
867 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
868 ASSERT(iter == ShapesinSceneMap.end(),
869 "GLWorldScene::addShape() - same shape "+_name+" added again.");
870 ShapesinSceneMap.insert( make_pair(_name, shapeObject) );
871 } else
872 ELOG(2, "GLWorldScene::addShape() - shape disappeared before we could draw it.");
873
874 emit changed();
[284551]875}
876
[07136a]877void GLWorldScene::removeShape(const std::string &_name)
[85c36d]878{
[07136a]879 ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
[ba6b5c]880 ASSERT(iter != ShapesinSceneMap.end(),
[07136a]881 "GLWorldScene::removeShape() - shape "+_name+" not in scene.");
[148dde0]882 ShapesinSceneMap.erase(iter);
[85c36d]883 delete(iter->second);
[07136a]884
885 emit changed();
[85c36d]886}
887
888void GLWorldScene::updateSelectedShapes()
[284551]889{
890 foreach (QObject *obj, children()) {
891 GLMoleculeObject_shape *shapeobj = qobject_cast<GLMoleculeObject_shape *>(obj);
[85c36d]892 if (shapeobj){
893 shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
894 }
[284551]895 }
[07136a]896
897 emit changed();
[f75491]898}
899
[7188b1]900void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
901{
902 // Initialize all of the mesh objects that we have as children.
903 foreach (QObject *obj, children()) {
904 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
905 if (meshobj)
906 meshobj->initialize(view, painter);
907 }
908}
909
[72a4c1]910void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
[7188b1]911{
912 // Draw all of the mesh objects that we have as children.
913 foreach (QObject *obj, children()) {
914 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
915 if (meshobj)
[72a4c1]916 meshobj->draw(painter, cameraPlane);
[7188b1]917 }
[907636]918}
[06ebf5]919
[6966b7]920void GLWorldScene::setSelectionMode(SelectionModeType mode)
921{
922 selectionMode = mode;
923 // TODO send update to toolbar
924}
925
926void GLWorldScene::setSelectionModeAtom()
927{
928 setSelectionMode(SelectAtom);
929}
930
931void GLWorldScene::setSelectionModeMolecule()
932{
933 setSelectionMode(SelectMolecule);
934}
[20f9b5]935
Note: See TracBrowser for help on using the repository browser.