[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