]> Git trees. - libqmvoc.git/commitdiff
- fix compilation against latest OpenBabel (so you need to update your
authorBenoît Jacob <jacob.benoit.1@gmail.com>
Sun, 26 Nov 2006 12:17:25 +0000 (12:17 +0000)
committerBenoît Jacob <jacob.benoit.1@gmail.com>
Sun, 26 Nov 2006 12:17:25 +0000 (12:17 +0000)
OpenBabel)
- remove abstract base class VertexArray, remove virtual stuff in
Sphere and Cylinder. That doesn't increase speed, because anyway we
use OpenGL displaylist caching, but that makes the source code easier
to read.

svn path=/trunk/KDE/kdeedu/kalzium/src/kalziumglhelperclasses.cpp; revision=607943

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

index f9e3c321662afc3abf29142c6e862019cf5a1d1d..f7af456d34219f22a7d7ef3650c9270d320140e8 100644 (file)
@@ -90,28 +90,22 @@ void Color::applyAsMaterials()
        glMaterialf( GL_FRONT, GL_SHININESS, 50.0 );
 }
 
-VertexArray::VertexArray( GLenum mode,
-       bool hasIndexBuffer,
-       bool hasSeparateNormalBuffer )
+Sphere::Sphere()
 {
-       m_mode = mode;
        m_vertexBuffer = 0;
-       m_normalBuffer = 0;
        m_indexBuffer = 0;
        m_displayList = 0;
-       m_hasIndexBuffer = hasIndexBuffer;
-       m_hasSeparateNormalBuffer = hasSeparateNormalBuffer;
-       m_isValid = false;
+       m_detail = 0;
 }
 
-VertexArray::~VertexArray()
+Sphere::~Sphere()
 {
        freeBuffers();
        if( m_displayList )
                glDeleteLists( m_displayList, 1 );
 }
 
-void VertexArray::freeBuffers()
+void Sphere::freeBuffers()
 {
        if( m_indexBuffer )
        {
@@ -123,82 +117,91 @@ void VertexArray::freeBuffers()
                delete [] m_vertexBuffer;
                m_vertexBuffer = 0;
        }
-       if( m_normalBuffer && m_hasSeparateNormalBuffer ) 
-       {
-               delete [] m_normalBuffer;
-               m_normalBuffer = 0;
-       }
 }
 
-bool VertexArray::allocateBuffers()
+void Sphere::do_draw() const
+{
+       glVertexPointer( 3, GL_FLOAT, 0, m_vertexBuffer );
+       glNormalPointer( GL_FLOAT, 0, m_vertexBuffer );
+       glDrawElements( GL_TRIANGLE_STRIP, m_indexCount,
+                       GL_UNSIGNED_SHORT, m_indexBuffer );
+}
+
+void Sphere::draw( const Eigen::Vector3d &center, double radius ) const
+{
+       glPushMatrix();
+       glTranslated( center.x(), center.y(), center.z() );
+       glScaled( radius, radius, radius );
+#ifdef USE_DISPLAY_LISTS
+       glCallList( m_displayList );
+#else
+       do_draw();
+#endif
+       glPopMatrix();
+}
+
+void Sphere::initialize()
 {
-       if( m_vertexCount > 65536 ) return false;
+       if( m_detail < 1 ) return;
+
+       // compute number of vertices and indices
+       m_vertexCount = ( 3 * m_detail + 1 ) * ( 5 * m_detail + 1 );
+       m_indexCount = (2 * ( 2 * m_detail + 1 ) + 2 ) * 5 * m_detail;
 
+       // deallocate any previously allocated buffer
        freeBuffers();
 
+       // allocate memory for buffers
        m_vertexBuffer = new Vector3f[m_vertexCount];
-       if( ! m_vertexBuffer ) return false;
-       
-       if( m_hasSeparateNormalBuffer )
-       {
-               m_normalBuffer = new Vector3f[m_vertexCount];
-               if( ! m_normalBuffer ) return false;
-       }
-       else m_normalBuffer = m_vertexBuffer;
+       if( ! m_vertexBuffer ) return;
+       m_indexBuffer = new unsigned short[m_indexCount];
+       if( ! m_indexBuffer ) return;
 
-       if( m_hasIndexBuffer )
-       {
-               m_indexBuffer = new unsigned short[m_indexCount];
-               if( ! m_indexBuffer ) return false;
-       }
+       // build vertex buffer
+       for( int strip = 0; strip < 5; strip++ )
+       for( int column = 1; column < m_detail; column++ )
+       for( int row = column; row <= 2 * m_detail + column; row++ )
+               computeVertex( strip, column, row );
 
-       return true;
-}
+       for( int strip = 1; strip < 5; strip++ )
+       for( int row = 0; row <= 3 * m_detail; row++ )
+               computeVertex( strip, 0, row );
 
-void VertexArray::do_draw()
-{
-       glVertexPointer( 3, GL_FLOAT, 0, m_vertexBuffer );
-       glNormalPointer( GL_FLOAT, 0, m_normalBuffer );
-       if( m_hasIndexBuffer )
-               glDrawElements( m_mode, m_indexCount,
-                       GL_UNSIGNED_SHORT, m_indexBuffer );
-       else
-               glDrawArrays( m_mode, 0, m_vertexCount );
-}
+       for( int row = 0; row <= 2 * m_detail; row++ )
+               computeVertex( 0, 0, row );
+
+       for( int row = m_detail; row <= 3 * m_detail; row++ )
+               computeVertex( 4, m_detail, row );
+
+       // build index buffer
+       unsigned int i = 0;
+       for( int strip = 0; strip < 5; strip++ )
+       for( int column = 0; column < m_detail; column++ )
+       {
+               int row = column;
+               m_indexBuffer[i++] = indexOfVertex( strip, column, row );
+               for( ; row <= 2 * m_detail + column; row++ )
+               {
+                       m_indexBuffer[i++] =
+                               indexOfVertex( strip, column, row );
+                       m_indexBuffer[i++] =
+                               indexOfVertex( strip, column + 1, row + 1 );
+               }
+               m_indexBuffer[i++] = indexOfVertex( strip, column + 1,
+                       2 * m_detail + column + 1);
+       }
 
-void VertexArray::compileDisplayList()
-{
 #ifdef USE_DISPLAY_LISTS
-       if( ! m_displayList )
-               m_displayList = glGenLists( 1 );
+       // compile display list and free buffers
+       if( ! m_displayList ) m_displayList = glGenLists( 1 );
        if( ! m_displayList ) return;
-       
        glNewList( m_displayList, GL_COMPILE );
        do_draw();
        glEndList();
-
        freeBuffers();
 #endif
 }
 
-void VertexArray::initialize()
-{
-       m_isValid = false;
-       m_vertexCount = getVertexCount();
-       m_indexCount = getIndexCount();
-       if( m_indexCount < 0 || m_vertexCount < 0 ) return;
-       if( ! allocateBuffers() ) return;
-       buildBuffers();
-       compileDisplayList();
-       m_isValid = true;
-}
-
-Sphere::Sphere()
-       : VertexArray( GL_TRIANGLE_STRIP, true, false )
-{
-       m_detail = 0;
-}
-
 unsigned short Sphere::indexOfVertex( int strip, int column, int row)
 {
        return ( row + ( 3 * m_detail + 1 ) * ( column + m_detail * strip ) );
@@ -297,53 +300,6 @@ void Sphere::computeVertex( int strip, int column, int row)
        vertex.normalize();
 }
 
-int Sphere::getVertexCount()
-{
-       if( m_detail < 1 ) return -1;
-       return ( 3 * m_detail + 1 ) * ( 5 * m_detail + 1 );
-}
-
-int Sphere::getIndexCount()
-{
-       if( m_detail < 1 ) return -1;
-       return (2 * ( 2 * m_detail + 1 ) + 2 ) * 5 * m_detail;
-}
-
-void Sphere::buildBuffers()
-{
-       for( int strip = 0; strip < 5; strip++ )
-       for( int column = 1; column < m_detail; column++ )
-       for( int row = column; row <= 2 * m_detail + column; row++ )
-               computeVertex( strip, column, row );
-
-       for( int strip = 1; strip < 5; strip++ )
-       for( int row = 0; row <= 3 * m_detail; row++ )
-               computeVertex( strip, 0, row );
-
-       for( int row = 0; row <= 2 * m_detail; row++ )
-               computeVertex( 0, 0, row );
-
-       for( int row = m_detail; row <= 3 * m_detail; row++ )
-               computeVertex( 4, m_detail, row );
-
-       unsigned int i = 0;
-       for( int strip = 0; strip < 5; strip++ )
-       for( int column = 0; column < m_detail; column++ )
-       {
-               int row = column;
-               m_indexBuffer[i++] = indexOfVertex( strip, column, row );
-               for( ; row <= 2 * m_detail + column; row++ )
-               {
-                       m_indexBuffer[i++] =
-                               indexOfVertex( strip, column, row );
-                       m_indexBuffer[i++] =
-                               indexOfVertex( strip, column + 1, row + 1 );
-               }
-               m_indexBuffer[i++] = indexOfVertex( strip, column + 1,
-                       2 * m_detail + column + 1);
-       }
-}
-
 void Sphere::setup( int detail )
 {
        if( detail == m_detail ) return;
@@ -351,19 +307,33 @@ void Sphere::setup( int detail )
        initialize();
 }
 
-void Sphere::draw( const Vector3d &center, double radius )
+Cylinder::Cylinder()
 {
-       glPushMatrix();
-       glTranslated( center.x(), center.y(), center.z() );
-       glScaled( radius, radius, radius );
-       VertexArray::draw();
-       glPopMatrix();
+       m_vertexBuffer = 0;
+       m_normalBuffer = 0;
+       m_displayList = 0;
+       m_faces = 0;
 }
 
-Cylinder::Cylinder()
-       : VertexArray( GL_QUAD_STRIP, false, true )
+Cylinder::~Cylinder()
 {
-       m_faces = 0;
+       freeBuffers();
+       if( m_displayList )
+               glDeleteLists( m_displayList, 1 );
+}
+
+void Cylinder::freeBuffers()
+{
+       if( m_normalBuffer )
+       {
+               delete [] m_normalBuffer;
+               m_normalBuffer = 0;
+       }
+       if( m_vertexBuffer )
+       {
+               delete [] m_vertexBuffer;
+               m_vertexBuffer = 0;
+       }
 }
 
 void Cylinder::setup( int faces )
@@ -373,38 +343,54 @@ void Cylinder::setup( int faces )
        initialize();
 }
 
-int Cylinder::getVertexCount()
+void Cylinder::initialize()
 {
-       if( m_faces < 3 ) return -1;
-       return 2 * m_faces + 2;
-}
+       if( m_faces < 3 ) return;
 
-void Cylinder::buildBuffers()
-{
+       // compute number of vertices
+       m_vertexCount = 2 * m_faces + 2;
+
+       // deallocate any previously allocated buffer
+       freeBuffers();
+
+       // allocate memory for buffers
+       m_vertexBuffer = new Vector3f[m_vertexCount];
+       if( ! m_vertexBuffer ) return;
+       m_normalBuffer = new Vector3f[m_vertexCount];
+       if( ! m_normalBuffer ) return;
+
+       // build vertex and normal buffers
        for( int i = 0; i <= m_faces; i++ )
        {
                float angle = 2 * M_PI * i / m_faces;
-               float x = cosf( angle );
-               float y = sinf( angle );
-
-               m_normalBuffer[ 2 * i ].x() = x;
-               m_normalBuffer[ 2 * i ].y() = y;
-               m_normalBuffer[ 2 * i ].z() = 0.0;
-
-               m_normalBuffer[ 2 * i + 1 ] = m_normalBuffer[ 2 * i ];
+               Vector3f v( cosf(angle), sinf(angle), 0.0f );
+               m_normalBuffer[ 2 * i ] = v;
+               m_normalBuffer[ 2 * i + 1 ] = v;
+               m_vertexBuffer[ 2 * i ] = v;
+               m_vertexBuffer[ 2 * i + 1 ] = v;
+               m_vertexBuffer[ 2 * i ].z() = 1.0f;
+       }
 
-               m_vertexBuffer[ 2 * i ].x() = x;
-               m_vertexBuffer[ 2 * i ].y() = y;
-               m_vertexBuffer[ 2 * i ].z() = 1.0;
+#ifdef USE_DISPLAY_LISTS
+       // compile display list and free buffers
+       if( ! m_displayList ) m_displayList = glGenLists( 1 );
+       if( ! m_displayList ) return;
+       glNewList( m_displayList, GL_COMPILE );
+       do_draw();
+       glEndList();
+       freeBuffers();
+#endif
+}
 
-               m_vertexBuffer[ 2 * i + 1 ].x() = x;
-               m_vertexBuffer[ 2 * i + 1 ].y() = y;
-               m_vertexBuffer[ 2 * i + 1 ].z() = 0.0;
-       }
+void Cylinder::do_draw() const
+{
+       glVertexPointer( 3, GL_FLOAT, 0, m_vertexBuffer );
+       glNormalPointer( GL_FLOAT, 0, m_normalBuffer );
+       glDrawArrays( GL_QUAD_STRIP, 0, m_vertexCount );
 }
 
 void Cylinder::draw( const Vector3d &end1, const Vector3d &end2,
-       double radius, int order, double shift )
+       double radius, int order, double shift ) const
 {
        // the "axis vector" of the cylinder
        Vector3d axis = end2 - end1;
@@ -451,7 +437,12 @@ void Cylinder::draw( const Vector3d &end1, const Vector3d &end2,
        //now we can do the actual drawing !
        glPushMatrix();
        glMultMatrixd( matrix.array() );
-       if( order == 1 ) VertexArray::draw();
+       if( order == 1 )
+#              ifdef USE_DISPLAY_LISTS
+                       glCallList( m_displayList );
+#              else
+                       do_draw();
+#              endif
        else
        {
                double angleOffset = 0.0;
@@ -468,7 +459,11 @@ void Cylinder::draw( const Vector3d &end1, const Vector3d &end2,
                        glRotated( angleOffset + 360.0 * i / order,
                                   0.0, 0.0, 1.0 );
                        glTranslated( displacementFactor, 0.0, 0.0 );
-                       VertexArray::draw();
+#                      ifdef USE_DISPLAY_LISTS
+                               glCallList( m_displayList );
+#                      else
+                               do_draw();
+#                      endif
                        glPopMatrix();
                }
        }
@@ -657,12 +652,4 @@ void TextRenderer::print( int x, int y, const QString &string )
        if( ! m_isBetweenBeginAndEnd ) do_end();
 }
 
-void createOrthoBasisGivenFirstVector
-       ( const Vector3d &U, Vector3d * v, Vector3d * w )
-{
-       U.makeOrthoVector(v);
-       *w = cross( U, *v );
-       w->normalize();
-}
-
 } // namespace KalziumGLHelpers
index d025e0dba0bab2bdb3ef4d663f82eaf275292d6a..f736fbb45490cf51ccb2c4530feacad85a9f907d 100644 (file)
@@ -30,7 +30,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
@@ -150,117 +150,6 @@ struct Color
        void applyAsMaterials();
 };
 
-/**
-* Given a vector U, constructs two unit vectors v and w
-* such that (U, v, w) is an orthogonal basis.
-* U is not supposed to be normalized.
-*
-* Returns false if something went wrong.
-*/
-void createOrthoBasisGivenFirstVector( const Eigen::Vector3d & U,
-                                             Eigen::Vector3d * v,
-                                             Eigen::Vector3d * w );
-
-/**
-* 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
-*/
-class VertexArray
-{
-       protected:
-               /** Pointer to the buffer storing the vertex array */
-               Eigen::Vector3f *m_vertexBuffer;
-               /** Pointer to the buffer storing the normal array.
-                * If m_hasSeparateNormalBuffer is false, then this is equal
-                * to m_vertexBuffer. */
-               Eigen::Vector3f *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, this could be GL_TRIANGLE_STRIP) */
-               GLenum m_mode;
-               /** The number of vertices, i.e. the size of m_vertexBuffer
-                * or equivalently m_normalBuffer */
-               int m_vertexCount;
-               /** The number of indices, i.e. the size of m_indexBuffer */
-               int m_indexCount;
-               /** The id of the OpenGL display list (used only if this option
-                * is turned on) */
-               GLuint m_displayList;
-               /** Equals true if there is an index buffer, i.e. if this is an
-                * indexed vertex array */
-               bool m_hasIndexBuffer;
-               /** If this equals false, then the vertex buffer will also be
-                * used as normal buffer. This allows to divide by 2 the space
-                * taken by a sphere vertex array. For most objects other than
-                * spheres, this should equal true. */
-               bool m_hasSeparateNormalBuffer;
-               /** Equals true if this is a valid, well-initialized vertex
-                * array */
-               bool m_isValid;
-               
-               /** This pure virtual method should return the number of
-                * 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
-                * 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. */
-               bool allocateBuffers();
-               /** This method frees the buffers. If display list compilation
-                * is enabled, then it is safe to call it once the display list
-                * has been compiled.
-                */
-               void freeBuffers();
-               /** This pure virtual method should fill the buffers with the
-                * geometric data. It should be called only after
-                * allocateBuffers() */
-               virtual void buildBuffers() = 0;
-               /** If display list compilation is enabled, then this method
-                * compiles the display list and then calls freeBuffers().
-                * It should only be called after buildBuffers(). */
-               void compileDisplayList();
-               /** 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. */
-               void initialize();
-               /** This function draws the vertex array using OpenGL. */
-               void do_draw();
-
-       public:
-               /** This constructors only sets the values of the member data to
-                * some pre-initialization state. See the initialize() method
-                * for actual initialization. */
-               VertexArray( GLenum mode,
-                       bool hasIndexBuffer,
-                       bool hasSeparateNormalBuffer );
-               /** This destructor frees the buffers if necessary, and also
-                * deletes the display list if it has been compiled. */
-               virtual ~VertexArray();
-
-               /** If display list compilation is enabled, then this function
-                * just calls the display list. Otherwise, it calls do_draw().
-                */
-               inline void draw()
-               {
-#ifdef USE_DISPLAY_LISTS
-                       if( m_isValid ) glCallList( m_displayList );
-#else
-                       if( m_isValid ) do_draw();
-#endif
-               }
-};
-
 /**
 * This class represents and draws a sphere. The sphere is computed as a
 * "geosphere", that is, one starts with an icosahedron, which is the regular
@@ -270,47 +159,57 @@ class VertexArray
 *
 * @author Benoit Jacob
 */
-class Sphere : public VertexArray
+class Sphere
 {
-       private:
-               /** computes the index (position inside the index buffer)
-                * of a vertex given by its position (strip, column, row)
-                * inside a certain flat model of the sub-tesselated
-                * icosahedron */
-               inline unsigned short indexOfVertex(
-                       int strip, int column, int row);
-               /** computes the coordinates
-                * of a vertex given by its position (strip, column, row)
-                * inside a certain flat model of the sub-tesselated
-                * icosahedron */
-               void computeVertex( int strip, int column, int row );
-
-       protected:
-               /** the detail-level of the sphere. Must be at least 1.
-                * This is interpreted as the number of sub-edges into which
-                * each edge of the icosahedron must be split. So the
-                * number of faces of the sphere is simply:
-                * 20 * detail^2. When detail==1, the sphere is just the
-                * icosahedron */
-               int m_detail;
-
-               int getVertexCount();
-               int getIndexCount();
-               void buildBuffers();
-
-       public:
-               Sphere();
-               ~Sphere() {}
-
-               /** initializes the sphere with given level of detail. If the
-                * sphere was already initialized, any pre-allocated buffers
-                * are freed and then re-allocated.
-               @param detail the wanted level of detail. See m_detail member */
-               void setup( int detail );
-
-               /** draws the sphere at specifiec position and with
-                * specified radius */
-               void draw( const Eigen::Vector3d &center, double radius );
+protected:
+       /** Pointer to the buffer storing the vertex array */
+       Eigen::Vector3f *m_vertexBuffer;
+       /** Pointer to the buffer storing the indices */
+       unsigned short *m_indexBuffer;
+       /** The number of vertices, i.e. the size of m_vertexBuffer */
+       int m_vertexCount;
+       /** The number of indices, i.e. the size of m_indexBuffer */
+       int m_indexCount;
+       /** The id of the OpenGL display list (used only if this option
+         * is turned on) */
+       GLuint m_displayList;
+
+       /** computes the index (position inside the index buffer)
+         * of a vertex given by its position (strip, column, row)
+         * inside a certain flat model of the sub-tesselated
+         * icosahedron */
+       inline unsigned short indexOfVertex(
+               int strip, int column, int row);
+       /** computes the coordinates
+         * of a vertex given by its position (strip, column, row)
+         * inside a certain flat model of the sub-tesselated
+         * icosahedron */
+       void computeVertex( int strip, int column, int row );
+       /** the detail-level of the sphere. Must be at least 1.
+         * This is interpreted as the number of sub-edges into which
+         * each edge of the icosahedron must be split. So the
+         * number of faces of the sphere is simply:
+         * 20 * detail^2. When detail==1, the sphere is just the
+         * icosahedron */
+       int m_detail;
+
+       void freeBuffers();
+       void initialize();
+       void do_draw() const;
+
+public:
+       Sphere();
+       ~Sphere();
+
+       /** initializes the sphere with given level of detail. If the
+         * sphere was already initialized, any pre-allocated buffers
+         * are freed and then re-allocated.
+       @param detail the wanted level of detail. See m_detail member */
+       void setup( int detail );
+
+       /** draws the sphere at specified position and with
+         * specified radius */
+       void draw( const Eigen::Vector3d &center, double radius ) const;
 };
 
 /**
@@ -318,45 +217,59 @@ class Sphere : public VertexArray
 *
 * @author Benoit Jacob
 */
-class Cylinder : public VertexArray
+class Cylinder
 {
-       protected:
-               /** the number of faces of the cylinder. This only
-                * includes the lateral faces, as the base and top faces (the
-                * two discs) are not rendered. */
-               int m_faces;
-
-               int getVertexCount();
-               void buildBuffers();
-
-       public:
-               Cylinder();
-               ~Cylinder() {}
-               /** initializes the cylinder with given number of faces. If the
-                * cylinder was already initialized, any pre-allocated buffers
-                * are freed and then re-allocated */
-               void setup( int faces );
-               /**
-                * draws the cylinder at specified position, with specified
-                * radius. the order and shift arguments allow to render
-                * multiple cylinders at once. If you only want to render one
-                * cylinder, leave order and shift at their default values.
-                @param end1 the position of the first end of the cylinder.
-                       that is, the center of the first disc-shaped face.
-                @param end2 the position of the second end of the cylinder.
-                       that is, the center of the second disc-shaped face.
-                @param radius the radius of the cylinder
-                @param order to render only one cylinder, leave this set to
-                       the default value, which is 1. If order>1, then order
-                       parallel cylinders are drawn around the axis
-                       (end1 - end2).
-               @param order this is only meaningful of order>1, otherwise
-                       just let this set to the default value. When order>1,
-                       this is interpreted as the displacement of the axis
-                       of the drawn cylinders from the axis (end1 - end2).
-                */
-               void draw( const Eigen::Vector3d &end1, const Eigen::Vector3d &end2,
-                       double radius, int order = 1, double shift = 0.0 );
+protected:
+       /** Pointer to the buffer storing the vertex array */
+       Eigen::Vector3f *m_vertexBuffer;
+       /** Pointer to the buffer storing the normal array */
+       Eigen::Vector3f *m_normalBuffer;
+       /** The number of vertices, i.e. the size of m_vertexBuffer
+         * or equivalently m_normalBuffer */
+       int m_vertexCount;
+       /** The id of the OpenGL display list (used only if this option
+         * is turned on) */
+       GLuint m_displayList;
+       /** Equals true if the vertex array has been correctly initialized */
+       bool m_isValid;
+
+       /** the number of faces of the cylinder. This only
+         * includes the lateral faces, as the base and top faces (the
+         * two discs) are not rendered. */
+       int m_faces;
+
+       void initialize();
+       void freeBuffers();
+       void do_draw() const;
+
+public:
+       Cylinder();
+       ~Cylinder();
+       /** initializes the cylinder with given number of faces. If the
+         * cylinder was already initialized, any pre-allocated buffers
+         * are freed and then re-allocated */
+       void setup( int faces );
+       /**
+         * draws the cylinder at specified position, with specified
+         * radius. the order and shift arguments allow to render
+         * multiple cylinders at once. If you only want to render one
+         * cylinder, leave order and shift at their default values.
+           @param end1 the position of the first end of the cylinder.
+                  that is, the center of the first disc-shaped face.
+           @param end2 the position of the second end of the cylinder.
+                  that is, the center of the second disc-shaped face.
+           @param radius the radius of the cylinder
+           @param order to render only one cylinder, leave this set to
+                  the default value, which is 1. If order>1, then order
+                  parallel cylinders are drawn around the axis
+                  (end1 - end2).
+           @param order this is only meaningful of order>1, otherwise
+                  just let this set to the default value. When order>1,
+                  this is interpreted as the displacement of the axis
+                  of the drawn cylinders from the axis (end1 - end2).
+         */
+       void draw( const Eigen::Vector3d &end1, const Eigen::Vector3d &end2,
+               double radius, int order = 1, double shift = 0.0 ) const;
 };
 
 /** BEEP BEEP BEEP this will likely be removed as Qt 4.2 has something better
index aa0827762598aac08dd136429114592711efc66c..9d7b59d1e0832166b124cdd51884e242977b34dc 100644 (file)
@@ -433,8 +433,8 @@ void KalziumGLWidget::drawAtom( OBAtom *atom )
 
 void KalziumGLWidget::drawBond( OBBond *bond )
 {
-       OBAtom *atom1 = static_cast<OBAtom *>( bond->GetBgn() );
-       OBAtom *atom2 = static_cast<OBAtom *>( bond->GetEnd() );
+       OBAtom *atom1 = static_cast<OBAtom *>( bond->GetBeginAtom() );
+       OBAtom *atom2 = static_cast<OBAtom *>( bond->GetEndAtom() );
 
        Vector3d v1 ( atom1->GetVector().AsArray() );
        Vector3d v2 ( atom2->GetVector().AsArray() );
@@ -576,7 +576,8 @@ void KalziumGLWidget::prepareMoleculeData()
        // compute rotation matrix to orient the molecule in the (x,y)-plane
        Vector3d planeNormalVector( & planeCoeffs(0) ), v, w;
        planeNormalVector.normalize();
-       createOrthoBasisGivenFirstVector( planeNormalVector, &v, &w );
+       planeNormalVector.makeOrthoVector( &v );
+       w = cross( planeNormalVector, v );
        Matrix3d rotation;
        rotation.setRow( 0, v );
        rotation.setRow( 1, w );