Visualisation
Design Philosophy
The visualisation category consists of the classes required to display
detector geometry, particle trajectories, tracking steps, and hits. It also
provides visualisation drivers, which are interfaces to external graphics
systems.
A wide variety of user requirements went into the design of the visualisation
category, for example:
very quick response in surveying successive events,
high-quality output for presentation and documentation,
flexible camera control for debugging detector geometry and physics,
selection of visualisable objects,
interactive picking of graphical objects for attribute editing or
feedback to the associated data,
highlighting incorrect intersections of physical volumes,
co-working with graphical user interfaces.
Because it is very difficult to respond to all of these requirements
with only one built-in visualiser, an abstract interface was developed
which supports several complementary graphics systems. Here the term
graphics system means either an
application running as a process independent of Geant4 or a graphics
library to be compiled with Geant4. A concrete implementation of the
interface is called a visualisation driver,
which can use a graphics library directly, communicate with an
independent process via pipe or socket, or simply write an intermediate
file for a separate viewer.
The Graphics Interfaces
G4VVisManager:
All user code writes to the graphics systems
through this pure abstract interface. It contains Draw methods for
all the graphics primitives in the graphics_reps category
(G4Polyline, G4Circle, etc.), geometry objects (through their base
classes, G4VSolid, G4PhysicalVolume and G4LogicalVolume) and hits and
trajectories (through their base classes, G4VHit and G4VTrajectory).
Since this is an abstract interface, all user code must check that
there exists a concrete instantiation of it. A static method is
provided, so a typical user code fragment is:
G4VVisManager* pVVisManager = G4VVisManager::GetConcreteInstance();
if(pVVisManager) {
pVVisManager->Draw(G4Circle...
...
Note that this allows the building an application without a concrete
implementation, for example for a batch job, even if some code, like
the above, is still included. Most of the novice examples can be
built this way if G4VIS_NONE is specified.
The concrete implementation of this interface is hereafter
referred to as the visualisation manager.
G4VGraphicsScene:
The visualisation manager must also
provide a concrete implementation of the subsidiary interface,
G4VGraphicsScene. It is only for use by the kernel and the modeling
category. It offers direct access to a ``scene handler'' through a
reference provided by the visualisation manager. It is described in
more detail in the section on extending the toolkit functionality.
The Geant4 distribution includes implementations of the above
interfaces, namely G4VisManager
and G4VSceneHandler
respectively, and their associated classes. These define further
abstract base classes for visualisation drivers. Together they form
the Geant4 Visualisation System.
A variety of concrete visualisation drivers are also included
in the distribution. Details of how to implement a visualisation
driver are given in .
Of course, it is always possible for
a user to implement his or her own concrete implementations of
G4VVisManager and G4VGraphicsScene replacing the Geant4 Visualisation
System altogether.
The Geant4 Visualisation System
The Geant4 Visualisation System consists of
G4VisManager: An implementation
of the G4VVisManager
interface. It manages multiple graphics systems and defines three
more concepts -- the scene (G4Scene),
the scene handler
(base class G4VSceneHandler, itself a sub-class of G4VGraphicsScene)
and the viewer (base class G4VViewer)
-- see below.
G4VisManager is a singleton and an abstract class, requiring the
user to derive from it a concrete visualisation manager
(G4VisExecutive is provided -- see below). Roles and structure of
the visualisation manager are described in Chapter 8 of the User's
Guide for Application Developers.
G4VisExecutive: A concrete visualisation
manager that implements the virtual functions RegisterGraphicsSystems and
RegisterModelFactories. These functions must be in the users'
domain, since the graphics systems and models that are instantiated
by them are, in many cases, provided by the user (graphics
libraries, etc.). It is therefore implemented as a .hh-.icc
combination that is designed to be included in the users' code. Of
course, the user may write his or her own.
G4Scene The scene is a list if
models for physical
volumes, axes, hits, trajectories, etc. - see Section
.
They are distinguished according to their
lifetime -- ``run-duration'' for physical volumes, etc.,
``end-of-event'' for hits and trajectories, etc. The end-of-event
models are only to be used when the Geant4 state indicates the end
of event has been reached. The scene has an
extent (G4VisExtent),
which is updated by the scene when a new model is
added (each model itself has an extent), and a ``standard'' target
point; these are used to define the standard view -- see
below. In addition, the scene keeps flags which indicate whether
end-of-event objects should be accumulated or refreshed for each
event or run.
G4VGraphicsSystem: This is an
abstract base class for scene
handler and viewer factories. It is used by the visualisation
manager to create scene handlers and viewers on request.
G4VSceneHandler: A sub-class of
G4VGraphicsScene, itself an abstract base class for specific scene
handlers, whose job is to
convert the scene into graphics-system-specific code for the viewer.
For example, the scene handler may create a graphical database,
taking care to separate run-duration (persistent) and end-of-event
(transient) information (this is described further in
.
G4VViewer: An abstract base class
for specific viewers.
Its job is to create windows or files and identify where and how the
final view should be rendered. It has
view parameters
(G4ViewParameters) which specify viewpoint direction, type of
rendering (wireframe or surface), etc. It is the view's
responsibility, noting the scene's extent and target point, to
choose a camera position and magnification that ensures that the
scene is automatically and comfortably rendered in the viewing
window. This is then the standard view,
and any further
operations requested by the user - zoom, pan, etc. - are
relative to this standard view. The class G4ViewParameters has
utility routines to assist this procedure; it is strongly advised
that toolkit developers writing a viewer should study the
G4ViewParameters class, whose header file contains much useful
information (also preserved in the Software Reference Manual).
The viewer is messaged by the vis manager when the user issues
commands, such as /vis/viewer/refresh.
This invokes methods
such as SetView, ClearView and DrawView. A detailed description of
the call sequences is given in
-
.
Note there is no restriction on the number or type of scene handlers
or viewers. There may be several scene handlers processing the same
or different scenes, each with several viewers (for example, the same
scene from differing viewpoints).
By defining a set of three C++ classes inheriting from the virtual
base classes - G4VGraphicsSystem, G4VSceneHandler and G4VViewer - an
arbitrary graphics system can easily be plugged in to Geant4.
The plugged-in graphics system is then available for visualising
detector simulations. Together, this set of three concrete classes is
called a "visualisation driver". The DAWN-File driver, for example,
is the interface to the Fukui Renderer DAWN, and is implemented by the
following set of classes:
G4DAWNFILE : public G4VGraphicsSystem for creation of the
scene handlers and viewers
G4DAWNFILESceneHandler : public G4VSceneHandler for
modeling 3D scenes
G4DAWNFILEView : public G4VView for rendering 3D scenes
Several visualisation drivers are distributed with Geant4. They are
complementary to each other in many aspects. For details, see Chapter 8 of
the User's Guide for Application Developers.
Modeling sub-category
G4VModel -
a base class for visualisation models. A model is a
graphics-system-independent description of a Geant4 component.
The sub-category visualisation/modeling defines how to model a 3D
scene for visualisation. The term "3D scene" indicates a set of
visualisable component objects put in a 3D world. A concrete class
inheriting from the abstract base class G4VModel defines a "model",
which describes how to visualise the corresponding component object
belonging to a 3D scene. G4ModelingParameters defines various
associated parameters.
For example, G4PhysicalVolumeModel knows how to visualise
a physical volume. It describes a physical volume
and its daughters to any desired depth. G4HitsModel knows
how to visualise hits. G4TrajectoriesModel
knows how to visualise trajectories.
The main task of a model is to describe itself to a 3D scene by
giving a concrete implementation of the following virtual
method of G4VModel:
virtual void DescribeYourselfTo (G4VGraphicsScene&) = 0;
The argument class G4VGraphicsScene is a minimal abstract
interface of a 3D scene for the Geant4 kernel defined in the
graphics_reps category. Since G4VSceneHandler and its concrete
descendants inherit from G4VGraphicsScene, the
method DescribeYourselfTo() can pass information of a 3D scene
to a visualisation driver.
It is easy for a toolkit developer of Geant4 to add a new kind
of visualisable component object. It is done by implementing a
new class inheriting from G4VModel.
G4VTrajectoryModel -
an abstract base class for trajectory drawing models.
A trajectory model governs how an individual trajectory is drawn.
Concrete models inheriting from G4VTrajectoryModel must implement
two pure virtual functions:
virtual void Draw(const G4VTrajectory&, G4int i_mode = 0) const = 0;
virtual void Print(std::ostream& ostr) const = 0;
See for example G4TrajectoryDrawByParticleID.
G4VModelFactory -
an abstract base class for factories creating models and associated
messengers.
It is not necessary to generate messengers for a trajectory model
that will be constructed and configured directly in compiled code.
If the user requires model creation and configuration features through
interactive commands, however, there must be a mechanism to generate
both models and their associated messengers. This is the role of
G4VModelFactory. Concrete factories inheriting from G4VModelFactory
are responsible for creating a concrete model and concrete messengers.
To help ensure a type safe messenger to model interaction on the
command line, the messengers should inherit from G4VModelCommand.
Concrete factories must implement one pure virtual function:
virtual ModelAndMessengers
Create(const G4String& placement, const G4String& modelName) = 0;
where placement indicates which directory space the commands should
occupy. See for example G4TrajectoryDrawByParticleIDFactory.
View parameters
View parameters such as camera parameters, drawing styles
(wireframe/surface etc) are held by G4ViewParameters. Each
viewer holds a view parameters object which can be changed
interactively and a default object (for use in the
/vis/viewer/reset command).
If a toolkit developer of Geant4 wants to add entries of view
parameters, he should add fields and methods to G4ViewParameters.
Visualisation Attributes
All drawable objects (should) have a method:
const G4VisAttributes* GetVisAttributes() const;
A drawable object might be:
a "visible" (i.e., inheriting G4Visible), such as a polyhedron,
polyline, circle, etc. (note that text is a slightly special case
- see below) or
a solid whose vis attributes are held in its logical volume.
Finding the applicable vis attributes
This is an issue for all scene handlers. The scene handler is where
the colour, style, auxiliary edge visibility, marker size, etc., of
individual drawable objects are needed.
Visibles
If the vis attributes pointer is zero, drivers should pick up the
default vis attributes from the viewer:
const G4VisAttributes* pVisAtts = visible.GetVisAttributes();
if (!pVisAtts)
pVisAtts = fpViewer->GetViewParameters().GetDefaultVisAttributes();
where visible denotes any visible object (polyhedron, circle, etc.).
There is a utility function G4VViewer::GetApplicableVisAttributes
which does this, so an alternative is:
const G4VisAttributes* pVisAtts =
fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
Confusingly, there is a utility function G4VSceneHandler::GetColour
which also does this, so if it's only colour you need, the following
suffices:
const G4Colour& colour GetColour(visible);
but equally well:
const G4VisAttributes* pVisAtts =
fpViewer->GetApplicableVisAttributes(visible.GetVisAttributes());
const G4Colour& colour pVisAtts->GetColour();
or even:
const G4VisAttributes* pVisAtts = visible.GetVisAttributes();
if (!pVisAtts)
pVisAtts = fpViewer->GetViewParameters().GetDefaultVisAttributes();
const G4Colour& colour pVisAtts->GetColour();
Text
Text is a special case because it has its own default vis attributes:
const G4VisAttributes* pVisAtts = text.GetVisAttributes();
if (!pVisAtts)
pVisAtts = fpViewer->GetViewParameters().GetDefaultTextVisAttributes();
const G4Colour& colour pVisAtts->GetColour();
and there is a utility function G4VSceneHandler::GetTextColour:
const G4Colour& colour GetTextColour(text);
Solids
For specific solids, the G4PhysicalVolumeModel that provides the
solids also provides, via PreAddSolid, a pointer to its vis
attributes. If the vis attribites pointer in the logical volume is
zero, it provides a pointer to the default vis attributes in the
model, which in turn is (currently) provided by the viewer's vis
attributes (see G4VSceneHandler::CreateModelingParameters). So the
vis attributes pointer is guaranteed to be pertinent.
If the concrete driver does not implement AddSolid for any particular
solid, the base class converts it to primitives (usually a
G4Polyhedron) and again, the vis attributes pointer is guaranteed.
Drawing style
The drawing style is normally determined by the view parameters but
for individual drawable objects it may be overridden by the forced
drawing style flags in the vis attributes. A utility function
G4ViewParameters::DrawingStyle G4VSceneHandler::GetDrawingStyle is
provided:
G4ViewParameters::DrawingStyle drawing_style = GetDrawingStyle(pVisAtts);
Auxiliary edges
Similarly, the visibility of auxiliary/soft edges is normally
determined by the view parameters but may be overridden by the forced
auxiliary edge visible flag in the vis attributes. Again, a utility
function G4VSceneHandler::GetAuxEdgeVisible is provided:
G4bool isAuxEdgeVisible = GetAuxEdgeVisible (pVisAtts);
LineSegmentsPerCircle
Also, the precision of rendering curved edges in the polyhedral
representation of volumes is normally determined by the view
parameters but may be overridden by a forced attribute. A utility
function that respects this, G4VSceneHandler::GetNoOfSides, is
provided. For example:
G4Polyhedron::SetNumberOfRotationSteps (GetNoOfSides (pVisAttribs));
Marker size
These have nothing to do with vis attributes; they are an extra
property of markers, i.e., objects that inherit G4VMarker (circles,
squares, text, etc.). However, the algorithm for the actual size is
quite complicated and a utility function
G4VSceneHandler::GetMarkerSize is provided:
MarkerSizeType sizeType;
G4double size = GetMarkerSize (text, sizeType);
sizeType is world or screen, signifying that the size is in world
coordinates or screen coordinates respectively.
[Status of this chapter]
27.06.05 partially re-organized and section on design philosophy added (from
Geant4 general paper) by D.H. Wright
13.10.05 Section on vis attributes added by John Allison.
06.01.06 Re-write of ``Design Philosphy'' and introduction of ``The Graphics
Interfaces'' and ``The Geant4 Visualisation System'' by John Allison.
Dec. 2006 Conversion from latex to Docbook verson by K. Amako