[yt-svn] commit/yt: ngoldbaum: Merged in atmyers/yt (pull request #2135)
commits-noreply at bitbucket.org
commits-noreply at bitbucket.org
Wed May 18 11:23:59 PDT 2016
1 new commit in yt:
https://bitbucket.org/yt_analysis/yt/commits/d39510be5062/
Changeset: d39510be5062
Branch: yt
User: ngoldbaum
Date: 2016-05-18 18:23:47+00:00
Summary: Merged in atmyers/yt (pull request #2135)
Interactive Unstructured Mesh Rendering with OpenGL
Affected #: 9 files
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/frontends/exodus_ii/data_structures.py
--- a/yt/frontends/exodus_ii/data_structures.py
+++ b/yt/frontends/exodus_ii/data_structures.py
@@ -154,7 +154,8 @@
units_override=units_override)
self.index_filename = filename
self.storage_filename = storage_filename
- self.default_field = ("connect1", "diffused")
+ self.default_field = [f for f in self.field_list
+ if f[0] == 'connect1'][-1]
def _set_code_unit_attributes(self):
# This is where quantities are created that represent the various
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/frontends/stream/data_structures.py
--- a/yt/frontends/stream/data_structures.py
+++ b/yt/frontends/stream/data_structures.py
@@ -1826,5 +1826,7 @@
sds._node_fields = node_data[0].keys()
sds._elem_fields = elem_data[0].keys()
+ sds.default_field = [f for f in sds.field_list
+ if f[0] == 'connect1'][-1]
return sds
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/utilities/lib/mesh_construction.h
--- a/yt/utilities/lib/mesh_construction.h
+++ b/yt/utilities/lib/mesh_construction.h
@@ -37,7 +37,7 @@
{-1, -1, -1}
};
-// Triangule wedges
+// Triangulate wedges
int triangulate_wedge[MAX_NUM_TRI][3] = {
{0, 1, 2},
{0, 3, 1},
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/visualization/volume_rendering/interactive_vr.py
--- a/yt/visualization/volume_rendering/interactive_vr.py
+++ b/yt/visualization/volume_rendering/interactive_vr.py
@@ -18,6 +18,7 @@
from collections import OrderedDict
import matplotlib.cm as cm
import numpy as np
+import ctypes
from yt.utilities.math_utils import \
get_translate_matrix, \
@@ -29,7 +30,6 @@
rotation_matrix_to_quaternion
from .shader_objects import known_shaders, ShaderProgram
-
bbox_vertices = np.array(
[[ 0., 0., 0., 1.],
[ 0., 0., 1., 1.],
@@ -77,6 +77,27 @@
+1.0, +1.0, 0.0], dtype=np.float32
)
+triangulate_hex = np.array([
+ [0, 2, 1], [0, 3, 2],
+ [4, 5, 6], [4, 6, 7],
+ [0, 1, 5], [0, 5, 4],
+ [1, 2, 6], [1, 6, 5],
+ [0, 7, 3], [0, 4, 7],
+ [3, 6, 2], [3, 7, 6]]
+)
+
+triangulate_tetra = np.array([
+ [0, 1, 3], [2, 3, 1],
+ [0, 3, 2], [0, 2, 1]]
+)
+
+triangulate_wedge = np.array([
+ [3, 0, 1], [4, 3, 1],
+ [2, 5, 4], [2, 4, 1],
+ [0, 3, 2], [2, 3, 5],
+ [3, 4, 5], [0, 2, 1]]
+)
+
class IDVCamera(object):
'''Camera object used in the Interactive Data Visualization
@@ -532,8 +553,180 @@
GL.GL_RED, GL.GL_FLOAT, n_data.T)
GL.glGenerateMipmap(GL.GL_TEXTURE_3D)
+class ColorBarSceneComponent(SceneComponent):
+ '''
-class SceneGraph(SceneComponent):
+ A class for scene components that apply colorbars using a 1D texture.
+
+ '''
+
+ def __init__(self):
+ super(ColorBarSceneComponent, self).__init__()
+ self.camera = None
+ self.cmap_texture = None
+
+ def set_camera(self, camera):
+ pass
+
+ def update_minmax(self):
+ pass
+
+ def setup_cmap_tex(self):
+ '''Creates 1D texture that will hold colormap in framebuffer'''
+ self.cmap_texture = GL.glGenTextures(1) # create target texture
+ GL.glBindTexture(GL.GL_TEXTURE_1D, self.cmap_texture)
+ GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
+ GL.glTexParameterf(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE)
+ GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
+ GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
+ GL.glTexImage1D(GL.GL_TEXTURE_1D, 0, GL.GL_RGBA, 256,
+ 0, GL.GL_RGBA, GL.GL_FLOAT, self.camera.cmap)
+ GL.glBindTexture(GL.GL_TEXTURE_1D, 0)
+
+ def update_cmap_tex(self):
+ '''Updates 1D texture with colormap that's used in framebuffer'''
+ if self.camera is None or not self.camera.cmap_new:
+ return
+
+ if self.cmap_texture is None:
+ self.setup_cmap_tex()
+
+ GL.glBindTexture(GL.GL_TEXTURE_1D, self.cmap_texture)
+ GL.glTexSubImage1D(GL.GL_TEXTURE_1D, 0, 0, 256,
+ GL.GL_RGBA, GL.GL_FLOAT, self.camera.cmap)
+ self.camera.cmap_new = False
+
+class MeshSceneComponent(ColorBarSceneComponent):
+ '''
+
+ A scene component for representing unstructured mesh data.
+
+ '''
+
+ def __init__(self, data_source, field):
+ super(MeshSceneComponent, self).__init__()
+ self.set_shader("mesh.v")
+ self.set_shader("mesh.f")
+
+ self.data_source = None
+ self.redraw = True
+
+ GL.glEnable(GL.GL_DEPTH_TEST)
+ GL.glDepthFunc(GL.GL_LESS)
+ GL.glEnable(GL.GL_CULL_FACE)
+ GL.glCullFace(GL.GL_BACK)
+
+ vertices, data, indices = self.get_mesh_data(data_source, field)
+
+ self._initialize_vertex_array("mesh_info")
+ GL.glBindVertexArray(self.vert_arrays["mesh_info"])
+
+ self.add_vert_attrib("vertex_buffer", vertices, vertices.size)
+ self.add_vert_attrib("data_buffer", data, data.size)
+
+ self.vert_attrib["element_buffer"] = (GL.glGenBuffers(1), indices.size)
+ GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.vert_attrib["element_buffer"][0])
+ GL.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL.GL_STATIC_DRAW)
+
+ self.transform_matrix = GL.glGetUniformLocation(self.program.program,
+ "model_to_clip")
+
+ self.cmin = data.min()
+ self.cmax = data.max()
+
+ def set_camera(self, camera):
+ r""" Sets the camera orientation for the entire scene.
+
+ Parameters
+ ----------
+ camera : Camera
+
+ """
+ self.camera = camera
+ self.camera.cmap_min = float(self.cmin)
+ self.camera.cmap_max = float(self.cmax)
+ self.redraw = True
+
+ def get_mesh_data(self, data_source, field):
+ """
+
+ This reads the mesh data into a form that can be fed in to OpenGL.
+
+ """
+
+ # get mesh information
+ ftype, fname = field
+ mesh_id = int(ftype[-1])
+ mesh = data_source.ds.index.meshes[mesh_id-1]
+ offset = mesh._index_offset
+ vertices = mesh.connectivity_coords
+ indices = mesh.connectivity_indices - offset
+
+ # get vertex data
+ data = data_source[field]
+ vertex_data = np.zeros(vertices.shape[0], dtype=data.dtype)
+ vertex_data[indices.flatten()] = data.flatten()
+
+ if indices.shape[1] == 8:
+ tri_array = triangulate_hex
+ elif indices.shape[1] == 4:
+ tri_array = triangulate_tetra
+ elif indices.shape[1] == 6:
+ tri_array = triangulate_wedge
+ else:
+ raise NotImplementedError
+
+ tri_indices = []
+ for elem in indices:
+ for tri in tri_array:
+ tri_indices.append(elem[tri])
+ tri_indices = np.array(tri_indices)
+
+ v = vertices.astype(np.float32).flatten()
+ d = vertex_data.astype(np.float32).flatten()
+ i = tri_indices.astype(np.uint32).flatten()
+
+ return v, d, i
+
+ def run_program(self):
+ """ Renders one frame of the scene. """
+ with self.program.enable():
+
+ # Handle colormap
+ self.update_cmap_tex()
+
+ GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
+ projection_matrix = self.camera.projection_matrix
+ view_matrix = self.camera.view_matrix
+ model_to_clip = np.dot(projection_matrix, view_matrix)
+ GL.glUniformMatrix4fv(self.transform_matrix, 1, True, model_to_clip)
+
+ GL.glActiveTexture(GL.GL_TEXTURE1)
+ GL.glBindTexture(GL.GL_TEXTURE_1D, self.cmap_texture)
+
+ self.program._set_uniform("cmap", 0)
+ self.program._set_uniform("cmap_min", self.camera.cmap_min)
+ self.program._set_uniform("cmap_max", self.camera.cmap_max)
+
+ GL.glEnableVertexAttribArray(0)
+ GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vert_attrib["vertex_buffer"][0])
+ GL.glVertexAttribPointer(0, 3, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0))
+
+ GL.glEnableVertexAttribArray(1)
+ GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vert_attrib["data_buffer"][0])
+ GL.glVertexAttribPointer(1, 1, GL.GL_FLOAT, False, 0, ctypes.c_void_p(0))
+
+ GL.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, self.vert_attrib["element_buffer"][0])
+ GL.glDrawElements(GL.GL_TRIANGLES, self.vert_attrib["element_buffer"][1],
+ GL.GL_UNSIGNED_INT, ctypes.c_void_p(0))
+
+ GL.glDisableVertexAttribArray(0)
+ GL.glDisableVertexAttribArray(1)
+
+ render = run_program
+
+
+class SceneGraph(ColorBarSceneComponent):
"""A basic OpenGL render for IDV.
The SceneGraph class is the primary driver behind creating a IDV rendering.
@@ -554,8 +747,6 @@
self.collections = []
self.fbo = None
self.fb_texture = None
- self.cmap_texture = None
- self.camera = None
self.shader_program = None
self.fb_shader_program = None
self.min_val, self.max_val = 1e60, -1e60
@@ -587,36 +778,8 @@
self.setup_fb(self.width, self.height)
- def setup_cmap_tex(self):
- '''Creates 1D texture that will hold colormap in framebuffer'''
- self.cmap_texture = GL.glGenTextures(1) # create target texture
- GL.glBindTexture(GL.GL_TEXTURE_1D, self.cmap_texture)
- GL.glPixelStorei(GL.GL_UNPACK_ALIGNMENT, 1)
- GL.glTexParameterf(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE)
- GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR)
- GL.glTexParameteri(GL.GL_TEXTURE_1D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR)
- GL.glTexImage1D(GL.GL_TEXTURE_1D, 0, GL.GL_RGBA, 256,
- 0, GL.GL_RGBA, GL.GL_FLOAT, self.camera.cmap)
- GL.glBindTexture(GL.GL_TEXTURE_1D, 0)
-
-
- def update_cmap_tex(self):
- '''Updates 1D texture with colormap that's used in framebuffer'''
- if self.camera is None or not self.camera.cmap_new:
- return
-
- if self.cmap_texture is None:
- self.setup_cmap_tex()
-
- GL.glBindTexture(GL.GL_TEXTURE_1D, self.cmap_texture)
- GL.glTexSubImage1D(GL.GL_TEXTURE_1D, 0, 0, 256,
- GL.GL_RGBA, GL.GL_FLOAT, self.camera.cmap)
- GL.glBindTexture(GL.GL_TEXTURE_1D, 0)
- self.camera.cmap_new = False
-
-
def setup_fb(self, width, height):
- '''Setups FrameBuffer that will be used as container
+ '''Sets up FrameBuffer that will be used as container
for 1 pass of rendering'''
# Clean up old FB and Texture
if self.fb_texture is not None and \
@@ -670,7 +833,6 @@
status = GL.glCheckFramebufferStatus(GL.GL_FRAMEBUFFER)
assert status == GL.GL_FRAMEBUFFER_COMPLETE, status
-
def add_collection(self, collection):
r"""Adds a block collection to the scene. Collections must not overlap.
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/visualization/volume_rendering/interactive_vr_helpers.py
--- a/yt/visualization/volume_rendering/interactive_vr_helpers.py
+++ b/yt/visualization/volume_rendering/interactive_vr_helpers.py
@@ -58,7 +58,8 @@
raise ImportError("This functionality requires the cyglfw3 and PyOpenGL "
"packages to be installed.")
- from .interactive_vr import SceneGraph, BlockCollection, TrackballCamera
+ from .interactive_vr import SceneGraph, BlockCollection, TrackballCamera, \
+ MeshSceneComponent
from .interactive_loop import RenderingContext
if isinstance(data_source, Dataset):
@@ -78,16 +79,23 @@
if cam_focus is None:
cam_focus = dobj.ds.domain_center
+ rc = RenderingContext(*window_size)
+
+ if hasattr(dobj.ds.index, "meshes"):
+ # unstructured mesh datasets tend to have tight
+ # domain boundaries, do some extra padding here.
+ cam_position = 3.0*dobj.ds.domain_right_edge
+ scene = MeshSceneComponent(dobj, field)
+ else:
+ scene = SceneGraph()
+ collection = BlockCollection()
+ collection.add_data(dobj, field)
+ scene.add_collection(collection)
+
aspect_ratio = window_size[1] / window_size[0]
far_plane = np.linalg.norm(cam_focus - cam_position) * 2.0
near_plane = 0.01 * far_plane
- rc = RenderingContext(*window_size)
- scene = SceneGraph()
- collection = BlockCollection()
- collection.add_data(dobj, field)
- scene.add_collection(collection)
-
c = TrackballCamera(position=cam_position, focus=cam_focus, near_plane=near_plane,
far_plane=far_plane, aspect_ratio=aspect_ratio)
rc.start_loop(scene, c)
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/visualization/volume_rendering/shader_objects.py
--- a/yt/visualization/volume_rendering/shader_objects.py
+++ b/yt/visualization/volume_rendering/shader_objects.py
@@ -29,7 +29,7 @@
class ShaderProgram(object):
'''
Wrapper class that compiles and links vertex and fragment shaders
- into shader program.
+ into a shader program.
Parameters
----------
@@ -269,3 +269,13 @@
'''A second pass vertex shader that performs no operations on vertices'''
_source = "passthrough.vertexshader"
_shader_name = "passthrough.v"
+
+class MeshVertexShader(VertexShader):
+ '''A vertex shader used for unstructured mesh rendering.'''
+ _source = "mesh.vertexshader"
+ _shader_name = "mesh.v"
+
+class MeshFragmentShader(FragmentShader):
+ '''A vertex shader used for unstructured mesh rendering.'''
+ _source = "mesh.fragmentshader"
+ _shader_name = "mesh.f"
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/visualization/volume_rendering/shaders/mesh.fragmentshader
--- /dev/null
+++ b/yt/visualization/volume_rendering/shaders/mesh.fragmentshader
@@ -0,0 +1,17 @@
+#version 330 core
+
+in float fragmentData;
+out vec4 color;
+
+uniform sampler1D cmap;
+uniform float cmap_min;
+uniform float cmap_max;
+
+void main()
+{
+ float data = fragmentData;
+ float cm = cmap_min;
+ float cp = cmap_max;
+
+ color = texture(cmap, (data - cm) / (cp - cm));
+}
diff -r ff0ec06d8bd66146811459f03f99c6cf7b7b0883 -r d39510be50625c14c6ee0ecb2d0195ff72a76dd8 yt/visualization/volume_rendering/shaders/mesh.vertexshader
--- /dev/null
+++ b/yt/visualization/volume_rendering/shaders/mesh.vertexshader
@@ -0,0 +1,11 @@
+#version 330 core
+
+layout(location = 0) in vec3 vertexPosition_modelspace;
+layout(location = 1) in float vertexData;
+out float fragmentData;
+uniform mat4 model_to_clip;
+void main()
+{
+ gl_Position = model_to_clip * vec4(vertexPosition_modelspace, 1);
+ fragmentData = vertexData;
+}
Repository URL: https://bitbucket.org/yt_analysis/yt/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.spacepope.org/pipermail/yt-svn-spacepope.org/attachments/20160518/09d97b0a/attachment.html>
More information about the yt-svn
mailing list