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

📄 curveview.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 <qpoint.h>#include <qpainter.h>#include <qcursor.h>#include <qevent.h>#include <Inventor/SbLinear.h>#include "ColorCurve.h"#include "CurveView.h"#include "moc_CurveView.icc"CurveView::CurveView(int numcolors,                     SoQtColorTableEditor::Mode mode,                     QCanvas * canvas,                     QWidget * parent,                     const char * name,                     Qt::WFlags flags)                      : QCanvasView(canvas, parent, name, flags), ptsize(3){  this->colormode = mode;  this->canvas = canvas;  this->canvas->resize(numcolors, numcolors);  this->setFixedSize(numcolors+2, numcolors+2);  this->setVScrollBarMode(QScrollView::AlwaysOff);  this->setHScrollBarMode(QScrollView::AlwaysOff);  this->curvemode = CurveView::SMOOTH;  this->mousepressed = FALSE;  this->movingitem = NULL;    this->size = numcolors;  this->initColorCurves();  this->hideUnselected();    this->initGrid();  this->initCanvasCurve();  this->viewport()->setMouseTracking(TRUE);}CurveView::~CurveView(){  for (int i = 0; i < this->colormode; i++) {    delete this->colorcurves[i];  }}voidCurveView::initColorCurves(){  for (int i = 0; i < this->colormode; i++) {    this->colorindex = i;    ColorCurve::CurveType type = ColorCurve::LINEAR;    if (((this->colormode == SoQtColorTableEditor::LUMINANCE_ALPHA) && (i == 1)) ||        ((this->colormode == SoQtColorTableEditor::RGBA) && (i == 3))){      type = ColorCurve::CONSTANT;    }    this->colorcurves.append(new ColorCurve(type, this->size));    this->canvasctrlpts.append(this->newCanvasCtrlPtList());  }  this->colorindex = 0;}void CurveView::initCanvasCurve(){  const uint8_t * curvepts = this->colorcurves[this->colorindex]->getColorMap();  for (int i = 2; i < this->colorcurves[this->colorindex]->getNumColors(); i+=2) {    QCanvasLine * line = new QCanvasLine(this->canvas);    line->setPoints(i-2, int(this->size - 1) - curvepts[i-2], i, int(this->size - 1) - curvepts[i]);    line->setZ(1); // to make the curve be drawn on top of the grid    line->show();    this->curvesegments.append(line);  }}void CurveView::initGrid(){  int step = this->size/4;  QPen pen(Qt::gray);  for (int i = step; i < this->size; i+=step) {    QCanvasLine * line = new QCanvasLine(this->canvas);    line->setPoints(i, 0, i, (this->size - 1));    line->setPen(pen);    line->show();    this->grid.append(line);  }  for (int j = step; j < this->size; j+=step) {    QCanvasLine * line = new QCanvasLine(this->canvas);    line->setPoints(0, j, this->size, j);    line->setPen(pen);    line->show();    this->grid.append(line);  }  }void CurveView::contentsMousePressEvent(QMouseEvent* e){  if (e->button() == Qt::LeftButton) {    this->mousepressed = TRUE;  }  QPoint p = inverseWorldMatrix().map(e->pos());  this->movingstart = p;  this->lastpos = p;  QCanvasItemList list = this->canvas->collisions(p);  if (this->curvemode == CurveView::SMOOTH) {    QCanvasItemList::Iterator it = list.begin();    if ((it != list.end()) && ((*it)->rtti() == QCanvasRectangle::RTTI)) {      if (e->button() == Qt::LeftButton) {        this->movingitem = (*it);      } else {        if (this->canvasctrlpts[this->colorindex].size() > 2) {          delete (*it);          this->canvasctrlpts[this->colorindex].remove(*it);        }      }    } else {      if (e->button() == Qt::LeftButton) {        QCanvasRectangle * ctrlpt = this->newControlPoint(p.x(), p.y());        this->movingitem = ctrlpt;        this->canvasctrlpts[this->colorindex].append(ctrlpt);      }    }    this->updateCurve();  }  this->canvas->update();}voidCurveView::contentsMouseReleaseEvent(QMouseEvent * e){  this->mousepressed = FALSE;  this->colorcurves[this->colorindex]->notify();}void CurveView::contentsMouseMoveEvent(QMouseEvent* e){  QPoint p = inverseWorldMatrix().map(e->pos());  if (this->curvemode == CurveView::SMOOTH) {    // change the cursor if it is over a control point    QCanvasItemList list = this->canvas->collisions(p);    QCanvasItemList::Iterator it = list.begin();    if ((it != list.end()) && ((*it)->rtti() == QCanvasRectangle::RTTI)) {      this->setCursor(Qt::SizeAllCursor);    } else {      this->setCursor(Qt::ArrowCursor);    }      if (this->movingitem && this->mousepressed) { // move the control point      int x = p.x();      int y = p.y();          if (x > (this->size - 1) - this->ptsize) x = (this->size - 1) - this->ptsize;      if (y > (this->size - this->ptsize)) y = this->size  - this->ptsize;      if (x < this->ptsize) x = this->ptsize;      if (y < this->ptsize) y = this->ptsize;      this->movingitem->moveBy(x - movingstart.x(), y - movingstart.y());      this->movingstart = QPoint(x, y);      this->updateCurve();    }  } else { // draw a color mapping    if (this->mousepressed) {      int lastx = lastpos.x();      int lasty = lastpos.y();      int currentx = p.x();      int currenty = p.y();      if ((lastx >= 0) && (lastx <= (this->size - 1)) &&           (currentx >= 0) && (currentx <= (this->size - 1))) {        if (currentx < lastx) { // swap          /* FIXME: two lines needed, otherwise ends up in compiler             warning: operation on `currenty' may be             undefined. 20061019 tamer. */          lastx ^= currentx ^= lastx;          currentx ^= lastx;          lasty ^= currenty ^= lasty;          currenty ^= lasty;        }        float x0 = float(lastx);        float y0 = float(lasty);        float x1 = float(currentx);        float y1 = float(currenty);        float dx = x1 - x0;        // fill in the points between p and lastpos,        // linearly interpolate the position        for (int i = lastx; i < currentx; i++) {          float w0 = (x1 - float(i)) / dx;          float w1 = (float(i) - x0) / dx;          int y = int(w0 * y0 + w1 * y1 + 0.5f);          // clamp          if (y > (this->size - 1)) y = (this->size - 1);          if (y < 0) y = 0;          this->colorcurves[this->colorindex]->setColorMapping(i, (this->size - 1)-y);        }        this->lastpos = p;        this->updateCurve();      }    }  }  this->canvas->update();}voidCurveView::drawContents(QPainter * p){  this->drawContents(p, 0, 0, this->contentsWidth(), this->contentsHeight());}void CurveView::drawContents(QPainter * p, int cx, int cy, int cw, int ch){  QCanvasItemList::Iterator it;      // draw the grid in the background  it = this->grid.begin();  for (; it != this->grid.end(); it++) {    (*it)->draw(*p);  }  // draw the curve  it = this->curvesegments.begin();  for (; it != this->curvesegments.end(); it++) {    (*it)->draw(*p);  }  // draw the control points  if (this->curvemode == CurveView::SMOOTH) {    it = this->canvasctrlpts[this->colorindex].begin();    for (; it != this->canvasctrlpts[this->colorindex].end(); ++it) {        (*it)->draw(*p);    }  }}void CurveView::hideUnselected(){  QCanvasItemList::Iterator it;  for (int i = 0; i < this->colormode; i++) {    it = this->canvasctrlpts[i].begin();    for (; it != this->canvasctrlpts[i].end(); ++it) {      if ((this->colorindex == i) && (this->curvemode != CurveView::FREE)) {        (*it)->show();      } else {        (*it)->hide();      }    }  }}voidCurveView::resetActive() {  this->colorcurves[this->colorindex]->resetCtrlPoints();  // QCanvasItemList::clear() only removes the items from the list,   // but they need to be deleted also.  QCanvasItemList::Iterator it = this->canvasctrlpts[this->colorindex].begin();  for (; it != this->canvasctrlpts[this->colorindex].end(); it++) {    delete (*it);  }  this->canvasctrlpts[this->colorindex].clear();  this->canvasctrlpts[this->colorindex] = this->newCanvasCtrlPtList();  this->curvemode = CurveView::SMOOTH;  this->updateCurve();  this->canvas->update();}QCanvasItemListCurveView::newCanvasCtrlPtList(){  QCanvasItemList list;  int numpts = this->colorcurves[this->colorindex]->getNumCtrlPoints();  const QValueVector<SbVec3f> ctrlpts = this->colorcurves[this->colorindex]->getCtrlPoints();  for (int i = 0; i < numpts; i++) {    list.append(this->newControlPoint(int(ctrlpts[i][0] * (this->size - 1)), int((this->size - 1) - ctrlpts[i][1] * (this->size - 1))));  }  return list;}QCanvasRectangle *CurveView::newControlPoint(int x, int y){  QCanvasRectangle * rect    = new QCanvasRectangle(x-this->ptsize, y-this->ptsize,                           this->ptsize*2, this->ptsize*2,                           this->canvas);  rect->setZ(2); // the control points will be drawn on top of the curve  rect->show();  return rect;}void CurveView::updateCurve(){  QCanvasItemList::iterator it;  int i = 0;  if (this->curvemode == CurveView::SMOOTH) {     QCanvasItemList list = this->canvasctrlpts[this->colorindex];    QCanvasItemList sortedlist;        // Sort the list of control points    while ((it = list.begin()) != list.end()) {      QCanvasRectangle * smallest = (QCanvasRectangle *) this->smallestItem(&list);      smallest->setBrush(Qt::black);      sortedlist.append(smallest);      list.remove(smallest);    }    QValueVector<SbVec3f> ctrlpts;    for (it =  sortedlist.begin(); it != sortedlist.end(); it++) {      float x = ((*it)->x() + float(this->ptsize)) / (this->size - 1);      float y = 1.0f - ((*it)->y() + float(this->ptsize)) / (this->size - 1);        ctrlpts.append(SbVec3f(x, y, 0.0f));    }    this->colorcurves[this->colorindex]->setCtrlPoints(ctrlpts);  }  i = 2;  it = this->curvesegments.begin();  const uint8_t * curvepts = this->colorcurves[this->colorindex]->getColorMap();  for (; it != this->curvesegments.end(); it++) {    QCanvasLine* line = (QCanvasLine*)(*it);    line->setPoints(i-2, int(this->size - 1)-curvepts[i-2], i, int(this->size - 1)-curvepts[i]);    i+=2;  }      emit this->curveChanged();}QCanvasItem * CurveView::smallestItem(QCanvasItemList * list){  QCanvasItemList::Iterator it = list->begin();  QCanvasItem * smallest = (*it);  it++;  for (; it != list->end(); ++it) {    if ((*it)->x() < smallest->x()) {      smallest = (*it);    }  }  return smallest;}voidCurveView::setMode(SoQtColorTableEditor::Mode mode){  for (int i = 0; i < this->colormode; i++) {    delete this->colorcurves[i];    QCanvasItemList::Iterator it = this->canvasctrlpts[i].begin();    for (; it != this->canvasctrlpts[i].end(); it++) {      delete *it;    }  }  this->colorcurves.clear();  this->canvasctrlpts.clear();  this->colormode = mode;  this->initColorCurves();  this->hideUnselected();}void CurveView::changeColorMode(int mode){  if (mode != this->colorindex) {    this->colorindex = mode;    this->hideUnselected();    this->updateCurve();    this->canvas->update();  }}voidCurveView::changeCurveMode(int cmode){  if (cmode != this->curvemode) {    this->curvemode = (CurveType) cmode;    if (this->curvemode == CurveView::SMOOTH) {      this->interpolateFromColors();    }    this->hideUnselected();    this->updateCurve();    this->canvas->update();  }}voidCurveView::interpolateFromColors(){  for (int i = 0; i < this->colormode; i++) {    this->colorcurves[i]->interpolateColorMapping();    QValueVector<SbVec3f> ctrlpts = this->colorcurves[i]->getCtrlPoints();    QCanvasItemList::Iterator it = this->canvasctrlpts[i].begin();    for (; it != this->canvasctrlpts[i].end(); it++) {      delete (*it);    }    this->canvasctrlpts[i].clear();    for (int j = 0; j < this->colorcurves[i]->getNumCtrlPoints(); j++) {      this->canvasctrlpts[i].append(        this->newControlPoint(int(ctrlpts[j][0] * (this->size - 1)), int((this->size - 1) - ctrlpts[j][1] * (this->size - 1))));    }  }}voidCurveView::setConstantValue(int value){  this->colorcurves[this->colorindex]->fill(value);  this->updateCurve();  this->canvas->update();}void CurveView::getColors(uint8_t * colors, int num) const{  uint8_t * clrs = new uint8_t[num];  for (int i = 0; i < this->colormode; i++) {    this->colorcurves[i]->getColors(clrs, num);    for (int j = 0; j < num; j++) {      colors[j*(this->colormode) + i] = clrs[j];    }  }  delete [] clrs;}void CurveView::setColors(uint8_t * colors, int num){  uint8_t * clrs = new uint8_t[num];  for (int i = 0; i < colormode; i++) {    for (int j = 0; j < num; j++) {      clrs[j] = colors[j*colormode + i];    }    this->colorcurves[i]->setColors(clrs, num);  }  delete [] clrs;  this->changeCurveMode(CurveView::FREE);}QPixmapCurveView::getPixmap(int width, int height) const{  QImage img(width, height, 32);  QPixmap pm;  if (this->colormode < 3) {    const uint8_t * colors = this->colorcurves[0]->getColorMap();    pm = this->makePixmap(width, height, colors, colors, colors);  } else {    const uint8_t * red = this->colorcurves[0]->getColorMap();    const uint8_t * green = this->colorcurves[1]->getColorMap();    const uint8_t * blue = this->colorcurves[2]->getColorMap();    pm = this->makePixmap(width, height, red, green, blue);  }  return pm;}QPixmapCurveView::makePixmap(int w, int h, const uint8_t * r, const uint8_t * g, const uint8_t * b) const{  // use an image since it is optimized for direct pixel access  QImage img(w, h, 32);  for (int i = 0; i < w; i++) {#if 0     // FIXME: org variable unused. 20061019 tamer.    int org = (int) ((float(i) / float(w)) * (this->size - 1));#endif    for (int j = 0; j < h; j++) {      img.setPixel(i, j, qRgb(r[i], g[i], b[i]));    }  }  return QPixmap(img);}// just a convenient method used to get the vertical gradient// that indicates the y-axisQPixmapCurveView::getGradient(int width, int height) const{  QImage img(width, height, 32);  for (int i = 0; i < height; i++) {    for (int j = 0; j < width; j++) {      img.setPixel(j, i, qRgb((this->size - 1)-i, (this->size - 1)-i, (this->size - 1)-i));    }  }  return QPixmap(img);}voidCurveView::setCallBack(ColorCurve::ChangeCB * cb, void * userData){  for (int i = 0; i < this->colormode; i++) {    this->colorcurves[i]->setChangeCallBack(cb, userData);  }}

⌨️ 快捷键说明

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