/*
* Project: MoleCuilder
* Description: creates and alters molecular systems
* Copyright (C) 2010-2012 University of Bonn. All rights reserved.
* Copyright (C) 2013 Frederik Heber. All rights reserved.
*
*
* This file is part of MoleCuilder.
*
* MoleCuilder is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* MoleCuilder is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MoleCuilder. If not, see .
*/
/*
* GLWorldScene.cpp
*
* This is based on the Qt3D example "teaservice", specifically parts of teaservice.cpp.
*
* Created on: Aug 17, 2011
* Author: heber
*/
// include config.h
#ifdef HAVE_CONFIG_H
#include
#endif
#include "GLWorldScene.hpp"
#include
#include
#include
#include
#include
#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject.hpp"
#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_atom.hpp"
#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_bond.hpp"
#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_molecule.hpp"
#include "UIElements/Views/Qt4/Qt3D/GLMoleculeObject_shape.hpp"
#include "UIElements/Qt4/InstanceBoard/QtObservedInstanceBoard.hpp"
#include "CodePatterns/MemDebug.hpp"
#include "CodePatterns/Log.hpp"
#include
#include "Actions/SelectionAction/Atoms/AtomByIdAction.hpp"
#include "Actions/SelectionAction/Atoms/NotAtomByIdAction.hpp"
#include "Actions/SelectionAction/Molecules/MoleculeByIdAction.hpp"
#include "Actions/SelectionAction/Molecules/NotMoleculeByIdAction.hpp"
#include "Atom/atom.hpp"
#include "Bond/bond.hpp"
#include "Descriptors/AtomIdDescriptor.hpp"
#include "Descriptors/MoleculeIdDescriptor.hpp"
#include "Helpers/helpers.hpp"
#include "Shapes/ShapeRegistry.hpp"
#include "molecule.hpp"
#include "World.hpp"
#include
using namespace MoleCuilder;
GLWorldScene::GLWorldScene(
QtObservedInstanceBoard * _board,
QObject *parent) :
QObject(parent),
BondNodeParentMaps(std::vector(2)),
selectionMode(SelectAtom),
board(_board)
{
qRegisterMetaType("atomId_t");
qRegisterMetaType("GLMoleculeObject_bond::SideOfBond");
int sphereDetails[] = {5, 3, 2, 0};
int cylinderDetails[] = {16, 8, 6, 3};
for (int i=0;isetOption(QGLSceneNode::CullBoundingBox, true);
QGLBuilder cylinderBuilder;
cylinderBuilder << QGLCylinder(.25,.25,1.0,cylinderDetails[i]);
GLMoleculeObject::meshCylinder[i] = cylinderBuilder.finalizedSceneNode();
GLMoleculeObject::meshCylinder[i]->setOption(QGLSceneNode::CullBoundingBox, true);
}
connect(board, SIGNAL(moleculeInserted(QtObservedMolecule::ptr)),
this, SLOT(insertMolecule(QtObservedMolecule::ptr)));
connect(board, SIGNAL(moleculeRemoved(ObservedValue_Index_t)),
this, SLOT(removeMolecule(ObservedValue_Index_t)));
connect(board, SIGNAL(atomInserted(QtObservedAtom::ptr)),
this, SLOT(connectAtom(QtObservedAtom::ptr)), Qt::DirectConnection);
connect(this, SIGNAL(atomConnected(QtObservedAtom::ptr)),
this, SLOT(insertAtom(QtObservedAtom::ptr)));
connect(board, SIGNAL(atomRemoved(ObservedValue_Index_t)),
this, SLOT(removeAtom(ObservedValue_Index_t)));
connect(board, SIGNAL(bondInserted(QtObservedBond::ptr)),
this, SLOT(connectBond(QtObservedBond::ptr)), Qt::DirectConnection);
connect(this, SIGNAL(bondConnected(QtObservedBond::ptr)),
this, SLOT(insertBond(QtObservedBond::ptr)));
connect(board, SIGNAL(bondRemoved(ObservedValue_Index_t)),
this, SLOT(removeBond(ObservedValue_Index_t)));
// connect(this, SIGNAL(updated()), this, SLOT(update()));
}
GLWorldScene::~GLWorldScene()
{
// remove all elements
GLMoleculeObject::cleanMaterialMap();
}
void GLWorldScene::clickAtom(atomId_t no)
{
LOG(3, "INFO: GLWorldScene - atom " << no << " has been clicked.");
const atom * const Walker = const_cast(World::getInstance()).
getAtom(AtomById(no));
ASSERT( Walker != NULL,
"GLWorldScene::clickAtom() - clicked atom has disappeared.");
if (selectionMode == SelectAtom){
if (!World::getInstance().isSelected(Walker))
SelectionAtomById(std::vector(1,no));
else
SelectionNotAtomById(std::vector(1,no));
}else if (selectionMode == SelectMolecule){
const molecule *mol = Walker->getMolecule();
ASSERT(mol, "Atom without molecule has been clicked.");
molids_t ids(1, mol->getId());
if (!World::getInstance().isSelected(mol))
SelectionMoleculeById(ids);
else
SelectionNotMoleculeById(ids);
}
emit clicked(no);
}
/** Prepares adding an atom to the scene
*
* We need to listen to moleculeChanged() in order to properly re-parent()
* this QObject
*
* @param _atom atom to connect
*/
void GLWorldScene::connectAtom(QtObservedAtom::ptr _atom)
{
connect(_atom.get(), SIGNAL(moleculeChanged()), this, SLOT(reparentAtom()));
{
const ObservedValue_Index_t atomid = _atom->getIndex();
boost::recursive_mutex::scoped_lock lock(AtomNodeParentMap_mutex);
AtomNodeParentMap.left.insert( std::make_pair(atomid, (ObservedValue_Index_t)NULL) );
}
emit atomConnected(_atom);
}
/** Adds an atom to the scene.
*
* @param _atom atom to add
*/
void GLWorldScene::insertAtom(QtObservedAtom::ptr _atom)
{
LOG(3, "INFO: GLWorldScene: Received signal atomInserted for atom "
<< _atom->getAtomIndex());
const ObservedValue_Index_t atomid = _atom->getIndex();
QObject *parent = static_cast(this);
GLMoleculeObject_atom *atomObject = NULL;
{
boost::recursive_mutex::scoped_lock lock(AtomNodeParentMap_mutex);
AtomNodeParentMap_t::left_iterator parentiter = AtomNodeParentMap.left.find(atomid);
ASSERT (parentiter != AtomNodeParentMap.left.end(),
"GLWorldScene::insertAtom() - parent to atom id "+toString(atomid)+" unknown?");
const ObservedValue_Index_t parentindex = parentiter->second;
if (parentindex != (ObservedValue_Index_t)NULL) {
const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(parentindex);
if (moliter != MoleculesinSceneMap.end())
parent = moliter->second;
}
atomObject = new GLMoleculeObject_atom(
GLMoleculeObject::meshSphere,
parent,
_atom);
ASSERT( atomObject != NULL,
"GLWorldScene::atomInserted - could not create atom object for "
+toString(_atom->getAtomIndex()));
}
AtomNodeMap::iterator iter = AtomsinSceneMap.find(atomid);
ASSERT(iter == AtomsinSceneMap.end(),
"GLWorldScene::insertAtom - same atom with id "
+toString(_atom->getAtomIndex())+" added again.");
AtomsinSceneMap.insert( make_pair(atomid, atomObject) );
connect (atomObject, SIGNAL(clicked(atomId_t)), this, SLOT(clickAtom(atomId_t)));
connect (atomObject, SIGNAL(changed()), this, SIGNAL(changed()));
connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SIGNAL(changed()));
connect (atomObject, SIGNAL(hoverChanged(GLMoleculeObject *)), this, SLOT(hoverChangedSignalled(GLMoleculeObject *)));
emit changed();
emit changeOccured();
}
/** Removes an atom.
*
* @param _atomid index of the atom that is removed
*/
void GLWorldScene::removeAtom(ObservedValue_Index_t _atomid)
{
LOG(3, "INFO: GLWorldScene: Received signal atomRemoved for atom "+toString(_atomid)+".");
// bonds are removed by signal coming from ~bond
// remove atoms
AtomNodeMap::iterator iter = AtomsinSceneMap.find(_atomid);
ASSERT(iter != AtomsinSceneMap.end(),
"GLWorldScene::removeAtom() - atom "+toString(_atomid)+" not on display.");
GLMoleculeObject_atom *atomObject = iter->second;
AtomsinSceneMap.erase(iter);
delete atomObject;
{
boost::recursive_mutex::scoped_lock lock(AtomNodeParentMap_mutex);
AtomNodeParentMap.left.erase(_atomid);
}
emit changed();
emit changeOccured();
}
/** Prepares adding a bond to the scene
*
* We need to listen to moleculeChanged() in order to properly re-parent()
* this QObject
*
* @param _bond bond to connect
*/
void GLWorldScene::connectBond(QtObservedBond::ptr _bond)
{
connect(_bond.get(), SIGNAL(leftmoleculeChanged()), this, SLOT(reparentBondLeft()));
connect(_bond.get(), SIGNAL(rightmoleculeChanged()), this, SLOT(reparentBondRight()));
{
const ObservedValue_Index_t bondid = _bond->getIndex();
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
if ((_bond->getLeftAtom() != NULL) && (_bond->getLeftAtom()->getMoleculeRef() != NULL))
BondNodeParentMaps[0].left.insert(
std::make_pair(bondid, _bond->getLeftAtom()->getMoleculeRef()->getIndex()) );
else
BondNodeParentMaps[0].left.insert(
std::make_pair(bondid, (ObservedValue_Index_t)NULL) );
if ((_bond->getRightAtom() != NULL) && (_bond->getRightAtom()->getMoleculeRef() != NULL))
BondNodeParentMaps[1].left.insert(
std::make_pair(bondid, _bond->getRightAtom()->getMoleculeRef()->getIndex()) );
else
BondNodeParentMaps[1].left.insert(
std::make_pair(bondid, (ObservedValue_Index_t)NULL) );
}
emit bondConnected(_bond);
}
/** Adds a bond to the scene.
*
* @param _bond bond to add
*/
void GLWorldScene::insertBond(QtObservedBond::ptr _bond)
{
static const std::vector< GLMoleculeObject_bond::SideOfBond > bondsides =
boost::assign::list_of
(GLMoleculeObject_bond::left)
(GLMoleculeObject_bond::right);
LOG(3, "INFO: GLWorldScene::insertBond() - Adding bonds " << _bond->getBondIndex());
const ObservedValue_Index_t bondid = _bond->getIndex();
#ifdef NDEBUG
BondNodeMap::iterator iter = BondsinSceneMap.find(bondid);
ASSERT( iter == BondsinSceneMap.end(),
"GLWorldScene::insertBond() - bond "+toString(bondid)+" is already known.");
#endif
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
for (size_t i=0;i<2;++i) {
BondNodeParentMap_t::left_iterator parentiter = BondNodeParentMaps[i].left.find(bondid);
ASSERT (parentiter != BondNodeParentMaps[i].left.end(),
"GLWorldScene::insertBond() - parent to bond id "+toString(bondid)+" unknown?");
QObject *parent = this;
if (parentiter->second != (ObservedValue_Index_t)NULL) {
const MoleculeNodeMap::iterator moliter = MoleculesinSceneMap.find(parentiter->second);
if (moliter != MoleculesinSceneMap.end())
parent = moliter->second;
}
GLMoleculeObject_bond *bondObject = new GLMoleculeObject_bond(
GLMoleculeObject::meshCylinder,
parent,
_bond,
bondsides[i]);
connect (bondObject, SIGNAL(changed()), this, SIGNAL(changed()));
BondsinSceneMap.insert( std::make_pair(bondid, bondObject) );
}
}
emit changed();
emit changeOccured();
}
/** Removes a bond.
*
* @param _bondid id of bond to remove
*/
void GLWorldScene::removeBond(ObservedValue_Index_t _bondid)
{
LOG(3, "INFO: GLWorldScene::removedBond() - Removing bond to id " << _bondid);
// left bond
std::pair iters =
BondsinSceneMap.equal_range(_bondid);
ASSERT( iters.first != iters.second,
"GLWorldScene::removedBond() - could not find bond to id "+toString(_bondid));
for (BondNodeMap::iterator iter = iters.first; iter != iters.second; ++iter) {
GLMoleculeObject_bond *bondObject = iter->second;
delete bondObject; // is done by signal from bond itself
//LOG(4, "INFO: Still present bonds " << BondsinSceneMap << ".");
}
BondsinSceneMap.erase(_bondid);
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
BondNodeParentMaps[0].left.erase(_bondid);
BondNodeParentMaps[1].left.erase(_bondid);
}
emit changed();
emit changeOccured();
}
void GLWorldScene::hoverChangedSignalled(GLMoleculeObject *ob)
{
// Find the atom, ob corresponds to.
hoverAtomId = -1;
GLMoleculeObject_atom *atomObject = dynamic_cast(ob);
if (atomObject){
for (AtomNodeMap::iterator iter = AtomsinSceneMap.begin();iter != AtomsinSceneMap.end(); ++ iter){
if (iter->second == atomObject)
hoverAtomId = iter->second->objectId();
}
// Propagate signal.
emit hoverChanged(hoverAtomId);
} else {
// Find the atom, ob corresponds to.
GLMoleculeObject_molecule *moleculeObject = dynamic_cast(ob);
if (moleculeObject){
// Propagate signal.
emit hoverChanged(moleculeObject->objectId(), 0);
}
}
}
void GLWorldScene::clickMolecule(moleculeId_t no)
{
LOG(3, "INFO: GLMoleculeObject_molecule - mol " << no << " has been clicked.");
const molecule * const mol= const_cast(World::getInstance()).
getMolecule(MoleculeById(no));
ASSERT(mol, "Atom without molecule has been clicked.");
molids_t ids(1, mol->getId());
if (!World::getInstance().isSelected(mol))
SelectionMoleculeById(ids);
else
SelectionNotMoleculeById(ids);
emit clicked(no);
}
/** Inserts a molecule into the scene.
*
* @param _mol molecule to insert
*/
void GLWorldScene::insertMolecule(QtObservedMolecule::ptr _mol)
{
const ObservedValue_Index_t molid = _mol->getIndex();
LOG(3, "INFO: GLWorldScene: Received signal moleculeInserted for molecule "
<< _mol->getMolIndex());
MoleculeNodeMap::const_iterator iter = MoleculesinSceneMap.find(molid);
ASSERT( iter == MoleculesinSceneMap.end(),
"GLWorldScene::insertMolecule() - molecule's id "+toString(molid)
+" already present.");
// add new object
LOG(1, "DEBUG: Adding GLMoleculeObject_molecule to id " << molid);
GLMoleculeObject_molecule *molObject =
new GLMoleculeObject_molecule(
GLMoleculeObject::meshEmpty,
this,
_mol);
ASSERT( molObject != NULL,
"GLWorldScene::insertMolecule - could not create molecule object for "
+toString(molid));
// check all atoms for not yet assigned parents
{
boost::recursive_mutex::scoped_lock lock(AtomNodeParentMap_mutex);
std::pair iters =
AtomNodeParentMap.right.equal_range(molid);
for (AtomNodeParentMap_t::right_const_iterator iter = iters.first;
iter != iters.second; ++iter) {
AtomNodeMap::const_iterator atomiter = AtomsinSceneMap.find(iter->second);
if (atomiter != AtomsinSceneMap.end())
resetParent(atomiter->second, molObject);
}
}
// check all bonds for not yet assigned parents
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
for (size_t i=0;i<2;++i) {
std::pair iters =
BondNodeParentMaps[i].right.equal_range(molid);
for (BondNodeParentMap_t::right_const_iterator iter = iters.first;
iter != iters.second; ++iter) {
BondNodeMap::const_iterator bonditer = BondsinSceneMap.find(iter->second);
if (bonditer != BondsinSceneMap.end())
resetParent(bonditer->second, molObject);
}
}
}
#ifndef NDEBUG
std::pair inserter =
#endif
MoleculesinSceneMap.insert( make_pair(molid, molObject) );
ASSERT(inserter.second,
"GLWorldScene::insertMolecule() - molecule "+toString(_mol->getMolIndex())
+" already present in scene.");
connect (molObject, SIGNAL(changed()), this, SIGNAL(changed()));
connect (molObject, SIGNAL(changeOccured()), this, SIGNAL(changeOccured()));
emit changed();
emit changeOccured();
}
/** Removes a molecule from the scene.
*
* @param _molid index of the molecule to remove
*/
void GLWorldScene::removeMolecule(ObservedValue_Index_t _molid)
{
LOG(3, "INFO: GLWorldScene: Received signal moleculeRemoved for molecule "+toString(_molid)+".");
MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_molid);
ASSERT ( iter != MoleculesinSceneMap.end(),
"GLWorldScene::removeMolecule() - to be removed molecule "+toString(_molid)
+" is already gone.");
// check if it's already empty
GLMoleculeObject_molecule *molObject = iter->second;
delete molObject;
MoleculesinSceneMap.erase(iter);
emit changed();
emit changeOccured();
}
void GLWorldScene::moleculesVisibilityChanged(ObservedValue_Index_t _id, bool _visible)
{
MoleculeNodeMap::iterator iter = MoleculesinSceneMap.find(_id);
ASSERT( iter != MoleculesinSceneMap.end(),
"GLWorldScene::moleculeInserted() - molecule's id "
+toString(board->getMoleculeIdToIndex(_id))+" is unknown.");
GLMoleculeObject_molecule *molObject = iter->second;
molObject->setVisible(_visible);
emit changed();
emit changeOccured();
}
/** This converts safely index into a GLMoleculeObject_molecule.
*
* \param _MoleculesinSceneMap all present molecules
* \param _molid index to look for
* \return MolObject or NULL when not found
*/
GLMoleculeObject_molecule *GLWorldScene::getMoleculeObject(
const ObservedValue_Index_t _molid) const
{
const MoleculeNodeMap::const_iterator moliter = MoleculesinSceneMap.find(_molid);
if (moliter != MoleculesinSceneMap.end())
return moliter->second;
else
return NULL;
}
/** Changes the parent of an object in the scene.
*
* \param _id index of the object whose parent to change
* \param _ob new parent
*/
void GLWorldScene::reparentAtom()
{
QtObservedAtom *walker = dynamic_cast(sender());
boost::recursive_mutex::scoped_lock lock(AtomNodeParentMap_mutex);
const ObservedValue_Index_t walkerid = walker->getIndex();
AtomNodeParentMap_t::left_iterator parentiter = AtomNodeParentMap.left.find(walkerid);
ASSERT( parentiter != AtomNodeParentMap.left.end(),
"GLWorldScene::reparentAtom() - could not find object to id "+toString(walkerid));
// change parent entry
AtomNodeParentMap.left.erase(parentiter);
if (walker->getMoleculeRef() != NULL)
AtomNodeParentMap.left.insert( std::make_pair(walkerid, walker->getMoleculeRef()->getIndex()) );
else
AtomNodeParentMap.left.insert( std::make_pair(walkerid, (ObservedValue_Index_t)NULL) );
parentiter = AtomNodeParentMap.left.find(walkerid);
const AtomNodeMap::iterator atomiter = AtomsinSceneMap.find(walkerid);
if (atomiter != AtomsinSceneMap.end())
resetParent(atomiter->second, getMoleculeObject(parentiter->second));
// else atom does not yet exist
}
/** Changes the parent of an left-side bond in the scene.
*
*/
void GLWorldScene::reparentBondLeft()
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
QtObservedBond *bond = dynamic_cast(sender());
reparentBond(bond, bond->getLeftAtom(), GLMoleculeObject_bond::left);
}
/** Changes the parent of an right-side bond in the scene.
*
*/
void GLWorldScene::reparentBondRight()
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
QtObservedBond *bond = dynamic_cast(sender());
reparentBond(bond, bond->getRightAtom(), GLMoleculeObject_bond::right);
}
GLMoleculeObject_bond *GLWorldScene::getBondInScene(
const ObservedValue_Index_t _bondid,
GLMoleculeObject_bond::SideOfBond _side) const
{
std::pair iters =
BondsinSceneMap.equal_range(_bondid);
ASSERT( std::distance(iters.first, iters.second) == 2,
"GLWorldScene::getBondInScene() - not exactly two bonds of same id "
+toString(_bondid)+" present in scene.");
for (GLWorldScene::BondNodeMap::const_iterator bonditer = iters.first;
bonditer != iters.second; ++bonditer) {
if (bonditer->second->BondSide == _side)
return bonditer->second;
}
return NULL;
}
/** Changes the parent of an object in the scene.
*
* \param _atom atom of bond whose molecule we are associated to
* \param _side side of bond
*/
void GLWorldScene::reparentBond(
QtObservedBond *_bond,
const QtObservedAtom * const _atom,
const GLMoleculeObject_bond::SideOfBond _side)
{
boost::recursive_mutex::scoped_lock lock(BondNodeParentMap_mutex);
const size_t dim = (_side == GLMoleculeObject_bond::left) ? 0 : 1;
const ObservedValue_Index_t bondid = _bond->getIndex();
BondNodeParentMap_t::left_iterator parentiter = BondNodeParentMaps[dim].left.find(bondid);
ASSERT( parentiter != BondNodeParentMaps[dim].left.end(),
"GLWorldScene::reparentBond() - could not find object to id "+toString(bondid));
// change parent entry
BondNodeParentMaps[dim].left.erase(bondid);
if ((_atom != NULL) && (_atom->getMoleculeRef() != NULL))
BondNodeParentMaps[dim].left.insert( std::make_pair( bondid, _atom->getMoleculeRef()->getIndex()));
else
BondNodeParentMaps[dim].left.insert( std::make_pair( bondid, (ObservedValue_Index_t)NULL) );
parentiter = BondNodeParentMaps[dim].left.find(bondid);
// reset parent
resetParent(getBondInScene(bondid, _side), getMoleculeObject(parentiter->second));
}
/** Resets the parent of an GLMoleculeObject.
*
* \param _obj object to reparent
* \param _molid index of parent molecule
*/
void GLWorldScene::resetParent(
GLMoleculeObject *_obj,
GLMoleculeObject_molecule *_molobj)
{
if (_obj != NULL) {
QObject *parent = this;
if (_molobj != NULL)
parent = _molobj;
// else: molecule does not yet exist: is done when molecule is instantiated
_obj->setParent(parent);
}
// else object does not yet exist
}
/** Adds a shape to the scene.
*
*/
void GLWorldScene::addShape(const std::string &_name)
{
Shape * const shape = ShapeRegistry::getInstance().getByName(_name);
if (shape != NULL) {
GLMoleculeObject_shape *shapeObject = new GLMoleculeObject_shape(*shape, this);
ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
ASSERT(iter == ShapesinSceneMap.end(),
"GLWorldScene::addShape() - same shape "+_name+" added again.");
ShapesinSceneMap.insert( make_pair(_name, shapeObject) );
} else
ELOG(2, "GLWorldScene::addShape() - shape disappeared before we could draw it.");
emit changed();
}
void GLWorldScene::removeShape(const std::string &_name)
{
ShapeNodeMap::iterator iter = ShapesinSceneMap.find(_name);
ASSERT(iter != ShapesinSceneMap.end(),
"GLWorldScene::removeShape() - shape "+_name+" not in scene.");
ShapesinSceneMap.erase(iter);
delete(iter->second);
emit changed();
}
void GLWorldScene::updateSelectedShapes()
{
foreach (QObject *obj, children()) {
GLMoleculeObject_shape *shapeobj = qobject_cast(obj);
if (shapeobj){
shapeobj->enable(ShapeRegistry::getInstance().isSelected(shapeobj->getShape()));
}
}
emit changed();
}
void GLWorldScene::initialize(QGLView *view, QGLPainter *painter) const
{
// Initialize all of the mesh objects that we have as children.
foreach (QObject *obj, children()) {
GLMoleculeObject *meshobj = qobject_cast(obj);
if (meshobj)
meshobj->initialize(view, painter);
}
}
void GLWorldScene::draw(QGLPainter *painter, const QVector4D &cameraPlane) const
{
// Draw all of the mesh objects that we have as children.
foreach (QObject *obj, children()) {
GLMoleculeObject *meshobj = qobject_cast(obj);
if (meshobj)
meshobj->draw(painter, cameraPlane);
}
}
void GLWorldScene::setSelectionMode(SelectionModeType mode)
{
selectionMode = mode;
// TODO send update to toolbar
}
void GLWorldScene::setSelectionModeAtom()
{
setSelectionMode(SelectAtom);
}
void GLWorldScene::setSelectionModeMolecule()
{
setSelectionMode(SelectMolecule);
}