source: trunk/source/visualization/OpenGL/src/G4OpenGLSceneHandler.cc @ 1117

Last change on this file since 1117 was 1116, checked in by garnier, 15 years ago

bug fix

  • Property svn:mime-type set to text/cpp
File size: 29.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// $Id: G4OpenGLSceneHandler.cc,v 1.55 2009/03/03 14:51:29 lgarnier Exp $
28// GEANT4 tag $Name:  $
29//
30//
31// Andrew Walkden  27th March 1996
32// OpenGL stored scene - creates OpenGL display lists.
33// OpenGL immediate scene - draws immediately to buffer
34//                           (saving space on server).
35
36#ifdef G4VIS_BUILD_OPENGL_DRIVER
37
38// Included here - problems with HP compiler if not before other includes?
39#include "G4NURBS.hh"
40
41// Here follows a special for Mesa, the OpenGL emulator.  Does not affect
42// other OpenGL's, as far as I'm aware.   John Allison 18/9/96.
43#define CENTERLINE_CLPP  /* CenterLine C++ workaround: */
44// Also seems to be required for HP's CC and AIX xlC, at least.
45
46
47// FIXME : L.Garnier 22 Sept 09
48// This include should be the first, because we should include
49// qobject.h first. I don't know why, but on macOSX 10.5.8, if
50// we do not, it says :
51// /Library/Frameworks/QtCore.framework/Headers/qglobal.h:1895: error: redefinition of ‘class QTypeInfo<char>’
52// /Library/Frameworks/QtCore.framework/Headers/qglobal.h:1894: error: previous definition of ‘class QTypeInfo<char>’
53
54#include <qobject.h>
55#include "G4OpenGLQtViewer.hh"
56#include "G4OpenGLSceneHandler.hh"
57#include "G4OpenGLViewer.hh"
58#include "G4OpenGLFontBaseStore.hh"
59#include "G4OpenGLTransform3D.hh"
60#include "G4Point3D.hh"
61#include "G4Normal3D.hh"
62#include "G4Transform3D.hh"
63#include "G4Polyline.hh"
64#include "G4Polymarker.hh"
65#include "G4Text.hh"
66#include "G4Circle.hh"
67#include "G4Square.hh"
68#include "G4VMarker.hh"
69#include "G4Polyhedron.hh"
70#include "G4VisAttributes.hh"
71#include "G4PhysicalVolumeModel.hh"
72#include "G4VPhysicalVolume.hh"
73#include "G4LogicalVolume.hh"
74#include "G4VSolid.hh"
75#include "G4Scene.hh"
76#include "G4VisExtent.hh"
77#include "G4AttHolder.hh"
78
79G4OpenGLSceneHandler::G4OpenGLSceneHandler (G4VGraphicsSystem& system,
80                              G4int id,
81                              const G4String& name):
82  G4VSceneHandler (system, id, name),
83  fPickName(0),
84  fProcessing2D (false),
85  fProcessingPolymarker(false)
86{
87#ifdef G4DEBUG_VIS_OGL
88  printf("INIT G4OpenGLSceneHandler (after G4OpenGLSceneHandler G4VSceneHandler (system, id, name)\n");
89#endif
90}
91
92G4OpenGLSceneHandler::~G4OpenGLSceneHandler ()
93{
94  ClearStore ();
95}
96
97const GLubyte G4OpenGLSceneHandler::fStippleMaskHashed [128] = {
98  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
99  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
100  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
101  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
102  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
103  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
104  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
105  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
106  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
107  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
108  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
109  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
110  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
111  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
112  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
113  0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55
114};
115
116void G4OpenGLSceneHandler::ClearAndDestroyAtts()
117{
118  std::map<GLuint, G4AttHolder*>::iterator i;
119  for (i = fPickMap.begin(); i != fPickMap.end(); ++i) delete i->second;
120  fPickMap.clear();
121}
122
123void G4OpenGLSceneHandler::PreAddSolid
124(const G4Transform3D& objectTransformation,
125 const G4VisAttributes& visAttribs)
126{
127  G4VSceneHandler::PreAddSolid (objectTransformation, visAttribs);
128}
129
130void G4OpenGLSceneHandler::BeginPrimitives
131(const G4Transform3D& objectTransformation)
132{
133  G4VSceneHandler::BeginPrimitives (objectTransformation);
134}
135
136void G4OpenGLSceneHandler::EndPrimitives ()
137{
138  G4VSceneHandler::EndPrimitives ();
139}
140
141void G4OpenGLSceneHandler::BeginPrimitives2D
142(const G4Transform3D& objectTransformation)
143{
144  G4VSceneHandler::BeginPrimitives2D (objectTransformation);
145  fProcessing2D = true;
146}
147
148void G4OpenGLSceneHandler::EndPrimitives2D ()
149{
150  fProcessing2D = false;
151  G4VSceneHandler::EndPrimitives2D ();
152}
153
154const G4Polyhedron* G4OpenGLSceneHandler::CreateSectionPolyhedron ()
155{
156  // Clipping done in G4OpenGLViewer::SetView.
157  return 0;
158
159  // But...OpenGL no longer seems to reconstruct clipped edges, so,
160  // when the BooleanProcessor is up to it, abandon this and use
161  // generic clipping in G4VSceneHandler::CreateSectionPolyhedron...
162  // return G4VSceneHandler::CreateSectionPolyhedron();
163}
164
165const G4Polyhedron* G4OpenGLSceneHandler::CreateCutawayPolyhedron ()
166{
167  // Cutaway done in G4OpenGLViewer::SetView.
168  return 0;
169
170  // But...if not, when the BooleanProcessor is up to it...
171  // return G4VSceneHandler::CreateCutawayPolyhedron();
172}
173
174void G4OpenGLSceneHandler::AddPrimitive (const G4Polyline& line)
175{
176  G4int nPoints = line.size ();
177  if (nPoints <= 0) return;
178
179  // Loads G4Atts for picking...
180  if (fpViewer->GetViewParameters().IsPicking()) {
181    G4AttHolder* holder = new G4AttHolder;
182    LoadAtts(line, holder);
183    fPickMap[fPickName] = holder;
184  }
185
186  // Note: colour treated in sub-class.
187
188  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
189    glDisable (GL_DEPTH_TEST);
190  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
191
192  glDisable (GL_LIGHTING);
193
194  // Get vis attributes - pick up defaults if none.
195  const G4VisAttributes* pVA =
196    fpViewer -> GetApplicableVisAttributes (line.GetVisAttributes ());
197
198  G4double lineWidth = GetLineWidth(pVA);
199  glLineWidth(lineWidth);
200
201  glBegin (GL_LINE_STRIP);
202  for (G4int iPoint = 0; iPoint < nPoints; iPoint++) {
203  G4double x, y, z;
204    x = line[iPoint].x();
205    y = line[iPoint].y();
206    z = line[iPoint].z();
207    glVertex3d (x, y, z);
208  }
209  glEnd ();
210}
211
212void G4OpenGLSceneHandler::AddPrimitive (const G4Polymarker& polymarker)
213{
214  G4int nPoints = polymarker.size ();
215  if (nPoints <= 0) return;
216
217  fProcessingPolymarker = true;
218
219  // Loads G4Atts for picking...
220  if (fpViewer->GetViewParameters().IsPicking()) {
221    G4AttHolder* holder = new G4AttHolder;
222    LoadAtts(polymarker, holder);
223    fPickMap[fPickName] = holder;
224  }
225
226  switch (polymarker.GetMarkerType()) {
227  default:
228  case G4Polymarker::dots:
229    {
230      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
231        G4Circle dot (polymarker);
232        dot.SetPosition (polymarker[iPoint]);
233        dot.SetWorldSize  (0.);
234        dot.SetScreenSize (0.1);  // Very small circle.
235        G4OpenGLSceneHandler::AddPrimitive (dot);
236      }
237    }
238    break;
239  case G4Polymarker::circles:
240    {
241      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
242        G4Circle circle (polymarker);
243        circle.SetPosition (polymarker[iPoint]);
244        G4OpenGLSceneHandler::AddPrimitive (circle);
245      }
246    }
247    break;
248  case G4Polymarker::squares:
249    {
250      for (size_t iPoint = 0; iPoint < polymarker.size (); iPoint++) {
251        G4Square square (polymarker);
252        square.SetPosition (polymarker[iPoint]);
253        G4OpenGLSceneHandler::AddPrimitive (square);
254      }
255    }
256    break;
257  }
258
259  fProcessingPolymarker = false;
260}
261
262void G4OpenGLSceneHandler::AddPrimitive (const G4Text& text) {
263
264#ifdef G4DEBUG_VIS_OGL
265  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT\n");
266#endif 
267  // Loads G4Atts for picking...
268  if (fpViewer->GetViewParameters().IsPicking()) {
269#ifdef G4DEBUG_VIS_OGL
270  printf ("G4OpenGLSceneHandler::AddPrimitives PICKING\n");
271#endif 
272    G4AttHolder* holder = new G4AttHolder;
273    LoadAtts(text, holder);
274    fPickMap[fPickName] = holder;
275  }
276
277  const G4Colour& c = GetTextColour (text);  // Picks up default if none.
278  MarkerSizeType sizeType;
279  G4double size = GetMarkerSize (text, sizeType);
280  G4ThreeVector position (text.GetPosition ());
281  G4String textString = text.GetText();
282
283#ifdef G4DEBUG_VIS_OGL
284  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT -%s-X:%f Y:%f Z:%f- - Red:%f Green:%f Blue:%f--\n",textString.c_str(),position.x(),position.y(),position.z(),c.GetRed (), c.GetGreen (), c.GetBlue ());
285#endif 
286
287  G4int font_base = G4OpenGLFontBaseStore::GetFontBase(fpViewer,size);
288#ifdef G4DEBUG_VIS_OGL
289  printf ("G4OpenGLSceneHandler::AddPrimitives getFontBase ?size=%f-recu:%d-\n",size,font_base);
290#endif 
291  if (font_base < 0) {
292#ifdef G4DEBUG_VIS_OGL
293    printf ("G4OpenGLSceneHandler::AddPrimitives NO FONT BASE--\n");
294#endif 
295   
296#ifdef G4DEBUG_VIS_OGL
297    printf ("G4OpenGLSceneHandler::AddPrimitives SPECIAL CASE\n");
298#endif 
299    G4OpenGLQtViewer* oGLSQtViewer = dynamic_cast<G4OpenGLQtViewer*>(fpViewer);
300    if (oGLSQtViewer) {
301      // FIXME : No font for the moment
302      const char* textCString = textString.c_str();
303      oGLSQtViewer->drawText(textCString,position.x(),position.y(),position.z(),size);
304    }
305    static G4int callCount = 0;
306    ++callCount;
307    if (callCount <= 10 || callCount%100 == 0) {
308     
309     
310     
311      G4cout <<
312        "G4OpenGLSceneHandler::AddPrimitive (const G4Text&) call count "
313             << callCount <<
314        "\n  No fonts available."
315        "\n  Called with text \""
316             << text.GetText ()
317             << "\"\n  at " << position
318             << ", size " << size
319             << ", offsets " << text.GetXOffset () << ", " << text.GetYOffset ()
320             << ", type " << G4int(sizeType)
321             << ", colour " << c
322             << G4endl;
323    }
324    return;
325  }
326  const char* textCString = textString.c_str();
327  glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
328  G4OpenGLQtViewer* oGLSQtViewer = dynamic_cast<G4OpenGLQtViewer*>(fpViewer);
329
330  if (oGLSQtViewer) {
331    // FIXME : No font for the moment
332    oGLSQtViewer->drawText(textCString,position.x(),position.y(),position.z(),size);
333  } else {
334    glDisable (GL_DEPTH_TEST);
335    glDisable (GL_LIGHTING);
336   
337    glRasterPos3d(position.x(),position.y(),position.z());
338    // No action on offset or layout at present.
339    glPushAttrib(GL_LIST_BIT);
340    glListBase(font_base);
341    glCallLists(strlen(textCString), GL_UNSIGNED_BYTE, (GLubyte *)textCString);
342    glPopAttrib();
343  }
344  //     //////////////
345  //     makeCurrent();
346  //     glPushAttrib(GL_LIST_BIT | GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT);
347  //     glRasterPos3d(x, y, z);
348  //     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
349  //     glEnable(GL_BLEND);
350  //     glListBase(fontDisplayListBase(fnt, listBase));
351  //     glCallLists(str.length(), GL_UNSIGNED_BYTE, str.local8Bit());
352  //     glPopAttrib();
353  //     //////////////
354 
355#ifdef G4DEBUG_VIS_OGL
356  printf ("G4OpenGLSceneHandler::AddPrimitives TEXT\n");
357#endif 
358}
359
360void G4OpenGLSceneHandler::AddPrimitive (const G4Circle& circle) {
361  glEnable (GL_POINT_SMOOTH);
362  AddCircleSquare (circle, G4OpenGLBitMapStore::circle);
363}
364
365void G4OpenGLSceneHandler::AddPrimitive (const G4Square& square) {
366  glDisable (GL_POINT_SMOOTH);
367  AddCircleSquare (square, G4OpenGLBitMapStore::square);
368}
369
370void G4OpenGLSceneHandler::AddCircleSquare
371(const G4VMarker& marker,
372 G4OpenGLBitMapStore::Shape shape) {
373
374  if (!fProcessingPolymarker) {  // Polymarker has already loaded atts.
375    // Loads G4Atts for picking...
376    if (fpViewer->GetViewParameters().IsPicking()) {
377      G4AttHolder* holder = new G4AttHolder;
378      LoadAtts(marker, holder);
379      fPickMap[fPickName] = holder;
380    }
381  }
382
383  // Note: colour treated in sub-class.
384
385  if (fpViewer -> GetViewParameters ().IsMarkerNotHidden ())
386    glDisable (GL_DEPTH_TEST);
387  else {glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LESS);}
388 
389  glDisable (GL_LIGHTING);
390 
391  // Get vis attributes - pick up defaults if none.
392  const G4VisAttributes* pVA =
393    fpViewer -> GetApplicableVisAttributes (marker.GetVisAttributes ());
394
395  G4double lineWidth = GetLineWidth(pVA);
396  glLineWidth(lineWidth);
397
398  G4VMarker::FillStyle style = marker.GetFillStyle();
399
400  G4bool filled = false;
401  static G4bool hashedWarned = false;
402 
403  switch (style) {
404  case G4VMarker::noFill:
405    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
406    filled = false;
407    break;
408   
409  case G4VMarker::hashed:
410    if (!hashedWarned) {
411      G4cout << "Hashed fill style in G4OpenGLSceneHandler."
412             << "\n  Not implemented.  Using G4VMarker::filled."
413             << G4endl;
414      hashedWarned = true;
415    }
416    // Maybe use
417    //glPolygonStipple (fStippleMaskHashed);
418    // Drop through to filled...
419   
420  case G4VMarker::filled:
421    glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
422    filled = true;
423    break;
424   
425  }
426
427  // A few useful quantities...
428  G4Point3D centre = marker.GetPosition();
429  MarkerSizeType sizeType;
430  G4double size = GetMarkerSize(marker, sizeType);
431
432  // Draw...
433   if (sizeType == world) {  // Size specified in world coordinates.
434
435     DrawXYPolygon (shape, size, centre, pVA);
436
437   } else { // Size specified in screen (window) coordinates.
438     glPointSize (size);       
439     glBegin (GL_POINTS);
440     glVertex3f(centre.x(),centre.y(),centre.z());
441     glEnd();
442     //Antialiasing
443     glEnable (GL_POINT_SMOOTH);
444     //Transparency
445     glEnable(GL_BLEND);
446     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
447
448     // L. GARNIER 1 March 2009
449     // Old method, we draw a bitmap instead of a GL_POINT.
450     // I remove it because it cost in term of computing performances
451     // and gl2ps can't draw bitmaps
452
453     //      glRasterPos3d(centre.x(),centre.y(),centre.z());
454     //      const GLubyte* marker =
455     //        G4OpenGLBitMapStore::GetBitMap(shape, size, filled);
456     //      glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
457     //      glBitmap(GLsizei(size), GLsizei(size), size/2., size/2., 0., 0., marker);
458   }
459}
460
461void G4OpenGLSceneHandler::DrawXYPolygon
462(G4OpenGLBitMapStore::Shape shape,
463 G4double size,
464 const G4Point3D& centre,
465 const G4VisAttributes* pApplicableVisAtts)
466{
467  G4int nSides;
468  G4double startPhi;
469  if (shape == G4OpenGLBitMapStore::circle) {
470    nSides = GetNoOfSides(pApplicableVisAtts);
471    startPhi = 0.;
472  } else {
473    nSides = 4;
474    startPhi = -pi / 4.;
475  }
476
477  const G4Vector3D& viewpointDirection =
478    fpViewer -> GetViewParameters().GetViewpointDirection();
479  const G4Vector3D& up = fpViewer->GetViewParameters().GetUpVector();
480  const G4double dPhi = twopi / nSides;
481  const G4double radius = size / 2.;
482  G4Vector3D start = radius * (up.cross(viewpointDirection)).unit();
483  G4double phi;
484  G4int i;
485
486  glBegin (GL_POLYGON);
487  for (i = 0, phi = startPhi; i < nSides; i++, phi += dPhi) {
488    G4Vector3D r = start; r.rotate(phi, viewpointDirection);
489    G4Vector3D p = centre + r;
490    glVertex3d (p.x(), p.y(), p.z());
491  }
492  glEnd ();
493}
494
495void G4OpenGLSceneHandler::AddPrimitive (const G4Scale& scale)
496{
497  G4VSceneHandler::AddPrimitive(scale);
498}
499
500//Method for handling G4Polyhedron objects for drawing solids.
501void G4OpenGLSceneHandler::AddPrimitive (const G4Polyhedron& polyhedron) {
502  // Assume all facets are planar convex quadrilaterals.
503  // Draw each facet individually
504#ifdef G4DEBUG_VIS_OGL
505  printf ("G4OpenGLSceneHandler::AddPrimitives BEGIN poly\n");
506#endif 
507  if (polyhedron.GetNoFacets() == 0) return;
508#ifdef G4DEBUG_VIS_OGL
509    printf ("G4OpenGLSceneHandler::AddPrimitives BEGIN 2 poly %d ++ %d\n",fpViewer,fpViewer->GetViewParameters().IsPicking());
510#endif
511
512  // Loads G4Atts for picking...
513  if (fpViewer->GetViewParameters().IsPicking()) {
514    G4AttHolder* holder = new G4AttHolder;
515    const G4Visible vis;
516#ifdef G4DEBUG_VIS_OGL
517    printf ("G4OpenGLSceneHandler::AddPrimitives poly %d\n",&polyhedron);
518#endif
519    LoadAtts(polyhedron, holder);
520    //    LoadAtts(polyhedron, holder);
521    fPickMap[fPickName] = holder;
522  }
523
524  // Get vis attributes - pick up defaults if none.
525  const G4VisAttributes* pVA =
526    fpViewer -> GetApplicableVisAttributes (polyhedron.GetVisAttributes ());
527
528  // Get view parameters that the user can force through the vis
529  // attributes, thereby over-riding the current view parameter.
530  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
531
532  //Get colour, etc...
533  G4bool transparency_enabled = true;
534  G4OpenGLViewer* pViewer = dynamic_cast<G4OpenGLViewer*>(fpViewer);
535  if (pViewer) transparency_enabled = pViewer->transparency_enabled;
536  const G4Colour& c = pVA->GetColour();
537  GLfloat materialColour [4];
538  materialColour [0] = c.GetRed ();
539  materialColour [1] = c.GetGreen ();
540  materialColour [2] = c.GetBlue ();
541  if (transparency_enabled) {
542    materialColour [3] = c.GetAlpha ();
543  } else {
544    materialColour [3] = 1.;
545  }
546
547  G4double lineWidth = GetLineWidth(pVA);
548  glLineWidth(lineWidth);
549
550  GLfloat clear_colour[4];
551  glGetFloatv (GL_COLOR_CLEAR_VALUE, clear_colour);
552
553  G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
554
555  G4bool clipping = pViewer->fVP.IsSection() || pViewer->fVP.IsCutaway();
556
557  // Lighting disabled unless otherwise requested
558  glDisable (GL_LIGHTING);
559
560  switch (drawing_style) {
561  case (G4ViewParameters::hlhsr):
562    // Set up as for hidden line removal but paint polygon faces later...
563  case (G4ViewParameters::hlr):
564    glEnable (GL_STENCIL_TEST);
565    // The stencil buffer is cleared in G4OpenGLViewer::ClearView.
566    // The procedure below leaves it clear.
567    glStencilFunc (GL_ALWAYS, 0, 1);
568    glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
569    glEnable (GL_DEPTH_TEST);
570    glDepthFunc (GL_LEQUAL);
571    if (materialColour[3] < 1.) {
572      // Transparent...
573      glDisable (GL_CULL_FACE);
574      glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
575    } else {
576      // Opaque...
577      if (clipping) {
578        glDisable (GL_CULL_FACE);
579        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
580      } else {
581        glEnable (GL_CULL_FACE);
582        glCullFace (GL_BACK);
583        glPolygonMode (GL_FRONT, GL_LINE);
584      }
585    }
586    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
587    break;
588  case (G4ViewParameters::hsr):
589    glEnable (GL_DEPTH_TEST);
590    glDepthFunc (GL_LEQUAL);   
591    if (materialColour[3] < 1.) {
592      // Transparent...
593      glDepthMask (0);  // Make depth buffer read-only.
594      glDisable (GL_CULL_FACE);
595      glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
596      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, materialColour);
597    } else {
598      // Opaque...
599      glDepthMask (1);  // Make depth buffer writable (default).
600      if (clipping) {
601        glDisable (GL_CULL_FACE);
602        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
603      } else {
604        glEnable (GL_CULL_FACE);
605        glCullFace (GL_BACK);
606        glPolygonMode (GL_FRONT, GL_FILL);
607      }
608      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
609    }
610    if (!fProcessing2D) glEnable (GL_LIGHTING);
611    break;
612  case (G4ViewParameters::wireframe):
613  default:
614    glEnable (GL_DEPTH_TEST);
615    glDepthFunc (GL_LEQUAL);    //??? was GL_ALWAYS
616    glDisable (GL_CULL_FACE);
617    glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
618    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
619    break;
620  }
621
622  //Loop through all the facets...
623  glBegin (GL_QUADS);
624  G4bool notLastFace;
625  do {
626
627    //First, find vertices, edgeflags and normals and note "not last facet"...
628    G4Point3D vertex[4];
629    G4int edgeFlag[4];
630    G4Normal3D normals[4];
631    G4int n;
632    notLastFace = polyhedron.GetNextFacet(n, vertex, edgeFlag, normals);
633
634    //Loop through the four edges of each G4Facet...
635    G4int edgeCount = 0;
636    for(edgeCount = 0; edgeCount < n; ++edgeCount) {
637      // Check to see if edge is visible or not...
638      if (isAuxEdgeVisible) {
639        edgeFlag[edgeCount] = 1;
640      }
641      if (edgeFlag[edgeCount] > 0) {
642        glEdgeFlag (GL_TRUE);
643      } else {
644        glEdgeFlag (GL_FALSE);
645      }
646      glNormal3d (normals[edgeCount].x(),
647                  normals[edgeCount].y(),
648                  normals[edgeCount].z());
649      glVertex3d (vertex[edgeCount].x(),
650                  vertex[edgeCount].y(),
651                  vertex[edgeCount].z());
652    }
653    // HepPolyhedron produces triangles too; in that case add an extra
654    // vertex identical to first...
655    if (n == 3) {
656      edgeCount = 3;
657      normals[edgeCount] = normals[0];
658      vertex[edgeCount] = vertex[0];
659      edgeFlag[edgeCount] = -1;
660      glEdgeFlag (GL_FALSE);
661      glNormal3d (normals[edgeCount].x(),
662                  normals[edgeCount].y(),
663                  normals[edgeCount].z());
664      glVertex3d (vertex[edgeCount].x(),
665                  vertex[edgeCount].y(),
666                  vertex[edgeCount].z());
667    }
668    // Trap situation where number of edges is > 4...
669    if (n > 4) {
670      G4cerr <<
671        "G4OpenGLSceneHandler::AddPrimitive(G4Polyhedron): WARNING";
672      G4PhysicalVolumeModel* pPVModel =
673        dynamic_cast<G4PhysicalVolumeModel*>(fpModel);
674      if (pPVModel) {
675        G4VPhysicalVolume* pCurrentPV = pPVModel->GetCurrentPV();
676        G4LogicalVolume* pCurrentLV = pPVModel->GetCurrentLV();
677        G4cerr <<
678        "\n  Volume " << pCurrentPV->GetName() <<
679        ", Solid " << pCurrentLV->GetSolid()->GetName() <<
680          " (" << pCurrentLV->GetSolid()->GetEntityType();
681      }
682      G4cerr<<
683        "\n   G4Polyhedron facet with " << n << " edges" << G4endl;
684    }
685
686    // Do it all over again (twice) for hlr...
687    if  (drawing_style == G4ViewParameters::hlr ||
688         drawing_style == G4ViewParameters::hlhsr) {
689
690      glEnd ();  // Placed here to balance glBegin above, allowing GL
691                 // state changes below, then glBegin again.  Avoids
692                 // having glBegin/End pairs *inside* loop in the more
693                 // usual case of no hidden line removal.
694
695      // Lighting disabled unless otherwise requested
696      glDisable (GL_LIGHTING);
697
698      // Draw through stencil...
699      glStencilFunc (GL_EQUAL, 0, 1);
700      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
701      if (drawing_style == G4ViewParameters::hlhsr) {
702        if (!fProcessing2D) glEnable (GL_LIGHTING);
703      }
704      glEnable (GL_DEPTH_TEST);
705      glDepthFunc (GL_LEQUAL);   
706      if (materialColour[3] < 1.) {
707        // Transparent...
708        glDepthMask (0);  // Make depth buffer read-only.
709        glDisable (GL_CULL_FACE);
710        glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
711      } else {
712        // Opaque...
713        glDepthMask (1);  // Make depth buffer writable (default).
714        if (clipping) {
715          glDisable (GL_CULL_FACE);
716          glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
717        } else {
718          glEnable (GL_CULL_FACE);
719          glCullFace (GL_BACK);
720          glPolygonMode (GL_FRONT, GL_FILL);
721        }
722      }
723      GLfloat* painting_colour;
724      if  (drawing_style == G4ViewParameters::hlr) {
725        if (materialColour[3] < 1.) {
726          // Transparent - don't paint...
727          goto end_of_drawing_through_stencil;
728        }
729        painting_colour = clear_colour;
730      } else {  // drawing_style == G4ViewParameters::hlhsr
731        painting_colour = materialColour;
732      }
733      if (materialColour[3] < 1.) {
734        // Transparent...
735        glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, painting_colour);
736      } else {
737        // Opaque...
738        glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, painting_colour);
739      }
740      glColor4fv (painting_colour);
741      glBegin (GL_QUADS);
742      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
743        if (edgeFlag[edgeCount] > 0) {
744          glEdgeFlag (GL_TRUE);
745        } else {
746          glEdgeFlag (GL_FALSE);
747        }
748        glNormal3d (normals[edgeCount].x(),
749                    normals[edgeCount].y(),
750                    normals[edgeCount].z());
751        glVertex3d (vertex[edgeCount].x(),
752                    vertex[edgeCount].y(),
753                    vertex[edgeCount].z());
754      }
755      glEnd ();
756    end_of_drawing_through_stencil:
757
758      // and once more to reset the stencil bits...
759      glStencilFunc (GL_ALWAYS, 0, 1);
760      glStencilOp (GL_INVERT, GL_INVERT, GL_INVERT);
761      glDepthFunc (GL_LEQUAL);  // to make sure line gets drawn. 
762      if (materialColour[3] < 1.) {
763        // Transparent...
764        glDisable (GL_CULL_FACE);
765        glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
766      } else {
767        // Opaque...
768        if (clipping) {
769          glDisable (GL_CULL_FACE);
770          glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
771        } else {
772          glEnable (GL_CULL_FACE);
773          glCullFace (GL_BACK);
774          glPolygonMode (GL_FRONT, GL_LINE);
775        }
776      }
777      glDisable (GL_LIGHTING);
778      glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
779      glBegin (GL_QUADS);
780      for (int edgeCount = 0; edgeCount < 4; ++edgeCount) {
781        if (edgeFlag[edgeCount] > 0) {
782          glEdgeFlag (GL_TRUE);
783        } else {
784          glEdgeFlag (GL_FALSE);
785        }
786        glNormal3d (normals[edgeCount].x(),
787                    normals[edgeCount].y(),
788                    normals[edgeCount].z());
789        glVertex3d (vertex[edgeCount].x(),
790                    vertex[edgeCount].y(),
791                    vertex[edgeCount].z());
792      }
793      glEnd ();
794      glDepthFunc (GL_LEQUAL);   // Revert for next facet.
795      glBegin (GL_QUADS);      // Ready for next facet.  GL
796                               // says it ignores incomplete
797                               // quadrilaterals, so final empty
798                               // glBegin/End sequence should be OK.
799    }
800  } while (notLastFace); 
801 
802  glEnd ();
803  glDisable (GL_STENCIL_TEST);  // Revert to default for next primitive.
804  glDepthMask (1);              // Revert to default for next primitive.
805  glDisable (GL_LIGHTING);      // Revert to default for next primitive.
806}
807
808//Method for handling G4NURBS objects for drawing solids.
809//Knots and Ctrl Pnts MUST be arrays of GLfloats.
810void G4OpenGLSceneHandler::AddPrimitive (const G4NURBS& nurb) {
811
812  // Loads G4Atts for picking...
813  if (fpViewer->GetViewParameters().IsPicking()) {
814    G4AttHolder* holder = new G4AttHolder;
815    LoadAtts(nurb, holder);
816    fPickMap[fPickName] = holder;
817  }
818
819  GLUnurbsObj *gl_nurb;
820  gl_nurb = gluNewNurbsRenderer ();
821
822  GLfloat *u_knot_array, *u_knot_array_ptr;
823  u_knot_array = u_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::U)];
824  G4NURBS::KnotsIterator u_iterator (nurb, G4NURBS::U);
825  while (u_iterator.pick (u_knot_array_ptr++)){}
826
827  GLfloat *v_knot_array, *v_knot_array_ptr;
828  v_knot_array = v_knot_array_ptr = new GLfloat [nurb.GetnbrKnots(G4NURBS::V)];
829  G4NURBS::KnotsIterator v_iterator (nurb, G4NURBS::V);
830  while (v_iterator.pick (v_knot_array_ptr++)){}
831
832  GLfloat *ctrl_pnt_array, *ctrl_pnt_array_ptr;
833  ctrl_pnt_array = ctrl_pnt_array_ptr =
834    new GLfloat [nurb.GettotalnbrCtrlPts () * G4NURBS::NofC];
835  G4NURBS::CtrlPtsCoordsIterator c_p_iterator (nurb);
836  while (c_p_iterator.pick (ctrl_pnt_array_ptr++)){}
837
838  // Get vis attributes - pick up defaults if none.
839  const G4VisAttributes* pVA =
840    fpViewer -> GetApplicableVisAttributes (nurb.GetVisAttributes ());
841
842  // Get view parameters that the user can force through the vis
843  // attributes, thereby over-riding the current view parameter.
844  G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle (pVA);
845  //G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVA);
846 
847  //Get colour, etc..
848  const G4Colour& c = pVA -> GetColour ();
849
850  switch (drawing_style) {
851
852  case (G4ViewParameters::hlhsr):
853    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
854    // << "Using hidden surface removal." << G4endl;
855  case (G4ViewParameters::hsr):
856    {
857      if (!fProcessing2D) glEnable (GL_LIGHTING);
858      glEnable (GL_DEPTH_TEST);
859      glEnable (GL_AUTO_NORMAL);
860      glEnable (GL_NORMALIZE);
861      gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_FILL);
862      gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
863      GLfloat materialColour [4];
864      materialColour [0] = c.GetRed ();
865      materialColour [1] = c.GetGreen ();
866      materialColour [2] = c.GetBlue ();
867      materialColour [3] = 1.0;  // = c.GetAlpha () for transparency -
868                                 // but see complication in
869                                 // AddPrimitive(const G4Polyhedron&).
870      glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, materialColour);
871      break;
872    }
873  case (G4ViewParameters::hlr):
874    //    G4cout << "Hidden line removal not implememented in G4OpenGL.\n"
875    // << "Using wireframe." << G4endl;
876  case (G4ViewParameters::wireframe):
877  default:
878    glDisable (GL_LIGHTING);
879//    glDisable (GL_DEPTH_TEST);
880    glEnable (GL_DEPTH_TEST);
881    glDisable (GL_AUTO_NORMAL);
882    glDisable (GL_NORMALIZE);
883    gluNurbsProperty (gl_nurb, GLU_DISPLAY_MODE, GLU_OUTLINE_POLYGON);
884    gluNurbsProperty (gl_nurb, GLU_SAMPLING_TOLERANCE, 50.0);
885    glColor3d (c.GetRed (), c.GetGreen (), c.GetBlue ());
886    break;
887  }     
888
889  gluBeginSurface (gl_nurb);
890  G4int u_stride = 4;
891  G4int v_stride = nurb.GetnbrCtrlPts(G4NURBS::U) * 4;
892
893  gluNurbsSurface (gl_nurb,
894                   nurb.GetnbrKnots (G4NURBS::U), (GLfloat*)u_knot_array,
895                   nurb.GetnbrKnots (G4NURBS::V), (GLfloat*)v_knot_array,
896                   u_stride,
897                   v_stride, 
898                   ctrl_pnt_array,
899                   nurb.GetUorder (),
900                   nurb.GetVorder (),
901                   GL_MAP2_VERTEX_4);
902 
903  gluEndSurface (gl_nurb);
904
905  delete [] u_knot_array;  // These should be allocated with smart allocators
906  delete [] v_knot_array;  // to avoid memory explosion.
907  delete [] ctrl_pnt_array;
908
909  gluDeleteNurbsRenderer (gl_nurb);
910}
911
912void G4OpenGLSceneHandler::AddCompound(const G4VTrajectory& traj) {
913  G4VSceneHandler::AddCompound(traj);  // For now.
914}
915
916void G4OpenGLSceneHandler::AddCompound(const G4VHit& hit) {
917  G4VSceneHandler::AddCompound(hit);  // For now.
918}
919
920#endif
Note: See TracBrowser for help on using the repository browser.