Lots of Updates

So it’s Sunday, and I was super motivated. That’s why you have about 10
e-mails from SF.

First and most interesting is that I got the rendering engines
implemented. Look in the src/engines directory for examples (i should
really rename this renderers even though i know that hard to spell).

Everytime you create a new MainWindow instance it looks at the plugins
directory (right now it’s hardcoded to the AppDir + engines) and loads
various instances RendererFactory classes (right now BSRendererFactory
[1 radius atom balls] and SBSRendererFactory [.5 radius atom balls]).
What i found was that you want to use a Factory which creates an
instance of the actualy Renderer because each time to make a new SDI
window; each NewWindow needs it’s own instance of the renderer.

Ok so that’s confusing; and maybe i pulled a bad design on this;

Basically i wrapped the OBMol / OBAtom / OBBond classes with just basic
classes that have a “render” call. I then had two options; 1) Let each
Atom class handle it’s own GL Display List; meaning it will call a
Renderer::renderAtom and save that render sequence to a display list. 2)
Let the Renderer handle it’s own GL Display List and thus the atom can
ignore having to worry about it. I chose 2 for a few reasons; the
renderer should have control of it’s basic display lists. For example;
when you render Ball and Stick all the balls are the same except size
(glScale) whereas with 1) there is no advantage to using Display Lists
for the spheres which can get up there in polygons. It also would mean
that if each atom had a display list it would just be too many in
big molecules. I believe that spheres and cylinders are complex enough
to warrant having a display list and if they don’t warrant a display
list then the rendering engine can decide that; the Atom shouldn’t.

The other thing (and i’m getting sidetracked a bit) is that we can
eventually add where molecules can manage a bigger display list
(heiarchical display lists work) and we can get the optimization there.

I made each Atom have a ‘render’ call because we had discussed how we
would like to specify rendering options on a primative level not just
molecular / view based.

Ok, so that’s why i have the plugins as Factories which create and
instance of the “Renderer” class. Everytime to make a Display List it
gets bound to whatever GL context you are in. By make a new instance of
the renderer it is bound to the GL widget for the MainWindow it is
instanciated in. It also gives us a WHOLE lot of optimization options
because each engine can optimize how it wants to. I hope that makes
sense; the code may explain it more and if there is to be a discussion i
would suggest it be over; IRC / AIM / Jabber (something more realtime).

The other thing i did was created a bunch of .pro files that makes it
easy to build from any directory and build recursively.

And cleaned up the old stuff.

Unfortunatly the bond code is not implemented yet. I’ll probably have
the engines up tomm and then i will implement where you can switch
rendering options (for now just globally).

Let me know what you think Geoff and if you have any comments/questions.
This was a lot of change but it seems to be working great. QT made it
really easy for the most part; just minor workings and bugs i had to do
a lot of testing to understand what was going on.

-Donald

On Aug 21, 2006, at 2:07 AM, Donald Ephraim Curtis wrote:

What i found was that you want to use a Factory which creates an
instance of the actualy Renderer because each time to make a new SDI
window; each NewWindow needs it’s own instance of the renderer.

Ok so that’s confusing; and maybe i pulled a bad design on this;

Last night, I was thinking about this too. I think what you’ve added
is great and does offer some great places to improve optimization.

I think there’s one slight addition to what we’ve done so far.
Eventually, we’ll want to have a GLWidget handle multiple renderers.
For example:

  • The user wants to have multiple views of a protein (e.g., show all
    atoms as dots, but add a protein “ribbon” renderer).
  • Someone like me wants to show the atoms from a GAMESS run, but
    overlay an electron density surface.
  • Someone like me wants to emphasize two atoms in the middle of some
    structure, rendering them as a big sphere (i.e., maybe separate
    renderers => display lists for a few random “customizations”).

I think this also means I should move the “data” (i.e., the OBMol)
into the GLWidget itself, so it can maintain separate lists of data
items (OBMol, OBGrid…) and render plugins. (I stick to calling them
“render” because “renderer” seems harder to type. :slight_smile:

Also, we need a slight change in finding the plugin directory. For
now, can you make it also check an environment variable with getenv
()? On the Mac, the resulting app is a multi-folder “bundle,” so it
can’t find the renderers and crashes.

Otherwise it looks great. Thanks for a lot of great stuff “for
breakfast.” :slight_smile:

Cheers,
-Geoff

P.S. I’m thinking that basically anything worth rendering is based on
OBBase. Then we can use RTTI to pick specific render options (e.g.,
the current engines don’t handle OBResidue or OBGrid):

I’ll need to check if this requires any changes to Open Babel 2.1.
Certainly, if in the development of Avogadro we find something to
change in OB, I’ll try to fix it ASAP.

(Mon, Aug 21, 2006 at 08:18:05AM -0400) Geoffrey Hutchison geoff.hutchison@gmail.com:

I think this also means I should move the “data” (i.e., the OBMol)
into the GLWidget itself, so it can maintain separate lists of data
items (OBMol, OBGrid…) and render plugins. (I stick to calling them
“render” because “renderer” seems harder to type. :slight_smile:

Maybe we should call them Engine(s). I totally agree it’s harder to
type.

I’m also glad you mention this cause i was thinking the EXACT same thing
while i was doing it. However; it’s a bit more complicated than just
moving it because when you add to one view, it should update the others;
therefore they should share OBMol/OBAtom data but not share GL data.

But the problem i see is that subclassing OBMol / OBAtom doesn’t quite
work that way; in fact we would have to have a Molecule per GLWidget and
then any changes need to propogate to all GLWidgets. Is there a way to
have only ONE instance of the OBMol + OBAtoms + OBBonds and then have a
wrapper class that points to all of them rather than duplicating? And
not only that but the wrapper class needs to make sure whenever a change
happens it knows about it! Magic?

Also, we need a slight change in finding the plugin directory. For
now, can you make it also check an environment variable with getenv
()? On the Mac, the resulting app is a multi-folder “bundle,” so it
can’t find the renderers and crashes.

yeah my bad; it took me forever so cut some corners.

Otherwise it looks great. Thanks for a lot of great stuff “for
breakfast.” :slight_smile:

Cheers,
-Geoff

P.S. I’m thinking that basically anything worth rendering is based on
OBBase. Then we can use RTTI to pick specific render options (e.g.,
the current engines don’t handle OBResidue or OBGrid):
http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=120&rl=1

Ok cool. There probably only needs to be one render call per engine
then too. Although i’m still not sold on dynamic-casting; don’t know
why ;).

-Donald