Index: src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.cpp
===================================================================
--- src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.cpp	(revision 907636a5dab60af4f441f0c8888aadfce03987fc)
+++ src/UIElements/Views/Qt4/Qt3D/GLMoleculeObject.cpp	(revision 907636a5dab60af4f441f0c8888aadfce03987fc)
@@ -0,0 +1,206 @@
+/*
+ * Project: MoleCuilder
+ * Description: creates and alters molecular systems
+ * Copyright (C)  2010 University of Bonn. All rights reserved.
+ * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
+ */
+
+/*
+ * GLMoleculeObject.cpp
+ *
+ *  This is based on the Qt3D example "teaservice", specifically meshobject.cpp.
+ *
+ *  Created on: Aug 17, 2011
+ *      Author: heber
+ */
+
+// include config.h
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "GLMoleculeObject.hpp"
+
+#include <Qt3D/qglview.h>
+#include <Qt3D/qglscenenode.h>
+#include <Qt3D/qglpainter.h>
+#include <Qt3D/qglmaterial.h>
+
+#include "CodePatterns/MemDebug.hpp"
+
+#include "CodePatterns/Assert.hpp"
+#include "CodePatterns/Log.hpp"
+
+#include "Helpers/defs.hpp"
+#include "element.hpp"
+#include "periodentafel.hpp"
+#include "World.hpp"
+
+GLMoleculeObject::ElementMaterialMap GLMoleculeObject::ElementNoMaterialMap;
+
+
+#include "CodePatterns/MemDebug.hpp"
+
+
+GLMoleculeObject::GLMoleculeObject(QGLSceneNode *GLMoleculeObject, QObject *parent)
+   : QObject(parent)
+{
+   m_mesh = 0;
+   m_GLMoleculeObject = GLMoleculeObject;
+   m_scale = 1.0f;
+   m_rotationAngle = 0.0f;
+   m_effect = 0;
+   m_objectId = -1;
+   m_hovering = false;
+   m_material = 0;
+   m_hoverMaterial = 0;
+}
+
+GLMoleculeObject::GLMoleculeObject(QGLAbstractScene *scene, QObject *parent)
+   : QObject(parent)
+{
+   scene->setParent(this);
+   m_mesh = 0;
+   m_GLMoleculeObject = scene->mainNode();
+   m_scale = 1.0f;
+   m_rotationAngle = 0.0f;
+   m_effect = 0;
+   m_objectId = -1;
+   m_hovering = false;
+   m_material = 0;
+   m_hoverMaterial = 0;
+}
+
+GLMoleculeObject::~GLMoleculeObject()
+{
+   delete m_mesh;
+}
+
+void GLMoleculeObject::initialize(QGLView *view, QGLPainter *painter)
+{
+   Q_UNUSED(painter);
+   if (m_objectId != -1)
+       view->registerObject(m_objectId, this);
+}
+
+void GLMoleculeObject::draw(QGLPainter *painter)
+{
+   // Position the model at its designated position, scale, and orientation.
+   painter->modelViewMatrix().push();
+   painter->modelViewMatrix().translate(m_position);
+   if (m_scale != 1.0f)
+       painter->modelViewMatrix().scale(m_scale);
+   if (m_rotationAngle != 0.0f)
+       painter->modelViewMatrix().rotate(m_rotationAngle, m_rotationVector);
+
+   // Apply the material and effect to the painter.
+   QGLMaterial *material;
+   if (m_hovering)
+       material = m_hoverMaterial;
+   else
+       material = m_material;
+   painter->setColor(material->diffuseColor());
+   painter->setFaceMaterial(QGL::AllFaces, material);
+   if (m_effect)
+       painter->setUserEffect(m_effect);
+   else
+       painter->setStandardEffect(QGL::LitMaterial);
+
+   // Mark the object for object picking purposes.
+   int prevObjectId = painter->objectPickId();
+   if (m_objectId != -1)
+       painter->setObjectPickId(m_objectId);
+
+   // Draw the geometry mesh.
+   if (m_GLMoleculeObject)
+       m_GLMoleculeObject->draw(painter);
+   else
+       m_mesh->draw(painter);
+
+   // Turn off the user effect, if present.
+   if (m_effect)
+       painter->setStandardEffect(QGL::LitMaterial);
+
+   // Revert to the previous object identifier.
+   painter->setObjectPickId(prevObjectId);
+
+   // Restore the modelview matrix.
+   painter->modelViewMatrix().pop();
+}
+
+bool GLMoleculeObject::event(QEvent *e)
+{
+   // Convert the raw event into a signal representing the user's action.
+   if (e->type() == QEvent::MouseButtonPress) {
+       QMouseEvent *me = (QMouseEvent *)e;
+       if (me->button() == Qt::LeftButton)
+           emit pressed();
+   } else if (e->type() == QEvent::MouseButtonRelease) {
+       QMouseEvent *me = (QMouseEvent *)e;
+       if (me->button() == Qt::LeftButton) {
+           emit released();
+           if (me->x() >= 0)   // Positive: inside object, Negative: outside.
+               emit clicked();
+       }
+   } else if (e->type() == QEvent::MouseButtonDblClick) {
+       emit doubleClicked();
+   } else if (e->type() == QEvent::Enter) {
+       m_hovering = true;
+       emit hoverChanged();
+   } else if (e->type() == QEvent::Leave) {
+       m_hovering = false;
+       emit hoverChanged();
+   }
+   return QObject::event(e);
+}
+
+/** Returns the ref to the Material for element No \a from the map.
+ *
+ * \note We create a new one if the element is missing.
+ *
+ * @param no element no
+ * @return ref to QGLMaterial
+ */
+QGLMaterial* GLMoleculeObject::getMaterial(size_t no)
+{
+  ASSERT( (no >= 0) && (no < MAX_ELEMENTS),
+      "GLMoleculeView::getMaterial() - Element no "+toString(no)+" is invalid.");
+  if (ElementNoMaterialMap.find(no) != ElementNoMaterialMap.end()){
+    // get present one
+    return ElementNoMaterialMap[no];
+  } else {
+    // create new one
+    LOG(1, "Creating new material for element "+toString(no)+".");
+    QGLMaterial *newmaterial = new QGLMaterial(NULL);
+
+    if (no == 0) { // create hover material
+      newmaterial->setAmbientColor( QColor(0, 128, 128) );
+    } else { // create material for element
+      periodentafel *periode = World::getInstance().getPeriode();
+      const element *desiredelement = periode->FindElement(no);
+      ASSERT(desiredelement != NULL,
+          "GLMoleculeView::getMaterial() - desired element "+toString(no)+" not present in periodentafel.");
+      const unsigned char* color = desiredelement->getColor();
+      LOG(1, "Creating new material with color " << (int)color[0] << "," << (int)color[1] << "," << (int)color[2] << ".");
+      newmaterial->setAmbientColor( QColor((int)color[0], (int)color[1], (int)color[2]) );
+    }
+    newmaterial->setSpecularColor( QColor(60, 60, 60) );
+    newmaterial->setShininess( 128 );
+    ElementNoMaterialMap.insert( make_pair(no, newmaterial) );
+
+    return newmaterial;
+  }
+}
+
+/** Static function to be called when Materials have to be removed.
+ *
+ */
+void GLMoleculeObject::cleanMaterialMap()
+{
+  for (ElementMaterialMap::iterator iter = ElementNoMaterialMap.begin();
+      !ElementNoMaterialMap.empty();
+      iter = ElementNoMaterialMap.begin()) {
+    delete iter->second;
+    ElementNoMaterialMap.erase(iter);
+  }
+}
