Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
Starbase Display List Programmer's Manual: HP 9000 Series 700 Computers > Chapter 7 Display List Editing

The Element-Directed Functions

» 

Technical documentation

» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

As the descriptor implies, the "element-directed functions" relate to individual elements in the currently open segment. The element pointer was discussed in some detail in “The Element Pointer”. Here, we will discuss its use in more detail.

Setting the Element Pointer

There are four routines that set the element pointer; each has its own way of being useful:

  • set_ele_ptr(〈fildes〉, 〈offset〉);

    • and

  • set_ele_ptr_relative(〈fildes〉, 〈offset〉);

    • and

  • set_ele_ptr_relative_to_label(〈fildes〉, 〈label_id〉, 〈offset〉);

    • and

  • set_ele_ptr_at_end(〈fildes〉);

where:

  • offset〉 is a 32-bit integer whose value specifies the location that the element pointer is to indicate. There are three different uses:

    • In the case of set_ele_ptr, 〈offset〉 specifies the offset relative to the null element at the beginning of the segment. A positive value indicates a position somewhere in the segment, a value of zero indicates the null element at the beginning, and a negative value acts like zero.

    • In the case of set_ele_ptr_relative, 〈offset〉 specifies the offset relative to the current value of the element pointer. A positive value moves the pointer forward, zero does nothing, and a negative value moves the pointer backward.

    • In the case of set_ele_ptr_relative_to_label, 〈offset〉 specifies the offset relative to the specified label. A positive value moves the pointer to a position after the label, zero moves the pointer to the label itself, and a negative value moves the pointer to a position before the label.

    In all cases, attempting to move to a position before the first (null) element causes the pointer to indicate the first element; and attempting to move to a position beyond the end of the segment results in the pointer indicating the last element in the segment.

  • label_id〉 is a 32-bit integer value that specifies a previously-defined display list label.

Defining a Display List Label

Of course, the set_ele_ptr_relative_to_label routine described above presumes the presence of a label (which had not yet been discussed). There is a Display List routine — dl_label — that inserts a "display list label" element, containing the specified label identifier, into the current segment. The syntax of the routine is:

  • dl_label(〈fildes〉, 〈label_id〉);

where:

  • label_id〉 is a 32-bit integer that is the label identifier.

The primary reason for using Display List labels is to ease editing and picking tasks. For example, suppose you want to remove a section of a segment. You could easily write a piece of code to delete all elements between two labels. Other useful operations might be copying sections of a display list to another place, replacing elements, locating the code that drew an object that was picked — in short, any time you want to locate a particular place in your display list at which you want to do some operation.

Typically, display list labels are made mnemonic through the use of constants in whatever flavor is appropriate for your language: "#define" for C, "parameter" for Fortran, and "const" for Pascal.

Inquiring the Element Type

Every Display List element has a type. For example, the type of an element might be polyline2d, make_picture_current, polygon3d, refresh_segment, and so forth.

If your application requires the ability to determine, after the fact, what sorts of things have been put into a particular segment, you can do this with the inq_ele_type routine:

  • inq_ele_type(〈fildes〉, 〈ele_type〉);

where:

  • ele_type〉 is a pointer to an integer.

Prior to calling inq_ele_type, a segment must be open, and the element pointer must indicate the element you wish to interrogate. Upon return from inq_ele_type, 〈ele_type〉 will contain a value that indicates the kind of element the current element is. The various possible values of 〈ele_type〉 are enumerated and made mnemonic by a list of hundreds of tokens in the appropriate include file: for C, dl.c.h; for Fortran, dl.f2.h; for Pascal, dl.p1.h; all in the directory 〈sb-incl[18].

After calling inq_ele_type, you can compare the value returned with the values of the tokens from the include file. The tokens from dl.c.h, for example, look like the following:

#define OP_NULL                           0
#define OP_BACKGROUND_COLOR_INDEX 1
#define OP_BACKGROUND_COLOR 2
#define OP_BUFFER_MODE 3
.
.
.
#define OP_SPLINE_CURVE2D 266
#define OP_SPLINE_CURVE3D 267
#define OP_RENDERING_HINTS 268
#define DL_LAST_OPCODE 268

Example with Labels and Element-Type Inquiries

The following example program illustrates the use of display list labels as well as inquiring the element type. The example once again draws the house, but there are several differences from previous versions:

  • All components of the house are now contained in a single segment: House.

  • Display list labels are placed at the beginning of each section of code. That is, the segment is composed of:

    1. A display list label for the wall,

    2. The Starbase commands that draw the wall,

    3. A display list label for the door,

    4. The Starbase commands that draw the door,

    5. And so forth.

  • The house is drawn in a "random" order; that is, the labels are selected in whatever order the programmer wants, and that section of the segment — up to the next label — is drawn.

  • The two sections (entitled FrameLabel and PanesLabel) that draw the window are removed from the display list, and the house is redrawn. The location and removal of these two sections illustrates the ease of using Display List labels.

The randomly-ordered drawing of the various sections of the segment is implemented through a subroutine whose parameters are merely the 〈fildes〉 of the display list, and the label specifying the section to draw. The inner workings of the subroutine are as follows (assume that AtBottom has been initialized to FALSE):

set_ele_ptr_relative_to_label(fildes, Label, 1);
inq_ele_type(fildes, &ElementType);
while (ElementType != OP_DL_LABEL && ! AtBottom) {
refresh_element(fildes);
set_ele_ptr_relative(fildes, 1);
inq_ele_type(fildes, &ElementType);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
}
make_picture_current(fildes);
sleep(1);

Title not available (Example with Labels and Element-Type Inquiries)

Line 1:

The display list label itself doesn't cause any action to be taken; it is just a marker. Therefore, an 〈offset〉 of 1 is passed (along with the label) to set_ele_ptr_relative_to_label. This positions the element pointer to the element immediately following the label.

Line 2:

This sets up the initial value of ElementType, which is one of the loop-control variables. The other loop-control variable, AtBottom, is initially set to FALSE.

Line 3:

The beginning of the element-displaying loop. The loop iterates until the current element is another label (which happens in every section but the last one in the segment), or until the end of the segment is reached (which happens in the last section in the segment).

Line 4:

This call to refresh_element causes the Starbase primitive to be executed, drawing that portion of the image on the display.

Line 5:

Increment the element pointer. If the current element is not the last one in the segment, the current pointer is advanced normally. If the current element is the last one in the segment, attempting to advance the element pointer is a no-op. Since no error is generated, no test of AtBottom is required.

Lines 6-7:

Interrogate the element type and the boundary conditions. These two tests set the loop control variables. If we are at the bottom of the segment, the loop will terminate because of AtBottom being TRUE. If we are not at the bottom of the segment, the loop will terminate when the next label is encountered, causing ElementType to be equal to OP_DL_LABEL.

Lines 9-10

Dump any buffered primitives to the display, and pause long enough that the user can see the order in which the various sections are drawn.

This ability to draw a segment piece by piece can be useful when writing and debugging code — you could determine which section of a segment was causing a problem.

The second operation — removing a specified section[19] of a segment — is accomplished by a very similar algorithm:

set_ele_ptr_relative_to_label(fildes, Label, 1);
inq_ele_type(fildes, &ElementType);
while (ElementType != OP_DL_LABEL &&! AtBottom) {
ElementCount++;
set_ele_ptr_relative(fildes, 1);
inq_ele_type(fildes, &ElementType);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
}
set_ele_ptr_relative_to_label(fildes, Label, 0);
delete_eles(fildes, ElementCount);

The above code:

  1. Goes to the specified label,

  2. Counts the number of elements until the next label or the end of the segment,

  3. Returns to the specified label,

  4. Deletes the number of elements it counted.

ElementCount is initially set to 1, because in our definition of "removing a section," the label for that section is also included.

Here is the whole program:

#include <starbase.c.h>                 /* get Starbase definitions */
#include <dl.c.h> /* get Display List definitions */
#include <stdio.h> /* get standard I/O functions */

#define AppendOff FALSE /* sent to "open_segment" */
#define AppendOn TRUE /* sent to "open_segment" */
#define DisplayOff FALSE /* sent to "open_segment" */
#define DisplayOn TRUE /* sent to "open_segment" */
#define AlwaysCurrent FALSE /* sent to "buffer_mode" */
#define Edges TRUE /* sent to "interior_style" */
#define NoFlags FALSE /* sent to "polygon2d" */

#define House 1 /* segment number for whole house */
#define WallLabel 1 /* \\ */
#define DoorLabel 2 /* \\ */
#define FrameLabel 3 /* \\ display list */
#define PanesLabel 4 /* / label values */
#define RoofLabel 5 /* / */
#define ChimneyLabel 6 /* / */
main() /* program "EleHouse.c" */
{
int fildes; /* file descriptor */
static float RoofStructure[3][2] = {
1.0, 5.0, 9.0, 5.0, 5.0, 7.0};
static float ChimneyStructure[4][2] = {
6.0, 6.5, 7.0, 6.0, 7.0, 7.5, 6.0, 7.5};

if ((fildes = gopen(getenv("SB_OUTDEV"), OUTDEV, NULL,
INIT)) == -1) {
fprintf(stderr, "%s %s\\n", "Error: gopen failed using environment",
"variable SB_OUTDEV.");
exit(-1);
}
buffer_mode(fildes, AlwaysCurrent);
vdc_extent(fildes, 0.0, 0.0, 0.0, 1.25, 1.0, 0.0);
view_window(fildes, 0.0, 0.0, 10.0, 8.0);
interior_style(fildes, INT_HOLLOW, Edges);
    /*- define the display list segment comprising the house */
open_segment(fildes, House, AppendOff, DisplayOff);
dl_label(fildes, WallLabel);
rectangle(fildes, 2.0, 1.0, 8.0, 5.0);
dl_label(fildes, DoorLabel);
rectangle(fildes, 2.5, 1.0, 4.2, 4.2);
ellipse(fildes, 0.06, 0.06, 2.65, 2.3);
dl_label(fildes, FrameLabel);
rectangle(fildes, 5.0, 2.0, 7.0, 4.0);
dl_label(fildes, PanesLabel);
rectangle(fildes, 5.1, 2.1, 5.95, 2.95);
rectangle(fildes, 6.05, 2.1, 6.9, 2.95);
rectangle(fildes, 6.05, 3.05, 6.9, 3.9);
rectangle(fildes, 5.1, 3.05, 5.95, 3.9);
dl_label(fildes, RoofLabel);
polygon2d(fildes, RoofStructure, 3, NoFlags);
dl_label(fildes, ChimneyLabel);
polygon2d(fildes, ChimneyStructure, 4, NoFlags);
close_segment(fildes);
/*- draw the house in a random order */
open_segment(fildes, House, AppendOff, DisplayOff);
RefreshSection(fildes, ChimneyLabel);
RefreshSection(fildes, PanesLabel);
RefreshSection(fildes, RoofLabel);
RefreshSection(fildes, DoorLabel);
RefreshSection(fildes, WallLabel);
RefreshSection(fildes, FrameLabel);
close_segment(fildes);
/*- remove the window and redraw */
sleep(1);
clear_view_surface(fildes);
open_segment(fildes, House, AppendOff, DisplayOff);
DeleteSection(fildes, FrameLabel);
DeleteSection(fildes, PanesLabel);
refresh_segment(fildes, House);
close_segment(fildes);
gclose(fildes);
}
/**************************************************************/
RefreshSection(fildes, Label)
int fildes; /* file descriptor of display list */
int Label; /* indicates desired section of seg. */
{
int ElementType; /* returned from "inq_ele_type" */
int AtTop, AtBottom = FALSE;/* loop control variables */

set_ele_ptr_relative_to_label(fildes, Label, 1);
inq_ele_type(fildes, &ElementType);
while (ElementType != OP_DL_LABEL &&! AtBottom) {
refresh_element(fildes);
set_ele_ptr_relative(fildes, 1);
inq_ele_type(fildes, &ElementType);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
}
make_picture_current(fildes);
sleep(1);
}
/************************************************************/
DeleteSection(fildes, Label)
int fildes; /* file descriptor of display list */
int Label; /* indicates desired section of seg. */
{
int ElementType; /* returned from "inq_ele_type" */
int ElementCount = 1;/* how many elements to delete? */
int AtTop, AtBottom = FALSE;/* loop control variables */

set_ele_ptr_relative_to_label(fildes, Label, 1);
inq_ele_type(fildes, &ElementType);
while (ElementType != OP_DL_LABEL &&! AtBottom) {
ElementCount++;
set_ele_ptr_relative(fildes, 1);
inq_ele_type(fildes, &ElementType);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
}
set_ele_ptr_relative_to_label(fildes, Label, 0);
delete_eles(fildes, ElementCount);
}

The graphical output of the above program is the same house as before: drawn piecemeal the first time, and then drawn all at once, with the window removed.

Modifying a Segment

The three ways of modifying a segment — inserting, replacing, and deleting elements — are described in the following few sections.

Inserting Elements Into a Segment

In the examples up to this point, when elements were inserted, they were inserted at the end of the segment. This may have happened without (your even realizing) the exact procedure.

Elements are inserted into a display list whenever a Starbase or Display List primitive or attribute routine is called and a segment is open. An element of the corresponding type is inserted into the open segment immediately after the element to which the element pointer is pointing. Then, the element pointer is advanced one element, so it points to the new element. In prior examples, elements were added only to the end of the segment; this procedure was followed, and it worked intuitively.

What may be new is this: the procedure works regardless of where the element pointer points. You can go into a previously-defined segment, set the element pointer to the element after which the new element(s) are supposed to go, and insert as before. The same procedure is followed: the new element is inserted after the current element (all subsequent elements being pushed down one location), and the element pointer is incremented to point to the new element. Additional elements may then be inserted without further manual adjustment of the element pointer.

The process of inserting an element is illustrated in the following two diagrams:

Figure 7-1 Before Insertion

Before Insertion

Figure 7-2 After Insertion

After Insertion

For example, in our "house" example, let's add a flower box to the window frame. To do this, we need to take the following steps:

  1. Open the House segment.

  2. Using set_ele_ptr_relative_to_label with an 〈offset〉 of 1, set the element pointer to the element following the window frame label FrameLabel. Since additions occur after the current element, the flower-box primitives will be inserted after the rectangle comprising the window frame itself.

  3. Add the Starbase primitives required to draw the flower box (two rectangles).

  4. Close the segment.

In source code, this would look like:

open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, FrameLabel, 1);
rectangle(fildes, 4.8, 1.6, 7.2, 1.95);
rectangle(fildes, 4.85, 1.65, 7.15, 1.95);
close_segment(fildes);

Replacing Elements In a Segment

Replacing an element in a segment is very similar to inserting a segment, as described above. The only difference is that prior to replacement of each element, the replace_ele routine must be called:

  • replace_ele(〈fildes〉);

This routine sets an internal Display List flag that says, "The next element is to replace the current element, not be inserted after it." Note that this "replace" flag automatically reverts to its "off" state after a single replacement; "replace mode" goes back to "insert mode." A single call to replace_ele permits exactly one element to be replaced, after which, insertions start happening again. Thus, for example, to replace four elements, you must call replace_ele four times.

The process of replacing an element is illustrated in the following two diagrams:

Figure 7-3 Before Replacement

Before Replacement

Figure 7-4 After Replacement

After Replacement

In our house example, let's say we want to replace the gabled roof with a different kind: a gambrel roof. Of course, we don't want the old roof to remain when we install the new one (a la "insert mode"); we really do want to replace it (a la "replace mode"). To effect this in our house, we need to:

  1. Open the House segment.

  2. Using set_ele_ptr_relative_to_label with an 〈offset〉 of 1, set the element pointer to the element following the roof label RoofLabel. This is the element to be replaced. Since replacements occur at the current element, the old roof polygon will be replaced by the new roof polygon.

  3. Call replace_ele to turn on replace mode.

  4. Call the Starbase primitive required to draw the new roof (one polygon).

  5. Close the segment.

In source code, this would look like:

open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, RoofLabel, 1);
replace_ele(fildes);
polygon2d(fildes, NewRoofStructure, 5, NoFlags);
close_segment(fildes);
NOTE: If no replacing is done after setting replace mode, Display List remains in replace mode; the next element inserted into a segment on that file descriptor will replace the element previously there.

Using replace_ele — instead of a logically equivalent delete_eles and subsequent insertion — has the advantage of computational efficiency; performance is better. This is especially important in applications such as animation.

Deleting Elements From a Segment

The final element-directed form of segment editing is that of deleting elements. Deletions occur starting with the current element, and continue for as many elements as you specify. Deletions are accomplished with the routine delete_eles:

  • delete_eles(〈fildes〉, 〈count〉);

where:

  • count〉 is an integer specifying the number of elements to delete, starting with the current element.

After a deletion, the element pointer points to the element following the last element deleted. If the last element in a segment is deleted, the element pointer points to the new last element.

The process of deleting two elements is illustrated in the following two diagrams:

Figure 7-5 Before Deletion

Before Deletion

Figure 7-6 After Deletion

After Deletion

Because of the nature of the concept of deletion, there are several incongruities that can arise from specifying improper values for 〈count〉. Below, these incongruities are enumerated, along with Display List's response to the improper input.

  • count〉 is less than zero. Display List gives an error, and nothing is deleted.

  • count〉 is larger than the number of elements remaining in the segment. Display List merely deletes the current element and all the following elements (within the open segment). You could use this fact to implement a "delete to the end" function by specifying a huge number for 〈count〉.

  • The current element is element 0 — the null element. This cannot be deleted; Display List gives an error.

Specifying 〈count〉 equal to zero is permissible; nothing is deleted — it is a no-op.

In our example, we need to get rid of the chimney — it doesn't fit now anyway, what with the new roof and all. And we should also delete the label for the chimney; a label without a referent makes no sense. To accomplish the desired deletions, we need to:

  1. Open the House segment.

  2. Using set_ele_ptr_relative_to_label with an 〈offset〉 of zero this time, set the element pointer to the display list label RoofLabel. This element (the label) and the following one (the chimney polygon) are the elements to be deleted.

  3. Call delete_eles with 〈count〉 equal to 2.

  4. Close the segment.

In source code, this would look like:

open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, ChimneyLabel, 0);
delete_eles(fildes, 2);
close_segment(fildes);

But How Do We Know It Really Happened?

For those of you who are made just the tiniest bit leery by all this talk about things that are happening in your display list, when you can't actually see it, this section should provide some comfort. For the example program, let's start with a single segment that has all the House elements in it; just like the previous example EleHouse.c. Let's print a "before" picture of the segment, do the editing, and then print an "after" picture of the segment. Comparing the two listings of the segment contents, we can satisfy ourselves that the operations we thought we were doing actually got done.

The source code for printing the contents of a segment might look like this:

set_ele_ptr(fildes, 0);
do {
print_element(fildes, AbbreviateArrays);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
set_ele_ptr_relative(fildes, 1);
} while (! AtBottom);
close_segment(fildes);

Here is the whole program. It draws the same house we've seen before, and prints the segment contents. When you are satisfied that it is the same picture you've seen before, press Return to continue. Then, it does the addition, replacement, and deletion operations discussed above. Finally, it draws the modified version of the house, and prints the modified segment.

#include <starbase.c.h>        /* get Starbase definitions */
#include <dl.c.h> /* get Display List definitions */
#include <stdio.h> /* get standard I/O functions */

#define AppendOff FALSE /* sent to "open_segment" */
#define AppendOn TRUE /* sent to "open_segment" */
#define DisplayOff FALSE /* sent to "open_segment" */
#define DisplayOn TRUE /* sent to "open_segment" */
#define AbbreviateArrays TRUE /* sent to "print_element"
#define AlwaysCurrent FALSE /* sent to "buffer_mode" */
#define Edges TRUE /* sent to "interior_style" */
#define NoFlags FALSE /* sent to "polygon2d" */

#define House 1 /* segment number for whole house */
#define WallLabel 1 /* \\ */
#define DoorLabel 2 /* \\ */
#define FrameLabel 3 /* \\ display list */
#define PanesLabel 4 /* / label values */
#define RoofLabel 5 /* / */
#define ChimneyLabel 6 /* / */
main() /* program "NewHouse.c" */
{
int fildes; /* file descriptor */
static float RoofStructure[3][2] = {
1.0, 5.0, 9.0, 5.0, 5.0, 7.0};
static float NewRoofStructure[5][2] = {
1.0, 5.0, 9.0, 5.0, 7.0, 7.5, 5.0, 8.0, 3.0, 7.5};
static float ChimneyStructure[4][2] = {
6.0, 6.5, 7.0, 6.0, 7.0, 7.5, 6.0, 7.5};
    if ((fildes = gopen(getenv("SB_OUTDEV"), OUTDEV, NULL,
INIT)) == -1) {
fprintf(stderr, "%s %s\\n", "Error: gopen failed using environment",
"variable SB_OUTDEV.");
exit(-1);
}
buffer_mode(fildes, AlwaysCurrent);
vdc_extent(fildes, 0.0, 0.0, 0.0, 1.25, 1.0, 0.0);
view_window(fildes, 0.0, 0.0, 10.0, 8.0);
interior_style(fildes, INT_HOLLOW, Edges);
/*=== define and display the original house ============*/
open_segment(fildes, House, AppendOff, DisplayOff);
dl_label(fildes, WallLabel);
rectangle(fildes, 2.0, 1.0, 8.0, 5.0);
dl_label(fildes, DoorLabel);
rectangle(fildes, 2.5, 1.0, 4.2, 4.2);
ellipse(fildes, 0.06, 0.06, 2.65, 2.3);
dl_label(fildes, FrameLabel);
rectangle(fildes, 5.0, 2.0, 7.0, 4.0);
dl_label(fildes, PanesLabel);
rectangle(fildes, 5.1, 2.1, 5.95, 2.95);
rectangle(fildes, 6.05, 2.1, 6.9, 2.95);
rectangle(fildes, 6.05, 3.05, 6.9, 3.9);
rectangle(fildes, 5.1, 3.05, 5.95, 3.9);
dl_label(fildes, RoofLabel);
polygon2d(fildes, RoofStructure, 3, NoFlags);
dl_label(fildes, ChimneyLabel);
polygon2d(fildes, ChimneyStructure, 4, NoFlags);
close_segment(fildes);
refresh_segment(fildes, House);
PrintSegment(fildes, House);
make_picture_current(fildes);
printf("Press [Return] to go on.\\n");
getchar();
clear_view_surface(fildes);
    /*=== modify the house and redisplay it ===============*/
/*- add the flower box to the window frame */
open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, FrameLabel, 1);
rectangle(fildes, 4.8, 1.6, 7.2, 1.95);
rectangle(fildes, 4.85, 1.65, 7.15, 1.95);
close_segment(fildes);
/*- replace the gabel roof with a gambrel roof */
open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, RoofLabel, 1);
replace_ele(fildes);
polygon2d(fildes, NewRoofStructure, 5, NoFlags);
close_segment(fildes);
/*- remove the chimney */
open_segment(fildes, House, AppendOff, DisplayOff);
set_ele_ptr_relative_to_label(fildes, ChimneyLabel, 0);
delete_eles(fildes, 2);
close_segment(fildes);
/*- display the house -*/
refresh_segment(fildes, House);
PrintSegment(fildes, House);
gclose(fildes);
}
/**************************************************************/
PrintSegment(fildes, SegmentNo)
int fildes; /* file descriptor */
int SegmentNo; /* segment to print */
{
int AtTop, AtBottom; /* booleans */

open_segment(fildes, SegmentNo, AppendOff, DisplayOff);
set_ele_ptr(fildes, 0);
do {
print_element(fildes, AbbreviateArrays);
inq_ele_ptr_at_bound(fildes, &AtTop, &AtBottom);
set_ele_ptr_relative(fildes, 1);
} while (! AtBottom);
close_segment(fildes);
}

The first image is like those you've seen before. The second image, with its flower box, new roof, and missing chimney, looks like the following:

Figure 7-7 New House

New House

The fact that the segment has been successfully modified is attested by both the correctly changed image and the difference between the segment's "before" and "after" pictures. As the program's printout shows, the segment starts out like this:

ELEMENT 0                            (null
element) dl_label( fd, 1)                     (Wall) rectangle( fd, 2, 1, 8, 5) 
dl_label( fd, 2) (Door) rectangle( fd, 2.5, 1, 4.2, 4.2)
ellipse( fd, 0.06, 0.06, 2.65, 2.3, 0)
dl_label( fd, 3) (Window frame)
rectangle( fd, 5, 2, 7, 4)
dl_label( fd, 4) (Window panes) rectangle( fd, 5.1, 2.1, 5.95, 2.95)
rectangle( fd, 6.05, 2.1, 6.9, 2.95)
rectangle( fd, 6.05, 3.05, 6.9, 3.9)
rectangle( fd, 5.1, 3.05, 5.95, 3.9)
dl_label( fd, 5) (Roof) polygon2d( fd, {}, 3, 0)
dl_label( fd, 6) (Chimney)
polygon2d( fd, {}, 4, 0)

Note the one-element window frame section, the three-element coordinate list in the roof polygon, and the presence of the chimney and its label.

After the segment editing, the segment looks as follows:

ELEMENT 0                               (null
element)
dl_label( fd, 1) (Wall)
rectangle( fd, 2, 1, 8, 5)
dl_label( fd, 2) (Door)
rectangle( fd, 2.5, 1, 4.2, 4.2)
ellipse( fd, 0.06, 0.06, 2.65, 2.3, 0)
dl_label( fd, 3) (Window frame)
rectangle( fd, 5, 2, 7, 4)
rectangle( fd, 4.8, 1.6, 7.2, 1.95) (Flower box)
rectangle( fd, 4.85, 1.65, 7.15, 1.95)
dl_label( fd, 4) (Window panes)
rectangle( fd, 5.1, 2.1, 5.95, 2.95)
rectangle( fd, 6.05, 2.1, 6.9, 2.95)
rectangle( fd, 6.05, 3.05, 6.9, 3.9)
rectangle( fd, 5.1, 3.05, 5.95, 3.9)
dl_label( fd, 5) (Roof)
polygon2d( fd, {}, 5, 0)

Note the three-element window frame section (the flower box has been added), the five-element coordinate list in the roof polygon (the roof was replaced), and the absence of the chimney and its label (they were deleted).



[18] The actual path names of directories in angle brackets depend on the file system structure. See the Graphics Administration Guide for details.

[19] The command used to delete elements — delete_eles — is described in detail in the next section of this chapter. See there for the discussion.

Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1995 Hewlett-Packard Development Company, L.P.