Engineering Sketch Pad (ESP) Version 1.09

Authors: John F. Dannenhoffer, III (Syracuse University) and Bob Haimes (MIT)

Date: August 2016.

0.0 Table of Contents

1.0 Overview

2.0 Tutorials

    2.1 First tutorial: Basic usage

    2.2 Second tutorial: Sketcher

    2.3 Third tutorial: Aircraft example

3.0 Command Line

4.0 Interactive Options

5.0 Format of the .csm and .udc Files

    5.1 Format of the .csm file

    5.2 Format of the .udc file

    5.3 Special characters

    5.4 Valid CSM statements

    5.5 User-defined Primitives shipped with OpenCSM

    5.6 Number rules

    5.7 Parameter rules

    5.8 Expression rules

    5.9 Attribute rules

6.0 Example .csm file

7.0 Frequently Asked Questions

8.0 Release notes

    8.1 New/extended features in v1.09

    8.2 Bug fixes since v1.08

    8.3 New/extended features in v1.08

    8.4 Bug fixes since v1.07

    8.5 New/extended features in v1.07

    8.6 Bug fixes since v1.06

    8.7 New/extended features in v1.06

    8.8 Bug fixes since v1.05

    8.9 Known problems in v1.09

9.0 Error Codes

    9.1 OpenCSM error codes

    9.2 EGADS error codes

10.0 Bug Reports and Other Feedback

11.0 Copyright

12.0 Glossary

1.0: Overview

The Engineering Sketch Pad (ESP) is a browser-based program for creating, editing, and generating constructive solid models for use in the multi-disciplinary analysis and optimization of engineered systems. It is built using a client-server architecture.

The server consists of a back-end program (serveCSM) that performs the majority of the computational work; the server has been designed to work on a variety of compute platforms, including UNIX, LINUX, OSX, and Windows. As will be described below, the user of ESP typically starts a session by starting the server.

The client, which is built within a web browser, provides the graphical user interface with which most users will provide inputs and receive outputs. The supported browsers include recent versions of FireFox, Google Chrome, and Safari. (Internet Explorer is not supported because of a bug within the WebSockets layer provided by the browser).

ESP is technically just the user-interface to a system of software packages, including:

All the parts of the ESP system are distributed as source code that is licensed via the LGPL 2.1 license. See the Copyright section below for details.

In most cases, a user will start with a configuration that is described in a .csm file and then modify it and/or build it via OpenCSM's various commands.

Back to Table of Contents

2.0: Tutorials

The following tutorials have been designed to walk a new ESP user through the basic capabilities that are available through the user interface. The tutorials have been designed to be executed in order, since latter tutorials assume that the user knows how to perform certain actions that were learned in an earlier tutorial. Additional information and examples can be found in the training section of the ESP distribution.

Users of ESP who do not plan on using the user interface are still encouraged to execute the tutorials, since many of the ideas used within OpenCSM (the underlying constructive solid modeler) are described in the tutorials.

2.1 First tutorial: Basic usage

This tutorial will help you understand the use of serveCSM and ESP for a variety of tasks. Details about the Command Line, cursor and keyboard options, and the Example .csm file are contained in sections that follow this tutorial.

The tutorial starts with a pre-made part that is defined by the file tutorial1.csm. (See Example .csm file below for a listing of this file.)

To start ESP there are two steps: (1) start the "server" and (2) start the "browser". This can be done in a variety of ways, but the two most common follow.

Technique 1: issue the two commands:

        setenv ESP_START "open -a /Applications/Firefox.app ../ESP/ESP.html"
        serveCSM ../data/tutorial1
      
if using a c-shell; make appropriate changes for your shell and/or operating system.

The first of these tells serveCSM to open FireFox on the file ../ESP/ESP.html when serveCSM has generated a graphical representation of the configuration. The second of these actually starts the serveCSM server. As long as the browser stays connected to serveCSM, serveCSM will stay alive and handle requests sent to it from the browser. Once the last browser that is connected to serveCSM exits, serveCSM will shut down.

Technique 2: issue the command:

         serveCSM ../data/tutorial1
       
Once the server starts, start a browser (for example, FireFox) and open the page ESP/ESP.html. As above, serveCSM will stay alive as long as there is a browser attached to it.

Note that the default "port" used by serveCSM is 7681. One can change the port in the call to serveCSM with a command such as:

         serveCSM ../data/tutorial1 -port 7788
       

Once the browser starts, you will be prompted for a "hostname:port" as in:

Most of the time, the "hostname" will be "Localhost" (meaning that serveCSM and the browser are on the same computer). It is possible to attach to serveCSM that is running on another computer by giving an appropriate "hostname".

As mentioned above, it is possible to change the "port" with a command line argument when starting serveCSM; if that is done, then the alternative "port" must be included in ESP's prompt.

Once all the setup is done, the browser then presents the following 4 windows:

The window on the top left is called the "Tree" window. At the top of this window is a series of buttons. Below that is a scrollable tree-like listing of the Parameters and Branches in the Model. It also contains the controls for the "Graphics" window.

The window on the top right is called the "Graphics" window, which contains one of the following:

The window on the bottom left is the "Key" window. Like the "Graphics" window, its contents will be one of:

The window on the bottom right is called the "Messages" window. It contains the messages that ESP posts for the user.

The first thing to do is to play with the image in the "Graphics" window. This is done with the mouse in the following ways:

It is suggested that you use the left or middle mouse button for these operations, since in most browsers the right mouse button will post a popup menu.

When using the mouse, it is possible to enter "flying mode", in which the view continually changes until the mouse button is released. Flying mode is particularly useful when one needs to translate a long distance. Toggling flying mode is done by pressing the "!" key in the "Graphics" window.

At any time, a user might want to "save" a view for later use in the browser session. This is done by pressing the ">" key in the "Graphics" window; the "saved" view can be retrieved by pressing the "<" key.

The default (home) view can be obtained by pressing either "<Home>", "<Ctrl-h>", "<Ctrl-f>", or the "H" button near the top of the "Tree" window. (The home view is one in which the x-coordinate increases from left to right and the y-coordinate increases from bottom to top.) One can also get the top view by pressing "<Ctrl-t>" or the "T" button, the bottom view by pressing "<Ctrl-b>" or the "B" button, the left side view by pressing "<Ctrl-l>" or the "L", or the right side view by pressing "<Ctrl-r>" or the "R" button.

The function of the arrow keys depends on whether "flying mode" is active or not. For example, if "flying mode" is not active (the default), pressing the "<Left>" key causes the object to rotate to the left by 30 degrees; if "flying mode" is active (because the "!" key was pressed), then pressing the "<Left>" key causes the object on the screen to translate to the left. If the "Shift" is held while the "<Left>" key is pressed, the increments are 5 degrees and the translations are also smaller.

The "<PgUp>" or "<Ctrl-i>" keys or the "+" button can be used to zoom in and the "<PgDn>" or "<Ctrl-o>" key or the "-" button can be used to zoom out. The behavior of these keys/buttons does not depend on the current "flying mode".

To re-center the image at a given point and simultaneously reset the point about which mouse rotations will occur, point to any location in the "Graphics" window and press "*"; the image will be recentered and a message will be posted in the "Messages" window.

To determine the identity of any object in the "Graphics" window, simply put your cursor on the object and press "^"; a summary of the identified object is shown in the "Messages" window. (Note that if the cursor is not exactly over any object, the message will only be posted once the mouse passes over a graphic object.)

To determine the approximate coordinates of any location in the "Graphics" window, simply put your cursor on the location and press "@"; the approximate coordinates of the location are shown in the "Messages" window.

Lastly, to get help on the commands that are available in the "Graphics" window, press "?" and a short listing will be given in the "Messages" window.

The results of several of these commands is shown in:

Now it is time to understand the "Tree" window. When not in the Sketcher (the default), at the top of the "Tree" window is a series of buttons:

One can verify the view with the little axes at the bottom-left corner of the "Graphics" window. The red axis corresponds to "x", the green axis corresponds to "y", and the blue axis corresponds to "z".

Below the buttons is a tree-like representation of the "Design Parameters", "Local Variables", and "Branches" that describe the current "Model". In all cases, pressing the "+" at the beginning of any line expands (opens up) that particular entry in the tree; pressing the "-" at the beginning of any line collapses (closes) that particular entry.

Start off by pressing the "+" to the left of the words "Design Parameters". When this is done, all the Design Parameters in the current Model are displayed as shown in:

Notice that the Design Parameter names are shown in green type; this indicates that the Parameter can be "edited" by the user; the Local Variable names are listed in black type and cannot be edited.

Press on the label "Lbar" to edit the Parameter named "Lbar". When this is done, the user is provided with an editing form that asks for the new value; the current value is pre-loaded in this window, as in:

For now change the value from "6" to "9" and press the "OK" button or press the "Enter" key. Note that the Parameter name is now listed in red (to indicate that it has been changed) and that the button at the top of the "Tree" window has changed to a green button that says "Press to Re-build". This tells the user that changes have been made (to either a design Parameter or feature tree), but that the configuration shown in the "Graphics" window has not been updated. (The reason this is done is that a user might want to make several changes to the "Model" before spending the CPU time necessary to re-build.)

Press the "Press to Re-build" button and notice that it first turns yellow while the configuration is being rebuilt. Then (after a few seconds) the image in the "Graphics" window will be updated and the "Design Parameters" will no longer be red.

We will now change the value of "Lbar" back to "6". (Do not re-build yet.)

Collapse the Parameters by pressing the "-" to the left of the word "Design Parameters" and expand the Branches by pressing the "+" to the left of the word "Branches". This will result in a screen that looks like:

There is an "Undo" button near the top of the "Tree" window. This button un-does your last change; an example of using this is shown later in this tutorial; for now, try not to use this button.

We are going to want to add a SPHERE to this configuration. Do this by pressing "Branches", giving you:

The different types of Branches that can be added are listed in groups. The groups at the top, which are labelled, generally construct or modify Bodys. The Branches listed at the bottom are utilities, which generally effect the order in which the Branches are executed. Those Branches marked with a star (*) are deprecated, meaning that they may be removed in future versions of ESP.

We will choose a SPHERE and press the "OK" button (or press the "Enter" key), giving us:

Now fill in the entries with "xcent" set to "1", "ycent" set to "0", "zcent" set to "0", and "radius" set to "2". An easy way to cycle through the various entries is to press the "Tab" key. Press the "OK" button (or "Enter" key) and then "Press to Re-build" and you should see:

Now let's look at the "Display" part of the "Tree" window. By default "Display" is expanded and you can see that you have two bodies named "Body 10" and "Body 9". Expand the listing for Body 9 by pressing the "+" to the left of "Body 9" and you will see entries for Faces and Edges. To the right of "Faces" (below "Body 9") you will see three items:

Try each of these and see what happens. (Notice that Body 9 is the original solid and Body 10 is the new sphere.)

Notice also that there is a "+" to the left of "Faces", which indicates that you can interact with the object on a Face-by-Face basis. The basic rules here are:

Now let's combine the sphere and the original solid by adding a UNION Branch. (Press "Branches" and add a UNION). This operation wants to know if the operation should be applied to the top two Bodys on the stack (tomark=0) or to all the Bodys on the stack since the last mark (tomark=1). For now, we want to use the default (tomark=0). Also, we want an untrimmed union (the default), and so set (trimList=0). Lastly, we do not want to modify the tolerances associated with this operation, so use the default (maxtol=0). Re-build the configuration and you should get the solid shown in:

Note that we now only have one body. (Body 11)

After some thought you realize that you really didn't want the union (or fusion) of these two volumes, but instead you wanted the solid that is common to them (that is, their intersection). First, remove the UNION; this can easily be done by clicking on "Brch_00012" and then choosing "Delete this Branch". (Alternatively you could press the "Undo" button at the top of the "Tree" window; but if you use "Undo" the Branch numbering will be slightly different, making it slightly more difficult to follow the directions in this tutorial.)

Now add the intersection by pressing "Branches" and then choosing INTERSECT. This operation wants to know what happens if more than one solid is produced by the operation. Specifically, the "$order" argument describes how the bodies that are produced should be ordered: for example in order of volume, surface area, ... The "index" argument tells which body in the list should be selected. Since we are only expecting one body to be produced, we can leave the defaults. Also, for now we do not want to modify the tolerances, so leave the default (maxtol=0) and then "Press to Re-build", producing:

You notice that the "head" is too thin, and so you change the "radius" of the SPHERE to "2.3". (Press "Brch_000011" and change the "radius".) While you are at it, change the Parameter "Rbar" to "0.4" (you will need to expand the Design Parameters) and rebuild, producing:

Now we want to drill a hole through the center of the shaft; this is done by subtracting a cylinder from the solid. Create a cylinder by selecting "Branches" and CYLINDER. We want the hole to go the entire length of the configuration (which is centered and whose length is 2*L), and so we enter "-1.2*L" for "xbeg" and "+1.2*L" for "xend"; the "1.2" simply ensures that the cylinder extends beyond the end of the configuration. Since it is on the centerline, set "ybeg", "zbeg", "ybeg", and "yend" all to "0", and finally the "radius" to "0.2".

Note that any argument can either be entered as a numeric constant or as an expression (using Matlab-like syntax), possibly using the name of a Design Parameter (such as "L") or a Local Variable.

To add the SUBTRACT Branch, we will click on "Branches" and then choose SUBTRACT, use the defaults and rebuild, producing:

Now we want to create a series (pattern) of small holes that are drilled across the shaft. Start by creating a new Parameter (by clicking on "Design Parameters") and name it "Rhole". The rules for names is that they must start with a letter and contain up to 32 letters, digits, and underscores. By default the new "Design Parameter" contains only one value (that is, it is a scalar). (Aside: If one wants a row vector, a column vector, or a 2D matrix, press the "Add row" or "Add column" button before entering values in the table.)

Since we only want a scalar, just use the standard form, such as:

Set the (only) value to "0.08". You can either press the "OK" button or press the "Enter" key to save this value.

Now we are going to add a pattern of holes. Do this by adding a new PATBEG Branch; the "$pmtrName" will be "i" and the "ncopy" will be 7 (since we want 7 holes). (The "$" at the beginning of "$pmtrName" says that this is the name of the Parameter that will be created rather than the value of the Parameter "i"). This will produce a warning in the Messages window that informs us that we do not yet have a matching PATEND Statement yet.

Also add a CYLINDER with "xbeg" and "xend" set to "i/3", "ybeg" and "yend" set to "0", "zbeg" set to "-1", "zend" set to "+1", and "radius" set to "Rhole". Press "OK" or "Enter". Again you will get the warning telling you that you still do not have a matching PATEND.

We would now like to name this Branch. To do this, edit the Branch (by pressing "Brch_000017") and change its "Name" to "small_holes". (Notice that we could not name it when we created it since the names are originally auto-created to ensure that we do not get an illegal name.)

Next add another SUBTRACT Branch (with the default arguments) and finally a PATEND Branch and then re-build (which will take several seconds), giving:

Now we want to change the hole in the center of the shaft into a hole that starts at "xbeg" equal to "0". Make the change to "Brch_000014" and re-build. To see if you were successful, change the visibility of the faces and ensure that you have the correct hole, as in:

Now change the cylindrical hole into a conical hole. To do this, we must delete the cylinder hole (which is Brch_000014). Click on "Brch_000014" and choose "Delete this Branch". Notice that doing this warns you that the Branches are not properly nested. To fix the error, add a conical hole after "Brch_000013" by clicking "Brch_000013" and choosing "Add new Branch after this Branch", as in:

Re-build and notice that the vertex of the cone is near the head; you will have to change the visibility of the Faces to see this. We had meant to do it the other way, so change "xvrtx" to "0" and "xbase" to "1.2*L" and re-build, producing (after manipulating the display):

By now you probably have noticed that the Branches with a pattern (that is, between the PATBEG and PATEND) are hidden; to see these, press the - to the left of Brch_000016. Now let's rotate the small holes, so after the "small_holes" Branch, add a ROTATEX with arguments "-15*(i-1)", "0", and "0", and rebuild, producing:

Now we will experiment with the "activity" of the Branches. A Branch that is "suppressed" is skipped during the re-build process. So click on the "small_holes" Branch (you will need to expand the listing of the pattern first) and change the "Activity" from "Active" to "Suppressed", and select "OK" or press "Enter". Note that a few other Branches become "inactive" (since they cannot be executed). Re-build, producing:

Now similarly suppress "Brch_000021" and activate "small_holes" and re-build. Note that the hole re-appeared but that the ROTATEX is not executed. Finally, re-activate all Branches and re-build.

Another feature is ESP allows a user to only build part of the configuration. This is done by clicking on a Branch (for example, "Brch_000010") and choosing "Build to this Branch", giving:

To rebuild the whole configuration, either re-build to the last Branch by clicking it and choosing "Build to this Branch" or press the "Up to date" button (which will ask if you are sure before regenerating the configuration).

The next part of the ESP tutorial involves Attributes. Each Branch can have zero or more Attributes associated with it that are carried throughout the build process. Open the "Brch_000009" Branch for editing and press "Show Attributes/Csystems". You will see that this Branch has an Attribute ("clipper") that has the value "1". Change the Attribute to "10", and press OK.

We can add an Attribute to "Brch_000009" by editing it, pressing "Show Attributes/Csystems", and then "Add Attribute/Csystem". The first choice is whether we want to add an Attribute or a Csystem; we want to enter "1"; we will use the name "test" and the value "ESP". After some thought, you realize that "ESP" is not defined (that is, does not have a value), so you can "undo" this change by pressing the "Undo" button at the top of the "Tree" window. Re-build.

Now point to the face that represents the corner of the head (as shown with its grid here) and press the "^" key, producing:

(Depending on the version of OpenCASCADE that you are using, the face number that is returned may be different.)

Note that the "Messages" window contains a description of the face including the Attribute that we edited ("clipper" is "10") as well as a "body" and "brch" Attribute. The latter tells which Branch ("Brch_000009") was responsible for generating that face.

A unique feature of ESP is that it allows a user to compute the sensitivity of the configuration with respect to any perturbation in the specified Parameters. Most often this is done by clicking on a the name of one of the Design Parameters and selecting "Compute Sensitivity".

For the current case, expand the Parameters list (in the Tree window) and click on "Rbar" and select "Compute Sensitivity". ESP notes this by putting a caret before the "Rbar" and then will automatically compute the sensitivity and display, in the Graphics window, an updated configuration that is colored based upon the change in the local surface normal; positive sensitivity indicates that the surface will tend to move in the direction of the outward normal. The Key window will show the meanings of the various colors and will be titled "d(norm)/d(Rbar)", as in:

To change the limits of the color spectrum, left click in the Key window and you will be prompted for the minimum value (associated with blue) and the maximum value (associated with red). Try clicking on the Key window and set the limits to "-0.5" and "+0.5" and see how the display changes.

Now ask for the sensitivity with respect to "D" (click on "D" and select "Compute Sensitivity") and again the display will automatically update.

Occasionally one wants to know the change in the configuration based upon the perturbation of more than one Parameter (at the same time). To do this, first clear all the Design Velocities by clicking on any Design Parameter and choosing "Clear Design Velocities", and then "Set Design Velocity" to 1 and then click on "Rhole" and "Set Design Velocity" to 1.5. Now manually re-build the configuration (since you may want to set the Design Velocity for multiple Parameters before rebuilding). Note that the legend in the Key window will now be "d(norm)/d(***)", indicating that there was either more than one Design Parameter for which the Design Velocity was set (see that Rbar and Rhole both are prepended with a caret to indicate this), or there is one Parameter whose Design Velocity is not unity (and hence the color does not show sensitivity but rather a scaled sensitivity.)

Lastly, save your work by pressing the "Save File" button and entering "tutorial1_new.csm" as the name of the new file. Exit the browser and you should see that serveCSM also shuts down.

If we now rename the file journal file (which was automatically generated while you were running ESP) with:

        mv port7681.jrnl tutorial1.jrnl
      
we can replay our session by the command:
        serveCSM ../data/tutorial1 -jrnl tutorial1.jrnl
      
This replays all your operations, so it may take a while to execute.

Alternatively, we can start with the new tutorial1_new.csm file (which we just created above) with the command:

        serveCSM tutorial1_new
      
This will run more quickly since it simply executes the final feature tree (of Branches).

This tutorial covered most of ESP's user interface. Further details are contained in the sections that follow.

2.2 Second tutorial: Sketcher

For the second tutorial, we will start serveCSM without a .csm file and investigate the use of the Sketcher.

Start ESP by issuing the command:

        serveCSM
      

If you have not set the ESP_START environment variable, you will have to open a browser on a file named ../ESP/ESP.html and select the default hostname and port (Localhost:7681). A blank ESP should open up for you.

We are going to start with an empty sketch. To do this we will first add a SKBEG Branch by pressing "Branches", selecting a SKBEG, and making the "x", "y", and "z" all zero. The final argument, relative, is set to 1 to indicate that all coordinates in the sketch are relative to the coordinates that were contained in the SKBEG statement.

(New in v1.08) When a SKBEG Branch is added, ESP now automatically adds the matching SKEND Branch and automatically enters the Sketcher.

There are several changes between normal 3D mode and the Sketcher. The first difference are the buttons on the top of the "Tree" window. The first button now has the legend "Drawing...", the "Edit" button now has the legend "Quit", and the Save button has the legend "Save Sketch". The second major difference is that the "Key" window now lists the Sketcher's status, in terms of the number of degrees of freedom (ndof) and the number of constraints (ncon). This is followed by a listing of the available commands in the Sketcher.

Within the Sketcher (which is displayed in the "Graphics" window), there is a point at the center that has the legend "XY" and a blue line between that point and the current cursor location. As you move the cursor around in the Sketcher, you will notice that the blue line follows the cursor. You will also notice that if the line is approximately horizontal or vertical, it will change from blue to orange; this is an indication that if the current cursor location is chosen (see below), an implicit "horizontal" or "vertical" constraint will be created.

As you can see in the "Key" window, you have 6 choices:

If you just press the mouse button, the "l" option will be chosen for you. So now, draw the sketch shown in:

in a counter-clockwise direction, starting at the point with the label "XY". Make sure that when you have completed the closed sketch, the last point should be the same as the first point. You can ensure this by noting that a circle is placed around the first point if the last point is "close enough".

Notice that several of the line segments have either the letter "H" or "V" associated with them. These "horizontal" or "vertical" constraints were automatically added for you since you pressed "l" or the mouse button when the line was orange. Also notice that since you "closed" the sketch, it got filled in with grey. (If you had left it open by pressing the "o" key, there would be no filling.)

Your completed sketch should now have 16 degrees of freedom (since there are 8 points and no arcs) and 10 constraints. To see what the meaning of the various constraint letters are, notice that the "Key" window has now changed to explain the meaning of the constraints. In summary, at the first point, both the "x" and "y" coordinates are fixed. The other constraints are that certain line segments are either constrained to be horizontal (H) or vertical(V).

Since the number of constraints is fewer than the number of degrees of freedom, we will have to add more constraints. We can do this by:

Since the number of constraints matches the number of degrees of freedom, the grey fill has changed to a light green fill and the first button has turned green with the legend "Press to Solve". Press that button and (hopefully) your sketch will solve. (If it does not, you can always remove constraints by moving the cursor over the constraint and pressing "<", which deletes selected constraints at that point or on that segment.) To center the image, either press or press the "H" button. You screen should look like:

We are now finished with the Sketcher (for now), so press "Save Sketch" to return to the normal 3D view. You can now press "Press to Re-build" to rebuild the 3D object, giving a screen that looks like:

You will notice that we hard-coded dimensions into our sketch. To make the sketch more useful, it would be convenient to drive it with Design Parameters. To do this, we first have to create them. This is done (as in tutorial 1) by pressing "Design Parameters" in the "Tree" window, entering "length" as the Parameter name and setting its value to "4".

In a similar way, create a "height" Design Parameter whose value is "3" and a "thick" Design Parameter whose value is "0.5".

Now, let's use these Design Parameters in the sketch. To do this, choose one of the statements between the SKBEG and SKEND. I suggest choosing "Branch_00003", which is the SKVAR statement (which shows the default locations of each of the sketch points). Select "Enter Sketcher".

We are now going to change the various "L" constraints, by moving the mouse over the "L", pressing "L" and entering the new value. Specifically, you should change the "L" constrains as follows:

"Press to Solve", giving:

"Save Sketch" (to exit the Sketcher) and "Press to Re-build" to use the latest changes.

Think about what we have done. We have made a U-shaped channel whose overall length and height were given, and whose channel walls were all set to "thick". Suppose instead that the "design intent" of the channel was to create a channel of a given slot width. In this case, we would want to constrain the sketch differently.

Start by creating a Design Parameter named "slot" whose single value was "1". Now select "Branch_000028" and "Enter Sketcher". We are going to have to remove the "L" constraints from the top two horizontal segments, so go to each and press "<". Since there are two constraints here, you are asked which constraint to remove. Simply enter "L" at the prompt and the length constraint will be removed by the horizontal constraint will remain. If you want to remove all constraints, press "<" multiple times.

Now move the mouse over the horizontal segment at the bottom of the slot and press "L" and set the length to "slot". You will notice that the sketch is under-constrained (is grey). We need to add a constraint that the slot is centered. To do this, we are going to make the lengths of the two small horizontal segments near the top on each side of the U equal to each other. The first step here is to identify one of the segments. This is done with the "?" command. So, move the cursor over the top-left horizontal segment and press "?". You will notice in the "Messages" window that this is segment 7. Now move over the top-right horizontal segment and enter the length "::L[7]", which tells it to use the same length as segment 7. "Press to Solve" to give:

"Save Sketch" and "Press to Re-build".

Now open the list of Design Parameters (using the "+" to the left of "Design Parameters") and change the value of "slot" to "2". "Press to Re-build" to see the effect of this change.

We will now experiment with some of the other constraints. Specifically we will be removing some of our "H" and "V" constraints and instead add constraints at some of the points. Re-enter the Sketcher and move the cursor over the right-hand segment, press "<" to remove the vertical constraint. Similarly remove the horizontal constraint from the top-right horizontal segment.

The sketch is under-constrained (is grey). We are going to add a perpendicularity constraint at the point at the lower-left corner by moving the mouse over the point and pressing "P". Just to be different, at the top-right point we are going to add an "angle" constraint by pressing "A" and adding a value of "90".

"Press to Solve" and "Save Sketch".

We are now going to extrude the sketch into a solid. This is done by first creating a Design Parameter named "depth" and giving it a default value of "3". Then add an EXTRUDE Branch, whose arguments are "dx"="0", "dy"="0", and "dz"="depth". This will extrude the sketch in the "z" direction (out of the screen). "Press to Re-build", yielding:

As with most programs, it makes sense to periodically save your work, so press "Save File" and save the current model in a file named "../data/tutorial2". (Note that the ".csm" suffix will automatically be added for you.)

To see the .csm file associated with the current model, press the "Edit" button. At the top of the file, all the Design Parameters are defined (along with their current values). This is followed by the Branches in the feature tree. Note the the sketch starts with a SKBEG statement. This is followed by a SKVAR statement that specifies the initial locations of the various points in the sketch. (These positions were automatically set up for you when you drew the sketch). Following that , there is a series of SKCON statements that define the various constraints in the Sketcher. The first argument of each SKCON statement is the constraint type (which corresponds with the letters in the Sketcher), followed by the point (or segment) number and the value; again these were automatically set up for you when you drew the sketch and constrained it. This is then followed by a series of LINSEG Branches, which say that our current sketch is made up of a series of line segments. Again the number of the points to use in the LINSEG Branches was set up automatically for you.

Press "Cancel" to exit the editor and return to the normal view.

We are now going to create another sketch, which will be used to cut a hole in the bracket's left upright. This cut will be parametrized with a Design Parameter named "rad" whose sole value is "0.5". (You can create that now.)

Now we want to create a new sketch. We do this by adding a SKBEG Branch (with all "0" arguments).

The sketch that we are going to create consists of a race-track-shape curve, as shown in:

This is done with the following actions. Draw a horizontal segment off to the right (make sure the line from the last point is drawn in orange) and press "L" (or click the mouse) to create the first horizontal segment. Then move the mouse up and press the "C" key to create a circular arc segment. When you have done that, the segment that you just created turns red and follows the cursor; move the cursor and see how it changes. Once it is located at approximately the correct location, press the mouse button. Then sketch the horizontal line segment to the left, a circular arc on the left end, and finally a line segment back to the original point.

You might be wondering why the bottom of the racetrack was created with two LINSEGs. The reason is that we are ultimately going to want to center the sketch on the left-leg of the bracket, so having a point at the "center" of the sketch will be convenient.

We are now going to constrain the sketch as follows:

"Press to Solve", zoom in (using the "+" button) and center the sketch in the window (using the "H") button, yielding:

"Save Sketch" and "Press to Re-build". If you turn the configuration around, you will see the sketch at the back left bottom corner, as in:

We want to rotate this to be parallel with the y-z plane by adding a ROTATEY Branch (with arguments "90", "0", "0"), move it to its proper location by adding a TRANSLATE Branch (with arguments "0", "height-3*rad", and "depth/2"). If you "Press to Re-build" you will see that the sketch is now properly positioned. We can then add an EXTRUDE Branch (with arguments "length/2", "0", and "0") and finally subtract that new volume by adding a SUBTRACT Branch (with the default arguments). If you "Press to Re-build", you should get:

Now we will add a chamfer at the edges of the cut-out that the just made. Add a Design Parameter named "filrad" whose sole value is "0.1" and a new CHAMFER Branch whose arguments are "filrad" and "0" (meaning all Edges). "Press to Re-build", yielding:

We are now going to make another cut-out for the right leg of the bracket. As usual, make a SKBEG Branch (with all zero arguments). The figure that we want to sketch looks like:

To make this, start by drawing a horizontal line segment to the right (by pressing the "L" key). We are now going to set the control points for a Bezier curve. Do this by moving the cursor horizontally to the right (remember to look for an orange line), and pressing "B". We then continue to add two "B"'s along the top and a "B" to the left of the original point. Finally move the cursor over the original point (the one labeled "XY") and press "L".

You can put the cursor over any of the points and "drag" it to a new location. This movement will effect the display, but will likely be over-written when the sketch is ultimately solved.

Constrain the sketch as follows:

"Press to Solve", "Save Sketch", and "Press to Re-build". You should see:

Again, we want to rotate and translate the sketch, extrude it, and subtract it, by adding the Branches:

"Press to Re-build", giving:

Finally, we want to modify the original bracket to put fillets along the bottom of the slot. To do this, we have to go back and add a FILLET Branch immediately after the EXTRUDE that created the bracket. If we look back through the feature tree, we see the first EXTRUDE is at "Branch_000103". (To verify this, select "Branch_000103" and "Build to this Branch"). We are going to want to add a FILLET statement after this Branch, but first we must determine the identity of the Edges that we want filleted. To do this, press the "+" to the left of the Body (near the bottom of the "Tree" window), turn the visibility of the Faces off (press "Viz" to the right of Faces), and query the two Edges shown in:

Identifying them is done by pressing "^" over the two Edges. (In the picture above, these Edges were identified for you by turning their "Grd" on before capturing the screen; these Edges will likely not be highlighted on your screen.) You will notice in the "Messages" window that the Branches have an "edgeID" set to "11 6 11 7 1" and "11 7 11 8 1". This means (for example) that the first Edge was created at the intersection of Faces 6 and 7 of Body 11.

We can now create the FILLET Branch (edit "Branch_000103" and press "Add new Branch after this Branch"), with arguments "filrad" (which was set above for the CHAMFER) and "6;7;7;8;" (which selects the Edges between Faces 6 and 7 and between 7 and 8. "Press to Re-build", giving:

Finally, we might want to see the sensitivity of this configuration with respect to some of the Design Parameters. This is done exactly as in the first tutorial (by selecting a Design Parameter and pressing "Compute sensitivity").

We can now save our .csm file by choosing "Save File" with the filename "../data/tutorial2". Close the browser and serveCSM should close automatically.

2.3 Third tutorial: Aircraft example

For the third tutorial, we will start serveCSM with the file data/tutorial3.csm, which represents a fighter-like aircraft using blends and ruled surfaces.

Start serveCSM with commands such as

        serveCSM ../data/tutorial3
      
After a few minutes, the following will appear:

We are going to modify this case by using the "Edit" button. Pressing it gives:

Listed in the "Graphics" window is a listing of the tutorial3.csm file. We will dissect this file in a few minutes. But first, edit the file by adding the following after line 2:

        # this is an added line
      

If you now press the "Cancel" button, the change you made will not be saved and the original aircraft picture will appear. To see this, press the "Edit" button again and you will see that we have the original tutorial3.csm file. Now edit the file by adding the following after line 2:

        # this is another added line
      
When we press the "OK" button, you will be asked if you want to over-write the original file. Press "OK" to this question and then the file will be updated and the configuration will rebuild with the updated file. (This happens now even though the changes were inconsequential because all we did is added a comment.)

Now add a new Design Parameter called "xyz" that has 1 row and 3 columns, with the values "11", "22", and "33". (Recall that this done by clicking on "Design Parameters" in the "Tree" window.)

If we try to "Edit" the file again, ESP will inform you that you made changes interactively and that you must save those changes first. Press the "Save" button and give the new file the name "foo".

If you now press "Edit", you will see that the new current file is foo.csm. You will also see that this file is formatted differently from your original tutorial3.csm file. For example, the arguments in foo.csm are not nicely spaced as they were in the original tutorial3.csm file. As a result, you will probably find it easier to only make changes via the user interface (as you did in tutorial 1) or to edit the file directly using the "Edit" button. You can now "Cancel" out of the editor, bringing back the picture of the airplane.

In addition to understanding how to "Edit" .csm files, this tutorial also describes best practices when writing a .csm file. So let's now dissect the original tutorial3.csm file.

As a good practice, it is suggested that you add comments to the top of the file, such as:

        # tutorial3
        # written by John Dannenhoffer
      

This is then followed by the Design Parameters. Those that describe the fuselage are given by:

        # design parameters associated with fuselage
        #                      x      y    zmin   zmax
        dimension fuse      15  4  1
        despmtr   fuse     " 1.00; -0.40; -0.20;  0.20;\
                             2.00; -0.60; -0.30;  0.50;\
                             3.00; -0.60; -0.30;  0.80;\
                             4.00; -0.60; -0.30;  1.20;\
                             5.00; -0.60; -0.20;  1.20;\
                             6.00; -0.60; -0.10;  1.00;\
                             7.00; -0.60;  0.00;  0.80;\
                             8.00; -0.50;  0.00;  0.70;\
                             9.00; -0.40;  0.00;  0.60;\
                            10.00; -0.30;  0.00;  0.60;\
                            11.00; -0.30;  0.00;  0.60;\
                            12.00; -0.30;  0.00;  0.60;\
                            13.00; -0.30;  0.00;  0.60;\
                            13.90; -0.30;  0.00;  0.60;\
                            14.00; -0.30;  0.00;  0.60;"

        dimension  noseList 2  4  1
        despmtr    noseList "0.20; 0; 1; 0;\
                             0.10; 0; 0; 1"
      
Here, fuse is a 15 row, 4 column, Design Parameter with the given values. The values are listed across rows, with semi-colons between the various entries. Since spaces are used to enhance readability, the entire list of values is placed between quotation marks. Also, since the inputs are split across multiple lines, the backslash character is used to denote that the next line should be concatenated with the current line before processing; all characters starting at the backslash are ignored. The noseList Design Parameter has 2 rows and 4 columns. (More on the use of these Design Parameters below.)

The Design Parameters that describe the wing, horizontal and vertical tails are given by:

        # design parameters associated with wing
        despmtr   series_w  4409

        dimension  wing     3  5  1

        #                     x       y      z   chord  angle
        despmtr    wing    " 4.00;  0.00;  0.20;  6.00;  0.00;\
                             7.00;  1.00;  0.20;  3.00;  0.00;\
                             9.00;  4.60;  0.10;  1.00; 20.00;"

        # design parameters associated with htail
        despmtr   series_h  0406
        despmtr   xroot_h  12.10
        despmtr   zroot_h   0.20
        despmtr   aroot_h   0.00
        despmtr   area_h    7.28
        despmtr   taper_h   0.55
        despmtr   aspect_h  3.70
        despmtr   sweep_h  25.00
        despmtr   dihed_h   3.00
        despmtr   twist_h   2.00

        set       cbar_h    sqrt(area_h/aspect_h)
        set       span_h    cbar_h*aspect_h
        set       croot_h   (2*cbar_h)/(taper_h+1)
        set       ctip_h    taper_h*croot_h
        set       xtip_h    xroot_h+(span_h/2)*tand(sweep_h)
        set       ytip_h    span_h/2
        set       ztip_h    zroot_h+(span_h/2)*tand(dihed_h)
        set       atip_h    aroot_h+twist_h

        # design parameters associated with vtail
        despmtr   series_v  0404
        despmtr   xroot_v  11.20
        despmtr   zroot_v   0.50
        despmtr   area_v    9.60
        despmtr   taper_v   0.30
        despmtr   aspect_v  3.00
        despmtr   sweep_v  45.00

        set       cbar_v    sqrt(area_v/aspect_v)
        set       span_v    cbar_v*aspect_v
        set       croot_v   (2*cbar_v)/(taper_v+1)
        set       ctip_v    taper_v*croot_v
        set       xtip_v    xroot_v+(span_v/2)*tand(sweep_v)
        set       ztip_v    zroot_v+span_v/2
      

Notice the SET statements that compute Local Variables in terms of the Design Variables. For example, the mean-chord of the horizontal tail (cbar_h) is computed as the square-root of the ratio of the tail area and the tail aspect ratio.

Now we are going to build the fuselage. This will be done using by blending data from various cross-sections. The sections that will ultimately be blended are those create after the previous MARK. Creating the mark is done with the code:

        # build the fuselage
        mark
      

We want to begin the fuselage at a point. This is accomplished by using a Sketch with only one entry, such as:

        skbeg     0  0  0
        skend
      
This creates a point at the origin.

Then we need to generate the remaining 15 cross-sections. This is done with a "pattern" (similar to a "for" loop in MATLAB):

        patbeg    i  15
           udprim ellipse   ry  abs(fuse[i,2])  rz  (fuse[i,4]-fuse[i,3])/2
           translate        fuse[i,1]  0            (fuse[i,4]+fuse[i,3])/2
        patend
      
Within the pattern we create an ellipse (using the "ellipse" user-defined primitive) with its Parameters taken from the second, third, and fourth columns of the fuse Design Parameter. Each cross-section is then translated into its final position using the TRANSLATE statement. The patend statement closes the pattern. (Although not used here, it is possible to enclose patterns within patterns.)

Finally we will generate the fuselage by blending the point and 15 sections (everything since the mark) using:

        blend     noseList
      

At this point it is worth looking into the noseList. The first four entries (the first row) contain the nose radius in the direction specified (in this case, "0,1,0", which is a vector in the "y"-direction). The next four entries contain the nose radius in the "0,0,1" direction (which is the "z"-direction). Similar coding would be used at the tail if a tailList had been specified as the second argument in the BLEND command.

The wing is built in a similar manner using a ruled surface. The code here is:

        # build the wing
        mark

        udprim    naca      Series    series_w
        rotatez   -wing[3,5]   0   0
        rotatex   90           0   0
        scale     wing[3,4]
        translate wing[3,1]    -wing[3,2]   wing[3,3]

        udprim    naca      Series    series_w
        rotatez   -wing[2,5]   0   0
        rotatex   90           0   0
        scale     wing[2,4]
        translate wing[2,1]    -wing[2,2]   wing[2,3]

        udprim    naca      Series    series_w
        rotatez   -wing[1,5]   0   0
        rotatex   90           0   0
        scale     wing[1,4]
        translate wing[1,1]    wing[1,2]   wing[1,3]

        udprim    naca      Series    series_w
        rotatez   -wing[2,5]   0   0
        rotatex   90           0   0
        scale     wing[2,4]
        translate wing[2,1]    +wing[2,2]   wing[2,3]

        udprim    naca      Series    series_w
        rotatez   -wing[3,5]   0   0
        rotatex   90           0   0
        scale     wing[3,4]
        translate wing[3,1]    +wing[3,2]   wing[3,3]

        rule
      
Notice here that instead of using a pattern, the five sections were explicitly created; this was done to ensure that the left and right wings were the same. Also note that the naca user-defined primitive was used to generate the cross-sections.

The next statement:

        union
      
combines the fuselage and wing into a single Body.

The code for the tails is:

        # build the horizontal tail
        mark

        udprim    naca      Series    series_h
        rotatez   -atip_h   0         0
        rotatex   90        0         0
        scale     ctip_h
        translate xtip_h   -ytip_h    ztip_h

        udprim    naca      Series    series_h
        rotatez   -aroot_h  0         0
        rotatex   90        0         0
        scale     croot_h
        translate xroot_h   0         zroot_h

        udprim    naca      Series    series_h
        rotatez   -atip_h   0         0
        rotatex   90        0         0
        scale     ctip_h
        translate xtip_h    ytip_h    ztip_h

        rule
        union

        # build  the vertical tail
        mark

        udprim    naca      Series    series_v
        scale     croot_v
        translate xroot_v   0         zroot_v

        udprim    naca      Series    series_v
        scale     ctip_v
        translate xtip_v    0         ztip_v

        rule
        union
      

The tutorial3.csm file completes with the statement:

        end
      
Although such a statement is not required, it is good practice to use it.

Feel free to experiment by modifying this file.

Back to Table of Contents

3.0: Command Line

To start serveCSM, one uses the command:

        serveCSM [casename[.csm]] [options...]
           where [options...] = -addVerify
                                -batch
                                -dict dictname
                                -egg eggname
                                -help  -or-  -h
                                -jrnl jrnlname
                                -outLevel X
                                -port X
                                -printBreps
                                -sensTess
                                -tessFact factor
                                -verify
                                -version  -or-  -v  -or-  --version
      

The -addVerify option tells to write a .csm_verify file that contains information about the Bodys on the stack. This information can be used in a subsequent call (using the -verify flag) to verify that the results are "close enough" to a previous run.

If the -batch option is given, serveCSM is started without any graphical user interface. This option is useful for regenerating configurations as part of a bigger process, such as for testing or within an MDAO environment.

The -dict option tells serveCSM to read the dictname file to define constant Parameters that should be defined before the configuration is built. The format of the dictname file is a series of lines, where each line contains a constant name and a value, separated by white space; these Parameters are defined after the .csm is read but before it is executed.

The -egg option tells serveCSM to use the eggname external grid generator instead of the built-in EGADS tessellator.

The -help option produces a listing of the command line options.

The -jrnl option is useful for replaying a previous session. This journal file is an ASCII file that can be created with any text-editor. But more typically, a user modifies the portX.jrnl file that is automatically produced every time serveCSM is started. (Note: be sure to copy and/or rename this file before using it as an input to serveCSM, since the next serveCSM will overwrite this file.)

The -outLevel option sets the level of output (0 to 3) that the server should produce during its execution. Higher numbers are useful for debugging and should seldom be used by most users.

The -port option tells serveCSM with which port to connect. If a port other than the default is used, be certain to use that same port number in ESP's initial prompt.

The -printBrep option tells serveCSM to print a summary of the boundary representations (BReps) of the Bodys on the stack. This information can be useful when debugging a user-defined primitive or the code.

The -sensTess flag allows a user to select "configuration" sensitivities instead of the (default) "tessellation" sensitivities.

The -tessFace flag specifies that the Edge lengths and sag in the EGADS tessellation that is produced is factor as big as the default.

The -verify is typically used during testing to verify that the Bodys that are produced "match" those that were produced when the -addVerify flag was used. It does this by actually checking the ASSERT Branches whose verify option is set to 1.

The -version flag is used to print version information for the user.

Back to Table of Contents

4.0: Interactive Options

The tutorial (above) gives an overview of nearly all the interactive commands that are available in ESP. Future versions of this document will add more details here.

Back to Table of Contents

5.0: Format of the .csm and .udc Files

5.1: Format of the .csm file

The .csm file contains a series of statements.

If a line contains a hash (#), all characters starting at the hash are ignored.

If a line contains a backslash, all characters starting at the backslash are ignored and the next line is appended; spaces at the beginning of the next line are treated normally.

All statements begin with a keyword (described below) and must contain at least the indicated number of arguments.

Any CSM statement can be used except the INTERFACE statement.

Blocks of statements must be properly nested. The Blocks are bounded by PATBEG/PATEND, IFTHEN/ELSEIF/ELSE/ENDIF, SOLBEG/SOLEND, and CATBEG/CATEND.

Extra arguments in a statement are discarded. If one wants to add a comment, it is recommended to begin it with a hash (#) in case optional arguments are added in future releases.

Any statements after an END statement are ignored.

All arguments must not contain any spaces or must be enclosed in a pair of double quotes (for example, "a + b").

Parameters are evaluated in the order that they appear in the file, using MATLAB-like syntax (see 'Expression rules' below).

During the build process, OpenCSM maintains a LIFO 'Stack' that can contain Bodies and Sketches.

The csm statements are executed in a stack-like way, taking their inputs from the Stack and depositing their results onto the Stack.

The default name for each Branch is 'Brch_xxxxxx', where xxxxxx is a unique sequence number.

5.2: Format of the .udc file

A .udc file follows the rules of a .csm file, EXCEPT:

Zero or more INTERFACE statements must preceed any other non-comment statement.

Any CSM statement can be used except the DIMENSION, CONPMTR, DESPMTR, LBOUND, and UBOUND statements.

SET statements define parameters that are visible only within the .udc file (that is, parameters have local scope).

Parameters defined outside the .udc file are not available, except those passed in via INTERFACE statements.

.udc files can be nested to a depth of 10 levels.

.udc files are executed via a UDPRIM statement.

5.3: Special characters

   #          introduces comment
   "          ignore spaces until following "
   \          ignore this and following characters and concatenate next line
   <space>    separates arguments in .csm file (except between " and ")

   0-9        digits used in numbers and in names
   A-Z a-z    letters used in names
   _ : @      characters used in names (see rule for names)
   .          decimal separator (used in numbers), introduces dot-suffixes
                 (in names)
   ,          separates function arguments and row/column in subscripts
   ;          multi-value item separator
   ( )        groups expressions and function arguments
   [ ]        specifies subscripts in form [row,column] or [index]
   + - * / ^  arithmetic operators
   $          as first character, forces argument not to be evaluated
                 (used internally)
   @          as first character, introduces @-parameters (see below)
   !          evaluate before setting Attribute

   ~          not used
   %          not used
   &          not used
   =          not used
   { }        not used
   '          not used
   < >        not used
   ?          not used
      

5.4: Valid CSM statements

The current CSM statements are listed here, grouped by type. A full alphabetical description of any command can be obtained by clicking on the command name.

In the descriptions below, the conventions used are:

Primitives
point xloc yloc zloc
box xbase ybase zbase dx dy dz
sphere xcent ycent zcent radius
cone xvrtx yvrtx zvrtx xbase ybase zbase radius
cylinder xbeg ybeg zbeg xend yend zend radius
torus xcent ycent zcent dxaxis dyaxis dzaxis majorRad minorRad
import $filename bodynumber=1
restore $name index=0
udprim $primtype $argName1 argValue1 $argName2 argValue2 $argName3 argValue3 $argName4 argValue4
Grown
extrude dx dy dz
rule reorder=0
blend begList=0 endList=0 reorder=0 oneFace=0
revolve xorig yorig zorig dxaxis dyaxis dzaxis angDeg
sweep
Applied
fillet radius edgeList=0
chamfer radius edgeList=0
hollow thick faceList=0
Booleans
intersect $order=none index=1 maxtol=0
subtract $order=none index=1 maxtol=0
union toMark=0 trimList=0 maxtol=0
join toler=0
connect faceList1 faceList2
extract index
combine
Transform
translate dx dy dz
rotatex angDeg yaxis zaxis
rotatey angDeg zaxis xaxis
rotatez angDeg xaxis yaxis
scale fact
mirror nx ny nz dist=0
applycsys $csysName ibody=0
reorder ishift iflip=0
Sketch
skbeg x y z relative=0
skvar $type valList
skcon $type index1 index2=-1 $value=0
linseg x y z
cirarc xon yon zon xend yend zend
arc xend yend zend dist $plane=xy
spline x y z
bezier x y z
skend wireonly=0
Solver
solbeg $varList
solcon $expr
solend
Utilities
set $pmtrName exprs
assert arg1 arg2 toler=0 verify=0
udparg $primtype $argName1 argValue1 $argName2 argValue2 $argName3 argValue3 $argName4 argValue4
mark
group
patbeg $pmtrName ncopy
patbreak expr
patend
ifthen val1 $op1 val2 $op2=and val3=0 $op3=eq val4=0
elseif val1 $op1 val2 $op2=and val3=0 $op3=eq val4=0
else
endif
store $name index=0 keep=0
dump $filename remove=0 toMark=0
select $type ...
project x y z dx dy dz useEdges=0
throw sigCode
catbeg sigCode
catend
Declarations
conpmtr $pmtrName value
despmtr $pmtrName values
lbound $pmtrName bounds
ubound $pmtrName bounds
dimension $pmtrName nrow ncol despmtr=0
name $branchName
attribute $attrName attrList
csystem $csysName csysList
interface $argName $argType default
end
Deprecated
loft smooth
macbeg imacro
macend
recall imacro

The following is taken from the OpenCSM.h file:

applycsys

APPLYCSYS $csysName ibody=0
          use:    apply transformation given by a CSYSTEM
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  if ibody==0, then search backward from last Body
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $body_not_found
                     $insufficient_bodys_on_stack
                     $name_not_found
        

arc

ARC       xend yend zend dist $plane=xy
          use:    create a new circular arc to the new point, with a specified
                     offset distance
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  $plane must be xy, yz, or zx
                  point on circle is dist from midpoint in plane specified
                  if dist>0, sweep is counterclockwise
                  sensitivity computed w.r.t. xend, yend, zend, dist
                  signals that may be thrown/caught:
      

assert

ASSERT    arg1 arg2 toler=0 verify=0
          use:    return error if arg1 and arg2 differ
          pops:   -
          pushes: -
          notes:  if toler==0, set toler=1e-6
                  if toler<0, set toler=abs(arg1*toler)
                  if (abs(arg1-arg2) > toler) return an error
                  only executed if verify<=MODL->verify
                  cannot be followed by ATTRIBUTE or CSYSTEM
        

attribute

ATTRIBUTE $attrName attrList
          use:    sets an Attribute for the Group on top of Stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  if first char of attrList is '$', then string Attribute
                  elseif attrList is a Parameter name, all its elements
                     are stored in Attribute
                  otherwise attrList is a semicolon-separated list of
                     scalar numbers/expressions
                  does not create a Branch
                  if before first Branch, then defines a global Attribute
                  is applied to a single Edge or Face if after a SELECT
                     statement
        

bezier

BEZIER    x y z
          use:    add a Bezier control point
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  sensitivity computed w.r.t. x, y, z
                  signals that may be thrown/caught:
        

blend

BLEND     begList=0 endList=0 reorder=0 oneFace=0
          use:    create a Body by blending through Sketches since Mark
          pops:   Sketch1 ... Mark
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  all Sketches must have the same number of Edges
                  if all Sketches are WireBodys, then a SheetBody is created
                     otherwise a SolidBody is created
                  the first and/or last Sketch can be a point
                  begList is either a 0 or the name of an 8-valued parameter
                  begList is only applied if first Sketch is a point
                  endList is either a 0 or the name of an 8-valued parameter
                  endList is only applied if last Sketch is a point
                  if begList!=0 and endList!=0, there must be at least
                     three interior sketches
                  interior sketches can be repeated once for C1 continuity
                  interior sketches can be repeated twice for C2 continuity
                  C1 continuity cannot be adjacent to a rounded beg or end
                  begList and endList contain
                     rad1;dx1;dy1;dz1;rad2;dx2;dy2;dz2
                  if reorder!=0 then Sketches are reordered to minimize Edge
                     lengths
                  first Sketch is unaltered if reorder>0
                  last  Sketch is unaltered if reorder<0
                  if oneFace==1 then do not split at C0 (multiplicity=3)
                  sensitivity computed w.r.t. begList, endList
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: base, end, strip1:part1, strip1:part2, ...
                     strip2:part1, ...
                  signals that may be thrown/caught:
                     $error_in_bodys_on_stack
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
        

box

BOX       xbase ybase zbase dx dy dz
          use:    create a box Body
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xbase, ybase, zbase, dx, dy, dz
                  computes Face, Edge, and Node sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: xmin, xmax, ymin, ymax, zmin, zmax
                  signals that may be thrown/caught:
                     $illegal_value
        

catbeg

CATBEG    sigCode
          use:    execute Block of Branches if current signal matches sigCode
          pops:   -
          pushes: -
          notes:  sigCode can be an integer or one of:
                     $body_not_found
                     $created_too_many_bodys
                     $did_not_create_body
                     $edge_not_found
                     $error_in_bodys_on_stack
                     $face_not_found
                     $file_not_found
                     $illegal_argument
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $name_not_found
                     $node_not_found
                     $wrong_types_on_stack
                     $func_arg_out_of_bounds
                  if sigCode does not match current signal, skip to matching
                     CATEND
                  Block contains all Branches up to matching CATEND
                  cannot be followed by ATTRIBUTE or CSYSTEM
        

catend

CATEND
          use:    designates the end of a CATBEG Block
          pops:   -
          pushes: -
          notes:  inner-most Block must be a CATBEG Block
                  closes CATBEG Block
                  cannot be followed by ATTRIBUTE or CSYSTEM
        

chamfer

CHAMFER   radius edgeList=0
          use:    apply a chamfer to a Body
          pops:   Body
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if previous operation is boolean, apply to all new Edges
                  edgeList=0 is the same as edgeList=[0;0]
                  edgeList is a multi-value Parameter or a semicolon-separated
                     list
                  pairs of edgeList entries are processed in order
                  pairs of edgeList entries are interpreted as follows:
                    col1  col2   meaning
                     =0    =0    add all Edges
                     >0    >0    add    Edges between iford=+icol1
                                                  and iford=+icol2
                     <0    <0    remove Edges between iford=-icol1
                                                  and iford=-icol2
                     >0    =0    add    Edges adjacent to iford=+icol1
                     <0    =0    remove Edges adjacent to iford=-icol1
                  sensitivity computed w.r.t. radius
                  sets up @-parameters
                  new Faces all receive the Branch's Attributes
                  face-order is based upon order that is returned from EGADS
                  signals that may be thrown/caught:
                     $illegal_argument
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
        

cirarc

CIRARC    xon yon zon xend yend zend
          use:    create a new circular arc, using the previous point
                     as well as the two points specified
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  sensitivity computed w.r.t. xon, yon, zon, xend, yend, zend
                  signals that may be thrown/caught:
        

combine

COMBINE
          use:    combine Bodys since Mark into next higher type
          pops:   Body1 ... Mark
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  Mark must be set
                  if all Bodys since Mark are SheetBodys
                     create SolidBody from closed Shell
                  elseif all Bodys since Mark are WireBodys and are co-planar
                     create SheetBody from closed Loop
                  endif
                  sets up @-parameters
                  new Faces all receive the Branch's Attributes
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
        

cone

CONE      xvrtx yvrtx zvrtx xbase ybase zbase radius
          use:    create a cone Body
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xvrtx, yvrtx, zvrtz, xbase, ybase,
                     zbase, radius
                  computes Face, Edge, and Node sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: (empty), base, umin, umax
                     if x-aligned: umin=ymin, umax=ymax
                     if y-aligned: umin=xmax, umax=xmin
                     if z-aligned: umin=ymax, umax=ymin
                  signals that may be thrown/caught:
                     $illegal_value
        

connect

CONNECT   faceList1 faceList2
          use:    connects two Bodys with bridging Faces
          pops:   Body1 Body2
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  faceList1 and faceList2 must have the same length
                  all Faces in the faceLists must have 4 Edges
                  Faces within each faceList must be contiguous
                  faceList1[i] corresponds to faceList2[i]
                  new Faces all receive the Branch's Attributes
                  signals that may be thrown/caught:
                     $illegal_argument
                     $illegal_value
                     $insufficient_bodys_on_stack
        

conpmtr

CONPMTR   $pmtrName value
          use:    define a CONSTANT Parameter
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  may not be used in a .udc file
                  pmtrName must be in form 'name'
                  pmtrName must not start with '@'
                  pmtrName must not refer to an INTERNAL/EXTERNAL Parameter
                  pmtrName will be marked as CONSTANT
                  pmtrName is used directly (without evaluation)
                  value must be a number
                  does not create a Branch
                  cannot be followed by ATTRIBUTE or CSYSTEM
        

csystem

CSYSTEM   $csysName csysList
          use:    attach a Csystem to Body on top of stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  if     csysList contains 9 entries:
                     {x0, y0, z0, dx1, dy1, dz1, dx2, dy2, dz3}
                     origin is at (x0,y0,q0)
                     dirn1  is in (dx1, dy1,dz1) direction
                     dirn2  is in (dx2,dy2,dz2)  direction
                  elseif csysList contains 5 entries and first is positive
                     {+iface, ubar0, vbar0, du2, dv2}
                     origin is at normalized (ubar0,vbar0) in iface
                     dirn1  is normal to Face
                     dirn2  is in (du2,dv2) direction
                  elseif csyList contains 5 entries and first is negative
                     {-iedge, tbar, dx2, dy2, dz2}
                     origin is at normalized (tbar) in iedge
                     dirn1  is tangent to Edge
                     dirn2  is in (dx2,dy2,dz2) direction
                  elseif csysList contains 7 entries
                     {inode, dx1, dy1, dz1, dx2, dy2, dz2}
                     origin is at Node inode
                     dirn1  is in (dx1,dy1,dz1) direction
                     dirn2  is in (dx1,dy2,dz2) direction
                  else
                     error
                  semicolon-sep lists can instead refer to
                     multi-valued Parameter
                  dirn3 is formed by (dirn1)-cross-(dirn2)
                  does not create a Branch
          

cylinder

CYLINDER  xbeg ybeg zbeg xend yend zend radius
          use:    create a cylinder Body
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xbeg, ybeg, zbeg, xend, yend,
                     zend, radius
                  computes Face, Edge, and Node sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: beg, end, umin, umax
                     if x-aligned: umin=ymin, umax=ymax
                     if y-aligned: umin=xmax, umax=xmin
                     if z-aligned: umin=ymax, umax=ymin
                  signals that may be thrown/caught:
                     $illegal_value
          

despmtr

DESPMTR   $pmtrName values
          use:    define a (constant) EXTERNAL design Parameter
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  may not be used in a .udc file
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  pmtrName must not refer to an INTERNAL/CONSTANT Parameter
                  pmtrName will be marked as EXTERNAL
                  pmtrName is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  if irow is a colon (:), then all rows    are input
                  if icol is a colon (:), then all columns are input
                  pmtrName[:,:] is equivalent to pmtrName
                  values cannot refer to any other Parameter
                  if value already exists, it is not overwritten
                  values are defined across rows, then across columns
                  if values has more entries than needed, extra values
                     are lost
                  if values has fewer entries than needed, last value
                     is repeated
                  does not create a Branch
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

dimension

DIMENSION $pmtrName nrow ncol despmtr=0
          use:    set up an array Parameter
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  if despmtr=1, may not be used in a .udc file
                  nrow >= 1
                  ncol >= 1
                  pmtrName must not start with '@'
                  if despmtr=0, then marked as INTERNAL
                  if despmtr=1, then marked as EXTERNAL
                  if despmtr=1, then may not be used in a .udc file
                  if despmtr=1, then does not create a Branch
                  old values are not overwritten
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

dump

DUMP      $filename remove=0 toMark=0
          use:    write a file that contains the Body
          pops:   Body1 (if remove=1)
          pushes: -
          notes:  Solver may not be open
                  if file exists, it is overwritten
                  filename is used directly (without evaluation)
                  if filename starts with '$/', it is prepended with path of
                     the .csm file
                  if remove=1, then Body1 is removed after dumping
                  if toMark=1, all Bodys back to the Mark (or all if no Mark)
                     are combined into a single model
                  if toMark=1, the remove flag is ignored
                  for .stl and .ugrid files, toMark must be 0
                  valid filetypes are:
                     .brep   .BREP   --> OpenCASCADE output
                     .egads  .EGADS  --> EGADS       output
                     .egg    .EGG    --> EGG restart output
                     .iges   .IGES   --> IGES        output
                     .igs    .IGS    --> IGES        output
                     .step   .STEP   --> STEP        output
                     .stl    .STL    --> ASCII stl   output
                     .stp    .STP    --> STEP        output
                     .tess   .TESS   --> ASCII tess  output
                     .ugrid  .UGRID  --> ASCII AFRL3 output
                  signals that may be thrown/caught:
                     $file_not_found
                     $insufficient_bodys_on_stack
          

else

ELSE
          use:    execute or skip a Block of Branches
          pops:   -
          pushes: -
          notes:  inner-most Block must be an Ifthen Block
                  must follow an IFTHEN or ELSEIF statment
                  if preceeding (matching) IFTHEN or ELSEIF evaluated true,
                     then skip Branches up to the matching ENDIF
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

elseif

ELSEIF    val1 $op1 val2 $op2=and val3=0 $op3=eq val4=0
          use:    execute or skip a sequence of Branches
          pops:   -
          pushes: -
          notes:  inner-most Block must be an Ifthen Block
                  must follow an IFTHEN or ELSEIF statement
                  if preceeding (matching) IFTHEN or ELSEIF evaluated true,
                     then skip Branches up to matching ENDIF
                  op1 must be one of: lt le eq ge gt ne
                  op2 must be one of: or and
                  op3 must be one of: lt le eq ge gt ne
                  if expression evaluates false, skip Branches up to next
                     ELSEIF, ELSE, or ENDIF
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

end

END
          use:    signifies end of .csm or .udc file
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  Bodys on Stack are returned last-in-first-out
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

endif

ENDIF
          use:    terminates an Ifthen Block of Branches
          pops:   -
          pushes: -
          notes:  inner-most Block must be an Ifthen Block
                  must follow an IFTHEN, ELSEIF, or ELSE
                  closes Ifthen Block
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

extract

EXTRACT   index
          use:    extract a Face of Node from a Body
          pops:   Body1
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if     Body1=SolidBody and index>0
                     create SheetBody from +index'th Face of Body1
                  elseif Body1=SolidBody and index<0
                     create WireBody from -index'th Edge of Body1
                  elseif Body1=SolidBody and index=0
                     create SheetBody from outer Shell of Body1
                  elseif Body1=SheetBody and index>0
                     create SheetBody from +index'th Face of Body1
                  elseif Body1=SheetBody and index<0
                     create WireBody from -index'th Edge of Body1
                  elseif Body=SheetBody and index=0
                     create WireBody from outer Loop of Body1
                     CURRENTLY NOT IMPLEMENTED
                  endif
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

extrude

EXTRUDE   dx dy dz
          use:    create a Body by extruding a Sketch
          pops:   Sketch
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if Sketch is a SheetBody, then a SolidBody is created
                  if Sketch is a WireBody, then a SheetBody is created
                  sensitivity computed w.r.t. dx, dy, dz
                  computes Face sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: base, end, feat1, ...
                  signals that may be thrown/caught:
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

fillet

FILLET    radius edgeList=0
          use:    apply a fillet to a Body
          pops:   Body
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if previous operation is boolean, apply to all new Edges
                  edgeList=0 is the same as edgeList=[0;0]
                  edgeList is a multi-value Parameter or a semicolon-separated
                     list
                  pairs of edgeList entries are processed in order
                  pairs of edgeList entries are interpreted as follows:
                    col1  col2   meaning
                     =0    =0    add all Edges
                     >0    >0    add    Edges between iford=+icol1
                                                  and iford=+icol2
                     <0    <0    remove Edges between iford=-icol1
                                                  and iford=-icol2
                     >0    =0    add    Edges adjacent to iford=+icol1
                     <0    =0    remove Edges adjacent to iford=-icol1
                  sensitivity computed w.r.t. radius
                  sets up @-parameters
                  new Faces all receive the Branch's Attributes
                  face-order is based upon order that is returned from EGADS
                  signals that may be thrown/caught:
                     $illegal_argument
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

group

GROUP
          use:    create a Group of Bodys since Mark for subsequent transformations
          pops:   Body1 ... Mark
          pushes: Body1 ...
          notes:  Sketch may not be open
                  Solver may not be open
                  if no Mark on stack, all Bodys on stack are in Group
                  the Mark is removed from the stack
                  Attributes are set on all Bodys in Group
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

hollow

HOLLOW    thick faceList=0
          use:    hollow out a SolidBody
          pops:   Body
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if thick=0, then SolidBody is converted to SheetBody or
                     SheetBody to WireBody
                  if faceList=0, then create an offset Body instead
                  faceList is a multi-value Parameter or a semicolon-separated
                     list
                  pairs of faceList entries are processed in order
                  the first  entry in a pair indicates the Body when Face was
                     generated
                  the second entry in a pair indicates the face-order
                  sensitivity computed w.r.t. thick
                  sets up @-parameters
                  new Faces all receive the Branch's Attributes
                  face-order is based upon order that is returned from EGADS
                  signals that may be thrown/caught:
                     $illegal_argument
                     $insufficient_bodys_on_stack
          

ifthen

IFTHEN    val1 $op1 val2 $op2=and val3=0 $op3=eq val4=0
          use:    execute or skip a Block of Branches
          pops:   -
          pushes: -
          notes:  works in combination with ELSEIF, ELSE, and ENDIF statements
                  op1 must be one of: lt le eq ge gt ne
                  op2 must be one of: or and
                  op3 must be one of: lt le eq ge gt ne
                  if expression evaluates false, skip Block of Branches up
                     to next (matching) ELSEIF, ELSE, or ENDIF are skipped
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

import

IMPORT    $filename bodynumber=1
          use:    import from filename
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  filename is used directly (without evaluation)
                  if filename starts with '$$/', use path relative to .csm file
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is based upon order in file
                  signals that may be thrown/caught:
                     $did_not_create_body
                     udp-specific code
          

interface

INTERFACE $argName $argType default
          use:    defines an argument for a .udc file
          pops:   -
          pushes: -
          notes:  only allowed in a .udc file
                  must be placed before any executable statement
                  argType must be "in", "out", or "dim"
                  if argType=="dim", then default contains number of elements
                  if argType=="dim", the default values are zero
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

intersect

INTERSECT $order=none index=1 maxtol=0
          use:    perform Boolean intersection (Body2 & Body1)
          pops:   Body1 Body2
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if     Body1=SolidBody and Body2=SolidBody
                     create SolidBody that is common part of Body1 and Body2
                  elseif Body1=SolidBody and Body2=SheetBody
                     create SheetBody that is the part of Body2 that is
                        inside Body1
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=SolidBody and Body2=WireBody
                     create WireBody that is the part of Body2 that is
                        inside Body1
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=SheetBody and Body2=SolidBody
                     create SheetBody that is the part of Body1 that is
                        inside Body2
                  elseif Body1=SheetBody and Body2=SheetBody and Bodys are
                        co-planar
                     create SheetBody that is common part of Body1 and Body2
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=SheetBody and Body2=SheetBody and Bodys are not
                        co-planar
                     create WireBody at the intersection of Body1 and Body2
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=SheetBody and Body2=WireBody
                     create WireBody that is the part of Body2 that is
                        inside Body1
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=WireBody and Body2=SolidBody
                     create WireBody that is the part of Body1 that is
                        inside Body2
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=WireBody and Body2=SheetBody
                     create WireBody that is the part of Body1 that is
                        inside Body2
                     CURRENTLY NOT IMPLEMENTED
                  endif
                  if intersection does not produce at least index Bodys, an
                     error is returned
                  order may be one of:
                     none    same order as returned from geometry engine
                     xmin    minimum xmin   is first
                     xmax    maximum xmax   is first
                     ymin    minimum ymin   is first
                     ymax    maximum ymax   is first
                     zmin    minimum zmin   is first
                     zmax    maximum zmax   is first
                     amin    minimum area   is first
                     amax    maximum area   is first
                     vmin    minimum volume is first
                     vmax    maximum volume is first
                  order is used directly (without evaluation)
                  if maxtol>0, then tolernce can be relaxed until successful
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

join

JOIN      toler=0
          use:    join two Bodys at a common Face
          pops:   Body1 Body2
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if     Body1=SolidBody and Body2=SolidBody
                     create SolidBody formed by joining Body1 and Body2 at
                        common Faces
                  elseif Body1=SheetBody and Body2=SheetBody
                     create SheetBody formed by joining Body1 and Body2 at
                        common Edges
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=WireBody and Body2=WireBody
                     create WireBody formed by joining Body1 and Body2 at
                        common end Node
                     CURRENTLY NOT IMPLEMENTED
                  endif
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $created_too_many_bodys
                     $did_not_create_body
                     $face_not_found
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

lbound

LBOUND    $pmtrName bounds
          use:    defines a lower bound for a design Parameter
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  may not be used in a .udc file
                  if value of Parameter is smaller than bounds, a warning is
                     generated
                  pmtrName must have been defined previously by DESPMTR
                     statement
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  pmtrName is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  if irow is a colon (:), then all rows    are input
                  if icol is a colon (:), then all columns are input
                  pmtrName[:,:] is equivalent to pmtrName
                  bounds cannot refer to any other Parameter
                  bounds are defined across rows, then across columns
                  if bounds has more entries than needed, extra bounds
                     are lost
                  if bounds has fewer entries than needed, last bound
                     is repeated
                  any previous bounds are overwritten
                  does not create a Branch
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

linseg

LINSEG    x y z
          use:    create a new line segment, connecting the previous
                     and specified points
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  sensitivity computed w.r.t. x, y, z
                  signals that may be thrown/caught:
          

loft

LOFT      smooth
          use:    create a Body by lofting through Sketches since Mark
          pops:   Sketch1 ... Mark
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  all Sketches must have the same number of Segments
                  if Sketch is a SheetBody, then a SolidBody is created
                  if Sketch is a WireBody, then a SheetBody is created
                  the Faces all receive the Branch's Attributes
                  face-order is: base, end, feat1, ...
                  if NINT(smooth)=1, then sections are smoothed
                  the first and/or last Sketch can be a point

                  LOFT (through OpenCASCADE) is not very robust
                  use BLEND or RULE if possible
                  sets up @-parameters
                  MAY BE DEPRECATED (use RULE or BLEND)
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

macbeg

MACBEG    imacro
          use:    marks the start of a macro
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  imacro must be between 1 and 100
                  cannot overwrite a previous macro
                  cannot be followed by ATTRIBUTE or CSYSTEM
                  MAY BE DEPRECATED (use UDPRIM)
          

macend

MACEND
          use:    ends a macro
          pops:   -
          pushes: -
          notes:  cannot be followed by ATTRIBUTE or CSYSTEM
                  MAY BE DEPRECATED (use UDPRIM)
          

mark

MARK
          use:    used to identify groups such as in RULE, BLEND, or GROUP
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

mirror

MIRROR    nx ny nz dist=0
          use:    mirrors Group on top of Stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  normal of the mirror plane is given by nx,ny,nz
                  mirror plane is dist from origin
                  sensitivity computed w.r.t. nx, ny, nz, dist
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

name

NAME      $branchName
          use:    names the entry on top of Stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  does not create a Branch
          

patbeg

PATBEG    $pmtrName ncopy
          use:    execute a Block of Branches ncopy times
          pops:   -
          pushes: -
          notes:  Solver may not be open
                  Block contains all Branches up to matching PATEND
                  pmtrName must not start with '@'
                  pmtrName takes values from 1 to ncopy (see below)
                  pmtrName is used directly (without evaluation)
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

patbreak

PATBREAK  expr
          use:    break out of inner-most Patbeg Block
          pops:   -
          pushes: -
          notes:  Solver may not be open
                  must be in a Patbeg Block
                  skip to Branch after matching PATEND if expr>0
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

patend

PATEND
          use:    designates the end of a Patbeg Block
          pops:   -
          pushes: -
          notes:  Solver may not be open
                  inner-most Block must be a Patbeg Block
                  closes Patbeg Block
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

point

POINT     xloc yloc zloc
          use:    create a single point Body
          pops:   -
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xloc, yloc, zloc
                  computes Node sensitivity analytically
                  sets up @-parameters
          

project

PROJECT   x y z dx dy dz useEdges=0
          use:    find the first projection from given point in given direction
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  if useEdges!=1
                      look for intersections with Faces and overwrite @iface
                  else
                      look for intersections with Edges and overwrite @iedge
                  endif
                  over-writes the following @-parameters: @xcg, @ycg, and @zcg
                  cannot be followed by ATTRIBUTE or CSYSTEM
                  signals that may be thrown/caught:
                     $face_not_found
                     $insufficient_bodys_on_stack
          

recall

RECALL    imacro
          use:    recalls copy of macro from a storage location imacro
          pops:   -
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  storage location imacro must have been previously filled by
                     a MACBEG statement
                  MAY BE DEPRECATED (use UDPRIM)
          

reorder

REORDER   ishift iflip=0
          use:    change the order of Edges in a Body
          pops:   Body1
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  Body1 must be either WireBody or SheetBody Body
                  Body1 must contain 1 Loop
                  if the Loop is open, ishift must be 0
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

restore

RESTORE   $name index=0
          use:    restores Body(s) that was/were previously stored
          pops:   -
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  $name is used directly (without evaluation)
                  error results if nothing has been stored in name
                  the Faces all receive the Branch's Attributes
                  signals that may be thrown/caught:
                     $name_not_found
          

revolve

REVOLVE   xorig yorig zorig dxaxis dyaxis dzaxis angDeg
          use:    create a Body by revolving a Sketch around an axis
          pops:   Sketch
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if Sketch is a SheetBody, then a SolidBody is created
                  if Sketch is a WireBody, then a SheetBody is created
                  sensitivity computed w.r.t. xorig, yorig, zorig, dxaxis,
                     dyaxis, dzaxis, andDeg
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: (base), (end), feat1, ...
                  signals that may be thrown/caught:
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

rotatex

ROTATEX   angDeg yaxis zaxis
          use:    rotates Group on top of Stack around x-like axis
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. angDeg, yaxis, zaxis
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

rotatey

ROTATEY   angDeg zaxis xaxis
          use:    rotates Group on top of Stack around y-like axis
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. angDeg, zaxis, xaxis
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

rotatez

ROTATEZ   angDeg xaxis yaxis
          use:    rotates Group on top of Stack around z-like axis
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. angDeg, xaxis, yaxis
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

rule

RULE      reorder=0
          use:    create a Body by creating ruled surfaces through Sketches
                     since Mark
          pops:   Sketch1 ... Mark
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if reorder!=0 then Sketches are reordered to minimize Edge
                     lengths
                  first Sketch is unaltered if reorder>0
                  last  Sketch is unaltered if reorder<0
                  all Sketches must have the same number of Edges
                  if all Sketches are WireBodys, then a SheetBody is created
                     otherwise a SolidBody is created
                  the first and/or last Sketch can be a point
                  computes Face sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: base, end, strip1:part1, strip1:part2, ...
                     strip2:part1, ...
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $error_in_bodys_on_stack
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

scale

SCALE     fact
          use:    scales Group on top of Stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. fact
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

select

SELECT    $type arg1 ...
          use:    selects entity for which @-parameters are evaluated
          pops:   -
          pushes: -
          notes:  if     arguments are: "body"
                     sets @ibody to @nbody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "body ibody"
                     sets @ibody to ibody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "face"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "face iface"
                     uses @ibody
                     sets @iface to iface
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "face ibody1 iford1 iseq=1"
                     uses @ibody
                     sets @iface to Face in @ibody that matches ibody1/iford1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "edge"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "edge iedge"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to iedge
                     sets @inode to -1
                  elseif arguments are: "edge ibody1 iford1 ibody2 iford2 iseq=1"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to Edge in @ibody that adjoins Faces
                        ibody1/iford1 and ibody2/iford2
                     sets @inode to -1
                  elseif arguments are: "node"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to -1
                  elseif arguments are: "node inode"
                     uses @ibody
                     sets @iface to -1
                     sets @iedge to -1
                     sets @inode to inode
//                elseif arguments are: "node ibody1 iford1 ibody2 iford2
//                                                          ibody3 iford3 iseq=1"
//                   uses @ibody
//                   sets @iface to -1
//                   sets @iedge to -1
//                   sets @inode to Node in @ibody that adjoins
//                      Faces ibody1/iford1, ibody2/iford2, and ibody3/iford3
                  endif

                  Face specifications are stored in _faceID Attribute
                  Edge specifications are stored in _edgeID Attribute
//                Node specifications are stored in _nodeID Attribute
                  iseq selects from amongst multiple Faces/Edges/Nodes that
                     match the ibody/iford specifications
                  sets up @-parameters
                  cannot be followed by CSYSTEM
                  signals that may be thrown/caught:
                     $body_not_found
                     $edge_not_found
                     $face_not_found
                     $node_not_found
          

set

SET       $pmtrName exprs
          use:    define a (redefinable) INTERNAL Parameter
          pops:   -
          pushes: -
          notes:  Solver may not be open
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  pmtrName must not refer to an EXTERNAL/CONSTANT Parameter
                  pmtrName will be marked as INTERNAL
                  pmtrName is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  if exprs has multiple values (separated by ;), then
                     any subscripts in pmtrName are ignored
                  exprs are defined across rows
                  if exprs is longer than Parameter size, extra exprs are lost
                  if exprs is shorter than Parameter size, last expr is repeated
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

skbeg

SKBEG     x y z relative=0
          use:    start a new Sketch with the given point
          pops:   -
          pushes: -
          notes:  opens Sketch
                  Solver may not be open
                  if relative=1, then all values in sketch are relative to x,y,z
                  sensitivity computed w.r.t. x, y, z
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

skcon

SKCON     $type index1 index2=-1 $value=0
          use:    creates a Sketch constraint
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  may only follow SKVAR or another SKCON statement
                  $type
                     X  ::x[index1]=value
                     Y  ::y[index1]=value
                     Z  ::z[index1]=value
                     P  segments adjacent to point index1 are perpendicular
                     T  segments adjacent to point index1 are tangent
                     A  segments adjacent to point index1 have
                                                           angle=$value (deg)
                     W  width:  ::x[index2]-::x[index1]=value  if plane==xy
                                ::y[index2]-::y[index1]=value  if plane==yz
                                ::z[index2]-::z[index1]=value  if plane==zx
                     D  depth:  ::y[index2]-::y[index1]=value  if plane==xy
                                ::z[index2]-::z[index1]=value  if plane==zx
                                ::x[index2]-::x[index1]=value  if plane==zx
                     H  segment from index1 and index2 is horizontal
                     V  segment from index1 and index2 is vertical
                     I  segment from index1 and index2 has
                                                     inclination=$value (deg)
                     L  segment from index1 and index2 has length=$value
                     R  cirarc  from index1 and index2 has radius=$value
                     S  cirarc  from index1 and index2 has sweep=$value (deg)
                  index=1 refers to point in SKBEG statement
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

skend

SKEND     wireonly=0
          use:    completes a Sketch
          pops:   -
          pushes: Sketch
          notes:  Sketch must be open
                  Solver may not be open
                  if Sketch contains SKVAR/SKCON, then Sketch variables are
                     updated first
                  if wireonly=0, all LINSEGs and CIRARCs must be x-, y-, or
                     z-co-planar
                  if Sketch is     closed and wireonly=0,
                     then a SheetBody is created
                  if Sketch is     closed and wireonly=1,
                     then a WireBody  is created
                  if Sketch is not closed,
                     then a WireBody  is created
                  if SKEND immediately follows SKBEG, then a NODE is created
                     (which can be used at either end of a LOFT or BLEND)
                  closes Sketch
                  new Face receives the Branch's Attributes
          

skvar

SKVAR     $type valList
          use:    create multi-valued Sketch variables and their initial values
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  may only follow SKBEG statement
                  $type
                     xy valList contains ::x[1]; ::y[1]; ::d[1]; ::x[2]; ...
                     yz valList contains ::y[1]; ::z[1]; ::d[1]; ::y[2]; ...
                     zx valList contains ::z[1]; ::x[1]; ::d[1]; ::z[2]; ...
                  valList is a semicolon-separated list
                  valList must end with a semicolon
                  the number of entries in valList is taken from number of
                     semicolons
                  the number of entries in valList must be evenly divisible by 3
                  enter :d[i] as zero for LINSEGs
                  values of ::x[1], ::y[1], and ::z[1] are overwritten by
                     values in SKBEG
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

solbeg

SOLBEG    $varList
          use:    starts a Solver Block
          pops:   -
          pushes: -
          notes:  Solver must not be open
                  opens the Solver
                  varList is a list of semicolon-separated INTERNAL parameters
                  varList must end with a semicolon
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

solcon

SOLCON    $expr
          use:    constraint used to set Solver parameters
          pops:   -
          pushes: -
          notes:  Sketch must not be open
                  Solver must be open
                  SOLEND will drive expr to zero
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

solend

SOLEND
          use:    designates the end of a Solver Block
          pops:   -
          pushes: -
          notes:  Sketch must not be open
                  inner-most Block must be a Solver Block
                  adjust parameters to drive constraints to zero
                  closes Solver Block
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

sphere

SPHERE    xcent ycent zcent radius
          use:    create a sphere Body
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xcent, ycent, zcent, radius
                  computes Face, Edge, and Node sensitivities analytically
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: ymin, ymax
                  signals that may be thrown/caught:
                     $illegal_value
          

spline

SPLINE    x y z
          use:    add a point to a spline
          pops:   -
          pushes: -
          notes:  Sketch must be open
                  Solver may not be open
                  sensitivity computed w.r.t. x, y, z
                  signals that may be thrown/caught:
          

store

STORE     $name index=0 keep=0
          use:    stores Group on top of Stack
          pops:   any
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  $name is used directly (without evaluation)
                  previous Group in name/index is overwritten
                  if keep==1, the Group is not popped off stack
                  cannot be followed by ATTRIBUTE or CSYSTEM
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

subtract

SUBTRACT  $order=none index=1 maxtol=0
          use:    perform Boolean subtraction (Body2 - Body1)
          pops:   Body1 Body2
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if     Body1=SolidBody and Body2=SolidBody
                     create SolidBody that is the part of Body1 that is
                        outside Body2
                  elseif Body1=SolidBody and Body2=SheetBody
                     create SolidBody that is Body1 scribed with Edges at
                        intersection with Body2
                  elseif Body1=SheetBody and Body2=SolidBody
                     create SheetBody that is part of Body1 that is
                        outside Body2
                  elseif Body1=SheetBody and Body2=SheetBody
                     create SheetBody that is Body1 scribed with Edges at
                        intersection with Body2
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=WireBody and Body2=SolidBody
                     create WireBody that is part of Body1 that is outside Body2
                     CURRENTLY NOT IMPLEMENTED
                  elseif Body1=WireBody and Body2=SheetBody
                     create WireBody that is Body1 scribed with Nodes at
                        intersection with Body2
                     CURRENTLY NOT IMPLEMENTED
                  endif
                  if subtraction does not produce at least index Bodys,
                     an error is returned
                  order may be one of:
                     none    same order as returned from geometry engine
                     xmin    minimum xmin   is first
                     xmax    maximum xmax   is first
                     ymin    minimum ymin   is first
                     ymax    maximum ymax   is first
                     zmin    minimum zmin   is first
                     zmax    maximum zmax   is first
                     amin    minimum area   is first
                     amax    maximum area   is first
                     vmin    minimum volume is first
                     vmax    maximum volume is first
                  if maxtol>0, then tolernce can be relaxed until successful
                  sets up @-parameters
                  order is used directly (without evaluation)
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

sweep

SWEEP
          use:    create a Body by sweeping a Sketch along a Sketch
          pops:   Sketch1 Sketch2
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  Sketch1 must be either a SheetBody or WireBody
                  Sketch2 must be a WireBody
                  if Sketch2 is not slope-continuous, result may not be
                     as expected
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: base, end, feat1a, feat1b, ...
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

throw

THROW     sigCode
          use:    set current signal to sigCode
          pops:   -
          pushes: -
          notes:  skip statements until a matching CATBEG Branch is found
                  sigCode>0 are usually user-generated signals
                  sigCode<0 are usually system-generated signals
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

torus

TORUS     xcent ycent zcent dxaxis dyaxis dzaxis majorRad minorRad
          use:    create a torus Body
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. xcent, ycent, zcent, dxaxis,
                     dyaxis, dzaxis, majorRad, minorRad
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is: xmin/ymin, xmin/ymax, xmax/ymax, xmax,ymax
                  signals that may be thrown/caught:
                     $illegal_value
          

translate

TRANSLATE dx dy dz
          use:    translates Group on top of Stack
          pops:   any
          pushes: any
          notes:  Sketch may not be open
                  Solver may not be open
                  sensitivity computed w.r.t. dx, dy, dz
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $insufficient_bodys_on_stack
          

ubound

UBOUND    $pmtrName bounds
          use:    defines an upper bound for a design Parameter
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  may not be used in a .udc file
                  if value of Parameter is larger than bounds, a warning is
                     generated
                  pmtrName must have been defined previously by DESPMTR
                     statement
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  pmtrName is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  if irow is a colon (:), then all rows    are input
                  if icol is a colon (:), then all columns are input
                  pmtrName[:,:] is equivalent to pmtrName
                  bounds cannot refer to any other Parameter
                  bounds are defined across rows, then across columns
                  if bounds has more entries than needed, extra bounds
                     are lost
                  if bounds has fewer entries than needed, last bound
                     is repeated
                  any previous bounds are overwritten
                  does not create a Branch
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

udparg

UDPARG    $primtype $argName1 argValue1 $argName2 argValue2 $argName3 argValue3
                                                            $argName4 argValue4
          use:    pre-set arguments for next UDPRIM statement
          pops:   -
          pushes: -
          notes:  Sketch may not be open
                  Solver may not be open
                  there can be no statements except other UDPARGs before the
                     next matching UDPRIM
                  primtype determines the type of primitive
                  primtype must match primtype of next UDPRIM statement
                  primtype is used directly (without evaluation)
                  argName#  is used directly (without evaluation)
                  argValue# is used directly if it starts with '$', otherwise it
                     is evaluated
                  if argValue starts with '$$/', use path relative to .csm file
                  arguments for following UDPRIM statement are evaluated
                     in the order they are encountered (UDPARG first)
                  sensitivity computed w.r.t. argValue1, argValue2, argValue3,
                     argValue4
                  cannot be followed by ATTRIBUTE or CSYSTEM
          

udprim

UDPRIM    $primtype $argName1 argValue1 $argName2 argValue2 $argName3 argValue3
                                                            $argName4 argValue4
          use:    create a Body by executing a user-defined primitive
          pops:   -
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  primtype  determines the type of primitive and the number of
                     argName/argValue pairs
                  if primtype begins with a letter
                     then a compiled udp whose name is primtype.so is used
                  if primtype starts with a /
                     then a .udc file in the current directory will be used
                  if primtype starts with $/
                     then a .udc file in the same directory of the .csm file
                        will be used
                  primtype  is used directly (without evaluation)
                  argName#  is used directly (without evaluation)
                  argValue# is used directly if it starts with '$', otherwise it
                     is evaluated
                  if argValue# is <<, use data to matching >> as inline file
                  if argValue# starts with '$$/', use path relative to .csm file
                  extra arguments can be set with UDPARG statement
                  when called to execute a .udc file:
                     the level is incremented
                     INTERNAL Parameters are created for all INTERFACE stmts
                        for "in"  the value is set to its default
                        for "out" the value is set to its default
                        for "dim" an array is created (of size=value) with
                           value=dot=0
                     the associated UDPARG and UDPRIM statements are processed
                        in order
                        if argName matches a Parameter created by an INTERFACE
                           statement
                           if argValueX matches the name of a Parameter at
                              level-1
                              the values are copied into the new Parameter
                           else
                              argValueX is evalued and stored in the new
                                 Parameter
                        else
                           an error is returned
                     the statements in the .udc are executed until an END
                        statement
                        a SET statement either creates a new Parameter or
                           overwrites a value
                     during the execution of the END statement
                        for values associated with an INTERFACE "out" statement
                           the value is copied to the appropriate @@-parameter
                              (at level-1)
                        all Parameters at the current level are destroyed
                        the level is decremented
                  sensitivity computed w.r.t. argValue1, argValue2, argValue3,
                     argValue4
                  computes Face and Edge sensitivities analytically (if supplied
                     by the udp)
                  sets up @-parameters
                  the Faces all receive the Branch's Attributes
                  face-order is based upon order returned from UDPRIM
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $insufficient_bodys_on_stack
                     udp-specific code
                  see udp documentation for full information
          

union

UNION     toMark=0 trimList=0 maxtol=0
          use:    perform Boolean union
          pops:   Body1 Body2  -or-  Body1 ... Mark
          pushes: Body
          notes:  Sketch may not be open
                  Solver may not be open
                  if     toMark=1
                     create SolidBody that is combination of SolidBodys
                        since Mark
                  elseif Body1=SolidBody and Body2=SolidBody
                     if trimList=0
                        create SolidBody that us combination of Body1 and Body2
                     else
                        create SolidBody that is trimmed combination of Body1
                           and Body2
                        trimList contains x;y;z;dx;dy;dz where
                           (x,y,z) is inside the Body to be trimmed
                           (dx,dy,dz) is direction toward the trimming Body
                     endif
                  elseif Body1=SheetBody and Body2=SheetBody
                     create SheetBody that is the combination of Bodys with
                        possible new Edges
                  endif
                  if maxtol>0, then tolernce can be relaxed until successful
                  sets up @-parameters
                  signals that may be thrown/caught:
                     $did_not_create_body
                     $illegal_value
                     $insufficient_bodys_on_stack
                     $wrong_types_on_stack
          

5.5: User-Defined Primitives shipped with OpenCSM

UDPRIM bezier
       arguments:
           filename   name of bezier file (prepended with '$' or '$$/')
           debug      =0 for no debug, =1 for debug   [default 0]
       usage:
           read imax, jmax
           for (j=0; j < jmax; j++)
               for (i=0; i < imax; i++)
                   read x(i,j), y(i,j), z(i,j)
               endfor
           endfor

           if (jmax==1)
               generate WIRE Body
           elseif (surface is open)
               generate SHEET Body
           else
               generate SOLID Body
           endif
       notes:
           vsp files can be converted to this format by vsp2csm

UDPRIM biconvex
       arguments:
           thick      maximum thickness      [default 0]
           camber     maximum camber         [default 0]
       notes:
           thick  must be positive
           camber must not exceed thick/2
           leading edge at (0,0,0)
           trailing edge at (1,0,0)
           airfoil generated in x-y plane

UDPRIM box
       arguments:
           dx         width in x-direction   [default 0]
           dy         width in y-direction   [default 0]
           dz         width in z-direction   [default 0]
           rad        corner radius          [default 0]
       usage:
           if     (dx>0 && dy>0 && dz>0)
               if (2*rad>dx && 2*rad>dy && 2*rad>dz)
                   ERROR
               elseif (rad>0)
                   generate SOLID Body with rounded edges
               else
                   generate SOLID Body
               endif
           elseif (dx==0 && dy>0 && dz>0)
               if (2*rad>dy && 2*rad>dz)
                   generate SHEET Body in yz-plane with rounded corners
               else
                   generate SHEET Body iy yz-plane
               endif
           elseif (dx>0 && dy==0 && dz>0)
               if (2*rad>dx && 2*rad>dz)
                   generate SHEET Body in xz-plane with rounded corners
               else
                   generate SHEET Body iy xz-plane
               endif
           elseif (dx>0 && dy>0 && dz==0)
               if (2*rad>dx && 2*rad>dy)
                   generate SHEET Body in xy-plane with rounded corners
               else
                   generate SHEET Body in xy-plane
               endif
           elseif (dx==0 && dy==0 && dz>0)
               generate WIRE Body along z-axis
           elseif (dx>0 && dy==0 && dz==0)
               generate WIRE Body along x-axis
           elseif (dx==0 && dy>0 && dz==0)
               generate WIRE Body along y-axis
           else
               ERROR
           endif
       notes:
           all Bodys are centered at origin

UDPRIM createBEM
       arguments:
          filename    name of output file
          space       nominal spacing         [default 0]
          imin        minimum points on Edge  [default 3]
          imax        maximum points on Edge  [default 5]
       usage:
          creates a NASTRAN-stype BEM file from Body on stack

UDPRIM createPoly
       arguments:
           filename   name of output file
           hole       coordinates of "hole"   [default 0;0;0]
       usage:
           pops 2 Bodys from stack
           writes a AFLR .poly file between the two Bodys
           pushed the inner Body back onto the stack

UDPRIM ellipse
       arguments:
           rx         radius in x-direction   [default 0]
           ry         radius in y-direction   [default 0]
           rz         radius in z-direction   [default 0]
       usage:
           if     (rx==0 && ry>0 && rz>0)
               generate an elliptical SHEET Body in yz-plane
           elseif (rx>0 && ry==0 && rz>0)
               generate an elliptical SHEET Body in xz-plane
           elseif (rx>0 && ry>0 && rz==0)
               generate an elliptical SHEET Body in xy-plane
          else
               ERROR
          endif
       note:
           all Bodys are centered at origin

UDPRIM freeform
       arguments:
           filename   name of file (prepended with '$' or '$$/')
           imax       number of points in i-direction   [default 1]
           jmax       number of points in j-direction   [default 1]
           kmax       number of points in k-direction   [default 1]
           xyz        coordinates
       usage:
           if (filename exists)
               read imax, jmax, kmax
               if (kmax <= 1)
                   for (k=0; k < kmax; k++)
                       for (j=0; j < jmax; j++)
                           for (i=0; i < imax; i++)
                               if (i==0 || i==imax-1 ||
                                   j==0 || j==jmax-1 ||
                                   k==0 || k==kmax-1   )
                                   read x(i,j,k), y(i,j,k), z(i,j,k)
                               endif
                           endfor
                       endfor
                   endfor
               else
                   for (j=0; j < jmax; j++)
                       for (i=0; i < imax; i++)
                           read x(i,j,0), y(i,j,0), z(i,j,0)
                       endfor
                   endfor
               endif
           else
               for (k=0; k < kmax; k++)
                   for (j=0; j < jmax; j++)
                       for (i=0; i < imax; i++)
                           x(i,j,k) = xyz[3*(i+imax*(j+jmax*k)  ]
                           y(i,j,k) = xyz[3*(i+imax*(j+jmax*k)+1]
                           z(i,j,k) = xyz[3*(i+imax*(j+jmax*k)+2]
                       endfor
                   endfor
               endfor
           endif

           if     (jmax <= 1)
               generate WIRE Body
           elseif (kmax <= 1)
               generate SHEET Body
           else
               generate SOLID Body from outer planes of data
           endif

UDPRIM import
       arguments:
           filename   name of file (prepended with '$' or '$$/')
           bodynumber number of body within filename (bias-1)   [default 1]
       usage:
           read the .egads or .stp file
           extract the bodynumber'th Body

UDPRIM kulfan
       arguments:
           class      class function at leading and trailing edge (2 values)
           ztail      height of upper and lower trailing edge (2 values)
           aupper     vector of control points for upper surface
           alower     vector of control points fpr lower surface
       notes:
            always generates airfoil with 3 edges (upper, lower, TE)
            leading edge is at (0,0,0)
            airfoil generated in x-y plane

UDPRIM naca
       arguments:
           series     NACA 4-digit designator             [default 0012]
           camber     maximum camber    (percent chord)   [default 0.0]
           thickness  maximum thickness (percent chord)   [default 0.0]
           sharpte    =1 to change thickness for sharp TE [default 0.0]
       usage:
           if (camber <= 0 && thickness <= 0)
               extract camber and thickness from series
           endif
           if (thickness==0)
               generate WIRE Body of camber line in xy-plane
           else
               generate SHEET Body in xy-plane
           endif
       notes:
           leading  edge is at (0,0,0)
           trailing edge is at (1,0,0)
           airfoil generated in x-y plane
           if sharpte=1, the x^4 coefficient in thickness eqn is changed

UDPRIM naca456
       arguments:
           thkcode    thickness code: $4, $4M, $63, $63A, $64, $64A, $65, $65A,
                         $66, or $67
           toc        thickness/chord ratio
           xmaxt      chordwise location of maximum thickness (only for $4M)
           leindex    leading edge raius parameter (only for $4M)
           camcode    camber code: $0, $2, $3, $3R, $6 or $6M
           cmax       maximum camber/chord
           xmaxc      chordwise location of maximum camber (only for $2)
           cl         design lift coefficient (only for $3, $3R, $6x, and $6xA)
           a          extent of constant loading (only for $6x and $6xA)
       usage:
           NACA 00tt    -> thkcode=$4,   toc=tt/100,
                           camcode=$0
           NACA mptt    -> thkcode=$4,   toc=tt/100,
                           camcode=$2,   cmax=m/100, xmaxc=p/10
           NACA mptt-lx -> thkcode=$4M,  toc=tt/100, leindex=l, xmaxt=x,
                           camcode=$2,   cmax=m/100, xmaxc=p/10
           NACA mp0tt   -> thkcode=$4,   toc=tt/100,
                           camcode=$3,   cl=m*.15,   xmaxc=p/20
           NACA mp1tt   -> thkcode=$4,   toc=tt/100,
                           camcode=$3R,  cl=m*.15,   xmaxc=p/20
           NACA 63-mtt  -> thkcode=$63,  toc=tt/100,
                           camcode=$6,   cl=m/10,    a=??
           NACA 63Amtt  -> thkcode=$63A, toc=tt/100,
                           camcode=$6M,  cl=m/10,    a=0.8
           NACA 64-mtt  -> thkcode=$64,  toc=tt/100,
                           camcode=$6,   cl=m/10,    a=??
           NACA 64Amtt  -> thkcode=$64A, toc=tt/100,
                           camcode=$6M,  cl=m/10,    a=0.8
           NACA 65-mtt  -> thkcode=$65,  toc=tt/100,
                           camcode=$6,   cl=m/10,    a=??
           NACA 65Amtt  -> thkcode=$65A, toc=tt/100,
                           camcode=$6M,  cl=m/10,    a=0.8
           NACA 66-mtt  -> thkcode=$66,  toc=tt/100,
                           camcode=$6,   cl=m/10,    a=??
           NACA 67-mtt  -> thkcode=$67,  toc=tt/100,
                           camcode=$6,   cl=m/10,    a=??
       notes:
           leading  edge is at (0,0,0)
           trailing edge is at (1,0,0)
           airfoil generated in x-y plane

UDPRIM parsec
       arguments:
           yte        trailing edge height   [default 0]
           param      Sobiesky's parameters  [no defaults]
                      [1] = rle
                      [2] = xtop
                      [3] = ytop
                      [4] = d2x/dy2 at top
                      [5] = top theta at trailing edge (degrees)
                      [6] = xbot
                      [7] = ybot
                      [8] = d2x/dy2 at bot
                      [9] = bot theta at trailing edge (degrees)
           poly       polynomial coefficient [no defaults]
                      [  1 to  n] for top polynomial
                      [n+1 to 2n] for bot polynomial
       usage:
           either param or poly (but not both) must be specified
       notes:
           leading  edge is at (0,0,0)
           trailing edge is at (1,yte,0)
           airfoil generated in x-y plane

UDPRIM pod
       arguments:
           length     length of pod          [default 0]
           fineness   fineness ratio         [default 0]
       usage:
           creates VSP-style pod
       notes:
           leading  edge is at (0,0,0)
           trailing edge is at (1,length,0)

UDPRIM sample
       arguments:
           dx         size in X direction    [default 0]
           dy         size in Y direction    [default 0]
           dz         size in Z direction    [default 0]
           center     center of Body         [default 0;0;0]
       usage:
           if center is prescribed, it must contain 3 values
           if all dx, dy, dz are positive
              make SOLID Body centered at center
           elseif two of dx, dy, dz are positive
              make SHEET Body centered at center
           elseif one of dx, dy, dz is positive
              make WIRE Body centered at center
           else
              error
           endif
     
UDPRIM sew
       arguments:
           filename   name of file (prepended with '$' or '$$/')
           toler      tolerance
       usage:
           read the .egads or .stp file
           combines the various bodies into a single SHEET or SOLID Body
           if specified toler is smaller than Face tolers, use Face tolers

UDPRIM supell
       arguments:
           rx        width  in X-direction                     [default=0]
           rx_w      width  on left   (west)  side             [default=0]
           rx_e      width  on right  (east)  side             [default=0]
           ry        height in Y-direction                     [default=0]
           ry_s      height on bottom (south) side             [default=0]
           ry_n      height on top    (north) side             [default=0]
           n         superellipse power                        [default=2]
           n_w       superellipse power on left   (west ) side [default=2]
           n_e       superellipse power on right  (east ) side [default=2]
           n_s       superellipse power on bottom (south) side [default=2]
           n_n       superellipse power on top    (north) side [default=2]
           n_sw      superellipse power in southwest quadrant  [default=2]
           n_se      superellipse power in southeast quadrant  [default=2]
           n_nw      superellipse power in northwest quadrant  [default=2]
           n_ne      superellipse power in northeast quadrant  [default=2]
       usage:
           superellipse is generated separately in each quadrant, using:
               edge 1: 
                   rx_e  is latest rx or rx_e
                   ry_n  is latest ry or ry_n
                   n_ne  is latest n, n_n, n_e, or n_ne
               edge 2: 
                   rx_w  is latest rx or rx_w
                   ry_n  is latest ry or ry_n
                   n_nw  is latest n, n_n, n_w, or n_nw
               edge 3: 
                   rx_w  is latest rx or rx_w
                   ry_s  is latest ry or ry_s
                   n_sw  is latest n, n_s, n_w, or n_sw
               edge 4: 
                   rx_e  is latest rx or rx_e
                   ry_s  is latest ry or ry_s
                   n_se  is latest n, n_s, n_e, or n_se
           to get a simple ellipse, only need to specify rx and ry
       notes:
           super-ellipse centered at (0,0,0)
           super-ellipse generate in x-y plane

UDPRIM waffle
       arguments:
           depth      depth in z-direction   [default 1]
           segments   array of segments
       usage:
           if (length(segments)%4 != 0)
               ERROR
           else
               for (i=0; i < length(segments)/4; i++)
                   xbeg=segments[4*i  ]
                   ybeg=segments[4*i+1]
                   xend=segments[4*i+2]
                   yend=segments[4(i+3]
                   generate SHEET Body from (xbeg,ybeg,0) to (xend,yend,depth)
               endfor
           endif
       

5.6: Number rules

The following is taken from the OpenCSM.h file:

Numbers:
    start with a digit or decimal (.)
    followed by zero or more digits and/or decimals (.)
    there can be at most one decimal in a number
    optionally followed by an e, e+, e-, E, E+, or E-
    if there is an e or E, it must be followed by one or more digits
      

5.7: Parameter rules

The following is taken from the OpenCSM.h file:

Valid names:
    start with a letter, colon (:), or at-sign (@)
    contains letters, digits, at-signs (@), underscores (_), and colons (:)
    contains fewer than 32 characters
    names that start with an at-sign cannot be set by a CONPMTR, DESPMTR,
       or SET statement
    if a name has a dot-suffix, a property of the name (and not its value) is
       returned
       x.nrow   number of rows     in x
       x.ncol   number of columns  in x
       x.size   number of elements in x (=x.nrow*x.ncol)
       x.sum    sum of elements    in x
       x.norm   norm of elements   in x (=sqrt(x[1]^2+x[2]^2+...))
       x.min    minimum value      in x
       x.max    maximum value      in x

Array names:
    basic format is: name[irow,icol] or name[ielem]
    name must follow rules above
    irow, icol, and ielem must be valid expressions
    irow, icol, and ielem start counting at 1
    values are stored across rows ([1,1], [1,2], ..., [2,1], ...)

Types:
    CONSTANT
       declared and defined by a CONPMTR statement
       must be a scalar
        is only available at the .csm file level
        can be set  outside ocsmBuild by a call to ocsmSetValu
        can be read outside ocsmBuild by a call to ocsmGetValu
    EXTERNAL
        if a scalar, declared and defined by a DESPMTR statement
        if an array, declared by a DIMENSION statement (with despmtr=1)
                     values defined by one or more DESPMTR statements
        each value can only be defined in one DESPMTR statement
        can have an optional lower bound
        can have an optional upper bound
        is only available at the .csm file level
        can be set  outside ocsmBuild by a call to ocsmSetValu
        can be read outside ocsmBuild by a call to ocsmGetValu
    INTERNAL
        if a scalar, declared and defined by a SET statement
        if an array, declared by a DIMENSION statement (with despmtr=0)
                     values defined by one or more SET statements
        values can be overwritten by subsequent SET statements
        are created by an INTERFACE statement in a .udc file
        see scope rules (below)

    @-parameters depend on the last SELECT statement.
        each time a new Body is added to the Stack, 'SELECT body' is
            implicitly called
        depending on last SELECT statement, the values of the
             @-parameters are given by:

               body face edge node  <- last SELECT

        @nbody   x    x    x    x   number of Bodys
        @ibody   x    x    x    x   current   Body
        @nface   x    x    x    x   number of Faces in @ibody
        @iface  -1    x   -1   -1   current   Face  in @ibody
        @nedge   x    x    x    x   number of Edges in @ibody
        @iedge  -1   -1    x   -1   current   Edge  in @ibody
        @nnode   x    x    x    x   number of Nodes in @ibody
        @inode  -1   -1   -1    x   current   Node  in @ibody
        @igroup  x    x    x    x   group of current Body

        @ibody1 -1    x    x   -1   first  element of 'Body' Attribute in @ibody
        @ibody2 -1    x    x   -1   second element of 'Body' Attribute in @ibody

        @xmin    x    x    *    x   x-min of bounding box or x at beg of edge
        @ymin    x    x    *    x   y-min of bounding box or y at beg of edge
        @zmin    x    x    *    x   z-min of bounding box or z at beg of edge
        @xmax    x    x    *    x   x-max of bounding box or x at end of edge
        @ymax    x    x    *    x   y-max of bounding box or y at end of edge
        @zmax    x    x    *    x   z-max of bounding box or z at end of edge

        @length  0    0    x    0   length of edge
        @area    x    x    0    0   area of face or surface area of body
        @volume  x    0    0    0   volume of body (if a solid)

        @xcg     x    x    x    x   location of center of gravity
        @ycg     x    x    x    x
        @zcg     x    x    x    x

        @Ixx     x    x    x    0   centroidal moment of inertia
        @Ixy     x    x    x    0
        @Ixz     x    x    x    0
        @Iyx     x    x    x    0
        @Iyy     x    x    x    0
        @Iyz     x    x    x    0
        @Izx     x    x    x    0
        @Izy     x    x    x    0
        @Izz     x    x    x    0

        in above table:
           x -> value is set
           * -> special value is set (if edge)
           0 -> value is set to  0
          -1 -> value is set to -1

Scope:
    CONSTANT parameters are available everywhere
    EXTERNAL parameters are only usable within the .csm file
    INTERNAL within a .csm file
                created by a DIMENSION or SET statement
                values are usable only within the .csm file
             within a .udc file
                created by an INTERFACE of SET statament
                values are usable only with the current .udc file
      

5.8: Expression rules

The following is taken from the OpenCSM.h file:

Valid operators (in order of precedence):
    ( )            parentheses, inner-most evaluated first
    func(a,b)      function arguments, then function itself
    ^              exponentiation      (evaluated left to right)
    * /            multiply and divide (evaluated left to right)
    + -            add and subtract    (evaluated left to right)

Valid function calls:
    pi(x)                        3.14159...*x
    min(x,y)                     minimum of x and y
    max(x,y)                     maximum of x and y
    sqrt(x)                      square root of x
    abs(x)                       absolute value of x
    int(x)                       integer part of x  (3.5 -> 3, -3.5 -> -3)
                                     produces derivative=0
    nint(x)                      nearest integer to x
                                     produces derivative=0
    ceil(x)                      smallest integer not less than x
                                     produces derivative=0
    floor(x)                     largest integer not greater than x
                                     produces derivative=0
    mod(a,b)                     modulus(a/b), with same sign as a and b>=0
    sign(test)                   returns -1, 0, or +1
                                     produces derivative=0
    exp(x)                       exponential of x
    log(x)                       natural logarithm of x
    log10(x)                     common logarithm of x
    sin(x)                       sine of x          (in radians)
    sind(x)                      sine of x          (in degrees)
    asin(x)                      arc-sine of x      (in radians)
    asind(x)                     arc-sine of x      (in degrees)
    cos(x)                       cosine of x        (in radians)
    cosd(x)                      cosine of x        (in degrees)
    acos(x)                      arc-cosine of x    (in radians)
    acosd(x)                     arc-cosine of x    (in degrees)
    tan(x)                       tangent of x       (in radians)
    tand(x)                      tangent of x       (in degrees)
    atan(x)                      arc-tangent of x   (in radians)
    atand(x)                     arc-tangent of x   (in degrees)
    atan2(y,x)                   arc-tangent of y/x (in radians)
    atan2d(y,x)                  arc-tangent of y/x (in degrees)
    hypot(x,y)                   hypotenuse: sqrt(x^2+y^2)
    hypot3(x,y,z)                hypotenuse: sqrt(x^2+y^2+z^2)
    Xcent(xa,ya,dab,xb,yb)       X-center of circular arc
                                     produces derivative=0
    Ycent(xa,ya,dab,xb,yb)       Y-center of circular arc
                                     produces derivative=0
    Xmidl(xa,ya,dab,xb,yb)       X-point at midpoint of circular arc
                                     produces derivative=0
    Ymidl(xa,ya,dab,xb,yb)       Y-point at midpoint of circular arc
                                     produces derivative=0
    seglen(xa,ya,dab,xb,yb)      length of segment
                                     produces derivative=0
    incline(xa,ya,dab,xb,yb)     inclination of chord (in degrees)
                                     produces derivative=0
    radius(xa,ya,dab,xb,yb)      radius of curvature (or 0 for LINSEG)
                                     produces derivative=0
    sweep(xa,ya,dab,xb,yb)       sweep angle of circular arc (in degrees)
                                     produces derivative=0
    turnang(xa,ya,dab,xb,yb,...
                     dbc,xc,yc)  turnnig angle at b (in degrees)
                                     produces derivative=0
    dip(xa,ya,xb,yb,rad)         acute dip between arc and chord
                                     produces derivative=0
    smallang(x)                  ensures -180<=x<=180
    ifzero(test,ifTrue,ifFalse)  if test=0, return ifTrue, else ifFalse
    ifpos(test,ifTrue,ifFalse)   if test>0, return ifTrue, else ifFalse
    ifneg(test,ifTrue,ifFalse)   if test<0, return ifTrue, else ifFalse
    ifnan(test,ifTrue,ifFalse)   if test is NaN, return ifTrue, else ifFalse
      

5.9: Attribute rules

The following is taken from the OpenCSM.h file:

EGADS Attributes assigned to Bodys:

    _body       Body index (bias-1)

    _brch       Branch index (bias-1)

           all global Attributes

           all Attributes associated with Branch that created Body

           all Attributes associated with "SELECT $body" statement

EGADS Attributes assigned to Faces:

    _body       non-unique 2-tuple associated with first Face creation
        [0]     Body index in which Face first existed (bias-1)
        [1]     face-order associated with creation (see above)

    _brch       non-unique even-numbered list associated with Branches
                   that are active when the Face is created (most
                   recent Branch is listed first)
        [2*i  ] Branch index (bias-1)
        [2*i+1] (see below)

                Branches that contribute to brch Attribute are
                   primitive  (for which _brch[2*i+1] is face-order)
                   UDPRIM.udc (for which _brch[2*i+1] is 1)
                   grown      (for which _brch[2*i+1] is face-order)
                   applied    (for which _brch[2*i+1] is face-order)
                   sketch     (for which _brch[2*i+1] is Sketch primitive if
                               making WireBody)
                   PATBEG     (for which _brch[2*i+1] is pattern index)
                   IFTHEN     (for which _brch[2*i+1] is -1)
                   RECALL     (for which _brch[2*i+1] is +1)
                   RESTORE    (for which _brch[2*i+1] is Body number stored)

    _faceID     unique 3-tuple that is assigned automatically
          [0]   _body[0]
          [1]   _body[1]
          [2]   sequence number

                if multiple Faces have same _faceID[0] and _faceID[1],
                   then the sequence number is defined based upon the
                   first rule that applies:
                   * Face with smaller xcg  has lower sequence number
                   * Face with smaller ycg  has lower sequence number
                   * Face with smaller zcg  has lower sequence number
                   * Face with smaller area has lower sequence number

           all Attributes associated with Branch that first created Face

           all Attributes associated with "SELECT $face" statement

                Note: if the Attribute name is "color" then the Face is
                      colored in ESP if the Attribute value is "red",
                      "green", "blue", "yellow", "magenta", "cyan",
                      "white", "black" or a 3-tuple that contains values
                      between 0 and 1 for the rgb components

EGADS Attributes assigned to Edges:

    _body       non-unique 2-tuple associated with first Edge creation
        [0]     Body index in which Edge first existed (bias-1)
        [1]     100 * min(_body[1][ileft],_body[1][irite])
                    + max(_body[1][ileft],_body[1][irite])
                (or -3 if non-manifold)

    _edgeID     unique 5-tuple that is assigned automatically
          [0]   _faceID[0] of Face 1 (or 0 if non-manifold)
          [1]   _faceID[1] of Face 1 (or 0 if non-manifold)
          [2]   _faceID[0] of Face 2 (or 0 if non-manifold)
          [3]   _faceID[1] of Face 2 (or 0 if non-manifold)
          [4]   sequence number

                _edgeID[0]/[1] swapped with edge[2]/[3]
                   100*_edgeID[0]+_edgeID[1] > 100*_edgeID[2]+_edgeID[3]
                if multiple Edges have same _edgeID[0], _edgeID[1],
                   _edgeID[2], and _edgeID[3], then the sequence number
                   is defined based upon the first rule that applies:
                   * Edge with smaller xcg    has lower sequence number
                   * Edge with smaller ycg    has lower sequence number
                   * Edge with smaller zcg    has lower sequence number
                   * Edge with smaller length has lower sequence number

           all Attributes associated with "SELECT $edge" statement

EGADS Attributes assigned to Nodes:

    _nodeID     not assigned at this time

           all Attributes associated with "SELECT $node" statement
      

Back to Table of Contents

6.0: Example .csm file

The following is a copy of tutorial1.csm

# tutorial1
# written by John Dannenhoffer

# default design parameters
despmtr   Lbar      6.00      length of bar
despmtr   Rbar      0.15      radius of bar
despmtr   T         0.50      thickness of weights
despmtr   D         2.00      diameter  of weights
despmtr   Rout      1.20      outer radius (for intersection)
despmtr   Rfil      0.10      fillet radius at end of bar

set       L         Lbar/2

# shaft
cylinder  -L        0.0       0.0       +L        0.0       0.0       Rbar
name      shaft
attribute shaft     1

# left weight
box       -L-T/2    -D/3      -D        T         D*2/3     2*D
name      left_weight
attribute weight    1
union
fillet    Rfil

# rite weight 
box       +L-T/2    -D/2      -D/2      T         D         D
name      rite_weight
attribute weight    2
union
fillet    Rfil

# clip weights with outer cylinder
cylinder  -L-T      0.00      0.00      +L+T      0.00      0.00      Rout
attribute clipper   1
intersect

end
      

Back to Table of Contents

7.0: Frequently Asked Questions (FAQ)

Back to Table of Contents

8.0: Release Notes

8.1: New/extended features in v1.09

New commands/statements

CONPMTR to define a constant Parameter

POINT for generating a Node (with its derivatives)

GROUP for grouping Bodys for STORE, DUMP, and transformations; add associated @igroup at-Parameter

IFTHEN, ELSEIF, ELSE, and ENDIF to conditionally control execution of Branches

THROW, CATBEG, and CATEND to handle errors; also have statements throw errors that could be caught

CSYSTEM and APPLYCSYS to generate and use coordinate systems

New arguments to commands

Allow C1 or C0 continuity in BLEND command by duplicated sketeches; add oneFace=0 argument to BLEND

Add ability to created rounded tips in BLEND command

Add toler=0 and verify=0 arguments to ASSERT command

Extend DUMP command to write .stl, .ugrid, .tess and .egg files

Add toMark=0 argument to DUMP command

Add useEdges=0 argument to PROJECT command

Extend SELECT statement to allow a user to apply attributes to all Edges or Faces

New command line arguments

--version flag to return version

-verify and -addVerify flags for verification execution and setup

-egg to suppport external grid generator

-dict to support dictionary of constant Parameters

-sensTess to choose between configuration and tessellation sensitivities

New/updated UDPs, UDCs, or UDFs

udfCreateBEM to create a BEM and associated file

udfCreatePoly to write a .poly file

udpPod to generate a pod (like in VSP)

udpSample to act as a sample for new user-defined primitives

Add sharpte argument to udpNaca

Add sensitivities to udpParsec

Add attributes to Faces in udpWaffle

ESP updates

Configuration can be colored in Graphics Window if Face has "color" attribute

Post messages in Message Window when ESP is started without a .csm file

Add tooltips to ESP

Clicking on Body name in Tree Window posts the Body's attributes

Allow complete rebuild (without recycling) in ESP by pressing "Up to date"

Add axis labels to axes in lower-left corner of Graphics Window

Add (optional) light-grey axes centered at origin

Allow user to expand/collapse Branch list in ESP

Add "Show Attributes/Csystem" button in ESP

Do not allow statements within a UDC to be edited in ESP

Reorganize and update ESP-help

Miscellaneous updates

Print mass properties (in serveCSM) for all Bodys on stack

Quadrilaterals are generated (and visualized) if a Face has a _makeQuads attribute

Add ocsmSetDtime, ocsmPrintEgo, ocsmGetNorm, ocsmRetCsys, ocsmGetCsys, and ocsmSetCsys functions to OpenCSM API

Add support for an external grid generator (egg) to be used in place of the EGADS tessellator; add ocsmSetTess function to API

Allow all lists to be input either as name of a multi-values Parameter or a semicolon-separated list of expressions

Allow all command names to be specified either in lowercase or UPPERCASE

Add global ID to all Edges and Faces

Add Body, Face, Edge, and Node attribute printing in ocsmPrintBrep

Update ocsmGetVel so that it returns vector sensitivities

Add many new test cases, all with verification data

8.2: Bug fixes since v1.08

Improve robustness of UNION when applied to SheetBodys

Fix .ibody attribute for Edges associated with a Body that is restored more than once

Fix .ibody attribute for Edges associated with FILLET, CHAMFER, HOLLOW, and CONNECT commands

Fix .ibody attribute for Edges

Fix ocsmGetUV and ocsmGetXYZ results when uv=NULL

Fix several memory leaks

Execute dimension checks at run-time (and not load-time)

Fix bug that caused SELECT statements to be written incorrectly in ocsmSave

Fix indentation for PATBREAK statement

Fix bug associated with adding and editing a SELECT statement in ESP

Fix bug associated with single digit attributes

Fix sensitivity error for end-caps in EXTRUDEs, RULEs, and BLENDs

Fix Face sensitivity info in udpBox

Remove MACBEG, MACEND, and RECALL statements from ESP

Mark Branch as dirty if an Attribute or Csystem changes

Fix erroneous truncation of very long metadata in ESP

8.3: New/extended features in v1.08

A new ocsmDelPmtr function has been added to the OpenCSM API to delete a Design Parameter

A new ocsmGetTessVel function has been added to the OpenCSM API to return the 3D sensitivities at all the tessellation points

A new biconvex UDP was written

An additional argument, relative=0, has been added to the SKBEG statement. If set to 1, the coordinates specified by LINSEG, CIRARC, ARC, SPLINE, and BEZIER statements are all relative to the coorindates in the SKBEG statement

The DESPMTR, LBOUND, and UBOUND statements have been extended to allow specification of a single value, a whole row, a whole column, or the whole matrix

The smallang(ang) function has been added to convert angles into the range -180 < ang <= 180

The hypot3(x,y,z) function has been added for 3D vectors

The mod(i,j) function has been added

The x.norm dot suffix has been added to compute the norm of array x

When an edit form is displayed, the first entry box now automatically gets focus on entry

The TAB key now correctly moves between inputs in the edit forms in ESP

Pressing the ENTER key in an edit form is now the same as pressing the OK button

When a SKBEG statement is added in ESP, a matching SKEND is automatically added and ESP enters the sketcher automatically

If a SKBEG Branch is deleted, the whole associated sketch is now deleted

Once a UDPRIM or UDPARG statement has been added, the number of name-value pairs cannot be changed. Add another UDPARG statement if more are needed.

When a new Design Parameter is added, it defaults to be a scalar. New buttons have been added to "Add a Row" or "Add a Column"

The Delete Parameter button has been added to the edit parameter form

5 levels of Undo are now kept in the sketcher

Circle centers can now be constrained in the sketcher

The X and Y constraints at the beginning of a relative sketch can no longer be deleted

In the sketcher, the correct sign is suggested for W, D, R, and S constraints based pon what user draws

Arrow keys and PgUp and PgDn can be used to transform the image in the sketcher

Zero-length segments cannot be accidentally drawn via double clicks in the Sketcher. A new "z" command has been added to create zero-length segments.

Pressing ESC in sketcher no longer exits the sketcher

Pressing < to delete a constraint in the sketcher now gives the user the option to select the one constraint to delete if there are multiple constraints present

The @ key in the sketcher reports coordinates in the Message window

Descriptions of the supell and kulfan UDPs have been added to the help file

NodeBodys are now left on the stack

Attributes can now be assigned to NodeBodys

NodeBodys are now displayed on the screen

For -outLevel=2 in serveCSM, the debug messages now are explicit as to which messages are sent by the browser and which message are sent by the server

8.4: Bug fixes since v1.07

Numerous typos were fixed in this help file

A segmentation fault associated with very large arguments has been fixed

Inclination is now handled consistently in the sketcher and OpenCSM

Temporary sketch variables are freed before starting a new sketch

Trying to save a .csm file to a nonexistent directory no longer causes a segmentation fault

Sensitivities associated with UDCs have been fixed

A bug that prevented a user from having more than one name-value pair in a UDPRIM statement (for a UDC) has been fixed

A memory leak was fixed by freeing of storage associated with arguments before stack finalization

A bug that allowed a udprim to be recycled even when there are velocities in its arguments has been fixed

Analytic sensitivity of EXTRUDE and RULE of a transformed sketch are now correct

A bug associated with the analytic sensitivities for the endcaps in EXTRUDE and RULE has been fixed

Infinite loop in sensitivities for Windows x64, Visual Studio 12.0 has been fixed

Finite difference sensitivities for cylinders and cones that are almost aligned with an axis are now correct

Analytic edge sensitivities in the supell UDP are now correct

Analytic edge sensitivities in ellipse UDP have been corrected for cases when DY=0

A bug that left a picture even after all Branches were deleted has been fixed

Global Attributes are now properly written in .csm files by ocsmSave

A check has been added to make sure that there are at least 2 sketches between rounded nose and tail points in BLEND

Spaces have been removed from constraint expressions that the user specified in the Sketcher so that the sketch can be saved properly

The upper limit must now be greater than the lower limit when changing them in the Key window

A bug that caused surfaces to always be rendered in grey on some Intel graphics devices has been fixed

A bug that caused tutorial3 to seg fault has been fixed

A bug that erroneously recycled a UDPRIM if values in the UDPARG statement changed was fixed

Leaving blank entries in a UDPRIM or UDPARG statement no longer asks the user for confirmation

Pressing Undo after solving a sketch now just undoes the solve

Fixed a bug associated with order of calls during cleanup

The correct bodyID is now applied to WireBodys

Body Attributes are now applied directly to Edges if a WireBody was created by an open sketch

The testing process has been changed to better catch errors during the execution of the test suite

Sensitivities are now correctly computed for non-manifold Edges

8.5: New/extended features in v1.07

CAPRI is no longer supported

serveCSM now returns 1 if running in batch and an error is encountered

A warning is issued if a SolidBody has a non-positive volume

All lists are now semicolon-separated (including in BLEND, CHAMFER, CONNECT, FILLET, HOLLOW, and UNION)

Functions "seglen", "incline", "radius", "sweep", and "dip" were added to the expression evaluator

More checks were added for invalid arguments in the BOX, CYLINDER, CONE, SPHERE, TORUS, EXTRUDE, and REVOLVE commands

An ARC statement was added as an alternative to the CIRARC statement

In an ATTRIBUTE statement, if the attrValue is a multi-valued parameter, then multiple values will be assigned

Errors are raised if trying to apply Attributes to an ASSERT, DESPMTR, DIMENSION, END, INTERFACE, LBOUND, MACBEG, MACEND, MARK, PATBEG, PROJECT, SET, SKBEG, SOLBEG, STORE, UBOUND, or UDPARG statement

Tessellation parameters can be specified in a ".tParams" Attribute at either the global, Body, Face, or Edge level (for use by the internal tessellator)

A BEZIER statement was added to create Bezier curves

A CONNECT statement was added to create a new Body from two old Bodys with certain faces "connected" by a local set of Faces (see flapz.udc for an example use)

The INTERFACE statement now supports multi-valued parameters

Tolerances can be relaxed in INTERSECT statement

The JOIN command has an optional "tolerance" argument

A patbreak statement was added to allow one to break out of a pattern

A REORDER statement has been added to reorient faces (such as might be needed before a RULE or BLEND)

Warnings are generated if the REVOLVE statement yields a possibly-inside-out Body

Analytic sensitivities have been added to the RULE statement

A reorder option was added to RULE and BLEND to allow OpenCSM to automatically reorder loops so as to minimize the chance of twist

A SKCON statement was added to allow constraints to be defined for the sketch solver

The number of Edges are reported when executing the SKEND statement

A SKVAR statement was added to initialize sketcher variables

A "keep" option was added to the STORE command

Tolerances can be relaxed in SUBTRACT statement

Added optional "trimList" to UNION operation to allow a user to union "up to" the closest intersection to the given point

Tolerances can be relaxed in UNION statement commands

The kulfan user-defined primitive (udp) was added to create CST airfoils

The supell user-defined primitive (udp) was added to create a super-ellipse (to assist in creating fuselages)

The biconvex user-defined component (udc) was added to create a biconvex airfoil

The diamond user-defined component (udc) was added to create a diamond-shaped airfoil

The flapz user-defined component (udc) was added to add a (possibly-deflected) flap to an existing body

The popupz user-defined component (udc) was added to generate a "pop-up" from an existing surface

If the server (serveCSM) dies, the Messages window turns pink and no alert is issued

Rolling the middle -mouse button zooms in/out

An interactive sketcher was added

Buttonslabeled "H", "L", "R", "B", "T", "+", and "-" buttons as an alternative to "<Ctrl-h>", "<Ctrl-l>", "<Ctrl-r>", "<Ctrl-b>", "<Ctrl-t>", "<Ctrl-i>" and "<Ctrl-o>" (since some browsers steal some of these control sequences)

The spectrum was changed from blue-green-red to blue-white-red

The environment variable ESP_START was changed to ESP_START (although ESP_START still works)

8.6: Bug fixes since v1.06

A journalling error was associated with the UNION command

The REVOLVE command did not work if given a SheetBody

Storage associated with UDPs was not properly released

Nested UDCs without END statements caused infinite loops

The PROJECT command could fail in certain situations, such as during rebuilds

Repeated points caused problem when creating a spline (so now they are removed)

Errors were raised for expressions in the form "0^any" (they now return "0")

Multi-valued parameters in UDPs were not handled properly when computing sensitivities

Arrays were flattened when being transferred into UDCs

Expressions such as "x[i+1]" were not parsed properly

SheetBodys from BLEND with open sketches were improperly classified as SolidBodys

Infinite loop resulted when an END statement was put into a pattern with zero iterates

The vertical tail was misplaced in myPlane with fidelity set to 1 or 2

Sensitivity failed if using a UDP with an integer or string argument

Default velocity was set to -HUGEQ, causing unset variables to inadvertently execute sensitivities (they are now set to "0")

An error in the first Branch caused ESP to hang

8.7: New/extended features in v1.06

User-defined components (UDCs) have been implemented to execute consistently with user-defined primitives (UDPs). The main difference is that UDCs are defined in scripts (in a file named *.udc) whereas UDPs are defined in C-code that is pre-compiled. The first argument of the UDPRIM statement selects a UDC if it starts with a "/" or a "$/"; otherwise it looks for a UDP.

The INTERFACE statement has been added to be used within UDCs to define the UDC's INTERFACE, including the default values for its arguments.

The JOIN command was added to combine Bodys at common Faces. Using the JOIN command is preferred over the UNION command when the user expects some of the Faces to match exactly.

The STORE and RESTORE commands were added to keep copies of Bodys in memory (rather than in an external files, as was done for DUMP and IMPORT). The advantage is that the build tree information is retained, allowing Bodys to sometimes be reused during the regeneration process.

The EXTRACT command has been added to extract a lower-dimension object (for example, an Edge from a Body).

The COMBINE command has been added to create a higher-dimension object (for example, a Faces from a group of Edges).

The ASSERT command has been added to return an error if the assertion is not satisfied.

The direction vectors in the "noselist" and "taillist" arguments to the BLEND command no longer need to be normalized.

If the arguments to the SUBTRACT command are a SOLID Body and a SHEET Body, then the SOLID Body is scribed with Edges at the intersection of the SOLID and SHEET.

An optional argument (wireonly) has been added to the SKEND command; if wireonly is set to 1, then a (possibly non-planar) WIRE Body is created instead of a SHEET Body.

Array elements can be addressed with a single subscript, which are numbered across rows.

Names are allowed to include colons ":", which is useful for hierarchically organizing names.

The "ifnan", "sign", "ceil", and "floor" functions have been added to the expression evaluator.

".nrow", ".ncol", ".size", ".sum", ".min", and ".max" dot-suffixes can be appended to variables to return properties of the Design Parameter of Local Variable rather than its value.

The "naca456" UDP was added to create NACA-4, -5, and -6 series airfoils.

Global Attributes are placed on all Bodys.

Keyboard shortcuts were added to the ESP viewer:

<Ctrl-h> home (same as <Home>)
<Ctrl-i> zoom in (same as <PgUp>)
<Ctrl-o> zoom out (same as <PgDn>)
<Ctrl-f> front view (same as <Home>)
<Ctrl-t> top view
<Ctrl-b> bottom view
<Ctrl-l> leftside view
<Ctrl-r> riteside view

When a Branch is edited in ESP, the first field associated with the Branch in the Tree window is colored magenta, the Branch's parents are colored cyan, and the Branch's child is colored yellow.

When a Design Parameter is edit-ted in ESP, the first field associated with the Parameter in the Tree window is colored magenta.

If one selects another Branch or Parameter in the Tree window while editting another Branch or Parameter, the current edit is cancelled and the new edit started.

Axes are displayed in ESP.

Branches are indented (with ">") in Tree Window in ESP.

8.8: Bug fixes since v1.05

Attribute values can be strings (prepended by "$").

Improved nose an tail treatment in BLEND.

A sketch can be composed of a single closed spline.

Error in face-order for REVOLVE command.

If a DESPMTR statement tries to redefine a parameter, print out warning message that previous values will be used

Allow filename argument in IMPORT statement to be in form $$/filename (to be consistent with UDPRIM import).

"ifpos", "ifneg", and "ifzero" perform lazy evaluations so that errors in unused arguments do not trigger an error.

Print comment lines that start with a space.

Report number of segments in blending message.

Flip sketch so that its normal direction is in the +x, +y, or +z direction.

Remove creation of spurious Bodys created by JOIN command.

Allow more than one matched Face in JOIN command.

Allow blanks in SELECT, UDPARG, and UDPRIM statement in ESP (but only at end).

Fix serveCSM so that the JSON that it transfers to the browser does not contain ",]" nor ",}".

8.9: Known problems in v1.09

Internet Explorer (11) is not recommended since it sometimes stops sending messages to the server.

When using 64-bit OS X 10.8 or higher, you should use OpenCASCADE 6.6.0 (as opposed to 6.8.0). There is an error somewhere that causes "serveCSM tutorial1_new" to sometimes produces a segmentation fault during rebuilds.

Edges are not drawn in ESP when running a LINUX64 virtual machine under VMware with OSX 10.8 or higher as the host operating system.

The <Ctrl-l> (leftside view) keyboard shortcut does not work in Safari (since it appears that Safari intercepts the <Ctrl-l> before it gets to ESP). Use the "L" button instead.

Test cases with the HOLLOW command do not work when using the pre-built versions of OpenCASCADE 6.6.0 or 6.8.0 for Windows.

In OpenCASCADE 6.8.0, the tolerances associated with the sew operation cause cases with loose tolerances to no longer work.

The "Edit" command in ESP can only be used to edit the .csm file; any .udc files that are opened cannot be edited.

OpenCASCADE can write .step files that are unreadable by other applications (such as an ellipsoid)

Case design8 in sensCSM has two families of results, depending on the version of OS and OCC that is used

Back to Table of Contents

9.0: Error Codes

9.1: OpenCSM error codes

OpenCSM performs extensive error checking that can issue the following error codes:

SUCCESS                                 0

OCSM_FILE_NOT_FOUND                  -201
OCSM_ILLEGAL_STATEMENT               -202
OCSM_NOT_ENOUGH_ARGS                 -203
OCSM_NAME_ALREADY_DEFINED            -204
OCSM_NESTED_TOO_DEEPLY               -205
OCSM_IMPROPER_NESTING                -206
OCSM_NESTING_NOT_CLOSED              -207
OCSM_NOT_MODL_STRUCTURE              -208
OCSM_PROBLEM_CREATING_PERTURB        -209

OCSM_MISSING_MARK                    -211
OCSM_INSUFFICIENT_BODYS_ON_STACK     -212
OCSM_WRONG_TYPES_ON_STACK            -213
OCSM_DID_NOT_CREATE_BODY             -214
OCSM_CREATED_TOO_MANY_BODYS          -215
OCSM_TOO_MANY_BODYS_ON_STACK         -216
OCSM_ERROR_IN_BODYS_ON_STACK         -217
OCSM_MODL_NOT_CHECKED                -218
OCSM_NEED_TESSELLATION               -219

OCSM_BODY_NOT_FOUND                  -221
OCSM_FACE_NOT_FOUND                  -222
OCSM_EDGE_NOT_FOUND                  -223
OCSM_NODE_NOT_FOUND                  -224
OCSM_ILLEGAL_VALUE                   -225
OCSM_ILLEGAL_ATTRIBUTE               -226
OCSM_ILLEGAL_CSYSTEM                 -227

OCSM_SKETCH_IS_OPEN                  -231
OCSM_SKETCH_IS_NOT_OPEN              -232
OCSM_COLINEAR_SKETCH_POINTS          -233
OCSM_NON_COPLANAR_SKETCH_POINTS      -234
OCSM_TOO_MANY_SKETCH_POINTS          -235
OCSM_TOO_FEW_SPLINE_POINTS           -236
OCSM_SKETCH_DOES_NOT_CLOSE           -237
OCSM_CLOSED_SKETCH_NOT_PLANAR        -238
OCSM_ASSERT_FAILED                   -239

OCSM_ILLEGAL_CHAR_IN_EXPR            -241
OCSM_CLOSE_BEFORE_OPEN               -242
OCSM_MISSING_CLOSE                   -243
OCSM_ILLEGAL_TOKEN_SEQUENCE          -244
OCSM_ILLEGAL_NUMBER                  -245
OCSM_ILLEGAL_PMTR_NAME               -246
OCSM_ILLEGAL_FUNC_NAME               -247
OCSM_ILLEGAL_TYPE                    -248
OCSM_ILLEGAL_NARG                    -249

OCSM_NAME_NOT_FOUND                  -251
OCSM_NAME_NOT_UNIQUE                 -252
OCSM_PMTR_IS_EXTERNAL                -253
OCSM_PMTR_IS_INTERNAL                -254
OCSM_PMTR_IS_CONSTANT                -255
OCSM_FUNC_ARG_OUT_OF_BOUNDS          -256
OCSM_VAL_STACK_UNDERFLOW             -257  /* probably not enough args to func */
OCSM_VAL_STACK_OVERFLOW              -258  /* probably too many   args to func */

OCSM_ILLEGAL_BRCH_INDEX              -261  /* should be from 1 to nbrch */
OCSM_ILLEGAL_PMTR_INDEX              -262  /* should be from 1 to npmtr */
OCSM_ILLEGAL_BODY_INDEX              -263  /* should be from 1 to nbody */
OCSM_ILLEGAL_ARG_INDEX               -264  /* should be from 1 to narg  */
OCSM_ILLEGAL_ACTIVITY                -265  /* should OCSM_ACTIVE or OCSM_SUPPRESSED */
OCSM_ILLEGAL_MACRO_INDEX             -266  /* should be between 1 and 100 */
OCSM_ILLEGAL_ARGUMENT                -267
OCSM_CANNOT_BE_SUPPRESSED            -268
OCSM_STORAGE_ALREADY_USED            -269
OCSM_NOTHING_PREVIOUSLY_STORED       -270

OCSM_SOLVER_IS_OPEN                  -271
OCSM_SOLVER_IS_NOT_OPEN              -272
OCSM_TOO_MANY_SOLVER_VARS            -273
OCSM_UNDERCONSTRAINED                -274
OCSM_OVERCONSTRAINED                 -275
OCSM_SINGULAR_MATRIX                 -276
OCSM_NOT_CONVERGED                   -277

OCSM_UDP_ERROR1                      -281
OCSM_UDP_ERROR2                      -282
OCSM_UDP_ERROR3                      -283
OCSM_UDP_ERROR4                      -284
OCSM_UDP_ERROR5                      -285
OCSM_UDP_ERROR6                      -286
OCSM_UDP_ERROR7                      -287
OCSM_UDP_ERROR8                      -288
OCSM_UDP_ERROR9                      -289

OCSM_OP_STACK_UNDERFLOW              -291
OCSM_OP_STACK_OVERFLOW               -292
OCSM_RPN_STACK_UNDERFLOW             -293
OCSM_RPN_STACK_OVERFLOW              -294
OCSM_TOKEN_STACK_UNDERFLOW           -295
OCSM_TOKEN_STACK_OVERFLOW            -296
OCSM_UNSUPPORTED                     -298
OCSM_INTERNAL_ERROR                  -299
      

9.2: EGADS error codes

In addition, sometimes EGADS or CAPRI will issue an error code. The EGADS error codes that may be seen from time to time include:

EGADS_NOTFOUND                         -1
EGADS_NULLOBJ                          -2
EGADS_NOTOBJ                           -3
EGADS_MALLOC                           -4
EGADS_INDEXERR                         -5
EGADS_NONAME                           -6
EGADS_NODATA                           -7
EGADS_MIXCNTX                          -8
EGADS_NOTCNTX                          -9
EGADS_NOTXFORM                        -10
EGADS_REFERCE                         -11
EGADS_NOTTOPO                         -12
EGADS_EMPTY                           -13
EGADS_NOTTESS                         -14
EGADS_NOTGEOM                         -15
EGADS_RANGERR                         -16
EGADS_NOLOAD                          -17
EGADS_NOTMODEL                        -18
EGADS_WRITERR                         -19
EGADS_NOTBODY                         -20
EGADS_GEOMERR                         -21
EGADS_TOPOERR                         -22
EGADS_CONSTERR                        -23
EGADS_DEGEN                           -24
EGADS_NOTORTHO                        -25
EGADS_BADSCALE                        -26
EGADS_OCSEGFLT                        -27
EGADS_TOPOCNT                         -28
EGADS_ATTRERR                         -29
EGADS_EXISTS                          -30
      

Back to Table of Contents

10.0: Bugs Reports and Other Feedback

All reports of possible 'bugs' and any other feedback should be e-mailed to 'jfdannen@syr.edu' or 'haimes@mit.edu'. If a bug report, please include the version number you are running (listed in the title bar at the top of the program), what you were doing at the time of the bug, and what happened that you didn't expect. The more information that you include, the better the chances that the bug can be reproduced and hence fixed.

Back to Table of Contents

11.0: Copyright

Copyright (C) 2010/2016 John F. Dannenhoffer, III (Syracuse University)

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

Back to Table of Contents

12.0: Glossary

activity An Attribute of a Branch which tells if the Branch should be executed the next time the Model is re-built. ESP supports 'active' and 'suppressed' activities.

Branch An entity in the Model's feature tree that corresponds to either a primitive solid, transformation, boolean operator, sketch entity, or other item used in the construction of a Model.

browser A computer program with which a user interacts with ESP. ESP currently runs in FireFox and SeaMonkey.

collapse The process of 'closing up' a node in a tree so that its children are not displayed. This is accomplished by pressing the - to the left of an (expanded) tree node.

drag An operation in which a user presses a mouse button and holds it down while moving it to another location on the screen.

Design Velocity A change in an input paramater from which changes in the local surface normals will be computed.

ESP The Engineering Sketch Pad is a browser-based software system that allows users create, modify, (re-)build, and save constructive solid models built via OpenCSM.

expand The process of 'opening up' a node in a tree to see its children nodes. This is accomplished by pressing the + to the left of a (collapsed) tree node.

flying mode A way of panning, zooming, and rotating a display in which the motion of the image in the Graphics Window changes as long as the user holds the mouse button. Use the ! key in the Graphics Window to toggle flying mode on and off.

Graphics window The window on the top-right of the ESP screen that contains a graphical representation of the current configuration.

hostname The name of the computer that is running the server (typically serveCSM). If using a single computer for both the browser and server, use 'Localhost' as the hostname.

journal A file that is written (on the server) that keeps track of the commands that user executed while running ESP. A user (who has access to the server) can copy the journal file to another name and use it to automatically replay the session that was journalled during a future invocation of serveCSM.

Key window The window on the bottom left of the ESP screen that contains a spectrum to indicate sensitivity values. If no sensitivity is active, this window in blank.

Messages window The window on the bottom right of the ESP screen that contains status information and other messages to the user.

Model A container that contains the Parameters and (feature-tree) Branches.

Parameter A two-dimensional array of floating-point numbers that is used during the build process to generate a specific instance of a Model.

port The port number on which the server (typically serveCSM) is listening for requests by the browser. serveCSM uses 7681 as its default port.

server A computer program in which OpenCSM runs and which 'serves' Models and Boundary Representations to ESP. The program 'serveCSM' is the initial server for ESP.

Tree window The window on the top-left of the ESP screen that contains command buttons, a tree-like view of the current Parameters, a tree-like view of the current Branches (of the feature tree), and a tree-like view of the display settings.

UDC User-defined component. This is essentially a macro that is stored in a .udc file. It is execute with a UDPRIM statement, where the primtype either starts with / or $/

UDP User-defined primitive. This is a user-supplied compiled file (from C or FORTRAN) that creates a non-standard primitive. It is executed with a UDPRIM statement, where the promtype starts with a letter

Back to Table of Contents