Visualization attributes are extra pieces of information associated with the visualizable objects. This information is necessary only for visualization, and is not included in geometrical information such as shapes, position, and orientation. Typical examples of visualization attributes are Color, Visible/Invisible, Wireframe/Solid. For example, in visualizing a box, the Visualization Manager must know its colour. If an object to be visualized has not been assigned a set of visualization attributes, then an appropriate default set is used automatically.
A set of visualization attributes is held by an instance of
class G4VisAttributes
defined in the
graphics_reps
category. In the following, we
explain the main fields of the G4VisAttributes
one by one.
Visibility is a boolean flag to control the visibility of objects that are passed to the Visualization Manager for visualization. Visibility is set with the following access function:
void G4VisAttributes::SetVisibility (G4bool visibility);
If you give false
to the argument, and if culling is
activated (see below), visualization is skipped for objects for
which this set of visualization attributes is assigned. The default
value of visibility is true
.
Note that whether an object is visible or not is also affected by the current culling policy, which can be tuned with visualization commands.
By default the following public static function is defined:
static const G4VisAttributes& GetInvisible();
which returns a reference to a const object in which visibility is
set to false
. It can be used as follows:
experimentalHall_logical -> SetVisAttributes (G4VisAttributes::GetInvisible());
Direct access to the public static const data member
G4VisAttributes::Invisible
is also possible but deprecated
on account of initialisation issues with dynamic libraries.
Class G4Colour
(an equivalent class name,
G4Color
, is also available) has 4 fields,
which represent the RGBA (red, green,
blue, and alpha) components of colour. Each component takes a value
between 0 and 1. If an irrelevant value, i.e., a value less than 0
or greater than 1, is given as an argument of the constructor, such
a value is automatically clipped to 0 or 1. Alpha is opacity. Its
default value 1
means "opaque".
A G4Colour
object is instantiated by giving red, green,
and blue components to its constructor, i.e.,
G4Colour::G4Colour ( G4double r = 1.0, G4double g = 1.0, G4double b = 1.0, G4double a = 1.0); // 0<=red, green, blue <= 1.0
The default value of each component is 1.0. That is to say, the default colour is "white" (opaque).
For example, colours which are often used can be instantiated as follows:
G4Colour white () ; // white G4Colour white (1.0, 1.0, 1.0) ; // white G4Colour gray (0.5, 0.5, 0.5) ; // gray G4Colour black (0.0, 0.0, 0.0) ; // black G4Colour red (1.0, 0.0, 0.0) ; // red G4Colour green (0.0, 1.0, 0.0) ; // green G4Colour blue (0.0, 0.0, 1.0) ; // blue G4Colour cyan (0.0, 1.0, 1.0) ; // cyan G4Colour magenta (1.0, 0.0, 1.0) ; // magenta G4Colour yellow (1.0, 1.0, 0.0) ; // yellow
It is also possible to instantiate common colours through static public data member functions:
static const G4Colour& White (); static const G4Colour& Gray (); static const G4Colour& Grey (); static const G4Colour& Black (); static const G4Colour& Red (); static const G4Colour& Green (); static const G4Colour& Blue (); static const G4Colour& Cyan (); static const G4Colour& Magenta (); static const G4Colour& Yellow ();
For example, a local G4Colour
could be constructed
as:
G4Colour myRed(G4Colour::Red());
After instantiation of a G4Colour
object, you can access
to its components with the following access functions:
G4double G4Colour::GetRed () const ; // Get the red component. G4double G4Colour::GetGreen () const ; // Get the green component. G4double G4Colour::GetBlue () const ; // Get the blue component.
G4Colour
also provides a static colour map, giving access to
predefined G4Colour
's through a
G4String
key. The default mapping is:
G4String G4Colour --------------------------------------- white G4Colour::White () gray G4Colour::Gray () grey G4Colour::Grey () black G4Colour::Black () red G4Colour::Red () green G4Colour::Green () blue G4Colour::Blue () cyan G4Colour::Cyan () magenta G4Colour::Magenta () yellow G4Colour::Yellow ()
Colours can be retrieved through the GetColour method:
bool G4Colour::GetColour(const G4String& key, G4Colour& result)
For example:
G4Colour myColour(G4Colour::Black()); if (G4Colour::GetColour("red", myColour)) { // Successfully retrieved colour "red". myColour is now red } else { // Colour did not exist in map. myColour is still black }
If the key is not registered in the colour map, a warning message is printed and the input colour is not changed. The colour map is case insensitive.
It is also possible to load user defined G4Colour
's into
the map through the public AddToMap method. For example:
G4Colour myColour(0.2, 0.2, 0.2, 1); G4Colour::AddToMap("custom", myColour);
This loads a user defined G4Colour
with key "custom" into
the colour map.
Class G4VisAttributes
holds its colour entry as an object of
class G4Colour
. A G4Colour
object is
passed to a G4VisAttributes
object with the following
access
functions:
//----- Set functions of G4VisAttributes. void G4VisAttributes::SetColour (const G4Colour& colour); void G4VisAttributes::SetColor (const G4Color& color );
We can also set RGBA components directly:
//----- Set functions of G4VisAttributes void G4VisAttributes::SetColour ( G4double red , G4double green , G4double blue , G4double alpha = 1.0); void G4VisAttributes::SetColor ( G4double red , G4double green , G4double blue , G4double alpha = 1.);
The following constructor with G4Colour
as its argument is
also supported:
//----- Constructor of G4VisAttributes G4VisAttributes::G4VisAttributes (const G4Colour& colour);
Note that colour assigned to a G4VisAttributes
object is
not always the colour that ultimately appears in the visualization.
The ultimate appearance may be affected by shading and lighting
models applied in the selected visualization driver or stand-alone
graphics system.
As you will see later, you can select a "drawing style" from various options. For example, you can select your detector components to be visualized in "wireframe" or with "surfaces". In the former, only the edges of your detector are drawn and so the detector looks transparent. In the latter, your detector looks opaque with shading effects.
The forced wireframe and forced solid styles make it possible to mix the wireframe and surface visualization (if your selected graphics system supports such visualization). For example, you can make only the outer wall of your detector "wired" (transparent) and can see inside in detail.
Forced wireframe style is set with the following access function:
void G4VisAttributes::SetForceWireframe (G4bool force);
If you give true
as the argument, objects for which this
set of visualization attributes is assigned are always visualized
in wireframe even if in general, the surface drawing style has been
requested. The default value of the forced wireframe style is
false
.
Similarly, forced solid style, i.e., to force that objects are always visualized with surfaces, is set with:
void G4VisAttributes::SetForceSolid (G4bool force);
The default value of the forced solid style is false
, too.
You can also force auxiliary edges to be visible. Normally they are not visible unless you set the appropriate view parameter. Forcing the auxiliary edges to be visible means that auxiliary edges will be seen whatever the view parameters.
Auxiliary edges are not genuine edges of the volume. They may be in a curved surface made out of polygons, for example, or in plane surface of complicated shape that has to be broken down into simpler polygons. HepPolyhedron breaks all surfaces into triangles or quadrilaterals. There will be auxiliary edges for any volumes with a curved surface, such as a tube or a sphere, or a volume resulting from a Boolean operation. Normally, they are not shown, but sometimes it is useful to see them. In particular, a sphere, because it has no egdes, will not be seen in wireframe mode in some graphics systems unless requested by the view parameters or forced, as described here.
To force auxiliary edges to be visible, use:
void G4VisAttributes::SetForceAuxEdgeVisible (G4bool force);
The default value of the force auxiliary edges visible flag is
false
.
For volumes with edges that are parts of a circle, such as a tube (G4Tubs), etc., it is possible to force the precision of polyhedral representation for visualisation. This is recommended for volumes containing only a small angle of circle, for example, a thin tube segment.
For visualisation, a circle is represented by an N-sided polygon. The default is 24 sides or segments. The user may change this for all volumes in a particular viewer at run time with /vis/viewer/set/lineSegmentsPerCircle; alternatively it can be forced for a particular volume with:
void G4VisAttributes::SetForceLineSegmentsPerCircle (G4int nSegments);
Here is a list of Set methods for class
G4VisAttributes
:
void SetVisibility (G4bool); void SetDaughtersInvisible (G4bool); void SetColour (const G4Colour&); void SetColor (const G4Color&); void SetColour (G4double red, G4double green, G4double blue, G4double alpha = 1.); void SetColor (G4double red, G4double green, G4double blue, G4double alpha = 1.); void SetLineStyle (LineStyle); void SetLineWidth (G4double); void SetForceWireframe (G4bool); void SetForceSolid (G4bool); void SetForceAuxEdgeVisible (G4bool); void SetForceLineSegmentsPerCircle (G4int nSegments); // Allows choice of circle approximation. A circle of 360 degrees // will be composed of nSegments line segments. If your solid has // curves of D degrees that you need to divide into N segments, // specify nSegments = N * 360 / D. void SetStartTime (G4double); void SetEndTime (G4double); void SetAttValues (const std::vector<G4AttValue>*); void SetAttDefs (const std::map<G4String,G4AttDef>*);
The following constructors are supported for class
G4VisAttributes
:
//----- Constructors of class G4VisAttributes G4VisAttributes (void); G4VisAttributes (G4bool visibility); G4VisAttributes (const G4Colour& colour); G4VisAttributes (G4bool visibility, const G4Colour& colour);
In constructing your detector components, you may assign a set of
visualization attributes to each "logical volume" in order to
visualize them later (if you do not do this, the graphics system
will use a default set). You cannot make a solid such as
G4Box
hold a set of visualization attributes; this is
because a solid should hold only geometrical information. At
present, you cannot make a physical volume hold one, but there are
plans to design a memory-efficient way to do it; however, you can
visualize a transient piece of solid or physical volume with a
temporary assigned set of visualization attributes.
Class G4LogicalVolume
holds a pointer of
G4VisAttributes.
This field is set and referenced with the
following access functions:
//----- Set functions of G4VisAttributes void G4VisAttributes::SetVisAttributes (const G4VisAttributes* pVA); void G4VisAttributes::SetVisAttributes (const G4VisAttributes& VA); //----- Get functions of G4VisAttributes const G4VisAttributes* G4VisAttributes::GetVisAttributes () const;
The following is sample C++ source codes for assigning a set of visualization attributes with cyan colour and forced wireframe style to a logical volume:
//----- C++ source codes: Assigning G4VisAttributes to a logical volume ... // Instantiation of a logical volume myTargetLog = new G4LogicalVolume( myTargetTube,BGO, "TLog", 0, 0, 0); ... // Instantiation of a set of visualization attributes with cyan colour G4VisAttributes * calTubeVisAtt = new G4VisAttributes(G4Colour(0.,1.,1.)); // Set the forced wireframe style calTubeVisAtt->SetForceWireframe(true); // Assignment of the visualization attributes to the logical volume myTargetLog->SetVisAttributes(calTubeVisAtt); //----- end of C++ source codes
Note that the life of the visualization attributes must be at least as long as the objects to which they are assigned; it is the users' responsibility to ensure this, and to delete the visualization attributes when they are no longer needed (or just leave them to die at the end of the job).
Geant4 Trajectories and Hits can be assigned additional arbitrary attributes that will be displayed when you click on the relevant object in the WIRED or FRED HepRep browsers. WIRED then lets you label objects by any of these attributes or cut visibility based on these attributes.
Define the attributes with lines such as:
std::map<G4String,G4AttDef>* store = G4AttDefStore::GetInstance("G4Trajectory",isNew); G4String PN("PN"); (*store)[PN] = G4AttDef(PN,"Particle Name","Physics","","G4String"); G4String IMom("IMom"); (*store)[IMom] = G4AttDef(IMom, "Momentum of track at start of trajectory", "Physics", "", "G4ThreeVector");
Then fill the attributes with lines such as:
std::vector<G4AttValue>* values = new std::vector<G4AttValue>; values->push_back(G4AttValue("PN",ParticleName,"")); s.seekp(std::ios::beg); s << G4BestUnit(initialMomentum,"Energy") << std::ends; values->push_back(G4AttValue("IMom",c,""));
See geant4/source/tracking/src/G4Trajectory.cc for a good example.
G4AttValue
objects are light, containing just the value;
for the long description and other sharable information the
G4AttValue
object refers to a G4AttDef
object. They are based on the HepRep standard described at
http://www.slac.stanford.edu/~perl/heprep/
.
Geant4 also provides an G4AttDefStore
.
Geant4 provides some default examples of the use of this
facility in the trajectory classes in /source/tracking such as
G4Trajectory
, G4SmoothTrajectory
.
G4Trajectory::CreateAttValues
shows how
G4AttValue
objects can be made and
G4Trajectory::GetAttDefs
shows how
to make the corresponding G4AttDef
objects and use the
G4AttDefStore
. Note that the "user" of CreateAttValues
guarantees to destroy them; this is a way of allowing creation on
demand and leaving the G4Trajectory
object, for example,
free of such objects in memory. The comments in
G4VTrajectory.hh
explain further and additional insights
might be obtained by looking at two methods which use them, namely
G4VTrajectory::DrawTrajectory
and
G4VTrajectory::ShowTrajectory
.
Hits classes in examples /extended/analysis/A01 and
/extended/runAndEvent/RE01 show how to do the same for your hits.
The base class no-action methods CreateAttValues and GetAttDefs
should be overridden in your concrete class. The comments in
G4VHit.hh
explain further.
In addition, the user is free to add a
G4std::vector<G4AttValue>*
and a
G4std::vector<G4AttDef>*
to a
G4VisAttributes
object as could, for example,
be used by a G4LogicalVolume
object.
At the time of writing, only the HepRep graphics systems are capable of displaying the G4AttValue information, but this information will become useful for all Geant4 visualization systems through improvements in release 8.1 or later.