Changeset 8557:e2d728380882 in orange


Ignore:
Timestamp:
08/01/11 17:54:33 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
0ef9e5ad3c823ca6b3e596074163a583e7138bba
Message:

Added 3d version of orngScaleLinProj (too many changes required)

Location:
orange
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • orange/Orange/preprocess/scaling.py

    r8545 r8557  
    798798    createProjectionAsNumericArray = create_projection_as_numeric_array 
    799799     
     800    @deprecated_keywords({"useAnchorData": "use_anchor_data", 
     801                          "anchorRadius": "anchor_radius"}) 
     802    def _getsum_i(self, data, use_anchor_data = 0, anchor_radius = None): 
     803        """ 
     804        Function to compute the sum of all values for each element in the data. 
     805        Used to normalize. 
     806         
     807        """ 
     808        if use_anchor_data: 
     809            if anchor_radius == None: 
     810                anchor_radius = numpy.sqrt([a[0]**2+a[1]**2 for a in self.anchor_data]) 
     811            sum_i = numpy.add.reduce(numpy.transpose(numpy.transpose(data)*anchor_radius)) 
     812        else: 
     813            sum_i = numpy.add.reduce(data) 
     814        if len(numpy.nonzero(sum_i)) < len(sum_i):    # test if there are zeros in sum_i 
     815            sum_i += numpy.where(sum_i == 0, 1.0, 0.0) 
     816        return sum_i 
     817     
     818    _getSum_i = _getsum_i 
     819 
     820ScaleLinProjData = deprecated_members({"setAnchors": "set_anchors", 
     821                                       "createAnchors": "create_anchors", 
     822                                       "createXAnchors": "create_xanchors", 
     823                                       "createYAnchors": "create_yanchors", 
     824                                       "saveProjectionAsTabData": "save_projection_as_tab_data", 
     825                                       "get_projected_point_position": "get_projected_point_position", 
     826                                       "create_projection_as_example_table": "create_projection_as_example_table", 
     827                                       "create_projection_as_numeric_array": "create_projection_as_numeric_array", 
     828                                       "_getSum_i": "_getsum_i", 
     829                                       "normalizeExamples": "normalize_examples", 
     830                                       "anchorData": "anchor_data", 
     831                                       "lastAttrIndices": "last_attr_indices", 
     832                                       "anchorDict": "anchor_dict", 
     833                                      })(ScaleLinProjData) 
     834 
     835class ScaleLinProjData3D(ScaleData): 
     836    def __init__(self): 
     837        ScaleData.__init__(self) 
     838        self.normalize_examples = 1 
     839        self.anchor_data = []        # form: [(anchor1x, anchor1y, anchor1z, label1),(anchor2x, anchor2y, anchor2z, label2), ...] 
     840        self.last_attr_indices = None 
     841        self.anchor_dict = {} 
     842 
     843    @deprecated_keywords({"xAnchors": "xanchors", "yAnchors": "yanchors"}) 
     844    def set_anchors(self, xanchors, yanchors, zanchors, attributes): 
     845        print('set anchors') 
     846        if attributes: 
     847            if xanchors != None and yanchors != None and zanchors != None: 
     848                self.anchor_data = [(xanchors[i], yanchors[i], zanchors[i], attributes[i]) 
     849                                    for i in range(len(attributes))] 
     850            else: 
     851                self.anchor_data = self.create_anchors(len(attributes), attributes) 
     852 
     853    setAnchors = set_anchors 
     854 
     855    @deprecated_keywords({"numOfAttr": "num_of_attr"}) 
     856    def create_anchors(self, num_of_attr, labels=None): 
     857        """ 
     858        Create anchors on the sphere. 
     859         
     860        """ 
     861        print('creating anchors') 
     862        # Golden Section Spiral algorithm approximates even distribution of points on a sphere 
     863        # (read more here http://www.softimageblog.com/archives/115) 
     864        n = num_of_attr 
     865        xanchors = [] 
     866        yanchors = [] 
     867        zanchors = [] 
     868 
     869        inc = math.pi * (3 - math.sqrt(5)) 
     870        off = 2. / n 
     871        for k in range(n): 
     872            y = k * off - 1 + (off / 2) 
     873            r = math.sqrt(1 - y*y) 
     874            phi = k * inc 
     875            xanchors.append(math.cos(phi)*r) 
     876            yanchors.append(y) 
     877            zanchors.append(math.sin(phi)*r) 
     878        r = numpy.ones(len(xanchors), numpy.float) 
     879 
     880        if labels: 
     881            return [(xanchors[i], yanchors[i], zanchors[i], labels[i]) for i in range(num_of_attr)] 
     882        else: 
     883            return [(xanchors[i], yanchors[i], zanchors[i]) for i in range(num_of_attr)] 
     884 
     885    createAnchors = create_anchors 
     886 
     887    @deprecated_keywords({"fileName": "filename", "attrList": "attrlist", 
     888                          "useAnchorData": "use_anchor_data"}) 
     889    def save_projection_as_tab_data(self, filename, attrlist, use_anchor_data=0): 
     890        """ 
     891        Save projection (xattr, yattr, classval) into a filename filename. 
     892         
     893        """ 
     894        Orange.core.saveTabDelimited(filename, 
     895            self.create_projection_as_example_table([self.attribute_name_index[i] 
     896                                                     for i in attrlist], 
     897                                                    use_anchor_data=use_anchor_data)) 
     898     
     899    saveProjectionAsTabData = save_projection_as_tab_data 
     900 
    800901    @deprecated_keywords({"attrIndices": "attr_indices", 
    801902                          "settingsDict": "settings_dict"}) 
    802     def create_projection_as_numeric_array_3D(self, attr_indices, **settings_dict): 
     903    def get_projected_point_position(self, attr_indices, values, **settings_dict): 
     904        """ 
     905        For attributes in attr_indices and values of these attributes in values 
     906        compute point positions. This function has more sense in radviz and 
     907        polyviz methods. 
     908     
     909        """ 
     910        # load the elements from the settings dict 
     911        use_anchor_data = settings_dict.get("useAnchorData") 
     912        xanchors = settings_dict.get('xAnchors') 
     913        yanchors = settings_dict.get('yAnchors') 
     914        zanchors = settings_dict.get('zAnchors') 
     915        anchor_radius = settings_dict.get("anchorRadius") 
     916        normalize_example = settings_dict.get("normalizeExample") 
     917 
     918        if attr_indices != self.last_attr_indices: 
     919            print "get_projected_point_position. Warning: Possible bug. The "+\ 
     920                  "set of attributes is not the same as when computing the "+\ 
     921                  "whole projection" 
     922 
     923        if xanchors != None and yanchors != None and zanchors != None: 
     924            xanchors = numpy.array(xanchors) 
     925            yanchors = numpy.array(yanchors) 
     926            zanchors = numpy.array(zanchors) 
     927            if anchor_radius == None: anchor_radius = numpy.sqrt(xanchors*xanchors + 
     928                                                                 yanchors*yanchors + 
     929                                                                 zanchors*zanchors) 
     930        elif use_anchor_data and self.anchor_data: 
     931            xanchors = numpy.array([val[0] for val in self.anchor_data]) 
     932            yanchors = numpy.array([val[1] for val in self.anchor_data]) 
     933            zanchors = numpy.array([val[2] for val in self.anchor_data]) 
     934            if anchor_radius == None: anchor_radius = numpy.sqrt(xanchors*xanchors + 
     935                                                                 yanchors*yanchors + 
     936                                                                 zanchors*zanchors) 
     937        else: 
     938            self.create_anchors(len(attr_indices)) 
     939            xanchors = numpy.array([val[0] for val in self.anchor_data]) 
     940            yanchors = numpy.array([val[1] for val in self.anchor_data]) 
     941            zanchors = numpy.array([val[2] for val in self.anchor_data]) 
     942            anchor_radius = numpy.ones(len(attr_indices), numpy.float) 
     943 
     944        if normalize_example == 1 or (normalize_example == None 
     945                                      and self.normalize_examples): 
     946            m = min(values); M = max(values) 
     947            if m < 0.0 or M > 1.0:  
     948                # we have to do rescaling of values so that all the values will 
     949                # be in the 0-1 interval 
     950                #print "example values are not in the 0-1 interval" 
     951                values = [max(0.0, min(val, 1.0)) for val in values] 
     952                #m = min(m, 0.0); M = max(M, 1.0); diff = max(M-m, 1e-10) 
     953                #values = [(val-m) / float(diff) for val in values] 
     954 
     955            s = sum(numpy.array(values)*anchor_radius) 
     956            if s == 0: return [0.0, 0.0] 
     957            x = self.trueScaleFactor * numpy.dot(xanchors*anchor_radius, 
     958                                                 values) / float(s) 
     959            y = self.trueScaleFactor * numpy.dot(yanchors*anchor_radius, 
     960                                                 values) / float(s) 
     961            z = self.trueScaleFactor * numpy.dot(zanchors*anchor_radius, 
     962                                                 values) / float(s) 
     963        else: 
     964            x = self.trueScaleFactor * numpy.dot(xanchors, values) 
     965            y = self.trueScaleFactor * numpy.dot(yanchors, values) 
     966            z = self.trueScaleFactor * numpy.dot(zanchors, values) 
     967 
     968        return [x, y, z] 
     969 
     970    getProjectedPointPosition = get_projected_point_position 
     971 
     972    @deprecated_keywords({"attrIndices": "attr_indices", 
     973                          "settingsDict": "settings_dict"}) 
     974    def create_projection_as_example_table(self, attr_indices, **settings_dict): 
     975        """ 
     976        Create the projection of attribute indices given in attr_indices and 
     977        create an example table with it. 
     978        """ 
     979        if self.data_domain.class_var: 
     980            domain = settings_dict.get("domain") or \ 
     981                     Orange.data.Domain([Orange.data.variable.Continuous("xVar"), 
     982                                         Orange.data.variable.Continuous("yVar"), 
     983                                         Orange.data.variable.Continuous("zVar"), 
     984                                         Orange.data.variable.Discrete(self.data_domain.class_var.name, 
     985                                                                       values = get_variable_values_sorted(self.data_domain.class_var))]) 
     986        else: 
     987            domain = settings_dict.get("domain") or \ 
     988                     Orange.data.Domain([Orange.data.variable.Continuous("xVar"), 
     989                                         Orange.data.variable.Continuous("yVar"), 
     990                                         Orange.data.variable.Continuous("zVar")]) 
     991        data = self.create_projection_as_numeric_array(attr_indices, 
     992                                                       **settings_dict) 
     993        if data != None: 
     994            return Orange.data.Table(domain, data) 
     995        else: 
     996            return Orange.data.Table(domain) 
     997 
     998    createProjectionAsExampleTable = create_projection_as_example_table 
     999 
     1000    @deprecated_keywords({"attrIndices": "attr_indices", 
     1001                          "settingsDict": "settings_dict"}) 
     1002    def create_projection_as_numeric_array(self, attr_indices, **settings_dict): 
    8031003        print('create projection as numeric array') 
    8041004        # load the elements from the settings dict 
     
    8551055                ZAnchors *= r 
    8561056        elif (XAnchors != None and YAnchors != None and ZAnchors != None): 
    857             XAnchors = numpy.array(XAnchors); 
     1057            XAnchors = numpy.array(XAnchors) 
    8581058            YAnchors = numpy.array(YAnchors) 
    8591059            ZAnchors = numpy.array(ZAnchors) 
    8601060            r = numpy.sqrt(XAnchors*XAnchors + YAnchors*YAnchors + ZAnchors*ZAnchors)     # compute the distance of each anchor from the center of the circle 
    8611061        else: 
    862             # Golden Section Spiral algorithm approximates even distribution of points on a sphere 
    863             # (read more here http://www.softimageblog.com/archives/115) 
    864             n = len(attr_indices) 
    865             XAnchors = [] 
    866             YAnchors = [] 
    867             ZAnchors = [] 
    868  
    869             inc = math.pi * (3 - math.sqrt(5)) 
    870             off = 2. / n 
    871             for k in range(n): 
    872                 y = k * off - 1 + (off / 2) 
    873                 r = math.sqrt(1 - y*y) 
    874                 phi = k * inc 
    875                 XAnchors.append(math.cos(phi)*r) 
    876                 YAnchors.append(y) 
    877                 ZAnchors.append(math.sin(phi)*r) 
     1062            self.create_anchors(len(attr_indices)) 
     1063            XAnchors = numpy.array([val[0] for val in self.anchor_data]) 
     1064            YAnchors = numpy.array([val[1] for val in self.anchor_data]) 
     1065            ZAnchors = numpy.array([val[2] for val in self.anchor_data]) 
    8781066            r = numpy.ones(len(XAnchors), numpy.float) 
    8791067 
     
    9031091                x_validData = x_positions 
    9041092                y_validData = y_positions 
     1093                z_validData = z_positions 
    9051094             
    9061095            dist = math.sqrt(max(x_validData*x_validData + y_validData*y_validData + z_validData*z_validData)) or 1 
     
    9271116            return numpy.transpose(numpy.array((x_positions, y_positions, z_positions))) 
    9281117 
    929     createProjectionAsNumericArray3D = create_projection_as_numeric_array_3D 
    930   
     1118    createProjectionAsNumericArray = create_projection_as_numeric_array 
     1119 
    9311120    @deprecated_keywords({"useAnchorData": "use_anchor_data", 
    9321121                          "anchorRadius": "anchor_radius"}) 
    933     def _getsum_i(self, data, use_anchor_data = 0, anchor_radius = None): 
     1122    def _getsum_i(self, data, use_anchor_data=0, anchor_radius=None): 
    9341123        """ 
    9351124        Function to compute the sum of all values for each element in the data. 
     
    9391128        if use_anchor_data: 
    9401129            if anchor_radius == None: 
    941                 anchor_radius = numpy.sqrt([a[0]**2+a[1]**2 for a in self.anchor_data]) 
     1130                anchor_radius = numpy.sqrt([a[0]**2+a[1]**2+a[2]**2 for a in self.anchor_data]) 
    9421131            sum_i = numpy.add.reduce(numpy.transpose(numpy.transpose(data)*anchor_radius)) 
    9431132        else: 
     
    9491138    _getSum_i = _getsum_i 
    9501139 
    951 ScaleLinProjData = deprecated_members({"setAnchors": "set_anchors", 
     1140ScaleLinProjData3D = deprecated_members({"setAnchors": "set_anchors", 
    9521141                                       "createAnchors": "create_anchors", 
    953                                        "createXAnchors": "create_xanchors", 
    954                                        "createYAnchors": "create_yanchors", 
    9551142                                       "saveProjectionAsTabData": "save_projection_as_tab_data", 
    9561143                                       "get_projected_point_position": "get_projected_point_position", 
    9571144                                       "create_projection_as_example_table": "create_projection_as_example_table", 
    9581145                                       "create_projection_as_numeric_array": "create_projection_as_numeric_array", 
    959                                        "create_projection_as_numeric_array_3D": "create_projection_as_numeric_array_3D", 
    9601146                                       "_getSum_i": "_getsum_i", 
    9611147                                       "normalizeExamples": "normalize_examples", 
     
    9631149                                       "lastAttrIndices": "last_attr_indices", 
    9641150                                       "anchorDict": "anchor_dict", 
    965                                       })(ScaleLinProjData) 
     1151                                      })(ScaleLinProjData3D) 
    9661152 
    9671153class ScalePolyvizData(ScaleLinProjData): 
  • orange/OrangeWidgets/Prototypes/OWRadviz3D.py

    r8555 r8557  
    1212from OWLinProjQt import * 
    1313 
    14 class OWRadviz3DPlot(OWPlot3D, orngScaleLinProjData): 
     14class OWRadviz3DPlot(OWPlot3D, orngScaleLinProjData3D): 
    1515    def __init__(self, widget, parent=None, name='None'): 
    1616        OWPlot3D.__init__(self, parent) 
    17         orngScaleLinProjData.__init__(self) 
     17        orngScaleLinProjData3D.__init__(self) 
     18 
     19        self.camera_fov = 40. 
     20        self.show_axes = self.show_chassis = self.show_grid = False 
    1821 
    1922        self.point_width = 5 
     
    2629        self.gui = OWPlotGUI(self) 
    2730 
    28         self.sphere_data = parse_obj(os.path.join(os.path.dirname(__file__), '../plot/primitives/sphere_hq.obj')) 
    29         self.show_axes = self.show_chassis = self.show_grid = False 
     31    def setData(self, data, subsetData=None, **args): 
     32        orngScaleLinProjData3D.setData(self, data, subsetData, **args) 
    3033 
    31     def setData(self, data, subsetData=None, **args): 
    32         orngScaleLinProjData.setData(self, data, subsetData, **args) 
     34    def updateData(self, labels=None, setAnchors=0, **args): 
     35        self.clear() 
     36 
     37        if not self.haveData or len(labels) < 3: 
     38            self.anchor_data = [] 
     39            self.updateLayout() 
     40            return 
     41 
     42        # TODO: do this once (in constructor?) 
     43        sphere_data = parse_obj(os.path.join(os.path.dirname(__file__), '../plot/primitives/sphere_hq.obj')) 
     44        vertices = [] 
     45        for v0, v1, v2, n0, n1, n2 in sphere_data: 
     46            vertices.extend([v0[0],v0[1],v0[2], n0[0],n0[1],n0[2], 
     47                             v1[0],v1[1],v1[2], n1[0],n1[1],n1[2], 
     48                             v2[0],v2[1],v2[2], n2[0],n2[1],n2[2]]) 
     49 
     50        self.sphere_vao_id = GLuint(0) 
     51        glGenVertexArrays(1, self.sphere_vao_id) 
     52        glBindVertexArray(self.sphere_vao_id) 
     53 
     54        vertex_buffer_id = glGenBuffers(1) 
     55        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_id) 
     56        glBufferData(GL_ARRAY_BUFFER, numpy.array(vertices, 'f'), GL_STATIC_DRAW) 
     57 
     58        vertex_size = (3+3)*4 
     59        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(0)) 
     60        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, c_void_p(3*4)) 
     61        glEnableVertexAttribArray(0) 
     62        glEnableVertexAttribArray(1) 
     63 
     64        glBindVertexArray(0) 
     65        glBindBuffer(GL_ARRAY_BUFFER, 0) 
     66 
     67        self.sphere_vao_id.num_vertices = len(vertices) / (vertex_size / 4) 
     68 
     69        self.sphere_shader = QtOpenGL.QGLShaderProgram() 
     70        vertex_shader_source = ''' 
     71            #extension GL_EXT_gpu_shader4 : enable 
     72 
     73            attribute vec3 position; 
     74            attribute vec3 normal; 
     75 
     76            uniform vec3 color; 
     77 
     78            varying vec4 var_color; 
     79 
     80            void main(void) { 
     81                gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * vec4(position*8.6602, 1.); 
     82                var_color = vec4(0.8, 0.8, 0.8, 0.2); 
     83            } 
     84            ''' 
     85 
     86        fragment_shader_source = ''' 
     87            varying vec4 var_color; 
     88 
     89            void main(void) { 
     90              gl_FragColor = var_color; 
     91            } 
     92            ''' 
     93 
     94        self.sphere_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Vertex, vertex_shader_source) 
     95        self.sphere_shader.addShaderFromSourceCode(QtOpenGL.QGLShader.Fragment, fragment_shader_source) 
     96 
     97        self.sphere_shader.bindAttributeLocation('position', 0) 
     98        self.sphere_shader.bindAttributeLocation('normal',   1) 
     99 
     100        if not self.sphere_shader.link(): 
     101            print('Failed to link sphere shader!') 
     102        else: 
     103            print('Sphere shader linked.') 
     104 
     105        if setAnchors: 
     106            self.setAnchors(args.get('XAnchors'), args.get('YAnchors'), args.get('ZAnchors'), labels) 
     107 
     108        data_size = len(self.rawData) 
     109        indices = [self.attributeNameIndex[anchor[3]] for anchor in self.anchor_data] 
     110        valid_data = self.getValidList(indices) 
     111        trans_proj_data = self.createProjectionAsNumericArray(indices, validData=valid_data, 
     112            scaleFactor=self.scaleFactor, normalize=self.normalizeExamples, jitterSize=-1, 
     113            useAnchorData=1, removeMissingData=0) 
     114        if trans_proj_data == None: 
     115            return 
     116        proj_data = trans_proj_data.T 
     117        x_positions = proj_data[0] 
     118        y_positions = proj_data[1] 
     119        z_positions = proj_data[2] 
     120 
     121        self.scatter(x_positions, y_positions, z_positions) 
     122 
     123        self.commands.append(('custom', self.draw_sphere_callback)) 
     124        self.updateGL() 
    33125 
    34126    def updateGraph(self, attrList=None, setAnchors=0, insideColors=None, **args): 
    35127        pass 
    36128 
    37     def draw_callback(self): 
     129    def draw_sphere_callback(self): 
    38130        glDisable(GL_DEPTH_TEST) 
    39         glDisable(GL_BLEND) 
    40         glColor4f(1,0,0,0.5) 
     131        glEnable(GL_BLEND) 
     132        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) 
    41133 
    42         # TODO: vaos 
    43         glScalef(5, 5, 5) 
    44         glBegin(GL_TRIANGLES) 
    45         for v0, v1, v2, n0, n1, n2 in self.sphere_data: 
    46             glVertex3f(*v0) 
    47             glVertex3f(*v1) 
    48             glVertex3f(*v2) 
    49         glEnd() 
     134        self.sphere_shader.bind() 
     135        glBindVertexArray(self.sphere_vao_id) 
     136 
     137        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) 
     138        glDrawArrays(GL_TRIANGLES, 0, self.sphere_vao_id.num_vertices) 
     139        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) 
     140 
     141        glBindVertexArray(0) 
     142        self.sphere_shader.release() 
     143 
     144        radius = (25*3)**0.5 
     145 
     146        if self.showAnchors: 
     147            for anchor in self.anchor_data: 
     148                x, y, z, label = anchor 
     149                glLineWidth(2.) 
     150                glColor4f(0.8, 0, 0, 1) 
     151                glBegin(GL_LINES) 
     152                glVertex3f(x*0.98*radius, y*0.99*radius, z*0.98*radius) 
     153                glVertex3f(x*1.02*radius, y*1.02*radius, z*1.02*radius) 
     154                glEnd() 
     155                glLineWidth(1.) 
     156 
     157                glColor4f(0, 0, 0, 1) 
     158                self.renderText(x*1.1*radius, y*1.1*radius, z*1.1*radius, label) 
    50159 
    51160    def setCanvasColor(self, c): 
    52161        pass 
    53  
    54     def updateData(self, labels=None, setAnchors=0, **args): 
    55         self.commands.append(('custom', self.draw_callback)) 
    56         self.updateGL() 
    57162 
    58163    def getSelectionsAsExampleTables(self, attrList, useAnchorData=1, addProjectedPositions=0): 
     
    81186                        ("Unselected Examples", ExampleTable), 
    82187                        ("Attribute Selection List", AttributeList)] 
     188        self.resize(1000, 600) 
    83189 
    84190if __name__ == '__main__': 
  • orange/OrangeWidgets/plot/owplot3d.py

    r8554 r8557  
    5454from OpenGL.GL import * 
    5555from OpenGL.GLU import * 
    56 from OpenGL.arrays import ArrayDatatype 
    5756from OpenGL.GL.ARB.vertex_array_object import * 
    5857from OpenGL.GL.ARB.vertex_buffer_object import * 
  • orange/orngScaleLinProjData.py

    r8378 r8557  
    11from orngScaleData import * 
    22from Orange.preprocess.scaling import ScaleLinProjData as orngScaleLinProjData 
     3from Orange.preprocess.scaling import ScaleLinProjData3D as orngScaleLinProjData3D 
Note: See TracChangeset for help on using the changeset viewer.