Changeset 8812:ef1e29cf04e1 in orange


Ignore:
Timestamp:
08/27/11 16:42:32 (3 years ago)
Author:
matejd <matejd@…>
Branch:
default
Convert:
052cf42d34b38077461ab839fb6daf2c6cb29faf
Message:

Moved selections processing code to c++, improved drawing

Location:
source/orangeqt
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • source/orangeqt/plot3d.cpp

    r8804 r8812  
    11#include "plot3d.h" 
    22#include <iostream> 
     3#include <limits> 
    34#include <QGLFormat> 
    45#include <GL/glx.h> 
     
    1516typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); 
    1617PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = NULL; 
    17 //typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); 
    1818PFNGLUNIFORM2FPROC glUniform2f = NULL; 
    1919 
     
    2222Plot3D::Plot3D(QWidget* parent) : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) 
    2323{ 
    24     vbo_generated = false; 
     24    vbos_generated = false; 
    2525} 
    2626 
    2727Plot3D::~Plot3D() 
    2828{ 
     29    // TODO: delete vbos 
    2930} 
    3031 
     
    6566    this->num_examples = num_examples; 
    6667    this->example_size = example_size; 
     68    this->selected_indices = QVector<bool>(num_examples); 
    6769 
    6870    // Load required extensions (OpenGL context should be up by now). 
     
    8688                         bool x_discrete, bool y_discrete, bool z_discrete, bool use_2d_symbols) 
    8789{ 
     90    // TODO: delete vbos 
     91    this->x_index = x_index; 
     92    this->y_index = y_index; 
     93    this->z_index = z_index; 
     94 
    8895    const float scale = 0.001; 
    89     float* vbo_data = new float[num_examples * 144 * 13]; 
    90     float* vbo_edges_data = new float[num_examples * 144 * 13]; 
    91     float* dest = vbo_data; 
    92     float* dest_edges = vbo_edges_data; 
    93     int size_in_bytes = 0; 
    94     int size_in_bytes_edges = 0; 
     96 
     97    float* vbo_selected_data   = new float[num_examples * 144 * 13]; // TODO: better size approximation 
     98    float* vbo_unselected_data = new float[num_examples * 144 * 13]; 
     99    float* vbo_edges_data      = new float[num_examples * 144 * 13]; 
     100    float* dests = vbo_selected_data; 
     101    float* destu = vbo_unselected_data; 
     102    float* deste = vbo_edges_data; 
     103    // Sizes in bytes. 
     104    int sib_selected   = 0; 
     105    int sib_unselected = 0; 
     106    int sib_edges      = 0; 
     107 
    95108    QMap<int, QList<QVector3D> >& geometry = use_2d_symbols ? geometry_data_2d : geometry_data_3d; 
    96109    QMap<int, QList<QVector3D> >& geometry_edges = use_2d_symbols ? geometry_data_edges_2d : geometry_data_edges_3d; 
     
    122135            color = QColor(0., 0., 0.8); 
    123136 
     137        float*& dest = selected_indices[index] ? dests : destu; 
     138 
     139        // TODO: make sure symbol is in geometry map 
    124140        for (int i = 0; i < geometry[symbol].count(); i += 6) { 
    125             size_in_bytes += 3*13*4; 
     141            if (selected_indices[index]) 
     142                sib_selected += 3*13*4; 
     143            else 
     144                sib_unselected += 3*13*4; 
    126145 
    127146            for (int j = 0; j < 3; ++j) 
     
    152171        } 
    153172 
     173        // No need for edges in selected examples (those are drawn fully opaque) 
     174        if (this->selected_indices[index]) 
     175            continue; 
     176 
    154177        for (int i = 0; i < geometry_edges[symbol].count(); i += 2) { 
    155             size_in_bytes_edges += 2*13*4; 
     178            sib_edges += 2*13*4; 
    156179 
    157180            for (int j = 0; j < 2; ++j) 
    158181            { 
    159                 *dest_edges = x_pos; dest_edges++;  
    160                 *dest_edges = y_pos; dest_edges++;  
    161                 *dest_edges = z_pos; dest_edges++;  
    162  
    163                 *dest_edges = geometry_edges[symbol][i+j].x()*size*scale; dest_edges++; 
    164                 *dest_edges = geometry_edges[symbol][i+j].y()*size*scale; dest_edges++; 
    165                 *dest_edges = geometry_edges[symbol][i+j].z()*size*scale; dest_edges++; 
    166  
    167                 *dest_edges = color.redF(); dest_edges++; 
    168                 *dest_edges = color.greenF(); dest_edges++; 
    169                 *dest_edges = color.blueF(); dest_edges++; 
    170  
    171                 // Just use offset 
    172                 *dest_edges = geometry_edges[symbol][i+j].x(); dest_edges++; 
    173                 *dest_edges = geometry_edges[symbol][i+j].y(); dest_edges++; 
    174                 *dest_edges = geometry_edges[symbol][i+j].z(); dest_edges++; 
    175  
    176                 *dest_edges = index; dest_edges++; 
     182                *deste = x_pos; deste++;  
     183                *deste = y_pos; deste++;  
     184                *deste = z_pos; deste++;  
     185 
     186                *deste = geometry_edges[symbol][i+j].x()*size*scale; deste++; 
     187                *deste = geometry_edges[symbol][i+j].y()*size*scale; deste++; 
     188                *deste = geometry_edges[symbol][i+j].z()*size*scale; deste++; 
     189 
     190                *deste = color.redF(); deste++; 
     191                *deste = color.greenF(); deste++; 
     192                *deste = color.blueF(); deste++; 
     193 
     194                // Just use offset as the normal for now 
     195                *deste = geometry_edges[symbol][i+j].x(); deste++; 
     196                *deste = geometry_edges[symbol][i+j].y(); deste++; 
     197                *deste = geometry_edges[symbol][i+j].z(); deste++; 
     198 
     199                *deste = index; deste++; 
    177200            } 
    178201        } 
    179202    } 
    180203 
    181     glGenBuffers(1, &vbo_id); 
    182     glBindBuffer(GL_ARRAY_BUFFER, vbo_id); 
    183     glBufferData(GL_ARRAY_BUFFER, size_in_bytes, vbo_data, GL_STATIC_DRAW); 
     204    glGenBuffers(1, &vbo_selected_id); 
     205    glBindBuffer(GL_ARRAY_BUFFER, vbo_selected_id); 
     206    glBufferData(GL_ARRAY_BUFFER, sib_selected, vbo_selected_data, GL_STATIC_DRAW); 
    184207    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    185208 
    186     delete [] vbo_data; 
     209    delete [] vbo_selected_data; 
     210 
     211    glGenBuffers(1, &vbo_unselected_id); 
     212    glBindBuffer(GL_ARRAY_BUFFER, vbo_unselected_id); 
     213    glBufferData(GL_ARRAY_BUFFER, sib_unselected, vbo_unselected_data, GL_STATIC_DRAW); 
     214    glBindBuffer(GL_ARRAY_BUFFER, 0); 
     215 
     216    delete [] vbo_unselected_data; 
    187217 
    188218    glGenBuffers(1, &vbo_edges_id); 
    189219    glBindBuffer(GL_ARRAY_BUFFER, vbo_edges_id); 
    190     glBufferData(GL_ARRAY_BUFFER, size_in_bytes_edges, vbo_edges_data, GL_STATIC_DRAW); 
     220    glBufferData(GL_ARRAY_BUFFER, sib_edges, vbo_edges_data, GL_STATIC_DRAW); 
    191221    glBindBuffer(GL_ARRAY_BUFFER, 0); 
    192222 
    193223    delete [] vbo_edges_data; 
    194224 
    195     num_vertices = size_in_bytes / (13*4); 
    196     num_edges_vertices = size_in_bytes_edges / (13*4); 
    197     vbo_generated = true; 
     225    num_selected_vertices = sib_selected / (13*4); 
     226    num_unselected_vertices = sib_unselected / (13*4); 
     227    num_edges_vertices = sib_edges / (13*4); 
     228 
     229    vbos_generated = true; 
     230} 
     231 
     232void Plot3D::draw_data_solid() 
     233{ 
     234    // TODO 
    198235} 
    199236 
    200237void Plot3D::draw_data(GLuint shader_id, float alpha_value) 
    201238{ 
    202     if (!vbo_generated) 
     239    if (!vbos_generated) 
    203240        return; 
    204241 
    205     glUniform2f(glGetUniformLocation(shader_id, "alpha_value"), alpha_value-0.4, alpha_value-0.4); 
    206  
    207     glBindBuffer(GL_ARRAY_BUFFER, vbo_id); 
     242    // Draw opaque selected examples first. 
     243    glBindBuffer(GL_ARRAY_BUFFER, vbo_selected_id); 
    208244    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(0)); 
    209245    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(3*4)); 
     
    217253    glEnableVertexAttribArray(4); 
    218254 
    219     glDrawArrays(GL_TRIANGLES, 0, num_vertices); 
     255    glDrawArrays(GL_TRIANGLES, 0, num_selected_vertices); 
    220256 
    221257    glDisableVertexAttribArray(0); 
     
    225261    glDisableVertexAttribArray(4); 
    226262 
     263    // Draw transparent unselected examples (triangles and then edges). 
     264    glUniform2f(glGetUniformLocation(shader_id, "alpha_value"), alpha_value-0.6, alpha_value-0.6); 
     265 
     266    glBindBuffer(GL_ARRAY_BUFFER, vbo_unselected_id); 
     267    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(0)); 
     268    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(3*4)); 
     269    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(6*4)); 
     270    glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(9*4)); 
     271    glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(12*4)); 
     272    glEnableVertexAttribArray(0); 
     273    glEnableVertexAttribArray(1); 
     274    glEnableVertexAttribArray(2); 
     275    glEnableVertexAttribArray(3); 
     276    glEnableVertexAttribArray(4); 
     277 
     278    glDrawArrays(GL_TRIANGLES, 0, num_unselected_vertices); 
     279 
     280    glDisableVertexAttribArray(0); 
     281    glDisableVertexAttribArray(1); 
     282    glDisableVertexAttribArray(2); 
     283    glDisableVertexAttribArray(3); 
     284    glDisableVertexAttribArray(4); 
     285 
     286    // Edges 
    227287    glUniform2f(glGetUniformLocation(shader_id, "alpha_value"), alpha_value, alpha_value); 
    228288 
    229     // Edges 
    230289    glBindBuffer(GL_ARRAY_BUFFER, vbo_edges_id); 
    231290    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 13*4, BUFFER_OFFSET(0)); 
     
    251310} 
    252311 
     312QList<double> Plot3D::get_min_max_selected(const QList<int>& area, 
     313                                          const QMatrix4x4& mvp, 
     314                                          const QList<int>& viewport, 
     315                                          const QVector3D& plot_scale, 
     316                                          const QVector3D& plot_translation) 
     317{ 
     318    float x_min = std::numeric_limits<float>::max(); 
     319    float x_max = std::numeric_limits<float>::min(); 
     320    float y_min = x_min; 
     321    float y_max = x_max; 
     322    float z_min = x_min; 
     323    float z_max = x_max; 
     324 
     325    bool any_point_selected = false; 
     326    for (int index = 0; index < num_examples; ++index) 
     327    { 
     328        float* example = data_array + index*example_size; 
     329        float x_pos = *(example + x_index); 
     330        float y_pos = *(example + y_index); 
     331        float z_pos = *(example + z_index); 
     332 
     333        QVector3D position(x_pos, y_pos, z_pos); 
     334        position += plot_translation; 
     335        position *= plot_scale; 
     336 
     337        QVector4D projected = mvp * QVector4D(position, 1.0f); 
     338        projected /= projected.z(); 
     339        int winx = viewport[0] + (1 + projected.x()) * viewport[2] / 2; 
     340        int winy = viewport[1] + (1 + projected.y()) * viewport[3] / 2; 
     341        winy = viewport[3] - winy; 
     342 
     343        if (winx >= area[0] && winx <= area[0]+area[2] && winy <= area[1]+area[3] && winy >= area[1]) 
     344        { 
     345            any_point_selected = true; 
     346 
     347            if (x_pos < x_min) x_min = x_pos; 
     348            if (x_pos > x_max) x_max = x_pos; 
     349 
     350            if (y_pos < y_min) y_min = y_pos; 
     351            if (y_pos > y_max) y_max = y_pos; 
     352 
     353            if (z_pos < z_min) z_min = z_pos; 
     354            if (z_pos > z_max) z_max = z_pos; 
     355        } 
     356    } 
     357 
     358    if (any_point_selected) 
     359    { 
     360        QList<double> min_max; 
     361        min_max << x_min << x_max; 
     362        min_max << y_min << y_max; 
     363        min_max << z_min << z_max; 
     364        return min_max; 
     365    } 
     366    else 
     367    { 
     368        QList<double> min_max; 
     369        min_max << 0. << 1.; 
     370        min_max << 0. << 1.; 
     371        min_max << 0. << 1.; 
     372        return min_max; 
     373    } 
     374} 
     375 
     376void Plot3D::select_points(const QList<int>& area, 
     377                           const QMatrix4x4& mvp, 
     378                           const QList<int>& viewport, 
     379                           const QVector3D& plot_scale, 
     380                           const QVector3D& plot_translation, 
     381                           Plot::SelectionBehavior behavior) 
     382{ 
     383    if (behavior == Plot::ReplaceSelection) 
     384        selected_indices.fill(false);//selected_indices = QVector<bool>(num_examples); 
     385 
     386    for (int index = 0; index < num_examples; ++index) 
     387    { 
     388        float* example = data_array + index*example_size; 
     389        float x_pos = *(example + x_index); 
     390        float y_pos = *(example + y_index); 
     391        float z_pos = *(example + z_index); 
     392 
     393        QVector3D position(x_pos, y_pos, z_pos); 
     394        position += plot_translation; 
     395        position *= plot_scale; 
     396 
     397        QVector4D projected = mvp * QVector4D(position, 1.0f); 
     398        projected /= projected.z(); 
     399        int winx = viewport[0] + (1 + projected.x()) * viewport[2] / 2; 
     400        int winy = viewport[1] + (1 + projected.y()) * viewport[3] / 2; 
     401        winy = viewport[3] - winy; 
     402 
     403        if (winx >= area[0] && winx <= area[0]+area[2] && winy <= area[1]+area[3] && winy >= area[1]) 
     404        { 
     405            if (behavior == Plot::AddSelection || behavior == Plot::ReplaceSelection) 
     406                selected_indices[index] = true; 
     407            else if (behavior == Plot::RemoveSelection) 
     408                selected_indices[index] = false; 
     409            else if (behavior == Plot::ToggleSelection) 
     410                selected_indices[index] = !selected_indices[index]; 
     411        } 
     412    } 
     413} 
     414 
     415void Plot3D::unselect_all_points() 
     416{ 
     417    this->selected_indices = QVector<bool>(num_examples); 
     418} 
     419 
     420QList<bool> Plot3D::get_selected_indices() 
     421{ 
     422    return this->selected_indices.toList(); 
     423} 
     424 
    253425#include "plot3d.moc" 
  • source/orangeqt/plot3d.h

    r8804 r8812  
    22#define PLOT_3D_H 
    33 
     4#include "plot.h" 
    45#include <QtOpenGL/QGLWidget> 
    56#include <QVector3D> 
     7#include <QVector4D> 
     8#include <QMatrix4x4> 
    69#include <GL/gl.h> 
    710 
     
    1316    virtual ~Plot3D(); 
    1417 
    15     void set_symbol_geometry(int symbol, int type, const QList<QVector3D>& geometry); 
     18    void set_symbol_geometry(int symbol, 
     19                             int type, 
     20                             const QList<QVector3D>& geometry); 
    1621 
    17     void set_data(quint64 array_address, int num_examples, int example_size); 
     22    void set_data(quint64 array_address, 
     23                  int num_examples, 
     24                  int example_size); 
    1825    void update_data(int x_index, int y_index, int z_index, 
    19                 int color_index, int symbol_index, int size_index, int label_index, 
    20                 const QList<QColor>& colors, int num_symbols_used, 
    21                 bool x_discrete, bool y_discrete, bool z_discrete, bool use_2d_symbols); 
    22     void draw_data(GLuint shader_id, float alpha_value); 
     26                     int color_index, int symbol_index, int size_index, int label_index, 
     27                     const QList<QColor>& colors, int num_symbols_used, 
     28                     bool x_discrete, bool y_discrete, bool z_discrete, bool use_2d_symbols); 
     29    void draw_data(GLuint shader_id, 
     30                   float alpha_value); 
     31    void draw_data_solid(); // (only draws solid geometry as a performance optimization) 
     32 
     33    QList<double> get_min_max_selected(const QList<int>& area, 
     34                                      const QMatrix4x4& mvp, 
     35                                      const QList<int>& viewport, 
     36                                      const QVector3D& plot_scale, 
     37                                      const QVector3D& plot_translation); 
     38 
     39    void select_points(const QList<int>& area, 
     40                       const QMatrix4x4& mvp, 
     41                       const QList<int>& viewport, 
     42                       const QVector3D& plot_scale, 
     43                       const QVector3D& plot_translation, 
     44                       Plot::SelectionBehavior behavior = Plot::AddSelection); 
     45 
     46    void unselect_all_points(); 
     47 
     48    QList<bool> get_selected_indices(); 
    2349 
    2450private: 
    2551    float* data_array; 
     52    QVector<bool> selected_indices; // Array of length num_examples 
    2653    int num_examples; 
    2754    int example_size; 
    28     int num_vertices; 
     55    int num_selected_vertices; 
     56    int num_unselected_vertices; 
    2957    int num_edges_vertices; 
    30     GLuint vbo_id; 
    31     GLuint vbo_edges_id; 
    32     bool vbo_generated; 
     58    GLuint vbo_selected_id;   // Triangles (drawn opaque) 
     59    GLuint vbo_unselected_id; // Triangles (drawn slightly transparent) 
     60    GLuint vbo_edges_id;      // Edges are in a separated VBO (but drawn together with vbo_unselected) 
     61    bool vbos_generated; 
     62 
     63    int x_index; 
     64    int y_index; 
     65    int z_index; 
    3366 
    3467    QMap<int, QList<QVector3D> > geometry_data_2d; 
  • source/orangeqt/plot3d.sip

    r8804 r8812  
    1010    virtual ~Plot3D(); 
    1111 
    12     void set_symbol_geometry(int symbol, int type, const QList<QVector3D>& geometry); 
     12    void set_symbol_geometry(int symbol, 
     13                             int type, 
     14                             const QList<QVector3D>& geometry); 
    1315 
    14     void set_data(quint64 array_address, int num_examples, int example_size); 
     16    void set_data(quint64 array_address, 
     17                  int num_examples, 
     18                  int example_size); 
    1519    void update_data(int x_index, int y_index, int z_index, 
    16                 int color_index, int symbol_index, int size_index, int label_index, 
    17                 const QList<QColor>& colors, int num_symbols_used, 
    18                 bool x_discrete, bool y_discrete, bool z_discrete, bool use_2d_symbols); 
    19     void draw_data(GLuint shader_id, float alpha_value); 
     20                     int color_index, int symbol_index, int size_index, int label_index, 
     21                     const QList<QColor>& colors, int num_symbols_used, 
     22                     bool x_discrete, bool y_discrete, bool z_discrete, bool use_2d_symbols); 
     23    void draw_data(GLuint shader_id, 
     24                   float alpha_value); 
     25    void draw_data_solid(); // (only draws solid geometry as a performance optimization) 
     26 
     27    QList<double> get_min_max_selected(const QList<int>& area, 
     28                                      const QMatrix4x4& mvp, 
     29                                      const QList<int>& viewport, 
     30                                      const QVector3D& plot_scale, 
     31                                      const QVector3D& plot_translation); 
     32 
     33    void select_points(const QList<int>& area, 
     34                       const QMatrix4x4& mvp, 
     35                       const QList<int>& viewport, 
     36                       const QVector3D& plot_scale, 
     37                       const QVector3D& plot_translation, 
     38                       Plot::SelectionBehavior behavior = Plot::AddSelection); 
     39 
     40    void unselect_all_points(); 
     41 
     42    QList<bool> get_selected_indices(); 
    2043}; 
Note: See TracChangeset for help on using the changeset viewer.