 |
» |
|
|
 |
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〉); set_ele_ptr_relative(〈fildes〉,
〈offset〉); set_ele_ptr_relative_to_label(〈fildes〉,
〈label_id〉, 〈offset〉); 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: A display list label for the wall, The Starbase commands that draw the wall, A display list label for the door, The Starbase commands that draw the door, 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: Goes to the specified label, Counts the number of elements until the next label
or the end of the segment, Returns to the specified label, 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 SegmentIn 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: 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: Open the House
segment. 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. Add the Starbase primitives required to draw the
flower box (two rectangles). 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 SegmentReplacing 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: 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: 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: Open the House
segment. 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. Call replace_ele
to turn on replace mode. Call the Starbase primitive required to draw the
new roof (one polygon). 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 SegmentThe 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: 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: Open the House
segment. 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. Call delete_eles
with 〈count〉 equal
to 2. 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: 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).
|