QGraphicsView

Carsten brought it to my attention that there is a “QGraphicsView” class
in QT (and i think you mentioned it a while back) that will probably
save us a lot of time with clicking / collision etc. So revision 49 is
the last one we have using our old way. I’m going to play with changing
it so we take advantage of this and see how it comes out. If it works
i’ll commit the changes. I didn’t know if you had any input on this.
We’ll see how it turns out. It looks like the same way I was already
kinda doing it by wrapping our Molecule / Atom / Bond items.

-Donald

Am Sonntag, den 27.08.2006, 15:41 -0500 schrieb Donald Ephraim Curtis:

Carsten brought it to my attention that there is a "QGraphicsView"
class
in QT (and i think you mentioned it a while back) that will probably
save us a lot of time with clicking / collision etc.

Just keep in mind that QGraphicsView is only in Qt 4.2 which is not yet
released.

Carsten

I just talked to someone in #qt who said that for the most part, the
only reason you can use a GLWidget for a QGraphicsView is to optimize
the performance. So i’m not sure that it’d be that useful for us as
we’d have to rewrite the functions for 3d orientation.

After doing some research I haven’t found that it’s useful for that
either; at least there is no documentation on the 3d rendering.

(Mon, Aug 28, 2006 at 12:39:46AM +0200) Carsten Niehaus cniehaus@gmx.de:

Am Sonntag, den 27.08.2006, 15:41 -0500 schrieb Donald Ephraim Curtis:

Carsten brought it to my attention that there is a "QGraphicsView"
class
in QT (and i think you mentioned it a while back) that will probably
save us a lot of time with clicking / collision etc.

Just keep in mind that QGraphicsView is only in Qt 4.2 which is not yet
released.

Carsten

On Aug 27, 2006, at 4:41 PM, Donald Ephraim Curtis wrote:

We’ll see how it turns out. It looks like the same way I was already
kinda doing it by wrapping our Molecule / Atom / Bond items.

Yes, I haven’t had time to look at the QGraphicsView class – if it
helps, great. If not, no worries. As to depending on Qt-4.2, other
parts of the Avogadro code already require this (e.g., menu
shortcuts, the undo framework to come, etc.).

One minor nitpick – the render engine interface should be more general:

  1. It should accept render engines which render the whole Molecule at
    once (e.g., for a molecular surface). This also offers optimization
    improvements. The previous render code was faster because it created
    one gluQuadric for the entire molecule, rather than constantly
    creating/deleting for each atom and bond.

  2. We’ll eventually need render engines which deal with residues
    (e.g., protein ribbons, etc.)

The mouse tools code is in OK shape, but I will need to spend some
time putting in glLoadName() for selection tool purposes. I also
spent some time thinking about other plugin interfaces.

-Geoff

One minor nitpick – the render engine interface should be more general:

  1. It should accept render engines which render the whole Molecule at
    once (e.g., for a molecular surface). This also offers optimization
    improvements. The previous render code was faster because it created
    one gluQuadric for the entire molecule, rather than constantly
    creating/deleting for each atom and bond.

The performance problem is just the way i implemented the first
rendering engines. BSEngine is only instanciated once per GLWidget
therefore if you want to, you can generate that gluQuadric in the
constructor then just use that for all renderings.

  1. We’ll eventually need render engines which deal with residues
    (e.g., protein ribbons, etc.)

I am not quite sure what you mean by more general and i don’t know
exactly what you mean by protein ribbons etc but the GLEngine::render
function is polymorphic in that; if the parameter is Atom the engine
knows it’s being asked to render an Atom. This is easily extended to
whatever parameters we want. Right now of course i don’t have
GLEngine::render(Molecule) as an option but it can easily be there. If
we need to add another View subclass for supporting protiens we can do
that too.

so as you say; if an engine wants to render only off the molecule it can
(just implement render(Molecule); it’s up to the engine implementer.

The mouse tools code is in OK shape, but I will need to spend some
time putting in glLoadName() for selection tool purposes. I also
spent some time thinking about other plugin interfaces.

Should tools be implemented as plugins also?

On Aug 27, 2006, at 9:15 PM, Donald Ephraim Curtis wrote:

The mouse tools code is in OK shape, but I will need to spend some
time putting in glLoadName() for selection tool purposes. I also
spent some time thinking about other plugin interfaces.

Should tools be implemented as plugins also?

Yes, I think so. Remember that there are two types of plugins –
static and dynamic.

I think almost everything should be implemented as a plugin. Here’s
a list:

  • rendering engines
  • label rendering
  • color mappings (by element, by atom type, by atom index, by
    residue…)
  • tools (i.e., basic rotate, translate, zoom, plus building, erasing,
    selection, measuring…)
    – this makes it easy to add more build tools (e.g., protein
    builder, fragment builder, …)
    – it also makes it easy for teachers to customize functionality
    for students (e.g., viewer only, limited edit, etc.)
  • selection commands (i.e., select by SMARTS, select by residue,
    select by element, select all solvent molecules)
  • compute plugins (i.e., spin off a separate thread for running QM or
    MM or MD or…)
  • “quick tasks” (i.e., adding hydrogens, running embedded Python
    scripts, etc.)

I haven’t even gotten into surface or grid data yet, and I’m sure
there are features we haven’t imagined.

Since Qt makes it easy to have static plugins, critical pieces can be
guaranteed (e.g., wireframe and balls & stick engines). Enforcing
plugin interfaces means that we can be very sure the interfaces are
designed well enough for the future.

Cheers,
-Geoff

I am starting to work more and more on selection / clicking etc etc
code. Also drawing. Selectin and picking gets more and more
complicated so i’m going to work on putting in code to select atoms,
select groups of atoms, manipulate coords of selected groups etc etc and
see how that goes. I have a feeling that manipulation can be done with
one tool (plus command / control / alt / shift). I am using the Gimp
editor as a kinda “model” for manipulation at least for the time being.

I will probably put this code down for a while. I had a hell of a time
with the picking code just because of the way we setup our view. Did
you pull a lot of that code?

Anyways, once we get some functionality built into the GLWidget we’ll be
better suited to see what interface we need to give so we can extract
that functionality to a plugin. That make any sense?

(Mon, Aug 28, 2006 at 03:49:32PM -0400) Geoffrey Hutchison geoff.hutchison@gmail.com:

On Aug 27, 2006, at 9:15 PM, Donald Ephraim Curtis wrote:

The mouse tools code is in OK shape, but I will need to spend some
time putting in glLoadName() for selection tool purposes. I also
spent some time thinking about other plugin interfaces.

Should tools be implemented as plugins also?

Yes, I think so. Remember that there are two types of plugins –
static and dynamic.

I think almost everything should be implemented as a plugin. Here’s
a list:

  • rendering engines
  • label rendering
  • color mappings (by element, by atom type, by atom index, by
    residue…)
  • tools (i.e., basic rotate, translate, zoom, plus building, erasing,
    selection, measuring…)
    – this makes it easy to add more build tools (e.g., protein
    builder, fragment builder, …)
    – it also makes it easy for teachers to customize functionality
    for students (e.g., viewer only, limited edit, etc.)
  • selection commands (i.e., select by SMARTS, select by residue,
    select by element, select all solvent molecules)
  • compute plugins (i.e., spin off a separate thread for running QM or
    MM or MD or…)
  • “quick tasks” (i.e., adding hydrogens, running embedded Python
    scripts, etc.)

I haven’t even gotten into surface or grid data yet, and I’m sure
there are features we haven’t imagined.

Since Qt makes it easy to have static plugins, critical pieces can be
guaranteed (e.g., wireframe and balls & stick engines). Enforcing
plugin interfaces means that we can be very sure the interfaces are
designed well enough for the future.

Cheers,
-Geoff

On Aug 28, 2006, at 11:43 PM, Donald Ephraim Curtis wrote:

see how that goes. I have a feeling that manipulation can be done
with
one tool (plus command / control / alt / shift). I am using the Gimp
editor as a kinda “model” for manipulation at least for the time
being.

Well, the beauty of the plugin model is that you can make a “one tool
fits all” tool, and I can have a “one tool per job” set. :slight_smile:

For now, it doesn’t matter too much, although I’m certainly happy to
see a selection rectangle after working with Ghemical for so many years.

I will probably put this code down for a while. I had a hell of a
time
with the picking code just because of the way we setup our view. Did
you pull a lot of that code?

No, I didn’t pull any active code. BTW, if you’re having trouble with
picking/selection, it’s because the render engines don’t call
glLoadName at all.

Try the current revision. Any name you find will correspond to an
atom index.

Cheers,
-Geoff

(Tue, Aug 29, 2006 at 10:13:10AM -0400) Geoffrey Hutchison geoff.hutchison@gmail.com:

On Aug 28, 2006, at 11:43 PM, Donald Ephraim Curtis wrote:

see how that goes. I have a feeling that manipulation can be done
with
one tool (plus command / control / alt / shift). I am using the Gimp
editor as a kinda “model” for manipulation at least for the time
being.

Well, the beauty of the plugin model is that you can make a “one tool
fits all” tool, and I can have a “one tool per job” set. :slight_smile:

For now, it doesn’t matter too much, although I’m certainly happy to
see a selection rectangle after working with Ghemical for so many years.

yeah, i like it.

I will probably put this code down for a while. I had a hell of a
time
with the picking code just because of the way we setup our view. Did
you pull a lot of that code?

I drempt of Matricies last night; that seems scary!

No, I didn’t pull any active code. BTW, if you’re having trouble with
picking/selection, it’s because the render engines don’t call
glLoadName at all.

Try the current revision. Any name you find will correspond to an
atom index.

It wasn’t the naming that was the problem. It was that we were using
the orthogonal layout and our viewport was getting set to negative
values to keep the ratio. You’ll notice the “historical” commit i did
that used the orthoganal view with selection; code was a mess.

As a note, we’ll have to be careful here; like you said; an engine may
only render at the molecule level; however, tools will have / or should
have, some guaruntee as to the naming “scheme/heirarchy” of things.
Thus, i have put glLoadName/glPushName/glPopName into the “Views” class
surrounding the render calls.

-Donald

On Aug 29, 2006, at 10:32 AM, Donald Ephraim Curtis wrote:

As a note, we’ll have to be careful here; like you said; an engine may
only render at the molecule level; however, tools will have / or
should
have, some guarantee as to the naming “scheme/heirarchy” of things.
Thus, i have put glLoadName/glPushName/glPopName into the "Views"
class
surrounding the render calls.

Yes. I thought about the scheme sometime over the weekend and think
the scheme should be something like this:

//! Names for rendering objects
enum GLrenderTypeName { moleculeType, atomType, bondType,
residueType, surfaceType, otherType };

Then in the code, something like this:

glPushName( MOLECULE / ATOM / BOND / RESIDUE / OTHER);
// atom rendering, bond rendering, etc.
glPopName();

I’ll put this into the View classes shortly, along with code for
rendering the molecule in one shot – I think the AtomView and
BondView classes should mostly be used when a user decides to add
custom rendering to a particular atom or bond. To make this "fun,"
I’ll add two small render options: render a molecule as a sphere, and
rendering each residue as a sphere.

Cheers,
-Geoff

(Tue, Aug 29, 2006 at 07:07:21PM -0400) Geoffrey Hutchison geoff.hutchison@gmail.com:

On Aug 29, 2006, at 10:32 AM, Donald Ephraim Curtis wrote:

As a note, we’ll have to be careful here; like you said; an engine may
only render at the molecule level; however, tools will have / or
should
have, some guarantee as to the naming “scheme/heirarchy” of things.
Thus, i have put glLoadName/glPushName/glPopName into the "Views"
class
surrounding the render calls.

Yes. I thought about the scheme sometime over the weekend and think
the scheme should be something like this:

//! Names for rendering objects
enum GLrenderTypeName { moleculeType, atomType, bondType,
residueType, surfaceType, otherType };

Then in the code, something like this:

glPushName( MOLECULE / ATOM / BOND / RESIDUE / OTHER);
// atom rendering, bond rendering, etc.
glPopName();

Well, the problem is that we want to use the names to actually say which
atom has been picked, rather than that a non-specific atom has been
picked. Plus, if you put two things in as GLrenderTypeName.moleculeType
then when either one of them gets clicked, both of them get clicked.

If i get what you’re saying correctly, maybe i’m off.

Is there some sorta global index in OB? That would almost be much
easier (such as that whenever something gets added to a molecule it not
only gets and atomIdx but a globalIdx too.

I’ll put this into the View classes shortly, along with code for
rendering the molecule in one shot – I think the AtomView and
BondView classes should mostly be used when a user decides to add
custom rendering to a particular atom or bond. To make this "fun,"
I’ll add two small render options: render a molecule as a sphere, and
rendering each residue as a sphere.

Cheers,
-Geoff

On Aug 29, 2006, at 7:40 PM, Donald Ephraim Curtis wrote:

//! Names for rendering objects
enum GLrenderTypeName { moleculeType, atomType, bondType,
residueType, surfaceType, otherType };

Then in the code, something like this:

glPushName( MOLECULE / ATOM / BOND / RESIDUE / OTHER);
// atom rendering, bond rendering, etc.
glPopName();

Well, the problem is that we want to use the names to actually say
which
atom has been picked, rather than that a non-specific atom has been
picked. Plus, if you put two things in as
GLrenderTypeName.moleculeType
then when either one of them gets clicked, both of them get clicked.

I guess I wasn’t clear enough in my pseudo-code. The idea is that two
"names" are pushed on the stack for everything. First you push on the
GLrenderTypeName (pick a different label if you want). Then you push
on the index for that type.
Here are a few examples:

atomType, 1 // atom #1 (atom indexing from 1)
atomType, 1, atomType 13 // two atoms selected, atom 1 and atom 13
residueType, 13 // residue #14 (residue indexing from 0)
moleculeType, 0 // molecule indexing from 0

Now the code is slightly more complicated than for having just the
atom id on the stack, since you have to filter through “dummy” name
records explaining what type is coming up. But it’s so much more
flexible. See for example:
http://www.lighthouse3d.com/opengl/picking/

There’s an example with pushing names for rows and columns for a grid
of snowmen.

Cheers,
-Geoff

I see what you mean. That sounds good. I think that atomType will be
below a moleculeType when rendered too correct? So you can get the
heirarchical view? I guess it’s not necissary but i think it’s cool to
set it up that way.

(Tue, Aug 29, 2006 at 08:26:06PM -0400) Geoffrey Hutchison geoff.hutchison@gmail.com:

On Aug 29, 2006, at 7:40 PM, Donald Ephraim Curtis wrote:

//! Names for rendering objects
enum GLrenderTypeName { moleculeType, atomType, bondType,
residueType, surfaceType, otherType };

Then in the code, something like this:

glPushName( MOLECULE / ATOM / BOND / RESIDUE / OTHER);
// atom rendering, bond rendering, etc.
glPopName();

Well, the problem is that we want to use the names to actually say
which
atom has been picked, rather than that a non-specific atom has been
picked. Plus, if you put two things in as
GLrenderTypeName.moleculeType
then when either one of them gets clicked, both of them get clicked.

I guess I wasn’t clear enough in my pseudo-code. The idea is that two
"names" are pushed on the stack for everything. First you push on the
GLrenderTypeName (pick a different label if you want). Then you push
on the index for that type.
Here are a few examples:

atomType, 1 // atom #1 (atom indexing from 1)
atomType, 1, atomType 13 // two atoms selected, atom 1 and atom 13
residueType, 13 // residue #14 (residue indexing from 0)
moleculeType, 0 // molecule indexing from 0

Now the code is slightly more complicated than for having just the
atom id on the stack, since you have to filter through “dummy” name
records explaining what type is coming up. But it’s so much more
flexible. See for example:
http://www.lighthouse3d.com/opengl/picking/

There’s an example with pushing names for rows and columns for a grid
of snowmen.

Cheers,
-Geoff

On Aug 29, 2006, at 8:50 PM, Donald Ephraim Curtis wrote:

I see what you mean. That sounds good. I think that atomType will be
below a moleculeType when rendered too correct? So you can get the
heirarchical view? I guess it’s not necissary but i think it’s
cool to
set it up that way.

Actually, my current design plan is that a render engine should only
push the appropriate type for what it’s rendering. So if you’re
showing atoms to the user, you should push atomType and then an atom
index.

If you’re showing a “molecular blob,” with no obvious atoms or bonds,
then you should push moleculeType and a molecule index. Not quite
sure if there’s any use for that, but better to leave the door open.

I expect that atom, bond, and residue types are more useful than
anything else right now.

Any sort of chemistry hierarchy shouldn’t be dependent on the render
engine, I think it should be worked out by the tool and or mode. For
example, I think the Ghemical “selection mode” system works well. GL
returns a pick for an atom, but the application code selects
everything connected. Or I set the selection tool to "select residue"
and a pick for an atom selects the entire amino acid.

This is why I think there will need to be a selection plugin
interface. GAMESS could code in something for “user selected atoms in
a water molecule, go select all H2O fragments.”

So I see one “selection tool” that handles getting hits from OpenGL
and working out what the user hit. Then there’s another step removed
which takes a list of hits and marks selections.

Cheers,
-Geoff

P.S. Ghemical actually does all of this exactly the same. The code’s
just confusing and there’s no easy way to add more “selection modes.”