]> Git trees. - libqmvoc.git/commitdiff
Required: OpenBabel SVN revision 1534 or later
authorBenoît Jacob <jacob.benoit.1@gmail.com>
Sat, 22 Jul 2006 09:31:50 +0000 (09:31 +0000)
committerBenoît Jacob <jacob.benoit.1@gmail.com>
Sat, 22 Jul 2006 09:31:50 +0000 (09:31 +0000)
Make use again of OBMol::Center() and don't check anymore for weird bond
orders since Geoff fixed the cml-parsing

Fixed selection of atoms. Though, I've got a weird segfault when I
highlight 4 atoms or more, I don't understand what's happening. Atoms
are now highlighted in white because blue is taken by Nitrogen (OB's
color scheme), what do you think Carsten? I don't know what to do about
Hydrogen.

Re-enabled USE_DISPLAY_LISTS. With Mesa 6.5 (as provided with xorg 7.1)
I don't have problems, so maybe that was fixed between Mesa 6.2 and 6.5.
If anyone here has problems like "bonds are rendered too bright", please
tell me.

Some cosmetic changes in VertexArray.

Updated TODO.

CCMAIL: geoff@geoffhutchison.net

M    kalzium/ideas/TODO
M    kalzium/src/kalziumglwidget.h
M    kalzium/src/kalziumglhelperclasses.h
M    kalzium/src/moleculeview.cpp
M    kalzium/src/kalziumglwidget.cpp
M    kalzium/src/kalziumglhelperclasses.cpp

svn path=/trunk/KDE/kdeedu/kalzium/src/kalziumglwidget.h; revision=565050

kalzium/kalziumglhelperclasses.cpp
kalzium/kalziumglhelperclasses.h
kalzium/kalziumglwidget.cpp
kalzium/kalziumglwidget.h

index aabf99eae2ae5bdaed1defdac4edaae29bf82603..6b250f0064fc8dacf3f8baabc95ba399f804ba6b 100644 (file)
@@ -16,7 +16,7 @@
 using namespace KalziumGLHelpers;
 using namespace OpenBabel;
 
-void MolStyle::setup( BondStyle bondStyle, AtomStyle atomStyle,
+MolStyle::MolStyle( BondStyle bondStyle, AtomStyle atomStyle,
        double singleBondRadius,
        bool renderMultipleBonds,
        double multipleBondRadius,
@@ -32,6 +32,19 @@ void MolStyle::setup( BondStyle bondStyle, AtomStyle atomStyle,
        m_atomRadiusFactor = atomRadiusFactor;
 }
 
+MolStyle& MolStyle::operator=( const MolStyle& other )
+{
+       m_bondStyle = other.m_bondStyle;
+       m_atomStyle = other.m_atomStyle;
+       m_singleBondRadius = other.m_singleBondRadius;
+       m_renderMultipleBonds = other.m_renderMultipleBonds;
+       m_multipleBondRadius = other.m_multipleBondRadius;
+       m_multipleBondShift = other.m_multipleBondShift;
+       m_atomRadiusFactor = other.m_atomRadiusFactor;
+
+       return *this;
+}
+
 double MolStyle::getAtomRadius( int atomicNumber )
 {
        switch( m_atomStyle )
@@ -189,8 +202,8 @@ void VertexArray::compileDisplayList()
 void VertexArray::initialize()
 {
        m_isValid = false;
-       m_vertexCount = computeVertexCount();
-       m_indexCount = computeIndexCount();
+       m_vertexCount = getVertexCount();
+       m_indexCount = getIndexCount();
        if( m_indexCount < 0 || m_vertexCount < 0 ) return;
        if( ! allocateBuffers() ) return;
        buildBuffers();
@@ -292,13 +305,13 @@ void Sphere::computeVertex( int strip, int column, int row)
        vertex->z = v.z();
 }
 
-int Sphere::computeVertexCount()
+int Sphere::getVertexCount()
 {
        if( m_detail < 1 ) return -1;
        return ( 3 * m_detail + 1 ) * ( 5 * m_detail + 1 );
 }
 
-int Sphere::computeIndexCount()
+int Sphere::getIndexCount()
 {
        if( m_detail < 1 ) return -1;
        return (2 * ( 2 * m_detail + 1 ) + 2 ) * 5 * m_detail;
@@ -368,7 +381,7 @@ void Cylinder::setup( int faces )
        initialize();
 }
 
-int Cylinder::computeVertexCount()
+int Cylinder::getVertexCount()
 {
        if( m_faces < 3 ) return -1;
        return 2 * m_faces + 2;
index 0b0b821df8aa26ca87db99dd56773d1bae5e4f34..c5a546b9923a11540ecc5e0a6be1a2d7f29b80e3 100644 (file)
@@ -27,7 +27,7 @@
  * counter. Use only for testing: this makes the GL Widget constantly
  * redraw, which under normal circumstances is a waste of CPU time.
  */
-#define USE_FPS_COUNTER 
+#define USE_FPS_COUNTER
 
 /** USE_DISPLAY_LISTS: if defined, the whole scene will be stored in
  * an OpenGL display list. The vertex arrays will then be converted into
@@ -35,7 +35,7 @@
  * This option improves performance, especially when rendering complex models,
  * but increases memory usage.
  */
-//#define USE_DISPLAY_LISTS
+#define USE_DISPLAY_LISTS
 
 namespace KalziumGLHelpers
 {
@@ -87,15 +87,17 @@ struct MolStyle
         * ATOMS_USE_FIXED_RADIUS, this s interpreted as the radius itself. */
        double m_atomRadiusFactor;
 
-       /** This method is just a convenient way to set the values of
-        * the members. */
-       void setup( BondStyle bondStyle, AtomStyle atomStyle,
+       MolStyle() {}
+
+       MolStyle( BondStyle bondStyle, AtomStyle atomStyle,
                double singleBondRadius,
                bool renderMultipleBonds,
                double multipleBondRadius,
                double multipleBondShift,
                double atomRadiusFactor );
 
+       MolStyle& operator=( const MolStyle& other );
+
        /** This function returns the radius in which an atom with given atomic
         * number should be rendered, when using this style */
        double getAtomRadius( int atomicNumber );
@@ -158,7 +160,9 @@ struct Color
 bool createOrthoBasisGivenFirstVector( const OpenBabel::vector3 &U, OpenBabel::vector3 & v, OpenBabel::vector3 & w );
 
 /**
-* This is an abstract base class for an OpenGL vertex array.
+* This is an abstract base class for an OpenGL vertex array, with an option
+* (controlled by USE_DISPLAY_LISTS) to compile a display list from it, in which
+* case the vertex array is freed and only the display list is kept.
 *
 * @author Benoit Jacob
 */
@@ -178,14 +182,14 @@ class VertexArray
 
                /** Pointer to the buffer storing the vertex array */
                Vector *m_vertexBuffer;
-               /** Pointer to the buffer storing the normal array
+               /** Pointer to the buffer storing the normal array.
                 * If m_hasSeparateNormalBuffer is false, then this is equal
                 * to m_vertexBuffer. */
                Vector *m_normalBuffer;
                /** Pointer to the buffer storing the indices */
                unsigned short *m_indexBuffer;
                /** The mode in which OpenGL should interpred the vertex arrays
-                * (for example, that could be GL_TRIANGLE_STRIP) */
+                * (for example, this could be GL_TRIANGLE_STRIP) */
                GLenum m_mode;
                /** The number of vertices, i.e. the size of m_vertexBuffer
                 * or equivalently m_normalBuffer */
@@ -208,14 +212,14 @@ class VertexArray
                bool m_isValid;
                
                /** This pure virtual method should return the number of
-                * vertices, as computed from certain properties of a child
-                * class */
-               virtual int computeVertexCount() = 0;
+                * vertices, as computed from certain properties determining
+                * the level of detail */
+               virtual int getVertexCount() = 0;
                /** This virtual method returns 0, and should be reimplemented
                 * in child classes to return the number of indices
-                * vertices as computed from certain properties of a child
-                * class */
-               virtual int computeIndexCount() { return 0; }
+                * as computed from certain properties determining
+                * the level of detail */
+               virtual int getIndexCount() { return 0; }
                /** This method allocates enough memory for the buffers. It
                 * should only be called once m_vertexCount and m_indexCount
                 * have been set. */
@@ -233,8 +237,8 @@ class VertexArray
                 * compiles the display list and then calls freeBuffers().
                 * It should only be called after buildBuffers(). */
                void compileDisplayList();
-               /** This is a convenient method calling computeVertexCount(),
-                * computeIndexCount(), allocateBuffers(), buildBuffers() and
+               /** This is a convenient method calling getVertexCount(),
+                * getIndexCount(), allocateBuffers(), buildBuffers() and
                 * compileDisplayList() in that order, thus doing all the
                 * initialization, whether or not display list compilation is
                 * enabled. */
@@ -299,8 +303,8 @@ class Sphere : public VertexArray
                 * icosahedron */
                int m_detail;
 
-               virtual int computeVertexCount();
-               virtual int computeIndexCount();
+               virtual int getVertexCount();
+               virtual int getIndexCount();
                virtual void buildBuffers();
 
        public:
@@ -331,7 +335,7 @@ class Cylinder : public VertexArray
                 * two discs) are not rendered. */
                int m_faces;
 
-               virtual int computeVertexCount();
+               virtual int getVertexCount();
                virtual void buildBuffers();
 
        public:
index 078f72fbb95826f11c7fe4be515f152a0ceb9f67..0d0f38b8fdeb57c97a760c0711ac63a3ee71a44c 100644 (file)
@@ -42,13 +42,12 @@ KalziumGLWidget::KalziumGLWidget( QWidget * parent )
        m_inZoom = false;
        m_inMeasure = false;
 
-       slotSetMolStyle( 0 );
-
        QFont f;
        f.setStyleHint( QFont::SansSerif, QFont::PreferAntialias );
        m_textRenderer.setup( this, f );
        
        setMinimumSize( 100,100 );
+       setMolStyle( 0 );
 }
 
 KalziumGLWidget::~KalziumGLWidget()
@@ -87,8 +86,6 @@ void KalziumGLWidget::initializeGL()
        glFogfv( GL_FOG_COLOR, fogColor );
        glFogi( GL_FOG_MODE, GL_LINEAR );
        glFogf( GL_FOG_DENSITY, 0.45 );
-       glFogf( GL_FOG_START, 2.7 * getMolRadius() );
-       glFogf( GL_FOG_END, 5.0 * getMolRadius() );
 
        glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
@@ -98,6 +95,8 @@ void KalziumGLWidget::initializeGL()
 
        glEnableClientState( GL_VERTEX_ARRAY );
        glEnableClientState( GL_NORMAL_ARRAY );
+
+       setupObjects();
 }
 
 void KalziumGLWidget::paintGL()
@@ -154,7 +153,6 @@ void KalziumGLWidget::paintGL()
        }
        glCallList( m_displayList );
 #endif
-
        renderSelection();
 
 #ifdef USE_FPS_COUNTER
@@ -165,48 +163,38 @@ void KalziumGLWidget::paintGL()
 
 void KalziumGLWidget::renderAtoms()
 {
-       if( m_molStyle.m_atomStyle == MolStyle::ATOMS_DISABLED ) return;
-
-       FOR_ATOMS_OF_MOL( atom, m_molecule )
+       if( m_molStyle.m_atomStyle != MolStyle::ATOMS_DISABLED )
        {
+               FOR_ATOMS_OF_MOL( atom, m_molecule )
+               {
                        drawAtom( &*atom );
+               }
        }
 }
 
 void KalziumGLWidget::renderBonds()
 {
-       if( m_molStyle.m_bondStyle == MolStyle::BONDS_DISABLED ) return;
-
-       // render the bonds
-       FOR_BONDS_OF_MOL( bond, m_molecule )
+       if( m_molStyle.m_bondStyle != MolStyle::BONDS_DISABLED )
        {
-               drawBond( &*bond );
+               FOR_BONDS_OF_MOL( bond, m_molecule )
+               {
+                       drawBond( &*bond );
+               }
        }
 }
 
 void KalziumGLWidget::renderSelection()
 {
-/*     if( ! m_selectedAtoms.count() ) return;
-       
-       Color c( 0.4, 0.4, 1.0, 0.7 );
-
-       GLdouble radius = m_molMinBondLength * 0.35;
-       const GLdouble min_radius = (GLdouble) atomRadius () * 1.25;
-       if( radius < min_radius ) radius = min_radius;
+       if( ! m_selectedAtoms.count() ) return;
 
+       Color c( 1.0, 1.0, 1.0, 0.5 );
        glEnable( GL_BLEND );
-       glEnable( GL_LIGHTING );
-*/
-/*     foreach(OpenBabel::OBAtom* atom, m_selectedAtoms)
-       {//iterate through all OBAtoms and highlight one after eachother
-
-               drawSphere(
-                               x, y, z,
-                               radius,
-                               c);
+       foreach(OpenBabel::OBAtom* atom, m_selectedAtoms)
+       {
+               c.applyAsMaterials();
+               m_sphere.draw( atom->GetVector(),
+                       0.18 + m_molStyle.getAtomRadius( atom ) );
        }
-*/
-
        glDisable( GL_BLEND );
 }
 
@@ -360,25 +348,11 @@ void KalziumGLWidget::drawBond( OBBond *bond )
        vector3 v3 = ( v1 + v2 ) / 2;
 
        int order;
-       if( m_molStyle.m_renderMultipleBonds == false
-        || bond->IsSingle() ) order = 1;
+       if( m_molStyle.m_renderMultipleBonds == false || bond->IsSingle() )
+               order = 1;
        else if( bond->IsDouble() ) order = 2;
        else if( bond->IsTriple() ) order = 3;
-       else
-       {
-               order = bond->GetBondOrder();
-               if( order > 12 ) // probably a bogus molecule file!
-                       // according to the element.txt file in OB,
-                       // no element can have more than 12 bonds
-               {
-                       order = 1;
-                       kDebug()<<"Umm, some bond pretends to have "
-                               "order "<<bond->GetBondOrder()<<endl;
-                       kDebug()<<"I'd better close now, 'cause I feel "
-                               "like I might segfault any time!"<<endl;
-                       parentWidget()->parentWidget()->close();
-               }
-       }
+       else order = bond->GetBondOrder();
 
        double radius;
        if( order == 1 ) radius = m_molStyle.m_singleBondRadius;
@@ -387,7 +361,7 @@ void KalziumGLWidget::drawBond( OBBond *bond )
        switch( m_molStyle.m_bondStyle )
        {
                case MolStyle::BONDS_GRAY:
-                       Color( 0.5, 0.5, 0.5 ).applyAsMaterials();
+                       Color( 0.55, 0.55, 0.55 ).applyAsMaterials();
                        m_cylinder.draw( v1, v2, radius, order,
                                m_molStyle.m_multipleBondShift );
                        break;
@@ -428,32 +402,33 @@ void KalziumGLWidget::slotSetMolecule( OpenBabel::OBMol* molecule )
        if ( !molecule ) return;
        m_molecule = molecule;
        m_haveToRecompileDisplayList = true;
+       m_selectedAtoms.clear();
        prepareMoleculeData();
        setupObjects();
        updateGL();
 }
 
-void KalziumGLWidget::slotSetMolStyle( int style )
+void KalziumGLWidget::setMolStyle( int style )
 {
        switch( style )
        {
                case 0: // sticks-style
-                       m_molStyle.setup( MolStyle::BONDS_USE_ATOMS_COLORS,
+                       m_molStyle = MolStyle( MolStyle::BONDS_USE_ATOMS_COLORS,
                                MolStyle::ATOMS_USE_FIXED_RADIUS,
                                0.20, false, 0.06, 0.14, 0.20 );
                        break;
                case 1: // atoms: smaller van der Waals, bonds: gray
-                       m_molStyle.setup( MolStyle::BONDS_GRAY,
+                       m_molStyle = MolStyle( MolStyle::BONDS_GRAY,
                                MolStyle::ATOMS_USE_VAN_DER_WAALS_RADIUS,
                                0.08, true, 0.08, 0.14, 0.20 );
                        break;
                case 2: // atoms: smaller van der Waals, bonds: use atom colors
-                       m_molStyle.setup( MolStyle::BONDS_USE_ATOMS_COLORS,
+                       m_molStyle = MolStyle( MolStyle::BONDS_USE_ATOMS_COLORS,
                                MolStyle::ATOMS_USE_VAN_DER_WAALS_RADIUS,
                                0.08, true, 0.08, 0.14, 0.20 );
                        break;
                case 3: // atoms: real van der Waals, bonds: disabled
-                       m_molStyle.setup( MolStyle::BONDS_DISABLED,
+                       m_molStyle = MolStyle( MolStyle::BONDS_DISABLED,
                                MolStyle::ATOMS_USE_VAN_DER_WAALS_RADIUS,
                                0.00, false, 0.00, 0.00, 1.00 );
                        break;
@@ -461,6 +436,11 @@ void KalziumGLWidget::slotSetMolStyle( int style )
                default: break;
        }
        m_haveToRecompileDisplayList = true;
+}
+
+void KalziumGLWidget::slotSetMolStyle( int style )
+{
+       setMolStyle( style );
        setupObjects();
        updateGL();
 }
@@ -468,32 +448,11 @@ void KalziumGLWidget::slotSetMolStyle( int style )
 void KalziumGLWidget::prepareMoleculeData()
 {
        //Center the molecule
-       //normally this is done by OBMol::Center()
-       //but it doesn't seem to work for me
-       //perhaps I'm stupid (Benoit 03/07/06)
-
-       //first, calculate the coords of the center of the molecule
-       vector3 center( 0.0, 0.0, 0.0 );
-       int number_of_atoms = 0;
-       FOR_ATOMS_OF_MOL( a, m_molecule )
-       {
-               center += a->GetVector();
-               number_of_atoms++;
-       }
-       center /= number_of_atoms;
-
-       //now, translate the molecule so that it gets centered.
-       //unfortunately OBMol::Translate doesn't seem to work for me
-       //(Benoit 03/07/06)
-       FOR_ATOMS_OF_MOL( a, m_molecule )
-       {
-               vector3 new_vector = a->GetVector() - center;
-               a->SetVector( new_vector );
-       }
+       m_molecule->Center();
 
-       // calculate the radius of the molecule
-       // that is, the maximal distance between an atom of the molecule
-       // and the center of the molecule
+       // calculate the radius of the molecule without the electrons
+       // that is, the maximal distance between the center of an atom
+       // of the molecule and the center of the molecule
        m_molRadiusWithoutElectrons = 0.0;
        FOR_ATOMS_OF_MOL( a, m_molecule )
        {
index bbd124652a125fc1c6c4c8888996a30ee6de4dc9..10b7e1f16e7e1956caf04c3f2f19ab996a875a62 100644 (file)
@@ -222,6 +222,15 @@ class KalziumGLWidget : public QGLWidget
                 * cylinder ).
                 */
                virtual void setupObjects();
+
+               /**
+                * Sets the molecule style, but contrary to slotSetMolStyle,
+                * doesn't call setupObjects and updateGL. Useful for
+                * setting the initial style when the GL widget is created.
+                * Called by slotSetMolStyle.
+                * @param style the wanted molecule style
+                */
+               void setMolStyle( int style );
 };
 #endif // KALZIUMGLWIDGET_H