1 /**********************************************************************
2 POVPainter - drawing spheres, cylinders and text in a POVRay scene
4 Copyright (C) 2007 Marcus D. Hanwell
6 This file is part of the Avogadro molecular editor project.
7 For more information, see <http://avogadro.sourceforge.net/>
9 Avogadro is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 Avogadro is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 **********************************************************************/
25 #ifndef __POVPAINTER_H
26 #define __POVPAINTER_H
28 #include <avogadro/global.h>
29 #include <avogadro/painter.h>
30 #include <avogadro/glwidget.h>
35 using namespace Eigen
;
39 // Forward declaration
43 * @class POVPainter povpainter.h
44 * @brief Implementation of the Painter class using POV-Ray.
45 * @author Marcus D. Hanwell
47 * This class implements the base Painter class using POV-Ray. It is intended
48 * to be used with the POV-Ray to raytrace molecules and other constructs to
53 class POVPainterPrivate
;
54 class A_EXPORT POVPainter
: public Painter
59 * @param quality defaults to -1, valid range from 0 to 4.
69 * @return the current global quality setting.
71 int quality() const { return 4; };
74 * Uses the primitive to set the type and name. Not used by POV-Ray as it
75 * is not an interactive display.
77 void setName (const Primitive
*) { }
80 * Sets the primitive type and id. Not used by POV-Ray as it is not an
81 * interactive display.
83 void setName (Primitive::Type
, int) { }
86 * Set the color to paint the primitives with.
87 * @param color the color to be used for painting.
89 void setColor (const Color
*color
);
92 * Set the color to paint elements with where 0.0 is the minimum and 1.0
94 * @param red component of the color.
95 * @param green component of the color.
96 * @param blue component of the color.
97 * @param alpha component of the color.
99 void setColor (float red
, float green
, float blue
, float alpha
= 1.0);
102 * Sets the plane normal of the scene, this affects the way higher order
103 * bonds are rendered.
105 void setPlaneNormal (Vector3d planeNormalVector
);
108 * Draws a sphere, leaving the Painter choose the appropriate detail level based on the
109 * apparent radius (ratio of radius over distance) and the global quality setting.
110 * @param center the position of the center of the sphere.
111 * @param radius the radius of the sphere.
113 void drawSphere (const Vector3d
& center
, double radius
);
116 * Draws a cylinder, leaving the Painter choose the appropriate detail level based on the
117 * apparent radius (ratio of radius over distance) and the global quality setting.
118 * @param end1 the position of the first end of the cylinder.
119 * @param end2 the position of the second end of the cylinder.
120 * @param radius the radius, i.e. half-width of the cylinder.
122 void drawCylinder (const Vector3d
&end1
, const Vector3d
&end2
,
126 * Draws a multiple cylinder (see below), leaving the Painter choose the appropriate
127 * detail level based on the apparent radius (ratio of radius over distance) and the
128 * global quality setting.
130 * What is a "multiple cylinder"? Think bond of order two or more between two atoms.
131 * This function is here to allow drawing multiple bonds in a single call.
133 * This function takes care of rendering multiple bonds in such a way that the individual
134 * bonds avoid hiding each other, at least in the defaut viewpoint of a molecule.
135 * To achieves that, it asks the GLWidget for the the normal vector of the
136 * molecule's best-fitting plane.
138 * @param end1 the position of the first end of the bond.
139 * @param end2 the position of the second end of the bond.
140 * @param radius the radius, i.e. half-width of each cylinder.
141 * @param order the multiplicity order of the bond, e.g. 2 for a double bond.
142 * When this parameter equals 1, this function is equivalent to
144 * @param shift how far away from the central axis the cylinders are shifted.
145 * In other words this influences the total width of multiple bonds.
147 void drawMultiCylinder (const Vector3d
&end1
, const Vector3d
&end2
,
148 double radius
, int order
, double shift
);
151 * Draws a cone between the tip and the base with the base radius given.
152 * @param base the position of the base of the cone.
153 * @param tip the position of the tip of the cone.
154 * @param radius the radius of the base of the cone.
156 void drawCone(const Eigen::Vector3d
&, const Eigen::Vector3d
&,
160 * Draws a line between the given points of the given width.
161 * @param start the position of the start of the line.
162 * @param end the position of the end of the line.
163 * @param lineWidth the width of the line.
165 void drawLine(const Eigen::Vector3d
&, const Eigen::Vector3d
&,
169 * Draws a multiple line between the given points. This function is the
170 * line equivalent to the drawMultiCylinder function and performs the
171 * same basic operations using simpler and quicker lines.
172 * @param start the position of the start of the line.
173 * @param end the position of the end of the line.
174 * @param lineWidth the width of the line.
175 * @param order the order of the bond, e.g. 2 for a double bond.
176 * @param stipple The stipple parameter for the bond, can be used to
177 * draw aromatic bonds etc.
178 * sa drawMultiCylinder
180 void drawMultiLine(const Eigen::Vector3d
&, const Eigen::Vector3d
&,
181 double, int, short) { }
184 * Draws a triangle with vertives on the three given points. This function
185 * calculates the normal of the triangle and corrects the winding order to
186 * ensure the front face is facing the camera.
187 * @param p1 first triangle vertex.
188 * @param p2 second triangle vertex.
189 * @param p3 third triangle vertex.
191 void drawTriangle(const Eigen::Vector3d
&, const Eigen::Vector3d
&,
192 const Eigen::Vector3d
&) { }
195 * Draws a triangle with vertives on the three given points using the
196 * given normal. This function corrects the triangle's winding order.
197 * @param p1 first triangle vertex.
198 * @param p2 second triangle vertex.
199 * @param p3 third triangle vertex.
200 * @param n the normal of the triangle.
202 void drawTriangle(const Eigen::Vector3d
&, const Eigen::Vector3d
&,
203 const Eigen::Vector3d
&, const Eigen::Vector3d
&) { }
206 * Draw a cubic B-spline between the given points.
207 * @param pts QVector containing the points to draw the cubic B-spline
209 * @param radius the radius of the cubic B-spline.
211 void drawSpline(const QVector
<Eigen::Vector3d
>&, double) { }
214 * Draws a shaded sector of a circle. The sector is defined by three vectors,
215 * the center of the circle, and two vectors that define the lines going out
216 * from the centre of the circle to the circumference of the circle. The
217 * actual points on the circumference are found using these two vectors and
218 * the radius of the circle.
220 * @param origin the center of the circle this sector is a portion of.
221 * @param direction1 a vector defining the line the first point will lie on.
222 * @param direction2 a vector defining the line the second point will lie on.
223 * @param radius the radius of the circle this sector is a portion of.
224 * @param alternateAngle whether to draw the obtuse angle made by the two vectors
225 * instead of the acute angle between them.
227 void drawShadedSector(Eigen::Vector3d origin
, Eigen::Vector3d direction1
,
228 Eigen::Vector3d direction2
, double radius
,
229 bool alternateAngle
= false);
232 * Draws an arc. The arc is defined by three vectors, the center of the circle,
233 * and two vectors that define the lines going out from the center of the
234 * circle to the circumference of the circle. The actual points on the
235 * circumference are found using these two vectors and the radius of the circle.
237 * @param origin the center of the circle whose circumference this arc is a portion of.
238 * @param direction1 a vector defining the line the start of the arc will lie on.
239 * @param direction2 a vector defining the line the end of the arc will lie on.
240 * @param radius the radius of the circle whose circumference this arc is a portion of.
241 * @param lineWidth the thickness of the line the arc will be drawn with.
242 * @param alternateAngle whether to draw the obtuse angle made by the two vectors
243 * instead of the acute angle between them.
245 void drawArc(Eigen::Vector3d origin
, Eigen::Vector3d direction1
, Eigen::Vector3d direction2
,
246 double radius
, double lineWidth
, bool alternateAngle
= false);
249 * Draws a solid two dimensional quadrilateral in three dimensional space.
251 * @param point1 the first of the four corners of the quadrilateral.
252 * @param point2 the second of the four corners of the quadrilateral.
253 * @param point3 the third of the four corners of the quadrilateral.
254 * @param point4 the last of the four corners of the quadrilateral.
256 void drawShadedQuadrilateral(Eigen::Vector3d point1
, Eigen::Vector3d point2
,
257 Eigen::Vector3d point3
, Eigen::Vector3d point4
);
260 * Draws the outline of a two dimensional quadrilateral in three dimensional space.
262 * @param point1 the first of the four corners of the quadrilateral.
263 * @param point2 the second of the four corners of the quadrilateral.
264 * @param point3 the third of the four corners of the quadrilateral.
265 * @param point4 the last of the four corners of the quadrilateral.
266 * @param lineWidth the thickness of the line the quadrilateral will be drawn with.
268 void drawQuadrilateral(Eigen::Vector3d point1
, Eigen::Vector3d point2
,
269 Eigen::Vector3d point3
, Eigen::Vector3d point4
,
272 int drawText (int x
, int y
, const QString
&string
) const;
273 int drawText (const QPoint
& pos
, const QString
&string
) const;
274 int drawText (const Vector3d
& pos
, const QString
&string
) const;
276 void begin(QTextStream
*output
, Vector3d planeNormalVector
);
280 POVPainterPrivate
* const d
;
284 class A_EXPORT POVPainterDevice
: public PainterDevice
287 POVPainterDevice(const QString
& filename
, const GLWidget
* glwidget
);
290 void initializePOV();
293 Painter
*painter() const { return m_painter
; }
294 Camera
*camera() const { return m_glwidget
->camera(); }
295 bool isSelected(const Primitive
*p
) const { return m_glwidget
->isSelected(p
); }
296 double radius(const Primitive
*p
) const { return m_glwidget
->radius(p
); }
297 const Molecule
*molecule() const { return m_glwidget
->molecule(); }
298 Color
*colorMap() const { return m_glwidget
->colorMap(); }
300 int width() { return m_glwidget
->width(); }
301 int height() { return m_glwidget
->height(); }
304 const GLWidget
*m_glwidget
;
305 QList
<Engine
*> m_engines
;
306 POVPainter
*m_painter
;
308 QTextStream
*m_output
;
311 } // End namespace Avogadro