summaryrefslogtreecommitdiff
path: root/src/silx/gui/plot3d/scene/function.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/silx/gui/plot3d/scene/function.py')
-rw-r--r--src/silx/gui/plot3d/scene/function.py152
1 files changed, 82 insertions, 70 deletions
diff --git a/src/silx/gui/plot3d/scene/function.py b/src/silx/gui/plot3d/scene/function.py
index 3d0a62f..cde7cad 100644
--- a/src/silx/gui/plot3d/scene/function.py
+++ b/src/silx/gui/plot3d/scene/function.py
@@ -44,8 +44,7 @@ _logger = logging.getLogger(__name__)
class ProgramFunction(object):
- """Class providing a function to add to a GLProgram shaders.
- """
+ """Class providing a function to add to a GLProgram shaders."""
def setupProgram(self, context, program):
"""Sets-up uniforms of a program using this shader function.
@@ -63,6 +62,7 @@ class Fog(event.Notifier, ProgramFunction):
The background of the viewport is used as fog color,
otherwise it defaults to white.
"""
+
# TODO: add more controls (set fog range), add more fog modes
_fragDecl = """
@@ -120,26 +120,29 @@ class Fog(event.Notifier, ProgramFunction):
"""
# Provide scene z extent in camera coords
bounds = viewport.camera.extrinsic.transformBounds(
- viewport.scene.bounds(transformed=True, dataBounds=True))
+ viewport.scene.bounds(transformed=True, dataBounds=True)
+ )
return bounds[:, 2]
def setupProgram(self, context, program):
if not self.isOn:
return
- far, near = context.cache(key='zExtentCamera',
- factory=self._zExtentCamera,
- viewport=context.viewport)
+ far, near = context.cache(
+ key="zExtentCamera", factory=self._zExtentCamera, viewport=context.viewport
+ )
extent = far - near
- gl.glUniform2f(program.uniforms['fogExtentInfo'],
- 0.9/extent if extent != 0. else 0.,
- near)
+ gl.glUniform2f(
+ program.uniforms["fogExtentInfo"],
+ 0.9 / extent if extent != 0.0 else 0.0,
+ near,
+ )
# Use background color as fog color
bgColor = context.viewport.background
if bgColor is None:
- bgColor = 1., 1., 1.
- gl.glUniform3f(program.uniforms['fogColor'], *bgColor[:3])
+ bgColor = 1.0, 1.0, 1.0
+ gl.glUniform3f(program.uniforms["fogColor"], *bgColor[:3])
class ClippingPlane(ProgramFunction):
@@ -183,7 +186,7 @@ class ClippingPlane(ProgramFunction):
void clipping(vec4 position) {}
"""
- def __init__(self, point=(0., 0., 0.), normal=(0., 0., 0.)):
+ def __init__(self, point=(0.0, 0.0, 0.0), normal=(0.0, 0.0, 0.0)):
self._plane = utils.Plane(point, normal)
@property
@@ -209,7 +212,7 @@ class ClippingPlane(ProgramFunction):
It MUST be in use and using this function.
"""
if self.plane.isPlane:
- gl.glUniform4f(program.uniforms['planeEq'], *self.plane.parameters)
+ gl.glUniform4f(program.uniforms["planeEq"], *self.plane.parameters)
class DirectionalLight(event.Notifier, ProgramFunction):
@@ -279,9 +282,14 @@ class DirectionalLight(event.Notifier, ProgramFunction):
}
"""
- def __init__(self, direction=None,
- ambient=(1., 1., 1.), diffuse=(0., 0., 0.),
- specular=(1., 1., 1.), shininess=0):
+ def __init__(
+ self,
+ direction=None,
+ ambient=(1.0, 1.0, 1.0),
+ diffuse=(0.0, 0.0, 0.0),
+ specular=(1.0, 1.0, 1.0),
+ shininess=0,
+ ):
super(DirectionalLight, self).__init__()
self._direction = None
self.direction = direction # Set _direction
@@ -291,10 +299,10 @@ class DirectionalLight(event.Notifier, ProgramFunction):
self._specular = specular
self._shininess = shininess
- ambient = event.notifyProperty('_ambient')
- diffuse = event.notifyProperty('_diffuse')
- specular = event.notifyProperty('_specular')
- shininess = event.notifyProperty('_shininess')
+ ambient = event.notifyProperty("_ambient")
+ diffuse = event.notifyProperty("_diffuse")
+ specular = event.notifyProperty("_specular")
+ shininess = event.notifyProperty("_shininess")
@property
def isOn(self):
@@ -359,28 +367,29 @@ class DirectionalLight(event.Notifier, ProgramFunction):
if self.isOn and self._direction is not None:
# Transform light direction from camera space to object coords
lightdir = context.objectToCamera.transformDir(
- self._direction, direct=False)
+ self._direction, direct=False
+ )
lightdir /= numpy.linalg.norm(lightdir)
- gl.glUniform3f(program.uniforms['dLight.lightDir'], *lightdir)
+ gl.glUniform3f(program.uniforms["dLight.lightDir"], *lightdir)
# Convert view position to object coords
viewpos = context.objectToCamera.transformPoint(
- numpy.array((0., 0., 0., 1.), dtype=numpy.float32),
+ numpy.array((0.0, 0.0, 0.0, 1.0), dtype=numpy.float32),
direct=False,
- perspectiveDivide=True)[:3]
- gl.glUniform3f(program.uniforms['dLight.viewPos'], *viewpos)
+ perspectiveDivide=True,
+ )[:3]
+ gl.glUniform3f(program.uniforms["dLight.viewPos"], *viewpos)
- gl.glUniform3f(program.uniforms['dLight.ambient'], *self.ambient)
- gl.glUniform3f(program.uniforms['dLight.diffuse'], *self.diffuse)
- gl.glUniform3f(program.uniforms['dLight.specular'], *self.specular)
- gl.glUniform1f(program.uniforms['dLight.shininess'],
- self.shininess)
+ gl.glUniform3f(program.uniforms["dLight.ambient"], *self.ambient)
+ gl.glUniform3f(program.uniforms["dLight.diffuse"], *self.diffuse)
+ gl.glUniform3f(program.uniforms["dLight.specular"], *self.specular)
+ gl.glUniform1f(program.uniforms["dLight.shininess"], self.shininess)
class Colormap(event.Notifier, ProgramFunction):
-
- _declTemplate = string.Template("""
+ _declTemplate = string.Template(
+ """
uniform sampler2D cmap_texture;
uniform int cmap_normalization;
uniform float cmap_parameter;
@@ -429,7 +438,8 @@ class Colormap(event.Notifier, ProgramFunction):
}
return color;
}
- """)
+ """
+ )
_discardCode = """
if (value == 0.) {
@@ -439,13 +449,13 @@ class Colormap(event.Notifier, ProgramFunction):
call = "colormap"
- NORMS = 'linear', 'log', 'sqrt', 'gamma', 'arcsinh'
+ NORMS = "linear", "log", "sqrt", "gamma", "arcsinh"
"""Tuple of supported normalizations."""
_COLORMAP_TEXTURE_UNIT = 1
"""Texture unit to use for storing the colormap"""
- def __init__(self, colormap=None, norm='linear', gamma=0., range_=(1., 10.)):
+ def __init__(self, colormap=None, norm="linear", gamma=0.0, range_=(1.0, 10.0)):
"""Shader function to apply a colormap to a value.
:param colormap: RGB(A) color look-up table (default: gray)
@@ -459,11 +469,11 @@ class Colormap(event.Notifier, ProgramFunction):
# Init privates to default
self._colormap = None
- self._norm = 'linear'
- self._gamma = -1.
- self._range = 1., 10.
+ self._norm = "linear"
+ self._gamma = -1.0
+ self._range = 1.0, 10.0
self._displayValuesBelowMin = True
- self._nancolor = numpy.array((1., 1., 1., 0.), dtype=numpy.float32)
+ self._nancolor = numpy.array((1.0, 1.0, 1.0, 0.0), dtype=numpy.float32)
self._texture = None
self._textureToDiscard = None
@@ -471,8 +481,7 @@ class Colormap(event.Notifier, ProgramFunction):
if colormap is None:
# default colormap
colormap = numpy.empty((256, 3), dtype=numpy.uint8)
- colormap[:] = numpy.arange(256,
- dtype=numpy.uint8)[:, numpy.newaxis]
+ colormap[:] = numpy.arange(256, dtype=numpy.uint8)[:, numpy.newaxis]
# Set to values through properties to perform asserts and updates
self.colormap = colormap
@@ -484,7 +493,8 @@ class Colormap(event.Notifier, ProgramFunction):
def decl(self):
"""Source code of the function declaration"""
return self._declTemplate.substitute(
- discard="" if self.displayValuesBelowMin else self._discardCode)
+ discard="" if self.displayValuesBelowMin else self._discardCode
+ )
@property
def colormap(self):
@@ -503,17 +513,21 @@ class Colormap(event.Notifier, ProgramFunction):
data = numpy.empty(
(16, self._colormap.shape[0], self._colormap.shape[1]),
- dtype=self._colormap.dtype)
+ dtype=self._colormap.dtype,
+ )
data[:] = self._colormap
format_ = gl.GL_RGBA if data.shape[-1] == 4 else gl.GL_RGB
self._texture = _glutils.Texture(
- format_, data, format_,
+ format_,
+ data,
+ format_,
texUnit=self._COLORMAP_TEXTURE_UNIT,
minFilter=gl.GL_NEAREST,
magFilter=gl.GL_NEAREST,
- wrap=gl.GL_CLAMP_TO_EDGE)
+ wrap=gl.GL_CLAMP_TO_EDGE,
+ )
self.notify()
@@ -524,7 +538,7 @@ class Colormap(event.Notifier, ProgramFunction):
@nancolor.setter
def nancolor(self, color):
- color = numpy.clip(numpy.array(color, dtype=numpy.float32), 0., 1.)
+ color = numpy.clip(numpy.array(color, dtype=numpy.float32), 0.0, 1.0)
assert color.ndim == 1
assert len(color) == 4
if not numpy.array_equal(self._nancolor, color):
@@ -545,7 +559,7 @@ class Colormap(event.Notifier, ProgramFunction):
if norm != self._norm:
assert norm in self.NORMS
self._norm = norm
- if norm in ('log', 'sqrt'):
+ if norm in ("log", "sqrt"):
self.range_ = self.range_ # To test for positive range_
self.notify()
@@ -557,7 +571,7 @@ class Colormap(event.Notifier, ProgramFunction):
@gamma.setter
def gamma(self, gamma):
if gamma != self._gamma:
- assert gamma >= 0.
+ assert gamma >= 0.0
self._gamma = gamma
self.notify()
@@ -577,15 +591,13 @@ class Colormap(event.Notifier, ProgramFunction):
assert len(range_) == 2
range_ = float(range_[0]), float(range_[1])
- if self.norm == 'log' and (range_[0] <= 0. or range_[1] <= 0.):
- _logger.warning(
- "Log normalization and negative range: updating range.")
+ if self.norm == "log" and (range_[0] <= 0.0 or range_[1] <= 0.0):
+ _logger.warning("Log normalization and negative range: updating range.")
minPos = numpy.finfo(numpy.float32).tiny
range_ = max(range_[0], minPos), max(range_[1], minPos)
- elif self.norm == 'sqrt' and (range_[0] < 0. or range_[1] < 0.):
- _logger.warning(
- "Sqrt normalization and negative range: updating range.")
- range_ = max(range_[0], 0.), max(range_[1], 0.)
+ elif self.norm == "sqrt" and (range_[0] < 0.0 or range_[1] < 0.0):
+ _logger.warning("Sqrt normalization and negative range: updating range.")
+ range_ = max(range_[0], 0.0), max(range_[1], 0.0)
if range_ != self._range:
self._range = range_
@@ -593,8 +605,7 @@ class Colormap(event.Notifier, ProgramFunction):
@property
def displayValuesBelowMin(self):
- """True to display values below colormap min, False to discard them.
- """
+ """True to display values below colormap min, False to discard them."""
return self._displayValuesBelowMin
@displayValuesBelowMin.setter
@@ -615,33 +626,34 @@ class Colormap(event.Notifier, ProgramFunction):
self._texture.bind()
- gl.glUniform1i(program.uniforms['cmap_texture'],
- self._texture.texUnit)
+ gl.glUniform1i(program.uniforms["cmap_texture"], self._texture.texUnit)
min_, max_ = self.range_
- param = 0.
- if self._norm == 'log':
+ param = 0.0
+ if self._norm == "log":
min_, max_ = numpy.log10(min_), numpy.log10(max_)
normID = 1
- elif self._norm == 'sqrt':
+ elif self._norm == "sqrt":
min_, max_ = numpy.sqrt(min_), numpy.sqrt(max_)
normID = 2
- elif self._norm == 'gamma':
+ elif self._norm == "gamma":
# Keep min_, max_ as is
param = self._gamma
normID = 3
- elif self._norm == 'arcsinh':
+ elif self._norm == "arcsinh":
min_, max_ = numpy.arcsinh(min_), numpy.arcsinh(max_)
normID = 4
else: # Linear
normID = 0
- gl.glUniform1i(program.uniforms['cmap_normalization'], normID)
- gl.glUniform1f(program.uniforms['cmap_parameter'], param)
- gl.glUniform1f(program.uniforms['cmap_min'], min_)
- gl.glUniform1f(program.uniforms['cmap_oneOverRange'],
- (1. / (max_ - min_)) if max_ != min_ else 0.)
- gl.glUniform4f(program.uniforms['nancolor'], *self._nancolor)
+ gl.glUniform1i(program.uniforms["cmap_normalization"], normID)
+ gl.glUniform1f(program.uniforms["cmap_parameter"], param)
+ gl.glUniform1f(program.uniforms["cmap_min"], min_)
+ gl.glUniform1f(
+ program.uniforms["cmap_oneOverRange"],
+ (1.0 / (max_ - min_)) if max_ != min_ else 0.0,
+ )
+ gl.glUniform4f(program.uniforms["nancolor"], *self._nancolor)
def prepareGL2(self, context):
if self._textureToDiscard is not None: