(require 'solid)

http://people.csail.mit.edu/jaffer/Solid/#Example gives an example use of this package.

 -- Function: vrml node ...
     Returns the VRML97 string (including header) of the concatenation of strings NODES, ....

 -- Function: vrml-append node1 node2 ...
     Returns the concatenation with interdigitated newlines of strings NODE1, NODE2, ....

 -- Function: vrml-to-file file node ...
     Writes to file named FILE the VRML97 string (including header) of the concatenation of strings NODES, ....

 -- Function: world:info title info ...
     Returns a VRML97 string setting the title of the file in which it appears to TITLE.  Additional strings INFO, ... are comments.

VRML97 strings passed to vrml and vrml-to-file as arguments will appear in the resulting VRML code.  This string turns off the headlight at the viewpoint:

     " NavigationInfo {headlight FALSE}"

 -- Function: scene:panorama front right back left top bottom
     Specifies the distant images on the inside faces of the cube enclosing the virtual world.

 -- Function: scene:sphere colors angles

     COLORS is a list of color objects.  Each may be of type color, a 24-bit sRGB integer, or a list of 3 numbers between 0.0 and 1.0.

     ANGLES is a list of non-increasing angles the same length as COLORS.  Each angle is between 90 and -90 degrees.  If 90 or -90 are not elements of ANGLES, then the color at the zenith and nadir are taken from the colors paired with the angles nearest them.

     scene:sphere fills horizontal bands with interpolated colors on the background sphere encasing the world.

 -- Function: scene:sky-and-dirt
     Returns a blue and brown background sphere encasing the world.

 -- Function: scene:sky-and-grass
     Returns a blue and green background sphere encasing the world.

 -- Function: scene:sun latitude julian-day hour turbidity strength

 -- Function: scene:sun latitude julian-day hour turbidity

     LATITUDE is the virtual place's latitude in degrees.  JULIAN-DAY is an integer from 0 to 366, the day of the year.  HOUR is a real number from 0 to 24 for the time of day; 12 is noon.  TURBIDITY is the degree of fogginess described in see turbidity.

     scene:sun returns a bright yellow, distant sphere where the sun would be at HOUR on JULIAN-DAY at LATITUDE.  If STRENGTH is positive, included is a light source of STRENGTH (default 1).

 -- Function: scene:overcast latitude julian-day hour turbidity strength

 -- Function: scene:overcast latitude julian-day hour turbidity

     LATITUDE is the virtual place's latitude in degrees.  JULIAN-DAY is an integer from 0 to 366, the day of the year.  HOUR is a real number from 0 to 24 for the time of day; 12 is noon.  TURBIDITY is the degree of cloudiness described in see turbidity.

     scene:overcast returns an overcast sky as it might look at HOUR on JULIAN-DAY at LATITUDE.  If STRENGTH is positive, included is an ambient light source of STRENGTH (default 1).

Viewpoints are objects in the virtual world, and can be transformed individually or with solid objects.

 -- Function: scene:viewpoint name distance compass pitch

 -- Function: scene:viewpoint name distance compass
     Returns a viewpoint named NAME facing the origin and placed DISTANCE from it. COMPASS is a number from 0 to 360 giving the compass heading.  PITCH is a number from -90 to 90, defaulting to 0, specifying the angle from the horizontal.

 -- Function: scene:viewpoints proximity
     Returns 6 viewpoints, one at the center of each face of a cube with sides 2 * PROXIMITY, centered on the origin.

Light Sources
-------------

In VRML97, lights shine only on objects within the same children node and descendants of that node.  Although it would have been convenient to let light direction be rotated by solid:rotation, this restricts a rotated light's visibility to objects rotated with it.

To workaround this limitation, these directional light source procedures accept either Cartesian or spherical coordinates for direction.  A spherical coordinate is a list (THETA AZIMUTH); where THETA is the angle in degrees from the zenith, and AZIMUTH is the angle in degrees due west of south.

It is sometimes useful for light sources to be brighter than 1. When INTENSITY arguments are greater than 1, these functions gang multiple sources to reach the desired strength.

 -- Function: light:ambient color intensity

 -- Function: light:ambient color
     Ambient light shines on all surfaces with which it is grouped.

     COLOR is a an object of type color, a 24-bit sRGB integer, or a list of 3 numbers between 0.0 and 1.0.  If COLOR is #f, then the default color will be used.  INTENSITY is a real non-negative number defaulting to 1.

     light:ambient returns a light source or sources of COLOR with total strength of INTENSITY (or 1 if omitted).

 -- Function: light:directional color direction intensity

 -- Function: light:directional color direction

 -- Function: light:directional color
     Directional light shines parallel rays with uniform intensity on all objects with which it is grouped.

     COLOR is a an object of type color, a 24-bit sRGB integer, or a list of 3 numbers between 0.0 and 1.0.  If COLOR is #f, then the default color will be used.

     DIRECTION must be a list or vector of 2 or 3 numbers specifying the direction to this light.  If DIRECTION has 2 numbers, then these numbers are the angle from zenith and the azimuth in degrees; if DIRECTION has 3 numbers, then these are taken as a Cartesian vector specifying the direction to the light source.  The default direction is upwards; thus its light will shine down.

     INTENSITY is a real non-negative number defaulting to 1.

     light:directional returns a light source or sources of COLOR with total strength of INTENSITY, shining from DIRECTION.

 -- Function: light:beam attenuation radius aperture peak

 -- Function: light:beam attenuation radius aperture

 -- Function: light:beam attenuation radius

 -- Function: light:beam attenuation

     ATTENUATION is a list or vector of three nonnegative real numbers specifying the reduction of intensity, the reduction of intensity with distance, and the reduction of intensity as the square of distance.  RADIUS is the distance beyond which the light does not shine.  RADIUS defaults to 100.

     APERTURE is a real number between 0 and 180, the angle centered on the light's axis through which it sheds some light.  PEAK is a real number between 0 and 90, the angle of greatest illumination.

 -- Function: light:point location color intensity beam

 -- Function: light:point location color intensity

 -- Function: light:point location color

 -- Function: light:point location

     Point light radiates from LOCATION, intensity decreasing with distance, towards all objects with which it is grouped.

     COLOR is a an object of type color, a 24-bit sRGB integer, or a list of 3 numbers between 0.0 and 1.0.  If COLOR is #f, then the default color will be used.  INTENSITY is a real non-negative number defaulting to 1.  BEAM is a structure returned by light:beam or #f.

     light:point returns a light source or sources at LOCATION of COLOR with total strength INTENSITY and BEAM properties.  Note that the pointlight itself is not visible. To make it so, place an object with emissive appearance at LOCATION.

 -- Function: light:spot location direction color intensity beam

 -- Function: light:spot location direction color intensity

 -- Function: light:spot location direction color

 -- Function: light:spot location direction

 -- Function: light:spot location

     Spot light radiates from LOCATION towards DIRECTION, intensity decreasing with distance, illuminating objects with which it is grouped.

     DIRECTION must be a list or vector of 2 or 3 numbers specifying the direction to this light.  If DIRECTION has 2 numbers, then these numbers are the angle from zenith and the azimuth in degrees; if DIRECTION has 3 numbers, then these are taken as a Cartesian vector specifying the direction to the light source.  The default direction is upwards; thus its light will shine down.

     COLOR is a an object of type color, a 24-bit sRGB integer, or a list of 3 numbers between 0.0 and 1.0.  If COLOR is #f, then the default color will be used.

     INTENSITY is a real non-negative number defaulting to 1.

     light:spot returns a light source or sources at LOCATION of DIRECTION with total strength COLOR.  Note that the spotlight itself is not visible.  To make it so, place an object with emissive appearance at LOCATION.

Object Primitives
-----------------

 -- Function: solid:box geometry appearance

 -- Function: solid:box geometry
     GEOMETRY must be a number or a list or vector of three numbers.  If GEOMETRY is a number, the solid:box returns a cube with sides of length GEOMETRY centered on the origin.  Otherwise, solid:box returns a rectangular box with dimensions GEOMETRY centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:lumber geometry appearance

     Returns a box of the specified GEOMETRY, but with the y-axis of a texture specified in APPEARANCE being applied along the longest dimension in GEOMETRY.

 -- Function: solid:cylinder radius height appearance

 -- Function: solid:cylinder radius height
     Returns a right cylinder with dimensions (abs RADIUS) and (abs HEIGHT) centered on the origin.  If HEIGHT is positive, then the cylinder ends will be capped.  If RADIUS is negative, then only the ends will appear. APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:disk radius thickness appearance

 -- Function: solid:disk radius thickness
     THICKNESS must be a positive real number.  solid:disk returns a circular disk with dimensions RADIUS and THICKNESS centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:cone radius height appearance

 -- Function: solid:cone radius height
     Returns an isosceles cone with dimensions RADIUS and HEIGHT centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:pyramid side height appearance

 -- Function: solid:pyramid side height
     Returns an isosceles pyramid with dimensions SIDE and HEIGHT centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:sphere radius appearance

 -- Function: solid:sphere radius
     Returns a sphere of radius RADIUS centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:ellipsoid geometry appearance

 -- Function: solid:ellipsoid geometry
     GEOMETRY must be a number or a list or vector of three numbers.  If GEOMETRY is a number, the solid:ellipsoid returns a sphere of diameter GEOMETRY centered on the origin. Otherwise, solid:ellipsoid returns an ellipsoid with diameters GEOMETRY centered on the origin.  APPEARANCE determines the surface properties of the returned object.

 -- Function: solid:polyline coordinates appearance

 -- Function: solid:polyline coordinates
     COORDINATES must be a list or vector of coordinate lists or vectors specifying the x, y, and z coordinates of points.  solid:polyline returns lines connecting successive pairs of points.  If called with one argument, then the polyline will be white.  If APPEARANCE is given, then the polyline will have its emissive color only; being black if APPEARANCE does not have an emissive color.

     The following code will return a red line between points at (1 2 3) and (4 5 6):

          (solid:polyline '((1 2 3) (4 5 6)) (solid:color #f 0 #f 0 '(1 0 0)))

 -- Function: solid:prism xz-array y appearance

 -- Function: solid:prism xz-array y
     XZ-ARRAY must be an N-by-2 array holding a sequence of coordinates tracing a non-intersecting clockwise loop in the x-z plane.  solid:prism will close the sequence if the first and last coordinates are not the same.

     solid:prism returns a capped prism Y long.

 -- Function: solid:basrelief width height depth colorray appearance

 -- Function: solid:basrelief width height depth appearance

 -- Function: solid:basrelief width height depth
     One of WIDTH, HEIGHT, or DEPTH must be a 2-dimensional array; the others must be real numbers giving the length of the basrelief in those dimensions.  The rest of this description assumes that HEIGHT is an array of heights.

     solid:basrelief returns a WIDTH by DEPTH basrelief solid with heights per array HEIGHT with the buttom surface centered on the origin.

     If present, APPEARANCE determines the surface properties of the returned object.  If present, COLORRAY must be an array of objects of type color, 24-bit sRGB integers or lists of 3 numbers between 0.0 and 1.0.

     If COLORRAY's dimensions match HEIGHT, then each element of COLORRAY paints its corresponding vertex of HEIGHT.  If COLORRAY has all dimensions one smaller than HEIGHT, then each element of COLORRAY paints the corresponding face of HEIGHT.  Other dimensions for COLORRAY are in error.

 -- Function: solid:text fontstyle str len appearance

 -- Function: solid:text fontstyle str len

     FONTSTYLE must be a value returned by solid:font.

     STR must be a string or list of strings.

     LEN must be #f, a nonnegative integer, or list of nonnegative integers.

     APPEARANCE, if given, determines the surface properties of the returned object.

     solid:text returns a two-sided, flat text object positioned in the Z=0 plane of the local coordinate system

Surface Attributes
------------------

 -- Function: solid:color diffuseColor ambientIntensity specularColor shininess emissiveColor transparency

 -- Function: solid:color diffuseColor ambientIntensity specularColor shininess emissiveColor

 -- Function: solid:color diffuseColor ambientIntensity specularColor shininess

 -- Function: solid:color diffuseColor ambientIntensity specularColor

 -- Function: solid:color diffuseColor ambientIntensity

 -- Function: solid:color diffuseColor

     Returns an appearance, the optical properties of the objects with which it is associated.  AMBIENTINTENSITY, SHININESS, and TRANSPARENCY must be numbers between 0 and 1.  DIFFUSECOLOR, SPECULARCOLOR, and EMISSIVECOLOR are objects of type color, 24-bit sRGB integers or lists of 3 numbers between 0.0 and 1.0. If a color argument is omitted or #f, then the default color will be used.

 -- Function: solid:texture image color scale rotation center translation

 -- Function: solid:texture image color scale rotation center

 -- Function: solid:texture image color scale rotation

 -- Function: solid:texture image color scale

 -- Function: solid:texture image color

 -- Function: solid:texture image

     Returns an appearance, the optical properties of the objects with which it is associated.  IMAGE is a string naming a JPEG or PNG image resource.  COLOR is #f, a color, or the string returned by solid:color.  The rest of the optional arguments specify 2-dimensional transforms applying to the IMAGE.

     SCALE must be #f, a number, or list or vector of 2 numbers specifying the scale to apply to IMAGE.  ROTATION must be #f or the number of degrees to rotate IMAGE.  CENTER must be #f or a list or vector of 2 numbers specifying the center of IMAGE relative to the IMAGE dimensions.  TRANSLATION must be #f or a list or vector of 2 numbers specifying the translation to apply to IMAGE.

 -- Function: solid:font family style justify size spacing language direction

     Returns a fontstyle object suitable for passing as an argument to solid:text.  Any of the arguments may be #f, in which case its default value, which is first in each list of allowed values, is used.

     FAMILY is a case-sensitive string naming a font; SERIF, SANS, and TYPEWRITER are supported at the minimum.

     STYLE is a case-sensitive string PLAIN, BOLD, ITALIC, or BOLDITALIC.

     JUSTIFY is a case-sensitive string FIRST, BEGIN, MIDDLE, or END; or a list of one or two case-sensitive strings (same choices).  The mechanics of JUSTIFY get complicated; it is explained by tables 6.2 to 6.7 of http://www.web3d.org/x3d/specifications/vrml/ISO-IEC-14772-IS-VRML97WithAmendment1/part1/nodesRef.html#Table6.2

     SIZE is the extent, in the non-advancing direction, of the text. SIZE defaults to 1.

     SPACING is the ratio of the line (or column) offset to SIZE. SPACING defaults to 1.

     LANGUAGE is the RFC-1766 language name.

     DIRECTION is a list of two numbers: (X Y).  If (> (abs X) (abs Y)), then the text will be arrayed horizontally; otherwise vertically.  The direction in which characters are arrayed is determined by the sign of the major axis: positive X being left-to-right; positive Y being top-to-bottom.

Aggregating Objects
-------------------

 -- Function: solid:center-row-of number solid spacing
     Returns a row of NUMBER SOLID objects spaced evenly SPACING apart.

 -- Function: solid:center-array-of number-a number-b solid spacing-a spacing-b
     Returns NUMBER-B rows, SPACING-B apart, of NUMBER-A SOLID objects SPACING-A apart.

 -- Function: solid:center-pile-of number-a number-b number-c solid spacing-a spacing-b spacing-c
     Returns NUMBER-C planes, SPACING-C apart, of NUMBER-B rows, SPACING-B apart, of NUMBER-A SOLID objects SPACING-A apart.

 -- Function: solid:arrow center

     CENTER must be a list or vector of three numbers.  Returns an upward pointing metallic arrow centered at CENTER.

 -- Function: solid:arrow
     Returns an upward pointing metallic arrow centered at the origin.

Spatial Transformations
-----------------------

 -- Function: solid:translation center solid ...
     CENTER must be a list or vector of three numbers.  solid:translation Returns an aggregate of SOLIDS, ... with their origin moved to CENTER.

 -- Function: solid:scale scale solid ...
     SCALE must be a number or a list or vector of three numbers.  solid:scale Returns an aggregate of SOLIDS, ... scaled per SCALE.

 -- Function: solid:rotation axis angle solid ...
     AXIS must be a list or vector of three numbers.  solid:rotation Returns an aggregate of SOLIDS, ... rotated ANGLE degrees around the axis AXIS.