Skip to content

Commit

Permalink
Improve freeglut support in OpenGL visualizer (espressomd#4691)
Browse files Browse the repository at this point in the history
Description of changes:
- always check for the presence of GLE functions before invoking them
  • Loading branch information
kodiakhq[bot] authored and jngrad committed Mar 21, 2023
1 parent 289ac79 commit 6ff3501
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 24 deletions.
2 changes: 1 addition & 1 deletion doc/sphinx/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ Run the following commands:
.. code-block:: bash
brew install cmake python cython boost boost-mpi fftw \
doxygen gsl numpy scipy ipython jupyter
doxygen gsl numpy scipy ipython jupyter freeglut
brew install hdf5-mpi
brew link --force cython
pip install -c requirements.txt PyOpenGL matplotlib
Expand Down
54 changes: 31 additions & 23 deletions src/python/espressomd/visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,12 @@ def _rasterize_shape(self):
continue
return points

def _has_gle_features(self, feature_names):
for feature_name in feature_names:
if not bool(getattr(OpenGL.GLE, feature_name)):
return False
return True


class Cylinder(Shape):
"""
Expand Down Expand Up @@ -2006,14 +2012,16 @@ def __init__(self, shape, particle_type, color, material,
self.length = self.shape.get_parameter('length')
self.thickness = self.shape.get_parameter('thickness')
self.central_angle = self.shape.get_parameter('central_angle')
self.use_gle = self._has_gle_features(
["gleSpiral", "gleSetNumSides", "gleSetJoinStyle"])

def draw(self):
"""
Draw using OpenGL Extrusion library, if available.
Use rasterization of base class, otherwise.
"""
if bool(OpenGL.GLE.gleSpiral) and self.central_angle == 0.:
if self.use_gle and self.central_angle == 0.:
self._draw_using_gle()
else:
super().draw()
Expand Down Expand Up @@ -2072,6 +2080,8 @@ def __init__(self, shape, particle_type, color, material,
self.smoothing_radius = np.array(
self.shape.get_parameter('smoothing_radius'))
self.max_box_l = max(box_l)
self.use_gle = self._has_gle_features(
["gleSpiral", "gleSetNumSides", "gleSetJoinStyle"])

def draw(self):
"""
Expand All @@ -2086,35 +2096,33 @@ def draw(self):
ax, rx, ry = rotation_helper(self.axis)
OpenGL.GL.glRotatef(ax, rx, ry, 0.0)

if bool(OpenGL.GLE.gleSpiral):
if self.use_gle:
self._draw_using_gle()
else:
self._draw_using_primitives()

OpenGL.GL.glPopMatrix()

def _draw_using_gle(self):
# if available, use the GL Extrusion library
if bool(OpenGL.GLE.gleSpiral):
n = max(10, self.quality // 3)
contour = [[0.5 * self.max_box_l, -0.5 * self.length]]
for theta in np.linspace(0, 0.5 * np.pi, n):
contour.append([(1. - np.sin(theta)) * self.smoothing_radius,
-0.5 * self.length + (1. - np.cos(theta)) * self.smoothing_radius])
for theta in np.linspace(0.5 * np.pi, np.pi, n):
contour.append([(1. - np.sin(theta)) * self.smoothing_radius,
0.5 * self.length - (1. + np.cos(theta)) * self.smoothing_radius])
contour.append([0.5 * self.max_box_l, 0.5 * self.length])

normals = np.diff(np.array(contour), axis=0)
normals /= np.linalg.norm(normals, ord=2, axis=1, keepdims=True)
normals = np.roll(normals, 1, axis=1)
normals[:, 0] *= -1

OpenGL.GLE.gleSetJoinStyle(OpenGL.GLE.TUBE_JN_ANGLE)
OpenGL.GLE.gleSetNumSides(max(90, 3 * self.quality))
OpenGL.GLE.gleSpiral(contour, normals, [0, 0, 1], self.radius, 0., 0., 0.,
[[1, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0]], 0., 360)
n = max(10, self.quality // 3)
contour = [[0.5 * self.max_box_l, -0.5 * self.length]]
for theta in np.linspace(0, 0.5 * np.pi, n):
contour.append([(1. - np.sin(theta)) * self.smoothing_radius,
-0.5 * self.length + (1. - np.cos(theta)) * self.smoothing_radius])
for theta in np.linspace(0.5 * np.pi, np.pi, n):
contour.append([(1. - np.sin(theta)) * self.smoothing_radius,
0.5 * self.length - (1. + np.cos(theta)) * self.smoothing_radius])
contour.append([0.5 * self.max_box_l, 0.5 * self.length])

normals = np.diff(np.array(contour), axis=0)
normals /= np.linalg.norm(normals, ord=2, axis=1, keepdims=True)
normals = np.roll(normals, 1, axis=1)
normals[:, 0] *= -1

OpenGL.GLE.gleSetJoinStyle(OpenGL.GLE.TUBE_JN_ANGLE)
OpenGL.GLE.gleSetNumSides(max(90, 3 * self.quality))
OpenGL.GLE.gleSpiral(contour, normals, [0, 0, 1], self.radius, 0., 0., 0.,
[[1, 0, 0], [0, 1, 0]], [[0, 0, 0], [0, 0, 0]], 0., 360)

def _draw_using_primitives(self):
clip_plane = get_extra_clip_plane()
Expand Down

0 comments on commit 6ff3501

Please sign in to comment.