Engineering Sketch Pad (ESP) Version 1.05

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

Date: July, 2014.

0.0 Table of Contents

1.0 Overview

2.0 Tutorials

2.1 First tutorial

2.2 Second tutorial

2.3 Third tutorial

3.0 Command Line

4.0 Interactive Options

5.0 Format of the .csm File

5.1 Special characters

5.2 Valid CSM statements

5.3 User-defined Primitives shipped with OpenCSM

5.4 Parameter rules

5.5 Expression rules

5.6 Attribute rules

6.0 Example .csm file

7.0 Error Codes

7.1 OpenCSM error codes

7.2 EGADS error codes

8.0 Bug Reports and Other Feedback

9.0 Copyright

10.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. ESP can use either the EGADS/OpenCASCADE or CAPRI geometric modeler.

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.

Table of Contents

2.0: Tutorials

2.1 First tutorial

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 .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 WV_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. It contains listings 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. It contains a graphical representation of the current configuration. Occasionally, the "Graphics" window will contain a form (such as when adding or editting a Branch); when a form is present, you must press Cancel or OK in the form to return to the graphical representation.

The window on the bottom left is the "Key" window. If the user has asked for a sensitivity calculation, this window will contain an annotated spectrum to tell the user the meaning of the colors in the "Graphics" window; otherwise the "Key" window will be blank.

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; the "saved" view can be retrieved by pressing the "<" key.

The default (home) view can be obtained by pressing "<Home>". (The home view is one in which the x-coordinate increases from left to right and the y-coordinate increases from bottom to top.)

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>" key can be used to zoom in and the "<PgDn>" key can be used to zoom out. The behavior of these keys 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.

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. At the top of the "Tree" window is a series of buttons:

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 a prompt that asks for the new value; the current value is pre-loaded in this prompt window, as in:

For now change the value to "9" and press OK. 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, 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.

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. Those marked with plus signs (+) are commands that are expected to be added in the future.

We will choose a "sphere" and press OK, 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". Press OK 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). 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 fusion of these two volumes, but instead you wanted the solid that is common to them. First, remove the "union"; this can easily be done by clicking on "Brch_00012" and then choosing "Delete this Branch". (Alternatively you can press the "Undo" button at the top of the "Tree" window.)

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 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. Since Design Parameters can have multiple values (think "array"), ESP asks for the number of rows and columns. Since we only have a single value, enter "1" for both of these. You are then presented with a form such as:

Set the (only) value to "0.08".

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". 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.

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 tells you that you have an error. 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):

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 and change the "Activity" from "Active" to "Suppressed", and select OK. 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, re-build to the last Branch by clicking it and choosing "Build to this Branch".

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. By pressing the "+" to the left of "Brch_000009", its attribute ("clipper") can be seen to have the value "1". Change the attribute to "10" by pressing "clipper" and entering "10" at the prompt.

We can add an attribute to "Brch_000009" by choosing "Add Attribute"; use the name "test" and the value "ESP". Press the "+" to the left of "Brch_000009" and you will see that the Branch now has 2 attributes. After some thought, you realize that "ESP" is not defined, 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 "-1" and "+1" 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". Now click on "Rbar" and "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.)

Readjust the limits of the Key window again to -2 and 1 (by clicking in the Key window to get the prompts).

Lastly, save your work by pressing the "Save" button and choosing "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
      

Alternatively, we can start with the new tutorial1_new.csm file with the command:

        serveCSM tutorial1_new
      

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

2.2 Second tutorial

For the second tutorial, we will start serveCSM without a .csm file and investigate the various filleting, chamfering, and hollowing options.

Start serveCSM with commands such as

        setenv WV_START "open -a /Applications/Firefox.app ../ESP/ESP.html"
        serveCSM
      
This will bring up the browser with no "Design Parameters", "Local Variables", or "Branches".

Click on "Branches" and create a "sphere" centered at the origin with radius of "0.5". Then click on "Branches" to create a "box" anchored at "0", "0", "0" (which is at the center of the sphere) and specify its length, width, and height to be "1". Build this configuration, producing:

We will now set up for our exploration of fillets (and chamfers). These operations are performed on the last primitive (such as "box" or "cylinder") or last Boolean operation (such as "intersect", "union", or "subtract"). If we were to add a "fillet" Branch now, it would be applied to the "box".

But before we do that, let up set up a design parameter that defines the Edges to be filleted. Do this by clicking "Design Parameters" and adding one called "edges", that has 2 rows and 2 columns with the values "2", "4", "2", and "3".

We can now add a "fillet" Branch with a radius of "0.1" and an "$edgeList" set to "edges". Build this configuration, producing:

The way ESP determines which edges to fillet is based upon the code included in "edges". Specifically, ESP takes pairs of elements from "edges" and interprets them (in order) as:

Therefore the "edges" Design Parameter says to select the Edge(s) between the "2" (right) and "4" (top) Faces; then select the Edge(s) between the "2" (right) and "3" (bottom) Face.

We will now investigate several other options. To do this, we will specify the "$edgeList" directly with a comma-separated list rather than by reference to a Design Parameter. Expand the "Branches" list (by clicking on the "+" to the left of "Branches"). Now click on "Brch_000002" and change "$edgeList" to "2,4,2,3" and rebuild. You should get exactly the same result as before.

Now change the "$edgeList" of "Brch_000002" to simply "2" and rebuild. You should get an error, since ESP expects the entries in "$edgeList$" to come in pairs.

Now change the "$edgeList" of "Brch_000002" to "2," and rebuild. Since there was a naked "," at the end of "$edgeList", a "0" was implicitly added. The pair of entries now consisted of "2" and "0", meaning that all Edges associated with the "2" (right) Face are to be filleted, producing:

Now change the "$edgeList" of "Brch_000002" to "2,4" and rebuild. This should fillet the "2" (right) "4" (top) Edge.

Now change the "$edgeList" of "Brch_000002" to "2,4," and rebuild. Again the naked "," at the end of "$edgeList" adds a "0". Since there is not an even number of entries ("2", "4", and "0") an error results.

Now change the "$edgeList" of "Brch_000002" to "2,4,2" and rebuild. Again, an odd number of entries causes an error.

Now change the "$edgeList" of "Brch_000002" to "2,4,2," and rebuild. This results in the Edge(s) between "2" (right) and "4" (top) being selected, followed by all the Edges associated with Face "2". Since the latter pair essentially over-writes the "2" "4" selection, this is the same as "2,0" which we saw above.

Now change the "$edgeList" of "Brch_000002" to "2,4,2,3" and rebuild. This should fillet the "2" (right) "4" (top) Edge and the "2" (right) "3" (bottom) Edge, yielding the same result as we had when we used "edges".

Changing the "$edgeList" of "Brch_000002" to "2,4,2,3," and rebuilding once again produces an error since the implicitly-added "0" (by the naked trailing ",") results in an odd number of entries.

Finally, change the "$edgeList" of "Brch_000002" to "0,0,-2,-4,-2,-3" and rebuild, producing:

To understand why this happens, the "0,0" at the beginning selects all the Edges, then the "-2,-4" unselects the Edge between "2" (right) and "4" (top), then the "-2,-3" unselects the Edge between the "2" (right) and "3" (bottom) Faces.

Now add a "union" Branch with the defaults and then a "chamfer" Branch with its "radius" to set "0.2" and "$edgeList" to "0".

The "chamfer" works exactly the same as the "fillet". But because the last Branch was a Boolean ("union"), it creates the chamfer on the intersection of the sphere and the box. When the "fillet" or "chamfer" is associated with a Boolean, the values in "$edgeList" are ignored and all Edges are automatically filleted of chamfered. The resulting configuration is:

Fillets and chamfers can be suppressed by changing their "Activity" to "Suppressed". Rebuild. Reactivate them and rebuild.

Lastly we will investigate the "hollow" command. Since this command is rather fragile, we are going to start off by deleting "Brch_000005", "Brch_000004", and "Brch_000003" (by selecting them and choosing "Delete this Branch"). Rebuild.

Now identify the Faces on the left and right of the configuration by pointing to it and pressing "^"; you should see that they are faces 1 and 2. Here we are using the actual Face number and not the face-order as we did for fillets and chamfers.

Now add a "hollow" Branch with its "thick" set to "0.1" and "$faceList" set to "2,1". This says to make a Body whose shell thickness is 0.1 and which pokes through the left (1) Face of Body 2.

If we wanted to remove both the left and right Faces, edit "Brch_000006" and set "$faceList" to "2,1,2,2" and rebuild.

Note that we significantly simplified the configuration before using "hollow". Experience has shown that this command is very fragile and should be avoided if possible. For example to avoid it in t his case, it would have been more robust to "subtract" a smaller "box" from the outer "box".

2.3 Third tutorial

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

        setenv WV_START "open -a /Applications/Firefox.app ../ESP/ESP.html"
        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 the will ultimately be blended are those back to the previous "mark". This 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.

Table of Contents

3.0: Command Line

To start serveCSM, one uses the command:

        serveCSM filename [-port portnum] [-outLevel n] [-jrnl jrnlname] [-batch]
      

The -port option tells serveCSM with which port to connect.

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 -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, user modifies the file portX.jrnl 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.)

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 within an MDAO environment.

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.

Table of Contents

5.0: 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.

Extra arguments in a statement are discarded and can thus be used as a comment.

The last statement must be 'end'. (Everything else is 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.1: Special characters

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

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

!          not used (but allowed within names for backward compatibility)
~          not used
%          not used
&          not used
=          not used
{ }        not used
'          not used
:          not used
< >        not used
?          not used
      

5.2: Valid CSM statements

The following is taken from the OpenCSM.h file:

dimension pmtrName nrow ncol despmtr=0
          use:    set up an array Parameter
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  nrow >= 1
                  ncol >= 1
                  pmtrName must not start with '@'
                  if despmtr=0, then marked as INTERNAL
                  if despmtr=1, then marked as EXTERNAL
                  does not create a Branch

despmtr   pmtrName values
          use:    define a (constant) driving design Parameter
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  name must not refer to an INTERNAL Parameter
                  name will be marked as EXTERNAL
                  if pmtrName already exists, value is set by last despmtr statement
                  name is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  values cannot refer to any other Parameter
                  if values has multiple values (separated by ;), then
                     any subscripts in pmtrName are ignored
                  values are defined across rows
                  if values is longer than Parameter size, extra values are lost
                  if values is shorter than Parameter size, last value is repeated
                  does not create a Branch

lbound    pmtrName bounds
          use:    defines a lower bound for a design Parameter
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  pmtrName must have been defined previously by despmtr statement
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  bound is set by last lbound statement
                  name is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  bounds cannot refer to any other Parameter
                  does not create a Branch
                  if value of Parameter is smaller than bounds, a warning is generated

ubound    pmtrName bounds
          use:    defines an upper bound for a design Parameter
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  pmtrName must have been defined previously by despmtr statement
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  bound is set by last ubound statement
                  name is used directly (without evaluation)
                  irow and icol cannot contain a comma or open bracket
                  bounds cannot refer to any other Parameter
                  does not create a Branch
                  if value of Parameter is larger than bounds, a warning is generated

box       xbase ybase zbase dx dy dz
          use:    create a box Body
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  face-order is: xmin, xmax, ymin, ymax, zmin, zmax

sphere    xcent ycent zcent radius
          use:    create a sphere Body
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  face-order is: ymin, ymax

cone      xvrtx yvrtx zvrtx xbase ybase zbase radius
          use:    create a cone Body
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  face-order is: (empty), base, umin, umax

cylinder  xbeg ybeg zbeg xend yend zend radius
          use:    create a cylinder Body
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  face-order is: beg, end, umin, umax

torus     xcent ycent zcent dxaxis dyaxis dzaxis majorRad minorRad
          use:    create a torus Body
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  face-order is: xmin/ymin, xmin/ymax, xmax/ymax, xmax,ymax

import    filename bodynumber=1
          use:    import from filename
          pops:   -
          pushes: Body
          notes:  sketcher 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
                  face-order is based upon order in file

udprim    primtype argName1 argValue1 argName2 argValue2 argName3 argValue3 argName4 argValue4
          use:    create a Body by executing a user-defined primitive
          pops:   -
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  primtype  determines the type of primitive and the number of argName/argValue pairs
                  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
                  face-order is based upon order returned from udprim
                  see udp documentation for full information

extrude   dx dy dz
          use:    create a Body by extruding a Sketch
          pops:   Sketch
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  if Sketch is a SHEET Body, then a SOLID Body is created
                  if Sketch is a WIRE  Body, then a SHEET Body is created
                  face-order is: base, end, feat1, ...

rule
          use:    create a Body by creating ruled surfaces through Sketches since mark
          pops:   Sketch1 ... mark
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  all Sketches must have the same number of Segments
                  if all Sketches are WIRE Bodies, then a SHEET Body is created
                     otherwise a SOLID Body is created
                  the first and/or last Sketch can be a point
                  face-order is: base, end, seg1a, seg1b, ..., seg2a, ...

loft      smooth
          use:    create a Body by lofting through Sketches since mark
          pops:   Sketch1 ... mark
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  all Sketches must have the same number of Segments
                  if Sketch is a SHEET Body, then a SOLID Body is created
                  if Sketch is a WIRE  Body, then a SHEET Body is created
                  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
                  loft may be deprecated in the future

blend     noseList=0 tailList=0
          use:    create a Body by blending through Sketches since mark
          pops:   Sketch1 ... mark
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  all Sketches must have the same number of Segments
                  if all Sketches are WIRE Bodies, then a SHEET Body is created
                     otherwise a SOLID Body is created
                  the first and/or last Sketch can be a point
                  noseList is either a 0 or the name of an 8-valued parameter
                  noseList is only applied if first Sketch is a point
                  tailList is either a 0 or the name of an 8-valued parameter
                  tailList is only applied if last  Sketch is a point
                  noseList and tailList contain rad1;dx1;dy1;dz1;rad2;dx2;dy2;dz2
                  face-order is: base, end, seg1, seg2, ...

revolve   xorig yorig zorig dxaxis dyaxis dzaxis angDeg
          use:    create a Body by revolving a Sketch around an axis
          pops:   Sketch
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  if Sketch is a SHEET Body, then a SOLID Body is created
                  if Sketch is a WIRE  Body, then a SHEET Body is created
                  face-order is: (base), (end), feat1, ...

sweep
          use:    create a Body by sweeping a Sketch along a Sketch
          pops:   Sketch1 Sketch2
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  Sketch1 must be either a SHEET or WIRE Body
                  Sketch2 must be a WIRE Body
                  if Sketch2 is not slope-continuous, result may not be as expected
                  face-order is: base, end, feat1a, feat1b, ...

fillet    radius edgeList=0
          use:    apply a fillet to a Body
          pops:   Body
          pushes: Body
          notes:  sketcher 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 comma-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
                  face-order is based upon order that is returned from EGADS

chamfer   radius edgeList=0
          use:    apply a chamfer to a Body
          pops:   Body
          pushes: Body
          notes:  sketcher 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 comma-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
                  face-order is based upon order that is returned from EGADS

hollow    thick   iface1=0  iface2=0  iface3=0  iface4=0  iface5=0  iface6=0
          use:    hollow out a solid Body
          pops:   Body
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  if thick==0, then SOLID is converted to SHEET or SHEET to WIRE
                  if iface*=0, then Face not added to list
                  if all iface*=0 then create an offset body instead
                  face-order is based upon faceID order of offset Faces

intersect order=none index=1
          use:    perform Boolean intersection (Body2 & Body1)
          pops:   Body1 Body2
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  Body1 and Body2 must be SOLID Bodys
                  if intersection does not produce at least index Bodies, 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)

subtract  order=none index=1
          use:    perform Boolean subtraction (Body2 - Body1)
          pops:   Body1 Body2
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  Body1 and Body2 must be SOLID Bodys
                  if subtraction does not produce at least index Bodies, 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)

union  tomark=0
          use:    perform Boolean union
          pops:   Body1 Body2  -or-  Body1 ... mark
          pushes: Body
          notes:  sketcher may not be open
                  solver   may not be open
                  if tomark=0
                     union SOLID Body1 and SOLID Body2
                     create a SOLID Body
                  if tomark=0
                     union SHEET Body1 and SHEET Body2
                     create a SHEET Body
                  if tomark=1
                     union all SOLID Bodys since mark
                     create a SOLID Body
                  if tomark=2
                     union all SHEET Bodys since mark
                     create a SOLID Body

translate dx dy dz
          use:    translates the entry on top of Stack
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open

rotatex   angDeg yaxis zaxis
          use:    rotates entry on top of Stack around x-like axis
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open

rotatey   angDeg zaxis xaxis
          use:    rotates entry on top of Stack around y-like axis
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open

rotatez   angDeg xaxis yaxis
          use:    rotates entry on top of Stack around z-like axis
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open

scale     fact
          use:    scales entry on top of Stack
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open

mirror    nx ny nz dist=0
          use:    mirrors entry on top of Stack
          pops:   any
          pushes: any
          notes:  sketcher 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

skbeg     x y z
          use:    start a new sketch with the given point
          pops:   -
          pushes: -
          notes:  opens sketcher
                  solver   may not be open

linseg    x y z
          use:    create a new line segment, connecting the previous
                     and specified points
          pops:   -
          pushes: -
          notes:  sketcher must be open
                  solver   may not be open

cirarc    xon yon zon xend yend zend
          use:    create a new circular arc, using t he previous point
                     as well as the two points specified
          pops:   -
          pushes: -
          notes:  sketcher must be open
                  solver   may not be open

spline    x y z
          use:    add a point to a spline
          pops:   -
          pushes: -
          notes:  sketcher must be open
                  solver   may not be open

skend
          use:    completes a Sketch
          pops:   -
          pushes: Sketch
          notes:  sketcher must be open
                  solver   may not be open
                  all linsegs and cirarcs must be x-, y-, or z-co-planar
                  if sketch is     closed, then a SHEET Body is created
                  if sketch is not closed, then a WIRE  Body is created
                  if skend immediately follows skbeg, then a Point
                     is created (which can be used at either end of a loft or blend)
                  closes sketcher

solbeg    varlist
          use:    starts a solver block
          pops:   -
          pushes: -
          notes:  solver must not be open
                  opens the solver
                  varlist is a list of semi-colon-separated INTERNAL parameters
                  varlist must end with a semi-colon

solcon    expr
          use:    constraint used to set solver variables
          pops:   -
          pushes: -
          notes:  sketcher must not be open
                  solver must be open
                  solend will drive expr to zero

solend
          use:    close a solver block
          pops:   -
          pushes: -
          notes:  sketcher must not be open
                  solver must be open
                  adjust variables to drive constrains to zero
                  closes the solver

set       pmtrName exprs
          use:    define a (redefinable) driven Parameter
          pops:   -
          pushes: -
          notes:  solver   may not be open
                  pmtrName can be in form 'name' or 'name[irow,icol]'
                  pmtrName must not start with '@'
                  name must not refer to an EXTERNAL Parameter
                  name will be marked as INTERNAL
                  name 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

include   filename arg1=0 arg2=0 arg3=0 arg4=0 arg5=0 arg6=0 arg7=0 arg8=0
          use:    include a file into the current input stream
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  filename is used directly (without evaluation)
                  include files have the extension .csmi
                  if filename starts with '$$/', use path relative to .csm file
                  include file may not contain despmtr, lbound, or ubound statements
                  include files can be nested, but not circular
                  if include file does not have a return statement, one is generated
                      automatically at end
                  when the include file starts, @arg1 contains the
                     evaluated value of arg1, ...
                  any set statements within the include file have
                     local scope (ie, they cannot be seen by the caller)

return    ret1=0 ret2=0 ret3=0 ret4=0 ret5=0 ret6=0 ret7=0 ret8=0
          use:    return from an include file
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  statements after a return statement are not processed
                  after execution of include file, the caller will have access
                     to @ret1, @ret2, ... @ret8

updarg    primtype argName argValue
          use:    pre-set arguments for next udprim statement
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  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)

select    type arg1 ...
          use:    selects entity for which @-parameters are evaluated
          pops:   -
          pushes: -
          notes:  if arguments are: body
                     @-parameters apply to last Body on Stack
                  if arguments are: face iface
                     @-parameters apply to Face iface in the last Body on Stack
                  if arguments are: face ibody1 iford1 iseq=1
                     @-parameters apply to the Face in the last Body on Stack
                        that matches ibody1/iford1
                  if arguments are: edge iedge
                     @-parameters apply to Edge iedge in the last Body on Stack
                  if arguments are: edge ibody1 iford1 ibody2 iford2 iseq=1
                     @-parameters apply to the Edge in the last Body on Stack
                        that adjoins Faces ibody1/iford1 and ibody2/iford2
                  if arguments are: node inode
                     @-parameters apply to Node inode in the last Body on Stack
                  if arguments are: node ibody1 iford1 ibody2 iford2 ibody3 iford3 iseq=1
                     @-paramaters apply to the Node in the last Body on Stack
                        that adjoins Faces ibody1/iford1, ibody2/iford2,
                        and ibody3/iford3
                  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

macbeg    imacro
          use:    marks the start of a macro
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  imacro must be between 1 and 100
                  cannot overwrite a previous macro

macend
          use:    ends a macro
          pops:   -
          pushes: -
          notes:

recall    imacro
          use:    recalls copy of macro from a storage location imacro
          pops:   -
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open
                  storage location imacro must have been previously filled by a macro command

store     name
          use:    stores Body on top of Stack
          pops:   any
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  name is used directrly (without evaluation)
                  previous Body in name is overwritten

restore   name
          use:    restores Body from previous store statement
          pops:   -
          pushes: any
          notes:  sketcher may not be open
                  solver   may not be open
                  name is used directrly (without evaluation)
                  error results if nothing has been stored in name

patbeg    pmtrName ncopy
          use:    execute the pattern multiple times
          pops:   -
          pushes: -
          notes:  solver   may not be open
                  pattern contains all statement up to the matching patend
                  pmtrName must not start with '@'
                  pmtrName takes values from 1 to ncopy (see below)
                  pmtrName is used directly (without evaluation)

patend
          use:    mark the end of a pattern
          pops:   -
          pushes: -
          notes:  solver   may not be open
                  there must be a matching patbeg for each patend

mark
          use:    used to identify groups such as in rule, loft, or blend
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open

dump      filename remove=0
          pops:   -
          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 .csm file
                  if remove == 1, then Body is removed after dumping

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

attribute attrName attrValue
          use:    sets an attribute for the entry on top of Stack
          pops:   any
          pushes: any
          notes:  sketcher may not be open
                  if first char of attrValue is '$', then do not evaluate
                  does not create a Branch
                  if before first Branch, then defines a global Attribute

end
          pops:   -
          pushes: -
          notes:  sketcher may not be open
                  solver   may not be open
                  does not create a Branch
                  Bodys on Stack are returned last-in-first-out
       

5.3: 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 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 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 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]
       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)

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)

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 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.4: Parameter rules

The following is taken from the OpenCSM.h file:

Valid names:
    start with a letter
    contains letters, digits, and underscores
    contains fewer than 32 characters

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

Types:
    EXTERNAL
        if a scalar, declared and defined by a despmtr statement
        if an array, declared by a dimension statement
                     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
        has  global scope (accessible everywhere)
        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 despmtr statement
        if an array, declared by a dimension statement
                     values defined by one or more set statements
        values can be overwritten by subsequent set statements
        see scope rules (below)
    SOLVER
        not implemented yet

    @-parameters that 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
        @nbody   x    x    x    x   current body (also number of bodies)
        @nface   x    x    x    x   number of faces in current body
        @nedge   x    x    x    x   number of edges in current body
        @nnode   x    x    x    x   number of nodes in current body

        @ibody1       x    x        first  element of 'Body' attribute
        @ibody2       x    x        second element of 'Body' attribute

        @iface        x             current face
        @iedge             x        current edge
        @inode                  x   current node

        @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            x        length of edge
        @area    x    x             area of face or surface area of body
        @volume  x                  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        centroidal moment of inertia
        @Ixy     x    x    x
        @Ixz     x    x    x
        @Iyx     x    x    x
        @Iyy     x    x    x
        @Iyz     x    x    x
        @Izx     x    x    x
        @Izy     x    x    x
        @Izz     x    x    x

    @-parameters that are associated with include and return statements:
        these are only seeable within included file:
            @arg1 first   argument in include statement
            @arg2 second  argument in include statement
            @arg3 third   argument in include statement
            @arg4 fourth  argument in include statement
            @arg5 fifth   argument in include statement
            @arg6 sixth   argument in include statement
            @arg7 seventh argument in include statement
            @arg8 eighth  argument in include statement
        these are only seeable after the return statement has been executed:
            @ret1 value associated with first   argument of return statement in include file
            @ret2 value associated with second  argument of return statement in include file
            @ret3 value associated with third   argument of return statement in include file
            @ret4 value associated with fourth  argument of return statement in include file
            @ret5 value associated with fifth   argument of return statement in include file
            @ret6 value associated with sixth   argument of return statement in include file
            @ret7 value associated with seventh argument of return statement in include file
            @ret8 value associated with eighth  argument of return statement in include file

Scope:
    EXTERNAL parameters have global scope (accessible everywhere)
    INTERNAL parameters have local scope (accessible in current file and its children)
                the first set statement within an include creates a new variable
                new variables created in an include are removed by return statement
    SOLVER   parameters are only accessible between SKBEG and SKEND statements
       

5.5: 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)
    nint(x)                      nearest integer to x
    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 dagrees)
    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)
    Xcent(xa,ya,Cab,xb,yb)       X-center of circular arc
    Ycent(xa,ya,Cab,xb,yb)       Y-center of circular arc
    Xmidl(xa,ya,Cab,xb,yb)       X-point at midpoint of circular arc
    Ymidl(xa,ya,Cab,xb,yb)       Y-point at midpoint of circular arc
    turnang(xa,ya,Cab,xb,yb)     turning angle of circular arc (in degrees)
    tangent(xa,ya,Cab,xb,yb,...
                     Cbc,xc,yc)  tangent angle at b (in degrees)
    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
       

5.6: 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)

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)
                 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 WIRE Body)
                 patbeg     (for which brch[2*i+1] is pattern index)
                 recall     (for which brch[2*i+1] is 1)

  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

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])

  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

EGADS attributes assigned to Nodes:

  nodeID      not assigned at this time
       

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/4      -D        T         D/2       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
      

Table of Contents

7.0: Error Codes

7.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_PATTERNS_NESTED_TOO_DEEPLY      -205
OCSM_PATBEG_WITHOUT_PATEND           -206
OCSM_PATEND_WITHOUT_PATBEG           -207
OCSM_NOTHING_TO_DELETE               -208
OCSM_NOT_MODL_STRUCTURE              -209

OCSM_DID_NOT_CREATE_BODY             -211
OCSM_CREATED_TOO_MANY_BODYS          -212
OCSM_EXPECTING_ONE_BODY              -213
OCSM_EXPECTING_TWO_BODYS             -214
OCSM_EXPECTING_ONE_SKETCH            -215
OCSM_EXPECTING_MULTI_SINCE_MARK      -216
OCSM_LOFT_WITHOUT_MARK               -217
OCSM_RULE_LOFT_OR_BLEND_ERROR        -218
OCSM_MODL_NOT_CHECKED                -219
OCSM_NEED_TESSELLATION               -220

OCSM_FILLET_AFTER_WRONG_TYPE         -221
OCSM_CHAMFER_AFTER_WRONG_TYPE        -222
OCSM_NO_BODYS_PRODUCED               -223
OCSM_NOT_ENOUGH_BODYS_PRODUCED       -224
OCSM_TOO_MANY_BODYS_ON_STACK         -225
OCSM_FACE_NOT_FOUND                  -226
OCSM_EDGE_NOT_FOUND                  -227
OCSM_NODE_NOT_FOUND                  -228
OCSM_ILLEGAL_VALUE                   -229

OCSM_SKETCHER_IS_OPEN                -231
OCSM_SKETCHER_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_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_FUNC_ARG_OUT_OF_BOUNDS          -255
OCSM_VAL_STACK_UNDERFLOW             -256  /* probably not enough args to func */
OCSM_VAL_STACK_OVERFLOW              -257  /* 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
      

7.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
      

Table of Contents

8.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.

Table of Contents

9.0: Copyright

Copyright (C) 2010/2014 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

Table of Contents

10.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.

Table of Contents