mirror of https://github.com/CGAL/cgal
+ Improve implicit function drawing efficiency (use display list stuff from base class)
+ Adjust Color_ramp
This commit is contained in:
parent
a5d085b67d
commit
70ae043666
|
|
@ -1,145 +1,126 @@
|
||||||
#include "Color_ramp.h"
|
#include "Color_ramp.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// -----------------------------------
|
||||||
|
// Color_component
|
||||||
|
// -----------------------------------
|
||||||
|
Color_component::
|
||||||
|
Color_component()
|
||||||
|
{
|
||||||
|
add(0,0);
|
||||||
|
add(1,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Color_component::
|
||||||
|
Color_component(const double c0, const double c1)
|
||||||
|
{
|
||||||
|
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() )
|
||||||
|
{
|
||||||
|
return prev->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_component::
|
||||||
|
add(const double v, double color)
|
||||||
|
{
|
||||||
|
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_component::
|
||||||
|
rebuild(const double c0, const double c1)
|
||||||
|
{
|
||||||
|
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()
|
Color_ramp::Color_ramp()
|
||||||
|
: r_()
|
||||||
|
, g_()
|
||||||
|
, b_()
|
||||||
{
|
{
|
||||||
build_thermal();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Color_ramp::rebuild()
|
|
||||||
{
|
|
||||||
// build nodes
|
|
||||||
m_colors[3][0] = 1;
|
|
||||||
m_colors[3][255] = 1;
|
|
||||||
unsigned int nb_nodes = 0;
|
|
||||||
for(int i=0;i<256;i++)
|
|
||||||
{
|
|
||||||
if(m_colors[3][i])
|
|
||||||
{
|
|
||||||
m_nodes[nb_nodes] = i;
|
|
||||||
nb_nodes++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Color_ramp::reset()
|
|
||||||
{
|
|
||||||
for(int i=1;i<=254;i++)
|
|
||||||
m_colors[3][i] = 0;
|
|
||||||
m_colors[3][0] = 1;
|
|
||||||
m_colors[3][255] = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Color_ramp::add_node(unsigned int index,
|
|
||||||
unsigned char r,
|
|
||||||
unsigned char g,
|
|
||||||
unsigned char b)
|
|
||||||
{
|
|
||||||
m_colors[3][index] = 1;
|
|
||||||
m_colors[0][index] = r;
|
|
||||||
m_colors[1][index] = g;
|
|
||||||
m_colors[2][index] = b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Color_ramp::build_red()
|
Color_ramp::build_red()
|
||||||
{
|
{
|
||||||
reset();
|
r_.rebuild(1,0.5);
|
||||||
m_colors[3][0] = 1;
|
g_.rebuild(1,0);
|
||||||
m_colors[0][0] = 128;
|
b_.rebuild(1,0);
|
||||||
m_colors[1][0] = 0;
|
|
||||||
m_colors[2][0] = 0;
|
|
||||||
|
|
||||||
m_colors[3][80] = 1;
|
r_.add(0.3,1);
|
||||||
m_colors[0][80] = 255;
|
r_.add(0.05,1);
|
||||||
m_colors[1][80] = 0;
|
g_.add(0.05,0.95);
|
||||||
m_colors[2][80] = 0;
|
g_.add(0.3,0.5);
|
||||||
|
b_.add(0.05,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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Color_ramp::build_blue()
|
Color_ramp::build_blue()
|
||||||
{
|
{
|
||||||
reset();
|
r_.rebuild(1,0);
|
||||||
m_colors[3][0] = 1;
|
g_.rebuild(1,0);
|
||||||
m_colors[0][0] = 0;
|
b_.rebuild(1,0.5);
|
||||||
m_colors[1][0] = 0;
|
|
||||||
m_colors[2][0] = 128;
|
|
||||||
|
|
||||||
m_colors[3][80] = 1;
|
b_.add(0.1,0.8);
|
||||||
m_colors[0][80] = 0;
|
g_.add(0.1,0.4);
|
||||||
m_colors[1][80] = 0;
|
r_.add(0.1,0.4);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Color_ramp::
|
||||||
|
print() const
|
||||||
|
{
|
||||||
|
std::cout << "r: ";
|
||||||
|
r_.print();
|
||||||
|
std::cout << "g: ";
|
||||||
|
g_.print();
|
||||||
|
std::cout << "b: ";
|
||||||
|
b_.print();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,31 @@
|
||||||
#ifndef _COLOR_RAMP_H
|
#ifndef _COLOR_RAMP_H
|
||||||
#define _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
|
class Color_ramp
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
|
|
@ -8,26 +33,55 @@ public :
|
||||||
~Color_ramp() {}
|
~Color_ramp() {}
|
||||||
|
|
||||||
public :
|
public :
|
||||||
unsigned char r(unsigned int index) const { return m_colors[0][index%256]; }
|
inline double r(double v) const;
|
||||||
unsigned char g(unsigned int index) const { return m_colors[1][index%256]; }
|
inline double g(double v) const;
|
||||||
unsigned char b(unsigned int index) const { return m_colors[2][index%256]; }
|
inline double b(double v) const;
|
||||||
|
|
||||||
void add_node(unsigned int index,
|
|
||||||
unsigned char r,
|
|
||||||
unsigned char g,
|
|
||||||
unsigned char b);
|
|
||||||
|
|
||||||
void build_red();
|
void build_red();
|
||||||
void build_thermal();
|
|
||||||
void build_blue();
|
void build_blue();
|
||||||
|
void print() const;
|
||||||
private:
|
|
||||||
void rebuild();
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
int m_nodes[256];
|
Color_component r_;
|
||||||
unsigned char m_colors[4][256];
|
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
|
#endif // _COLOR_RAMP_H
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,10 @@ Scene_implicit_function_item(Implicit_function_interface* f)
|
||||||
{
|
{
|
||||||
blue_color_ramp_.build_blue();
|
blue_color_ramp_.build_blue();
|
||||||
red_color_ramp_.build_red();
|
red_color_ramp_.build_red();
|
||||||
|
compute_min_max();
|
||||||
|
compute_function_grid();
|
||||||
|
|
||||||
connect(frame_, SIGNAL(modified()), this, SLOT(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
|
void
|
||||||
Scene_implicit_function_item::draw() const
|
Scene_implicit_function_item::direct_draw() const
|
||||||
{
|
{
|
||||||
|
|
||||||
draw_function_grid(red_color_ramp_, blue_color_ramp_);
|
draw_function_grid(red_color_ramp_, blue_color_ramp_);
|
||||||
draw_bbox();
|
draw_bbox();
|
||||||
}
|
}
|
||||||
|
|
@ -158,18 +160,18 @@ draw_grid_vertex(const Point_value& pv,
|
||||||
const Color_ramp& ramp_negative) const
|
const Color_ramp& ramp_negative) const
|
||||||
{
|
{
|
||||||
const Point& p = pv.first;
|
const Point& p = pv.first;
|
||||||
const double& v = pv.second;
|
double v = pv.second;
|
||||||
|
|
||||||
// determines grey level
|
// determines grey level
|
||||||
if ( v > 0 )
|
if ( v > 0 )
|
||||||
{
|
{
|
||||||
unsigned int i = 255 - static_cast<unsigned int>(255. * v / max_value_);
|
v = v/max_value_;
|
||||||
::glColor3ub(ramp_positive.r(i),ramp_positive.g(i),ramp_positive.b(i));
|
::glColor3d(ramp_positive.r(v),ramp_positive.g(v),ramp_positive.b(v));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int i = 255 - static_cast<unsigned int>(255. * v / min_value_);
|
v = v/min_value_;
|
||||||
::glColor3ub(ramp_negative.r(i),ramp_negative.g(i),ramp_negative.b(i));
|
::glColor3d(ramp_negative.r(v),ramp_negative.g(v),ramp_negative.b(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
::glVertex3d(p.x,p.y,p.z);
|
::glVertex3d(p.x,p.y,p.z);
|
||||||
|
|
@ -192,8 +194,6 @@ compute_function_grid()
|
||||||
m[1], m[5], m[9], m[13],
|
m[1], m[5], m[9], m[13],
|
||||||
m[2], m[6], m[10], m[14]);
|
m[2], m[6], m[10], m[14]);
|
||||||
|
|
||||||
max_value_ = 0;
|
|
||||||
min_value_ = 0;
|
|
||||||
double diag = bbox().diagonal_length() * .6;
|
double diag = bbox().diagonal_length() * .6;
|
||||||
|
|
||||||
const double dx = diag;
|
const double dx = diag;
|
||||||
|
|
@ -212,8 +212,41 @@ compute_function_grid()
|
||||||
double v = function_->operator()(query.x(), query.y(), query.z());
|
double v = function_->operator()(query.x(), query.y(), query.z());
|
||||||
|
|
||||||
implicit_grid_[i][j] = Point_value(Point(query.x(),query.y(),query.z()),v);
|
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_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#include <QGLViewer/manipulatedFrame.h>
|
#include <QGLViewer/manipulatedFrame.h>
|
||||||
#include <QGLViewer/qglviewer.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
|
class SCENE_IMPLICIT_FUNCTION_ITEM_EXPORT Scene_implicit_function_item
|
||||||
|
|
@ -37,11 +37,8 @@ public:
|
||||||
virtual bool manipulatable() const { return true; }
|
virtual bool manipulatable() const { return true; }
|
||||||
virtual ManipulatedFrame* manipulatedFrame() { return frame_; }
|
virtual ManipulatedFrame* manipulatedFrame() { return frame_; }
|
||||||
|
|
||||||
// draw
|
// draw (overload only direct_draw() to use display list of base class)
|
||||||
virtual void direct_draw() const { draw(); }
|
virtual void direct_draw() const;
|
||||||
virtual void direct_draw_edges() const { draw_edges(); }
|
|
||||||
virtual void draw() const;
|
|
||||||
virtual void draw_edges() const { draw(); }
|
|
||||||
|
|
||||||
virtual QString toolTip() const;
|
virtual QString toolTip() const;
|
||||||
|
|
||||||
|
|
@ -57,6 +54,8 @@ private:
|
||||||
void draw_grid_vertex(const Point_value&,
|
void draw_grid_vertex(const Point_value&,
|
||||||
const Color_ramp&, const Color_ramp&) const;
|
const Color_ramp&, const Color_ramp&) const;
|
||||||
|
|
||||||
|
void compute_min_max();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Implicit_function_interface* function_;
|
Implicit_function_interface* function_;
|
||||||
ManipulatedFrame* frame_;
|
ManipulatedFrame* frame_;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue