Skip to content
This repository has been archived by the owner on Sep 27, 2023. It is now read-only.

Latest commit

 

History

History
200 lines (150 loc) · 7.6 KB

README.rst

File metadata and controls

200 lines (150 loc) · 7.6 KB

1. The User Interface

The user interface is the curv command, which you run from a Terminal window using a command line shell like bash. After building and installing curv, use curv --help for command line options.

Batch mode

To view a shape defined by a Curv program without editing the file, just type curv myshape.curv. For example:

$ curv examples/shreks_donut.curv
3D shape 75.3982×75.3982×25.1327
**a graphics window opens, displaying the shape**

Live Editing Mode (curv -le)

Type curv -le myshape.curv to create a 3 window GUI for live editing a Curv script.

  • A text editor window pops up, for editing myshape.curv. (The file doesn't need to exist yet.)
  • A graphics window pops up either immediately, or once myshape.curv exists and contains a valid Curv program.
  • The original Terminal window that you invoked curv -le from now serves as the console window. This is where error messages are displayed.

After repositioning the text editor, graphics window and Terminal window so that they are all visible, you can now start editing your Curv script. Each time you save the file, the graphics window updates to display the new shape.

(Type Ctrl-S in Linux or Command-S in macOS to save the file.)

When you close the text editor window, the graphics window disappears and the curv command exits, giving you a new shell prompt. [On macOS, you must quit the gedit text editing application (eg, Command-Q) before the curv command will exit.]

Live Editing with a Custom Editor (for advanced users)

If you want to use a custom editor, just open your favourite editor to edit your source file foo.curv. Then, from another shell window, type curv -l foo.curv. The curv command will run forever, redisplaying the shape whenever the source file changes. You must remember to terminate the curv command using ctrl-C when you are done.

For more convenience, you can configure the behaviour of curv -le by setting the CURV_EDITOR environment variable. This is an advanced feature that requires some research. The CURV_EDITOR command must open a graphical editor window. The top level process must run in the foreground. It must not exit immediately after opening the window: it must continue running until you close the window. This usually requires special command line flags, and not all graphical editors support this mode of operation.

Desired editor Operating System CURV_EDITOR string
vim Linux, MacOS gvim -f
gedit Linux, MacOS gedit --new-window --wait

Once you figure this out, you can add export CURV_EDITOR="gvim -f" (substituting your favourite text editor) to your bash .profile file in your home directory, and then curv -le filename will just work.

Interactive CLI mode:

$ curv
curv> 2+2
4
curv> cube
3D shape 2×2×2
**a graphics window opens, displaying the shape**
curv>

Exporting a mesh (STL, OBJ or X3D file)

To convert a shape into an STL file for 3D printing, use:

$ curv -o foo.stl foo.curv

Rendering is much faster if you use the -O jit option. (But that requires a C++ compiler and the glm library to be installed.) For more details and more options, see Mesh_Export.rst.

Exporting an image (PNG format)

To export a 2D shape as a PNG image file, use:

$ curv -o foo.png foo.curv

For more details, see Image_Export.rst.

Configuration File

You can customize the behaviour of the Viewer window and of file export (-o) using command line -O options. Use curv --help for help. You can create a configuration file to specify default values for the -O options, and thereby customize the behaviour of Curv when viewing or exporting shapes.

For more details, see Config.rst.

2. The Core Language

Full language documentation: language/README.rst.

Curv is a domain specific language for constructing 2D and 3D geometric shapes. It's not a general purpose programming language. There is no concept of I/O. A Curv program is simply an expression that computes a shape, without causing side effects.

Curv is dynamically typed, with 6 fundamental types: symbols, numbers, characters, lists, records and functions. All application level data is built from these 6 types. For example, a geometric shape is simply a record value with a standard set of fields.

Curv is an array language: scalar arithmetic operations are generalized to work on vectors, matrices, and higher dimensional arrays. A vector is represented as a list of numbers: the syntax is [x,y,z]. A matrix is a list of vectors.

Curv is a pure functional language. This means that functions are values, and that functions are "pure": they compute a result value that varies only based on the argument values. There is no global mutable state that a function can read.

Function call (f x) is a binary operation that applies the function f to the argument x. There are 3 ways to pass more than one argument to a function:

Argument lists:

f[x,y] can be thought of in two ways: as passing a single argument (a 2-list) to the function f, or as passing 2 arguments.

Argument records:

rotate{angle: a, axis: v} is a function call where the argument is a record value, which can be interpreted as a function call with multiple named arguments.

Curried functions:

f x y is a function call f x, returning another function that is applied to y. This can be interpreted as a call to a "Curried" function with two arguments.

A nested function call like f(g(h x)) can be rewritten as x >> h >> g >> f, which reads like a Unix pipeline, with data passing from left to right. When combined with curried functions, this syntax is used for chaining together geometry operations without nested parentheses. For example:

sphere 1 >> colour red >> move[10,0,0]

A let block allows locally scoped definitions to be included in an expression:

let definition1; definition2; ... in result_expression

Here are examples of definition syntax:

pi = 3.141592653589793;
shape = cube >> colour red;
factorial n = product(1..n);

Within a let block, the scope of each definition is the entire block, and function definitions may be recursive or mutually recursive. The order of definitions does not matter.

Curv is an expression language: programs are expressions, blocks are expressions, if (cond) a else b is an expression, etc. Consequently, every syntactic construct can be nested in every other construct.

3. The Shape Library

Full shape library documentation: shapes/README.rst.

The "shape library" is a set of primitive shapes, and a set of operations for transforming and combining shapes to create new shapes.

The goal is for this interface to be both powerful and easy to use.

  • It's powerful because there is a rich collection of powerful operations that can be combined in many different ways.
  • Building new shapes is as easy as plugging together existing shapes and operators like Lego.

You can look in ../examples to see examples.

The low level interface used to implement the shape library is poorly documented right now. You can read the source code in ../lib/curv/std.curv. See Theory.rst more more information about how the shape library works.