HOOPS has three ways to insert lines: single lines, polylines, and ink.
A single line is a straight line segment. For example, to insert a line that goes from the origin to 1 unit in the y direction, use
A polyline is a sequence of connected line segments. The following code draws a unit square centered about the origin:
Notice that the first point had to be repeated at the end to close the figure, because polylines are not assumed to be closed.
Sometimes it is useful to insert a collection of disjoint line segments into the scene graph as one element. To do this, you can also use HC_Insert_Polyline. Pass your list of points as you would for a continuous line. For the point count, pass a even negative number to indicate that this is a disjoint polyline. HC_Insert_Polyline will return a negative count for the number of lines inserted. The following code draws a perforated square inserted as a disjoint polyline using HC_Insert_Polyline.
An infinite line is a line that has no beginning or end. It extends indefinitely into space. To draw an infinite line, call Insert_Infinite_Line and specify two points that lie on the line as shown in the following code snippet:
Note that infinite lines are considered unbounded geometry. Thus, they will be ignored in bounding calculations.
An infinite ray is a line that has a beginning but no end. In other words, it has a starting point and then extends indefinitely into space in one specific direction. To draw an infinite ray, call Insert_Infinite_Ray and specify two points. The first point defines the beginning of the ray while the second point specifies a location in which the ray passes through as it extends to infinity. The following code sample shows how you can define a set of five infinite rays. In figure 2.5.4a, you can see these rays rendered in HOOPS.
Note that infinite rays are considered unbounded geometry. Thus, they will be ignored in bounding calculations.
An alternate way to insert a polyline is with the Insert_Ink command. Ink works like the ink coming out of a pen on a pen plotter. The first call to Insert_Ink moves the hypothetical pen to its starting position. Each subsequent call to Insert_Ink moves the pen to a new position, inking a straight line segment as it goes. For example, to draw the same square in the above code, given the same array, you can use
The advantage of ink is that you do not need to construct an array of points. For example, you can read in coordinates from a file, and ink each one without having to wait until the entire file is read so that you can allocate an array for all the points. You do not even have to ink the entire polyline at the same time - you can close the segment being inked, and later can come back to it and resume inking where you left off.
You can terminate the line by calling Restart_Ink. After that, the next call to Insert_Ink will start a new polyline.
HOOPS also allows you to remove vertices that were added by calls to Insert_Ink. If Restart_Ink has not been called for a given polyline created by Insert_Ink, you can use Rollback_Ink to "erase" a specified number of vertices starting with the most recently added one.
A polyline drawn via ink is considered to be multiple form, even though each line segment is drawn with its own HOOPS commands. That is, an inked polyline is equivalent to a regular polyline in all respects, but both are different from a sequence of calls to Insert_Line.
You can change the width of a line using Set_Line_Weight. The default weight is 1.0, which is usually a line one pixel wide (except on very-high-resolution devices - greater than 1000 pixels high - when it is one-thousandth of the screen height). You can force the line to be the minimum possible (a hairline) by specifying 0 as the line weight. This causes lines to be drawn in a fixed (screen space) size, and they will not scale as the object scales. However, HOOPS/3dGS also supports line weights which will scale as the object is scaled or the camera changes. This is enabled by calling Set_Variable_Line_Weight.
You can make a line dashed with Set_Line_Pattern. The pattern is (usually) specified figuratively. For example, here are a few possible line patterns:
There are other line patterns available; see the HOOPS Reference Manual entry for Set_Line_Pattern for details.
Lines whose weight is greater than 1.0 are able to have line treatments. You can treat the ends of lines, and, for a polyline, you can treat how the individual segments join. The endcap of a line is specified as a prefix, and the line join is specified as a suffix, on the line pattern; you must specify a pattern to specify a treatment. For example, to round the ends of a solid line, and to mitre the joints where the line segments of a polyline meet, specify
The leading parenthesis "(" specifies that the ends are to be rounded, the two dashes "--" specify a solid line pattern, and the trailing angle bracket (greater-than sign) ">" specifies that the individual segments are to be joined with a mitre joint. The result looks something like Figure 2.5.4.a.
You can change the color and visibility of lines just the way you might expect. For example,
Although you can set the color for lines and polylines, color interpolation is not available for this primitive. However, you can achieve the effect of color interpolated lines via color interpolation with polycylinders as described in section 2.16.3 of the HOOPS/3dGS Programming Guide.
HOOPS/3dGS includes support for defining custom line and marker styles.
We'll start reviewing the custom marker style functionality since that is used as a basis for custom line styles. Custom markers are specified by defining a custom glyph using Define_Glyph, and then setting the marker style to be the glyph name. The following code example defines 4 glyphs, and inserts 4 markers with each one using a different glyph as a custom marker style:
The result is:
The custom linestyle functionality is considerably more sophisticated. First review the reference manual entry for Define_Line_Style. The following examples are taken from the refman entry:
A solid line (specifically, a dash without blanks) of weight=1 is the default parallel. Therefore the line style resulting from an empty string passed as the definition will be a single, solid line of weight one (1 pixel). However, let's say we want to create the default solid line style with triple weight:
The result:
The double-line version of the above example, with a 20 pixel separation, would look like this:
The following example creates and sets a scalable line pattern that alternates between a line segment, a blank, and a line segment in the segment's contrast line color:
Let's define a custom line style which has arrowheads at either end. We'll first specify the array which defines the glyph for the arrowhead:
const char Arrow[] ={10, 0, 0, -1, 4, -10, 0, 0, 10, 10, 0, -10, 0, -3, 0};
The array entries are as follows:
10 | radius |
0,0 | offset |
-1 | start fill |
4 | point count |
-10,0 | point 1 |
0,10 | point 2 |
10,0 | point 3 |
-10,0 | point 4 |
-3 | end fill |
0 | terminate glyph |
Now we'll define the custom glyph and line style, and insert a line with the new style:
Using parallels, we can easily create a triple-line style:
This example uses the "fixed" setting to force one of the parallels to be always 5 pixels from the center-line, while the other will be affected by the local line weight and consequently be 10 pixels from the center-line.
All the preceding examples describe custom lines that are projected onto the plane of the screen. A result is that, on the screen, line offsets maintain a fixed distance from centerlines and glyphs are always screen-facing regardless of the camera or 3D line orientation. While this is useful in some situations, in other cases you might want to render offset lines and glyphs such that they appear to be lines in 3D space, not screen space. Note that these lines are still temporary geometry – they do not exist in the Hoops database on any permanent basis. To do this in HOOPS/3DGS, use the pattern keyword 'transformed' when defining a line using Define_Line_Style.
![]() | ![]() | ![]() |
To create the 3D effect for your custom line, HOOPS projects the line pattern onto an arbitrary plane. The default plane is defined by the normal (0,0,1) and up vector (0,1,0), however, this may not provide the desired appearance for your line pattern. You can use the Set_Geometry_Options method to define the orientation plane onto which you want your line pattern to projected. If you specifiy one vector to orient your line pattern, then HOOPS assumes that the vector is normal to the plane you want to project onto. If you specify two vectors to orient your line, HOOPS assumes the first vector is the normal and the second vector is an up vector. By specifying an up vector, you can specify a full 3d orientation for glyphs in patterns. Note that geometry options are assigned on a per-geometry basis (not on a segment) and thus are not inherited or shared amongst geometries in a segment like other attributes. Be aware that since these patterns are the result of 3D lines being projected onto a 2D surface, some surprising results may occur when using transformed patterns with offsets on polylines that do not lie in a single plane.
![]() | ![]() | ![]() |
When defining orientation for line styles that use glyphs, use the "fixed" keyword to indicate to HOOPS/3DGS that you want your glyphs to orient themselves via the orientation vectors define is Set_Geometry_Options as opposed to the polyline as shown in the following code sample.
![]() | ![]() |
With Define_Line_Style, you can create a variety of custom designs for your lines with predefined markers as well as specialty glyphs. Then, they can be applied to any segment using Set_Line_Pattern. This function offers some latitude to alter your custom line style during its application but there are limits including no option to change a start or end glyph. However, HOOPS offers the ability to modulate all the available parameters in Define_Line_Style and Set_Line_Pattern with the Set_Line_Pattern_Explicit function.
With Set_Line_Pattern_Explicit, you can set and/or change the following options on a line style:
If at any point, you want to revert to the initial line style defined via Set_Line_Pattern or Define_Line_Style, just call Set_Line_Pattern_Explicit and pass the unset glyphs option.
We've now reviewed enough geometry types to draw the clock described in Section
This example begins with the definition of struct Point, and the inclusion of several standard header files. Remember that HC_POINT must be defined before hc.h is included.
The next part of our example defines the main function. First, we open the segment "?Picture" and set options on it.
The Set_Driver_Options command sets the size and location of the output window. The display is assumed to go from -1 to +1 in each dimension, so this command creates a window that is one-half of the height and width of the display, positioned in the middle of the display.
The heuristic no hidden surfaces (line 17) tells HOOPS that the geometry that we will be using consists of lines and text, with no surfaces (no polygons or other filled objects). Thus, HOOPS does not need to perform hidden-surface calculations. We will get the same picture if we do not specify this heuristic, but it will usually be produced more slowly. It is always a good idea to specify this heuristic if your scene does not contain any hidden surfaces. This heuristic is discussed further in Section 6.1.
Now we get into the heart of this example. Remember that the "?Picture" segment is currently open (it was opened on line 14).
The color of the clock is set to dark blue, and the size of the hour numerals is set to 0.1 oru. Thus, the size of the numbers is set relative to the other objects in the scene, rather than relative to the size of the output window (the default). We also turn on text transforms, because in this case the text is part of the scene (numbers on the face of the clock), and is not just annotation.
The constants rimr and numr control the distance of the edge of the clock and the numerals from the center of the clock. Since the output window goes from -1 to +1 in both the x and y dimensions, the clock will nearly fill the output window.
Lines 26 to 39 contain a loop from 0 to 12 (making a total of 13 iterations). Inside this loop, we use Insert_Ink to draw a polyline for the rim of the clock face, and Insert_Text to place the numerals for the hours.
The final part of the clock face is the central hub. For the hub we use a marker - a solid circle specified figuratively as "(*)" - whose color is set to reddish blue.
Note that we have put the hub in its own segment, to keep its attributes separate from those of the rest of the clock. This separation is good programming style in HOOPS. In this example, however, the only attribute that conflicts is the color of the hub, so we could have left everything in the same segment and set the marker color with the command
If we later change the hub from a marker to a polygon, it is easier to find and change the attributes that apply to it if the hub is in its own segment.
Next, we create the clock hands. Each hand has a different line-weight attribute, so each must be in a separate segment. But both hands are red, so we create a separate parent segment to hold the common color attribute.
Next | Previous | Index |