2.3.2. GraphMaster

The GraphMaster class library extends Open Inventor capabilities in the following three areas:

Before going any further, it is very important to read Section 2.1, “ What You Must Know about MeshViz XLM: ”, mainly for the reminder about node kits and the explanation of the GraphMaster and 3DdataMaster domain facilities.

GraphMaster introduces the following 2D and 3D classes that complement the Open Inventor 3D shape node set:


All the above are node kits and have one appearance part that allows the application to change the appearance (material, draw style, texture, etc.) of each of them. The PoArrow( C++ | Java | .NET )and PoArrow3( C++ | Java | .NET )nodes, however, have three appearance parts that allow for the control of the starting shape of the arrow, the ending shape, and the line of the arrow. All angles are specified in radians. Refer to the reference manual for a full description of node kit parts and node fields. The following example (located in $OIVHOME/src/MeshViz/Mentor) shows how to create an arrow and set the appearance of the parts. Note that the domain functionality is important for PoArrow( C++ | Java | .NET )and PoArrow3( C++ | Java | .NET )nodes since the length and width of the starting and ending patterns are given as percentages of the domain (as a reminder, the default domain is [0,1] × [0,1] × [0,1], and default pattern widths and heights are 5% of the domain).


PoCurve( C++ | Java | .NET )and PoCurve3( C++ | Java | .NET )are the two classes used to draw curves in 2D or 3D. PoCurve( C++ | Java | .NET ) builds a curve in the XY plane and may use different representations depending on the curveRepfield. This representation may be a standard polyline joining the given points, a smooth curve, a stair curve, etc. The area between the curve and a given threshold may be filled. “Raised” points can be added to the visualization, as well as markers to identify the location of points on the curve. The 3D class PoCurve3( C++ | Java | .NET )only supports polyline and smooth representations.

The following example (located in $OIVHOME/src/MeshViz/Mentor) creates a curve (sine curve) and shows different attributes that can be used to change the visualization:


[Note]

GraphMaster objects are node kits (see the section called “ Visualization classes”), so you can access each part and change the appearance of each of them. Many axis attributes are computed relative to the domain (see Section 2.1, “ What You Must Know about MeshViz XLM: ”). Text height, arrow length and width, number of ticks, height of ticks, etc. are all computed automatically by GraphMaster (if the field is <= 0.) relative to the domain if your application does not provide a value. All Cartesian and polar axes have geometric starting and ending points. These points are used to compute the location of the axes on the display. For an angular axis, the axis is always centered, when built, at point (0,0,0).

The following example (located in $OIVHOME/src/MeshViz/Mentor) uses Example 2.14, “ A curve and its attributes”, but the curve representation now keeps only the polyline and gets rid of the fill, and the raised and marked points. We are going to use two Cartesian linear axes and add them to our curve to get a new visualization.

Example 2.15. A curve which keeps only the polyline


C++
// tutorialGraph03.cxx
  ...
// Create the curve
  PoCurve *myCurve = new PoCurve;
  SbVec2f points[N_PT];
  double ang;
  int i;
  for (i=0, ang=0.; i < N_PT; i++, ang += 4.*PI/(double)N_PT)
     points[i].setValue(ang, 6. * sin(ang));
  myCurve->point.setValues(0,N_PT,points);
  myCurve->set("curvePointApp.material", 
                  "diffuseColor [1 0 0]");

// Create simple automatic X and Y linear axis
// Do not forget to set the domain if you want
// default parameters to be correct...
  PoLinearAxis *myXAxis = new PoLinearAxis;
  myXAxis->start.setValue(SbVec3f(0.,0.,0.));
  myXAxis->end = 4.*PI;
  myXAxis->type = PoCartesianAxis::XY;
  myXAxis->set("appearance.material", 
                  "diffuseColor 0 0 0");

  PoLinearAxis *myYAxis = new PoLinearAxis;
  myYAxis->start.setValue(SbVec3f(0.,-6.,0.));
  myYAxis->end = 6.;
  myYAxis->type = PoCartesianAxis::YX;
  myYAxis->set("appearance.material", 
                  "diffuseColor 0 0 0");

// Create the root of the scene graph
  SoSeparator *root = new SoSeparator;
  root->ref();

// Define domain
#ifdef USE_PB
    PbDomain myDom(0.,-6.,4.*PI,6.);
    myXAxis->setDomain(&myDom);
    myYAxis->setDomain(&myDom);
    myCurve->setDomain(&myDom);
#else
    PoDomain *myDom = new PoDomain;
    myDom->min = SbVec3f(0,-6,0);
    myDom->max = SbVec3f(4.*PI,6.,0);
    root->addChild(myDom);
#endif
    root->addChild(myXAxis);
    root->addChild(myYAxis);
    root->addChild(myCurve);

    SoXtPlaneViewer *viewer = new SoXtPlaneViewer(myWindow);
    viewer->setSceneGraph(root);
    viewer->setBackgroundColor(SbColor(1., 1., 1.));
...

We perhaps want the axes to share the same origin, and not to cross each other. To make this, we simply have to change the origin of our X axis:


C++
myXAxis->start.setValue(SbVec3f(0.,-6.,0.));


[Important]

Notice that the grid lines are drawn on top of the curve. This is because of the traversal order of the scene graph: the curve object is traversed (thus drawn) before the axes. If you prefer to have the curve drawn on top of the grid, just add the curve to the scene graph after adding the axes.

Instead of creating two PoLinearAxis( C++ | Java | .NET )nodes we could have chosen to use a group of axes. GraphMaster provides five classes to deal directly with “boxes” of axes (2D and 3D axes):

The following program (located in $OIVHOME/src/MeshViz/Mentor) draws the same curve but this time using a PoGroup2Axis( C++ | Java | .NET )node. You will notice in this example that each individual axis may be customized in the same way as in the previous example. To do this, all you have to do is get the part corresponding to the axis in the PoGroup2Axis( C++ | Java | .NET )node kit using the SO_GET_PARTOpen Inventor macro and then edit whatever field you want on this specific axis:


Several curves may also share the same axis system. The following example (located in $OIVHOME/src/MeshViz/Mentor) draws two curves sharing the same PoGroup2Axis( C++ | Java | .NET ) node.

[Tip]

Refer to the section called “ Step 4: Multiple curves sharing one X axis and different Y axes”, if you want to draw several curves that do not share the same axis system.

Example 2.18. Two curves sharing the same axes


You may want to display real-time data and then animate your curve. The following example (located in $OIVHOME/src/MeshViz/Mentor) shows this capability using an SoTimerSensor( C++ | Java | .NET )sensor from Open Inventor. At each time interval, a random number is generated and added to the curve. The X axis shows the step number and the Y axis the random value. The animation cycles through a maximum number of steps, N_PT. You will notice that the domain changes (no matter what kind of property classes are used) and then the display is updated automatically.


The purpose of this section is to show the use of domain functionality when you want to draw multiple data sets which share the same X axis but have different Y domains. In the following example we are going to mix a bar chart representation with a curve representation. Each of the representations has a different Y domain but shares the same X domain.

Two things may be tricky when mixing axes like this. First, you must compute the Y translation for the second axis so that its origin will line up with the origin of the first Y axis. Then you must compute the X translation for the second Y axis so that it does not overlap the first one.

To compute the first translation, you must remember the domain transformation. Then you must compute the scale and/or the translation applied to the Y-axis coordinates because of this transformation. In our example we use the SCALE_X_FIXED transformation. This means that X will not be scaled and Y will be scaled by dx/dy (refer to the domain section in the Section 2.1, “ What You Must Know about MeshViz XLM: ”). Our first axis domain is from -1 to 1 in Y and from 0 to 13 in X. All Y coordinates are thus scaled using a 2/13 factor. So the curve’s Y axis origin is (-1. * 13. / 2.) after the domain transformation. We can apply the same method to the bar chart’s Y axis. Its domain is from -10 to 20 for Y and from 0 to 13 for X. So the transformed Y origin is (-10. * 13. / 30.). We now have both Y coordinates in the same space where we will compute the translation to be applied. To compute the second translation, we will use the SoGetBoundingBoxAction( C++ | Java | .NET )action from Open Inventor. This action, when applied to the root of an axis system, will give you the real bounding box of this system, including ticks, arrows, and text strings. We can use the following skeleton if we want to build a visualization with multiple curves:

For all axis systems:

This method allows you to build as many non-overlapping Y axes as you want. You can also, of course, use the same method if you want to have multiple X axes or multiple axes wherever you want. In fact, you can use the translation value to add a translation node to your scene graph or use this value as the X axis origin of your new axis (the next example, located in $OIVHOME/src/MeshViz/Mentor, uses this second solution).

Example 2.20. A curve and a histogram sharing two different Y axes but the same X axis


C++
// tutorialGraph07.cxx 
  ...
#define N_PT 50
#define PI 3.1315

  // Create the curve
  PoCurve *myCurve = new PoCurve;
    SbVec2f points[N_PT];
    double ang;
    int i;
    for (i=0, ang=0.; i < N_PT; i++, ang += 4.*PI/(double)N_PT)
      points[i].setValue(ang, sin(ang));
    myCurve->point.setValues(0,N_PT,points);
    myCurve->set("curvePointApp.material", 
                    "diffuseColor [1 0 0]");

  // Create the root of the scene graph
    SoSeparator *root = new SoSeparator;
    root->ref();

  // Domain of the curve
  #ifdef USE_PB
    PbDomain myCurveDom(0.,-1.,13.,1.);
    myXAxis->setDomain(&myCurveDom);
    myCurveYAxis->setDomain(&myCurveDom);
    myCurve->setDomain(&myCurveDom);
  #else
    PoDomain *myCurveDom = new PoDomain;
    myCurveDom->min = SbVec3f(0,-1,0);
    myCurveDom->max = SbVec3f(13,1,0);
    root->addChild(myCurveDom);
  #endif
    root->addChild(myXAxis);
    root->addChild(myCurveYAxis);
    root->addChild(myCurve);

  // We compute the bounding box of the first axis system
  // So we will know how to translate the second Y axis
    SoGetBoundingBoxAction myAction(SbViewportRegion(1000,1000));
    myAction.apply(root);
    float xmin,ymin,zmin,xmax,ymax,zmax;
    myAction.getBoundingBox().getBounds(xmin,ymin,zmin,xmax,ymax,zmax);

  // Create the bar chart
    PoSingleHistogram *myHist = new PoSingleHistogram;
    myHist->start.setValue(0.,0.);
    myHist->end = 13.;
    float values[13] = {1.,10.,12.,3.,-5.,15.,10.,7.,-2.,-10.,20.,3.,5.};
  myHist->value.setValues(0,13,values);
    myHist->set("appearance.material", "diffuseColor 0 0 0");

  // Create Y axis for the bar chart
    PoLinearAxis *myHistYAxis = new PoLinearAxis;
    myHistYAxis->start.setValue(SbVec3f(xmin,-10.,0.));
    myHistYAxis->set("appearance.material", "diffuseColor 0 0 0");
    myHistYAxis->end = 20.;
    myHistYAxis->type = PoCartesianAxis::YX;

  // Domain of the histogram
  #ifdef USE_PB
    PbDomain myHistDom(0.,-10,13.,20.);
    myHistYAxis->setDomain(&myHistDom);
    myHist->setDomain(&myHistDom);
  #else
    PoDomain *myHistDom = new PoDomain;
    myHistDom->min = SbVec3f(0,-10,0);
    myHistDom->max = SbVec3f(13,20,0);
    root->addChild(myHistDom);
  #endif

  // Now we have to align horizontally the two Y axis
    SoTranslation *myTrans = new SoTranslation;
    float trans;
    trans = (-130./30.) - (-13./2.);
    myTrans->translation.setValue(0.,-trans,0.);

  // Complete the scene graph (The curve will be drawn after bar chart.
  // The translation should only apply to the bar chart and its Y axis
    root->addChild(myTrans);
    root->addChild(myHistYAxis);
    root->addChild(myHist);

    SoXtPlaneViewer *viewer = new SoXtPlaneViewer(myWindow);
    viewer->setSceneGraph(root);
    viewer->setBackgroundColor(SbColor(1., 1., 1.));
    ...

If you draw business graphs you may want to identify the different parts of your visualization. In this section we are going to look at the PoItemLegend( C++ | Java | .NET )node derived from PoLegend( C++ | Java | .NET )class. All key nodes derived from this class will be illustrated in the 3DdataMaster part of this manual. When you draw curves with GraphMaster, you may use a line representation or draw it using markers for instance. The PoItemLegend( C++ | Java | .NET ) node allows you to annotate your visualization with legends corresponding to the different types of visualization you use in your display. Items in the legend include an optional text string, an optional colored box, an optional set of markers, and an optional line. You can change the appearance of each of these parts. The items may be arranged in one or several columns. Depending on the size of the bounding box of all items (which you specify when you create the legend node), GraphMaster will compute the text height, the box sizes, the number of markers to be drawn, and/or the length of the lines. You cannot control these attributes, but you can adjust margins around these items and the aspect ratio of the filled boxes. Here are some examples of legends you can create:

The following example (located in $OIVHOME/src/MeshViz/Mentor) draws a set of curves and then adds a legend to the display in order to identify these curves.

Example 2.21. Adding a legend to your set of curves


C++
// tutorialGraph08.cxx
    ...
  // Create the legend
    PoItemLegend *myLegend = new PoItemLegend;
    myLegend->start.setValue(-10.,7.);
    myLegend->end.setValue(-3,2);
    myLegend->item.set1Value(0,"sin(x)");
    myLegend->item.set1Value(1,"cos(x)");
    myLegend->item.set1Value(2,"sin(x)*cos(x)");
    SbColor colors[3] =
    {
    SbColor(1., 0., 0.),
      SbColor(0., 1., 0.),
      SbColor(0., 0., 1.)
    };
  myLegend->boxColor.setValues(0, 3, colors);
    myLegend->set("backgroundApp.material", 
                     "diffuseColor 1 1 1");
    myLegend->set("backgroundBorderApp.material", 
                     "diffuseColor 0 0 0");
    myLegend->set("boxBorderApp.material", 
                     "diffuseColor 0 0 0");
    myLegend->set("valueTextApp.material", 
                     "diffuseColor 0 0 0");

  #define PI 3.1415
  #define N_PT 50

  // Create X axis
    PoLinearAxis *myXAxis = new PoLinearAxis;
    myXAxis->set("appearance.material", 
                    "diffuseColor 0 0 0");
    myXAxis->start.setValue(SbVec3f(0.,-1.,0.));
    myXAxis->end = 4.*PI;
    myXAxis->type = PoCartesianAxis::XY;

  // Create Y axis
    PoLinearAxis *myYAxis = new PoLinearAxis;
    myYAxis->set("appearance.material", 
                    "diffuseColor 0 0 0");
    myYAxis->start.setValue(SbVec3f(0.,-1.,0.));
    myYAxis->end = 1.;
    myYAxis->type = PoCartesianAxis::YX;

  // Create the curves
    double ang;
    int i;
    PoCurve *myCurve1 = new PoCurve;
    SbVec2f points1[N_PT];
    for (i=0, ang=0.; i < N_PT; i++, ang += 4.*PI/(double)N_PT)
       points1[i].setValue(ang, sin(ang));
    myCurve1->point.setValues(0,N_PT,points1);
    myCurve1->set("curvePointApp.material", 
                     "diffuseColor [1 0 0]");

    PoCurve *myCurve2 = new PoCurve;
    SbVec2f points2[N_PT];
    for (i=0, ang=0.; i < N_PT; i++, ang += 4.*PI/(double)N_PT)
    points2[i].setValue(ang, cos(ang));
    myCurve2->point.setValues(0,N_PT,points2);
    myCurve2->set("curvePointApp.material", 
                     "diffuseColor [0 1 0]");

    PoCurve *myCurve3 = new PoCurve;
    SbVec2f points3[N_PT];
    for (i=0, ang=0.; i < N_PT; i++, ang += 4.*PI/(double)N_PT)
    points3[i].setValue(ang, sin(ang) * cos(ang));
    myCurve3->point.setValues(0,N_PT,points3);
    myCurve3->set("curvePointApp.material", 
                     "diffuseColor [0 0 1]");

  // Create the root of the scene graph
    SoAnnotation *root = new SoAnnotation;
    root->ref();
    root->addChild(myLegend);

  #ifdef USE_PB
  // Define domain
    PbDomain myDom(0.,-1.,4.*PI,1.);
    myXAxis->setDomain(&myDom);
    myYAxis->setDomain(&myDom);
    myCurve1->setDomain(&myDom);
    myCurve2->setDomain(&myDom);
    myCurve3->setDomain(&myDom);
  #else
    PoDomain *myDom = new PoDomain;
    myDom->min = SbVec3f(0,-1,0);
    myDom->max = SbVec3f(4.*PI,1.,0);
    root->addChild(myDom);
  #endif
    root->addChild(myXAxis);
    root->addChild(myYAxis);
    root->addChild(myCurve1);
    root->addChild(myCurve2);
    root->addChild(myCurve3);

    SoXtPlaneViewer *viewer = new SoXtPlaneViewer(myWindow);
    viewer->setSceneGraph(root);
    viewer->setBackgroundColor(SbColor(1., 1., 1.));
...


You may have noticed in the previous example that the legend is transformed in the same way as the curves during camera manipulation. If the plane viewer is replaced by an Examiner Viewer and if we change the 3D view, we will then get a display like this.

Since we did not define any camera in the previous examples, the plane or examiner viewers add their own at the top of our scene graph to manipulate the scene.

[Tip]

To avoid any view transformation inheritance in the legend node, all we have to do is add our own camera node to the scene graph, between the legend node and the axis and curves nodes. The viewers will then use this camera and any changes made to this camera will affect the axes and the curves, but not our legend node.

In the following code, you will notice the changes for the start and end fields of the legend node. As the legend will not be affected by the viewer camera nor by the camera we have included in the scene graph, the default view will be used to render this node, and the default space for this view is [-1,1]x[-1,1].

[Note]

Furthermore, MeshViz supplies classes to manage multiple views. These classes are PoBaseView( C++ | Java | .NET ) ,PoView( C++ | Java | .NET ) , and PoSceneView( C++ | Java | .NET ) (see the Reference Manual for more information).


All that we have seen concerning 2D applies in the same way to 3D. Instead of a 2D domain, we will deal with a 3D domain. The following example (located in $OIVHOME/src/MeshViz/Mentor) builds a 3D curve and displays it with its 3D axis system. Here we will use the PoGroup6Axisnode. As with PoGroup2Axis( C++ | Java | .NET )which we have already used, the SO_GET_PART Open Inventor macro may be used to retrieve each axis of the node kit. You can then customize each axis if the default representation does not suit your needs.


Property nodes specify the appearance of the representation classes. Only classes inherited from PoChart( C++ | Java | .NET ) take into account these properties.

Figure 2.46. Property node classes for charting


The following visualization nodes may apply to 1D meshes:

Figure 2.47. Enhanced business graphics node classes


The following example (located in $OIVHOME/src/MeshViz/Mentor) displays a tube curve with an elliptic profile curve where the thickness and the color is variable for each vertex of the curve.

Example 2.24. A tube curve


C++
// tutorialGraph10.cxx
...
#define NP 14

float x[NP] =
  {
    0.5, 1.5, 1.8, 2.4,
    3.2, 4.5, 6.3, 6.9,
    8.0, 8.5, 9.0, 9.5,
    9.8, 10
  };
float y[NP] =
  {
    9.0, 7.0, 6.5, 6.0,
    5.0, 5.5, 6.0, 7.7,
    6.8, 6.0, 5.5, 4.5, 3.5, 2.5
  };
float size[NP] = {1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3, 5, 1, 3};

SbColor colorListD[3] =
  {
    SbColor(1,0,0),
    SbColor(0, 1, 0),
    SbColor(0, 0, 1)
  };

// Domain of the representation from [0,0,-1] to [10,1O,1]
PoDomain *myDomain = new PoDomain;
  myDomain->min.setValue(0., 0., -1);
  myDomain->max.setValue(10., 10., 1);

// Font use for axis
  PoMiscTextAttr *myTextAttr = new PoMiscTextAttr;
  myTextAttr->fontName = "Courier";

  SoSeparator *root = new SoSeparator;

// Define the irregular 1D mesh for the geometry of the tube curve.
  PoIrregularMesh1D *mesh1D = new PoIrregularMesh1D;
  mesh1D->setGeometry(NP, x);      // Abscissas of the tube.
  mesh1D->addValuesSet(0, y);      // Ordinates of the tube.
  mesh1D->addValuesSet(1, size);   // Values-set for the variable
// sizes of the tube.

// The tube will be smoothed.
  PoMesh1DHints *mesh1DHints = new PoMesh1DHints;
  mesh1DHints->geomInterpretation = PoMesh1DHints::SMOOTH;

// Material use by the tube.
  SoMaterial *mat = new SoMaterial;
  mat->diffuseColor.setValues(0, 3, colorListD);

// Defined the elliptic profile of the tube.
  PoEllipticProfile *profile = new PoEllipticProfile;
  profile->xRadius = 0.15;
  profile->yRadius = 0.025;

// Define the tube curve representation.
  PoTube *tube = new PoTube;
  tube->material.setValue(mat);
  tube->colorBinding = PoTube::PER_VERTEX;
  tube->thicknessFactor = 0.5;
  tube->thicknessIndex = 1;

// Defines the three axis.
  PoGroup2Axis *g2Axis = new PoGroup2Axis(SbVec2f(0.,0.),
                                          SbVec2f(10., 10.),
                                          PoGroup2Axis::LINEAR,
                                          PoGroup2Axis::LINEAR,
                                          "X-Axis",
                                          "Y-Axis");
  PoLinearAxis *zAxis = new PoLinearAxis(SbVec3f(0,0,-1), 1,
                                         PoLinearAxis::ZY);

// Builds the scene graph.
  root->ref();
  root->addChild(mesh1D);
  root->addChild(myDomain);
  root->addChild(myTextAttr);
  root->addChild(mesh1DHints);
  root->addChild(profile);
  root->addChild(tube);
  root->addChild(zAxis);
  root->addChild(g2Axis);

// Builds the examiner viewer.
  SoXtExaminerViewer *viewer = new SoXtExaminerViewer(myWindow);
  viewer->setSceneGraph(root);
  viewer->setTitle("Tube"); 
...

There are several reasons for the existence of the domain.

First imagine that you have a curve that ranges from 0 to 1 along the x-axis and from 0 to 1000 in the y-axis. You want to represent this curve and also the axis system associated with it.

If you don’t use a transformation, the resulting display will not be legible because the y-axis is very large compared to the x-axis. Intuitively you will want to scale the y-axis relative to the x-axis (or vice versa) in order to obtain something legible. If you do this using an SoScale( C++ | Java | .NET ), it will work for the curve representation (PoCurve) but you will have some problems with the axis representation (PoLinearAxis). Specifically, you will note that the graduation labels as well as the arrow at the end of the axis will appear very flattened along the direction of the Y-axis. So, applying a simple scale transformation is not the correct way to achieve a good result because some parts of your representation need to be uniformly scaled but not others.

The property node PoDomain( C++ | Java | .NET ) addresses these kinds of problems.

Second, many fields of MeshViz nodekits are expressed in the space defined by the current domain. The chapter on Domains of the MeshViz User’s Guide provides additional details about the use of domains.

Generally, you define the domain values as the bounding box of your data and you obtain a square representation.

For instance, if you want to have an X-axis from 0 to 1 and a Y-axis from 0 to 10, you set the domain (PoDomain) fields to: min (0,0,0) and max (1,10,1).

Now, if you want to obtain an X-axis which is double the size of the Y-axis, you must define a domain which has double the size of the Y-data -- that is, min (0,0,0) and max (1,20,1) -- and you obtain the following:

In the first case (square representation), the scale applied by the PoDomain( C++ | Java | .NET ) to the axis is the following:

min and max are the fields of the PoDomain( C++ | Java | .NET ) node.

dx = max[0] - min[0]

dy = max[1] - min[1]

dz = max[2] - min[2]

Sx = 1: the end coordinate of the X-Axis is 1.

Sy = dx/dy = 1 / 10 = 0.1 -> the top coordinate of the Y-Axis is 10 x 0.1 = 1.

Sz = dx/dz = 1 / 1 = 1

In the second case (rectangular representation), the scale applied by the PoDomain( C++ | Java | .NET ) to the axis is the following:

Sx = 1 : the end coordinate of the X-Axis is 1.

Sy = dx/dy = 1 / 20 = 0.05 -> the top coordinate of the Y-Axis is 10 x 0.05 = 0.5

Sz = dx/dz = 1 / 1 = 1

As described in the previous question, defining the domain values as the bounding box of your data gives a square representation. However if you absolutely need to preserve the aspect ratio of your data, you can use the PoDomain( C++ | Java | .NET )::setValues() method with the last argument set to MIN_BOUNDING_CUBE.

For instance, if you want to have an X-axis from 0 to 1 and an Y-axis from 0 to 5, and preserve the original (1 to 5) aspect ratio:

myDomain->setValues(SbVec3f(0,0,0), SbVec3f( C++ | Java )(1,5,1), PoDomain( C++ | Java | .NET )::MIN_BOUNDING_CUBE);

All MeshViz representations ignore the node SoFont( C++ | Java | .NET ) for selecting the font name and size. Instead the property node PoMiscTextAttr( C++ | Java | .NET ) is used for this purpose.

The property node PoNumericDisplayFormat( C++ | Java | .NET ) manages the format of all numeric values displayed by MeshViz. Insert this node with the requested format in the scene graph just before the representation to be configured.