⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gradient.cpp

📁 学习 open inventor 的例子
💻 CPP
字号:
/**************************************************************************\ * *  This file is part of the Coin 3D visualization library. *  Copyright (C) 1998-2003 by Systems in Motion.  All rights reserved. * *  This library is free software; you can redistribute it and/or *  modify it under the terms of the GNU General Public License *  ("GPL") version 2 as published by the Free Software Foundation. *  See the file LICENSE.GPL at the root directory of this source *  distribution for additional information about the GNU GPL. * *  For using Coin with software that can not be combined with the GNU *  GPL, and for taking advantage of the additional benefits of our *  support services, please contact Systems in Motion about acquiring *  a Coin Professional Edition License. * *  See <URL:http://www.coin3d.org> for more information. * *  Systems in Motion, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY. *  <URL:http://www.sim.no>. *\**************************************************************************/#include <assert.h>#include "qtsupport.h"#include <qfile.h>#include <qimage.h>#include "Gradient.h"// *************************************************************************class GradientP {public:  GradientP(Gradient * publ);  unsigned int getColorIndex(unsigned int i, Gradient::TickSide s) const;  Gradient * pub;  QValueList<float> parameters;  QValueList<QRgb> colors;  Gradient::ChangeCB * callBack;  void * callBackData;  void copy(const GradientP * p);};#define PRIVATE(p) (p->pimpl)#define PUBLIC(p) (p->pub)// *************************************************************************GradientP::GradientP(Gradient * publ){  PUBLIC(this) = publ;}void GradientP::copy(const GradientP * p) {  this->callBack = p->callBack;  this->callBackData = p->callBackData;  this->parameters = p->parameters;  this->colors = p->colors;}unsigned intGradientP::getColorIndex(unsigned int i, Gradient::TickSide s) const{  int colidx;  if (i==0 && s==Gradient::LEFT) { colidx = this->colors.size() - 1; } // wrap around  // there are parameters times two minus one number of colors  else { colidx = i * 2 - ((s==Gradient::LEFT) ? 1 : 0); }  if (colidx == this->colors.size()) { colidx = 0; } // wrap around  assert(colidx < this->colors.size() && "border violation");  return (unsigned int) colidx;}Gradient::Gradient(const QColor& color0, const QColor& color1){  this->pimpl = new GradientP(this);  PRIVATE(this)->callBack = NULL;    // parameter values will be in the range [0 - 1]  PRIVATE(this)->parameters.append(0.0f);  PRIVATE(this)->parameters.append(1.0f);  PRIVATE(this)->colors.append(color0.rgb());  PRIVATE(this)->colors.append(color1.rgb());}Gradient::Gradient(const Gradient & grad){  this->pimpl = new GradientP(this);  this->operator=(grad);}Gradient::Gradient(const QString & filename){  this->pimpl = new GradientP(this);  PRIVATE(this)->callBack = NULL;  this->load(filename);}Gradient::~Gradient(){}Gradient &Gradient::operator=(const Gradient & grad){  PRIVATE(this)->copy(grad.pimpl);  return *this;}SbBool Gradient::operator == (const Gradient & grad) const{  return (PRIVATE(this)->parameters == grad.pimpl->parameters) &&         (PRIVATE(this)->colors == grad.pimpl->colors);}QRgbGradient::eval(float t) const{  // FIXME: The assert seemed abit strict. Replaced with a clamp and a  // warning instead. (20061201 handegar)  //assert(t >= 0.0f && t <= 1.0f && "t must be in the interval [0,1]");  if (t > 1.0f) {    fprintf(stderr, "t=%f > 1.0f. Clamped to 1.0f.", t);    t = 1.0f;  }  else if (t < 0.0f) {    fprintf(stderr, "t=%f < 0.0f. Clampedx to 0.0f.", t);    t = 0.0f;  }  int i = 0;  // find the interval to evaluate in  while (PRIVATE(this)->parameters[++i] < t);  int j = (i-1)*2;  float t0 = PRIVATE(this)->parameters[i-1];  float t1 = PRIVATE(this)->parameters[i];  float dt = t1 - t0;  // weights for linear interpolation  float w0, w1;//   assert((dt != 0.0f) && "division by zero");  if (dt == 0.0f) {    w0 = w1 = 0.5f;  }  else {    w0 = (t1 - t) / dt;    w1 = (t - t0) / dt;  }  const QRgb color0 = PRIVATE(this)->colors[j];  const QRgb color1 = PRIVATE(this)->colors[j+1];  // add 0.5 to get rounding  int r = int(w0 * float(qRed(color0)) + w1 * float(qRed(color1)) + 0.5f);  int g = int(w0 * float(qGreen(color0)) + w1 * float(qGreen(color1)) + 0.5f);  int b = int(w0 * float(qBlue(color0)) + w1 * float(qBlue(color1)) + 0.5f);  int a = int(w0 * float(qAlpha(color0)) + w1 * float(qAlpha(color1)) + 0.5f);  return qRgba(r, g, b, a);}unsigned intGradient::numTicks(void) const{  return PRIVATE(this)->parameters.size();}floatGradient::getParameter(unsigned int i) const{  return PRIVATE(this)->parameters[i];}voidGradient::moveTick(unsigned int i, float t){  if ((PRIVATE(this)->parameters[i-1] != t) && PRIVATE(this)->parameters[i+1] != t) {    PRIVATE(this)->parameters[i] = t;    if (PRIVATE(this)->callBack) { PRIVATE(this)->callBack(*this, PRIVATE(this)->callBackData); }  }}unsigned intGradient::insertTick(float t){  // find position to insert before  int i = 0;  QValueList<float>::Iterator it = PRIVATE(this)->parameters.begin();  QValueList<QRgb>::Iterator it2 = PRIVATE(this)->colors.begin();  // it2 = it * 2 - 1, (+= operator wasnt available until Qt 3.1.0)  while ((*it) < t) { i++; it++; it2++; it2++; }  it2--;  // we use the color of the gradient at this parameter value  QRgb color = this->eval(t);  PRIVATE(this)->parameters.insert(it, t);  PRIVATE(this)->colors.insert(it2, 2, color);  if (PRIVATE(this)->callBack) { PRIVATE(this)->callBack(*this, PRIVATE(this)->callBackData); }  return i;}voidGradient::removeTick(unsigned int i){  QValueList<float>::Iterator it = PRIVATE(this)->parameters.begin();  QValueList<QRgb>::Iterator it2 = PRIVATE(this)->colors.begin();  // the += operator wasn't available until Qt 3.1.0. Just iterate  // and use ++. pederb, 2003-09-22  for (unsigned int j = 0; j < i; j++) { it++; it2++; it2++; }  it2--;  PRIVATE(this)->parameters.remove(it);  it2 = PRIVATE(this)->colors.remove(it2);  PRIVATE(this)->colors.remove(it2);  if (PRIVATE(this)->callBack) { PRIVATE(this)->callBack(*this, PRIVATE(this)->callBackData); }}SbBoolGradient::leftEqualsRight(unsigned int i) const{  i = PRIVATE(this)->getColorIndex(i, Gradient::LEFT);  unsigned int n = PRIVATE(this)->colors.size();  return (PRIVATE(this)->colors[i] == PRIVATE(this)->colors[(i+1) % n]);}/*!  See Gradient::getColor() for documentation of input arguments.*/voidGradient::setColor(unsigned int i, TickSide s, const QRgb & color){  i = PRIVATE(this)->getColorIndex(i, s);  PRIVATE(this)->colors[i] = color;  if (PRIVATE(this)->callBack) { PRIVATE(this)->callBack(*this, PRIVATE(this)->callBackData); }}/*!  Specify tickmark number for \a i, and either Gradient::LEFT or  Gradient::RIGHT for \a s to indicate which side of tickmark to read  the color from.  Note that tickmark 0 is the invisible tickmark on the far left side,  and ditto the last tickmark is invisible on the far right side.*/QRgbGradient::getColor(unsigned int i, TickSide s) const{  i = PRIVATE(this)->getColorIndex(i, s);  return PRIVATE(this)->colors[i];}voidGradient::setChangeCallback(Gradient::ChangeCB * callBack, void * userdata){  PRIVATE(this)->callBack = callBack;  PRIVATE(this)->callBackData = userdata;}voidGradient::getColorArray(QRgb * colorArray, unsigned int num) const{  for (unsigned int i = 0; i < num; i++) {    float t = float(i) / float(num - 1);    colorArray[i] = this->eval(t);  }}QImageGradient::getImage(unsigned int width, unsigned int height, unsigned int depth) const{  QImage gradImage(width, height, depth);  QRgb * colors = new QRgb[width];  this->getColorArray(colors, width);  for (unsigned int i = 0; i < width; i ++) {    float alpha = float(qAlpha(colors[i])) / 255.0f;    for (unsigned int j = 0; j < height; j++) {      // produces a checkerboard pattern of black and white      QRgb background = 0;      if (((i & 0x8) == 0) ^ ((j & 0x8) == 0)) {        background = 255;      }      const unsigned char bg = (unsigned char)((1.0f - alpha) * float(background));      const unsigned char r = (unsigned char)(alpha * float(qRed(colors[i])) + bg);      const unsigned char g = (unsigned char)(alpha * float(qGreen(colors[i])) + bg);      const unsigned char b = (unsigned char)(alpha * float(qBlue(colors[i])) + bg);            gradImage.setPixel(i, j, qRgb(r, g, b));    }  }  delete [] colors;  return gradImage;}voidGradient::save(const QString & filename) const{  QFile outfile(filename);  if (outfile.open(IO_WriteOnly)) {    QTextStream stream(&outfile);    stream << PRIVATE(this)->parameters.size() << " ";    QValueList<float>::Iterator it = PRIVATE(this)->parameters.begin();    for (; it != PRIVATE(this)->parameters.end(); it++) {      stream << (*it) << " ";#if 0 // debug      printf("%f\n", *it);#endif    }    stream << PRIVATE(this)->colors.size() << " ";    QValueList<QRgb>::Iterator it2 = PRIVATE(this)->colors.begin();    for (; it2 != PRIVATE(this)->colors.end(); it2++) {      stream << (*it2) << " ";#if 0 // debug      QRgb rgb = *it2;      printf("0x%02x 0x%02x 0x%02x 0x%02x\n",             qRed(rgb), qGreen(rgb), qBlue(rgb), qAlpha(rgb));#endif    }    outfile.close();  }}voidGradient::load(const QString & filename){  PRIVATE(this)->colors.clear();  PRIVATE(this)->parameters.clear();  QFile infile(filename);  if (infile.open(IO_ReadOnly)) {    QTextStream stream(&infile);    this->load(stream);    infile.close();  }  // FIXME: error handling. 20040308 mortene.}voidGradient::load(QTextStream & stream){  // FIXME: proper parsing with error checking. 20040308 mortene.  PRIVATE(this)->colors.clear();  PRIVATE(this)->parameters.clear();  int i;  int numParameters;  stream >> numParameters;      for (i = 0; i < numParameters; i++) {    float t;    stream >> t;    PRIVATE(this)->parameters.append(t);  }  int numColors;  stream >> numColors;  for (i = 0; i < numColors; i++) {    QRgb clr;    stream >> clr;    PRIVATE(this)->colors.append(clr);  }}#undef PRIVATE#undef PUBLIC

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -