SoDatumLabel.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2011                                                    *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 #include "PreCompiled.h"
00024 
00025 #ifndef _PreComp_
00026 # ifdef FC_OS_WIN32
00027 # include <windows.h>
00028 # undef min
00029 # undef max
00030 # endif
00031 # ifdef FC_OS_MACOSX
00032 # include <OpenGL/gl.h>
00033 # else
00034 # include <GL/gl.h>
00035 # endif
00036 # include <cfloat>
00037 # include <algorithm>
00038 # include <QFontMetrics>
00039 # include <QGLWidget>
00040 # include <QPainter>
00041 # include <QPen>
00042 # include <Inventor/SoPrimitiveVertex.h>
00043 # include <Inventor/actions/SoGLRenderAction.h>
00044 # include <Inventor/misc/SoState.h>
00045 # include <math.h>
00046 #endif
00047 
00048 #include <Inventor/elements/SoFontNameElement.h>
00049 #include <Inventor/elements/SoFontSizeElement.h>
00050 #include <Inventor/elements/SoModelMatrixElement.h>
00051 #include <Inventor/elements/SoProjectionMatrixElement.h>
00052 #include <Inventor/elements/SoViewingMatrixElement.h>
00053 #include <Inventor/elements/SoViewVolumeElement.h>
00054 #include <Inventor/elements/SoViewportRegionElement.h>
00055 
00056 #include "SoDatumLabel.h"
00057 #include <Gui/BitmapFactory.h>
00058 
00059 using namespace SketcherGui;
00060 
00061 // ------------------------------------------------------
00062 
00063 SO_NODE_SOURCE(SoDatumLabel);
00064 
00065 void SoDatumLabel::initClass()
00066 {
00067     SO_NODE_INIT_CLASS(SoDatumLabel, SoShape, "Shape");
00068 }
00069 
00070 
00071 SoDatumLabel::SoDatumLabel()
00072 {
00073     SO_NODE_CONSTRUCTOR(SoDatumLabel);
00074     SO_NODE_ADD_FIELD(string, (""));
00075     SO_NODE_ADD_FIELD(textColor, (SbVec3f(1.0f,1.0f,1.0f)));
00076     SO_NODE_ADD_FIELD(name, ("Helvetica"));
00077     SO_NODE_ADD_FIELD(size, (12));
00078 
00079     this->bbx = 0;
00080     this->bby = 0;
00081 }
00082 
00083 void SoDatumLabel::drawImage()
00084 {
00085     const SbString* s = string.getValues(0);
00086     int num = string.getNum();
00087     if (num == 0) {
00088         this->image = SoSFImage();
00089         return;
00090     }
00091 
00092     QFont font(QString::fromAscii(name.getValue()), size.getValue());
00093     QFontMetrics fm(font);
00094     QString str = QString::fromUtf8(s[0].getString());
00095     int w = fm.width(str);
00096     int h = fm.height();
00097 
00098     // No Valid text
00099     if (!w) {
00100         this->image = SoSFImage();
00101         return;
00102     }
00103 
00104     const SbColor& t = textColor.getValue();
00105     QColor front;
00106     front.setRgbF(t[0],t[1], t[2]);
00107 
00108     QImage image(w, h,QImage::Format_ARGB32_Premultiplied);
00109     image.fill(0x00000000);
00110     
00111     QPainter painter(&image);
00112     painter.setRenderHint(QPainter::Antialiasing);
00113 
00114     painter.setPen(front);
00115     painter.setFont(font);
00116     painter.drawText(0,0,w,h, Qt::AlignLeft , str);
00117     painter.end();
00118 
00119     SoSFImage sfimage;
00120     Gui::BitmapFactory().convert(image, sfimage);
00121     this->image = sfimage;
00122 }
00123 
00124 void SoDatumLabel::computeBBox(SoAction *action, SbBox3f &box, SbVec3f &center)
00125 {
00126     SbVec2s size;
00127     int nc;
00128 
00129     const unsigned char * dataptr = this->image.getValue(size, nc);
00130     if (dataptr == NULL) {
00131         box.setBounds(SbVec3f(0,0,0), SbVec3f(0,0,0));
00132         center.setValue(0.0f,0.0f,0.0f);
00133         return;
00134     }
00135 
00136     float srcw = size[0];
00137     float srch = size[1];
00138 
00139     float height, width;
00140 
00141     if(action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
00142          // Update using the GL state
00143         SoState *state =  action->getState();
00144         float srcw = size[0];
00145         float srch = size[1];
00146 
00147         const SbViewVolume & vv = SoViewVolumeElement::get(state);
00148         float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
00149 
00150         float aspectRatio =  (float) srcw / (float) srch;
00151         float height = scale / (float) srch;
00152         float width  = aspectRatio * (float) height;
00153 
00154         // Update stored values
00155         this->bbx = width;
00156         this->bby = height;
00157     } else {
00158         // Update Primitives using stored dimensions
00159         width = this->bbx;
00160         height = this->bby;
00161     }
00162 
00163     SbVec3f min (-width / 2, -height / 2, 0.f);
00164     SbVec3f max (width  / 2, height  / 2, 0.f);
00165     box.setBounds(min, max);
00166     center.setValue(0.f,0.f,0.f);
00167 }
00168 
00169 void SoDatumLabel::generatePrimitives(SoAction * action)
00170 {
00171     // Get the size
00172     SbVec2s size;
00173     int nc;
00174 
00175     const unsigned char * dataptr = this->image.getValue(size, nc);
00176     if (dataptr == NULL)
00177         return;
00178     
00179     float width, height;
00180 
00181     if (action->getTypeId() == SoGLRenderAction::getClassTypeId()) {
00182          // Update using the GL state
00183         SoState *state =  action->getState();
00184         float srcw = size[0];
00185         float srch = size[1];
00186 
00187         const SbViewVolume & vv = SoViewVolumeElement::get(state);
00188         float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.5f);
00189 
00190         float aspectRatio =  (float) srcw / (float) srch;
00191         float height = scale / (float) srch;
00192         float width  = aspectRatio * (float) height;
00193 
00194         // Update stored dimensions
00195         this->bbx = width;
00196         this->bby = height;
00197     } else {
00198         // Update Primitives using stored dimensions
00199         width = this->bbx;
00200         height = this->bby;
00201     }
00202 
00203     SoPrimitiveVertex pv;
00204 
00205     beginShape(action, QUADS);
00206 
00207     pv.setNormal( SbVec3f(0.f, 0.f, 1.f) );
00208 
00209     // Set coordinates
00210     pv.setPoint( SbVec3f(-width / 2, height / 2, 0.f) );
00211     shapeVertex(&pv);
00212 
00213     pv.setPoint( SbVec3f(-width / 2, -height / 2, 0.f) );
00214     shapeVertex(&pv);
00215 
00216     pv.setPoint( SbVec3f(width / 2, -height / 2, 0.f) );
00217     shapeVertex(&pv);
00218     
00219     pv.setPoint( SbVec3f(width / 2, height / 2, 0.f) );
00220     shapeVertex(&pv);
00221 
00222     endShape();
00223 }
00224 
00225 void SoDatumLabel::GLRender(SoGLRenderAction * action)
00226 {
00227     SoState *state = action->getState();
00228     if (!shouldGLRender(action))
00229         return;
00230     if (action->handleTransparency(true))
00231       return;
00232     drawImage();
00233 
00234     SbVec2s size;
00235     int nc;
00236     const unsigned char * dataptr = this->image.getValue(size, nc);
00237     if (dataptr == NULL) return; // no image
00238 
00239     int srcw = size[0];
00240     int srch = size[1];
00241 
00242     state->push();
00243 
00244     glPixelStorei(GL_UNPACK_ROW_LENGTH, srcw);
00245     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00246 
00247     glPushAttrib(GL_ENABLE_BIT | GL_PIXEL_MODE_BIT | GL_COLOR_BUFFER_BIT);
00248     glDisable(GL_LIGHTING);
00249     glEnable(GL_DEPTH_TEST);
00250     glEnable(GL_TEXTURE_2D); // Enable Textures
00251     glEnable(GL_BLEND); 
00252     // Copy the text bitmap into memory and bind
00253     GLuint myTexture;
00254     // generate a texture
00255     glGenTextures(1, &myTexture);
00256 
00257     glBindTexture(GL_TEXTURE_2D, myTexture);
00258 
00259     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00260     glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00261 
00262     glTexImage2D(GL_TEXTURE_2D, 0, nc, srcw, srch, 0, GL_RGBA, GL_UNSIGNED_BYTE,(const GLvoid*)  dataptr);
00263 
00264     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00265     // Create the quad to hold texture
00266     const SbViewVolume & vv = SoViewVolumeElement::get(state);
00267     float scale = vv.getWorldToScreenScale(SbVec3f(0.f,0.f,0.f), 0.4f);
00268                     
00269     float aspectRatio =  (float) srcw / (float) srch;
00270     float height = scale / (float) srch;
00271     float width  = aspectRatio * (float) height;
00272 
00273     this->bbx = width;
00274     this->bby = height;
00275     glBegin(GL_QUADS);
00276     glColor3f(1.f, 1.f, 1.f);
00277     glTexCoord2f(0.f, 1.f); glVertex2f(-width/ 2, height / 2);
00278     glTexCoord2f(0.f, 0.f); glVertex2f(-width / 2,-height / 2);
00279     glTexCoord2f(1.f, 0.f); glVertex2f( width/ 2,-height / 2);
00280     glTexCoord2f(1.f, 1.f); glVertex2f( width / 2, height / 2);
00281 
00282     glEnd();
00283 
00284     // Reset the Mode
00285     glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
00286     glPopAttrib();
00287     state->pop();
00288 }

Generated on Wed Nov 23 19:00:39 2011 for FreeCAD by  doxygen 1.6.1