Changeset 6c16a0 for src


Ignore:
Timestamp:
Aug 5, 2015, 5:32:08 PM (9 years ago)
Author:
Frederik Heber <heber@…>
Branches:
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
Children:
20f9b5
Parents:
3e52834
git-author:
Frederik Heber <heber@…> (06/21/15 12:16:19)
git-committer:
Frederik Heber <heber@…> (08/05/15 17:32:08)
Message:

GLMoleculeObject_molecule uses ObservedValue for internally representing atom's state.

Location:
src/UIElements/Views/Qt4/Qt3D
Files:
2 edited

Legend:

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

    r3e52834 r6c16a0  
    4444
    4545#include "CodePatterns/MemDebug.hpp"
     46
     47#include <boost/assign.hpp>
    4648
    4749#include "CodePatterns/Assert.hpp"
     
    6567#include "World.hpp"
    6668
     69using namespace boost::assign;
     70
    6771#include "GLMoleculeObject_atom.hpp"
    6872
    69 static QGLSceneNode *createMoleculeMesh(const moleculeId_t molid, QObject *parent)
    70 {
    71   const molecule *molref = const_cast<const World &>(World::getInstance()).
    72       getMolecule(MoleculeById(molid));
     73static Observable::channels_t getAtomsChannels()
     74{
     75  Observable::channels_t channels;
     76  channels += molecule::AtomInserted, molecule::AtomRemoved;
     77  return channels;
     78}
     79
     80static Observable::channels_t getAllAtomicChangesChannels()
     81{
     82  Observable::channels_t channels;
     83  channels += molecule::AtomInserted, molecule::AtomRemoved, molecule::AtomMoved;
     84  return channels;
     85}
     86
     87// static instances
     88const Observable::channels_t GLMoleculeObject_molecule::AtomsChannels(getAtomsChannels());
     89const Observable::channels_t GLMoleculeObject_molecule::HullChannels(getAllAtomicChangesChannels());
     90const Observable::channels_t GLMoleculeObject_molecule::BoundingBoxChannels(getAllAtomicChangesChannels());
     91const Observable::channels_t GLMoleculeObject_molecule::IndexChannels(1, molecule::IndexChanged);
     92
     93static QGLSceneNode *createMoleculeMesh(const QGeometryData &_geo)
     94{
     95  // Build a mesh from the geometry.
     96  QGLBuilder builder;
     97  builder.addTriangles(_geo);
     98  QGLSceneNode *mesh = builder.finalizedSceneNode();
     99  return mesh;
     100}
     101
     102GLMoleculeObject_molecule::GLMoleculeObject_molecule(QObject *parent, const moleculeId_t _molid) :
     103  GLMoleculeObject((QGLSceneNode *)NULL, parent),
     104  Observer(std::string("GLMoleculeObject_molecule")+toString(_molid)),
     105  owner(NULL),
     106  molref(getMolecule(_molid)),
     107  /* We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
     108   * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
     109   * the class has not been fully constructed yet. "This" itself seems to be working fine.
     110   */
     111  MolIndexUpdater(
     112      boost::bind(&GLMoleculeObject_molecule::updateIndex, this)
     113      ),
     114  TesselationHullUpdater(
     115      boost::bind(&GLMoleculeObject_molecule::updateTesselationHull, this)
     116      ),
     117  IsSelectedUpdater(
     118      boost::bind(&GLMoleculeObject_molecule::updateIsSelected, this)
     119      ),
     120  BoundingBoxUpdater(
     121      boost::bind(&GLMoleculeObject_molecule::updateBoundingBox, this)
     122      ),
     123  PresentAtomsUpdater(
     124      boost::bind(&GLMoleculeObject_molecule::updateAtoms, this)
     125      ),
     126  MolIndex(
     127      molref,
     128      MolIndexUpdater,
     129      "MoleculeIndex_"+toString(_molid),
     130      _molid,
     131      IndexChannels),
     132  TesselationHull(
     133      molref,
     134      TesselationHullUpdater,
     135      "MoleculeTesselationHull_"+toString(_molid),
     136      HullChannels),
     137  isSelected(
     138      const_cast<const World * const>(World::getPointer()),
     139      IsSelectedUpdater,
     140      "MoleculeBoundingBox_"+toString(_molid),
     141      updateIsSelected(),
     142      BoundingBoxChannels),
     143  BoundingBox(
     144      molref,
     145      BoundingBoxUpdater,
     146      "MoleculeBoundingBox_"+toString(_molid),
     147      updateBoundingBox(),
     148      BoundingBoxChannels),
     149  PresentAtoms(
     150      molref,
     151      PresentAtomsUpdater,
     152      "MoleculeAtoms_"+toString(_molid),
     153      updateAtoms(),
     154      AtomsChannels),
     155  hoverAtomId(-1)
     156{
     157  setObjectId(_molid);
     158  setMaterial(getMaterial(1));
     159
     160  // initially, atoms and bonds should be visible
     161  m_visible = false;
     162
     163  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     164  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     165  connect (this, SIGNAL(TesselationHullChanged()), this, SLOT(resetTesselationHull()), Qt::QueuedConnection);
     166  connect (this, SIGNAL(BoundingBoxChanged()), this, SLOT(resetBoundingBox()), Qt::QueuedConnection);
     167  connect (this, SIGNAL(IsSelectedChanged()), this, SLOT(resetIsSelected()), Qt::QueuedConnection);
     168  connect (this, SIGNAL(IdChanged()), this, SLOT(resetIndex()), Qt::QueuedConnection);
     169  connect (this, SIGNAL(AtomInserted(const atomId_t)), this, SLOT(atomInserted(const atomId_t)), Qt::QueuedConnection);
     170  connect (this, SIGNAL(AtomInserted(const atomId_t)), this, SLOT(resetAtoms()), Qt::QueuedConnection);
     171  connect (this, SIGNAL(AtomRemoved(const atomId_t)), this, SLOT(resetAtoms()), Qt::QueuedConnection);
     172  connect (this, SIGNAL(AtomRemoved(const atomId_t)), this, SLOT(atomRemoved(const atomId_t)), Qt::QueuedConnection);
     173
     174  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
     175}
     176
     177GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const moleculeId_t _molid) :
     178  GLMoleculeObject(mesh, parent),
     179  Observer(std::string("GLMoleculeObject_molecule")+toString(_molid)),
     180  owner(NULL),
     181  molref(getMolecule(_molid)),
     182  /* We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
     183   * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
     184   * the class has not been fully constructed yet. "This" itself seems to be working fine.
     185   */
     186  MolIndexUpdater(
     187      boost::bind(&GLMoleculeObject_molecule::updateIndex, this)
     188      ),
     189  TesselationHullUpdater(
     190      boost::bind(&GLMoleculeObject_molecule::updateTesselationHull, this)
     191      ),
     192  IsSelectedUpdater(
     193      boost::bind(&GLMoleculeObject_molecule::updateIsSelected, this)
     194      ),
     195  BoundingBoxUpdater(
     196      boost::bind(&GLMoleculeObject_molecule::updateBoundingBox, this)
     197      ),
     198  PresentAtomsUpdater(
     199      boost::bind(&GLMoleculeObject_molecule::updateAtoms, this)
     200      ),
     201  MolIndex(
     202      molref,
     203      MolIndexUpdater,
     204      "MoleculeIndex_"+toString(_molid),
     205      _molid,
     206      IndexChannels),
     207  TesselationHull(
     208      molref,
     209      TesselationHullUpdater,
     210      "MoleculeTesselationHull_"+toString(_molid),
     211      HullChannels),
     212  isSelected(
     213      const_cast<const World * const>(World::getPointer()),
     214      IsSelectedUpdater,
     215      "MoleculeBoundingBox_"+toString(_molid),
     216      updateIsSelected(),
     217      BoundingBoxChannels),
     218  BoundingBox(
     219      molref,
     220      BoundingBoxUpdater,
     221      "MoleculeBoundingBox_"+toString(_molid),
     222      updateBoundingBox(),
     223      BoundingBoxChannels),
     224  PresentAtoms(
     225      molref,
     226      PresentAtomsUpdater,
     227      "MoleculeAtoms_"+toString(_molid),
     228      atoms_t(),
     229      AtomsChannels),
     230  hoverAtomId(-1)
     231{
     232  setObjectId(_molid);
     233  setMaterial(getMaterial(1));
     234
     235  // initially, atoms and bonds should be visible
     236  m_visible = false;
     237
     238  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
     239  connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
     240  connect (this, SIGNAL(TesselationHullChanged()), this, SLOT(resetTesselationHull()), Qt::QueuedConnection);
     241  connect (this, SIGNAL(BoundingBoxChanged()), this, SLOT(resetBoundingBox()), Qt::QueuedConnection);
     242  connect (this, SIGNAL(IsSelectedChanged()), this, SLOT(resetIsSelected()), Qt::QueuedConnection);
     243  connect (this, SIGNAL(IdChanged()), this, SLOT(resetIndex()), Qt::QueuedConnection);
     244  connect (this, SIGNAL(AtomInserted(const atomId_t)), this, SLOT(atomInserted(const atomId_t)), Qt::QueuedConnection);
     245  connect (this, SIGNAL(AtomInserted(const atomId_t)), this, SLOT(resetAtoms()), Qt::QueuedConnection);
     246  connect (this, SIGNAL(AtomRemoved(const atomId_t)), this, SLOT(resetAtoms()), Qt::QueuedConnection);
     247  connect (this, SIGNAL(AtomRemoved(const atomId_t)), this, SLOT(atomRemoved(const atomId_t)), Qt::QueuedConnection);
     248
     249  connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
     250}
     251
     252GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
     253{
     254  deactivateObserver();
     255}
     256
     257void GLMoleculeObject_molecule::deactivateObserver()
     258{
     259  if (owner != NULL) {
     260    owner->signOff(this, molecule::AtomInserted);
     261    owner->signOff(this, molecule::AtomRemoved);
     262    owner->signOff(this, molecule::AtomMoved);
     263    owner->signOff(this, molecule::IndexChanged);
     264    /*_atom->signOff(this, AtomObservable::IndexChanged);
     265    _atom->signOff(this, AtomObservable::PositionChanged);
     266    _atom->signOff(this, AtomObservable::ElementChanged);
     267    _atom->signOff(this, AtomObservable::BondsAdded);*/
     268    World::getInstance().signOff(this, World::SelectionChanged);
     269    owner = NULL;
     270  }
     271}
     272
     273void GLMoleculeObject_molecule::activateObserver()
     274{
     275  // sign on as observer (obtain non-const instance before)
     276  const molecule * const _molecule = getMolecule(MolIndex.get());
     277  if (_molecule != NULL) {
     278    owner = static_cast<const Observable *>(_molecule);
     279    owner->signOn(this, molecule::AtomInserted);
     280    owner->signOn(this, molecule::AtomRemoved);
     281    owner->signOn(this, molecule::AtomMoved);
     282    owner->signOn(this, molecule::IndexChanged);
     283    /*molref->signOn(this, AtomObservable::IndexChanged);
     284    molref->signOn(this, AtomObservable::PositionChanged);
     285    molref->signOn(this, AtomObservable::ElementChanged);
     286    molref->signOn(this, AtomObservable::BondsAdded);*/
     287    World::getInstance().signOn(this, World::SelectionChanged);
     288  } else {
     289    ELOG(1, "GLMoleculeObject_molecule() - added null object for not present mol id " << MolIndex.get());
     290  }
     291
     292}
     293
     294void GLMoleculeObject_molecule::addAtomBonds(
     295    const bond::ptr &_bond,
     296    const GLMoleculeObject_bond::SideOfBond _side
     297    )
     298{
     299  bool bond_present = false;
     300  const BondIds ids = getBondIds(_bond, _side);
     301  // check whether bond is not present already
     302  bond_present = BondsinSceneMap.count(ids);
     303  if (!bond_present)
     304    bondInserted(ids.first, ids.second, _side);
     305  else {
     306    BondsinSceneMap[ids]->resetPosition();
     307    BondsinSceneMap[ids]->resetWidth();
     308  }
     309}
     310
     311void GLMoleculeObject_molecule::addAtomBonds(
     312    const atom *_atom)
     313{
     314  const bool atom_present = AtomsinSceneMap.count(_atom->getId());
     315  const BondList &bondlist = _atom->getListOfBonds();
     316  for (BondList::const_iterator bonditer = bondlist.begin();
     317      (bonditer != bondlist.end()) && atom_present;
     318      ++bonditer) {
     319    const bond::ptr _bond = *bonditer;
     320    // check if OtherAtom's sphere is already present
     321    const atom *OtherAtom = _bond->GetOtherAtom(_atom);
     322    const bool otheratom_present = AtomsinSceneMap.count(OtherAtom->getId());
     323    if (otheratom_present && atom_present) {
     324      const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == _atom) ?
     325          GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
     326      const GLMoleculeObject_bond::SideOfBond otherside = (_bond->leftatom == _atom) ?
     327          GLMoleculeObject_bond::right : GLMoleculeObject_bond::left;
     328      addAtomBonds(_bond, side);
     329      addAtomBonds(_bond, otherside);
     330    }
     331  }
     332}
     333
     334QGeometryData GLMoleculeObject_molecule::updateTesselationHull() const
     335{
     336  QGeometryData geo;
     337
     338  const molecule * const molref = getMolecule(MolIndex.get());
    73339  if (molref == NULL) {
    74     ELOG(1, "Could not createMoleculeMesh, molecule with id " << molid << " already gone.");
    75     return NULL;
    76   }
    77 //  Shape shape = molref->getBoundingSphere();
     340    ELOG(1, "Could not createMoleculeMesh, molecule with id " << MolIndex.get() << " already gone.");
     341    return geo;
     342  }
    78343  double minradius = 2.; // TODO: set to maximum bond length value
    79344  LOG(3, "DEBUG: Molecule fits into sphere of radius " << minradius);
    80345  // check minimum bond radius in molecule
    81   double minlength = std::numeric_limits<double>::max(); 
     346  double minlength = std::numeric_limits<double>::max();
    82347  for (molecule::const_iterator iter = molref->begin();
    83348      iter != molref->end(); ++iter) {
     
    91356  minradius = std::max( std::max(minradius, minlength), 1.);
    92357
    93   QGeometryData geo;
    94358  // we need at least three points for tesselation
    95359  if (molref->getAtomCount() >= 3) {
     
    140404  }
    141405
    142   // Build a mesh from the geometry.
    143   QGLBuilder builder;
    144   builder.addTriangles(geo);
    145   QGLSceneNode *mesh = builder.finalizedSceneNode();
    146   return mesh;
    147 }
    148 
    149 GLMoleculeObject_molecule::GLMoleculeObject_molecule(QObject *parent, const moleculeId_t molid) :
    150   GLMoleculeObject(createMoleculeMesh(molid, parent), parent),
    151   Observer(std::string("GLMoleculeObject_molecule")+toString(molid)),
    152   isBoundingBoxUptodate(true),
    153   isSignedOn(false),
    154   moleculeid(molid),
    155   TesselationHullUptodate(true),
    156   hoverAtomId(-1)
    157 {
    158   setMaterial(getMaterial(1));
    159   updateBoundingBox();
    160 
    161   // initially, atoms and bonds should be visible
    162   m_visible = false;
    163 
    164   connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
    165   connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
    166 
    167   connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
    168 }
    169 
    170 GLMoleculeObject_molecule::GLMoleculeObject_molecule(QGLSceneNode *mesh[], QObject *parent, const moleculeId_t molid) :
    171   GLMoleculeObject(mesh, parent),
    172   Observer(std::string("GLMoleculeObject_molecule")+toString(molid)),
    173   isBoundingBoxUptodate(true),
    174   isSignedOn(false),
    175   moleculeid(molid),
    176   TesselationHullUptodate(true),
    177   hoverAtomId(-1)
    178 {
    179   setMaterial(getMaterial(1));
    180   updateBoundingBox();
    181 
    182   // initially, atoms and bonds should be visible
    183   m_visible = false;
    184 
    185   connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
    186   connect (this, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
    187 
    188   connect( this, SIGNAL(clicked()), this, SLOT(wasClicked()));
    189 }
    190 
    191 GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
    192 {
    193   if (isSignedOn) {
    194     const molecule *_molecule = const_cast<const World &>(World::getInstance()).
    195         getMolecule(MoleculeById(moleculeid));
    196     if (_molecule != NULL) {
    197       _molecule->signOff(this, molecule::AtomInserted);
    198       _molecule->signOff(this, molecule::AtomRemoved);
    199       _molecule->signOff(this, molecule::AtomMoved);
    200     } else {
    201       ELOG(1, "GLMoleculeObject_molecule cannot sign off, molecule with "
    202           << moleculeid << " has disappeared.");
    203     }
    204   }
    205   /*_atom->signOff(this, AtomObservable::IndexChanged);
    206   _atom->signOff(this, AtomObservable::PositionChanged);
    207   _atom->signOff(this, AtomObservable::ElementChanged);
    208   _atom->signOff(this, AtomObservable::BondsAdded);*/
    209   World::getInstance().signOff(this, World::SelectionChanged);
    210 }
    211 
    212 void GLMoleculeObject_molecule::activateObserver()
    213 {
    214   // sign on as observer (obtain non-const instance before)
    215   const molecule *_molecule = const_cast<const World &>(World::getInstance()).
    216       getMolecule(MoleculeById(moleculeid));
     406  return geo;
     407}
     408
     409bool GLMoleculeObject_molecule::updateIsSelected() const
     410{
     411  return const_cast<const World &>(World::getInstance()).isMoleculeSelected(MolIndex.get());
     412}
     413
     414GLMoleculeObject_molecule::BoundingBoxInfo GLMoleculeObject_molecule::updateBoundingBox() const
     415{
     416  BoundingBoxInfo info;
     417  const molecule * const _molecule = getMolecule(MolIndex.get());
    217418  if (_molecule != NULL) {
    218     _molecule->signOn(this, molecule::AtomInserted);
    219     _molecule->signOn(this, molecule::AtomRemoved);
    220     _molecule->signOn(this, molecule::AtomMoved);
    221     isSignedOn = true;
    222   } else {
    223     ELOG(1, "GLMoleculeObject_molecule() - added null object for not present mol id " << moleculeid);
    224   }
    225   /*molref->signOn(this, AtomObservable::IndexChanged);
    226   molref->signOn(this, AtomObservable::PositionChanged);
    227   molref->signOn(this, AtomObservable::ElementChanged);
    228   molref->signOn(this, AtomObservable::BondsAdded);*/
    229   World::getInstance().signOn(this, World::SelectionChanged);
    230 }
    231 
    232 void GLMoleculeObject_molecule::addAtomBonds(
    233     const bond::ptr &_bond,
    234     const GLMoleculeObject_bond::SideOfBond _side
    235     )
    236 {
    237   bool bond_present = false;
    238   const BondIds ids = getBondIds(_bond, _side);
    239   // check whether bond is not present already
    240   bond_present = BondsinSceneMap.count(ids);
    241   if (!bond_present)
    242     bondInserted(_bond, _side);
    243   else {
    244     BondsinSceneMap[ids]->resetPosition();
    245     BondsinSceneMap[ids]->resetWidth();
    246   }
    247 }
    248 
    249 void GLMoleculeObject_molecule::addAtomBonds(
    250     const atom *_atom)
    251 {
    252   const bool atom_present = AtomsinSceneMap.count(_atom->getId());
    253   const BondList &bondlist = _atom->getListOfBonds();
    254   for (BondList::const_iterator bonditer = bondlist.begin();
    255       (bonditer != bondlist.end()) && atom_present;
    256       ++bonditer) {
    257     const bond::ptr _bond = *bonditer;
    258     // check if OtherAtom's sphere is already present
    259     const atom *OtherAtom = _bond->GetOtherAtom(_atom);
    260     const bool otheratom_present = AtomsinSceneMap.count(OtherAtom->getId());
    261     if (otheratom_present && atom_present) {
    262       const GLMoleculeObject_bond::SideOfBond side = (_bond->leftatom == _atom) ?
    263           GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
    264       const GLMoleculeObject_bond::SideOfBond otherside = (_bond->leftatom == _atom) ?
    265           GLMoleculeObject_bond::right : GLMoleculeObject_bond::left;
    266       addAtomBonds(_bond, side);
    267       addAtomBonds(_bond, otherside);
    268     }
    269   }
    270 }
    271 
    272 void GLMoleculeObject_molecule::updateBoundingBox()
    273 {
    274   isBoundingBoxUptodate = true;
    275   const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
    276       getMolecule(MoleculeById(moleculeid));
    277   if (_molecule == NULL) {
    278     ELOG(1, "GLMoleculeObject_molecule cannot updateBoundingBox, molecule with "
    279         << moleculeid << " has disappeared.");
    280     return;
    281   }
    282   Shape shape = _molecule->getBoundingSphere();
    283   Vector v = shape.getCenter();
    284   setPosition(QVector3D(v[0], v[1], v[2]));
    285   setScale(shape.getRadius() + 0.3); // getBoundingShape() only sees atoms as points, so make the box a bit bigger
     419    Shape shape = _molecule->getBoundingSphere();
     420    info.position = shape.getCenter();
     421    info.radius = shape.getRadius();
     422  } else
     423    ELOG(2, "GLMoleculeObject_molecule cannot updateBoundingBox, molecule with "
     424        << MolIndex.get() << " has disappeared.");
     425  return info;
     426}
     427
     428GLMoleculeObject_molecule::atoms_t GLMoleculeObject_molecule::updateAtoms()
     429{
     430  const molecule * const mol = getMolecule(MolIndex.get());
     431  const atomId_t id = mol->lastChanged()->getId();
     432  if (mol->containsAtom(id))
     433    DisplayedAtoms.insert(id);
     434  else
     435    DisplayedAtoms.erase(id);
     436  return DisplayedAtoms;
     437}
     438
     439moleculeId_t GLMoleculeObject_molecule::updateIndex() const
     440{
     441  const molecule * const mol = World::getInstance().lastChanged<molecule>();
     442  if (mol != NULL) {
     443    return mol->getId();
     444  }
     445  return (moleculeId_t)-1;
     446}
     447
     448void GLMoleculeObject_molecule::resetTesselationHull()
     449{
     450  if (!TesselationHull.isValid())
     451    updateMesh(createMoleculeMesh(*TesselationHull));
     452}
     453
     454void GLMoleculeObject_molecule::resetIsSelected()
     455{
     456  setSelected(isSelected.get());
     457}
     458
     459void GLMoleculeObject_molecule::resetBoundingBox()
     460{
     461  BoundingBoxInfo info = BoundingBox.get();
     462  setPosition(QVector3D(info.position[0], info.position[1], info.position[2]));
     463  setScale(info.radius + 0.3); // getBoundingSphere() only sees atoms as points, so make the box a bit bigger
     464}
     465
     466void GLMoleculeObject_molecule::resetAtoms()
     467{
     468  const atoms_t atoms = PresentAtoms.get();
     469  std::vector<atomId_t> InsertedAtoms;
     470  std::vector<atomId_t> RemovedAtoms;
     471  // obtain all newly inserted and removed atoms
     472  std::set_difference(
     473      atoms.begin(), atoms.end(),
     474      DisplayedAtoms.begin(), DisplayedAtoms.end(),
     475      std::back_inserter(InsertedAtoms));
     476  std::set_difference(
     477      DisplayedAtoms.begin(), DisplayedAtoms.end(),
     478      atoms.begin(), atoms.end(),
     479      std::back_inserter(RemovedAtoms));
     480  // remove the atoms
     481  std::for_each(RemovedAtoms.begin(), RemovedAtoms.end(),
     482      boost::bind(&GLMoleculeObject_molecule::atomRemoved, this, _1));
     483  // insert the atoms
     484  std::for_each(InsertedAtoms.begin(), InsertedAtoms.end(),
     485      boost::bind(&GLMoleculeObject_molecule::atomInserted, this, _1));
     486
     487  emit changed();
     488}
     489
     490void GLMoleculeObject_molecule::resetIndex()
     491{
     492  const atomId_t newId = MolIndex.get();
     493  const size_t oldId = objectId();
     494  ASSERT( newId != oldId,
     495      "GLMoleculeObject_molecule::resetIndex() - index "+toString(newId)+" did not change.");
     496  LOG(4, "INFO: GLMoleculeObject_molecule: new index is "+toString(newId)+".");
     497  setObjectId(newId);
     498
     499  emit indexChanged(this, oldId, newId);
    286500}
    287501
     
    296510void GLMoleculeObject_molecule::subjectKilled(Observable *publisher)
    297511{
    298   isSignedOn = false;
     512  deactivateObserver();
    299513}
    300514
    301515void GLMoleculeObject_molecule::recieveNotification(Observable *publisher, Notification_ptr notification)
    302516{
    303   const molecule * const _molecule = const_cast<const World &>(World::getInstance()).
    304       getMolecule(MoleculeById(moleculeid));
     517  const molecule * const _molecule = getMolecule(MolIndex.get());
    305518  if (publisher == dynamic_cast<const Observable*>(_molecule)){
    306519    // notofication from atom
     
    317530        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
    318531  #endif
    319         QMetaObject::invokeMethod(this,        // pointer to a QObject
    320                                   "atomInserted",       // member name (no parameters here)
    321                                   Qt::QueuedConnection,     // connection type
    322                                   Q_ARG(atomId_t, _id));     // parameters
     532        emit AtomInserted(_id);
     533        emit TesselationHullChanged();
     534        emit BoundingBoxChanged();
    323535        break;
    324536      }
     
    329541        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been removed.";
    330542  #endif
    331         QMetaObject::invokeMethod(this,        // pointer to a QObject
    332                                   "atomRemoved",       // member name (no parameters here)
    333                                   Qt::QueuedConnection,     // connection type
    334                                   Q_ARG(const atomId_t, _id));     // parameters
     543        emit AtomRemoved(_id);
     544        emit TesselationHullChanged();
     545        emit BoundingBoxChanged();
    335546        break;
    336547      }
     
    341552        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+" has been inserted.";
    342553  #endif
    343         TesselationHullUptodate = false;
    344         isBoundingBoxUptodate = false;
     554        emit TesselationHullChanged();
     555        emit BoundingBoxChanged();
     556        break;
     557      }
     558      case molecule::IndexChanged:
     559      {
     560  #ifdef LOG_OBSERVER
     561        const atomId_t _id = _molecule->lastChanged()->getId();
     562        observerLog().addMessage() << "++ Observer " << observerLog().getName(static_cast<Observer *>(this)) << " received notification that atom "+toString(_id)+"'s index has changed.";
     563  #endif
     564        emit IdChanged();
    345565        break;
    346566      }
     
    357577    switch (notification->getChannelNo()) {
    358578      case World::SelectionChanged:
    359         if (_molecule != NULL) {
    360           setSelected(World::getInstance().isSelected(_molecule));
    361         } else {
    362           ELOG(1, "GLMoleculeObject_molecule cannot change selection, molecule with "
    363               << moleculeid << " has disappeared.");
    364         }
     579        emit IsSelectedChanged();
    365580        break;
    366581      default:
     
    388603  // draw either molecule's mesh or all atoms and bonds
    389604  if (m_visible) {
    390     updateTesselationHull();
     605    resetTesselationHull();
    391606
    392607    painter->modelViewMatrix().push();
     
    437652
    438653    // update bounding box prior to selection
    439     if (!isBoundingBoxUptodate)
    440       updateBoundingBox();
     654    resetBoundingBox();
    441655
    442656    painter->modelViewMatrix().push();
     
    463677{
    464678  LOG(3, "INFO: GLMoleculeObject_molecule: Received signal atomInserted for atom "+toString(_id)+".");
    465 
    466   TesselationHullUptodate = false;
    467   isBoundingBoxUptodate = false;
    468679
    469680  GLMoleculeObject_atom *atomObject = new GLMoleculeObject_atom(GLMoleculeObject::meshSphere, this, _id);
     
    483694  connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
    484695  connect (atomObject, SIGNAL(selectionChanged()), this, SIGNAL(changed()));
    485   connect (atomObject, SIGNAL(BondsInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const bond::ptr , const GLMoleculeObject_bond::SideOfBond)));
    486   connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, int, int)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, int, int)));
    487 
    488   isBoundingBoxUptodate = false;
     696  connect (atomObject, SIGNAL(BondsChanged(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)), this, SLOT(bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)));
     697  connect (atomObject, SIGNAL(BondsRemoved(const atomId_t, const atomId_t)), this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
     698  connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, const atomId_t, const atomId_t)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, const atomId_t, const atomId_t)));
    489699
    490700  if (m_objectId  == -1)
     
    512722  LOG(3, "INFO: GLMoleculeObject_molecule: Received signal atomRemoved for atom "+toString(_id)+".");
    513723  // bonds are removed by signal coming from ~bond
    514 
    515   TesselationHullUptodate = false;
    516   isBoundingBoxUptodate = false;
    517724
    518725  if ((unsigned int)m_objectId == _id)
     
    528735  delete atomObject;
    529736
    530   isBoundingBoxUptodate = false;
    531 
    532737  emit changeOccured();
    533738}
     
    551756    if (moleculeObject == this){
    552757      // Propagate signal.
    553       emit hoverChanged(moleculeid, 0);
     758      emit hoverChanged(MolIndex.get(), 0);
    554759    }
    555760  }
     
    582787 * @param side which side of the bond (left or right)
    583788 */
    584 void GLMoleculeObject_molecule::bondInserted(const bond::ptr _bond, const enum GLMoleculeObject_bond::SideOfBond _side)
    585 {
    586   LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(*_bond)+".");
     789void GLMoleculeObject_molecule::bondInserted(
     790    const atomId_t _left, const atomId_t _right,
     791    const enum GLMoleculeObject_bond::SideOfBond _side)
     792{
     793  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(_left)
     794      +toString(_right)+".");
    587795  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
    588796
    589   const BondIds ids = getBondIds(_bond, _side);
     797  const BondIds ids( std::make_pair(_left, _right) );
    590798  BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
    591799  if (iter == BondsinSceneMap.end()) {
     
    638846}
    639847
    640 void GLMoleculeObject_molecule::updateTesselationHull()
    641 {
    642   if (!TesselationHullUptodate) {
    643     updateMesh(createMoleculeMesh(moleculeid, parent()));
    644     TesselationHullUptodate = true;
    645   }
    646 }
    647 
    648848std::ostream &operator<<(std::ostream &ost, const GLMoleculeObject_molecule::BondIds &t)
    649849{
     
    654854void GLMoleculeObject_molecule::wasClicked()
    655855{
    656   LOG(4, "INFO: GLMoleculeObject_molecule: atom " << moleculeid << " has been clicked");
    657   emit moleculeClicked(moleculeid);
    658 }
    659 
    660 void GLMoleculeObject_molecule::changeAtomId(GLMoleculeObject_atom *ob, int oldId, int newId)
     856  LOG(4, "INFO: GLMoleculeObject_molecule: atom " << MolIndex.get() << " has been clicked");
     857  emit moleculeClicked(MolIndex.get());
     858}
     859
     860void GLMoleculeObject_molecule::changeAtomId(
     861    GLMoleculeObject_atom *ob,
     862    const atomId_t oldId,
     863    const atomId_t newId)
    661864{
    662865  LOG(3, "INFO: GLMoleculeObject_molecule - change atom id " << oldId << " to " << newId << ".");
     
    679882  AtomsinSceneMap.insert( make_pair(newId, ob) );
    680883}
     884
     885const molecule * const GLMoleculeObject_molecule::getMolecule(const moleculeId_t _id)
     886{
     887  const molecule * const mol = const_cast<const World &>(World::getInstance()).
     888      getMolecule(MoleculeById(_id));
     889  return mol;
     890}
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp

    r3e52834 r6c16a0  
    1616#include "GLMoleculeObject.hpp"
    1717
     18#include <Qt3D/qgeometrydata.h>
     19
     20#include "CodePatterns/Cacheable.hpp"
    1821#include "CodePatterns/Observer/Observer.hpp"
     22#include "CodePatterns/ObservedValue.hpp"
    1923
    2024#include "GLMoleculeObject_bond.hpp"
     
    3438  virtual ~GLMoleculeObject_molecule();
    3539
    36   void updateBoundingBox();
    37 
    3840  // Observer functions
    3941  void update(Observable *publisher);
     
    5153      const enum GLMoleculeObject_bond::SideOfBond side);
    5254
    53   void selected(const bool _isSelected)
    54   { isSelected = _isSelected; }
    55 
    5655signals:
    5756  void changed();
     
    5958  void hoverChanged(const atomId_t);
    6059  void hoverChanged(const moleculeId_t, int);
     60  void indexChanged(GLMoleculeObject_molecule *, const moleculeId_t, const moleculeId_t);
    6161  void atomClicked(atomId_t no);
    6262  void moleculeClicked(moleculeId_t no);
     63  void TesselationHullChanged();
     64  void BoundingBoxChanged();
     65  void IsSelectedChanged();
     66  void AtomInserted(const atomId_t _id);
     67  void AtomRemoved(const atomId_t _id);
     68  void IdChanged();
    6369
    6470private slots:
     
    6975  void atomInserted(const atomId_t _id);
    7076  void atomRemoved(const atomId_t _id);
    71   void bondInserted(const bond::ptr _bond, const GLMoleculeObject_bond::SideOfBond side);
     77  void bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond side);
    7278  void bondRemoved(const atomId_t leftnr, const atomId_t rightnr);
    7379  void hoverChangedSignalled(GLMoleculeObject *ob);
    74   void changeAtomId(GLMoleculeObject_atom *, int, int);
     80  void changeAtomId(GLMoleculeObject_atom *, const atomId_t, const atomId_t);
    7581
    7682  void setVisible(bool value);
    7783
    7884  void activateObserver();
     85  void deactivateObserver();
     86
     87  void resetTesselationHull();
     88  void resetIsSelected();
     89  void resetBoundingBox();
     90  void resetAtoms();
     91  void resetIndex();
     92
     93private:
     94  static const molecule * const getMolecule(const moleculeId_t _id);
    7995
    8096private:
     
    85101  void addAtomBonds(const atom *_atom);
    86102
    87   void updateTesselationHull();
     103  //!> typedef for the internal set of atoms
     104  typedef std::set<atomId_t> atoms_t;
    88105
    89   //!> states whether selection box is additionally drawn or not
    90   bool isSelected;
    91   bool isBoundingBoxUptodate;
     106  /** Structure for the required information on the bounding box.
     107   *
     108   */
     109  struct BoundingBoxInfo {
     110    //!> position of center
     111    Vector position;
     112    //!> radius of sphere
     113    double radius;
     114  };
    92115
    93   //!> whether we are signed on to the associated molecule
    94   bool isSignedOn;
     116  /** Structure for the required information on the tesselation hull.
     117   *
     118   */
     119  struct TesselationHullInfo {
     120  };
    95121
    96   const moleculeId_t moleculeid;
     122  QGeometryData updateTesselationHull() const;
     123  bool updateIsSelected() const;
     124  BoundingBoxInfo updateBoundingBox() const;
     125  atoms_t updateAtoms();
     126  moleculeId_t updateIndex() const;
    97127
    98   bool TesselationHullUptodate;
     128  //!> the Observable we are signed on, also indicates whether we are sign on (not NULL)
     129  const Observable * owner;
     130
     131  //!> internal variable for caching molecule ref in cstor
     132  const molecule * const molref;
     133
     134  //!> list of channels when contained atoms needs to update
     135  static const Observable::channels_t AtomsChannels;
     136  //!> list of channels when tesselation hull needs to update
     137  static const Observable::channels_t HullChannels;
     138  //!> list of channels when selection status needs to update
     139  static const Observable::channels_t SelectionStatusChannels;
     140  //!> list of channels when bounding box needs to update
     141  static const Observable::channels_t BoundingBoxChannels;
     142  //!> list of channels when the index needs to update
     143  static const Observable::channels_t IndexChannels;
     144
     145  boost::function<moleculeId_t ()> MolIndexUpdater;
     146  boost::function<QGeometryData ()> TesselationHullUpdater;
     147  boost::function<bool ()> IsSelectedUpdater;
     148  boost::function<BoundingBoxInfo ()> BoundingBoxUpdater;
     149  boost::function<atoms_t ()> PresentAtomsUpdater;
     150
     151  //!> contains the current molecule index
     152  ObservedValue<moleculeId_t> MolIndex;
     153  //!> contains current version of the tesselation hull on request
     154  Cacheable<QGeometryData> TesselationHull;
     155  //!> contains newest version of the selection status
     156  ObservedValue<bool> isSelected;
     157  //!> contains newest version of the bounding box on request
     158  ObservedValue<BoundingBoxInfo> BoundingBox;
     159  //!> contains the current live set of atoms for the molecule
     160  ObservedValue<atoms_t> PresentAtoms;
     161
     162  //!> contains the set of atoms displayed
     163  atoms_t DisplayedAtoms;
    99164
    100165  typedef std::map< atomId_t, GLMoleculeObject_atom* > AtomNodeMap;
Note: See TracChangeset for help on using the changeset viewer.