SoBox.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 //
00028 // $Id$
00029 //
00030 /*----------------------------HEPVis----------------------------------------*/
00031 /*                                                                          */
00032 /* Node:             SoBox                                                  */
00033 /* Description:      Represents the G4Box Geant Geometry entity             */
00034 /* Author:           Joe Boudreau Nov 11 1996                               */
00035 /*                                                                          */
00036 /*--------------------------------------------------------------------------*/
00037 
00038 #ifdef G4VIS_BUILD_OI_DRIVER
00039 
00040 // this :
00041 #include "HEPVis/nodes/SoBox.h"
00042 
00043 #include <assert.h>
00044 #include <cmath>
00045 
00046 #include <Inventor/SbBox.h>
00047 #include <Inventor/fields/SoSFFloat.h>
00048 #include <Inventor/misc/SoChildList.h>
00049 #include <Inventor/nodes/SoSeparator.h>
00050 #include <Inventor/nodes/SoCube.h>
00051 #include <Inventor/nodes/SoScale.h>
00052 #include <Inventor/actions/SoAction.h>
00053 #include <Inventor/nodes/SoIndexedFaceSet.h>
00054 #include <Inventor/SoPrimitiveVertex.h>
00055 #include <Inventor/elements/SoTextureCoordinateElement.h>
00056 
00057 // This statement is required
00058 SO_NODE_SOURCE(SoBox)
00059 
00060 // Constructor
00061 SoBox::SoBox() {
00062   // This statement is required
00063   SO_NODE_CONSTRUCTOR(SoBox);
00064 
00065   // Data fields are initialized like this:
00066   SO_NODE_ADD_FIELD(fDx,                (1.0));
00067   SO_NODE_ADD_FIELD(fDy,                (1.0));
00068   SO_NODE_ADD_FIELD(fDz,                (1.0));
00069   SO_NODE_ADD_FIELD(alternateRep,       (NULL));
00070   children = new SoChildList(this);
00071 }
00072 
00073 // Destructor
00074 SoBox::~SoBox() {
00075  delete children;
00076 }
00077 
00078 
00079 // initClass
00080 void SoBox::initClass(){
00081   // This statement is required.
00082   SO_NODE_INIT_CLASS(SoBox,SoShape,"Shape");
00083 }
00084 
00085 
00086 // generatePrimitives
00087 void SoBox::generatePrimitives(SoAction *action) {
00088   // This variable is used to store each vertex
00089   SoPrimitiveVertex pv;
00090 
00091   // Access the stat from the action
00092   SoState *state = action->getState();
00093 
00094   // See if we have to use a texture coordinate function,
00095   // rather than generating explicit texture coordinates.
00096   SbBool useTexFunction=
00097     (SoTextureCoordinateElement::getType(state) == 
00098      SoTextureCoordinateElement::FUNCTION);
00099 
00100   // If we need to generate texture coordinates with a function,
00101   // we'll need an SoGLTextureCoordinateElement.  Otherwise, we'll
00102   // set up the coordinates directly.
00103   const SoTextureCoordinateElement *tce = NULL;
00104   SbVec4f texCoord;
00105   if (useTexFunction) {
00106     tce = SoTextureCoordinateElement::getInstance(state);
00107   }
00108   else {
00109     texCoord[2] = 0.0;
00110     texCoord[3] = 1.0;
00111   }
00112   SbVec3f point, normal;
00113 
00114 
00116   //----------------------------------------
00117 #define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)  \
00118   point.setValue(x,y,z);                   \
00119   normal.setValue(nx,ny,nz);               \
00120   if (useTexFunction) {                    \
00121     texCoord=tce->get(point,normal);       \
00122   }                                        \
00123   else {                                   \
00124     texCoord[0]=s;                         \
00125     texCoord[1]=t;                         \
00126   }                                        \
00127   pv.setPoint(point);                      \
00128   pv.setNormal(normal);                    \
00129   pv.setTextureCoords(texCoord);           \
00130   shapeVertex(&pv);
00131   //----------------------------------------
00133 
00134   const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
00135   int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,  //z back.
00136                            4,5,6,7, SO_END_FACE_INDEX,  //z front.
00137                            0,1,5,4, SO_END_FACE_INDEX,  //y up.
00138                            1,2,6,5, SO_END_FACE_INDEX,  //x left.
00139                            2,3,7,6, SO_END_FACE_INDEX,  //y down.
00140                            3,0,4,7, SO_END_FACE_INDEX}; //x right.
00141 
00142   
00143   // points for the eight vertices
00144   float points[NPOINTS][3];
00145   points[0][0] =  fDx.getValue(); 
00146   points[0][1] =  fDy.getValue(); 
00147   points[0][2] = -fDz.getValue();
00148 
00149   points[1][0] = -fDx.getValue();
00150   points[1][1] =  fDy.getValue();
00151   points[1][2] = -fDz.getValue();
00152 
00153   points[2][0] = -fDx.getValue(); 
00154   points[2][1] = -fDy.getValue(); 
00155   points[2][2] = -fDz.getValue();
00156 
00157   points[3][0] =  fDx.getValue(); 
00158   points[3][1] = -fDy.getValue(); 
00159   points[3][2] = -fDz.getValue();
00160 
00161   points[4][0] =  fDx.getValue(); 
00162   points[4][1] =  fDy.getValue(); 
00163   points[4][2] =  fDz.getValue();
00164 
00165   points[5][0] = -fDx.getValue(); 
00166   points[5][1] =  fDy.getValue(); 
00167   points[5][2] =  fDz.getValue();
00168 
00169   points[6][0] = -fDx.getValue(); 
00170   points[6][1] = -fDy.getValue(); 
00171   points[6][2] =  fDz.getValue();
00172 
00173   points[7][0] =  fDx.getValue(); 
00174   points[7][1] = -fDy.getValue(); 
00175   points[7][2] =  fDz.getValue();
00176 
00177   float normals[NFACES][3];
00178   //z back.
00179   normals[0][0] =  0  ; normals[0][1] =    0; normals [0][2] =  -1;    
00180   //z front.
00181   normals[1][0] =  0  ; normals[1][1] =    0; normals [1][2] =   1;    
00182   //y up.
00183   normals[2][0] =  0  ; normals[2][1] =    1; normals [2][2] =   0;    
00184   //x left.
00185   normals[3][0] = -1  ; normals[3][1] =    0; normals [3][2] =   0;    
00186   //y down.
00187   normals[4][0] =  0  ; normals[4][1] =   -1; normals [4][2] =   0;    
00188   //x right.
00189   normals[5][0] =  1  ; normals[5][1] =    0; normals [5][2] =   0;    
00190 
00191   float x,y,z;
00192   int   index;
00193   for (int nf=0;nf<NFACES;nf++) {
00194     beginShape(action,TRIANGLE_FAN);
00195     index = indices[nf * 5];   
00196     x = points[index][0];
00197     y = points[index][1];
00198     z = points[index][2];
00199     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00200     index = indices[nf * 5 + 1];   
00201     x = points[index][0];
00202     y = points[index][1];
00203     z = points[index][2];
00204     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00205     index = indices[nf * 5 + 2];   
00206     x = points[index][0];
00207     y = points[index][1];
00208     z = points[index][2];
00209     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00210     index = indices[nf * 5 + 3];   
00211     x = points[index][0];
00212     y = points[index][1];
00213     z = points[index][2];
00214     GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
00215     endShape();
00216   }
00217 }
00218 
00219 // getChildren
00220 SoChildList *SoBox::getChildren() const {
00221   return children;
00222 }
00223 
00224 
00225 // computeBBox
00226 void SoBox::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
00227   SbVec3f vmin(-fDx.getValue(),-fDy.getValue(),-fDz.getValue()), 
00228           vmax( fDx.getValue(), fDy.getValue(), fDz.getValue());
00229   center.setValue(0,0,0);
00230   box.setBounds(vmin,vmax);
00231 }
00232 
00233 
00234 
00235 
00236 // updateChildren
00237 void SoBox::updateChildren() {
00238 
00239 
00240   // Redraw the G4Box....
00241 
00242   assert(children->getLength()==1);
00243   SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
00244   SoScale           *scale              = (SoScale *)( sep->getChild(0));
00245   //SoCube            *cube               = (SoCube  *)( sep->getChild(1));
00246   scale->scaleFactor.setValue(fDx.getValue(), fDy.getValue(), fDz.getValue());
00247 }
00248 
00249 // generateChildren
00250 void SoBox::generateChildren() {
00251 
00252   // A box consists of a set of scale factors and a 
00253   // cube.
00254 
00255   assert(children->getLength() ==0);
00256   SoSeparator      *sep              = new SoSeparator(); 
00257   SoScale          *scale            = new SoScale();
00258   SoCube           *cube             = new SoCube();
00259 
00260   sep->addChild(scale);
00261   sep->addChild(cube);
00262   children->append(sep);
00263 }
00264 
00265 // generateAlternateRep
00266 void SoBox::generateAlternateRep() {
00267 
00268   // This routine sets the alternate representation to the child
00269   // list of this mode.  
00270 
00271   if (children->getLength() == 0) generateChildren();
00272   updateChildren();
00273   alternateRep.setValue((SoSeparator *)  ( *children)[0]);
00274 }
00275 
00276 // clearAlternateRep
00277 void SoBox::clearAlternateRep() {
00278   alternateRep.setValue(NULL);
00279 }
00280 
00281 #endif

Generated on Mon May 27 17:50:34 2013 for Geant4 by  doxygen 1.4.7