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

Last change on this file since 1172 was 921, checked in by garnier, 17 years ago

en test de gl2ps. Problemes de libraries

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.jpg"
28 format="JPG" contentwidth="10.0cm" align="center" />
29 </imageobject>
30 <imageobject role="html">
31 <imagedata fileref="./AllResources/GuideToExtendFunctionality/Visualization/visClassDiagram.jpg"
32 format="JPG" 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.