source: trunk/documents/UserDoc/DocBookUsersGuides/ForToolkitDeveloper/xml/GuideToExtendFunctionality/Visualization/visualization.xml @ 904

Last change on this file since 904 was 904, checked in by garnier, 16 years ago

ajout de la doc

File size: 33.6 KB
Line 
1<!-- ******************************************************** -->
2<!--  Docbook Version:  For Toolkit Developers Guide          -->
3<!-- ******************************************************** -->
4
5<!-- ******************* Section (Level#1) ****************** -->
6<sect1 id="sect.ExtdFuncVis">
7<title>
8Visualisation
9</title>
10
11<para>
12This Chapter is intended to be read after Chapter
13<xref linkend="sect.DsgnFuncVis" />
14on Visualisation object oriented design in Part II.  Many of the concepts
15used here are defined there, and it strongly recommended that a writer
16of a new visualisation driver or trajectory drawer reads Chapter
17<xref linkend="sect.DsgnFuncVis" /> first. 
18The class structure described there is
19summarised in <xref linkend="fig.ExtdFuncVis_1" />.
20
21<figure id="fig.ExtdFuncVis_1">
22<title>
23Geant Visualisation System Class Diagram
24</title>
25<mediaobject>
26  <imageobject role="fo">
27    <imagedata fileref="./AllResources/GuideToExtendFunctionality/Visualization/visClassDiagram.gif" 
28               format="GIF" contentwidth="10.0cm" align="center" />
29  </imageobject>
30  <imageobject role="html">
31    <imagedata fileref="./AllResources/GuideToExtendFunctionality/Visualization/visClassDiagram.gif" 
32               format="GIF" align="center" scale="110" />
33  </imageobject>
34</mediaobject>
35</figure>
36</para>
37
38<!-- ******************* Section (Level#2) ****************** -->
39<sect2 id="sect.ExtdFuncVis.CrtGrpDrv">
40<title>
41Creating a new graphics driver
42</title>
43
44<para>
45To create a new graphics driver for Geant4, it is necessary to implement a
46new set of three classes derived from the three base classes,
47<literal>G4VGraphicsSystem</literal>, <literal>G4VSceneHandler </literal>
48and <literal>G4VViewer</literal>.
49</para>
50
51<!-- ******************* Section (Level#3) ****************** -->
52<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt">
53<title>
54A useful place to start
55</title>
56
57<para>
58A skeleton set of classes is included in the code distribution in the
59visualisation category under subdirectory <literal>visualisation/XXX</literal> 
60(but they are not default-registered graphics systems
61<footnote>
62  <para>
63  To do this,simply instantiate and register, for example:
64  <literal>visManager-&gt;RegisterGraphicsSystem(new G4XXX)</literal> 
65  before <literal>visManager-&gt;Initialise()</literal>
66  </para>
67</footnote>
68</para>
69
70<para>
71There are several sets of classes, described in more detail below. 
72A recommended approach is to copy the files that best match your graphics
73system  to a new subdirectory with a name that suits your graphics system . 
74</para>
75
76<para>
77Then
78
79<orderedlist spacing="compact">
80  <listitem><para>
81    Change the name of the files (change the code -- <literal>XXX</literal> or
82    <literal>XXXFile</literal>, etc., as chosen -- to something that suits
83    your graphics system ).
84  </para></listitem>
85  <listitem><para>
86    Change <literal>XXX</literal> similarly in all files.
87  </para></listitem>
88  <listitem><para>
89    Change <literal>XXX</literal> similarly in <literal>name := G4XXX</literal> 
90    in <literal>GNUmakefile</literal>.
91  </para></listitem>
92  <listitem><para>
93    Add your new subdirectory to <literal>SUBDIRS</literal> and
94    <literal>SUBLIBS</literal> in <literal>visualisation/GNUmakefile</literal>.
95  </para></listitem>
96  <listitem><para>
97    Look at the code and use it to build your visualisation
98    driver. You might also find it useful to look at
99    <literal>ASCIITree</literal> (and <literal>VTree</literal>) as an example
100    of a minimal graphics driver .  Look at <literal>FukuiRenderer</literal> 
101    as an example of a driver which implements <literal>AddSolid</literal>
102    methods for some solids.  Look at <literal>OpenGL</literal> as an example
103    of a driver which implements a graphical database (display lists) and the
104    machinery to decide when to rebuild.  (OpenGL is complicated by the
105    proliferation of combinations of the use or not of display lists for
106    three window systems, X-windows, X with motif (interactive), Microsoft
107    Windows (Win32), a total of six combinations, and much use is made of
108    inheritance to avoid code duplication.)
109  </para></listitem>
110  <listitem><para>
111    If it requires external libraries, introduce two new environment
112    variables <literal>G4VIS_BUILD_XXX_DRIVER</literal> and
113    <literal>G4VIS_USE_XXX</literal>
114    (where <literal>XXX</literal> is your choice as above) and make the
115    modifications to:
116    <itemizedlist spacing="compact">
117      <listitem><para>
118        <literal>source/visualization/management/include/G4VisExecutive.icc</literal>
119      </para></listitem>
120      <listitem><para>
121        <literal>config/G4VIS_BUILD.gmk</literal>
122      </para></listitem>
123      <listitem><para>
124        <literal>config/G4VIS_USE.gmk</literal>
125      </para></listitem>
126     </itemizedlist>
127  </para></listitem>
128</orderedlist>
129</para>
130
131<!-- ******************* Section (Level#4) ****************** -->
132<sect4 id="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt.Tmpl">
133<title>
134Graphics driver templates in the <literal>XXX</literal> sub-category
135</title>
136
137<para>
138You may use the following templates to help you get started writing a
139graphics driver .  (The word ``template'' is used in the ordinary sense of the
140word; they are not C++ templates.)
141
142<itemizedlist spacing="compact">
143  <listitem><para>
144    <literal>G4XXX, G4XXXSceneHandler, G4XXXViewer</literal> Templates for the
145    simplest possible graphics driver . These would be suitable for an ``immediate''
146    driver, i.e., one which renders each object immediately to a screen.
147    Of course, if the view needs re-drawing, as, for example, after a
148    change of viewpoint, the viewer requests a re-issue of drawn
149    objects.
150  </para></listitem>
151  <listitem><para>
152    <literal>G4XXXFile, G4XXXFileSceneHandler, G4XXXFileViewer</literal> Templates
153    for a file-writing graphics driver.  The particular features are:
154    delayed opening of the file on receipt of the first item; rewinding
155    file on ClearView (to simulate the clearing of views and prevent the
156    duplication of material in the file); closing of the file on ShowView,
157    which may also trigger the launch of a browser.  There are various
158    degrees of sophistication in, for example, the allocation of filenames
159    -- see <literal>FukuiRenderer</literal> or <literal>HepRepFile</literal>.
160    </para>
161    <para>
162    These templates also show the use of a specific <literal>AddSolid</literal> 
163    function whereby the specific parameters, for example, the dimensions of a
164    <literal>G4Box</literal>, can be accessed.
165  </para></listitem>
166  <listitem><para>
167    <literal>G4XXXStored, G4XXXStoredSceneHandler, G4XXXStoredViewer</literal>
168    Templates for a graphics driver with a store/database.  The advantage
169    of a store is that the view can be refreshed, for example, from a
170    different viewpoint, without a need to recompute.  It is up to the
171    viewer to decide when a re-computation is necessary.  They also show how
172    to distinguish between permanent and transient objects -- see also
173    Section <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
174  </para></listitem>
175  <listitem><para>
176    <literal>G4XXXSG, G4XXXSGSceneHandler, G4XXXSGViewer</literal> Templates for a
177    sophisticated graphics driver  with a scene graph.  The scene graph, following Open
178    Inventor parlance, is a tree of objects that dictates the order in
179    which the objects are rendered.  It obviously lends itself to the
180    rendering of the Geant4 geometry hierarchy.  For example, the Open
181    Inventor driver draws only the top level volumes unless made invisible
182    by picking.  Thus the user can unwrap a branch of the geometry level
183    by level. This has performance benefits and gives the user significant
184    and useful control over the view.  These classes show how to make a
185    scene graph of <emphasis role="bold">drawn</emphasis> volumes, i.e.,
186    the set of volumes that have
187    not been culled.  (Normally, volumes marked invisible are culled,
188    i.e., not drawn.  Also, the user may wish to limit the number of drawn
189    volumes for performance reasons.)  The drivers also have to process
190    non-geometry items and distinguish between transient and permanent
191    objects as above.
192  </para></listitem>
193</itemizedlist>
194</para>
195
196</sect4>
197</sect3>
198
199<!-- ******************* Section (Level#3) ****************** -->
200<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.ImpCmdAct">
201<title>
202Important Command Actions
203</title>
204
205<para>
206To help understand how the Geant4 Visualization System works, here are a
207few important function invocation sequences that follow user commands. 
208For an explanation of the commands themselves, see command guidance or
209the Control section of the Application Developers Guide.  For a
210fuller explanation of the functions, see appropriate base class head
211files or Software Reference Manual.
212
213<itemizedlist spacing="compact">
214  <listitem><para>
215    <literal>/vis/viewer/clear</literal>
216    <informalexample><programlisting>
217    viewer->ClearView();   // Clears buffer or rewinds file.
218    viewer->FinishView();  // Swaps buffer (double buffer systems).
219    </programlisting></informalexample>
220  </para></listitem>
221  <listitem><para>
222    <literal>/vis/viewer/flush</literal>
223    <informalexample><programlisting>
224    /vis/viewer/refresh
225    /vis/viewer/update
226    </programlisting></informalexample>
227  </para></listitem>
228  <listitem><para>
229    <literal>/vis/viewer/rebuild</literal>
230    <informalexample><programlisting>
231    viewer->SetNeedKernelVisit(true);
232    </programlisting></informalexample>
233  </para></listitem>
234  <listitem><para>
235    <literal>/vis/viewer/refresh</literal> If the view is ``auto-refresh'', this
236    command is also invoked after <literal>/vis/viewer/create</literal>,
237    <literal>/vis/viewer/rebuild</literal> or a change of view parameters
238    (<literal>/vis/viewer/set/</literal>..., etc.). 
239    <informalexample><programlisting>
240    viewer->SetView();    // Sets camera position, etc.
241    viewer->ClearView();  // Clears buffer or rewinds file.
242    viewer->DrawView();   // Draws to screen or writes to
243                          // file/socket.
244    </programlisting></informalexample>
245  </para></listitem>
246  <listitem><para>
247    <literal>/vis/viewer/update</literal>
248    <informalexample><programlisting>
249    viewer->ShowView();   // Activates interactive windows or
250                          // closes file and/or triggers
251                          // post-processing.
252    </programlisting></informalexample>
253  </para></listitem>
254  <listitem><para>
255    <literal>/vis/scene/notifyHandlers</literal> For each viewer of the current
256    scene, the equivalent of
257    <informalexample><programlisting>
258    /vis/viewer/refresh
259    </programlisting></informalexample>
260    If ``flush'' is specified on the command line, the equivalent of
261    <informalexample><programlisting>
262    /vis/viewer/update
263    </programlisting></informalexample>
264    <literal>/vis/scene/notifyHandlers</literal> is also invoked after a change
265    of scene (<literal>/vis/scene/add/</literal>..., etc.).
266  </para></listitem>
267</itemizedlist>
268</para>
269
270</sect3>
271
272<!-- ******************* Section (Level#3) ****************** -->
273<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtDrwVw">
274<title>
275What happens in <literal>DrawView</literal>?
276</title>
277
278<para>
279This depends on the viewer.  Those with their own graphical database,
280for example, OpenGL's display lists or Open Inventor's scene graph, do
281not need to re-traverse the scene unless there has been a significant
282change of view parameters.  For example, a mere change of viewpoint
283requires only a change of model-view matrix whilst a change of
284rendering mode from wireframe to surface might require a rebuild of
285the graphical database.  A rebuild of the run-duration (persistent)
286objects in the scene is called a ``kernel visit''; the viewer prints
287``Traversing scene data...''.
288</para>
289
290<para>
291Note that end-of-event (transient) objects are only rebuilt at the end
292of an event or run, under control of the visualisation manager.  Smart
293scene handlers keep them in separate display lists so that they can be
294rebuilt separately from the run-duration objects - see
295<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
296
297<itemizedlist spacing="compact">
298  <listitem><para>
299    <emphasis role="bold">Integrated viewers with no graphical database</emphasis> 
300    For example, <literal>G4OpenGLImmediateXViewer::DrawView()</literal>.
301    <informalexample><programlisting>
302    NeedKernelVisit();  // Always need to visit G4 kernel.
303    ProcessView();
304    FinishView();
305    </programlisting></informalexample>
306  </para></listitem>
307  <listitem><para>
308    <emphasis role="bold">Integrated viewers with graphical database</emphasis> 
309    For example, <literal>G4OpenGLStoredXViewer::DrawView()</literal>.
310    <informalexample><programlisting>
311    KernelVisitDecision();  // Private function containing...
312      if significant change of view parameters...
313        NeedKernelVisit();
314    ProcessView();
315    FinishView();
316    </programlisting></informalexample>
317  </para></listitem>
318  <listitem><para>
319    <emphasis role="bold">File-writing viewers</emphasis> For example,
320    <literal>G4DAWNFILEViewer::DrawView()</literal>.
321    <informalexample><programlisting>
322    NeedKernelVisit();
323    ProcessView();
324    </programlisting></informalexample>
325
326    Note that viewers needing to invoke <literal>FinishView</literal> must do it in
327    <literal>DrawView</literal>.
328  </para></listitem>
329</itemizedlist>
330</para>
331
332</sect3>
333
334<!-- ******************* Section (Level#3) ****************** -->
335<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcVw">
336<title>
337What happens in <literal>ProcessView</literal>?
338</title>
339
340<para>
341<literal>ProcessView</literal> is inherited from <literal>G4VViewer</literal>:
342
343<informalexample><programlisting>
344void G4VViewer::ProcessView() {
345  // If ClearStore has been requested, e.g., if the scene has changed,
346  // of if the concrete viewer has decided that it necessary to visit
347  // the kernel, perhaps because the view parameters have changed
348  // drastically (this should be done in the concrete viewer's
349  // DrawView)...
350  if (fNeedKernelVisit) {
351    fSceneHandler.ProcessScene(*this);
352    fNeedKernelVisit = false;
353  }
354}
355</programlisting></informalexample>
356</para>
357
358</sect3>
359
360<!-- ******************* Section (Level#3) ****************** -->
361<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn">
362<title>
363What happens in <literal>ProcessScene</literal>?
364</title>
365
366<para>
367ProcessScene is inherited from <literal>G4VSceneHandler}</literal>
368It causes a traversal of the run-duration models in the scene. 
369For drivers with graphical databases, it causes a rebuild
370(<literal>ClearStore</literal>).  Then for the run-duration models:
371
372<informalexample><programlisting>
373    fReadyForTransients = false;
374    BeginModeling();
375    for each run-duration model...
376      pModel -&gt; DescribeYourselfTo(*this);
377    EndModeling();
378    fReadyForTransients = true;
379</programlisting></informalexample>
380
381(A second pass is made on request -- see
382<literal>G4VSceneHandler::ProcessScene</literal>.) 
383The use of <literal>fReadyForTransients</literal>
384is described in <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
385</para>
386
387<para>
388What happens then depends on the type of model:
389
390<itemizedlist spacing="compact">
391  <listitem><para>
392    <literal>G4AxesModel</literal> <literal>G4AxesModel::DescribeYourselfTo</literal> 
393    simply calls sceneHandler.AddPrimitive methods directly.
394
395    <informalexample><programlisting>
396    sceneHandler.BeginPrimitives();
397    sceneHandler.AddPrimitive(x_axis);  // etc.
398    sceneHandler.EndPrimitives();
399    </programlisting></informalexample>
400
401    Most other models are like this, except for the following...
402
403  </para></listitem>
404  <listitem><para>
405    <literal>G4PhysicalVolumeModel</literal> The geometry is descended
406    recursively, culling policy is enacted, and for each accepted (and
407    possibly, clipped) solid:
408
409    <informalexample><programlisting>
410    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
411    pSol-&gt;DescribeYourselfTo(sceneHandler);
412    // For example, if pSol points to a G4Box...
413    |--&gt;G4Box::DescribeYourselfTo(G4VGraphicsScene&amp; scene){
414         scene.AddSolid(*this);
415        }
416    sceneHandler.PostAddSolid();
417    </programlisting></informalexample>
418
419    The scene handler may implement the virtual function {
420    AddSolid(const G4Box&amp;)}, or inherit:
421
422    <informalexample><programlisting>
423    void G4VSceneHandler::AddSolid(const G4Box&amp; box) {
424      RequestPrimitives(box);
425    }
426    </programlisting></informalexample>
427
428    <literal>RequestPrimitives</literal> converts the solid into primitives
429    (<literal>G4Polyhedron</literal>) and invokes <literal>AddPrimitive</literal>:
430
431    <informalexample><programlisting>
432    BeginPrimitives(*fpObjectTransformation);
433    pPolyhedron = solid.GetPolyhedron();
434    AddPrimitive(*pPolyhedron);
435    EndPrimitives();
436    </programlisting></informalexample>
437
438    The resulting default sequence for a <literal>G4PhysicalVolumeModel</literal> 
439    is shown in <xref linkend="fig.ExtdFuncVis_2" />.
440
441    <figure id="fig.ExtdFuncVis_2">
442    <title>
443    The default sequence for a <literal>G4PhysicalVolumeModel}</literal>
444    </title>
445    <screen>
446    DrawView();
447    |--&gt;ProcessView();
448        |--&gt;ProcessScene();
449            |--&gt;BeginModeling();
450            |--&gt;pModel -&gt; DescribeYourselfTo(*this);
451            |   |--&gt;sceneHandler.PreAddSolid(theAT, *pVisAttribs);
452            |   |--&gt;pSol-&gt;DescribeYourselfTo(sceneHandler);
453            |   |   |--&gt;sceneHandler.AddSolid(*this);
454            |   |       |--&gt;RequestPrimitives(solid);
455            |   |           |--&gt;BeginPrimitives (*fpObjectTransformation);
456            |   |           |--&gt;pPolyhedron = solid.GetPolyhedron();
457            |   |           |--&gt;AddPrimitive(*pPolyhedron);
458            |   |           |--&gt;EndPrimitives();
459            |   |--&gt;sceneHandler.PostAddSolid();
460            |--&gt;EndModeling();
461    </screen>
462    </figure>
463
464    Note the sequence of calls at the core:
465
466    <informalexample><programlisting>
467    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
468    pSol-&gt;DescribeYourselfTo(sceneHandler);
469    |--&gt;sceneHandler.AddSolid(*this);
470       |--&gt;RequestPrimitives(solid);
471          |--&gt;BeginPrimitives (*fpObjectTransformation);
472          |--&gt;pPolyhedron = solid.GetPolyhedron();
473          |--&gt;AddPrimitive(*pPolyhedron);
474          |--&gt;EndPrimitives();
475    sceneHandler.PostAddSolid();
476    </programlisting></informalexample>
477
478    is reduced to
479
480    <informalexample><programlisting>
481    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
482    pSol-&gt;DescribeYourselfTo(sceneHandler);
483    |--&gt;sceneHandler.AddSolid(*this); 
484    sceneHandler.PostAddSolid();
485    </programlisting></informalexample>
486
487    if the scene handler implements its own <literal>AddSolid</literal>
488    Moreover, the sequence
489
490    <informalexample><programlisting>
491    BeginPrimitives (*fpObjectTransformation);
492    AddPrimitive(*pPolyhedron);
493    EndPrimitives();
494    </programlisting></informalexample>
495
496    can be invoked without a prior <literal>PreAddSolid</literal>, etc. 
497    The flag <literal>fProcessingSolid</literal> will be false for the
498    last case.  The possibility of any or all of these three scenarios
499    occurring, for both permanent and
500    transient objects, affects the implementation of a scene handler if
501    there is any attempt to build a graphical database.  This is reflected
502    in the templates <literal>XXXStored</literal> and
503    <literal>XXXSG</literal> described in
504    <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt.Tmpl" />
505    Transients are discussed in
506    <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
507  </para></listitem>
508  <listitem><para>
509    <literal>G4TrajectoriesModel</literal> At end of event, the trajectory
510    container is unpacked and, for each trajectory,
511    <literal>sceneHandler.AddCompound</literal> called. 
512    The scene handler may implement this virtual function or inherit:
513
514    <informalexample><programlisting>
515    void G4VSceneHandler::AddCompound (const G4VTrajectory&amp; traj) {
516      traj.DrawTrajectory(((G4TrajectoriesModel*)fpModel)-&gt;GetDrawingMode());
517    }
518    </programlisting></informalexample>
519
520    Similarly, the user may implement <literal>DrawTrajectory</literal> 
521    or inherit:
522
523    <informalexample><programlisting>
524    void G4VTrajectory::DrawTrajectory(G4int i_mode) const {
525      G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
526      if (0 != pVVisManager) {
527        pVVisManager-&gt;DispatchToModel(*this, i_mode);
528      }
529    }
530    </programlisting></informalexample>
531
532    Thence, the <literal>Draw</literal> method of the current trajectory model
533    is invoked (see <xref linkend="sect.ExtdFuncVis.EnhcTrjDrw" /> for details
534    on trajectory models), which in turn, invokes <literal>Draw</literal> 
535    methods of the visualisation manager.
536
537    The resulting default sequence for a <literal>G4TrajectoriesModel</literal> 
538    is shown in <xref linkend="fig.ExtdFuncVis_3" />.
539
540    <figure id="fig.ExtdFuncVis_3">
541    <title>
542    The default sequence for a <literal>G4PhysicalVolumeModel}</literal>
543    </title>
544    <screen>
545    DrawView();
546    |-->ProcessView();
547        |-->ProcessScene();
548            |-->BeginModeling();
549            |-->pModel -> DescribeYourselfTo(*this);
550            |   |-->AddCompound(trajectory);
551            |       |-->trajectory.DrawTrajectory(...);
552            |           |-->DispatchToModel(...);
553            |               |-->model->Draw(...);
554            |                   |-->G4VisManager::Draw(...);
555            |                       |-->BeginPrimitives(objectTransform);
556            |                       |-->AddPrimitive(...);
557            |                       |-->EndPrimitives();
558            |-->EndModeling();
559    </screen>
560    </figure>
561
562  </para></listitem>
563</itemizedlist>
564</para>
565
566</sect3>
567
568<!-- ******************* Section (Level#3) ****************** -->
569<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj">
570<title>
571Dealing with transient objects
572</title>
573
574<para>
575Any visualisable object not defined in the run-duration part of a
576scene is treated as ``transient''.  This includes trajectories, hits
577or anything drawn by the user through the <literal>G4VVisManager</literal>
578user-level interface (unless as part of a run-duration model implementation). 
579A flag, <literal>fReadyForTransients}</literal>, is maintained by
580the scene handler.  In fact, its normal state is <literal>true</literal>, and
581only temporarily, during handling of the run-duration part of the scene, is
582it set to <literal>false</literal> -- see description of ProcessScene,
583<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn" />.
584</para>
585
586<para>
587If the driver supports a graphical database, it is smart to
588distinguish transient and permanent objects.  In this case, every
589<literal>Add</literal> method of the scene handler must be transient-aware. 
590In some cases, it is enough to open a graphical data base component in
591<literal>BeginPrimitives</literal>, fill it in <literal>AddPrimitive</literal> 
592and close it appropriately in <literal>EndPrimitives</literal>
593In others, initialisation is done in <literal>BeginModeling</literal> 
594and consolidation in <literal>EndModeling</literal> -- see
595<literal>G4OpenGLStoredSceneHandler</literal>
596If any <literal>AddSolid</literal> method is
597implemented, then the graphical data base component should be opened
598in <literal>PreAddSolid</literal>, protecting against double opening,
599for example,
600
601<informalexample><programlisting>
602void G4XXXStoredSceneHandler::BeginPrimitives
603(const G4Transform3D&amp; objectTransformation) {
604  G4VSceneHandler::BeginPrimitives(objectTransformation);
605  // If thread of control has already passed through PreAddSolid,
606  // avoid opening a graphical data base component again.
607  if (!fProcessingSolid) {
608</programlisting></informalexample>
609
610for other solids.
611</para>
612
613<para>
614The reason for this distinction is that at end of run the user
615typically wants to display trajectories on a view of the detector,
616then, at the end of the next event
617
618<footnote>
619  <para>
620  There is an option to accumulate trajectories across events and runs
621  -- see commands
622  <literal>/vis/scene/endOfEventAction</literal> and
623  <literal>/vis/scene/endOfRunAction</literal>.
624  </para>
625</footnote>
626
627, erase the old and see new trajectories.  The visualisation manager
628messages the scene handler with <literal>ClearTransientStore</literal> 
629just before drawing the trajectories to achieve this.
630</para>
631
632<para>
633If the driver does not have a graphical database or does not
634distinguish between transient and persistent objects, it must emulate
635<literal>ClearTransientStore</literal>.  Typically, it must erase everything,
636including the detector, and re-draw the detector and other run-duration
637objects, ready for the transients to be added.  File-writing drivers must
638rewind the output file.  Typically:
639
640<informalexample><programlisting>
641void G4HepRepFileSceneHandler::ClearTransientStore() {
642  G4VSceneHandler::ClearTransientStore();
643  // This is typically called after an update and before drawing hits
644  // of the next event.  To simulate the clearing of "transients"
645  // (hits, etc.) the detector is redrawn...
646  if (fpViewer) {
647    fpViewer -&gt; SetView();
648    fpViewer -&gt; ClearView();
649    fpViewer -&gt; DrawView();
650  }
651}
652</programlisting></informalexample>
653</para>
654
655<para>
656<literal>ClearView</literal> rewinds the output file and
657<literal>DrawView</literal> re-draws the detector, etc. 
658(For smart drivers, <literal>DrawView</literal> is smart enough to
659know not to redraw the detector, etc., unless the view parameters have
660changed significantly -- see
661<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtDrwVw" />)
662</para>
663
664</sect3>
665
666<!-- ******************* Section (Level#3) ****************** -->
667<sect3 id="sect.sect.ExtdFuncVis.CrtGrpDrv.MrScnMdl">
668<title>
669More about scene models
670</title>
671
672<para>
673Scene models conform to the <literal>G4VModel</literal> abstract interface.
674Available models are listed and described there in varying detail.
675<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn" /> describes their
676use in some common command actions.
677</para>
678
679<para>
680In the design of a new model, care should be taken to handle the
681possibility that the <literal>G4ModelingParameters</literal> pointer is zero.
682Currently the only use of the modeling parameters is to communicate
683the culling policy.  Most models, therefore, have no need for modeling
684parameters.
685</para>
686
687</sect3>
688</sect2>
689
690<!-- ******************* Section (Level#2) ****************** -->
691<sect2 id="sect.ExtdFuncVis.EnhcTrjDrw">
692<title>
693Enhanced Trajectory Drawing
694</title>
695
696<!-- ******************* Section (Level#3) ****************** -->
697<sect3 id="sect.ExtdFuncVis.EnhcTrjDrw.CrtTrjMdl">
698<title>
699Creating a new trajectory model
700</title>
701
702<para>
703New trajectory models must inherit from G4VTrajectoryModel and
704implement these pure virtual functions:
705
706<informalexample><programlisting>
707    virtual void Draw(const G4VTrajectory&amp;, G4int i_mode = 0,
708                      const G4bool&amp; visible = true) const = 0;
709    virtual void Print(std::ostream&amp; ostr) const = 0;
710</programlisting></informalexample>
711</para>
712
713<para>
714To use the new model directly in compiled code, simply
715register it with the G4VisManager, eg:
716
717<informalexample><programlisting>
718  G4VisManager* visManager = new G4VisExecutive;
719  visManager-&gt;Initialise();
720
721  // Create custom model
722  MyCustomTrajectoryModel* myModel =
723             new MyCustomTrajectoryModel("custom");
724
725  // Configure it if necessary then register with G4VisManager
726  ...
727  visManager-&gt;RegisterModel(myModel);
728</programlisting></informalexample>
729</para>
730
731</sect3>
732
733<!-- ******************* Section (Level#3) ****************** -->
734<sect3 id="sect.ExtdFuncVis.EnhcTrjDrw.AddIntFunc">
735<title>
736Adding interactive functionality
737</title>
738
739<para>
740Additional classes need to be written if the new model is to
741be created and configured interactively:
742
743<itemizedlist spacing="compact">
744  <listitem><para>
745    <emphasis role="bold">Messenger classes</emphasis>
746    </para>
747    <para>
748    Messengers to configure the model should inherit from
749    G4VModelCommand. The concrete trajectory model type should be
750    used for the template parameter, eg:
751
752    <informalexample><programlisting>
753    class G4MyCustomModelCommand
754          : public G4VModelCommand&lt;G4TrajectoryDrawByParticleID&gt; {
755    ...
756    };
757    </programlisting></informalexample>
758 
759    A number of general use templated commands are available in
760    G4ModelCommandsT.hh.
761  </para></listitem>
762  <listitem><para>
763    <emphasis role="bold">Factory class</emphasis>
764    </para>
765    <para>
766    A factory class responsible for the model and associated messenger
767    creation must also be written. The factory should inherit from
768    G4VModelFactory. The abstract model type should be used for the
769    template parameter, eg:
770
771    <informalexample><programlisting>
772    class G4TrajectoryDrawByChargeFactory
773       : public G4VModelFactory&lt;G4VTrajectoryModel&gt; {
774     ...
775    };
776    </programlisting></informalexample>
777
778    The model and associated messengers should be constructed in the Create
779    method. Optionally, a context object can also be created, with its own
780    associated messengers. For example:
781
782    <informalexample><programlisting>
783    ModelAndMessengers
784    G4TrajectoryDrawByParticleIDFactory::
785        Create(const G4String&amp; placement, const G4String&amp; name)
786    { 
787      // Create default context and model
788      G4VisTrajContext* context = new G4VisTrajContext("default");
789      G4TrajectoryDrawByParticleID* model =
790                  new G4TrajectoryDrawByParticleID(name, context);
791
792      // Create messengers for default context configuration
793      AddContextMsgrs(context, messengers, placement+"/"+name);
794
795      // Create messengers for drawer
796      messengers.push_back(new
797        G4ModelCmdSetStringColour&lt;G4TrajectoryDrawByParticleID&gt;
798                                               (model, placement));
799      messengers.push_back(new
800        G4ModelCmdSetDefaultColour&lt;G4TrajectoryDrawByParticleID&gt;
801                                               (model, placement));
802      messengers.push_back(new
803        G4ModelCmdVerbose&lt;G4TrajectoryDrawByParticleID&gt;
804                                               (model, placement));
805
806      return ModelAndMessengers(model, messengers);
807    }
808    </programlisting></informalexample>
809  </para></listitem>
810</itemizedlist>
811</para>
812
813<para>
814The new factory must then be registered with the visualisation manager.
815This should be done by overriding the G4VisManager::RegisterModelFactory
816method in a subclass. See, for example, the G4VisManager implementation:
817
818<informalexample><programlisting>
819G4VisExecutive::RegisterModelFactories()
820{
821   ...
822   RegisterModelFactory(new G4TrajectoryDrawByParticleIDFactory());
823}
824</programlisting></informalexample>
825</para>
826
827</sect3>
828</sect2>
829
830<!-- ******************* Section (Level#2) ****************** -->
831<sect2 id="sect.ExtdFuncVis.TrjFltr">
832<title>
833Trajectory Filtering
834</title>
835
836<!-- ******************* Section (Level#3) ****************** -->
837<sect3 id="sect.ExtdFuncVis.TrjFltr.CrtTrjFltr">
838<title>
839Creating a new trajectory filter model
840</title>
841
842<para>
843New trajectory filters must inherit at least from G4VFilter. The
844models supplied with the Geant4 distribution inherit from
845G4SmartFilter, which implements some specialisations on top of
846G4VFilter. The models implement these pure virtual functions:
847
848<informalexample><programlisting>
849  // Evaluate method implemented in subclass
850  virtual G4bool Evaluate(const T&amp;) = 0;
851
852  // Print subclass configuration
853  virtual void Print(std::ostream&amp; ostr) const = 0;
854</programlisting></informalexample>
855</para>
856
857<para>
858To use the new filter model directly in compiled code, simply
859register it with the G4VisManager, eg:
860
861<informalexample><programlisting>
862  G4VisManager* visManager = new G4VisExecutive;
863  visManager-&gt;Initialise();
864
865  // Create custom model
866  MyCustomTrajectoryFilterModel* myModel =
867        new MyCustomTrajectoryFilterModel("custom");
868
869  // Configure it if necessary then register with G4VisManager
870  ...
871  visManager-&gt;RegisterModel(myModel);
872</programlisting></informalexample>
873</para>
874
875</sect3>
876
877<!-- ******************* Section (Level#3) ****************** -->
878<sect3 id="sect.ExtdFuncVis.TrjFltr.AddIntFunc">
879<title>
880Adding interactive functionality
881</title>
882
883<para>
884Additional classes need to be written if the new model is to
885be created and configured interactively. The mechanism is exactly
886the same as that used to create enchanced trajectory drawing
887models and associated messengers. See the filter factories in
888G4TrajectoryFilterFactories for example implementations.
889</para>
890
891</sect3>
892</sect2>
893
894<!-- ******************* Section (Level#2) ****************** -->
895<sect2 id="sect.ExtdFuncVis.OthrRsrc">
896<title>
897Other Resources
898</title>
899
900<para>
901The following sections contain various information for extending
902other class functionalities of Geant4 visualisation:
903
904<itemizedlist spacing="compact">
905  <listitem><para>
906    User's Guide for Application Developers, Chapter 8 - Visualization
907  </para></listitem>
908  <listitem><para>
909    User's Guide for Toolkit Developers, Object-oriented Analysis
910    and Design of Geant4 Classes, <xref linkend="sect.DsgnFuncVis" />.
911  </para></listitem>
912</itemizedlist>
913</para>
914
915</sect2>
916
917<!-- ******* Bridgehead ******* -->
918<bridgehead role="revisionHistory" renderas="sect4">
919[Status of this chapter]
920</bridgehead>
921<para>
922<simplelist type="var">
923  <member>
924    03.12.05 ``Enhanced Trajectory Drawing'' added by Jane Tinsley.
925  </member>
926  <member>
927    03.12.05 ``Creating a new visualisation driver'' (from Part II)
928    by John Allison.
929  </member>
930  <member>
931    09.01.06 ``Creating a new visualisation driver'' considerably expanded
932    by John Allison.
933  </member>
934  <member>
935    20.06.06 Some sections improved or added from draft vis paper. 
936    John Allison.
937  </member>
938  <member>
939    Dec. 2006 Conversion from latex to Docbook verson by K. Amako
940  </member>
941</simplelist>
942</para>
943   
944
945</sect1>
Note: See TracBrowser for help on using the repository browser.