Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp

    ra2a2f7 r52cd7b  
    4141
    4242#include <Qt3D/qglscenenode.h>
     43#include <Qt3D/qglbuilder.h>
    4344
    4445#include "CodePatterns/MemDebug.hpp"
     
    5455#include "Element/element.hpp"
    5556#include "LinearAlgebra/Vector.hpp"
     57#include "LinkedCell/PointCloudAdaptor.hpp"
     58#include "LinkedCell/linkedcell.hpp"
     59#include "Tesselation/tesselation.hpp"
     60#include "Tesselation/BoundaryLineSet.hpp"
     61#include "Tesselation/BoundaryTriangleSet.hpp"
     62#include "Tesselation/CandidateForTesselation.hpp"
     63#include "Atom/TesselPoint.hpp"
    5664#include "World.hpp"
    5765
    58 GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref) :
    59   GLMoleculeObject(mesh, parent),
     66#include "GLMoleculeObject_atom.hpp"
     67
     68static QGLSceneNode *createMoleculeMesh(const molecule *molref, QObject *parent)
     69{
     70//  Shape shape = molref->getBoundingSphere();
     71  double minradius = 2.; // TODO: set to maximum bond length value
     72  LOG(3, "DEBUG: Molecule fits into sphere of radius " << minradius);
     73  if (minradius < 1.)
     74    minradius = 1.;
     75
     76  QGeometryData geo;
     77  // we need at least three points for tesselation
     78  if (molref->getAtomCount() >= 3) {
     79    // Tesselate the points.
     80    Tesselation T;
     81    PointCloudAdaptor<molecule> cloud(const_cast<molecule *>(molref), molref->getName());
     82    T(cloud, minradius);
     83
     84    // Fill the points into a Qt geometry.
     85    LinkedCell_deprecated LinkedList(cloud, minradius);
     86    std::map<int, int> indices;
     87    std::map<int, Vector> normals;
     88    int index = 0;
     89    for (PointMap::const_iterator piter = T.PointsOnBoundary.begin();
     90        piter != T.PointsOnBoundary.end(); ++piter) {
     91      const Vector &point = piter->second->getPosition();
     92      // add data to the primitive
     93      geo.appendVertex(QVector3D(point[0], point[1], point[2]));
     94      Vector normalvector;
     95      for (LineMap::const_iterator lineiter = piter->second->lines.begin();
     96          lineiter != piter->second->lines.end(); ++lineiter)
     97        for (TriangleMap::const_iterator triangleiter = lineiter->second->triangles.begin();
     98            triangleiter != lineiter->second->triangles.end(); ++triangleiter)
     99          normalvector +=
     100              triangleiter->second->NormalVector;
     101      normalvector.Normalize();
     102      geo.appendNormal(QVector3D(normalvector[0], normalvector[1], normalvector[2]));
     103      geo.appendColor(QColor(1, 1, 1, 1));
     104      geo.appendTexCoord(QVector2D(0, 0));
     105      indices.insert( std::make_pair( piter->second->getNr(), index++));
     106    }
     107
     108    // Fill the tesselated triangles into the geometry.
     109    for (TriangleMap::const_iterator runner = T.TrianglesOnBoundary.begin();
     110        runner != T.TrianglesOnBoundary.end(); runner++) {
     111      int v[3];
     112      for (size_t i=0; i<3; ++i)
     113        v[i] = runner->second->endpoints[i]->getNr();
     114
     115      // Sort the vertices so the triangle is clockwise (relative to the normal vector).
     116      Vector cross = T.PointsOnBoundary[v[1]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition();
     117      cross.VectorProduct(T.PointsOnBoundary[v[2]]->getPosition() - T.PointsOnBoundary[v[0]]->getPosition());
     118      if (cross.ScalarProduct(runner->second->NormalVector) > 0)
     119        geo.appendIndices(indices[v[0]], indices[v[1]], indices[v[2]]);
     120      else
     121        geo.appendIndices(indices[v[0]], indices[v[2]], indices[v[1]]);
     122    }
     123  }
     124
     125  // Build a mesh from the geometry.
     126  QGLBuilder builder;
     127  builder.addTriangles(geo);
     128  QGLSceneNode *mesh = builder.finalizedSceneNode();
     129  return mesh;
     130}
     131
     132GLMoleculeObject_molecule::GLMoleculeObject_molecule(QObject *parent, const molecule *molref) :
     133  GLMoleculeObject(createMoleculeMesh(molref, parent), parent),
    60134  Observer(std::string("GLMoleculeObject_molecule")+toString(molref->getId())),
    61   _molecule(molref)
     135  isBoundingBoxUptodate(true),
     136  isSignedOn(false),
     137  _molecule(molref),
     138  TesselationHullUptodate(true),
     139  hoverAtom(NULL)
    62140{
    63141  // sign on as observer (obtain non-const instance before)
     142  _molecule->signOn(this, molecule::AtomInserted);
     143  _molecule->signOn(this, molecule::AtomRemoved);
     144  _molecule->signOn(this, molecule::AtomMoved);
     145  isSignedOn = true;
    64146  /*molref->signOn(this, AtomObservable::IndexChanged);
    65147  molref->signOn(this, AtomObservable::PositionChanged);
     
    69151  World::getInstance().signOn(this, World::SelectionChanged);
    70152  updateBoundingBox();
     153
     154  // initially, atoms and bonds should be visible
     155  m_visible = false;
     156
     157  init();
     158
     159  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     160  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     161
     162  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
     163}
     164
     165GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const molecule *molref) :
     166  GLMoleculeObject(mesh, parent),
     167  Observer(std::string("GLMoleculeObject_molecule")+toString(molref->getId())),
     168  isBoundingBoxUptodate(true),
     169  isSignedOn(false),
     170  _molecule(molref),
     171  TesselationHullUptodate(true),
     172  hoverAtom(NULL)
     173{
     174  // sign on as observer (obtain non-const instance before)
     175  _molecule->signOn(this, molecule::AtomInserted);
     176  _molecule->signOn(this, molecule::AtomRemoved);
     177  _molecule->signOn(this, molecule::AtomMoved);
     178  isSignedOn = true;
     179  /*molref->signOn(this, AtomObservable::IndexChanged);
     180  molref->signOn(this, AtomObservable::PositionChanged);
     181  molref->signOn(this, AtomObservable::ElementChanged);
     182  molref->signOn(this, AtomObservable::BondsAdded);*/
     183  setMaterial(getMaterial(1));
     184  World::getInstance().signOn(this, World::SelectionChanged);
     185  updateBoundingBox();
     186
     187  // initially, atoms and bonds should be visible
     188  m_visible = false;
     189
     190  init();
     191
     192  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     193  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     194
     195  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
    71196}
    72197
    73198GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
    74199{
     200  if (isSignedOn) {
     201    _molecule->signOff(this, molecule::AtomInserted);
     202    _molecule->signOff(this, molecule::AtomRemoved);
     203    _molecule->signOff(this, molecule::AtomMoved);
     204  }
    75205  /*_atom->signOff(this, AtomObservable::IndexChanged);
    76206  _atom->signOff(this, AtomObservable::PositionChanged);
     
    80210}
    81211
     212/** Initialise the WorldScene with molecules and atoms from World.
     213 *
     214 */
     215void GLMoleculeObject_molecule::init()
     216{
     217  if (_molecule->begin() != _molecule->end()) {
     218    int atomicid = -1;
     219    for (molecule::const_iterator atomiter = _molecule->begin();
     220        atomiter != _molecule->end();
     221        atomiter++) {
     222      // create atom objects in scene
     223      atomicid = (*atomiter)->getId();
     224      atomInserted(atomicid);
     225
     226      // create bond objects in scene
     227      const BondList &bondlist = (*atomiter)->getListOfBonds();
     228      for (BondList::const_iterator bonditer = bondlist.begin();
     229          bonditer != bondlist.end();
     230          ++bonditer) {
     231        const bond::ptr _bond = *bonditer;
     232        const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == *atomiter) ?
     233            GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
     234        bondInserted(_bond, side);
     235      }
     236    }
     237    // set id to one of the atom's as either mol or atoms is present at the same time
     238    setObjectId(atomicid);
     239  }
     240}
     241
     242void GLMoleculeObject_molecule::addAtomBonds(
     243    const bond::ptr &_bond,
     244    const GLMoleculeObject_bond::SideOfBond _side
     245    )
     246{
     247  bool bond_present = false;
     248  const BondIds ids = getBondIds(_bond, _side);
     249  // check whether bond is not present already
     250  bond_present = BondsinSceneMap.count(ids);
     251  if (!bond_present)
     252    bondInserted(_bond, _side);
     253  else {
     254    BondsinSceneMap[ids]->resetPosition();
     255    BondsinSceneMap[ids]->resetWidth();
     256  }
     257}
     258
     259void GLMoleculeObject_molecule::addAtomBonds(
     260    const atom *_atom)
     261{
     262  const bool atom_present = AtomsinSceneMap.count(_atom->getId());
     263  const BondList &bondlist = _atom->getListOfBonds();
     264  for (BondList::const_iterator bonditer = bondlist.begin();
     265      (bonditer != bondlist.end()) && atom_present;
     266      ++bonditer) {
     267    const bond::ptr _bond = *bonditer;
     268    // check if OtherAtom's sphere is already present
     269    const atom *OtherAtom = _bond->GetOtherAtom(_atom);
     270    const bool otheratom_present = AtomsinSceneMap.count(OtherAtom->getId());
     271    if (otheratom_present && atom_present) {
     272      const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == _atom) ?
     273          GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
     274      const GLMoleculeObject_bond::SideOfBond otherside = (_bond->leftatom == _atom) ?
     275          GLMoleculeObject_bond::right : GLMoleculeObject_bond::left;
     276      addAtomBonds(_bond, side);
     277      addAtomBonds(_bond, otherside);
     278    }
     279  }
     280}
     281
     282void GLMoleculeObject_molecule::reinit()
     283{
     284  if (_molecule->getAtomCount() > 0) {
     285    for (molecule::const_iterator atomiter = _molecule->begin();
     286        atomiter != _molecule->end();
     287        atomiter++) {
     288      // check whether atom already exists
     289      const atomId_t atomid = (*atomiter)->getId();
     290      const bool atom_present = AtomsinSceneMap.count(atomid);
     291      if (!atom_present)
     292        atomInserted((*atomiter)->getId());
     293      else
     294        AtomsinSceneMap[atomid]->resetPosition();
     295
     296
     297      // create bond objects in scene
     298      addAtomBonds(*atomiter);
     299    }
     300  }
     301}
     302
    82303void GLMoleculeObject_molecule::updateBoundingBox()
    83304{
     305  isBoundingBoxUptodate = true;
    84306  Shape shape = _molecule->getBoundingSphere();
    85307  Vector v = shape.getCenter();
     
    97319
    98320void GLMoleculeObject_molecule::subjectKilled(Observable *publisher)
    99 {}
     321{
     322  isSignedOn = false;
     323}
    100324
    101325void GLMoleculeObject_molecule::recieveNotification(Observable *publisher, Notification_ptr notification)
     
    108332          << notification->getChannelNo() << ".";
    109333#endif
     334    switch (notification->getChannelNo()) {
     335      case molecule::AtomInserted:
     336      {
     337        const atomId_t _id = _molecule->lastChanged()->getId();
     338  #ifdef LOG_OBSERVER
     339        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
     340  #endif
     341        TesselationHullUptodate = false;
     342        isBoundingBoxUptodate = false;
     343        atomInserted(_id);
     344        break;
     345      }
     346      case World::AtomRemoved:
     347      {
     348        const atomId_t _id = _molecule->lastChanged()->getId();
     349  #ifdef LOG_OBSERVER
     350        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
     351  #endif
     352        TesselationHullUptodate = false;
     353        isBoundingBoxUptodate = false;
     354        atomRemoved(_id);
     355        break;
     356      }
     357      case molecule::AtomMoved:
     358      {
     359  #ifdef LOG_OBSERVER
     360        const atomId_t _id = _molecule->lastChanged()->getId();
     361        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
     362  #endif
     363        TesselationHullUptodate = false;
     364        isBoundingBoxUptodate = false;
     365        break;
     366      }
     367      default:
     368        break;
     369    }
    110370  }else{
    111371    // notification from world
     
    125385}
    126386
     387void GLMoleculeObject_molecule::initialize(QGLView *view, QGLPainter *painter)
     388{
     389  // Initialize all of the mesh objects that we have as children.
     390  if (m_visible) {
     391    GLMoleculeObject::initialize(view, painter);
     392  } else {
     393   foreach (QObject *obj, children()) {
     394     GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     395       if (meshobj)
     396         meshobj->initialize(view, painter);
     397   }
     398  }
     399}
     400
     401void GLMoleculeObject_molecule::draw(QGLPainter *painter, const QVector4D &cameraPlane)
     402{
     403  // draw either molecule's mesh or all atoms and bonds
     404  if (m_visible) {
     405    updateTesselationHull();
     406
     407    painter->modelViewMatrix().push();
     408
     409    // Apply the material and effect to the painter.
     410    QGLMaterial *material;
     411    if (m_hovering)
     412        material = m_hoverMaterial;
     413    else if (m_selected)
     414        material = m_selectionMaterial;
     415    else
     416        material = m_material;
     417
     418    ASSERT(material, "GLMoleculeObject::draw: chosen material is NULL");
     419
     420    painter->setColor(material->diffuseColor());
     421    painter->setFaceMaterial(QGL::AllFaces, material);
     422    if (m_effect)
     423        painter->setUserEffect(m_effect);
     424    else
     425        painter->setStandardEffect(QGL::LitMaterial);
     426
     427    // Mark the object for object picking purposes.
     428    int prevObjectId = painter->objectPickId();
     429    if (m_objectId != -1)
     430        painter->setObjectPickId(m_objectId);
     431
     432    m_mesh[0]->draw(painter);
     433
     434    // Turn off the user effect, if present.
     435    if (m_effect)
     436        painter->setStandardEffect(QGL::LitMaterial);
     437
     438    // Revert to the previous object identifier.
     439    painter->setObjectPickId(prevObjectId);
     440
     441    // Restore the modelview matrix.
     442    painter->modelViewMatrix().pop();
     443
     444    //    GLMoleculeObject::draw(painter, cameraPlane);
     445  } else {
     446    // Draw all of the mesh objects that we have as children.
     447    foreach (QObject *obj, children()) {
     448      GLMoleculeObject *meshobj = qobject_cast<GLMoleculeObject *>(obj);
     449      if (meshobj)
     450        meshobj->draw(painter, cameraPlane);
     451    }
     452
     453    // update bounding box prior to selection
     454    if (!isBoundingBoxUptodate)
     455      updateBoundingBox();
     456
     457    painter->modelViewMatrix().push();
     458    painter->modelViewMatrix().translate(m_position);
     459    if ((m_scaleX != 1.0f) || (m_scaleY != 1.0f) || (m_scaleZ != 1.0f))
     460      painter->modelViewMatrix().scale(m_scaleX, m_scaleY, m_scaleZ);
     461    if (m_rotationAngle != 0.0f)
     462      painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
     463
     464    // Draw a box around the mesh, if selected.
     465    if (m_selected)
     466      drawSelectionBox(painter);
     467
     468    // Restore the modelview matrix.
     469    painter->modelViewMatrix().pop();
     470  }
     471}
     472
     473/** Adds an atom of this molecule to the scene.
     474 *
     475 * @param _atom atom to add
     476 */
     477void GLMoleculeObject_molecule::atomInserted(const atomicNumber_t _id)
     478{
     479  LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "+toString(_id)+".");
     480  GLMoleculeObject_atom *atomObject = new GLMoleculeObject_atom(GLMoleculeObject::meshSphere, this, _id);
     481  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
     482  ASSERT(iter == AtomsinSceneMap.end(),
     483      "GLWorldScene::atomAdded() - same atom with id "+toString(_id)+" added again.");
     484  AtomsinSceneMap.insert( make_pair(_id, atomObject) );
     485
     486  qRegisterMetaType<atomId_t>("atomId_t");
     487  qRegisterMetaType<bond::ptr>("bond::ptr");
     488  qRegisterMetaType<GLMoleculeObject_bond::SideOfBond>("GLMoleculeObject_bond::SideOfBond");
     489  connect (atomObject, SIGNAL(clicked(atomId_t)), this, SIGNAL(atomClicked(atomId_t)));
     490  connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
     491  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     492  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     493  connect (atomObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
     494  connect (atomObject, SIGNAL(BondsInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)));
     495  connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, int, int)), this, SIGNAL(changeAtomId(GLMoleculeObject_atom*, int, int)));
     496
     497  isBoundingBoxUptodate = false;
     498
     499  if (m_objectId  == -1)
     500    setObjectId(_id);
     501
     502  // add all bonds
     503  const atom *Walker = World::getInstance().getAtom(AtomById(_id));
     504  addAtomBonds(Walker);
     505
     506  emit changeOccured();
     507}
     508
     509/** Removes an atom of this molecule from the scene.
     510 *
     511 * We just the id as the atom might have already been destroyed.
     512 *
     513 * @param _id id of atom to remove
     514 */
     515void GLMoleculeObject_molecule::atomRemoved(const atomicNumber_t _id)
     516{
     517  LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_id)+".");
     518  // bonds are removed by signal coming from ~bond
     519
     520  if (m_objectId == _id)
     521    setObjectId(-1);
     522
     523  // remove atoms
     524  AtomNodeMap::iterator iter = AtomsinSceneMap.find(_id);
     525  ASSERT(iter != AtomsinSceneMap.end(),
     526      "GLWorldScene::atomRemoved() - atom "+toString(_id)+" not on display.");
     527  GLMoleculeObject_atom *atomObject = iter->second;
     528  atomObject->disconnect();
     529  AtomsinSceneMap.erase(iter);
     530  delete atomObject;
     531
     532  isBoundingBoxUptodate = false;
     533
     534  emit changeOccured();
     535}
     536
     537void GLMoleculeObject_molecule::hoverChangedSignalled(GLMoleculeObject *ob)
     538{
     539  // Find the atom, ob corresponds to.
     540  hoverAtom = NULL;
     541  GLMoleculeObject_atom *atomObject = dynamic_cast<GLMoleculeObject_atom *>(ob);
     542  if (atomObject){
     543    for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
     544      if (iter->second == atomObject)
     545        hoverAtom = World::getInstance().getAtom(AtomById(iter->first));
     546    }
     547
     548    // Propagate signal.
     549    emit hoverChanged(*hoverAtom);
     550  } else {
     551    // Find the atom, ob corresponds to.
     552    GLMoleculeObject_molecule *moleculeObject = dynamic_cast<GLMoleculeObject_molecule *>(ob);
     553    if (moleculeObject == this){
     554      // Propagate signal.
     555      emit hoverChanged(*_molecule, 0);
     556    }
     557  }
     558}
     559
     560
     561/** Helper function to get bond ids in the correct order for BondNodeMap.
     562 *
     563 * \return pair of ids in correct order.
     564 */
     565GLMoleculeObject_molecule::BondIds GLMoleculeObject_molecule::getBondIds(
     566    const bond::ptr _bond,
     567    const enum GLMoleculeObject_bond::SideOfBond _side)
     568{
     569  BondIds ids;
     570  switch (_side) {
     571    case GLMoleculeObject_bond::left:
     572      ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
     573      break;
     574    case GLMoleculeObject_bond::right:
     575      ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
     576      break;
     577  }
     578  return ids;
     579}
     580
     581/** Adds a bond to the scene.
     582 *
     583 * @param _bond bond to add
     584 * @param side which side of the bond (left or right)
     585 */
     586void GLMoleculeObject_molecule::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
     587{
     588  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
     589  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
     590
     591  const BondIds ids = getBondIds(_bond, _side);
     592  BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
     593  if (iter == BondsinSceneMap.end()) {
     594    GLMoleculeObject_bond * bondObject =
     595        new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, _bond, _side);
     596    connect (
     597        bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
     598        this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
     599    connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
     600    BondsinSceneMap.insert( make_pair(ids, bondObject) );
     601  //    BondIdsinSceneMap.insert( Leftids );
     602  } else {
     603    iter->second->resetPosition();
     604    iter->second->resetWidth();
     605  }
     606  emit changeOccured();
     607}
     608
     609/** Removes a bond from the scene.
     610 *
     611 * @param _bond bond to remove
     612 */
     613void GLMoleculeObject_molecule::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
     614{
     615  LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
     616  {
     617    // left bond
     618    const BondIds Leftids( make_pair(leftnr, rightnr) );
     619    BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
     620    ASSERT(leftiter != BondsinSceneMap.end(),
     621        "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
     622        +toString(rightnr)+" not on display.");
     623    GLMoleculeObject_bond *bondObject = leftiter->second;
     624    bondObject->disconnect();
     625    BondsinSceneMap.erase(leftiter);
     626    delete bondObject; // is done by signal from bond itself
     627    //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
     628  }
     629
     630  emit changeOccured();
     631}
     632
     633void GLMoleculeObject_molecule::setVisible(bool value)
     634{
     635  // first update the mesh if we are going to be visible now
     636  if (value)
     637    updateTesselationHull();
     638  // then emit onward
     639  GLMoleculeObject::setVisible(value);
     640}
     641
     642void GLMoleculeObject_molecule::updateTesselationHull()
     643{
     644  if (!TesselationHullUptodate) {
     645    updateMesh(createMoleculeMesh(_molecule, parent()));
     646    TesselationHullUptodate = true;
     647  }
     648}
     649
     650std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t)
     651{
     652  ost << t.first << "," << t.second;
     653  return ost;
     654}
     655
     656void GLMoleculeObject_molecule::wasClicked()
     657{
     658  LOG(4, "INFO: GLMoleculeObject_molecule: atom " << _molecule->getId() << " has been clicked");
     659  emit moleculeClicked(_molecule->getId());
     660}
Note: See TracChangeset for help on using the changeset viewer.