source: trunk/documents/UserDoc/UsersGuides/ForToolkitDeveloper/latex/GuideToExtendFunctionality/Visualization/visualization.tex@ 1215

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

CVS update

File size: 25.4 KB
Line 
1\newcommand{\Gfour}{{\sc Geant4}\xspace}
2\newcommand{\GI}{Graphics Interface\xspace}
3\newcommand{\GVS}{\Gfour Visualisation System\xspace}
4\newcommand{\GVM}{\Gfour Visualisation Manager\xspace}
5\newcommand{\gd}{graphics driver\xspace}
6\newcommand{\gds}{graphics drivers\xspace}
7\newcommand{\gs}{graphics system\xspace}
8\newcommand{\gss}{graphics systems\xspace}
9\newcommand{\vs}{visualisation system\xspace}
10\newcommand{\vm}{visualisation manager\xspace}
11\newcommand{\UGA}{User Guide for Application Developers\xspace}
12\newcommand{\UGT}{User Guide for Toolkit Developers\xspace}
13\newcommand{\SRM}{Software Reference Manual\xspace}
14
15\chapter{Visualisation}
16\label{ExtendChapVis}
17
18This Chapter is intended to be read after Chapter \ref{OOChapVis} on
19Visualisation object oriented design in Part II. Many of the concepts
20used here are defined there, and it strongly recommended that a writer
21of a new visualisation driver or trajectory drawer reads Chapter
22\ref{OOChapVis} first. The class structure described there is
23summarised in the Figure \ref{VisClassDiagram}.
24
25\begin{figure}
26\begin{center}
27\includegraphics[width=\linewidth]{GuideToExtendFunctionality/Visualization/visClassDiagram.eps}
28\caption{Geant Visualisation System Class Diagram}
29\label{VisClassDiagram}
30\end{center}
31\end{figure}
32
33\section{Creating a new \gd}
34
35To create a new \gd for {\sc Geant4}, it is necessary to implement a
36new set of three classes derived from the three base classes, {\tt
37G4VGraphicsSystem}, {\tt G4VSceneHandler} and {\tt G4VViewer}.
38
39\subsection{A useful place to start}
40
41A skeleton set of classes is included in the code distribution in the
42visualisation category under subdirectory {\tt visualisation/XXX} (but
43they are not default-registered graphics systems\footnote{To do this,
44simply instantiate and register, for example: {\tt
45visManager->\-RegisterGraphicsSystem(new G4XXX)} before {\tt
46visManager->Initialise()}.}). There are several sets of classes,
47described in more detail below. A recommended approach is to copy the
48files that best match your \gs to a new subdirectory with a name that
49suits your \gs. Then
50\begin{enumerate}
51\item Change the name of the files (change the code -- {\tt XXX} or
52{\tt XXXFile}, etc., as chosen -- to something that suits your \gs).
53\item Change {\tt XXX} similarly in all files.
54\item Change {\tt XXX} similarly in {\tt name := G4XXX} in {\tt GNUmakefile}.
55\item Add your new subdirectory to {\tt SUBDIRS} and {\tt SUBLIBS} in
56{\tt visualisation/GNUmakefile}.
57\item Look at the code and use it to build your visualisation
58driver. You might also find it useful to look at {\tt ASCIITree} (and
59{\tt VTree}) as an example of a minimal \gd. Look at
60{\tt FukuiRenderer} as an example of a driver which implements {\tt AddSolid}
61methods for some solids. Look at {\tt OpenGL} as an example of a driver
62which implements a graphical database (display lists) and the
63machinery to decide when to rebuild. (OpenGL is complicated by the
64proliferation of combinations of the use or not of display lists for
65three window systems, X-windows, X with motif (interactive), Microsoft
66Windows (Win32), a total of six combinations, and much use is made of
67inheritance to avoid code duplication.)
68\item If it requires external libraries, introduce two new environment
69 variables {\tt G4VIS\_BUILD\_XXX\_DRIVER} and {\tt G4VIS\_USE\_XXX}
70 (where {\tt XXX} is your choice as above) and make the modifications to:
71\begin{itemize}
72\item {\tt source/visualization/management/include/G4VisExecutive.icc}
73\item {\tt config/G4VIS\_BUILD.gmk}
74\item {\tt config/G4VIS\_USE.gmk}
75\end{itemize}
76\end{enumerate}
77
78\subsubsection{Graphics driver templates in the {\tt XXX} sub-category}
79\label{XXXsub}
80
81You may use the following templates to help you get started writing a
82\gd. (The word ``template'' is used in the ordinary sense of the
83word; they are not C++ templates.)
84
85\begin{itemize}
86
87\item{\tt G4XXX, G4XXXSceneHandler, G4XXXViewer} Templates for the
88simplest possible \gd. These would be suitable for an ``immediate''
89driver, i.e., one which renders each object immediately to a screen.
90Of course, if the view needs re-drawing, as, for example, after a
91change of viewpoint, the viewer requests a re-issue of drawn
92objects.
93
94\item{\tt G4XXXFile, G4XXXFileSceneHandler, G4XXXFileViewer} Templates
95for a file-writing graphics driver. The particular features are:
96delayed opening of the file on receipt of the first item; rewinding
97file on ClearView (to simulate the clearing of views and prevent the
98duplication of material in the file); closing of the file on ShowView,
99which may also trigger the launch of a browser. There are various
100degrees of sophistication in, for example, the allocation of filenames
101-- see {\tt FukuiRenderer} or {\tt HepRepFile}.
102
103These templates also show the use of a specific {\tt AddSolid} function
104whereby the specific parameters, for example, the dimensions of a {\tt
105G4Box}, can be accessed.
106
107\item{\tt G4XXXStored, G4XXXStoredSceneHandler, G4XXXStoredViewer}
108Templates for a graphics driver with a store/database. The advantage
109of a store is that the view can be refreshed, for example, from a
110different viewpoint, without a need to recompute. It is up to the
111viewer to decide when a re-computation is necessary. They also show how
112to distinguish between permanent and transient objects -- see also
113Section \ref{Transients}.
114
115\item{\tt G4XXXSG, G4XXXSGSceneHandler, G4XXXSGViewer} Templates for a
116sophisticated \gd with a scene graph. The scene graph, following Open
117Inventor parlance, is a tree of objects that dictates the order in
118which the objects are rendered. It obviously lends itself to the
119rendering of the \Gfour geometry hierarchy. For example, the Open
120Inventor driver draws only the top level volumes unless made invisible
121by picking. Thus the user can unwrap a branch of the geometry level
122by level. This has performance benefits and gives the user significant
123and useful control over the view. These classes show how to make a
124scene graph of {\em drawn} volumes, i.e., the set of volumes that have
125not been culled. (Normally, volumes marked invisible are culled,
126i.e., not drawn. Also, the user may wish to limit the number of drawn
127volumes for performance reasons.) The drivers also have to process
128non-geometry items and distinguish between transient and permanent
129objects as above.
130\end{itemize}
131
132\subsection{Important Command Actions}
133\label{Actions}
134
135To help understand how the \GVS works, here are a few important
136function invocation sequences that follow user commands. For an
137explanation of the commands themselves, see command guidance or the
138Control section of the Application Developers Guide. For a
139fuller explanation of the functions, see appropriate base class head
140files or Software Reference Manual.
141
142\begin{itemize}
143
144\item{\tt /vis/viewer/clear}
145\begin{verbatim}
146 viewer->ClearView(); // Clears buffer or rewinds file.
147 viewer->FinishView(); // Swaps buffer (double buffer systems).
148\end{verbatim}
149
150\item{\tt /vis/viewer/flush}
151\begin{verbatim}
152 /vis/viewer/refresh
153 /vis/viewer/update
154\end{verbatim}
155
156\item{\tt /vis/viewer/rebuild}
157\begin{verbatim}
158 viewer->SetNeedKernelVisit(true);
159\end{verbatim}
160
161\item{\tt /vis/viewer/refresh} If the view is ``auto-refresh'', this
162command is also invoked after {\tt /vis/viewer/create}, {\tt
163/vis/viewer/rebuild} or a change of view parameters ({\tt
164/vis/viewer/set/}..., etc.).
165\begin{verbatim}
166 viewer->SetView(); // Sets camera position, etc.
167 viewer->ClearView(); // Clears buffer or rewinds file.
168 viewer->DrawView(); // Draws to screen or writes to
169 // file/socket.
170\end{verbatim}
171
172\item{\tt /vis/viewer/update}
173\begin{verbatim}
174 viewer->ShowView(); // Activates interactive windows or
175 // closes file and/or triggers
176 // post-processing.
177\end{verbatim}
178
179\item{\tt /vis/scene/notifyHandlers} For each viewer of the current
180scene, the equivalent of
181\begin{verbatim}
182 /vis/viewer/refresh
183\end{verbatim}
184If ``flush'' is specified on the command line, the equivalent of
185\begin{verbatim}
186 /vis/viewer/update
187\end{verbatim}
188{\tt /vis/scene/notifyHandlers} is also invoked after a change
189of scene ({\tt /vis/scene/add/}..., etc.).
190
191\end{itemize}
192
193\subsection{What happens in {\tt DrawView}?}
194\label{DrawView}
195
196This depends on the viewer. Those with their own graphical database,
197for example, OpenGL's display lists or Open Inventor's scene graph, do
198not need to re-traverse the scene unless there has been a significant
199change of view parameters. For example, a mere change of viewpoint
200requires only a change of model-view matrix whilst a change of
201rendering mode from wireframe to surface might require a rebuild of
202the graphical database. A rebuild of the run-duration (persistent)
203objects in the scene is called a ``kernel visit''; the viewer prints
204``Traversing scene data...''.
205
206Note that end-of-event (transient) objects are only rebuilt at the end
207of an event or run, under control of the visualisation manager. Smart
208scene handlers keep them in separate display lists so that they can be
209rebuilt separately from the run-duration objects - see Section
210\ref{Transients}.
211
212\begin{itemize}
213
214\item{\bf Integrated viewers with no graphical database} For example,
215G4OpenGLImmediateXViewer::DrawView().
216\begin{verbatim}
217 NeedKernelVisit(); // Always need to visit G4 kernel.
218 ProcessView();
219 FinishView();
220\end{verbatim}
221
222\item{\bf Integrated viewers with graphical database} For example,\\
223G4OpenGLStoredXViewer::DrawView().
224\begin{verbatim}
225 KernelVisitDecision(); // Private function containing...
226 if significant change of view parameters...
227 NeedKernelVisit();
228 ProcessView();
229 FinishView();
230\end{verbatim}
231
232\item{\bf File-writing viewers} For example, G4DAWNFILEViewer::DrawView().
233\begin{verbatim}
234 NeedKernelVisit();
235 ProcessView();
236\end{verbatim}
237
238Note that viewers needing to invoke {\tt FinishView} must do it in
239{\tt DrawView}.
240
241\end{itemize}
242
243\subsection{What happens in {\tt ProcessView}?}
244
245{\tt ProcessView} is inherited from {\tt G4VViewer}:
246
247\begin{verbatim}
248void G4VViewer::ProcessView() {
249 // If ClearStore has been requested, e.g., if the scene has changed,
250 // of if the concrete viewer has decided that it necessary to visit
251 // the kernel, perhaps because the view parameters have changed
252 // drastically (this should be done in the concrete viewer's
253 // DrawView)...
254 if (fNeedKernelVisit) {
255 fSceneHandler.ProcessScene(*this);
256 fNeedKernelVisit = false;
257 }
258}
259\end{verbatim}
260
261\subsection{What happens in {\tt ProcessScene}?}
262\label{ProcessScene}
263
264ProcessScene is inherited from {\tt G4VSceneHandler}. It causes a
265traversal of the run-duration models in the scene. For drivers with
266graphical databases, it causes a rebuild ({\tt ClearStore}). Then for
267the run-duration models:
268\begin{verbatim}
269 fReadyForTransients = false;
270 BeginModeling();
271 for each run-duration model...
272 pModel -> DescribeYourselfTo(*this);
273 EndModeling();
274 fReadyForTransients = true;
275\end{verbatim}
276(A second pass is made on request -- see {\tt
277G4VSceneHandler::ProcessScene}.) The use of {\tt fReadyForTransients}
278is described in Section \ref{Transients}.
279
280What happens then depends on the type of model:
281
282\begin{itemize}
283
284\item{\tt G4AxesModel} {\tt G4AxesModel::DescribeYourselfTo} simply calls
285sceneHandler.AddPrimitive methods directly.
286\begin{verbatim}
287 sceneHandler.BeginPrimitives();
288 sceneHandler.AddPrimitive(x_axis); // etc.
289 sceneHandler.EndPrimitives();
290\end{verbatim}
291
292Most other models are like this, except for the following...
293
294\item{\tt G4PhysicalVolumeModel} The geometry is descended
295 recursively, culling policy is enacted, and for each accepted (and
296 possibly, clipped) solid:
297\begin{verbatim}
298 sceneHandler.PreAddSolid(theAT, *pVisAttribs);
299 pSol->DescribeYourselfTo(sceneHandler);
300 // For example, if pSol points to a G4Box...
301 |-->G4Box::DescribeYourselfTo(G4VGraphicsScene& scene){
302 scene.AddSolid(*this);
303 }
304 sceneHandler.PostAddSolid();
305\end{verbatim}
306
307The scene handler may implement the virtual function {\tt
308AddSolid(const G4Box\&)}, or inherit:
309\begin{verbatim}
310void G4VSceneHandler::AddSolid(const G4Box& box) {
311 RequestPrimitives(box);
312}
313\end{verbatim}
314
315{\tt RequestPrimitives} converts the solid into primitives ({\tt G4Polyhedron})
316and invokes {\tt AddPrimitive}:
317\begin{verbatim}
318 BeginPrimitives(*fpObjectTransformation);
319 pPolyhedron = solid.GetPolyhedron();
320 AddPrimitive(*pPolyhedron);
321 EndPrimitives();
322\end{verbatim}
323
324The resulting default sequence for a {\tt G4PhysicalVolumeModel} is shown in
325Figure \ref{FigPVModel}.
326\begin{figure}[t]
327\begin{boxedverbatim}
328 DrawView();
329 |-->ProcessView();
330 |-->ProcessScene();
331 |-->BeginModeling();
332 |-->pModel -> DescribeYourselfTo(*this);
333 | |-->sceneHandler.PreAddSolid(theAT, *pVisAttribs);
334 | |-->pSol->DescribeYourselfTo(sceneHandler);
335 | | |-->sceneHandler.AddSolid(*this);
336 | | |-->RequestPrimitives(solid);
337 | | |-->BeginPrimitives (*fpObjectTransformation);
338 | | |-->pPolyhedron = solid.GetPolyhedron();
339 | | |-->AddPrimitive(*pPolyhedron);
340 | | |-->EndPrimitives();
341 | |-->sceneHandler.PostAddSolid();
342 |-->EndModeling();
343\end{boxedverbatim}
344\caption{The default sequence for a {\tt G4PhysicalVolumeModel}}
345\label{FigPVModel}
346\end{figure}
347
348Note the sequence of calls at the core:
349\begin{verbatim}
350 sceneHandler.PreAddSolid(theAT, *pVisAttribs);
351 pSol->DescribeYourselfTo(sceneHandler);
352 |-->sceneHandler.AddSolid(*this);
353 |-->RequestPrimitives(solid);
354 |-->BeginPrimitives (*fpObjectTransformation);
355 |-->pPolyhedron = solid.GetPolyhedron();
356 |-->AddPrimitive(*pPolyhedron);
357 |-->EndPrimitives();
358 sceneHandler.PostAddSolid();
359\end{verbatim}
360is reduced to
361\begin{verbatim}
362 sceneHandler.PreAddSolid(theAT, *pVisAttribs);
363 pSol->DescribeYourselfTo(sceneHandler);
364 |-->sceneHandler.AddSolid(*this);
365 sceneHandler.PostAddSolid();
366\end{verbatim}
367if the scene handler implements its own {\tt AddSolid}. Moreover, the sequence
368\begin{verbatim}
369 BeginPrimitives (*fpObjectTransformation);
370 AddPrimitive(*pPolyhedron);
371 EndPrimitives();
372\end{verbatim}
373can be invoked without a prior {\tt PreAddSolid}, etc. The flag {\tt
374fProcessingSolid} will be false for the last case. The possibility of
375any or all of these three scenarios occurring, for both permanent and
376transient objects, affects the implementation of a scene handler if
377there is any attempt to build a graphical database. This is reflected
378in the templates {\tt XXXStored} and {\tt XXXSG} described in Section
379\ref{XXXsub}. Transients are discussed in Section \ref{Transients}.
380
381\item{\tt G4TrajectoriesModel} At end of event, the trajectory
382container is unpacked and, for each trajectory,
383{\tt sceneHandler.AddCompound} called. The scene handler may implement this
384virtual function or inherit:
385\begin{verbatim}
386void G4VSceneHandler::AddCompound (const G4VTrajectory& traj) {
387 traj.DrawTrajectory(((G4TrajectoriesModel*)fpModel)->GetDrawingMode());
388}
389\end{verbatim}
390Similarly, the user may implement {\tt DrawTrajectory} or inherit:
391\begin{verbatim}
392void G4VTrajectory::DrawTrajectory(G4int i_mode) const {
393 G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
394 if (0 != pVVisManager) {
395 pVVisManager->DispatchToModel(*this, i_mode);
396 }
397}
398\end{verbatim}
399Thence, the {\tt Draw} method of the current trajectory model is invoked
400(see Section \ref{EnhancedTraj} for details on trajectory models),
401which in turn, invokes {\tt Draw} methods of the visualisation manager.
402The resulting default sequence for a {\tt G4TrajectoriesModel} is shown in
403Figure \ref{FigTrajsModel}.
404\begin{figure}[t]
405\begin{boxedverbatim}
406 DrawView();
407 |-->ProcessView();
408 |-->ProcessScene();
409 |-->BeginModeling();
410 |-->pModel -> DescribeYourselfTo(*this);
411 | |-->AddCompound(trajectory);
412 | |-->trajectory.DrawTrajectory(...);
413 | |-->DispatchToModel(...);
414 | |-->model->Draw(...);
415 | |-->G4VisManager::Draw(...);
416 | |-->BeginPrimitives(objectTransform);
417 | |-->AddPrimitive(...);
418 | |-->EndPrimitives();
419 |-->EndModeling();
420\end{boxedverbatim}
421\caption{The default sequence for a G4TrajectoriesModel}
422\label{FigTrajsModel}
423\end{figure}
424
425\end{itemize}
426
427
428\subsection{Dealing with transient objects}
429\label{Transients}
430
431Any visualisable object not defined in the run-duration part of a
432scene is treated as ``transient''. This includes trajectories, hits
433or anything drawn by the user through the {\tt G4VVisManager}
434user-level interface (unless as part of a run-duration model
435implementation). A flag, {\tt fReadyForTransients}, is maintained by
436the scene handler. In fact, its normal state is {\tt true}, and only
437temporarily, during handling of the run-duration part of the scene, is
438it set to {\tt false} -- see description of ProcessScene, Section
439\ref{ProcessScene}.
440
441If the driver supports a graphical database, it is smart to
442distinguish transient and permanent objects. In this case, every {\tt
443Add} method of the scene handler must be transient-aware. In some
444cases, it is enough to open a graphical data base component in {\tt
445BeginPrimitives}, fill it in {\tt AddPrimitive} and close it
446appropriately in {\tt EndPrimitives}. In others, initialisation is
447done in {\tt BeginModeling} and consolidation in {\tt EndModeling} --
448see {\tt G4OpenGLStoredSceneHandler}. If any {\tt AddSolid} method is
449implemented, then the graphical data base component should be opened
450in {\tt PreAddSolid}, protecting against double opening, for example,
451\begin{verbatim}
452void G4XXXStoredSceneHandler::BeginPrimitives
453(const G4Transform3D& objectTransformation) {
454 G4VSceneHandler::BeginPrimitives(objectTransformation);
455 // If thread of control has already passed through PreAddSolid,
456 // avoid opening a graphical data base component again.
457 if (!fProcessingSolid) {
458\end{verbatim}
459for other solids.
460
461The reason for this distinction is that at end of run the user
462typically wants to display trajectories on a view of the detector,
463then, at the end of the next event\footnote{There is an option to
464accumulate trajectories across events and runs -- see commands {\tt
465/vis/scene/endOfEventAction} and {\tt /vis/scene/endOfRunAction}.},
466erase the old and see new trajectories. The \vm messages the scene
467handler with {\tt ClearTransientStore} just before drawing the
468trajectories to achieve this.
469
470If the driver does not have a graphical database or does not
471distinguish between transient and persistent objects, it must emulate
472{\tt ClearTransientStore}. Typically, it must erase everything, including
473the detector, and re-draw the detector and other run-duration objects,
474ready for the transients to be added. File-writing drivers must
475rewind the output file. Typically:
476\begin{verbatim}
477void G4HepRepFileSceneHandler::ClearTransientStore() {
478 G4VSceneHandler::ClearTransientStore();
479 // This is typically called after an update and before drawing hits
480 // of the next event. To simulate the clearing of "transients"
481 // (hits, etc.) the detector is redrawn...
482 if (fpViewer) {
483 fpViewer -> SetView();
484 fpViewer -> ClearView();
485 fpViewer -> DrawView();
486 }
487}
488\end{verbatim}
489{\tt ClearView} rewinds the output file and {\tt DrawView} re-draws the
490detector, etc. (For smart drivers, {\tt DrawView} is smart enough to
491know not to redraw the detector, etc., unless the view parameters have
492changed significantly -- see Section \ref{DrawView}.)
493
494
495\subsection{More about scene models}
496
497Scene models conform to the {\tt G4VModel} abstract interface.
498Available models are listed and described there in varying detail.
499Section \ref{ProcessScene} describes their use in some common command
500actions.
501
502In the design of a new model, care should be taken to handle the
503possibility that the {\tt G4ModelingParameters} pointer is zero.
504Currently the only use of the modeling parameters is to communicate
505the culling policy. Most models, therefore, have no need for modeling
506parameters.
507
508
509\section{Enhanced Trajectory Drawing}
510\label{EnhancedTraj}
511\subsection{Creating a new trajectory model}
512New trajectory models must inherit from G4VTrajectoryModel and
513implement these pure virtual functions:
514
515\begin{verbatim}
516 virtual void Draw(const G4VTrajectory&, G4int i_mode = 0,
517 const G4bool& visible = true) const = 0;
518 virtual void Print(std::ostream& ostr) const = 0;
519\end{verbatim}
520
521To use the new model directly in compiled code, simply
522register it with the G4VisManager, eg:
523
524\begin{verbatim}
525 G4VisManager* visManager = new G4VisExecutive;
526 visManager->Initialise();
527
528 // Create custom model
529 MyCustomTrajectoryModel* myModel =
530 new MyCustomTrajectoryModel("custom");
531
532 // Configure it if necessary then register with G4VisManager
533 ...
534 visManager->RegisterModel(myModel);
535\end{verbatim}
536
537\subsection{Adding interactive functionality}
538
539Additional classes need to be written if the new model is to
540be created and configured interactively:
541
542\begin{itemize}
543\item {\bf Messenger classes}
544
545 Messengers to configure the model should inherit from
546G4VModelCommand. The concrete trajectory model type should be
547used for the template parameter, eg:
548
549\begin{verbatim}
550 class G4MyCustomModelCommand
551 : public G4VModelCommand<G4TrajectoryDrawByParticleID> {
552 ...
553 };
554
555\end{verbatim}
556
557A number of general use templated commands are available in
558G4ModelCommandsT.hh.
559
560\item {\bf Factory class}
561
562A factory class responsible for the model and associated messenger
563creation must also be written. The factory should inherit from
564G4VModelFactory. The abstract model type should be used for the
565template parameter, eg:
566\begin{verbatim}
567 class G4TrajectoryDrawByChargeFactory
568 : public G4VModelFactory<G4VTrajectoryModel> {
569 ...
570 };
571\end{verbatim}
572
573The model and associated messengers should be constructed in the Create
574method. Optionally, a context object can also be created, with its own
575associated messengers. For example:
576
577\begin{verbatim}
578ModelAndMessengers
579G4TrajectoryDrawByParticleIDFactory::
580 Create(const G4String& placement, const G4String& name)
581{
582 // Create default context and model
583 G4VisTrajContext* context = new G4VisTrajContext("default");
584 G4TrajectoryDrawByParticleID* model =
585 new G4TrajectoryDrawByParticleID(name, context);
586
587 // Create messengers for default context configuration
588 AddContextMsgrs(context, messengers, placement+"/"+name);
589
590 // Create messengers for drawer
591 messengers.push_back(new
592 G4ModelCmdSetStringColour<G4TrajectoryDrawByParticleID>
593 (model, placement));
594 messengers.push_back(new
595 G4ModelCmdSetDefaultColour<G4TrajectoryDrawByParticleID>
596 (model, placement));
597 messengers.push_back(new
598 G4ModelCmdVerbose<G4TrajectoryDrawByParticleID>
599 (model, placement));
600
601 return ModelAndMessengers(model, messengers);
602}
603\end{verbatim}
604
605\end{itemize}
606
607The new factory must then be registered with the visualisation manager.
608This should be done by overriding the G4VisManager::RegisterModelFactory
609method in a subclass. See, for example, the G4VisManager implementation:
610\begin{verbatim}
611G4VisExecutive::RegisterModelFactories()
612{
613 ...
614 RegisterModelFactory(new G4TrajectoryDrawByParticleIDFactory());
615}
616\end{verbatim}
617
618
619\section{Trajectory Filtering}
620\label{TrajFilter}
621\subsection{Creating a new trajectory filter model}
622New trajectory filters must inherit at least from G4VFilter. The
623models supplied with the Geant4 distribution inherit from
624G4SmartFilter, which implements some specialisations on top of
625G4VFilter. The models implement these pure virtual functions:
626
627\begin{verbatim}
628 // Evaluate method implemented in subclass
629 virtual G4bool Evaluate(const T&) = 0;
630
631 // Print subclass configuration
632 virtual void Print(std::ostream& ostr) const = 0;
633\end{verbatim}
634
635To use the new filter model directly in compiled code, simply
636register it with the G4VisManager, eg:
637
638\begin{verbatim}
639 G4VisManager* visManager = new G4VisExecutive;
640 visManager->Initialise();
641
642 // Create custom model
643 MyCustomTrajectoryFilterModel* myModel =
644 new MyCustomTrajectoryFilterModel("custom");
645
646 // Configure it if necessary then register with G4VisManager
647 ...
648 visManager->RegisterModel(myModel);
649\end{verbatim}
650
651\subsection{Adding interactive functionality}
652
653Additional classes need to be written if the new model is to
654be created and configured interactively. The mechanism is exactly
655the same as that used to create enchanced trajectory drawing
656models and associated messengers. See the filter factories in
657G4TrajectoryFilterFactories for example implementations.
658
659\section{Other Resources}
660The following sections contain various information for extending
661other class functionalities of {\sc Geant4} visualisation:
662\begin{itemize}
663\item User's Guide for Application Developers, Chapter 8 - Visualization
664\item User's Guide for Toolkit Developers, Object-oriented Analysis
665 and Design of {\sc Geant4} Classes, Chapter \ref{OOChapVis} -
666 Visualisation
667\end{itemize}
668
669\section{Status of this chapter}
670
67103.12.05 ``Enhanced Trajectory Drawing'' added by Jane Tinsley.\\
67203.12.05 ``Creating a new visualisation driver'' (from Part II) by John Allison.\\
67309.01.06 ``Creating a new visualisation driver'' considerably expanded by John Allison.\\
67420.06.06 Some sections improved or added from draft vis paper. John Allison.
Note: See TracBrowser for help on using the repository browser.