+ Improve implicit function drawing efficiency (use display list stuff from base class)

+ Adjust Color_ramp
This commit is contained in:
Stéphane Tayeb 2010-06-16 16:12:32 +00:00
parent a5d085b67d
commit 70ae043666
4 changed files with 219 additions and 152 deletions

View File

@ -1,145 +1,126 @@
#include "Color_ramp.h"
#include <iostream>
Color_ramp::Color_ramp()
{
build_thermal();
// -----------------------------------
// Color_component
// -----------------------------------
Color_component::
Color_component()
{
add(0,0);
add(1,1);
}
void
Color_ramp::rebuild()
Color_component::
Color_component(const double c0, const double c1)
{
// build nodes
m_colors[3][0] = 1;
m_colors[3][255] = 1;
unsigned int nb_nodes = 0;
for(int i=0;i<256;i++)
add(0,c0);
add(1,c1);
}
double
Color_component::
interpolate(const double v) const
{
Values::const_iterator next = next_it(v);
// next is just after v
Values::const_iterator prev = --next;
++next;
if ( v>=1 && next != values_.end())
std::cerr << ".";
if ( next == values_.end() )
{
if(m_colors[3][i])
{
m_nodes[nb_nodes] = i;
nb_nodes++;
}
return prev->second;
}
// build color_ramp
for(int k=0;k<3;k++)
for(unsigned int i=0;i<(nb_nodes-1);i++)
{
int x1 = m_nodes[i];
int x2 = m_nodes[i+1];
int y1 = m_colors[k][x1];
int y2 = m_colors[k][x2];
float a = (float)(y2-y1) / (float)(x2-x1);
float b = (float)y1 - a*(float)x1;
for(int j=x1;j<x2;j++)
m_colors[k][j] = (unsigned char)(a*(float)j+b);
}
const double& a = prev->first;
const double& b = next->first;
return (b-v)/(b-a) * prev->second + (v-a)/(b-a) * next->second;
}
void
Color_ramp::reset()
void
Color_component::
add(const double v, double color)
{
for(int i=1;i<=254;i++)
m_colors[3][i] = 0;
m_colors[3][0] = 1;
m_colors[3][255] = 1;
if ( color > 1 ) { color = 1; }
if ( color < 0 ) { color = 0; }
Values::iterator next = next_it(v);
values_.insert(next, std::make_pair(v,color));
}
void
Color_ramp::add_node(unsigned int index,
unsigned char r,
unsigned char g,
unsigned char b)
void
Color_component::
rebuild(const double c0, const double c1)
{
m_colors[3][index] = 1;
m_colors[0][index] = r;
m_colors[1][index] = g;
m_colors[2][index] = b;
values_.clear();
add(1,c1);
add(0,c0);
}
void
Color_component::
print() const
{
for ( Values::const_iterator it = values_.begin(),
end = values_.end() ; it != end ; ++it )
{
std::cout << "<" << it->first << "," << it->second << "> ";
}
std::cout << std::endl;
}
// -----------------------------------
// Color_ramp
// -----------------------------------
Color_ramp::Color_ramp()
: r_()
, g_()
, b_()
{
}
void
Color_ramp::build_red()
{
reset();
m_colors[3][0] = 1;
m_colors[0][0] = 128;
m_colors[1][0] = 0;
m_colors[2][0] = 0;
m_colors[3][80] = 1;
m_colors[0][80] = 255;
m_colors[1][80] = 0;
m_colors[2][80] = 0;
m_colors[3][160] = 1;
m_colors[0][160] = 255;
m_colors[1][160] = 128;
m_colors[2][160] = 0;
m_colors[3][255] = 1;
m_colors[0][255] = 255;
m_colors[1][255] = 255;
m_colors[2][255] = 255;
rebuild();
}
r_.rebuild(1,0.5);
g_.rebuild(1,0);
b_.rebuild(1,0);
void
Color_ramp::build_thermal()
{
reset();
m_colors[3][0] = 1;
m_colors[0][0] = 0;
m_colors[1][0] = 0;
m_colors[2][0] = 0;
m_colors[3][70] = 1;
m_colors[0][70] = 128;
m_colors[1][70] = 0;
m_colors[2][70] = 0;
m_colors[3][165] = 1;
m_colors[0][165] = 255;
m_colors[1][165] = 128;
m_colors[2][165] = 0;
m_colors[3][240] = 1;
m_colors[0][240] = 255;
m_colors[1][240] = 191;
m_colors[2][240] = 128;
m_colors[3][255] = 1;
m_colors[0][255] = 255;
m_colors[1][255] = 255;
m_colors[2][255] = 255;
rebuild();
r_.add(0.3,1);
r_.add(0.05,1);
g_.add(0.05,0.95);
g_.add(0.3,0.5);
b_.add(0.05,0);
}
void
Color_ramp::build_blue()
{
reset();
m_colors[3][0] = 1;
m_colors[0][0] = 0;
m_colors[1][0] = 0;
m_colors[2][0] = 128;
r_.rebuild(1,0);
g_.rebuild(1,0);
b_.rebuild(1,0.5);
m_colors[3][80] = 1;
m_colors[0][80] = 0;
m_colors[1][80] = 0;
m_colors[2][80] = 255;
m_colors[3][160] = 1;
m_colors[0][160] = 0;
m_colors[1][160] = 255;
m_colors[2][160] = 255;
m_colors[3][255] = 1;
m_colors[0][255] = 255;
m_colors[1][255] = 255;
m_colors[2][255] = 255;
rebuild();
b_.add(0.1,0.8);
g_.add(0.1,0.4);
r_.add(0.1,0.4);
}
void
Color_ramp::
print() const
{
std::cout << "r: ";
r_.print();
std::cout << "g: ";
g_.print();
std::cout << "b: ";
b_.print();
}

View File

@ -1,6 +1,31 @@
#ifndef _COLOR_RAMP_H
#define _COLOR_RAMP_H
#include <list>
class Color_component
{
typedef std::list<std::pair<double,double> > Values;
public:
Color_component();
Color_component(const double c0, const double c1);
~Color_component() {}
double interpolate(const double v) const;
void add(const double v, double color);
void rebuild(const double c0, const double c1);
void print() const;
private:
inline Values::const_iterator next_it(const double v) const;
inline Values::iterator next_it(const double v);
private:
Values values_;
};
class Color_ramp
{
public :
@ -8,26 +33,55 @@ public :
~Color_ramp() {}
public :
unsigned char r(unsigned int index) const { return m_colors[0][index%256]; }
unsigned char g(unsigned int index) const { return m_colors[1][index%256]; }
unsigned char b(unsigned int index) const { return m_colors[2][index%256]; }
void add_node(unsigned int index,
unsigned char r,
unsigned char g,
unsigned char b);
void build_red();
void build_thermal();
void build_blue();
inline double r(double v) const;
inline double g(double v) const;
inline double b(double v) const;
private:
void rebuild();
void reset();
void build_red();
void build_blue();
void print() const;
private :
int m_nodes[256];
unsigned char m_colors[4][256];
Color_component r_;
Color_component g_;
Color_component b_;
};
inline
Color_component::Values::const_iterator
Color_component::
next_it(const double v) const
{
Values::const_iterator next = values_.begin();
while ( next != values_.end() && v >= next->first ) { ++next; }
return next;
}
inline
Color_component::Values::iterator
Color_component::
next_it(const double v)
{
Values::iterator next = values_.begin();
while ( next != values_.end() && v >= next->first ) { ++next; }
return next;
}
inline
double
Color_ramp::r(double v) const
{ return r_.interpolate(v); }
inline
double
Color_ramp::g(double v) const
{ return g_.interpolate(v); }
inline
double
Color_ramp::b(double v) const
{ return b_.interpolate(v); }
#endif // _COLOR_RAMP_H

View File

@ -23,9 +23,10 @@ Scene_implicit_function_item(Implicit_function_interface* f)
{
blue_color_ramp_.build_blue();
red_color_ramp_.build_red();
compute_min_max();
compute_function_grid();
connect(frame_, SIGNAL(modified()), this, SLOT(compute_function_grid()));
compute_function_grid();
}
@ -42,8 +43,9 @@ Scene_implicit_function_item::bbox() const
}
void
Scene_implicit_function_item::draw() const
Scene_implicit_function_item::direct_draw() const
{
draw_function_grid(red_color_ramp_, blue_color_ramp_);
draw_bbox();
}
@ -158,18 +160,18 @@ draw_grid_vertex(const Point_value& pv,
const Color_ramp& ramp_negative) const
{
const Point& p = pv.first;
const double& v = pv.second;
double v = pv.second;
// determines grey level
if ( v > 0 )
{
unsigned int i = 255 - static_cast<unsigned int>(255. * v / max_value_);
::glColor3ub(ramp_positive.r(i),ramp_positive.g(i),ramp_positive.b(i));
v = v/max_value_;
::glColor3d(ramp_positive.r(v),ramp_positive.g(v),ramp_positive.b(v));
}
else
{
unsigned int i = 255 - static_cast<unsigned int>(255. * v / min_value_);
::glColor3ub(ramp_negative.r(i),ramp_negative.g(i),ramp_negative.b(i));
v = v/min_value_;
::glColor3d(ramp_negative.r(v),ramp_negative.g(v),ramp_negative.b(v));
}
::glVertex3d(p.x,p.y,p.z);
@ -192,8 +194,6 @@ compute_function_grid()
m[1], m[5], m[9], m[13],
m[2], m[6], m[10], m[14]);
max_value_ = 0;
min_value_ = 0;
double diag = bbox().diagonal_length() * .6;
const double dx = diag;
@ -212,8 +212,41 @@ compute_function_grid()
double v = function_->operator()(query.x(), query.y(), query.z());
implicit_grid_[i][j] = Point_value(Point(query.x(),query.y(),query.z()),v);
max_value_ = (std::max)(v, max_value_);
min_value_ = (std::min)(v, min_value_);
}
}
// Update display list
this->changed();
}
void
Scene_implicit_function_item::
compute_min_max()
{
max_value_ = 0;
min_value_ = 0;
double probes_nb = double(grid_size_) / 2;
// Probe bounding box
const Bbox& b = bbox();
for ( int i = 0 ; i <= probes_nb ; ++i )
{
double x = b.xmin + double(i) * (b.xmax - b.xmin) / probes_nb;
for ( int j = 0 ; j <= probes_nb ; ++j )
{
double y = b.ymin + double(j) * (b.ymax - b.ymin) / probes_nb;
for ( int k = 0 ; k <= probes_nb ; ++k )
{
double z = b.zmin + double(k) * (b.zmax - b.zmin) / probes_nb;
double v = (*function_)(x,y,z);
max_value_ = (std::max)(v,max_value_);
min_value_ = (std::min)(v,min_value_);
}
}
}
}

View File

@ -10,7 +10,7 @@
#include <QGLViewer/manipulatedFrame.h>
#include <QGLViewer/qglviewer.h>
#define SCENE_IMPLICIT_GRID_SIZE 100
#define SCENE_IMPLICIT_GRID_SIZE 120
class SCENE_IMPLICIT_FUNCTION_ITEM_EXPORT Scene_implicit_function_item
@ -37,11 +37,8 @@ public:
virtual bool manipulatable() const { return true; }
virtual ManipulatedFrame* manipulatedFrame() { return frame_; }
// draw
virtual void direct_draw() const { draw(); }
virtual void direct_draw_edges() const { draw_edges(); }
virtual void draw() const;
virtual void draw_edges() const { draw(); }
// draw (overload only direct_draw() to use display list of base class)
virtual void direct_draw() const;
virtual QString toolTip() const;
@ -57,6 +54,8 @@ private:
void draw_grid_vertex(const Point_value&,
const Color_ramp&, const Color_ramp&) const;
void compute_min_max();
private:
Implicit_function_interface* function_;
ManipulatedFrame* frame_;