The Graphics Symbiosis System

De Fanti, T A

1973

Ohio State University

TABLE OF CONTENTS

Throughout the document, the "Graphics Symbiosis System" was used to describe the system called GRASS. To aid readability, the long form has been shortened to GRASS.

THE GRAPHICS SYMBIOSIS SYSTEM: GRASS

AN INTERACTIVE MINI-COMPUTER ANIMATION GRAPHICS LANGUAGE DESIGNED FOR HABITABILI1Y AND EXTENSIBILITY

ACKNOWLEDGEMENTS

Professors Lee J. White, Larry H. Reeker, Balakrishnan Chandrasekaran and Charles A. Csuri served as advisers for the dissertation and constituted the reading committee. Much of the motivation to thoroughly implement the system was provided directly or indirectly by these gentlemen. Professor White deserves special thanks for reading and re-reading the dissertation as often as he did.

Professor Charles Csuri provided direction to the project and conscientiously acted as system resident artist to create data and critically evaluate the habitability of the system with respect to his colleagues both in Art and Education.

Manfred Knemeyer was responsible for choosing the equipment, maintaining the PDP-11 Monitor, and writing various I/0 drivers. He also wrote the matrix multiplication routines and the basic algorithms for rotation and segmentation, and was often called upon for insights into the problems and solutions faced while developing the system. He was responsible for the algorithms behind shading and linear interpolation as they now exist.

Gerard Moersdorf is to be credited with the implementation of "TEXT", the debugging technique, and with rewriting all the disk-oriented code. He recently developed the method for swapping assembler modules. Gerry helped fill in the code and thus bring the system to fruition much faster than could have been done otherwise. Some of the system documentation is due to him, as well as most of the efforts to make the system compatible with other similar systems. Gerry has written most of the system utility macros as well.

Mark Gillenson is the system's sophisticated user. Pursuing his own project in Artificial Intelligence and Pattern Recognition, he has coded the shading algorithms, and authored the "FILL", "WARP", and "INTERP" commands. Much of the system's visual quality is due to Mark's work and he is to be credited with many months of work that made the system usable that much sooner.

The implementation of GRASS has been a group effort by the members of the Computer Graphics Research Group at The Ohio State University, supported in part by National Science Foundation Grant GJ-204.

All photographs are reproduced with the permission of The Ohio State University Research Foundation.

VITA

1969
B.A., Queens College, New York City
1969-1970
University Fellow, The Ohio State University, Columbus Ohio
1970
M.S., The Chio State University, Columbus, Ohio
1970-1971
Research Associate responsible for the PDP-10 System of the Department of Computer and Information Science, The Ohio State University, Columbus, Chio
1971-1972
University Fellow, The Ohio State University, Columbus, Ohio
1972-1973
Research Associate, The Computer Graphics Research Group, The Ohio State University, Columbus, Ohio

PUBLICATIONS

Some Considerations for Providing Extensibility and Habitability in a Mini-computer Graphics System, Proceedings of the Eleventh Annual UAIDE Meeting, October 1972.

FIELDS OF STUDY

Undergraduate
Mathematics: Professor L. Mansfield
Romance Languages: Professor R. Picken
Graduate
Programming language Theory: Professor L. White and Professor L. Reeker
Computational Linguistics: Professor L. Reeker
Automata Theory: Professor L. Reeker

LIST OF FIGURES

FRONTISPIECE

Frontispiece

INTRODUCTION

Much has been learned about higher-level programming languages in the eighteen years since FCRTRAN has been with us. Both theory and usage have shown that to make any implementable computer system adaptable to users and their tasks, a considerable effort must be made in the planning stages to provide for natural user interface (habitability) and to incluae methods for easily increasing the power of the language in terms of itself (extensibility). These design features are particularly important in a general purpose animation graphics system for two reasons: first, the users of a graphics system are typically not programmers or even scientists; and second, it is extremely difficult to forsee the future requirements of computer graphics.

In discussing the concepts of habitability and extensibility in a graphics system, it is worthwhile to note that most present day systems are not very good examples . FORTRAN is neither particularly habitable nor extensible - yet most graphics applications use assembler routines added to FORTRAN. The majority of the remaining systems use assembler routines stand-alone in an interpretive mode to draw lines, points, arcs, and to display text. The general simplicity of the stand-alone approaches preclude extensibility although most have made some attempts to be more habitable, with good mnemonics for the commands, for example. However, since any conceivable graphics system must either use a host language or have its own language, the advantages and disadvantages of both approaches must be considered.

FORTRAN is the most common graphics host language for several reasons. It is relatively easy to add assembler routines to FORTRAN to do graphics. Any user input/output is simply and conventionally handled. Numerical calculations of significant complexity may be readily coded in FORTRAN. Most programmers likely to be in the graphics business know FORTRAN and it is the closest thing to a machine independent language in that FORTRAN is most widely available on large and small computers.

FORTRAN, however, is not an ideal language for complex data structure manipulation, parsing language input, or managing critical timing information. A basic difficulty in designing a graphics language is that of retaining FORTRAN's comparatively excellent numerical capabilities (which are compiled) in an interpretive, real-time, on-line system.

One approach might be using PL/I as a host language for the systems programming and numerical calculation and SNOBOL4 for the data structuring and command parsing. A very large system may be obtained using such a combination. None of these state-of-the-art languages is available on a mini-computer, however.

Naturally, the display part of lhe system chanzes at least as often as the computer part so the machine independence and portability advantages gained in FORTRAN may fade when compared to the restyling of the system to allow efficient use of a new "scope." It seems to the author that, given present tools, only a very numerically oriented graphics system for scientists, or a relatively small system may justify using the FORTRAN-based approach. Computer animators, whose numerical needs may be otherwise dealt with, just cannot live with FORTRAN on a mini-computer, mainly for reasons of timing and memory restrictions.

The other approach in common use is creating interpretive line and circle drawing programs which are generally single purpose or limited purpose. Usually, a good idea of the exact application precedes the development, and the program eventually does its job of laying out printed circuit boards or designing tire treads.

Computer animation, as it turns out, is a much more complex problem. The artists - who are as much a part of the animation system as the programmers and the hardware - tend to make demands not readily anticipated by experienced computer people. To expect an animation system to include all features desirable in the present and future as resident functions is as unrealistic as trying to solve all scientific problems with FORTRAN library routines. What is needed, then, is a language that can be built upon, added to in various ways, and constantly expanded as more people interact with it - an extensible computer graphics language.

However, a language of this type must also encourage interaction by the people who will demand the most from it - the artists, filmnakers and instructors. Every effort must be made to avoid rigid syntax, to use "natural language" input and to provide useful feedback. Reference to complex structures should be as simple as possible, and most of the systems programming aspects should be transparent to the user. Furthermore, since flicker is generally unacceptable (and usually unhealthy), interrupt-level structures must be designed to adjust time and execution priorities in order to maintain a real-time display wherever possible. Storage allocation and reclamation are also critical. In short, a good graphics system must take on most of the problems of a timesharing/swapping system for non-programmers while trying to accommodate both persistence of vision and movie cameras.

The remainder of the discussion here will explore in detail one approach to the problem: the design and implementation of an entire graphics programing language on a mini-computer, with provisions for as much extensibility and habitability as seemed practical. Features of the "ideal" system which turned out to be impractical to implement in the present system were natural language input, extensibility through addition of unanticipated data types, usability on computers of different architecture, as well as a host of more difficult problems such as accepting spoken word input and synthesizing speech output (to replace the teletype for user communication), and adapting the system to any display system, plotter or microfilm recorder.

Much of what has been learned in the eighteen years since FORTRAN arrived can be thought of as the general "desiderata" of programing languages. Many of these new concepts are relevant to a graphics system which has, in addition, several of its own requirements. Next discussed will be the design features which were considered desirable in an animation-oriented system.

Let's start with the simpler elements:

  1. basic system functions: In FORTRAN, the basic functions (primitives) include: +,-,*,**,SIN,CALL,DO, etc. In a graphics language, they include something like: DRAW, MOVE, ROTATE, SCALE, DELETE, WARP, etc.
  2. Basic variables: In FORTRAN, these are generally numeric, sometimes alphanumeric. A graphics laneuage needs some alphanumeric and numeric variables, but most of the basic variables are pictures.
  3. Iteration loops: Computers were designed to save program space by iterating. FORTRAN has straightforward looping mechanisms (ALGOL and PL/I have more sophistication here). A graphics language should be able to support loops too.
  4. Good readability: This helps in documentation. To the uninitiated, LISP is unreadable, FORTRAN is better, and COBOL is better yet. Someone other than the programmer should be able to read the graphics program. Now to some more esoteric features:
  5. Facility for adding assembler subroutines: FORTRAN has this capability but most interpretive languages cannot swap code at run time. This is necessary for future, unexpected routines and for efficient core usage when these routines can be swapped onto disk.
  6. Link swapping of code and data: Swapping can sometimes be done in FORTRAN with difficulty. Pictures, assembler modules and graphics language statements should all be disk storable and recallable at swapping speed.
  7. Dynamic storage allocation and reclamation: Often, even if a language allows expansion of core requirements at run time, the operating system does not. FORTRAN is designed to allocate the maximum amount of core any program step will use - an approach which creates difficulties in graphics unless core is very extensive. Reclamation of storage is necessary to keep from constantly running out of core and to maintain some space for swapping.
  8. User-oriented error messages: FORTRAN diagnostics require a manual to decipher. The habitability of any programming language depends largely on the quality of its diagnostics. A graphics system for non-programmers certainly needs more than "??35" or "PUSHDOWN STACK OVERFLOW" to help its users.
  9. Good interactive response time: This is more a systems consideration than a language design criterion, though it does aid the user in learning the language. Minimization of response time provides a reason for coding in assembler. Anything that takes more time than a carriage return and is not specifically designed to be slow, is probably undesirable.
  10. A macro facility: This provides for generating new code from old code easily and efficiently. No such thing exists in FORTRAN, and it is primitive in PL/I. APL has this power and every language should have it.
  11. Natural language input: COBOL was an attempt in this direction. Use of "real" natural language falls afoul of a number of unresolved linguistic problems. The language input does not have to be "unnatural" though, and this is an important consideration for habitability.
  12. Substring matching: This is difficult and unnatural to do in FORTRAN; PL/I and SNOBOL allow it. Ihis facility allows the user to process teletype input in his own way. Finally, the features especially for graphics which make visual data more programmable:
  13. An arbitrarily complex tree-like data structure: This allows dealing with groups of sub-pictures and groups of groups of sub-pictures in a hierarchy. It should feed the display in the order specified by the user, or default to a simple linear linked list when not needed.
  14. A facility for naming pictures and functions with alphanumeric names and storing them on the disk with these names.
  15. user-specified sensitivity to analog controls in a natural way: The user must be able to affect pictures by his interaction with analog devices. This becomes a non-trivial problem when one's installation has a three-dimensional data tablet, ten dials, and a joystick, as well as the binary function switches, cpu switches and lightpen to watch (the exact configuration is given in Appendix B).
  16. ON and IF conditions for discrete phenomena such as function switch states, user-defined variable and dial tests, and teletype substring matches: These operators allow the user to control execution of portions of code synchronously or asynchronously according to his choice of binary input devices, programmable counters, variables, dials, and, with keyboard substring matching, a vast number of possible position independent alphanumeric input strings.
  17. Writing notes to the user when creating segments for interaction with less knowledgeable users: When these segments run off the disk, the user can be carefully stepped through the program if necessary. A fast alphanumeric display terminal is necessary to avoid teletype fatigue here.
  18. Retention of program steps for re-display and debugging: This is necessary for reproducing sequences for filming and testing.
  19. Accurate and flexible timing capability for specifying rate of motion, rotation, function calling, picture duration, etc.: Timing should be specified as a count or as the result of evaluating a function, or as the y-value of the graph in which x is the time count. This feature is critical for filming and precision animation.
  20. In addition, the language ought to be able to accept any well-coded hidden line, shading, linear interpolation, picture editing, compound rotation algorithm or any other display manipulating technique as if the system designer had planned for it.

With the exception of the natural language input, all the above features were designed into GRASS. All are implemented and working, as well as many additional features which are discussed later. At this point, films have been made and several different types of users accommodated by this system. Chapter V has some comments regarding these films and the impact of this work on computer graphics and society.

W C Watt, in his paper on habitability, defines a habitable language (with respect to natural language question answering systems) as one "in which its users can express themselves without straying over the language's boundaries" [1, p.338]. In computer graphics, we deal with the input, processing and output of essentially two- and three- dimensional data. The input is only partially in written language, the remainder being from the electro-sonic-mechanical-analog devices used to create or modify pictures. Therefore, the liberty has been taken here to expand the scope of Watt's "habitability" to include most of what affects "natural" man-machine interfacing in an animation environment.

The quality of being "natural" is obviously relative. Using a paint brush or a chisel and hammer is not particularly more "natural" than drawing with a lighpen. However, inputting all points by keypunching cards is far removed irom drawing and therefore "unnatural."

When creating a language for use by non-programmers, then, one does not use System/360 Job Control Language as a model. Neither should one expect a mini-computer based language to derive "DRAW CAR" from "Listen, machine, I could really get into making a car on that tube." Habitability is not thought of as an all-or-none quality, though, so an effort may be made to make the language as usable as possible by any intelligent person likely to use the system. This naturally leads to a system in which the programmer is no longer required at every step of the way to help the animator or instructor create sequences.

Now let us examine which of the previous desirable features lead to a more habitable graphics system. We will start off simply again and progress from there.

Clearly, if a language is easily readable, with comments and a minimum of strange symbols and syntax, it is probably easily written too, though the converse may not hold, as in APL. To extend this by allowing the user to send himself (or others) notes on a terminal at run time while stepping through a long disk-resident program segment conceptually aids the interaction between man and "tube." Add to this user-oriented error messages with suggestions to alleviate the particular problem, and maybe include some fix-ups for commonly encountered errors, and the machine will be a lot less frustrating to use.

Also not overly complex, but dependent on the data structure implemented, is the ability to group sub-pictures and groups of sub-pictures. This allows reference to a composite picture by a single name and thereby permits the user to translate, scale, rotate, and perform other functions to the composite as a whole, and at the same time. The references to single elements and subgroups of the composite picture are also retained.

Although less trivial than group manipulation from a systems point of view, permitting compound applications of rotation, motion, and scaling to groups of sub-pictures is a natural capability that might be expected of a graphics system. Compound applications of motion and rotation, for example, would be necessary to move a truck along with a dragonfly and two hornets flyine elliptical paths inside the cab. Compound rotation allows helicopters to be flown in figure eights with moving rotors going at independent speeds. Implementing this compound capability is simplified greatly by making the display traverse the data structure in the same way that the user actually creates and interacts with it.

A system is made more habitable if storage allocation and garbage collection operate automatically, simply because the user does not have to worry about it. Certain techniques can be used to compact recollected space and to automatically delete or store infrequently used modules of code or picture data, and automatically recall them when needed again, allowing much more efficient use of core without the user's being explicitly aware of the techniques.

To make the habitat more natural for the user, considerable effort must be directed at letting him specify the interaction between visual or program elements and the twelve-bit analog devices. These devices can be used to specify variation in any dimension, including time. Furthermore, the system should be capable of storing the values of these devices when asked to do so. Then, on a rerun, the user may sit back and watch the program sequence as it was, without touching anything, or he may again interact with some or all of the devices by pushing a button. The new interactions, as mixed with the old, become a new file which can be replayed in turn.

Similarly, sensitivity to binary devices such as function switches must be natural. For this reason, "ON" and "IF" conditions are included in the language. This feature allows the user to key execution of modules, however complex, to the settings of the function or central processor console switches. "ON" conditions set up pending conditions which execute whenever the condition is satisfied. "IF" conditions are used to poll switches and devices within looped code. Since the switches may be programmatically as well as manually turned off and on, this interaction may become quite complex if the user wishes it to be.

The aim of allowing the user more flexibility than he might ever want is furthered by including a number of arithmetic variables. The user can use these as counters, and add, subtract, multiply and divide them. He can use them as x,y,z-coordinate modifiers in place of twelve-bit analog devices when so specified. Since testing is a binary operation, he can test the variables against constants or each other to control program flow by using the "ON" and "IF" conditions combined with the usual arithmetic comparison symbols: EQ, NE, LT, GT, LE, and GE.

These variables and the substring matching facility to be described were incorporated originally as an attempt to accommodate the exploration of methods to study, create and distort the human face. It was necessary to be able to accept teletype input like "make the nose bigger" and translate it into something like "SCALE NOSE, A .... A=A+30CC." The result was designing a keyboard substring matching module to execute code on the basis of the binary success or fail of a match. With enough patience, a rudimentary second-level interpreter could be developed along the lines of writing SNOBOL in PL/I, instead of in assembler. An example (the syntax details are not important here, but they are correct) :

A=O 
SCALE NOSE,A 
ON KB=" NOSE" , DO NOSEBIG 
OR KB= 'EYE', DO EYEBIG 
...
...
NOSEBIG:< IF KB='BIGGER, IF KB='LITTLE', SKIP 4
          IF KB='BIGGER, IF KB='LOT', SKIP 5 
          IF KB='BIGGER', A=A+30CC
          EXIT 
          A=A+1500 
          EXIT 
          A=A+5000
          EXIT>
EYEBIG:<...etc...>

If the code above were stored as a function named, say FACE1, the command "ON FS1, DO FACE1" would cause FACE1 to be executed once the first function switch were tapped. As every line is sent from tbe keyboard, the code checks for the above keywords, and does the processing corresponding to the match, if any. If no match, the program will simply continue until a match is seen. This code will recognize the following sentences:

1) Make the nose a little bigger
2) Make the nose a lot bigger
3) make the nose bigger

and, incidentally,

4) Colorless green noses sleep bigger 

which can be taken as you wish.

A further refinement is to let a word position be enforced. For example, "ON KB='NOSE',..." has the match only succeed on the third word in the line. Less rudimentary linguistic approaches could conceivably be added at a later date, if desired.

Note that substring matching of this type allows users to deal with special purpose applications that the system would otherwise need an enormous dictionary or extra-sensory perception to process. A program dealing with facial features can economically and realistically parse a string like "widen the mouth" whereas a single general purpose system could most likely not, since it could never anticipate all the possible input strings.

As it turns out, this substring matching facility also leads to a degree of extensibility. Extensibility, itself, is normally an attribute associated with compiled languages like PL/I. This distinction may exist because the difference between macros and subroutines in interpretive languages often becomes nebulous. Nevertheless, if a language has "a method for assigning meaning to new syntax constructions and these meanings are, of course, always in terms of old meanings," [2] the language can be considered extensible.

With the exception of PL/I and MAD, widely-used compiled languages have not had anything like an assembler macro definition facility. For an interpretive language in which the code is essentially kept in alphanumerics, the addition of macros is done by adding some SNOBOL-like string manipulation and parsing operations. TECO, on the PDP-10, for example, is an editor with macros of sufficient power to generate other editors.

More ambitious extensibility as found in ALGOL 68 [22] or Galler and Perlis' ALGOL D [3, Chapter 4] is not being considered at this time since most of these extensions to ALGOL 60 are designed for the sophisticated and/or systems programmer, and not for the people at whom GRASS is aimed.

Before continuing with a more detailed exposition, it will be helpful to examine some previous animation graphics languages and systems. In this manner, GRASS may be later viewed by the reader in the context of past efforts. It should be noted that none of the following systems is comparable to GRASS in power or flexibility. Each of these systems advanced the state of the art, however, and the respective contributions should be regarded in that light. Hardware has changed significantly since 1968, a fact that should also be realized in evaluating these systems.

The systems briefly described below will generally be restricted to interactive animation systems, thus precluding microfilm-oriented systems, circuit board and other design layout systems, management information, and any graphics the consoles of the CYBER 70 and S/360 series of computers have to offer. No system prior to 1968 will be considered because the hardware and software did not really start to be significant for animation graphics until about five years ago.

All but two of the systems to be discussed have one deficiency in common - there have been too few films made and circulated. One would think that a system which took considerable effort and backing to realize would be used for producing film. If a system has been around for a few years and only has demonstration film clips to show, the reason surely is not the worldly lack of apllications for computer graphics. The exceptions, of course, are the efforts of The National Hesearch Council of Canada, and the work of the Computer Image Corporation (discussed below).

Systems which rely on random effects to generate abstract films will also not be discussed. It now appears that the age of abstract computer art is past, and that the true use of computer graphics is in portraying recognizable images.

The systems to be explored, then, are those that have attacked the computer animation problem and have had some degree of success.

CAFE [4] is a line-drawing animation system implemented in SNOBOL and FORTRAN on an IBM 360/67 and 2250 configuration. The system has an easily learned language which allows simple single-axis rotations, some data structuring, and development of "scenes" or reproducible picture sequences. It also has some good camera commands.

This system has no tactile devices and its error messages are largely limited to "EH?." All parameters must be numerically specified. The language is not extensible and no macro facility exists. Nevertheless, the CAFE system was an attempt to move away from single-purpose graphics programs.

The Computer Image Corporation system [5] uses primarily analog devices to control video tape equipment integrated into a hybrid computer configuration. Its output is roughly the equivalent of hand-drawn "Hanna-Barbera" work (e.g the "Flintstones"), and, therefore, represents the state of the art in non-digital computer animation. The system's deficiencies seem to center around the cardboard quality of the two-dimensional images (output of the CAESAR system [6]) and the use of scan alteration techniques which give the Foldes' film "Narcissus" [7] some of its quality and limitations. The Computer Image Corporation has successfully mastered the video tape technology. Another technique to their credit is the use of the anthropometric harness to generate figure motion sequences [5, p 105].

In abandoning the digital In abandoning the digital approach to computer graphics, they have limited future capabilities severely. The system does not have a programming language, much less an extensible one. Adding new analog hardware to create a new function is an expensive, time-consuming approach. One would hope that the concepts and video hardware developed by Computer Image could be merged with a. powerful, extensible, yet habitable digital system, thus resulting in an environment that could produce large volumes of high quality film, in short periods of time.

Two systems make extensive use of linear interpolation to produce images. First, KARMA [8], which was essentially more of' an experiment than a system, produced intermediate frames from key frames using an IBN 1130/2250 configuration. The operations were simple and easy to learn in that only linear interpolation commands were developed; no shading, rotation, scaling, or three dimensional effects were provided. Concurrently developed, and much more successful from the animators point of view, was the system created by N. Burtnyk and M. Wein of the National Research Council in Ottawa [9]. Conventional animation techniques were used as a basis for an interactive system exploiting shadeable key frame animation algorithms. ihe system is oriented towards professional animators and, presumably, would not be particularly habitable in an educational environment since the commands often use keywords and concepts that are familiar only to animators. The language used is also not extensible, and the tactile devices are limited to a 2-D data tablet.

Output from this system has been impressive. The hidden line problem has been simplified by establishing layers of picture motion so that the processing necessary to remove hidden surfaces and lines is simplified somewhat. Recent work [10] shows the use of linear interpolation to approximate walking and other human motions in a realistic manner. One would like to see the N.R.C. members acquire more sophisticated hardware to carry on their work.

The interactive movie making system developed at the Moore School of Electrical Engineering [11] is an example of an interactive system written in FORTRAN, with a fairly primitive scope (DEC 338) and slow computing equipment (Spectra 70/46). The system is not particularly habitable due to the lack of analog input devices and the FORTRAN implementation, and is not extensible. It is a system usable by scientists for producing science films by coding pictures and specifying time and motion sequences algorithmically in FORTRAN. This system is not suited for non-scientists unless aided by a programmer, and is thus an example of how FORTRAN can severely limit the use of an animation package. In what it was intended to do, however, this system could be called a success.

Another FORTRAN-based approach is Anderson's work in CAMP and its extensions CAMPER, HICAMP, and HICAPER [12]. CAMP and the later versions have a novel list processing concept for storing pictures in push down stacks. The list processing technique was used to allow pictures of any length to be stored without wasting core, the analogy being to the variable length number fields in earlier computers (IBM 1401, 1620, etc.). Pictures can be grouped to one level using the "stacks" and the stacks can themselves be manipulated like pictures. This approach made it possible to allocate picture space and create a simple hierarchy within the constraints of FORTRAN. In general, the list processing and storage allocation techniques here are considerably less sophisticated than found in GRASS. Limitations oi this work are that motion dynamics must be expressed by equations and input must initially be punched on cards. The system is not extensible either. Several good features exist, however, and these included the capability to generate 3-D perspective drawings in stereo and the concept of the data structure used [13].

GENESYS is a system developed by Ron Baecker at M.I.T. [14] which represents a very habitable computer animation package. The user communicates with the system by using a data tablet to draw, specify motion and timing curves and select commands from a menu. Motion and timing sequences can have variations in them which the user can easily specify by replacing one picture or motion sequence for another in a given time slot. However, the methods used to create animation are fairly primitive and cannot really be extended to larger systems with better hardware. The chief contribution of GENESYS is the high level of user interaction provided.

The picture quality of GENESYS leaves much to be desired - all images are composed of large dots, cannot be shaded or represented in three-dimensions. The system has no real programmable language and is not extensible in any way. GENESYS does represent the first computer animation system for naive users, and, therefore, is a valuable contribution to the world of graphics.

This introduction will be ended with a statement from Ron Baecker, a plea which is now hopefully answered to a great extent by the implementation of GRASS:

What is needed, I believe, are some fresh ideas, a thorough rethinking and reformulation of fundamental concepts for describing images and animator actions, and perhaps a touch of formalization. The concepts of conversational languages, extensible languages, and picture grammars provide some new directions that I think will be of assistance. [15, p283]

I. HABITABILITY IN A GRAPHICS SYSTEM

In the Introduction, several methods were discussed which would help provide a certain degree of natural interaction within a computer graphics animation environment. The purpose of this chapter is to examine in detail the actual features and capabilities of GRASS which lead to reasonably natural interaction.

In an attempt to define "habitable", one must remember that "habitable" can be used as an absolute. A habitable system, in this usage, would be one that only required the user to think of his problem, conceptualize his pictures, imagine the paths, and the system would produce film in colors and perhaps stereovision, without so much as the user's physical presence, his mental "presence" being sufficient. There are no truly habitable systems, obviously. A reasonably habitable system, on the other hand, is one whose conventions are easy to learn and whose commands are powerful, yet easy to use. A truly unhabitable system would be one that required the user to program all his requests in binary machine code, and a fairly unhabitable system might necessitate describing all interactions within FORTRAN syntax.

In a graphics system, habitability is best realized qualitatively by providing a high degree of interaction with the images and equipment. To attain a high degree of interaction, two design criteria must be implemented. First, all available methods of communicating with the electronics must be exploited. Tactile devices are particularly important since they provide direct communication. Where these are insufficient, language may be used, but it should be easy to learn and use. Second, the results of the interaction should be immediately visible - essentially the idea expressed by the concept "real-time:" "that is, time which is 'real' because the moment of the artistic idea is also the moment of its materialization. This is a revolutionary idea in film-making, rather like editing the film before it is made. It makes the creative process a very spontaneous thing, for all the problems of execution are solved in advance" [32]. A "real-time image" is one whose display is complete in less than the one-fifteenth of a second that determines the threshold of persistence of vision. Accordingly, system execution priorities must be adjusted to maintain a flicker-free image or the interaction gained by clever language and device usage is lost.

One must also decide how free the language will be, that is, what syntax requirements will be imposed upon user input strings. If the power of a language is defined as the range of programming tasks that can be attempted within the syntax, one can note that a rigid, unhabitable language may be just as powerful, more powerful. or less powerful than a language that accepts a subset of English sentences. There is no real correlation between the power of a language and its habitability (although execution speed may be sacrificed by excess syntax processing). That few people can use a language does not affect its power, only its use. If one wishes to maintain a real-time system with reasonably instantaneous response time, it is necessary to require some sort of easily parsed syntax that does not need minutes of directory searching and linguistic analysis. It seems, at this point, that a language with easily remembered keywords and predictable syntax is the best approach.

Rotation, for example, is a complex manipulation when compared to scaling er translation. It requires calculation of sines, matrix multiplications, and some housekeeping. An unhabitable system would require the user to write a matrix multiply routine and a sine calculation routine and apply it to the data point-by-point. A FORTRAN-based system might supply the matrix multiply and sine routines as subroutines, or even a subroutine handling rotation within FORTRAN "CALL" syntax, thus only requiring a knowledge of FORTRAN. A reasonably habitable system should recognize "ROTATE" as a command and use its alphanumerical operators to set up the sines, matrices, and do all the housekeeping. A habitable system with tactile interactions also allows the user to specify the operands as tactile devices, or as numbers, if so desired. Finally, a system with good error messages tells the user if he has incorrectly specified the axis or speed of rotation, for example, and thus helps him to learn the syntax and avoid further errors. The term "habitability" contains the root "habit", and a habitable system should be one that leads the user in forming (good) habits as a result of his interactions. A more habitable system simply achieves this goal with less pain on the user's part.

Any interactive computer graphics system that is even barely usable has at least one feature that makes it more habitable for non-scientists (in particular) than other computer packages - the visual feedback. This revelation is both startlingly obvious and profound when thought about. For instance, the visual feedback in an interactive graphics system instantly tells the user if things are working correctly, in at least ninety-nine per cent of the pictures and picture sequences he will attempt. The user is capable of pattern recognition (to say nothing of aesthetic judgements) far more sophisticated that the machine generating the image, and he is thereby much more in the position of knowing whether the picture is "right" or not.

To explore this point further, consider the possibility of a simulated computer graphics programming language, written on a high-speed super-computer. The purpose of the simulation would be to allow preparation of code that would produce animation sequences, at the low cost of hooking up a terminal to the super-computer. No scope would be permitted, however, since interfacing is so costly on big machines. Later, the sequences would be filmed on the mini-computer system being simulated. What could be done with such a capability? Unfortunately, very little; the visual feedback is so important to animators, and coordinates listed on a teletype are so nearly meaningless to anyone but the system programmers, that it would be very difficult to do more than syntax checking of the language commands. Any kind of interactive data generation capability would be lost; rotation effects are not perceivable from matrix values; and even the aesthetics of size relationships is left purely to the imagination.

The point is that although the display and the computer are number-oriented, many people likely to use graphics are not, and that computer graphics without more or less instantaneous visual feedback necessitates accepting a far less productive environment and one that is much less attractive to the animator than a system like GRASS. Computers have the image of being both frustrating and remote - an image which can be overcome only by making interaction less difficult and more tactile.

Most interactive graphics systems have a further inherent capability which helps make them habitable - the interaction itself. The tactile devices one uses to affect the image on the screen take many forms - teletypes, dials, joysticks, data tablets, function switches, etc. Let us discuss how GRASS handles these devices. (See Figures 1 and 2.)

Figure 1 - Environment
ENVIRONMENT. A) Working with the sonic pen - a 3-D data tablet. B) Controlling an image with the light pen and dials.
Figure 2 - Devices
DEVICES -- A) The ten dials - 12 bit analog devices. B) The joystick - a 12 bit analog device. C) The function switches and panic button. D) The VT05 - the user's alphanumeric display terminal.

One may conceptually separate the above gadgets into two categories - binary devices and analog devices. The former carry on/off values and are useful for controlling discrete phenomena. Of course, if no other way is available, a function switch may be used to affect small changes at the expense of much button pushing (or many buttons). Function switches are ideal for controlling execution of animation sequences, or for initiating standard housekeeping tasks, for example. Analog devices are somewhat rarer on display systems, at least in quantity. Typically, such a device will deliver nine to twelve bits of information, which, when scaled to the size of a sixteen inch by sixteen inch screen, comes out to an accuracy of 1/32 to 1/256 of an inch. GRASS makes use of some sixteen analog and thirty-three binary devices. There are ten dials which are referred to as "D0" through "D9", a joystick whose axes are called "JX", "JY", and "JZ ", and the three-dimensional data tablet "SP" (for sonic pen) whose axes are known as "SX", "SY", and "SZ". As a group, with the variables to be discussed later, they are all called "DEV's". A "DEV" is, therefore, a twelve-bit analog device, and anywhere in the syntax that a "DEV" is specified, the user can choose any of these devices or variables. Thus the user can specify which dials control the rotation, path following speed, scaling, zooming, translation, intensity or zoom point of an object, to name a few capabilities. He can also use the sonic pen or joystick axes to transmit these values. DEV's may be multiply assigned, thus giving an easily defined correspondence between x-displacement and size, or intensity and rotation speed and y-dimensional scaling, for example.

If the analog imput devices were unavailable, a very perceptible amount of the system's habitability would vaporize. At least nine bits of information must be supplied somehow and the analog devices are the best suited from a man-machine interaction point of view. Function switches may be repeatedly tapped or set in groups of nine or twelve for each function, but interaction is somewhat less rapid and much less natural. Four digits or two-letter codes typed on a teletype provide enough bits but every change requires re-typing, an action which is only marginally tactile and quite removed from the "feel" of turning a dial or moving the sonic pen. In other words, habitability, being derived mainly from natural interactions, requires interactions to be as natural as possible, within restraints. If the programmatic or financial restraints do not eliminate analog devices, the user benefits greatly.

Since the analog devices are read left-justified into memory, the accuracy lost is on the low-order end, thus allowing fairly accurate comparisons between the nine-bit dials, the eleven-bit sonic pen and the sixteen-bit variables ("A" through "Z") . By using variables set to dials, for example, the user can easily make other than one-to-one correspondences by looping arithmetic assignment statements. Let WITCH and FISH be picture names:

SCALE WITCH, DO 
SCALE FISH,A 
A=DO/2 

every time this code is executed, it will set the witch to the fractional size indicated by "DO" and the fish to half that size.

The above example serves to illustrate one further advantage of the system: certain commands, namely those whose dynamic control is important, are only required to be set up once. Thus, scaling, translation, arbitrary-axis three-dimensional rotation, intensity, cutoff plane setting and zoom point location are commands which assign the device or devices to the name mentioned in the command. "SCALE WITCH,DO" will constantly cause the witch to be scaled on "DO" even though the command is executed only once. "SCALE FISH,A" also allows any change to variable A in the future to be reflected as the size of the fish. To maintain a correspondence between the variable "A" and the device "DO" as in the three-line example above, only the line "A=DO" must be re-executed. The right side of an assignment statement may have any combination of DEV"s, decimal numbers, function switches (used as Boolean values) as long as they are separated by the normal arithmetic operators (+,-,*, and /). One could have variable A represented as the result of a system of equations whose independent variables were dials even though this system is not particularly well-suited to numerical analysis, since it does not compile code. Note hat the "FIX" command will remove DEV assignments and freeze the picture at that point, whereas the "RESET" command will reset the scale, translation, rotation, intensity, etc. to the original positions.

If each command had to be continuously set up, operation of the system in line-by-line interpretive mode (asterisk or non--macro mode), would be impossible, and real-time motion without macros could not be achieved. Much of the system's habitability is derived from the ease with which users can set up constantly changing rotations, scaling, translations and so on, with single commands issued only once. The naive user will spend most of his time in non-macro mods and most film is generated in this mode at this point, so the system must be, and is, easiest to learn and use at this level of usage.

Variables are also useful as the image complexity mounts, causing one to run out. of dials - something quite easy to do, considering it takes five dials to do an arbitrary axis rotation, three for translation, three for single axis scaling on all three axes, three for zoom point, two for cutoff plane, and one for intensity setting. The user can turn the dial he chooses until the desired effect is obtained and then set a variable to the dial, retype the command with the variable as the DEv, and the dial is automatically deallocated.

Variables may also be used as counters for timing control, as coordinates to generate new pictures or algorithmically modify old ones. Variables can be assigned values to alter program control, although it is just as simple to use function switches which can be programmed to turn off and on.

Without variables, two problems would immediately appear. The first is that without variables, users would be absolutely limited to the analog devices. Once these were exhausted, the user would have to limit future interactions severely. Variables can substitute as placeholders for analog devices and therefore allow the user to manipulate many objects in a complex image. Second, variables are used in macros where they are necessary for passing results, algorithmically creating and modifying data, and setting up conditions for which the user need not be called upon to adjust dials. It is hard to conceive of a programming language without numeric variables. Treating programmed variables as analog devices and allowing both analog and digital (algorithmic) settings sets to be a valuable concept and is one that helps the user get himself out of difficulties and explore new techniques through macros as well.

The other tactile device which the system uses is the display terminal, called the V105 by the manufacturer (see Figure 2). Users enter commands, macros and values; they are prompted by this device, receive error messages on it and can take corrective action on it. In other words, it is the teletype assigned to the scope user. If a teletype were not available, inputting statements interactively would be difficult. An approach that could be used is the "menu" technique whereby the user points with a lightpen at keywords appearing on the scope, and the system decides which command was chosen on the basis of the lightpen hit. This method is difficult to use if the user has to input any alphanumeric strings, such as new names. Of course, a scope could have a picture of a typewriter on it and the user could hunt-and-peck "type" with the lightpen but this would be fairly time consuming. Many systems have keyboards. available which are not really teletypes because they go directly to the scope hardware rather than through the host computer, with the characters echoign on the scope's screen through a hardware character generator. Keyboards are normally just as useful as teletypes, except that for animation purposes, it is nice to have the whole screen to film without portions dedicated to listing commands and options. With a system as rich as GRASS, there might be very little picture space left.

Text input as commands can be entered in relatively free form with respect to spaces, tabs, and commas. The operators and operands of a command are definitely position dependent, but some care has been taken to make the ordering natural, or at least predictable. Comments may be interspersed by the "REMARK" command or by use of a semi-colon before the comment.

Several different levels of teletype interaction are provided the user, and a key character is echoed to indicate each mode of input. Normal mode - that is, system command level - is indicated by an asterisk("*") at the beginning of each line, and will be referred to as "asterisk mode". The key character, by the way, also indicates readiness to accept input. Asterisk mode is the default mode to which the user starts and remains until he types a command which triggers another mode. It is also the level to which the panic button, a "CTRL C" on the teletype, and the "EXIT" command trap.

If, during a creation command ("GETDSK" primarily, but "SHADE", "PUTPOI", and "FILL"), the user pushes function switch fifteen (FS15), the creation command will interrupt and allow the user to type commands to alter the partially completed picture. Typically, he might rotate the image, or scale it, for example. When he types "RESUME", the creation command continues until finished, unless of course he pushes FS15 again. This mode is indicated by a pound sign ("#").

The modes of input were developed as time progressed and needs appeared. It became clear that the key characters help the user to recognize at a glance the mode in which he is operating. Without these characters at the beginning of each line, one would never be sure of the operational status of the system. These mode indicators are simply a type of feedback that lets the user know whether he and the system are in agreement, something he should always know. Providing the user with feedback of this type adds to the system's habitability, although perhaps in a minor way. It is surprising how many "minor" features such as this one were included during development to make things easier to learn and easier to use, by providing meaningful feedback.

Often during the execution of a macro, it may be necessary to get teletype input of one or several lines, or the name of a picture or value of a variable. The macro author has the option of using either the "WAIT" command to put him in period (".") mode, or the command "INPUT," which waits only for a single name or value to be typed. Once "WAIT" is issued, the user must type "RESUME" to have the macro continue, unless an operand is specified as the number of lines for which to wait. Thus "WAIT 3" would allow. and require exactly three lines of input before continuing, whereas "WAIT" would allow an indefinite amount of input.

"INPUT $A" (where $A through $H are permissible) requires a name to be input. "INPUT A" requires a numerical expression to be typed in before continuing. By using "INPUT," general purpose utility macros may be written to apply to any name, with the macro querying the user for necessary input as it executes. Several examples of reasonable complexity will be found in Appendix C.

While creating a macro on the display terminal, the user is reminded that he has not yet supplied enough matching right angle brackets by a plus sign ("+") appearing at the beginning of each line, thus indicating macro-creation mode. These plus signs also appear in multi-line commands, of which "TEXT" is a good example. Cnce the user specifies enough right angle brackets, the system reverts to its previous mode.

Error messages in GRASS have been carefully developed to aid the user in learning and interacting with the system. Some redundancy in syntax specifications permits typographic errors to be indicated as such, rather than let them unluckily fall into a strange syntax mode and produce undesired results. When an error occurs, the user is first notified by "??ERROR xxx". He may already know what the number means, but before he so much as blinks, the line in error and a following line with an arrow pointing at the error are typed out. If the user understands the error at this point, he can skip the next step and take corrective acion. If, however, the error needs explaining, he types "?" and a disk file is searched for the error message corresponding to the number. If the user is not in asterisk mode, as when executing a macro, for example, he is put in question mark mode, indicated by a "?" in which he is able to input a line, or a number of lines of code to replace the one in error. When he types "RESUME", he can re-enter the macro at the instruction which follows the one that failed. By just typing "RESUME", he can, in effect, skip the line in error. If in asterisk mode, the line is cancelled and the user remains in asterisk mode.

At this, as well as at any other point, the user has the option of consulting the "HELP" file by using the "HELP" command. In any mode accepting teletype input, "HELP" gives the names of all the system functions. "HELP HELP" explains the system conventions and how to use the help command, and "HELP" followed by a command-name types out the syntax of the command indicated, the switch options if any, an explanation of what the command does, some helpful hints, and at least one example for commands that have operands. The user may type "0 to abort the typeout if he has seen enough. Pages come out until the terminal display screen is full, at which point the user must hit the carriage return button to advance the type-out to the next half page. The "HELP" file is listed in Appendix A.

During the preparation of a macro, it might be helpful to use error interrupts creatively to input multiple lines of code. This particular facility leads to the name "creative error messages". All the macro author needs do is type a funny character in a line and the error message mode could be entered. Of course, "WAIT" could also be used.

Without error messages of any kind, the system would be usable but not very habitable. During early development, processor halts were used to indicate errors, an approach which soon lead to the idea of ignoring errors. This, too, was a poor idea since one never quite knew where errors were occurring, although the visual feedback made it obvious that something was wrong. Quickly implemented (as part of the original master plan, but with increased priority) was an error reporting technique that printed out the program counter contents of the error location. This helped development, but was predictably recognized to be useless to users who have no way of correlating core locations with error meanings. The present error reporting system was developed and is certainly much nicer to use. "Impossible" errors, that is, ones occurring only as the result of drastic system failures are reported with the program counter contents and the message "SYSTEM CRASH--CALL THE SYSTEMS FROGRAMMERS!"

As it stands, the error messages provide good diagnostics. The little arrow under the syntax element in error is very useful, and the disk-resident explanations help the users learn the system. A new step in user interaction was probably taken with the inclusion of "creative" error messages. In any system, diagnostics are very important for establishing habitability, and a system aimed at non-programmers derives even more of its habitability or lack thereof from its error messages.

In concluding the discussion or tactile and keyboard interaction, it is necessary to note the panic facilities of GRASS, which can also be used creatively. The function switch interrupt button-marked "panic" on plastic overlays that fit over the buttons - will interrupt any macro at the next statement and return the user to asterisk level. Many long or time-oriented routines like "SMOOTH" Or "PATHMOV" also check the panic button in their innermost loops. On the display terminal, a "CTRL C" will abort anything as soon as any input or output is requested, and also return the user to asterisk mode. "O" stops output to the terminal display screen and leaves the user in his current mode. "U" allows the user to cancel an entire line that he has typed, and the "rubout" key will backspace over the last letter typed, erase it, and replace it with the next character typed. Furthermore, the user could program any device or function switch in the system to cause the "EXIT" command to execute, thereby programmatically simulating a panic button push.

An example of creative use of the panic button is the following macro which aids in adjusting the joystick to zero with the rheostat trims:

<PROMPT JX,JY,JZ  ; THIS HINTS THE VALUES OF 
                     ; JX, JY, AND JZ. 

SKIP -1> 

This macro would go on forever unless the panic button were pushed.

A habitability consideration aimed primarily at naive users is maintaining the impression that they are controlling the system when in fact the system is simply permitting them to input alphanumerics, adjust dials, and push buttons. User panic facilities make the system less scary to use, since even adventurous macros and experiments can be tried and later aborted if necessary by a single button push in most cases. It is often much easier to write a macro without initially specifying exit conditions and rely on the panic button for escape. A system in which the user has positive control over program execution at all times is easier to learn and use than one which allows no non-destructive escape from accidental user-caused infinite loops.

It should be noted here that the user does not need to know all the commands, control characters and tricks of the system. He only needs to know a subset of the features roughly matched to the complexity of his problem. Most user interaction is at asterisk level and only five or six commands are necessary to satisfy the demands of many naive users. In fact, much good film was made on the system before anything other than asterisk mode existed.

So far, we have dealt with the details of the habitability considerations which concerned interaction with the programming language via keyboard, devices and buttons. GRASS allows levels of complexity not only in macros, but in structuring the displayed pictures as well. Chapter III has a detailed description of the mechanics of this interaction.

To a computer scientist, the notion of a tree structure is basic. He might have trouble explaining the utility of trees to an artist or filmmaker, but at least the idea is well understood by him. The notion of a tree can be fairly easily introduced to graphics users once they have used the system a little while. They ask if one can group items for reference purposes. Soon, they want to control size, translation and maybe intensity of a group of items in some kind of hierarchical scheme. Once they know such grouping can be done, they want to learn how to do it. Visual feedback is also a fine motivational influence. Furthermore, once the notion of compound rotations - propellers or flapping wings on objects that are moving - is introduced the small burden of doing "housekeeping" for the data structure, given suitable aids, is accepted.

The capability of grouping picture elements to any level and applying any transformation on any or all levels of the structure in real time is easily the single most visually exciting contribution of this system to the world of computer graphics. Half-tone birds have been taught to fly, air-planes flap their wings, and a witch flies around with a propeller providing the pull. Even walking motion, when analysed, is really a series of bounded rotations around joints, nested to four or five levels. Control over each level is, cf course, assignable to analog devices or to the variables so the interaction may be tactile, programmatic, or both.

How, then, does a person to whom tree structures mean nothing interact with this powerful tool? He simply is required to use the "GROUP" command with the appropriate operands. For example, given two pictures as leaves - AIRPLN and PROP - the following sequence would fly the AIRPLN around with the PROP spinning:

GETDSK AIRPLN            ;GET THE AIRPLN FROM THE DISK 
GETDSK PROP              ;GET THE PROP TOO 
GROUP PROP,AIRPLN,PLAINE ;GROUPED STRUCTURE IS 
                         ;NAMED "PLANE" 
ROTATE PROP,X,DO         ;PROPELLER SPEED ON DO 
ROTATE PLANE,Z,D5,D6,L7  ;ARBITRARY AXIS ROTATION 
REMARK               /SEE APPENDIX A FOR SYNTAX HELP/ 

A little more (but not much) work is necessary if the position of the propeller is not originally correct, as is the case when the same propeller is attached to the witch's broomstick. All that is needed, however, is simple scaling and translation to adjust the propeller position and size. Figure 3, which follows on the next four pages, is a photo-scenario illustrating the use of grouping and other system functions.

Figure 3a - Scenario
GROUPING -- A) First the user gets the witch outline and shades it, B) Then she gets the propeller, groups the shaded outline (SWITCH) with the PROP and requests a diagram of the data structure with "TREE".
Figure 3b - Scenario
C) After checking that the data structure is all right, she scales the propeller to the correct size, sets it rotating and moves it into place with the joystick. D) Then the entire group is rotated and a directory of the picture elements is requested.
Figure 3c - Scenario
E) The directory gives the devices assigned to each picture and group. F) The final grouped image can be manipulated as if it were a single vector list.

The user builds groups into hierarchies by grouping them (see Figure 10 and Figure 11 - Chapter III). A command "TREE" lists the structure on the display terminal with tabs to indicate the grouping level of each element. To insert and delete elements from a formed group structure, the "PUTLIB" and "GETLIB" commands are necessary. When the user specifies the first two operands of the group command, he is tacitly including all group nodes or leaves in between the two, if any, although the order in which he specifies them is not important. Thus, if he makes a mistake and groups too much - and this is immediately visually evident if any group transformation is applied - he simply "PUTLIB's" the entry in error. The "PUTLIB" command selectively blanks the image but saves its core image and structure, and chains it to the in-core library data structure. The entry, which can be a group (node) or a single picture (leaf), is also removed from the hierarchy of displayed pictures. The entry could also be deleted, but then its core image would be destroyed. A "GETLIB" command will redisplay the picture, placing the entry in front of the data structure if the leaf or node name is the only operand of the command, or after any element in the entire displayed data structure if that element's name is the second operand. Thus, with "GETLIB/FUILIB" sequences, the picture may be moved around within the data structure quite easily. One always knows which element he is moving because it is temporarily blanked. For example, in the above code, "GETLIB WING,PROP" would put the "WING" into the group "PLANE", whereas "GETLIB WING" would display the wing, but not. place it in the group, assuming "WING" was put in the in-core library at one point or another. Then, "PUTLIB WING" could remove the "WING" from the displayed structure and blank it, removing group assignments, if any. Note that, for all practical purposes, the order of sub-elements of a group is unimportant unless some of them later have to be subgrouped. A group may also contain just a single leaf, a technique which is useful for creating complex tumbling sequences which require multiple-level rotations.

It must be reiterated that the capability of specifying something as powerful as grouping so easily is an important addition to the system's habitability. Were this capability not developed, the ordinary user simply could not effect compound transformations unless he resorted to some special assembler coding, an unacceptable approach for the non-programmer user. Providing easy access to the power inherent in a tree data structure for even relatively naive users is a design feature that was deemed necessary from the earliest stages of planning.

Details of algorithmic implementation of grouping and compound transformations will'be found in Chapter III.

Also of convenience to the user are the disk access and file manipulation commands. "GETDSK" and "PUTDSK" commands are written so well that it is now considerably easier- to use GRASS to do general purpose file manipulation than to use the program supplied by the computer manufacturer. The user has the choice of recording and retrieving his pictures in binary to save space, in easily readable decimal format, or in Vector General display instruction format. Renaming disk files is as easy as renaming core resident names. A background job was implemented to print any disk file on the system hardcopy device while people are using the system for graphics. Taking advantage of the Disk Operating System's file structuring capabilities, the system also allows access from common areas and requires a password log-in for integrity of the user production disk cartridge. Macros can be fetched from the common area by the "CALL" command, and from the user area by the "DO" command. Disk directories may be obtained for any area of the disk ("DIRDSK" and "DIRCOM") or for all of the disk ("DIRALL"). The "HELP" command in Appendix A further explains the disk oriented commands in the system.

One exciting capability of the system that resulted as one of the many interactions between users and systems programmers was the variable intensity setting of grey-shaded areas. The extremely flexible system shading routines include two dimensional and three dimensional shading at any angle (or optimized angles), with any raster for spacing, and, by user interaction with the "SETINT/S" command, any grey level. By specifying a dial, the user can vary the intensity of any surface of a shaded object, one surface at a time, until the desired effect is achieved (see Figure 4).

Figure 4 - Setintensity
SETINTENSITY - The graphics language allows the user to interactively specify the intensity of each facet of a 3-D shaded picture. The intensity is normally set by a dial whose variations can run through all 32 levels of intensity.

If the system were coupled to a DATACOLOR colorizer [23], the artist could look at the colorizer's screen and the grey level he chose could be transformed into a rich, saturated color. By varying the dial, a whole range of colors could be investigated.

Other interactions with the system software architecture include a start on data generation and editing facilities ("WARP") and the "FILL" command. "FILL" allows the user to specify an outline, a fill character, and a speed of filling. Filling is done by positioning the character randomly in the outline until a function switch push terminates the fill. The orientation of the fill character may be specified as randomly rotated or parallel. Thus, grass can be grown on a hillside, trees fill a forest, hair grown on a billiard ball, or feathers appear on a bird. The potential of this command should be limited only by one's imagination - a nice feature for a computer package.

Text on the screen is handled unconventionally GRASS. All characters are software subroutines and are the result of conversions of Alan Hershey's [16] beautiful set of some fifteen character fonts. Since these are software characters, they may be rotated, scaled, and translated like any other picture elements - a level of flexibility not to be obtained with hardware characters which bypass the analog hardware (see the Frontispiece and Figures 5, 6, and 7).

Figure 5 - Text Example I
Figure 6 - Text Example II
Figure 7 - Text Example III

Habitability, as defined in the Introduction, really appears both actively and passively. So far, the active aspects of the system's habitability - that is those apparent to the user - have been discussed. There remain, however, many features in this system which are invisible to the user in most cases but which actually allow the active features to exist and function smoothly. These could be called the passive habitability considerations.

Probably the most important internal algorithm to the system's functioning is the storage allocation and reclamation routine. Thirty-two word blocks of memory are kept in the largest possible chunks (up to 4,096 words each) without shuffling by the reclamation routine. Allocation is done by a best-fit method if the size of the new element is known. When the size is not known, that is, in the case of dynamically growing allocations such as drawing new pictures or shading or creating new macros, the largest block available is taken. Any leftover is always returned to the stack. Chunks are automatically chained to permit pictures of larger than 4,096 words. More detailed discussion of the allocation and reclamation routine is found in Chapter III.

Other passive habitability features include handling all the interrupt-level activity, directing the data structure traversal by the display, input syntax checking, names table building, device polling and other systems programming tasks. Most of these algorithms are also more fully discussed in Chapter III.

One could define a hierarchy of users too. A "first-level" user understands the concepts of graphics and can write macros fairly readily. A "second-level" user is a beginner who is comfortable only with simple commands. A "third-level" user knows nothing of the system and his entire verbal interaction is with strings of some natural language (presumably but not necessarily English). Almost anyone who has the dexterity to operate a typewriter in any capacity fits into one of these three categories.

At the risk of leading into the next chapter, one more concept incorporated in the system that makes it easy to use must be mentioned: macros are user-oriented too. For the sophisticated ("first-level") user macros are easy to write, easy to learn to write, easy to follow, and easy to document as well as being powerful. The "PROMPT" and "INPUT" commands make it simple to step a "second-level" user, however naive, through a complex macro. Substring matching of keyboard input will allow macro authors to anticipate natural language responses from "third-level" users, at least in a rudimentary fashion. It is in providing access to a graphics system for these second- and third-level users that the true beauty and habitability of the system is found.

A project for the near future is a long tutorial macro to aid in teaching the system to beginners. It might even exhibit some of the computer assisted instruction capability of GRASS.

II. EXTENSIBILTIY IN A GRAPHICS SYSTEM

In the last chapter, the concept of habitability was broadened so that it could apply to most features that make a system easier to learn and use. Likewise, "extensibility" has been broadened by programming languages theorists. J.A. Feldman commented in a panel on extensibility:

I thought I understood it before I came here and I will first tell you what I think has happened here. It seems to have become "all useful things to do in helping to write systems programs", [17, p 53]. The software in a complex graphics system has many of the problems of a time-sharing operating system. If this software allows extensions to be written in terms of itself, thus adding new "system" functions as well as new user-oriented functions, it would rightfully earn the descriptor "extensible.

It would be helpful to have some programming language background to make this chapter readable.

Extensibility in interpretive languages is a somewhat nebulous concept. Extensibility usually refers to compiled languages in which compile-time procedures are used to expand prototype macros into code, change data types and add new operators all at the one-time expense of more compilation. The object code will run as if there were no macros, since all the macro processing has already been done. Interpretive languages, however, never get rid of the syntax checking and macro generating code and all the extensible features must be processed at run time, often at great efficiency losses. For this reason, interpretive extensible languages have not been used for systems programming because no one wants a large and powerful interpreter taking up great amounts of memory and computing time. Other applications of programming could benefit from an extensible language in interpretive form and the following discussion will attempt to clarify why this very approach is acceptable in an interactive graphics environment.

If the basic system functions (often called "primitives") of the language are very simple, say, on the level of adding, bit testing, or shifting, the interpretive overhead for syntax checking is going to be very costly as compared to the machine code eventually executed to do the primitive function. If the primitives are on the level of complexity of, say, matrix multiplying routines, the interpretive effort starts to be effective since the overhead is less out of proportion to the eventual "work" done - it takes more instructions to do the matrix multiply than to do the syntax checking. For example, Comba's un-implemented design of. a manipulation language for abstract geometry [34] includes complex basic functions for model building, specifying hierarchies and orienting drawings in three dimensions. The primitives of GRASS are very powerful and each represents a large number of individual calculations. For this reason, interpretive statements and even macros are reasonably efficient, which is fortunate because the interpretive mode of operation is so necessary to interactive applications. These observations are supported by the comments of Stephen A. Schuman in a paper on extensible interpreters:

... an interpretive system is not without its accompanying drawbacks,which are all too often cited as sufficient reasons for abandoning this sort of approach altogether. The most serious arguments, of course, are based on considerations of efficiency. There is inevitably a certain amount of overhead associated with interpretation, though it is not necessarily inordinate. The proportion depends on the disparity in "level" between the abstract machine which is realized by the interpreter and the actual machine on which it is implemented. When the difference is substantial, an interpretive implementation can compare quite favorably with any other conceivable approach. [18, p 120]

Thus, within GRASS, the level of the abstract machine - that is, the language for graphics - and PDP-11 machine code is very great and therefore the macro language would appear to be reasonably efficient.

For example, when the drawing routines in the system were replaced by macros (see Appendix C), the macros operated sufficiently fast to be able to trace the sonic pen or joystick in real-time. Furthermore, the joystick drawing macro only takes six hundred words of storage in ASCII format, yet the original assembler command took much more. Also, it is quite a bit easier to add features to macros than it is to code up new assembler routines or modify old ones.

The system was never designed to do complex mathematical tasks at the macro level, simply because the primitives for arithmetic are so close in operation to actual machine level instructions but need to be interpreted as text at nearly the same cost as "ROTATE" or any other command. The arithmetic processing is not so slow as to be useless, especially for the level of mathematics one expects of non-scientific users, but still represents something less than a good computational facility. In other words, the primitive for addition might take three hundred instructions for the realization of what a single machine instruction would do, but the primitive for "ROTATE" could probably not be done more than ten percent more efficiently if coded in straight assembler.

What exactly is a macro in an interpretive language? Does the inclusion of a macro facility make a language extensible? It should be noted first that the distinction between macros and subroutine calls in an interpretive language is fairly nebulous at times. To answer the above questions, Stephen Shuman discusses extensible interpretive languages which handle macros much the same way that GRASS does. He explains concepts that become evident to anyone who has written or designed a language of this type, but probably to no one else:

The most important advantage accruing from this sort of organization is that it provides a particularly coherent framework for accommodating extensibility. The fundamental concept - that new operations are defined in terms of existing ones - becomes essentially equivalent to the elementary capability for defining procedures (hence, in one sense, an extensible language really requires nothing "new".) From a linguistic point of view, such an approach guarantees the requisite def1nitional consistency, insuring that the operations introduced by extension are fully compatible with the primitive operations, since both are formulated in terms of the same mechanism. ...The ability to invoke an extended operation ... corresponds, in effect to an "interpretive subroutine call". Ihis primitive instruction serves to establish a new level of interpretation ... The constituent instructions of this operation (possibly including further subroutine calls) are executed in exactly the same fashion as any other sequence of primitive instructions, until such point as the entire operation has been carried out, whereupon this level is abandoned and control is returned to the program which contained the original call (with the result, if any, being retained in the restored environment.) [18, p 122]

Schuman goes on to describe the overhead of the "cascaded definitional structure" associated with extensible languages [18, p 124] and a separate compilation phase which would eliminate the cascading overhead. The macro facility in GRASS at this point is what Schuman would call "traditional" because it makes no attempt at attacking this problem (some overhead is eliminated by skipping the syntax checking of certain system utility macros, as will be seen later, and arithmetic statements will eventually be handled in a compiled manner, however.) It is not clear at this point that the cascading will reach "impossible" proportions in tine graphics context. If and when the macro facility becomes too cumbersome to use with large, multi-level macros, some sort of compiling feature or syntax shortcuts will have to be added. This type of mounting complexity will only rear its head in numerical calculations and not with the more efficient primitives such as "ROTAIE," "GROUP," "SMOOTH," "SCALE," "SHADE" and so on. The writing of a special purpose arithmetic compiler is a task that will probably be undertaken in the near future; the need for compiling other commands is not yet proven in this environment.

It should be clear that an interpretive language with a flexible macro facility can be called "extensible." Macros are used to define new syntax meanings in terms of old, that is, to add new primitives to the system. Each user will, no doubt, find a need for his own unique macros and these will extend the system in his direction in particular. Jean Sammet, for one, believes this to be an important feature of such a language: "In fact, it may even be true that the only practical application of extensible languages is to produce specialized application languages and their compilers or interpreters" [19, p.141].

Very ambitious extensible languages are typically at least as difficult to learn (if not more!) than regular programming languages. The procedures one must follow to extend data types and operators are too often quite complicated and mathematical. Yet, in the case of GRASS, the goal is to let the sophisticated user - one with a decent amount of time logged on the system, but who is not necessarily a programmer - write his own extensions to the language. Furthermore, the naive user should be accommodated, that is, the habitability should not be sacrificed for the extensibility. Is this impossible? Does a trade-off exist between extensibility and habitability? If the methods of achieving extensibility are simple to use then the answer is "no." In other words, to maintain the system's habitability, the macro facility must be habitable as well. As stated in the last chapter, macros are easy to learn to write and easy to use, a fact that is verified by the non-trivial macro writing by non-programmer artists currently using the system (see "DBLPCI" in Appendix C). Thus, the system was conceived to include a programming language for non-scientists which would also permit, and hopefully lead the user to a high level of sophisticated programming. Given the advantages of visual feedback and high motivation, the users have shown that GRASS can handle many classes of graphics problems to a very demonstrable practical level.

GRASS - like APL - might be called operator-rich but data-poor. The data types in graphics are essentially one-dimensional, two-dimensional and three-dimensional vector lists. This system also has integer, name and device variables, as well as integer constants, register load values, three-by-four matrices and x,y,z coordinates as data types. The sophisticated user can manipulate words, bits, and bytes in any radix, or ASCII characters. The power to programmatically add new data types (e.g. packed decimal) was never considered to be worth the effort of development, since its usefulness has not been shown to satisfaction.

One can, however, change data types as far as the display allows. The Vector General Scope has some twenty data types, of which four are used by the system. A user can, with care, build lists of any peculiar form at the risk of abending the display interrupt routines if he makes a mistake. Naturally, many of the system functions will fail on unanticipated data types, since most of them rely on three-dimensional absolute vector lists.

Defining new operators, however, is a very important feature to a graphics implementation. Let us, then, in the next several pages, build up from the basic command syntax to the system features which allow the writing of extensions - for it is in these features that the true extensibility lies.

The simplest type of macro is written at asterisk or system command level. It allows delay of execution until a matching bracket is seen. For example:

 
<FLAP WING1,-300,300 
FLAP WING2,-300,300> 

will start the two wings flapping together, since the time lag between processing the first line and the second is small enough to have no visible difference. Chances are that the macro would execute completely before the next display cycle when the changes would take effect, so the instructions appear to be simultaneously executed.

When the command syntax checker sees the left angle bracket as the user types in the code, it immediately builds a special system name (&&S001 to &&S999) for the code being typed. It then continues building in the core allocated until a matching angle bracket is found. The user is notified that he is building a macro by the plus sign appearing at the beginning of each new line until the macro is finished. If he should desire, he can nest this kind of macro (i.e. have an unnamed macro within an unnamed macro), although no reason to do this has yet been found in practice. The macro can be up to 4,090 characters long, if the user has the physical stamina to keep typing that long. As soon as the matching right angle bracket is seen, the code in brackets is immediately executed. When execution is finished, the macro is automatically deleted and the storage it used is reclaimed. All looping facilities (to be discussed later) are allowed, and the user may also call named macros from the disk within this type of macro. These unnamed macros (as they are called) are particularly useful for testing short segments of code, since no subsequent commands are required to execute or delete them. An example created during a film exposure test is shown in Figure 8. It was better, in this case, to write a short macro to lower and raise the landing gear of the airplane than to manipulate the dials - exact reproducibility was required in the test. Since this macro did not have to be saved, it was created as an unnamed macro.

Figure 8 - Unnamed Macro Example
AIRPLANE - A short macro was written to raise and lower the landing gear of the airplane. This airplane can fly about with the propeller spinning. If the user desires, he can also flap the wings, open and close the cockpit, eject the occupants along a path, and turn the wheels of the landing gear, all at the same time.

Named macros, on the other hand, are for production purposes. One can create this type of macro to eliminate typing fatigue, of course, if the code is to be executed often. But named macros are essentially what allow the line-by-line interpreter of GRASS to be transformed into a programming language.

When the command syntax checker sees a colon (":"), it goes into named macro building mode. First the name is built corresponding to the letters preceding the colon, then storage is allocated to the name and the ASCII characters are read into core, in the same way as the unnamed macros are handled. All macros are kept in ASCII format at all times, a technique which permits dynamic changes to occur to code even as it is executing. Syntax checking is made easier since a line is not checked until it is executed. This use of the macro as a text string makes re-entrancy and recursiveness automatically possible since the code is always "pure". The time cost involved in executing macros, of course, is part of the interpretive nature of the system. It is much easier to have a compute-bound macro take noticeable time than an assembler routine which performs the same task. For this reason, complicated system utility macros, like the sonic pen drawing routine, may elect to bypass the syntax checking and reformatting loops, if the author has been careful to test the macro in advance. Such macros must be executed from the common area on which no user can write without entering the suitable password.

Macros can be created within macros. For example:

  TOM:<PROMPT "WHAT IS THE NAME OF THIS PICTURE?" 
       INPUT $A       ;ASK FOR THE NAME 
       GETDSK A 
  SAM:<MOVE $A,JS     ;TRANSLATE THE PICTURE USING 
                      ; THE JOYSTICK 
       SCALE SA,SX    ;SIZE VARYING WITH THE X 
                      ;VALUE OF THE SONIC PEN 
       ROTATE $A,X,DO ;ROTATE IT AROUND THE X AXIS 
        SETINT $A,D9  ;INTENSITY ON DIAL 9> 
  DC SAM> 

When the user types "DO TOM," the macro "TOM" will get the figure whose name is passed by the user response to "INPUT $A." The picture's name in core is then the same as it was on the disk. "SAM" is built dynamically, and then executed when the "DO SAM" line is reached. Later, at any time, one could type "DO SAM" or just "SAM" and the code in "SAM" would be re-executed using whatever name the "$A" variable held at tha point. If "TOM" were re-executed, the macro routine would try to re-build "SAM" and a conflict in naming would result since the system will not allow multiply-defined names. Typically, the last line of such a macro is to delete itself, so no housekeeping would be necessary to re-execute "TOM". Any other routine that used "$A" could use "SAM" as a subroutine. Also, "INPUT $A" is a legal asterisk level instruction which simply takes the next line of input as the name, so that "SAM could be used at any time if preceded by an "INPUT $A in any mode. Note that no effort has been made to have local and global declarations of names, and it is not at all clear at this point that this omission could result in deficiencies severe enough to warrant the complexity of permitting declarations of local variables. In fact, allowing local variables makes it difficult to enter macros at points other than the beginning. As will be seen, the present macro structure allows very flexible program flow control in sometimes quite unusual ways. There is no limit to the nesting of macros other than user fatigue and processor stack space on the PDP-11. It requires about eight words of storage in the push down stack to go down a level in a macro - five are for register saving and three for return information. Consequently, at the cost of eight words per call, a macro can re-enter itself until the stack underflows. If this happens, the user is notified and returned to asterisk level at which point the stack is reinitialized. Of course, very little can be done recursively in a program that cannot be done in other ways, but at least the capability is there for the use of the clever or lazy user (providing, powerful tools for lazy users is a habitability consideration, of course).

The single most significant thing computers do is loop. Looping permits repetitive tasks do be done at electronic speed, ad infinitum. Looping is essentially what distinguishes hand calculators from computers. Accordingly, a graphics language should have simple as well as sophisticated looping facilities. These facilities are known as the program flow control commands.

"SKIP" is the simplest of these commands. The operand that "SKIP" takes indicates the number of lines forward or backward the control is to be passed. A skip with a negative number transfers control backwards and is used mostly for looping. A negative number exceeding the number of lines preceding the "SKIP" in the macro will result in transfer to the first statement. A "SKIP will look into a loop, so it is not allowed except if it is part of an "IF" statement, which is discussed later. A "SKIP" with a positive operand will skip over the number of lines indicated. Since a line is not syntax checked unless executed, a "SKIP" could be used to branch around some non-executable alphanumeric strings.

Furthermore, the operand to "SKIP" can be a full expression. Thus, "SKIP A" will result in a skip of the number of lines indicated by the numerical value of the variable "A". Since expressions are evaluated dynamically, the program control can be the result of a computation. "SKIP DO/2-200" is also permissible, although of questionable utility, since it causes control to skip the number of lines indicated by half the value of dial 0, whatever it might be at that time, minus two hundred.

To eliminate counting fatigue in compiling skip offsets, disk-resident macros may have pseudo-labels for "SKIP" operands. When these macros are called into core, the pseudo-labels are resolved and replaced. by numeric values much like an assembler resolves addresses. One may create a macro with pseudo-labels in the ordinary manner, but he must "COMPILE" it to resolve the labels. If he neglects this step, he will be notified by an error message that unresolved labels exist. Pseudo labels are preceded by a percent sign (%).

Named macros are called into execution in several ways. For system utility macros (see Appendix C), "CALL Macro-name" is sufficient. The "CALL" processor first checks to see if the macro is in core, and if it is not, it is called in, and then executed. Much of the syntax checking is disabled if "CALL" is used. If the user knows that the macro is already in core, he can simply type the macro's name to cause execution. Most system utility macros delete themselves upon exit, however, to reclaim space, so the use of the "CALL" is usually necessary each time.

The user also has the option of getting all his macros into core at once by using "GETDSK Or "GETCOM" commands. Then, when the macros are called, no delay attributable to disk access overhead could ever be present.

If the macro is on his own disk area, that is, if the user is the author, a "DO Macro-name" will get the macro for him. Syntax checking is not disabled, however, so his macro will run slightly slower than a comparable system utility macro. If he includes the disk area specification, he can use another user's macros. For example, "DO FLUFF[30,11]" will allow access to the macro "FLUFF" on area "30,11." Similarly, "DO JSDRAW[31,1]" would get the system utility joystick draw routine but enforce syntax checking (31,1 is the common area). The clever user could "GETDSK" a macro from any area on the disk, and then "CALL" it, thus eliminating syntax checking, at his own risk, of course.

Again, the macro calling facility is very flexible, but all the ordinary user need know is the name of the macro he wants and the simple syntax of "CALL" and "DO."

Although it seems like the discussion has strayed from the program control features, it really has not. "CALL" and "DO" also allow subroutine linkage to modules which are either disk or core resident. Typing just the macro name without "DO" or "CALL" provides linkage to core resident modules only. There is a further operator "GOTO" which acts like a jump rather than a subroutine call. "GOTO" takes a macro name and an optional positive displacement, and will transfer control to that macro plus the displacement in lines, if any. Of course, if the calling routine were in turn called by another routine, the return is to the original calling routine.

For very complex nesting within macros, the user has to keep track of where he is - one could hardly expect the machine to second-guess him. Presumably, the user who can think recursively and program nested subroutine and macro calls is competent enough to keep track of them. Commands like "LIST" and "PROMPT" can help in debugging macro code, however.

The "RETURN" command will pop up one level in the macro nesting. It is equivalent to a "GOTO" to a no-operation macro. If it has a positive operand, "RETURN" will pop up that many levels of nesting. The "EXIT" command is equivalent to a "RETURN" whose operand exceeds numerically the level of nesting. Thus, "EXIT" always returns one to asterisk level.

All these program flow control features are nearly useless without conditional statemeus, however. GRASS has very flexible conditional statements too. There are synchronous and asynchronous conditionals. The synchronous conditionals are triggered by the "IF" operator, and can be set up and used dynamically on any level. The asynchronous conditionals - called "ON" conditions after "PL/I" - may be set up in a macro, but are only tested and executed during command input wait at asterisk level. At this time, the command level processor is idle and can conveniently process such requests if the conditions are satisfied. "IF" statements must be continuously looped upon, or "polled" in a macro if the condition is to be checked at any time. Therefore, a macro must have control of the system if an "IF" statement is to have any effect, so it is only within macros that synchronous conditionals make sense. "ON" conditions, on the other hand, are for calling macros when no macro has control. The distinction should become clearer as the discussion progresses.

The syntax of "IF" statements is as follows:

IF FSn operator expression, simple command 
or 
IF DEV operator expression, simple command 

"FSn" is one of the sixteen function switches, or if specified as "CPn", is one of the sixteen PDP-11 console switches. "Operator" is one of the usual arithmetic comparison mnemonics: LT, GT, EQ, NE, GE, and LE with "=" and "#" also substituting for "equals" and "not equals" respectively. "Expression" is a combination of numbers, variables, dials and arithmetic operators of the type previously discussed. The comma terminates the clause, and if the condition is satisfied, the simple command which follows will be executed. A simple command is defined as one which will fit on the rest of the line, a hardware dictated restriction that can be most simply circumvented by use of the "DO" operator, as described below. "DEV's" may be aiso tested with "IF" statements as the second syntax specification shows.

If the condition is not satisfied, control passes to the next statement in line. Thus, "IF FS1=0, SKIP -10" will cause the code to loop ten instructions until FS1 is pushed. With function switches, if the operator and expression is left out, "1" is assumed. "IF A LT 2000, DO GEORGE" will cause execution of the macro "GEORGE" if the variable "A" is less than 2000 at the point of execution of the "IF" statement. Similarly, "IF K GT M+N+2000, PROMPT "K IS TOO BIG" will send the message to the user if the condition is satisfied. If a multi-line sequence must be executed as a result of the "IF" condition being satisfied, the user has the choice of creating a named macro to do the sequence and then executing it by using a "DO NAME" as the simple command, or setting up the complementary condition to skip around the multi-line sequence that would then follow the "IF statement. The former approach saves storage because the multi-line sequence may be disk resident until needed, and can delete itself upon completion. "GOTO's" and "RETURN's" may be used for simple commands, as well as arithmetic statements, or any other command (except "TEXI," which is multi-line). Furthermore, as long as it will fit on one line, several "IF" statements can form a nested conditional in a rather elegant way:

IF FS1, IF A LI 20, IF FS2 NE 0, IF DO GT 0, HELP 

A user could build a macro as long as it fit on one line:

IF FS1, SAM:<'FILL TOM,FRED,HAIR,D7> 

although this is somewhat limited in application.

The asynchronous conditions are treated differently. The syntax is as follows:

ON DEV operator expression, on command 
or
ON FSn operator expression, on command 

The operator and expression specifications are the same as for the "IF" statement; however, following the comma, there must be either a macro name preceded by "DO" or "CALL" or a macro building sequence. The difference here is because the table of dispatch addresses for the "ON" condition processor must have an address of macro code to correspond to the condition. The user may also specify a named or unnamed macro building procedure in the normal way. If named, it is equivalent to building a macro and then using an "IF ... , DO... " sequence. If unnamed, however, the macro will be automatically deleted after the condition is satisfied and the code executed. Thus the following are possible:

ON FS1, <DELETE SAM> 
ON FS15, <ROTATE GLOBE,X,D0,D1,D2 
           SCALE GLOBE, D9> 

A macro could easily be written to set up all the "ON" conditions that a user might need for himself or his second-level user. Then, anytime such a condition was satisfied the appropriate action would be taken and the condition disabled. If continuous monitoring is desired, the last statement of the code executed as a result of the "ON" condition could set the condition up again. Typically, the macro author would turn off function switches corresponding to those which triggered execution in this case, or the condition would be constantly satisfied. Since the macro executed as a result of the "ON" statement could have "IF" statements in it, logical "and" and "not" conditions may be programmed by checking more function switches or "DEV's". Of course, since the very nature of the "ON" condition is a logical "or" operation, a logically complete set of interactions with any device, variable, or function switch collection may thus be realized. Furthermore, since coordinates may be read into variables by the "GETPOIN" command, elementary data analysis may be undertaken by a series of "ON" and "IF" conditions.

"ON" conditions, as was stated before, are only checked while the system is waiting for a command. If a macro is in progress, the macro author can issue a "WAIT" command to force an input wait if necessary. One or all of these "ON" conditions could trigger code containing a "RESUME" command which would return the user to macro control. The tactile interaction can thus be as simple or complex as the user desires, an option not usually offered in a programming language.

Keyboard substring matching is a special extension to the "ON" and IF" conditions. lhis feature allows very flexible decision making on the basis of an anticipated set of keyboard inputs. The macro author sets up his "KB" conditions as follows:

IF KB=text string, simple command 
or
ON KB=text string, on command 

where "simple command" and "on command" were described before. The user has the option of specifying a modifier of "KB" such as "KB5" which would match only the fifth word in the line, with normal English punctuation taken as word delimiters. In the case of the "ON" condition here, once it is enabled, every line input on the display terminal is checked for matches. If the input line does not have a match, the line is passed to the line processor to be executed as a command. If the line is not in valid command syntax, of course, an error message will be sent to indicate the fact.

The "IF KB" condition is, as might be expected, used within macros. Its use follows an "INPUT KB" command which calls for a line of input which is stored in a special line buffer. The desired strings can be tested by looping the "IF KB" statements. The line remains in the buffer until another "INPUT" is issued.

As the need arises, a more "SNOBL"-like string matching facility could be developed, using these conditions as a framework. A universal matching character could be added to allow matches of strings that are less than or more than one word. Since the keyboard match tables are built dynamically, the user can set up many entries before running out of table space. At this point, GRASS is still too new and the users have not begun to write macros for "third-level" users. When more sophisticated pattern matching is required, the code can be expanded fairly easily.

It should be realized by now that the macro facility allows very powerful extensions to the language to be written in relatively short amounts of time. Thus, an instructor could appear one day, have an experienced user write a few macros which define a special system, and fairly complex sequences could be developed, filmed and sent off to be developed. An educational movie could be produced in a matter of days, if necessary, so an instructor could conceivably even use the system to generate film to explain some concepts he found difficult to explain conventionally earlier in the week. The language of GRASS can be quickly tailored to the needs of any particular naive user, through the power of the macro facility.

Previous computer animation systems have at most a small fraction of this power. Most graphics efforts have, in fact, consisted of linking a series of one-shot, throw-away, single purpose programs not by subroutine linkage, or under a system of any sort, but in a film lab, where the film clips are assembled. In this light, the flexibility of GRASS is probably best appreciated.

Occasionally, there will be features that a particular user may want to add that simply cannot be done in a macro. Macros do not as yet have matrix multiplying capability or floating point variables. Also, if speed is all-important, the user may want to have his algorithm coded in assembler rather than in a macro. GRASS is designed to make adding assembler modules very easy. A new name can be generated, added to the system function table, and the interfaces to allocation, expression evaluators and names accessing routines can be added as a series of subroutine jumps in a matter of five or ten minutes. The user has only to code the heart of the algorithm.

If the system were to continually grow as the result of adding new assembler routines, it would be at the cost of picture space. The present memory limit of the system is 28k words. Fortunately, a method was planned and recently - has been implemented to allow modules of assembler code to swap from the disk providing certain conventions are observed. Access to system resident modules is through a fixed location table, but the swapped module may be allocated the smallest chunk of core in which it will fit, and thus be anywhere in core. Fortunately, the PDP-11 assembler creates position-independent code unless it is specifically subverted, and this, of course, makes preparing swapping modules much easier. About half the system code is now non-resident. The system has yet to require any major modifications to implement new assembler algorithms, and should be able to accept virtually any suitable code as its own.

The programmer who desires to add an assembler swap module must first modify the system names table to include the new name. The dispatch address of the new module becomes -10 which indicates that it is a swap module on the disk. He then codes the module, including the bit 12 lockout convention for functions in the first word and -10 in the second word. (Control is always transferred to two words past the beginning of a module.) The module must exit with a standard subroutine return. If the programmer wishes to communicate with system modules (which he no doubt does), the LNKSUB assembler macro sets up the proper linkage. Register four, if used, must be restored before entering the LNKSUB expansion since it holds the base address of the LNKSUB dispatch table. The new module is assembled with the system parameter file S.MAC. The object module is then linked with SWPMAK.OBJ and SWPEND.OBJ, the first of which later causes the resulting load module to write out the new module on the disk in the proper form for a swap module. SWPEND is simply an end directive. The load module is then executed and produces a file SWP.TMP which must be renamed to the intended name. This procedure normally takes only a few minutes once the algorithm is coded and typed.

Clearly, a language which depends solely on adding assembler routines to expand its capabilities cannot be described as "extensible." Note, however, that extensible languages became extensible only by adding enough assembler routines to make the language rich enough to define new syntax meanings in terms of existing ones. The aim of GRASS was always to provide a viable system whose obsolescence was neither envisioned nor planned, at least until the technology changes. It seems that, for the moment anyway, the data manipulation part of computer graphics is under control to a very usable degree. This system should remain a creative tool for a few years, which is about the best any new programming effort could expect.

III. IMPLEMENTATION DETAILS

Don Knuth's "Art of Computer Programming" volumes are a notable exception to standard computer science works in which all too often the capabilities of a system are given, but not the methodology involved. Knuth supplies information of the kind normally available only to readers of microfiche. Following Knuth's example, this chapter will give some insights into the internal workings of the algorithms that make GRASS work. Considerable time was spent generating these methods, and if they have been duplicated elsewhere, it is not the intention here to assume uniqueness. Each routine was worked out independently, and not consciously adapted from any other source.

GRASS was inspired greatly by the study of and workings with the PDP-10 time--sharing monitor, TECO - a text editor of great power (also on the PDP-10), and a couple of years of interaction with System/360 Operating System and Job Control Language. The last of these inspirations was mostly in a negative sense - no graphics language could ever look like JCL and be usable by artists. A goal, however, was to provide the kind of flexibility JCL offers - so one could, among other things, spend most of his time writing macros, as many systems programmers do with JCL. Some of the advantages of BASIC, PL/I, ALGOL and SNOBOL were studied in preparation for the project. And, of course, many graphics systems were consulted, although all of these were painfully lacking in implementation details. This chapter is for the reader looking for implementation ideas, but who does not enjoy deciphering assembler code.

A. Reasons for the Assembler Implementation

One of the unconventional aspects of GRASS when compared to other graphics efforts, is its assembler implementation. Most graphics systems use FORTRAN as a host language - but most systems do not contain extensible programming languages nor do they have the kind of intricate interrupt level structures found in GRASS.

The reasons for rejecting FORTRAN are not unique to the graphics environment. Computer operating systems are not written in FORTRAN and no usable implementation of SNOBOL, COBOL, or ALGOL exists as series of FORTRAN-callable subroutines. Jean Sammet states that standard FORTRAN has never been used to bootstrap itself' [24, p 150 ], a comment on its lack of extensibility powers. FORTRAN was not intended to do much more than translate formulas into machine code: "Its largest disadvantages stem from attempts to use it outside of the realm for which it was intended, namely for any type of alphanumeric data handling" [24, p 157]. Languages which have adequate character handling and bit manipulation (PL/I, BLISS[25]) are not widely available, especially on mini-computers. Since FORTRAN is so awkward in the operations necessary for language processing, any system written in FORTRAN cannot do significant input string parsing, and be even remotely efficient.

FORTRAN's bit manipulation deficiencies would also make it difficult to attain much sophistication in the storage allocation and reclamation routines and the traversal algorithms to be described in this chapter. Lack of pointer variables makes list processing unnatural, to say the least: "Because it was designed so early, better ways have been found to do almost everything that is currently in FORTRAN" [24, p 169 ].

If PL/I or BLISS were available on mini-computers and had reasonable memory requirements for operation, one could consider using a higher-level language to implement a graphics system. One cannot, however, justify implementing BLISS or PL/I on a mini-computer to save oneself the effort of coding in assembler.

FORTRAN is available but it is not acceptable for large amounts of character manipulation. Why is character manipulation so important to animation graphics? First, to deal with the complex sequences often required, a full-scale programming language is needed, that is, no practical series of button pushes or intensity of lightpen waving by itself will ever convey the amount of information that a programming language can. Of course, one cannot write macros solely in terms of button pushing either. The reason why this necessary programming language cannot be FORTRAN itself (as a language) is the second major reason for creating a new language: interactive graphics requires an interactive language. Interactive languages are interpretive languages, which FORTRAN is not. Therefore, one is left with the task of writing an interpretive language in FORTRAN - precisely why character manipulation is such an issue.

It may not be obvious to batch computer users why interaction is important. Thomas Standish gives two good reasons:

The first is that conversational systems which provide rapid response to trivial requests permit one to evolve and modify a program at a very rapid pace.... Conversational systems permit you to observe the misbehavior, to request a trivial change and have it rapidly satisfied, and immediately to set the program in motion again to check whether the new behavior is correct. One should not have to go through the whole cycle of updating a source file, compiling, loading, initializing and then setting up the proper routine circumstances in order to sense the behavioral implications of a trivial change.

The second case in which interactive computer animation systems are important is to satisfy applications where man must be in the loop to supply decisions about how the animation is to proceed .... man must set the time scale, the focus and the level of detail. Since man has changing interests that the machine can't predict, he must be in the loop to decide what to look at, to compress the uninteresting, to expand the interesting, and to jump in and out of the hierarchy of detail depending on whether he is excited or bored. Conversational graphics systems and conversational programming languages are structured to permit just this sort of thing. [26, p 308 ]

Non-interactive graphics, such as plotting and microfilm recording can be done well in FORTRAN. However, one cannot simply type "CALL ROTATE (BIRD)" in FORTRAN syntax and have the bird instantly rotate on the screen, given the subroutine and picture already exist. One cannot even hand the computer a card out of a deck - FORTRAN programs, even single statement ones, must be compiled, loaded and executed - and this is not particularly interactive or desirable. To interpret "CALL ROTATE(BIRD)" takes as much work as "ROTATE BIRD" if not more, so why maintain the FORTRAN syntax?

The advantages of FORTRAN outweigh its disadvantages in some applications of graphics. For instance, users of microfilm plotter packages such as the Polygraphics Package [41] often take advantage of the many subroutines which exist in FORTRAN submitted by other users from all over the world. Furthermore, FGRTRAN library subroutines to solve systems of equations, integrate and differentiate functions and perform various statistical and mathematical tasks are readily available, if necessary. Of course, rapid response to trivial changes cannot be obtained with this approach since everything has to be edited, re-compiled, linked and re-executed to affect each change in the output. Thus, even if a user can get feedback from such a device in ten seconds, it might take him twenty minutes to make a simple change. Until an industry standard graphics programming language is adopted, the user will simply have to choose between interaction with interpretive languages and the kind of exportability and availability of libraries of subroutines represented by the FORTRAN approach. Of course, it would be possible to write an interpretive language for a microfilm system which would eliminate the compiling and loading problems but then the advantages of FORTRAN would no longer be available.

Similar arguments may be raised for FORTRAN implementation of storage tube systems and the same advantages and disadvantages exist. The storage tube has a better response time than a microfilm plotter (one-half second with a high-speed line), and is a good alternative when equipment like the Vector General is not available. If the system designer is more interested in using previously coded algorithms for such things as hidden-line removal, shading and character generation, he would be advised to use FORTRAN. If he is more interested in interaction and habitability, he will probably have to write an interpreter and recode the algorithms he wants by himself, in assembler or another host language.

In any graphics implementation, several routines would have to be written in assembler no matter what the base language. Interrupt level code and vector list manipulating is best done in assembler, since higher level languages do not typically have interrupt trap facilities or data types of the vector relative variety. In retrospect, the only algorithms that could have been more easily coded in FORTRAN are the SMOOTH and SHADE routines, and the effort saved would not justify putting up with the compiler.

Higher level programming languages are designed to save programming time. The amount of time it would take to add enough bit manipulation and character handling facilities to FORTRAN would exceed any time saved by coding in FORTRAN, and the end product would probably run slower (compilers with optimizing options like IBM's FORTRAN H are not available on mini-computers either). Any hopes of machine independence would be lost also, and machine independence is one of the reasons people use FORTRAN in the first place. A FORTRAN-based system cannot achieve the level of flexibility possible whitn an assembler implemented system. Animation graphics is the type of endeavor that demands all the computational speed and flexibility it can get, and then some.

B. Storage Allocation and Reclamation

Storage is allocated in chunks of thirty-two word blocks, up to 128 blocks contiguously, or 4K of memory. These sizes were chosen to give some degree of compatibility with the segmentation hardware of the PDP-11/45, so the system could be upgraded to a multi-user re-entrant system eventually. One of several allocation methods could be used in a graphics language. A very simple allocation scheme would chip off pieces from the large chunk of available core, until there was none left. Then the user would have to restart the system, there being little effective way to reclaim storage.

If larger blocks of core were chosen as the minimum size - say 512 words - a bit map with ones corresponding to open locations could be used for storage allocation and reclamation. When a block was deleted, the corresponding bit would be turned on again. To search for the largest contiguous chunks would be fairly costly with this scheme, however, especially if smaller block sizes are used.

The allocation block size was chosen partially to keep the addresses of allocated elements on thirty-two word boundaries to conform with the segmentation hardware. A smaller block size would be impractical anyway, since only a trivial macro could fit in sixteen words. As it is, two blocks are required for even the smallest picture since the size of the register load block exceeds thirty-two words, larger size blocks were not used because the amount of storage wasted by rounding off the number of words actually used to the next block increases as the block size gets larger. No simulation studies were undertaken to ascertain the sagacity of the choice, but the thirty-two word block has proven to be quite acceptable nevertheless.

Another approach to storage reclamation is by shuffling as the non-paging PDP-10 does it. Shuffling dynamically compacts core by re-adjusting addresses, and thus leaves all the free space at the top. However, in a graphics system, it is not really possible to shuffle while maintaining a real-time display. Even on the PDP-10, display jobs are typically locked in core and never shuffled, unless the display has finished, and this has even been known to confuse the system more often than not. The advantage of shuffling is that one can maintain all the unallocated core in one large chunk, if necessary to do so. However, if the display can accept either hardware or software jumps to continue vector lists, one can really use core as if it were all in one big chunk anyway.

GRASS makes major use of push down stacks, as will be seen. Allocation is handled by placing address/displacement pairs on a separate allocation stack. The displacement is a count of thirty-two word blocks which ranges from one to one hundred twenty-eight. The address is the physical core address, that together with the displacement should not cross a 4K boundary - again a consideration for segmentation and paging.

Two types of allocation requests are honored: a known-size and an unknown-size request. The former is used when disk resident files whose length is known are transferred into core. The latter is needed during dynamic creation - that is, drawing, macro creating, and any other data generating processes like "SHADE", "FILL", and "PUTFOI" (see Appendix A for explanations of these commands). Each time allocation is called, a chunk of core is passed to the calling routine which uses what it needs and returns the leftover blocks. The address and displacement of the leftover chunk are pushed on the stack and a sort is done on the address/displacement pairs based on the displacements with the largest elements going to the top. Since the bottom of the stack is always known, the known-size allocation routine starts at the bottom and compares upwards until it finds a large enough chunk (remember that the smaller chunks are nearer the bottom now). If there is no chunk large enough, the largest is taken, and then dynamically linked to another non-contiguous chunk when necessary. Thus the best fit is chosen for the known-size case.

Again, no simulation studies were under taken to determine if the best fit technique is, in fact, best. A justification for the choice of method can be given, however: it is imperative that the largest possible chunks of core be maintained, and that small pieces not be constantly chipped off the largest blocks, but fit into small pieces if possible. For example, the character set subroutine blocks for "TEXT" vectors cannot be continued and chained to other blocks, and many are nearly 4K in size. If many small elements were allocated by first fit, it is more likely that the large chunks would not be available when needed. This argument is less effective if the allocation stack is never sorted, and in retrospect, a slightly more efficient allocation might be obtained if the algorithm were changed to eliminate sorting and best-fit usage. In any case, a trivial change in the code could realize these modifications if the effort was deemed necessary. At the time, it seemed the approach taken would assure efficient utilization of core in the short as well as long term case. Arguments for the first fit method usually only consider the long term case, which the naive user may just never encounter.

When the size is unknown, the allocation algorithm takes the top element from the stack since it is guaranteed to be the largest. If that chunk turns out to be too small, the next largest chunk is dynamically appended to it by a jump and the process is repeated until enough core is gotten or all the core is exhausted. Of all the functions in the system, "SHADE" and "FILL" are the best at running out of core - it takes a lot of coordinates to transform a wireframe three-dimensional drawing into a half-tone representation.

A word might be said about the sorting of the allocation stack, which seems to offend the sensibilities of those who find sorting unacceptably inefficient. First, the stack never has many elements because they are combined when possible, so that even if the sorting takes time on the order of the square of the number of elements, the time taken is still trivial, especially since allocation is not done as often as the traversal algorithm, for example. Secondly, sorting the stack made implementation easier in that it was simpler to check if core was allocating and deleting properly, and all blocks of core could be tested for position independence of pictures and algorithms, without having to fill all of core each time. Since development is still in progress, these allocation techniques have not been abandoned. Furthermore, to use a best fit technique, some sorting has to be done anyway, and criticism of sorting is only valid if the number of elements to be sorted is considerably larger than ever found on the allocation push down stack.

The "DELETE" command reclaims storage and returns it to the allocation stack. First, the displacement and address of the deleted item is placed on the stack. Then, each element down in the stack is tested to see if it is physically adjacent above or below the new element and joined if it is. The element physically above the new element is called the "physical preceder" and the element after is called the "physical follower". An element can have at most one physical follower and one physical preceder on the stack at a time. The testing procedure can now be explained. First, the newly pushed displacement is added to its accompanying address, and the sum is saved. This number corresponds to the physical follower. The stack, which typically has less than ten entries, is quickly searched to see if the physical follower appears there. If it is, the displacements are added, the first address is kept, and the physical follower address/displacement pair is compacted out of the stack. If the physical follower does not appear on the stack, it simply means that the core following the new element is still allocated. Second, the address/displacement pairs on the stack are each added to see if the sum matches the address of the new element. If so, the old address is kept, the displacements added, and the top two words - the new element's address/displacement pair - are popped off. A sort then arranges the displacements in descending order and the algorithm is finished. Thus, the largest possible chunks of storage are maintained without shuffling. All this housekeeping is transparent to the user, and takes much less time than a carriage return.

The storage allocation and reclamation routine is very heavily used in the system, and is, after much effort, a solid and dependable piece of code that is "user-proof". Macros, swapping assembler routines, pictures and group nodes all use this routine.

C. The Line and Macro Processor

The line processor handles the interpretive part of the system. It includes all the syntax checking that ever goes on, dispatches to the routine to execute system functions (like "ROTATE," "GROUP," "GETDSK," etc.), builds and executes macros, and calls the arithmetic routines. The notable part of this complex routine is the way in which it handles nesting, re-entrancy, and recursiveness.

Several key characters trigger special processing. A colon indicates that a named macro is about to be built. A right angle bracket marks the creation of an unnamed macro. An equals sign calls the assignment statement routine. In addition, several special words are checked for: "CALL", "DO", "IF", and "GN", since these operators may require operands which violate normal line syntax.

The named-macro processor dynamically calls allocation for a chunk of memory, at which time it records the ASCII text string into core until the last matching angle bracket is seen. The name is built in the normal way, using the letters preceding the colon, and the user can refer to his macro, delete it, save it on the disk, or change it. The named-macro processor then returns control to the calling module.

The unnamed-macro processor builds a system name (&&S000 to &&S999), gets core, and builds the macro until a matching right angle bracket is seen. This processor retains control, however, and causes automatic execution of the unnamed macro by pushing its own status on the stack and doing a re-entrant call to the line processor. Thus, if nested angle brackets are seen, a new system name is used and this macro is executed similarly by calling the line processor again. Once an unnamed macro is finished, it pops its status from the stack and resumes the calling routine if any. If a colon is seen, the named-macro processor is called automatically as a result of the line-by-line execution of the macro by the line processor. Finally, when the original unnamed macro is fin1shed, the unnamed-macro processor deletes all names beginning with "&&S" prefixes, thus reclaiming all the space used in creating the macro.

Named macros similarly can nest named macros and include unnamed macros. The line processor simply re-enters itself until the lowest level is reached, and then pops its way back up until back to asterisk level. Note that named macros must be explicitly executed and deleted, and are the only ones which can be saved on the disk.

The line processor also includes the ON processor whose syntax requirements necessitate calling the named- or unnamed-macro processor or the DO processor. The address passed by one of the three calls represents a macro and is built into a table of addresses that corresponds to the conditions. The "ON condition table - ONTAB (see Figure 9) - contains three sixteen-bit words per entry.

Figure 9 - ON Condition Table

The first word indicates the type of device being tested-function switch, dial or variable, or keyboard substring-in the high order byte of the first word, and the number of the device (i.e. ten for "D10") in the low order byte. Also kept in the high order byte are the three bits which indicate the operator, specifically LT,GT,EQ,NE,GE, and LE. The second word contains the sixteen bit value of the expression or device being tested, except in the case of keyboard matching, in which an address of the test string is found. The third word then contains the address of the macro to be executed if the conditions are satisfied.

The DO processor first checks to see if the macro is already in core. If it is, the code immediately passes control to it, pushing the status onto the stack in case that macro has any nesting or "DO" statements in it. Any macro can be made recursive by simply including a "DC" with its own name internal to it. If the macro runs too long without satisfying an exit condition, too much is pushed on the stack and the macro aborts with an error message, but this only happens after several hundred levels. Similarly, macros can call each other until a exit condition is reached.

The CALL processor is like the DO processor except that it changes the disk area to [31,1] and disables syntax checking. Otherwise, they use the same basic routines, so that a called macro can call or do another macro.

The IF processor simply evaluates the conditions at that instant of execution and if satisfied, shuffles the rest of the line to the beginning of the command buffer and re-enters the line processor. Otherwise, the rest of the line is ignored and control passes to the next line in sequence. Thus, the following is perfectly permissible:

IF FS1, IF FS2, IF A LT O, IF DO GT 400, SKIP -12 

The error message processor interacts with the line processor also. It handles the "creative" error messages discussed earlier. The error message processor can function because the line processor cleverly saves the stack address of the top element upon entry, so that all that has to be done when an error is encountered, is to restore the stack to the saved value. All extraneous elements left on the stack by PDP-11 assembler subroutine jumps and parameter passing are cleaned up in this way. (The central hardware processor also uses the stack for register saving and linkage.) The error message processor can thus recover quite nicely, no matter how far down in a macro the error occurred. The user can then enter as many lines or code as he wishes to be executed before continuing in the macro. He may also just type or "EXIT" or simply hit the panic button if he wishes to return to asterisk level. If an error were to occur in one of the new lines typed in, the error message routine would re-enter itself and allow the user to fix the error.

It is hard to believe that some computer systems function at all without hardware push down stacks.

D. Data Structure Traversal

The data structure traversal algorithm runs asynchronously with the rest of the system. It is called at interrupt level by the Vector General display driver. The driver allows PDP-11 assembler routines to be processed between display list calls. Every time the driver sees a final display subroutine return (in Vector General code), it calls the traversal algorithm for a pointer to a new list. The traversal algorithm does more than set up pointers, however.

At the beginning of every data list, there are twenty-eight words of non-display information and another twenty-three words of non-vector drawing display register information (see Figure 10 in which the addresses are given in octal and represent byte offsets - remember, there are two bytes to a word).

Figure 10 - Leaf and Node Information

The first twenty-eight (indicated by octal byte addresses 0 through 66 in Figure 10) give all the information this picture needs to generate all the display register settings contained in the twenty-three words (indicated by octal byte addresses 70 through 144 in Figure 10). Every group node also contains the same information. When the traversal algorithm returns control to the driver, it passes the pointer to the first of the twenty-three words which are display register load instructions. The traversal algorithm essentially is occupied with placing the correct values into the operands of these load instructions.

The first word of the picture (indicated by "0" in Figure 10, which is, incidentally, the address corresponding to the name of the picture, is critically important. If this word is positive, and non-zero, the element is a picture (called a "leaf" of the structure). The high order bits give the first trap bits which, if on, indicate rotation, scaling, translation, and path following. Bit 12 is a lockout bit which prevents functions from being displayed and pictures from being executed. Bit 14 prevents any modifications from being recalculated if the leaf is part of a modified group structure (more on this later). The low order bits give the length of the leaf in thirty-two word blocks. Bit 15, of course, is the sign bit. If the first word is zero, it is a group node with no modifications, in other words, a group structure that is grouped for convenience of reference, or one to which group transformations have not yet been applied. Once a group is used for compounding transformations, it is set to have a negative first word, with the high order bits and all other information corresponding to the leaf case.

The second word (indicated by octal address 2 in Figure 10) of the leaf or group node is a pointer. In the group case, it points down to a lower group node or leaf, or itself if all its sub-elements have been deleted. In a leaf, this word points at the sibling, be it a leaf or group node, or up at a group. The group has its sibling or up pointer fifty-two words down (octal address 150).

Other types of data structures for graphics are discussed by Gray [33], Van Dam [35], Abrams [36] and Williams [37].

The rest of the first twenty-eight words hold ten words of rotation information, two of scaling information, six of motion information, one for cutoff plane and intensity and another one and a half words of trap and flag bits which control the interrupt level algorithms for each group or leaf. There are also words for linear interpolation information plus a couple of words for expansion. The position of this information is identical for group nodes and leaves.

The twenty-three words of load register instructions are executed by the display in the leaf case but not in the group case, where they are merely used for storage of intermediate compounded values. The format was kept identical for the two cases so that the same algorithms could be used to set up both groups and leaves.

The traversal algorithm also makes heavy use of the PDP-11 system stack. (Figure 11 should be consulted at this point to aid understanding of the data structure design).

Figure 11a - Data Structure
Figure 11b - Data Structure

When a group with trap bits set is seen, it does the modifications specified, records the values in the load register operands, and then pushes a marker followed by the group node address on the stack. The next item element down in the structure is then checked for modifications. It may be a group or a leaf. The modifications are carried out to the lower element, and then the higher group's register values replace those register values where no modification was indicated and are compounded with changed values. Compounding is done by matrix multiplying the rotation matrices, by multiplying the scale factors, and by adding translation factors (translation is additive, whereas the others are multiplicative for compounding), the answers replacing the lower element's load register values. Cut-off plane and intensity settings are simply replaced by the higher group's values. Then, bit 14 is set in the first word of the lower element to cancel any processing when the traversal algorithm reaches this element later - remember that traversal algorithm itself still points at the higher group, and will later chain through the lower elements in order to pass pointers to the display. The procedure is to this point simply compounding transformations.

Now, if the lower element is a group, it is then a subgroup to the higher group, and its address in turn is pushed on the stack, and the next lower leaf or group is consulted. The modifications, multiplications, etc. take place again, this time using the last element in the stack to retrieve the compounding information. This process continues until a leaf is reached. That leaf now has all the compounded transformations stored in its register load instructions. It is these values only which are passed to the analog hardware of the scope. lherefore, it is only at the point that the traversal algorithm reaches this leaf and passes its address to the display, that any visible results occur. If bit 14 were not set, the traversal algorithm would recalculate the modifications based only on the leaf information and destroy the important compounded information. The traversal algorithm has not reached this point yet, however, and is still pointing at the top group. The compounding algorithm is ready for more action, though.

Assume the leaf has a sibling in the data structure. The sibling can be a leaf or another group. If it is a group, the same code re-enters, the modifications are compounded and that group's address is pushed on the stack. The level of grouping is obviously indefinite for all practical purposes. Since recursion of grouping makes absolutely no sense, it is not allowed in the sense that groups cannot point to preceding elements. Any lower elements would then be compounded on the basis of the last element whose address was pushed on the stack. If the sibling were a leaf, it is treated exactly as the first leaf was, and the pointer to its sibling is taken. Assume the next leaf is the last leaf. Its pointer points up at a group node sibling/up pointer, which is found at the fifty-second word past the group's address. That group's address is then popped off the stack and its sibling, if any is processed using the top of the stack address to generate compounding information. If there is no sibling at this level, the pointer is an up pointer at a higher group. The compounding algorithm thus threads through the structure pushing and popping until the marker is again seen. At that point, the traversal algorithm zips down immediately to all the leaves, passing their addresses in turn to the display driver until a first word of a group or leaf is found with bit 14 cleared. Then the compounding algorithm takes over if it is a group as before, or the modifications are simply processed if it is a leaf.

It might be mentioned that the register load instructions affect the analog values of the display's hardware transformations. Rotation, scaling, translation, intensity, etc. are done by analog modifications to the vectors after they are retrieved from core. A software-only system would have to modify the vectors in core then ship the values out to the scope. Thus, the Vector General Scope is always rotating pictures - when a picture is stable, it is rotating with an identity matrix. This type of analog transformations also allows two leaves to share the same vector list, but with the controlling and register load information of each being completely different, so that the motion dynamics of each leaf can be separately controlled. (The "COPY" command sets up this linkage for the user.)

A few other things are done by the traversal algorithm after it has finished handing pointers to the driver. Each frame, that is, each time every list has been passed once, the analog devices are read, the function switches polled and the system timing table (TIMTAB) incremented. The display is then told to wait until the next clock interval to restart the process again.

As was stated in an earlier chapter, the ability to have arbitrarily complex compounded display transformations in real-time is the most visually exciting capability of this system. The fact that it is so easy for the user to specify should be more acutely appreciated at this point.

E. System Timing Table and Motion Table Interaction

GRASS has a powerful timing facility built into it which, to this point, has been only partially exploited. Every fifteenth of a second or, more exactly, four display cycles, the sixteen entries of the timing table are incremented by the traversal algorithm. If the display is overloaded, in that too much display information is being passed for shading or filling, the timing table still provides accurate timing information. Since any camera would have to be adjusted to the flicker rate of a complex picture, and the timing table is incremented at interrupt level in direct relation to the number of frames displayed, the film will later translate timing back to real time when projected at twenty-four frames per second. Thus, six hundred ticks of the timing table represents forty seconds of film no matter how long it took to film it. Interrupt level timing is the only way to assure such accuracy.

Coupled with the timing table is the motion table (see Figure 12 ).

Figure 12 - Motion and Time Tables

The timing table can deal with absolute counts, and could use counts determined by the x value on a curve in the x-y plane, and counts algorithmically generated. If a time count is expired one way or another, the corresponding entry in the motion table is consulted for the dispatch address to the routine whose execution is dependent on the timing information. Eventually, by this method, one will be able to specify any coordinate path or algorithm as a timing factor.

Presently, only path following ("PATHMOV") uses this facility. Before drawing was replaced by system utility macros, it too used the timing and motion tables for sampling frequency. The facility is obviously open for further development, when the needs arise.

As an example, path following requires that a figure be moved from point to point along a path according to the speed indicated by a dial (or some other DEV). The path following algorithm places the count from the dial setting in the first timing table word. When that count and the system incremented count match, the routine is executed and sets up the new count, and zeroes the system incremented count. Even at this point, equations for acceleration and motion dynamics of other forms may be generated within macros, using a variable for speed of path following instead of a dial. Path following is an extremely valuable tool for animation. GRASS provides a three-dimensional tangential path following capability, examples of which can be seen in Figures 13 and 14.

Figure 13 - Pathmov Example I
PATHMOV - A swallow flapping its wings and moving about a path in real-time.
Figure 14 - Pathmov Example II
PATHMOV - Any object can be moved tangentially along any 3-D path with Z-axis motion simulated by proportional reduction in size of the object as it moves "away" from the user.

F. Grouping and Data Structure Manipulation

Essentially two data structures are maintained in the system. The displayed data structure is the one used by the traversal algorithm. The non-displayed data-structure is used for holding pictures that are selectively erased but will be used again. Both structures are threaded trees which were modified slightly. Elements can be removed from groupings by passing them from one structure to the other by the "PUTLIB and "GETLIB commands. Links are of the one-way type, since the extra effort necessary for deleting items from one-way linked lists due to searching is not significant in this case. Standard methods are used for pointer chaining, except some timing waits were put in to prevent a list that is currently being displayed from having its pointers changed.

As in allocation and deletion, grouping is not a particularly time-sensitive operation. Whereas extreme care was taken to make the interrupt level code as efficient as possible because it is directly related to the number of vectors that can be displayed in real-time, allocation, deletion and grouping run at normal level and any inefficiencies due to searching and sorting do not result in more flicker, or for all practical purposes, the system being any less interactive. In the unlikely case that a user would spend all his time allocating, deleting and grouping, and nothing else, he might be slightly penalized as a result of the methods used for these functions.

G. Names Building and Accessing

GRASS was designed to make the use of names as convenient as possible. The system resident names table includes all the system functions, followed by a macro parameter passing area, followed by the user names, all in ASCII format (see Figure 15).

Figure 15 - Names Table

Access to the table is from any of these three entry points, depending on how the name is to be used. For instance, "ROTATE ROTATE,X,DO" is permissible if the user has a picture called "ROTATE." All functions that could deal with the picture "ROTATE" access names from the beginning of the user names table, rather than from the beginning of the system names table where the function "ROTATE" is found. Any confusion is thus avoided. To refer to a name, only enough letters to uniquely identify it need be typed (except for disk access functions for which the whole name must be typed). Thus, "R R,X,DO" is sufficient if "ROTATE" the function and "ROTATE" the picture are the first occurrences of "R" in their respective names tables. If the picture name were "ROBIN," "R R,X,DO" would still work, of course, providing "ROBIN" were the first name begining with "R" in the user table.

The system will not let the user create a name that could cause a multiply-defined name conflict. Thus, if a name like "TEST3" exists, the user cannot have another picture or macro named any of "TEST", "TE", "TEST3", "TES", or "T" until "TEST3" is deleted. An error message informs the user if he tries to multiply define a name.

The names table access routines also have a "wild card" capability. For example, if "DELETE TE" were typed, all names beginning with "TE" would be deleted. At this point, however, none of the system routines yet acknowledge this capability, a state of affairs which should improve soon. Note, though, that an unnamed macro, namely:

<DELETE TE 
SKIP -1> 

would do the same thing, stopping when all names beginning with "TE" were deleted by printing out an error message.

The system was designed to leave room for expansion and thus, many "hooks" are left in the software. An example of this is the presently unused eighth character that every name has in the names table. lhis character is never passed, but may be used for flags, if that need arises in the future. Every name is also set up to pass switches, although only the system function names are presently consulted for switch values.

One further names-oriented routine is the "RENAME" command which is often useful for resolving the name conflicts in which the use of abbreviated names results from time to time. "RENAME" simply replaces the old name with the new name letter for letter in the names table.

Clearly, the names table routines are not milestones of computer science. The explanations are only included to round out the reader's knowledge of the system.

H. Critical Comparison of this System with Three Other Systems

In the Introduction, several computer animation systems were briefly examined. In this section, three of these systems - CAFE [4][28], GENESYS [14][29] and the National Research Council of Canada System [9] - will be contrasted and compared to GRASS in enough detail to document the differences in language power, quality of interaction, and the relative level of habitability and extensibility in each of the systems.

GRASS was designed for habitability and extensibility. Since these terms and the concepts they represent are fairly new, most likely these other systems did not explicitly have habitability and extensibility as goals. GENESYS, of course, was designed to be very habitable, but the other two systems seem to be oriented more towards film production than towards advancing the state of the art in programming languages. The application of these design criteria to GRASS has resulted in a product that is more powerful, more interactive, and more of a true programming language than previous efforts in graphics, only part of which is due to better hardware. As hardware becomes more complex, it gets increasingly challenging to make good use of the augmented power.

Before further discussion, the concept of a programming language must be defined. A suitable definition in the present context is a command set that includes some form of subroutine calls and looping facility. Therefore, the capability of concatenating command strings by itself is not a sufficient reason for calling a command set a programming language. Similarly, an interpretive effort such as the typical interactive text editor cannot be called a programming language (an exception is PDP-10 TECO which can have named macros and loops). This definition of programming languages may be too strict but it represents an important distinction, especially in interpretive languages.

CAFE is not an interactive system in the sense of the discussion here. Commands may be prepared interactively in the same manner one creates source language programs on a time-sharing computer terminal with an editor, but they must be further processed before displaying. There is no run-time interaction. The 2250 display, in fact, is used for viewing the picture sequences prior to microfilming for proofing purposes - an excellent approach for a microfilm-oriented system.

CAFE uses the admirable approach of combining SNOBOL4 (for language transformation and data referencing), and FORTRAN (for numerical aspects). SNOBOL, of course, has very powerful string manipulation and data structuring capabilities, two essential features for using a higher level language when implementing an animation graphics system. Unfortunately, CAFE's language is not a programming language. There are no program flow control statements, no conditionals, no subroutines, and no numeric or alphanumeric variables. Secondly, CAFE is not interactive in that all picture sequences are determined by previously prepared command files. The SNOBOL part of the implementation makes this command language quite attractive otherwise.

Every point in a CAFE picture has a name. Points make up objects which also have names. Objects combined with motion instructions make up "graphs". Since there is no interactive drawing facility in CAFE, it is fortunate that the authors devised a good method for describing points. In most systems, description of a unit cube takes forty-five coordinates (fifteen points) because a cube cannot be drawn with a continuous line without backtracking. In CAFE, the eight corner points are named and the interconnecting lines are specified in one statement. A slash indicates a drawn vector, and an asterisk indicates a blanked vector. Thus, the twelve visible lines in the unit cube are represented as follows: "a(0,0,0) / b(0,0,1) / d(0,1,1) / c (0,1,0) / g(1,1,0) / h(1,1,1) / f(1,0,1) / e(1,0,0) / a / c*g / e*f / b*d / h." This approach is particularly useful when many lines radiate from several of the vertices.

Given this data specification, one can easily refer to points within objects for purposes of generating data. In contrast, GRASS allows the user to interactively create and identify displayed points with the lightpen, dials, or other devices so that each point in a picture does not need a name. Then, these points taken as numbers may then be used for whatever purpose the user desires - for creating new data, setting scale, translation, rotation or intensity values, or as inputs to numerical calculations within macros.

The transformations in CAFE are done by software and necessitate point-by-point calculations. The original picture description as named points is never modified, however, so the transformations are always erasable. Rotation is not very flexible in this system since only simple rotation around coordinate axes is provided. Complex, arbitrary-axis, arbitrary-origin compounded rotation is necessary to display swimming fish and birds with flapping wings, and this type of rotation is not possible in the CAFE system. Furthermore, all of CAFE's objects are stick figures - no shading commands exist.

If CAFE were a truly interactive system with real-time response, the system's data specification and object description would constitute a fairly powerful system. The concept of "scenes", that is, sequences of picture modifying commands, could easily be carried over to an interactive approach, as could the user-oriented command syntax. The CAFE system also lacks a path following facility, a technique which was shown to be essential to animation graphics by the next system to be discussed.

GENESYS is a highly interactive system which exploits the concept of two-dimensional path following to achieve animation sequences. The user draws his pictures on a data tablet and the image is recorded in real-time. Since the drawing is displayed, the user can watch the screen while drawing. The same device is used to move a cursor which, with a button push, allows the user to select modes of operation from a displayed menu. The path following curves are generated in the same way as pictures and the system relies heavily on the fact that by sampling at a constant rate, more points are recorded per unit distance the slower the user moves the tablet pen. If he moves the pen rapidly, fewer points per unit distance are recorded. When the image is put on the path, if the time interval between points is again constant, the path following controls time relationships as well as x-y plane positioning in the exact way that the user specified the motion. Thus, the user can control his pictures in the same way he controls the position of his hand on a two-dimensional surface.

In conventional animation, motion is simulated by changing the position of objects on an animation stand. Computer animation is essentially the act of replacing the animation stand. To change the shape of an object in conventional animation, a new picture must be drawn and inserted in front of the camera at the proper time. If the object continually changes shape, up to 14,400 drawings might be required for a ten-minute animation sequence. GENESYS automates this changing of object procedure in an innovative manner. The user can substitute one picture for another at any given time. The substitution procedure involves interacting with a displayed row of dots each representing a time slice of a fraction of a second. By moving the cursor, the user can specify which of the time slice dots are to be assigned to the substitute picture. By repeating this procedure, a varied animation sequence can be built up. Clearly, to generate a thousand frames (about forty-two seconds), a lot of dot manipulation could be involved if much image metamorphosis were involved.

GENESYS also allows the user to specify timing by tapping a function switch, thus adding another means of tactile interaction. Further features of the system permit editing of motion sequences and some positioning of objects with dials.

Ron Baecker himself describes the hardware he used as "stone-age" [15, p.265]. His work is admirable in that some of the philosophy of interaction in animation graphics was explored to a great depth. GENESYS, however, has serious shortcomings. lhe picture quality is poor and the implementation is totally two-dimensional. The command language is minimal and is not a programming language in the sense described above. Of course, there is no macro facility. Shaded images are not possible and the lack of three-dimensional representations preclude all but z-axis rotation and the rotations that can be simulated by one-dimensional scaling.

Furthermore, the picture substitution approach to computer animation is not conducive to smooth transitions between pictures. To achieve this kind of transition, one would have to specify a change of picture at nearly every step, and draw all the in-between pictures. This procedure cannot be automated easily, and is not nearly as effective and exciting as the totally automated linear interpolation (blending) as it exists in the National Research Council's system or GRASS. Furthermore, the path following in GENESYS is not even tangential. GRASS allows three-dimensional tangential or non-tangential path following (user option) with speed controlled by the point density of the path, optionally compounded with dial settings or interactively specified algorithms. A form of picture substitution similar to that of GENESYS can be done with macros. Furthermore, a blending picture can be moved along a path, rotated, the path and the picture rotated, translated, scaled and combined with fade-ins and fade-outs. The path can be put on a path, as in the case of ejecting the contents of an airplane cockpit along a path while the airplane is flying along another path, and this process can be repeated to any desired level. The picture quality of GRASS is far superior to that of GENESYS. In other words, one is a production system and the other is not. GENESYS does represent the first habitable animation system and its implementation introduced many new concepts. Both the GENESYS film [30] and Csuri's film "Real-Time Film Animation" [31] can be acknowledged as influences on the design of GRASS.

Another system designed for production and really used for production is the National Research Council system. The system is oriented towards the professional animator and is based on conventional cel (a transparent overlay) animation techniques. During the design stage, the animator manipulates wire-frame figures which can later be converted to raster scanned shaded pictures for filming. Burtnyk and Wein are to be credited with the first useful implementation of linear interpolation [9].

The N.R.C. system uses a combination of the "menu" technique and a somewhat cryptic command language whose operands are mostly numerical. The menu is used for the interactive part of the system which includes two-dimensional drawing and picture modification routines. ("GRABBER," "PULLER" and "SHAPER"). All the motion sequences are prepared off-line using the command language so there is no interaction during run-time. In fact, Burtnyk and Wein maintain: "Neither the use of a drawn path nor the generation of a path by continuous interactive control have been found satisfactory except for purposes of experimentation." The users of GRASS would strongly disagree with this conclusion.

Within the command language it is possible to specify frame numbers and indicate the interactions between any of several levels of "cels" during any particular frame. Several different types of transformation may take place simultaneously on one or more pictures, if so indicated in the command string. One must specify the type of velocity curve (decelerating, accelerating, linear, etc.) mapping the rate of change for each transformation applied to the picture. All parameters are specified numerically and very exacting motion sequences may be generated.

The linear interpolation will preserve boundaries if some conventions are preserved. Thus, shading blending images is possible, resulting in merging solids, a very striking visual effect.

The command language of the system is not a programming language in that it is only a long string of sequentially listed commands which control several simultaneous operations. Any new additions to the language would have to be done in assembler.

GRASS allows control of any picture or hierarchy of pictures with motion sequences algorithmically specified or interactively generated. At least forty or fifty individual pictures can be manipulated separately and up to one hundred square inches of shading can be displayed in real-time (due to a high-speed vector generator), all while moving, path following, rotating, and flapping wings. Recent implementation of a boundary preserving linear interpolation technique provides the capability of blending solids as is done by Burtnyk and Wein. GRASS is much easier to use as well, since parameters rarely have to be specified as numbers, and the language is fairly easy to learn and read. The program flow control statements and macro facility allow the user to define acceleration and deceleration in terms of paths, algorithms, dials and switches. The quality and quantity of the interaction is much greater than with the N.R.C. system.

The N.R.C. system has no facility for compounding transformations, so all complex motions must be specified in terms of linear interpolations. This may, in fact, turn out to be a better approach to automating complex walking motion animation and other such phenomena. Of course, it's best to let the user decide, since linear interpolation may not be usable for the generation of scientific-type films which one is likely to desire in an educational environment.

GRASS owes its flexibility and productivity to the fact that it was designed for extensibility and habitability, and uses state-of-the-art equipment. As the electronics become more sophisticated and new modes of thinking are adopted, it is hoped that this system, if nothing else, can be used to demonstrate that a powerful, easy-to-use interactive system is worth the effort of implementation.

IV. THE FUTURE

The discussion so far has covered the features of GRASS that are implemented and working. This chapter will consider new features which will enrich the system and will undoubtedly keep the system programmers busy for a while. The extensions are not primarily to the power of the programming language, but are more generally oriented toward making the animator's tasks even easier. The topics presented are more or less in the order in which they will be implemented, the last couple being somewhat fuzzy at this point. A few words will be said at the end of the chapter about work that needs to be done in habitability and extensibility studies.

First, a "TRACE" command will be written. "TRACE" will record the states of the analog devices and the function switches, as well as any keyboard input from the moment the user types "TRACE" and will continue until disabled. Cnly changes of values will be recorded every fifteenth of a second, so that even in the case of the user turning half the dials continuously, a good half-hour could fit on half a disk cartridge (600,000 words). A half-hour represents a lot of film. Note that the variables do not have to be recorded since they are algorithmically generated or read from dials. The time represented in the file will also be real-time, since it will result in the same amount of film, regardless of the time it took to generate complex pictures. If the user creates a half-hour long "recording," he should have accurately reproducible sequences to the point that he could conceivably set up the camera with a thousand feet of film and go have dinner. "TRACE" will go a long way towards automating the filming, and thus would increase the system's habitability.

Linear interpolation is a technique whereby the animator specifies two pictures and the interpolation routine generates the "in between" frames to produce a smooth transition from the first to the second picture. Thus, most of the drudgery of blending images is automated and a new tool is given the animator. Peter Foldes, in conjunction with N. Burtnyk and M. Wein of the National Research Council of Canada, has produced fi1ms [10][27] in which motion is approximated by successive interpolation sequences, which is essentially how conventional cartooning is done. The technique needs to be exploited in a wider field of application than Foldes' admirable work is based, and GRASS is the ideal vehicle for this work because blending pictures can be rotated, scaled, moved along paths, and generally treated like regular pictures. The linear interpolation technique presently available to the system preserves boundaries which permits shading to occur at each intermediate frame (at somewhat less than real--time,,averaging about two to four seconds per frame), thus creating sequences of blending half-tone solids. Another improvement was to allow parts of the first picture to selectively blend into parts of the second picture, thereby eliminating the current blending of heads into feet and other such normally undesirable effects. Linear interpolation is a technique which does much to automate the production of quality film, thereby enhancing the system's habitability.

Concurrently developed will be data generation facilities, the most sorely needed aids to computer animation at this point. The work bas been started with "WARP" which allows flexible manipulation of boundaries (or any vector list), and "FILL" which permits the user to fill boundaries with randomly placed "fill-characters" of his choosing, thereby creating textures (see Figure 16).

Figure 16 - "FILL" Example
An example of the "FILL" routine. The "fill character" in this case is a small straight line which is randomly placed and randomly rotated within the specified outline.

The sonic pen will be developed as a three-dimensional drawing tool, perhaps through the use of macros, possibly through off-line programs with different data structures. A prototype modeling macro which allows the building of complex pictures from user-created simpler elements was written in a single morning. This macro represents a level of flexibility and sophistication which would take months to achieve on a new machine with little or no graphics software available. Various curve fitting and parabola generating techniques will be exploited to help artists and instructors describe their conceptions to the computer. Perhaps generated perspective views on a split-screen or two monitors with adjusted parallax will be used to aid in viewing three-dimensional structures being built. The data generation problem is a user-oriented one in that each step in solving it will increase the ease of producing images, a definite improvement in the level of habitability.

Then, a full FORTRAN-like arithmetic capability will be added, complete with floating point variables, precedence operators and nesting. Since the interpretive approach is somewhat lacking for complex numerical calculations, it is planned to compile arithmetic statement groups into PDP-11 assembler code, create a swap module for the code during disk-to-core transfer, and use the module within a macro like any other assembler swap module. Thus, very efficient numerical processing will be possible. Subroutine calls to assembler routines for sine, cosine, matrix multiplication, and others also will be included, and thereby increase the capability of the language for numerical computation. Adding such capabilities is a conventional problem in computer science that has been solved many times. The implementation is simply tedious.

The system presently contains a debugging technique which was patterned after the standard Digital Equipment Corporation's "DDT" or "CDT." This debugging technique has been extremely useful to the systems programmers for aid in quickly isolating and correcting errors in the code. What is still needed is a macro-level debugging technique, a feature which will add to the system's habitability since complex macros will then be easier to construct and make usable. Presently, the "LIST" command helps debug macros by listing statements on the display terminal as they are executed. The user may interrupt a program and query a value by using the "PROMPT" command. A more advanced technique will be written once enough experience has been obtained in writing macros to discover where help is needed. Present programming languages tend to be inadequate in terms of on-line debugging aids, so much of the work would have to be original. Better macro editing facilities will be needed, but this is again a question of tedious implementation.

The idea of introducing color is a very exciting one. Of the many techniques available, none is ideal in all respects. Color cathode ray tubes exist, but the color is fairly "washed out", cannot be blended effectively, and the whole spectrum is not represented. External processes like DATACOLOR are good for translating grey levels to colors assuming the raster is fine enough for projection quality and fringing does not occur.

Recently, the support for a color wheel was added to GRASS. The color wheel (see Figure 17) revolves at 1,800 r.p.m. and is synchronized to the line frequency (60 c.p.s.).

Figure 17 - Color Wheel
COLOR WHEEL - The color wheel is a rotary four color disk which with proper display synchronization results in full color real-time images when viewed or filmed. Colors may be dynamically blended and assigned any of several intensity levels.

The software amounted to about eleven lines of new code, and includes a new command "COLOR". The hardware came to less than one hundred dollars. The color is easily specified, brilliant (except for red, which is a little washed out due to the spectral deficiencies of the F-4 phosphor), and can be readily filmed. Color may be specified by having the axes of the sonic pen keyed to the three primary colors, with motion of the pen resulting in spectral variations. The color wheel approach is limited, however, because the time allotted each color is less than 1/120 second, and thus the number of vectors in colored shaded pictures that can be displayed is much, less than can be put up flicker-free without the color wheel. This problem will be partially solved when the color wheel is interfaced to the Arriflex camera through the PDP-11, with pulses controlling the shutter of the camera and the stepping motors of both the camera and the color wheel. Color for complex pictures will then be somewhat less than real-time, but the film will be of high quality.

Presently there are commands in the system to aid filming ("FILM" and "UNFILM"). Ihese commands will be modified and added to when the interface of the Arriflex camera to the PDP-11 is completed.

Another project to be started is the use of the segmentation hardware of the PDP-11/45. This mini-computer allows addressing to 128k words with sixteen bit addresses by the hardware memory management unit. The first task will be to get at the 16k of core already available, but presently inaccessible. The code has been written for this task, but it is not yet interfaced to the system. The segmentation hardware may eventually be used to exploit GRASS's inherent re-entrancy. The entire system keeps its storage in a separate section of core so that multiple users could be permitted by duplicating only the storage area for each user. Only one copy of the system code would be needed. Obviously, a multi-user system would require more than one monitor. Fortunately, the Vector General hardware can handle up to four scopes, each with its own analog input devices, function switches and light pen, at the cost of sharing the vector generator.

Much work still needs to be done in computer graphics that has not even been attempted by the implementation of GRASS. Many problems are simply too complex to handle in real-time. For example, the display normally shows all sides of a three-dimensional object, both front and back, both outside and inside. Removing the lines and surfaces of objects so that the front surfaces would block out the back, as is the case with opaque objects in real life is a problem whose solution tends to use inordinate amounts of computer time, getting worse as the picture complexity mounts. Faster general purpose and special purpose hardware may eventually allow hidden line and surface calculations for the concave case to be undertaken in real-time. GRASS has the capability of removing hidden surfaces for totally convex objects in real-time, but only a small class of objects are convex from every view (see Figure 18).

Figure 18 - Hidden Surface Example
A) A shaded 3-D "steeple". Every other surface component has been deintensified. B) The same steeple, but with the hidden surfaces removed.

In any case, with new hardware or without, new algorithms will have to be worked out for use with pictures of useful complexity. The recent work at the University of Utah by Watkins [39], Gouraud [42] and Parke [20] with shading and softening of the shaded surface edges is, hopefully, an indication of what can be done.

It must be emphasized again that the most difficult unsolved problem in computer graphics is still that of data generation. One approach is using shaded origami-like objects (see Figures 3,4,13,14,19).

Figure 19 - "Origami" Fish
A) The outline of a fish composed of planar surface outlines B) The shaded fish in 3D.

The thrust of future-graphics efforts should be in this direction in order to make the description of three-dimensional input to the computer possible in much more habitable ways than presently exist.

Work needs to be done in the general fields of habitability and extensibility studies, as well. Standing in the way of increasing habitability are many obstacles, some of which can be overcome by faster or special purpose hardware, some by software. Software may be developed to parse natural language input, although linguists today know the problem is significantly more difficult than it was thought to be ten years-ago. More hardware along the lines of analog input devices is clearly feasible (e.g. Noll 's tactile communication work [38] and Sutherland's head-mounted display [40]. New approaches ranging all the way to electro-encephalographic techniques (reading alpha waves) could conceivably improve communication, leading to a level of direct interchange at near electronic speeds. GRASS has made innovative use of the hardware available to it and should be a good vehicle for the exploration of new hardware techniques for improving habitability and for real-time solution of difficult problems. Experiments may be done in which habitability is measured statistically in controlled environments, but the area of study then becomes one of man-machine psychology, and is thus outside the scope of the present discussion.

Extensibility in interpretive languages is likely to become more popular since, in general, computer time is becoming cheaper and programmers more expensive. Interpretive languages help people communicate their problems to computer systems and extensible interpreters allow the rapid generation of special purpose systems that themselves can grow with needs. The methods used to process syntax may be studied and progress can be made in the area of compiling interpretive segments that have been checked out to satisfaction and are ready for production tasks, following along the lines of Schuman's work on compilable interpretive extensible languages discussed in Chapter II [18].

The best method of finding out areas of needed improvement in extensible languages is to implement them, as has been done here in a very specialized situation. T.E. Cheatham is in agreement with this philosophy:

There are clearly many who feel ... that we have a long way to go in basic research and development of extensible languages and their host facilities; I do not share this opinion. Rather, I think that in a very strong sense "we have arrived" - that there exist languages and #host systems which fulfill the goals of extensibility.

This is not to suggest that the problem is completely solved.... However, it is my pos1tion that further research in extensible language, per se, is probably destined to yield only marginal results until such a time as significant period of exploition has clearly pinpointed issues with which a new wave of extensible language research might attempt to contend. [21, p 146]

Beyond more implementation of extensible languages, Cheatham suggests that the process of programming be automatead - a logical step from the very high level of coding possible with extensible languages. For this, theorem proving and correctness of program techniques will have to be refined, and the area of study quickly involves artificial intelligence, pattern recognition and mathematical logic.

Computer graphics is an excellent area in which to pursue the implementation of languages which are more extensible and more habitable, for the reasons that the users are typically more or less naive but their animation problems can be as complex to solve by computer as those of any scientific endeavor. The future of computers as tools for use by the general public lies in providing computer systems which are easy to learn and use - ones which the user, with brief instructions, can describe his problems and have computer systems quickly adapted to his needs.

V. DISCUSSION OF THE IMPACT ON COMPUTER GRAPHICS AND SOCIETY

The people who have worked on GRASS in the past year are confident that the state of the art in computer graphics has been significantly advanced by this project.

There are two essential reasons for the present paucity of computer graphics installations and the relative inaccessability of existing ones. The first is cost. Heretofore, the only hardware available of comparable power for animation graphics involved a PDF-10/Evans and Sutherland LDS-I system that runs a minimum of $600,000. The PDP-11/45 and Vector General configuration at The Ohio State University represents an investment of approximately $160,C00. A minimal PDP-11/20 system with a 3-D scope would cost about $60,000 and have everything but half-tone shading (which requires floating point calculations in the present implementation). A two-dimensional scope is still less expensive (one could still do rotations by software). Admittedly, a PDP-10/LDS-I system represents more powerful hardware, but not in the order of four to six times as powerful. An IBM 1130/2250 system costs twice as much as the CSU system above, but it is at least twenty times slower and has no rotation or floating point hardware.

Thus, it may be observed that by simply diverting funds for a high-speed line printer from the local computer center (maybe a tape drive or two also), a decent stand-alone graphics system may be purchased. The cost of such systems will decrease as soon as volume sales justify the abandonment of hand-wired modules. Even now, the equipment cost is within the reach of many teaching aids laboratories, state institutions and computer assisted instruction centers.

It costs more today to develop software than to purchase hardware. For this reason, GRASS has been carefully modularized to allow its use on systems of less complexity than the CSU system. Feature switch settings permit or prevent assembly of flcating point code, hardware or software multiply and divide instructions, and polling and accessing dials, function switches, and VT05-like devices, in any combination. Features like the keyboard substring matching facility or the login and password restrictions may be conditionally assembled. All the feature sw1tcnes are in a system parameter file which may be edited to fit a particular configuration. The intention is to eventually distribute the software.

The second reason that has prevented general accessibility to computer graphics installations has been the high level of expertise normally needed to program packages for computer graphics applications. In that it is a general purpose graphics programming language, GRASS has eliminated, to a great extent, the need for the expensive coding of what have been called "throw-aways" one-shot, single purpose programs. Furthermore, the habitability considerations included in the design of the language allow a non-programmer who could not effectively program in FORTRAN to interact with the system to make useful films in relatively short periods. The first film made on the system, using unsophisticated newsreel camera equipment, lasted twenty-five minutes and was shot entirely in the week before it was shown for the first time. About eight hours of setting up and filming were required, and the level of expertise was somewhat lacking at that point. The images were generated beforehand, but the sequences were all developed as shooting progressed. Such an effort using conventional techniques could easily have taken several months.

In recent weeks, GRASS has been put into production use at The Ohio State University. The first naive users are now writing macros and making film. New users express astonishment at how easily they can manipulate pictures. They had all read the command descriptions and some introductory material and seen examples of film made on the system but claimed that the verbal and visual documentation did not do justice to the part of the system that was most important to them - what we have been calling "habitability." It is hard for the beginner to appreciate the quality of this essentially tactile and visual interaction by reading about it. Sophisticated computer graphics audiences have been able to appreciate the nature of this system, but even then, film was necessary to support the discussion. Computer graphics gives what is essentially four-dimensional output: the two-dimensional movies give the illusion of three dimensions through motion and the fourth dimension is conveyed by the time the film takes. To explain this system in terms of one-dimensional English syntax, or two-dimensional photographs is a task that rarely succeeds, especially when aimed at the uninitiated.

To document the realism that can be achieved within the system, an incident that happened during the final editing stages of the first film can be related. The film was being shown in the presence of several people and a neighborhood stray cat who tends to be quite lethargic. It has been remarked that nothing save physical violence and petting gets a reaction from this cat. During the first several minutes of the film, the cat was watching the screen, half-asleep. When the shaded, three-dimensional "origami" swallow (see Figure 14) with its sinusoidally flapping wings came on, the cat literally went wild and climbed the screen. After the swallow sequence, it left the room. In a day and age in which television sets are advertised as being superior because live cats paw at images of parakeets in bird cages on the screen, this incident must mean something. The image quality is by no means good enough to fool humans, however.

Video tape systems could be coupled with computer graphics equipment for general purpose special effects generation. Indeed, on-line, real-time graphics with video backgrounds or foregrounds is a real possibility for commercial and educational television environments. Using video disk techniques, and a system like GRASS, colors may be introduced and automatic masking of backgrounds used to create high quality video output for entertainment and educational use.

Computer assisted instruction efforts have been hampered by the high cost of graphics, so that only a few systems use visual aids more complex than a slide projector. GRASS could be used to prepare images for use on either a storage-tube display terminal (which looks like a teletype to a computer's operating system) or a small, low-cost vector generating display terminal of the type recently announced by both Vector General and Digital Equipment Corporation. These terminals represent a viable alternative to fifteen character-per-second. text oriented computer assisted instruction systems, especially when fast hardcopy facilities are added.

This project's true short term benefits to society will probably be realized in the inexpensive generation of film or video tape. This film or tape will communicate information that has been too expensive or too time consuming to conventionally animate, or that is not really possible to explore otherwise, as in some topics of the mathematical and physical sciences. Recently, a video tape was generated for the Mathematics department illustrating some concepts of geometry and two multi-media shows used many minutes of computer graphics to illustrate shifting continents, evolution of lystrosauri, the fibonnacci series in plants, the three-dimensional nature of complex molecules, among other things. These efforts were accomplished rather rapidly, the mathematics film in about two hours.

Mixed media of this type can facilitate the introduction of sophisticated concepts to students, or even to the general public. One project might be to illustrate birth control concepts graphically to those persons least likely to understand overpopulation and the need for zero population growth, that is, the persons most necessary to reach. Another sequence could simulate a rail system on existing tracks that could alleviate commuter auto traffic in cities without subway systems. Productions like these could be distributed at low cost on video tapes to be shown in neighborhoods. The potential of computer graphics is clearly unbounded.

The possibility of some elements in society using such a tool to indoctrinate is unfortunately present. In fact, much of the animosity one perceives towards computers in general is due to the wide misuse of information storage and retrieval facilities. One has to sometimes rationalize not being a modern-day Luddite in this respect, and hope that the legal apparatus of this country, and other countries, will obstruct misuse of computer graphics, computer assisted instruction, and data banks as vigorously as it has other undesirable elements.

REFERENCES

[1] W C Watt, "Habitability," American Documentation, Vol 19, No 3, July 1968.

[2] A J Perlis, "Proceedings of the Extensible Languages Symposium," SIGPLAN Notices, Vol 4, No 8, August 1965.

[3] B A Galler, A J Perlis, "A View of Programming Languages, Addison-Wesley, 1970.

[4] Lynn D Yarbrough, "Experience with CAFE, A New On-line Computer Animation System," UAIDE 1968.

[5] Francis J Honey, "Computer Animation - A New Look," UAIDE 1968.

[6] Francis J Honey, "Computer Animated Episodes by Single-Axis Rotations," UAIDE 1971.

[7] Peter Foldes, "Narcissus," (film), First Internationel Animation Film Festival, New York, 1972.

[8] F Gracer, M W Plasgen, "KAKA: A System for Storyboard Animation," UAIDE 1970.

[9] N Burtnyk, M Wein, "A Computer Animation System for the Animator, UAIDE 1971.

[10] Peter Foldes, "Hunger"," (film), First International Animation Film Festival, New York, 1972.

[11] John W Carr III, et al, "Interactive Movie Making", UAIDE 1970.

[12] S E Anderson, "Generating Computer Animated Movies from a Graphics Console," UAIDE 1970.

[13] S E Anderson, "A List Processing System For Effectively Storing Computer Animated Pictures," UAIDE 1968.

[14] R Baecker, "Interacive Computer Mediated Animation, PhD, April 1969.

[15] R Baecker, "Current Issues in Interactive Computer-Mediated Animation," UAIDE 1970.

[16] A V Hershey, "Caligraphy for Computers", US Naval Weapons Laboratory Report 2101, August 1967.

[17] J A Feldman, "Panel on the Concept of Extensibility",SIGPLAN NOTICES Vol4 No 8, August 1969.

[18] Stephen A. Schuman, "An Extensible Interpreter" SIGPLAN NOTICES, Vol 6 No 12, December 1971.

[19] Jean E Sammet, "Application of' Extensible Languages to Specialized Application Languages", SIGPLAN NOTICES, Vol 6 No 12, December 1971.

[20] Frederick I Parke, "Computer Generated Animation of Faces," ACM National August, 1972.

[21] T E Cheatham Jr, "Extensible Language - Where Are We Going" SIGPLAN NOTICES Vol 6 No 12, December 1971.

[22] A Van Wijngaarden, et al., "Report on the Algorithmic Language ALGOL 68" Numerische Mathematik, 1969.

[23] DATACOLOR Colorizer, Spatiai Data Corporation, Coletta, Ca.

[24] Jean E Sammet, "Programming Languages: History and .Fundamentals", Prentice-Hall, 1969.

[25] W A Wulf, et al, "BLISS: A Language for Systems Programmers," CACM, Vol 14, No 12 , December 1971.

[26] Thomas A. Standish, "Remarks on Interactive Computer Mediated Animation," UAIDE, 1970.

[27] Peter Foldes and P Moretti, "METADATA," National Film Board of Canada, 1971.

[28] J Nolan, L Yarbrough, "An On-line Computer Drawing and Animation System," IFIP 1968.

[29] R M Baecker, "Picture-Driven Animation," SJCC 1968.

[30] R M Baecker, "GENESYS: An Interactive Computer-Mediated Animation System," (film), MIT, Lincoln Labs, 1970.

[31] C Csuri, M Knemeyer, "Real-Time Film Animation," (film), Ohio State University, 1970.

[32] C Csuri, "Real-Time Film Animation," UAIDE, 1970.

[33] J C Gray, "Compound Data Structure for Computer Aided Design; A Survey," ACM National Meeting, 1967.

[34] P G Comba, "A Language for Three-Dimensional Geometry," IBM Systems Journal, Vol. 7, Nos. 34, 1968.

[35] A van Dam, "Data Storage Structures for Interactive Graphics," SIGFLAN Notices, Vol 6, No 2, February 1971.

[36] D Abrams, "Data Structures For Computer Graphics," SIGFLAN Notices, Vol 6, No 2, February 1971.

[37] H. Williams,"A Survey of Data Structures for Computer Graphics Systems," Couputer Surveys, No 3, March 1971.

[38] A M Noll, "Real-time Interactive Stereoscopy," Bell Labs.

[39] G Watkins, "A Real-Time Visible Surface Algorithm, Dissertation, Utah, 1971.

[40] I E Sutherland, "A Head Mounted Three-Dimensional Display," FJCC, 1968.

[41] F J Sarno, "The Polygraphics Software Package - A Survey Of Its Features," UAIDE 1968.

[42] H Gouraud, "Computer Display of Curved Surfaces", Dissertation, Utah, 1971.

APPENDICES

A. SYNTAX OF THE LANGUAGE

This Appendix gives the syntax of each command of the system. The printout is from the "HELP" message file. The commands are listed alphabetically (with some very new ones added on the end) and are printed exactly as they would appear on the display terminal. 'This appendix was produced by changing the command device to the hardcopy terminal, an option available to any user.

The listing is included as a PDF file.

Below is a more readable version of the information given in the listing.

HELP COMMAND-NAME
HELP is here to answer syntax questions. Certain abbreviations have been used which, hopefully, aid understanding:
ANAME  Any picture or macro name
PNAME  Any picture name (group or single picture)
LNAME  Any single picture
GNAME  Any group name
MNAME  Any macro name
DNAME  Any disk file name
Names may be abbreviated to enough letters to ensure understanding.
DEV is one of the following:
DIALS 0-9        (D0-D9)
JOY STICK        (JS or JX,JY,JZ)
SONIC PEN        (SP or SX,SY,SZ)
VARIABLES        (A-Z)
EXPRE is a mix of numbers, DEVs, and arithmetic operators which always evaluates to a single number.
RESET PNAME
RESET is the same as FIX except that the original values of the rotation matrix, ORIGIN,SCALE, INTENSITY, etc are restored.
SWITCHES: Same as FIX
EXAMPLE:

RESET/R PROP
RETURN
Pops up one level in a macro being executed and thus provides convenient exit to the end of the macro.
EXAMPLE:

TOM:<Y=0
SAM:<Y=Y+1
IF Y GT 10, EXIT
IF Y GT S, PROM Y+Y
IF Y GT 1, RETURN
IF Y LT 10, GOTO SAM
PROM *THOSE WERE THE SQUARES OF 5 THROUGH 10*>
GETHIT N,X,Y,Z,K
GETHIT gives the status of a lightpen hit where N=the nummber of the point in the list, X,Y,Z are the respective coordinates, and K is zero if it is a drawn point, one if it is the initial point of a vector (following a jump), and minus one if it is the last point. Of course, N,X,Y,Z, and K can be any variables.
EXAMPLE:

GETHIT F,U,V,W,G
GETLIB PNAME1,PNAME2
Gets PNAME1 from non-displayed data structure (i.e. PUTLIB'D) and puts it into the displayed data structure after PNAME2. If no PNAME2, then PNAME1 becomes the first element in the data structure. PNAME1 must have been PUTLID'D or gotten by .BIN format in GETDSK. PNAME2 must be displayed.
EXAMPLE:

GETLIB SAM
GETLIB MARY,SAM
GETPOIN LNAME,N,X,Y,Z,K
Gets a point from an LNAME, The X,Y,Z coordinates of the point indicated by the expression N are returned in variables indicated here by X,Y,Z. N ranges from 1 (the first point) to the last vector in the LNAME (depends on how big the picture is). K is a variable in which the following is indicated:
K=0 drawn vector
K=1 non-drawn vector (JUMP)
K=-1 end of list (last vector)
EXAMPLE:

GETPOIN,WITCH,20,G,H,I,K
This will get the coordinates in decimal of the 20th vector in WITCH and place them in variables G,H,I and indicate whether this line was drawn, a jump or the end of the list, in variable K.
GOTO MNAME+EXPRESSION
GOTO is used to transfer control to named macros either internal or external to the macro being executed.
EXAMPLE:

TOM:<X=0
SAM:<X=X+1>
IF FS0=0, GOTO SAM>
This example will increment variable X until FS0 is pushed.
FSON EXPR1,EXPR2,EXPR3,....
FSON turns on (sets to one) function switches corresponding to EXPR1,EXPR2, etc. FSON does not work with FS15 or the PANIC button.
EXAMPLE:

FSON 9,2,4,6,8,10,12,14
This turns on the even function switches so that they light up.
GETCOM DNAME.EXT
GETCOM is the same as GETDSK except it takes DNAME from the common area on the disk ([30,1]). GETCOM is equivalent to:
GETDSK DNAME.EXT[30,1]_
GETDSK DNAME.EXT[30,X]
GETDSK gets the DNAME from the disk area indicated by [30,X] (default is your area). If no .ET, it defaults to .DEC. DNAME becomes the name of the thing you are GETDSK'ING.
EXTENSIONS:
.DEC  Decimal mode
.BIN  Binary mode
.VGN  Vector General format
.CST  Character Set (automatically called by 'TEXT')
.DLN  Present blend format
.MAC  Macro format (for macros, not for pictures)
Note that .DEC, .VGN, .BLN come up on the screen. .BIN pictures are put into the nonpdisplayed data structure (PUTLIB'D) and must be gotten by GETLIB to be seen. .BIN also preserves the setups of dials, etc for ROTATE, MOVE, SCALE, etc whereas the others do not.
EXAMPLE:

GETDSK WITCH
GETDSK WITCH.DEC
GETDSK WITCH.DEC[30,10]
GETDSK DRAW.MAC
GETDSK ROM2.CST
GETDSK OH101.DLN
FIX PNAME
FIX freezes the position of a picture or the value of a PNAME's modifier according to the switch options. No switch fixes everything. FIX also removes DEV assignments if any.
SWITCHES:
NONE Fixes all of the below
/R   Fixes ROTATION
/S   Fixes SCALE
/M   Fixes MOVE
/P   Fixes PATHMOV
/I   Fixes INTENSITY
/C   Fixes CUTOFF plane
/H   Fixes GIDE feature
/O   Fixes SETORG
EXAMPLE:

FIX/R COPTER
FIX GLOBE
FLAP PNAME,EXPR1,EXPR2
FLAP pits bounds on the rotation angle. The bounds are given by EXPR1 (the higher bound) and EXPR2 (the lower bound). FLAP will settle faster if
FLAP PNAME,0,0
is typed first, followed by the FLAP command with the desired bounds.
EXAMPLE:

ROTATE WING,X,D0,D1,D2
FLAP WING,100,-120
FSOFF EXPR1,EXPR2,EXPR3,...
FSOFF turns off the function switches corresponding to the expressions
EXAMPLE:

FSOFF 1,3,5,7,9,11,13
This turns off the odd function switches. (Note that FS15 is not user programmable.)
DASHES LNAME
DASHES changes the LNAME's vectors to DASH mode.
SWITCHES:
NONE  Dashes mode
/R    DOTS mode (really short dashes)
EXAMPLE:

DASHES DIAMON
DELETE ANAME
Deletes the ANAME from core, removes the name and reclaims the storage the ANAME took. Does not presently work with GROUPS.
SWITCHES:
NONE  As above
/D    Deletes on your disk area
EXAMPLE:

DELETE GLOBE
DELETE JSDRAW
DELETE/D WITCH.DEC
DELPOI
DELPOI deletes the last previously PUT point in an OPEND/D list. It takes the LNAME from the OPENO command issued.
EXAMPLE:

<PUTPOI D0/16,D1/16,D2/16,1
IF FS1,DELPOI
SKIP -2>
This causes vectors to be drawn unless FS1 is pushed.
DIRALL
DIRALL gives the user the disk directories of everyone's areas.
EXAMPLE:

BYE
BYE logs user out if he types *YES* to confirm. Login must be used to reenter system. BYE is useful for changing disk areas while running GRASS.
CLEAR
CLEAR simply clears the VT05 screen.
COPY LNAME1,LNAME2
COPY causes LNAME2 (the new name) to share the data of LNAME1 (the old name). Any command that does not modify data lists (e.g. ROTATE, SCALE, MOVE etc) may then independently be used on either LNAME, Commands hat alter data lists (e.g. SMOOTH, SOFTROT) will modify both copies. COPY may be used to reflect a picture around an axis by using the single dimensional SCALE.
EXAMPLE:

COPY GLOBE,WORLD
ROTATE GLOBE,X,D0,D1,D2
ROTATE WORLD,Z,D9
SCALE WORLD,D6
COLOR LNAME,EXPR
COLOR sets up the LNAME for use with the color wheel. The EXPR must evaluate to 0,1,2,3,4, or the LNAME will be blanked. Zero indicates all colors. That is WHITE. The other values indicate one of the four separate color wheel colors. The choice of which must be done after the color wheel is spinning, Colors may be mixed by using the COPY command and setting the copy to a different color than the original. If the image does not appear to have pure colors, too much picture is being displayed and the number of vectors being drawn must be reduced in this case.
EXAMPLE:

COLOR LEAF,1
COLOR BUMP,4
EXIT
EXIT is a super return. It acts like a Control C within a macro and returns control to "*" (i.e. VT05) level.
FILL OUTLINE,FILL-LINES,FILL-CHARACTER,SPEED,DEGREES
FILL takes a LNAME as an outline, builds a new LNAME composed of the FILL character randomly placed within the outline until FS13 15 pushed. The FILL character should be composed of a small number of vectors. If many are needed to fill the outline. DEGREES (/P only) indicates the angle at which the FILL character is rotated. the DEV for SPEED controls the rate at which the FILL character is repeated.
SWITCHES:
NONE  FILL character is randomly rotaated as
      it is placed within outline
/P    FILL character is placed at angle indicated by
      DEGREES
EXAMPLE:

FILL SQUARE,HAIR,CURL,DO
FILL/P HILL,FOREST,TREE,DO,45
FILMING
Sets single framing mode ("F" is enough to trigger this command)
GROUP PNAME1,PNAME2,GNAME
Groups PNAME1, PNAME2 and everything between them into a group named GNAME. PNAMEs must be displayed. PUTLIB/GETLIB sequences may be used to alter group structure by eliminating or adding pictures if necessary. Any command which will work on PNAMEs will work on grouped pictures.
EXAMPLE:

GROUP AIRPLAN,PROP,PLANE
HIDE
HIDE may be used to hide the rear surfaces of specially prepared 3-D shaded figures. The surfaces must be set by SETINT/S, drawn counter-clockwise as they rotate into view, and be shaded by SHADE/3,/4,5 or/6.
EXAMPLE:

SHADE/5 STEEPL,TOM,4
SETINT/S TOM,D9
HIDE TOM
INTERP OUTLINE,SHADE-LINES,EXPR
INTERP creates a new picture by running lines between the vectors of the outline. The new lines are spaced as indicated by the EXPR. The OUTLINE must have at least one jump in it, but may have more.
EXAMPLE:

INTERP FLUFF,STUFF,30
LINES LNAME
LINES puts LNAME's vectors in regular drawing mode. It is used to recover from DASHES and POINTS modes
EXAMPLE:

LINES DIAMON
LIST
LIST causes lines of macros to be echoed during execution. It is a useful debugging tool. LIST is suppressed by XLIST.
MOVE PNAME,ORIGIN
Moves PNAME to place indicated by ORIGIN. ORIGIN is new X,Y,Z position and is specified by DEV, DEV+1 and DEV+2.
EXAMPLE:

MOVE WITCH,JS
MOVE TOM,F
The first example moves the WITCH according to JX,JY and JZ. The second example moves TOM according to variables F,G and H.
OPENO LNAME
OPENO is necessary to allocate the core memory necessary to create a picture. It sets the LNAME fpr DELPOI and PUTPOI also.
EXAMPLE:

OPENO SAM
OPENO $A
The second example illustrates the use of the "$" feature (see HELP macro).
PATHMOV PNAME,LNAME,SPEED
PATHMOV moves PNAME tangentially along LNAME according to the speed infdicated by a DEV. The figure must be rotating if tangential quality is desired, otherwise, figure will be oriented along path just as it was originally. The figure also shrinks as it mpves into the Z axis.
EXAMPLE:

PATHMOV BFLY,TSINE,DO
PENOFF
PENOFF turns the light pen off.
PENSEN LNAME
PENSEN makes a LNAME sensitive to light pen hits, and turns off the previou PENSEN assignment. Only one LNAME may be PENSEN;d at a time.
EXAMPLE:
 PENSEN TARGET
POINTS LNAME
POINTS changes LNAME's vectors to display only the endpoints.
EXAMPLE:

POINTS MOREY
PRINT DNAME.EXT[30,X]
PRINT is the same as TYPE but it creates hardcopy on the Decwriter instead of display on the VT05. PRINT runs as a subjob and cannot be easily stopped.
EXAMPLE:

PRINT DRAW.MAC
PRINT WITCH.DEC[30,1]
PUTDSK DNAME.EXT
PUTDSK puts DNAME out to your area on the disk in the format indicated by the extension.
EXTENSIONS
.BIN  BINARY
.DEC  DECIMAL (default)
.MAC  MACRO
.VGN  Vector General Format
.BIN preserves device assigbments and other motion information the others do not. ,VGN and .BON may be used with any LNAME. .DEC may only be used with 3-D non-shaded data. You cannot write on anyone else's area.
EXAMPLE:

PUTDSK DRAW.MAC
PUTDSK WITCH.VGN
PUTDSK BLOD.BIN
PUTDSK GLOBE
PUTDSK WITCH.DEC
PUTLIB PNAME
Puts PNAME into non-displayed data structure. Removes PNAME from higher groups if any. PNAME must be displayed. All commands work on PUTLIB'd pictures except those explicitly stated not to by the command description itself.
EXAMPLE:

PUTLIB OUTLINE
PUTPOIN X,Y,Z,K
PUTPOIN puts a point into the LNAME indicated by an OPENO. X,Y,X are any expressions determining the X, Y, and Z coordinates of the point in decimal (range -2048 to 2047). K indicates the following:
K=0    Draw the  vector
K=1    Move to a new place but do not draw (jump)
K=-1   End of list
Note that (unlike GETPOIN) if K=-1, the last X,Y,Z are ignored (i.e. the last point should be specified:
PUTPOIN 0,0,0,-1
to terminate the list). Also note that the first point automatically is stored as K=1.
EXAMPLE:

PUTPOIN D0/16,D1/16/D2/16,1
PUTPOI A,B,C,0
PUTPOI 0,0,0,-1
This will create a picture with a line drawn from the instantaneous positions of D0,D1, and D2 to the positions of the variables A, B, and C. (The /16 is necessary because dials are read left justified.)
READ DOSDEVICE
READ changes the read device for type and print to the new PDP-11 directory device,
SWITCH:

NONE  For TYPE job
/P    for PRINT job

EXAMPLE:

READ/P DF
PRINT GRASS.MAP[30,4]
REMARK *ANY TEXT YOU ANY FOR COMMENTS UNTIL A DELIMITER IS SEEN*
The first character after the command is taken as a delimiter and all the following text until the delimiter is seen again is taken as comments. REMARK is useful for documenting macros.
EXAMPLE:

REMARK %THIS MACRO MAKES FLIES FLY
       ON DIAL 0, AND THE JOYSTICK
 %
RENAME ANAME1,ANAME2
RENAME replaces ANAME1 with ANAME2 in the NAME table. It is useful if a NAME has to be changed to bring another copy of a core resident picture into core, or to PUTDSK a modified picture whose name is already on the disk.

SWITCHES
NONE  As above
/D    Renames disk file on your area

EXAMPLE:

GETDSK WITCH
RENAME WITCH,OLDLADY
GETDSK WITCH
   Now there are tw copies of WITCH in memory
RENAME/D WITCH.DEC,LADY.DEC
   WITCH.DEC is now called LADY.DEC on the disk
RESTART
RESTART re-initializes the entire GRASS system.
RESUME
Used only to return from VT05 input mode to a macro in execution or to a FS15-interrupted GETDSK.
EXAMPLE:

*GETDSK GLOBE
      (PUSH FS15)
*ROTATE GLOBE,X,D0
*RESUME
      (FINISH GETDSK)
      *...ETC
Also see WAIT which is used for getting VT05 input when in a macro.
ROTATE PNAME,AXIS,SPEED,TILT,ORIGIN
ROTATE takes the PNAME and rotates it according to the axis (must be indicated as "X", "Y", or "Z") at the speed (or with /P, the angle) indicated by a DEV. If included, the TILT modifies the axis according to the setting of a DEV. If included, ORIGIN takes DEV, DEV+1, and DEV+2 for the origin of the axis of rotation.
SWITCHES
   NONE  FAST ROTATION
   /S    SLOW ROTATION
   /D    DEV indicates angle of rotation instead of speed.
   
EXAMPLE:
ROTATE PROP,X,D9
ROT/S GLOBE,A
ROT/D CUBE,Z,D8
ROTATE GLOBE,X,D0,D1
ROTATE BLADE,Z,D0,D1,D2
ROTATE SAM,X,D0,D1,A
ROTATE/D FRED,K,L,P
SCALE PNAME,FACTOR
Scales PNAME by factor indicated by a DEV
SWITCHES:
     NONE   Uses hardware scale which scales 10 PICTURE's 0,0,0
     /X     Scales along X axis (single dimension scaling)
     /Y     Scales along Y axis
     /Z     Scales along Z axis
     /A     Single dimensional scaling pn DEV, DEV+1 and DEV+2
Scaling with switches also allows the origib or scale to be reset by using SETORG command
EXAMPLE:
SCALE TON,D9
SCALE/X NOSE.D9
SCALE/A SPIRAL,J
The last line takes J for X scale, K for Y scale and L for Z scale.
SETCUT PNAME,VALUE
SETCUT sets the CUTOFF plane according to the value specified by a DEV. If DEV is set to be slightly negative, then varying the intensity set by SETINT will move the CUTOFF plane with respect to the Z-axis.
EXAMPLE:
SETCUT GLOBE,D8
SETDELA DELAY
The delay, indicated by a DEV, is used to slow down GETDSK for .DEC and .VGN modes. SETDFLA remains set for the rest of your session or until reset, for example by
A=0
SETDLA A
EXAMPLE:

SETDLA D0
SETINT PNAME,VALUE
SETINT sets the intensity of the PNAME as indicated by the DEV used for VALUE.
SWITCHES
   NONE   Changes intensity for entire frame
   /S     For use with 3-D shaded effects only
          FS13 is used to go from surface to surface,
          setting the intensity on the DEV indicated.
          
EXAMPLE:
SETINT GLOBE,D0
SETINT/S CUBE,D9
SHADE OUTLINE,SHADE-LINES,SPACING,DEGREES
SHADE has many options. The outline is always a 3-D data LNAME (which should be planar for the expected effect). Shade lines are built in a new LNAME according to the SWITCH indicated. Spacing is an expression which controls how far the lines are spaced apart (3 is the default). DEGREES indicates the angle of the shading lines (/P, /N, /M and /4 modes only)
SWITCHES
    NONE   2-D auto-increment shading. Very economical for filling
          convex areas drawn in X-Y plane only. (One word per vector.)
    /P    Parallel 2-D shading. Better quality shading than 
          auto-increment mode. (Two words per vector.)
    /M    2-D auto-increment shading which observes jumps (e.g.
          it will shase a donut correctly whereas NO-SWITCH mode
          will not). (one word per vector plus jumps.)
    /N    Parallel /M mode (two words per vector plus jumps)
    /3    3-D shading which leaves outline visible Includes
          hidden surface and intensity information (3 
          words per vector) All three-dimensions shading
          requires closed surfaces in a plane with the endpoints
          repeated in the case of adjacent planes. If hidden
          surface effect is desired in the convex case, surfaces
          must be specified in a counter-clockwise order as  the
          object is rotated into view.
    /4    Like /3 except that the outline is removed.
    /5    Optimized /3. This is the one normally used.
    /6    OPtimized /4.
    
EXAMPLE:
SHADE/5 WITCH,OLDLADY
SHADE/P BOX,PLANE,10,45
SHADE BLOB,NEWBLOB,17
SKIP EXPRESSION
SKIP is used to transfer control within a macro for looping expression must evaluate to a number. If negative, skips backwards that number of lines. If positive control skips forward that number of lines. Numbrs larger than possible within the macro will result in transfer to the first stement of the program if negative, or past the last (and this effectively a return) if positive.
EXAMPLE:
<X=X+1
PROMPT X
IF FS1=0, SKIP -2>
This example will increment X and print it until FS1 is pushed.
SMOOTH LNAME,NUMBER
SMOOTH uses a modified quadratic smoothing technique to smooth the 3-D LNAME the number of times indicated by an expression
EXAMPLE:

SMOOTH PATH,7
SMOOTH GLOBE,11/8-A*D0
SOFTROT LNAME
SOFTROT takes the various hardware modifications to the LNAME (specifically rotation, moving, and scaling) and software alters the display list to give actual vectors representing these changes. SOFTROT then does a reset to halt further hardware rotation, moving, scaling, until the user re-rotates, etc. (If he does). A PUTDSK would then put the transformed list onto the disk. Too many SOFTROT's will slowly destroy the picture due to roundoff errors.
EXAMPLE:

ROT GLOBE,Y,D0
SCALE GLOBE,D1
SOFTROT GLOBE
TEXT CNAME,LNAME + ONE LINE OF TEXT EXCLUDING "<" AND ">"
TEXT automatically calls the character set CNAME into core and if necessary creates an LNAME consisting of character subroutine calls. Do not delete the CNAME. Otherwise the LNAME will instantly cause the system to crash. Each LNAME represents one and only one line of text. The available character sets are as follows:
ROM2    Double line Roman font (upper and lower, complete punctuation)
SCR     Single line script font (Upper and Lower)
SCR2    Double line script font (Upper and Lower)
MAP     Selected MAP symbols
ITALL   Lower case Italian Gothic font
ITALU   Upper case Italian Gothic font
ENGL    Lower case English Gothic font
ENGU    Upper case Englisj Gothic font
RUSL    Lower case Cyrillic font
RUSU    Upper case Cyrillic font
To indicate lower case in character sets with both upper and lower case. you must type a "^" before each lower case character to be used. A double "^^" is used as a shift lock. If "^^" is used, "\" must be used to indicate an upper case letter "\\" will shift lock to upper case again
EXAMPLE:
TEXT ITALL,TOM
THIS IS AN EXAMPLE
TEXT SCR2,SAM
G^^RAPHICS\\SYMBIOSIS\\SYSTEM
Note that spaces must be entered as upper case characters. Punctuation in those sets where available is indicated by the same punctuation character being typed. MAP and RUSU/RUSL have special correspondances available from the systems programmers.
TREE
TREE gives the user a diagram of his data structure. It lists the picture and groups in the displayed structure by name, indicating groupong levels and hierarchies by tabs. TREE also checks out the data structure and informs the user by an error message if his data structure contains improper groups (groups across levels, for instance) which would cause problems if compound transformations were applied. If the error message is seen, the user should PUTLIB all his pictures and then GETLIB them one by one. Grouping where necessary, and checking the integrity of the structure by using TREE periodically.
TYPE DNAME.EXT[30,X]
TYPE types the DNAME from the area indicated by "[30,X]". The DNAME is typed on the VT05 and may be aborted by typing "^C". If no "[30,X]" is indicated, the default is to your area.
EXAMPLE:

TYPE DRAW.MAC
TYPW WITCH.DEC
UNFILM
Resets to normal run mode after filming was used. ("U" is enough to trigger this command.)
WAIT
WAIT causes the macro to wait for the user to type on the VT05. It inhibits the execution of the macro until the user types "RESUM". WAIT is useful for interaction with the user during the use of a long macro.
EXAMPLE:
<....
PROMPT  "TYPE HELP FOLLOWED BY THE COMMAND NAME"
PROMPT  "IF THERE IS A COMMAND THAT YOU DO NOT GROK. "
PROMPT  "TYPE RESUME WHEN YOU WISH TO CONTINUE WITH THIS "
PROMPT  "SELF-HELP MACRO "
WAIT
....>
WARP LNAME,DEV1,DEV2
WARP changes the shape of line segments according to the position of the DEV's. WARP is much easier to use if the WARP macro is used. This macro gets a cursor, sets the dials for moving the cursor and allows the user to switch WARP modes. The LNAME must not be in motion or be scaled (if it is, use SOFTROT). The WARP macro overlay is fairly self-explanatory.
SWITCHES:
     NONE  Warps line but preserves endpoints
     /P    Warps line between chosen points (use WARP macro)
     /M    Translates part of picture between jumps to cursor position.

EXAMPLE:

USE WARP MACRO
WRITE DOSDEVICE
WRITE is the same as READ except that it changes the PUTDSK device.
COMPILE MNAME1,MNAME2
COMPILE resolves %LABEL pseudo-labels in MNAME1. If a macro has pseudo-labels, COMPILE must be used to eliminate the task of counting lines for SKIP arguments in long macros. MNAME1 is auto-deleted if MNAME1 is called from disk, or PUTDSK'd before it is compiled. It must have the extension .MCS.
EXAMPLE:

GLOB:<IF FS1, SKIP %FLUFF
SKIP -1
%FLUFF:DIRCOR>
COMPIL GLOB,CGLOB
  CGLOB now looks like
CGLOB:<IF FS1,SKIP 2
SKIP -1
DIRCOR>
GLOB is aito-deleted and CGLOB can be executed

B. SYSTEM CONFIGURATION

Computer: 

     PDP-11/45 
     48K Memory, 16K MOS, 32K Core 
     RF and RK Disk and Cartridge Drives 
     Dual DECtape Drives 
     Paper Tape Punch and Reader 
     DECwriter and VT05 

Graphics Equipment: 
     Vector General 3-D Rotation Display 
     With Joystick, Ten Dials, Function Switches, Light Pen, and 
     
     Analog Hardware for Rotation, Scaling, Intensity, 
     Translation, Depth Cueiug and Z-Axis Cutoff. 
     
     Scientific Accessories Corporation 3-D Graf-Pen. 
     Arriflex 16mm Motion Picture Camera with Animation Motors. 

C. PROGRAM EXAMPLES

This Appendix gives several examples of usage of GRASS. Ten macros which represent a range of capabilities are reproduced here. In several cases, the user interaction with the macro at run-time is given in addition to the text of the macro. Most of the macros have pseudo-labels which are resolved by a one-pass processor command "COMPILE." The examples start with a simple macro and then progress to more complex examples. Appendix A can help in deciphering command syntax if there is difficulty following the code. Remember that names may be abbreviated to just enough letters to insure uniqueness so that "SHADE" is often coded as "SH," for example. The macros will be referenced below as "Macro C-1, Macro C-2,..."

Macro C-1: ROW3

"ROW3" (Macro C-1) is a simple user-written macro that sets up scaling and translation for any two pictures. The user thus has created a command for himself which does six repetitious lines of code in one call and two name responses. This is the type of macro that often makes the system easier to use and can be quickly written and tailored to any users needs. Thus it is a very simple illustration of the use of the system's extensibility to add to the system's habitability.

CLEAR 
PROMP *ROW3 - MOV X,Y SC X,Y SC BOTH*
PROMP *FIRST FEATURE: *;
INPUT $A
PROMP *SECOND FEATURE: *;
INPUT $B
MOV $A D0
SC/R $A,D2
SC $B,D4
MOV $B,D5
SCALE/A $B,D7
SCALE $B,D9
DELETE ROW3
*

Macro C-2: WARP

"WARP" (Macro C-2) is a macro which aids usage of the "WARP" command. It calls in a cursor whose motion is set to correspond to the location of the segment to be warped, and lets the user switch between the modes of warping by pushing function switches. It is an example of how the use of a complex primitive command is made easier and more flexible by embedding it in a macro. A picture of the function switches and overlay used with this macro is also included.

CLEAR 
PROMP *WARP - 3 OPTIONS - USE GRASS OVERLAY (4*
PROMP *CURSOR IS ON D8,D9*
PROMP *WHAT IS TO BE WARPED *;
INPUT $A
FSOFF 0,1,2,9
SOFT $A
GETC CURSOR
MOV CURSOR,D8
%LOOP IF FS0 EQ 1,SKIP %WARPM
IF FS1 EQ 1,SKIP %WARP
IF FS2 EQ 1,SKIP %WARPB
IF FS9 EQ 1,SKIP %EXIT
SKIP %LOOP
%WARPM WARP/M $A,D8,D9
SKIP %LOOP
%WARP WARP $A,D8,D9
SKIP %LOOP
$WARPB WARP/B $A,D8,D9
SKIP %LOOP
%EXIT DELETE CURSOR
DELETE WARP
*
The function switch assignments for the "WARP" macro. It is capable of producing a wide range of linear distortions and translations of figures.

Macro C-3: THICKR

"THICKR" (Macro C-3) is a data generation macro. It uses "GETPOIN/PUTPOIN" sequences to modify x,y,z coordinates as the user specifies. This macro illustrates a procedure which would simply be too time consuming and tedious to do without macros. An example of the output of "THICKR" can be seen in Figure 7. In the example of user interaction following the macro, system typed output is underlined. The user need only type the words and numbers that are not underlined. The core directory commands ("DIRC") show the size of the "BUNNY" in words before and after the use of "THICKR."

CLEAR 
REM *
(IDENTIFICATION GRSUTL--09-V01)

G.D. MOERSDORF

2D  TO 3D IMAGE PROJECTOR
*
PROMP *THICKR--2D THICKNESS UTILITY*
PROMP *ENTER THE FOLLOWING*
PROMP *PICTURE TO BE THICKENED *;
INPUT $A
GETPOI $A,1,Y,Y,Y,Y
Q=0
PROMP *NUMBER OF PROJECTIONS *;
INPUT I
J=I
PROMP *IMAGE SPACING *;
INPUT S
PROMP *X SKEW MAGNITUDE *;
INPUT O
PROMP *Y SKEQ MAGNITUDE *;
INPUT P
OPENO THKTMP
T=0
W=0
D=0
N=1
%LOOP1 GETPOI $A,N,X,Y,Z,K
IF K NE -1,SKIP %NOSET
Q=-1
K=0
%NOSET PUTPOI X+T,Y+D,Z+W,K
N=N+1
IF Q NE -1,SKIP %LOOP1
T=T+O
W=W+S
D=D+P
I=I-1
Q=0
V=N
N=1
IF I GT 0,SKIP %LOOP1
PROMP V*J,* VECTORS TOTAL*
PROMP *FINAL X=*,X+T-O,*, FINAL Y=*,Y+D-P,*, FINAL Z=*,Z+W-S
PUTPOI 0,0,0,-1
DELETE $A
RENAME THKTMP,$A
PROMP *NO ERRORS DETECTED*
DELETE THICKR
*

THICKR Execution Listing

*LOG 30,4
PASSWORD; NICE
. . .
WELCOME TO PDP-11 GRASS
*GETC BUNNY
*DIRC
CORE DIRECTORY
. . .
PICTURE SIZE     FLAGS
BUNNY   768      PX
. . .
768. WORDS USED IN 1. PICTURES  
10592. WORDS FREE IN 4. FRAGMENTS  
*CALL THICKR
THICKR--2D THICKNESS UTILITY
ENTER THE FOLLOWING:
PICTURE TO BE THICKENED ?BUNNY
NUMBER OF PROJECTIONS ?5
IMAGE SPACING ?120
X SKEW MAGNITUDE ?100
Y SKEQ MAGNITUDE ?0
1105 VECTORS TOTAL
FINAL X=230. FINAL Y-730. FINAL Z=480.
NO ERRORS DETECTED
*DIRC
CORE DIRECTORY
. . .
PICTURE SIZE     FLAGS
BUNNY   3616     PX
3616. WORDS USED IN 1. PICTURES
7744. WORDS USED IN 4. FRAGMENTS
. . .

Macro C-4: DBLPOI

"DBLPOI" (Macro C-4) is a simple data manipulation macro written by an art student. It is included here to document the ease of writing useful macros. "DBLPOI" places a point in the middle of every line segment in the drawing and thus doubles the original number of points. This macro is used to saturate a path to make the path following motion smoother if necessary, and also to create more points if "WARP" must be used on a long line segment. Variations like tripling the number of points or selectively placing the points in the middle of selected line segments can be done within a similar framework with more code.

CLEAR 
REM *DOUBLE POINT MACRO--TIM LIPETZ*
PROM *DBLPOI DOUBLES NUMBER OF POINTS IN  FIGURE*
PROM *ENTER NAME OF FIGURE*
INPUT $A
PROM *ENTER NEW NAME*
INPUT $B
OPENO $B
N=0
%INCRN N=N+1
REM /GET THE FIRST POINT OF PAIR/
GETPOI $A,N,A,B,C,K
REM/OUTPUT THIS POINT/
PUTPOI A,B,C,K
REM/GET THE SECOND POINT OF PAIR/
GETPOI $A,N+1,D,E,F,L
REM /CHECK  IF END OF DATA (-1) OR BLANKED LINE (1)/
IF L= -1, SKIP %EXIT
IF L=0, SKIP %G
REM /IF BLANKED LINE, GET NEXT POINT/
GETPOI $A,N+2,S,T,U,V
IF V=-1,  SKIP %G
SKIP %INCRN
%G G=A+D
H=B+E
I=C+F
PUTPOI G/2,H/2,I/2,0
SKIP %INCRN
%EXIT PUTPOI 0,0,0,-1
*

Macro C-5: MERGE

"MERGE" (Macro C-5) allows users to concatenate data lists and thereby build up pictures from simpler elements. If the simpler elements never need to be individually manipulated, this procedure is more efficient than grouping the elements. An example of user interaction with "MERGE" is given after the macro. Note the use of a computed "SKIP" which allows the correct ordinal suffix to be attached to the printout.

CLEAR 
REM *
(IDENTIFICATION GRSUTL-101-V01)

. . . THIS PROGRAM MERGES INCORE PICTURES
*
REM /GET THE NAME OF  THE PICTURE TO MERGE ALL THE OTHERS INTO/
PROMP *ENTER THE NAME OF THE OUTPUT PICTURE *;
INPUT $A
REM /OPENTHAT NAME DYNAMICALLY/
OPEN0 $A
REM/'F' IS THE NUMBER OF FILES MERGED SO DAR/
F=1
REM /THIS NEXT ROUTINE DECIDES WHAT CONSTRUCTION TO USE ON
        THE PRINTOUT FOR THE NUMBER OF EACH FILE THE USER IS NOW MERGING
        THIS DEMONSTRATES THE  USE OF THE 'SKIP' INSTRUCTION
        AS A FORTRAN-LIKE COMPUTED GOTO STATEMENT./
%LOOP1 PROMP *ENTER THE *,F;
S=F
REM /IF HE IS MERGING THE FOURTH FILE PR GREATER THE CONTRACTION
        IS 'TH./
IF S GR 4, S=4
S=S*2
S=S-1
SKIP S
PROMP *'ST*;
SKIP %CONT
PROMP *'ND*;
SKIP %CONT
PROMP *'RD*;
SKIP %CONT
PROMP *'TH*;
%CONT PROMP * FILE TO BE MERGED *'
REM /ASK FOR THE NEXT PICTURE TO MERGE/
INPUT $B
N=1
T=0
REM /THIS LOOP COPIES THE CURRENT PICTURE TO BE MERGED
      INTO THE OUTER PICTURE/
%LOOP3 GETPOI $B,N,X,Y,Z,K
IF K NE -1,SKIP %NOSET
T=1
K=0
%NOSET PUTPOI X,Y,Z,K
N=N+1
IF T NE 1,SKIP %LOOP3
F=F+1
REM/COME HERE WHEN CURRENT PICTURE IS COPIED INTO OUTPUT PICTURE
      AND SEE IF THE USER HAS MORE TO MERGE/
PROMP *ANOTHER FILE (1=YES, ELSE NO) *;
INPUT M
IF M EQ 1, SKIP %LOOP1
REM/COME HERE WHEN THE USER SAYS THAT HE IS DONE/
PUTPOI 0,0,0,-1
PROMP $A,* IS THE NEW FILE*
PROMP *NO ERRORS DETECTED*
REM /DELETE THE MACRO ITSELF/
DELETE MERGE
EXIT

MERGE Execution Listing

*LOG 
O.S.U. COMPUTER GRAPHICS *PRODUCTION*01-FEB-73 GRASS VIR
*30,4
PASSWORD; NICE
. . .
WELCOME TO PDP-11 GRASS
*GETC PROP
*GETC ROBIN
*GETD SBOD
*GETD SWING1
*GETD SWING2
*CALL MERGE
ENTER THE NAME OF THE OUTPUT PICTURE?BIGER
ENTER THE 1.'ST FILE  TO BE MERGED ?PROP
ANOTHER FILE (1=YES? ELSE NO) ?1
ENTER THE 2.'ND FILE  TO BE MERGED ?ROBIN
ANOTHER FILE (1=YES? ELSE NO) ?1
ENTER THE 3.'RD FILE  TO BE MERGED ?SBOD
ANOTHER FILE (1=YES? ELSE NO) ?1
ENTER THE 4.'TH FILE  TO BE MERGED ?SWING1
ANOTHER FILE (1=YES? ELSE NO) ?1
ENTER THE 5.'TH FILE  TO BE MERGED ?SWING2
ANOTHER FILE (1=YES? ELSE NO) ?5
BIGER IS THE NEW FILE
NO ERRORS DETECTED
*C
*

Macro C-6: LPDRAW

"LPDRAW" (Macro C-6) is a sophisticated macro which allows the user to draw with the lightpen. It operates sufficiently fast to keep ahead of the user - in other words, the user is not aware of the time it takes to process and record a point. "JSDRAW" and "SODRAW" are similar macros not shown here which permit drawing with the joystick and sonic pen respectively. To delete points, "LPDRAW" calls an external. macro "JSDDEL" which is common to all the drawing macros. Note that all the space taken up by the code and tracking cross is reclaimed by the "DELETE's" at the end. Several new commands were added ("GEIHIT", "PENSEN", etc.) as well as a new "IF" condition: "IF LP." These additions can be used in other macros that could make use of lightpen input for data identification and manipulation, for example.

CLEAR 
REM *
(IDENTIFICATION GRSUTL-99-V01)
G.B.MOERSDORF 25-JAN-72
*
GETDSK JSDDEL MAC[31,3]
GETCOM LPCURS
POINTS LPCURS
PENSEN LPCURS
FSOFF 1,2,3,4,5,6,7,8,9,10,11,12,13,14
PROMP *LPDRAW-- LIGHT PEN DRAW UTILITY --USE OVERLAY #3*
X=0
Y=0
Z=0
MOVE LPCURS,X
PROMP @WHAT IS THE DRAWING'S NAME *;
INPUT $A
OPENO $A
S=16
R=17
K=0
N=0
O=0
P=9
XLOOP1 IF FS1 EQ 1,K=1
IF FS2 EQ 1, SKIP %BAND
IF FS3 EQ 1, SKIP %DEL
IF FS4 EQ 1, SKIP %LKX
IF FS5 EQ 1, SKIP %LKY
IF FS6 EQ 1, SKIP %LKZ
IF FS7 EQ 1, SKIP %XEXIT
IF LP,SKIP %HIT
SKIP %LOOP1
%HIT GETHIT D,A,B,C,D
A=A*S
B=B*S
C=C*S
IF N EQ 0,X=X+A
IF O EQ 0,Y=Y+B
IF P EQ 0,Z=Z+C
IF FS0 NE 1,SKIP %LOOP1
PUTPOI X/S,Y/S,Z/S,K
FSOFF 1
K=0
J=D0
J=J+32768
J=J/2
%LOOP2 J=J-200
IF J GT 0,SKIP %LOOP2
FSOFF 0
SKIP %LOOP1
%DEL DELPOI
DO JSDDEL
FSOFF 3
SKIP %LOOP1
%LKX IF N EQ o SKIP %SETX
N=0
FSOFF 12
%OUTX DO JSDDEL
FSOFF 4
SKIP %LOOP1
%SETX N=1
FSON 12
SKIP %OUTX
%LKY IF O EQ 0, SKIP %SETY
O=0
FSOFF 13
%OUTY DO JSDDEL
FSOFF 5
SKIP %LOOP1
%SETY O=1
FSON 13
SKIP %OUTY
%LKZ IF P EQ 0, SKIP %SETZ
P-0
FSOFF 14
%OUTZ DO JSDDEL
FSOFF 6
SKIP %LOOP1
%SETZ P=1
FSON 14
SKIP %OUTZ
%BAND IF LP,SKIP %BHIT
SKIP %BAND
%BHIT GETHIT D,A,B,C,D
A=A*S
B=B*S
C=C*S
IF N EQ 0, X=X+A
IF O EQ 0, Y=Y+B
IF P EQ 0, Z-Z+C
PUTPOI X/S,Y/S,Z/S,K
FSOFF 2
L=R
%LOOP3 L-L-1
IF L NE 0,SKIP %LOOP3
IF FS2 NE 1,SKIP %LOOP1
DELPOI
SKIP %BAND
%EXIT PUTPOI 0,0,0,-1
PROMP $A,* CREATED*
FSOFF 0,1,2,3,4,5,6,7,8,9,19,11,12,13,14
DELETE LPCURS
DELETE JSDDEL
DELETE LPDRAW
EXIT

Macro C-7: SWDEMO

"SDEMO" (Macro C-7) is one of several demonstration macros. It sets up the wing flapping for the shaded swallow image that is found in several of the photographs. The last section of code aids the user in coordinating the flapping of the two wings together. Use of the panic button is also shown. Note how confusing the "SKIP's" can become even in a simple case when pseudo-labels are not used.

PROM *SWALLOW FLYING MACRO*
GETD SBOD.DEC[30,4] 
SH/3 SD,SSBOD
GETD SSW1.BIN[30,4]
GETD SSW2.BIN[30,4]
GETL SSW1
GETL SSW2
DEL SBOD
GROUP SSBOD,SSW2,BIRD
ROT/D BIRD,Y,D1
A=-32767
B-32752
C=1296
D=0
E=15000
ROT SSW1,Y,D0,A,B,C
ROT SSW2,Y,D0,A,B
FLAP SSW1,0,0
FLAP SSW2,0,0
PROM *FLAP SPEED ON D0*
PROM *BIRD ROT/D ON D1*
FLAP SSW1,-E,E
PROM *PUSH FS1 TO START OTHER WING FLAPPING*
A=A
IF FS1=0, SKIP -1
FLAP SSW2,-E,E
PROM *IF FLAPPING INCORRECT, PUSH FS1 TO STOP WING*
PROM *WAIT FOR WING TO SETTLE*
PROM *THEN PUSH FS2 TO START WING FLAPPING AGAIN*
PROM *REPEAT IF NECESSARY*
PROM *EXIT WITH PANIC BUTTON PUSH  WHEN OK*
FSOFF 1,2
IF FS1, SKIP 3
IF FS2, SKIP 5
SKIP -2
FLAP SSW2,0,0
FSOFF 1
SKIP -4
FLAP SSW2,-E,E
SKIP -8
*

Macro C-8: TRASCL

"TRASCL" (Macro C-8) allows the user to software scale his data by integral factors. Combining this macro with hardware scale give a facility whereby any picture may be transformed to any size. In addition, a software translate may be indicated with this macro. The example of user interaction following this macro shows doubling of the x and y coordinates and tripling of the z coordinates, and a y--translation of 500 raster units (approximately two inches).

CLEAR 
REM *
(IDENTIFICATION GRSUTL-001-V01)
G.B.MOERSDORF 
   THIS PROGRAM SCALES DATA UP VIA SOFTWARE
*
PROMP *TRASCL--SOFTWARE SCALE/TRANSLATE UTILITY*
PROMP *ENTER THE PICTURE TO BE WORKED ON *;
INPUT $A
O=0
REM / THIS NEXT LINE IS TO SEE IF WHAT HE TYPED IS IN CORE AND
IF IT IS NOT IT WILL DIE AND HE NEED NOT ENTER ANY MORE DATA/
GETPOI $A,1,F,F,F,F
PROMP *ENTER 'X' SCALE FACTOR *;
INPUT A
PROMP *ENTER 'Y' SCALE FACTOR *;
INPUT B
PROMP *ENTER 'Z' SCALE FACTOR *;
INPUT C
PROMP *ENTER 'X' SCALE FACTOR *;
INPUT D
PROMP *ENTER 'Y' SCALE FACTOR *;
INPUT E
PROMP *ENTER 'Z' SCALE FACTOR *;
INPUT F
OPENO.TRATMP
N=1
%LOOP GETPOI $A,N,X,Y,Z,K
IF K NE -1,SKIP %NOSET
K=0
O=-1
%NOSET X=X*A+D
Y=Y*B+E
Z=Z*C+F
PUTPOI X,Y,Z,K
N=N+1
IF 0 NE -1,SKIP %LOOP
PUTPOI 0,0,0,-1
DELETE $A
RENAME TRATMP,$A
PROMP *OUTPUT PICTUE *,$A,* NOW HAS *,N,* VECTORS*
DELETE TRASCL
*

TRASCL Execution Listing

*LOG 
O.S.U. COMPUTER GRAPHICS *PRODUCTION VERSION*01-FEB-73 GRASS VIR
*30,4
PASSWORD; NICE
. . .
WELCOME TO PDP-11 GRASS
*GETC WITCH
*CALL TRASCL
TRASCL--SOFTWARE SCALE/TRANSLATE UTILITY
ENTER THE  PICTURE TO BE WORKED ON?WITCH
ENTER 'X' SCALE FACTOR ?2
ENTER 'Y' SCALE FACTOR ?2
ENTER 'Z' SCALE FACTOR ?3
ENTER 'X' TRANSLATE FACTOR ?0
ENTER 'Y' TRANSLATE FACTOR ?500
ENTER 'Z' TRANSLATE FACTOR ?0
OUTPUT PICTURE WITCH NOW HAS 175 VECTORS
*DIRC
CORE DIRECTORY
. . .
PICTURE SIZE     FLAGS
WITCH   600      PX
608. WORDS USED IN 1. PICTURES
10752. WORDS USED IN 4. FRAGMENTS
*

Macro C-9: REFLEC

"REFLEC" (Macro C-9) is a macro which will reflect the image around the specified axis or axes and concatenate this reflection with the original. It is particularly useful in the case of symmetric figures for which the artist need only digitize or draw one-half of the data, using "REFLEC" to get the whole image. If the data is symmetric to more than one axis, this macro may be used to build a figure from one fourth or even one eighth of the intended image.

CLEAR 
O=0
REM *
(IDENTIFICATION GRSUTL-002-V01)
     THIS PROGRAM DEMONSTRATES SOME FOF THE NUMERIC CONTROL
     AND DYNAMIC CREATION COMMANDS
     
     THIS PROGRAM INVERTS ANY OR ALL OF THE THREE AXES
OF A FILE SO AN ARTIST W HO HAS SYNTHETIC DATA NEED ONLY
DIGITIZE ONE HALF, ONE QUARTER OR ONE EIGHTH OF HIS DATA
DEPENDING ON HOW MANY AXES ARE REFLECTED.

*
PROMP *REFLEC--REFLECTION UTILITY PROGRAM*
PROMP *ENTER THE NAME OF THE PICTURE *;
INPUT $A
GETPOI $A,1,F,F,F,F
PROMP *ANSWER THE FOLLOWING, 1=YES, 0=NO*
PROMP *REFLECT 'X' POINTS *;
INPUT A
PROMP *REFLECT 'Y' POINTS *;
INPUT B
PROMP *REFLECT 'Z' POINTS *;
INPUT C
OPENO REFTMP
R=-1
N=1
%LOOP1 GETPOI $A,N,X,Y,Z,K
IF K NE -1, SKIP %NOSET
K=0
O=-1
%NOSET PUTPOI X,Y,Z,K
N=N+1
IF O NE -1,SKIP %LOOP1
REM /NOW THE INVERTED COPY/
O=0
N=1
%LOOP2 GETPOI $A,N,X,Y,Z,K
IF K NE -1 ,SKIP %NOSET2
K-0
O=-1
%NOSET2 IF A GT 0,X=X+R
IF B GT 0, Y=Y+R
IF C GT 0, Z=Z+R
PUTPOI X,Y,Z,K
N=N+1
IF O NE -1,SKIP %LOOP2
PUTPOI 0,0,0,-1
DELETE $A
RENAME REFTMP,$A
PROMP $A, *NOW HAS *,N+2* VECTORS *
DELETE REFLEC
*

Macro C-10: EDITOR

Last is the "EDITOR" (Macro C-10) which illustrates. some of the alphanumeric handling possible in GRASS. The "$A" matching is a variant of the keyboard substring matching which allows matches of any alphanumeric strings in macros, decimal modules or any other alphanumeric data, as well as keyboard input. A search command could easily be added. This macro shows that an editor of fair complexity can be written for the system within the system by adding a few commands which will prove useful for general text manipulation as well.

CLEAR 
REM *
(IDENTIFICATION GRSUTL-105-V01)
G.D. MOERSDORF

THE ONLINE EDITOR
*
PROMP *EDIT V1*
%REDIT PROMP *DISK FILE NAME *,
REM /I EQ THE INSERT INCREMENT/
REM /AND DEFAULTS TO ONE ON STARTUP/
I=1
INPUT $A
PROMP *EXTENSION *,
INPUT $D
IF $D EQ 'MAC',SKIP XS1
IF $D EQ 'MCS',SKIP XS2
IF $D EQ 'PAL',SKIP XS3
IF $D EQ 'DEC',SKIP XS4
PROMP "??CANNOT EDIT THAT FILE TYPE??*
SKIP%REDIT
XS1 OPENED $A. MAC
T=1
SKIP %EDIT
XS2 OPENED $A. MCS
T=3
SKIP %EDIT
XS3 OPENED $A. PAL
T=5
SKIP %EDIT
XS4 OPENED $A. DEC
T=7
%EDIT INPUT $B,N
IF $B EQ 'P', SKIP %PRINT
IF $B EQ 'PRI', SKIP %PRINT
IF $B EQ 'D', SKIP %DELETE
IF $B EQ 'DEL', SKIP %DELETE
IF $B EQ 'I', SKIP %INSERT
IF $B EQ 'INS', SKIP %INSERT
IF $B EQ 'E', SKIP %EXIT
IF $B EQ 'EX1', SKIP %EDIT
IF $B EQ 'S', SKIP %SET
IF $B EQ 'SET', SKIP %SET
IF $B EQ 'R', SKIP %RESEQ
IF $B EQ 'RES', SKIP %RESEQ
IF $B EQ 'L', SKIP %LIST
IF $B EQ 'LIS', SKIP %LIST
IF $B EQ 'T', SKIP %TYPE
IF $B EQ 'TYP', SKIP %TYPE
IF $B EQ 'Z', SKIP %ZAP
IF $B EQ 'ZAP', SKIP %ZAP
PROMP *??UNKNOWN EDITOR COMMAND??*
SKIP %EDIT
%NOLINE PROMP *??LINE SPECIFIED DOES NOT EXIST??*
SKIP %EDIT
REM /NEXT ARE THE INDIVIDUAL COMMAND PROCESSORS -FIRST IS PRINT COMMAND-/
%PRINT IF N EQ 0,N=L
GETLIN N,N
IF N LE 0,SKIP %NOLINE
PROMP N,*        *,$$;
SKIP %EDIT
REM /TYPE PROCESSOR/
%TYPE IF N EQ 0,N=L
PROMP *STOP LINE *,
INPUT S
%TYPE1 GETLIN N,K
IF K EQ -1, SKIP%EDIT
IF K EQ 0,SKIP %NOLINE
PROMP K,*     *,$$;
N=02
IF K LT S,SKIP %TYPE1
SKIP %EDIT
REM/LIST PROCESSOR/
%LIST N=-1
%LIST0 GETLIN M,K
IF K EQ -1,SKIP %LIST99
PROMP/L K,*     *,$$;
M=-2
SKIP %LIST0
%LIST99 PROMP/L
PROMP/L
PROMP/L
SKIP %EDIT
REM /DELETE PROCESSOR/
%DELETE IF N EQ 0,N=L
DELLIN,N,D
IF D GT 0,SKIP %EDIT
SKIP %NOLINE
REM /SET INCRE PROCESSOR/
%SET IF N LE 0,SKIP %ARGER
I=N
SKIP %EDIT
REM /RESEQ PROCESSOR/
%RESEQ IF N LE 0, SKIP %ARGER
RESEQ N
SKIP %EDIT
REM /INSERT PEOC/
%INSERT IF N EQ 0,N=L
IF N LE 0,SKIP %ARGER
%INSERT1 PROMP N,*     *;
GETDUF K
IF K EQ -1,SKIP %EDIT
INSLIN N,K
L=N
N=N+I
IF K EQ 0,SKIP %INSERT1
IF K EQ -2,SKIP %NOCOR
PROMP *??LINE ALREADY EXISTS - DELETE FIRST -??*
SKIP %EDIT
%NOCOR PROMP *??NO MORE ROOM TO ADD LINES>>*
SKIP %EDIT
REM /ZAP (DELETE SEQUENCE OF NUMBERS) PROCESSOR /
%ZAP PROMP *STOP LINE *;
INPUT S
D=N
%ZAP1 DELLIN N,K
IF K LE 0,SKIP %NOLINE
N=-2
IF K LE S,SKIP %ZAP1
L=D
SKIP %EDIT
REM /EXIT PROC/
%EXIT SKIP T
DELETE/D $A.MAC
SKIP %STORE
DELETE/D $A.MCS
SKIP %STORE
DELETE/D $A.PAL
SKIP %STORE
DELETE/D $A.DEC
%STORE SKIP T
CLOSEDT $A.MAC
SKIP %EDIOUT
CLOSEDT $A.MCS
SKIP %EDIOUT
CLOSEDT $A.DEC
%EDIOUT PROMP *FILE *,$A,* UPDATED AND CLOSED*
IF N EQ 0,SKIP %REDIT
EXIT