MasterSuite
usage in
HEPInventor
October 1998
Olivier Couet
CERN Geneva, Switzerland
Abstract
This aim of the memorandum is to describe how MasterSuite
is used in the HEPInventor package. The primary goal of a
such description is to have some feedback from MasterSuite experts
(ie TGS) to make sure that, regarding the requirements we have,
the implementation of the HEPInventor package is the best
we can do. We also explain the problems we have encountered.
Finally we have benchmarked the Iris Explorer modules
made with HEPInventor . The results we obtained are very
bad compared to the PAW system. The results of these
benchmarks are given at the end of the memorandum.
Overview
What is HEPInventor
HEPinventor
has already been described in several papers. HEPInventor is
a data drawing (presentation) class library. The basic idea of this class
library is to provide an easy to use API making the link between the user
data (histOOgram
or vectors) and graphics. HEPInventor is based on the
MasterSuite
class library (provided by TGS)
, itself based on OpenInventor.
HEPInventor has been used to build IRIS Explorer
modules doing screen and PostScript output of user data in an interactive
environment (IRIS Explorer).
Basic concepts
The HEPInventor class library is built around 3 basic classes:
-
The Page (class HIPage): is a 2D
space defined in centimeters in which the HEPInventor user
compose the image he wanted to produce. A page is composed with zones.
Once created a page can be converted (draw) into an OpenInventor
scene graph which can be displayed on the screen via a viewer or
output on a file (Postscript, IV, HPGL). The page drawing consist of the
page drawing itself and the drawing of all the zones inside the page.
-
The Zone(s) (class HIZone): is the
basic unit used to compose a page. It cannot be displayed if it is not
included in a page. The zone position within a page is defined in the page
coordinates (cm). When a zone is included in a page, the page check that
the zone position is correct (inside the page coordinates). A zone can
be included in several pages. The zone is a ``container'' for the data.
A zone may contains several data. A zone has several attributes: it can
have linear or log coordinates, it can have a grid or not, the background
color can be modified. The zone drawing consist of the zone drawing itself
and the drawing of all the datas inside the zone.
-
The Data(s) (class HIData): is the
``graphics transposition'' of a data set (mainly vectors or histograms).
A ``data'' has to be put into a zone to be drawn. A ``data'' has several
attributes like the way it is represented (errors, stairs etc ..), the
color, the line width etc ... .
Classes library overview
Three basic classes are provided:
-
HIPage : Contains HIZone(s).
Can be displayed on the screen (via the window class), printed via PostScript
files or output as an Inventor file. The page size is defined in centimeters.
-
HIZone : Contains HIData(s).
Can be placed anywhere on a Page. This class is used to define the layout
of the page. The zone position in the page is given in centimeters.
-
HIData : Does the interface between
user data and graphics. User data can come from various sources. The class
HIData allows to disconnect the data
from the graphics representation. If a new type of data has to be drawn
by the HEPInventor package it is enough to create a new constructor
which accepts this new data type keeping unchanged the other parts of the
package.
The following example shows how to use the ``HI''
classes:
#include "HInventor.h"
int main()
{
#define PI 3.1415
#define N 50
HIPage P; // creates a HIPage P (20x20 cm)
HIZone Z(2.,18.,2.,18.); // creates a HIZone Z
P.AddZone(&Z); // puts the HIZone Z in the HIPage P
Z.set(HIZone::YGradLabelSize,0.7); // changes Y label size
Z.set(HIZone::XGradLabelSize,0.7); // changes X label size
float X[N],SINX[N],COSX[N]; //
float ANGLE = 0; //
float DX = 2*PI/N; //
int i; // generates 2 floating points
for ( i=0; i < N; i++) { // arrays one containing a sin and
X[i] = ANGLE; // this other one a cos.
SINX[i] = sin(ANGLE); //
COSX[i] = cos(ANGLE); //
ANGLE = ANGLE+DX; //
} //
HIData SINDATA(N,X,SINX); // creates a Data set SINDATA
HIData COSDATA(N,X,COSX); // creates a Data set COSDATA
Z.AddData(&SINDATA); // puts SINDATA in the HIZone Z
Z.AddData(&COSDATA); // puts COSDATA in the HIZone Z
HIPostScript(&P, "Ex002.ps"); // generates the PS file Ex002.ps from P
return 0;
}
Legend:
Create of a new object
Change some attributes
Put a new object in a container object (example
put a HIZone in a HIPage)
Output
This example produce the following output:
To have a complete and detailed description the HEPInventor class
library see the HEPInventor
manual.
Requirements
General graphics requirements for data presentation in High Energy Physics
(HEP) are explained in the document called ``HEP
graphics requirements for data presentation''. In this section we present
more ``technical'' issues involving MasterSuite usage. These points are
all related to the page geometry and the various coordinate spaces management.
-
The zones should be positionned in a cm space (the page). To allow
a ``natural'' positionning of the zones within the page, it has been decided
that the zone position will be defined at the zone creation time in centimeters.
The coordinates of the lower left and upper right corners of the zone are
defined in the page coordinates.
-
The axis label size, axis title etc ... should defined in the page coordinates
(cm) independently of the zone coordinates. It is very difficult to
manage the texts sizes if there are not defined in unique coordinate space.
Having them defined in the data coordinate system is not good because the
text size depend on the range of the date presented. That why it has been
decided to define text sizes in the page coordinate (cm).
-
The aspect ratio of the zone position in the page and the aspect ratio
of the zone coordinate space may be different (in fact most of the
time they are different). This seems obvious but this is not an easy requirements
to achieve with MasterSuite/OpenInventor.
Solutions adopted
In order to implement the requirements defined in the previous section,
the HIZone class define 3 PbDomain
and 3 Views:
-
The data domain and view are respectively used to define the space
coordinate in which data are drawn and place the data drawing correctly
(according to the zone position is the page).
-
The axis require a special domain and view definition mainly because
MasterSuite doesn't make the difference between the axis
position and the axis labeling. At the axis creation time, only one set
of parameter define both. To bypass this limitation we define an axis domain
whose aspect ratio matches the page dimension with space
coordinates containning the zone coordinates. Then, having this domain
defined with the page aspect ratio allows an easy setting of the geometrical
axis attributes (label size, tickmarks sizes etc ..), which are defined
in % of the domain, indepently from the zone coordinates.
-
The centimeters domain and view matches exactly
the page size and has its space coordinates defined in centimeters.
This domain is used to draw objects like PoLabelField
(use to draw the histogram statistics) which have their geometrical
attributes define in domain coordinates (not in % of the domain like the
axis).
Two procedures are used to define the Domains and the Views. To define
the domains we use HIDefineDomain:
//-----------------------------------------------------------------------------
//
// Define a domain according to its position in cm and its axis coordinates
//
PbDomain* HIDefineDomain(float X1P, float X2P, float Y1P, float Y2P,
float X1A, float X2A, float Y1A, float Y2A)
{
PbDomain *domain = new PbDomain;
float dxv = X2P-X1P;
float dyv = Y2P-Y1P;
float R = dxv/dyv;
float xd2 = X2A;
float yd2 = Y2A;
if (dxv > dyv) {
yd2 = (Y2A-Y1A)*R + Y1A;
} else {
xd2 = (X2A-X1A)/R + X1A;
}
domain->setDomain(X1A, Y1A, xd2, yd2);
return domain;
}
To define the views we use HIDefineView.
This procedure allows to positionned a zone in a page. It takes the zone
position in centimeters and define the corresponding PoSceneview in normalized
coordinates. The conversion between centimeters and normalized coordinates
is done via conversion methods provided by the HIPage
class.
//-----------------------------------------------------------------------------
//
// Define a view in cm coordinates.
//
PoSceneView* HIDefineView(float X1, float X2, float Y1, float Y2,
HIPage *page, SoSeparator *SceneGraph)
{
PoSceneView *view;
view = new PoSceneView() ;
view->sensitiveOnEvents(TRUE) ;
view->viewportOrigin.setValue(page->XCm2View(X1), page->YCm2View(Y1)) ;
view->viewportSize.setValue(page->XCm2View(X2)-page->XCm2View(X1),
page->YCm2View(Y2)-page->YCm2View(Y1)) ;
SoOrthographicCamera *camera = new SoOrthographicCamera ;
view->setPart("cameraKit.camera", camera) ;
view->setPart("scene", SceneGraph) ;
camera->viewAll(SceneGraph, SbViewportRegion(100, 100)) ;
return view;
}
Domain definition in HIZone:
//
// Data Domain
//
SoSeparator *DataSceneGraph = new SoSeparator;
PbDomain *DataDomain = new PbDomain;
DataDomain->setTransformType(PbDomain::TRANSFORM_01);
DataDomain = HIDefineDomain(X1ZonePos, X2ZonePos, Y1ZonePos, Y2ZonePos,
X1ZoneAxis, X2ZoneAxis, Y1ZoneAxis, Y2ZoneAxis);
//
// Axis domain.
//
SoSeparator *AxisSceneGraph = new SoSeparator;
PbDomain *AxisDomain = new PbDomain;
AxisDomain->setTransformType(PbDomain::TRANSFORM_01);
float x1 = XCm2Zone(0.);
float x2 = XCm2Zone(page->PageWidth);
float y1 = YCm2Zone(0.);
float y2 = YCm2Zone(page->PageHeight);
AxisDomain = HIDefineDomain(0., page->PageWidth, 0., page->PageHeight,
x1, x2, y1, y2);
//
// Centimeters domain.
//
SoSeparator *CMSceneGraph = new SoSeparator;
PbDomain *CMDomain = new PbDomain;
CMDomain->setTransformType(PbDomain::TRANSFORM_01);
CMDomain = HIDefineDomain(0., page->PageWidth, 0., page->PageHeight,
0., page->PageWidth, 0., page->PageHeight);
View definition in HIZone:
PoSceneView *DataView;
DataView = HIDefineView(X1ZonePos, X2ZonePos, Y1ZonePos, Y2ZonePos,
page, DataSceneGraph);
PageSceneGraph->addChild(DataView) ;
PoSceneView *AxisView;
AxisView = HIDefineView(0., page->PageWidth, 0., page->PageHeight,
page, AxisSceneGraph);
PageSceneGraph->addChild(AxisView) ;
PoSceneView *CMView;
CMView = HIDefineView(0., page->PageWidth, 0., page->PageHeight,
page, CMSceneGraph);
PageSceneGraph->addChild(CMView) ;
Problems encountered
-
The clipping doesn't work like expected: the system always try to put everything
visible in the domain.To illustrate the problem we have changed the axis
label sizes to 2.0cm in the previous example. With most graphical systems
the text would have been clipped on the viewport boundary. MasterSuite
(OpenInventor) doesn't. Instead it tries to display
the text completly (except the "-".. why ?) which shifted the axis and
produce the completly wrong picture below:
According to TGS this problem should be fixed in OIV 2.5 / 3DMS 3.5
-
The bounding box of a PbDomain should
be always drawn otherwise the content of the PbDomain
is stretched to the PbDomain boundary
in order to fulfill it.
To illustrate this problem we have modified the HIZone
creation in the example in order to have HIZone
limits bigger than the data limits:
HIZone Z(2.,18.,2.,18.,0.,8.,-2.,2.); // create a HIZone Z
HEPInventor draws the bounding box of the DataDomain
in order to have the right picture so the picture produced
is the following:
Then we have commented out the drawing of the bounding box DataDomain
in the HEPInventor code and the picture obtained
is the following which is obviously completly wrong:
-
When HEPInventor pictures (scene
graph(s)) are displayed with a viewer (for example in the Render window
of IRIS Explorer), they cannot be rotated. This is due to
the following code inside the HIDefineView routine:
SoOrthographicCamera *camera = new SoOrthographicCamera ;
view->setPart("cameraKit.camera", camera) ;
If this code is removed the picture can be rotated but the graphics output
obtained is wrong:
-
To draw boxes, the class PoRectangle should
be use. It works fine when it is displayed on screen. When it is output
on a PostScript file it is also good if the box is Filled. But if only
the outline of the box is drawn (hollow mode), the diagonal of the box
is drawn because the Mastersuite PostScript driver convert
all the primitives into triangles. This prevent us to use PoRectangle
to draw boxes outline. We use PoCurve
instead.
-
The quality of text PostScript output is very poor because PostScript fonts
are not used. This is done like that in order to be able to rotate the
text. In most of our cases, the text in not rotated and is drawn in the
screen plane (annotation text) for this type of text PostScript fonts could
be used. Also using PostScript font will reduce the size of the PostScript
files generated. It could be useful to use ``annotation text'' ito draw
axis labels, titles etc ...According to TGS this problem should be fixed
in OIV 2.5 / 3DMS 3.5