source: trunk/source/visualization/OpenInventor/src/SoTrap.cc @ 1340

Last change on this file since 1340 was 1337, checked in by garnier, 14 years ago

tag geant4.9.4 beta 1 + modifs locales

  • Property svn:mime-type set to text/cpp
File size: 14.1 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26//
27//
28// $Id: SoTrap.cc,v 1.8 2006/06/29 21:23:03 gunter Exp $
29// GEANT4 tag $Name: geant4-09-04-beta-01 $
30//
31/*-----------------------------HEPVis----------------------------------------*/
32/*                                                                           */
33/* Node:             SoTrap                                                  */
34/* Description:      Represents the G4Trap Geant Geometry entity             */
35/* Author:           Joe Boudreau Nov 11 1996                                */
36/*                                                                           */
37/*                                                                           */
38/*---------------------------------------------------------------------------*/
39
40#ifdef G4VIS_BUILD_OI_DRIVER
41
42// this :
43#include "HEPVis/nodes/SoTrap.h"
44
45#include <assert.h>
46#include <cmath>
47#include <Inventor/SbBox.h>
48#include <Inventor/actions/SoGLRenderAction.h>
49#include <Inventor/actions/SoAction.h>
50#include <Inventor/fields/SoSFFloat.h>
51#include <Inventor/misc/SoChildList.h>
52#include <Inventor/nodes/SoSeparator.h>
53#include <Inventor/nodes/SoIndexedFaceSet.h>
54#include <Inventor/nodes/SoNormal.h>
55#include <Inventor/nodes/SoCoordinate3.h>
56#include <Inventor/nodes/SoNormalBinding.h>
57#include <Inventor/SoPrimitiveVertex.h>
58#include <Inventor/elements/SoTextureCoordinateElement.h>
59
60#include "HEPVis/SbMath.h"
61
62// This statement is required
63SO_NODE_SOURCE(SoTrap)
64
65// Constructor
66SoTrap::SoTrap() {
67  // This statement is required
68  SO_NODE_CONSTRUCTOR(SoTrap);
69
70  // Data fields are initialized like this:
71  SO_NODE_ADD_FIELD(pDz,                 (1.0));
72  SO_NODE_ADD_FIELD(pTheta,              (0.0));
73  SO_NODE_ADD_FIELD(pPhi,                (0.0));
74  SO_NODE_ADD_FIELD(pDy1,                (1.0));
75  SO_NODE_ADD_FIELD(pDx1,                (1.0));
76  SO_NODE_ADD_FIELD(pDx2,                (1.0));
77  SO_NODE_ADD_FIELD(pDy2,                (1.0));
78  SO_NODE_ADD_FIELD(pDx3,                (1.0));
79  SO_NODE_ADD_FIELD(pDx4,                (1.0));
80  SO_NODE_ADD_FIELD(pAlp1,               (0.0));
81  SO_NODE_ADD_FIELD(pAlp2,               (0.0));
82  SO_NODE_ADD_FIELD(alternateRep,        (NULL));
83  children = new SoChildList(this);
84}
85
86// Destructor
87SoTrap::~SoTrap() {
88 delete children;
89}
90
91
92// initClass
93void SoTrap::initClass(){
94  // This statement is required.
95  SO_NODE_INIT_CLASS(SoTrap,SoShape,"Shape");
96}
97
98
99// generatePrimitives
100void SoTrap::generatePrimitives(SoAction *action) {
101  // This variable is used to store each vertex
102  SoPrimitiveVertex pv;
103
104  // Access the stat from the action
105  SoState *state = action->getState();
106
107  // See if we have to use a texture coordinate function,
108  // rather than generating explicit texture coordinates.
109  SbBool useTexFunction=
110    (SoTextureCoordinateElement::getType(state) ==
111     SoTextureCoordinateElement::FUNCTION);
112
113  // If we need to generate texture coordinates with a function,
114  // we'll need an SoGLTextureCoordinateElement.  Otherwise, we'll
115  // set up the coordinates directly.
116  const SoTextureCoordinateElement *tce = NULL;
117  SbVec4f texCoord;
118  if (useTexFunction) {
119    tce = SoTextureCoordinateElement::getInstance(state);
120  }
121  else {
122    texCoord[2] = 0.0;
123    texCoord[3] = 1.0;
124  }
125  SbVec3f point, normal;
126
127
128  //////////////////////////////////////////
129  //----------------------------------------
130#define GEN_VERTEX(pv,x,y,z,s,t,nx,ny,nz)  \
131  point.setValue(x,y,z);                   \
132  normal.setValue(nx,ny,nz);               \
133  if (useTexFunction) {                    \
134    texCoord=tce->get(point,normal);       \
135  }                                        \
136  else {                                   \
137    texCoord[0]=s;                         \
138    texCoord[1]=t;                         \
139  }                                        \
140  pv.setPoint(point);                      \
141  pv.setNormal(normal);                    \
142  pv.setTextureCoords(texCoord);           \
143  shapeVertex(&pv);
144  //----------------------------------------
145  //////////////////////////////////////////
146
147  const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
148  int indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX,  //z back.
149                           4,5,6,7, SO_END_FACE_INDEX,  //z front.
150                           0,1,5,4, SO_END_FACE_INDEX,  //y up.
151                           1,2,6,5, SO_END_FACE_INDEX,  //x left.
152                           2,3,7,6, SO_END_FACE_INDEX,  //y down.
153                           3,0,4,7, SO_END_FACE_INDEX}; //x right.
154
155  // points for the eight vertices
156  float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
157  float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
158  float Talp1 = FTAN(pAlp1.getValue());
159  float Talp2 = FTAN(pAlp2.getValue());
160
161  float points[NPOINTS][3];
162  points[0][0] =  pDx2.getValue()+pDy1.getValue()*Talp1;
163  points[0][1] =  pDy1.getValue();
164  points[0][2] = -pDz.getValue();
165
166  points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
167  points[1][1] =  pDy1.getValue();
168  points[1][2] = -pDz.getValue();
169
170  points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
171  points[2][1] = -pDy1.getValue();
172  points[2][2] = -pDz.getValue();
173
174  points[3][0] =  pDx1.getValue()-pDy1.getValue()*Talp1;
175  points[3][1] = -pDy1.getValue();
176  points[3][2] = -pDz.getValue();
177
178  points[4][0] =  pDx4.getValue()+pDy2.getValue()*Talp2;
179  points[4][1] =  pDy2.getValue();
180  points[4][2] =  pDz.getValue();
181
182  points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
183  points[5][1] =  pDy2.getValue();
184  points[5][2] =  pDz.getValue();
185
186  points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
187  points[6][1] = -pDy2.getValue();
188  points[6][2] =  pDz.getValue();
189
190  points[7][0] =  pDx3.getValue()-pDy2.getValue()*Talp2;
191  points[7][1] = -pDy2.getValue();
192  points[7][2] =  pDz.getValue();
193
194  int i;
195  for (i=0;i<4;i++) {
196    points[i][0] -= pDz.getValue()*TthetaCphi;
197    points[i][1] -= pDz.getValue()*TthetaSphi;
198  }
199  for (i=4;i<8;i++) {
200    points[i][0] += pDz.getValue()*TthetaCphi;
201    points[i][1] += pDz.getValue()*TthetaSphi;
202  }
203
204  SbVec3f normals[NFACES];
205  int nf;
206  for (nf=0;nf<NFACES;nf++) {
207    int j0 = indices[5*nf + 0];
208    int j1 = indices[5*nf + 1];
209    int j2 = indices[5*nf + 2];
210    SbVec3f p0(points[j0][0],points[j0][1],points[j0][2]);
211    SbVec3f p1(points[j1][0],points[j1][1],points[j1][2]);
212    SbVec3f p2(points[j2][0],points[j2][1],points[j2][2]);
213    normals[nf] = (p1-p0).cross(p2-p0);
214    normals[nf].normalize();
215  }
216
217  float x,y,z;
218  int   index;
219  for (nf=0;nf<NFACES;nf++) {
220    beginShape(action,TRIANGLE_FAN);
221    index = indices[nf * 5];   
222    x = points[index][0];
223    y = points[index][1];
224    z = points[index][2];
225    GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
226    index = indices[nf * 5 + 1];   
227    x = points[index][0];
228    y = points[index][1];
229    z = points[index][2];
230    GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
231    index = indices[nf * 5 + 2];   
232    x = points[index][0];
233    y = points[index][1];
234    z = points[index][2];
235    GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
236    index = indices[nf * 5 + 3];   
237    x = points[index][0];
238    y = points[index][1];
239    z = points[index][2];
240    GEN_VERTEX(pv,x,y,z,0.0,0.0,normals[nf][0],normals[nf][1],normals[nf][2]);   
241    endShape();
242  }
243}
244
245// getChildren
246SoChildList *SoTrap::getChildren() const {
247  return children;
248}
249
250
251// computeBBox
252void SoTrap::computeBBox(SoAction *, SbBox3f &box, SbVec3f &center ){
253  float pDx= pDx1.getValue(),pDy=pDy1.getValue();
254 
255  if (pDx2.getValue() > pDx) pDx = pDx2.getValue();
256  if (pDx3.getValue() > pDx) pDx = pDx3.getValue();
257  if (pDx4.getValue() > pDx) pDx = pDx4.getValue();
258  if (pDy2.getValue() > pDy) pDy = pDy2.getValue();
259  float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
260  float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
261  float Xalp = FFABS(std::tan(pAlp1.getValue())*pDy1.getValue());
262  float Xalp2 = FFABS(std::tan(pAlp2.getValue())*pDy2.getValue());
263  if (Xalp< Xalp2) Xalp=Xalp2;
264  pDx += FFABS(TthetaCphi*pDz.getValue());
265  pDx += Xalp;
266  pDy += FFABS(TthetaSphi*pDz.getValue()); 
267
268
269  center.setValue(0,0,0);
270  box.setBounds(SbVec3f(-pDx,-pDy,-pDz.getValue()),
271          SbVec3f( pDx, pDy, pDz.getValue()));
272}
273
274
275
276
277// updateChildren
278void SoTrap::updateChildren() {
279
280
281  // Redraw the G4Trap....
282
283  assert(children->getLength()==1);
284  SoSeparator       *sep                = (SoSeparator *)  ( *children)[0];
285  SoCoordinate3     *theCoordinates     = (SoCoordinate3 *)      ( sep->getChild(0));
286  SoNormal          *theNormals         = (SoNormal *)           ( sep->getChild(1));
287  SoNormalBinding   *theNormalBinding   = (SoNormalBinding *)    ( sep->getChild(2));
288  SoIndexedFaceSet  *theFaceSet         = (SoIndexedFaceSet *)   ( sep->getChild(3));
289
290  const int NPOINTS=8, NFACES=6, NINDICES = NFACES*5;
291  float points[NPOINTS][3];
292  // Indices for the eight faces
293#ifdef INVENTOR2_0
294  static long 
295#else
296  static int32_t
297#endif
298  indices[NINDICES] = {3,2,1,0, SO_END_FACE_INDEX, // bottom
299                     4,5,6,7, SO_END_FACE_INDEX, // top
300                     0,1,5,4, SO_END_FACE_INDEX,
301                     1,2,6,5, SO_END_FACE_INDEX,
302                     2,3,7,6, SO_END_FACE_INDEX,
303                     3,0,4,7, SO_END_FACE_INDEX};
304
305 
306  // points for the eight vertices
307  float TthetaCphi = FTAN(pTheta.getValue())*FCOS(pPhi.getValue());
308  float TthetaSphi = FTAN(pTheta.getValue())*FSIN(pPhi.getValue());
309  float Talp1 = FTAN(pAlp1.getValue());
310  float Talp2 = FTAN(pAlp2.getValue());
311
312  points[0][0] =  pDx2.getValue()+pDy1.getValue()*Talp1;
313  points[0][1] =  pDy1.getValue();
314  points[0][2] = -pDz.getValue();
315
316  points[1][0] = -pDx2.getValue()+pDy1.getValue()*Talp1;
317  points[1][1] =  pDy1.getValue();
318  points[1][2] = -pDz.getValue();
319
320  points[2][0] = -pDx1.getValue()-pDy1.getValue()*Talp1;
321  points[2][1] = -pDy1.getValue();
322  points[2][2] = -pDz.getValue();
323
324  points[3][0] =  pDx1.getValue()-pDy1.getValue()*Talp1;
325  points[3][1] = -pDy1.getValue();
326  points[3][2] = -pDz.getValue();
327
328  points[4][0] =  pDx4.getValue()+pDy2.getValue()*Talp2;
329  points[4][1] =  pDy2.getValue();
330  points[4][2] =  pDz.getValue();
331
332  points[5][0] = -pDx4.getValue()+pDy2.getValue()*Talp2;
333  points[5][1] =  pDy2.getValue();
334  points[5][2] =  pDz.getValue();
335
336  points[6][0] = -pDx3.getValue()-pDy2.getValue()*Talp2;
337  points[6][1] = -pDy2.getValue();
338  points[6][2] =  pDz.getValue();
339
340  points[7][0] =  pDx3.getValue()-pDy2.getValue()*Talp2;
341  points[7][1] = -pDy2.getValue();
342  points[7][2] =  pDz.getValue();
343
344  int i;
345  for (i=0;i<4;i++) {
346    points[i][0] -= pDz.getValue()*TthetaCphi;
347    points[i][1] -= pDz.getValue()*TthetaSphi;
348  }
349  for (i=4;i<8;i++) {
350    points[i][0] += pDz.getValue()*TthetaCphi;
351    points[i][1] += pDz.getValue()*TthetaSphi;
352  }
353
354  for (int np=0;np<NPOINTS;np++) theCoordinates->point.set1Value(np,points[np][0],points[np][1],points[np][2]);
355  theFaceSet->coordIndex.setValues(0,NINDICES,indices);
356  theNormals->vector.deleteValues(0);
357  theNormals->vector.insertSpace(0,6);
358  for (int n=0;n<6;n++) {
359    int i0 = 5*n+0,i1=5*n+1,i2=5*n+2;
360    int j0 = theFaceSet->coordIndex[i0];
361    int j1 = theFaceSet->coordIndex[i1];
362    int j2 = theFaceSet->coordIndex[i2];
363    SbVec3f p0= theCoordinates->point[j0];
364    SbVec3f p1= theCoordinates->point[j1];
365    SbVec3f p2= theCoordinates->point[j2];
366    SbVec3f normal = (p1-p0).cross(p2-p0);
367    normal.normalize();
368    theNormals->vector.set1Value(n,normal);
369  }
370  theNormalBinding->value=SoNormalBinding::PER_FACE;
371}
372
373// generateChildren
374void SoTrap::generateChildren() {
375
376  // This routines creates one SoSeparator, one SoCoordinate3, and
377  // one SoLineSet, and puts it in the child list.  This is done only
378  // once, whereas redrawing the position of the coordinates occurs each
379  // time an update is necessary, in the updateChildren routine.
380
381  assert(children->getLength() ==0);
382  SoSeparator      *sep              = new SoSeparator();
383  SoCoordinate3    *theCoordinates   = new SoCoordinate3();
384  SoNormal         *theNormals       = new SoNormal();
385  SoNormalBinding  *theNormalBinding = new SoNormalBinding();
386  SoIndexedFaceSet *theFaceSet       = new SoIndexedFaceSet();
387  //
388  // This line costs some in render quality! but gives speed.
389  //
390  sep->addChild(theCoordinates);
391  sep->addChild(theNormals);
392  sep->addChild(theNormalBinding);
393  sep->addChild(theFaceSet);
394  children->append(sep);
395}
396
397// generateAlternateRep
398void SoTrap::generateAlternateRep() {
399
400  // This routine sets the alternate representation to the child
401  // list of this mode. 
402
403  if (children->getLength() == 0) generateChildren();
404  updateChildren();
405  alternateRep.setValue((SoSeparator *)  ( *children)[0]);
406}
407
408// clearAlternateRep
409void SoTrap::clearAlternateRep() {
410  alternateRep.setValue(NULL);
411}
412
413#endif
Note: See TracBrowser for help on using the repository browser.