source: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp@ 62a0ee

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 62a0ee was 1b07b1, checked in by Frederik Heber <heber@…>, 9 years ago

QtObservedInstanceBoard now sends QtObserved..::ptr around in signals.

  • this should get rid of the problem that we need to keep the QtObservedAtom until it was requested at least once. And we don't know for how long. Now, we simply place the shared_ptr into the signal (to which it seems to be copied) and hence a representation of the atoms remains valid.
  • cstor of GLMoleculeObject_.. take Observed.. as ref.
  • Property mode set to 100644
File size: 20.2 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 * GLMoleculeObject_molecule.cpp
26 *
27 * Created on: Mar 30, 2012
28 * Author: ankele
29 */
30
31
32// include config.h
33#ifdef HAVE_CONFIG_H
34#include <config.h>
35#endif
36
37#include "GLMoleculeObject_molecule.hpp"
38
39#include <Qt3D/qglscenenode.h>
40#include <Qt3D/qglbuilder.h>
41
42#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp"
43
44#include "CodePatterns/MemDebug.hpp"
45
46#include <boost/assign.hpp>
47
48#include "CodePatterns/Assert.hpp"
49#include "CodePatterns/IteratorAdaptors.hpp"
50#include "CodePatterns/Log.hpp"
51
52#include "LinearAlgebra/Vector.hpp"
53#include "LinkedCell/PointCloudAdaptor.hpp"
54#include "LinkedCell/linkedcell.hpp"
55#include "Tesselation/tesselation.hpp"
56#include "Tesselation/BoundaryLineSet.hpp"
57#include "Tesselation/BoundaryTriangleSet.hpp"
58#include "Tesselation/CandidateForTesselation.hpp"
59#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
60#include "Atom/TesselPoint.hpp"
61#include "World.hpp"
62
63using namespace boost::assign;
64
65static Observable::channels_t getAllAtomicChangesChannels()
66{
67 Observable::channels_t channels;
68 channels += molecule::AtomInserted, molecule::AtomRemoved, molecule::AtomMoved;
69 return channels;
70}
71
72const Observable::channels_t GLMoleculeObject_molecule::HullChannels(getAllAtomicChangesChannels());
73
74static QGLSceneNode *createMoleculeMesh(const QGeometryData &_geo)
75{
76 // Build a mesh from the geometry.
77 QGLBuilder builder;
78 builder.addTriangles(_geo);
79 QGLSceneNode *mesh = builder.finalizedSceneNode();
80 return mesh;
81}
82
83GLMoleculeObject_molecule::GLMoleculeObject_molecule(
84 QObject *parent,
85 QtObservedInstanceBoard &_board,
86 QtObservedMolecule::ptr &_ObservedMolecule) :
87 GLMoleculeObject((QGLSceneNode *)NULL, parent),
88 owner(NULL),
89 molref(QtObservedMolecule::getMolecule(_ObservedMolecule->getMolIndex())),
90 hoverAtomId(-1),
91 board(_board),
92 ObservedMolecule(_ObservedMolecule)
93{
94 init(ObservedMolecule->getMolIndex());
95}
96
97GLMoleculeObject_molecule::GLMoleculeObject_molecule(
98 QGLSceneNode *mesh[],
99 QObject *parent,
100 QtObservedInstanceBoard &_board,
101 QtObservedMolecule::ptr &_ObservedMolecule) :
102 GLMoleculeObject(mesh, parent),
103 owner(NULL),
104 molref(QtObservedMolecule::getMolecule(_ObservedMolecule->getMolIndex())),
105 hoverAtomId(-1),
106 board(_board),
107 ObservedMolecule(_ObservedMolecule)
108{
109 init(ObservedMolecule->getMolIndex());
110}
111
112void GLMoleculeObject_molecule::init(const moleculeId_t _molid)
113{
114 setObjectId(_molid);
115 setMaterial(getMaterial(1));
116
117 m_selected = const_cast<const World &>(World::getInstance()).isMoleculeSelected(_molid);
118
119 // initially, atoms and bonds should be visible
120 m_visible = false;
121
122 connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
123 connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
124 connect (ObservedMolecule.get(), SIGNAL(tesselationhullChanged()), this, SLOT(resetTesselationHull()));
125 connect (ObservedMolecule.get(), SIGNAL(boundingboxChanged()), this, SLOT(resetBoundingBox()));
126 connect (ObservedMolecule.get(), SIGNAL(indexChanged()), this, SLOT(resetIndex()));
127 connect (ObservedMolecule.get(), SIGNAL(atomInserted(QtObservedAtom::ptr)), this, SLOT(atomInserted(QtObservedAtom::ptr)));
128 connect (ObservedMolecule.get(), SIGNAL(atomRemoved(const atomId_t)), this, SLOT(atomRemoved(const atomId_t)));
129 connect (ObservedMolecule.get(), SIGNAL(selectedChanged()), this, SLOT(resetSelected()));
130
131 connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
132}
133
134GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
135{}
136
137void GLMoleculeObject_molecule::addAtomBonds(
138 const bond::ptr &_bond,
139 const GLMoleculeObject_bond::SideOfBond _side
140 )
141{
142 bool bond_present = false;
143 const BondIds ids = getBondIds(_bond, _side);
144 // check whether bond is not present already
145 bond_present = BondsinSceneMap.count(ids);
146 if (!bond_present)
147 bondInserted(ids.first, ids.second, _side);
148 else {
149 BondsinSceneMap[ids]->resetPosition();
150 BondsinSceneMap[ids]->resetWidth();
151 }
152}
153
154QGeometryData GLMoleculeObject_molecule::updateTesselationHull() const
155{
156 QGeometryData geo;
157
158 const molecule * const molref =
159 QtObservedMolecule::getMolecule(ObservedMolecule->getMolIndex());
160 if (molref == NULL) {
161 ELOG(1, "Could not createMoleculeMesh, molecule with id "
162 << ObservedMolecule->getMolIndex() << " already gone.");
163 return geo;
164 }
165 double minradius = 2.; // TODO: set to maximum bond length value
166 LOG(3, "DEBUG: Molecule fits into sphere of radius " << minradius);
167 // check minimum bond radius in molecule
168 double minlength = std::numeric_limits<double>::max();
169 for (molecule::const_iterator iter = molref->begin();
170 iter != molref->end(); ++iter) {
171 const BondList &ListOfBonds = (*iter)->getListOfBonds();
172 for (BondList::const_iterator bonditer = ListOfBonds.begin();
173 bonditer != ListOfBonds.end(); ++bonditer) {
174 const double bond_distance = (*bonditer)->GetDistance();
175 minlength = std::min(bond_distance, minlength);
176 }
177 }
178 minradius = std::max( std::max(minradius, minlength), 1.);
179
180 // we need at least three points for tesselation
181 if (getPresentAtoms().size() >= 3) {
182 // Tesselate the points.
183 Tesselation T;
184 PointCloudAdaptor<molecule> cloud(
185 const_cast<molecule *>(molref),
186 ObservedMolecule->getMolName());
187 T(cloud, minradius);
188
189 // Fill the points into a Qt geometry.
190 LinkedCell_deprecated LinkedList(cloud, minradius);
191 std::map<int, int> indices;
192 std::map<int, Vector> normals;
193 int index = 0;
194 for (PointMap::const_iterator piter = T.PointsOnBoundary.begin();
195 piter != T.PointsOnBoundary.end(); ++piter) {
196 const Vector &point = piter->second->getPosition();
197 // add data to the primitive
198 geo.appendVertex(QVector3D(point[0], point[1], point[2]));
199 Vector normalvector;
200 for (LineMap::const_iterator lineiter = piter->second->lines.begin();
201 lineiter != piter->second->lines.end(); ++lineiter)
202 for (TriangleMap::const_iterator triangleiter = lineiter->second->triangles.begin();
203 triangleiter != lineiter->second->triangles.end(); ++triangleiter)
204 normalvector +=
205 triangleiter->second->NormalVector;
206 normalvector.Normalize();
207 geo.appendNormal(QVector3D(normalvector[0], normalvector[1], normalvector[2]));
208 geo.appendColor(QColor(1, 1, 1, 1));
209 geo.appendTexCoord(QVector2D(0, 0));
210 indices.insert( std::make_pair( piter->second->getNr(), index++));
211 }
212
213 // Fill the tesselated triangles into the geometry.
214 for (TriangleMap::const_iterator runner = T.TrianglesOnBoundary.begin();
215 runner != T.TrianglesOnBoundary.end(); runner++) {
216 int v[3];
217 for (size_t i=0; i<3; ++i)
218 v[i] = runner->second->endpoints[i]->getNr();
219
220 // Sort the vertices so the triangle is clockwise (relative to the normal vector).
221 Vector cross = T.PointsOnBoundary[v[1]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition();
222 cross.VectorProduct(T.PointsOnBoundary[v[2]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition());
223 if (cross.ScalarProduct(runner->second->NormalVector) > 0)
224 geo.appendIndices(indices[v[0]], indices[v[1]], indices[v[2]]);
225 else
226 geo.appendIndices(indices[v[0]], indices[v[2]], indices[v[1]]);
227 }
228 }
229
230 return geo;
231}
232
233void GLMoleculeObject_molecule::resetTesselationHull()
234{
235 if (owner != NULL) {
236 TesselationHull = updateTesselationHull();
237 updateMesh(createMoleculeMesh(TesselationHull));
238 }
239}
240
241void GLMoleculeObject_molecule::resetBoundingBox()
242{
243 molecule::BoundingBoxInfo info = ObservedMolecule->getBoundingBox();
244 setPosition(QVector3D(info.position[0], info.position[1], info.position[2]));
245 setScale(info.radius + 0.3); // getBoundingSphere() only sees atoms as points, so make the box a bit bigger
246}
247
248void GLMoleculeObject_molecule::resetIndex()
249{
250 const atomId_t newId = ObservedMolecule->getMolIndex();
251 const size_t oldId = objectId();
252 ASSERT( newId != oldId,
253 "GLMoleculeObject_molecule::resetIndex() - index "+toString(newId)+" did not change.");
254 LOG(4, "INFO: GLMoleculeObject_molecule: new index is "+toString(newId)+".");
255 setObjectId(newId);
256
257 emit indexChanged(this, oldId, newId);
258}
259
260void GLMoleculeObject_molecule::resetSelected()
261{
262 const bool new_selected = ObservedMolecule->getMolSelected();
263 ASSERT( m_selected != new_selected,
264 "GLMoleculeObject_molecule::resetSelected() - new and old selection state are the same.");
265 m_selected = new_selected;
266
267 emit changed();
268}
269
270void GLMoleculeObject_molecule::initialize(QGLView *view, QGLPainter *painter)
271{
272 // Initialize all of the mesh objects that we have as children.
273 if (m_visible) {
274 GLMoleculeObject::initialize(view, painter);
275 } else {
276 foreach (QObject *obj, children()) {
277 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
278 if (meshobj)
279 meshobj->initialize(view, painter);
280 }
281 }
282}
283
284void GLMoleculeObject_molecule::draw(QGLPainter *painter, const QVector4D &cameraPlane)
285{
286 // draw either molecule's mesh or all atoms and bonds
287 if (m_visible) {
288 resetTesselationHull();
289
290 painter->modelViewMatrix().push();
291
292 // Apply the material and effect to the painter.
293 QGLMaterial *material;
294 if (m_hovering)
295 material = m_hoverMaterial;
296 else if (m_selected)
297 material = m_selectionMaterial;
298 else
299 material = m_material;
300
301 ASSERT(material, "GLMoleculeObject::draw: chosen material is NULL");
302
303 painter->setColor(material->diffuseColor());
304 painter->setFaceMaterial(QGL::AllFaces, material);
305 if (m_effect)
306 painter->setUserEffect(m_effect);
307 else
308 painter->setStandardEffect(QGL::LitMaterial);
309
310 // Mark the object for object picking purposes.
311 int prevObjectId = painter->objectPickId();
312 if (m_objectId != -1)
313 painter->setObjectPickId(m_objectId);
314
315 m_mesh[0]->draw(painter);
316
317 // Turn off the user effect, if present.
318 if (m_effect)
319 painter->setStandardEffect(QGL::LitMaterial);
320
321 // Revert to the previous object identifier.
322 painter->setObjectPickId(prevObjectId);
323
324 // Restore the modelview matrix.
325 painter->modelViewMatrix().pop();
326
327 // GLMoleculeObject::draw(painter, cameraPlane);
328 } else {
329 // Draw all of the mesh objects that we have as children.
330 foreach (QObject *obj, children()) {
331 GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
332 if (meshobj)
333 meshobj->draw(painter, cameraPlane);
334 }
335
336 // update bounding box prior to selection
337 resetBoundingBox();
338
339 painter->modelViewMatrix().push();
340 painter->modelViewMatrix().translate(m_position);
341 if (m_rotationAngle != 0.0f)
342 painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
343 if ((m_scaleX != 1.0f) || (m_scaleY != 1.0f) || (m_scaleZ != 1.0f))
344 painter->modelViewMatrix().scale(m_scaleX, m_scaleY, m_scaleZ);
345
346 // Draw a box around the mesh, if selected.
347 if (m_selected)
348 drawSelectionBox(painter);
349
350 // Restore the modelview matrix.
351 painter->modelViewMatrix().pop();
352 }
353}
354
355/** Adds an atom of this molecule to the scene.
356 *
357 * @param _atom atom to add
358 */
359void GLMoleculeObject_molecule::atomInserted(QtObservedAtom::ptr _atom)
360{
361 const atomId_t atomid = _atom->getAtomIndex();
362 LOG(3, "INFO: GLMoleculeObject_molecule: Received signal atomInserted for atom "+toString(atomid)+".");
363
364 if (_atom) {
365 GLMoleculeObject_atom *atomObject =
366 new GLMoleculeObject_atom(
367 GLMoleculeObject::meshSphere,
368 this,
369 _atom);
370 ASSERT( atomObject != NULL,
371 "GLMoleculeObject_molecule::atomInserted - could not create atom object for "+toString(atomid));
372 AtomNodeMap::iterator iter = AtomsinSceneMap.find(atomid);
373 ASSERT(iter == AtomsinSceneMap.end(),
374 "GLMoleculeObject_molecule::atomInserted - same atom with id "+toString(atomid)+" added again.");
375 AtomsinSceneMap.insert( make_pair(atomid, atomObject) );
376
377 qRegisterMetaType<atomId_t>("atomId_t");
378 qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
379 connect (atomObject, SIGNAL(clicked(atomId_t)), this, SIGNAL(atomClicked(atomId_t)));
380 connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
381 connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
382 connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
383 // connect (atomObject, SIGNAL(bondsChanged()), this, SLOT(bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)));
384 connect (atomObject, SIGNAL(BondsAdded(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)));
385 connect (atomObject, SIGNAL(BondsRemoved(const atomId_t, const atomId_t)), this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
386 connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, const atomId_t, const atomId_t)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, const atomId_t, const atomId_t)));
387
388 if (m_objectId == -1)
389 setObjectId(atomid);
390
391 emit changed();
392 emit changeOccured();
393 }
394}
395
396/** Removes an atom of this molecule from the scene.
397 *
398 * We just the id as the atom might have already been destroyed.
399 *
400 * @param _id id of atom to remove
401 */
402void GLMoleculeObject_molecule::atomRemoved(const atomId_t _id)
403{
404 LOG(3, "INFO: GLMoleculeObject_molecule: Received signal atomRemoved for atom "+toString(_id)+".");
405 // bonds are removed by signal coming from ~bond
406
407 if ((unsigned int)m_objectId == _id)
408 setObjectId(-1);
409
410 // remove atoms
411 AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
412 ASSERT(iter != AtomsinSceneMap.end(),
413 "GLMoleculeObject_molecule::atomRemoved() - atom "+toString(_id)+" not on display.");
414 GLMoleculeObject_atom *atomObject = iter->second;
415 AtomsinSceneMap.erase(iter);
416 atomObject->disconnect();
417 delete atomObject;
418
419 emit changed();
420 emit changeOccured();
421}
422
423void GLMoleculeObject_molecule::hoverChangedSignalled(GLMoleculeObject *ob)
424{
425 // Find the atom, ob corresponds to.
426 hoverAtomId = -1;
427 GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
428 if (atomObject){
429 for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
430 if (iter->second == atomObject)
431 hoverAtomId = iter->first;
432 }
433
434 // Propagate signal.
435 emit hoverChanged(hoverAtomId);
436 } else {
437 // Find the atom, ob corresponds to.
438 GLMoleculeObject_molecule *moleculeObject = dynamic_cast<GLMoleculeObject_molecule *>(ob);
439 if (moleculeObject == this){
440 // Propagate signal.
441 emit hoverChanged(ObservedMolecule->getMolIndex(), 0);
442 }
443 }
444}
445
446
447/** Helper function to get bond ids in the correct order for BondNodeMap.
448 *
449 * \return pair of ids in correct order.
450 */
451GLMoleculeObject_molecule::BondIds GLMoleculeObject_molecule::getBondIds(
452 const bond::ptr _bond,
453 const enum GLMoleculeObject_bond::SideOfBond _side)
454{
455 BondIds ids;
456 switch (_side) {
457 case GLMoleculeObject_bond::left:
458 ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
459 break;
460 case GLMoleculeObject_bond::right:
461 ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
462 break;
463 }
464 return ids;
465}
466
467/** Adds a bond to the scene.
468 *
469 * @param _bond bond to add
470 * @param side which side of the bond (left or right)
471 */
472void GLMoleculeObject_molecule::bondInserted(
473 const atomId_t _left, const atomId_t _right,
474 const enum GLMoleculeObject_bond::SideOfBond _side)
475{
476 LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(_left)
477 +toString(_right)+".");
478 //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
479
480 const BondIds ids( std::make_pair(_left, _right) );
481 BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
482 if (iter == BondsinSceneMap.end()) {
483 GLMoleculeObject_bond * bondObject =
484 new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, ids, _side);
485 connect (
486 bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
487 this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
488 connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
489 BondsinSceneMap.insert( make_pair(ids, bondObject) );
490 // BondIdsinSceneMap.insert( Leftids );
491 } else {
492 iter->second->resetPosition();
493 iter->second->resetWidth();
494 }
495 emit changed();
496 emit changeOccured();
497}
498
499/** Removes a bond from the scene.
500 *
501 * @param _bond bond to remove
502 */
503void GLMoleculeObject_molecule::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
504{
505 LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
506 {
507 // left bond
508 const BondIds Leftids( make_pair(leftnr, rightnr) );
509 BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
510 ASSERT(leftiter != BondsinSceneMap.end(),
511 "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
512 +toString(rightnr)+" not on display.");
513 GLMoleculeObject_bond *bondObject = leftiter->second;
514 bondObject->disconnect();
515 BondsinSceneMap.erase(leftiter);
516 delete bondObject; // is done by signal from bond itself
517 //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
518 }
519
520 emit changed();
521 emit changeOccured();
522}
523
524void GLMoleculeObject_molecule::setVisible(bool value)
525{
526 // first update the mesh if we are going to be visible now
527 if (value)
528 updateTesselationHull();
529 // then emit onward
530 GLMoleculeObject::setVisible(value);
531
532 emit changed();
533 emit changeOccured();
534}
535
536std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t)
537{
538 ost << t.first << "," << t.second;
539 return ost;
540}
541
542void GLMoleculeObject_molecule::wasClicked()
543{
544 LOG(4, "INFO: GLMoleculeObject_molecule: atom "
545 << ObservedMolecule->getMolIndex() << " has been clicked");
546 emit moleculeClicked(ObservedMolecule->getMolIndex());
547}
548
549void GLMoleculeObject_molecule::changeAtomId(
550 GLMoleculeObject_atom *ob,
551 const atomId_t oldId,
552 const atomId_t newId)
553{
554 LOG(3, "INFO: GLMoleculeObject_molecule - change atom id " << oldId << " to " << newId << ".");
555
556 // Remove from map.
557 AtomNodeMap::iterator iter = AtomsinSceneMap.find(oldId);
558 ASSERT(iter != AtomsinSceneMap.end(),
559 "GLMoleculeObject_molecule::changeAtomId() - atom with old id "+toString(oldId)+" not on display.");
560 ASSERT(iter->second == ob,
561 "GLMoleculeObject_molecule::changeAtomId() - atom with id "
562 +toString(oldId)+" does not match with object in AtomsinSceneMap.");
563 AtomsinSceneMap.erase(iter);
564
565 // Reinsert with new id.
566 {
567 AtomNodeMap::iterator iter = AtomsinSceneMap.find(newId);
568 ASSERT(iter == AtomsinSceneMap.end(),
569 "GLMoleculeObject_molecule::changeAtomId() - atom with new id "+toString(newId)+" already known.");
570 }
571 AtomsinSceneMap.insert( make_pair(newId, ob) );
572}
573
574
575GLMoleculeObject_molecule::atoms_t GLMoleculeObject_molecule::getPresentAtoms() const
576{
577 atoms_t returnAtomIds;
578 returnAtomIds.insert(
579 MapKeyConstIterator<AtomNodeMap::const_iterator>(const_cast<const AtomNodeMap &>(AtomsinSceneMap).begin()),
580 MapKeyConstIterator<AtomNodeMap::const_iterator>(const_cast<const AtomNodeMap &>(AtomsinSceneMap).end()));
581 return returnAtomIds;
582}
Note: See TracBrowser for help on using the repository browser.