View3DInventorExamples.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2004 Jürgen Riegel <juergen.riegel@web.de>              *
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 
00024 #include "PreCompiled.h"
00025 
00026 #ifndef _PreComp_
00027 # include <Inventor/nodes/SoMaterial.h>
00028 # include <Inventor/nodes/SoShapeHints.h>
00029 # include <Inventor/SbClip.h>
00030 # include <Inventor/nodes/SoCoordinate3.h>
00031 # include <Inventor/nodes/SoComplexity.h>
00032 # include <Inventor/nodes/SoMaterial.h>
00033 # include <Inventor/nodes/SoTexture3.h>
00034 # include <Inventor/nodes/SoTextureCoordinate3.h>
00035 # include <Inventor/nodes/SoFaceSet.h>
00036 # include <Inventor/nodes/SoLineSet.h>
00037 # include <Inventor/nodes/SoBaseColor.h>
00038 # include <Inventor/draggers/SoTransformerDragger.h>
00039 
00040 # include <float.h>
00041 # include <cstring>
00042 #endif
00043 
00044 #include "../Base/Console.h"
00045 
00046 
00047 #include "View3DInventorExamples.h"
00048 
00049 #include <Inventor/SbPlane.h>
00050 #include <Inventor/Qt/SoQt.h>
00051 #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
00052 #include <Inventor/SoDB.h>
00053 #include <Inventor/actions/SoSearchAction.h>
00054 #include <Inventor/manips/SoPointLightManip.h>
00055 #include <Inventor/nodes/SoSeparator.h>
00056 #include <Inventor/draggers/SoTransformerDragger.h>
00057 #include <Inventor/SbBasic.h>
00058 #include <Inventor/nodes/SoShapeHints.h>
00059 #include <Inventor/nodes/SoSeparator.h>
00060 #include <Inventor/nodes/SoTexture2.h>
00061 #include <Inventor/nodes/SoCube.h>
00062 #include <Inventor/sensors/SoTimerSensor.h>
00063 
00064 
00065 
00066 unsigned char * generateTexture(int w, int h, int d)
00067 {
00068   int val;
00069   float x,y,z;
00070 //  unsigned char pixval;
00071   unsigned char * bitmap = new unsigned char[w*h*d];
00072 
00073   for (int k = 0;k<d;k++) {
00074     z = k*360/d;
00075     for (int j = 0;j<h;j++) {
00076       y = (j-h/2)/2;
00077       for (int i = 0;i<w;i++) {
00078         x = (i-w/2)/2;
00079         val = int(x*x + y*y*sin(2*x*M_PI/w + z*M_PI/180));
00080         val = abs(val%512);
00081         if (val >= 256) val = 511-val;
00082         bitmap[k*w*h + j*h + i] = val;
00083       }
00084     }
00085   }
00086 
00087   
00088   return bitmap;
00089 }
00090 
00091 void doClipping(SbVec3f trans, SbRotation rot)
00092 {
00093   SbMatrix mat;
00094   SbVec3f normal;
00095 
00096   mat.setTransform(trans, rot, SbVec3f(1,1,1));
00097   mat.multDirMatrix(SbVec3f(0, -1, 0), normal);
00098   SbPlane plane(normal, trans);
00099 
00100   const float coords[][3] = {
00101     {-5,-5,-5},
00102     {5,-5,-5},
00103     {5,5,-5},
00104     {-5,5,-5},
00105     {-5,-5,5},
00106     {5,-5,5},
00107     {5,5,5},
00108     {-5,5,5}
00109   };
00110   const int indices[] = {
00111     0,3,2,1,-1,
00112     0,1,5,4,-1,
00113     2,6,5,1,-1,
00114     3,7,6,2,-1,
00115     3,0,4,7,-1,
00116     7,4,5,6,-1
00117   };
00118 
00119   // Clip box against plane
00120 
00121   SbClip clip;
00122   SoMFVec3f * globalVerts = 
00123     (SoMFVec3f *)SoDB::getGlobalField(SbName("globalVerts"));
00124   SoMFVec3f * globalTVerts = 
00125     (SoMFVec3f *)SoDB::getGlobalField(SbName("globalTVerts"));
00126   SoMFInt32 * globalnv = 
00127     (SoMFInt32 *)SoDB::getGlobalField(SbName("globalnv"));
00128   globalVerts->startEditing();
00129   globalVerts->setNum(0);
00130   globalTVerts->startEditing();
00131   globalTVerts->setNum(0);
00132   globalnv->startEditing();
00133   globalnv->setNum(0);
00134   int i;
00135   for (i = 0;i<6*5;i++) {
00136     if (indices[i] == -1) {
00137       clip.clip(plane);
00138       int numVerts = clip.getNumVertices();
00139       if (numVerts > 0) {
00140         for (int j = 0;j<numVerts;j++) {
00141           SbVec3f v;
00142           clip.getVertex(j, v);
00143           globalVerts->set1Value(globalVerts->getNum(), v);
00144           v += SbVec3f(5, 5, 5);
00145           v /= 10.0;
00146           globalTVerts->set1Value(globalTVerts->getNum(), v);
00147         }
00148         globalnv->set1Value(globalnv->getNum(), numVerts);
00149       }
00150       clip.reset();
00151     }
00152     else clip.addVertex(coords[indices[i]]);
00153   }
00154   globalVerts->finishEditing();
00155   globalTVerts->finishEditing();
00156   globalnv->finishEditing();
00157 
00158   // Close hole in clipped box by clipping against all 6 planes
00159   
00160   const SbVec3f planecoords[] = {
00161     SbVec3f(-10,0,-10),
00162     SbVec3f(10,0,-10),
00163     SbVec3f(10,0,10),
00164     SbVec3f(-10,0,10)
00165   };
00166 
00167   
00168   clip.reset();
00169   for (i = 0;i<4;i++) {
00170     SbVec3f v;
00171     mat.multVecMatrix(planecoords[i], v);
00172     clip.addVertex(v);
00173   }
00174   for (i = 0;i<6*5;i+=5) {
00175     SbPlane p(coords[indices[i+2]],
00176               coords[indices[i+1]],
00177               coords[indices[i]]);
00178     clip.clip(p);
00179   }
00180   int numVerts = clip.getNumVertices();
00181   SoMFVec3f * planeVerts = 
00182     (SoMFVec3f *)SoDB::getGlobalField(SbName("planeVerts"));
00183   SoMFVec3f * planeTVerts = 
00184     (SoMFVec3f *)SoDB::getGlobalField(SbName("planeTVerts"));
00185   planeVerts->startEditing();
00186   planeVerts->setNum(0);
00187   planeTVerts->startEditing();
00188   planeTVerts->setNum(0);
00189   for (i = 0;i<numVerts;i++) {
00190     SbVec3f v;
00191     clip.getVertex(i, v);
00192     planeVerts->set1Value(planeVerts->getNum(), v);
00193     v += SbVec3f(5, 5, 5);
00194     v /= 10.0;
00195     planeTVerts->set1Value(planeTVerts->getNum(), v);
00196   }
00197   planeVerts->finishEditing();
00198   planeTVerts->finishEditing();
00199 }
00200 
00201 void draggerCB(void * data, SoDragger * dragger)
00202 {
00203   SoTransformerDragger * drag = (SoTransformerDragger *)dragger;
00204   doClipping(drag->translation.getValue(), drag->rotation.getValue());
00205 }
00206 
00207 void Texture3D(SoSeparator * root)
00208 {
00209 
00210   SoDB::createGlobalField("globalVerts", SoMFVec3f::getClassTypeId());
00211   SoDB::createGlobalField("globalTVerts", SoMFVec3f::getClassTypeId());
00212   SoDB::createGlobalField("globalnv", SoMFInt32::getClassTypeId());
00213   SoDB::createGlobalField("planeVerts", SoMFVec3f::getClassTypeId());
00214   SoDB::createGlobalField("planeTVerts", SoMFVec3f::getClassTypeId());
00215 
00216   doClipping(SbVec3f(0,0,0), SbRotation());
00217 
00218 //  SoSeparator * root = new SoSeparator;
00219 //  root->ref();
00220 
00221   SoComplexity * comp = new SoComplexity;
00222   comp->textureQuality.setValue((float)0.9);
00223   root->addChild(comp);
00224 
00225   SoTexture3 * texture = new SoTexture3;
00226   texture->wrapR.setValue(SoTexture3::CLAMP);
00227   texture->wrapS.setValue(SoTexture3::CLAMP);
00228   texture->wrapT.setValue(SoTexture3::CLAMP);
00229 //    SbString filenames[64];
00230 //    for (int i=0;i<64;i++)
00231 //      filenames[i].sprintf("../../../data/pgmvol/slice%02d.raw.pgm",i);
00232 //    texture->filenames.setValues(0,64,filenames);
00233   unsigned char * img = generateTexture(256,256,256);
00234   texture->images.setValue(SbVec3s(256,256,256), 1, img);
00235   root->addChild(texture);
00236 
00237   SoMaterial * mat = new SoMaterial;
00238   mat->emissiveColor.setValue(1,1,1);
00239   root->addChild(mat);
00240     
00241   SoTransformerDragger * dragger = new SoTransformerDragger;
00242   dragger->scaleFactor.setValue(5,5,5);
00243   dragger->addValueChangedCallback(draggerCB, NULL);
00244   root->addChild(dragger);
00245 
00246   SoCoordinate3 * clippedCoords = new SoCoordinate3;
00247   clippedCoords->point.connectFrom((SoMFVec3f *)
00248                                    SoDB::getGlobalField("globalVerts"));
00249   root->addChild(clippedCoords);
00250   SoTextureCoordinate3 * clippedTCoords = new SoTextureCoordinate3;
00251   clippedTCoords->point.connectFrom((SoMFVec3f *)
00252                                     SoDB::getGlobalField("globalTVerts"));
00253   root->addChild(clippedTCoords);
00254   SoFaceSet * clippedFS = new SoFaceSet;
00255   clippedFS->numVertices.connectFrom((SoMFInt32 *)
00256                                      SoDB::getGlobalField("globalnv"));
00257   root->addChild(clippedFS);
00258 
00259   SoCoordinate3 * planeCoords = new SoCoordinate3;
00260   planeCoords->point.connectFrom((SoMFVec3f *)
00261                                  SoDB::getGlobalField("planeVerts"));
00262   root->addChild(planeCoords);
00263   SoTextureCoordinate3 * planeTCoords = new SoTextureCoordinate3;
00264   planeTCoords->point.connectFrom((SoMFVec3f *)
00265                                   SoDB::getGlobalField("planeTVerts"));
00266   root->addChild(planeTCoords);
00267   SoFaceSet * planeFS = new SoFaceSet;
00268   root->addChild(planeFS);
00269 
00270   /*
00271   SoQtExaminerViewer * renderarea = new SoQtExaminerViewer( window );
00272   renderarea->setSceneGraph( root );
00273   renderarea->setBackgroundColor( SbColor( 0.0f, 0.2f, 0.3f )  );
00274   renderarea->setTitle(argv[0]);
00275   renderarea->setIconTitle(argv[0]);
00276   renderarea->viewAll();
00277   renderarea->show();
00278 
00279   SoQt::show(window);
00280   SoQt::mainLoop();
00281 
00282   delete renderarea;
00283   root->unref();
00284 
00285   return 0;
00286   */
00287 }
00288 
00289 // *************************************************************************
00290 
00291 
00292 static const char scenegraph[] = "#Inventor V2.1 ascii\n"
00293 "Separator {\n"
00294 "   DEF RedLight   PointLight { location -10 -10 10  color 1 0 0 }\n"
00295 "   DEF GreenLight PointLight { location  -5 5 10  color 0 1 0 }\n"
00296 "   DEF BlueLight  PointLight { location  10 10 10  color 0 0 1 }\n"
00297 "   Material { diffuseColor 0.5 0.5 0.5  specularColor 1 1 1 }\n"
00298 "   Array {\n"
00299 "     origin CENTER\n"
00300 "     numElements1 3  separation1 5.5 0 0\n"
00301 "     numElements2 3  separation2 0 5.5 0\n"
00302 "\n"
00303 "     Sphere { radius 3 }\n"
00304 "   }\n"
00305 "}\n";
00306 
00307 void LightManip(SoSeparator * root)
00308 {
00309 
00310   SoInput in;
00311   in.setBuffer((void *)scenegraph, std::strlen(scenegraph));
00312   SoSeparator * _root = SoDB::readAll( &in );
00313   root->addChild(_root);
00314   if ( root == NULL ) exit( 1 ); // Shouldn't happen.
00315   root->ref();
00316 
00317   const char * pointlightnames[3] = { "RedLight", "GreenLight", "BlueLight" };
00318   SoSearchAction sa;
00319 
00320   for (int i = 0; i < 3; i++) {
00321     sa.setName( pointlightnames[i] );
00322     sa.setInterest( SoSearchAction::FIRST );
00323     sa.setSearchingAll( FALSE );
00324     sa.apply( root );
00325     SoPath * path = sa.getPath();
00326     if ( path == NULL) exit( 1 ); // Shouldn't happen.
00327 
00328     SoPointLightManip * manip = new SoPointLightManip;
00329     manip->replaceNode( path );
00330   }
00331 
00332 
00333 } 
00334 
00335 
00336 
00337 
00338 /***********************************************************************************************************/
00339 
00340 
00341 // Global constants
00342 const int texturewidth = 128;
00343 const int textureheight = 128;
00344 
00345 // Global variables
00346 double cr = 0.33;
00347 double ci = 0.43;
00348 
00349 // Global pointer
00350 //unsigned char * bitmap = new unsigned char[texturewidth*textureheight];
00351 unsigned char bitmap[texturewidth*textureheight];
00352 
00353 // Function to generate a julia set
00354 // Parameters:
00355 //  double cr   - real part of the julia set point
00356 //  double ci   - imaginary part of the julia set point
00357 //  float zoon  - lenth of the square to display (zoom*zoom), center (0,0)
00358 //  int width   - width of the bitmap
00359 //  int height  - height of the bitmap
00360 //  int mult    - number to multiply each color by.
00361 //  unsigned char * bmp - pointer to the bitmap
00362 //  int n       - number of itterations 
00363 void
00364 julia(double crr, double cii, float zoom, int width, int height, int mult, 
00365       unsigned char * bmp, int n)
00366 {
00367   double zr, zr_old, zi;
00368   int w;
00369 
00370   for (int y=0; y<height/2; y++)
00371     for (int x=0; x<width; x++) {
00372       zr = ((double)(x)/(double)width)*zoom-zoom/2;
00373       zi = ((double)(y)/(double)height)*zoom-zoom/2;
00374       for (w = 0; (w < n) && (zr*zr+zi*zi)<n; w++) {
00375         zr_old = zr;
00376         zr = zr*zr - zi*zi + crr;
00377         zi = 2*zr_old*zi + cii;
00378       }
00379       bmp[y*width+x] = 255-w*mult;
00380       bmp[((height-y)*width)-(x+1)] = 255-w*mult;
00381     }
00382 }
00383 
00384 // Function that loads a texture from memory, and return a pointer to a
00385 // SoTexture2 node containing this texture..
00386 // Return:
00387 //  SoTexture2 *
00388 SoTexture2 *
00389 texture()
00390 {
00391   SoTexture2 * texture = new SoTexture2;
00392   texture->image.setValue(SbVec2s(texturewidth, textureheight), 1, bitmap);
00393   texture->model = SoTexture2::MODULATE;
00394   texture->blendColor.setValue(1.0, 0.0, 0.0);
00395   return texture;
00396 }
00397 
00398 // This function is called 20 times each second. 
00399 static void
00400 timersensorcallback(void * data, SoSensor *)
00401 {
00402   static SbBool direction = FALSE;
00403 
00404   SoTexture2 * texnode = (SoTexture2*) data;
00405 
00406   if (!direction) {
00407     cr -= 0.0005;
00408     ci += 0.0005;
00409   }
00410   else {
00411     cr += 0.0005;
00412     ci -= 0.0005;
00413   }
00414 
00415   if (ci<0.30)
00416     direction = !direction;
00417   else if (ci>0.83)
00418     direction = !direction;
00419 
00420   SbVec2s size;
00421   int nc;
00422   unsigned char * image = texnode->image.startEditing(size, nc);
00423   // Generate a julia set to use as a texturemap
00424   julia(cr, ci, 2.5, size[0], size[1], 4, image, 64);
00425   texnode->image.finishEditing();
00426 }
00427 
00428 void AnimationTexture(SoSeparator * root)
00429 {
00430 
00431   // Generate a julia set to use as a texturemap
00432   julia(cr, ci, 2.5, texturewidth, textureheight, 4, bitmap, 64);
00433 
00434  
00435   SoTexture2 * texnode = texture();
00436 
00437   // Enable backface culling
00438   SoShapeHints * hints = new SoShapeHints;
00439 
00440   hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE;
00441   hints->shapeType = SoShapeHints::SOLID;
00442 
00443   // Timer sensor
00444   SoTimerSensor * texturetimer = new SoTimerSensor(timersensorcallback, texnode);
00445   texturetimer->setInterval(0.05);
00446   texturetimer->schedule();
00447 
00448   // Scene graph
00449   if ( root == NULL ) exit( 1 ); // Shouldn't happen.
00450   root->ref(); // prevent from being deleted because of the still running timer sensor
00451 //  SoSeparator * root = new SoSeparator;
00452 //  root->ref();
00453 
00454   root->addChild(hints);
00455   root->addChild(texnode);
00456   root->addChild(new SoCube);
00457 
00458  }
00459 

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