Logo ROOT   6.08/07
Reference Guide
TGLOutput.cxx
Go to the documentation of this file.
1 // @(#)root/gl:$Id$
2 // Author: Richard Maunder, Olivier Couet 02/07/2005
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2005, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TGLOutput.h"
13 
14 #include "Riostream.h"
15 #include "TVirtualPad.h"
16 #include "TVirtualPS.h"
17 #include "TGLViewer.h"
18 #include "TSystem.h" // For gSystem
19 // FIXME: Some gl2ps.h versions (see ROOT-8219) rely on including gl.h, which
20 // in we shadow in our isystem/gl.h intentionally. Including TGLIncludes.h, will
21 // temporary workaround the issue.
22 #include "TGLIncludes.h"
23 #include "gl2ps.h"
24 #include "TError.h"
25 #include <assert.h>
26 
27 /** \class TGLOutput
28 \ingroup opengl
29 Wrapper class for GL capture & output routines
30 */
31 
33 
34 ////////////////////////////////////////////////////////////////////////////////
35 /// Capture viewer to file. Arguments are:
36 /// - 'viewer' - viewer object to capture from
37 /// - 'format' - output format - only postscript types presently.
38 /// One of kEPS_SIMPLE, kEPS_BSP, kPDF_SIMPLE or kPDF_BSP
39 /// See TGLOutput::CapturePostscript() for meanings
40 /// - 'filePath' - file output name. If null defaults to './viewer.eps' or './viewer.pdf'
41 /// depending on format requested
42 ///
43 /// Note : Output files can be large and take considerable time (up to mins)
44 /// to generate
45 
46 Bool_t TGLOutput::Capture(TGLViewer & viewer, EFormat format, const char * filePath)
47 {
48  switch(format) {
49  case(kEPS_SIMPLE):
50  case(kEPS_BSP):
51  case(kPDF_SIMPLE):
52  case(kPDF_BSP): {
53  return CapturePostscript(viewer, format, filePath);
54  }
55  }
56 
57  assert(kFALSE);
58  return kFALSE;
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// Capture viewer to postscript file. Arguments are:
63 /// - 'viewer' - viewer object to capture from
64 /// - 'format' - output format
65 /// - kEPS_SIMPLE - lower quality EPS
66 /// - kEPS_BSP - higher quality EPS
67 /// - kPDF_SIMPLE - lower quality PDF
68 /// - kPDF_BSP - higher quality PDF
69 /// - 'filePath' - file output name. If null defaults to './viewer.eps' or './viewer.pdf'
70 /// depending on format requested
71 
72 Bool_t TGLOutput::CapturePostscript(TGLViewer & viewer, EFormat format, const char * filePath)
73 {
74  if (!filePath || !filePath[0]) {
75  if (format == kEPS_SIMPLE || format == kEPS_BSP) {
76  filePath = "viewer.eps";
77  } else if (format == kPDF_SIMPLE || format == kPDF_BSP) {
78  filePath = "viewer.pdf";
79  }
80  }
81  Info("TGLOutput::Postscript()", "Start creating %s.", filePath);
82  std::cout << "Please wait.";
83 
84  if (FILE *output = fopen (filePath, "w+b"))
85  {
86  Int_t gl2psFormat;
87  Int_t gl2psSort;
88 
89  switch(format) {
90  case kEPS_SIMPLE:
91  gl2psFormat = GL2PS_EPS;
92  gl2psSort = GL2PS_SIMPLE_SORT;
93  break;
94  case kEPS_BSP:
95  gl2psFormat = GL2PS_EPS;
96  gl2psSort = GL2PS_BSP_SORT;
97  break;
98  case kPDF_SIMPLE:
99  gl2psFormat = GL2PS_PDF;
100  gl2psSort = GL2PS_SIMPLE_SORT;
101  break;
102  case kPDF_BSP:
103  gl2psFormat = GL2PS_PDF;
104  gl2psSort = GL2PS_BSP_SORT;
105  break;
106  default:
107  assert(kFALSE);
108  return kFALSE;
109  }
110  Int_t buffsize = 0, state = GL2PS_OVERFLOW;
111  viewer.DoDraw();
112  viewer.fIsPrinting = kTRUE;
113  while (state == GL2PS_OVERFLOW) {
114  buffsize += 1024*1024;
115  gl2psBeginPage ("ROOT Scene Graph", "ROOT", NULL,
116  gl2psFormat, gl2psSort, GL2PS_USE_CURRENT_VIEWPORT
117  | GL2PS_SILENT | GL2PS_BEST_ROOT | GL2PS_OCCLUSION_CULL | 0,
118  GL_RGBA, 0, NULL,0, 0, 0,
119  buffsize, output, NULL);
120  viewer.DoDraw();
121  state = gl2psEndPage();
122  std::cout << ".";
123  }
124  std::cout << std::endl;
125  fclose (output);
126  viewer.fIsPrinting = kFALSE;
127  if (!gSystem->AccessPathName(filePath)) {
128  Info("TGLOutput::Postscript", "Finished creating %s.", filePath);
129  return kTRUE;
130  }
131  } else {
132  Error("TGLOutput::Postscript", "Failed to create %s. ", filePath);
133  }
134 
135  return kFALSE;
136 }
137 
138 ////////////////////////////////////////////////////////////////////////////////
139 /// this function used by gl-in-pad
140 
142 {
143  Info("TGLOutput::StartEmbeddedPS", "PS output started ...");
144 
145  gVirtualPS->PrintStr("@");
146  gVirtualPS->PrintStr("% Start gl2ps EPS@");
147  gVirtualPS->PrintStr("newpath gsave save@");
148  Double_t xx[2] = {0.}, yy[2] = {0.};
149  xx[0] = gPad->GetUxmin();
150  yy[0] = gPad->GetUymin();
151  xx[1] = gPad->GetUxmax();
152  yy[1] = gPad->GetUymax();
153  gVirtualPS->PrintStr("@");
154 
155  GLint vp[4];
156  glGetIntegerv(GL_VIEWPORT,vp);
157  gVirtualPS->DrawPS(0, xx, yy);
158  gVirtualPS->PrintStr(" exch");
159  xx[0] = xx[1];
160  yy[0] = yy[1];
161  gVirtualPS->DrawPS(0, xx, yy);
162  gVirtualPS->PrintStr(" 4 1 roll exch sub 3 1 roll sub");
163  gVirtualPS->WriteInteger(2*4*gPad->GetBorderSize());
164  gVirtualPS->PrintStr(" sub exch");
165  gVirtualPS->WriteInteger(2*4*gPad->GetBorderSize());
166  gVirtualPS->PrintStr(" sub exch");
167  gVirtualPS->WriteInteger((Int_t)(vp[3]));
168  gVirtualPS->WriteInteger((Int_t)(vp[2]));
169  gVirtualPS->PrintStr(" 4 1 roll div 3 1 roll exch div exch scale@");
170  gVirtualPS->PrintStr("@");
171  gVirtualPS->PrintStr("countdictstack@");
172  gVirtualPS->PrintStr("mark@");
173  gVirtualPS->PrintStr("/showpage {} def@");
174 
175  // Close the gVirtualPS output stream
176  std::ofstream *fs = (std::ofstream*)gVirtualPS->GetStream();
177  fs->close();
178 
179 }
180 
181 ////////////////////////////////////////////////////////////////////////////////
182 ///this function used by gl-in-pad
183 /// Restore the gVirtualPS output stream
184 
186 {
187  std::ofstream *fs = new std::ofstream(gVirtualPS->GetName(),std::ios::app);
188  gVirtualPS->SetStream(fs);
189  gVirtualPS->PrintStr("@");
190  gVirtualPS->PrintStr("cleartomark@");
191  gVirtualPS->PrintStr("countdictstack exch sub { end } repeat@");
192  gVirtualPS->PrintStr("restore grestore@");
193  gVirtualPS->PrintStr("% End gl2ps EPS@");
194 
195  Info("TGLOutput::CloseEmbeddedPS", "PS output finished");
196 }
197 
198 ////////////////////////////////////////////////////////////////////////////////
199 ///this function used by gl-viewer, embedded into pad
200 
202 {
203  StartEmbeddedPS();
204 
205  FILE *output = fopen (gVirtualPS->GetName(), "a");
206  if (!output) {
207  //Quite stupid fix, since if fopen fails, CloseEmbeddedPS will also
208  //fail but still I have to do it.
209  Error("TGLOutput::Capture", "can not open file for embedding ps");
210  CloseEmbeddedPS();
211  return;
212  }
213 
214  Int_t gl2psFormat = GL2PS_EPS;
215  Int_t gl2psSort = GL2PS_BSP_SORT;
216  Int_t buffsize = 0, state = GL2PS_OVERFLOW;
217  viewer.DoDraw();
218  viewer.fIsPrinting = kTRUE;
219 
220  while (state == GL2PS_OVERFLOW) {
221  buffsize += 1024*1024;
222  gl2psBeginPage ("ROOT Scene Graph", "ROOT", NULL,
223  gl2psFormat, gl2psSort, GL2PS_USE_CURRENT_VIEWPORT
224  | GL2PS_SILENT | GL2PS_BEST_ROOT | GL2PS_OCCLUSION_CULL | 0,
225  GL_RGBA, 0, NULL,0, 0, 0,
226  buffsize, output, NULL);
227  viewer.DoDraw();
228  state = gl2psEndPage();
229  std::cout << ".";
230  }
231 
232  std::cout << std::endl;
233  fclose (output);
234  viewer.fIsPrinting = kFALSE;
235 
236  CloseEmbeddedPS();
237 }
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:51
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1266
virtual void SetStream(std::ofstream *os)
Definition: TVirtualPS.h:82
void DoDraw(Bool_t swap_buffers=kTRUE)
Draw out the viewer.
Definition: TGLViewer.cxx:546
virtual void WriteInteger(Int_t i, Bool_t space=kTRUE)
Write one Integer to the file.
Definition: TVirtualPS.cxx:170
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
static std::string format(double x, double y, int digits, int width)
static Bool_t CapturePostscript(TGLViewer &viewer, EFormat format, const char *filePath)
Capture viewer to postscript file.
Definition: TGLOutput.cxx:72
Wrapper class for GL capture & output routines.
Definition: TGLOutput.h:28
virtual void PrintStr(const char *string="")
Output the string str in the output buffer.
Definition: TVirtualPS.cxx:72
void Info(const char *location, const char *msgfmt,...)
virtual void * GetStream() const
Definition: TVirtualPS.h:81
void Error(const char *location, const char *msgfmt,...)
static void StartEmbeddedPS()
this function used by gl-in-pad
Definition: TGLOutput.cxx:141
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
Bool_t fIsPrinting
debug mode (forced rebuild + draw scene/frustum/interest boxes)
Definition: TGLViewer.h:157
Base GL viewer object - used by both standalone and embedded (in pad) GL.
Definition: TGLViewer.h:53
static Bool_t Capture(TGLViewer &viewer, EFormat format, const char *filePath=0)
Capture viewer to file.
Definition: TGLOutput.cxx:46
#define ClassImp(name)
Definition: Rtypes.h:279
double Double_t
Definition: RtypesCore.h:55
static void CloseEmbeddedPS()
this function used by gl-in-pad Restore the gVirtualPS output stream
Definition: TGLOutput.cxx:185
virtual void DrawPS(Int_t n, Float_t *xw, Float_t *yw)=0
#define NULL
Definition: Rtypes.h:82
R__EXTERN TVirtualPS * gVirtualPS
Definition: TVirtualPS.h:91
#define gPad
Definition: TVirtualPad.h:289
const Bool_t kTRUE
Definition: Rtypes.h:91