![]() |
![]() |
![]() |
![]() |
This chapter describes how to assemble the various objects in the Graphics Display Kit to create a Graphics Display Kit application. You should have completed the tutorials in Chapter 2, Tutorials before starting those presented here.
- Introduction, Section 3.1
- Graphics Display Kit objects, Section 3.2
- Datamaps, Section 3.3
- Views, Section 3.4
- Virtual palettes, Section 3.5
- Window, Section 3.6
- Editors, Section 3.7
A Graphics Display Kit application consists of several interacting parts. An application has, at minimum, one or more Graphics Display Kit objects, a view, and a window. Keep the following "big picture" in mind:
![]()
The Graphics Display Kit generally gives you two ways to build each part of an application:
- From the ground up, by assembling base objects.
- With an application component. An application component is a macro object that packages a set of Graphics Display Kit capabilities. For example, Mscene3D is a macro object that defines a view, including a 3D camera, a set of lights, and other view-related base type objects.
The Graphics Display Kit provides an application program interface for accessing the base objects.
You can create a Graphics Display Kit object by assembling base type objects, according to the structure shown below. All objects except DefaultObject (the "root" object) are optional:
The objects that make up a Graphics Display Kit object are summarized in the following table.
You can create an object with any of the application components described below.
A primary use of alternate objects is to speed up rendering while interacting with complex scenes. You do this by connecting an easily rendered alternate object to DefaultObject.
If DefaultObject's active subobject is set to 1, the Graphics Display Kit renders the alternate object instead of DefaultObject. The Graphics Display Kit track editor (that is, GDtrack_edit) always sets active to 1 when DefaultObject is being transformed (that is, moved, scaled, or rotated).
An alternate object typically renders one of three things:
- the bounds of the connect object
- the connected object's data but with different attributes
- some other data entirely
An alternate object can render the bounds of the connected object. You do this by using an alternate object whose modes is set to render bounds. This is the default configuration for the alternate object that is contained inside the Graphic Display kit's DataObject component.
The following diagram, which shows how to do this, is taken from the Bound1AltObj example that is found in Libraries.Examples.Graphics_Display. To see the objects shown in the network, maximize Read_Geom, maximize DataObject, maximize AltObject. Open AltModes, then open mode[5].
An alternate object can render the same data, but with a different set of attributes. For example, you can render spheres as points while they are being manipulated. You do this by using an alternate object whose modes is set to render points.
The following diagram, which shows how to do this, is taken from the AttribAltObj example that is found in Libraries.Examples.Graphics_Display. To see the objects shown in the network, maximize Read_Geom, maximize DataObject, maximize AltObject. Open AltModes, then open mode[5].
It is also possible to set up the alternate object capability to render a bounds around all the objects in the view. To do this, each individual object in the view needs to have an alternate object that is not visible. This is done by setting the visible parameter of the object to 0 as illustrated in the diagram below.
![]()
The top object in the view, which is found inside the viewer, needs to have an alternate object configured to render bounds as shown above. To see an actual example, instance Bound2AltObj, maximize Read_Geom, maximize DataObject, maximize AltObject and open Obj to see an object configured to be invisible. Then maximize Uviewer3D, maximize Scene, maximize Top and look at AltObject to see the top object configured to render bounds.
An alternate object can render entirely different data, perhaps an axis glyph or a downsized version of the data. You do this by creating an alternate object with distinct data.
The following diagram shows how to connect an alternate object that renders a 3D axis glyph instead of the actual object when manipulating it.
This diagram is taken from the DataAltObj example that is found in Libraries.Examples.Graphics_Display. To see the objects shown in the network, instance DataAltObj, maximize Read_Geom, maximize DataObject and maximize AltObject.
An alternate object can be forced to render data with 2D primitives. This may be desirable in cases where you have large data sets being rendered or you are rendering to a remote display. This feature can be used to improve interactivity.
The following diagram shows how to connect an alternate object that renders with 2D primitives when manipulating it.
This diagram is taken from the AltObj2D example that is found in Libraries.Examples.Graphics_Display. To see the objects shown in the pictured network, instance AltObj2D, maximize external_edges, maximize obj, maximize AltObject and open Obj. Notice that space is set to a value of 1. This forces the object to be rendered with 2D primitives.
A datamap converts scalar node data or cell data values to colors.
For example, if you define a datamap that maps data values 0 to 255 to the color range red to green. 0then displays as red, 255 as green, and a value in between as some color between red and green.
AVS/Express datamaps have the following chief characteristics:
- Objects and datamaps - Each Graphics Display Kit object can have its own datamap. An object without a datamap inherits its parent's datamap.
- Single or multiple data ranges - A datamap typically consists of a single data range, one that spans the Graphics Display Kit object's minimum and maximum values. Alternatively, a datamap can consist of multiple data ranges.
- Linear and Step data-range models - For each data range, you specify the color associated with the data range's minimum value and the color associated with the maximum value. These are called control points. The Graphics Display Kit uses an interpolation method to assign colors to data values that fall between the minimum and maximum values. Linear and step are the supported interpolation methods. As part of the interpolation, you indicate the number of color steps for a data range.
- HSV and RGB color models - You can specify control-point colors in terms of either HSV or RGB. Architecturally, datamaps can support other color models. HSV and RGB are the ones currently supported. AVS/Express builds an internal value-color table for each data range. In this table, colors are always expressed in terms of RGB.
- Clamping - A datamap's range need not span the entire data-value range of the Graphics Display Kit object. Data values below the datamap's minimum are clamped to (that is, assigned) the minimum's color. Data values above the maximum are clamped to the maximum's color. Data values between two data ranges are clamped to the minimum color of the range above.
The underlying structure of a datamap consists of low-level objects: Datamap, DataRange, DataRangeModel, DatamapValue, and ColorModel. The objects are located in Libraries.Templates.DMAP.
You typically do not build your own datamaps from these objects. Instead you use and customize higher-level objects, as described later. It is helpful, however, to have some knowledge of a datamap's underlying structure as shown in the diagram shown below.
Many Graphics Display Kit objects that you commonly use already include a default datamap.
DataObject defines a Graphics Display Kit object. Through an object called Datamap, DataObject includes a datamap with the following characteristics:
- a single data range spanning the Graphics Display Kit object's minimum and maximum data values
- HSV-defined colors ranging from blue to red
- 256 color steps
A user can subsequently edit the datamap with the Graphic Display Kit's datamap editor.
In the example below, you create a Graphics Display Kit object with DataObject. The object includes a default datamap:
![]()
The Data Visualization Kit's readers, geometries, filters, and mappers supply their output both as field data (first output port) and as a Graphics Display Kit object (second output port). Inside these macros, the Graphics Display Kit object is created with DataObject, and thus includes the default datamap.
In the example below, you create a Graphics Display Kit object with isosurface. The object includes a default datamap:
![]()
As described previously, DataObject includes DefaultDatamap, so it supplies a datamap whose color range is blue to red. The Data Visualization Kit's readers, geometries, filters, and mappers include DataObject, so they too include DefaultDatamap. You can easily replace DefaultDatamap with another predefined datamap, as illustrated below.
1. Start AVS/Express and choose Single-window DataViewer with a 3D viewer from the startup dialog, or, from an existing AVS/Express session, start a new Single-window DataViewer with a 3D viewer by selecting the appropriate entries from the File->New Application... dialog, as appropriate.
2. Instance into the SingleWindowApp workspace the following: ReadField, bounds and isosurface. Then, connect them as shown in the diagram below.
![]()
You need to supply some data for the example to use.
3. Select Editors->Modules to make the modules user interface panel visible. Select Read Field from the Modules option menu to make the Read Field user interface visible. Select the Browse button, a dialog box appears. Select wind.x, then select the OK button.
4. Select Editors->Light to display the light editor's user interface. Select Bi-Directional in the light type option menu.
5. Select Editors->Modules to make the modules user interface panel visible. Select isosurface from the Modules option menu. Deselect Data0 and select Data1 from the iso component radio box. This causes isosurface to generate the isosurface from one component and map it with the colors from another component.
6. Select the isosurface object in the view using the left mouse button. This makes isosurface the current object. Notice that the Current Object label at the bottom of the view window now says isosurface.
Notice that the data value at the right of the editor's window is 46.77. The data value at the left of the editor's window is -20.84. Isosurface's datamap is currently ranged to these values.
You are now ready to replace the existing datamap.
9. Select GreyScale and hit the Apply button. This datamap is found in Libraries.Templates.DATAMAPS.
Notice that the isosurface is now colored in shades of grey as you would expect with a grey scale datamap.
The completed example is found in Libraries.Examples.Graphics_Display.ReplaceDatamap.
You can create a view by assembling base objects, according to the structure shown below. DefaultPickCtrl and DefaultLight are optional. A view must have at least one camera:
Here is a summary of the objects that make up a view.
You can create a view with any of the application-component objects described below.
The virtual palette gives the Graphics Display Kit the ability to manage its color resources, providing basic control both initially and at runtime over such attributes as the type of visual used, the sharing of palettes and the gamma correction value. The virtual palette provides the following functionality:
- multiple different visuals in use at the same time
- conversion of scalar data values directly to indices without dithering
- support for multiple simultaneous ramps - both greyscale and color - at the same time in the same view
- support for a color allocation mechanism that allows all color resource requests to be satisfied to some degree
- dynamic colormap changes without rerendering
Included below is the V description of the virtual palette.
group+OPort PALvirt<struct_name = "PALvirt",
struct_bitmask = "PALvirtBitmask",
NEnumColors=6,
NEcolor0=0xff0000,NEcolor1=0xffff00,NEcolor2=0x00ff00,
NEcolor3=0x00ffff,NEcolor4=0x0000ff,NEcolor5=0xff00ff> {
int update;
int vclass;
int vid;
int share;
float gamma;
int cube_size;
cmethod+notify_inst init = "PALvirtif_init";
cmethod+notify_val upd = "PALvirtif_update";
cmethod+notify_del delete = "PALvirtif_delete"
The update element is set by objects that are attached to the view. This forces the virtual palette to recalculate the color resources required, possibly causing the underlying system palette to change. All views that have the virtual palette attached are notified that they need to rerender. This occurs under the following conditions:
- object is attached/detached to/from a camera
- datamap is attached/detached to/from an object
- datamap changes
- object's dither technique changes
- object is attached/detached to/from an object
The vclass element controls the visual class that is used by the virtual palette. The following values are valid visual classes:
The vid element provides a way to directly specify a visual id to be used by the virtual palette. If a visual id is provided, it overrides the visual class that is chosen.
The share element specifies if the virtual palette should be shared with others in the system palette or if a private system palette should be created. If a shared virtual palette is specified, an attempt is made to share with virtual palettes that have the same visual type specified.
The gamma element controls the gamma correction used in the system palette.
When an 8-bit visual is being used, the cube_size element controls the size of the color cube that is used.
This section discusses the relationship between the virtual palette and other components in the system: system palette, view, camera, object, and datamap.
![]()
Each system palette is associated with a separate hardware colormap. A system palette is created whenever a virtual palette is attached to it. Other virtual palettes may also be attached to the system palette if they meet a set of matching requirements. When the number of virtual palettes attached to the system palette reaches zero, the system palette is deleted. There are a number of possible relationships between the virtual palette and the system palette:
- A 1:1 relationship where each instance of a virtual palette is attached to a single system palette. This occurs in cases where all the virtual palettes in use are unique. For example, the visuals being used are different or private virtual palettes have been requested.
- A one-to-many relationship where a single system palette supports more than one virtual palette. This occurs in cases where multiple virtual palettes use the same visual and ask to be shared.
Each view has a window on the screen that is rendered into by the Graphics Display Kit. There are a number of possible connections between the virtual palette and the view:
- A 1:1 relationship where each instance of a virtual palette is attached to a single view.
- A one-to-many relationship where single virtual palette is attached to more than one view.
Each object is attached indirectly to a view(s) through a camera. A datamap may be attached to an object or inherited from a parent object. Each object has a dither technique attribute. This attribute is meaningful when the visual used in the view is 8-bit (that is, PseudoColor). Valid values for this attribute are cube and ramp. When cube is selected, scalar data values are converted into RGB values using the datamap. When ramp is selected, the datamap associated with the object is converted into a linear ramp of the specified size. This linear ramp is loaded into a section of the system palette. The scalar data values are converted into indices into the ramp in the system palette.
This section discusses the color allocation scheme that is used. This is necessary only if you are using is an 8-bit visual. For 24-bit visuals, you can directly represent any color. The color allocation scheme must be managed on a system palette basis. This is necessary because a system palette may have multiple virtual palettes attached. Each virtual palette may have different views attached to it. The views may have different objects in them, with different color resource requests.
The first step of the color allocation scheme is the calculation of the resources that have been requested. The color resources requested of the system palette are of two basic kinds: cube and ramp. The cube size for the system palette is determined when virtual palettes are attached to views. Part of this attachment process is to find an appropriate system palette for the virtual palette. If it is the first virtual palette for the system palette, the requested cube size of the system palette is obtained from the virtual palette. If the virtual palette is sharing the system palette with other virtual palettes, it assumes the cube size of the first virtual palette. A subsequent change to the cube size in any of the virtual palettes attached to the system palette is assumed by all virtual palettes. To find all the ramp color resources requested for a system palette, the steps listed below are followed.
This process builds a list of ramps that need to be loaded into the system palette. Each ramp is associated with a datamap. The datamap size is the requested size of the ramp. Each datamap is added as a ramp only once.
The second step of the color allocation scheme is fitting the requested resources to the available resources in the system palette. The first part of the fit process is to determine the largest available region in the colormap that you are using. The colormap used is determined by the visual and share mode that the virtual palette specifies. The size of the region and the color indices of each entry in this region are saved. The next step is to take the requested color resources and map them into the available resources. The basic rules followed are:
- Fit the requested cube size to the available resource. If it does not fit, degrade it until it does.
- Give each of the ramps a percentage of the left-over color resource based on the total requested size of all the ramps.
- The minimum size given is 1. The maximum size given is what has been asked for.
The final step is to calculate and load the requested colors into the hardware colormap. The interesting part in this stage is the conversion of the datamap specification to a linear ramp. If you look at the datamap as a whole, the minimum is the min value for the first range and the maximum the max value for the last range. Each ramp has a size from the previous step that it needs to fit into. So, you query the datamap for a table of the allowed size that spans the minimum to maximum data values. These are the colors that are loaded into the hardware colormap. This has the effect of making each range in the datamap the same size in the ramp no matter what size was actually requested for it. This is necessary since the conversion from scalar value to pixel using a ramp is simply a linear lookup.
The following sections describe the processing that takes place when typical changes occur that cause the virtual palette allocation to change.
Assume that the largest region in the system palette that is available is 150 cells. The requested cube size is 6 and no ramps have been requested. The number of color cells needed to accommodate the cube is 216 (that is, 6x6x6). Since there are only 150 cells available, the cube size is degraded to 5. Now, 125 cells are needed to accommodate the cube. Since the number of cells needed are now available, the process is complete.
Assume that the largest region in the system palette that is available is 256 cells (that is, the whole colormap). The requested cube size is 6 and one ramp of size 256 has been requested. This is the size that would be requested if you ask to have the default datamap converted into a ramp. The number of color cells needed to accommodate the cube is 216 (that is, 6x6x6). Since there are 256 cells available, the cube fits. There are now 40 cells left over. Since only one ramp has been requested, it gets all the color resources it asked for up to what is currently available. So the size of the ramp is 40 cells.
Continuing directly from the previous example, you change the size of the cube in the virtual palette to 5. You now need 125 cells to accommodate the cube. There are 256 cells available, so there is a fit. There are 131 cells left over. Since only one ramp of a size of 256 cells has been requested, it gets all the color resources up to what is currently available. So the size of the ramp is 131 cells.
Assume that the largest region in the system palette that is available is 256 cells (that is, the whole colormap). The requested cube size is 5. Two ramps have been requested: one of size 256 and the other of size 100. The number of cells needed to accommodate the cube is 125. Since there are 256 cells available, there is a fit. There are 131 cells left over to satisfy the two ramps. The ramp allocation works as follows:
- Find the total requested size of all the ramps.
- Allocate to each ramp the percentage it is from the total requested size from the cells available.
For this case, the total ramp allocation requested is 356. Ramp 1 of size 256 is 72%. Ramp 2 of size 100 is 28%. As a result, ramp 1 is given 72% of 131 cells or 94 cells. Ramp 2 is given 28% of 131 cells or 36 cells. The total number of cells allocated for the two ramps is 130. There are 131 cells available. The difference is due to round-off. This may happen from time to time depending on the sizes of the ramps requested and the number of cells available. Each ramp is given at least one cell even if the size calculation is 0. This may happen if one ramp is extremely large and another is small. AVS/Express makes sure that it does not give out more than the number of cells available. It may be that at the last ramp, the calculated size may be greater than what is left. This may happen due to round off or if a ramp size was calculated to be 0. In this case, the ramp gets only the number of cells that are left.
The Graphics Display Kit provides the following virtual-palette objects. They are all created from the base class PALvirt:
The Graphics Display Kit viewers can be set to use an X11 standard colormap. To use the standard colormap with a viewer, set the vclass parameter of the VirtPal subobject to 6.
For example, to have Uviewer3D use the standard colormap, do the following:
The renderer will then try to use a standard colormap. The same procedure can be used for any of the other viewers. In the Uviewer3d object look for VirtPal in the Uscene3D subobject. In the Uviewer2d object look for VirtPal in the Uscene2d subobject. In the Uviewer object, look for VirtPal in the Uscene subobject.
Interactive modification of the virtual palette's subobjects when using standard colormaps is extremely limited. Changes to the share, gamma and cube_size subobjects are ignored. AVS/Express does not do any modifications to the standard colormap once it has been created and installed.
This example shows how to configure the virtual palette so an image is rendered with a ramp using an 8-bit visual. In this configuration, it is possible to dynamically change the colors in the hardware color lookup table.
This example is found in Libraries.Examples.Graphics_Display. The example renders an image of a mandrill in the viewer's window.
You are now ready to configure the virtual palette. This is the first step to allow the image to be rendered with a ramp. Note: these steps have already been done for you in the example that has been loaded.
b. Open vclass. This controls the visual class that is used for this view. Set vclass to 3, which means 8-bit pseudo color visual.
c. Open cube_size. This controls the size of the color cube that is allocated in the virtual palette. Set cube_size to 3.
This reduces the amount of color resource consumed by the cube and allows the ramp to be larger. The dither pattern should now be readily apparent since the cube size is small.
You are now ready to configure the Graphics Display Kit object that represents the image so it will use a ramp. Note: these steps have already been done for you in the example that has been loaded.
This causes the image to become the current object. Any subsequent changes you make using the viewer's editors will affect this object. Notice that the Current Object string at the bottom of the view window now says extract_scalar.
5. Select Editors->Object to make the object editor's user interface visible. Select Field Conversion from the Object option menu. Select Image from the Type option menu.
This causes the datamap that is attached to the Graphics Display Kit object to be converted into a ramp and loaded into a section of the system palette. You should notice that the dither pattern that was present goes away since the image is now rendered with a ramp.
You are now ready to start modifying the datamap and see the effect of the changes you make.
8. Set the Immediate toggle. This causes changes made to the sliders in the datamap editor to be processed as the slider is moved as opposed to when you are done moving the slider.
Notice that the colors of the image are updated immediately. This is because the section of the hardware colormap that is used to render this image is being changed. The view is not rerendered in this case - a virtual palette that is using an 8-bit visual and an object that has a dither technique of ramp.
10. Select Edit Range/Data from the Options option menu. Set the Sub-range Values toggle. This will allow you to perform window leveling on the image.
As you move, all values in the image that are less than the slider value are clamped to the minimum color value. This process can be repeated for the Range Max slider.
You are now ready to change the datamap's ramp size. By default, the requested size of the ramp is 256 as indicated by the range size typein.
13. Set the range size typein to 5. Notice the effect this has on the image and on the color bar in the datamap editor. The individual color bands should be clearly visible.
This completes the tutorial. The completed tutorial is available in Libraries.Examples.Graphics_Display.vpalRamp.
A window defines the UI window in which the view appears.
You can create a window by assembling UI objects according to a structure similar to the one shown below.
The annotations in the diagram indicate the subobjects you typically set.
The diagram illustrates UIrenderView connected to Mscene3D, an application component that defines a view.
Here is a summary of the objects that make up a window.
You can create a window with the application component ViewUI. ViewUI includes UIcmdList, UIshell, UIpanel, and UIrenderView.
An editor lets the user control a root or base object. For example, a camera editor lets the user control a view's camera.
You can build an editor by assembling base objects according to the following structure.
The diagram illustrates a camera editor. It shows only a small portion of the UI objects that make up the user interface. For a complete example, see the application component Ucamera_editor.
Here is a summary of related objects:
Here is a portion of GDcamera_edit, with comments inserted to highlight the main parts of an edit object:
group GDcamera_edit_notify_templ {
//
// shell_vis.
//
int shell_vis;
//
// Parameters used to update the base object.
//
float from_x;
float from_y;
float from_z;
...
//
// Connection to a base object.
//
GDcamera_templ &camera;
};
An edit object has three main parts:
- A shell_vis parameter - This parameter controls whether the editor is active: 0 means it is not; 1 means it is.
shell_vis is only checked if the camera that the editor is attached to has changed. In this case, if shell_vis is not set to 1, the editor does not update. This inhibits updates to the editor's other subobjects - which are normally attached to UI widgets - when the user interface is not visible. The editor always executes when the values of the other parameters change. This means that the camera that the editor is attached to is always updated even if the user interface is not visible.
Typically you connect shell_vis to the same UIcmd object that the user selects to display the editor's user interface:
- Parameters used to update the base object- For example, DefaultCamera3D has a subobject from[3]. GDcamera_edit has subobjects from_x, from_y, from_z. You connect the editor's user-interface widgets to these subobjects.
In this way, when the camera editor first appears, the from_x field contains the current from_x setting for the camera. If the user changes the value, GDcamera_edit is modified, and it in turn modifies the camera.
- A connection to a base object - For example, you connect a camera edit object to the 2D or 3D camera that the edit object controls:
You can create an editor with an application component.
The Graphics Display Kit provides the following editors:
- Ucamera_editor / Mcamera_editor
- Udmap_editor
- Ulight_editor / Mlight_editor
- Uobject_editor / Mobject_editor
- Utrack_editor / Mtrack_editor
- Uview_editor / Mview_editor
The Uxxx editors all work essentially the same way. Each
- Contains one or more edit objects (for example, GDcamera_edit).
- Defines a complete user interface.
- Has an input port for a Graphics Display Kit view and/or Graphics Display Kit object. For example, you connect CameraEditor's first input port to a view, such as the view output of the application component View. The editor then controls the view's picked camera.
![]() |
![]() |
![]() |
![]() |
![]() |
Copyright © 2001 Advanced Visual Systems
Inc.
All rights reserved.