<!-- ******************************************************** -->
<!--  Docbook Version:  For Toolkit Developers Guide          -->
<!-- ******************************************************** -->

<!-- ******************* Section (Level#1) ****************** -->
<sect1 id="sect.ExtdFuncVis">
<title>
Visualisation
</title>

<para>
This Chapter is intended to be read after Chapter 
<xref linkend="sect.DsgnFuncVis" />
on Visualisation object oriented design in Part II.  Many of the concepts
used here are defined there, and it strongly recommended that a writer
of a new visualisation driver or trajectory drawer reads Chapter
<xref linkend="sect.DsgnFuncVis" /> first.  
The class structure described there is
summarised in <xref linkend="fig.ExtdFuncVis_1" />.

<figure id="fig.ExtdFuncVis_1">
<title>
Geant Visualisation System Class Diagram
</title>
<mediaobject>
  <imageobject role="fo">
    <imagedata fileref="./AllResources/GuideToExtendFunctionality/Visualization/visClassDiagram.jpg" 
               format="JPG" contentwidth="10.0cm" align="center" />
  </imageobject>
  <imageobject role="html">
    <imagedata fileref="./AllResources/GuideToExtendFunctionality/Visualization/visClassDiagram.jpg" 
               format="JPG" contentwidth="120%" align="center" />
  </imageobject>
</mediaobject>
</figure>
</para>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ExtdFuncVis.CrtGrpDrv">
<title>
Creating a new graphics driver
</title>

<para>
To create a new graphics driver for Geant4, it is necessary to implement a
new set of three classes derived from the three base classes, 
<literal>G4VGraphicsSystem</literal>, <literal>G4VSceneHandler </literal>
and <literal>G4VViewer</literal>.
</para>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt">
<title>
A useful place to start
</title>

<para>
A skeleton set of classes is included in the code distribution in the
visualisation category under subdirectory <literal>visualisation/XXX</literal> 
(but they are not default-registered graphics systems
<footnote>
  <para>
  To do this,simply instantiate and register, for example: 
  <literal>visManager-&gt;RegisterGraphicsSystem(new G4XXX)</literal> 
  before <literal>visManager-&gt;Initialise()</literal>.  
  </para>
</footnote>
</para>

<para>
There are several sets of classes, described in more detail below.  
A recommended approach is to copy the files that best match your graphics 
system  to a new subdirectory with a name that suits your graphics system .  
</para>

<para>
Then

<orderedlist spacing="compact">
  <listitem><para>
    Change the name of the files (change the code -- <literal>XXX</literal> or
    <literal>XXXFile</literal>, etc., as chosen -- to something that suits 
    your graphics system ).
  </para></listitem>
  <listitem><para>
    Change <literal>XXX</literal> similarly in all files.
  </para></listitem>
  <listitem><para>
    Change <literal>XXX</literal> similarly in <literal>name := G4XXX</literal> 
    in <literal>GNUmakefile</literal>.
  </para></listitem>
  <listitem><para>
    Add your new subdirectory to <literal>SUBDIRS</literal> and 
    <literal>SUBLIBS</literal> in <literal>visualisation/GNUmakefile</literal>.
  </para></listitem>
  <listitem><para>
    Look at the code and use it to build your visualisation
    driver. You might also find it useful to look at 
    <literal>ASCIITree</literal> (and <literal>VTree</literal>) as an example 
    of a minimal graphics driver .  Look at <literal>FukuiRenderer</literal> 
    as an example of a driver which implements <literal>AddSolid</literal>
    methods for some solids.  Look at <literal>OpenGL</literal> as an example 
    of a driver which implements a graphical database (display lists) and the
    machinery to decide when to rebuild.  (OpenGL is complicated by the
    proliferation of combinations of the use or not of display lists for
    three window systems, X-windows, X with motif (interactive), Microsoft
    Windows (Win32), a total of six combinations, and much use is made of
    inheritance to avoid code duplication.)
  </para></listitem>
  <listitem><para>
    If it requires external libraries, introduce two new environment
    variables <literal>G4VIS_BUILD_XXX_DRIVER</literal> and 
    <literal>G4VIS_USE_XXX</literal>
    (where <literal>XXX</literal> is your choice as above) and make the 
    modifications to:
    <itemizedlist spacing="compact">
      <listitem><para>
        <literal>source/visualization/management/include/G4VisExecutive.icc</literal>
      </para></listitem>
      <listitem><para>
        <literal>config/G4VIS_BUILD.gmk</literal>
      </para></listitem>
      <listitem><para>
        <literal>config/G4VIS_USE.gmk</literal>
      </para></listitem>
     </itemizedlist>
  </para></listitem>
</orderedlist>
</para>

<!-- ******************* Section (Level#4) ****************** -->
<sect4 id="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt.Tmpl">
<title>
Graphics driver templates in the <literal>XXX</literal> sub-category
</title>

<para>
You may use the following templates to help you get started writing a
graphics driver .  (The word ``template'' is used in the ordinary sense of the
word; they are not C++ templates.)

<itemizedlist spacing="compact">
  <listitem><para>
    <literal>G4XXX, G4XXXSceneHandler, G4XXXViewer</literal> Templates for the
    simplest possible graphics driver . These would be suitable for an ``immediate''
    driver, i.e., one which renders each object immediately to a screen.
    Of course, if the view needs re-drawing, as, for example, after a
    change of viewpoint, the viewer requests a re-issue of drawn
    objects.
  </para></listitem>
  <listitem><para>
    <literal>G4XXXFile, G4XXXFileSceneHandler, G4XXXFileViewer</literal> Templates
    for a file-writing graphics driver.  The particular features are:
    delayed opening of the file on receipt of the first item; rewinding
    file on ClearView (to simulate the clearing of views and prevent the
    duplication of material in the file); closing of the file on ShowView,
    which may also trigger the launch of a browser.  There are various
    degrees of sophistication in, for example, the allocation of filenames
    -- see <literal>FukuiRenderer</literal> or <literal>HepRepFile</literal>.
    </para>
    <para>
    These templates also show the use of a specific <literal>AddSolid</literal> 
    function whereby the specific parameters, for example, the dimensions of a 
    <literal>G4Box</literal>, can be accessed.
  </para></listitem>
  <listitem><para>
    <literal>G4XXXStored, G4XXXStoredSceneHandler, G4XXXStoredViewer</literal>
    Templates for a graphics driver with a store/database.  The advantage
    of a store is that the view can be refreshed, for example, from a
    different viewpoint, without a need to recompute.  It is up to the
    viewer to decide when a re-computation is necessary.  They also show how
    to distinguish between permanent and transient objects -- see also
    Section <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
  </para></listitem>
  <listitem><para>
    <literal>G4XXXSG, G4XXXSGSceneHandler, G4XXXSGViewer</literal> Templates for a
    sophisticated graphics driver  with a scene graph.  The scene graph, following Open
    Inventor parlance, is a tree of objects that dictates the order in
    which the objects are rendered.  It obviously lends itself to the
    rendering of the Geant4 geometry hierarchy.  For example, the Open
    Inventor driver draws only the top level volumes unless made invisible
    by picking.  Thus the user can unwrap a branch of the geometry level
    by level. This has performance benefits and gives the user significant
    and useful control over the view.  These classes show how to make a
    scene graph of <emphasis role="bold">drawn</emphasis> volumes, i.e., 
    the set of volumes that have
    not been culled.  (Normally, volumes marked invisible are culled,
    i.e., not drawn.  Also, the user may wish to limit the number of drawn
    volumes for performance reasons.)  The drivers also have to process
    non-geometry items and distinguish between transient and permanent
    objects as above.
  </para></listitem>
</itemizedlist>
</para>

</sect4>
</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.ImpCmdAct">
<title>
Important Command Actions
</title>

<para>
To help understand how the Geant4 Visualization System works, here are a 
few important function invocation sequences that follow user commands.  
For an explanation of the commands themselves, see command guidance or 
the Control section of the Application Developers Guide.  For a
fuller explanation of the functions, see appropriate base class head
files or Software Reference Manual.

<itemizedlist spacing="compact">
  <listitem><para>
    <literal>/vis/viewer/clear</literal>
    <informalexample><programlisting>
    viewer->ClearView();   // Clears buffer or rewinds file.
    viewer->FinishView();  // Swaps buffer (double buffer systems).
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <literal>/vis/viewer/flush</literal>
    <informalexample><programlisting>
    /vis/viewer/refresh
    /vis/viewer/update
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <literal>/vis/viewer/rebuild</literal>
    <informalexample><programlisting>
    viewer->SetNeedKernelVisit(true);
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <literal>/vis/viewer/refresh</literal> If the view is ``auto-refresh'', this
    command is also invoked after <literal>/vis/viewer/create</literal>, 
    <literal>/vis/viewer/rebuild</literal> or a change of view parameters 
    (<literal>/vis/viewer/set/</literal>..., etc.).  
    <informalexample><programlisting>
    viewer->SetView();    // Sets camera position, etc.
    viewer->ClearView();  // Clears buffer or rewinds file.
    viewer->DrawView();   // Draws to screen or writes to 
                          // file/socket.
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <literal>/vis/viewer/update</literal>
    <informalexample><programlisting>
    viewer->ShowView();   // Activates interactive windows or 
                          // closes file and/or triggers 
                          // post-processing.
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <literal>/vis/scene/notifyHandlers</literal> For each viewer of the current
    scene, the equivalent of
    <informalexample><programlisting>
    /vis/viewer/refresh
    </programlisting></informalexample>
    If ``flush'' is specified on the command line, the equivalent of
    <informalexample><programlisting>
    /vis/viewer/update
    </programlisting></informalexample>
    <literal>/vis/scene/notifyHandlers</literal> is also invoked after a change
    of scene (<literal>/vis/scene/add/</literal>..., etc.).
  </para></listitem>
</itemizedlist>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtDrwVw">
<title>
What happens in <literal>DrawView</literal>?
</title>

<para>
This depends on the viewer.  Those with their own graphical database,
for example, OpenGL's display lists or Open Inventor's scene graph, do
not need to re-traverse the scene unless there has been a significant
change of view parameters.  For example, a mere change of viewpoint
requires only a change of model-view matrix whilst a change of
rendering mode from wireframe to surface might require a rebuild of
the graphical database.  A rebuild of the run-duration (persistent)
objects in the scene is called a ``kernel visit''; the viewer prints
``Traversing scene data...''.
</para>

<para>
Note that end-of-event (transient) objects are only rebuilt at the end
of an event or run, under control of the visualisation manager.  Smart
scene handlers keep them in separate display lists so that they can be
rebuilt separately from the run-duration objects - see 
<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.

<itemizedlist spacing="compact">
  <listitem><para>
    <emphasis role="bold">Integrated viewers with no graphical database</emphasis> 
    For example, <literal>G4OpenGLImmediateXViewer::DrawView()</literal>.
    <informalexample><programlisting>
    NeedKernelVisit();  // Always need to visit G4 kernel.
    ProcessView();
    FinishView();
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <emphasis role="bold">Integrated viewers with graphical database</emphasis> 
    For example, <literal>G4OpenGLStoredXViewer::DrawView()</literal>.
    <informalexample><programlisting>
    KernelVisitDecision();  // Private function containing...
      if significant change of view parameters...
        NeedKernelVisit();
    ProcessView();
    FinishView();
    </programlisting></informalexample>
  </para></listitem>
  <listitem><para>
    <emphasis role="bold">File-writing viewers</emphasis> For example, 
    <literal>G4DAWNFILEViewer::DrawView()</literal>.
    <informalexample><programlisting>
    NeedKernelVisit();
    ProcessView();
    </programlisting></informalexample>

    Note that viewers needing to invoke <literal>FinishView</literal> must do it in
    <literal>DrawView</literal>.
  </para></listitem>
</itemizedlist>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcVw">
<title>
What happens in <literal>ProcessView</literal>?
</title>

<para>
<literal>ProcessView</literal> is inherited from <literal>G4VViewer</literal>:

<informalexample><programlisting>
void G4VViewer::ProcessView() {
  // If ClearStore has been requested, e.g., if the scene has changed,
  // of if the concrete viewer has decided that it necessary to visit
  // the kernel, perhaps because the view parameters have changed
  // drastically (this should be done in the concrete viewer's
  // DrawView)...
  if (fNeedKernelVisit) {
    fSceneHandler.ProcessScene(*this);
    fNeedKernelVisit = false;
  }
}
</programlisting></informalexample>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn">
<title>
What happens in <literal>ProcessScene</literal>?
</title>

<para>
ProcessScene is inherited from <literal>G4VSceneHandler}</literal>.  
It causes a traversal of the run-duration models in the scene.  
For drivers with graphical databases, it causes a rebuild 
(<literal>ClearStore</literal>).  Then for the run-duration models:

<informalexample><programlisting>
    fReadyForTransients = false;
    BeginModeling();
    for each run-duration model...
      pModel -&gt; DescribeYourselfTo(*this);
    EndModeling();
    fReadyForTransients = true;
</programlisting></informalexample>

(A second pass is made on request -- see 
<literal>G4VSceneHandler::ProcessScene</literal>.)  
The use of <literal>fReadyForTransients</literal>
is described in <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
</para>

<para>
What happens then depends on the type of model:

<itemizedlist spacing="compact">
  <listitem><para>
    <literal>G4AxesModel</literal> <literal>G4AxesModel::DescribeYourselfTo</literal> 
    simply calls sceneHandler.AddPrimitive methods directly.

    <informalexample><programlisting>
    sceneHandler.BeginPrimitives();
    sceneHandler.AddPrimitive(x_axis);  // etc.
    sceneHandler.EndPrimitives();
    </programlisting></informalexample>

    Most other models are like this, except for the following...

  </para></listitem>
  <listitem><para>
    <literal>G4PhysicalVolumeModel</literal> The geometry is descended
    recursively, culling policy is enacted, and for each accepted (and
    possibly, clipped) solid:

    <informalexample><programlisting>
    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
    pSol-&gt;DescribeYourselfTo(sceneHandler);
    // For example, if pSol points to a G4Box...
    |--&gt;G4Box::DescribeYourselfTo(G4VGraphicsScene&amp; scene){
         scene.AddSolid(*this);
        }
    sceneHandler.PostAddSolid();
    </programlisting></informalexample>

    The scene handler may implement the virtual function {
    AddSolid(const G4Box&amp;)}, or inherit:

    <informalexample><programlisting>
    void G4VSceneHandler::AddSolid(const G4Box&amp; box) {
      RequestPrimitives(box);
    }
    </programlisting></informalexample>

    <literal>RequestPrimitives</literal> converts the solid into primitives 
    (<literal>G4Polyhedron</literal>) and invokes <literal>AddPrimitive</literal>:

    <informalexample><programlisting>
    BeginPrimitives(*fpObjectTransformation);
    pPolyhedron = solid.GetPolyhedron();
    AddPrimitive(*pPolyhedron);
    EndPrimitives();
    </programlisting></informalexample>

    The resulting default sequence for a <literal>G4PhysicalVolumeModel</literal> 
    is shown in <xref linkend="fig.ExtdFuncVis_2" />.

    <figure id="fig.ExtdFuncVis_2">
    <title>
    The default sequence for a <literal>G4PhysicalVolumeModel}</literal>
    </title>
    <screen>
    DrawView();
    |--&gt;ProcessView();
        |--&gt;ProcessScene();
            |--&gt;BeginModeling();
            |--&gt;pModel -&gt; DescribeYourselfTo(*this);
            |   |--&gt;sceneHandler.PreAddSolid(theAT, *pVisAttribs);
            |   |--&gt;pSol-&gt;DescribeYourselfTo(sceneHandler);
            |   |   |--&gt;sceneHandler.AddSolid(*this);
            |   |       |--&gt;RequestPrimitives(solid);
            |   |           |--&gt;BeginPrimitives (*fpObjectTransformation);
            |   |           |--&gt;pPolyhedron = solid.GetPolyhedron();
            |   |           |--&gt;AddPrimitive(*pPolyhedron);
            |   |           |--&gt;EndPrimitives();
            |   |--&gt;sceneHandler.PostAddSolid();
            |--&gt;EndModeling();
    </screen>
    </figure>

    Note the sequence of calls at the core:

    <informalexample><programlisting>
    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
    pSol-&gt;DescribeYourselfTo(sceneHandler);
    |--&gt;sceneHandler.AddSolid(*this);
       |--&gt;RequestPrimitives(solid);
          |--&gt;BeginPrimitives (*fpObjectTransformation);
          |--&gt;pPolyhedron = solid.GetPolyhedron();
          |--&gt;AddPrimitive(*pPolyhedron);
          |--&gt;EndPrimitives();
    sceneHandler.PostAddSolid();
    </programlisting></informalexample>

    is reduced to

    <informalexample><programlisting>
    sceneHandler.PreAddSolid(theAT, *pVisAttribs);
    pSol-&gt;DescribeYourselfTo(sceneHandler);
    |--&gt;sceneHandler.AddSolid(*this);  
    sceneHandler.PostAddSolid();
    </programlisting></informalexample>

    if the scene handler implements its own <literal>AddSolid</literal>.  
    Moreover, the sequence

    <informalexample><programlisting>
    BeginPrimitives (*fpObjectTransformation); 
    AddPrimitive(*pPolyhedron);
    EndPrimitives();
    </programlisting></informalexample>

    can be invoked without a prior <literal>PreAddSolid</literal>, etc.  
    The flag <literal>fProcessingSolid</literal> will be false for the 
    last case.  The possibility of any or all of these three scenarios 
    occurring, for both permanent and
    transient objects, affects the implementation of a scene handler if
    there is any attempt to build a graphical database.  This is reflected
    in the templates <literal>XXXStored</literal> and 
    <literal>XXXSG</literal> described in
    <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.UsfStrt.Tmpl" />.  
    Transients are discussed in
    <xref linkend="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj" />.
  </para></listitem>
  <listitem><para>
    <literal>G4TrajectoriesModel</literal> At end of event, the trajectory
    container is unpacked and, for each trajectory,
    <literal>sceneHandler.AddCompound</literal> called.  
    The scene handler may implement this virtual function or inherit:

    <informalexample><programlisting>
    void G4VSceneHandler::AddCompound (const G4VTrajectory&amp; traj) {
      traj.DrawTrajectory(((G4TrajectoriesModel*)fpModel)-&gt;GetDrawingMode());
    }
    </programlisting></informalexample>

    Similarly, the user may implement <literal>DrawTrajectory</literal> 
    or inherit:

    <informalexample><programlisting>
    void G4VTrajectory::DrawTrajectory(G4int i_mode) const {
      G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
      if (0 != pVVisManager) {
        pVVisManager-&gt;DispatchToModel(*this, i_mode);
      }
    }
    </programlisting></informalexample>

    Thence, the <literal>Draw</literal> method of the current trajectory model 
    is invoked (see <xref linkend="sect.ExtdFuncVis.EnhcTrjDrw" /> for details 
    on trajectory models), which in turn, invokes <literal>Draw</literal> 
    methods of the visualisation manager.

    The resulting default sequence for a <literal>G4TrajectoriesModel</literal> 
    is shown in <xref linkend="fig.ExtdFuncVis_3" />.

    <figure id="fig.ExtdFuncVis_3">
    <title>
    The default sequence for a <literal>G4PhysicalVolumeModel}</literal>
    </title>
    <screen>
    DrawView();
    |-->ProcessView();
        |-->ProcessScene();
            |-->BeginModeling();
            |-->pModel -> DescribeYourselfTo(*this);
            |   |-->AddCompound(trajectory);
            |       |-->trajectory.DrawTrajectory(...);
            |           |-->DispatchToModel(...);
            |               |-->model->Draw(...);
            |                   |-->G4VisManager::Draw(...);
            |                       |-->BeginPrimitives(objectTransform);
            |                       |-->AddPrimitive(...);
            |                       |-->EndPrimitives();
            |-->EndModeling();
    </screen>
    </figure>

  </para></listitem>
</itemizedlist>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.CrtGrpDrv.DlgTrnsObj">
<title>
Dealing with transient objects
</title>

<para>
Any visualisable object not defined in the run-duration part of a
scene is treated as ``transient''.  This includes trajectories, hits
or anything drawn by the user through the <literal>G4VVisManager</literal>
user-level interface (unless as part of a run-duration model implementation).  
A flag, <literal>fReadyForTransients}</literal>, is maintained by
the scene handler.  In fact, its normal state is <literal>true</literal>, and 
only temporarily, during handling of the run-duration part of the scene, is
it set to <literal>false</literal> -- see description of ProcessScene, 
<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn" />.
</para>

<para>
If the driver supports a graphical database, it is smart to
distinguish transient and permanent objects.  In this case, every 
<literal>Add</literal> method of the scene handler must be transient-aware.  
In some cases, it is enough to open a graphical data base component in 
<literal>BeginPrimitives</literal>, fill it in <literal>AddPrimitive</literal> 
and close it appropriately in <literal>EndPrimitives</literal>.  
In others, initialisation is done in <literal>BeginModeling</literal> 
and consolidation in <literal>EndModeling</literal> -- see 
<literal>G4OpenGLStoredSceneHandler</literal>.  
If any <literal>AddSolid</literal> method is
implemented, then the graphical data base component should be opened
in <literal>PreAddSolid</literal>, protecting against double opening, 
for example,

<informalexample><programlisting>
void G4XXXStoredSceneHandler::BeginPrimitives
(const G4Transform3D&amp; objectTransformation) {
  G4VSceneHandler::BeginPrimitives(objectTransformation);
  // If thread of control has already passed through PreAddSolid,
  // avoid opening a graphical data base component again.
  if (!fProcessingSolid) {
</programlisting></informalexample>

for other solids.
</para>

<para>
The reason for this distinction is that at end of run the user
typically wants to display trajectories on a view of the detector,
then, at the end of the next event

<footnote>
  <para>
  There is an option to accumulate trajectories across events and runs 
  -- see commands 
  <literal>/vis/scene/endOfEventAction</literal> and 
  <literal>/vis/scene/endOfRunAction</literal>.
  </para>
</footnote>

, erase the old and see new trajectories.  The visualisation manager 
messages the scene handler with <literal>ClearTransientStore</literal> 
just before drawing the trajectories to achieve this.
</para>

<para>
If the driver does not have a graphical database or does not
distinguish between transient and persistent objects, it must emulate
<literal>ClearTransientStore</literal>.  Typically, it must erase everything, 
including the detector, and re-draw the detector and other run-duration 
objects, ready for the transients to be added.  File-writing drivers must
rewind the output file.  Typically:

<informalexample><programlisting>
void G4HepRepFileSceneHandler::ClearTransientStore() {
  G4VSceneHandler::ClearTransientStore();
  // This is typically called after an update and before drawing hits
  // of the next event.  To simulate the clearing of "transients"
  // (hits, etc.) the detector is redrawn...
  if (fpViewer) {
    fpViewer -&gt; SetView();
    fpViewer -&gt; ClearView();
    fpViewer -&gt; DrawView();
  }
}
</programlisting></informalexample>
</para>

<para>
<literal>ClearView</literal> rewinds the output file and 
<literal>DrawView</literal> re-draws the detector, etc.  
(For smart drivers, <literal>DrawView</literal> is smart enough to
know not to redraw the detector, etc., unless the view parameters have
changed significantly -- see 
<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtDrwVw" />)
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.sect.ExtdFuncVis.CrtGrpDrv.MrScnMdl">
<title>
More about scene models
</title>

<para>
Scene models conform to the <literal>G4VModel</literal> abstract interface.
Available models are listed and described there in varying detail.
<xref linkend="sect.ExtdFuncVis.CrtGrpDrv.WhtPrcScn" /> describes their 
use in some common command actions.
</para>

<para>
In the design of a new model, care should be taken to handle the
possibility that the <literal>G4ModelingParameters</literal> pointer is zero.
Currently the only use of the modeling parameters is to communicate
the culling policy.  Most models, therefore, have no need for modeling
parameters.
</para>

</sect3>
</sect2>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ExtdFuncVis.EnhcTrjDrw">
<title>
Enhanced Trajectory Drawing
</title>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.EnhcTrjDrw.CrtTrjMdl">
<title>
Creating a new trajectory model
</title>

<para>
New trajectory models must inherit from G4VTrajectoryModel and
implement these pure virtual functions:

<informalexample><programlisting>
    virtual void Draw(const G4VTrajectory&amp;, G4int i_mode = 0, 
                      const G4bool&amp; visible = true) const = 0;
    virtual void Print(std::ostream&amp; ostr) const = 0;
</programlisting></informalexample>
</para>

<para>
To use the new model directly in compiled code, simply 
register it with the G4VisManager, eg:

<informalexample><programlisting>
  G4VisManager* visManager = new G4VisExecutive;
  visManager-&gt;Initialise();

  // Create custom model
  MyCustomTrajectoryModel* myModel = 
             new MyCustomTrajectoryModel("custom");

  // Configure it if necessary then register with G4VisManager
  ...
  visManager-&gt;RegisterModel(myModel);
</programlisting></informalexample>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.EnhcTrjDrw.AddIntFunc">
<title>
Adding interactive functionality
</title>

<para>
Additional classes need to be written if the new model is to 
be created and configured interactively:

<itemizedlist spacing="compact">
  <listitem><para>
    <emphasis role="bold">Messenger classes</emphasis>
    </para>
    <para>
    Messengers to configure the model should inherit from 
    G4VModelCommand. The concrete trajectory model type should be 
    used for the template parameter, eg:

    <informalexample><programlisting>
    class G4MyCustomModelCommand 
          : public G4VModelCommand&lt;G4TrajectoryDrawByParticleID&gt; {
    ...
    };
    </programlisting></informalexample>
  
    A number of general use templated commands are available in 
    G4ModelCommandsT.hh.
  </para></listitem>
  <listitem><para>
    <emphasis role="bold">Factory class</emphasis>
    </para>
    <para>
    A factory class responsible for the model and associated messenger 
    creation must also be written. The factory should inherit from 
    G4VModelFactory. The abstract model type should be used for the 
    template parameter, eg:

    <informalexample><programlisting>
    class G4TrajectoryDrawByChargeFactory 
       : public G4VModelFactory&lt;G4VTrajectoryModel&gt; {
     ...
    };
    </programlisting></informalexample>

    The model and associated messengers should be constructed in the Create 
    method. Optionally, a context object can also be created, with its own 
    associated messengers. For example:

    <informalexample><programlisting>
    ModelAndMessengers
    G4TrajectoryDrawByParticleIDFactory::
        Create(const G4String&amp; placement, const G4String&amp; name)
    {  
      // Create default context and model
      G4VisTrajContext* context = new G4VisTrajContext("default");
      G4TrajectoryDrawByParticleID* model = 
                  new G4TrajectoryDrawByParticleID(name, context);

      // Create messengers for default context configuration
      AddContextMsgrs(context, messengers, placement+"/"+name);

      // Create messengers for drawer
      messengers.push_back(new 
        G4ModelCmdSetStringColour&lt;G4TrajectoryDrawByParticleID&gt;
                                               (model, placement));
      messengers.push_back(new 
        G4ModelCmdSetDefaultColour&lt;G4TrajectoryDrawByParticleID&gt;
                                               (model, placement));
      messengers.push_back(new 
        G4ModelCmdVerbose&lt;G4TrajectoryDrawByParticleID&gt;
                                               (model, placement));

      return ModelAndMessengers(model, messengers);
    }
    </programlisting></informalexample>
  </para></listitem>
</itemizedlist>
</para>

<para>
The new factory must then be registered with the visualisation manager. 
This should be done by overriding the G4VisManager::RegisterModelFactory 
method in a subclass. See, for example, the G4VisManager implementation:

<informalexample><programlisting>
G4VisExecutive::RegisterModelFactories()
{
   ...
   RegisterModelFactory(new G4TrajectoryDrawByParticleIDFactory());
}
</programlisting></informalexample>
</para>

</sect3>
</sect2>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ExtdFuncVis.TrjFltr">
<title>
Trajectory Filtering
</title>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.TrjFltr.CrtTrjFltr">
<title>
Creating a new trajectory filter model
</title>

<para>
New trajectory filters must inherit at least from G4VFilter. The 
models supplied with the Geant4 distribution inherit from 
G4SmartFilter, which implements some specialisations on top of 
G4VFilter. The models implement these pure virtual functions:

<informalexample><programlisting>
  // Evaluate method implemented in subclass
  virtual G4bool Evaluate(const T&amp;) = 0;

  // Print subclass configuration
  virtual void Print(std::ostream&amp; ostr) const = 0;
</programlisting></informalexample>
</para>

<para>
To use the new filter model directly in compiled code, simply 
register it with the G4VisManager, eg:

<informalexample><programlisting>
  G4VisManager* visManager = new G4VisExecutive;
  visManager-&gt;Initialise();

  // Create custom model
  MyCustomTrajectoryFilterModel* myModel = 
        new MyCustomTrajectoryFilterModel("custom");

  // Configure it if necessary then register with G4VisManager
  ...
  visManager-&gt;RegisterModel(myModel);
</programlisting></informalexample>
</para>

</sect3>

<!-- ******************* Section (Level#3) ****************** -->
<sect3 id="sect.ExtdFuncVis.TrjFltr.AddIntFunc">
<title>
Adding interactive functionality
</title>

<para>
Additional classes need to be written if the new model is to 
be created and configured interactively. The mechanism is exactly 
the same as that used to create enchanced trajectory drawing 
models and associated messengers. See the filter factories in 
G4TrajectoryFilterFactories for example implementations.
</para>

</sect3>
</sect2>

<!-- ******************* Section (Level#2) ****************** -->
<sect2 id="sect.ExtdFuncVis.OthrRsrc">
<title>
Other Resources
</title>

<para>
The following sections contain various information for extending 
other class functionalities of Geant4 visualisation: 

<itemizedlist spacing="compact">
  <listitem><para>
    User's Guide for Application Developers, Chapter 8 - Visualization
  </para></listitem>
  <listitem><para>
    User's Guide for Toolkit Developers, Object-oriented Analysis
    and Design of Geant4 Classes, <xref linkend="sect.DsgnFuncVis" />.
  </para></listitem>
</itemizedlist>
</para>

</sect2>

<!-- ******* Bridgehead ******* -->
<bridgehead role="revisionHistory" renderas="sect4">
[Status of this chapter]
</bridgehead>
<para>
<simplelist type="var">
  <member>
    03.12.05 ``Enhanced Trajectory Drawing'' added by Jane Tinsley.
  </member>
  <member>
    03.12.05 ``Creating a new visualisation driver'' (from Part II) 
    by John Allison.
  </member>
  <member>
    09.01.06 ``Creating a new visualisation driver'' considerably expanded 
    by John Allison.
  </member>
  <member>
    20.06.06 Some sections improved or added from draft vis paper.  
    John Allison.
  </member>
  <member>
    Dec. 2006 Conversion from latex to Docbook verson by K. Amako
  </member>
</simplelist>
</para>
    

</sect1>
