Changeset 96f14a for src/UIElements


Ignore:
Timestamp:
Apr 20, 2016, 10:58:43 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:
d48a16
Parents:
b4bd0e
git-author:
Frederik Heber <heber@…> (03/24/16 13:26:51)
git-committer:
Frederik Heber <heber@…> (04/20/16 22:58:43)
Message:

Modified all GLMoleculeObjects and GLWorldScene to the new QtObservedBond.

  • GLWorldScene transmits bondInserted/bondRemoved similarly to those for the atoms to the molecule if aLready present and otherwise into the MissedStateMap.
Location:
src/UIElements/Views/Qt4/Qt3D
Files:
8 edited

Legend:

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

    rb4bd0e r96f14a  
    7777  connect( ObservedAtom.get(), SIGNAL(elementChanged()), this, SLOT(resetElement()));
    7878  connect( ObservedAtom.get(), SIGNAL(positionChanged()), this, SLOT(resetPosition()));
    79   connect( ObservedAtom.get(), SIGNAL(bondsChanged()), this, SLOT(resetBonds()));
    8079  connect( ObservedAtom.get(), SIGNAL(selectedChanged()), this, SLOT(resetSelected()));
    81 
    82   // use that ObservedValues::AtomBonds is always up-to-date
    83   // don't call here, is done by GLMoleculeObject_molecule
    84 //  resetBonds();
    85 
    8680}
    8781
     
    10498{
    10599  const Vector Position = ObservedAtom->getAtomPosition();
    106   LOG(4, "INFO: GLMoleculeObject_atom::resetIndex() - new position is "+toString(Position)+".");
     100  LOG(4, "INFO: GLMoleculeObject_atom::resetPosition() - new position is "+toString(Position)+".");
    107101  setPosition(QVector3D(Position[0], Position[1], Position[2]));
    108102}
     
    118112    elementno = 1;
    119113  }
    120   LOG(4, "INFO: GLMoleculeObject_atom::resetIndex() - new element number is "+toString(elementno)+".");
     114  LOG(4, "INFO: GLMoleculeObject_atom::resetElement() - new element number is "+toString(elementno)+".");
    121115
    122116  // set materials
    123117  QGLMaterial *elementmaterial = getMaterial(elementno);
    124118  ASSERT(elementmaterial != NULL,
    125       "GLMoleculeObject_atom::GLMoleculeObject_atom() - QGLMaterial ref from getter function is NULL.");
     119      "GLMoleculeObject_atom::resetElement() - QGLMaterial ref from getter function is NULL.");
    126120  setMaterial(elementmaterial);
    127121
     
    134128  }
    135129  setScale( radius / 4. );
    136 }
    137 
    138 void GLMoleculeObject_atom::resetBonds()
    139 {
    140   QtObservedAtom::ListOfBonds_t ListOfBonds_new = ObservedAtom->getAtomBonds();
    141   std::sort(ListOfBonds_new.begin(), ListOfBonds_new.end());
    142   QtObservedAtom::ListOfBonds_t BondsToAdd;
    143   std::set_difference(
    144       ListOfBonds_new.begin(), ListOfBonds_new.end(),
    145       ListOfBonds.begin(), ListOfBonds.end(),
    146       std::back_inserter(BondsToAdd));
    147   QtObservedAtom::ListOfBonds_t BondsToRemove;
    148   std::set_difference(
    149       ListOfBonds.begin(), ListOfBonds.end(),
    150       ListOfBonds_new.begin(), ListOfBonds_new.end(),
    151       std::back_inserter(BondsToRemove));
    152   for (QtObservedAtom::ListOfBonds_t::const_iterator iter = BondsToAdd.begin();
    153       iter != BondsToAdd.end();
    154       ++iter) {
    155     const GLMoleculeObject_bond::SideOfBond side = (iter->first == ObservedAtom->getAtomIndex()) ?
    156         GLMoleculeObject_bond::left : GLMoleculeObject_bond::right;
    157     emit BondsAdded(iter->first, iter->second, side);
    158   }
    159   for (QtObservedAtom::ListOfBonds_t::const_iterator iter = BondsToRemove.begin();
    160       iter != BondsToRemove.end();
    161       ++iter) {
    162     emit BondsRemoved(iter->first, iter->second);
    163   }
    164   ListOfBonds = ListOfBonds_new;
    165130}
    166131
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp

    rb4bd0e r96f14a  
    4141  void draw(QGLPainter *painter, const QVector4D &cameraPlane);
    4242
    43   void resetBonds();
    44 
    4543private slots:
    4644  void wasClicked();
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.cpp

    rb4bd0e r96f14a  
    4747#include "CodePatterns/Assert.hpp"
    4848#include "CodePatterns/Log.hpp"
    49 #include "CodePatterns/Observer/Notification.hpp"
    50 #include "CodePatterns/Observer/ObserverLog.hpp"
    51 #include "Descriptors/AtomIdDescriptor.hpp"
     49
    5250#include "Atom/atom.hpp"
    5351#include "Bond/bond.hpp"
     
    5654#include "LinearAlgebra/Line.hpp"
    5755#include "LinearAlgebra/Vector.hpp"
    58 #include "UIElements/Qt4/InstanceBoard/ObservedValue_wCallback.hpp"
    5956#include "World.hpp"
    60 
    61 
    62 // static entities
    63 const Observable::channels_t
    64 GLMoleculeObject_bond::IndexChannels(1, AtomObservable::IndexChanged);
    65 const Observable::channels_t
    66 GLMoleculeObject_bond::BondPositionChannels(1, AtomObservable::PositionChanged);
    67 const Observable::channels_t
    68 GLMoleculeObject_bond::BondDegreeChannels(1, BondObservable::DegreeChanged);
    69 const Observable::channels_t
    70 GLMoleculeObject_bond::BondElementChannels(1, AtomObservable::ElementChanged);
    71 
    72 static GLMoleculeObject_bond::bondIds_t getBondIdsForIds(
    73     const boost::function<const atomId_t()> &_left,
    74     const boost::function<const atomId_t()> &_right)
    75 {
    76   return std::make_pair(_left(), _right());
    77 }
    7857
    7958GLMoleculeObject_bond::GLMoleculeObject_bond(
    8059    QGLSceneNode *mesh[],
    8160    QObject *parent,
    82     const bondIds_t bondIds,
     61    QtObservedBond::ptr &_ObservedBond,
    8362    const enum SideOfBond side) :
    8463  GLMoleculeObject(mesh, parent),
    85   Observer(std::string("GLMoleculeObject_bond")
    86       +toString(bondIds.first)
    87       +std::string("-")
    88       +toString(bondIds.second)),
    89   leftowner(getAtomConst(bondIds.first)),
    90   rightowner(getAtomConst(bondIds.second)),
    91   bondowner(getAtomConst(bondIds.first)->getBond(getAtomConst(bondIds.second)).get()),
    9264  BondSide(side),
    93   ObservedValues(MAX_ObservedTypes),
    94   subjectKilledCount(0),
    95   leftobservable_enabled(false),
    96   rightobservable_enabled(false),
    97   board_subjectKilled(
    98       boost::bind(
    99           static_cast<void (GLMoleculeObject_bond::*) ()>(
    100               &GLMoleculeObject_bond::countsubjectKilled),
    101           this))
     65  ObservedBond(_ObservedBond)
    10266{
    103   boost::function<void(const atomId_t &)> leftsubjectKilled =
    104       boost::bind(
    105           static_cast<void (GLMoleculeObject_bond::*) (const atomId_t &)>(
    106               &GLMoleculeObject_bond::countsubjectKilled),
    107           this, _1);
    108   boost::function<void(const atomId_t &)> rightsubjectKilled =
    109       boost::bind(
    110           static_cast<void (GLMoleculeObject_bond::*) (const atomId_t &)>(
    111               &GLMoleculeObject_bond::countsubjectKilled)
    112               , this, _1);
    113   boost::function<void(const bondIds_t &)> bondsubjectKilled =
    114       boost::bind(
    115           static_cast<void (GLMoleculeObject_bond::*) (const bondIds_t &)>(
    116               &GLMoleculeObject_bond::countsubjectKilled)
    117               , this, _1);
    118   initObservedValues(
    119       ObservedValues,
    120       bondIds.first,
    121       bondIds.second,
    122       leftowner,
    123       rightowner,
    124       bondowner,
    125       leftsubjectKilled,
    126       rightsubjectKilled,
    127       bondsubjectKilled);
    128 
    129   init();
    130 }
    131 
    132 GLMoleculeObject_bond::GLMoleculeObject_bond(
    133     QGLSceneNode *mesh[],
    134     QObject *parent,
    135     const bondIds_t bondIds,
    136     const enum SideOfBond side,
    137     std::vector<boost::any> &_ObservedValues,
    138     const boost::function<void (const bondIds_t)> &_subjectKilled) :
    139   GLMoleculeObject(mesh, parent),
    140   Observer(std::string("GLMoleculeObject_bond")
    141       +toString(bondIds.first)
    142       +std::string("-")
    143       +toString(bondIds.second)),
    144   leftowner(getAtomConst(bondIds.first)),
    145   rightowner(getAtomConst(bondIds.second)),
    146   bondowner(getAtomConst(bondIds.first)->getBond(getAtomConst(bondIds.second)).get()),
    147   BondSide(side),
    148   ObservedValues(_ObservedValues),
    149   subjectKilledCount(0),
    150   leftobservable_enabled(false),
    151   rightobservable_enabled(false),
    152   board_subjectKilled(_subjectKilled)
    153 {
    154   init();
    155 }
    156 
    157 void GLMoleculeObject_bond::init()
    158 {
    159   // sign on as observer (obtain non-const instance before)
    160   bondowner->signOn(this, BondObservable::BondRemoved);
    161   bondowner->signOn(this, BondObservable::DegreeChanged);
    162   bond_enabled = true;
    163   leftowner->signOn(this, AtomObservable::PositionChanged);
    164   leftowner->signOn(this, AtomObservable::ElementChanged);
    165   leftobservable_enabled = true;
    166   rightowner->signOn(this, AtomObservable::PositionChanged);
    167   rightowner->signOn(this, AtomObservable::ElementChanged);
    168   rightobservable_enabled = true;
    169 
    17067  resetElement();
    17168  resetPosition();
    17269  resetWidth();
    17370
    174   connect(this, SIGNAL(elementChanged()), this, SLOT(resetElement()), Qt::QueuedConnection);
    175   connect(this, SIGNAL(positionChanged()), this, SLOT(resetPosition()), Qt::QueuedConnection);
    176   connect(this, SIGNAL(degreeChanged()), this, SLOT(resetWidth()), Qt::QueuedConnection);
     71  // connect to observed bond's signals
     72  connect(_ObservedBond.get(), SIGNAL(degreeChanged()), this, SLOT(resetWidth()));
     73  if (side == left)
     74    connect(_ObservedBond.get(), SIGNAL(leftAtomElementChanged()), this, SLOT(resetElement()));
     75  else
     76    connect(_ObservedBond.get(), SIGNAL(rightAtomElementChanged()), this, SLOT(resetElement()));
     77  connect(_ObservedBond.get(), SIGNAL(leftAtomPositionChanged()), this, SLOT(resetPosition()));
     78  connect(_ObservedBond.get(), SIGNAL(rightAtomPositionChanged()), this, SLOT(resetPosition()));
     79}
     80
     81static const atomicNumber_t& getElement(
     82    const QtObservedBond::ptr &_ObservedBond,
     83    const enum GLMoleculeObject_bond::SideOfBond _side)
     84{
     85  if (_side == GLMoleculeObject_bond::left)
     86    return _ObservedBond->getLeftAtomElement();
     87  else
     88    return _ObservedBond->getRightAtomElement();
     89}
     90
     91static const Vector& getPosition(
     92    const QtObservedBond::ptr &_ObservedBond,
     93    const enum GLMoleculeObject_bond::SideOfBond _side)
     94{
     95  if (_side == GLMoleculeObject_bond::left)
     96    return _ObservedBond->getLeftAtomPosition();
     97  else
     98    return _ObservedBond->getRightAtomPosition();
     99}
     100
     101static const Vector& getOtherPosition(
     102    const QtObservedBond::ptr &_ObservedBond,
     103    const enum GLMoleculeObject_bond::SideOfBond _side)
     104{
     105  if (_side == GLMoleculeObject_bond::left)
     106    return _ObservedBond->getRightAtomPosition();
     107  else
     108    return _ObservedBond->getLeftAtomPosition();
    177109}
    178110
    179111GLMoleculeObject_bond::~GLMoleculeObject_bond()
    180112{
    181   LOG(3, "DEBUG: Destroying  GLMoleculeObject_bond to bond [" <<
    182       getleftIndex() << "," << getrightIndex() << "] and side " << BondSide << ".");
     113  LOG(4, "DEBUG: Destroying  GLMoleculeObject_bond to bond [" <<
     114      ObservedBond->getBondIndex() << "] and side " << BondSide << ".");
    183115  // signOff() if not already done
    184   removeChannels();
    185   destroyObservedValues(ObservedValues);
    186 }
    187 
    188 void GLMoleculeObject_bond::removeChannels()
    189 {
    190   // at this point both atoms should still be alive, hence we may safely sign off
    191   // from the AtomObservable itself
    192   if (bond_enabled) {
    193     if (bondowner != NULL) {
    194       bondowner->signOff(this, BondObservable::BondRemoved);
    195       bondowner->signOff(this, BondObservable::DegreeChanged);
    196     }
    197     bond_enabled = false;
    198   }
    199   if (leftobservable_enabled) {
    200     if (leftowner != NULL) {
    201       leftowner->signOff(this, AtomObservable::PositionChanged);
    202       leftowner->signOff(this, AtomObservable::ElementChanged);
    203     }
    204     leftobservable_enabled = false;
    205   }
    206   if (rightobservable_enabled) {
    207     if (rightowner != NULL) {
    208       rightowner->signOff(this, AtomObservable::PositionChanged);
    209       rightowner->signOff(this, AtomObservable::ElementChanged);
    210     }
    211     rightobservable_enabled = false;
    212   }
    213 }
    214 
    215 void GLMoleculeObject_bond::update(Observable *publisher)
    216 {
    217   ASSERT(0, "GLMoleculeObject_bond::update() - we are not signed on for any global updates.");
    218 }
    219 
    220 void GLMoleculeObject_bond::subjectKilled(Observable *publisher)
    221 {
    222   // we signOff from all other sources
    223   removeChannels();
    224   // check whether we should be removed
    225   board_subjectKilled(std::make_pair(getleftIndex(), getrightIndex()));
    226 }
    227 
    228 void GLMoleculeObject_bond::recieveNotification(Observable *publisher, Notification_ptr notification)
    229 {
    230 #ifdef LOG_OBSERVER
    231   if (publisher == static_cast<const Observable *>(bondowner)) {
    232     observerLog().addMessage() << "++ Update of Observer "
    233         << observerLog().getName(static_cast<Observer*>(this))
    234         << " received notification from bond for channel "
    235         << notification->getChannelNo() << ".";
    236   } else if (publisher == static_cast<const Observable * const>(leftowner)) {
    237     observerLog().addMessage() << "++ Update of Observer "
    238         << observerLog().getName(static_cast<Observer*>(this))
    239         << " received notification from leftatom " << getleftIndex() << " for channel "
    240         << notification->getChannelNo() << ".";
    241   } else if (publisher == static_cast<const Observable * const>(rightowner)) {
    242     observerLog().addMessage() << "++ Update of Observer "
    243         << observerLog().getName(static_cast<Observer*>(this))
    244         << " received notification from rightatom " << getrightIndex() << " for channel "
    245         << notification->getChannelNo() << ".";
    246   }
    247 #endif
    248   if (publisher == static_cast<const Observable *>(bondowner)){
    249     switch (notification->getChannelNo()) {
    250     case BondObservable::BondRemoved:
    251 //      removeMe();
    252       break;
    253     case BondObservable::DegreeChanged:
    254       emit degreeChanged();
    255       break;
    256     default:
    257       ASSERT(0, "GLMoleculeObject_bond::recieveNotification() - unknown signal.");
    258       break;
    259     }
    260   } else {
    261     // from an atom
    262     switch (notification->getChannelNo()) {
    263     case AtomObservable::PositionChanged:
    264       LOG(2, "INFO: Received notification of PositionChanged.");
    265       emit positionChanged();
    266       break;
    267     case AtomObservable::ElementChanged:
    268       LOG(2, "INFO: Received notification of ElementChanged.");
    269       emit elementChanged();
    270       break;
    271     default:
    272       break;
    273     }
    274   }
    275 }
    276 
    277 atomId_t GLMoleculeObject_bond::updateIndex()
    278 {
    279   return const_cast<const World &>(World::getInstance()).lastChangedAtomId();
    280 }
    281 
    282 Vector GLMoleculeObject_bond::updateLeftPosition(
    283     const boost::function<const atomId_t ()> &_getLeftAtomIndex)
    284 {
    285   const atom * const _atom = getAtomConst(_getLeftAtomIndex());
    286   return _atom->getPosition();
    287 }
    288 
    289 Vector GLMoleculeObject_bond::updateRightPosition(
    290     const boost::function<const atomId_t ()> &_getRightAtomIndex)
    291 {
    292   const atom * const _atom = getAtomConst(_getRightAtomIndex());
    293   return _atom->getPosition();
    294 }
    295 
    296 atomicNumber_t GLMoleculeObject_bond::updateLeftElement(
    297     const boost::function<const atomId_t ()> &_getLeftAtomIndex)
    298 {
    299   const atom * const _atom = getAtomConst(_getLeftAtomIndex());
    300   return _atom->getElementNo();
    301 }
    302 
    303 atomicNumber_t GLMoleculeObject_bond::updateRightElement(
    304     const boost::function<const atomId_t ()> &_getRightAtomIndex)
    305 {
    306   const atom * const _atom = getAtomConst(_getRightAtomIndex());
    307   return _atom->getElementNo();
    308 }
    309 
    310 int GLMoleculeObject_bond::updateDegree(
    311     const boost::function<const atomId_t ()> &_getLeftAtomIndex,
    312     const boost::function<const atomId_t ()> &_getRightAtomIndex)
    313 {
    314   const atom * const _leftatom = const_cast<const World &>(World::getInstance()).
    315       getAtom(AtomById(_getLeftAtomIndex()));
    316   const atom * const _rightatom = const_cast<const World &>(World::getInstance()).
    317       getAtom(AtomById(_getRightAtomIndex()));
    318   if ((_leftatom != NULL) && (_rightatom != NULL)) {
    319     bond::ptr _bond = _leftatom->getBond(_rightatom);
    320     return _bond->getDegree();
    321   } else {
    322     return 1;
    323   }
    324116}
    325117
    326118void GLMoleculeObject_bond::resetElement()
    327119{
    328   size_t elementno = getrightElement();
     120  const atomicNumber_t& elementno = getElement(ObservedBond, BondSide);
    329121  QGLMaterial *elementmaterial = getMaterial(elementno);
    330122  setMaterial(elementmaterial);
     
    333125void GLMoleculeObject_bond::resetWidth()
    334126{
    335   const double factor = 1.0f+.5f*(getDegree()-1);
    336   LOG(2, "DEBUG: GLMoleculeObject_bond::resetWidth() - setting bond's width to " << factor << ".");
     127  const double factor = 1.0f+.5f*(ObservedBond->getBondDegree()-1);
     128  LOG(4, "DEBUG: GLMoleculeObject_bond::resetWidth() - setting bond's width to " << factor << ".");
    337129  setScaleX(factor);
    338130  setScaleY(factor);
     
    343135void GLMoleculeObject_bond::resetPosition()
    344136{
    345   Vector Position = getleftPosition();
    346   Vector OtherPosition = getrightPosition();
     137  const Vector& Position = getPosition(ObservedBond, BondSide);
     138  const Vector& OtherPosition = getOtherPosition(ObservedBond, BondSide);
    347139  const double distance =
    348140      Position.distance(OtherPosition)/2.;
     
    355147  Vector OtherAxis;
    356148  double alpha;
    357   a = Position - OtherPosition;
     149  a = OtherPosition - Position;
    358150  // construct rotation axis
    359151  b = a;
     
    370162  // check
    371163  Vector a_rotated = axis.rotateVector(a, alpha);
    372   LOG(3, "INFO: Created cylinder from "// << Position << " to " << OtherPosition
     164  LOG(4, "DEBUG: Created cylinder from "// << Position << " to " << OtherPosition
    373165      << a << " to " << a_rotated << " around " << b << " by " << alpha/M_PI*180. << ", respectively.");
    374166
    375167  // set position (cylinder offset is in its barymetric center)
    376   Vector OneFourth(Position - 0.75 * a);
     168  Vector OneFourth(OtherPosition - 0.75 * a);
    377169  setPosition(QVector3D(OneFourth[0], OneFourth[1], OneFourth[2]));
    378170  setRotationVector(QVector3D(b[0], b[1], b[2]));
     
    381173  emit changed();
    382174}
    383 
    384 atom * const GLMoleculeObject_bond::getAtom(const atomId_t _id)
    385 {
    386   atom * const _atom = World::getInstance().getAtom(AtomById(_id));
    387   return _atom;
    388 }
    389 
    390 const atom * const GLMoleculeObject_bond::getAtomConst(const atomId_t _id)
    391 {
    392   const atom * const _atom = const_cast<const World &>(World::getInstance()).
    393       getAtom(AtomById(_id));
    394   return _atom;
    395 }
    396 
    397 void GLMoleculeObject_bond::countsubjectKilled()
    398 {
    399   ++subjectKilledCount;
    400 
    401   if (subjectKilledCount > ObservedValues.size())
    402     emit BondRemoved(getleftIndex(), getrightIndex());
    403 }
    404 
    405 void GLMoleculeObject_bond::initObservedValues(
    406     std::vector<boost::any> &_ObservedValues,
    407     const atomId_t _leftatomId,
    408     const atomId_t _rightatomId,
    409     const Observable * const _leftowner,
    410     const Observable * const _rightowner,
    411     const Observable * const _bondowner,
    412     const boost::function<void(const atomId_t &)> &_leftsubjectKilled,
    413     const boost::function<void(const atomId_t &)> &_rightsubjectKilled,
    414     const boost::function<void(const bondIds_t &)> &_bondsubjectKilled)
    415 {
    416   /* This is an old note from when the code was still part of cstor's initializer body.
    417    * TODO: Probably does not apply anymore but has not yet been tested.
    418    *
    419    * We must not use boost::cref(this) as "this" has not been properly constructed and seemingly
    420    * boost::cref tries to do some magic to grasp the inheritance hierarchy which fails because
    421    * the class has not been fully constructed yet. "This" itself seems to be working fine.
    422    */
    423 
    424   ASSERT( _ObservedValues.size() == MAX_ObservedTypes,
    425       "GLMoleculeObject_bond::initObservedValues() - given ObservedValues has not correct size.");
    426 
    427   // fill ObservedValues: index first
    428   // Note that we only need one as the function just checks on the last changed id
    429   // and ids cannot be changed simultaneously
    430   const boost::function<atomId_t ()> AtomIndexUpdater(
    431       boost::bind(&GLMoleculeObject_bond::updateIndex));
    432 
    433   ObservedValue_wCallback<atomId_t> * const LeftIndexObservable =
    434       new ObservedValue_wCallback<atomId_t>(
    435         _leftowner,
    436         AtomIndexUpdater,
    437         "Bonds_LeftAtomIndex_"+toString(_leftatomId),
    438         _leftatomId,
    439         IndexChannels,
    440         _leftsubjectKilled);
    441   _ObservedValues[leftIndex] = LeftIndexObservable;
    442   ObservedValue_wCallback<atomId_t> * const RightIndexObservable =
    443       new ObservedValue_wCallback<atomId_t>(
    444         _rightowner,
    445         AtomIndexUpdater,
    446         "Bonds_RightAtomIndex_"+toString(_rightatomId),
    447         _rightatomId,
    448         IndexChannels,
    449         _rightsubjectKilled);
    450   _ObservedValues[rightIndex] = RightIndexObservable;
    451 
    452   const boost::function<const atomId_t ()> LeftIndexGetter =
    453       boost::bind(&ObservedValue_wCallback<atomId_t>::get,
    454           LeftIndexObservable);
    455   const boost::function<const atomId_t ()> RightIndexGetter =
    456       boost::bind(&ObservedValue_wCallback<atomId_t>::get,
    457           RightIndexObservable);
    458 
    459   // fill ObservedValues: then all the other that need index
    460   const boost::function<Vector ()> LeftPositionUpdater(
    461       boost::bind(&GLMoleculeObject_bond::updateLeftPosition, LeftIndexGetter));
    462   const boost::function<Vector ()> RightPositionUpdater(
    463       boost::bind(&GLMoleculeObject_bond::updateRightPosition, RightIndexGetter));
    464   const boost::function<atomicNumber_t ()> LeftElementUpdater(
    465       boost::bind(&GLMoleculeObject_bond::updateLeftElement, LeftIndexGetter));
    466   const boost::function<atomicNumber_t ()> RightElementUpdater(
    467       boost::bind(&GLMoleculeObject_bond::updateRightElement, RightIndexGetter));
    468   const boost::function<int ()> DegreeUpdater(
    469       boost::bind(&GLMoleculeObject_bond::updateDegree, LeftIndexGetter, RightIndexGetter));
    470   const boost::function<bondIds_t ()> BondIdGetter(
    471       boost::bind(&getBondIdsForIds, LeftIndexGetter, RightIndexGetter));
    472 
    473   _ObservedValues[leftPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
    474       _leftowner,
    475       LeftPositionUpdater,
    476       "BondleftPosition_"+toString(_leftatomId),
    477       LeftPositionUpdater(),
    478       BondPositionChannels,
    479       _leftsubjectKilled,
    480       LeftIndexGetter);
    481   _ObservedValues[rightPosition] = new ObservedValue_wCallback<Vector, atomId_t>(
    482       _rightowner,
    483       RightPositionUpdater,
    484       "BondrightPosition_"+toString(_rightatomId),
    485       RightPositionUpdater(),
    486       BondPositionChannels,
    487       _rightsubjectKilled,
    488       RightIndexGetter);
    489   _ObservedValues[leftElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
    490       _leftowner,
    491       LeftElementUpdater,
    492       "BondleftElement"+toString(_leftatomId),
    493       LeftElementUpdater(),
    494       BondElementChannels,
    495       _leftsubjectKilled,
    496       LeftIndexGetter);
    497   _ObservedValues[rightElement] = new ObservedValue_wCallback<atomicNumber_t, atomId_t>(
    498       _rightowner,
    499       RightElementUpdater,
    500       "BondrightElement"+toString(_rightatomId),
    501       RightElementUpdater(),
    502       BondElementChannels,
    503       _rightsubjectKilled,
    504       RightIndexGetter);
    505   _ObservedValues[Degree] = new ObservedValue_wCallback<int, bondIds_t>(
    506       _bondowner,
    507       DegreeUpdater,
    508       "BondDegree"+toString(_leftatomId)+"_"+toString(_rightatomId),
    509       DegreeUpdater(),
    510       BondDegreeChannels,
    511       _bondsubjectKilled,
    512       BondIdGetter);
    513 }
    514 
    515 void GLMoleculeObject_bond::destroyObservedValues(
    516     std::vector<boost::any> &_ObservedValues)
    517 {
    518   delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[leftIndex]);
    519   delete boost::any_cast<ObservedValue_wCallback<atomId_t> *>(_ObservedValues[rightIndex]);
    520   delete boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(_ObservedValues[leftPosition]);
    521   delete boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(_ObservedValues[rightPosition]);
    522   delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t,atomId_t> *>(_ObservedValues[leftElement]);
    523   delete boost::any_cast<ObservedValue_wCallback<atomicNumber_t,atomId_t> *>(_ObservedValues[rightElement]);
    524   delete boost::any_cast<ObservedValue_wCallback<int, bondIds_t> *>(_ObservedValues[Degree]);
    525   _ObservedValues.clear();
    526 }
    527 
    528 const atomId_t& GLMoleculeObject_bond::getleftIndex() const
    529 {
    530   return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[leftIndex])->get();
    531 }
    532 
    533 const atomId_t& GLMoleculeObject_bond::getrightIndex() const
    534 {
    535   return boost::any_cast<ObservedValue_wCallback<atomId_t> *>(ObservedValues[rightIndex])->get();
    536 }
    537 
    538 const Vector& GLMoleculeObject_bond::getleftPosition() const
    539 {
    540   return boost::any_cast<ObservedValue_wCallback<Vector,atomId_t> *>(ObservedValues[leftPosition])->get();
    541 }
    542 
    543 const Vector& GLMoleculeObject_bond::getrightPosition() const
    544 {
    545   return boost::any_cast<ObservedValue_wCallback<Vector, atomId_t> *>(ObservedValues[rightPosition])->get();
    546 }
    547 
    548 const atomicNumber_t& GLMoleculeObject_bond::getleftElement() const
    549 {
    550   return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[leftElement])->get();
    551 }
    552 
    553 const atomicNumber_t& GLMoleculeObject_bond::getrightElement() const
    554 {
    555   return boost::any_cast<ObservedValue_wCallback<atomicNumber_t, atomId_t> *>(ObservedValues[rightElement])->get();
    556 }
    557 
    558 const int& GLMoleculeObject_bond::getDegree() const
    559 {
    560   return boost::any_cast<ObservedValue_wCallback<int, bondIds_t> *>(ObservedValues[Degree])->get();
    561 }
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp

    rb4bd0e r96f14a  
    2020#include <boost/function.hpp>
    2121
    22 #include "CodePatterns/Observer/Observer.hpp"
    23 #include "CodePatterns/ObservedValue.hpp"
    24 
    2522#include "LinearAlgebra/Vector.hpp"
    2623
    27 #include "Bond/bond.hpp"
    2824#include "types.hpp"
     25
     26#include "UIElements/Qt4/InstanceBoard/QtObservedBond.hpp"
    2927
    3028class atom;
     
    3230class GLWorldScene;
    3331
    34 class GLMoleculeObject_bond : public GLMoleculeObject, public Observer
     32class GLMoleculeObject_bond : public GLMoleculeObject
    3533{
    3634  Q_OBJECT
     
    4341      QGLSceneNode *mesh[],
    4442      QObject *parent,
    45       const bondIds_t bondIds,
     43      QtObservedBond::ptr &_ObservedBond,
    4644      const enum SideOfBond side);
    47   GLMoleculeObject_bond(
    48       QGLSceneNode *mesh[],
    49       QObject *parent,
    50       const bondIds_t bondIds,
    51       const enum SideOfBond side,
    52       std::vector<boost::any> &_ObservedValues,
    53       const boost::function<void (const bondIds_t)> &_subjectKilled);
    5445  virtual ~GLMoleculeObject_bond();
    55 
    56   // Observer functions
    57   void update(Observable *publisher);
    58   void subjectKilled(Observable *publisher);
    59   void recieveNotification(Observable *publisher, Notification_ptr notification);
    6046
    6147signals:
    6248  void BondRemoved(const atomId_t leftnr, const atomId_t rightnr);
    63   void elementChanged();
    64   void positionChanged();
    65   void degreeChanged();
    6649
    6750private slots:
     
    8568
    8669private:
    87 
    88   void init();
    89 
    90   void removeChannels();
    91 
    92   static atomId_t updateIndex();
    93   static Vector updateLeftPosition(
    94       const boost::function<const atomId_t ()> &_getLeftAtomIndex);
    95   static Vector updateRightPosition(
    96       const boost::function<const atomId_t ()> &_getRightAtomIndex);
    97   static atomicNumber_t updateLeftElement(
    98       const boost::function<const atomId_t ()> &_getLeftAtomIndex);
    99   static atomicNumber_t updateRightElement(
    100       const boost::function<const atomId_t ()> &_getRightAtomIndex);
    101   static int updateDegree(
    102       const boost::function<const atomId_t ()> &_getLeftAtomIndex,
    103       const boost::function<const atomId_t ()> &_getRightAtomIndex);
    104 
    105   static const atom * const getAtomConst(const atomId_t _id);
    106   static atom * const getAtom(const atomId_t _id);
    107 
    108 private:
    109   //!> contains ref to Observable of left atom
    110   const Observable * const leftowner;
    111   //!> contains ref to Observable of right atom
    112   const Observable * const rightowner;
    113   //!> temporary variable used in cstor
    114   const Observable * const bondowner;
    115 
     70  //!> which part of half the bond this object represents
    11671  const enum SideOfBond BondSide;
    117 
    118 
    119 private:
    120   /** Observed Values **/
    121 
    122   //!> enumeration of observed values to match with entries in ObservedValues
    123   enum ObservedTypes {
    124     //!> contains the id of the left atom
    125     leftIndex,
    126     //!> contains the id of the right atom
    127     rightIndex,
    128     //!> contains the position of the left atom
    129     leftPosition,
    130     //!> contains the position of the right atom
    131     rightPosition,
    132     //!> contains the element of the left atom
    133     leftElement,
    134     //!> contains the element of the right atom
    135     rightElement,
    136     //!> contains the degree of the bond
    137     Degree,
    138     //!> gives the size of the enumeration
    139     MAX_ObservedTypes
    140   };
    141 
    142   //!> vector with all observed values
    143   std::vector<boost::any> ObservedValues;
    144 
    145   /** Initializes all \a ObservedValues entries.
    146    *
    147    * \param _ObservedValues vector of ObservedValue to be filled
    148    * \param _leftatomId left atom id
    149    * \param _rightatomId right atom id
    150    * \param _leftowner reference to left atom
    151    * \param _rightowner reference to right atom
    152    * \param _bondowner reference to bond
    153    * \param _leftsubjectKilled ref to function to call on subjectKilled() for left atom
    154    * \param _rightsubjectKilled ref to function to call on subjectKilled() for right atom
    155    * \param _bondsubjectKilled ref to function to call on subjectKilled() for bond
    156    */
    157   static void initObservedValues(
    158       std::vector<boost::any> &_ObservedValues,
    159       const atomId_t _leftatomId,
    160       const atomId_t _rightatomId,
    161       const Observable * const _leftowner,
    162       const Observable * const _rightowner,
    163       const Observable * const _bondowner,
    164       const boost::function<void(const atomId_t &)> &_leftsubjectKilled,
    165       const boost::function<void(const atomId_t &)> &_rightsubjectKilled,
    166       const boost::function<void(const bondIds_t &)> &_bondsubjectKilled);
    167 
    168   /** Destroys all \a ObservedValues entries.
    169    *
    170    * \param _ObservedValues vector of ObservedValue to be destroyed
    171    */
    172   static void destroyObservedValues(
    173       std::vector<boost::any> &_ObservedValues);
    174 
    175   /** Getter to left atom's id contained in \a ObservedValues.
    176    *
    177    * \return left atom's id
    178    */
    179   const atomId_t& getleftIndex() const;
    180 
    181   /** Getter to right atom's id contained in \a ObservedValues.
    182    *
    183    * \return right atom's id
    184    */
    185   const atomId_t& getrightIndex() const;
    186 
    187   /** Getter to left atom's position contained in \a ObservedValues.
    188    *
    189    * \return left atom's position
    190    */
    191   const Vector& getleftPosition() const;
    192 
    193   /** Getter to right atom's position contained in \a ObservedValues.
    194    *
    195    * \return right atom's position
    196    */
    197   const Vector& getrightPosition() const;
    198 
    199   /** Getter to left atom's element contained in \a ObservedValues.
    200    *
    201    * \return left atom's element
    202    */
    203   const atomicNumber_t& getleftElement() const;
    204 
    205   /** Getter to rightatom's element contained in \a ObservedValues.
    206    *
    207    * \return right atom's element
    208    */
    209   const atomicNumber_t& getrightElement() const;
    210 
    211   /** Getter to bond's degree contained in \a ObservedValues.
    212    *
    213    * \return bond's degree
    214    */
    215   const int& getDegree() const;
    216 
    217   /** Counts how many ObservedValues got subjectKilled.
    218    *
    219    * This is used to give InstanceRemoved() signal only when each and every
    220    * ObservedValue (and the instance itself) has been subjectKilled by the
    221    * monitored Observable. Only then can we safely remove the instance.
    222    *
    223    * \param _bondIds bond ids whose bond has called subjectKilled()
    224    */
    225   void countsubjectKilled(
    226       const bondIds_t &_bondIds)
    227   {
    228     countsubjectKilled();
    229   }
    230 
    231   void countsubjectKilled(
    232       const atomId_t &_atomid)
    233   {
    234     countsubjectKilled();
    235   }
    236 
    237   void countsubjectKilled();
    238 
    239   //!> counts how many ObservedValues have already been subjectKilled()
    240   mutable size_t subjectKilledCount;
    241 
    242 private:
    243 
    244   //!> indicate whether we are signed in to leftobservable
    245   bool leftobservable_enabled;
    246   //!> indicate whether we are signed in to rightobservable
    247   bool rightobservable_enabled;
    248   //!> indicate whether we are signed in to bond itself
    249   bool bond_enabled;
    250 
    251   //!> list of channels when id needs to update
    252   static const Observable::channels_t IndexChannels;
    253   //!> list of channels when position needs to update
    254   static const Observable::channels_t BondPositionChannels;
    255   //!>list of channels when degree needs to update
    256   static const Observable::channels_t BondDegreeChannels;
    257   //!> list of channels when element needs to update
    258   static const Observable::channels_t BondElementChannels;
    259 
    260   //!> callback function to inform about subjectKilled()
    261   const boost::function<void (const bondIds_t)> board_subjectKilled;
     72  //!> state of the bond this object visually represents
     73  const QtObservedBond::ptr ObservedBond;
    26274};
    26375
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.cpp

    rb4bd0e r96f14a  
    9191  ObservedMolecule(_ObservedMolecule)
    9292{
    93   init(ObservedMolecule->getMolIndex());
     93  init();
    9494}
    9595
     
    105105  ObservedMolecule(_ObservedMolecule)
    106106{
    107   init(ObservedMolecule->getMolIndex());
    108 }
    109 
    110 void GLMoleculeObject_molecule::init(const moleculeId_t _molid)
    111 {
    112   setObjectId(_molid);
     107  init();
     108}
     109
     110void GLMoleculeObject_molecule::init()
     111{
     112  setObjectId(ObservedMolecule->getMolIndex());
    113113  setMaterial(getMaterial(1));
    114114
    115   m_selected = const_cast<const World &>(World::getInstance()).isMoleculeSelected(_molid);
     115  m_selected = ObservedMolecule->getMolSelected();
    116116
    117117  // initially, atoms and bonds should be visible
     
    136136GLMoleculeObject_molecule::~GLMoleculeObject_molecule()
    137137{}
    138 
    139 void GLMoleculeObject_molecule::addAtomBonds(
    140     const bond::ptr &_bond,
    141     const GLMoleculeObject_bond::SideOfBond _side
    142     )
    143 {
    144   bool bond_present = false;
    145   const BondIds ids = getBondIds(_bond, _side);
    146   // check whether bond is not present already
    147   bond_present = BondsinSceneMap.count(ids);
    148   if (!bond_present)
    149     bondInserted(ids.first, ids.second, _side);
    150   else {
    151     BondsinSceneMap[ids]->resetPosition();
    152     BondsinSceneMap[ids]->resetWidth();
    153   }
    154 }
    155138
    156139QGeometryData GLMoleculeObject_molecule::updateTesselationHull() const
     
    382365    connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
    383366    connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
    384   //  connect (atomObject, SIGNAL(bondsChanged()), this, SLOT(bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond)));
    385     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)));
    386     connect (atomObject, SIGNAL(BondsRemoved(const atomId_t, const atomId_t)), this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
    387     connect (atomObject, SIGNAL(indexChanged(GLMoleculeObject_atom*, const atomId_t, const atomId_t)), this, SLOT(changeAtomId(GLMoleculeObject_atom*, const atomId_t, const atomId_t)));
    388367
    389368    if (m_objectId  == -1)
    390369      setObjectId(_atom->getAtomIndex());
    391 
    392     // first reset bonds when signals connections have been made
    393     atomObject->resetBonds();
    394370
    395371    emit changed();
     
    448424}
    449425
    450 
    451 /** Helper function to get bond ids in the correct order for BondNodeMap.
    452  *
    453  * \return pair of ids in correct order.
    454  */
    455 GLMoleculeObject_molecule::BondIds GLMoleculeObject_molecule::getBondIds(
    456     const bond::ptr _bond,
    457     const enum GLMoleculeObject_bond::SideOfBond _side)
    458 {
    459   BondIds ids;
    460   switch (_side) {
    461     case GLMoleculeObject_bond::left:
    462       ids = std::make_pair(_bond->leftatom->getId(), _bond->rightatom->getId());
    463       break;
    464     case GLMoleculeObject_bond::right:
    465       ids = std::make_pair(_bond->rightatom->getId(), _bond->leftatom->getId());
    466       break;
    467   }
    468   return ids;
    469 }
    470 
    471426/** Adds a bond to the scene.
    472427 *
    473428 * @param _bond bond to add
    474  * @param side which side of the bond (left or right)
    475429 */
    476430void GLMoleculeObject_molecule::bondInserted(
    477     const atomId_t _left, const atomId_t _right,
    478     const enum GLMoleculeObject_bond::SideOfBond _side)
    479 {
    480   LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bond "+toString(_left)
    481       +toString(_right)+".");
     431    QtObservedBond::ptr _bond)
     432{
     433  static const std::vector< GLMoleculeObject_bond::SideOfBond > bondsides =
     434      boost::assign::list_of<GLMoleculeObject_bond::SideOfBond>
     435          (GLMoleculeObject_bond::left)
     436          (GLMoleculeObject_bond::right);
     437  LOG(3, "INFO: GLWorldScene::bondInserted() - Adding bonds " << _bond->getBondIndex());
    482438  //LOG(4, "INFO: Currently present bonds " << BondsinSceneMap << ".");
    483439
    484   const BondIds ids( std::make_pair(_left, _right) );
    485   BondNodeMap::iterator iter = BondsinSceneMap.find(ids);
    486   if (iter == BondsinSceneMap.end()) {
    487     GLMoleculeObject_bond * bondObject =
    488         new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, ids, _side);
    489     connect (
    490         bondObject, SIGNAL(BondRemoved(const atomId_t, const atomId_t)),
    491         this, SLOT(bondRemoved(const atomId_t, const atomId_t)));
    492     connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
    493     BondsinSceneMap.insert( make_pair(ids, bondObject) );
    494   //    BondIdsinSceneMap.insert( Leftids );
     440  const ObservedValue_Index_t bondid = _bond->getIndex();
     441  const std::pair<BondNodeMap::iterator, BondNodeMap::iterator> iters =
     442      BondsinSceneMap.equal_range(bondid);
     443  if (iters.first == iters.second) {
     444    for (size_t i=0;i<2;++i) {
     445      GLMoleculeObject_bond * bondObject =
     446          new GLMoleculeObject_bond(GLMoleculeObject::meshCylinder, this, _bond, bondsides[i]);
     447      connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
     448      BondsinSceneMap.insert( std::make_pair(bondid, bondObject) );
     449    }
    495450  } else {
    496     iter->second->resetPosition();
    497     iter->second->resetWidth();
     451    for (BondNodeMap::iterator iter = iters.first; iter != iters.second; ++iter) {
     452      iter->second->resetPosition();
     453      iter->second->resetWidth();
     454    }
    498455  }
    499456  emit changed();
     
    505462 * @param _bond bond to remove
    506463 */
    507 void GLMoleculeObject_molecule::bondRemoved(const atomId_t leftnr, const atomId_t rightnr)
    508 {
    509   LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond between "+toString(leftnr)+" and "+toString(rightnr)+".");
     464void GLMoleculeObject_molecule::bondRemoved(ObservedValue_Index_t _id)
     465{
     466  LOG(3, "INFO: GLWorldScene::bondRemoved() - Removing bond to id " << _id);
    510467  {
    511468    // left bond
    512     const BondIds Leftids( make_pair(leftnr, rightnr) );
    513     BondNodeMap::iterator leftiter = BondsinSceneMap.find( Leftids );
    514     ASSERT(leftiter != BondsinSceneMap.end(),
    515         "GLWorldScene::bondRemoved() - bond "+toString(leftnr)+"-"
    516         +toString(rightnr)+" not on display.");
    517     GLMoleculeObject_bond *bondObject = leftiter->second;
    518     bondObject->disconnect();
    519     BondsinSceneMap.erase(leftiter);
    520     delete bondObject; // is done by signal from bond itself
    521     //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
     469    const std::pair<BondNodeMap::iterator, BondNodeMap::iterator> iters =
     470        BondsinSceneMap.equal_range(_id);
     471    for (BondNodeMap::iterator iter = iters.first; iter != iters.second; ++iter) {
     472      GLMoleculeObject_bond *bondObject = iter->second;
     473      bondObject->disconnect();
     474      delete bondObject; // is done by signal from bond itself
     475      //LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
     476    }
     477    BondsinSceneMap.erase(_id);
    522478  }
    523479
  • src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp

    rb4bd0e r96f14a  
    2323
    2424#include <boost/function.hpp>
    25 
    26 #include "CodePatterns/Cacheable.hpp"
    27 #include "CodePatterns/Observer/Observable.hpp"
    2825
    2926#include "GLMoleculeObject_bond.hpp"
     
    5956  friend std::ostream &operator<<(std::ostream &ost, const BondIds &t);
    6057
    61   static BondIds getBondIds(
    62       const bond::ptr _bond,
    63       const enum GLMoleculeObject_bond::SideOfBond side);
    64 
    6558signals:
    6659  void changed();
     
    8073  void atomInserted(QtObservedAtom::ptr _atom);
    8174  void atomRemoved(ObservedValue_Index_t _id);
    82   void bondInserted(const atomId_t, const atomId_t, const GLMoleculeObject_bond::SideOfBond side);
    83   void bondRemoved(const atomId_t leftnr, const atomId_t rightnr);
     75  void bondInserted(QtObservedBond::ptr _bond);
     76  void bondRemoved(ObservedValue_Index_t _id);
    8477  void hoverChangedSignalled(GLMoleculeObject *ob);
    8578
     
    9285
    9386private:
    94   void addAtomBonds(
    95       const bond::ptr &_bond,
    96       const GLMoleculeObject_bond::SideOfBond _side
    97       );
    9887
    99   void init(const moleculeId_t _molid);
     88  void init();
    10089
    10190private:
     
    113102
    114103  typedef std::map< ObservedValue_Index_t, GLMoleculeObject_atom* > AtomNodeMap;
    115   typedef std::map< BondIds , GLMoleculeObject_bond* > BondNodeMap;
     104  typedef std::multimap< ObservedValue_Index_t, GLMoleculeObject_bond* > BondNodeMap;
    116105  AtomNodeMap AtomsinSceneMap;
    117106  BondNodeMap BondsinSceneMap;
  • src/UIElements/Views/Qt4/Qt3D/GLWorldScene.cpp

    rb4bd0e r96f14a  
    101101  connect(board, SIGNAL(atomRemoved(ObservedValue_Index_t)),
    102102      this, SLOT(atomRemoved(ObservedValue_Index_t)));
     103  connect(board, SIGNAL(bondInserted(QtObservedBond::ptr)),
     104      this, SLOT(bondInserted(QtObservedBond::ptr)));
     105  connect(board, SIGNAL(bondRemoved(ObservedValue_Index_t)),
     106      this, SLOT(bondRemoved(ObservedValue_Index_t)));
    103107  connect(this, SIGNAL(insertMolecule(QtObservedMolecule::ptr)),
    104108      this, SLOT(moleculeInserted(QtObservedMolecule::ptr)) );
     
    182186      +" is not present in QtObservedAtomMap.");
    183187  QtObservedAtomMap.erase(eraseiter);
     188}
     189
     190/** Prepares insertion of a bond.
     191 *
     192 * This is called before the insertion into a molecule and thus before the
     193 * insertion into the scene.
     194 *
     195 * @param _bond bond to insert
     196 */
     197void GLWorldScene::bondInserted(QtObservedBond::ptr _bond)
     198{
     199  const ObservedValue_Index_t bondid = _bond->getIndex();
     200  ASSERT( QtObservedBondMap.find(bondid) == QtObservedBondMap.end(),
     201      "GLWorldScene::BondInserted() - bond with id "+toString(_bond->getBondIndex())
     202      +" is already present in QtObservedBondMap.");
     203  QtObservedBondMap[bondid] = _bond;
     204
     205  // assign to its molecule if present
     206  const moleculeId_t molid = _bond->getMoleculeIndex();
     207  if (molid != (moleculeId_t)-1) {
     208    QtObservedMolecule::ptr mol = board->getObservedMolecule(molid);
     209    emit moleculesBondInserted(_bond, mol.get());
     210  } else {
     211    // watch bond till it has a molecule
     212    connect( _bond.get(), SIGNAL(moleculeIndexChanged(moleculeId_t,moleculeId_t)),
     213        this, SLOT(bondsMoleculeChanged(moleculeId_t, moleculeId_t)));
     214  }
     215}
     216
     217/** Handle change of molecule from initial none.
     218 *
     219 */
     220void GLWorldScene::bondsMoleculeChanged(moleculeId_t _oldid, moleculeId_t _newid)
     221{
     222  ASSERT( _oldid == (moleculeId_t)-1,
     223      "GLWorldScene::bondsMoleculeChanged() - got true index change from "
     224      +toString(_oldid)+" to "+toString(_newid)+" and not just added to mol.");
     225  QtObservedBond* bondref = static_cast<QtObservedBond*>(sender());
     226
     227  // disconnect from further molecule changes
     228  disconnect( bondref, SIGNAL(moleculeIndexChanged(moleculeId_t,moleculeId_t)),
     229      this, SLOT(bondsMoleculeChanged(moleculeId_t, moleculeId_t)));
     230
     231  // add it to its molecule
     232  QtObservedMolecule::ptr mol = board->getObservedMolecule(_newid);
     233  emit moleculesBondInserted(bondref->getRef(), mol.get());
     234}
     235
     236
     237/** Removes an general bond.
     238 *
     239 * This is called when the bond has been removed from the molecule.
     240 *
     241 * @param _bond bond to remove
     242 */
     243void GLWorldScene::bondRemoved(ObservedValue_Index_t _bondid)
     244{
     245  const QtObservedBondMap_t::iterator eraseiter = QtObservedBondMap.find(_bondid);
     246  ASSERT( eraseiter != QtObservedBondMap.end(),
     247      "GLWorldScene::BondRemoved() - bond with id "+toString(_bondid)
     248      +" is not present in QtObservedBondMap.");
     249  QtObservedBond::ptr bondref = eraseiter->second;
     250
     251  // tell its assigned molecule if present
     252  const moleculeId_t molid = bondref->getMoleculeIndex();
     253  if (molid != (moleculeId_t)-1) {
     254    QtObservedMolecule::ptr mol = board->getObservedMolecule(molid);
     255    emit moleculesBondRemoved(_bondid, mol.get());
     256  } else {
     257    // it might have still been waiting for a molecule assignment
     258    disconnect( bondref.get(), SIGNAL(moleculeIndexChanged(moleculeId_t,moleculeId_t)),
     259        this, SLOT(bondsMoleculeChanged(moleculeId_t, moleculeId_t)));
     260  }
     261  QtObservedBondMap.erase(eraseiter);
    184262}
    185263
     
    329407}
    330408
     409/** Inserts an bond into the scene when molecule is present.
     410 *
     411 * @param _bond bond to insert
     412 */
     413void GLWorldScene::moleculesBondInserted(QtObservedBond::ptr _bond, QtObservedMolecule * _mol)
     414{
     415  const ObservedValue_Index_t bondid = _bond->getIndex();
     416  LOG(3, "INFO: GLWorldScene: Received signal bondInserted for bond " << _bond->getBondIndex());
     417  const ObservedValue_Index_t molid = _mol->getIndex();
     418
     419  // check of molecule is already present
     420  boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
     421  const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
     422  if (moliter != MoleculesinSceneMap.end()) {
     423    // check that it is the right molecule
     424    QtObservedMolecule::ptr &checkmol = moliter->second->ObservedMolecule;
     425    ASSERT( checkmol.get() == _mol,
     426        "GLWorldScene::moleculesBondInserted() - claimed and present molecule differ.");
     427    LOG(3, "INFO: GLWorldScene: Sending signal moleculesBondInserted for bond "
     428        << _bond->getBondIndex());
     429    QMetaObject::invokeMethod(moliter->second,        // pointer to a QObject
     430                              "bondInserted",       // member name (no parameters here)
     431                              Qt::QueuedConnection,     // connection type
     432                              Q_ARG(QtObservedBond::ptr, _bond));     // parameters
     433  } else {
     434#ifndef NDEBUG
     435    const RemovedMoleculesMap_t::iterator removedmoliter = RemovedMolecules.find(_mol);
     436    ASSERT( removedmoliter != RemovedMolecules.end(),
     437          "GLWorldScene::moleculesBondInserted() - would need to send bondInserted to already removed molecule.");
     438#endif
     439    boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
     440    // only record missed state for molecule if (still) present but not instantiated
     441    if (QtObservedMoleculeMap.count(molid)) {
     442      // store signal for when it is instantiated
     443      if (MoleculeMissedStateMap.count(molid) == 0)
     444        MoleculeMissedStateMap.insert( std::make_pair(molid ,StateChangeMap_t()) );
     445      MoleculeMissedStateMap[molid].insert( std::make_pair(bondid, bondInsertedState) );
     446      ASSERT( QtObservedBondMap[bondid] == _bond,
     447          "GLWorldScene::moleculesBondInserted() - bond "+toString(bondid)
     448          +" inserted in molecule "+toString(_mol->getMolIndex())
     449          +" which does not match bond in QtObservedBondMap.");
     450      LOG(3, "INFO: GLWorldScene: Placing bondInserted for bond " << _bond->getBondIndex()
     451           << " and molecule " << _mol->getMolIndex() << " into missed state map.");
     452    }
     453  }
     454}
     455
     456/** Removes an bond into the scene before molecule is present.
     457 *
     458 * @param _bondid bond to remove
     459 */
     460void GLWorldScene::moleculesBondRemoved(ObservedValue_Index_t _bondid, QtObservedMolecule * _mol)
     461{
     462  LOG(3, "INFO: GLWorldScene: Received signal bondRemoved for bond "+toString(_bondid)+".");
     463
     464  const ObservedValue_Index_t molid = _mol->getIndex();
     465  // check of molecule is already present
     466  boost::recursive_mutex::scoped_lock lock(MoleculeinSceneMap_mutex);
     467  const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(molid);
     468  if (moliter != MoleculesinSceneMap.end()) {
     469    const QtObservedMolecule::ptr &checkmol = moliter->second->ObservedMolecule;
     470    if (checkmol.get() == _mol) {
     471      LOG(3, "INFO: GLWorldScene: Sending signal moleculesBondRemoved for bond "+toString(_bondid)+".");
     472      QMetaObject::invokeMethod(moliter->second,        // pointer to a QObject
     473                                "bondRemoved",       // member name (no parameters here)
     474                                Qt::QueuedConnection,     // connection type
     475                                Q_ARG(ObservedValue_Index_t, _bondid));     // parameters
     476    } else {
     477      // relay bondRemoved to GLMoleculeObject_molecule in RemovedMolecules
     478      LOG(3, "INFO: GLWorldScene: Sending signal moleculesBondRemoved for bond "+toString(_bondid)
     479          +" to molecule in RemovedMolecules.");
     480      const RemovedMoleculesMap_t::iterator removedmoliter = RemovedMolecules.find(_mol);
     481      ASSERT( removedmoliter != RemovedMolecules.end(),
     482          "GLWorldScene::moleculesBondRemoved() - signal from old molecule "
     483          +toString(molid)+", but not present in RemovedMolecules");
     484#ifndef NDEBUG
     485      const QtObservedMolecule::ptr &othercheckmol = removedmoliter->second->ObservedMolecule;
     486      ASSERT( othercheckmol.get() == _mol,
     487          "GLWorldScene::moleculesBondRemoved() - signal from old molecule "
     488          +toString(molid)+", but different one "+toString(othercheckmol)
     489          +" present in RemovedMolecules.");
     490#endif
     491      QMetaObject::invokeMethod(removedmoliter->second,        // pointer to a QObject
     492                                "bondRemoved",       // member name (no parameters here)
     493                                Qt::QueuedConnection,     // connection type
     494                                Q_ARG(ObservedValue_Index_t, _bondid));     // parameters
     495    }
     496  } else {
     497    const RemovedMoleculesMap_t::iterator removedmoliter = RemovedMolecules.find(_mol);
     498    if (removedmoliter != RemovedMolecules.end()) {
     499      ASSERT( removedmoliter != RemovedMolecules.end(),
     500          "GLWorldScene::moleculesBondRemoved() - signal from old molecule "
     501          +toString(molid)+", but not present in RemovedMolecules");
     502#ifndef NDEBUG
     503      const QtObservedMolecule::ptr &othercheckmol = removedmoliter->second->ObservedMolecule;
     504      ASSERT( othercheckmol.get() == _mol,
     505          "GLWorldScene::moleculesBondRemoved() - signal from old molecule "
     506          +toString(molid)+", but different one "+toString(othercheckmol)
     507          +" present in RemovedMolecules.");
     508#endif
     509      QMetaObject::invokeMethod(removedmoliter->second,        // pointer to a QObject
     510                                "bondRemoved",       // member name (no parameters here)
     511                                Qt::QueuedConnection,     // connection type
     512                                Q_ARG(ObservedValue_Index_t, _bondid));     // parameters
     513    } else {
     514      boost::recursive_mutex::scoped_lock lock(MoleculeMissedStateMap_mutex);
     515      // only record missed state for molecule if (still) present but not instantiated
     516      if (QtObservedMoleculeMap.count(molid)) {
     517        // store signal for when it is instantiated
     518        if (MoleculeMissedStateMap.count(molid) == 0)
     519          MoleculeMissedStateMap.insert( std::make_pair(molid, StateChangeMap_t()) );
     520        MoleculeMissedStateMap[molid].insert( std::make_pair(_bondid, bondRemovedState) );
     521        LOG(3, "INFO: GLWorldScene: Placing bondRemoved for bond " << _bondid
     522             << " and molecule " << molid << " into missed state map.");
     523      }
     524    }
     525  }
     526}
     527
    331528void GLWorldScene::moleculeSignOn(QtObservedMolecule::ptr _mol)
    332529{
     
    418615            stateiter != rangeiter.second; ++stateiter)
    419616          ++StateChangeAmounts[stateiter->second];
    420         ASSERT( StateChangeAmounts[atomInsertedState] >= StateChangeAmounts[atomRemovedState],
    421             "GLWorldScene::moleculeInserted() - more atomRemoved states "
    422             +toString(StateChangeAmounts[atomRemovedState])+" than atomInserted "
    423             +toString(StateChangeAmounts[atomInsertedState])+" for atom "+toString(iter->first));
    424         if (StateChangeAmounts[atomInsertedState] > StateChangeAmounts[atomRemovedState]) {
    425           LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
    426           QMetaObject::invokeMethod(molObject,        // pointer to a QObject
    427                                     "atomInserted",       // member name (no parameters here)
    428                                     Qt::QueuedConnection,     // connection type
    429                                     Q_ARG(QtObservedAtom::ptr, QtObservedAtomMap[iter->first]));     // parameters
    430         } else {
    431           LOG(1, "INFO: Atom " << iter->first << " has been inserted and removed already.");
     617        // is it an atom?
     618        if ((StateChangeAmounts[atomInsertedState] + StateChangeAmounts[atomRemovedState]) != 0) {
     619          ASSERT( StateChangeAmounts[atomInsertedState] >= StateChangeAmounts[atomRemovedState],
     620              "GLWorldScene::moleculeInserted() - more atomRemoved states "
     621              +toString(StateChangeAmounts[atomRemovedState])+" than atomInserted "
     622              +toString(StateChangeAmounts[atomInsertedState])+" for atom "+toString(iter->first));
     623          if (StateChangeAmounts[atomInsertedState] > StateChangeAmounts[atomRemovedState]) {
     624            LOG(1, "INFO: invoking atomInserted for atom " << iter->first);
     625            QMetaObject::invokeMethod(molObject,        // pointer to a QObject
     626                                      "atomInserted",       // member name (no parameters here)
     627                                      Qt::QueuedConnection,     // connection type
     628                                      Q_ARG(QtObservedAtom::ptr, QtObservedAtomMap[iter->first]));     // parameters
     629          } else {
     630            LOG(1, "INFO: Atom " << iter->first << " has been inserted and removed already.");
     631          }
    432632        }
    433         // removed all state changes for this atom
     633        // or is it a bond?
     634        if ((StateChangeAmounts[bondInsertedState] + StateChangeAmounts[bondInsertedState]) != 0) {
     635          ASSERT( StateChangeAmounts[bondInsertedState] >= StateChangeAmounts[bondRemovedState],
     636              "GLWorldScene::moleculeInserted() - more bondRemoved states "
     637              +toString(StateChangeAmounts[bondRemovedState])+" than bondInserted "
     638              +toString(StateChangeAmounts[bondInsertedState])+" for bond "+toString(iter->first));
     639          if (StateChangeAmounts[bondInsertedState] > StateChangeAmounts[bondRemovedState]) {
     640            LOG(1, "INFO: invoking bondInserted for bond " << iter->first);
     641            QMetaObject::invokeMethod(molObject,        // pointer to a QObject
     642                                      "bondInserted",       // member name (no parameters here)
     643                                      Qt::QueuedConnection,     // connection type
     644                                      Q_ARG(QtObservedBond::ptr, QtObservedBondMap[iter->first]));     // parameters
     645          } else {
     646            LOG(1, "INFO: Bond " << iter->first << " has been inserted and removed already.");
     647          }
     648        }
     649        ASSERT( (StateChangeAmounts[bondInsertedState] + StateChangeAmounts[bondInsertedState]
     650            + StateChangeAmounts[atomInsertedState] + StateChangeAmounts[atomRemovedState]) != 0,
     651            "GLWorldScene::moleculeInserted() - state with no changes for "+toString(iter->first));
     652        // removed all state changes for this atom/bond
    434653        MoleculeMissedStateMap[molid].erase(rangeiter.first, rangeiter.second);
    435654      } else {
     
    450669            break;
    451670          }
     671          case bondRemovedState:
     672            ASSERT( 0,
     673                "GLWorldScene::moleculeInserted() - bondRemoved state without bondInserted for bond "
     674                +toString(iter->first));
     675            break;
     676          case bondInsertedState:
     677          {
     678            LOG(1, "INFO: invoking bondInserted for bond " << iter->first);
     679            QMetaObject::invokeMethod(molObject,        // pointer to a QObject
     680                                      "bondInserted",       // member name (no parameters here)
     681                                      Qt::QueuedConnection,     // connection type
     682                                      Q_ARG(QtObservedBond::ptr, QtObservedBondMap[iter->first]));     // parameters
     683            break;
     684          }
    452685          default:
    453686            ASSERT( 0,
     
    455688            break;
    456689        }
    457         // removed state changes for this atom
     690        // removed state changes for this atom/bond
    458691        MoleculeMissedStateMap[molid].erase(iter);
    459692      }
  • src/UIElements/Views/Qt4/Qt3D/GLWorldScene.hpp

    rb4bd0e r96f14a  
    2828
    2929#include "UIElements/Qt4/InstanceBoard/QtObservedAtom.hpp"
     30#include "UIElements/Qt4/InstanceBoard/QtObservedBond.hpp"
    3031#include "UIElements/Qt4/InstanceBoard/QtObservedMolecule.hpp"
    3132
     
    9192  void moleculeClicked(moleculeId_t no);
    9293  void moleculeRemoved(QtObservedMolecule* _mol);
    93   void moleculeSignOff(ObservedValue_Index_t _id);
    9494  void moleculeEmpty(QtObservedMolecule::ptr _mol);
    9595  void moleculeInserted(QtObservedMolecule::ptr);
    9696  void moleculeSignOn(QtObservedMolecule::ptr);
     97  void moleculeSignOff(ObservedValue_Index_t _id);
    9798  void moleculesAtomRemoved(ObservedValue_Index_t _atomid, QtObservedMolecule * _mol);
    9899  void moleculesAtomInserted(QtObservedAtom::ptr, QtObservedMolecule *_mol);
     100  void moleculesBondRemoved(ObservedValue_Index_t _bondid, QtObservedMolecule * _mol);
     101  void moleculesBondInserted(QtObservedBond::ptr, QtObservedMolecule *_mol);
    99102  void atomRemoved(ObservedValue_Index_t _atomid);
    100103  void atomInserted(QtObservedAtom::ptr);
     104  void bondRemoved(ObservedValue_Index_t _bondid);
     105  void bondInserted(QtObservedBond::ptr);
     106  void bondsMoleculeChanged(moleculeId_t _oldid, moleculeId_t _newid);
    101107  void setSelectionModeAtom();
    102108  void setSelectionModeMolecule();
     
    122128    atomInsertedState,
    123129    atomRemovedState,
     130    bondInsertedState,
     131    bondRemovedState,
    124132    MAX_StateChangeType
    125133  };
    126134  typedef std::map< ObservedValue_Index_t, QtObservedAtom::ptr> QtObservedAtomMap_t;
     135  typedef std::map< ObservedValue_Index_t, QtObservedBond::ptr> QtObservedBondMap_t;
    127136  typedef std::map< ObservedValue_Index_t, QtObservedMolecule::ptr> QtObservedMoleculeMap_t;
    128137  typedef std::multimap< ObservedValue_Index_t, StateChangeType> StateChangeMap_t;
    129   typedef std::map< ObservedValue_Index_t, StateChangeMap_t> MoleculeMissedStateMap_t;
     138  typedef std::map< ObservedValue_Index_t, StateChangeMap_t> MissedStateMap_t;
    130139  //!> map of all missed state changes
    131   MoleculeMissedStateMap_t MoleculeMissedStateMap;
     140  MissedStateMap_t MoleculeMissedStateMap;
    132141  //!> map to contain all QtObservedAtom that have not been instantiated so far
    133142  QtObservedAtomMap_t QtObservedAtomMap;
     143  //!> map to contain all QtObservedBond that have not been instantiated so far
     144  QtObservedBondMap_t QtObservedBondMap;
    134145  //!> map to contain all QtObservedMolecule that have not been instantiated so far
    135146  QtObservedMoleculeMap_t QtObservedMoleculeMap;
Note: See TracChangeset for help on using the changeset viewer.