DWARF LayoutManager Tutorial
This tutorial should help you to understand how you can add automatic layout and label placement to your applications.
It first guides you through a simple demo application and than explains the most important aspects of the LayoutManager
interface. It finally gives a rough overview over the implementation of automatic layout in the DWARF framework.
If you are interested in the details of the properties which lead to automatic layout decisions then you are welcome
to read my diploma thesis:
Issues in View Management for 3D Objects on Multiple Displays
Prerequisites
For this tutorial, you should
Lesson 1: Start a simple label demo
In this lesson you will learn to start a simple demo showing some of the capabilities of the
LayoutManager.
Installation:
Install DWARF as usual with the bootstrap, configure, make install cycle but add
the option
--enable-label
to your configure command.
This will build and install a version of DWARF able to run the simplelabel demo.
Running the demo:
To run the simple label demo open a shell window and change to the DWARF installation
directory (usually ~/dwarf/bin). Now execute
./run-servicemgr simplelabel
in the
shell and wait until several new windows appear.
The 3D Viewer window shows 4 objects. The two rectangles are labels which have for their target position the green sphere.
The green sphere as an object generating an anchor position for labels and a yellow cone as obstacle (With the default values the yellow
cone is behind the green sphere).
You can now move the green sphere around with the Manualtracker which has the
Target Object ID = sphere
.
The pictures below show a sequence where the green sphere is moved from left to right and the labels try to
follow, without obscuring the yellow cone.
Lesson 2: How automatic layout is added to a DWARF application
Necessary steps to activate automatic layout:
Automatic layout can be added to almost any scene of a DWARF application.
The first step is to add objects and labels to the scene. The objects can be anchors for labels, obstacles
or both and be part of the 3D or 2D scene graph. The labels can be any object but are limited to the
2D scene graph.
The objects can also already be part of the scene loaded during the Viewer startup, but in this case the parent node
of the objects must be a SoSeparator or a SoVRMLTransform node! Any object added to the scene via the
ViewerControl interface will work.
Now you need to create a layout area in the Viewer. Normally this is the complete visible Viewer window.
It is done via the
ViewerLayoutControl interface. This is the sample python code to do this:
# add LayoutArea
id = "#Screen"
parents = []
oc = DWARF.ViewerLayoutControlObjectConstraints(DWARF.VLC_RECTANGLE, False, DWARF.VLC_ALL_FIXED, 0, 0, 0)
ls = DWARF.ViewerLayoutControlLayoutSettings(True, DWARF.VLC_WHOLE_SPACE, 0, 0, 0, 0, ["SpaceManager"])
ip = DWARF.ViewerLayoutControlPosition25D(0,0,0);
isize = DWARF.ViewerLayoutControlSize25D(26666,20000);
veventsender.sendEvent(DWARF.VLC_ADD, id, parents, oc, ls, ip, isize)
Next you need to register any object taking part in the layout in the Viewer. This is done with the
ViewerLayoutControl interface. E.g. you send a command to define an object as label-anchor or as an
obstacle. Or you define an object to be a label which then is automatically placed.
# add sphere as the label anchor
id = "sphere";
parents = ["#Screen"]
oc = DWARF.ViewerLayoutControlObjectConstraints(DWARF.VLC_POINT, False, DWARF.VLC_ALL_FIXED, 0, 0, 0)
ls = DWARF.ViewerLayoutControlLayoutSettings(False, DWARF.VLC_EMPTY_SPACE, 0, 0, 0, 0, ["SpaceManager"])
ip = DWARF.ViewerLayoutControlPosition25D(0,0,0)
isize = DWARF.ViewerLayoutControlSize25D(0,0)
veventsender.sendEvent(DWARF.VLC_ADD, id, parents, oc, ls, ip, isize)
# add a label
id = "cube";
parents = ["sphere"]
oc = DWARF.ViewerLayoutControlObjectConstraints(DWARF.VLC_RECTANGLE, True, DWARF.VLC_SIZE_FIXED, 0, 0, 0)
ls = DWARF.ViewerLayoutControlLayoutSettings(True, DWARF.VLC_WHOLE_SPACE, 0, 0, 0, 0, ["SpaceManager"])
ip = DWARF.ViewerLayoutControlPosition25D(0,0,0)
isize = DWARF.ViewerLayoutControlSize25D(10,10)
if test.veventsender.sendEvent(DWARF.VLC_ADD, id, parents, oc, ls, ip, isize):
Don't get scared by all the parameters to the
ViewerLayoutControl, they are all explained in the
ViewerLayoutControl.idl
file. But in a first try use the ones from above. Most interesting are the first two object constraints.
The first constraint is either VLC_RECTANGLE or VLC_POINT. In the first case the objects bounding box is used for layout
and in the later the middle point of the objects bounding box (e.g. a label-anchor can be a single point,
but a label should always be a rectangle). The second object constraint decides which parameters can be modified
by the layout algorithm. E.g. label-anchors and obstacles normally are not touched by the layout algorithm, therefore
they have a VLC_ALL_FIXED property. And labels normally are only fixed in their size but not their position.
Therefore they have a VLC_SIZE_FIXED property.
The parents property of an object finally defines to which area an object refers.
E.g. obstacles normally have the screen as their parent and labels their anchor object.
Sample demo with necessary services:
The picture below shows a DWARF application with automatic layout.
It consists of 3 services. The Viewer which displays the scene, a python script
which sends
ViewerLayoutControl commands to the Viewer to initially setup the layout in the scene
and the
LayoutManager receiving
LayoutManagerControl? commands from the Viewer and returning
the calculated layout result back to the Viewer.
Lesson 3: Understanding the LayoutManager code
At this point you should already know that the automatic layout is done in two parts.
One part is done by the Viewer. It calculates all objects bounding boxes and sends them to
the
LayoutManager. And after the
LayoutManager returned a layout result, the Viewer moves all
labels accordingly.
The other part is done by the
LayoutManager. It keeps track of all layout objects and
their properties and calculates new layout results whenever the Viewer asks for it.
The communication between the Viewer and the
LayoutManager is done via the DWARF CORBA
communication channels and defined in the
LayoutManager.idl
file.
The picture below shows the event loop inside the Viewer source code.
It is part of the actualRedraw() method of the Viewer.
It illustrates when the bounding boxes of objects are calculated and when this
information is send to the
LayoutManager and how the results are processed.
--
FabianSturm? - 17 Oct 2004