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,
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 )
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();
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;
initialize();
}
-int Cylinder::computeVertexCount()
+int Cylinder::getVertexCount()
{
if( m_faces < 3 ) return -1;
return 2 * m_faces + 2;
* 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
* This option improves performance, especially when rendering complex models,
* but increases memory usage.
*/
-//#define USE_DISPLAY_LISTS
+#define USE_DISPLAY_LISTS
namespace KalziumGLHelpers
{
* 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 );
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
*/
/** 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 */
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. */
* 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. */
* icosahedron */
int m_detail;
- virtual int computeVertexCount();
- virtual int computeIndexCount();
+ virtual int getVertexCount();
+ virtual int getIndexCount();
virtual void buildBuffers();
public:
* two discs) are not rendered. */
int m_faces;
- virtual int computeVertexCount();
+ virtual int getVertexCount();
virtual void buildBuffers();
public:
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()
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 );
glEnableClientState( GL_VERTEX_ARRAY );
glEnableClientState( GL_NORMAL_ARRAY );
+
+ setupObjects();
}
void KalziumGLWidget::paintGL()
}
glCallList( m_displayList );
#endif
-
renderSelection();
#ifdef USE_FPS_COUNTER
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 );
}
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;
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;
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;
default: break;
}
m_haveToRecompileDisplayList = true;
+}
+
+void KalziumGLWidget::slotSetMolStyle( int style )
+{
+ setMolStyle( style );
setupObjects();
updateGL();
}
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 )
{