RFC: Multiple painters to allow for POVRay export + other features

Hi,

I have talked with Benoit and Donald about this on IRC. After chatting with
Donald earlier I think it might be a good idea to write down my ideas. This
will hopefully let everyone know what my intentions are as well as giving you
a chance to point out flaws in my thinking or better methodologies for
implementing these features.

  1. Goal

The goal of having multiple painters is to provide some level of independence
for the engines from the particular method of rendering the molecular
structure. This will immediately allow me to write a POVPainter in order to
output the scene as POVRay primitives for high quality ray tracing.

It will also allow us to write an alternate painter that takes advantage of
programmable OpenGL shaders such as those used by Qutemol to render awesome
images using relatively few triangles for the spheres etc. Other targets
could include writing a gl2ps painter to take advantage of the gl2ps library
and an SVG painter to export our scenes as SVG.

  1. Possible Implementations

It could be implemented in a very similar fashion to the tools, engines etc
where a base class is written with all core functions. Each painter would
then take care of the specifics for that particular rendering surface. This
was the initial approach I took.

Donald suggested that a PaintEngine approach could be taken where we have a
painter that can use different PaintEngines depending up on the rendering
surface. This is the way that Qt does this and so it could be advantageous to
remain consistent with Qt. I need to read up a little on this approach.

Either approach would also necessitate having a base rendering surface too -
i.e. something the current GLWidget would inherit from. It would also mean
that the engines would not be passed a GLWidget but a painter. So all drawing
operations would need to be encapsulated in the painter/paint engine.

  1. Conclusions

There are probably other ways that this could be implemented. I was going to
work on this tomorrow. As Donald pointed out nothing would be set in stone
and the API could be improved if it were found to be lacking. I am open to
suggestions on how people would like to see this implemented.

The engines would remain largely unchanged, simply
calling ::drawSphere(), ::drawText(), ::drawCylinder(), ::drawRibbon() (soon)
etc. It would be up to the painter to implement the low level drawing.

Thanks,

Marcus

I think generally the proposal sounds great – it solves an obvious
problem of export to other formats and rendering in different styles
(e.g., Qutemol or other shaders). The engines can then be blissfully
ignorant of such issues. This is a great, modular approach.

images using relatively few triangles for the spheres etc. Other
targets
could include writing a gl2ps painter to take advantage of the
gl2ps library
and an SVG painter to export our scenes as SVG.

One minor quibble. Actually, the gl2ps library also has SVG as an
option. One important side benefit of this work is that we could also
optionally enable a “Print” command. :slight_smile:

The engines would remain largely unchanged, simply
calling ::drawSphere(), ::drawText(), ::drawCylinder(), ::drawRibbon
() (soon)
etc. It would be up to the painter to implement the low level drawing.

This is the key step. While it’s easy to expand later (because the
design/architecture allows for it), we should try to enumerate likely
graphics calls now:

  • drawSphere()
  • drawText()
  • drawCylinder()

Changes/new:

  • drawSpline() – used for ribbon and maybe other curves – this is
    the smallest component of a ribbon view
  • drawPoint() – for wireframe view and maybe grid points
  • drawLine() – for wireframe view, arrows, annoations, etc.

Also, I think we should have a drawPoly() – which can be called with
a list of points (e.g., 3 points = triangle, 4 points = quad…).
This might be used for surface meshes, but also for planes (e.g.,
Carsten’s engine which draws planes through rings).

Most of those (poly, point, line) are really easy, but will really
help implementation of more advanced engines.

Cheers,
-Geoff

http://doc.trolltech.com/4.3/paintsystem.html
^^ good reading

On Saturday 23 June 2007 01:43:22 pm Geoffrey Hutchison wrote:

I think generally the proposal sounds great – it solves an obvious
problem of export to other formats and rendering in different styles
(e.g., Qutemol or other shaders). The engines can then be blissfully
ignorant of such issues. This is a great, modular approach.

images using relatively few triangles for the spheres etc. Other
targets
could include writing a gl2ps painter to take advantage of the
gl2ps library
and an SVG painter to export our scenes as SVG.

One minor quibble. Actually, the gl2ps library also has SVG as an
option. One important side benefit of this work is that we could also
optionally enable a “Print” command. :slight_smile:

The engines would remain largely unchanged, simply
calling ::drawSphere(), ::drawText(), ::drawCylinder(), ::drawRibbon
() (soon)
etc. It would be up to the painter to implement the low level drawing.

This is the key step. While it’s easy to expand later (because the
design/architecture allows for it), we should try to enumerate likely
graphics calls now:

  • drawSphere()
  • drawText()
  • drawCylinder()

Changes/new:

  • drawSpline() – used for ribbon and maybe other curves – this is
    the smallest component of a ribbon view
  • drawPoint() – for wireframe view and maybe grid points
  • drawLine() – for wireframe view, arrows, annoations, etc.

Also, I think we should have a drawPoly() – which can be called with
a list of points (e.g., 3 points = triangle, 4 points = quad…).
This might be used for surface meshes, but also for planes (e.g.,
Carsten’s engine which draws planes through rings).

Most of those (poly, point, line) are really easy, but will really
help implementation of more advanced engines.

Cheers,
-Geoff


This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/avogadro-devel

On Saturday 23 June 2007 19:43:22 Geoffrey Hutchison wrote:

One minor quibble. Actually, the gl2ps library also has SVG as an
option. One important side benefit of this work is that we could also
optionally enable a “Print” command. :slight_smile:

The SVG produced by gl2ps is quite different to the other possibility Benoit
and I discussed. With gl2ps it takes the triangles generated by the gl code
and turns them into vectors. We were thinking about the possibility of
turning the scene into SVG circles etc - a simpler representation that may
look cleaner. We were batting around ideas at the time and I thought that it
might be a useful representation that would also be made possible using this
approach.

The engines would remain largely unchanged, simply
calling ::drawSphere(), ::drawText(), ::drawCylinder(), ::drawRibbon
() (soon)
etc. It would be up to the painter to implement the low level drawing.

This is the key step. While it’s easy to expand later (because the
design/architecture allows for it), we should try to enumerate likely
graphics calls now:

  • drawSphere()
  • drawText()
  • drawCylinder()

Changes/new:

  • drawSpline() – used for ribbon and maybe other curves – this is
    the smallest component of a ribbon view
  • drawPoint() – for wireframe view and maybe grid points
  • drawLine() – for wireframe view, arrows, annoations, etc.

Also, I think we should have a drawPoly() – which can be called with
a list of points (e.g., 3 points = triangle, 4 points = quad…).
This might be used for surface meshes, but also for planes (e.g.,
Carsten’s engine which draws planes through rings).

Most of those (poly, point, line) are really easy, but will really
help implementation of more advanced engines.

I totally agree, I had some of the ones you propose for engines we already
have. I had thought about putting placeholders in for others although there
is no reason more couldn’t be added later if we found we had missed any.

Glad you like the proposal - I have been doing more reading this morning on
the way Qt implements this functionality. One problem I am not sure how to
abstract is some engines/tools using a different projection matrix such as
the selection box for the selectrotatetool and the axes for the axes engine.
They are not things we need to export and so in some senses could be left as
they are or we would figure out how to implement them without using a
different projection matrix.

Thanks,

Marcus

On Saturday 23 June 2007 20:51:39 Donald Ephraim Curtis wrote:

http://doc.trolltech.com/4.3/paintsystem.html
^^ good reading

I have been doing lots of reading but not so much coding. Not sure if that is
a good or a bad thing… I now understand pretty well how and why Qt handles
painting the way that it does. I can see how we could express a similar
concept in a 3D paint device that is specialised for our purposes.

Our painters/paint devices will be incompatible with the Qt ones, but that is
not a problem and is to be expected as they are expressing quite different
things. That is what I have concluded after reading lots of Qt source code
and documentation.

I still don’t see any compelling reason why having one painter with multiple
3dPaintEngines would be better than having multiple 3dPainters all inherited
from a base 3dPainter. Both would work but I could be missing something in
the advantages. It seems to revolve around whether the PaintDevice holds a
pointer to its PaintEngine accessed by the Painter, or holds a pointer to its
Painter. The former approach allows multiple Painters with different
attributes whilst the latter approach would only allow one Painter per
PaintDevice.

Question about Engine code layout too - is it better to have specific atom and
molecule rendering functions as I did for BSDY, Sphere etc or have much
larger render functions such as is present in BSDY now? I also don’t quite
see what all the sorting gets us in BSDY. You could presumably code a
Painter/PainterEngine that would store all its primitives and sort them
before rendering if you wanted perfect rendering and again free the Engine
from this detail. It could even be a Painter option, sortPrimitives(true) to
enable primitive sorting…

Shouldn’t the Painter/PainterEngine also take care of pushing the name/type of
the primitive. They could be the final two arguments to the drawing functions
defaulting to 0 if they are not set. Or it could be a separate function,
setType(int type), setId(int id) and a function setPrimitive(const Primitive*
p) that could get the values for itself. Benoit proposed a similar scheme for
use with the GLWidget but it seems better encapsulated along with other
Painter functions.

I don’t feel particularly productive but I would like to make sure that what I
code is suitably flexible and useful. So I would appreciate feedback and I
will be reading more source code and documentation. I will hopefully get the
chance to talk to some of the Trolls next week at aKademy too! The more I
read the more I see I have to learn.

Thanks,

Marcus

On Jun 24, 2007, at 9:48 AM, Marcus D. Hanwell wrote:

I have been doing lots of reading but not so much coding. Not sure
if that is
a good or a bad thing… I now understand pretty well how and why
Qt handles
painting the way that it does. I can see how we could express a
similar
concept in a 3D paint device that is specialised for our purposes.

I don’t know if Donald agrees, but I’ve found there’s a mix between
design and code. (Actually similar to starting a new chemistry
project. :slight_smile: You want to do some initial design, but at some point,
you won’t know how well things will work until you try them. There
are often design issues that only become obvious once you start.

General advice aside, it sounds like a good approach, but I do have
one question.

Right now with engines, you can have multiple engines rendering at
once – this allows really cool things like flexible labels, the
transparent sphere engine, etc.

What if I want to use the QuteMol painter, but send the result to a
PDF file? Am I out of luck? Can you “chain” painter objects? Would
you want to?

I see a few possible graphical outputs:

  • high-resolution bitmap (probably highest fidelity of on-screen
    shaders, etc.)
  • QuteMol shaders
  • “Cartoon” shaders
  • PDF / PS
  • SVG
  • POV-Ray

While I see some benefit to sending shader results to SVG or PDF, I
think the end result may be too complicated for a fairly small
percentage of usage. If we say you can have SVG or PDF with normal
rendering, or high-resolution bitmap with the cool effects, but not
both yet, I think most people would understand.

Thoughts? Am I just rambling?

Cheers,
-Geoff

Yes, i like to discuss a LOT before i start coding but there are always things
that we / I forget to talk about.

So, the painters are going to be what the engines use to draw to whatever
painting system we’re using. For now, painters will do all the stuff like
drawing spheres as they are now. Ideally, this will all translate to the
other painting surfaces. It’s not totally ideal because it limits some of
the other painting surfaces, but if we just focus on the OpenGL and then do
our “best” with the other ones, we should be good. I don’t know how
programmable shaders and stuff work so that QuteMol stuff may or may not be
how we think it will be. We should look into how that works or try to get
some input from the author.

In other words, whatever we want to be able to do in OpenGL, the other types
of painters need to find a similar way to display it for their painter. This
does mean that it will pass through all the engines and the image will
be “prepared” using the engines for any surface. That answer your question?

On Monday 25 June 2007, Geoffrey Hutchison wrote:

On Jun 24, 2007, at 9:48 AM, Marcus D. Hanwell wrote:

I have been doing lots of reading but not so much coding. Not sure
if that is
a good or a bad thing… I now understand pretty well how and why
Qt handles
painting the way that it does. I can see how we could express a
similar
concept in a 3D paint device that is specialised for our purposes.

I don’t know if Donald agrees, but I’ve found there’s a mix between
design and code. (Actually similar to starting a new chemistry
project. :slight_smile: You want to do some initial design, but at some point,
you won’t know how well things will work until you try them. There
are often design issues that only become obvious once you start.

General advice aside, it sounds like a good approach, but I do have
one question.

Right now with engines, you can have multiple engines rendering at
once – this allows really cool things like flexible labels, the
transparent sphere engine, etc.

What if I want to use the QuteMol painter, but send the result to a
PDF file? Am I out of luck? Can you “chain” painter objects? Would
you want to?

I see a few possible graphical outputs:

  • high-resolution bitmap (probably highest fidelity of on-screen
    shaders, etc.)
  • QuteMol shaders
  • “Cartoon” shaders
  • PDF / PS
  • SVG
  • POV-Ray

While I see some benefit to sending shader results to SVG or PDF, I
think the end result may be too complicated for a fairly small
percentage of usage. If we say you can have SVG or PDF with normal
rendering, or high-resolution bitmap with the cool effects, but not
both yet, I think most people would understand.

Thoughts? Am I just rambling?

Cheers,
-Geoff


This SF.net email is sponsored by DB2 Express
Download DB2 Express C - the FREE version of DB2 express and take
control of your XML. No limits. Just data. Click to get it now.
http://sourceforge.net/powerbar/db2/


Avogadro-devel mailing list
Avogadro-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/avogadro-devel