SilverScreen API Reference

Table of Contents

Introduction

The SilverScreen API
About This Document
Document Conventions
Distributed Include Files

Script Commands

Introduction
Command System
Application Programs and Commands
Using ss_command
A Short Example
C-Space Coordinates
C-Space Coordinates: An Example
Command Formats

Drawing Hierarchy

Introduction
Direct Structure Access
Entity Structures
Primitive Structures
Edges and Vertices
Entity Paths
Primitive Paths
Groups and Wildcards
Tags
E-Space, Base, Axis and Extents
Visibility

Application-Oriented Commands

Object-oriented 2D Boolean Commands
Commands to Control Screen Refresh
Schema and Attribute Commands
Printing Commands
     The PRINT Command
     The PAGE Command
     Legacy Printing Commands
Annotation
     Commands for Setting the Detailing Environment
     Commands for Inserting Details
     Commands for Reinserting Details
Interactive Drawing Commands
Miscellaneous Commands
     CURSOR commands
     ID RESET command
     COPY commands
     E-SPACE commands
     RELOCATE commands
     NOTE command
     The WAIT command
     The TEXT-EDIT command

Tools and Techniques

Panel Menus
Generic Data Sets
SilverScreen Transformation Matrices
Colors and RGB
Icons
Custom Menus
Control Variables
System Variables
V-EDIT Command
Multi-Language Applications: Tfiles
Keyboard and Pointer
Executable Libraries
Direct Pointer Variables
Copy Protection
B-tree Databases
Quick Advice

 

 

Introduction

The SilverScreen API

The SilverScreen API is the common set of functions used to develop applications with SilverScreen Solid Modeling technologies. The modeling software supports three platforms:

  • SilverEngine
  • SilverPlus
  • SilverC

Each of these platforms has available the full functionality of the SilverScreen Solid Modeler.  This functionality includes:

  • Open architecture drawing database
  • Data input panels
  • B-tree database facilities
  • Solid modeling
  • Rendering with multiple light sources and shadows
  • OpenGL rendering
  • Import and export of IGES, DXF, and STL
  • Import and export of a variety of image formats
  • Sweeping -- linear, circular, spiral and joining
  • Hierarchical drawing structures
  • Multiple windows of arbitrary configuration
  • Different drawings in different windows
  • Multiple screens
  • Multiple reference drawings
  • Inter-drawing copy
  • Shaded and hidden surface printer output
  • Mass properties and planar properties
  • ASME Y14.5 3D dimensioning
  • Mass properties dimensioning
  • Support for TrueType fonts
  • External and internal model libraries

In this manual, we assume some familiarity with the C/C++ languages and SilverScreen operation, plus some understanding of 3D concepts. For more complete coverage of SilverScreen, see the SilverScreen Reference Manual.

About This Document

This document describes the SilverScreen API, and is divided into several parts:

  • Overview
  • Script Commands
  • Drawing Hierarchy
  • Application-Oriented Commands
  • Tools and Techniques

Document Conventions

Important type styles and conventions used in this document:

  • Groups of text lines, indicating C program source or script command sequences are set off from normal text as follows:

void main( void )
{
ss_command( "note Hello world" );
}

  • C keywords, variable names, C source file names and other C language components embedded in the text are set off as follows: strcpy( msg, "a message" );
  • A row or column of three dots indicates that a part of a program or sequence has been omitted:

...

or:

.
.
.

  • Italicized words denote placeholders for unspecified text; these may be enclosed in less-than/greater-than signs for clarity:

identifier
<bos name>

  • Script commands (or portions thereof) appearing in text are bold-faced:

isolate object arm

  • Sometimes we will describe patterns required for text sequences; we will use a form similar to:

[whitespace][sign][digits][.digits][{e | E}[sign]digits]

where:

whitespace refers to a sequence of space, tab or newline characters
sign refers to a plus sign (
'+') or a minus sign ('-')
digit refers to a decimal digit: '0' through '9'
digits refers to a sequence of decimal digits
The boldfaced characters are literal characters:
E stands for the literal character 'E'
The items enclosed in brackets ([]) are optional.
The items enclosed in braces (
{}) denote a choice among items separated by a vertical bar (|).

  • 3D points, or XYZs are denoted by three values in parentheses, for example, (x, y, z) or (1, 2, 3)

Distributed Include Files

The distribution toolkit includes a number of header files that are used to define various objects used by the SilverScreen developer. There are two types of headers: SilverScreen-specific headers and Standard C compatible headers. The SilverScreen-specific headers are provided specifically for interfacing with SilverScreen-specific functions and structures. The Standard C headers are provided for compatibility with Standard C.

The SilverScreen-specific headers are the following:

silver.h general SilverScreen access
ssnodes.h support for direct access to SilverScreen data structures
sskeys.h keystroke and event types
ssdef.h basic data type definitions

It is of interest to note that SilverScreen shares these exact includes, and hence the same data structures.

SILVER.H -- General SilverScreen Access

SILVER.H contains structures and definitions that are of common use in the SilverScreen API. The file includes the code and bit definitions necessary for identifying primitives and entities. Structures for the load functions (load_variable and load_attribute) also appear in this file. SILVER.H includes SSDEF.H, SSNODES.H and SSKEYS.H, making access to all SilverScreen API functionality a simple matter.

SSNODES.H -- Direct SilverScreen Access

ssnodes.h provides definitions for the SilverScreen internal structures. Descriptions of these structures appears in the section on SilverScreen Internal Structures.

SSKEYS.H -- Input Events

sskeys.h provides definitions for keys and events returned by the predefined SilverScreen functions inchar and nextkey .

SSDEF.H -- Basic SilverScreen Type Definitions

ssdef.h provides basic definitions used commonly in SilverScreen.

 

Script Commands

Introduction

The script command is a primary means of communication between programs and the SilverScreen.  The ss_command function, available in SilverC and C++, sends commands to SilverScreen for processing.  In this section we will describe how the script command fits into the overall structure of the SilverScreen API.

Command System

SilverScreen is a command-based system.  Every activity, interactive or otherwise, is executed by means of a command.  Below is a schematic that shows the relationship between the three systems that operate within interactive SilverScreen.

SilverScreen Command System

Here are the steps that occur in the interactive selection and execution of a command.

  1. The user selects from the SilverScreen menu.  On the basis of this selection, a command is sent to the Interactive System.
  2. The Interactive System interprets the command and requests appropriate information from the user.  Once the user has supplied this information, one or more commands are issued by the Interactive system and sent to the Execution System.
  3. The Execution System interprets and executes the commands.

The commands that are passed from the Menu System to the Interactive System are called icommands (interactive commands).  The commands between the Interactive System and the Execution System are simply called commands.  (The word "command" is often used generically to refer to either a command or an icommand.)

Example:

A user selects Draw Polygon from the menu.  The Menu System issues an icommand which is sent to the Interactive System.  Here is the icommand:

icommand draw polygon common

When the Interactive System receives this command, it prompts the user for a set of polygon points.  Let us assume that the user selects five points.  Then the commands sent by the Interactive System to the Execution System might be as follows:

begin polygon
point 1,1,10
point 1,5,10
point 3,8,10
point 6,10,10
point 10,0,10
end

These commands will cause the Execution System to draw a polygon on the screen and to include the polygon within the drawing database.

Application Programs and Commands

SilverScreen is designed so that the Interactive and Execution Systems are independent of the source of the commands that they process.  That is, these systems do not know whether a command comes from an interactive user or from an application program.

Using the ss_command function, a C++ or SilverC application program can send the icommand

ss_command ("icommand draw polygon common");

The Interactive System will respond to this icommand exactly as if the icommand were sent from the Menu System.   That is, it will prompt the user for a set of points.  After the user has supplied the points, it will then send commands to the Execution System to draw the polygon.

Application programs can also use ss_command to send commands directly to the Execution System.  The following command will rotate a block about the y-axis.

ss_command ( "rotate block \\body w-space angles y%d", degrees );

ss_command function provides the full power of SilverScreen, both at the interactive level and the execution level, available to the application program.

Using ss_command

ss_command is a member of the printf family of functions. It uses formatting descriptors such as %d and %s in the same manner as printf. In additon to the descriptors supported by printf, ss_command also supports one additional descriptor, %z. This descriptor allows for easy formatting of variables of the type SS_XYZ.

The SS_XYZ structure is used to store three-dimensional coordinates. The structure has three components:

SS_XYZ
   {
   double x;
   double y;
   double z;
   };

The %z descriptor requires a pointer to a variable of type SS_XYZ. Let us assume that p1, p2, and p3 contain the coordinates of three points. Then ss_command can be used to draw a triangle as follows:

SS_XYZ p1,p2,p3;
...
ss_command ("begin polygon");
ss_command ("point %z",&p1);
ss_command ("point %z",&p2);
ss_command ("point %z",&p3);
ss_command ("end polygon");

The use of the %z descriptor is equivalent to the use of three comma-separated %.15g descriptors. Without using %z, the above statements can be rewritten as:

ss_command ("point %.15g,%.15g,%.15g",p1.x,p1.y,p1.z);
ss_command ("point %.15g,%.15g,%.15g",p2.x,p2.y,p2.z);
ss_command ("point %.15g,%.15g,%.15g",p3.x,p3.y,p3.z);

A Short Example

The following program begins by opening a drawing with the name machine. The viewing mode is set to perspective, and the drawing is zoomed so that it appears at the center of the screen. The horizonal angle of view is then altered 12 times, each time by 30 degrees. With each change in view, the drawing is rendered and a BMP image is exported. After unloading the drawing, the 12 BMP images are successively displayed on the screen.

   int i;
  
   // Load the drawing
   ss_command ("load drawing machine");
  
   // Set up window view
   ss_command ("cursor disable");
   ss_command ("view project perspective");
   ss_command ("zoom drawing");
  
   // Loop 12 times: hide, save an image, then move view
   for ( i = 1 ; i <= 12 ; ++i )
      {
      ss_command ("hide drawing fill edged gray");
      ss_command
       ("export picture file vw%d.bmp format bmp24 screen",i);
      ss_command ("view modify h-angle absolute %d",i*30);
      }
  
   ss_command ("unload");
  
   for ( i = 1 ; i <= 12 ; ++i )
      ss_command
       ("import picture file vw%d.bmp screen best-fit",i);
  
   ss_command ("cursor enable");

C-Space Coordinates

SilverScreen supports three types of coordinate systems: W-Space (world space), C-Space (construction space), and E-Space (entity space).

The W-Space coordinate system corresponds to the standard Cartesian coordinate system. C-Space refers to a three-dimensional coordinate system that can be oriented anywhere in the world coordinate system. Interactive users frequently use C-Space for their drawing activities. E-Space is a local coordinate system that stored with each entity. When an entity is created, the E-Space of the entity is initialized to the C-Space that is current at the time that the entity is created. When an entity is rotated or moved, the E-Space of the entity is also rotated or moved along with the entity.

There are a number of commands that can be used to define a C-Space. Two of these commands are illustrated below. The first command defines the C-Space according to an origin point and the direction of the x and y axes. The second command aligns the C-Space to the E-Space of a object with the name \room2\wall2.


ss_command ("c-space align axes %z %z %z",&origin,&xaxis,&yaxis);
ss_command ("c-space align e-space object \\room2\\wall2");

In application programs, it is very useful to be able to execute SilverScreen commands relative to C-Space. The following two commands draw lines in W-Space.


SS_XYZ p, q;
...
ss_command ( "draw line 2,3,4 1,1,5" );
ss_command ( "draw line %z %z", &p, &q );

By enclosing the coordinates by square brackets, the points are interpreted to be C-Space points. The first command below will draw a line between C-Space points 2,3,4 and 1,1,5. This is shown below.


SS_XYZ p, q;
...
ss_command ( "draw line [2,3,4] [1,1,5]" );
ss_command ( "draw line [%z] [%z]", &p, &q );

C-Space Coordinates: An Example

The function draw_frame, shown later in this section, draws a frame in C-Space. The frame will be of height h and width w, and will consist of four solid members. The members will be of thickness t and depth d.. Here is a front view of the frame:

The orientation of the frame is determined by the parameters origin, xaxis, and yaxis. The lower left corner of the frame will be constructed at origin. The frame will extend to the right in the direction of xaxis, and will extend upward in the direction of the yaxis.

The draw_frame function begins by aligning the C-Space to the parameters origin, xaxis, and yaxis. Four polygons are then drawn within the object temp. Note that the function draw_polygon draws these points in C-Space. The solids are then created by sweeping all four polygons in a single operation. The direction and depth of the sweep is determined by the C-Space points [0,0,0] and [0,0,d]. This specifies a sweep of distance d along the z-axis of the C-Space.

void draw_frame(double h, double w, double t, double d,
                XYZ *origin, XYZ *xaxis, XYZ *yaxis)
{
XYZ ll,ul,lr,ur;

ss_command ("c-space align axes %z %z %z",origin,xaxis,yaxis);
ss_command ("create object temp");

ll.z = ul.z = lr.z = ur.z = 0.0;

// Draw the lower member
ll.x = ul.x = 0.0;
lr.x = ur.x = w;
ll.y = lr.y = 0.0;
ul.y = ur.y = t;
draw_polygon (&ll,&lr,&ur,&ul);

// Draw the left member
ll.x = ul.x = 0.0;
lr.x = ur.x = t;
ll.y = lr.y = t;
ul.y = ur.y = h-t;
draw_polygon (&ll,&lr,&ur,&ul);

// Draw the right member
ll.x = ul.x = w-t;
lr.x = ur.x = w;
ll.y = lr.y = t;
ul.y = ur.y = h-t;
draw_polygon (&ll,&lr,&ur,&ul);

// Draw the upper member
ll.x = ul.x = 0.0;
lr.x = ur.x = w;
ll.y = lr.y = h-t;
ul.y = ur.y = h;
draw_polygon (&ll,&lr,&ur,&ul);

ss_command ("sweep linear object \\temp points [0,0,0] [0,0,%f] color white fill-color yellow name frame1", t);
}

void draw_polygon (XYZ *p1, XYZ *p2, XYZ *p2, XYZ *p4)
{
ss_command ("begin polygon");
ss_command("point [%z]",p1);
ss_command("point [%z]",p2);
ss_command("point [%z]",p3);
ss_command("point [%z]",p4);
ss_command("end");
}

Command Formats

SilverScreen has several thousand commands and variations of commands. To use a specific command in a program, it is necessary to know the exact format of that command. There are three ways to find the format.

The most obvious (and least useful) method is to search the reference manual of the SilverScreen Solid Modeler. This manual contains a complete listing of all commands. In practice, however, this is seldom done.

It is much easier to find the format of a command by simply executing the command in SilverScreen. Since all executed commands and icommands are recorded in the command log, it is a simple matter of executing the command and viewing the command log. It is very common for programmers to execute commands then copy those commands directly from the log to their program.

On occasion, there may be long sequences of commands that are required in a program. For example, one may require commands to draw polygons and circles, perform Boolean operations, and to sweep and render. In this case, Remember Mode is a very good tool. When Remember Mode is enabled, all commands are recorded into a script file. The recording of commands continues until Remember Mode is disabled. At the end of the recording session, the script file will contain a faithful record of all commands that were executed.

 

Drawing Hierarchy

Introduction

The SilverScreen internal drawing structure closely resembles the Windows file system. Whereas the Windows file system contains folders and files, the SilverScreen drawing structure contains blocks and entities.

Entities: An entity may be a block, an object, a text line, a detail, or a symbol. Each entity has a name that is unique within the block that contains the entity. This name is assigned to the entity when the entity is created. The entity structure for a drawing may be displayed with the STRUCTURE TREE command.

Blocks: The block is an organizational unit that contains contain zero or more entities. At the root of the drawing structure is a block that is referred to as the root block.

Objects: The object entity is the container of geometry in a SilverScreen drawing. An object contains zero or more primitives where each primitive is a basic drawing element such as a polygon, a line, a circle, or a curve. The object also contains an edge list and a vertex list. These lists are referenced by the primitives.

Text Lines: The text entity is a collection of text characters that form a single line of text. The font for a text entity may be a TrueType font or a SilverScreen stroke font. The characters of the text line are viewed through a transformation matrix that allows the text entity to be displayed in 3D space.

Details: The detail entity are used to provide annotation for the drawing. There are about 15 types of details that are used to display angles, linear distances, Y14.5 information, and notes. All detail entities are contained within special blocks called annotation blocks.

Symbols: The symbol entity is a reference to an internal model or to a model that resides in an external model library. Symbols allow the geometry of the model to be reused. Through a transformation matrix local to the symbol, the geometry of the model may be translated, scaled and rotated. A model may be either a block or an object.

Primitives: Primitives are always contained within objects. Primitive types include arcs, curves, circles and ellipses, lines, points, and polygons. Each primitive is identified by a identification number that is unique within the object that contains the primitive. Complex primitives (such as polygons) are composed of simple primitive types (lines and arcs). Information about primitives may be displayed with the STRUCTURE LIST command.

Direct Structure Access

All entities and primitives are directly accessable by application programs. Entity and primitive structures are described in SilverScreen Internal Structures.

Structures representing entities:

BOS_NODE
BLOCK_NODE
OBJECT_NODE
SYMBOL_NODE
TEXT_NODE
DETAIL_NODE

Structure representing primitives:

PRIM_NODE
ROUND_NODE
LINE_NODE
POINT_NODE
POLYGON_NODE
POLYLINE_NODE
BPOINT_NODE
SPOINT_NODE

Pointers to entity structures may be obtained via the get_bos function. Pointer to primitive structures are obtained either via the get_prim function, or by accessing the first_node field in an OBJECT_NODE .

Entity Structures

Although the structure for each type of entity is unique, there is a structural prefix that is common to all entity types. For convenience, these common fields are defined as an independent structure called the BOS_NODE. Informally, we speak of the of entity nodes as being BOS nodes. In actuality, there is no entity whose structure corresponds exactly with the structure of the BOS_NODE. Here is the BOS_NODE structure:

BOS_NODE
   {
   int bits1;
   int bits2;
   SS_XYZ high;
   SS_XYZ low;
   SS_XYZ center;
   SS_XYZ top_axis;
   SS_XYZ bottom_axis;
   SS_XYZ local_horz;
   SS_XYZ local_vert;
   SS_XYZ local_base;
   NAME name;
   int force_style_color;
   RGB force_rgb;
   BOS_NODE *next_bos;
   BOS_NODE *prev_bos;
   BLOCK_NODE *parent;
   };

This structure contains:

bits1   identification of entity type and entity infromation.
bits2   entity information.
high,low   contains extent information for the entity.
name   the name of the entity.
center   the base point used in scaling and rotation.
top_axis
bottom_axis  
the axis used in axial rotation.
local_horz
local_vert
local_base  
e-space information for entity.
next_bos   a pointer to the next entity within the block.
prev_bos   a pointer to the previous entity within the block.
parent   a pointer to the parent block.

An entity may be a block, an object, a symbol, a detail, or a text line. To distinguish between the different entity types, the bits1 field in the BOS_NODE can be examined. A specific bit of this field is set for each of the five entity types. The E_OBJECT bit (0x0002) is used to identify objects. If this bit is set then the entity is an object. Similar bit settings are defined in SSNODES.H for the other entity types:

#define E_BLOCK 0x0001
#define E_OBJECT 0x0002
#define E_SYMBOL 0x0004
#define E_TEXT 0x0400
#define E_DETAIL 0x0100

Here is an example showing how entities might be identified:

BOS_NODE *bos;

if ( bos->bits1 & E_BLOCK )
   ss_command ("note This is a block");
else if ( bos->bits1 & E_OBJECT )
   ss_command("note This is an object");
else if ( bos->bits1 & E_SYMBOL )
   ss_command("note This is a symbol");
else if ( bos->bits1 & E_TEXT )
   ss_command("note This is text");
else if ( bos->bits1 & E_DETAIL )
   ss_command("note This is a detail");

The annotation block (A-Block) has a special purpose within the SilverScreen hierarchical structure. This type of block is used to store the details (and possibly other entities) that belong to a specific annotation block. A-blocks always appear at the root and can be identified through the bits2 field and the IS_ANNOTATE definition. An A-Block is identified below:

BOS_NODE *bos;

if ( bos->bits1 & E_BLOCK )
   {
   if ( bos->bits2 & IS_ANNOTATE )
      ss_command ("note This is an annotation block");
   else
      ss_command("note This is not an annotation block");
   }

The BLOCK_NODE structure is shown below. Note that the first portion of the structure is identical to that of the BOS_NODE.

BLOCK_NODE
{
int bits1;
int bits2;
SS_XYZ high;
SS_XYZ low;
SS_XYZ center;
SS_XYZ top_axis;
SS_XYZ bottom_axis;
SS_XYZ local_horz;
SS_XYZ local_vert;
SS_XYZ local_base;
NAME name;
int force_style_color;
RGB force_rgb;
BOS_NODE *next_bos;
BOS_NODE *prev_bos;
BLOCK_NODE *parent;
BOS_NODE *first_bos;
SCHEMA_NODE *first_schema;
void *unused1;
};

The BLOCK_NODE structure contains first_bos, a pointer to the first entity within the block.

To access the entities within a block, the first_bos pointer is used to locate the first entity of the block. Once this first entity has been located, the next_bos pointer can then be used to traverse the list of entities within the block. The list terminates with a null pointer.

The following will display the entity names of a drawing in in-order sequence. Note that the function display_block is used recursively.

#include "silver.h"
#include "ssnodes.h"
void display_block( BLOCK_NODE *blk );

void main( void )
{
BLOCK_NODE *root;

// Get pointer to root of tree
root = (BLOCK_NODE *) get_bos ( "\\" );
display_block( root );
}

void display_block( BLOCK_NODE *blk )
{
BOS_NODE *bos;

ss_command ( "note Block Name: %s", bos->parent?bos->name:"ROOT" );

for ( bos = blk->first_bos ; bos ; bos = bos->next_bos )
   {
   if ( bos->bits1 & E_BLOCK )
      display_block( (BLOCK_NODE *)bos );
   else
      ss_command ( "note name: %s", bos->name );
   }
}

Note the manner in which the BOS_NODE pointer bos is cast to a BLOCK_NODE pointer. This technique is frequently used in accessing drawing structures. That is, the bits of the BOS_NODE are examined to determine the entity type of the node. If the bit setting in bits1 corresponds to that of an OBJECT_NODE, then the BOS_NODE pointer is cast to an OBJECT_NODE pointer.

The OBJECT_NODE is the organizational unit for the drawing primitives within a drawing. Each object has a pointer to the first primitive within the list of primitives contained in the object. These primitives may have pointers to other primitives. The organization of this structure is described in the next section.

The SYMBOL_NODE contains a pointer to a MODEL_NODE. The MODEL_NODE contains a pointer to a BLOCK_NODE which in turn contains a pointer to the first BOS_NODE within the model. The geometry of the model is viewed through the transformation matrix contained in the SYMBOL_NODE. Since the MODEL_NODE may contain symbols that have their own transformation matrices, the viewing of points should be handled with composite transformation matrices using a push-pop technique.

Blocks, symbols, and objects may be associated with schema. Thus the BLOCK_NODE, SYMBOL_NODE, and OBJECT_NODE each have a pointer to the to the first SCHEMA_NODE in a list of SCHEMA_NODEs. Each of the SCHEMA_NODEs has a pointer the first ATTRIBUTE_NODE in a list of ATTRIBUTE_NODEs.

Primitive Structures

Primitives are only contained in objects. The following primitives are supported in SilverScreen. Each of these primitive types has a structure definition. The names of these structures are:

Primitive Corresponding Structure
arc ROUND_NODE
circle/ellipse ROUND_NODE
line LINE_NODE
point POINT_NODE
polygon POLYGON_NODE
polyline POLYLINE_NODE
Bezier point BPOINT_NODE
spline point SPOINT_NODE

All primitives are directly or indirectly contained in objects. However, primitives may be contained within other primitives. A polyline, for example, consists of a set of lines; a Bezier curve consists of a set of Bezier points.

The following summarizes the rules of association for primitives:

  • An arc may be an independent primitive.
  • An arc may be contained in a polyline or polygon.
  • A circle/ellipse is an independent primitive.
  • A line may be an independent primitive.
  • A line may be contained in a polyline or polygon.
  • A polygon consists of lines and arcs.
  • A polyline consists of lines and arcs.
  • A point is an independent primitive.
  • A spline curve consists of a set of control points.
  • A Bezier curve consists of a set of control points.

Holes give a second level of association for certain primitives. Here are the rules of association for holes:

  • A circle/ellipse may contain one or more holes.
  • A polygon may contain one or more holes.
  • A closed spline curve may contain one or more holes.
  • A closed Bezier curve may contain one or more holes.
  • A circle/ellipse may be a hole.
  • A polygon may be a hole.
  • A closed spline curve may be a hole.
  • A closed Bezier curve may be a hole.
  • No other primitive may be a hole.

Another level of associativity is the phantom. Phantoms give additional information about a primitive.

To understand the use of the phantom, consider the following: A rectangle is drawn and filleted on all four corners. This results in a polygon that consists of four lines and four arcs. This polygon is then swept linearly to produce a solid. Since the SilverScreen solid consists of polygons that contain only lines, the arc information would seemingly be lost in producing the solid.

However, to retain this arc information, a new association is formed. This association relates the polygon to the arcs that, prior to the sweep, were part of the polygon. Arcs (and circles) of this type are called phantoms. Phantoms, while not visible on the screen, may be used for dimensioning or for export to CAM.

Here are the rules of association for phantoms:

  • A phantom may be either a circle/ellipse or an arc.
  • A phantom may be contained in either a polygon or a polyline.
  • A phantom may not contain holes.

All primitive structures have a common prefix consisting of 5 fields. This common structure is PRIM_NODE, a structure which is shown below.

PRIM_NODE
   {
   int bits;
   int id;
   PRIM_NODE *next_node;
   PRIM_NODE *prev_node;
   OBJECT_NODE *parent;
   };

This structure contains:

bits identifies node type and contains node information
id within the parent object, a unique primitive identifier
next_node a pointer to the next node within the object
prev_node a pointer to the previous node within the object
parent a pointer to the parent (an object)

The following shows the definitions that are used to identify the various node types:

#define P_LINE     0x0001
#define P_POLYGON  0x0002
#define P_SPLINE   0x0004
#define P_ROUND    0x0010
#define P_CIRCLE   0x1000
#define P_ARC      0x2000
#define P_SPOINT   0x0020
#define P_BEZIER   0x0040
#define P_BPOINT   0x0080
#define P_POLYLINE 0x0400
#define P_POINT    0x0800

The OBJECT_NODE has a first_node pointer that gives access to all of the primitives within an object. Each primitive has a pointer to the next primitive (next_node) that is directly contained within the object. The next_node list terminates with a null pointer.

The following illustrates a traversal of the primitives that linked directly to an object node:

void display_primitives( OBJECT_NODE *obj )
{
PRIM_NODE *prim;
for ( prim = obj->first_node ; prim ; prim = prim->next_node )
   {
   if ( prim->bits & P_LINE )
      ss_command ( "note Line with id %d", prim->id );
   else if ( prim->bits & P_POLYGON )
      ss_command ( "note Polygon with id %d", prim->id );
   else if ( prim->bits & P_POLYLINE )
      ss_command ( "note Polyline with id %d", prim->id );
   else
      ss_command ( "note Other type with id %d", prim->id );
   }
}

The above function only identifies three primitive types. The remaining types are lumped together as "Other type".

The structure of the polygon node is displayed below:

POLYGON_NODE
   {
   // Common PRIM_NODE section omitted.
  
   PRIM_NODE *first_hole;
   SURFACE_NODE *sn;
   RGB surface_rgb;
   int surface_pattern_number;
   PRIM_NODE *first_node;
   PRIM_NODE *first_phantom;
   TEXTURE_DATA *texture;
   };

The following function lists the lines that are contained in polygons that are directly within the object. This function uses a first_node pointer in the POLYGON_NODE to locate the first primitive in a list of primitives within the polygon. These primitives (within the polygon) are linked via the next_node pointer and terminate with a null pointer.

   void display_lines_in_polygons( OBJECT_NODE *obj )
   {
   PRIM_NODE *prim;
 
   for ( prim = obj->first_node ; prim ; prim = prim->next_node )
      {
      if ( prim->bits & P_POLYGON )
         {
         ss_command ( "note Polygon with id %d", prim->id )
         poly = (POLYGON_NODE *)prim;
         for ( prim2 = poly->first_node;
               prim2;
               prim2 = prim2->next_node )
            {
            if ( prim2->bits & P_LINE)
              ss_command ( "note Line with id %d", prim2->id );
            }
         }
      }
   }

This function ignores all primitives other than polygons. Also, for each polygon, the function lists only lines, ignoring any arcs that might appear in the polygon.

Edges and Vertices

Each object in SilverScreen has a set of vertices. Each vertex in the set may be addressed by its vertex number. For an object that has n vertices, the range of vertex numbers is 1 through n.

For a given object and a given vertex number, the function xyz_of_vertex returns a pointer to the xyz-coordinate associated with that vertex. The following will display the coordinates of all vertices in the object obj:

OBJECT_NODE *obj;
int i;

for ( i = 1 ; i <= obj->vertices ; i++ )
   ss_command ( "note vertex: %d %z", i, xyz_of_vertex (obj,i) );

Each object also has a set of edges. Each edge is addressable with an edge number, and is associated with two vertex numbers.

For a given object and a given edge number, the function vertex1_of_edge will return the vertex number of the first vertex, while vertex2_of_edge will return the vertex number of the second. The following displays the vertex numbers of all edges in obj:

for ( i = 1 ; i <= obj->edges ; i++ )
   ss_command ( "note edge: %d %z %z",
                i,
                vertex1_of_edge (obj,i),
                vertex2_of_edge (obj,i) );

For obj, the addresses of the coordinates of the vertices of edge i can be expressed as:

xyz_of_vertex (vertex1_of_edge (obj,i));
xyz_of_vertex (vertex2_of_edge (obj,i));

However, two additional functions, xyz1_of_edge and xyz2_of_edge, allow simpler expressions that are equivalent to those shown above:

xyz1_of_edge ( obj, i );
xyz2_of_edge ( obj, i );

The following can thus be used to display the coordinates of the edges of obj:

for ( i = 1 ; i <= obj->edges ; i++ )
   ss_command ("note edge: %d %z %z",
                i,
                xyz1_of_edge ( obj, i ),
                xyz2_of_edge ( obj, i ) );

The structures of the point, line and round (circle/arc) nodes are shown below:

POINT_NODE
   {
   // Common PRIM_NODE section omitted.
  
   VERTEX point;
   int point_type;
   USINT point_width_style;
   double point_size;
   RGB point_rgb;
   };

LINE_NODE
   {
   // Common PRIM_NODE section omitted.
  
   EDGE edge;
   };

ROUND_NODE
   {
   // Common PRIM_NODE section omitted.
  
   XYZ horizontal;
   XYZ vertical;
   double start_angle;
   double stop_angle;
   SURFACE_NODE *sn;
   RGB surface_rgb;
   RGB round_rgb;
   int surface_pattern_number;
   USINT round_width_style;
   VERTEX center;
   int round_type;
   TEXTURE_DATA *texture;
   };

Each of these primitives uses references to the edge and vertex lists. LINE_NODE has an edge number that can be used to retrieve the endpoints of the line. POINT_NODE and ROUND_NODE have vertex numbers that can be used to retrieve the coordinate of a point. We give several examples.

LINE_NODE contains an edge number edge. For LINE_NODE *p, the addresses of endpoints of p are given by the expressions:

xyz1_of_edge ( p->parent, p->edge );
xyz2_of_edge ( p->parent, p->edge );

The ROUND_NODE contains a vertex number center. For ROUND_NODE *r, the address of the center coordinate is given by:

xyz_of_vertex ( r->parent, r->center );

In both cases above, note that r->parent is a pointer to the OBJECT_NODE that contains p.

Note: The distributed sample program lister.c, which lists the components of a SilverScreen drawing, provides a guide to navigating the drawing data structure.

Entity Paths

Every primitive and entity may be referenced by means of a path. The path convention used for entities is nearly identical to the convention that is used in MS-DOS and Windows.

Suppose that the object "door" is contained within a block "wall" which is contained within the block "room". Further suppose that "room" is contained within the root block. Then path to this object is

\room\wall\door

and the path to the block that contains "door" is

\room\wall

Given a path to a entity, the function get_bos will return a pointer to the entity.

BOS_NODE *bos;
char *path;

bos = get_bos ( path );

Primitive Paths

Each primitive within an object has a unique identifying number. This id number, which appears in the PRIM_NODE structure, is automatically assigned when the primitive is created. A primitive within an object may be referenced by appending the id number to the object path. The path to the primitive with id 4 within the object "door" is

\room\wall\door.4

Each line node contains a reference to an edge. The edge, as noted earlier, contains a reference to two vertices. Suppose that the above primitive is a line. The first and second vertices of this line can be referenced by appending vertex number to the line path:

\room\wall\door.4.1
\room\wall\door.4.2

Given a path to a primitive, the pointer to the primitive can be obtained with the get_prim function. This function returns a pointer to the primitive while retrieving a pointer to the object that is the parent of the primitive. Note that the OBJECT_NODE pointer passed to get_prim is updated to point to the object node containing the primitive.

PRIM_NODE *prim;
OBJECT_NODE *obj;
char *path;

prim = get_prim ( path,&obj );

Groups and Wildcards

SilverScreen supports primitive groups and entity groups.

Primitive groups are defined by a P-GROUP BEGIN command, a list of primitives that are to be in the group, and a P-GROUP END command. Here is an example:

p-group begin
p-group polygon \main\arm.3
p-group polygon \main\arm.11
p-group polygon \main\bolt.13
p-group end

Q-groups are defined using a similar command sequence. The following defines a group of objects:

q-group begin
q-group object \main\arm
q-group object \main\lever
q-group object \main\bolt
q-group end

Wildcards are one of the powerful tools available to the developer. Wildcard path names may be used to create Q-groups. They may also be used in commands. The wildcard characters are:

Character Meaning
* Matches zero or more characters
? Matches any single character
# Identifies the highest numeric suffix
! Located at any level of the hierarchy
, Union of wildcard paths

The "*" and "?" are used in the conventional manner. Here are several examples:

\part* Identifies all entities with the prefix "part".
\part7\*\arm Identifies all entities with the name "arm" within a block within the block \part7.
\part?b Identifies all entities with the prefix "part", a single character, and the suffix "b".

The "#" wildcard is used to identify, within a block, the entity with the highest numeric suffix for a given prefix. Suppose that the blocks \part1, \part5, and \part14 appeared in the root block. Then \part# would identify the block \part14.

The "#" wildcard is often used in combination with the creation of entities. If the root block contained the blocks previously mentioned, then the command shown below will create a block \part15. Once this block has been created, it can be referenced by the wildcard path \part#.

create block at-root part#

The "!" wildcard will locate entities at any level of the drawing hierarchy. !knob* will match any entity in the drawing that has the prefix knob. Here it does not matter whether the entity is located at the root or six levels deep in the hierarchy.

The "," wildcard allows the union of wildcard paths. Suppose that we want to identify all entities in the drawing hierarchy that had either the prefix "knob" or the prefix "latch". This can be done with the wildcard union !knob*,!latch*.

Wildcards can be used to define groups. They can also be used directly in commands. The following illustrates both of these uses:

q-group begin
q-group object !knob*
q-group object !latch*
q-group end
surface object !knob*,!latch* color green

Tags

The TAG command permits information --- numeric values, strings, and 3D points --- to be attached to an entity. Each item of information is associated with a tag name.

Variations of the TAG command permit tagged information to be attached, deleted and copied. The formats of the TAG command are displayed below:

Add a tag to an entity:

tag <bos name> <tag name> value <number>
tag <bos name> <tag name> text <string>
tag <bos name> <tag name> xyz <number>,<number>,<number>

Remove a specific tag from an entity:

tag remove <bos name> <tag name>

Clear all tags attached to an entity:

tag clear <bos name>

Copy all tags from one entity to another:

tag copy from <bos name> to <bos name>

In these commands:

<bos name> is the full path name of an entity, including entity type;
<tag name>
is the name of the tag (case insensitive);
<string>
is a text string of up to 20 characters, delimited by double quotes.

Several examples of the TAG command:

tag block \roof\beams material text "PT pine"
tag object \roof\beams\beam1 width value 6.0

tag clear block \roof

tag copy from object \roof\beam\beam1 to object \roof\beam\beam2

Tag information for a specific tag name may retrieved program with the fetch_tag function. All tags associated with an entity may be retrieved with the get_tag function.

Tags are automatically saved with the drawing when the drawing is saved. The attached tag values may be viewed with the extended version of the LIST command.

E-Space, Base, Axis and Extents

Entity structures contain E-space, base, axis, and extent information.

The E-space is a private coordinate space for an entity, and is described by three fields within the entity structure: local_base, local_horz and local_vert. The local_base is the origin of the E-space, in world space coordinates. local_horz defines the direction of the positive x-axis of the space. local_vert defines the direction of positive y-axis of the space. The initial orientation of the E-space is dependent on the C-Space that is in effect when the entity is created. The E-SPACE command may be used to change this orientation.

The base point is used for commands that involve scaling, rotation and shearing. The base point is stored in the center field of the BOS_NODE. This field receives a value when the entity is scaled, rotated or sheared. A value for this field may also be established manually by the FIX BASE command. The definition HAS_CENTER (bits1) indicates whether or not the base point has been established.

Two points which define the axis of rotation are stored in the axis_top and axis_bottom fields of the BOS_NODE. These points are established when the entity is rotated axially. These may also be established manually by the FIX AXIS command. HAS_AXIS (bits1) indicates whether or not the axis has been established.

The extents of an entity are the maximum and minimum x, y and z world space coordinates of the entity. This data is described by the high and low fields of the BOS_NODE. The maximum is held in the high field; the minimum is held in the low field. Entity exents may be retrieved through direct access to the BOS_NODE or through the use of the bos_extents function.

Visibility

Each entity has a visibility setting. This setting determines whether or not the entity will be displayed when the screen is refreshed. An entity is visible if the IS_VISIBLE bit of bits1 of the BOS_NODE is turned on. Otherwise the entity is not visible. There are two commands that control visibility -- ISOLATE and VISIBILITY. There are two functions, save_visibility and restore_visibility that can be used to save the current entity visiblities and later to restore all visibilities to the saved state.

 

Application-Oriented Commands

There are a number of commands that are not available interactively. There are also a group of commands that require a more detailed description than is found in the SilverScreen Reference Manual. These commands are discussed in this section.

Object-oriented 2D Boolean Commands

The BOOLEAN commands permit Boolean operations between objects. The formats for these commands are described below:

   boolean trim objects object <path1> object <path2>

The TRIM command expects to find one or more polygons in the object at <path1> and one or more polygons in the object at <path2>. The result of the trim operation is placed in the object at <path1>. The object in <path2> is unaltered:

   boolean difference objects object <path1> object <path2>

The DIFFERENCE command is identical with the TRIM command except that the object in <path2> is purged at the completion of the operation:

   boolean intersection objects object <path1> object <path2>

The INTERSECTION command expects a single polygon in the object at <path1> and one or more polygons in the object at <path2>. The result of the trim operation is placed in the object at <path1>. The object in <path2> is purged at the completion of the operation:

Commands to Control Screen Refresh

It is often desirable to perform commands without showing the results of the command on the screen. Several commands are provided for this purpose:

refresh off disables screen refresh
refresh enable re-enables screen refresh
refresh repaints the screen
silent <command> executes <command> without refresh

A situation that frequently occurs is the following: one wishes to first zoom the drawing and then to hide it. This is to be done without displaying the zooming operation on the screen. The following example illustrates:

ss_command ( "refresh off" );
ss_command ( "zoom drawing" );
ss_command ( "refresh enable" );
ss_command ( "hide drawing hidden-line" );

This same result can also be accomplished with the SILENT keyword:

ss_command ( "silent zoom drawing" );
ss_command ( "hide drawing hidden-line" );

The record_visibility and reset_visibility functions are often used in combination with the REFRESH commands. Consider the following section:

record_visibility ("\\");
ss_command ( "refresh off" );
ss_command ( "isolate block \\room4" );
ss_command ( "refresh enable" );

if ( pick_entity ( "Select object", E_OBJECT, path ) )
   ss_command ( "note The object %s was selected", path );
else
   ss_command ( "note No object was selected" );

ss_command ( "refresh off" );
reset_visibility ( "\\" );
ss_command ( "refresh enable" );

The record_visibility function records the current visibility settings for the specified BOS (possibly root), while reset_visibility returns the BOS to their original settings. Between these two commands, the block \room4 is isolated. Since pick_entity only allows the selection of visible objects, only those objects in the block \room4 will candidates for selection. Other objects, although they can be seen on the screen, are, in fact, invisible. Note that this process takes place without changing the image that is displayed on the screen.

Schema and Attribute Commands

Schemas and attributes may be used to associate non-graphical information with drawing entities. An attribute is a named numerical or text value. A schema is a named collection of attributes that may be attached to an entity. Schemas and their attributes are analogous to database records and their fields.

Here are the commands to work with schemas:

attribute
   schema
   define <schema>
   list <destination>
   modify <schema>
   undefine <schema>

Here are the commands that work with attributes:

attribute
   assign <entity> <schema>
   attach <entity> <schema>
   edit <entity> <schema>
   list <destination>
   modify <entity> <schema> <attribute>
   query <formula> template <filename>
         <format1>
<destination>
   query <formula> manual <attribute fields>
         <format2> <destination>
   unassign <entity> <schema>

Secondary definitions:

<destination>: {disk <filename>|print|screen}
<entity>: {block|object|symbol} <entity name>
<format1>: {cdf|sdf|table}
<format2>: {cdf|table}

Schemas may be defined with fixed fields that may not be modified by the user, or with variable fields that need values assigned to them. If variable fields are present in the scheme, the ATTRIBUTE ASSIGN command will cause the Attribute editor to be invoked, so that the user may fill in values for the variable fields. The ATTRIBUTE ATTACH command causes any variable value fields to be assigned the value 0, and variable text fields to be assigned the empty string ("").

The ATTRIBUTE QUERY command causes entities from a drawing to be selected on the basis of a logical condition, as represented by <formula>. <formula> is an expression expressing logical or relational conditions. For example:

COST > 20 AND MODEL = "GT"

The result of the ATTRIBUTE QUERY is textual information that is written to the specified destination. The information written is specified by the <attribute fields>, which is a comma separated list of attribute names or information fields. For example:

item,model,cost,/x,/y,/z,/n

Information fields are provided to allow other information to be output as the result of a query:

Field Meaning
/a surface area of the entity
/cx centroid x-coordinate of the entity
/cy centroid y-coordinate of the entity
/cz centroid z-coordinate of the entity
/d world space depth of the entity
/h world space height of the entity
/ixx moment of inertia about e-space x-axis,
through entity's centroid
/iyy moment of inertia about e-space y-axis,
through entity's centroid
/izz moment of inertia about e-space z-axis,
through entity's centroid
/ixxo moment of inertia about e-space x-axis,
through entity-space origin (0,0,0)
/iyyo moment of inertia about e-space y-axis,
through entity-space origin (0,0,0)
/izzo moment of inertia about e-space z-axis,
through entity-space origin (0,0,0)
/v volume of entity
/n name of entity
/p path of entity
/s schema name
/w world space width of entity
/x x-coordinate of center point of entity
/y y-coordinate of center point of entity
/z z-coordinate of center point of entity

For a more comprehensive discussion of schemas and attributes, see the SilverScreen Reference Manual.

Printing Commands

The PRINT Command

The print command has been significantly expanded for Windows. The following discussion is an attempt to document all of the print command intricacies.

print setup

The print setup command presents the user with the default Windows print setup dialog. The user can use the dialog to change the current printer and (normally) the page orientation of the output.

print orientation {portrait | landscape}

The print orientation command is used to orient the printed output to be either vertical (portrait) or horizontal (landscape).

print resolution {low | medium | high}

The print resolution command is used to control the quality of the image. On an HP LaserJet Series II printer, when the resolution is set to high, the Dots-Per-Inch (dpi) will be set to 300x300. When the resolution is medium, the dpi will be set to 150x150 and when the resolution is low the dpi will be set to 75x75. These numbers are presented to clarify the print resolution command and will change from device to device.

print reset

The print reset command does two things. First, it sets SilverEngine’s printer to the default Windows printer. Second, it sets all print options to their defaults (i.e. resolution high, orientation portrait).

    print {screen | area #,# #,#} [interactive] [copies #] [file]

The print screen and print area commands are used to generate output onto the currently selected output device. Specifying the interactive keyword will cause SilverEngine to display a preview window with options to change the current printer, change the page setup, set the copies, and control the print destination. The file keyword means that output should go to a file and the user will be prompted for a file name. The copies keyword allows you to control the number of copies that will be generated on the output device. The number of copies must be greater than zero.

Print screen requires no further parameters, but print area requires two pairs of numbers between zero and one. These pairs of numbers express screen percentages that used together define an area within the boundaries of the currently active window.

The PAGE Command

The page command is used to control the appearance of printed output on the output device.

page setup

The page setup command presents the user with SilverScreen’s page setup dialog. The user can then use the dialog to change the appearance of printed output. If the user chooses OK then all of the proper page commands will be issued.

    page justify {horizontal [left | center | right]}
                 {vertical [top | center | bottom]}

The page justify command aligns the bounding rectangle of the data being printed within the rectangle that is bounded by the user margins.

    page border
      {window [enable | disable]} {margin [enable | disable]}

The page border command controls the display of window borders (the bounding rectangle of each window) and the margin border (the rectangle formed by the user margins).

page options {background [enable | disable]}
             {black-white [enable | disable]}
             {hide [enable | disable]}

The page options command controls the status of several page options. The background option, when enabled, will draw the window backgrounds onto the printed output. The black-white option, when enabled, will draw all edges in black. The hide option, when enabled, will perform hide commands in the print preview.

page template [none | file file-path]

The page template command assigns the print template that will be used during printing and previewing. To disable the use of a print template use the print template none form. To specify a particular template (say logo.pnt) use the print template file logo.pnt form.

page margin [reset | {top #} {bottom #} {left #} {right #}]

The page margin command is used to control the user-defined margins. To set the user margins to the hardware margins of the currently selected output device use the page margin reset form. To set the left margin to (say) 4 inches use the page margin left 4 form.

    page size
      [best-fit | width # | height # | scaled drawing # device #]

The page size command is used to control the size of the data being printed. The best-fit option will produce the largest possible print-out that maintains a correct aspect ratio. The width option allows you to specify the width of the printed output (the height will be automatically assigned). The height option allows you to specify the height of the printed output (the width will be automatically assigned). The scaled option allows you to control the ratio between the world-space of the current window and that of the printer. If you wanted to generate output where 1 measured inch is equivalent to 1 measured foot in the drawing then the following command would be used: page size scaled drawing 1’ device 1".

page reset

The page reset command sets all options that affect the appearance of printed output to their defaults. It has the same affect as issuing the following sequence commands:

    page justify horizontal left vertical top
    page border window enable margin enable
    page options background disable black-white disable hide enable
    page template none
    page margin reset
    page size best-fit

In certain situations, you may wish to exercise finer control over the output device. There are several built-in functions provided for this purpose: printer_close, printer_open, printer_send .

Legacy Printing Commands

The following commands are associated with the original DOS version of SilverScreen, but are still supported under Windows. The Windows version of SilverScreen takes these commands and converts them into appropriate versions of the above PAGE and PRINT commands.

The OPTIONS command:

hardcopy options resolution {low|medium|high}
                 rendering {enable|disable} {window|screen}

The following HARDCOPY WIDTH commands allow line width to be controlled during printing:

hardcopy width manual
hardcopy width auto
hardcopy width set <nine values>

Annotation

In SilverScreen, annotation is primarily an interactive process, and as such, the full command set as implemented by the menu process is not available to the interactive file user. However, a subset of detailing commands may be used in C/C++ programs or script files. A summary of the syntax of this command subset follows:

Commands for Setting the Detailing Environment

set
   general
      arrow size <value>
      aspect <value>
      {box|open}
      font <name>
      truetype <name> weight <weight> italics (enable|disable)
      height <value>
      units {include|omit}
      zeros {include|omit}
   angle
      arrows {first|second|both|none}
      arrows {inside|outside}
      color {text|line} <value>
      {degrees|radians}
      extension <value>
      location {inside|outside}
      orientation {horizontal|vertical|parallel}
      offset <value>
      precision <value>
      round <value>
      underscore {single|double|none}
      units {include|omit}
      witness {first|second|both|none}
      zeros {include|omit}
   bubble
      color {text|line} <value>
      extension <value>
      location {above|below|right|left}
      offset <value>
      orientation {horizontal|vertical}
   center
      color <value>
      size <value>
   linear
      arrows {first|second|both|none}
      arrows {inside|outside}
      color {text|line} <value>
      direction {horizontal|vertical|parallel|rotated <value>}
      endmark arrow <size>
      endmark tick <size>
      extension <value>
      location {inside|above|below|right|left}
      offset <value>
      orientation {horizontal|vertical|parallel}
      underscore {single|double|none }
      witness {first|second|both|none}
   note
      color {text line} <value>
      extension <value>
      location {above|below|right|left}
      offset <value>
      orientation {horizontal|vertical}
   primary
      denominator <value>
      precision <value>
      round <value>
   secondary
      denominator <value>
      {disable|enable}
      notation {scientific|decimal|engineering|
                architectural|fractional}
      precision <value>
      units {feet|inches|meters|centimeters|millimeters}
   y14-5
      color {text|line} <value>
      offset <value>
      extension <value>

Commands for Inserting Details

detail
   angle
      three-point <3 points> distance <value> <options>
      four-point <4 points> distance <value> <options>
         <options>: {inside|outside}
                    text <string>
                    origin
   bubble
      leader <shape> text <string> <point> delta <xyz> <option>
      free <shape> text <string>
         <option> : {left|right|above|below}
   center {circle <path> arc <path>}
   diameter
      horizontal {circle <path> arc <path>} <option1>
      vertical {circle <path> arc <path>} <option1>
      rotated <value> {circle <path> arc <path>} <option1>
      leader {circle <path> arc <path>}
      delta <xyz> <option1> <option2>
         <option1>: text <string> {left|right|above|below}
         <option2>: {inside|outside}
   linear
      horizontal <target 1> distance <value> <options>
      vertical <target 1> distance <value> <options>
      rotated <value> <target 1> distance <value> <options>
      parallel <target 2> distance <value> <options>
         <option1>: text <string>
         <option2>: {inside|above|below|right|left}
   measure
      leader <measure> <point> delta <xyz>
      free <measure>
   radius
      horizontal {circle <path> arc <path>} <option1>
      vertical {circle <path> arc <path>} <option1>
      rotated <value> {circle <path> arc <path>} <option1>
      leader {circle <path> arc <path>}
      delta <xyz> <option1> <option2>
         <option1>: text <string> {left|right|above|below}
         <option2>: {inside|outside}
   datum <string>
      attach detail <path>
      free
      leader <point> delta <xyz>
      plane horizontal <point> delta <xyz>
      plane vertical <point> delta <xyz>
   frame
      free
      simple <string> <option>
      composite <string> <string> <option>
      with-datum <string> <string> <option>
      with-zone <string> <string> <option>
   leader <point>
      simple <string> delta <xyz> <option>
      composite <string> <string> delta <xyz> <option>
      with-datum <string> <string> delta <xyz> <option>
      with-zone <string> <string> delta <xyz> <option>
         <option>: text <string>
   target <string>
      free
      leader <point> delta <xyz>
   note
      free
      leader <point> delta <xyz>

Secondary Definitions

<shape>:       circle
               triangle
               i-triangle
               square
               diamond
               pentagon
               hexagon
               octagon

<target 1>:
   arc <path>
               cirlipse <path>
               line <path>
               object <path>
               polygon <path>
               polyline <path>
               symbol <path>
               two-point <two points>

<target 2>
:    arc <path>
               line <path>
               two-point <two points>

<two points>
: <point> <point>

<point>
:       arc <path>
               center <path>
               centroid
               block <path>
               object <path>
               symbol <path>
               endpoint <path>
               intersection line <path> line <path>
               midpoint <path>
               point <path>
               xyz <xyz>

<measure>
:     area
                  object <path>
                  symbol <path>
                  arc <path>
                  cirlipse <path>
                  polygon <path>
               length
                  object <path>
                  symbol <path>
                  arc <path>
                  cirlipse <path>
                  line <path>
                  polygon <path>
                  polyline <path>
               moment {centroid|origin} {e-space|w-space}
                  block <path>
                  object <path>
                  symbol <path>
               volume
                  object <path>
                  symbol <path>

Commands for Reinserting Details

Once a detail is inserted, the REINSERT command permits the user to adjust the detail interactively. This command permits the same formatting functions that are available in the interactive REINSERT command.

The basic command is

reinsert detail <path>

This allows the user to adjust the single detail identified by <path>. A second version of this command,

reinsert detail

allows the user to first select a detail, and then to adjust that detail. A final version

reinsert

permits the user to modify as many details as he wishes. Detail modification, in this case, continues until the user signals that he is finished.

Interactive Drawing Commands

All of the interactive drawing commands can be invoked with the IDRAW command. Here are the most common formats for the command:

   idraw arc {angles|chord|points}
   idraw bezier {closed|open} {single|double}
   idraw circle {diameter|radius points}
   idraw donut {diameter|radius} between <distance>
   idraw ellipse
   idraw hole <type of hole> <primitive path>
   idraw lines {single|multiple}
   idraw polygon {common|isosceles|quad|rectangle|triangle}
   idraw polygon equilateral <sides> {edge vertex}
   idraw polygon linear {center|left|right} <width>
   idraw polygon star <points> radius <radius>
   idraw polygon wedge {angles|chord|points}
   idraw point common
   idraw point {triad|xy-plane|yz_plane|zx-plane} length <length>
   idraw polyline
   idraw spline {open|closed}

Since the user has the opportunity to escape from any of these commands, a program must be able to detect whether the user successfully completed the task. Here is one strategy for accomplishing this: create a new (empty) object; IDRAW; check to see if the object is empty. The code might appear similar to the following example:

   OBJECT_NODE *obj;
   ss_command ( "goto root" );
   ss_command ( "create object temp#" );
   ss_command ( "idraw polygon common" );
   obj = (OBJECT_NODE *)get_bos ("\\temp#");
   if ( obj->first_prim )
      ss_command ( "note The polygon was sucessfully drawn" );
   else
      ss_command ( "note The user aborted the drawing process" );

Miscellaneous Commands

CURSOR commands

cursor disable
cursor enable

These commands control the visibility of the world cursor. When the world cursor is enabled, there are five commands to control the type of cursor that is displayed:

cursor arrow-triad
cursor triad
cursor cross-hairs
cursor small-cross
cursor box

ID RESET command

id reset <bos path>

This command renumbers all primitive id's within a block or object. For each object, primitives are each given an integer id. This command will give these primitives an unbroken series of id’s starting at 1.

COPY commands

The COPY command is used to copy drawing items to different parts of the drawing hierarchy.

copy object <path1> to block <path2> name <new name>

This command places a copy of the object at <path1> in the block <path2>, giving it the name <new name>.

copy from polygon <path1> to object <path2>

This command copies the single primitive at <path1> into the object at <path2>.

copy primitive <primitive> to object <path2>

This command copies the single primitive at <path1> to the object at <path2>.

E-SPACE commands

There are several Geometry commands that are not available throughout the SilverScreen menu system. They are:

move <bos> e-space <displacement>
scale <bos> e-space relative <scaling factors>
scale <bos> e-space absolute <scaling factors>
rotate <bos> e-space angles <angles of rotation>
shear <bos> e-space angles <angles of shear>

RELOCATE commands

There is a variation of the RELOCATE command that allows an entity to be moved to the front or rear of its enclosing block. Since entities are displayed from front to rear, this command has the effect of altering the display sequence:

relocate <bos> front
relocate <bos> rear

NOTE command

The NOTE command displays a message on the help line and waits for a key press. The form of the command is:

note <message>

The NOTE command is sometimes used as a simple debugging tool. Examples:

ss_command ("note the area of the object is %g",area);
ss_command ("note the location of the point is %z",p);

The WAIT command

This is a variation of the NOTE command. It causes a message to be displayed on the screen for a fixed amount of time. The format is:

wait <seconds> <message>

The TEXT-EDIT command

The TEXT-EDIT command has a variation that invokes the text editor without the fancy programming features, that is without multiple windows, file-oriented text searches, DEBUG command support and SilverC help. The format is:

text-edit <file name> simple

 

Tools and Techniques

This section of the manual concerns itself with tips, tools and techniques for building applications.

Panel Menus

Panel Menus are a simple means for constructing dialogs that request information from the user. For SilverC development, this is the primary method for interface with the user. For SilverEngine and SilverPlus, these menus offer a quick alternative to a the construction of a custom dialogs.

There are three steps are required to use a panel menu:

  1. The program executes pm_initialize . This establishes the title of the panel and initiates the assembly process.
  2. Lines of the panel are sequentially assembled using the pm-family of functions. Each of these functions corresponds to a specific type of panel input. Among these are text entry, menu selection, color selection, and icon selection. The order in which these functions are called determines the order in which items appear in the panel.
  3. The program executes pm_execute. This displays the panel and allows the user to input or edit items in the panel. When the user signals completion, pm_execute returns to the program. Updated panel values are then available.

There are 15 functions that define different types of panel input. Here is an overview of these functions:

Function   Description
pm_box    Provides a button that will display a popup box. The item is then selected from the popup box.
pm_box2    Similar to pm_box .
pm_color    Prompts for a color value. The color value may be entered directly or may be selected via a button from a color bar, color palette, or a color slide.
pm_comment    Inserts a line of descriptive text into the panel.
pm_displacement    Allows entry of an xyz-displacement. The displacement may be marked interactively via a button.
pm_distance    Allows entry of a distance. The distance may be marked interactively via a button.
pm_double    Allows entry of a real number.
pm_font    Allows selection of a TrueType or SilverScreen font.
pm_formatted    Allows entry of a real number. The number is displayed in any of the notations supported by SilverScreen.
pm_generic    This is a generalized selection entry that allows selection of items from 15 categories.
pm_icon    Provides a button that will display a set of icons. The selected icon provides a value for the item.
pm_icon2    Similar to pm_icon .
pm_integer    Allows entry of an integer value.
pm_menu    Allows selection of an item from a menu. The item is selected by pointing at the desired item.
pm_rgb    Prompts for a RGB value. The RGB maybe entered directly, or may be selected via a button from a color bar, color palette, or a color slide.
pm_text    Allows entry of a text string.
pm_xyz    Allows entry of an xyz-coordinate. The coordinate may be marked interactively via a button.

Here is a short example illustrating the use of panels:

// Establish panel title
pm_initialize ( "Machine Specification" );

// Initial values
machine_size = 1;
width = 10.0;
machine_color = color_blue;

// Items to appear in panel
pm_menu ( "Machine size", "Small Medium Large", &machine_size );
pm_double ( "Machine width", &width, 1 );
pm_color ( "Machine color", &machine_color );

// Display panel and edit
if ( pm_execute () )
   ss_command ("note User signaled successful completion");
else
   ss_command ("note User terminated by cancellation");

The initial values for machine_size, width, and machine_color will be used to initialize the panel. Values will be returned in these variables if pm_execute returns TRUE.

Generic Data Sets

The generic data sets represent a wide assortment of data that is used in SilverScreen. Each generic set has a corresponding constant that is defined in silver.h . The following is the list:

Defined Constant Data Set
GN_DRW drawing names
GN_FNT font names
GN_IGS IGES files
GN_DXF DXF files
GN_EX executable programs
GN_SF script files
GN_ENV private environments
GN_ANN annotation environments
GN_SDF screen definitions
GN_MLB model libraries
GN_MODEL library.model names
GN_LIGHT light names in current drawing
GN_IMODEL internal model names in current drawing
GN_GROUP named groups in current drawing
GN_VIEW named views
GN_SCREENS named screens
GN_PATTERN patterns for a given library
GN_LINE_STYLE line styles of a given library
GN_FILE tokens in a text file
GN_FILE2 tokens in a text file
GN_MODEL2 model names for a given library
GN_XLB execution library
GN_XLB_ENTRY entries in execution library
GN_FILE_NAME wild-carded file names
GN_FNT_ENTRY font names
GN_PRP property library
GN_PRP_ENTRY entries in property library

There are several ways that these sets can be used.

The prompt_generic function displays a pop-up panel containing all names in a given data set. The user may then select one of these. This selection is then returned to the calling program. The following is an example:

  if ( prompt_generic("Select light source",buf,GN_LIGHT,"") )
     ss_command ("note The selected light source is %s", buf);
  else
      ss_command ("note No light source selected");

The pm_generic function adds a generic item to a panel menu. The button associated with this item gives the user the opportunity to select an item from the set. The following is an example:

buf[0] = 0;
pm_generic ( "Light source name", buf, GN_LIGHT, "" );

collect_generic is a function that assembles all items of a generic set into a list. This list may then be accessed through the get_generic function:

collect_generic ( GN_DRW, "" );
for ( i = 1 ; ; ++i )
   {
   if ( ! get_generic ( i, buf ) )
      break;
   ss_command ( "note item %d in the list is %s", i, buf );
   }

The generic data set is specified by a constant and an auxiliary string. In most cases, the auxiliary string is empty (as shown in the examples above). The sets that require a non-empty string are the following:

GN_PATTERN name of the pattern library
GN_LINE_STYLE name of the line style library
GN_FILE name of the file
GN_FILE2 name of the file
GN_MODEL2 name of the library
GN_XLB_ENTRY name of the execution library
GN_FNT_ENTRY name of the font library

For GN_PATTERN and GN_LINE_STYLE, only "silver" should be used since this is the only library presently supported.

GN_FILE requires the name of an ASCII text file containing space-delimited tokens. An example of such a file is the following (note that the end-of-line character counts as whitespace):

bill sue
mary kjel
henry
jack jill jim

GN_FILE2 requires the name of an ASCII text file where each line is an element in the data set. Example:

Jean Paul Sartre
Plato
Bertrand Russell
David Hume

GN_MODEL2 requires the name of the model library from which the model names are to be selected.

SilverScreen Transformation Matrices

In SilverScreen, a transformation matrix is a 4x4 array of doubles. One can view a transformation matrix as a function that maps points from one space to another space, typically representing some combination of the scaling, rotation and translation operations. For a point (x1,y1,z1), and a transformation matrix T, the mapping to (x2,y2,z2) is defined by the matrix multiplication

[x2 y2 z2 1] = T. [x1 y1 z1 1]

Transformation matrices may be multiplied together to produce composite transformations. For example, if the matrix T maps (x1,y1,z1) to (x2,y2,z2), and if the matrix S maps (x2,y2,z2) to (x3,y3,z3), then the matrix product T . S will map (x1,y1,z1) to (x3,y3,z3).

Most commonly, matrices are multiplied to produce composite transformations. The chain of multiplications begins with the unity matrix, a matrix that has the value one in each diagonal element, and the value zero in all other elements. This matrix, if used to transform the point (x1,y1,z1), will map the point onto itself. Thus the unity matrix is, in effect, a null transformation.

A typical operation performed with matrices is the following:

A polygon with points p1, p2, p3 is to be scaled to one-half its size by scaling about the point p1. Here we assume p1 = (x1,y1,z1), p2 = (x2,y2,z2), and p3 = (x3,y3,z3).

  1. Initialize the matrix T to be the unity matrix.
  2. Construct a translation matrix S that translates all points through a displacement (-x1,-y1,-z1). The effect of this transformation is to map the point p1 to (0,0,0), and to map the other points to (x2 - x1,y2 - y1,z2 - z1) and (x3 - x1,y3 - y1,z3 - z1).
  3. Multiply the matrix T by the matrix S.
  4. Construct a new translation matrix S that scales all points by a factor of 1/2.
  5. Multiply the matrix T by the matrix S.
  6. Construct a new translation matrix S that translates all points through a displacement (x1,y1,z1). This transformation effectively moves the points back to their original location.
  7. Multiply the matrix T by the matrix S.

The result of these operations is a composite transformation matrix that will scale all points in the polygon about the point p1.

There are three types of transformation matrices that are explicitly supported by the SilverScreen API: translation, rotation, and scaling. Each of these functions performs two operations: First, a transformation matrix is created; second, the transformation matrix is multiplied into a composite matrix.

The functions that perform these operations are:

  • translation: tm_translate
  • scaling: tm_scale_x , tm_scale_y, and tm_scale_z
  • rotation: tm_rotate_x, tm_rotate_y, and tm_rotate_z

The scaling and rotation functions are designed so that rotation and scaling can be performed independently on each axis.

Here is the code that will produce the composite transformation matrix described in steps 1 through 7 above.

    double t[4][4];
    SS_XYZ p1,p2,p3;
    SS_XYZ q1,q2,q3;
    tm_clear (t); // Initialize t to the unity matrix
    tmp.x = -p1.x;
    tmp.y = -p1.y;
    tmp.z = -p1.z;
    tm_translate ( &tmp, t ); // Translate (-p1.x,-p1.y,-p1.x)
    scale_x( 0.5, t );        // Scaling by 0.5
    scale_y( 0.5, t );
    scale_z( 0.5, t );
    tm_translate ( &p1, t );  // Translate (p1.x,p1.y,p1.x)
   
    // After these statements have been executed, the
    // transformation matrix can be used to transform
    // the points to their new locations. This is done by
    // the function tm_transform. Here we can transform
    // p1, p2, and p3 to q1,q2, and q3 by:
   
    tm_transform ( &p1, &q1, t );
    tm_transform ( &p2, &q2, t );
    tm_transform ( &p3, &q3, t );

In addition to the simple transformation functions described above, SilverC contains a number of specialized transformation tools.

The function tm_cspace will produce a transformation matrix that maps points from world space to the current construction space. The following will transform a w-space point p to a c-space point q:

tm_cspace ( tm );
tm_transform ( &p, &q, tm );

To transform a c-space point back to w-space, the function tm_inverse is used. The inverse function produces a matrix which maps in the opposite direction of the original matrix. The following will first get the w-space to c-space matrix tm. Then, tm_inverse is used to get the c-space to w-space matrix tm_inv. The final statement transforms the c-space point p1 to the w-space point p2.

tm_cspace ( tm );
tm_inverse ( tm, tm_inv );
tm_transform ( &p1, &p2, tm_inv );

For a more concrete example, consider the following problem. For a point p, we wish to locate a point q that is 2 units from p in the direction of the positive y-axis of c-space. Although this description, may sound complicated, this operation is, in fact, fairly common in geometric programming. The solution is:

double tm[4][4],tm_inv[4][4];
SS_XYZ p,pp,q;
tm_cspace ( tm );
tm_inverse ( tm, tm_inv );
tm_transform (&p,&pp,tm); // result: pp in c-space
pp.y += 2.0; // add c-space displacement
tm_transform ( &pp, &q, tm_inv ); // result: q in w-space

The function w_to_c implicitly uses the w-space to c-space transformation matrix to transform a point from w-space to c-space. For a point p in w-space, the following produces the corresponding point q in c-space:

w_to_c ( &p, &q );

This is exactly equivalent to:

tm_cspace ( tm );
tm_transform ( &p, &q, tm );

There is also an inverse function c_to_w that transforms a c-space point to w-space. The following function makes use of w_to_c and c_to_w to move the cursor on the xy-plane of c-space:

SS_XYZ wxyz,cxyz;
SS_XYZ new_position;
double zspace;

cv_set ( CV_VERY_QUIET, 1 );

// Get initial location of cursor
wxyz.x = worldx;
wxyz.y = worldy;
wxyz.z = worldz;

// Transform wxyz in w-space to cxyz in c-space
w_to_c ( &wxyz, &cxyz );

// Move location to xy-plane of c-space
cxyz.z = 0.0;
zspace = snap_spacing();
for ( ; ; )
   {
   switch ( inchar () )
      {
      case LARROW: cxyz.x -= zspace; break;
      case RARROW: cxyz.x += zspace; break;
      case UARROW: cxyz.y += zspace; break;
      case DARROW: cxyz.y -= zspace; break;
      case ESCAPE: return;
      default: continue;
      }

   // Find corresponding w-space location
   c_to_w (&cxyz, &new_position);

   // Reposition the cursor
   ss_command ( "at %z", &new_position );
   }

The function tm_to_2d will produce a transformation matrix that maps three non-collinear points to the xy-plane. For the points p1, p2, and p3, the tm_to_2d transformation will map p1 to the origin, p2 to a point on the positive x-axis, and p3 to a point on xy-plane with a positive y-coordinate. This function provides a powerful tool for solving 3D problems in 2D.

Suppose, for example, that the points p1, p2, and p3 form a triangle somewhere in 3D space. To compute the area of this triangle, we can do the following:

SS_XYZ p1, p2, p3;
SS_XYZ q2, q3;
double area;
tm_to_2d (&p1, &p2, &p3, tm );
tm_transform ( &p2, &q2, tm );
tm_transform ( &p3, &q3, tm );
area = 0.5 * q2.x * q3.y;

Colors and RGB

SilverScreen is fully RGB-based. In all drawings, colors are stored as RGB values rather than color numbers. When a drawing is loaded, the RGB values are converted to color numbers that are appropriate to the video display.

When a color is selected for a surface or a line, the user may express this color as an RGB value or as a color number. If a color number is selected, then this number is internally converted to an RGB value.

The advantage of this approach is clear: SilverScreen drawings are independent of any color limitations imposed by the video device on which they were created. A surface, even on a 16-color system, may be given the RGB color of r13g120b93. On a 16-color system, this color may be interpreted as the color 3 (cyan). If the drawing is later displayed on an RGB video device, the color will be accurately portrayed as r13g120b93 .

For video systems that do not have RGB display capability, SilverScreen uses a base palette of either 16 or 256 colors, dependent on the capabilities of the video device. Each color in SilverScreen is simultaneously maintained both as an RGB value and as a color from this palette.

A special data type, RGB, defined in silver.h, is used to store this color information. The data type is an int, 32 bits in length. Eight bits are used to store the base color and 24 bits are used to store the RGB. There are several macros that are defined in silver.h that allow each of these values to be extracted:

RED_COLOR (rgb)
GREEN_COLOR (rgb)
BLUE_COLOR (rgb)
THE_COLOR (rgb)
MAKE_RGB (color,red,green,blue)

The SilverScreen API also provides functions that convert color to RGB and RGB to color.

color_to_rgb for a given base color, the function returns the RGB components of the color.

rgb_to_color for an RGB, this function returns the base color appropriate for the current video device.

Icons

The functions described in this section provide a means to creating an icon-based dialog. These functions provides a relatively easy way to create a dialogs that are functionally similar to a toolbars.

Icons are supported with the icon, panel_icon, and pm_icon functions. The icon function displays the icons in the menu area, while the panel_icon function displays the icons at the center of the screen within a panel. The pm_icon function allows an icon item to be added to a panel menu, and invoked via a button. In this case, the icons appear in a pop-up panel in the center of the screen. Other related functions include icon2, panel_icon2, pm_icon2 , display_icon and clear_icons .

The use of the icon functions is relatively straightforward. The greater effort is the preparatory design work.

Icons are stored in what we shall call an icon drawing. Here are the characteristics of an icon drawing:

  1. An icon drawing is a normal SilverScreen drawing.
  2. Icon entities are stored at the root of the icon drawing.
  3. Icon entities are named icon1, icon2, icon3, and so on.
  4. An icon entity may be a block, an object or text.
  5. A block icon may contain any combination of blocks, objects, or text entities.
  6. Icon entities may be placed anywhere in the drawing provided that the zoom extents of the entities do not overlap.
  7. The scale of the icon entities is not important since zooming will occur prior to the display of the icon.
  8. The background color of the drawing will be the background color of the individual icons.
  9. The border color of the drawing will be the border color of the individual icons.
  10. Surface fills and patterns may be enabled for the drawing. This will cause fills and patterns to be displayed for all icons.
  11. The presence of entities that are not icon entities will not affect the display of icons except if these entities overlap the extents of icon entities.

It is often attractive to have different background colors for different icons. By (8) above, it would seem that all icons would have the same background color. However, there is a way to work around this.

Before creating any of the icons, create an object, say obj1. Since this object is the first entity in the drawing structure, it will be displayed first. Later, after all of the icons have been drawn, obj1 can be used to provide background color for individual icons. This is done by enabling fill and by placing colored polygons in obj1 that enclose the zoom extents of an icon. Since the polygon will be filled before the icon is drawn, the color of the polygon will be the background color for the icon.

The automatic zooming described in (7) is sometimes a convenience and sometimes a burden. Let us consider the one of the troublesome aspects of scaling.

Suppose that we wish to construct an icon drawing that has two icons, both of which are text. The first icon is to contain "YES" and the second "NO". We place the two lines in a drawing, and rename them so that "YES" is icon1 and "NO" is icon2. When these icons are displayed, we find that the letters of "NO" are larger than the letters of "YES". This is due to the automatic scaling that independently zooms each entity.

In order to produce icons that are uniformly scaled, a scaling object must be introduced for each icon. The purpose of the scaling object is to establish the physical extents of the icon. In the above case, we would create two blocks, icon1 and icon2. Within these blocks, we would place two identically sized polygons, and then place the lines of text within the extents of these polygons. Once this is done, the scaling of the icon is dependent on the size of the scaling objects rather that the size of the text. To prevent the scaling objects from being displayed as part of the icon, their visibilities can be disabled. Alternatively, they can be given the color of the background.

As a practical matter, it is often convenient to create a single icon block, icon1, which contains a scaling object. This block can then be matrix copied to produce as many icon blocks as desired.

Custom Menus

SilverScreen allows the use of custom menus. These menus, in appearance and in functionality, are very similar to the SilverScreen menus. The menus can be displayed using the built-in function menu. Using this function, a program can display a menu and receive the user's response.

The construction of custom menus begins with a source file that defines the structure of the menus. This file is then compiled to produce a .CMF file. It is the .CMF file that is used by the menu function.

Sample Custom Menu File

heading="Sample menu"
   {
   ceiling "CEILING Ceiling commands"
      {
      build "BUILD Build ceiling" 10
      display "DISPLAY Display ceiling" 20
      }
   floor "FLOOR Floor commands"
      {
      build "BUILD Build floor" 30
      display "DISPLAY Display floor" 40
      }
   quit "QUIT Exit" 50
   }

This is a simple menu consisting of three major menu selections (ceiling, floor, quit). The ceiling and floor selections have secondary menus, while the quit selection does not. The quoted strings are single line descriptors that appear at the top of the screen when the corresponding selection is highlighted.

The numbers at the right are returned to the program if the user selects that item. Note that these numbers appear only at the leaf level of the menu tree.

Let us assume that above source menu is stored in the file SAMPLE1. The file is compiled using the following SilverScreen command:

CUSTOM-MENU COMPILE <source menu file>

This will produce, in this example, a custom menu file SAMPLE1.CMF, which will be stored in the current directory. The CMF file may now be used by the menu function:

switch ( menu ( "sample1" ) )
   {
   case 0: // The user entered ESCAPE
      break;
   case 1: // The user entered a function key or control key
      switch ( ich )
         {
         case F1:
         ...
         case F2:
         ...
         }
      break;
   case 10: // CEILING BUILD
   ...
   case 20: // CEILING DISPLAY
   ...
   case 30: // FLOOR BUILD
   ...
   case 40: // FLOOR DISPLAY
   ...
   case 50: // QUIT
   ...
   }

The menu command returns 0, 1, or a number corresponding to a menu selection. The return value 0 means that the user chose to enter Esc rather than select an item from the menu. The return value 1 means that the user pressed a function or control key. When this occurs, the key is made available in the predefined variable ich. The other numbers correspond to a successful menu selection by the user.

.CMF files may be stored in executable libraries. This is particularly convenient when an application system has many such files.

Structure of a Custom Menu File

A custom menu file has the following format:

[HEADING = <string>]
[TITLE = <string>]
[MACRO = <string>]
MENU_UNIT

where:

MENU_UNIT ==>  { MENU_ITEMS }
MENU_ITEMS ==> [ MENU_ITEMS ] MENU_ITEM
MENU_ITEM ==>  <id> <string> MENU_UNIT ||
               <id> <string> <number> ||
               <id> <string> ||
               *

The ‘*’ menu item denotes that a menu separator is to appear at that location in the menu.

Control Variables

SilverScreen has a set of control variables that control the run-time environment. These variables may be modified by the cv_set function. The current settings of control variables may be examined by the cv_get function.

A number of these variables are read-only, that is, they may not be used as an argument to cv_set .

The control variables are references using defined constants that appear in silver.h. The following is a description of the variables. Variables that are marked as read-only may not be used with cv_set :

Variable Name Description  
CV_BREAK This variable can be used to enable/disable the user's ability to interrupt execution by Control-Break. Pressing the Control-Break key can be used to break out of a program only if this variable is on.  
CV_COMMANDS This variable controls the display of commands. Commands will be displayed only if this variable is on.  
CV_DEFER_PAINTING This variable controls drawing repaint procedure: normally SilverScreen draws to the refresh buffer, and then updates to the screen buffer at the end of repaint (default value of 1). This variable allows the default behavior to change, providing more or less immediate screen update visibility.

Possible values repaint procedure

0 Paint to screen and to refresh buffer at the same time.

1 Paint to refresh buffer, then at the end of repaint, update screen via BitBlt (this is the default value)

2 Paint to refresh buffer, but update to screen via BitBlt every 0.25 seconds.

 
CV_DISPATCH_SYSCHAR This variable controls whether the SilverScreen input system allows Windows system keys (WM_SYSCHAR) to be passed back to SilverScreen apllications via inchar/nextkey. A value of 0 means that system keys are returned to the inchar caller, otherwise they are passed through to MFC for default handling. The default value is 0.  
CV_ENABLE_CLOSE This variable enables or disables the System window close button on the SilverScreen frame window. The window close button will be displayed if the variable is non-zero, and will not be displayed if the variable is set to zero.  
CV_ENABLE_DLL_IDLE_PROCESSING This variable controls whether SilverScreen calls idle processing in its own frame idle routine, when the CWinApp-derived class returned via AfxGetApp is not SilverScreen (i.e. is a DLL). The default value is 1, which means that DLL idle processing is enabled.  
CV_ERRORS This variable controls the display of command error messages. These messages will be displayed only if this variable is on. This variable can be used in combination with the predefined variable ss_errno and the function error_text to intercept SilverScreen error messages.  
CV_FILL_ENABLED cv_get(CV_FILL_ENABLED) returns 1 if fill is currently enabled, and otherwise 0. read only
CV_GRID cv_get(CV_GRID) returns 1 if the grid is currently enabled, and otherwise 0. read only
CV_ICON_AREA_WIDTH This variable controls the pixel width of the icon area used in the icon and icon2 functions.  
CV_JUMP_MENU This variable controls the availabity of the popup Jump Menu when picking a point. If this variable is set to 0, the Jump Menu will not be available.  
CV_MESSAGES This variable controls the display of messages that appear at the bottom of the screen. (i.e., "Printing ...", "Sweeping ...") These messages will be displayed only if this variable is on.  
CV_MODIFIED cv_get(CV_MODIFIED) returns 1 if the current drawing is modified, and otherwise 0. read only
CV_NOTATION cv_get(CV_NOTATION) returns a number corresponding to the current setting for notation  
CV_NOTES If this variable is on, then NOTE and the WAIT commands will be handled normally. If the variable is off, these commands will be ignored.  
CV_ORTHO_SNAP cv_get(CV_ORTHO) returns 1 if ortho-snap is currently enabled, and otherwise 0. read only
CV_PAINT_ONE_WINDOW This variable controls the ability of the program to force repainting to occur in only the current window or in all windows.  
CV_PASSTHROUGH_CMDUI_ENABLE This variable determines whether SilverScreen will pass down ON_UPDATE_COMMAND_UI notifications to the DLL via the SilverScreen-defined message WM_CMDUI_ENABLE message. If set to 1, the update command UI messages are relayed to the DLL, otherwise, they are enabled automatically. The default is 0. This is documented more fully in the SilverPlus manual.  
CV_PATTERNS_ENABLED cv_get(CV_PATTERNS_ENABLED) returns 1 if patterns are currently enabled, and otherwise 0. read only
CV_QUICK_MENU When selecting points, entities or primitives, the CTRL-LEFT event will normally allow the user to change the view. This will be disallowed if this variable is set to 0.  
CV_REDRAW_LOCAL When the SilverScreen window is resized, SilverScreen will normally redraw the contents of the drawing windows. This automatic redraw can be disabled by setting CV_REDRAW_LOCAL to 0. When this is done, a refresh event (C_REDRAW or C_RESIZE) notifies that a resize has occurred.  
CV_REFRESH This variable controls display of the graphic area of the screen. If this variable is on, then the results of SilverScreen commands will be displayed on the screen; otherwise they will not. cv_set(CV_REFRESH, 1) is functionally equivalent to the SilverScreen command REFRESH ENABLE. cv_set(CV_REFRESH,0) is equivalent to REFRESH OFF.  
CV_RESIZE_PERMITTED This variable by be used to permit/disallow the resizing of the SilverScreen window. Only when the variable has the value 1 will the user will be able to alter the window’s size.  
CV_REUSE_ICON This variable controls the clearing of the icon area after icon prompting. It is useful to reduce screen updates when the same icon is used repeatedly. By setting this variable to 1, the icon area will not be cleared after the prompting has occurred  
CV_SINGLE_STEP This is a debugging variable that can be used to halt execution whenever a command is executed. If this variable is on, commands will be displayed and the system will await a key from the keyboard.  
CV_SNAP cv_get(CV_SNAP) returns 1 if snap is currently enabled, and otherwise 0. read only
CV_TRACE_INFO This variable controls the display of the trace information in the XYZ toolbar. This information appears during interactive drawing and when points and displacements are being marked. If the variable is on, and if the toolbar is visible, then the information is displayed; otherwise it is not.  
CV_UNITS cv_get(CV_UNITS) returns a number corresponding to the current setting for units of measure read only
CV_VERY_QUIET This is a composite variable that simultaneously sets CV_COMMANDS and CV_MESSAGES .  
CV_WINDOW_BORDER This variable controls the border color that is used for the current window. If the variable is on, the current window is displayed using the color white; otherwise the normal window color is used.  

Initial Setting at Start of Execution

CV_COMMANDS ON
CV_ERRORS ON
CV_MESSAGES ON
CV_SINGLE_STEP OFF
CV_BREAK ON
CV_TRACE_INFO ON
CV_REFRESH ON
CV_NOTES ON
CV_PAINT_ONE_WINDOW OFF
CV_REUSE_ICON OFF
CV_WINDOW_BORDER OFF

The following is an example of the use of CV_ERRORS:

cv_set ( CV_ERRORS, 0 ); // Disable error display
ss_command ( "redraw object \obj1 %d", the_color );
if ( ss_errno )
   {
   // Handle the error
   }
cv_set ( CV_ERRORS, 1 ); // Re-enable error display

System Variables

SilverScreen system variables are named storage objects that are global to the SilverScreen system. They are useful for communicating between programs. They may also be used to retrieve the results of certain SilverScreen commands (see below).

Three types of system variables are allowed: value, text and XYZ. Value variables are used to hold a single floating point number (double). Text variables are used to hold a text string (char). XYZ variables are used to hold the location of a point in 3D space. In order to support XYZ variables, the data type struct _xyz is predefined by the C compiler. System variables may be accessed via the load_variable function or the sysvar functions.

In SilverScreen, system variables are created, destroyed and assigned by using LANGUAGE VARIABLE commands:

  • They can be assigned a value by the VARIABLE ASSIGN script command. The command has three forms, each corresponding to a data type that can be associated with a system variable:

variable assign <name> value <value>
variable assign <name> text <string>
variable assign <name> xyz <xyz location>

  • Groups of variables can be assigned values by means of a VARIABLE LOAD command. This command is related to the VARIABLE SAVE command. The latter command saves all currently active variables in disk file with extension .VAR. These variables can then be reloaded with the VARIABLE LOAD command. See the SilverScreen manual for further details on these commands.
  • Groups of variables may also be assigned values with the VARIABLE V-EDIT command. This command is essentially a variant of the VARIABLE LOAD command. For further information on this topic, see the SilverScreen manual and the section on the V-EDIT command.
  • Variables can be assigned values as a result of a MEASURE command. There are roughly a dozen variables that are set by this command to reflect the result of a measurement. A listing of these variables appears at the end of this section.
  • Variables retain their values until they are unassigned with the VARIABLE UNASSIGN command, or until the CLEAR command is issued.

To use system variables in a program, the variable must first be defined by using a VARIABLE ASSIGN command, or by loading a group of variables from disk using the VARIABLE LOAD command.

A number of SilverScreen commands produce results that are assigned to various system variables. The commands that currently produce system variable results all belong in the GEOMETRY MEASURE family.

The following table describes the variable created, the SilverScreen command that creates it and the data type of the variable created (the GEOMETRY prefix is not included in the command description):

Variable SilverScreen Command Data Type
$angle MEASURE ANGLE value
$area MEASURE AREA value
$centroid MEASURE CENTROID XYZ
$dimx MEASURE DIMENSIONS value
$dimy MEASURE DIMENSIONS value
$dimz MEASURE DIMENSIONS value
$distance MEASURE DISTANCE value
$length MEASURE LENGTH value
$ixx MEASURE MOMENT CENTROID value
$ixx MEASURE MOMENT ORIGIN value
$ixy MEASURE MOMENT CENTROID value
$ixy MEASURE MOMENT ORIGIN value
$ixz MEASURE MOMENT CENTROID value
$ixz MEASURE MOMENT ORIGIN value
$moment MEASURE MOMENT AXIS value
$moment MEASURE MOMENT ENTITY AXIS value
$volume MEASURE VOLUME value

Here is an example where the MEASURE command is used to measure the area of a polygon:

   double area;
   ...
   ss_command ("measure area primitive polygon \\arm\\bolt4.26");
   sysvar_value ("$area",&area);
   ss_command ("note The area of \\arm\\bolt4.26 is %f",area);

V-EDIT command

The VARIABLE V-EDIT command is a means for creating tab dialogues where large numbers of variables can be edited. The V-EDIT command is a close cousin to the panel menu family of functions (that is, pm_execute). However it differs from these functions in two respects:

  • V-EDIT uses only system variables (rather than standard C variables).
  • At the start of an editing session, V-EDIT can retrieve initial values from a .VAR file.
  • At the conclusion of the editing session, V-EDIT can store the edited values in a .VAR file.
  • V-EDIT will permit an unlimited number of variables to be edited in the same session.
  • The values of the system variables stored in the .VAR file can later be loaded by the VARIABLE LOAD command.

V-EDIT is particularly useful in establishing a set of system parameters that are to be used during execution.

The appearance and contents of the are specified in a V-EDIT source file. A sample V-EDIT file is shown below:

title = "Sample V-EDIT file"
input = "sample1"
output = "sample1"
* ""
* "!0Editing of variables"
* ""
m $var1 "Variable 1" "one" "two" "three"
n $var2 "Variable 2" "one" "two" "three"
t $var3 "Variable 3" "hello"
f $var4 "Variable 4" 1.23
i $var5 "Variable 5" 6
* ""

title specifies text that is to appear at the top of the screen during editing. input specifies the .VAR file that is to be used to initialize system variables. output specifies the .VAR file to which the system variables are to be written when the editing session concludes. Both input and output are optional.

Starting on line 4, there is a line by line specification of the items that are to appear in the menu. The first character in each line identifies the type of information that is contained on the line:

Character Meaning
*!0 indicates the beginning of a tab section of the tab dialogue. Text from this line will be used in the tab.
* indicates that the line contains descriptive text.
m indicates that the line contains a selection of items, one of which is to be selected by the user.
n indicates that the line contains a selection of items, one of which is to be chosen by the user.
t indicates that the user may enter text.
f indicates that the user may enter a real number.
i indicates hat the user may enter an integer.

Except for the line containing descriptive text, each line is associated with a system variable. The variable name appears immediately after the line code. The line code determines variable type and the value that will be assigned at the conclusion of the editing session:

Character Meaning
m the variable is a text variable; it will be assigned the string corresponding to the selected item.
n the variable is a value variable; it will be assigned the ordinal number corresponding to the selected item.
t the variable is a text variable; it will be assigned the string that appears on the line.
f the variable is a value variable; it will be assigned the value that appears on the line.
i the variable is a value variable; it will be assigned the value that appears on the line.

Following the variable name is a string of display text. For menu lines, the last entry is the set of menu items. Initial values appear on the remaining lines.

Further information about the V-EDIT command can be found in the SilverScreen Reference Manual.

Multi-Language Applications: Tfiles

Support for multi-language applications through the use of tfiles. Typically the developer maintains a set of messages, prompts and other text used to communicate with the user. This text may be stored in a single file, the tfile, for access by message number. To move to another language, only the text in the tfile needs to be translated, preserving message numbers. By accessing different tfiles, the application can move readily back and forth among languages.

SilverScreen supports multiple language applications with a set of functions that allow the creation and use of external text files (tfiles). The tfile uses a text numbering system that associates each string of text with a number. By using the appropriate number, a line of text can be retrieved from the tfile.

Here is a description of the functions that support files:

tfile_make This function reads a text file and produces a tfile.
tfile_open This function opens a tfile and prepares it for text retrieval. If another tfile was open, it is automatically closed.
tfile_close This function closes the current tfile.
tfile_gets Using a text number, this function retrieves a text string from the current tfile.

These functions provide the ability to change language at any time. This is consistent with SilverScreen's ability to change languages at a single keystroke.

The tfile_make function permits developers to build their own tfiles from an input ASCII text file. The format of the input file is as follows:

1 First line of text
2 Second line of text
3 Third line of text
...

The syntax for the text file is:

  • All lines must begin with an integer (associated message number).
  • The integer must be followed by a single space and the message text.
  • The lines must be arranged in ascending sequence.
  • No breaks are permitted in the sequence.

The following is an example of how to use tfiles. Assume that there are two input text files: english.txt and spanish.txt ; we will call the resultant tfiles english.tf and spanish.tf .

To build the tfiles:

if ( ! tfile_make ( "english.txt", "english.tf" ) )
   // Error of some kind
if ( ! tfile_make ( "spanish.txt", "spanish.tf" ) )
   // Error of some kind

To start up in English:

char msg1[100];
if ( ! tfile_open ( "english.tf" ) )
   // Error of some kind
if ( ! tfile_gets ( msg1, 1 ) )
   // Error of some kind
display_text( msg1 );
. . .

To switch to Spanish:

char msg1[100];
if ( ! tfile_open ( "spanish.tf" ) )
   // Error of some kind
if ( ! tfile_gets ( msg1, 1 ) )
   // Error of some kind
display_text( msg1 );
. . .

To close out tfile usage:

tfile_close ();

Notice that there is no need to close a previous tfile before opening another -- that is done automatically by tfile_open .

Keyboard and Pointer

Keyboard and pointer events are handled in an event queue that is internal to SilverScreen. In a program, events are removed from the queue with the inchar function. The event may be a keystroke, a pointer movement, or a pointer button press. If the queue is empty when inchar is called, then the function waits until an event occurs.

A second function, nextkey, may be used to view the event that is at the front of the queue without removing this event. If the queue is empty, nextkey does not wait for an event to occur, but instead, returns 0.

The combination of nextkey and inchar can be used to clear the queue. First, nextkey checks to see if an event is in the queue. If so, then inchar is used to remove the event. Here is the code:

while ( nextkey () )
   inchar ();

Events handled in SilverScreen, both keys and pointer events, are defined in sskeys.h. This header file defines the function keys, the control keys, and the pointer button and motion events.

Programs are able to monitor the location of the arrow and to determine its location. Here are the functions:

pointer_mode sets the pointer mode
pointer_locate locates the arrow at a screen coordinate
pointer_char_locate locates the arrow at a position on a line
pointer_position returns the screen coordinates of the arrow
pointer_char_position returns the line and position of the arrow

The events received from the pointing device are dependent on a pointer mode that can be set with pointer_mode. There are three modes: 0, 1 and 2.

Mode 0 disables the pointer so that no pointer events occur. Mode 1 places the pointing device into key translation mode. When in this mode, pointer movement is translated to keyboard arrow movement, and certain button events are translated to keyboard keys. Mode 2 causes all pointer events to be returned. It is in mode 2 that pointer_locate and pointer_position functions are used.

The following section illustrates the use of several of the pointer functions:

pointer_mode ( 2 );
pointer_char_locate (20,20);
for ( ; ; )
   {
   switch ( inchar () )
      {
      case ESCAPE:
         ...
      case M_BOTH:
         ...
      case M_LEFT:
         pointer_char_position ( &line, &position );
         ...
      case M_RIGHT:
         pointer_char_position ( &line,&position );
         ...
      }
   }
}

The pointer is placed in mode 2, located at position 20 of line 20, and made visible. The program then reads events with inchar, identifying Esc from the keyboard and the three mouse events.

Executable Libraries

Executable libraries allow a consolidation of the various files that are included within an application. The following file types can be included in an executable library:

  • Script files (.SF)
  • Executable programs (.EX)
  • Custom menus (.CMF)
  • Icon drawings (.DRW)
  • ASCII text files

The notation "library>file" is used to refer to a file within a library. For example: iconlib>file1.

Script files and executable programs can be executed from a library with a command of the form:

execute libx>prog1

Custom menus can be loaded from a library with the menu function or with a command of the form:

custom-menu load libx>menu4

Icon menus can be displayed from a library using the icon, icon2, and display_icon functions. Icons can also be used in panel_icon, panel_icon2, pm_icon , and pm_icon2 .

Image files can be displayed from a library with a command of the form:

snapshot view screen libx>snap1

Direct Pointer Variables

The get_direct_pointer function is used to retrieve a direct pointer to the specified SilverScreen variable. Currently, the only variable supported is accessed by DP_LIGHT_LIST, which returns a pointer to the first LIGHT_NODE structure in a drawing (DP_LIGHT_LIST is defined in silver.h ; the LIGHT_NODE structure is defined in ss_nodes.h). See the get_direct_pointer in the Run-Time Library Reference.

Copy Protection

SilverScreen uses the Sentinel hardware lock. Each lock has a unique serial number that is recorded in the lock. The serial number can be accessed by the function get_version .

Developers are often faced with protecting new versions and upgrades of their software. The purpose of this section is to suggest a method whereby a developer may use the serial number of the hardware lock to secure their software.

The method involves computing a pass number based on the version number of the software and the serial number of the hardware lock. It assumes that the developer faithfully records the serial numbers of the packages on which their software is authorized to run. It also requires that the developer issue pass numbers with each release or update. These pass numbers are based on the serial number stored in the hardware lock.

Consider the following function:

int get_passnumber( int serial, int version )
{
int i;

for ( i = 1 ; i <= version ; ++i )
   serial *= 1315731;

return serial % 10000;
}

Based on a serial number and a version number, this function will generate a 5-digit pass number. For version 1, 2, ..., n, the function will generate a set of pass numbers that are seemingly unrelated to one another.

The mechanism for protecting the software is simple: Before the software is sent to the user, the developer records the serial number of the user's hardware lock. Using this serial number, and the version number of their software, the developer computes a pass number that he gives to the user.

When the user executes the developer's program, the program asks that the user enter a pass number. The program, using its access to the serial number, computes a pass number using the function shown above. If this number matches the number entered by the user, then access to the program is granted.

This basic approach can be enhanced by storing correctly entered pass numbers on disk. In this way, the user would be required to enter the pass number only once.

B-tree Databases

A b-tree database consists of two files: an index file and a data file. The index file is used to organize information that is stored in the data file. The index file contains a set of keys that are maintained in ascending sequence. Associated with each key is a record number. This record number identifies the record in the data file that is associated with the key.

The keys in the index file can be accessed sequentially or randomly. For a given key, the associated record number can be used to retrieve the data file information that is related to that key.

Two or more b-trees may be based on a single data file. This allows the information in the data file to be organized in several different ways. For a file containing employee information, one might construct one index to access employee information by employee number, while creating another index to access the information by employee name.

Here is a summary of the b-tree functions:

B-tree open, close and flush:

bt_open Open a b-tree
bt_close Close a b-tree
bt_flush Flush all b-trees to disk

File creation functions:

bt_create_data Create a data file
bt_create_tree Create an index file

Index file functions:

bt_delete Delete an entry
bt_find Find a key
bt_find2 Find key/record
bt_insert Insert a new entry
bt_next Retrieve the next entry
bt_previous Retrieve the previous entry
bt_set_first Set read marker to beginning of index
bt_set_key Set read marker to a specific key
bt_set_last Set read marker to end of index
bt_update Update an entry

Data file functions:

bt_erase Erase (remove) a record
bt_read Read a record
bt_store Store (create) a new record
bt_write Write (update) a record

B-trees are created by the bt_create_data and bt_create_tree functions. These functions create an empty data file and an empty index file respectively.

When a data file is created, the record size must be specified. If text information is to be stored, then record size should be the length of the longest possible string. If structure information is stored, then record size should be the size of the structure (sizeof <structure name>).

Before a b-tree can be accessed, it must be opened with bt_open. This function returns a b-tree handle. Index file functions use this handle to identify the index file, while data file functions use the handle to identify the data file. If two b-trees use a common data file, then either handle can be used to identify the data file.

Quick Advice

The purpose of this section is to describe a number of techniques that have proven themselves to be helpful in application development.

  • The hierarchical drawing structure is an important organizational tool. There is a strong relationship between the organization of the drawing and the organization of the information about the drawing. A block can be used to store information about the group of entities contained in the block. Information about an elementary entity can be stored with that entity.
  • Tags are a better means for storing information than schemas. They are faster to access and do not depend on an external library.
  • The names given to entities in a drawing are important. Suppose that a drawing consists of rooms where each room is a block. Further suppose that each room contains walls and doors, where each door is a block containing hinges, a doorknob and a panel.
  • If all of the doorknobs are given a common prefix, then a wildcard can be used to isolate doorknobs (i.e., to make doorknobs visible and all other entities invisible). If common prefixes are also used for the other entities, then it is a simple matter to make walls and doors visible and hinges and doorknobs invisible.
  • Consider the following sequence of commands:

sweep linear polygon \obj1.3 points 0,0,0 0,0,-10 name box
view select isometric front right top
zoom object \box
hide object \box hidden-line

When these commands are executed, the user would first see a sweep operation, followed by a change of view, followed by a zoom to the object, followed by hidden-line removal; probably a lot of unnecessary screen activity.

The control variable CV_REFRESH can be used with cv_set to control screen refreshes. When refresh is off, commands will execute without disturbing the contents of the screen. The following avoids unnecessary screen refresh:

cv_set (CV_REFRESH,0)
ss_command ( "sweep linear polygon \\obj1.3 points 0,0,0 0,0,-10 name box");
ss_command ("view select isometric front right top");
ss_command ("zoom object \\box");
cv_set (CV_REFRESH,1);
ss_command ("hide object \\box hidden-line");

  • It often occurs that an object of a certain type, say a doorknob, is to be picked by the user. The function to accomplish this is pick_entity. Unfortunately, pick_entity is not particularly clever. This function will pick the nearest visible object whether it be a doorknob or a light bulb.

    A nice solution is the following:

    cv_set ( CV_REFRESH, 0 );
    ss_command ("isolate object !knob*");
    if ( pick_entity ("Pick doorknob",E_OBJECT,path) )
       ...
    else
       ...
    ss_command ("isolate reset");
    cv_set (CV_REFRESH, 1 );

The trick is to isolate those objects that are candidates for selection without disturbing the screen. Once the pick has been made, isolation can be reset, again without disturbing the screen.

record_visibility is also a useful function in this context.

  • Many applications require a specific annotation environment. This can be handled by loading a private annotation environment.

 

Copyright

Copyright 1994-1999 by Schroff Development Corporation, Shawnee-Mission, Kansas, United States of America. All rights reserved.

 

Disclaimer of All Warranties and Liability

Schroff Development Corporation makes no warranties, either express or implied, with respect to this document or with respect to the hardware and software described in this document. Schroff Development Corporation does not guarantee, warrant or make any representation regarding the use of, or the results of the use of the information in terms of correctness, accuracy, reliability, or performance. Schroff Development Corporation assumes no liability for any direct, indirect, or consequential, special or exemplary damages, regardless of its having been advised of the possibility of such damage.