;This is the source file to create documentation for the IRIT Solid Modeler.
;First character in line specifies the action to take for this line/next block
;as follows:
; ';' - a comment that is always ignored.
; '#' - all lines following this line until next '#' are indented as an array.
;       Four integers follow specifying indentations, # of elements per
;       line, whether or not to put an internal vertical separator, and
;       if entries are row ordered (1) or column ordered (2).
; '@' - latex only manual. Latex commands can appear within this line.
; '=' - html only manual. Html commands can appear within this line.
; '-' - html and latex only manual. Latex commands can appear in this line.
; '^' - text/hlp only manual. Opposite of '@'.
; '!' - plain text and IRIT docs only manual - keywords/headers.
; '&' - plain text only manual - headers.
; '$' - terminator for current block.
; '*' - prints line in all modes but without any latex filtering on the line.
; '%' - copied verbatim to all output types.
;
; Latex commands can appear in regular text limited to a single line as
; {\command *}. For plain text the {\command } will be filtered out.
; Escaped characters via '\' (i.e. \#) will be left escaped (\#) in the
; latex output but unescaped (#) in the plain output.
;
;                       IRIT Solid Modeler (C) Gershon Elber 1989-2005.
;

@%
@% IRIT Solid Modeler Latex Manual.
@%
@% Authors:     Gershon Elber
@%
@% Copyright (c) 1989-2005 Gershon Elber
@%
@
@\documentstyle[epsfig,11pt]{article}
@\oddsidemargin  -.2in
@\evensidemargin -.2in
@\textwidth 6.75in
@\topmargin 0.0in
@\textheight 9.0in
@
@\renewcommand{\topfraction}{0.80}
@\renewcommand{\textfraction}{0.1}
@\renewcommand{\floatpagefraction}{0.8}
@\setcounter{bottomnumber}{0}
@
@\newcommand{\eqnref}[1]{(\ref{#1})}
@\newcommand{\inner}[2]{\left<{#1}, {#2} \right>}
@\def\binom#1#2{{#1\choose #2}}
@\newcommand{\choosein}[2]{\binom{#1}{#2}}
@
@\begin{document}
@
@\pagestyle{empty}
@   \rule{0in}{3in}
@   \begin{center}
@       {\huge\bf _IRIT_VERSION_ User's Manual}\\
@       \vspace{3cm}
@       {\Large A Solid modeling Program}\\
@       \vspace{2cm}
@       {\large (C) Copyright 1989-2005 Gershon Elber}\\
@       \vspace{1cm}
@       {\large EMail: gershon@cs.technion.ac.il }\\
@       \vspace{2cm}
@       {\large Join {\em IRIT} mailing list: gershon@cs.technion.ac.il }\\
@       {\large Mailing list: irit-mail@cs.technion.ac.il }\\
@       {\large Bug reports: irit-bugs@cs.technion.ac.il }\\
@       {\large WWW Page: http://www.cs.technion.ac.il/\verb-~-irit} \\
@       \vfill
@       {\small This manual is for IRIT _IRIT_VERSION_.}
@   \end{center}
@\newpage
@
@\tableofcontents
@\newpage
@
@\setcounter{page}{1}
@\markright{{\em {\em IRIT Solid modeler}}\hfil G. Elber}
@\pagestyle{myheadings}
@\newpage
@
@
+
+       <TITLE> Users' Manual - IRIT </TITLE>
+       <BGSOUND src="irit_open.wav" loop="1">
+       <BODY BACKGROUND="background_pawns2b1sml.gif" bgproperties="fixed">
+       <H1 align=center> Users' Manual - IRIT </H1><HR>
+       <H2 align=center> A Solid Modeling Program </H2>
+       <H2 align=center> (C) Copyright 1989-2005 
+              <A HREF="http://www.cs.technion.ac.il/~gershon">
+               Gershon Elber
+              </A> </H2><HR>
+       <TABLE ALIGN=CENTER BORDER=7 CELLPADDING=1>
+       <TR><TH ALIGN=RIGHT> EMail: <TH align=left> gershon@cs.technion.ac.il
+       <TR><TH ALIGN=RIGHT> Join IRIT mailing list: <TH align=left> gershon@cs.technion.ac.il
+       <TR><TH ALIGN=RIGHT> Mailing list: <TH align=left> irit-mail@cs.technion.ac.il
+       <TR><TH ALIGN=RIGHT> Bug reports: <TH align=left> irit-bugs@cs.technion.ac.il
+       <TR><TH ALIGN=RIGHT> WWW Page: <TH align=left>
+               <A HREF="http://www.cs.technion.ac.il/~irit">
+               http://www.cs.technion.ac.il/~irit
+               </A>
+       </TABLE><BR><BR><HR><BR><BR>
+
+       <H3 ALIGN=CENTER> This manual is for IRIT _IRIT_VERSION_ </H3><HR><BR><BR>
+

! IRIT _IRIT_VERSION_ User's Manual 

! A Solid Modeling Program 

^ Copyright (C) 1989-2005 Gershon Elber

^ EMail: gershon@cs.technion.ac.il

^ Join IRIT mailing list: gershon@cs.technion.ac.il
^ Mailing list: irit-mail@cs.technion.ac.il
^ Bug reports: irit-bugs@cs.technion.ac.il
^ WWW Page: http://www.cs.technion.ac.il/~irit

@%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@
@\section{Introduction}
!Introduction

   {\em IRIT} is a solid modeler developed for educational purposes. Although
 small, it is now powerful enough to create quite complex scenes.

   {\em IRIT} started as a polygonal solid modeler and was originally developed
 on an IBM PC under MSDOS. Version 2.0 was also ported to X11 and version 3.0
 to SGI 4D systems. Version 3.0 also includes quite a few free form curves
 and surfaces tools. See the UPDATE.NEW file for more detailed update
 information. In Version 4.0, the display devices were enhanced, freeform
 curves and surfaces are more extensively supported, functions can be defined,
 and numerous improvement and optimizations are added.
$

@\section{Copyrights}
!COPYRIGHTS

   BECAUSE {\em IRIT} AND ITS SUPPORTING TOOLS AS DOCUMENTED IN THIS DOCUMENT
 ARE LICENSED FREE OF CHARGE, I PROVIDE ABSOLUTELY NO WARRANTY, TO THE EXTENT
 PERMITTED BY APPLICABLE STATE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING, I
 GERSHON ELBER PROVIDE THE {\em IRIT} PROGRAM AND ITS SUPPORTING TOOLS "AS IS"
 WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 PARTICULAR PURPOSE.
 THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THESE PROGRAMS IS WITH
 YOU. SHOULD THE {\em IRIT} PROGRAMS PROVE DEFECTIVE, YOU ASSUME THE COST OF
 ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 
   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL GERSHON ELBER,
 BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES,
 OR OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
 USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR A
 FAILURE OF THE PROGRAMS TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY GERSHON
 ELBER) THE PROGRAMS, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
 
@\smallskip
 
   {\em IRIT} is a freeware solid modeler. It is not public domain since we
 hold copyrights on it. However, unless you are to sell or attempt to make
 money from any part of this code and/or any model you made with this solid
 modeler, you are free to make anything you want with it.  In order to use
 {\em IRIT} commercially, you must license it first - contact us is such a
 case.
 
   {\em IRIT} can be compiled and executed on numerous Unix systems as
 well as OS2, Windows 95/98/NT/2000/XP and AmigaDOS. However, beware the
 MSDOS support is fading away.  Also, under Windows, IRIT must be installed
 at a directory/path with no spaces.

   You are not obligated to me or to anyone else in any way by using {\em IRIT}.
   You are encouraged to share any model you made with it, but the models
 you made with it are {\em yours}, and you have no obligation to share them.
   You can use this program and/or any model created with it for non
 commercial and non profit purposes only. An acknowledgement on the way the
 models were created would be nice but is {\em not} required.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Command Line Options and Set Up}
!Setup

   The {\em IRIT} program reads a file called {\bf irit.cfg} each time it is executed.
   This file configures the system. It is a regular text file with comments, so
 you can edit it and properly modify it for your environment.
   This file is being searched for in the directory specified by the
 IRIT\_PATH environment variable.
   For example 'setenv IRIT\_PATH /u/gershon/irit/bin/'.
   Note IRIT\_PATH must terminate with '/'. If the variable is not set only
 the current directory is being searched for {\bf irit.cfg}.

   In addition, if it exists, a file by the name of {\bf iritinit.irt} will be
 automatically executed before any other '.irt' file. This file may contain
 any {\em IRIT} command. It is the proper place to put your predefined
 functions and procedures, if you have any.
   This file will be searched much the same way {\bf irit.cfg} is. The
 name of this initialization file may be changed by setting the StartFile
 entry in the configuration file.
   This file is far more important starting at version 4.0, because of the new
 function and procedure definition that has been added, and which is used
 to emulate BEEP, VIEW, and INTERACT, for example.

   The solid modeler can be executed in text mode (see the .cfg and the -t
 flag below) on virtually any system with a C compiler.

  Under all systems the following environment variables must be set
 and updated:
# 14 2 0 1
 path
  Add to path the directory where {\em IRIT}'s binaries are.
 IRIT\_PATH
  Directory with config., help and {\em IRIT}'s binary files.
 IRIT\_DISPLAY
  The graphics driver program/options. Must be in path.
 IRIT\_BIN\_IPC
  If set, uses binary Inter Process Communication.
#

 For example,

@\begin{verbatim}
   set path = ($path /u/gershon/irit/bin)
   setenv IRIT_PATH  /u/gershon/irit/bin/
   setenv IRIT_DISPLAY "xgldrvs -s-"
   setenv IRIT_BIN_IPC 1
@\end{verbatim}

 to set /u/gershon/irit/bin as the binary directory and to use the sgi's
 gl driver. If IRIT\_DISPLAY is not set, the server (i.e., the {\em IRIT}
 program) will prompt and wait for you to run a client (i.e., a display
 driver). if IRIT\_PATH is not set, none of the configuration files, nor
 the help file will be found.

 If IRIT\_BIN\_IPC is not set, text based IPC is used, which is far
 slower.  There is no real reason not to use IRIT\_BIN\_IPC, unless it does
 not work for you, for some reason.

  In addition, the following optional environment variables may be set.
# 17 2 0 1
 IRIT\_MALLOC
  If set, apply dynamic memory consistency testing.
 
  Programs will execute much slower in this mode.
 IRIT\_MALLOC\_PTR
  Set to a pointer address and the program will scream
 
  once this pointer is allocated, if IRIT\_MALLOC is set.
 IRIT\_NO\_SIGNALS
  If set, no signals are caught by IRIT.
 IRIT\_SERVER\_HOST
  Internet Name of IRIT server (used by graphics driver).
 IRIT\_SERVER\_PORT
  Used internally to the TCP socket number. Should not
 
  be set by users.
 IRIT\_TIME\_OUT
  Integer (seconds) for timing out when trying 
 
  to execute a display device from IRIT.  Default is 10 seconds.
 IRIT\_INCLUDE
  A semicolon separated list of directories, in which to look
 
  for the irt files to include.  See INCLUDE command.
 LD\_LIBRARY\_PATH
  If shared libraries are created, this variable must be
 
  updated to point to the shared libraries' directory.
#

 For example,

@\begin{verbatim}
   setenv IRIT_MALLOC 1
   setenv IRIT_MALLOC_PTR 1234567890
   setenv IRIT_NO_SIGNALS 1
   setenv IRIT_SERVER_HOST irit.cs.technion.ac.il
   setenv IRIT_INCLUDE "/d2/gershon/irit/irit/scripts;/tmp"
@\end{verbatim}

 IRIT\_MALLOC is useful for programmers, or when reporting a memory
 fatal error occurrence.  This variable, when set as a non zero value,
 will activate the following (hexadecimal bit settings with any combination
 of the following):
# 10 2 0 1
 0x01
  A test for overwriting before the dynamic memory
 
  is allocated or immediately after it. Cheap in time.
 0x02
  Savings of all allocated objects in a table for the
 
  detection of freeing unallocated objects and consistency
 
  of the entire dynamic memory. Time expensive.
 0x04
  Zeros every freed object, once it is freed.
 0x08
  On Windows environments - enables \_CrtCheckMemory checks
 
  every malloc/free, in debug compilation modes.
 0x10
  On Windows environments - enables \_CrtCheckMemory checks
 
  every 16 mallocs/frees, in debug compilation modes.
#

 IRIT\_NO\_SIGNALS is also useful for debugging when contorl-C is used
 within a debugger. The IRIT\_SERVER\_HOST/PORT controls the server/client
 ({\em IRIT}/Display device) communication.

 IRIT\_SERVER\_HOST and IRIT\_SERVER\_PORT are used in the unix and
 Window NT ports of {\em IRIT}.

   See the section on graphics drivers for more details.

   A session can be logged into a file as set via LogFile in the configuration
 file. See also the LOGFILE command.

   The following command line options are available:

@\begin{verbatim}
   IRIT [-t] [-g] [-q] [-i] [-z] {[-m ...]} [file.irt]
@\end{verbatim}

# 10 2 1 1
 -t
   Puts {\em IRIT} into text mode. No graphics will be displayed and
 
   the display commands will be ignored. This is useful when
 
   one needs to execute an IRIT file to create data on a tty
 
   device...
 -g
   IRIT under GUI mode.  Should not be used by end users.
 -q
   Quiet mode with no regular output to stdout.
 -i
   IRIT under Interactive mode.  Should not be used by end users.
 -z
   Prints usage message and current configuration/version
 
   information.
 -m
   Optional option...  If IRIT is compiled for debugging, allows
 
   setting three addition parameters of trap pointer, search
 
   pointer, and abort counter.
 file.irt
   A file to invoke directly instead of waiting to input from
 
   stdin.
#

@\subsection{IBM PC OS2 Specific Set Up}

 Under OS2 the IRIT\_DISPLAY environment variable must be set (if set) to
 os2drvs.exe without any option (-s- will be passed automatically).
 os2drvs.exe must be in a directory that is in the PATH environment
 variable. IRIT\_BIN\_IPC can be used to signal binary IPC which is faster.
 Here is a complete example:

@\begin{verbatim}
%set IRIT_PATH=c:\irit\bin\
 set IRIT_DISPLAY=os2drvs -s-
 set IRIT_BIN_IPC=1
@\end{verbatim}

 assuming the directory specified by IRIT\_PATH holds the executables of
 IRIT and is in PATH.

 If IRIT\_BIN\_IPC is not set, text based IPC is used which is far
 slower.  There is no real reason not to use IRIT\_BIN\_IPC unless it does
 not work for you, for some reason.

 The OS2 executables are typically built using the EMX port of gnu C
 compiler.  The distribution of the executables does not include the EMX run
 time library and any attempt to run IRIT will fail. You will get an error
 message such as "File EMX does not exist".  You can get the run time from

        ftp to ftp-os2.nmsu.edu (aliased also as hobbes.NMSU.Edu)
        cd to os2/unix/emx09c   (or a newer version number/level)
        get emxrt.zip and place its dlls in a place they would be found.

@\subsection{IBM PC Window 95/98/NT/2000/XP Specific Set Up}

 The NT port uses sockets and is, in this respect, similar to the Unix port.
 The envirnoment variables IRIT\_DISPLAY, IRIT\_SERVER\_HOST, and
 IRIT\_BIN\_IPC should all be set in a similar way to the Unix specific
 setup.
 As a direct result, the server (IRIT) and the display device can run
 on different hosts.  For example, the server might be running on an NT
 system while the display device will be running on an SGI4D, exploiting
 the graphic's hardware capabilities.  Here is a complete example:

@\begin{verbatim}
%set IRIT_PATH=c:\irit\bin\
 set IRIT_DISPLAY=wntgdrvs -s-
 set IRIT_BIN_IPC=1
@\end{verbatim}

 Also, under Windows, IRIT must be installed in a directory/path with
 no spaces.

@\subsection{Unix Specific Set Up}
   Under UNIX using X11 (x11drvs driver), add the following options to
 your .Xdefaults. Most are self explanatory. The Trans attributes control
 the transformation window, while the View attributes control the view window.
 SubWin attributes control the subwindows within the transformation window.
# 33 2 0 1
 \#if COLOR
  
 irit*Trans*BackGround:
  NavyBlue
 irit*Trans*BorderColor:
  Red
 irit*Trans*BorderWidth:
  3
 irit*Trans*TextColor:
  Yellow
 irit*Trans*SubWin*BackGround:
  DarkGreen
 irit*Trans*SubWin*BorderColor:
  Magenta
 irit*Trans*Geometry:
  =150x500+500+0
 irit*Trans*CursorColor:
  Green
 irit*View*BackGround:
  NavyBlue
 irit*View*BorderColor:
  Red
 irit*View*BorderWidth:
  3
 irit*View*Geometry:
  =500x500+0+0
 irit*View*CursorColor:
  Red
 irit*MaxColors:
  15
 \#else
  
 irit*Trans*Geometry:
  =150x500+500+0
 irit*Trans*BackGround:
  Black
 irit*View*Geometry:
  =500x500+0+0
 irit*View*BackGround:
  Black
 irit*MaxColors:
  1
 \#endif
  
#
$

@\section{First Usage}
!First Usage

   Commands to {\em IRIT} are entered using a textual interface, usually
 from the same window from which the program was executed.

   Some important commands to begin with are:

   1. include("file.irt"); - will execute the commands in file.irt. Note
      include can be recursive up to 10 levels. To execute the demo
      (demo.irt) simply type 'include("demo.irt");'. Another way to run
      the demo is by typing demo(); which is a predefined procedure defined
      in {\bf iritinit.irt}.

   2. help(""); - will print all available commands and how to get help on
      them. A file called irit.hlp will be searched as {\bf irit.cfg} is
      being searched (see above), to provide the help.

   3. exit(); - close everything and exit {\em IRIT}.

   Most operators are overloaded. This means that you can multiply
 two scalars (numbers), or two vectors, or even two matrices, with the same
 multiplication operator ($*$). To get the on-line help on the
 operator '$*$', type 'help("$*$");'

   The best way to learn this program (as any other program...) is by
 trying it. Print the manual and study each of the commands available.
   Study the demo programs ($*$.irt) provided, as well.

   The "best" mode in which to use IRIT is via the emacs editor. With this
 distribution an emacs mode for IRIT files (irt postfix) is provided
 (irit.el). Make your .emacs load this file automatically. Loading file.irt
 will switch emacs into an IRIT mode that supports the following keystrokes:
# 18 2 1 1
 Meta-E
  Executes the current line
 Meta-R
  Executes the current Region (Between Cursor and Mark)
 Meta-S
  Executes a single line from input buffer
 Meta-H
  Prints IRIT help on the current WORD the point is on using 'help("WORD");'
#
   The first time one of the above keystrokes is hit, emacs will fork an
 IRIT process so that IRIT'S stdin is controlled via the above commands.
   This emacs mode was tested under various Unix environments, under OS2
 2.x/3.x, and under Windows 95/98/NT/2000/XP.
$

@\section{Line Editing}
!Line Editing
   The {\em IRIT} interpreter provides full line editing capabilities.  The
 following are the available control options:
# 22 2 1 1
 \verb+^+a
  Beginning of line
 \verb+^+e
  End of line
 \verb+^+f
  Forward one character
 \verb+^+b
  Backward one character
 \verb+^+d
  Delete current character
 \verb+^+h (Backspace)
  Delete backward one character
 \verb+^+i (Tab)
  Toggles overwrite/insert mode
 \verb+^+k
  Kill to end of line
 \verb+^+p
  Get previous history line
 \verb+^+n
  Get next history line
 \verb+^+j (LineFeed)
  Done with this line
#
   Only lines entered from stdin will enter the history queue.  The above
 control capabilities are fully configurable via the {\bf irit.cfg}
 configuration file.

@\section{Data Types}
!Data Types
   These are the Data Types recognized by the solid modeler. They are also
 used to define the calling sequences of the different functions below:
# 18 2 1 1
 {\bf ConstantType}
  Scalar real type that cannot be modified.
 {\bf NumericType}
  Scalar real type.
 {\bf VectorType}
  3D real type vector.
 {\bf PointType}
  3D real type point.
 {\bf CtlPtType}
  Control point of a freeform curve or surface.
 {\bf PlaneType}
  3D real type plane.
 {\bf MatrixType}
  4 by 4 matrix (homogeneous transformation matrix).
 {\bf PolygonType}
  Object consists of polygons.
 {\bf PolylineType}
  Object consists of polylines.
 {\bf CurveType}
  Object consists of curves.
 {\bf SurfaceType}
  Object consists of surfaces.
 {\bf TrimSrfType}
  Object consists of trimmed surfaces.
 {\bf TriSrfType}
  Object consists of triangular surfaces
 {\bf TrivarType}
  Object consists of trivariate functions.
 {\bf MultivarType}
  Object consists of multivariate functions.
 {\bf FreeformType}
  One of CurveType, SurfaceType, TrimSrfType,
 
  TrivarType, MultivarType, TriSrfType.
 {\bf GeometricType}
  One of Polygon/lineType, FreeformType.
 {\bf InstanceType}
  Object with a GeometryType and a Transformation.
 {\bf GeometricTreeType}
  A list of GeometricTypes or GeometricTreeTypes.
 {\bf StringType}
  Sequence of chars within double quotes - "A string".
 
  Current implementation is limited to 80 chars.
 {\bf AnyType}
  Any of the above.
 {\bf ListType}
  List of (any of the above type) objects. List 
 
  size is dynamically increased, as needed.
#
  Although points and vectors are not the same, {\em IRIT} does not
 distinguish between them, most of the time. In this future this might change.
$

@\section{Commands summary}
!Commands

 These are all the commands and operators supported by the {\em IRIT} Solid
 Modeler:
@\begin{small}
# 12 5 1 0
 $+$
 $-$
 $*$
 $/$
 \verb+^+
 $=$
 $==$
 $!=$
 $<$
 $>$
 $<=$
 $>=$
 ABS
 ACOS
 ADAPISO
 ADWIDTH
 ALGSUM
 ANALYFIT
 ANIMEVAL
 AOFFSET
 ARC
 ARC360
 AREA
 ASIN
 ATAN
 ATAN2
 ATTRIB
 ATTRPROP
 AWIDTH
 BBOX
 BLHERMITE
 BLSHERMITE
 BLOSSOM
 BOOLONE
 BOOLSUM
 BOUNDARY
 BOX
 BSCTCONCN2
 BSCTCONCON
 BSCTCONCYL
 BSCTCONLN
 BSCTCONPL
 BSCTCONPT
 BSCTCONSPR
 BSCTCYLCYL
 BSCTCYLPL
 BSCTCYLPT
 BSCTCYLSPR
 BSCTPLNLN
 BSCTPLNPT
 BSCTSPRLN
 BSCTSPRPL
 BSCTSPRPT
 BSCTSPRSPR
 BSCTTRSPT
 BSCTTRSSPR
 BSP2BZR
 BZR2BSP
 CALPHASECTOR
 CANGLEMAP
 CARCLEN
 CAREA
 CARRANGMNT
 CBEZIER
 CBIARC
 CBISECTOR2D
 CBISECTOR3D
 CBSPLINE
 CCINTER
 CCRVTR
 CDERIVE
 CDIVIDE
 CEDITPT
 CENVOFF
 CEVAL
 CEXTREMES
 CFNCRVTR
 CHDIR
 CIEXTREME
 CINFLECT
 CINTERP
 CINTEG
 CIRCLE
 CIRCPOLY
 CLNTCLOSE
 CLNTCRSR
 CLNTEXEC
 CLNTREAD
 CLNTWRITE
 CMESH
 CMOEBIUS
 CMORPH
 CMULTIRES
 CNORMAL
 CNRMLCRV
 CNVXHULL
 COERCE
 COLOR
 COMMENT
 COMPOSE
 CON2
 CONE
 CONICSEC
 CONTOUR
 CONVEX
 COORD
 COS
 COVERISO
 COVERPT
 CPATTR
 CPOLY
 CPOWER
 CRAISE
 CRC2CRVTAN
 CREDUCE
 CREFINE
 CREGION
 CREPARAM
 CROSSEC
 CRV2TANS
 CRVKERNEL
 CRVLNDST
 CRVPTDST
 CRVPTTAN
 CSPIRAL
 CSURFACE
 CTANGENT
 CTLPT
 CTRIMSRF
 CUBICCRVS
 CVIEWMAP
 CVISIBLE
 CYLIN
 CZEROS
 DIST2FF
 DSTPTLN
 DSTPTPLN
 DSTLNLN
 DUALITY
 ELLIPSE3PT
 ERROR
 EVOLUTE
 EXEC
 EXIT
 EXP
 EXTRUDE
 FFCMPCRV
 FFCOMPAT
 FFCTLPTS
 FFEXTREME
 FFGTYPE
 FFKNTVEC
 FFMATCH
 FFMERGE
 FFMESH
 FFMSIZE
 FFORDER
 FFPOLES
 FFPTDIST
 FFPTTYPE
 FFSPLIT
 FITPMODEL
 FIXPLGEOM
 FIXPLNRML
 FLOOR
 FMOD
 FNFREE
 FOR
 FREE
 FUNCTION
 GBOX
 GETATTR
 GETLINE
 GETNAME
 GGINTER
 GPOLYGON
 GPOLYLINE
 HELP
 HERMITE
 HOMOMAT
 IF
 IMPLCTRANS
 INCLUDE
 INSERTPOLY
 INSTANCE
 INTERACT
 IQUERY
 IRITSTATE
 ISGEOM
 ISOCLINE
 KNOTCLEAN
 KNOTREMOVE
 LINTERP
 LIST
 LN
 LOAD
 LOFFSET
 LOG
 LOGFILE
 MAP3PT2EQL
 MATDECOMP
 MATPOSDIR
 MAXEDGELEN
 MBEZIER
 MBISECTOR
 MBSPLINE
 MDERIVE
 MDIVIDE
 MERGEPOLY
 MESHSIZE
 MEVAL
 MFROMMESH
 MFROMMV
 MMERGE
 MOFFSET
 MOMENT
 MPOWER
 MPROMOTE
 MRAISE
 MRCHCUBE
 MREFINE
 MREGION
 MREPARAM
 MREVERSE
 MSCIRC
 MSLEEP
 MVEXPLICIT
 MZERO
 NIL
 NREF
 NRMLCONE
 NTH
 OFFSET
 ORTHOTOMC
 PATTRIB
 PAUSE
 PCIRCLE
 PCRVTR
 PDECIMATE
 PDOMAIN
 PIMPRTNC
 PLANE
 PLANECLIP
 PLN3PTS
 PMORPH
 PNORMAL
 POINT
 POLARSIL
 POLY
 POWER
 PPINTER
 PPROPFTCH
 PRINTER
 PRINTF
 PRINTFILE
#

# 12 5 1 0
 PRISA
 PROCEDURE
 PROJMAT
 PT3BARY
 PTHMSPR
 PTLNPLN
 PTPTLN
 PTREGISTER
 PTS2PLLN
 PTSLNLN
 QUADCRVS
 QUADRIC
 RANDOM
 RAYTRAPS
 RFLCTLN
 RFLCTMAT
 RESET
 RMATTR
 ROTVEC
 ROTV2V
 ROTX
 ROTY
 ROTZ
 ROTZ2V
 ROTZ2V2
 RRINTER
 RULEDSRF
 RULEDTV
 SACCESS
 SASPCTGRPH
 SASYMPEVAL
 SAVE
 SBEZIER
 SBISECTOR
 SBSPLINE
 SCALE
 SCRVTR
 SCRVTREVAL
 SDDMMAP
 SDERIVE
 SDIVIDE
 SEDITPT
 SETCOVER
 SETNAME
 SEVAL
 SFLECNODAL
 SFOCAL
 SFROMCRVS
 SGAUSS
 SILHOUETTE
 SIN
 SINTERP
 SIZEOF
 SKEL2DINT
 SMEAN
 SMERGE
 SMESH
 SMOEBIUS
 SMOMENTS
 SMOOTHNRML
 SMORPH
 SNOC
 SNORMAL
 SNRMLSRF
 SPARABOLC
 SPHERE
 SPLITLST
 SQRT
 SRADCRVTR
 SRAISE
 SRAYCLIP
 SREFINE
 SREGION
 SREPARAM
 SREVERSE
 SRF2TANS
 SRF3TANS
 SRFFFORM
 SRFLNDST
 SRFKERNEL
 SRFPTDST
 SRINTER
 SSINTER
 STANGENT
 STRIMSRF
 STRIVAR
 SURFPREV
 SURFREV
 SURFREVAXS
 SURFREV2
 SURFREVAX2
 SVISIBLE
 SVOLUME
 SWEEPSRF
 SWPSCLSRF
 SWUNGASUM
 SYMBCPROD
 SYMBDIFF
 SYMBDPROD
 SYMBIPROD
 SYMBPROD
 SYMBSUM
 SYSTEM
 TAN
 TBEZIER
 TBSPLINE
 TCRVTR
 TDERIVE
 TDIVIDE
 TEDITPT
 TEVAL
 TEXTGEOM
 TEXTWARP
 TFROMSRFS
 TIME
 TINTERP
 THISOBJ
 TMORPH
 TNSCRCR
 TOFFSET
 TORUS
 TRAISE
 TRANS
 TREFINE
 TREGION
 TREPARAM
 TRIANGL
 TRIMSRF
 TRMSRFS
 TSBEZIER
 TSBSPLINE
 TSDERIVE
 TSEVAL
 TSGREGORY
 TSNORMAL
 TVLOAD
 TVZRJACOB
 UVPOLY
 VARLIST
 VECTOR
 VIEW
 VIEWOBJ
 VIEWSET
 VOLUME
 WHILE
 ZCOLLIDE
#
@\end{small}
$

@\section{Functions and Variables}
!Functions and Variables
@ This section lists all the functions supported by the {\em IRIT} system
@ according to their classes - mostly, the object type they return.
@

 Functions that return a {\bf NumericType}:
# 12 5 1 0
 ABS
 ACOS
 AREA
 ASIN
 ATAN
 ATAN2
 COS
 CLNTEXEC
 CPOLY
 DSTPTLN
 DSTPTPLN
 DSTLNLN
 EXP
 FLOOR
 FMOD
 LN
 LOG
 MESHSIZE
 POWER
 RANDOM
 SIN
 SIZEOF
 SQRT
 TAN
 THISOBJ
 VOLUME
#

 Functions that return a {\bf GeometricType}:
# 12 5 1 0
 ADAPISO
 ALGSUM
 ANALYFIT
 ANIMEVAL
 AOFFSET
 ARC
 ARC360
 BBOX
 BLHERMITE
 BLSHERMITE
 BLOSSOM
 BOOLONE
 BOOLSUM
 BOUNDARY
 BOX
 BSCTCONCN2
 BSCTCONCON
 BSCTCONCYL
 BSCTCONLN
 BSCTCONPL
 BSCTCONPT
 BSCTCONSPR
 BSCTCYLCYL
 BSCTCYLPL
 BSCTCYLPT
 BSCTCYLSPR
 BSCTPLNLN
 BSCTPLNPT
 BSCTSPRLN
 BSCTSPRPL
 BSCTSPRPT
 BSCTSPRSPR
 BSCTTRSPT
 BSCTTRSSPR
 BSP2BZR
 BZR2BSP
 CALPHASECTOR
 CANGLEMAP
 CARCLEN
 CAREA
 CARRANGMNT
 CBEZIER
 CBIARC
 CBISECTOR2D
 CBISECTOR3D
 CBSPLINE
 CCINTER
 CCRVTR
 CDERIVE
 CDIVIDE
 CEDITPT
 CENVOFF
 CEVAL
 CEXTREMES
 CFNCRVTR
 CIEXTREME
 CINFLECT
 CINTERP
 CIRCLE
 CIRCPOLY
 CLNTCRSR
 CLNTREAD
 CMESH
 CMOEBIUS
 CMORPH
 CMULTIRES
 CNORMAL
 CNRMLCRV
 CNVXHULL
 COERCE
 COMPOSE
 CON2
 CONE
 CONICSEC
 CONTOUR
 CONVEX
 COORD
 COVERISO
 COVERPT
 CPOWER
 CRAISE
 CRC2CRVTAN
 CREDUCE
 CREFINE
 CREGION
 CREPARAM
 CROSSEC
 CRV2TANS
 CRVKERNEL
 CRVLNDST
 CRVPTDST
 CRVPTTAN
 CSPIRAL
 CSURFACE
 CTANGENT
 CTRIMSRF
 CTLPT
 CUBICCRVS
 CVIEWMAP
 CVISIBLE
 CYLIN
 CZEROS
 DIST2FF
 DUALITY
 ELLIPSE3PT
 EVOLUTE
 EXTRUDE
 FFCMPCRV
 FFCOMPAT
 FFCTLPTS
 FFEXTREME
 FFGTYPE
 FFKNTVEC
 FFMATCH
 FFMERGE
 FFMESH
 FFMSIZE
 FFORDER
 FFPOLES
 FFPTDIST
 FFPTTYPE
 FFSPLIT
 FITPMODEL
 FIXPLGEOM
 FIXPLNRML
 GBOX
 GETATTR
 GETLINE
 GETNAME
 GGINTER
 GPOLYGON
 GPOLYLINE
 HERMITE
 IMPLCTRANS
 INSTANCE
 IRITSTATE
 ISGEOM
 ISOCLINE
 KNOTCLEAN
 KNOTREMOVE
 LINTERP
 LOFFSET
 MATDECOMP
 MAXEDGELEN
 MBEZIER
 MBISECTOR
 MBSPLINE
 MDERIVE
 MDIVIDE
 MERGEPOLY
 MEVAL
 MFROMMESH
 MFROMMV
 MMERGE
 MOFFSET
 MOMENT
 MPOWER
 MPROMOTE
 MRAISE
 MRCHCUBE
 MREFINE
 MREGION
 MREPARAM
 MREVERSE
 MSCIRC
 MVEXPLICIT
 MZERO
 NIL
 OFFSET
 ORTHOTOMC
 PATTRIB
 PCIRCLE
 PCRVTR
 PDECIMATE
 PDOMAIN
 PIMPRTNC
 PLANE
 PLANECLIP
 PLN3PTS
 PMORPH
 PNORMAL
 POINT
 POLARSIL
 POLY
 PPINTER
 PPROPFTCH
 PRINTER
 PRISA
 PROCEDURE
 PT3BARY
 PTHMSPR
 PTLNPLN
 PTPTLN
 PTREGISTER
 PTSLNLN
 QUADCRVS
 QUADRIC
 RAYTRAPS
 RFLCTLN
 RRINTER
 RULEDSRF
 RULEDTV
 SACCESS
 SASPCTGRPH
 SASYMPEVAL
 SBEZIER
 SBISECTOR
 SBSPLINE
 SCRVTR
 SCRVTREVAL
 SDDMMAP
 SDERIVE
 SDIVIDE
 SEDITPT
 SETCOVER
 SEVAL
 SFLECNODAL
 SFOCAL
 SFROMCRVS
 SGAUSS
 SILHOUETTE
 SINTERP
 SKEL2DINT
 SMEAN
 SMERGE
 SMESH
 SMOEBIUS
 SMOMENTS
 SMOOTHNRML
 SMORPH
 SNORMAL
 SNRMLSRF
 SPARABOLC
 SPHERE
 SPLITLST
#

# 12 5 1 0
 SRADCRVTR
 SRAISE
 SRAYCLIP
 SREFINE
 SREGION
 SREPARAM
 SREVERSE
 SRF2TANS
 SRF3TANS
 SRFFFORM
 SRFLNDST
 SRFKERNEL
 SRFPTDST
 SRINTER
 SSINTER
 STANGENT
 STRIMSRF
 STRIVAR
 SURFPREV
 SURFREV
 SURFREVAXS
 SURFREV2
 SURFREVAX2
 SVISIBLE
 SVOLUME
 SWEEPSRF
 SWPSCLSRF
 SWUNGASUM
 SYMBCPROD
 SYMBDIFF
 SYMBDPROD
 SYMBIPROD
 SYMBPROD
 SYMBSUM
 TBEZIER
 TBSPLINE
 TCRVTR
 TDERIVE
 TDIVIDE
 TEDITPT
 TEVAL
 TEXTGEOM
 TEXTWARP
 TFROMSRFS
 TINTERP
 TMORPH
 TNSCRCR
 TOFFSET
 TORUS
 TRAISE
 TREFINE
 TREGION
 TREPARAM
 TRIANGL
 TRIMSRF
 TRMSRFS
 TSBEZIER
 TSBSPLINE
 TSDERIVE
 TSEVAL
 TSGREGORY
 TSNORMAL
 TVLOAD
 TVZRJACOB
 UVPOLY
 ZCOLLIDE
#

 Functions that create linear transformation matrices:
# 12 5 1 0
 HOMOMAT
 MAP3PT2EQL
 MATPOSDIR
 PROJMAT
 RFLCTMAT
 ROTVEC
 ROTV2V
 ROTX
 ROTY
 ROTZ
 ROTZ2V
 ROTZ2V2
 SCALE
 TRANS
#

 Miscellaneous functions:
# 12 5 1 0
 ADWIDTH
 ATTRIB
 ATTRPROP
 AWIDTH
 CHDIR
 CLNTCLOSE
 CLNTWRITE
 COLOR
 COMMENT
 CPATTR
 ERROR
 EXEC
 EXIT
 FNFREE
 FOR
 FREE
 FUNCTION
 HELP
 IF
 INCLUDE
 INSERTPOLY
 INTERACT
 IQUERY
 LIST
 LOAD
 LOGFILE
 MSLEEP
 NREF
 NRMLCONE
 NTH
 PAUSE
 PRINTF
 PRINTFILE
 PROCEDURE
 RESET
 RMATTR
 SAVE
 SETNAME
 SNOC
 SYSTEM
 TIME
 VARLIST
 VECTOR
 VIEW
 VIEWOBJ
 VIEWSET
 WHILE
#

 Variables that are predefined in the system:
# 25 3 1 0
 AXES
 DRAWCTLPT
 FLAT4PLY
 MACHINE
 POLY\_APPROX\_OPT
 POLY\_APPROX\_UV
 POLY\_APPROX\_TOL
 POLY\_APPROX\_TRI
 POLY\_MERGE\_COPLANAR
 PRSP\_MAT
 RESOLUTION
 VIEW\_MAT
#

 Constants that are predefined in the system:
# 15 5 1 0
 AMIGA
 APOLLO
 BEZIER\_TYPE
 BLACK
 BLUE
 BSPLINE\_TYPE
 CLIENTS\_ALL
 COL
 CTLPT\_TYPE
 CURVE\_TYPE
 CYAN
 DEPTH
 E1
 E2
 E3
 E4
 E5
 E6
 E7
 E8
 E9
 FALSE
 GREEN
 HP
 IBMOS2
 IBMNT
 KV\_FLOAT
 KV\_OPEN
 LIST\_TYPE
 MAGENTA
 MATRIX\_TYPE
 MSDOS
 MULTIVAR\_TYPE
 NUMERIC\_TYPE
 OFF
 ON
 P1 
 P2
 P3
 P4
 P5
 P6
 P7
 P8
 P9
 PARAM\_CENTRIP
 PARAM\_CHORD
 PARAM\_NIELFOL
 PARAM\_UNIFORM
 PI
 PLANE\_TYPE
 POINT\_TYPE
 POLY\_TYPE
 POWER\_TYPE
 RED
 ROW
 SGI
 STRING\_TYPE
 SURFACE\_TYPE
 SUN
 TRIMSRF\_TYPE
 TRISRF\_TYPE
 TRIVAR\_TYPE
 TRUE
 UNDEF\_TYPE
 UNIX
 VECTOR\_TYPE
 WHITE
 YELLOW
#
$

@\section{Language description}
!Language Description
    The front end of the {\em IRIT} Solid Modeler is an infix parser that
 mimics some C language behavior. The infix operators that are supported
 are plus (+), minus (-), multiply (*), divide (/), and power (\verb+^+), for
 numeric operators, with the same precedence as in C.

    However, unlike the C language, these operators are overloaded,
@\footnote{In fact the C language does support overloaded operators to some
@extent: '1 + 2' and '1.0 + 2.0' implies invocation of two different
@actions.}
 or different action is taken, based upon the different operands.
   This means that one can write '1 + 2', in which the plus sign denotes a
 numeric addition, or one can write 'PolyObj1 + PolyObj2', in which case the
 plus sign denotes the Boolean operation of a union between two geometric
 objects.
   The exact way each operator is overloaded is defined below.

   In this environment, reals, integers, and even Booleans, are all represented
 as real types. Data are automatically promoted as necessary.
   For example, the constants TRUE and FALSE are defined as 1.0 and 0.0,
 respectively.

   Each expression is terminated by a semicolon. An expression can be as
 simple as 'a;' which prints the value of variable a, or as complex as:

@\begin{verbatim}
    for ( t = 1.1, 0.1, 1.9,
            cb1 = csurface( sb, COL, t ):
            color( cb1, green ):
            snoc( cb1, cb_all )
        );
@\end{verbatim}

   While an expression is terminated with a semicolon, a colon is used to
 terminate mini-expressions within an expression.

   Once a complete expression is read in (i.e., a semicolon is detected)
 and parsed correctly (i.e. no syntax errors are found), it is executed.
   Before each operator or a function is executed, parameter type matching
 tests are made to make sure the operator can be applied to these
 operand(s), or that the function gets the correct set of arguments.

   The parser is totally case insensitive, so Obj, obj, and OBJ will refer
 to the same object, while MergePoly, MERGEPOLY, and mergePoly will refer
 to the same function.

   Objects (Variables, if you prefer) need not be declared. Simply use them
 when you need them. Object names may be any alpha-numeric (and underscore)
 string of at most 30 characters. When assigned to an old object, the old
 object will be automatically deleted and if necessary, its type will be
 modified on the fly.

 Example:

@\begin{verbatim}
    V = sin( 45 * pi / 180.0 );
    V = V * vector( 1, 2, 3 );
    V = V * rotx( 90 );
    V = V * V;
@\end{verbatim}

 will assign to V a NumericType equal to the sine of 45 degrees, the VectorType
 ( 1, 2, 3 ) scaled by the sine of 45, rotate that vector around the X axis
 by 90 degrees, and finally a NumericType which is the dot (inner) product of
 V with itself.

   The parser will read from stdin, unless a file is specified on the command
 line or an INCLUDE command is executed. In both cases, when the end of file
 is encountered, the parser will again wait for input from stdin. In order
 to execute a file and quit at the end of the file, put an EXIT command as
 the last command in the file.
$

@\section{Operator overloading}
@
@ The basic operators $+$, $-$, $*$, $/$, and \verb+^+ are overloaded.
@ This section describes what action is taken by each of these operators
@ depending on its arguments.
@
@\subsection{Overloading $+$}
!Overloading Plus
 The $+$ operator is overloaded above the following domains:

@\begin{verbatim}
  NumericType + NumericType -> NumericType
  PointType   + PolygonType -> PolygonType  (Point polyline profiling)
  VectorType  + VectorType  -> VectorType   (Vector addition)
  MatrixType  + MatrixType  -> MatrixType   (Matrix addition)
  PolygonType + PolygonType -> PolygonType  (Boolean UNION operation)
  CurveType   + CurveType   -> CurveType    (Curve curve profiling)
  CurveType   + CtlPtType   -> CurveType    (Curve control point profiling)
  CtlPtType   + CtlPtType   -> CurveType    (Control points profiling)
  ListType    + ListType    -> ListType     (Append lists operator)
  StringType  + StringType  -> StringType   (String concat)
  StringType  + RealType    -> StringType   (String concat, real as int string)
@\end{verbatim}

 Note: Boolean UNION of two disjoint objects (no common volume) will result
 in the two objects being combined. It is the USER's responsibility to make
 sure that the non intersecting objects are also disjoint - this system only
 tests for no intersection.  Boolean UNION of two polyline objects will merge
 the list of polylines.
$

@\subsection{Overloading $-$}
!Overloading Minus
 The $-$ operator is overloaded above the following domains:

 As a binary operator:

@\begin{verbatim}
  NumericType - NumericType -> NumericType
  VectorType  - VectorType  -> VectorType   (Vectoric difference)
  MatrixType  - MatrixType  -> MatrixType   (Matrix difference) 
  PolygonType - PolygonType -> PolygonType  (Boolean SUBTRACT operation)
@\end{verbatim}

 As a unary operator:

@\begin{verbatim}
  - NumericType -> NumericType
  - PointType   -> PointType     (Scale vector by -1)
  - VectorType  -> VectorType    (Scale vector by -1)
  - CtlPtType   -> CtlPtType     (Scale vector by -1)
  - PlaneType   -> PlaneType     (Scale vector by -1)
  - StringType  -> StringType    (Reverse the order of string's characters)
  - MatrixType  -> MatrixType    (Scale matrix by -1)
  - PolygonType -> PolygonType   (Boolean NEGATION operation)
  - CurveType   -> CurveType     (Curve parameterization is reversed)
  - SurfaceType -> SurfaceType   (Surface parameterization is reversed)
  - TrimSrfType -> TrimSrfType   (Trim surface parameterization is reversed)
@\end{verbatim}

 Note: Boolean SUBTRACT of two disjoint objects (no common volume) will result
 in an empty object. For both a curve and a surface parameterization, reverse
 operation (binary minus) causes the object normal to be flipped as a side
 effect.
$

@\subsection{Overloading $*$}
!Overloading Astrisk
 The $*$ operator is overloaded above the following domains:

@\begin{verbatim}
  NumericType  * NumericType   -> NumericType
  VectorType   * NumericType   -> VectorType    (Vector scaling)
  VectorType   * CurveType     -> CurveType     (Inner product projection)
  VectorType   * SurfaceType   -> SurfaceType   (Inner product projection)
  VectorType   * VectorType    -> NumericType   (Inner product)
  PlaneType    * MatrixType    -> PlaneType     (Plane transformation)
  MatrixType   * NumericType   -> MatrixType    (Matrix Scaling)
  MatrixType   * PointType     -> PointType     (Point transformation)
  MatrixType   * CtlPtType     -> CtlPtType     (Ctl Point transformation)
  MatrixType   * VectorType    -> VectorType    (Vector transformation)
  MatrixType   * MatrixType    -> MatrixType    (Matrix multiplication)
  MatrixType   * GeometricType -> GeometricType (Object transformation)
  MatrixType   * ListType      -> ListType      (Object hierarchy transform.)
  PolygonType  * PolygonType   -> PolygonType   (Boolean INTERSECTION operation)
  InstanceType * MatrixType    -> InstanceType  (Transform of Instance's matrix)
@\end{verbatim}

 Note: Boolean INTERSECTION of two disjoint objects (no common volume) will
 result in an empty object. Object hierarchy transform transforms any
 transformable object (GeometricType) found in the list recursively. Boolean
 INTERSECTION of two planar (XY plane) polyline objects will compute the
 intersection points of the two lists of polylines.  Be aware that a plane
 multiplied by a matrix does not always do what you might expected. 
$

@\subsection{Overloading $/$}
!Overloading Slash
 The $/$ operator is overloaded above the following domains:

@\begin{verbatim}
  NumericType / NumericType -> NumericType
  PointType   / PointType   -> PolyType      (Polyline between two pts)
  PointType   / PolygonType -> PolygonType   (Point polyline profiling)
  PolygonType / PolygonType -> PolygonType   (Boolean CUT operation)
@\end{verbatim}

 Note: Boolean CUT of two disjoint objects (no common volume) will result
 with an empty object.
$

@\subsection{Overloading \^{\ }}
!Overloading Caret
 The \verb+^+ operator is overloaded above the following domains:

@\begin{verbatim}
  NumericType ^ NumericType -> NumericType
  VectorType  ^ VectorType  -> VectorType  (Cross product)
  MatrixType  ^ NumericType -> MatrixType  (Matrix to the (int) power)
  PolygonType ^ PolygonType -> PolygonType (Boolean MERGE operation)
  StringType  ^ StringType  -> StringType  (String concat)
  StringType  ^ RealType    -> StringType  (String concat, real as real string)
@\end{verbatim}

 Note: Boolean MERGE simply merges the two sets of polygons without
 any intersection tests. Matrix powers must be positive integers or -1
 or -2, in which case the matrix inverse (if it exists) or transpose
 is computed.
$

@\subsection{Overloading Equal (Assignments)}
!Overloading Equal (Assignments)
   Assignments are allowed as side effects, in any place in an expression.
 If "Expr" is an expression, then "var = Expr" is the exact same expression
 with the side effect of setting Var to that value. There is no guarantee
 of the order of evaluation, so using Vars that are set within the same
 expression is a bad practice. Use parentheses to force the order of
 evaluation, i.e., "( var = Expr )".
$

@\subsection{Comparison operators $==$, $!=$, $<$, $>$, $<=$, $>=$}
!Comparison operators - ==, !=, <, >, <=, >=
 The conditional comparison operators can be applied to the following
 domains (o for a comparison operator):

@\begin{verbatim}
  NumericType  o NumericType  -> NumericType
  StringType   o StringType   -> NumericType
  PointType    o PointType    -> NumericType
  VectorType   o VectorType   -> NumericType
  PlaneType    o PlaneType    -> NumericType
  CtlPtType    o CtlPtType    -> NumericType
  MatrixType   o MatrixType   -> NumericType
  CurveType    o CurveType    -> NumericType
  SurfaceType  o SurfaceType  -> NumericType
  TrivarType   o TrivarType   -> NumericType
  TriSrfType   o TriSrfType   -> NumericType
  MultivarType o MultivarType -> NumericType
@\end{verbatim}

 The returned NumericType is non-zero if the condition holds, or zero if
 not.
   The comparison operators other than $==$ and $!=$ can be used on
 NumericTypes and StringType only.
$

@\subsection{Logical operators $\&\&$, $\|\|$, !}
!Logical Operators - &&, ||, |
 Complex logical expressions can be defined using the logical {\em and} ($\&\&$),
 logical {\em or} ($||$) and logical {\em not} (!). These operators can be applied
 to NumericTypes that are considered Boolean results. That is, true for a
 non-zero value, and false otherwise.
   The returned NumericType is true if both operands are true for the {\em and}
 operator, at least one is true for the {\em or} operator, and the operand is
 false for the {\em not} operator. In all other cases, a false is returned.
   To make sure logical expressions are readable, the {\em and} and {\em or}
 operators are defined to have the {\em same} priority. Use parentheses to
 disambiguate a logical expression and to make it more readable.
$

@\subsection{Geometric Boolean Operations}
!Geometric Boolean Operations
   The {\em IRIT} Solid Modeling System supports Boolean operations between
 polyhedra objects. Freeform objects will be automaticaly converted to
 a polygonal representation when used in Boolean operations.
   The $+$, $*$, and $-$ are overloaded to denote Boolean union, intersection
 and subtraction when operating on geometric entities. $-$ can also be
 used as an unary operator to reverse the object orientation inside out.

 IRIT supports Boolean operations on polyhedra models.  A polyhedra
 based model is simply a collection of polygons.  While a polyhedra is
 simply a set of polygons, this set must conform to certain conditions:
@\begin{itemize}
@\item
        Every polygon has known adjacent polygons, for all its edges.
@\item
        The model must be a 2-manifold.  That is every edge is shared by
        exactly two polygons.
@\item  The model is expected to be closed.  Actually only the resulting
        intersection curves must be closed and the objects participating
        in the Boleans might be open in unintersecting regions.        
@\item
        Every polygon has a normal that points {\em into} the model.  That
        normal is inside/outside consistent with its adjacent polygons.
@\end{itemize}
 In other words, for every polygon, one can {\em locally} determine the
 inside or the outside of the model.  Moreover, every polygon has
 neighbors for all its edges, forming a {\em closed} object that
 consistently delineates inside from outside, {\em globally}.

 If your input geometry does not adhere to the above constrains, the Boolean
 operation is likely to fail.  You can enable a special intersection-curves 
 mode that only compute the intersection curves between the two input
 objects and does not form the output object.  This special model is
 insensitive to many of the above constraints so you could use this model 
 to examine the intersection curves and make sure there are indeed forming
 closed loops.  You can enable this intersection-curves mode via
 'iritstate("intercrv", true);'.  See also IRITSTATE command.

 The Boolean operations are {\em set operations} conducted between two
 such models, ${\cal M}_1$ and ${\cal M}_2$, that delineate inside from
 outside.  Boolean Union, Boolean Intersection and Boolean Subtraction
 are the three common operations that resemble the exact semantic that
 is expected, when treating ${\cal M}_1$ and ${\cal M}_2$ as 
 three-dimensional point sets.

 Certain attributes are propegated between input and output geometry,
 when processed through the Boolean operations module.  If the
 vertices of the input geometry have normals, uv parametric
 coordinates ("uvvals" attribute), or rgb colors ("rgb" attribute),
 they will be propertly propagated and interpolated through the
 Booleans.  Similarly, an integer "ID" attribute that is placed on an
 input object will propagate into its polygons and all polygons in the
 output that are part of the input objects will be carrying this "ID"
 attribute.

 The Boolean operations can be formulated into a binary tree structure
 also known as a Constructive Solid Geometry (CSG) tree.
@See, for example, Figure~\ref{fig-polyhedra1} for a sequence of
@Boolean operations on polyhedra model, defining a Constructive Solid
@Geometry (CSG) tree.

@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/csg.ps}
@\end{center}
@\begin{picture}(0,0)
@    \put( 50, 50){$B_1$}
@    \put(295, 50){$C_1$}
@    \put( 60,185){$S_1 = B_1 + C_1$}
@    \put(365,170){$B_2$}
@    \put(130,320){$S_2 = S_1 - B_2$}
@    \put(425,320){$C_2$}
@    \put(195,450){$S_3 = S_2 - C_2$}
@\end{picture}
=    <BR clear=all>
=    <img hspace=2 width=500 src="user_man/csg.gif">
=    <BR clear=all>
@\caption{
=<b><BR clear=all>  FIGURE:
-      A simple example of a polyhedra model, computed as a sequence of
-      several Boolean operation, presented as a CSG tree.
=</b><BR clear=all>
@}
@\label{fig-polyhedra1}
@\end{figure}

   Example:

@\begin{verbatim}
    resolution = 20;
    B = box(vector(-1, -1, -0.25), 2, 1.2, 0.5);
    C = con2(vector(0, 0, -1.5), vector(0, 0, 3), 0.7, 0.3);

    D = convex(B - C);
    E = convex(C - B);
    F = convex(B + C);
    G = convex(B * C);

    tr = rotx( -90 ) * roty( 40 ) * rotx( -30 );

    All = list( D * tr * trans( vector(  0.6,  0.5, 0.0 ) ),
                E * tr * trans( vector(  3.0,  0.0, 0.0 ) ),
                F * tr * trans( vector( -2.0,  0.0, 0.0 ) ),
                G * tr * trans( vector(  0.7, -1.0, 0.0 ) ) )
            * scale( vector( 0.25, 0.25, 0.25 ) )
            * trans( vector( -0.1, -0.3, 0.0 ) );
    view_mat = rotx( 0 );
    view( list( view_mat, All ), on );
    save( "booleans", list( view_mat, All ) );
@\end{verbatim}

    This is a complete example of how to compute the union, intersection and
 both differences of a box and a truncated cone.
@The result of this example can be seen in Figure~\ref{fig-booleans}
@with its hidden lines removed.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/booleans.ps, width=5in}
=    <BR clear=all>
=    <img hspace=2 width=700 src="user_man/booleans.gif">
=    <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Geometric Boolean operations between a box and a truncated cone.
-      Shown are union (left), intersection (bottom center), box minus
-      the cone (top center), and cone minus the box (right).
=</b><BR clear=all>
@}
@\label{fig-booleans}
@\end{figure}

 Special cases can be very difficult to handle when considering Boolean
 operations.  Consider an axes parallel bounding cube.  Consider a
 second cube rotated $\alpha$ degrees from the first cube.  At large
 angles, the Boolean operations are fairly simple to
 compute. Nevertheless, as $alpha$ approaches zero, the almost coplanar
 planes of the two intersecting cubes make it very difficult to
 robustly and consistently compute their intersection.
@Figure~\ref{fig-bool-robust} shows three such examples for $\alpha =
@10, 1, 0.1$ degrees, computed using IRIT. IRIT itself fails to return
@a valid result at $\alpha = 10^{-6}$, complaining about theye
@inconsistency of its computation.  Proper handling of coplanarity and
@almost tangent faces, in a robust manner, are one of the most
@challenging tasks in computing the Boolean operations.
@
@\begin{figure}
@\begin{center}
@\begin{tabular}{ccc}
@    \epsfig{file=user_man/cubes1.ps, width=2.0in} &
@        \epsfig{file=user_man/cubes2.ps, width=2.0in} &
@        \epsfig{file=user_man/cubes3.ps, width=2.0in} \\[0.5in]
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/cubes1.gif">
=        <img hspace=2 width=250 src="user_man/cubes2.gif">
=        <img hspace=2 width=250 src="user_man/cubes3.gif">
=    <BR clear=all>
@    $\alpha = 10$ degrees &
@        $\alpha = 1$ degree &
@        $\alpha = 0.1$ degrees
@\end{tabular}
@\end{center}
@
@\caption{
=<b><BR clear=all>  FIGURE:
-      Examples of robustness of Boolean Intersection operation. As
-      the rotation anlge approaches zero, the coplanarity of the
-      intersecting models puts very difficult constraints on the
-      robustness of the result.
-      In this specific example, using IRIT, the operation fails at
-      angles of 10e-6 and below.
=</b><BR clear=all>
@}
@\label{fig-bool-robust}
@\end{figure}

    There are several flags to control the Boolean operations. See
 IRITSTATE command for the "InterCrv", "Coplanar", and "PolySort"
 states.
$

@\subsection{Priority of operators}
!Priority of operators
   The following table lists the priority of the different operators.
# 19 3 0 1
 Lowest
 Operator
 Name of operator
 priority
 ,
 comma
 
 :
 colon
 
 $\&\&$, $||$
 logical and, logical or
 
 $=,==,!=,<=,>=,<,>$
 assignment, equal, not equal, less
 
 
 equal, greater equal, less, greater
 
 +, -
 plus, minus
 
 *, /
 multiply, divide
 Highest
 \verb+^+
 power
 priority
 -, !
 unary minus, logical not
# 

@\subsection{Grammar}
&Grammar
   The grammar of the {\em IRIT} parser follows guidelines similar to those of
 the C language for simple expressions. However, complex statements differ.
   See the IF, FOR, FUNCTION, and PROCEDURE below for the usage of these
 clauses.

$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Function Description}
!Function Description
$

@ The description below defines the parameters and returned values of the
@ predefined functions in the system, using the notation of functions
@ in ANSI C. All the functions in the system, in alphabetic
@ order, are listed are according to their classes.
@ 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{NumericType returning functions}
!NumericType returning functions
$

@\subsubsection{ABS}
!ABS

@\begin{verbatim}
 NumericType ABS( NumericType Operand )
@\end{verbatim}

   returns the absolute value of the given {\bf Operand}.
$

@\subsubsection{ACOS}
!ACOS

@\begin{verbatim}
 NumericType ACOS( NumericType Operand )
@\end{verbatim}

   returns the arc cosine value (in radians) of the given {\bf Operand}.
$

@\subsubsection{AREA}
!AREA

@\begin{verbatim}
 NumericType AREA( PolygonType Object )
@\end{verbatim}

   returns the area of the given {\bf Object} (in object units). 
 The area of the polygonal object, not the area of the primitive it might
 approximate,is returned.

   This means that the area of a polygonal approximation of a sphere will be
 returned, not the exact area of the sphere.
$

@\subsubsection{ASIN}
!ASIN

@\begin{verbatim}
 NumericType ASIN( NumericType Operand )
@\end{verbatim}

   returns the arc sine value (in radians) of the given {\bf Operand}.
$

@\subsubsection{ATAN}
!ATAN

@\begin{verbatim}
 NumericType ATAN( NumericType Operand )
@\end{verbatim}

   returns the arc tangent value (in radians) of the given {\bf Operand}.
$

@\subsubsection{ATAN2}
!ATAN2

@\begin{verbatim}
 NumericType ATAN2( NumericType Operand1, NumericType Operand2 )
@\end{verbatim}

   returns the arc tangent value (in radians) of the given ratio:
 {\bf Operand1} / {\bf Operand2}, over the whole circle.
$

@\subsubsection{COS}
!COS

@\begin{verbatim}
 NumericType COS( NumericType Operand )
@\end{verbatim}

   returns the cosine value of the given {\bf Operand} (in radians).
$

@\subsubsection{CLNTEXEC}
!CLNTEXEC

@\begin{verbatim}
 NumericType CLNTEXEC( StringType ClientName )
@\end{verbatim}

   Initiate communication channels to a client named {\bf ClientName}.
 {\bf ClientName} is executed by this function as a sub process.
 Two communication channels are opened between the IRIT server and the
 new client, for read and write. See also CLNTCRSR, CLNTREAD, CLNTWRITE, and
 CLNTCLOSE. If {\bf ClientName} is an empty string, the user is provided
 with the new communication port to be used and the server blocks for the
 user to manually execute the client after setting the proper
 IRIT\_SERVER\_HOST/PORT environment variables.
 
 Example:

@\begin{verbatim}
   h1 = CLNTEXEC( "" );
   h2 = CLNTEXEC( "nuldrvs -s-" );
@\end{verbatim}

 executes two clients, one named {\bf nuldrvs} while the other one is
 prompted for by the user. As a result of the second invokation of
 CLNTEXEC, the user will be prompted with a message similar to:

@\begin{verbatim}
    Irit: Startup your program - I am waiting...

    setenv IRIT_SERVER_PORT 2182
@\end{verbatim}

 and he/she will need to set the proper environment variable and execute
 their client manually.
$

@\subsubsection{CPOLY}
!CPOLY

@\begin{verbatim}
 NumericType CPOLY( PolygonType Object )
@\end{verbatim}

   returns the number of polygons in the given polygonal {\bf Object}.
$

@\subsubsection{DSTPTLN}
!DSTPTLN

@\begin{verbatim}
 NumericType DSTPTLN( PointType Pt, PointType LineOrig, VectorType LineRay )
@\end{verbatim}

   returns the distance between a given point {\bf Pt} and line
 {\bf LineOrig}, {\bf LineRay}. See also PTPTLN.
$

@\subsubsection{DSTPTPLN}
!DSTPTPLN

@\begin{verbatim}
 NumericType DSTPTPLN( PointType Pt, PlaneType Plane )
@\end{verbatim}

   returns the distance between a given point {\bf Pt} and plane
 {\bf Plane}.
$

@\subsubsection{DSTLNLN}
!DSTLNLN

@\begin{verbatim}
 NumericType DSTLNLN( PointType Line1Orig, VectorType Line1Ray,
                      PointType Line2Orig, VectorType Line2Ray )
@\end{verbatim}

   returns the distance between two lines defined by point {\bf LineiOrig}
 and ray {\bf LineiRay}. See also PTSLNLN.
$

@\subsubsection{EXP}
!EXP

@\begin{verbatim}
 NumericType EXP( NumericType Operand )
@\end{verbatim}

   returns the natural exponential value of the given {\bf Operand}.
$

@\subsubsection{FLOOR}
!FLOOR

@\begin{verbatim}
 NumericType FLOOR( NumericType Operand )
@\end{verbatim}

   returns the largest integer not greater than the {\bf Operand}.
$

@\subsubsection{FMOD}
!FMOD

@\begin{verbatim}
 NumericType FMOD( NumericType Operand, NumericType Mod )
@\end{verbatim}

   returns the floating point remainder of the division of the {\bf Operand} by
 {\bf Mod}.
$

@\subsubsection{LN}
!LN

@\begin{verbatim}
 NumericType LN( NumericType Operand )
@\end{verbatim}

   returns the natural logarithm value of the given {\bf Operand}.
$

@\subsubsection{LOG}
!LOG

@\begin{verbatim}
 NumericType LOG( NumericType Operand )
@\end{verbatim}

   returns the base 10 logarithm value of the given {\bf Operand}.
$

@\subsubsection{MESHSIZE}
!MESHSIZE

@\begin{verbatim}
 NumericType MESHSIZE( FreeformType Freeform, ConstantType Direction )
@\end{verbatim}

   returns the size of the {\bf Freeform}'s mesh in a {\bf Direction}, which
 will be COL, ROW or DEPTH.  For the case of a multivariate {\bf Freeform},
 the {\bf Direction} is an integer value starting from 0.  See also FFMSIZE.
 Examples:

@\begin{verbatim}
   Len = MESHSIZE( Crv, COL );
   RSize = MESHSIZE( Sphere, ROW );
   CSize = MESHSIZE( Sphere, COL );
   TVSize = MESHSIZE( TV, COL ) * MESHSIZE( TV, ROW ) * MESHSIZE( TV, DEPTH );
   MVSize1 = MESHSIZE( MV, 1 );
@\end{verbatim}
$

@\subsubsection{POWER}
!POWER

@\begin{verbatim}
 NumericType POWER( NumericType Operand, NumericType Exp )
@\end{verbatim}

   returns the {\bf Operand} to the power of {\bf Exp}.
$

@\subsubsection{RANDOM}
!RANDOM

@\begin{verbatim}
 NumericType RANDOM( NumericType Min, NumericType Max )
@\end{verbatim}

   returns a randomized value between {\bf Min} and {\bf Max}.
 See also "RandomInit", in the IRITSTATE function.
$

@\subsubsection{SIN}
!SIN

@\begin{verbatim}
 NumericType SIN( NumericType Operand )
@\end{verbatim}

   returns the sine value of the given {\bf Operand} (in radians).
$

@\subsubsection{SIZEOF}
!SIZEOF

@\begin{verbatim}
 NumericType SIZEOF( PointTypr Pt | VectorType Vec | PlaneType Pln |
                     CtlPtType CtlPt | ListType List | PolygonType Poly |
                     CurveType Crv | StringType Str )
@\end{verbatim}

   returns the size of a point, vector, plane, or control point (negative size
 if rational) or the length of a list if {\bf List}, the number of polygons
 if {\bf Poly}, the length of the control polygon if {\bf Crv}, or the
 number of characters in string if {\bf Str}.
   If, however, only one polygon is in {\bf Poly}, it returns the number
 of vertices in that polygon.
 
 Example:

@\begin{verbatim}
   len = SIZEOF( list( 1, 2, 3 ) );
   numPolys = SIZEOF( axes );
   numCtlpt = SIZEOF( circle( vector( 0, 0, 0 ), 1 ) );
@\end{verbatim}

 will assign the value of 3 to the variable {\bf len}, set {\bf numPolys}
 to the number of polylines in the axes object, and set numCtlPt to 9, the
 number of control points in a circle.
$

@\subsubsection{SQRT}
!SQRT

@\begin{verbatim}
 NumericType SQRT( NumericType Operand )
@\end{verbatim}

   returns the square root value of the given {\bf Operand}.
$

@\subsubsection{TAN}
!TAN

@\begin{verbatim}
 NumericType TAN( NumericType Operand )
@\end{verbatim}

   returns the tangent value of the given {\bf Operand} (in radians).
$

@\subsubsection{THISOBJ}
!THISOBJ

@\begin{verbatim}
 NumericType THISOBJ( StringType Object )
@\end{verbatim}

   returns the object type of the given name of an {\bf Object}. This can
 be one of the constants,
# 18 4 1 0
 UNDEF\_TYPE
 POLY\_TYPE
 NUMERIC\_TYPE
 POINT\_TYPE
 VECTOR\_TYPE
 PLANE\_TYPE
 MATRIX\_TYPE
 CURVE\_TYPE
 SURFACE\_TYPE
 STRING\_TYPE
 CTLPT\_TYPE
 LIST\_TYPE
 TRIVAR\_TYPE
 TRISRF\_TYPE
 TRIMSRF\_TYPE
 MODEL\_TYPE
 MULTIVAR\_TYPE
#
   This is also a way to ask if an object by a given name exists (if the
 returned type is UNDEF\_TYPE or not).
$

@\subsubsection{VOLUME}
!VOLUME

@\begin{verbatim}
 NumericType VOLUME( PolygonType Object )
@\end{verbatim}

   returns the volume of the given {\bf Object} (in object units). It returns
 the volume of the polygonal object, not the volume of the object it might
 approximate.

   This routine decomposes all non-convex polygons to convex ones, as a side
 effect (see CONVEX).
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{GeometricType returning functions}
!GeometricType returning functions
$

@\subsubsection{ADAPISO}
!ADAPISO

@\begin{verbatim}
 CurveType ADAPISO( SurfaceType Srf, NumericType Dir, NumericType Eps,
                    NumericType FullIso, NumericType SinglePath )
@\end{verbatim}

 constructs a {\em coverage} to {\bf Srf} using isocurve in the {\bf Dir} direction,
 so that for any point p on surface {\bf Srf}, there exists a point on one of
 the isocurves that is close to p within {\bf Eps}. If {\bf FullIso}, the
 extracted isocurves span the entire surface domain; otherwise they may
 span only a subset of the domain. If {\bf SinglePath}, an approximation to
 a single path (Hamiltonian path) that visits all isocurves is constructed
 (not supported). See also COVERPT, COVERISO.
 
@\begin{verbatim}
    srf = sbezier( list( list( ctlpt( E3, -0.5, -1.0,  0.0 ),
                               ctlpt( E3,  0.4,  0.0,  0.1 ),
                               ctlpt( E3, -0.5,  1.0,  0.0 ) ),
                         list( ctlpt( E3,  0.0, -0.7,  0.1 ),
                               ctlpt( E3,  0.0,  0.0,  0.0 ),
                               ctlpt( E3,  0.0,  0.7, -0.2 ) ),
                         list( ctlpt( E3,  0.5, -1.0,  0.1 ),
                               ctlpt( E3, -0.4,  0.0,  0.0 ),
                               ctlpt( E3,  0.5,  1.0, -0.2 ) ) ) );
    aiso = ADAPISO( srf, COL, 0.1, FALSE, FALSE );
@\end{verbatim}

 constructs an adaptive isocurve approximation with tolerance of {\bf 0.1} to
 surface {\bf srf} in direction {\bf COL}. Isocurves are allowed to span a
 subset of the surface domain. No single path is needed.

 The {\bf SinglePath} option is currently not supported.
$

@\subsubsection{ALGSUM}
!ALGSUM

@\begin{verbatim}
 SurfaceType ALGSUM( CurveType Crv1, CurveType Crv2 )
@\end{verbatim}

 Given two curves, compute a surface that is their algebraic sum:
^
^                        S(u, v) = C1(u) + C2(v)
^
@\begin{equation}
@    S(u, v) = C_1(u) + C_2(v)
@\end{equation}

 Example:

@\begin{verbatim}
 c1 = circle( vector( 0.0, 0.0, 0.0 ), 0.7 );
 c2 = ctlpt( E3, -0.2, -0.5, -1.5 ) + ctlpt( E3, 0.2, 0.5, 1.5 );

 s1 = algsum( c1, c2 );

 c2 = cbspline( 3,
                list( ctlpt( E3, 0.0, 0.0, 0.0 ),
                      ctlpt( E3, 0.0, 0.0, 0.7 ),
                      ctlpt( E3, 0.0, 1.5, 1.0 ),
                      ctlpt( E3, 0.0, 0.0, 1.3 ),
                      ctlpt( E3, 0.0, 0.0, 2.0 ) ),
                list( KV_OPEN ) );

 s2 = algsum( c1, c2 );
@\end{verbatim}

 creates two algebraic sum surfaces, one in the shape of a cylinder as
 a sum of a line and a circle, and one circular sweep like.
@See Figure~\ref{fig-algsum}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/algsum1.ps, width=3.0in} &
@        \epsfig{file=user_man/algsum2.ps, width=3.0in}
=    <BR clear=all>
=    <img hspace=2 width=350 src="user_man/algsum1.gif">
=        <img hspace=2 width=350 src="user_man/algsum2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      An algebraic sum of a circle and a line creating a cylinder (left)
-      and a general sweep like surface (right), both using ALGSUM.
=</b><BR clear=all>
@}
@\label{fig-algsum}
@\end{figure}
$

@\subsubsection{ANALYFIT}
!ANALYFIT

@\begin{verbatim}
 ListType ANALYFIT( ListType UVPts, ListType EucPts,
                    NumericType FirstAtOrigin, NumericType Degree )
@\end{verbatim}

   computes a surface fit to the given paraametrized points data.
 The fitted surface will be of bi-degree {\bf Degree}, fitting points
 {\bf EucPts} at parameters {\bf UVPts}.  Needless to say {\bf EucPts} 
 and {\bf UVPts} should be lists of points of similar length.  If
 {\bf FirstAtOrigin} is TRUE, all points are translated so the first point
 in {\bf EucPts} is at the origin.  Only the first coordinates of {\bf UVPts}
 are used.

 Example:

@\begin{verbatim}
    Fitting = nil();
    Eps = 1e-2;

    PtPln = nil():
    for (i = 1, 1, 100,
        snoc( point( random( -1, 1 ), random( -1, 1 ), random( -Eps, Eps ) ),
              PtPln ) );

    BilinCoefs = ANALYFIT( PtPln, PtPln, 0, 1 ) );
@\end{verbatim}

   fits a bilinear to the given planar data with noise.  See also the COERCE
 function from POWER\_TYPE to BEZIER\_TYPE, and FITPMODEL.
$

@\subsubsection{ANIMEVAL}
!ANIMEVAL

@\begin{verbatim}
 AnyType ANIMEVAL( NumericType Time, AnyType Object, NumericType EvalMats )
@\end{verbatim}

 evaluates the animation curves in {\bf Object} at time {\bf Time}.  The
 transformations for time {\bf Time} are saved at the respective sub objects
 of {\bf Object} as "animation\_mat" matrices, if {\bf EvalMats} is TRUE.
   If, however, {\bf EvalMats} is FALSE, the evaluated/mapped geometry is
 returned directly.

 For example,

@\begin{verbatim}
    mov_x = cbezier( list( ctlpt( E1, 0.0 ), ctlpt( E1, 1.0 ) ) );
    attrib( axes, "animation", list( mov_x ) );
    axes2 = ANIMEVAL( 0.5, axes, true );
@\end{verbatim}

 and axes2 will have a matrix in attribute "animation\_mat" of translation in x
 of 1/2.
$

@\subsubsection{AOFFSET}
!AOFFSET

@\begin{verbatim}
 CurveType AOFFSET( CurveType Crv, NumericType OffsetDistance,
                    NumericType Epsilon, NumericType TrimLoops,
                    NumericType BezInterp )

 or

 CurveType AOFFSET( CurveType Crv, CurveType OffsetDistance,
                    NumericType Epsilon, NumericType TrimLoops,
                    NumericType BezInterp )
@\end{verbatim}

 computes an offset of {\bf OffsetDistance} with a globally bounded error
 (controlled by {\bf Epsilon}). The smaller {\bf Epsilon} is, the better
 the approximation to the offset. The bounded error is achieved by adaptive
 refinement of the {\bf Crv}.
   If {\bf OffsetDistance} is a (scalar) curve, the curve's first coordinate
 is used to prescribe a variable offset amount along the curve.  Both
 {\bf Crv} and {\bf OffsetDistance} must share the same parametric domain.
   If {\bf TrimLoops} is TRUE or on, the regions of the object that
 self-intersect as a result of the offset operation are trimmed away.
   If {\bf BezInterp} is TRUE, each curve's segment is interpolated instead
 of approximated.

 Example:

@\begin{verbatim}
    OffCrv1 = AOFFSET( Crv, 0.5, 0.01, FALSE, FALSE );
    OffCrv2 = AOFFSET( Crv, 0.5, 0.01, TRUE, FALSE );
@\end{verbatim}

 computes an adaptive offset to {\bf Crv} with {\bf OffsetDistance} of
 0.5 and {\bf Epsilon} of 0.01 and trims the self intersection loops in
 the second instance.
 See also OFFSET, LOFFSET, and MOFFSET.
@See Figure~\ref{fig-caoffset}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/caoffset.ps, width=4in}
=    <img  hspace=2 src="user_man/caoffset.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       Adaptive offset approximation (thick) of a B-spline curve (thin).
-       On the left, the self intersections in the offset computed in the
-       right are eliminated. Both offsets were computed using AOFFSET.
@       (See also Figure~\protect\ref{fig-coffset}.)
=</b><BR clear=all>
@}
@\label{fig-caoffset}
@\end{figure}
$

@\subsubsection{ARC}
!ARC

@\begin{verbatim}
 CurveType ARC( VectorType StartPos, VectorType Center, VectorType EndPos )
@\end{verbatim}

 constructs an arc between the two end points {\bf StartPos} and {\bf EndPos},
 centered at {\bf Center}. THe arc will always be less than 180 degrees, so the
 shortest circular path from {\bf StartPos} to {\bf EndPos} is selected. The
 case where {\bf StartPos}, {\bf Center}, and {\bf EndPos} are collinear is
 illegal, since it attempts to define a 180 degrees arc. The arc is constructed
 as a single rational quadratic Bezier curve.

 Example:

@\begin{verbatim}
    Arc1 = ARC( vector( 1.0, 0.0, 0.0 ),
                vector( 1.0, 1.0, 0.0 ),
                vector( 0.0, 1.0, 0.0 ) );
@\end{verbatim}

 constructs a 90 degrees arc, tangent to both the X and Y axes at coordinate 1.
@See Figure~\ref{fig-arc}~(a).
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/arc1cnst.ps, width=3in} &
@    \epsfig{file=user_man/arc2cnst.ps, width=3in} 
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/arc1cnst.gif">
=    <img hspace=2 width=250 src="user_man/arc2cnst.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A 90 degree arc constructed using the ARC constructor (left) and
-      a 280 degrees arc (right) constructed using the ARC360 constructor.
=</b><BR clear=all>
@}
@\label{fig-arc}
@\end{figure}
 See also ARC360
$

@\subsubsection{ARC360}
!ARC360

@\begin{verbatim}
 CurveType ARC360( VectorType Center, NumericType Radius,
                   NumericType StartAngle, NumericType EndAngle )
@\end{verbatim}

 constructs an arc between the two angles (degrees) {\bf StartAngle} and
 {\bf EndAngle}, centered at {\bf Center}. The arc will always be less than 360
 degrees.  The arc is constructed as a rational quadratic B-spline curve.

 Example:

@\begin{verbatim}
    Arc2 = ARC360( vector( 0.0, 0.0, 0.0 ), 1.0, 75, 355 );
@\end{verbatim}

 constructs a 280 degrees arc.
@See Figure~\ref{fig-arc}~(b).
 See also ARC.
$

@\subsubsection{BBOX}
!BBOX

@\begin{verbatim}
 ListType BBOX( GeometricTreeType Geom )
@\end{verbatim}

 Given a (tree of) geometry, {\bf Geom} computes its bounding box and
 return it as a list of six numbers: XMin/Max, YMin/Max, ZMin/Max, in this
 order.

 Example:

@\begin{verbatim}
 B1 = BBOX( axes );
@\end{verbatim}
$

@\subsubsection{BLHERMITE}
!BLHERMITE

@\begin{verbatim}
 SurfaceType BLHERMITE( CurveType Bndry1, CurveType Bndry2,
                        CurveType Tan1, CurveType Tan2,
                        CurveType Sctn, CurveType Nrml )
@\end{verbatim}

 computes a Hermite blend surface that supports an arbitrary cross section.
 This constructs a surface between {\bf Bndry1} and {\bf Bndry2} so that the
 first derivative continuity constraints, as prescribed by {\bf Tan1} at
 {\bf Bndry1} and {\bf Tan2} at {\bf Bndry2}, are preserved.  In addition,
 the interior between {\bf Bndry1} and {\bf Bndry2} will follow the shape
 of planar cross section curve {\bf Sctn} and will be oriented along the
 vector field prescribed by {\bf Nrml}. 
   Cross section {\bf Sctn} is a planar curve that must start at (-1, 0) and
 end at (1, 0), and have zero speed at the ends (first control point equals
 the second and is the same at the end).

 Example:

@\begin{verbatim}
 c1 = ctlpt( e3, 0, 0, 0 ) + ctlpt( e3, 0, 1, 0 );
 c2 = ctlpt( e3, 1, 0, 0 ) + ctlpt( e3, 1, 1, 0 );
 d1 = ctlpt( e3,  1, 0,  1 ) + ctlpt( e3,  1, 0,  0.1 );
 d2 = ctlpt( e3,  1, 0, -0.1 ) + ctlpt( e3,  1, 0, -1 );

 s1 = hermite( c1, c2, d1, d2 );
 color( s1, red );

 cSec = cbspline( 3,
                  list( ctlpt( e2, -1,    0 ),
                        ctlpt( e2, -1,    0 ),
                        ctlpt( e2, -0.14, 0.26 ),
                        ctlpt( e2, -0.65, 0.51 ),
                        ctlpt( e2,  0,    0.76 ),
                        ctlpt( e2,  0.65, 0.51 ),
                        ctlpt( e2,  0.14, 0.26 ),
                        ctlpt( e2,  1,    0 ),
                        ctlpt( e2,  1,    0 ) ),
                  list( kv_open ) );
 n = ctlpt( e3, 0, 0, 1 ) + ctlpt( e3, 0, 0, 1 );

 s2 = BLHERMITE( c1, c2, d1, d2, cSec2, n );
 color( s2, yellow );
@\end{verbatim}

 constructs a regular Hermite surfaces {\bf s1} and a blending Hermite that
 follows the cross section {\bf cSec}.  See also HERMITE and BLSHERMITE.
@See Figure~\ref{fig-blshermite}~(a).
$

@\subsubsection{BLSHERMITE}
!BLSHERMITE

@\begin{verbatim}
 SurfaceType BLSHERMITE( SurfaceType Srf, CurveType PCrv,
                         CurveType Sctn, NumericType TanScale,
                         AnyType Width, AnyType Height )
@\end{verbatim}

 computes a Hermite blend surface on {\bf Srf} along parametric curve of
 {\bf Srf}, {\bf PCrv}, the cross section {\bf Sctn}, a tangent field scale
 control {\bf TanScale}, and the width and height control of {\bf Width}
 and {\bf Height}.  {\bf Width} and {\bf Height} can be either a numeric
 value of expected width and height or a scalar field curve prescribing the
 expected width and height along the constructed blend.

 The constructed surface, which is C1 continuous to {\bf Srf}, is positioned
 along {\bf PCrv}, a curve in the parametric domain of {\bf Srf}.  The
 cross section {\bf Sctn} is a planar curve that must start at (-1, 0) and
 end at (1, 0), and have zero speed at the ends (first control point equals
 the second and is the same at the end).  {\bf TanScale} controls how rapid
 the change in the tangent is, as we move away from the surface.

 Example:

@\begin{verbatim}
 cSec = cbspline( 3,
                  list( ctlpt( e2, -1,    0 ),
                        ctlpt( e2, -1,    0 ),
                        ctlpt( e2, -0.5,  0.2 ),
                        ctlpt( e2, -0.7,  0.3 ),
                        ctlpt( e2,  0,    0.5 ),
                        ctlpt( e2,  0.7,  0.3 ),
                        ctlpt( e2,  0.5,  0.2 ),
                        ctlpt( e2,  1,    0 ),
                        ctlpt( e2,  1,    0 ) ),
                  list( kv_open ) );

 s = -surfPRev( cregion( pcircle( vector( 0, 0, 0 ), 1 ),
                         0, 2 ) * rx( 90 ) );

 s1 = BLSHERMITE( s, ctlpt( E2, 0, 1 ) + ctlpt( E2, 4, 1 ),
                  cSec, 1, 0.2, 0.5 );
 s2 = BLSHERMITE( s, ctlpt( E2, 0, 1.5 ) + ctlpt( E2, 4, 1.5 ),
                  cSec, 0.1, 0.2, 0.5 );
 s3 = BLSHERMITE( s, ctlpt( E2, 0, 0.3 ) + ctlpt( E2, 4, 0.3 ),
                  cSec, 1.5, 0.2, 0.5 );
@\end{verbatim}

 places three Hermite blend surfaces {\bf s1, s2, s3} using the cross
 section {\bf cSec} on a unit sphere {\bf s}.  See also HERMITE and
 BLHERMITE.
@See Figure~\ref{fig-blshermite}~(b).
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/bl_hrmt.ps, width=3.0in} &
@        \epsfig{file=user_man/bls_hrmt.ps, width=3.0in} 
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/bl_hrmt.gif">
=        <img hspace=2 width=250 src="user_man/bls_hrmt.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Blending Hermite with a prescribed cross section (left) using BLHERMITE
-      and blending Hermite with a prescribed cross section on a surface
-      (right) using BLSHERMITE.
=</b><BR clear=all>
@}
@\label{fig-blshermite}
@\end{figure}
$

@\subsubsection{BLOSSOM}
!BLOSSOM

@\begin{verbatim}
 CtlPtType BLOSSOM( CurveType Crv, ListType BlossomVals )
@\end{verbatim}

 computes the blossom of the given {\bf Crv} and the given blossom values
 {\bf BlossomVals}.

 Example:

@\begin{verbatim}
 c1 = cbezier( list( ctlpt( E2, 1.7, 0.0 ),
                     ctlpt( E2, 0.7, 0.7 ),
                     ctlpt( E2, 1.7, 0.3 ),
                     ctlpt( E2, 1.5, 0.8 ),
                     ctlpt( E2, 1.6, 1.0 ) ) );

 BLOSSOM( c1, list( 0, 0, 0, 0 ) ) == coord( c1, 0 ) &&
 BLOSSOM( c1, list( 0, 0, 0, 1 ) ) == coord( c1, 1 ) &&
 BLOSSOM( c1, list( 0, 0, 1, 1 ) ) == coord( c1, 2 ) &&
 BLOSSOM( c1, list( 0, 1, 1, 1 ) ) == coord( c1, 3 ) &&
 BLOSSOM( c1, list( 1, 1, 1, 1 ) ) == coord( c1, 4 );
@\end{verbatim}

  extracts the control points of an quadric Bezier curve via blossoming and
 compares this to the results obtained via a traditional extraction
 approach (via the COORD function).
$

@\subsubsection{BOOLONE}
!BOOLONE

@\begin{verbatim}
 SurfaceType BOOLONE( CurveType Crv )
@\end{verbatim}

 Given a closed curve, the curve is subdivided into four segments equally
 spaced in the parametric space that are fed into BOOLSUM. This is useful if
 a surface should "fill" the area enclosed by a closed curve.

 Example:

@\begin{verbatim}
 Srf = BOOLONE( circle( vector( 0.0, 0.0, 0.0 ), 1.0 ) );
@\end{verbatim}

 creates a disk surface containing the area enclosed by the unit circle.
@See Figure~\ref{fig-boolsum-one}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/boolone.ps, width=3.0in} &
@        \epsfig{file=user_man/boolsum.ps, width=3.0in}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/boolone.gif">
=        <img hspace=2 width=250 src="user_man/boolsum.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       A boolean sum of a circle creates a disk (left) using BOOLONE and
-       a general Boolean sum of four curves (right) using BOOLSUM.
=</b><BR clear=all>
@}
@\label{fig-boolsum-one}
@\end{figure}
$

@\subsubsection{BOOLSUM}
!BOOLSUM

@\begin{verbatim}
 SurfaceType BOOLSUM( CurveType Crv1, CurveType Crv2,
                      CurveType Crv3, CurveType Crv4 )
@\end{verbatim}

 constructs a surface using the provided four curves as its four boundary
 curves. Curves do not have to have the same order or type, and will be
 promoted to their least common denominator. The end points of the four
 curves should match as follows:
# 30 2 0 1
 {\bf Crv1} start point,
  to {\bf Crv3} start point.
 {\bf Crv1} end point,
  to {\bf Crv4} start point.
 {\bf Crv2} start point,
  to {\bf Crv3} end point.
 {\bf Crv2} end point,
  to {\bf Crv4} end point.
#
 where {\bf Crv1} and {\bf Crv2} are the two boundaries in one parametric
 direction, and {\bf Crv3} and {\bf Crv4} are the two boundaries in the other
 parametric direction.

 Example:

@\begin{verbatim}
    Cbzr1 = cbezier( list( ctlpt( E3, 0.1, 0.1, 0.1 ),
                           ctlpt( E3, 0.0, 0.5, 1.0 ),
                           ctlpt( E3, 0.4, 1.0, 0.4 ) ) );
    Cbzr2 = cbezier( list( ctlpt( E3, 1.0, 0.2, 0.2 ),
                           ctlpt( E3, 1.0, 0.5, -1.0 ),
                           ctlpt( E3, 1.0, 1.0, 0.3 ) ) );
    Cbsp3 = cbspline( 4,
                      list( ctlpt( E3, 0.1,  0.1, 0.1 ),
                            ctlpt( E3, 0.25, 0.0, -1.0 ),
                            ctlpt( E3, 0.5,  0.0, 2.0 ),
                            ctlpt( E3, 0.75, 0.0, -1.0 ),
                            ctlpt( E3, 1.0,  0.2, 0.2 ) ),
                      list( KV_OPEN ) );
    Cbsp4 = cbspline( 4,
                      list( ctlpt( E3, 0.4,  1.0, 0.4 ),
                            ctlpt( E3, 0.25, 1.0, 1.0 ),
                            ctlpt( E3, 0.5,  1.0, -2.0 ),
                            ctlpt( E3, 0.75, 1.0, 1.0 ),
                            ctlpt( E3, 1.0,  1.0, 0.3 ) ),
                      list( KV_OPEN ) );
    Srf = BOOLSUM( Cbzr1, Cbzr2, Cbsp3, Cbsp4 );
@\end{verbatim}
$

@\subsubsection{BOUNDARY}
!BOUNDARY

@\begin{verbatim}
 AnyType BOUNDARY( AnyType Obj )
@\end{verbatim}

   Given a geometric object {\bf Obj}, let it be a surface, a trimed surface,
 or a polygonal model, returns the boundary of the shape.  If {\bf Obj} is a
 polygonal object originated with a surface and all vertices has "uvvals"
 attributes, by placing "SrfBoundary" attribute on {\bf Obj} with the
 "UMin VMin UMax VMax" surface domain, the surface boundary is will be
 properly detected, even if the surface is closed.

 Example:

@\begin{verbatim}
    CBndry1 = BOUNDARY( Srf );

    poly_approx_uv = 1;
    Pl = gpolygon( Srf, 1 );
    attrib( Pl, "SrfBoundary", "0 0 1 2" );  # Domain of Srf [0, 1] x [0, 2]

    CBndry2 = BOUNDARY( Pl );
@\end{verbatim}

   returns in {\bf CBndry1}, the four boundary curves of tensor product surface
 {\bf Srf} and in {\bf CBndry2}, the edges on the tesselation of {\bf Srf},
 {\bf Pl}, on the boundary of {\bf Srf}, even if {\bf Srf} is closed.
$

@\subsubsection{BOX}
!BOX

@\begin{verbatim}
 PolygonType BOX( VectorType Point,
                  NumericType Dx, NumericType Dy, NumericType Dz )
@\end{verbatim}

   creates a BOX polygonal object, whose boundary is coplanar with the
 $XY$, $XZ$, and $YZ$ planes. The BOX is defined by {\bf Point} as
 base position, and {\bf Dx, Dy, Dz} as BOX dimensions. Negative dimensions
 are allowed.

 Example:

@\begin{verbatim}
    B = BOX( vector( 0, 0, 0 ), 1, 1, 1);
@\end{verbatim}

 creates a unit cube from 0 to 1 in all axes.
$

@\subsubsection{BSCTCONCN2}
!BSCTCONCN2

@\begin{verbatim}
 SurfaceType BSCTCONCN2( PointType ConeApx1, VectorType ConeDir1,
                         NumericType ConeAngle1,
                         PointType ConeApx2, VectorType ConeDir2,
                         NumericType ConeAngle2 )
@\end{verbatim}

   computes the bisector surface of two cones in general position.
 The cones' apexes can be found in {\bf ConeApx1} and {\bf ConeApx2} 
 with axes directions {\bf ConeDir1} and {\bf ConeDir2} and spanning
 angles of {\bf ConeAngle1} and {\bf ConeAngle2}.

 Example:

@\begin{verbatim}
 BisectSrf = BSCTCONCN2( Apx1, Dir1, Ang1, Apx2, Dir2, Ang2 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCYL, BSCTCYLCYL, BSCTCONLN, BSCTCONPL,
 BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR,
$

@\subsubsection{BSCTCONCON}
!BSCTCONCON

@\begin{verbatim}
 SurfaceType | ListType BSCTCONCON( VectorType ConeDir1, NumericType ConeAngle1,
                                    VectorType ConeDir2, NumericType ConeAngle2,
                                    NumericType Size )
@\end{verbatim}

   computes the bisector surface of two cones that share the same apex.
 The cones' directions are {\bf ConeDir1} and {\bf ConeDir2} and the spanning
 angles of {\bf ConeAngle1} and {\bf ConeAngle2}. {\bf ConeDir1} and
 {\bf ConeDir2} must be in the northern hemisphere; i.e. their Z coefficient
 must be positive.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
 BisectSrf = BSCTCONCON( vector( 0, 0, 1 ), 50,
                         vector( 0, 0, 1 ), 20, 1.0 );
@\end{verbatim}

 computes the bisector of two concentric cones, which is also a cone.
 See also BSCTCONLN, BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL,
 BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR
$

@\subsubsection{BSCTCONCYL}
!BSCTCONCYL

@\begin{verbatim}
 SurfaceType BSCTCONCYL( PointType ConeApx1, VectorType ConeDir1,
                         NumericType ConeAngle1,
                         PointType CylPt2, VectorType CylDir2,
                         NumericType CylRad2 )
@\end{verbatim}

   computes the bisector surface of a cone and a cylinder in general position.
 The cones apex is in {\bf ConeApx1} with axes direction of {\bf ConeDir1}
 and spanning angles of {\bf ConeAngle1}.  The second cylinder starts at
 {\bf CylPt2}, in direction {\bf CylDir2} and radius {\bf CylRad2}.

 Example:

@\begin{verbatim}
 BisectSrf = BSCTCONCYL( Apx1, Dir1, Ang1, Pt2, Dir2, Rad2 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCYLCYL, BSCTCONLN, BSCTCONPL,
 BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR
$

@\subsubsection{BSCTCONLN}
!BSCTCONLN

@\begin{verbatim}
 SurfaceType | ListType BSCTCONLN( VectorType ConeDir, NumericType ConeAngle,
                                   VectorType LineDir, NumericType Size )
@\end{verbatim}

   computes the bisector surface of a cone and a line through its apex.
 The cone's direction is {\bf ConeDir} and its spanning angle is
 {\bf ConeAngle}.  {\bf ConeDir} and {\bf LineDir} must be in the northern
 hemisphere; i.e. their Z coefficient must be positive.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = ( vector( 0, 0, 1 ), 45, vector( 0, 0.1, 1 ), 1 );
@\end{verbatim}

 computes the bisector surface of a cone along the Z axis with spanning
 angle of 45 degrees, and a line through its apex in direction ( 0, 0.1, 1 ).

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONPL,
 BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR,
$

@\subsubsection{BSCTCONPL}
!BSCTCONPL

@\begin{verbatim}
 SurfaceType | ListType BSCTCONPL( PointType ConeApex, VectorType ConeDir,
                                   NumericType ConeAngle, NumericType Size )
@\end{verbatim}

   computes the bisector surface of a general cone and the XY plane (Z = 0
 plane).  The cone's apex is at {\bf ConeApex}, the cone's direction is
 {\bf ConeDir} and its spanning angle is {\bf ConeAngle}.  {\bf Dir} must be
 in the northern hemisphere; i.e. their Z coefficient must be positive.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTCONPL( point( 0, 0, -0.3 ), vector( 1, 1, 1 ), 20, 1 );
@\end{verbatim}

 computes the bisector surface of a cone with its apex at (0, 0, -0.3)
 along the axis (1, 1, 1) with spanning angle of 20 degrees, and the plane
 Z = 0.

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTCONPT}
!BSCTCONPT

@\begin{verbatim}
 SurfaceType | ListType BSCTCONPT( PointType ConeApex, VectorType ConeDir,
                                   NumericType ConeAngle, PointType Pt,
                                   NumericType Size )
@\end{verbatim}

   computes the bisector surface of a cone in a general position and a point,
 {\bf Pt}.
  The cone's apex is at {\bf ConeApex}, the cone's direction is {\bf ConeDir}
 and its spanning angle is {\bf ConeAngle}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
   Bisect = BSCTCONPT( point( 0, 0, 0 ), vector( 0, 0, 1 ), 22,
                       point( 0, 0.2, 0.7 ), 1 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTCONSPR}
!BSCTCONSPR

@\begin{verbatim}
 SurfaceType | ListType BSCTCONSPR( PointType ConeApex, VectorType ConeDir,
                                    NumericType ConeAngle, PointType SptCntr,
                                    NumericType SprRadius, NumericType Size )
@\end{verbatim}

   computes the bisector surface of a cone and a sphere.
   The cone's apex is at {\bf ConeApex}, the cone's direction is {\bf ConeDir}
 and its spanning angle is {\bf ConeAngle}.  The sphere is centered at
 {\bf SptCntr} and has a radius of {\bf SprRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTCONSPR( point( 0, 0, 0 ), vector( 0, 0, 1 ),
                            45, point( 0, 0, 1 ), 0.5, 2.0 );
@\end{verbatim}

 computes the bisector between a cone along the Z axis with a 45 degree
 spanning angle and a sphere at (0, 0, 1) of radius 0.5.

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTCYLCYL}
!BSCTCYLCYL

@\begin{verbatim}
 SurfaceType BSCTCYLCYL( PointType CylPt1, VectorType CylDir1,
                         NumericType CylRad1,
                         PointType CylPt2, VectorType CylDir2,
                         NumericType CylRad2 )
@\end{verbatim}

   computes the bisector surface of two cylinders in a general position.
 The cylinders start at {\bf CylPt1} and {\bf CylPt2} and follow the
 directions {\bf CylDir1} and  {\bf CylDir2}. They have radii of {\bf CylRad1}
 and {\bf CylRad2}.

 Example:

@\begin{verbatim}
 BisectSrf = BSCTCYLCYL( Pt1, Dir1, Rad1, Pt2, Dir2, Rad2 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONLN, BSCTCONPL,
 BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$


@\subsubsection{BSCTCYLPL}
!BSCTCYLPL

@\begin{verbatim}
 SurfaceType | ListType BSCTCYLPL( PointType CylPos, VectorType CylDir,
                                   NumericType CylRadius, Size )
@\end{verbatim}

   computes the bisector surface of a a cylinder and the XY plane (plane 
 Z = 0).
 The cylinder is located at {\bf CylPos}, in the direction of {\bf CylDir}
 which also sets the length of the cylinder.  The radius of the cylinder
 is {\bf CylRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    Pt = point( 0.1, 0, 0.2 );
    BisectSrf = BSCTCYLPL( point( 0, 0, 0.5 ), vector( 0, 0, 1 ), 0.2, 1 );
@\end{verbatim}

 computed the bisector surface between a cylinder of radius 0.2 along the
 Z axis and the XY plane.

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTCYLPT}
!BSCTCYLPT

@\begin{verbatim}
 SurfaceType | ListType BSCTCYLPT( PointType CylPos, VectorType CylDir,
                                   NumericType CylRadius, PointType Pt,
                                   NumericType Size )
@\end{verbatim}

   computes the bisector surface of a a cylinder and a point, {\bf Pt}.
 The cylinder is located at {\bf CylPos}, in the direction of {\bf CylDir}
 which also sets the length of the cylinder.  The radius of the cylinder
 is {\bf CylRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    Pt = point( 0.1, 0, 0.2 );
    BisectSrf = BSCTCYLPT( point( 0, 0, 0.5 ), vector( 0, 0, 1 ), 0.2, Pt, 1 );
@\end{verbatim}

 computes the bisector surface between a cylinder of radius 0.2 along the
 Z axis and a point at (0.1, 0, 0.2).

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLSPR, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR
$

@\subsubsection{BSCTCYLSPR}
!BSCTCYLSPR

@\begin{verbatim}
 SurfaceType | ListType BSCTCYLSPR( PointType CylPos, VectorType CylDir,
                                    NumericType CylRadius, PointType SprCntr,
                                    NumericType SprRadius, NumericType Size )
@\end{verbatim}

   computes the bisector surface of a cylinder and a sphere.
 The cylinder is located at {\bf CylPos}, in the direction of {\bf CylDir}
 which also sets the length of the cylinder.  The radius of the cylinder
 is {\bf CylRadius}.  The sphere is centered at {\bf SptCntr} and has a
 radius of {\bf SprRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTCYLSPR( point( 0, 0, 1.5 ), vector( 0, 0, 3 ), 0.2,
                            point( 0, 0, 0 ), 0.7, 3 );
@\end{verbatim}

 computed the bisector surface between a cylinder of radius 0.2 along the
 Z axis and a sphere at the origin with radius 0.7.

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTPLNLN,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTPLNLN}
!BSCTPLNLN

@\begin{verbatim}
 SurfaceType | ListType BSCTPLNLN( VectorType LineDir, NumericType Size )
@\end{verbatim}

   computes the bisector surface of the XY plane (plane Z = 0) and a
 line in direction {\bf LineDir}.  The plane and the line are assumed to
 intersect at the origin.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTPLNLN( vector( 0, 0, 1 ), 1 );
@\end{verbatim}

 computes the bisector of the XY plane and the Z axis (a cone).

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTPLNPT}
!BSCTPLNPT

@\begin{verbatim}
 SurfaceType | ListType BSCTPLNPT( PointType Pt, NumericType Size )
@\end{verbatim}

   computes the bisector surface of the XY plane (plane Z = 0) and a point
 {\bf Pt}.  This surface is a paraboloid of revolution.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTPLNPT( point( 0, 0, 1 ), 1 );
@\end{verbatim}

 computes the bisector surface of the XY plane and the point (0, 0, 1).

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNLN, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTSPRLN}
!BSCTSPRLN

@\begin{verbatim}
 SurfaceType | ListType BSCTSPRLN( PointType SprCntr, NumericType SprRadius,
                                   NumericType Size )
@\end{verbatim}

   computes the bisector surface of a sphere and the Z axis line.
 The sphere is centered at {\bf SptCntr} and has a radius of {\bf SprRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTSPRLN( vector( 2, 0, 0 ), 0.7, 1 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTSPRPL}
!BSCTSPRPL

@\begin{verbatim}
 SurfaceType | ListType BSCTSPRPL( PointType SprCntr, NumericType SprRadius,
                                   NumericType Size )
@\end{verbatim}

   computes the bisector surface of the XP plane (the plane Z = 0) and a
 sphere.  This bisector surface is a paraboloid of revolution.
 The sphere is centered at {\bf SptCntr} and has a radius of {\bf SprRadius}.
   {\bf Size} controls the portion of the (infinite) bisector actually
 represented.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTSPRPL( point( 0, 0, 1.5 ), 0.7, 0.5 );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNLN, BSCTPLNPT, BSCTSPRLN, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
@See Figure~\ref{fig-bsct-csg}.
$

@\subsubsection{BSCTSPRPT}
!BSCTSPRPT

@\begin{verbatim}
 SurfaceType | ListType BSCTSPRPT( PointType SprCntr, NumericType SprRadius
                                   PointType Pt )
@\end{verbatim}

   computes the bisector surface of a sphere and a point, {\bf Pt}.
 The sphere is centered at {\bf SptCntr} and has a radius of {\bf SprRadius}.
 
 Example:

@\begin{verbatim}
    Pt = point( 0, 0, 1 );
    BisectSrf = BSCTSPRPT( point( 0, 0, 0 ), 0.7, Pt );
@\end{verbatim}

 computes the bisector of a sphere of radius 0.7 centered at the origin, and
 the point (0, 0, 1).

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNLN, BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRSPR, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTSPRSPR}
!BSCTSPRSPR

@\begin{verbatim}
 SurfaceType | ListType BSCTSPRSPR( PointType Spr1Cntr, NumericType Spr1Radius
                                    PointType Spr2Cntr, NumericType Spr2Radius )
@\end{verbatim}

   computes the bisector surface of two spheres.
 The spheres are centered at {\bf Spt1Cntr} and {\bf Spt2Cntr} and have a
 radii of {\bf Spr1Radius} and {\bf Spr2Radius}, respectively.

 Example:

@\begin{verbatim}
    BisectSrf = ( point( 0, 0, 0 ), 0.7, point( 1, 0, 0 ), 0.2 );
@\end{verbatim}

 compute the bisectors of a sphere at the origin with radius 0.7, and
 a sphere at (1, 0, 0) with a radius of 0.2.

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNLN, BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTTRSPT,
 BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTTRSPT}
!BSCTTRSPT

@\begin{verbatim}
 SurfaceType | ListType BSCTTRSPT( PointType TrsPos, VectorType TrsDir,
                                   NumericType TrsMjrRad, NumericType TrsMnrRad,
                                   PointType Pt )
@\end{verbatim}

   computes the bisector surface of a torus and a point, {\bf Pt}.  The
 torus is located at {\bf TrsPos}, with its axis of symmetry {\bf TrsDir},
 a major radius of {\bf TrsMajorRad} and a minor radius pf {\bf TrsMinorRad}.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTTRSPT( point( 0.0, 0.0, 0.0 ), vector( 0.0, 0.0, 1.0 ),
                           0.7, 0.7, Pt );
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
  BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
  BSCTPLNLN, BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR,
  BSCTTRSSPR, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
$

@\subsubsection{BSCTTRSSPR}
!BSCTTRSSPR

@\begin{verbatim}
 SurfaceType | ListType BSCTTRSSPR( PointType TrsPos, VectorType TrsDir,
                                    NumericType TrsMjrRad, NumericType TrsMnrRad,
                                    PointType SprCntr, NumericType SprRadius )
@\end{verbatim}

   computes the bisector surface of a torus and a sphere.  The torus is
 located at {\bf TrsPos}, with its axis of symmetry {\bf TrsDir},
 a major radius of {\bf TrsMajorRad} and a minor radius pf {\bf TrsMinorRad}.
   The sphere is centered at {\bf SptCntr} and has a radius of {\bf SprRadius}.

 Example:

@\begin{verbatim}
    BisectSrf = BSCTTRSSPR( point( 0.0, 0.0, 0.0 ), vector( 0.0, 0.0, 1.0 ),
                            0.7, 0.7, point( 0.7, 0.0, 0.0 ), 0.7);
@\end{verbatim}

 See also BSCPCONCON, BSCTCONCN2, BSCTCONCYL, BSCTCONCON, BSCTCONLN,
 BSCTCONPL, BSCTCONPT, BSCTCONSPR, BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR,
 BSCTPLNLN, BSCTPLNPT, BSCTSPRLN, BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR,
 BSCTTRSPT, CALPHASECTOR, CBISECTOR2D, CBISECTOR3D, SBISECTOR.
@See Figure~\ref{fig-bsct-csg}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/BsctTrSp.ps, width=3.0in} &
@        \epsfig{file=user_man/BsctSpLn.ps, width=2.5in,angle=90}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/BsctTrSp.gif">
=        <img hspace=2 width=250 src="user_man/BsctSpLn.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       Bisectors of many CSG primitives such as points, lines, planes,
-       spheres, cones, cylinders, and torii are rational.  In (left), the
-       rational bisector of a line and a sphere is
-       shown while (right) shows the bisector 
-       of a sphere and a torus tangent to each other.  See
-       BSCTCONCON, BSCTCONLN, BSCTCONPL, BSCTCONPT, BSCTCONSPR,
-       BSCTCYLPL, BSCTCYLPT, BSCTCYLSPR, BSCTPLNLN, BSCTPLNPT, BSCTSPRLN,
-       BSCTSPRPL, BSCTSPRPT, BSCTSPRSPR, BSCTTRSPT, BSCTTRSSPR.
=</b><BR clear=all>
@}
@\label{fig-bsct-csg}
@\end{figure}
$

@\subsubsection{BZR2BSP}
!BZR2BSP

@\begin{verbatim}
 CurveType BZR2BSP( CurveType Crv )

 or

 SurfaceType BZR2BSP( SurfaceType Srf )
@\end{verbatim}

   creates a B-spline curve or a B-spline surface from the given Bezier curve
 or Bezier surface. The B-spline curve or surface is assigned an open end knot
 vector(s) with no interior knots, in the parametric domain of zero to one.

 Example:

@\begin{verbatim}
    BspSrf = BZR2BSP( BzrSrf );
@\end{verbatim}
$

@\subsubsection{BSP2BZR}
!BSP2BZR

@\begin{verbatim}
 CurveType | ListType BSP2BZR( CurveType Crv )

 or

 SurfaceType | ListType BSP2BZR( SurfaceType Srf )
@\end{verbatim}

   creates Bezier curve(s) or surface(s) from a given B-spline curve or a
 B-spline surface. The B-spline input is subdivided at all internal knots to
 create Bezier curves or surfaces. Therefore, if the input B-spline does have
 internal knots, a list of Bezier curves or surfaces is returned. Otherwise,
 a single Bezier curve or surface is returned.

 Example:

@\begin{verbatim}
    BzrCirc = BSP2BZR( circle( vector( 0.0, 0.0, 0.0 ), 1.0 ) );
@\end{verbatim}

 would subdivide the unit circle into four 90 degrees Bezier arcs returned
 in a list.
$

@\subsubsection{CALPHASECTOR}
!CALPHASECTOR

@\begin{verbatim}
 
 SurfaceType CALPHASECTOR( ListType TwoCrvs, NumericType Alpha)
 
 or
 
 {CurveType | SurfaceType} CALPHASECTOR( ListType CrvPt, NumericType Alpha)
@\end{verbatim}

    computes the alpha sector for {\bf TwoCrvs} of E3 type or between a 
 curve and a point, {\bf CrvPt}. {\bf Alpha} varies between zero and one. 
 An alpha-sector is created where for {\bf Alpha} equals zero, the created 
 surface will contain the first curve, and whereas for {\bf Tolerance} equals 
 one, the created surface will contain the second curve.
   For CrvPt case, if the Crv is E2, the alpha sector is a curve and if it
 is E3, the alpha sector is a surface.
   See also CBISECTOR2D, CBISECTOR3D.

 Example:

@\begin{verbatim}
    c1 = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 );
    c2 = cbezier( list( ctlpt( E3, -1.0, 0.0,  1.0 ),
                        ctlpt( E3,  1.0, 0.0, -1.0 ) ) );
    
    c1 = coerce( c1, E3);
    AlphaSect = CALPHASECTOR( list( c1, c2 ), 0.2 );
    interact( list( c1, c2, AlphaSect ) );
@\end{verbatim}

 computes the alpha sector surface between the two curves c1 and c2 for alpha
 equals 0.2.
$

@\subsubsection{CANGLEMAP}
!CANGLEMAP

@\begin{verbatim}
 CurveType CANGLEMAP( CurveType Crv, NumericType Tolerance,
                      NumericType Angle, NumericType DiagSpan )

 or 

 SurfaceType CANGLEMAP( CurveType Crv, NumericType Tolerance,
                        NumericType Angle, NumericType DiagSpan )
 
@\end{verbatim}

   computes the angular map of planar curve {\bf Crv}.  This bivariate map
 corresponds pairs of locations in {\bf Crv} with tangents that are {\bf Angle}
 degrees apart. 
   If, for example, {\bf Angle} is 90 degrees, locations with orthogonal
 tangents are identified.  The zero set of this bivariate map provides the
 actual correcpondence and this zero set is computed with {\bf Tolerance}
 accuracy, that approximately sets the number of desired surface samples.
   If {\bf Tolerance} is negative the function whose zero set is the angular
 map is returned instead.
   If {\bf DiagSpan} is non zero, the angular diagonal span is sampled
 {\bf DiagSpan} samples and is computed instead.
 The {\bf DiagSpan} will provide for each parameter $t$ the forward and
 backward step that could be taken before hitting an angular span of
 {\bf Angle} degrees for the first time.

    Example:

@\begin{verbatim}
    AM = cAngleMap( Crv, 30, Angle, false );
    ADS = cAngleMap( Crv, 30, Angle, 300 );
@\end{verbatim}

 computes the Angular map of curve {\bf Crv} ay angle {\bf Angle} with 
 tolerance 30 and then extract the angular diagonal span with the same
 parameters and 300 samples.

@Figure~\ref{fig-canglemap} provides some insight
=See provided figure for more insight.  Shown is a given planar
-curve, with three angular maps of 30, 60 and 90 degrees.  The angular
-diagonal span is also drawn in dark thin lines.
@
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/canglemap.ps, width=6in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/canglemap.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Angular maps computed for the given planar curve on the left, at 30,
-      60, and 90 degrees, using CANGLEMAP.  Also show is the angular diagonal
-      span in thin dark color.
=</b><BR clear=all>
@}
@\label{fig-canglemap}
@\end{figure}
 See also CVIEWMAP, CVISIBLE, CARRANGMNT.
$

@\subsubsection{CARCLEN}
!CARCLEN

@\begin{verbatim}
 CurveType CARCLEN( CurveType Crv, NumericType Fineness, NumericType Order )
@\end{verbatim}

   approximates an arc length curve out of the given curve {\bf Crv}.  The
 new approximated curve is sampled with tolerance that is governed by
 {\bf Fineness} and will be of order {\bf Order}. 
   The returned curve is not guaranteed to share the exact same trace as
 the original curve {\bf Crv}.

 Example:

@\begin{verbatim}
    c2 = carclen( c, 1e-4, 3 );
@\end{verbatim}

 approximates {\bf c} as a quadratic arc length curve {\bf c2} by sampling
 the original curve with tolerance 1e-4.
$

@\subsubsection{CAREA}
!CAREA

@\begin{verbatim}
 CurveType CAREA( CurveType Crv )
@\end{verbatim}

   computes the integral area curve, {\em ACrv}, of the given curve {\bf Crv},
 up to a sign.  If {\bf Crv} is a closed curve with domain t0 to t1, then the
 difference of {\em ACrv}(t1) - {\em ACrv}(t0) is the requested area.
@ 
@  The integral area curve $C(t) = (x(t), y(t))$ is computed as the following
@ integral:
@\[
@    \frac{1}{2} \int_{t_1}^{t_2} -x'(t) y(t) + x(t) y'(t) dt
@\]
 Example:

@\begin{verbatim}
    Crv = pcircle( vector( 0, 0, 0 ), 1 );
    ACrv = CAREA( Crv );
    Pi = abs( coord( ceval( ACrv, 4 ), 1 ) - coord( ceval( ACrv, 0 ), 1 ) );
@\end{verbatim}
 is yet another way of approximating the value of Pi.
 See also SMOMENTS and SVOLUME.
$

@\subsubsection{CARRANGMNT}
!CARRANGMNT

@\begin{verbatim}
 CurveType CARRANGMNT( CurveType Crvs, NumericType Eps,
                       NumericType Operation, PointType CenterPt )
@\end{verbatim}

   computations over the given arrangment of planar curves {\bf Crvs} upto
 accuracy that is governed by {\bf Eps}. {\bf Operation} can be one of:
@\begin{itemize}
@\item
  {\bf 1} - computes all the curve curve intersection locations in the
            arrangment and keep the results in "InterPts" attributes on the
            returned curves.
@\item
  {\bf 2} - computes all the curve curve intersection locations in the
            arrangment and split all curves at all those intersections.
@\item
  {\bf 3} - computes Y-minimum lower envelop for this curves' arrangement.
@\item
  {\bf 4} - computes radial lower envelop around point {\bf Center Pt}.
@\end{itemize}

   {\bf CenterPt} is ignored if {\bf Operation} is not equal to 4.

    Example:

@\begin{verbatim}
    LinearLowEnv = carrangmnt( Crvs, 1e-12, 3, 0 );
@\end{verbatim}

 computes the Y-minimum envelop of curve {\bf Crvs}.

@Figure~\ref{fig-carrangmt} show one example of Y-minimum envelop of curves.
=See provided figure for one example of Y-minimum envelop of curves.
@
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/carrangmnt.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/carrangmnt.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Y-minimum envelop for a set of curves, computed using CARRANGMNT.
-      The lower envelop is shown in thick lines.
=</b><BR clear=all>
@}
@\label{fig-carrangmt}
@\end{figure}
 See also CVIEWMAP, CVISIBLE, CANGLEMAP.
$

@\subsubsection{CBEZIER}
!CBEZIER

@\begin{verbatim}
 CurveType CBEZIER( ListType CtlPtList )
@\end{verbatim}

   creates a Bezier curve out of the provided control point list. {\bf CtlPtList}
 is a list of control points, all of which must be of type (E1-E9 P1-P9),
 or regular PointType defining the curve's control polygon. The curve's point
 type will be of a space which is the union of the spaces of all points.
@The created curve is polynomial (or rational),
@\begin{equation}
@     C(t) = \sum_{i=0}^k P_i B_i(t),
@\end{equation}
@where $P_i$ are the control points {\bf CtlPtList}, and k is the degree of
@the curve, which is one less than the number of points.

 Example:

@\begin{verbatim}
    s45 = sin(pi / 4);
    Arc90 = CBEZIER( list( ctlpt( P2, 1.0, 0.0, 1.0 ),
                           ctlpt( P2, s45, s45, s45 ),
                           ctlpt( P1, 1.0, 1.0 ) ) );
@\end{verbatim}

 constructs an arc of 90 degrees as a rational quadratic Bezier curve.

 See also CBSPLINE, CPOWER and SBEZIER.
$

@\subsubsection{CBIARC}
!CBIARC

@\begin{verbatim}
   ListType CBIARC( CurveType Crv, NumericType Tol, NumericType MaxAngle )
@\end{verbatim}

   computes bi-arc fitting to a given curve {\bf Crv}, with a tolarence
 {\bf Tol} in L-infinity sense, and a maximum angular span of each arc of
 at most {\bf MaxAngle} degrees.  Returned is a list of arcs as rational
 Bezier curves with an arc "center" point attribute to ease the reconstruction
 of the analytic representation of the geometry.

 Example:

@\begin{verbatim}
  C1 = cbspline( 4,
      list( ctlpt( E3, -0.287, -0.286, 0 ),
            ctlpt( E2, 0.0272, -0.425 ),
            ctlpt( E2, 0.265, -0.0839 ),
            ctlpt( E2, 0.607, -0.165 ),
            ctlpt( E2, 0.832, -0.205 ),
            ctlpt( E2, 0.737, 0.042 ),
            ctlpt( E2, 0.357, 0.103 ),
            ctlpt( E2, 0.508, 0.298 ),
            ctlpt( E2, 0.814, 0.649 ),
            ctlpt( E2, 0.692, 0.775 ),
            ctlpt( E2, 0.411, 0.391 ),
            ctlpt( E2, 0.301, 0.315 ),
            ctlpt( E2, 0.625, 0.945 ),
            ctlpt( E2, 0.49, 1.03 ),
            ctlpt( E2, 0.369, 0.829 ),
            ctlpt( E2, 0.185, 0.384 ),
            ctlpt( E2, 0.194, 0.518 ),
            ctlpt( E2, 0.243, 1.09 ),
            ctlpt( E2, 0.0653, 1.13 ),
            ctlpt( E2, 0.0644, 0.381 ),
            ctlpt( E2, 0.00925, 0.496 ),
            ctlpt( E2, -0.0113, 0.943 ),
            ctlpt( E2, -0.202, 0.954 ),
            ctlpt( E2, -0.147, 0.644 ),
            ctlpt( E2, -0.162, 0.208 ),
            ctlpt( E2, -0.337, -0.156 ) ),
      list( kv_periodic ) );
  C1 = coerce( C1, kv_open );
  Arcs = CBIARCS( Crv, 0.01, 90 );
@\end{verbatim}

 computes bi-arcs fitting to a given curve in the shape of a human hand,
 with arcs with at most 90 degrees and tolerance of 0.01.
@See Figure~\ref{fig-cbiarcs}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cbiarcs.ps, width=5in}
=    <img  hspace=2 src="user_man/cbiarcs.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Bi-arcs are fitted to the given curve in the shape of a human hand,
-      at two different tolerances, using CBIARC.
=</b><BR clear=all>
@}
@\label{fig-cbiarcs}
@\end{figure}
 See also QUADCRVS, CUBICCRVS.
$

@\subsubsection{CBISECTOR2D}
!CBISECTOR2D

@\begin{verbatim}
    CurveType  CBISECTOR2D( CurveType Crv,
                            NumericType ZeroSet,
                            NumericType BisectFunc,
                            NumericType Tolerance,
                            NumericType NumerImprove,
                            NumericType SameNormal )
 
 or
 
   CurveType   CBISECTOR2D( ListType TwoCrvs,
                            NumericType ZeroSet,
                            NumericType BisectFunc,
                            NumericType Tolerance,
                            NumericType NumerImprove,
                            NumericType SameNormal )
 
 or
 
   SurfaceType CBISECTOR2D( ListType CrvPt,
                            NumericType ZeroSet,
                            NumericType UseNrmlTan,
                            NumericType Tolerance,
                            NumericType NumerImprove,
                            NumericType SameNormal )
@\end{verbatim}

    computes the self bisector curve(s) for {\bf Crv} or the bisector(s)
 of {\bf TwoCrvs} or the bisector of a curve and a point, {\bf CrvPt}. If
 (\bf ZeroSet) is TRUE, the zero-set surface is computed and is used mainly
 for displaying the zero-set. If it is FALSE, the bisector is returned.
 The zero-set is computing using the functions F1, F2 and F3 in the paper 
 {\em Gershon Elber and Myung Soo Kim.  ``Bisector Curves of Planar Rational 
 Curves.'' CAD, Vol 30, No 14, pp 1089-1096, December 1998} which is 
 determined by the {\bf BisectFunc} parameter. If {\bf BisectFunc} = 1, then 
 F1 is used and so on.  {\bf Tolerance} controls the accuracy of the 
 computation, with 10 as a good starting value. If {\bf Tolerance} is 
 negative, {\bf NumerImprove} can be either TRUE or FALSE, allowing or 
 disabling a final numerical improvement stage.  {\bf SameNormal} can also 
 assume a TRUE or FALSE value, selecting only opposite facing normals,
 if TRUE.
   The bisector {\em curve} of a curve (E2) and a point {\bf CrvPt} is
 computed analytically.  Other parameters are ignored.
   See also CBISECTOR3D, CALPHASECTOR, SBISECTOR.

 Example:

@\begin{verbatim}
    c1 = cbezier( list( ctlpt( E2, -0.5, -0.2 ),
                        ctlpt( E2,  0.0, -0.2 ),
                        ctlpt( E2,  0.6,  0.6 ) ) );
    c2 = cbezier( list( ctlpt( E2,  0.3, -0.7 ),
                        ctlpt( E2, -0.2, -0.7 ),
                        ctlpt( E2,  0.7,  0.6 ) ) );
    BisectCrvs = CBISECTOR2D( list( c1, c2 ), FALSE, 1, 12, true, false );
    All = list( c1, c2, BisectCrvs );
    interact( list( All, view_mat2d ) );

@\end{verbatim}

 computes the bisector for planar curves as a set of bisector curves (refer
 Figure~\ref{fig-cbisector} (left).
 
@See Figure~\ref{fig-cbisector}.
$

@\subsubsection{CBISECTOR3D}
!CBISECTOR3D

@\begin{verbatim}
 SurfaceType CBISECTOR3D( ListType TwoCrvs, NumericType BisectFunc)
              
 or
 
 SurfaceType CBISECTOR3D( ListType CrvPt, NumericType BisectFunc)
@\end{verbatim}

    computes the bisector surface {\bf TwoCrvs} or the bisector surface of a 
 curve and a point, {\bf CrvPt}, in R3.  The {\bf BisectFunc} determines the
 function to be used for generating the bisector surface between the two E3
 curves.  If 1, a 3-space bisector surface is generated to the given
 curves or a curve and a point.  If 4, a surface whose zero set prescribes
 the bisectors of the given curves is returned.
   For a bisector between a curve and a point, the {\bf BisectFunc} parameter
 is ignored and a 3 space surface is always computed.
   See also CBISECTOR2D, CALPHASECTOR, SBISECTOR.

 Example:

@\begin{verbatim}
    c1 = creparam( pcircle( vector( 0.0, 0.0, 0.0 ), 1 ), 0, 1 );
    c2 = cbezier( list( ctlpt( E3, -1.0, 0.0,  1.0 ),
                        ctlpt( E3,  1.0, 0.0, -1.0 ) ) );
    c1 = coerce( c1, E3);
    BisectSrf = CBISECTOR3D( list( c1, c2 ), 1 );
    interact( list( c1, c2, BisectSrf ) );
@\end{verbatim}

 computes a bisector surface of a Z parallel line and a circle in the
 XY plane.
@See Figure~\ref{fig-cbisector}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/cbisectc.ps, width=3.5in} &
@        \epsfig{file=user_man/cbisects.ps, width=2.5in} 
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/cbisectc.gif">
=        <img hspace=2 width=250 src="user_man/cbisects.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      (left) Bisectors of two quadratic Bezier curves in the plane. (right) A
-      bisector surface of a line and a circle in three space. See
-      the CBISECTOR2D and CBISECTOR3D functions respectively.
=</b><BR clear=all>
@}
@\label{fig-cbisector}
@\end{figure}
$

@\subsubsection{CBSPLINE}
!CBSPLINE

@\begin{verbatim}
 CurveType CBSPLINE( NumericType Order, ListType CtlPtList,
                                                        ListType KnotVector )
@\end{verbatim}

   creates a B-spline curve out of the provided control point list, the
 knot vector, and the specified order. {\bf CtlPtList} is a list of control
 points, all of which must be of type (E1-E9 P1-P9, or regular PointType
 defining the curve's control polygon. The curve's point type will be of a
 space which is the union of the spaces of all points.
   The length of the {\bf KnotVector} must be equal to the number of control
 points in {\bf CtlPtList} plus the {\bf Order}. If, however, the length of
 the knot vector is equal to {\bf \#CtlPtList + Order + Order - 1}, the curve
 is assumed to be {\em periodic.}
   The knot vector list may be specified as either {\bf list( KV\_OPEN )},
 {\bf list( KV\_FLOAT )} or {\bf list( KV\_PERIODIC )} in which a uniform
 open, uniform floating or uniform periodic knot vector with the appropriate
 length is automatically constructed. 
@
@The created curve is the piecewise polynomial (or rational),
@\begin{equation}
@     C(t) = \sum_{i=0}^k P_i B_{i,\tau}(t),
@\end{equation}
@where $P_i$ are the control points {\bf CtlPtList} and k is the degree of
@the curve, which is one less than the {\bf Order} or number of points.
@$\tau$ is the knot vector of the curve.

 Example:

@\begin{verbatim}
    s45 = sin(pi / 4);
    HalfCirc = CBSPLINE( 3,
                         list( ctlpt( P3,  1.0,  1.0,  0.0, 0.0 ),
                               ctlpt( P3,  s45,  s45,  s45, 0.0 ),
                               ctlpt( P3,  1.0,  0.0,  1.0, 0.0 ),
                               ctlpt( P3,  s45, -s45,  s45, 0.0 ),
                               ctlpt( P3,  1.0, -1.0,  0.0, 0.0 ) ),
                         list( 0, 0, 0, 1, 1, 2, 2, 2 ) );
@\end{verbatim}

 constructs an arc of 180 degrees in the XZ plane as a rational quadratic
 B-spline curve.

 Example:

@\begin{verbatim}
    c = CBSPLINE( 4,
                  list( ctlpt( E2,  0.5,  0.5 ),
                        ctlpt( E2, -0.5,  0.5 ),
                        ctlpt( E2, -0.5, -0.5 ),
                        ctlpt( E2,  0.5, -0.5 ) ),
                  list( KV_PERIODIC ) );
    color( c, red );
    viewobj( c );
    
    c1 = cregion( c, 3, 4 );
    color( c1, green );
    c2 = cregion( c, 4, 5 );
    color( c2, yellow );
    c3 = cregion( c, 5, 6 );
    color( c3, cyan );
    c4 = cregion( c, 6, 7 );
    color( c3, magenta );
    viewobj( list( c1, c2, c3, c4 ) );
@\end{verbatim}

 creates a periodic curve and extracts its four polynomial domains as four
 {\em open} end B-spline curves.
@See Figure~\ref{fig-cperiodic}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cperiod.ps, width=4in}
=    <img  hspace=2 src="user_man/cperiod.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A cubic periodic curve created using KV\_PERIODIC end conditions.
=</b><BR clear=all>
@}
@\label{fig-cperiodic}
@\end{figure}

 See also CBEZIER, CPOWER and SBSPLINE.
$

@\subsubsection{CCINTER}
!CCINTER

@\begin{verbatim}
 ListType CCINTER( CurveType Crv1, CurveType Crv2, NumericType Epsilon,
                                                       NumericType SelfInter )
 
 or
 
 SurfaceType CCINTER( CurveType Crv1, CurveType Crv2, NumericType Epsilon,
                                                       NumericType SelfInter )
@\end{verbatim}

   compute the intersection point(s) of {\bf Crv1} and {\bf Crv2} in the
 $XY$ plane. Since this computation involves numeric operations, {\bf Epsilon}
 controls the accuracy of the parametric values of the result.
   It returns a list of PointTypes, each containing the parameter of {\bf Crv1}
 in the X coordinate, and the parameter of {\bf Crv2} in the Y coordinate.
   If, however, {\bf Epsilon} is negative, a scalar field surface representing
 the square of the distance function is returned instead.
   If {\bf SelfInter} is TRUE, {\bf Crv1} and {\bf Crv2} can be the same
 curve, and self intersection points are searched for instead.
 
 Example:

@\begin{verbatim}
 crv1 = cbspline( 3,
                  list( ctlpt( E2, 0, 0 ),
                        ctlpt( E2, 0, 0.5 ),
                        ctlpt( E2, 0.5, 0.7 ),
                        ctlpt( E2, 1, 1 ) ),
                  list( KV_OPEN ) );
 crv2 = cbspline( 3,
                  list( ctlpt( E2, 1, 0 ),
                        ctlpt( E2, 0.7, 0.25 ),
                        ctlpt( E2, 0.3, 0.5 ),
                        ctlpt( E2, 0, 1 ) ),
                  list( KV_OPEN ) );
 inter_pts = CCINTER( crv1, crv2, 0.0001, FALSE );
@\end{verbatim}
 
 computes the parameter values of the intersection point of {\bf crv1} and
 {\bf crv2} to a tolerance of 0.0001.
@See Figure~\ref{fig-cci}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cci.ps, width=4in}
=    <img  hspace=2 src="user_man/cci.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A intersection point of two freeform curve computed using CCINTER.
=</b><BR clear=all>
@}
@\label{fig-cci}
@\end{figure}
$

@\subsubsection{CCRVTR}
!CCRVTR

@\begin{verbatim}
 ListType CCRVTR( CurveType Crv, NumericType Epsilon, NumericType Operation )

 or

 CurveType CCRVTR( CurveType Crv, NumericType Epsilon, NumericType Operation )
@\end{verbatim}

   computes the curvature field's magnitude square of {\bf Crv} in the $XY$
 plane if {\bf Operation} is 1, or its extreme points if {\bf Operation} equals
 2. This set includes not only points of maximum (convexity) and mimumum
 (concavity) curvature, but also points of zero curvature locations, such as
 inflection points.  A list of parameter value(s) of the location(s) with 
 extreme curvature along the {\bf Crv} is returned in the latter case.
   Since this operation is partially numeric, {\bf Epsilon} is used to set
 the needed accuracy. 
   If, however, {\bf Operation} is 3, the input curve is being split at the
 extreme curvature location and a list of curve segments is returned instead.

@   This function computes the (square of the) curvature scalar field for
@ planar curves as,
@\begin{equation}
@      \kappa(t) = \frac{x'(t) y''(t) - x''(t) y'(t)}
@             {\left( (x'(t))^2 + (y'(t))^2\ \right)^{\frac{3}{2}}},
@\end{equation}
@ and computes (the square of) kN for three-dimensional curves as the
@ following vector field,
@\begin{equation}
@      \kappa(t) N(t) = \kappa(t) B(t) \times T(t) =
@       \frac{C' \times C''}{\| C' \| ^ 3} \times \frac{C'}{\| C' \|} =
@       \frac{(C' \times C'') \times C'}{\| C' \| ^ 4}.
@\end{equation}
^   This function computes the (square of the)  curvature scalar field for
^ planar curves as,
^
^          x' y'' - x'' y' 
^   k(t) = ----------------
^               2     2  3/2
^           ( x'  + y'  )
^
^ and computes (the square of) kN for three-dimensional curves as the
^ following vector field,
^
^                                  C' x C''     C'    (C' x C'') x C'
^   k(t) N(t) = K(t) B(t) x T(t) = -------- x ----- = ---------------
^                                        3    | C' |            4
^                                   | C'|                 | C' |

 The extremum values are extracted from the computed curvature field.
 This (square of the) curvature field is a high order curve, even if the
 input geometry is of low order. This is especially true for rational curves,
 for which the quotient rule for differentiation is used and almost doubles
 the degree in every differentiation.

 See also CINFLECT, CNRMLCRV, CZEROS, CEXTREMES, and SCRVTR.

 Example:
 
@\begin{verbatim}
 crv = cbezier( list( ctlpt( E2, -1.0,  0.5 ),
                      ctlpt( E2, -0.5, -2.0 ),
                      ctlpt( E2,  0.0,  1.0 ),
                      ctlpt( E2,  1.0,  0.0 ) ) ) * rotz( 30 );
 crvtr = CCRVTR( crv, 0.001, 2 );
 pt_crvtr = nil();
 pt = nil();
 for ( i = 1, 1, sizeof( crvtr ),
     ( pt = ceval( crv, nth( crvtr, i ) ) ):
     snoc( pt, pt_crvtr )
 );
 interact( list( crv, pt_crvtr ) );
@\end{verbatim}

 finds the extreme curvature points in {\bf Crv} and displays them all
 with the curve.
@See Figure~\ref{fig-ccrvtr}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/ccrvtr.ps, width=4in}
=    <img  hspace=2 src="user_man/ccrvtr.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Extreme curvature locations on a freeform curve computed using CCRVTR.
=</b><BR clear=all>
@}
@\label{fig-ccrvtr}
@\end{figure}
$

@\subsubsection{CDERIVE}
!CDERIVE

@\begin{verbatim}
 CurveType CDERIVE( CurveType Curve )
@\end{verbatim}

   returns a vector field curve representing the differentiated curve,
 also known as the Hodograph curve.

 Example:

@\begin{verbatim}
 Circ = circle( vector( 0.0, 0.0, 0.0 ), 1.0 );
 Hodograph = CDERIVE( Circ );
@\end{verbatim}
@See Figure~\ref{fig-cderive}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cderive.ps, width=4in}
=    <img  hspace=2 src="user_man/cderive.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      The Hodograph (thick) of a B-spline circle (thin) constructed as four
-      90 degrees rational Bezier arcs, computed using CDERIVE.
=</b><BR clear=all>
@}
@\label{fig-cderive}
@\end{figure}
 See also CINTEG, SDERIVE, TDERIVE, and MDERIVE
$

@\subsubsection{CDIVIDE}
!CDIVIDE

@\begin{verbatim}
 ListType CDIVIDE( CurveType Curve, NumericType Param )
@\end{verbatim}

   subdivides a curve into two sub-curves at the specified parameter value.
 {\bf Curve} can be either a B-spline curve in which {\bf Param} must be
 within the Curve's parametric domain, or a Bezier curve in which {\bf Param}
 can be arbitrary, extrapolating if not in the range of zero to one.

   It returns a list of the two sub-curves. The individual curves may be
 extracted from the list using the NTH command.

 Example:

@\begin{verbatim}
 CrvLst = CDIVIDE( Crv, 1.3 );
 Crv1 = nth( CrvLst, 1 );
 Crv2 = nth( CrvLst, 2 );
@\end{verbatim}

 subdivides the curve {\bf Crv} at the parameter value of 0.5.
@See Figure~\ref{fig-cdivide}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cdivide.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/cdivide.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A B-spline curve is subdivided into two distinct regions using CDIVIDE.
=</b><BR clear=all>
@}
@\label{fig-cdivide}
@\end{figure}
 See also SDIVIDE, TDIVIDE, and MDIVIDE
$

@\subsubsection{CEDITPT}
!CEDITPT

@\begin{verbatim}
 CurveType CEDITPT( CurveType Curve, CtlPtType CtlPt, NumericType Index )
@\end{verbatim}

   provides a simple mechanism to manually modify a single control point number
 {\bf Index} (base count is 0) in the {\bf Curve}, by substituting {\bf CtlPt}
 instead. {\bf CtlPt} must have the same point type as the control points of
 the {\bf Curve}. The original curve {\bf Curve} is not modified.

 Example:

@\begin{verbatim}
    CPt = ctlpt( E3, 1, 2, 3 );
    NewCrv = CEDITPT( Curve, CPt, 1 );
@\end{verbatim}

 constructs a {\bf NewCrv} with the second control point of {\bf Curve} being
 {\bf CPt}.
$

@\subsubsection{CENVOFF}
!CENVOFF

@\begin{verbatim}
 SurfaceType CENVOFF( CurveType Curve,
                      NumericType Height, NumericType Tolerance )
 
 or
 
 ListType CENVOFF( CurveType Curve, NumericType Height, NumericType Tolerance )
@\end{verbatim}

   computes the offset envelope of a given planar curve {\bf Curve}.  The
 offset envelope is the envelope of cones with apex on point on {\bf Curve}
 in the Z direction. {\bf Height} is the height of the cone which also
 equals the offset distance or the width of the cones.  {\bf Tolerance}
 controls the accuracy of the offset approximation.

   If the {\bf Curve} is closed, two surfaces are created in the offset envelope,
 one for the inside and another for the outside.  If {\bf Curve} is open, a single
 envelope offset surface is computed, wrapping around both sides.

 Example:


@\begin{verbatim}
    c1 = cbezier( list( ctlpt( E2, -0.8, 0.0 ),
                        ctlpt( E2, -0.2, 1.0 ),
                        ctlpt( E2,  0.2, 0.0 ),
                        ctlpt( E2,  0.8, 0.6 ) ) );
    s1 = CENVOFF( c1, 0.5, 0.01 );
@\end{verbatim}

 computes an envelope offset surface for a cubic Bezier curve {\bf c1} of
 {\bf Height} of 0.5 and {\bf Tolerance} of 0.01.
@See Figure~\ref{fig-cenvoff}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cenvoff.ps, width=4in}
=    <img  hspace=2 src="user_man/cenvoff.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     The envelope offset of a freeform planar curve computed using CENVOFF.
=</b><BR clear=all>
@}
@\label{fig-cenvoff}
@\end{figure}
$

@\subsubsection{CEVAL}
!CEVAL

@\begin{verbatim}
 CtlPtType CEVAL( CurveType Curve, NumericType Param )
@\end{verbatim}

   evaluates the provided {\bf Curve} at the given {\bf Param} value.
 {\bf Param} should be in the curve's parametric domain if the {\bf Curve} is
 a B-spline curve, or between zero and one if the {\bf Curve} is a Bezier curve.
 The returned control point has the same point type as the control points
 of the {\bf Curve}.

 Example:

@\begin{verbatim}
    CPt = CEVAL( Crv, 0.25 );
@\end{verbatim}

 evaluates {\bf Crv} at the parameter value of 0.25.
 See also SEVAL, MEVAL, TEVAL.
$

@\subsubsection{CEXTREMES}
!CEXTREMES

@\begin{verbatim}
 ListType CEXTREMES( CurveType Crv, NumericType Epsilon, NumericType Axis )
@\end{verbatim}
 
   computes the extreme set of the given {\bf Crv} in the given axis (1 for X,
 2 for Y, 3 for Z). Since this computation is numeric, an {\bf Epsilon} is
 also required to specify the desired tolerance. It returns a list of
 all the parameter values (NumericType) in which the curve takes an extreme
 value.

 Example:
 
@\begin{verbatim}
    extremes = CEXTREMES( Crv, 0.0001, 1 );
@\end{verbatim}

 computes the extreme set of curve {\bf crv}, in the {\bf X} axis, with
 error tolerance of {\bf 0.0001}. See also CZERO.
@See Figure~\ref{fig-cextreme}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cextreme.ps, width=4in}
=    <img  hspace=2 src="user_man/cextreme.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     The X local extremums of a freeform curve are isolated using CEXTREMES.
=</b><BR clear=all>
@}
@\label{fig-cextreme}
@\end{figure}
$


@\subsubsection{CFNCRVTR}
!CFNCRVTR

@\begin{verbatim}
 CurveType CFNCRVTR( CurveType E2Crv, NumericType Samples,
                     NumericType Order, NumericType ArcLen )
 
 or
 
 CurveType CFNCRVTR( CurveType CrvtrE1Crv, NumericType Accuracy,
                     NumericType Order, NumericType Periodic )
@\end{verbatim}
 
    computes the curvature field of planar curve {\bf E2Crv} in the first form,
 and reconstructs an E2 planar curve from the given curvature field
 {\bf CrvtrE1Crv} in the second form.
    In the first form, {\bf Samples} defines the numer of samples to use along
 the input curve while if {\bf ArcLen} TRUE the samples are also made along the
 arc length of {\bf E2Crv}.
   In the second form, a planar curve is reconstructed from the curvature field
 of {\bf CrvtrE1Crv}, with {\bf Accuracy} to control the accuracy.  If the
 reconstructed curve is suppose to be closed, set {\bf Periodic} to TRUE.
   In both forms, {\bf Order} sets the order of the return curve.

 Example:
 
@\begin{verbatim}
    CrvtrField = CFNCRVTR( Crv, 1000, 2, TRUE );
@\end{verbatim}
$

@\subsubsection{CIEXTREME}
!CIEXTREME

@\begin{verbatim}
 ListType CIEXTREME( SurfaceType Srf, NumericType Dir,
                     NumericType SubdivTol, NumericType NumerTol )
@\end{verbatim}

   computes the X- or Y-extreme values of the implicit univariate defined as
 the zero set of {\bf Srf}.  In addition, this function also detects 
 hyperbolic tangent contact of {\bf Srf} with the plane $Z = 0$. {\bf Dir}
 specified the desired direction of the extremum to extract, one of COL or
 ROW.
   See MZERO for the meaning of the {\bf SubdivTol} and {\bf NumerTol}.

 Example:

@\begin{verbatim}
    ViewMap = CIEXTREME( Srf, col, 0.01, 1e-9 );
@\end{verbatim}

@See Figure~\ref{fig-ciextreme}.
=See figure for an example.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/ciextreme.ps, width=5in} 
=  <BR clear=all>
=    <img  hspace=2 src="user_man/ciextreme.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      An example of computing the X- and Y-extreme locations of this implicit
-      curve defined as the zero set of the surface.  Also detected surface 
-      tangency contacts with the plane Z = 0.
=</b><BR clear=all>
@}
@\label{fig-ciextreme}
@\end{figure} 
$

@\subsubsection{CINFLECT}
!CINFLECT

@\begin{verbatim}
 ListType CINFLECT( CurveType Crv, NumericType Epsilon, NumericType Operation )

 or

 CurveType CINFLECT( CurveType Crv, NumericType Epsilon,
                     NumericType Operation )
@\end{verbatim}
 
   computes and returns a scalar field (the numerator of the curvature field,
 the sign of the curvature field if you like) whose zeros are the inflection
 points of {\bf Crv} in the $XY$ plane, if {\bf Operation} is 1.
   If {\bf Operation} is 2, the inflection points are derived and returned as
 list of all the parameter values (NumericType) in which the curve has an
 inflection point.
   Since this computation is partially numeric, an {\bf Epsilon} is also
 required to specify the desired tolerance.
   If, however, {\bf Operation} is 3, the input curve {\bf Crv} is being split
 at all the inflection points and the different, inflection free,  curve
 segements are returned in a list.

@ The sign of curvature scalar field is equal to,
@\begin{equation}
@      \sigma(t) = x'(t) y''(t) - x''(t) y'(t).
@\end{equation}
^ The sign of curvature scalar field is equal to
^
^       s(t) = x' y'' - x'' y' 
^
 Example:
 
@\begin{verbatim}
    inflect = CINFLECT( crv, 0.001, 2 );
    pt_inflect = nil();
    pt = nil();
    for ( i = 1, 1, sizeof( inflect ),
            pt = ceval( crv, nth( inflect, i ) ):
            snoc( pt, pt_inflect )
        );
    interact( list( axes, crv, pt_inflect ) );
@\end{verbatim}

 computes the set of inflection points of curve {\bf crv} with error
 tolerance of {\bf 0.001}. This set is then scanned in a loop and
 evaluated to the curve's locations which are then displayed with the {\bf crv}.
 See also CZEROS, CEXTREMES, and CCRVTR.
@See Figure~\ref{fig-cinflect}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cinflect.ps, width=4in}
=    <img  hspace=2 src="user_man/cinflect.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    The Inflection points of a freeform curve can be isolated using CINFLECT.
=</b><BR clear=all>
@}
@\label{fig-cinflect}
@\end{figure}
$

@\subsubsection{CINTEG}
!CINTEG

@\begin{verbatim}
 CurveType CINTEG( CurveType Crv );
@\end{verbatim}

   returns a vector field curve representing the integral curve.
   See also CDERIVE.
$

@\subsubsection{CINTERP}
!CINTERP

@\begin{verbatim}
 CurveType CINTERP( ListType PtList, NumericType Order, NumericType Size,
                                     ConstantType Param, NumericType Periodic)

 or
 
 CurveType CINTERP( CurveType Crv, NumericType Order, NumericType Size,
                                     ConstantType Param, NumericType Periodic)

 or
 
 CurveType CINTERP( ListType PtList, NumericType Order, NumericType Size,
                                        ListType Params, NumericType Periodic)

 or
 
 CurveType CINTERP( CurveType Crv, NumericType Order, NumericType Size,
                                        ListType Params, NumericType Periodic)
@\end{verbatim}
 
   compute a B-spline curve that interpolates or approximates
 the list of points in {\bf PtList} or a given curve {\bf Crv}. The
 B-spline curve will have order {\bf Order} and {\bf Size} control points,
 and will be periodic if {\bf periodic} is non zero.  The knots will be
 spaced according to {\bf Param} which can be one of PARAM\_UNIFORM,
 PARAM\_CHORD, PARAM\_CENTRIP or PARAM\_NEILFOL or lists of parameter
 values and knots (see below).  The PARAM\_UNIFORM prescribes a uniform
 knot sequence, PARAM\_CHORD specifies knot spacing according to the chord
 length and PARAM\_CENTRIP according to the square root of the chord length.
 Finally, PARAM\_NEILFOL takes into consideration the angles between three
 consecutive points.
   A periodic curve will be coerced to have a PARAM\_UNIFORM knot sequence.
   If {\bf Params} is a list object, it should contain two lists of
 numerical values.  The first list contains the parameter values at which
 to approximate or interpolate the data points. Hence, the length of this 
 list must equal the length of the {\bf PtList} data.  The second list
 specifies the knot vector of the construct B-spline curve.
   Use of {\bf Periodic} end conditions can create cases with degenerated
 linear systems (determinant equal zero).  Increase or decrease of the
 {\bf Order} of the B-spline by one will resolve the problem.
   All points in {\bf PtList} must be of type (E1-E9, P1-P9) control point,
 or regular PointType. If {\bf Size} is equal to the number of points in
 {\bf PtList}, the resulting curve will {\em interpolate} the data set.
 Otherwise, if {\bf Size} is less than the number of points in {\bf PtList},
 the point data set will be least square approximated. At no time can
 {\bf Size} be lower than {\bf Order}. {\bf Size} of zero forces
 interpolation by selecting {\bf Size} to be the size of the data set.
   All interior knots will be distinct, preserving maximal continuity.
 The resulting B-spline curve will have open end conditions.

 Example:
 
@\begin{verbatim}
    pl = nil();
    for ( x = 0, 1, 100,
          snoc(point(cos(x / 5), sin(x / 5), x / 50 - 1), pl)
    );
    c = CINTERP( pl, 3, 21, PARAM_UNIFORM, false );
@\end{verbatim}

 samples a helical curve at 100 points and least square fit of a quadratic
 B-spline curve with 21 points to the data set. The curve will have a uniform
 knot spacing and is not periodic.  See also SINTERP, TINTERP and LINTERP.
@See Figure~\ref{fig-cinterp}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cinterp.ps, width=4in}
=    <img  hspace=2 src="user_man/cinterp.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A Helix, sampled at 100 locations, is least square fitted using
-      CINTERP by a quadratic B-spline curve and 21 control points.
=</b><BR clear=all>
@}
@\label{fig-cinterp}
@\end{figure}
$

@\subsubsection{CIRCLE}
!CIRCLE

@\begin{verbatim}
 CurveType CIRCLE( VectorType Center, NumericType Radius )
@\end{verbatim}

   constructs a circle at the specified {\bf Center} with the specified
 {\bf Radius}. The returned circle is a B-spline curve of four piecewise Bezier
 90 degree arcs. The construced circle is always parallel to the $XY$ plane.
 Use the linear transformation routines to place the circle in the appropriate
 orientation and location.
$

@\subsubsection{CIRCPOLY}
!CIRCPOLY

@\begin{verbatim}
 PolygonType CIRCPOLY( VectorType Normal, VectorType Trans, NumericType Radius )
@\end{verbatim}

   defines a circular polygon in a plane perpendicular to {\bf Normal} that
 contains the {\bf Trans} point. The constructed polygon is centered at
 {\bf Trans}. RESOLUTION vertices will be defined with {\bf Radius} from
 distance from {\bf Trans}.

   Alternative ways to construct a polygon are manual construction of the
 vertices using POLY, or the construction of a flat ruled surface using
 RULEDSRF.
$

@\subsubsection{CLNTCRSR}
!CLNTCRSR

@\begin{verbatim}
 ListType CLNTCRSR( NumericType TimeOut )
@\end{verbatim}

   reads the mouse coordinates as well as mouse events from displace devices,
 or times out after TimeOut miliseconds. A list object 
 of two sub-objects, a points and a vector, named "\_PickCrsr\_" is returned.
  These point and vector define the three-dimensional line of the mouse in
 object space. 

   Mouse events are typically processed by the display device.  However, by
 the command "CLNTPICKCRSR" (in {\bf iritinit.irt}) which sends a "PICKCRSR"
 request to the display devices, mouse events will be sent to the server.
 The server can be requested to keep mouse events for "CLNTCRSR" to be read
 via the IritState command and the "CursorKeep" attribute.
 
   Both the point and the vector will have a numeric attribute of "EventType"
 that will have the following meaning:

# 3 2 0 1
 1
  Mouse motion event
 2
  Mouse down event
 5
  Mouse up event
#

   In case of a time out the returned list object will be empty and will
 have the name "\_PickFail\_".

 Example:

@\begin{verbatim}
   ClntPickCrsr( clients_all );

   IritState( "CursorKeep", 1 );

   Quit = 0;
   for ( i = 0, 1, 10,
       CLNTCRSR( 10000 ) );

   ClntPickDone( clients_all );
   IritState( "CursorKeep", 0 );
@\end{verbatim}

 asks all clients to send mouse events to the server, asks the server to keep
 mouse events, and then reads 10 mouse events.
$

@\subsubsection{CLNTREAD}
!CLNTREAD

@\begin{verbatim}
 AnyType CLNTREAD( NumericType Handler, NumericType Block )
@\end{verbatim}

   reads one object from a client communication channel.
 {\bf Handler} contains the index of the communication channel opened via
 CLNTEXEC. If no data is available in the communication channel, this
 function will block for at most {\bf Block} milliseconds until data is found
 or timeout occurs. In the latter, a single StringType object is returned
 with the content of "no data (timeout)".  If {\bf Handler} equals -1, the
 regular display device (forked via, for example, VIEWOBJ command) is used.
 See also VIEWSET, CLNTWRITE, CLNTCLOSE, and CLNTEXEC.
 
 Example:

@\begin{verbatim}
   h2 = clntexec( "xmtdrvs -s-" );
       .
       .

   Model = CLNTREAD( h2 );
       .
       .

   clntclose( h2,TRUE );
@\end{verbatim}

 reads one object from client through communication channel h2 and saves it
 in variable model.
$

@\subsubsection{CMESH}
!CMESH

@\begin{verbatim}
 CurveType CMESH( SurfaceType Srf, ConstantType Direction, NumericType Index )
@\end{verbatim}

   returns a single ROW or COLumn as specified by the {\bf Direction} and
 {\bf Index} (base count is 0) of the control mesh of surface {\bf Srf}.

   The returned curve will have the same knot vector as {\bf Srf} in the
 appropriate direction. See also CSURFACE.

   This curve is {\em not} necessarily in the surface {\bf Srf}.
@It is equal to,
@\begin{equation}
@     C(t) = \sum_{i=0}^m P_{ij} B_i(t),
@\end{equation}
@and similar for the other parametric direction.

 Example:

@\begin{verbatim}
    Crv = CMESH( Srf, COL, 0 );
@\end{verbatim}

 extracts the first column of surface {\bf Srf} as a curve. See also
 CSURFACE.  See also SMESH, MFROMMESH.
$

@\subsubsection{CMOEBIUS}
!CMOEBIUS

@\begin{verbatim}
 CurveType CMOEBIUS( CurveType Crv, NumericType Ratio )
@\end{verbatim}

   rebalances the weights of a rational curve using the Moebius transformation.
 The shape of the curve remains identical while the speed is modified.
 {\bf Ratio} controls the ratio between the last and the first weights. If
 {\bf Ratio} = 0, the first and last weights are made equal.

 See also SMOEBIUS.
$

@\subsubsection{CMORPH}
!CMORPH

@\begin{verbatim}
 CurveType CMORPH( CurveType Crv1, CurveType Crv2,
                   NumericType Method, NumericType Blend )
 
 or
 
 ListType CMORPH( CurveType Crv1, CurveType Crv2,
                  NumericType Method, NumericType Blend )
@\end{verbatim}

 create a new curve which is a {\em metamorph} of the two given curves.
 The two given curves must be compatible (see FFCOMPAT) before this blend
 is invoked. This is very useful if a sequence that "morphs" one curve to
 another is to be created. Several metamorphosis methods are supported
 according to the value of {\bf Method},

# 3 2 0 1
 0
  Simple convex blend.
 1
  Corner/Edge cutting scheme, scaled to same curve length.
 2 
  Corner/Edge cutting scheme, scaled to same bounding box.
 3
  Same as 1 but with filtering out of tangencies.
 4
  Same as 2 but with filtering out of tangencies.
 5
  Multiresolution decomposition based metamorphosis. See CMULTRES.
#

   In {\bf Method} 1, {\bf Blend} is a number between zero ({\bf Crv1})
 and one ({\bf Crv2}) defining the similarity to {\bf Crv1} and {\bf Crv2},
 respectively. A single curve is returned.

   In {\bf Method}s 2 to 5, {\bf Blend} is a step size for the
 metamorphosis operation and a whole list describing the entire
 metamorphosis operation is returned.

 Examples:

@\begin{verbatim}
    for ( i = 0, 1, 300,
        c = CMORPH( crv1a, crv1b, 0, i / 300.0 ):
        color( c, yellow ):
        viewobj( c )
    );
   
    crvs = CMORPH( crv1a, crv1b, 2, 0.003 );
    snoc( crv1b, crvs );
    for ( i = 1, 1, sizeof( crvs ),
        c = nth( crvs, i ):
        color( c, yellow ):
        viewobj( c )
    );

    Turtle2 = ffmatch( Wolf, Turtle, 20, 100, 2, false, 2 );
    ffcompat( Wolf, Turtle2 );
    for ( i = 0, 1, 25,
        c = CMORPH( Wolf, Turtle2, 0, i / 25 ):
        color( c, yellow ):
        viewobj( c )
    );
@\end{verbatim}

 creates three metamorphosis animation sequences, one that is based on
 a convex blend, and two that are based on corner/edge cutting schemes.
 See also PMORPH, SMORPH, TMORPH, and FFMATCH.
@See Figure~\ref{fig-cmorph}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/cmorph.ps, width=5in} \\
@    \epsfig{file=user_man/cmorph2.ps, width=5in} 
=    <BR clear=all>
=    <img hspace=2 src="user_man/cmorph.gif">
=    <img hspace=2 src="user_man/cmorph2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A morphing sequence using convex blend (top left), edge cutting
-      (top right), and using FFMATCH and convex blend (bottom).
=</b><BR clear=all>
@}
@\label{fig-cmorph}
@\end{figure}
$

@\subsubsection{CMULTIRES}
!CMULTIRES

@\begin{verbatim}
 ListType CMULTIRES( CurveType Crv, NumericType Discont,
                                                NumericType LeastSquares )
@\end{verbatim}

   computes a multiresolution decomposition of curve {\bf Crv} using least
 squares approximation, if {\bf LeastSquares} is TRUE, or using B-Wavelets
 if {\bf LeastSquares} is FALSE.  The latter is optimal but slower.
   The resulting list of curves describes an hierarchy of curves in linear
 subspaces of the space in which {\bf Crv} lay.
   If {\bf LeastSquares} is TRUE, the curves could be summed algebraically to
 form {\bf Crv}.  Each of the curves in the hierarchy is a least squares
 approximation of {\bf Crv} in the subspace in which it is defined.
   If {\bf LeastSquares} is FALSE, a list of orthogonal
 projections of the {\bf Crv} onto the prescibed subspaces (by the knot
 sequences) is provided.
   Finally, {\bf Discont} is a Boolean flag that controls the way tangent
 discontinuities are computed throughout the decomposition.

 Example:

@\begin{verbatim}
    MRCrv = CMULTIRES( Animal, false, true );

    sum = nth( MRCrv, 1 );
    MRCrvs = list( sum * tx( 3.0 ) );
    for ( ( i = 2 ), 1, sizeof( MRCrv ),
        sum = symbsum( sum, nth( MRCrv, i ) ):
        snoc( sum * tx( ( 3 - i ) * 1.5 ), MRCrvs )
    );

    All = MRCrvs * sc ( 0.25 );
    view( All, on );
@\end{verbatim}

 computes a multiresolution decomposition to curve {\bf CrossSec} as
 {\bf MRCrv} and displays all the decomposition levels by summing them all
 up. The use of {\bf none} as on object name allows one to display an
 object in the display device without replacing the previous object in the
 display device, carrying the same name.

 This creates two metamorphosis animation sequences, one based on
 a convex blend and one based on a corner/edge cutting scheme.
@See Figure~\ref{fig-cmultres}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cmultres.ps,height=0.8in}
=    <img  hspace=2 src="user_man/cmultres.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A multiresolution decomposition of a curve of an animal using
-      least squares. The original curve is shown on the left.
=</b><BR clear=all>
@}
@\label{fig-cmultres}
@\end{figure}
$

@\subsubsection{CNORMAL}
!CNORMAL

@\begin{verbatim}
 VectorType CNORMAL( CurveType Crv, NumericType TParam )
@\end{verbatim}

   computes the normal vector to curve {\bf Crv} at the
 parameter values {\bf TParam}. The returned vector has a
 unit length.

 Example:

@\begin{verbatim}
    Normal = CNORMAL( Crv, 0.5 );
@\end{verbatim}

 computes the normal to {\bf Crv} at the parameter value 0.5.
 See also CNRMLCRV, CTANGENT.
$

@\subsubsection{CNRMLCRV}
!CNRMLCRV

@\begin{verbatim}
 CurveType CNRMLCRV( CurveType Crv )
@\end{verbatim}

 symbolically computes a vector field curve representing the non-normalized
 normals of the given curve. That is, a normal vector field, evaluated at
 $t$, provides a vector in the direction of the normal of the original
 curve at $t$. The normal curve once computed is in fact equal to $kN$ where
 $k$ is the curvature of {\bf Crv} and $N$ is its normal.

 Example:

@\begin{verbatim}
 NrmlCrv = CNRMLCRV( Crv );
@\end{verbatim}

 See also CCRVTR.
$

@\subsubsection{CNVXHULL}
!CNVXHULL

@\begin{verbatim}
 PolygonType CNVXHULL( PolygonType Poly | PolylineType Poly,
                       NumericType FineNess );

 or

 CurveType CNVXHULL( CurveType Crv, NumericType FineNess );
@\end{verbatim}

 compute the convex hull of the given set of {\bf Poly} or {\bf Curve}
 with tolerance for curves only, which is governed by the polygon subdivision
 accuracy as set via {\bf FineNess}.  {\bf FineNess} is ignored for polylines.
 For curves, the result might be partial if the curve is not closed or
 periodic.  See also CRV2TANS and CRVPTTAN.

 Example:

@\begin{verbatim}
    Pts1 = nil();
    Pts2 = nil();
    for ( i = 0, 1, 7,
        R = 0.2 + fmod( i, 2 ) / 2:
        Pt = ctlpt( E2, R * cos( i * 2 * pi / 8 ), R * sin( i * 2 * pi / 8 ) ):
        snoc( Pt, Pts1 ):
        snoc( coerce( Pt, point_type ),  Pts2 ) );
    Crv = coerce( cbspline( 4, Pts1, list( KV_PERIODIC ) ), KV_OPEN );
    CHPts = CNVXHULL( poly( Pts2, 0 ), 0 );
    CHCrv = CNVXHULL( Crv, 10 );
@\end{verbatim}

 computes the convex hull of a given control polygon and freeform curve.
@See Figure~\ref{fig-cnvxhull}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cnvxhull.ps, width=4.5in}
=    <img  hspace=2 src="user_man/cnvxhull.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       A convex hull of a set of points and of a freeform B-spline curve.
-       The left show a convex hull of a set of points. The right shows the
-       convex hull (thick line) of a freeform curve.
=</b><BR clear=all>
@}
@\label{fig-cnvxhull}
@\end{figure}
$

@\subsubsection{COERCE}
!COERCE

@\begin{verbatim}
 AnyType COERCE( AnyType Object, ConstantType NewType )
@\end{verbatim}

   provides a coercion mechanism between different objects or object types.
 PointType, VectorType, PlaneType, and CtlPtType can be all coerced to each
 other by using the {\bf NewType} of POINT\_TYPE, VECTOR\_TYPE, PLANE\_TYPE,
 or one of E1-E9, P1-P9 (CtlPtType). Similarly, CurveType, SurfaceType,
 TrimSrfType, TriSrfType, TrivarType, and MultivarType can all be coerced to
 hold different CtlPtType control points, or even different open end
 conditions from KV\_PERIODIC to KV\_FLOAT to KV\_OPEN.  Freefroms can be
 coerced to a Power, Bezier or a B-spline type via the {\bf NewType} of
 POWER\_TYPE, BEZIER\_TYPE or the BSPLINE\_TYPE.
   If a scalar (E1 or P1) curve is coerced to E2 or P2 curve or
 a scalar (E1 or P1), the surface is coerced to an E3 or P3 surface, and the
 Y (YZ) coordinate(s) is (are) updated to hold the parametric domain of the
 curve (surface).  That is X = U (Y = V).
   Curves, Surfaces, and Trivariates can be coerced to/from Multivariates
 using the CURVE\_TYPE, SURFACE\_TYPE, TRIVAR\_TYPE and MULTIVAR\_TYPE.

 Example:
 
@\begin{verbatim}
    CrvE2 = COERCE( Crv, E2 );
    MultiVar == COERCE( COERCE( MultiVar, surface_type ), multivar_type );
    BzrSrfs = COERCE( BspSrf, bezier_type );
@\end{verbatim}

 coerces {\bf Crv} to a new curve that will have an E2 CtlPtType control
 points. Coerction of a projective curve (P1-P9) to a Euclidean curve
 (E1-E9) does not preseve the shape of the curve.  The second example
 coerces a bivariate {\bf MultiVar} into a {\bf Srf} and back and compares
 the result to the original multivariate {\bf MultiVar}...  The third
 example coerces a B-spline surface {\bf BspSrf} to a Bezier form, returning
 one or more Bezier surfaces representing the same geometry as {\bf BspSrf}.
$

@\subsubsection{COMPOSE}
!COMPOSE

@\begin{verbatim}
 CurveType COMPOSE( CurveType Crv1, CurveType Crv2 )

 or

 CurveType COMPOSE( SurfaceType Srf, CurveType Crv )
@\end{verbatim}

   symbolically compute the composition curve {\bf Crv1(Crv2(t))} or
 {\bf Srf(Crv(t))}. In the above first form of {\bf Crv1(Crv2(t)}, {\bf Crv1}
 can be any curve while {\bf Crv2} is assumed to be a one-dimensional curve
 that is either E1 or P1 (higher dimensions are ignored).
   In the above second form of {\bf Srf(Crv(t))}, the {\bf Srf} can be any surface,
 while the {\bf Crv} is assumed to be a two-dimensional curve, that is either E2
 or P2 (higher dimensions are ignored). Both {\bf Crv2} in the curve's composition,
 and {\bf Crv} is the surface's composition must be contained in the curve or
 surface parametric domain.

 Example:

@\begin{verbatim}
   srf = sbezier( list( list( ctlpt( E3, 0.0, 0.0, 0.0 ),
                              ctlpt( E3, 0.0, 0.5, 1.0 ),
                              ctlpt( E3, 0.0, 1.0, 0.0 ) ),
                        list( ctlpt( E3, 0.5, 0.0, 1.0 ),
                              ctlpt( E3, 0.5, 0.5, 0.0 ),
                              ctlpt( E3, 0.5, 1.0, 1.0 ) ),
                        list( ctlpt( E3, 1.0, 0.0, 1.0 ),
                              ctlpt( E3, 1.0, 0.5, 0.0 ),
                              ctlpt( E3, 1.0, 1.0, 1.0 ) ) ) );
   crv = circle( vector( 0.5, 0.5, 0.0 ), 0.4 );
   comp_crv = COMPOSE( srf, crv );
@\end{verbatim}

 composes a circle {\bf Crv} to be on the surface {\bf Srf}.
@See Figure~\ref{fig-compose}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/compose.ps, width=4in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/compose.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A circle in the parametric space of the freefrom surface is composed
-      to create a closed loop curve on the surface using COMPOSE.
=</b><BR clear=all>
@}
@\label{fig-compose}
@\end{figure}
$

@\subsubsection{CON2}
!CON2

@\begin{verbatim}
 PolygonType CON2( VectorType Center, VectorType Direction,
                   NumericType Radius1, NumericType Radius2,
                   NumericType Caps )
@\end{verbatim}

   creates a truncated CONE geometric object, defined by {\bf Center} as the
 center of the main base of the CONE, with the {\bf Direction} as both the CONE's
 axis and the length of CONE, and the two radii {\bf Radius1/2} of the two bases
 of the CONE. If {\bf Caps} equals zero, no caps are created.  If {\bf Caps} equal
 one (two), only the bottom (top) cap is created.  If {\bf Caps} equal three,
 both the top and the bottom caps are created.

   Unlike the regular cone (CONE) constructor which inherits
 discontinuities in its generated normals at the apex, CON2 can be used to
 form a (truncated) cone with continuous normals. 
   See RESOLUTION for the accuracy of the CON2 approximation as a polygonal
 model. See also CONE. See IRITSTATE's "PrimRatSrfs" and "PrimRatSrfs"
 state variables.

 Example:

@\begin{verbatim}
    Cone2 = CON2( vector( 0, 0, -1 ), vector( 0, 0, 4 ), 2, 1, 3 );
@\end{verbatim}

 constructs a truncated cone with bases parallel to the $XY$ plane at
 $Z = -1$ and $Z = 3$, and with radii of 2 and 1 respectively. Both
 caps are created.
@See Figure~\ref{fig-cones}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cones.ps, width=4in}
=    <img  hspace=2 src="user_man/cones.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A cone (left) can be constructed using the CONE constructor and
-      a truncated cone (right) using the constructor CONE2.
=</b><BR clear=all>
@}
@\label{fig-cones}
@\end{figure}
$

@\subsubsection{CONE}
!CONE

@\begin{verbatim}
 PolygonType CONE( VectorType Center, VectorType Direction,
                   NumericType Radius, NumericType Caps )
@\end{verbatim}

   creates a CONE geometric object, defined by {\bf Center} as the center of
 the base of the CONE, {\bf Direction} as the CONE's axis and height, and
 {\bf Radius} as the radius of the base of the CONE.  If {\bf Caps} equals
 zero, no cap is created.  If {\bf Caps} equal one, the bottom
 (top) cap is created.
   See RESOLUTION for accuracy of the CONE approximation as a polygonal model. 

 Example:

@\begin{verbatim}
    Cone1 = CONE( vector( 0, 0, 0 ), vector( 1, 1, 1 ), 1, 1 );
@\end{verbatim}

 constructs a cone based in an $XY$ parallel plane, centered at the origin
 with radius 1 and with tilted apex at ( 1, 1, 1 ).  Only the bottom cap is
 created.

   See IRITSTATE's "PrimRatSrfs" and "PrimRatSrfs" state variables.
   See also CON2.
@See Figure~\ref{fig-cones}.
$

@\subsubsection{CONICSEC}
!CONICSEC

@\begin{verbatim}
 CurveType CONICSEC( ListType ABCDEF,
                     NumericType ZLevel,
                     PointType StartPoint,
                     PointType EndPoint )

 or 

 {PolygonType | SurfaceType } CONICSEC( ListType TwoCurves,
                                        NumericType ZLevel,
                                        NumericType Dist,
                                        NumericType EvalCurve )
@\end{verbatim}

   In the first form, this will construct a quadratic form that represents the
 planar conic section prescribed by the list of six coefficients {\bf ABCDEF} as:
^     A x^2 + B xy + C y^2 + D x + E y + F = 0,
@\begin{equation}
@     A x^2 + B xy + C y^2 + D x + E y + F = 0,
@\end{equation}
   The conic will be parallel to the XY plane at Z level of {\bf Zlevel}.
   The section of the curve will be from {\bf StartPoint} to {\bf EndPoint},
 or alternatively, unlimited by specifying 'off' for {\bf StartPoint} and
 {\bf EndPoint}.  The conic might be rational (for circles and ellipses, for
 example) or intergral (for parabolas).

   Alternatively, in the second form, if the first list object
 parameter contains two planar curves in the XY plane, a piecewise linear
 curve at Z level of {\bf Zlevel} is computed that presents the
 elliptic/hyperbolic distance {\bf Dist} from the given two curves.
   The elliptic distance refers to the sum of distance (that equal
 {\bf Dist}) to the two curves, while hyperbolic distance refers
 to the difference of distances.  Finally, if {\bf EvalCurve} = 0, the
 surface whose zero set is the desired curve, is returned instead. If
 {\bf EvalCurve} = 1, distance curves are returned in the parametric
 space as correspondence between the two curves' parameters. If
 {\bf EvalCurve} = 2, the conic curves themselves are returned.
   Note only elliptic surfaces are compact and are reconstructed in whole.

 Example:

@\begin{verbatim}
    Circ2 = CONICSEC( list( 1, 0, 1, 0, -0.5, -1 ), 0.0,
                      point(  1.0, 0.0, 0.0 ) * ty( 0.25 ),
                      point( -0.707, -0.707, 0.0 ) * ty( 0.25 ) );
    Elp1 = CONICSEC( list( 1, 2, 4, 0.5, 2, -0.2 ), 0.0, off, off );
    Prb1 = CONICSEC( list( 0.1, 0, 0, 0, 1, -1 ), 2, off, off ) * sc( 0.1 );
@\end{verbatim}

 constructs a (portion of a) circle, an ellipse and a parabola as conic
 sections, and,

@\begin{verbatim}
    c1 = cbspline( 3,
                   list( ctlpt( E2, -1, -1 ),
                         ctlpt( E2,  1, -1 ),
                         ctlpt( E2,  1,  1 ),
                         ctlpt( E2, -1,  1 ) ),
                   list( KV_OPEN ) );
    c2 = -c1 * sx( -1 ) * tx( 5 );
    view( list( c1, c2 ), 1 );
    
    resolution = 15;
    
    DistCrvE = list( CONICSEC( list( c1, c2 ), 1.0, 10, 2 ),
                     CONICSEC( list( c1, c2 ), 1.0,  9, 2 ),
                     CONICSEC( list( c1, c2 ), 1.0,  8, 2 ),
                     CONICSEC( list( c1, c2 ), 1.0,  7, 2 ),
                     CONICSEC( list( c1, c2 ), 1.0,  6, 2 ) );
    color( DistCrvE, green );
@\end{verbatim}

 computes the conic distance to the two curves {\bf c1} and {\bf c2} at distances
 of 6, 7, 8, 9, and 10.

 See also QUADRIC.
$

@\subsubsection{CONTOUR}
!CONTOUR

@\begin{verbatim}
 PolygonType CONTOUR( SurfaceType ContouredSrf, PlaneType ContourPlane )

 or

 PolygonType CONTOUR( SurfaceType ContouredSrf, PlaneType ContourPlane,
                      SurfaceType MappedSrf )

 or

 PolygonType CONTOUR( SurfaceType ContouredSrf, PlaneType ContourPlane,
                      SurfaceType MappedSrf, ListType ValidatePt )
@\end{verbatim}

   contours surface {\bf ContouredSrf} by intersecting plane {\bf ContourPlane}
 with a polygonal approximating {\bf ContouredSrf} with resolution set
 via variable RESOLUTION (10 is a good starting resolution value, 20 is
 extreme).
   If {\bf ContouredSrf} is a scalar field surface of type E1 or P1 and
 {\bf MappedSrf} is provided, {\bf ContouredSrf} is contoured above its
 parametric domain (U is X, V is Y) and the resulting parametric curve
 is composed with {\bf MappedSrf} to yield the returned value.
   Further, if {\bf ValidatePt} is prescribed, it should contain two elements,
 a vector, V, and an angle, A, in degrees.  Only the contour points for which
 the normal of surface {\bf MappedSrf} there has less than A degrees from V
 are returned.

 Example:

@\begin{verbatim}
 resolution = 20;
 nglass = snrmlsrf( glass ) * vector( 1, 1, 1 );

 sils = contour( nglass, plane( 1, 0, 0, 0 ), glass );
 color( sils, cyan );
 attrib( sils, "dwidth", 4 );

 view( list( axes, glass, sils ), on );
@\end{verbatim}

 computes the normal field of the surface {\bf glass}, projects it onto
 the viewing direction of (1, 1, 1) and contours the resulting scalar field
 with the plane X = 0, to extract the silhouette curves from viewing direction
 (1, 1, 1).
@See Figure~\ref{fig-silhouettes}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/silhouet.ps, width=5in} \\
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/silhouet.gif">
=  <BR clear=all> 
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computes the silhouette of a freeform glass surface from viewing
-      direction (1, 1, 1). On the left, the original view is seen. On the
-      right, a different, general, view is provided.
=</b><BR clear=all>
@}
@\label{fig-silhouettes}
@\end{figure}
$

@\subsubsection{CONVEX}
!CONVEX

@\begin{verbatim}
 PolygonType CONVEX( PolygonType Object )

 or

 ListType CONVEX( ListType Object )
@\end{verbatim}

   convert non-convex polygons in {\bf Object}, into convex ones. New vertices
 are introduced into the polygonal data during this process. The Boolean
 operations require the input to have convex polygons only (although it may
 return non convex polygons...) and it automatically converts non-convex input
 polygons into convex ones, using this same routine.

   However, some external tools (such as irit2ray and poly3d-h) require convex
 polygons. This function must be used on the objects to guarantee that
 only convex polygons are saved into data files for these external tools.

 Example:

@\begin{verbatim}
    CnvxObj = CONVEX( Obj );
    save( "data", CnvxObj );
@\end{verbatim}

 converts non-convex polygons into convex ones, so that the data file can be
 used by external tools requiring convex polygons.
$

@\subsubsection{COORD}
!COORD

@\begin{verbatim}
 AnyType COORD( AnyType Object, NumericType Index )
@\end{verbatim}

   extracts an element from a given {\bf Object}, at index {\bf Index}. From
 a PointType, VectorType, PlaneType, CtlPtType and MatrixType. A NumericType
 is returned with {\bf Index} 0 for the X axis, 1 for the Y axis etc.
 {\bf Index} 0 denotes the weight of CtlPtType. For a PolygonType that
 contains more than one polygon, the {\bf Index}th polygon is returned. For
 a PolygonType that contains a single Polygon, the {\bf Index}th vertex is
 returned. For a freeform object (curve, surface, etc.), the {\bf Index}th 
 CtlPtType is returned. For a ListType, COORD behaves like NTH and returns the
 {\bf Index}th object in the list. For a StringType, the {\bf Index}th
 character is returned as its ASCII numeric code.

 Example:

@\begin{verbatim}
    a = vector( 1, 2, 3 );
    vector( COORD( a, 0 ), COORD( a, 1 ), COORD( a, 2 ) );
 
    a = ctlpt( P2, 6, 7, 8, 9 );
    ctlpt( P3, coord( a, 0 ), coord( a, 1 ), coord( a, 2 ), coord( a, 3 ) );
 
    a = plane( 10, 11, 12, 13 );
    plane( COORD( a, 0 ), COORD( a, 1 ), COORD( a, 2 ), COORD( a, 3 ) );
@\end{verbatim}

 constructs a vector/ctlpt/plane and reconstructs it by extracting the
 constructed scalar components of the objects using COORD.

   See also COERCE.
$

@\subsubsection{COVERISO}
!COVERISO

@\begin{verbatim}
 CurveType COVERISO( TrivarType TV,
                     NumericType NewOfStrokes,
                     NumericType StrokeType,
                     PointType MinMaxPwrLen,
                     NumericType StepSize,
                     NumericType IsoVal,
                     VectorType ViewDir )
@\end{verbatim}

 computes a coverage for an iso surface of a trivariate function {\bf TV},
 using curves. {\bf NewOfStrokes} strokes are distributed on the iso surface
 with a length that is set via {\bf MinMaxPwrLen}. {\bf MinMaxPwrLen} is
 a triplet of the form (Min, Max, Power) that determines the length of the
 strokes as,
^
^        Avg = (Max + Min) / 2,             Dev = (Max - Min) / 2
^
^        Length = Avg + Dev * Random(0, 1) ^ Pwr.
^
@\begin{equation}
@     Avg = \frac{Max + Min}{2},~~~~~~~~~  Dev = \frac{Max - Min}{2},
@\end{equation}
@ or,
@\begin{equation}
@     Length = Avg + Dev * Random(0, 1)^{Pwr}.
@\end{equation}
 {\bf StepSize} controls the steps size of the piecewise linear approximation
 formed and should typically be smaller than Min.
 {\bf StrokeType} can be one of,
# 10 2 0 1
 1
  Draw strokes along minimal principal curvature.
 2
  Draw strokes along maximal principal curvature.
 3
  Draw strokes along both principal curvatures.
 4
  Draw strokes along constant X planes.
 5
  Draw strokes along constant Y planes.
 6
  Draw strokes along constant Z planes.
#
 {\bf IsoVal} controls the constant value of the iso surface level.
 See also ADAPISO, COVERPT, MRCHCUBE, TVLOAD.
 Finally, {\bf ViewDir} is the direction of view, used for silhouette computation.

 Example:

@\begin{verbatim}
    IsoVal = 0.12;
    Cover = CoverIso( ThreeCyls, 500, 1, vector( 3, 10, 1.0 ), 0.2, IsoVal );
@\end{verbatim}

 draws 500 strokes on the iso surface of trivariate {\bf ThreeCyls} at iso
 value {\bf IsoVal} and step size of 0.2.  Strokes are drawn in length of 
 3 to 10 along lines of curvatures of minimal curvature.
@See Figure~\ref{fig-coveriso} and also Figure~\ref{fig-mrchcube}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/coveriso.ps, width=4in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/coveriso.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A uniform coverage of 500 curved strokes of an iso surface of a
-      trivariate function, computed using COVERISO command.
=</b><BR clear=all>
@}
@\label{fig-coveriso}
@\end{figure}
$

@\subsubsection{COVERPT}
!COVERPT

@\begin{verbatim}
 PolygonType COVERPT( PolygonType Model,
                      NumericType NumOfPts,
                      VectorType ViewDir )
@\end{verbatim}

 computes a uniform point distribution on the given polygonal {\bf Model}.
 Approximately {\bf NumOfPts} points are uniformly distributed on the
 {\bf model}'s surface, provided {\bf ViewDir} is the zero vector.
 If {\bf ViewDir} is a non zero vector, the distribution is made to be
 uniform from this given viewing direction.
   In all cases, {\bf NumOfPts} is an upper bound of the the real number of
 distributed points, which will be in the same order.

 See also ADAPISO, COVERISO, FFPTDIST.

 Example:

@\begin{verbatim}
    Pts1 = CoverPt( solid1, 1000, vector( 0, 0, 0 ) );
    Pts2 = CoverPt( solid1, 3000, vector( 0, 0, -1 ) );
@\end{verbatim}

 computes two uniform distributions of 1000 and 3000 points on {\bf Solid1}.
 {\bf Pts1} is uniform in three space, while {\bf Pts2} is viewed
 uniform from the -Z direction.

@See Figure~\ref{fig-coverpt}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/coverpt1.ps, width=3in} &
@    \epsfig{file=user_man/coverpt2.ps, width=3in} 
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/coverpt1.gif">
=    <img hspace=2 width=250 src="user_man/coverpt2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A uniform coverage of 1000 and 3000 points of a polygonal model in
-      three space, computed using the COVERPT command. On the left, the 
-      distribution is directional, from the viewing direction, while on
-      the right, shows a point distribution that is uniform in 3-space.
-      Distant points are smaller, emulating point depth cueing.
=</b><BR clear=all>
@}
@\label{fig-coverpt}
@\end{figure}
$

@\subsubsection{CPOWER}
!CPOWER

@\begin{verbatim}
 CurveType CPOWER( ListType CtlPtList )
@\end{verbatim}

   creates a polynomial/rational curve out of the provided control point list.
 The created curve is employing the monomial power basis.  {\bf CtlPtList} is a
 list of control points, all of which must be of type (E1-E9 P1-P9), or
 regular PointType defining the curve's control polygon.  The curve's point
 type will be of a space which is the union of the spaces of all points.
@The created curve is the polynomial (or rational),
@\begin{equation}
@     C(t) = \sum_{i=0}^k P_i t^i,
@\end{equation}
@where $P_i$ are the control points {\bf CtlPtList}, and k is the degree of
@the curve, which is one less than the number of points.

 Example:

@\begin{verbatim}
 c = CPOWER( list( ctlpt( E3, 0, 1, 0 ),
                   ctlpt( E3, 1, 0, 0 ),
                   ctlpt( E3, 0, 0, 1 ) ) );
 c == coerce( coerce( c, bezier_type ), power_type );
@\end{verbatim}

 constructs a quadratic power basis curve, coerces it to a Bezier form,
 coerces the Bezier form back to the power basis, and then compares the result
 for equality.

 See also CBEZIER, CBSPLINE and SPOWER.
$

@\subsubsection{CRAISE}
!CRAISE

@\begin{verbatim}
 CurveType CRAISE( CurveType Curve, NumericType NewOrder )
@\end{verbatim}

   Raise {\bf Curve} to the {\bf NewOrder} Order specified.

 Example:

@\begin{verbatim}
    Crv = cbezier( list( ctlpt( E2, -0.7,  0.3 ),
                         ctlpt( E2,  0.0,  1.0 ),
                         ctlpt( E2,  0.7,  0.0 ) ) );
    Crv2 = CRAISE( Crv, 5 );
@\end{verbatim}

 raises the 90 degrees corner Bezier curve {\bf Crv} to be a quadratic.
@See Figure~\ref{fig-craise}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/craise.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/craise.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Raises a 90 degrees corner quadratic Bezier curve to a quintic
-      using CRAISE. The control polygons are also shown.
=</b><BR clear=all>
@}
@\label{fig-craise}
@\end{figure}
 See also CREDUCE, TRAISE, SRAISE, and MRAISE.
$

@\subsubsection{CRC2CRVTAN}
!CRC2CRVTAN

@\begin{verbatim}
 ListType CRC2CRVTAN( CurveType Crv1, CurveType Crv2,
                      NumericType Radius, NumericType Tol )
@\end{verbatim}

   computes all circles that are bi-tangent to the given two curves {\bf Crv1}
 and {\bf Crv2}.  The circles will posses a radius of {\bf Radius}.  The
 accuracy of the computation is governed by the tolerance {\bf Tol}.  Returned
 is a list center point locations with "Params" attributes of parameter values
 of the tangent locations at the two curves.

 Example:

@\begin{verbatim}
  Cntrs = CRC2CRVTAN( c1, c2, R, 1e-3 );
@\end{verbatim}
 
 computes all the circles of radius 0.1 that are bi-tangent to the two
 curves {\bf c1} and {\bf c2}.   Tolerance of computation is 1e-3.
@See Figure~\ref{fig-crc2crvtan}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crc2crvtan.ps, width=4.5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/crc2crvtan.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computes all the bi-tangent circles to the given two curves via
-      the CRC2CRVTAN function.
=</b><BR clear=all>
@}
@\label{fig-crc2crvtan}
@\end{figure}
 See also SKEL2DINT, CRV2TANS, TNSCRCR.
$

@\subsubsection{CREDUCE}
!CREDUCE

@\begin{verbatim}
 CurveType CREDUCE( CurveType Curve, NumericType NewOrder )
@\end{verbatim}

   reduces the {\bf Curve} to the {\bf NewOrder} Order specified.  This function
 approximates the lower order curve in the infinity norm sense, minimizing
 the maximal deviation between the original curve {\bf Curve} and the low
 order curve {\bf NewOrder}.  {\bf NewOrder} will identify with {\bf Curve}
 only if {\bf Curve} was degree raised before.

 Example:

@\begin{verbatim}
    Crv = cbezier( list( ctlpt( E2, -0.7,  0.3 ),
                         ctlpt( E2,  0.0,  1.0 ),
                         ctlpt( E2,  0.7,  0.0 ) ) );
    Crv2 = CREDUCE( craise( Crv, 5 ), 3 );
    Crv == Crv2;
@\end{verbatim}

 Should restore the original quadratic order.  I.e. {\bf Crv2} should
 identify with {\bf Crv} and "Crv == Crv2;" should return TRUE.

 See also CRAISE.
$

@\subsubsection{CREFINE}
!CREFINE

@\begin{verbatim}
 CurveType CREFINE( CurveType Curve, NumericType Replace, ListType KnotList )
@\end{verbatim}

   provides the ability to {\bf Replace} a knot vector of {\bf Curve}, or refine 
 it. {\bf KnotList} is a list of knots at which to refine {\bf Curve}. All knots
 should be contained in the parametric domain of the {\bf Curve}. If the knot
 vector is replaced, the length of {\bf KnotList} should be identical to the
 length of the original knot vector of the {\bf Curve}. If {\bf Curve} is a
 Bezier curve, it is automatically promoted to be a B-spline curve.

 Example:

@\begin{verbatim}
    Crv2 = CREFINE( Crv, FALSE, list( 0.25, 0.5, 0.75 ) );
@\end{verbatim}

 refines {\bf Crv} and adds three new knots at 0.25, 0.5, and 0.75.
@See Figure~\ref{fig-crefine}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crefine.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/crefine.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Refines a 90 degrees corner quadratic Bezier curve at three interior
-      knots (the result is a B-spline curve) using CREFINE.
-      The control polygons are also shown.
=</b><BR clear=all>
@}
@\label{fig-crefine}
@\end{figure}
 See also SREFINE, TREFINE, and MREFINE.
$

@\subsubsection{CREGION}
!CREGION

@\begin{verbatim}
 CurveType CREGION( CurveType Curve, NumericType MinParam,
                                                       NumericType MaxParam )
@\end{verbatim}

   extracts a region from the {\bf Curve} between {\bf MinParam} and {\bf MaxParam}.
 Both {\bf MinParam} and {\bf MaxParam} should be contained in the
 parametric domain of the {\bf Curve}, except for Bezier curves when
 {\bf MinParam} and {\bf MaxParam} can be arbitrary (extrapolating if not 
 between zero and one).

 Example:

@\begin{verbatim}
    SubCrv = CREGION( Crv, 0.3, 0.6 );
@\end{verbatim}

 extracts the region from the {\bf Crv} from the parameter value 0.3 to the
 parameter value 0.6.
@See Figure~\ref{fig-cregion}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cregion.ps, width=4in}
=    <img  hspace=2 src="user_man/cregion.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Extracts a sub region from a curve using CREGION.
=</b><BR clear=all>
@}
@\label{fig-cregion}
@\end{figure}
 See also SREGION, TREGION, and MREGION.
$

@\subsubsection{CREPARAM}
!CREPARAM

@\begin{verbatim}
 CurveType CREPARAM( CurveType Curve, NumericType MinParam,
                                                       NumericType MaxParam )
@\end{verbatim}

   reparametrizes the {\bf Curve} over a new domain from {\bf MinParam} to {\bf MaxParam}.
 This operation does not affect the geometry of the curve and only affine
 transforms its knot vector. A Bezier curve will automatically be promoted
 into a B-spline curve by this function.

   If {\bf MinParam} equals {\bf MaxParam} and both equates with one of the
 parameterization keywords of PARAM\_CENTRIP, PARAM\_CENTRIP, PARAM\_CHORD, or
 PARAM\_NIELFOL, then that parametrization is approximated for the curve, by
 changing the knot sequence.  Note this last operation affects the geometry
 of the curve.

 Example:

@\begin{verbatim}
    arc1 = arc( vector( 0.0, 0.0, 0.0 ),
                vector( 0.5, 2.0, 0.0 ),
                vector( 1.0, 0.0, 0.0 ) );
    crv1 = arc( vector( 1.0, 0.0, 0.75 ),
                vector( 0.75, 0.0, 0.7 ),
                vector( 0.5,  0.0, 0.85 ) ) +
           arc( vector( 0.5,  0.0, 0.75 ),
                vector( 0.75, 0.0, 0.8 ),
                vector( 1.0,  0.0, 0.65 ) );

    arc1 = CREPARAM( arc1, 0, 10 );
    crv1 = CREPARAM( crv1, 0, 10 );
@\end{verbatim}

 sets the domain of the given two curves to be from zero to ten. The
 Bezier curve arc1 is promoted to a B-spline curve.
 See also SREPARAM, TREPARAM, and MREPARAM.
$

@\subsubsection{CROSSEC}
!CROSSEC

@\begin{verbatim}
 PolygonType CROSSEC( PolygonType Object )
@\end{verbatim}

;   invokes an interactive mode to edit/create a polygon in the plane Z = 0.
; The polygon must be in the domain [0..1] in X,Y. To begin with, the first
; polygon of the given {\bf Object} is copied. If the given {\bf Operand} is
; NOT a geometric object, but FALSE (numeric 0.0), a new polygon is created.
; This returns an (open) object with this one polygon only and an inside side
; of $+Z$. Note that if the given polygon (first polygon of Object) is not on
; the $XY$ plane, it is transformed to it before editing, and transformed
; back after.
   This feature is NOT implemented.
$

@\subsubsection{CRV2TANS}
!CRV2TANS

@\begin{verbatim}
 ListType CRV2TANS( CurveType Crv, NumericType FineNess )
@\end{verbatim}

   computes all the bi-tangents of {\bf Crv}, in the XY plane. That
 is, all lines that are tangent to {\bf Crv} at two different locations.
 A list of points with X and Y coefficients representing the
 parametric locations on {\bf Crv} of the bi-tangent is returned.  {\bf FineNess}
 controls the numerical accuracy of the computation. A value of 10 will
 provide a good start and the larger this number is, the better the
 accuracy will be. See also CRVPTTAN and CNVXHULL.

 Example:
 
@\begin{verbatim}
    Tans = nil();
    Crv2Tns = Crv2Tans( Crv, 10 );
    for ( i = 1, 1, sizeof( Crv2Tns ),
        pt = nth( Crv2Tns, i ):
        snoc( ceval( Crv, coord( pt, 0 ) ) +
              ceval( Crv, coord( pt, 1 ) ), Tans ) );
@\end{verbatim}

 finds the bi-tangents of {\bf Crv} and converts them to a set of line
 segments.
@See Figure~\ref{fig-crv2tans}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crv2tans.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/crv2tans.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Computes the bi-tangents of a freeform curve, using CRV2TANS.
=</b><BR clear=all>
@}
@\label{fig-crv2tans}
@\end{figure}
 See also CRC2CRVTAN, TNSCRCR
$

@\subsubsection{CRVKERNEL}
!CRVKERNEL

@\begin{verbatim}
 AnyType CRVKERNEL( CurveType Crv, NumericType Gamma, NumericType Euclid,
                    AnyType Fineness, NumericType Mode )
@\end{verbatim}

   computes the (gamma) kernel of a given planar curve {\bf Crv}.  If
 {\bf Gamma} is zero, regular kernel is computed.  Else, the gamma curves of
 {\bf Gamma} degrees is being computed.  If {\bf Euclid} is TRUE then the
 result is returned in the Euclidean space, or if zero, in the parametric
 space. 
   {\bf Mode} can be 0 for a (gamma) kernel solution, 1 to extract silhouette
 sampling only out of the trivariate function, and 2 for the gamma kernel
 surface/trivariate functions themselves to be returned.
   {\bf Fineness} controls the refinement that is applied to the numeric
 solution.  For {\bf Mode} 0 it sets the number of knots to insert into
 the (x, y, t) trivariate function.  In {\bf Mode} 2, it lists two numeric
 values, the subdivision and numeric tolerances, of the silhouette extraction
 process (See MZERO for their meaning).  In {\bf Mode} 2, it controls the
 extent of the surfaces/trivariates.

 Example:

@\begin{verbatim}
    Krnl = CrvKernel( Crv, 0, 0, list( 2, 3, 1 ), 0 );
@\end{verbatim}

 computes the regular kernel of curve {\bf Crv} with a refinement of
 (2, 3, 1) in the three (x, y, t) axes of the computed trivariate function.
$


@\subsubsection{CRVLNDST}
!CRVLNDST

@\begin{verbatim}
 NumericType CRVLNDST( CurveType Crv, PointType PtOnLine, VectorType LnDir,
                                 NumericType IsMinDist, NumericType Epsilon )
 
 or
 
 ListType CRVLNDST( CurveType Crv, PointType PtOnLine, VectorType LnDir,
                                NumericType IsMinDist, NumericType Epsilon )
@\end{verbatim}
 
   compute the closest (if {\bf IsMinDist} is TRUE, farthest if FALSE) point
 on the {\bf Curve} to the line specified by {\bf PtOnLine} and {\bf LnDir} as a
 point on the line and a line direction.
   Since this operation is partially numeric, {\bf Epsilon} is used to set
 the needed accuracy. It returns the parameter value of the location on
 {\bf Crv} closest to the line.
   If, however, {\bf Epsilon} is negative, -{\bf Epsilon} is used instead,
 and all local extrema in the distance function are returned as a list
 (both minima and maxima).
   If the line and the curve intersect, the point of intersection is
 returned as the minimum.

 Example:
 
@\begin{verbatim}
    Param = CRVLNDST( Crv, linePt, lineVec, TRUE, 0.001 );
@\end{verbatim}

 finds the closest point on {\bf Crv} to the line defined by {\bf linePt}
 and {\bf lineVec}.
@See Figure~\ref{fig-crvlndst}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crvlndst.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/crvlndst.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computes the locations on the freeform curve with local extreme
-      distance to the given line, using CRVLNDST.
=</b><BR clear=all>
@}
@\label{fig-crvlndst}
@\end{figure}
$

@\subsubsection{CRVPTDST}
!CRVPTDST

@\begin{verbatim}
 NumericType CRVPTDST( CurveType Crv, PointType Point, NumericType IsMinDist,
                                                         NumericType Epsilon )
 
 or
 
 ListType CRVPTDST( CurveType Crv, PointType Point, NumericType IsMinDist,
                                                         NumericType Epsilon )
@\end{verbatim}
 
   compute the closest (if {\bf IsMinDist} is TRUE, farthest if FALSE) point
 on {\bf Crv} to {\bf Point}.
   Since this operation is partially numeric, {\bf Epsilon} is used to set
 the needed accuracy. It returns the parameter value of the location on
 {\bf Crv} closest to {\bf Point}.
   If, however, {\bf Epsilon} is negative, -{\bf Epsilon} is used instead,
 and all local extrema in the distance function are returned as a list
 (both minima and maxima).
 
 Example:
 
@\begin{verbatim}
    Param = CRVPTDST( Crv, Pt, FALSE, 0.0001 ); 
@\end{verbatim}

 finds the farthest point on {\bf Crv} from point {\bf Pt}.
@See Figure~\ref{fig-crvptdst}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crvptdst.ps, width=3in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/crvptdst.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computes the locations on the freeform curve with local extreme
-      distance to the given point, using CRVPTDST.
=</b><BR clear=all>
@}
@\label{fig-crvptdst}
@\end{figure}
$

@\subsubsection{CRVPTTAN}
!CRVPTTAN

@\begin{verbatim}
 ListType CRVPTTAN( CurveType Crv, PointType Pt, NumericType FineNess )
@\end{verbatim}

   computes all the tangents to {\bf Crv} that go through point {\bf Pt},
 all in the XY plane. A list of points with X and Y
 coefficients representing the parametric locations on {\bf Crv} of the
 bi-tangent is returned.  {\bf FineNess} controls the numerical accuracy of
 the computation. A value of 0.01 will provide a good start, and the smaller
 this number is, the better the accuracy will be. See also CRV2TANS and
 CNVXHULL.

 Example:
 
@\begin{verbatim}
    Tans = nil();
    Pt = point( 2, 0, 0 );
    CrvPtTns = CrvPtTan( Crv, Pt, 0.01 );
    for ( i = 1, 1, sizeof( CrvPtTns ),
        snoc( ceval( Crv, nth( CrvPtTns, i ) ) + coerce( Pt, e3 ), Tans ) );
@\end{verbatim}

 finds the tangents of {\bf Crv} through {\bf Pt} and converts them to a
 set of line segments.
@See Figure~\ref{fig-crvpttan}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/crvpttan.ps, width=4.5in}
=    <img  hspace=2 src="user_man/crvpttan.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       Computes the tangents of a freeform curve through a point,
-       using CRVPTTAN.
=</b><BR clear=all>
@}
@\label{fig-crvpttan}
@\end{figure}
$

@\subsubsection{CSPIRAL}
!CSPIRAL

@\begin{verbatim}
 CurveType CSPIRAL( NumericType NumLoops, NumericType Pitch,
                    NumericType Samples, NumericType CtlPtsPerLoop )
@\end{verbatim}

   constructs a polynomial approximation of a spiral planar curve of
 {\bf NumLoops} loops and specified {\bf Pitch}.  The curve is approximated
 as a least sqaures fit of {\bf Samples} samples and {\bf CtlPtsPerLoop}
 control points per loop.

 Example:
 
@\begin{verbatim}
   Spiral = cspiral( 5, 0.7, 500, 6 );
@\end{verbatim}

@See Figure~\ref{fig-cspiral} for this spiral of 5 loops.
=See figure for this spiral of 5 loops.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cspiral.ps, width=4.5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/cspiral.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       Approximates a spiral curve using CSPIRAL.
=</b><BR clear=all>
@}
@\label{fig-cspiral}
@\end{figure}
$

@\subsubsection{CSURFACE}
!CSURFACE

@\begin{verbatim}
 CurveType CSURFACE( SurfaceType Srf, ConstantType Direction,
                                                          NumericType Param )

 or

 CurveType CSURFACE( TriSrfType Srf, ConstantType Direction,
                                                          NumericType Param )
@\end{verbatim}

   extract an isoparametric curve out of {\bf Srf} in the specified
 {\bf Direction} (ROW or COL (or DEPTH for triangular surface) at the
 specified parameter value {\bf Param}.
   {\bf Param} must be contained in the parametric domain of {\bf Srf} in
 {\bf Direction} direction.
 The returned curve is {\em in} the surface {\bf Srf}.
@For a tensor product surface, it is equal to,
@\begin{equation}
@     C(t) = S(t, v_0) = \sum_{i=0}^m \sum_{j=0}^n P_{ij} B_i(t) B_j(v_0) =
@            \sum_{i=0}^m \left( \sum_{j=0}^n P_{ij} B_j(u_0) \right) B_i(t) =
@            \sum_{i=0}^m Q_i B_i(t),
@     \label{eqn-crv-from-srf}
@\end{equation}
@where $Q_i = \sum_{j=0}^n P_{ij} B_j(u_0)$ are the coefficients of the
@returned curve, and similar to the other parametric direction $S(u_0, t)$.
@{\bf Param} of CSURFACE is $v_0$ in equation~\eqnref{eqn-crv-from-srf}
@
@For a triangular Bezier surface of degree $n$, it is equal to,
@\begin{eqnarray*}
@     C(v) & = & \sum_{i,j,k} \frac{n!}{i! j! k!} u_0^i v^j w^k P_{ijk} \\
@          & = & \sum_{i,j} \frac{n!}{i! j! (n-i-j)!} u_0^i v^j
@                                          (1-u_0-v)^{n-i-j} P_{ijk} \\
@          & = & \sum_i \frac{n!}{i! (n-i)!} u_0^i
@                \sum_j \frac{(n-i)!}{j! (n-i-j)!} v^j (1-u_0-v)^{n-i-j}
@                                                                P_{ijk} \\
@          & = & \sum_i \frac{n!}{i! (n-i)!} u_0^i (1-u_0)^{n-i}
@                \sum_j \frac{(n-i)!}{j! (n-i-j)!}
@                        \left(\frac{v}{1-u_0}\right)^j
@                        (1-\frac{v}{1-u_0})^{n-i-j} P_{ijk} \\
@     \label{eqn-crv-from-trisrf}
@\end{eqnarray*}
@as $i + j + k = n$, and $u + v + w = 1.0$. Hence, the resulting isoparametric
@curve is a weighted sum of $n+1$ Bezier curves of varying degrees $n-i$ formed
@by the different rows/cols/depths of the triangular mesh.
@{\bf Param} of CSURFACE is $u_0$ in equation~\eqnref{eqn-crv-from-trisrf}

 Example:

@\begin{verbatim}
    Crv = CSURFACE( Srf, COL, 0.45 ); 
@\end{verbatim}

 extracts an isoparametric curve in the COLumn direction at the parameter
 value of 0.15 from surface {\bf Srf}.
 See also CMESH, COMPOSE, STRIVAR, MFROMMV.
@See Figure~\ref{fig-csurface}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/csurface.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/csurface.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    Extracts an isoparametric curve from the given surface, using CSURFACE.
=</b><BR clear=all>
@}
@\label{fig-csurface}
@\end{figure}
$

@\subsubsection{CTANGENT}
!CTANGENT

@\begin{verbatim}
 VectorType CTANGENT( CurveType Curve, NumericType Param, NumericType Normalize )
@\end{verbatim}

   computes the tangent vector to the {\bf Curve} at the parameter value {\bf Param}.
   The returned vector will have a unit length, if {\bf Normalize} is TRUE.  

 Example:

@\begin{verbatim}
    Tang = CTANGENT( Crv, 0.5, true );
@\end{verbatim}

 computes the unit tangent vector to {\bf Crv} at the parameter value of 0.5.
 See also CNORMAL, CNRMLCRV.
$

@\subsubsection{CTLPT}
!CTLPT

@\begin{verbatim}
 CPt = CTLPT( ConstantType PtType, NumericType Coord1, ... )
@\end{verbatim}

   constructs a single control point to be used in the construction of curves
 and surfaces. Points can have from one to five dimensions, and may be
 either Euclidean or Projective (rational). Point type is set via the
 constants E1 to E9 and P1 to P9. The coordinates of the point are specified
 in order; weight is first if rational.

 Examples:

@\begin{verbatim}
    CPt1 = CTLPT( E3, 0.0, 0.0, 0.0 );
    CPt2 = CTLPT( P2, 0.707, 0.707, 0.707 );
@\end{verbatim}

 constructs an {\bf E3} point at the origin and a P2 rational point with
 a weight of 0.707. The Projective Pi points are specified as
 CTLPT(Pn, W, W X1, ... , W Xn).
$

@\subsubsection{CTRIMSRF}
!CTRIMSRF

@\begin{verbatim}
 ListType CTRIMSRF( TrimSrfType TSrf, NumericType Parametric )
@\end{verbatim}

   extracts the trimming curves of a trimmed surface {\bf TSrf}.
 If {\bf Parametric} is not zero, then the trimming curves are extracted
 as parametric space curves of {\bf TSrf}. Otherwise, the trimming curves
 are evaluated into Euclidean space as curves on the surface {\bf TSrf}.

 Example:

@\begin{verbatim}
    TrimCrvs = CTRIMSRF( TrimSrf, FALSE ); 
@\end{verbatim}

 extracts the trimming curves of {\bf TrimSrf} as Euclidean curves on
 {\bf TrimSrf}.
@See Figure~\ref{fig-ctrimsrf}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/ctrimsrf.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/ctrimsrf.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Extracts the trimming curves in Euclidean space (middle) and
-      parametric space (right) of a trimmed surface (left), using CTRIMSRF.
=</b><BR clear=all>
@}
@\label{fig-ctrimsrf}
@\end{figure}
$

@\subsubsection{CUBICCRVS}
!CUBICCRVS

@\begin{verbatim}
 ListType CUBICCRVS( CurveType Crv, NumericType Tolerance, NumericType MaxLen )
@\end{verbatim}

   approximates given curve {\bf Crv} using piecewise cubic curves upto
 the prescribed tolerance {\bf Tolerance}.  If {\bf MaxLen} is positive it
 is used to limit the arc length of the cubic curves' segments.


 Example:

@\begin{verbatim}
    PCubicCrvs = CUBICCRVS( Crv, 0.01, 0.5 );
@\end{verbatim}

   creates a piecewise cubic approximation to curve {\bf Crv} upto tolerance 0.01
 and maximal arc length of cubic segments of 0.5.  See also QUADCRVS, CBIARC.
$

@\subsubsection{CVIEWMAP}
!CVIEWMAP

@\begin{verbatim}
 PolygonType CVIEWMAP( CurveType Crv, CurveType ViewCrv,
                       NumericType SubdivTol, NumericType NumerTol,
                       NumericType TrimInvisible )
@\end{verbatim}

   computes algebraic constraints that reflects the visible domain of planar
 curve {\bf Crv} as seen from direction prescribed by planar vector curve
 {\bf ViewCrv}.  {\bf ViewCrv} is typically a unit circle curve, parametrizing
 all possible (360 degrees) planar views.
   See MZERO for the meaning of the {\bf SubdivTol} and {\bf NumerTol}
 tolerances.
   If {\bf TrimInvisible} is FALSE, the return set prescribes the 2D silhouette
 locations on {\bf Crv} from the specific view direction.  If
 {\bf TrimInvisible} is TRUE, attempt ismade to remove the invisile portions.
   Result is returned as 3D polylines, in $(t, v, r)$ space where $t$ and $r$
 parametrize {\bf Crv} and $v$ parametrizes {\bf ViewCrv}.  This, since a
 silhouette point $Crv(t)$ could hide a independent curve location $Crv(r)$.

 Example:

@\begin{verbatim}
    ViewMap = CVIEWMAP( Crv, pcircle( vector( 0, 0, 0 ), 1 ), 0.1, 1e-6, 0 );
@\end{verbatim}

 See also CANGLEMAP, CVISIBLE, CARRANGMNT.
$

@\subsubsection{CVISIBLE}
!CVISIBLE

@\begin{verbatim}
 PolygonType CVIVISIBLE( CurveType Crv, PointType Pt, NumericType Eps )

 or

 PolygonType CVIVISIBLE( CurveType Crv, VectorType Dir, NumericType Eps )
@\end{verbatim}

   computes the visible regions of planar curve {\bf Crv} as seen from
 either view point {\bf Pt} or from view direction {\bf Dir}. {\bf Eps}
 controls the accuracy of the computation.  {\bf Dir} must have its Z
 components zero, whereas {\bf Pt}'s Z coefficient must be one.

 Example:

@\begin{verbatim}
   Crvs = CVISIBLE( c, Pt, 1e-5 );
@\end{verbatim}

@See Figure~\ref{fig-cvisible} for an example.
=See figure for a example.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cvisible.ps, width=6in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/cvisible.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    The visibility of the given curve on the left is sampled along its 360
-    degrees to create a {\em visibility atlas} of the curve on the right,
-    using CVISIBLE.  Then SETCOVER is used to find the minimal set that can
-    see the entire curve, esselntially solving the so-called art-gallery
-    problem.
=</b><BR clear=all>
@}
@\label{fig-cvisible}
@\end{figure}
 See also CANGLEMAP, CVIEWMAP, CARRANGMNT, SETCOVER.
$

@\subsubsection{CYLIN}
!CYLIN

@\begin{verbatim}
 PolygonType CYLIN( VectorType Center, VectorType Direction,
                    NumericType Radius, NumericType Caps )
@\end{verbatim}

   creates a CYLINder geometric object, defined by {\bf Center} as the center of
 the base of the CYLINder, {\bf Direction} as the CYLINder's axis and height,
 and {\bf Radius} as the radius of the base of the CYLINder.
   If {\bf Caps} equals zero, no caps are created.  If {\bf Caps} equal
 one (two), only the bottom (top) cap is created.  If {\bf Caps} equal three,
 both the top and the bottom caps are created.

   See RESOLUTION for the accuracy of the CYLINder approximation as a
 polygonal model. See IRITSTATE's "PrimRatSrfs" and "PrimRatSrfs" state
 variables.

 Example:

@\begin{verbatim}
    Cylinder1 = CYLIN( vector( 0, 0, 0 ), vector( 1, 0, 0 ), 10, 3 );
@\end{verbatim}

 constructs a cylinder with two caps of radius 10 along the $X$ axis
 from the origin to $X = 1$.
@See Figure~\ref{fig-cylinder}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cylinder.ps, width=5in}
=    <img  hspace=2 src="user_man/cylinder.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    A cylinder primitive can be constructed using the CYLIN constructor.
=</b><BR clear=all>
@}
@\label{fig-cylinder}
@\end{figure}
$

@\subsubsection{CZEROS}
!CZEROS

@\begin{verbatim}
 ListType CZEROS( CurveType Crv, NumericType Epsilon, NumericType Axis )
@\end{verbatim}
 
   computes the zero set of the given {\bf Crv} in the given axis (1 for X,
 2 for Y, 3 for Z). Since this computation is numeric, an {\bf Epsilon} is
 also required to specify the desired tolerance. It returns a list of
 all the parameter values (NumericType) the curve is zero.
 
 Example:
 
@\begin{verbatim}
    xzeros = CZEROS( cb, 0.001, 1 );
    pt_xzeros = nil();
    pt = nil();
    for ( i = 1, 1, sizeof( xzeros ),
            pt = ceval( cb, nth( xzeros, i ) ):
            snoc( pt, pt_xzeros )
        );
    interact( list( axes, cb, pt_xzeros ), 0 );
@\end{verbatim}

 computes the {\bf X} zero set of curve {\bf cb} with error tolerance
 of {\bf 0.001}. This set is then scanned in a loop and evaluated to
 the curve's locations, which are then displayed.
 See also CINFLECT.
@See Figure~\ref{fig-czeros}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/czeros.ps, width=4in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/czeros.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computes the zero set of a given freeform curve, in the given axis,
-      using CZEROS.
=</b><BR clear=all>
@}
@\label{fig-czeros}
@\end{figure}
$

@\subsubsection{DIST2FF}
!DIST2FF

@\begin{verbatim}
 SurfaceType DIST2FF( CurveType Crv1, CurveType Crv2, NumericType DistType )

 or
 
 MultivarType DIST2FF( CurveType Crv1, SurfaceType Srf2, NumericType DistType )

 or
 
 MultivarType DIST2FF( SurfaceType Srf1, SurfaceType Srf2, NumericType DistType )
@\end{verbatim}

   computes the distance function between the two given freeform shapes.
 The returned variety is bi-variate, tri-variate, or a four-variate, depending
 on the dimensionality of the input, in order.  Based on {\bf DistType}, the
 following distance functions could be used:
# 10 2 1 1
 DistType Value
  Description
 0
  Computes the distance vector function, (V1 - V2).
 1
  Computes the distance square function, (V1 - V2)\verb+^+2.
 2
  Projection of the distance vector onto the normal
 
  field of the first varietly, < V1 - V2, N1 >.
 3
  Projection of the distance vector onto the normal
 
  field of the second varietly, < V1 - V2, N2 >.
#
  In cases 2 and 3, the normal field is not a unit field.

   Example:

@\begin{verbatim}
    Crv1 = cbezier( list( ctlpt( E1, .2 ),
                          ctlpt( E2, 0.5, 4 ),
                          ctlpt( E2, 1.3, 0.05 ) ) ) * sy( 0.2 );
    Crv2 = cbezier( list( ctlpt( E1, -.2 ),
                          ctlpt( E2, 0.25, 1.9 ),
                          ctlpt( E2, 1.3, 0.05 ) ) ) * ty( 0.3 ) * sx( 1.5 );
    bb = bbox( dist2ff( Crv1, Crv2, 1 ) );
@\end{verbatim}

 computes a bound on the minimal and maximal distance square between the
 given two curves, by computing a bounding box on this scalar distance square
 field. 
$

@\subsubsection{DUALITY}
!DUALITY

@\begin{verbatim}
 CurveType DUALITY( CurveType Curve )

 or

 SurfaceType DUALITY( SurfaceType Srf )
@\end{verbatim}

   computes the dual curve/surface to the given curve/surface.  The dual shape
 is a mapping of every point to a line (plane) in R2 (R3).

   Example:

@\begin{verbatim}
    Ellipsoid = sphereSrf( 1.1 ) * sx( 2 ) * sy( 1.2 );
    DualEllip = DUALITY( Ellipsoid );
@\end{verbatim}
@See Figure~\ref{fig-duality}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/dual_crv.ps, width=2.3in} &
@    \epsfig{file=user_man/dual_srf.ps, width=3.7in} 
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/dual_crv.gif">
=    <img hspace=2 width=250 src="user_man/dual_srf.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Two examples of a dual curve (left) and a dual surface (right) computed
-      using the DUALITY function.  The duals are shown in thin black color.
=</b><BR clear=all>
@}
@\label{fig-duality}
@\end{figure}
$

@\subsubsection{ELLIPSE3PT}
!ELLIPSE3PT

@\begin{verbatim}
 ListType ELLIPSE3PT( PointType Pt1, PointType Pt2, PointType Pt3,
                      NumericType Offset )
@\end{verbatim}

    computes the 6 coefficients A-F of,
^     Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0,
@\begin{equation}
@     Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0,
@\end{equation}
 defining the ellipse of minimal area that bounds these 3 points {\bf Pti}.
 computation is conducted in the XY plane, with Z ignored.   If {\bf Offset}
 is not zero, the ellipse is offset approximated by {\bf Offset} amount.

    Example:

@\begin{verbatim}
    Pt1 = point( random( -0.5, 0.5 ),  random( -0.5, 0.5 ),  0 );
    Pt2 = point( random( -0.5, 0.5 ),  random( -0.5, 0.5 ),  0 );
    Pt3 = point( random( -0.5, 0.5 ),  random( -0.5, 0.5 ),  0 );

    EllImp = ELLIPSE3PT( Pt1, Pt2, Pt3, 0 );
    Ell = ConicSec( EllImp, 0, off, off );
    color( Ell, yellow );
    adwidth( Ell, 2 );
@\end{verbatim}

   creates three random points in the XY plane and compute the implicit
 minimal area ellipse for these three points.  the Ellipse is realized
 geometrically using the ConicSec function.
   See also CONICSEC, IMPLCTTRANS, QUADRIC, MAP3PT2EQL.
$

@\subsubsection{EVOLUTE}
!EVOLUTE

@\begin{verbatim}
 CurveType EVOLUTE( CurveType Curve )

 or

 SurfaceType EVOLUTE( SurfaceType Srf )
@\end{verbatim}

   compute the evolute of a curve or a surface.
 For curves, the evolute is defined as,
@\begin{equation}
@  E(t) = C(t) + \frac{N(t)}{\kappa(t)},
@\end{equation}
@ where $N(t)$ is the unit normal of $C(t)$ and $k(t)$ is its curvature.
@
@  $E(t)$ is computed symbolically as the symbolic sum of $C(t)$ and
@ $\frac{N(t)}{\kappa(t)}$ where the latter is,
@
@\begin{eqnarray}
@  \frac{N(t)}{\kappa(t)}
@ & = & \frac{\kappa(t) N(t)}{k^2(t)} \nonumber \\
@ & = & \frac{(C'(t) \times C''(t)) \times C'(t)}
@             {\| C'(t) \|^4}
@       \frac{\|C'(t)\|^6}
@            {(C'(t) \times C''(t))^2}  \nonumber \\
@ & = & \frac{\left( {(C'(t) \times C''(t)) \times C'(t)} \right)
@                                        \| C'(t) \|^2}
@             {(C'(t) \times C''(t))^2}
@\end{eqnarray}
^
^               N(t)
^ E(t) = C(t) + ----
^               k(t)
^
^ where N(t) is the unit normal of C(t), and k(t) is its curvature.
^ E(t) is computed symbolically as the symbolic sum of C(t) and
^ N(t) / k(t).
 For surfaces, this function computes the mean evolute which is equal to,
@\begin{equation}
@  E(u, v) = S(u, v) + \frac{n(u, v)}{2 H(u, v)},
@\end{equation}
@ where $n(u, v)$ is the unit normal of $S(u, v)$ and $H(u, v)$ is
@ the mean curvature.
@
@  $E(u, v)$ is computed symbolically.
^
^                      n(u, v)
^ E(u, v) = S(u, v) + ---------
^                     2 H(u, v)
^
^ where n(u, v) is the unit normal of S(u, v), and H(u, v) is its mean
^ curvature. E(u, v) is computed symbolically.

 The result of this symbolic computation is exact (upto machine precision),
 unlike similar operations such as OFFSET or AOFFSET, that are only
 approximated.
 
 Example:

@\begin{verbatim}
    crv = cbspline( 3,
                    list( ctlpt( E3, -1.0,  0.1,  0.2 ),
                          ctlpt( E3, -0.1,  1.0,  0.1 ),
                          ctlpt( E3,  0.1,  0.1,  1.0 ),
                          ctlpt( E3,  1.0,  0.1,  0.1 ),
                          ctlpt( E3,  0.1,  1.0,  0.2 ) ),
                    list( KV_OPEN ) );
    cev = EVOLUTE( Crv );
@\end{verbatim}
@See Figure~\ref{fig-evolute}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/cevolute.ps, width=4in}
=    <img  hspace=2 src="user_man/cevolute.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     The evolute (thick) of a freeform curve (thin) can be computed using
-     EVOLUTE.
=</b><BR clear=all>
@}
@\label{fig-evolute}
@\end{figure}
 See also SMEAN.
$

@\subsubsection{EXTRUDE}
!EXTRUDE

@\begin{verbatim}
 PolygonType EXTRUDE( PolygonType Object, VectorType Dir, NumericType Caps )

 or
 
 SurfaceType EXTRUDE( CurveType Object, VectorType Dir, NumericType Caps )

 or
 
 TrivarType EXTRUDE( SurfaceType Object, VectorType Dir, NumericType Caps )
@\end{verbatim}

   create an extrusion of the given {\bf Object}. If the {\bf Object} is a
 PolygonObject, its first polygon is used as the base for the extrusion in
 {\bf Dir} direction.  If the {\bf Object} is a CurveType, an extrusion surface is
 constructed.  If the {\bf Object} is a SurfaceType, an extrusion trivariate
 is constructed.  If {\bf Caps} equals zero, no caps are created.  If
 {\bf Caps} equal one (two), only the bottom (top) cap is created.  If
 {\bf Caps} equal three, both the top and the bottom caps are created.
 Note that caps are created for a closed {\bf Object} only, so the {\bf Object}
 must be either a polygon or a closed curve for caps to be generated.
   Direction {\bf Dir} cannot be coplanar with the polygon plane. The curve
 may be nonplanar.

 Example:

@\begin{verbatim}
    Cross = cbspline( 3,
                      list( ctlpt( E2, -0.018, 0.001 ),
                            ctlpt( E2,  0.018, 0.001 ),
                            ctlpt( E2,  0.019, 0.002 ),
                            ctlpt( E2,  0.018, 0.004 ),
                            ctlpt( E2, -0.018, 0.004 ),
                            ctlpt( E2, -0.019, 0.001 ) ),
                      list( KV_OPEN ) );
    Cross = Cross + -Cross * scale( vector( 1, -1, 1 ) );
    Napkin = EXTRUDE( Cross * scale( vector( 1.6, 1.6, 1.6 ) ),
                      vector( 0.02, 0.03, 0.2 ),
                      0 );
@\end{verbatim}

 constructs a closed cross section {\bf Cross} by duplicating one half of
 it in reverse and merging the two sub-curves. {\bf Cross} is then used as
 the cross section for the extrusion operation.
@See Figure~\ref{fig-extrude}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/extrude.ps, width=4.5in}
=    <img  hspace=2 src="user_man/extrude.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     An extrusion of a freeform curve using EXTRUDE to create a freeform
-     surface.
=</b><BR clear=all>
@}
@\label{fig-extrude}
@\end{figure}
$

@\subsubsection{FFCMPCRV}
!FFCMPCRV

@\begin{verbatim}
 FFCMPCRV( CurveType Crv1, CurveType Crv2, NumericType Tolerance )
@\end{verbatim}

   compares the given two curves, {\bf Crv1} and {\bf Crv2} for an
 identical trace.  Curves could have identical trace while with
 different degrees (via degree raising of one of them), differet knot
 sequences (by applying refinements to either curves or both), or even
 different speed (via composition).  This function reduces both curves
 to a canonical representation by reverse engineering unnecessary
 degree raising, refinements, or composition and then compare the two
 curves upto the given tolerance {\bf Tolerance}.
   Returned is a list of 5 numeric values.  The first number equals 1
 if the curves are the same, 2 if the are the same but domain is not
 exactly the same, or 3 f the curves are different.  The other four numbers
 in the list are the domains of the two given curves that overlap as
 (Start1, End1, Start2, End2).

 Example:

@\begin{verbatim}
 Similarity = FFCMPCRV( Crv1, Crv2, 1e-6 );
@\end{verbatim}
$

@\subsubsection{FFCOMPAT}
!FFCOMPAT

@\begin{verbatim}
 FFCOMPAT( CurveType Crv1, CurveType Crv2 )

 or

 FFCOMPAT( SurfaceType Srf1, SurfaceType Srf2 )
@\end{verbatim}

 make the given two curves or surfaces compatible by making them share
 the same point type, the same curve type, the same degree, and the
 same continuity.  The same point type is gained by promoting a lower
 dimension into a higher one, and non-rational to rational
 points. Bezier curves are promoted to B-spline curves if necessary,
 for curve type compatibility.  Degree compatibility is achieved by
 raising the degree of the lower order curve. Continuity is achieved
 by refining both curves to the space with the same (unioned) knot
 vector. This function returns nothing and compatibility is made {\em
 in place}.

 Example:

@\begin{verbatim}
 FFCOMPAT( Srf1, Srf2 );
@\end{verbatim}

 See also CMORPH and SMORPH.
$

@\subsubsection{FFCTLPTS}
!FFCTLPTS

@\begin{verbatim}
 ListType FFCTLPTS( FreeformType Freeform );
@\end{verbatim}

 returns all the control points of the given {\bf Freeform} in a single list.
 See Also FFPTTYPE, FFGTYPE, FFKNTVEC, FFMSIZE, FFORDER.

 Example:

@\begin{verbatim}
 Ctls = FFCTLPTS( Srf1 );
@\end{verbatim}
$

@\subsubsection{FFEXTREME}
!FFEXTREME

@\begin{verbatim}
 CtlPtType FFEXTREME( CurveType Crv, NumericType Minimum )

 or

 CtlPtType FFEXTREME( SurfaceType Srf, NumericType Minimum )
@\end{verbatim}

 compute a bound on the extreme values a curves {\bf Crv} or surface
 {\bf Srf} can assume. Returned control points provide a bound on the
 minimum (maximum) values that can be assumed if {\bf Minimum} is TRUE
 (FALSE).

 Example:

@\begin{verbatim}
 Bound = FFEXTREME( Srf, false );
@\end{verbatim}

 computes a bound on the maximal values Srf can assume.
$

@\subsubsection{FFGTYPE}
!FFGTYPE

@\begin{verbatim}
 NumericType FFGTYPE( FreeformType Freeform )
@\end{verbatim}

 returns the geometric type (BEZIER\_TYPE, BSPLINE\_TYPE etc.) of the given 
 {\bf freeform}.
 See Also FFGTYPE, FFCTLPTS, FFKNTVEC, FFMSIZE, FFORDER, PDOMAIN.
$

@\subsubsection{FFKNTVEC}
!FFKNTVEC

@\begin{verbatim}
 ListType FFKNTVEC( FreeformType Freeform )
@\end{verbatim}

 returns all the knot vector(s) of the given {\bf Freeform} in a list of knot
 vector(s).  See Also FFPTTYPE, FFGTYPE, FFCTLPTS, FFMSIZE, FFORDER.

 Example:

@\begin{verbatim}
 KVs = FFKNTVEC( Srf1 );
@\end{verbatim}
$

@\subsubsection{FFMATCH}
!FFMATCH

@\begin{verbatim}
 FFMATCH( CurveType Crv1, CurveType Crv2, NumericType Reduce,
          NumericType Samples, NumericType ReparamOrder,
          NumericType Rotate, NumericType NormType )
@\end{verbatim}

 computes a reparametrization to {\bf Crv2} so it fits {\bf Crv1}, the best
 under some prescribed norm, {\bf NormType}. Currently the following norms
 are valid for {\bf NormType}
# 10 2 1 1
 Value
  Description
 1
  Suitable for ruled and blended curves, for modeling.
 
  See RULEDSRF.
 2
  Suitable for metamorphosis of curves. See CMORPH.
 3
  Distance norm in "walking the dog" notion.
 4
  Bisector (skeleton) matching norm for two curves.
#
 Whenever negative norms can result (for example, in cases were self
 intersection cannot be prevented in ruled surface constructions), one can
 allow negativity with no extra penalty by applying negative {\bf NormType}.
   Use of positive-only norms would yield no output at all if no matching
 with positive weights can be established, whereas allowing negative
 norm values would result in a globally optimal result, but with possible
 self intersectiions.

 The reparametrization is computed by sampling a fixed set of size
 {\bf Samples} off both curves, and fitting a B-spline curve of length
 {\bf Reduce} as the reparametrization curve. Hence, {\bf Reduce} must
 be less than or equal to {\bf Samples}. The reparametrization curve
 will have order of {\bf ReparamOrder}. If {\bf Rotate} is TRUE or ON,
 then attempt is made to rotate the reparametrization of the
 curves. Rotation can be used on closed curves only.

 See RULEDSRF and CMORPH for examples.
$

@\subsubsection{FFMERGE}
!FFMERGE

@\begin{verbatim}
 CurveType FFMERGE( ListType E1Curves, NumericType PointType )

 or

 SurfaceType FFMERGE( ListType E1Surfaces, NumericType PointType )

 or

 MultivarType FFMERGE( ListType E1Multivars, NumericType PointType )
@\end{verbatim}

 merge the scalar curves/surfaces/multivariates in the list of curves
 {\bf E1Curves} or list of surfaces {\bf E1Surfaces} or list of
 multivariates {\bf E1Multivars} to one vector curve/surface/multivariate
 of point type {\bf PointType}.

 Example:

@\begin{verbatim}
 Srf = FFMERGE( list( SrfW, SrfX, SrfY ), P2 );
@\end{verbatim}

 merges three scalar surfaces into a single surface with point type P2.
 See also FFSPLIT.
$

@\subsubsection{FFMESH}
!FFMESH
@\begin{verbatim}
 ListType FFMESH( FreeformType Freeform )
@\end{verbatim}

 returns the control mesh/polygon of the given {\bf Freeform} in a list.
 See Also FFCTLPTS, FFKNTVEC, FFORDER, FFPTTYPE, FFMSIZE.

 Example:

@\begin{verbatim}
 SrfMesh = FFMESH( Srf );
@\end{verbatim}
$

@\subsubsection{FFMSIZE}
!FFMSIZE

@\begin{verbatim}
 ListType FFMSIZE( FreeformType Freeform )
@\end{verbatim}

 returns the size of the control mesh/polygon of the given {\bf freeform}
 in a list.
 See Also MESHSIZE, FFMESH, FFPTTYPE, FFGTYPE, FFCTLPTS, FFKNTVEC, FFORDER,
 PDOMAIN.

 Example:

@\begin{verbatim}
 MSizes = FFMSIZE( Srf1 );
@\end{verbatim}
$

@\subsubsection{FFORDER}
!FFORDER

@\begin{verbatim}
 ListType FFORDER( FreeformType Freeform )
@\end{verbatim}

 returns all the orders of the given {\bf Freeform} in a single list.
 See Also FFPTTYPE, FFGTYPE, FFCTLPTS, FFKNTVEC, FFMSIZE, PDOMAIN.

 Example:

@\begin{verbatim}
 Orders = FFORDER( Srf1 );
@\end{verbatim}
$

@\subsubsection{FFPOLES}
!FFPOLES

@\begin{verbatim}
 NumericType FFPOLES( FreeformType Freeform );
@\end{verbatim}

 returns TRUE if the given {\bf Freeform} has poles, FALSE otherwise.
 Poles are zeros in the weights of rational functions.

 Example:

@\begin{verbatim}
 HasPoles = FFPOLES( Srf1 );
@\end{verbatim}
$

@\subsubsection{FFPTDIST}
!FFPTDIST

@\begin{verbatim}
 ListType FFPTDIST( CurveType Crv, NumericType Param, NumericType NumOfPts )
 
 or
 
 ListType FFPTDIST( SurfaceType Srf, NumericType Param, NumericType NumOfPts )
@\end{verbatim}

    compute a uniform point distribution for {\bf Crv} or {\bf Srf}.  If
 {\bf Param} is FALSE, the distribution is selected to be uniform in the
 Euclidean space; otherwise if TRUE, the distribution is made uniform in the
 parametric space. {\bf NumOfPts} sets the number of points in the
 distribution.

    The returned list of points prescribes parameter values in the freeforms.
 For {\bf Crv}, the returned list is a list of reals, in the parameter space
 of {\bf Crv}.  For {\bf Srf}, the returned list is a list of points, whose
 X and Y coefficients hold the U and V parameters of {\bf Srf}.
 See also COVERPT.

 Example:

@\begin{verbatim}
    c1 = cbezier( list( ctlpt( E2, -1.0,  0.0 ),
                        ctlpt( E2, -1.0,  0.1 ),
                        ctlpt( E2, -0.9, -0.1 ),
                        ctlpt( E2,  0.9,  0.0 ) ) );
    color( c1, magenta );
    
    pts = FFPTDIST( c1, true, 300 );
    e2pts = nil();
    for ( i = 1, 10, sizeof( pts ),
            pt = ceval( c1, coord( nth( pts, i ), 0 ) ):
            snoc( pt, e2pts )
        );
    interact( list( e2pts, c1 ) );
    
    pts = FFPTDIST( c1, false, 300 );
    e2pts = nil();
    for ( i = 1, 10, sizeof( pts ),
            pt = ceval( c1, coord( nth( pts, i ), 0 ) ):
            snoc( pt, e2pts )
        );
    interact( list( e2pts, c1 ) );
@\end{verbatim}

   computes the distribution of 100 points in curve {\bf c1} which has 
 highly nonuniform speed characteristics.  Two distributions are computed,
 one to be uniform in the parametric space and one to be uniform in the
 Euclidean space.
@See Figure~\ref{fig-ffptdist}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/ffptdst1.ps, width=4.5in} \\[0.2in]
@    \epsfig{file=user_man/ffptdst2.ps, width=4.5in} 
=    <BR clear=all>
=        <img hspace=2 src="user_man/ffptdst1.gif">
=        <img hspace=2 src="user_man/ffptdst2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      (top) A distribution of 30 points uniformly in Euclidean space.
-      (bottom) A distribution of 30 points uniformly in parameteric space.
-      Both examples were computed using FFPTDIST.
=</b><BR clear=all>
@}
@\label{fig-ffptdist}
@\end{figure}
$

@\subsubsection{FFPTTYPE}
!FFPTTYPE

@\begin{verbatim}
 NumericType FFPTTYPE( FreeformType Freeform )
@\end{verbatim}

 returns the point type (E2, P4 etc.) of the given {\bf freeform}.
 See Also FFGTYPE, FFCTLPTS, FFKNTVEC, FFMSIZE, FFORDER, PDOMAIN.
$

@\subsubsection{FFSPLIT}
!FFSPLIT

@\begin{verbatim}
 ListType FFSPLIT( CurveType Crv )

 or

 ListType FFSPLIT( SurfaceType Srf )

 or

 ListType FFSPLIT( MultivarType MV )
@\end{verbatim}

 split the given curve {\bf Crv} or surface {\bf Srf} or multivariate {\bf MV}
 into its scalar components that are returned as a list of scalar
 curves/surfaces/multivariates.

 Example:

@\begin{verbatim}
 E1Srfs = FFSPLIT( circle( vector( 0, 0, 0 ), 1 ) );
@\end{verbatim}

 splits the circle which is a curve in P3 into four scalar curves (W, X, Y, Z)
 that are returned in a single list.
 See also FFMERGE, FFPTTYPE.
$

@\subsubsection{FITPMODEL}
!FITPMODEL

@\begin{verbatim}
 ListType FITPMODEL( PolygonType PlObj, NumericType FitType,
                     NumericType Tol, NumericType NumIters )
@\end{verbatim}

   fits a primitive object to the given polygonal model, {\bf PlObj}.
 The numeric fitting process is controled via a bound on the number of
 iterations {\bf NumIters} and the resulting tolerance of the fit that is
 required, {\bf Tol}.   Returned is a list of numeric values with the
 error of the fit as the first value.  The rest of the list numeric values
 are the coefficients of the algebraic fitted form (see table below).
 {\bf FitType} can be one of:
# 10 2 1 1
 0
  A Planar face.  Returned list holds (A, B, C, D), the four
 
  coefficients of the plane equation.
 1
  A Sphere.  Returned list holds (Xcntr, Ycntr, Zcntr, Radius)
 
  of the fitted sphere.
 2
  A Cylinder. Returned list holds (Xcntr, Ycntr, Zcntr,
 
  Xdir, Ydir, Zdir, Radius) of the fitted cylinder.
 3
  A Circle. Returned list holds (Xcntr, Ycntr, Radius) of
 
  the fitted circle.
 4
  A Cone. Returned list holds (Xcntr, Ycntr, Zcntr, 
 
  Xdir, Ydir, Zdir, Radius) of the fitted cone.
#

 Example:

@\begin{verbatim}
  resolution = 20;
  x1 = triangl( sphere( vector( 1, 2, 3 ), 4 ), 1 );

  SprParams = FitPModel( x1, 1, 0.01, 100 );
@\end{verbatim}

 Computes a fitted sphere to a polygonal approximation of a sphere.
 See also ANALYFIT.
$

@\subsubsection{FIXPLGEOM}
!FIXPLGEOM

@\begin{verbatim}
 PolygonType FIXPLGEOM( PolygonType PlObj, NumericType Oper, NumericType Eps )

 or

 ListType FIXPLGEOM( ListType Obj, NumericType Oper, NumericType Eps )
@\end{verbatim}

   cleans polygonal geometry.  based on {\bf Oper}, the following will be
 conducted:
# 10 2 1 1
 0
  Remove identical duplicated polygons.
 1
  Remove zero length edges.
#

 The clean up of an object will be applied individually to each part
 found in the object list {\bf Obj}.

 Example:

@\begin{verbatim}
  Obj2 = FIXPLGEOM( Obj, 0 );
  Obj3 = FIXPLGEOM( Obj2, 1 );
  Obj4 = FIXPLNRML( Obj3, 2 );
@\end{verbatim}

 cleans duplicated polygons, zero length edges, and then reorient the result.
 See also FIXPLNRML.
$

@\subsubsection{FIXPLNRML}
!FIXPLNRML

@\begin{verbatim}
 PolygonType FIXPLNRML( PolygonType PlObj, NumericType TrustInfo )

 or

 ListType FIXPLNRML( ListType Obj, NumericType TrustInfo )
@\end{verbatim}

   corrects inconsistencies in polygonal geometry, between normals of polygons
 and normals at the vertices based on {\bf TrustInfo}.  If {\bf TrustInfo} is
# 10 2 1 1
 0
  Trust the normals at the vertices.
 1
  Trust the normals of the polygons.
 2
  Reorient all the polygon's normals and vertices
 
  normals to follow the orientation of first polygon.
#

 The computation on an object will be applied individually to each part
 found in the object list {\bf Obj}.  Option 2 of {\bf TrustInfo} will correct
 cases where adjacent polygons are not oriented the same, based on detection
 of adjacencies.

 Example:

@\begin{verbatim}
  Obj2 = FIXPLNRML( Obj, 2 );
@\end{verbatim}

 See also FIXPLGEOM.
$

@\subsubsection{GBOX}
!GBOX

@\begin{verbatim}
 PolygonType GBOX( VectorType Point,
                   VectorType Dx, VectorType Dy, VectorType Dz )
@\end{verbatim}

   creates a parallelepiped - generalized BOX polygonal object, defined by
 {\bf Point} as its base position, and {\bf Dx, Dy, Dz} as 3 3D vectors to define
 the 6 faces of this generalized BOX. The regular BOX object is a special case
 of GBOX where {\bf Dx} = vector(Dx, 0, 0), {\bf Dy} = vector(0, Dy, 0), and
 {\bf Dz} = vector(0, 0, Dz).

   {\bf Dx}, {\bf Dy}, {\bf Dz} must all be independent in order to create an
 object with positive volume.

 Example:

@\begin{verbatim}
    GB = GBOX( vector( 0.0, -0.35, 0.63 ), vector(  0.5, 0.0, 0.5 ),
                                           vector( -0.5, 0.0, 0.5 ),
                                           vector(  0.0, 0.7, 0.0 ) );
@\end{verbatim}
@See Figure~\ref{fig-gbox}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/gbox.ps, width=3in}
=    <img  hspace=2 src="user_man/gbox.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A warped box in a general position can be constructed using the GBOX
-      constructor.
=</b><BR clear=all>
@}
@\label{fig-gbox}
@\end{figure}
$

@\subsubsection{GETATTR}
!GETATTR

@\begin{verbatim}
 AnyType GETATTR( AnyType Obj, StringType Name )
@\end{verbatim}

   provides a mechanism to fetch an attribute named {\bf Name} from object
 {\bf Obj}.

 Example:

@\begin{verbatim}
    attrib( axes, "test", 15 );
    a = GETATTR( axes, "test" );
@\end{verbatim}

 will set the value of {\bf a} to be 15.
$

@\subsubsection{GETLINE}
!GETLINE

@\begin{verbatim}
 AnyType GETLINE( NumericType RequestedType )
@\end{verbatim}

   provides a method to get input from the keyboard within functions and
 or subroutines. {\bf RequestedType} can be a NUMERIC\_TYPE,
 POINT\_TYPE, VECTOR\_TYPE, or PLANE\_TYPE in which the entered line
 will be parsed into one, three, or four numeric values (operated by
 either spaces or commas) and the proper object will be created and
 returned. In any other case, including failure to parse the numeric
 input, a STRING\_TYPE object will be constructed from the entered line.

 Example:

@\begin{verbatim}
    Pt = GETLINE( point_type );
@\end{verbatim}

 to read one point (three numeric values) from stdin.
$

@\subsubsection{GETNAME}
!GETNAME

@\begin{verbatim}
 StringType GETNAME( ListType ListObj, NumericType Index )
@\end{verbatim}

   gets the name of a sub object of index {\bf Index} in list object
 {\bf ListObj}.  Index of the first element is one.

 Example:

@\begin{verbatim}
    A = list( XX, Second, C );
    GETNAME( A, 1 );
@\end{verbatim}

 returns the name of the second element, "Second".

 See also SETNAME.
$

@\subsubsection{GGINTER}
!GGINTER

@\begin{verbatim}
 ListType GGINTER( CurveType Srf1Axis, CurveType Srf1Rad,
                   CurveType Srf2Aixs, CurveType Srf2Rad,
                   NumericType Tolerance, NumericType ZeroSetFunc )
@\end{verbatim}

    computes the intersection curves of the given two ring surfaces,
  defined as spine surfaces with axis SrfiAxis, i = 1, 2 and circular
  cross section along the normal plane of the axis curve with radii
  SrfiRad. 

   The ring ring intersection (RRI) problem is tranformed into a zero set
 finding on another function.  If {\bf ZeroSetFunc} is true, the function
 whose zero set provides the RRIsolution is returned.  Otherwise, if
 {\bf ZeroSetFunc} is false, the RRI solution itself is returned.  The zero
 set is computed via numerical zero set finding methods and {\bf Tolerance}
 controls the fineness of the approximated solution.
@See Figure~\ref{fig-gginter}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/rngrng1.ps, width=3.5in} &
@    \epsfig{file=user_man/rngrng2.ps, width=2.8in}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/rngrng1.gif">
=        <img hspace=2 width=250 src="user_man/rngrng2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computation of the intersection curve between two ring surfaces via
-      the GGINTER command.  On the left, the zero set function is displayed
-      while on the right, the computed intersection between two ocylinders
-      is shown.
=</b><BR clear=all>
@}
@\label{fig-gginter}
@\end{figure}

 Example:

@\begin{verbatim}
    s1 = cylinSrf( 4, 1 ) * tz( -2 );
    c1 = cbezier( list( ctlpt( E3, 0.0, 0.0, -1.0 ),
                        ctlpt( E3, 0.0, 0.0,  1.0 ) ) );
    r1 = cbezier( list( ctlpt( E1, 1.0 ) ) );

    s2 = cylinSrf( 4, 1 ) * tz( -2 ) * rx( 90 ) * tx( 0.5 );
    c2 = cbezier( list( ctlpt( E3, 0.5, -1.0, 0.0 ),
                        ctlpt( E3, 0.5,  1.0, 0.0 ) ) );
    r2 = cbezier( list( ctlpt( E1, 1.0 ) ) );

    ZeroSetSrf = coerce( GGINTER( c1, r1, c2, r2, 10, true ), e3 )
                                                * rotx( -90 ) * roty( -90 );
    resolution = 100;
    ZeroSet = contour( ZeroSetSrf, plane( 0, 0, 1, 0 ) );
    interact( list( ZeroSetSrf * sz( 0.1 ), ZeroSet, axes ) );

    c = nth( GGINTER( c1, r1, c2, r2, 100, false ), 1 );
    interact( list( s1, s2, c ) );
@\end{verbatim}

   constructs two cylinders as {\bf s1} and {\bf s2}, defines the same two
 cylinders as a ring surface with axes spines of {\bf c1} and {\bf c2} and
 a constant radius, one in {\bf r1} and {\bf r2}, and computes the zero set
 of the intersection and the intersection curve itself.
$

@\subsubsection{GPOLYGON}
!GPOLYGON

@\begin{verbatim}
 PolygonType GPOLYGON( GeometryTreeType Object, NumericType Normals )
@\end{verbatim}

   approximates all Surface(s)/Trimmed surface(s)/Trivariate(s) in {\bf Object}
 with polygons using the POLY\_APPROX\_OPT, POLY\_APPROX\_TRI, 
 POLY\_MERGE\_COPLANAR, RESOLUTION and FLAT4PLY variables. 
   If POLY\_APPROX\_OPT is FALSE, RESOLUTION vaguely prescribes the number of
 uniform (in parametric space) samples to sample the surface in each direction.
   If POLY\_APPROX\_OPT is TRUE, POLY\_APPROX\_TOL prescribes the maximal
 deviation of the polygonal approximation from the original surface, in object
 space coordinates.
   IF POLY\_APPROX\_TRI is TRUE, only triangles are generated on the output
 set.
   POLY\_MERGE\_COPLANAR controls the way coplanar adjacent polygons are merged
 into one (or not.)
   FLAT4PLY is a Boolean flag controlling the conversion of an (almost) flat
 patch into four (TRUE) or two (FALSE) polygons.  {\bf Normals} are computed to
 polygon vertices using surface normals, so Gouraud or Phong shading can be
 exploited. It returns a single polygonal object.

   If {\bf Normals} is set, surface normals will be evaluated at the
 vertices. Otherwise flat shading and constant normals across polygons are
 assumed.

 Example:

@\begin{verbatim}
    Polys = GPOLYGON( list( Srf1, Srf2, Srf3 ), off );
@\end{verbatim}

 converts to polygons the three surfaces {\bf Srf1}, {\bf Srf2}, and {\bf Srf3}
 with no normals.  See also POLY\_APPROX\_OPT, POLY\_APPROX\_TOL, 
 POLY\_APPROX\_TRI, POLY\_APPROX\_UV, POLY\_MERGE\_COPLANAR, RESOLUTION and
 FLAT4PLY.
$

@\subsubsection{GPOLYLINE}
!GPOLYLINE

@\begin{verbatim}
 PolylineType GPOLYLINE( GeometryTreeType Object, NumericType Optimal )
@\end{verbatim}

   converts all Curves(s), (Trimmed) Surface(s), and Trivariate(s) {\bf Object}
 into polylines using the RESOLUTION variable. The larger the RESOLUTION is,
 the finer the resulting approximation will be. It returns a single polyline
 object.

   If {\bf Optimal} is false, the points are sampled at equally spaced
 intervals in the parametric space. If {\bf Optimal} true, a better, more
 expensive computationally algorithm is used to derive optimal sampling
 locations so as to minimize the maximal distance between the curve and
 piecewise linear approximation (L infinity norm).

 Example:

@\begin{verbatim}
    Polys = GPOLYLINE( list( Srf1, Srf2, Srf3, list( Crv1, Crv2, Crv3 ) ),
                       on );
@\end{verbatim}

 converts to polylines the three surfaces {\bf Srf1}, {\bf Srf2}, and {\bf Srf3}
 and the three curves {\bf Crv1}, {\bf Crv2}, and {\bf Crv3}.
$

@\subsubsection{HERMITE}
!HERMITE
    
@\begin{verbatim}
 SurfaceType HERMITE( CurveType Bndry1, CurveType Bndry2,
                      CurveType Tan1, CurveType Tan2 )

 or

 CurveType HERMITE( PointType Bndry1, PointType Bndry2,
                    VectorType Tan1, VectorType Tan2 )
@\end{verbatim}

 construct a cubic fit between {\bf Bndry1} and {\bf Bndry2} so that
 first derivative continuity constraints, as prescribed by {\bf Tan1} at
 {\bf Bndry1} and {\bf Tan2} at {\bf Bndry2}, are preserved.

 It returns either a curve or a surface, according to type of input parameters.

 Example:

@\begin{verbatim}
    h00 = HERMITE( point( 0, 0, 0 ),
                   point( 1, 1, 0 ),
                   vector( 1, 0, 0 ),
                   vector( 1, 0, 0 ) );
@\end{verbatim}
 constructs a curve in the shape of the first basis function of the cubic
 Hermite basis functions.  See also BLHERMITE and BLSHERMITE.
$

@\subsubsection{IMPLCTTRANS}
!IMPLCTTRANS

@\begin{verbatim}
 ListType IMPLCTTRANS( 1, ListType ImplicitConicSec, MatrixType Mat )

 or

 ListType IMPLCTTRANS( 2, ListType ImplicitQuadric, MatrixType Mat )
@\end{verbatim}

    transforms a given conic section as the 6 coefficients A-F of:
^     Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0,
@\begin{equation}
      Ax^2 + Bxy + Cy^2 + Dx + Ey + F = 0,
@\end{equation}
 in which case 6 coefficients are expected in {\bf ImplicitQuadric} or
 transforms a given quadric section given as the 10 coefficients A-J,
^     A x^2 + B y^2 + C z^2 + D xy + E xz + F yz + G x + H y + I z + J = 0,
@\begin{equation}
@     A x^2 + B y^2 + C z^2 + D xy + E xz + F yz + G x + H y + I z + J = 0,
@\end{equation}
 using the given transformation matrix {\bf Mat}.
 
    Example:

@\begin{verbatim}
    ImplicitMappedEllipse = IMPLCTRANS( 1, ImplicitEllipse, Mat );
@\end{verbatim}

  See also CONICSEC, QUADRIC, ELLIPSE3PT, MAP3PT2EQL.
$

@\subsubsection{INSTANCE}
!INSTANCE

@\begin{verbatim}
 InstanceType INSTANCE( StringType GeomName, MatrixType Mat );
@\end{verbatim}

 creates an instance of the geometry prescribed by {\bf GeomName} to be
 related to a different position as specified by matrix {\bf Mat}.
 
   The use of instances is advantageous where the same geometry is to be
 displayed/processed in several different locations in space.  A modification
 of the original geometry {\bf Geom} will affect all instances that reference
 it.  The reference is by the original object's {\em name}.  The original
 object can be a single object or a whole hierarchy of objects.

 Example:

@\begin{verbatim}
    Tea1 = INSTANCE( "Teapot", tx( 10 ) );
    Tea2 = INSTANCE( "Teapot", tx( 20 ) );
    Tea3 = INSTANCE( "Teapot", tx( 30 ) );
    viewobj( list( Teapot, Tea1, Tea2, Tea3 ) );
@\end{verbatim}

 will display {\em four} teapots 10 units apart along X.
$

@\subsubsection{IRITSTATE}
!IRITSTATE

@\begin{verbatim}
 AnyType IRITSTATE( StringType State, AnyType Data )
@\end{verbatim}

   sets a state variable in the {\em IRIT} Solid Modeller and returns the
 old value, if applicative. Current supported state variables are:

# 13 3 1 1
 State Name
  Data Type
  Comments
 
 
 
 CmpObjEps
  NumericType
  Sets the epsilon to use to compare two objects.
 CnvxPl2Vrtcs
  NumericType
  TRUE to try and split non convex polygons toward
 
 
  vertices, which is usually more efficient.
 Coplanar
  NumericType
  If TRUE, Coplanar polygons are handled by
 
 
  the Boolean operations.
 CursorKeep
  NumericType
  If TRUE, keep mouse events reported by the
 
 
  display devices for CLNTCRSR to read.
 DebugMalloc
  StringType
  If "Reset", memory allocation is cleared/reset.
 
 
  No "Free unallocated pointer" test after
 
 
  "Reset".  If "Print", all allocated blocks are
 
 
  printed.  Otherwise, used as "address, n": ptr
 
 
  address to search for with abort() called after
 
 
  n mallocs.
 DebugFunc
  NumericType
  $>0$ user func. debug information. $>2$ print params
 
 
  on entry, ret. val. on exit. $>4$ global var. list
 
 
  operations. 
 Dependency
  NumericType
  $0$ for no object dependency propagations, $1$ for
 
 
  automatic dependency propagation, in evaluation.
 DumpLevel
  NumericType
  Bitmask to control the way variables/expressions
 
 
  are dumped. Only object names/types if all 0.
 
 
  Scalars and vectors are dumped if 0x01.
 
 
  Curves and Surfaces are dumped if 0x02.
 
 
  Polygons/lines are dumped if DumpLvl 0x04.
 
 
  List objects are traversed recursively if 0x10.
 
 
  List objects are dumped verbatim if 0x20.
 
 
  Dependency information is dumped if 0x40.
 EchoSource
  NumericType
  If TRUE, IRIT scripts are echoed to stdout.
 FastPolys
  NumericType
  If 0x01, surface polygons are computed fast and
 
 
  are only approximated.  If 0x02, surface normals
 
 
  are computed fast and are only approximated.  If
 
 
  0x01 | 0x02, both are fast and approximated.
 FlatLoad
  NumericType
  If TRUE, the hierarchy of loaded objects is
 
 
  flattened into a linear list.
 FloatFrmt
  StringType
  Specifies a new printf floating point format.
 InterCrv
  NumericType
  If TRUE Boolean operations creates only
 
 
  intersection curves. If FALSE, full Boolean
 
 
  operation results.
 InterpProd
  NumericType
  TRUE for B-spline sym. products via
 
 
  interpolation, FALSE for B-spline sym. products
 
 
  via Bezier.
 LoadFont
  StringType
  Specifies a new IRIT font file to use in
 
 
  TEXTGEOM commands.
 MvNConeTst
  NumericType
  TRUE to use normal cone tests in multivariate
 
 
  zero set finding, FALSE to ignore such tests.
 PolySort
  NumericType
  Axis of Polygon Intersection sweep in Boolean
 
 
  operations: 0 for X axis, 1 for Y axis, 2 for
 
 
  Z axis.
#
# 13 3 1 1
 PrimRatSrfs
  NumericType
  TRUE for rational exact primitive surfaces,
 
 
  FALSE for approximated polynomial (integral)
 
 
  surfaces.  See also PrimSrfs.
 PrimSrfs
  NumericType
  TRUE for primitive construction as freeform
 
 
  surfaces, FALSE for polygonal primitives.
 
 
  See also PrimRatSrfs.
 RandomInit
  NumericType
  Initialize the seed random number generator
 
 
  in IRIT.  See also the RANDOM function.
 TrimCrvs
  NumericType
  Number of samples the higher order trimmed
 
 
  curves are sampled, in piecewise linear
 
 
  approximation.  If zero, computed
 
 
  symbolically as composition.
 UVBoolean
  NumericType
  If TRUE, Boolean between surfaces returns UV
 
 
  instead of Euclidean curves.
 BoolPerturb
  NumericType
  Controls epsilon-pertubation in Booleans.  Zero
 
 
  value to disable.
 GMEpsilon
  NumericType
  Controls the epsilon of the basic geometry processing
 
 
  computation (point on plane etc.)
# 

 Example:

@\begin{verbatim}
    IRITSTATE( "DebugFunc", 3 );
    IRITSTATE( "FloatFrmt", "%8.5lg" );
@\end{verbatim}

 To print parameters of user defined functions on entry, and return value on
 exit. Also selects a floating point printf format of "%8.5lg".
$

@\subsubsection{ISGEOM}
!ISGEOM

@\begin{verbatim}
 ListType ISGEOM( AnyType Obj, NumericType GeomType, NumericType Eps )
@\end{verbatim}

   verifies if the given freeform geometry in {\bf Obj} is a line,
 circle, plane, sphere, surface of revolution, extrusion, ruled surface,
 or a sweep surface, upto some tolerance {\bf Eps}. {\bf GeomType}
 prescribes the type to check for as one of the GEOM\_LINE/CIRCLE etc.
 constants.
   The return value is a list of two objects.  The first is a Boolean value
 with the success/failure of the result.  The second is a list with the
 construction entities of {\bf Obj}, if any.  For example, for a detected
 sphere, the center and radius will be returned.

 Example:

@\begin{verbatim}
    b = nth( ISGEOM( Crv, GEOM_LINE ), 1 ) ||
        nth( ISGEOM( Crv, GEOM_CIRCLE ), 1 );
@\end{verbatim}

 checks if {\bf Crv} is either line or a circle, ignoring the construction
 entities.
$

@\subsubsection{ISOCLINE}
!ISOCLINE

@\begin{verbatim}
 SurfaceType ISOCLINE( SurfaceType Srf, VectorType ViewDir,
                       NumericType Theta, NumericType Euc, NumericType Mode )
@\end{verbatim}

   computes the isocline edges of the given {\bf Srf} from the prescribed
 viewing direction {\bf ViewDir}.  Isocline curves are curves on the surface
 at which location the surface normal forms a fixed angle, {\bf Theta},
 in degrees, with the prescribed viewing direction, {\bf ViewDir}.
   The selection of 90 degrees for {\bf Theta} results in the extraction of
 silhouette edges.  The end result is a piecewise linear approximation of the
 exact isocline edges, and its accuracy is controlled via the RESOLUTION
 variable.
   If{\bf Mode} is zero, the isoclines are simply computed and returned.
 If{\bf Mode} is either -1 or +1, the surface regions with normals with angles
 of less than or great than {\bf Theta} are returned as trimmed surfaces.
 If{\bf Mode} is either -2, the surface regions with normals with angles
 of less than than {\bf Theta} are returned along with ruled surface that
 are stitched along the removed region.  This -2 mode is useful in mold
 design.
   If {\bf Euc} is TRUE, the isocline edges are returned on the surface,
 in Euclidean space.  Otherwise, the isocline edges are returned in the
 parametric space of {\bf Srf}.

 Example:

@\begin{verbatim}
 Resolution = 10;
 Isocs = ISOCLINE( glass, vector( 1, -2, 1 ), 80, true, 0 );
@\end{verbatim}

 computes the isocline edges forming 80 degrees between the surface
 normal and the given viewing direction {\bf (1, -2, 1)} for surface
 {\bf glass}, and returns the isocline edges in the Euclidean space.
 See also SILHOUETTE.
$

@\subsubsection{KNOTCLEAN}
!KNOTCLEAN

@\begin{verbatim}
 CurveType KNOTCLEAN( CurveType Crv, NumericType NormSamples )
@\end{verbatim}

   cleans unnecessary knots from the given curve {\bf Crv}.  The returned
 curve is identical to the given curve, but in, possibly, a sub space with
 less knots.  The L2 norm difference is measured via a discrete set of
 {\bf NormSamples} samples.  Note this function can undo refinement
 operations.
  
@\begin{verbatim}
   c1 = pcircle( vector( 0, 0, 0 ), 1 );
   c1r1 = crefine( c1, FALSE, list( 0.1, 0.3, 0.7, 1.5, 1.7, 1.7, 1.7, 1.7,
                                    2.3, 2.3, 2.7, 3.5, 3.5, 3.5 ) );

   c1r2 = KNOTCLEAN( c1r1, 100 );
   c1 == c1r2;
@\end{verbatim}

 refines a polynomial circle approximation and then restores the original
 curve via the KNOTCLEAN operation.  The last line validates this cleaning.
 See also KNOTREMOVE.
$

@\subsubsection{KNOTREMOVE}
!KNOTREMOVE

@\begin{verbatim}
 CurveType KNOTREMOVE( CurveType Crv, NumericType GlobalLimit,
                       NumericType IterationLimit, NumericType NormSamples )
@\end{verbatim}

   removes knots from curve {\bf Crv} so as to keep the global error less than the
 {\bf GlobalLimit}.  This is an iterative process and in each iteration the
 maximum allowed error is {\bf InterationLimit}.  The error norm is computed
 using a discrete set of {\bf NormSamples} samples.

   The {\bf GlobalLimit} can be positive, in which case the error is measured
 as the distance between the original and reduced curves.  Alternatively,
 {\bf GlobalLimit} can be negative, where it specifically states the number
 of knots to remove.  In all cases the L2 norm is employed.

@\begin{verbatim}
   c1r1 = KNOTREMOVE( c1, -30, 10, 100 );
   c1r2 = KNOTREMOVE( c1, 0.01, 0.002, 100 );
@\end{verbatim}

 Assuming curve ${\bf c1} has 50 knots, this reduces curve {\bf c1}$ to curve
 {\bf c1r1} with 20 knots, by removing up to 10 knots per iteration; curve
 {\bf c1r2} is the curve with the minimum number of knots possible such that the
 global error (distance between {\bf c1} and {\bf c1r2}) is less than 
 {\bf 0.01} and that in each iteration no error larger than {\bf 0.002} is
 introduced.  See also KNOTCLEAN.
$

@\subsubsection{LINTERP}
!LINTERP

@\begin{verbatim}
 ListType LINTERP( ListType PtList)
@\end{verbatim}
 
   computes a least squares fit of a line to a list of points, {\bf PtList}.
 A list of three elements, a point on the fitted line, a unit
 vector in the direction of the line and the average distance between a point
 and the fitted line, is returned.

 Example:
 
@\begin{verbatim}
    R = 10;
    Rx = Random( -1, 1 );
    Ry = Random( -1, 1 );
    Rz = Random( -1, 1 );

    Pts = nil();
    Len = 1.0;
    NumPts = 100;
    for ( i = 1, 1, NumPts,
          Pt = ctlpt( E3, ( Random( -R, R ) + Rx * i * 2 ) / NumPts,
                          ( Random( -R, R ) + Ry * i * -5 ) / NumPts,
                          ( Random( -R, R ) + Rz * i * Pi ) / NumPts ):
          snoc( Pt, Pts ) );
    Pts = Pts * trans( vector( random( -10, -10 ),
                               random( -10, -10 ),
                               random( -10, -10 ) ) );

    LnFit = LINTERP( Pts );
    LnPos = nth( LnFit, 1 );
    LnDir = nth( LnFit, 2 );
    LnErr = nth( LnFit, 3 );
@\end{verbatim}

 randomly samples 100 points to be approximately along a line and computes
 a least squares fit of a line to this data. {\bf LnPos}, {\bf LnDir}, and
 {\bf LnErr} contain a point on the fitted line, the unit direction of the
 fitted line and the average distance between a point and the line,
 respectively.  See also CINTERP and SINTERP.
$

@\subsubsection{LOFFSET}
!LOFFSET
    
@\begin{verbatim}
 CurveType LOFFSET( CurveType Crv, NumericType OffsetDistance,
                    NumericType NumOfSamples, NumericType NumOfDOF,
                    NumericType Order )
@\end{verbatim}

 approximates an offset of {\bf OffsetDistance} by sampling {\bf NumOfSamples}
 samples along the offset curve and least square fitting them using a B-spline
 curve of order {\bf Order} and {\bf NumOfDOF} control points.

 Example:

@\begin{verbatim}
    OffCrv1 = LOFFSET( Crv, -0.4, 100, 10, 4 );
@\end{verbatim}
 See also OFFSET, AOFFSET, and MOFFSET.
$

@\subsubsection{MATDECOMP}
!MATDECOMP

@\begin{verbatim}
 ListType MATDECOMP( MatrixType Mat );
@\end{verbatim}

    decomposes a given homogeneous transformation into its scaling and
 translation vectors, and a pure (orthogonal) rotation matrix.

 Example:

@\begin{verbatim}
    MATDECOMP( rx( 45 ) * sy( 3 ) * sx( 2 ) * tx( 5 ) * ty( 7 ) );
@\end{verbatim}

   would result in the "(2, 3, 1)" scaling vector, "(5, 7, 0)" translation
 vector and a rotation around X matrix of 45 degrees, all in one returned
 list object.
$

@\subsubsection{MAXEDGELEN}
!MAXEDGELEN

@\begin{verbatim}
 PolyType MAXEDGELEN( PolyType Pl, NumericTyoe MaxLen );
@\end{verbatim}

    splits all polygons in polygonal object {\bf Pl} to polygons with
 edges no greater than {\bf MaxLen} in length.

 Example:

@\begin{verbatim}
    PlNew = MAXEDGELEN( Pl, 0.5 );
@\end{verbatim}
$

@\subsubsection{MBEZIER}
!MBEZIER

@\begin{verbatim}
 MultivarType MBEZIER( ListType Orders, ListType CtlPts )
@\end{verbatim}

   creates a Bezier polynomial/rational multivariate out of the
 provided control mesh.  {\bf Orders} is a list of orders whose size
 define the number of dimensions that the multivariate has.
 {\bf CtlPts} is a linear list of control points.  All control points
 must be of type (E1-E9, P1-P9), or regular PointType defining the
 multivariate's control mesh. The multivariate's point type will be 
 of a space which is the union of the spaces of all points.

 Example:

@\begin{verbatim}
 MV = MBEZIER( list( 4 ),
               list( ctlpt( E3, -1,  0.5, 2 ),
                     ctlpt( E1,  3 ),
                     ctlpt( E3,  0, -1.5, 0 ),
                     ctlpt( E2, -1,  3.5 ) ) );
@\end{verbatim}

 constructs a univariate cubic multivariate object. See also MPOWER and
 MBSPLINE
$

@\subsubsection{MBISECTOR}
!MBISECTOR

@\begin{verbatim}
 ListType MBISECTOR( MultivarType MV1, MultivarType MV2, NumericType RetType,
                     NumericType SubdivTol, NumericType NumerTol )
@\end{verbatim}

    computes the bisector surface in R3 of two surfaces or a curve and a
 surface, posed as multivariate functions.

    The returned results depend upon the value of {\bf RetType}.
 If {\bf RetType} = 1, the algebraic constraints are returned as a list of
 multivariates.  If {\bf RetType} = 2, a list of points in R3 on the bisector
 sheet(s) is returned.  If {\bf RetType} = 3, a list of points in (u, v, x, y, z)
 space, as E5 points, is returned, where (u, v) are the respective parameter
 locations of the (must be) surface {\bf MV1}.  These E5 points can then
 directly be employed by SINTERP through which to fit a surface.  Finally,
 if {\bf RetType} = 4, marching cubes is applied to extract a piecewise
 linear approximation of the solution, in Euclidean space.

    This bisector problem is posed as a set of two multivariate algebraic
 constraints with three variables.  The simultaneous solution of these
 constraints is computed using the MZERO function.  See MZERO for the
 meaning of the {\bf SubdivTol} and {\bf NumerTol} tolerances.

 Example:

@\begin{verbatim}
    s1 = sbezier(
            list( list( ctlpt( E3, 0,  0,  0 ),
                        ctlpt( E3, 2,  0,  0 ) ),
                  list( ctlpt( E3, 0,  2,  0 ),
                        ctlpt( E3, 2,  2,  0 ) ) ) ) * tx( -1 ) * ty( -1 );
    color( s1, red );
    
    s2 = sbezier(
            list( list( ctlpt( E3, 0,  0,  2 ),
                        ctlpt( E3, 1,  0,  1 ),
                        ctlpt( E3, 2,  0,  2 ) ),
                  list( ctlpt( E3, 0,  1,  1 ),
                        ctlpt( E3, 1,  1,  0 ),
                        ctlpt( E3, 2,  1,  1 ) ),
                  list( ctlpt( E3, 0,  2,  2 ),
                        ctlpt( E3, 1,  2,  1 ),
                        ctlpt( E3, 2,  2,  2 ) ) ) )* tx( -1 ) * ty( -1 );
    color( s2, magenta );
    
    ms1 = coerce( s1, multivar_type );
    ms2 = coerce( s2, multivar_type );
    
    mb1 = MBISECTOR( ms1, ms2, 3, 0.3, -0.001 );
    b1 = sinterp( mb1, 3, 3, 4, 4, PARAM_UNIFORM );
    
    mb2 = MBISECTOR( ms1, ms2, 2, 0.3, -0.001 );
    
    interact( list( s1, s2, mb2, b1 ) );

    c = cbezier( list( ctlpt( E3,  0,  0,  0 ),
                       ctlpt( E3,  0,  0,  2 ) ) );
    color( c, red );
    
    mc = coerce( c, multivar_type );
    
    mb1 = MBISECTOR( mc, ms1, 3, 0.2, -0.001 );
    b1 = sinterp( mb1, 3, 3, 8, 8, PARAM_UNIFORM );
    
    mb2 = MBISECTOR( mc, ms1, 2, 0.2, -0.001 );

    interact( list( c, s1, mb2, b1 ) );
@\end{verbatim}

 computes two examples of a bisector between a plane and a biquadratic
 surface and between a plane and a line.  The cloud of points is computed
 twice, once interpolated by a surface, and also displayed as is.
@See Figure~\ref{fig-mbisect}.
@\begin{figure}
@\begin{center}
@    \begin{tabular}{cc}
@    \epsfig{file=user_man/mbisect1.ps, width=3in} &
@    \epsfig{file=user_man/mbisect2.ps, width=3in}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/mbisect1.gif">
=        <img hspace=2 width=250 src="user_man/mbisect2.gif">
=    <BR clear=all>
@    \end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A bisector between two surfaces (left) and a plane and
-      a line (right) computed using MBISECTOR.
=</b><BR clear=all>
@}
@\label{fig-mbisect}
@\end{figure}
$

@\subsubsection{MBSPLINE}
!MBSPLINE

@\begin{verbatim}
 MultivarType MBSPLINE( ListType Lengths, ListType Orders,
                        ListType CtlPts, ListType KVLst )
@\end{verbatim}

   creates a Bspline polynomial/rational multivariate out of the provided
 control mesh of lengths {\bf Lengths} and orders {\bf Orders} in each axis.
   The sizes of {\bf Lengths} and {\bf Orders} define the number of dimensions
 that the multivariate has.
   {\bf CtlPts} is a linear list of control points.  All
 control points must be of type (E1-E9, P1-P9), or regular PointType
 defining the multivariate's control mesh. The multivariate's point
 type will be of a space which is the union of the spaces of all
 points.  {\bf KVLst} is a list of knot sequences of the new Bspline
 multivariate.

 Example:

@\begin{verbatim}
 MV = MBSPLINE( list( 3, 3 ), list( 3, 3 ),
                list( ctlpt( E1, 0 ),
                      ctlpt( E2, 0.25, 1 ),
                      ctlpt( E3, 0.5, 0.25, 2 ),
                      ctlpt( E3, 0.5, -1, 3 ),
                      ctlpt( E3, 0.75, 0.25, 4 ),
                      ctlpt( E3, 1, -0.5, 5 ),
                      ctlpt( E3, 1, 0, 6 ),
                      ctlpt( E3, 1.25, 1, 7 ),
                      ctlpt( E3, 1.3, 0.25, 8 ) ),
                list( list( kv_open ),
                      list( kv_open ) ) );
@\end{verbatim}

 constructs a bivariate quadratic multivariate object.  See also MPOWER and
 MBEZIER.
$

@\subsubsection{MDERIVE}
!MDERIVE

@\begin{verbatim}
 MultivarType MDERIVE( MultivarType MV, NumericType Dir )
@\end{verbatim}

   returns a vector field multivariate representing the differentiated
 multivariate {\bf MV}, in the given direction. Evaluation of the
 returned multivariate at a given parameter value will return a vector
 {\em tangent} to {\bf TV} in {\bf Dir} at that parameter value.

@\begin{verbatim}
 DMV = MDERIVE( MV, 2 );
@\end{verbatim}
 
 computes the partial derivative of the multivariate {\bf MV} with respect
 to its second variable.  See also CDERIVE, SDERIVE, and TDERIVE.
$

@\subsubsection{MDIVIDE}
!MDIVIDE
 
@\begin{verbatim}
 MultivarType MDIVIDE( MultivarType MV, ConstantType Direction,
                                                          NumericType Param )
@\end{verbatim}

   subdivides a multivariate into two at the specified parameter value {\bf Param}
 in the specified {\bf Direction}. {\bf MV} can be either a B-spline
 multivariate in which {\bf Param} must be contained in the parametric
 domain of the multivariate, or a Bezier multivariate in which {\bf Param}
 can be arbitrary, extrapolating if not in the range of zero to one.

   It returns a list of the two sub-multivariates. The individual multivariates
 may be extracted from the list using the {\bf NTH} command.

 Example:

@\begin{verbatim}
    MvDiv = MDIVIDE( Mv2, 3, 0.3 );
    Mv2a = nth( MvDiv, 1 ) * tx( -2.2 );
    Mv2b = nth( MvDiv, 2 ) * tx( 2.0 );
@\end{verbatim}

 subdivides {\bf Mv2} at the parameter value of 0.3 in the direction 3 and
 then extracts the two subdivided multivariate.
 See also CDIVIDE, SDIVIDE, and TDIVIDE.
$

@\subsubsection{MERGPOLY}
!MERGEPOLY

@\begin{verbatim}
 PolygonType MERGEPOLY( ListType PolyList )
@\end{verbatim}

 merges a set of polygonal objects in the {\bf PolyList} list to a single polygonal
 object. All elements in the {\bf ObjectList} must be of PolygonType type. This
 function performs the same operation as the overloaded {\bf \verb+^+} operator
 would, but may be more convenient to use under some circumstances.

 Example:

@\begin{verbatim}
    Vrtx1 = vector( -3, -2, -1 );
    Vrtx2 = vector( 3, -2, -1 );
    Vrtx3 = vector( 3, 2, -1 );
    Vrtx4 = vector( -3, 2, -1 );
    Poly1 = poly( list( Vrtx1, Vrtx2, Vrtx3, Vrtx4 ), false ); 
    
    Vrtx1 = vector( -3, 2, 1 );
    Vrtx2 = vector( 3, 2, 1 );
    Vrtx3 = vector( 3, -2, 1 );
    Vrtx4 = vector( -3, -2, 1 );
    Poly2 = poly( list( Vrtx1, Vrtx2, Vrtx3, Vrtx4 ), false );
    
    Vrtx1 = vector( -3, -2, 1 );
    Vrtx2 = vector( 3, -2, 1 );
    Vrtx3 = vector( 3, -2, -1 );
    Vrtx4 = vector( -3, -2, -1 );
    Poly3 = poly( list( Vrtx1, Vrtx2, Vrtx3, Vrtx4 ), false );
   
    PolyObj = MERGEPOLY( list( Poly1, Poly2, Poly3 ) );
@\end{verbatim}
@See Figure~\ref{fig-mergpoly}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/mergpoly.ps, width=4in}
=    <img  hspace=2 src="user_man/mergpoly.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Individual polygons can be merged into a complete model using MERGEPOLY.
=</b><BR clear=all>
@}
@\label{fig-mergpoly}
@\end{figure}
 See also INSERTPOLY, SPLITLST.
$

@\subsubsection{MEVAL}
!MEVAL

@\begin{verbatim}
 CtlPtType MEVAL( MultivarType MV, ListType Params )
@\end{verbatim}

   evaluates the provided multivariate {\bf MV} at the given {\bf Params}
 values. {\bf Params} is a list of NumericTypes of length equal to the
 dimension of the multivariate that must be contained in the multivariate
 parametric domain, if {\bf MV} is a B-spline multivariate, or all between zero
 and one if {\bf MV} is a Bezier multivariate. The returned control point has the
 same type as the control points of {\bf MV}.

 Example:

@\begin{verbatim}
    CPt = MEVAL( MV1, list( 0.1, 0.25, 0.22, 0.7 ) );
@\end{verbatim}

 evaluates the four-variate {\bf MV1} at the parameter values of
 (0.1, 0.25, 0.22, 0.7).
 See also CEVAL, SEVAL, TEVAL.
$

@\subsubsection{MFROMMESH}
!MFROMMESH

@\begin{verbatim}
 MultivarType MFROMMESH( MultivarType MV, MumericType Dir, NumericType Index )
@\end{verbatim}

 extracts a multivariate out of a multivariate, {\bf MV}, as the {\bf Index}'s
 plane of the control mesh of {\bf MV} in direction {\bf Dir}.

 Example:

@\begin{verbatim}
 cmesh( s, row, 2 ) ==
         coerce( MFROMMESH( coerce( s, multivar_type ), 1, 2 ), curve_type );
@\end{verbatim}

 coerces surface {\bf s} to a multivariate, extracts a one-dimensional-less
 multivariate (a curve) from the second direction (first direction is
 direction zero), at index {\bf 2} and compares the result for equality to
 the curve extracted using cmesh from {\bf s}.
$

@\subsubsection{MFROMMV}
!MFROMMV

@\begin{verbatim}
 MultivarType MFROMMV( MultivarType MV, NumericType Dir, NumericType Param )
@\end{verbatim}

   extracts a multivariate of one lower dimension from multivariate {\bf MV} by
 extracting an iso-variate of {\bf MV} in direction {\bf Dir} at parameter
 value {\bf Param}.

 Example:

@\begin{verbatim}
    MVFirst = MFROMMV( MV, 0, FirstParam );
@\end{verbatim}

 extracts a multivariate for one less dimension than {\bf MV} as the
 constant first parameter of {\bf MV} at parameter value {\bf FirstParam}.
 See also STRIVAR, CSURFACE.
$

@\subsubsection{MMERGE}
!MMERGE

@\begin{verbatim}
 MultivarType MMERGE( MultivarType MV1, MultivarType MV2, NumericType Dir,
                      NumericType Discont )
@\end{verbatim}
 
 merges {\bf MV1} and {\bf MV2} together into one multivariate along the
 direction {\bf Dir}.  The first direction starts from zero.  If {\bf Discont},
 the merge is assumed to be along a discontoinuous edge.

 Example:

@\begin{verbatim}
    MVFirst = MMERGE( M1, M2, 2, false );
@\end{verbatim}

 merges {\bf M1} and {\bf M2} along the third direction.
 See also SMERGE,
$

@\subsubsection{MOFFSET}
!MOFFSET

@\begin{verbatim}
 CurveType MOFFSET( CurveType Crv, NumericType OffsetDistance,
                    NumericType AngularError )
@\end{verbatim}

 computes an offset of {\bf OffsetDistance} with a globally bounded error
 (controlled by {\bf AngularError}). The smaller the {\bf AngularError} is, the better
 the approximation to the offset. The bounded error is achieved by adaptive
 refinement of the {\bf Crv}.
   The offset is computed via matching of the tangent fields of the
 given curve {\bf Crv} and an arc spanning the same angular domain.
   Further, {\bf AngularError} measures the angular deviation allowed
 between the two tangent fields.

 Example:

@\begin{verbatim}
    OffCrv1 = MOFFSET( Crv, -0.4, 10 );
    OffCrv2 = MOFFSET( Crv, -0.4, 5 );
@\end{verbatim}

 computes an offset approximation to {\bf Crv} with {\bf OffsetDistance} of
 -0.4 and {\bf AngularError} of 10 and 5 degrees, respectively.
 See also OFFSET, AOFFSET, LOFFSET, and FFMATCH.
$

@\subsubsection{MOMENT}
!MOMENT
    
@\begin{verbatim}
 PointType MOMENT( CurveType Crv, 0 );

 or

 VectorType MOMENT( CurveType Crv, 1 );
@\end{verbatim}

 approximate the zero and first moments of curve {\bf Crv}.

 Example:

@\begin{verbatim}
    a = circle( vector( 0, 0, 0 ), 1 );
    a = cregion( a, 0, 1 );
    p = moment( a, 0 );
    v = moment( a, 1 );
    view(list(a, p, v), on);

    a = cregion( a, 0, 1 ) * rz( 45 );
    p = moment( a, 0 );
    v = moment( a, 1 );
    view(list(a, p, v), on);
@\end{verbatim}

 computes and displays the zero and first moments of a quarter of a circle
 in two orientations.
$

@\subsubsection{MPOWER}
!MPOWER

@\begin{verbatim}
 MultivarType MPOWER( ListType Orders, ListType CtlPts )
@\end{verbatim}

   creates a polynomial/rational multivariate out of the provided control mesh.
   {\bf Orders} is a list of orders whose size define the number of dimensions
 that the multivariate has.
   The created multivariate employs the monomial power basis. {\bf CtlPts} is a
 linear list of control points.
   All control points must be of type (E1-E9, P1-P9), or regular PointType
 defining the multivariate's control mesh. The multivariate's point type
 will be of a space which is the union of the spaces of all points.

 Example:

@\begin{verbatim}
 MV = MPOWER( list( 4 ),
              list( ctlpt( E3, -1,  0.5, 2 ),
                    ctlpt( E3,  3, -1.5, 0 ),
                    ctlpt( E3,  0, -1.5, 0 ),
                    ctlpt( E3, -1,  3.5, 0 ) ) );
@\end{verbatim}

 constructs a univariate cubic multivariate object.  See also MBEZIER and
 MBSPLINE.
$

@\subsubsection{MRAISE}
!MRAISE

@\begin{verbatim}
 MultivarType MRAISE( MultivarType TV,
                      ConstantType Direction,
                      NumericType NewOrder )
@\end{verbatim}

   raises {\bf Srf} to the specified {\bf NewOrder} in the specified
 {\bf Direction}.

 Example:

@\begin{verbatim}
    MV2 = MRAISE( MRAISE( MV2, 0, 4 ), 1, 4 );
@\end{verbatim}

 raises multivariate {\bf MV1} to a cubic in the first and second directions.
 See also TRAISE, SRAISE, and CRAISE.
$

@\subsubsection{MRCHCUBE}
!MRCHCUBE

@\begin{verbatim}
 PolygonType MRCHCUBE( ListType VolumeSpec,
                       PointType CubeDim,
                       NumericType SkipFactor,
                       NumericType IsoVal )
@\end{verbatim}

 applies (a variation of) the marching cubes algorithm (see
 W. E. Lorensen and H. E. Cline. "Marching Cubes: A High Resolution 3D
 Surface Construction Algorithm." Computer Graphics (SIGGRAPH '87
 Proceedings), Vol. 21, No. 4, pp 163-169, July 1987.) to the given
 volumetric data set or trivariate.  {\bf VolumeSpec} can be a list of
 four or five objects as follows:
# 10 2 1 1
 4
  a 4-tuple of the form

  (TrivarType TV, NumericType Axis, NumericType SamplingFactor,

                                             NumericType TVNormal)
 5
  a 5-tuple of the form

  (StringType FileName, NumericType DataType, NumericType Width,

                           NumericType Height, NumericType Depth )
#
 In the first case, the trivariate {\bf TV} is iso surface contoured at level
 {\bf IsoVal} along the prescribed {\bf Axis} (Note a trivariate need not
 be a scalar function, whereas Marching Cubes assumes a scalar function).
   The sampling rate of the trivariate is governed by {\bf SamplingFactor}
 with  {\bf SamplingFactor} equal 1.0 sets sampling rate that equates with
 the dimensions of the trivaariate (control mesh volume size).
   If {\bf TVNormals} is not zero, much more accurate normals are derived using
 the trivariate function though it is also slower.  Otherwise, first order
 differencing on the cubes is employed for normal estimation.

 In the second case, the volume file prescribed by {\bf FileName} is
 loaded and iso surface contoured.  The file is assumed to hold
 {\bf Width * Height * Depth} (Width first, Depth order last) scalar
 numeric values of type {\bf DataType}:
# 10 2 1 1
 1
  Regular float or int ASCII (separated by white spaces)
 2
  Two bytes short integer.
 3
  Four bytes long integer.
 4
  One byte (char) integer.
 5
  Four bytes float.
 6
  Eight bytes double.
#
 Beware of the little vs big Endian problem!  We assume here that you have read
 the volume in the same machine type in which this file was written.

 {\bf CubeDim} allows the user to prescribe the real cell size (not
 necessarily cubical). {\bf SkipFactor} allows the skipping of data in large
 data sets. {\bf SkipFactor} = 1 skips nothing. {\bf SkipFactor} = 2, skips
 every other scalar value, reducing in half all dimensions, etc.
 Last but not least, {\bf IsoVal} sets the iso surface level.

 See also COVERISO, TVLOAD, and TMORPH.

 Example:

@\begin{verbatim}
    IsoSrf = MRCHCUBE( list( ThreeCyls, 1, 1, TRUE ), point( 1, 1, 1 ), 1, 0.12 );
@\end{verbatim}

 iso surface contours the X axis of trivariate {\bf ThreeCyls} and uses
 the trivariate to get better normals' estimations.  Cell size is unit
 cube like, no dat is skipped and the iso surface level is 0.12.
@See Figure~\ref{fig-mrchcube} and also Figure~\ref{fig-coveriso}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/mrchcube.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/mrchcube.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       The result of applying Marching Cubes to a trivariate scalar function
-       using the MRCHCUBE command.
=</b><BR clear=all>
@}
@\label{fig-mrchcube}
@\end{figure}
$

@\subsubsection{MREFINE}
!MREFINE

@\begin{verbatim}
 MultivarType MREFINE( MultivarType TV, ConstantType Direction,
                       NumericType Replace, ListType KnotList )
@\end{verbatim}

   provides the ability to {\bf Replace} a knot vector of {\bf MV} or refine 
 it in the specified direction {\bf Direction}.
   {\bf KnotList} is a list of knots at which to refine {\bf MV}. All knots should be
 contained in the parametric domain of {\bf MV} in {\bf Direction}. If the knot
 vector is replaced, the length of {\bf KnotList} should be identical to the
 length of the original knot vector of {\bf MV} in {\bf Direction}. If {\bf MV}
 is a Bezier multivariate, it is automatically promoted to be a B-spline
 multivariate.

 Example:

@\begin{verbatim}
    MV = MREFINE( MREFINE( MREFINE( MV,
                                    0, FALSE, list( 0.333, 0.667 ) ),
                           1, FALSE, list( 0.333, 0.667 ) ),
                  2, FALSE, list( 0.333, 0.667 ) );
@\end{verbatim}

 refines {\bf MV} in the first three directions by adding two more knots at
 0.333 and 0.667. See also CREFINE, SREFINE, and TREFINE.
$

@\subsubsection{MREGION}
!MREGION

@\begin{verbatim}
 MultivarType MREGION( MultivarType MV, ConstantType Direction,
                       NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   extracts a region of {\bf MV} between {\bf MinParam} and {\bf MaxParam}
 in the specified {\bf Direction}. Both {\bf MinParam} and {\bf MaxParam}
 should be contained in the parametric domain of {\bf MV} in {\bf Direction}.

 Example:

@\begin{verbatim}
    MV1r1 = MREGION( MV1, 3, 0.1, 0.2 );
    MV1r2 = MREGION( MV1, 3, 0.4, 0.6 );
    MV1r3 = MREGION( MV1, 3, 0.99, 1.0 );
@\end{verbatim}

 extracts three regions of {\bf MV1} along the 4th (directions are counted
 from zero) direction.  See also CREGION, SREGION, and TREGION.
$

@\subsubsection{MREPARAM}
!MREPARAM

@\begin{verbatim}
 MultivarType MREPARAM( MultivarType MV, ConstantType Direction,
                        NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   reparametrizes {\bf MV} over a new domain from {\bf MinParam} to {\bf MaxParam},
 in the prescribed {\bf Direction}. This operation does not affect the geometry
 of the multivariate and only affine transforms its knot vectors. A Bezier
 multivariate will automatically be promoted into a B-spline surface by this
 function.

 Example:

@\begin{verbatim}
    MV = MREPARAM( MREPARAM( MV, 0, 0.1, 1.9 ),
                   1, 0.1, 0.9 );
@\end{verbatim}

 ensures that the multivariate {\bf MV} is defined over [0.1, 0.9] in the first
 two directions.  See also CREPARAM, SREPARAM, and TREPARAM.
$

@\subsubsection{MREVERSE}
!MREVERSE

@\begin{verbatim}
 MultivarType MREVERSE( MultivarType MV, NumericType Dir1, NumericType Dir2 )
@\end{verbatim}

   reverses {\bf MV} by flipping the given two parametric directions, {\bf Dir1}
 and {\bf Dir2}, (starting to count directions from zero).

 Example:

@\begin{verbatim}
  RevMV = MREVERSE( MV, 2, 4 );
@\end{verbatim}

   reverses {\bf MV} by flipping the third and fifth directions of {\bf MV}.
 See also SREVERSE.
$

@\subsubsection{MSCIRC}
!MSCIRC

@\begin{verbatim}
 CurveType MSCIRC( PolyType Poly, ListType Tols )

 or

 CurveType MSCIRC( ListType Geom, ListType Tols )

 or
 
 SurfaceType MSCIRC( ListType Geom, ListType Tols )
@\end{verbatim}

    computes a minimum spanning circle to polyline(s) (first form), or to
 a list of points or curves (second form) or a list of vector (third form).
    Note in the third form, a minimum spanning cone of the given list of
 vectors is returned.
    {\bf Tols} is a list of two numeric values, SubdivTol and NumerTol, that
 are used only if the minimum spannng circle of a set of curves is required.
    See MZERO for the meaning of the {\bf SubdivTol} and {\bf NumerTol}
 tolerances.
    The returned circle will have 'center' and 'radius' attributes with the
 circles parameters.  If a cone is returned, 'angle' and 'center' of the cone
 will be returned.

  Example:

@\begin{verbatim}
    Msc = MSCIRC( Crvs, list( 0.01, 1e-10 ) ):
@\end{verbatim}

@See Figure~\ref{fig-mscirc}.
=See figure for minimum spanning circle of curves.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/mscirc.ps, width=6in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/mscirc.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      The minimum spanning circle of a set of planar curves is computed with
-      the aid of MSCIRC.  Two examples are shown.
=</b><BR clear=all>
@}
@\label{fig-mscirc}
@\end{figure}
$

@\subsubsection{MVEXPLICIT}
!MVEXPLICIT

@\begin{verbatim}
 MultivarType MVEXPLICIT( NumericType Dim, StringType Expression )
@\end{verbatim}

   constructs a multivariate power basis from the given polynomial
 {\bf Expression}. The {\bf Expression} can be any infix notational expression
 using \verb=+-/*^= with no parenthesis.  The parameters are the 26 letters A-Z.
   The dimension of the multivariate is set by {\bf Dim} and should be in line
 with the variables used.  A stands for the first dimension, B for the second,
 etc., so if {\bf Dim} equal 3, only A, B, and C could appear in {\bf Expression}.
   Having a higher letter with a lower dimension constitutes an error.

 Example:

@\begin{verbatim}
  M1 = coerce( mvexplicit( 2, "A^2 + B^2 - 1" ), bezier_type );
  M2 = coerce( mvexplicit( 2, "4 * A^2 + B^2 / 4 - 1" ), bezier_type );
@\end{verbatim}

   constructs two scalar saddle Bezier bivariate surfaces, represented as
 multivariates.
$

@\subsubsection{MZERO}
!MZERO

@\begin{verbatim}
 ListType MZERO( ListType MVs, NumericType SubdivTol, NumericType NumerTol )
@\end{verbatim}

 computes the simultaneous zeros of several scalar multivariate functions, in
 {\bf MVs}.  {\bf SubdivTol} specifies the subdivision tolerance in the
 parametric domain of the multivariates, whereas {\bf NumerTol} prescribes the
 tolerance of the numerical improvement stage.  A numerical improvement stage
 is applied if |{\bf NumerTol}| < {\bf SubdivTol}.  If {\bf NumerTol} is
 negative, and a numeric improvement stage is indeed applied, all points that
 fail to improve to the requested accuracy are purged away.
 
   A list of control points, each designating one location in the
 parameter space of the multivariates, is returned.
 
   The number of multivariates cannot exceed the dimension of the
 multivariates.  That is, if the {\bf MVs} are trivariates, then, at most, three
 of them may be provided.  If less are provided, then the dimension of the
 solution space is larger than zero and a finite cloud of points
 sampled from that solution space will be returned.

 Example:

@\begin{verbatim}
  ZeroMVs = MZERO( list( MV1, MV2, MV3 ), 0.01, -1e-6 );
@\end{verbatim}.

 See also CONTOUR.  See MZERO for the meaning of {\bf SubdivTol} and
 {\bf NumerTol}.
$

@\subsubsection{MPROMOTE}
!MPROMOTE

@\begin{verbatim}
 PromMV = MPROMOTE( MultivarType MV, ListType AddDir );
 
 or
 
 PromMV = MPROMOTE( MultivarType MV, ListType NewDimStartAxis );
@\end{verbatim}

 promote the multivariate {\bf MV} to a higher dimension. In the first form
 (a list of one numeric value), the multivariate will be promoted to have one
 more dimension (i.e. a bivariate would become a trivariate).  The new added
 axis will be {\bf AddDir}.

   The second form (a list of two numeric values) allows the original
 multivariate to be placed at axes from {\bf StartAxis} and have a new
 dimensional {\bf NewDim}.
 
 Example:
 
@\begin{verbatim}
 ms = coerce( srf, multivar_type );
 coerce( mfrommv( MPROMOTE( ms, list( 0 ) ), 0, 0.5 ), surface_type ) == srf;
@\end{verbatim}

 coerces a surface to a multivariate, promotes it to a trivariate-multivariate,
 extracts an iso-surface bivariate-multivariate along the new introduced axis
 from the trivariate-multivariate and compares it to the original surface.  It
 should be equal!
$

@\subsubsection{NIL}
!NIL

@\begin{verbatim}
 ListType NIL()
@\end{verbatim}

   creates an empty list so data can be accumulated in it.
 See CINFLECT or CZEROS for examples. See also LIST and SNOC.
$

@\subsubsection{OFFSET}
!OFFSET

@\begin{verbatim}
 PolygonType OFFSET( PolygonType Poly, NumericType OffsetDistance,
                     NumericType Tolerance, NumericType BezInterp )

 or

 CurveType OFFSET( CurveType Crv, NumericType OffsetDistance,
                   NumericType Tolerance, NumericType BezInterp )

 or

 CurveType OFFSET( CurveType Crv, CurveType OffsetDistance,
                   NumericType Tolerance, NumericType BezInterp )

 or

 SurfaceType OFFSET( SurfaceType Srf, NumericType OffsetDistance,
                     NumericType Tolerance, NumericType BezInterp )

 or

 TrimSrfType OFFSET( TrimSrfType TrimSrf, NumericType OffsetDistance,
                     NumericType Tolerance, NumericType BezInterp )
@\end{verbatim}

 offset {\bf Poly}, {\bf Crv}, {\bf Srf} or a {\bf TrimSrf}, by translating
 all the (control) points in the direction of the normal of the poly/curve
 or of the (trimmed) surface by an {\bf OffsetDistance} amount.
   For a {\bf Poly} object, the result is an offset of the original polygon/line
 in the XY plane and is exact. Hence, {\bf Tolerance} and {\bf BezInterp}
 parameters are ignored.  The result is a mitter joint based offset.
   Otherwise, each control point has a {\em node} parameter value associated with
 it, which is used to compute the normal. The returned curve or surface only
 approximates the real offset. If the resulting approximation does not satisfy
 the accuracy required by {\bf Tolerance}, {\bf Crv} or {\bf Srf} or
 {\bf TrimSrf} is subdivided and an offset approximation fit is computed for
 the two halves. For curves, one can request a Bezier interpolation scheme in
 the offset approximation by setting {\bf BezInterp}. {\bf BezInterp} is
 not yet supported for (trimmed) surfaces.
   Negative {\bf OffsetDistance} denotes offset in the reversed direction of the
 normal.
   If {\bf OffsetDistance} is a (scalar) curve, the curve's first coordinate
 is used to prescribe a variable offset amount along the curve for which we
 compute the variable offset.  Both {\bf Crv} and {\bf OffsetDistance} must share
 the same parametric domain.

 Example:

@\begin{verbatim}
    OffCrv = OFFSET( Crv, -0.4, 0.1, off );
@\end{verbatim}

 offsets {\bf Crv} by the amount of $-0.4$ in the reversed normal direction,
 {\bf Tolerance} of 0.1 and no Bezier interpolation.
 See also AOFFSET, LOFFSET and MOFFSET.
@See Figure~\ref{fig-coffset}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/coffset.ps, width=4in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/coffset.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Offset approximation (thick) of a B-spline curve (thin).
@      (See also Figure~\protect\ref{fig-caoffset}.)
=</b><BR clear=all>
@}
@\label{fig-coffset}
@\end{figure}
$

@\subsubsection{ORTHOTOMC}
!ORTHOTOMC

@\begin{verbatim}
 CurveType ORTHOTOMC( CurveType Crv, PointType Pt, NumericType K )

 or,

 SurfaceType ORTHOTOMC( SurfaceType Srf, PointType Pt, NumericType K )
@\end{verbatim}

 compute the K-orthotomic of freeform curves and surfaces.  See
 Fundamentals of Computer Aided Geometric Design, by J. Hoschek and
 D. Lasser.   
@A K-orthotomic equal,
@\begin{equation}
@    Pt + K \left< (F - Pt), N \right> N,
@\end{equation}
@where F is the curve or surface and N is its unit normal field.

 Example:

@\begin{verbatim}
    pt = point( 0, 0.35, 0 );
    crv = cbezier( list( ctlpt( E2, -0.8, -0.6 ),
                         ctlpt( E2, -0.3, -0.2 ),
                         ctlpt( E2,  0.0,  0.0 ),
                         ctlpt( E2,  0.8, -0.6 ) ) );
    Orth = ORTHOTOMC( crv, pt, 2 );
    interact( list( Orth, crv, pt ) * tx( 0.5 ) ) );
@\end{verbatim}

 computes the orthotomic of a cubic Bezier curve that has an inflection
 point.  Note that inflection points are reduced to cusps in the orthotomic
 result.
@See Figure~\ref{fig-orthotomc}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/orthotmc.ps, width=4in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/orthotmc.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      An orthotomic (thick) of a cubic Bezier curve.  The inflection
-      point in the cubic Bezier is reduced to a cusp in the orthotomic.
-      Computed using the ORTHOTOMC command.
=</b><BR clear=all>
@}
@\label{fig-orthotomc}
@\end{figure}
$

@\subsubsection{PATTRIB}
!PATTRIB

@\begin{verbatim}
 AnyType PATTRIB( PolyType Poly, NumericType Index,
                  StringType Name, AnyType Value )
@\end{verbatim}

   provides a mechanism to set/get an attribute to a vertex of a polygon.
   Unlike the regular ATTRIB/RMATTR functions, PATTRIB allows access to the
 {\bf Index} vertex in polygon {\bf Poly}, access that is otherwise impossible.
 {\bf Index} starts at zero for the first vertex.
   The attribute will have a name {\bf Name} and a value {\bf Value}.  If {\bf Value}
 is NIL(), no attributes are set and the named attribute, if any, is returned.
   This PATTRIB function only allows numeric values or strings as {\bf Value}.

 For example,

@\begin{verbatim}
    PATTRIB( Tri, 0, "rgb", "255,0,0");
    PATTRIB( Tri, 1, "rgb", "0,255,0");
    PATTRIB( Tri, 2, "rgb", "0,0,255");
@\end{verbatim}

 sets the RGB values of the three vertices of triangle {\bf Tri}.
 See also PNORMAL, ATTRIB, ATTRPROP, GETATTR, RMATTR, CPATTR.
$

@\subsubsection{PCIRCLE}
!PCIRCLE

@\begin{verbatim}
 CurveType PCIRCLE( VectorType Center, NumericType Radius )
@\end{verbatim}

 is the same as CIRCLE but approximates the circle as a {\em polynomial} curve.
 See also CIRCLE.
$

@\subsubsection{PCRVTR}
!PCRVTR

@\begin{verbatim}
 PolyType PCRVTR( PolyType Pl, NumericType NumOfRings, NumericType CubicFit )
@\end{verbatim}

   estimates curvature properties of given polygonal model {\bf Pl}, assuming
 {\bf Pl} originated from a continuous freeform surfaces. {\bf NumOfRings}
 sets the number of rings around a vertex that will be used to estimate the
 curvature properties of the vertex.  If ({\bf CubicFit} is TRUE, a cubic
 fit is computed to the local vertex neighborhood, or a quadratic fit, if
 FALSE.
   The return polygonal object is identical to {\bf Pl}, but with the
 following attributes set at each vertex:

# 17 2 0 1
 "K1Curv"
  First principal curvature value
 "K2Curv"
  Second principal curvature value
 "KCurv"
  The Gaussian Curvature
 "HCurv"
  The Mean Curvature
 "D1"
  The first principal direction
 "D2"
  The second principal direction
#

   See also PPROPFTCH.
$

@\subsubsection{PDECIMATE}
!PDECIMATE

@\begin{verbatim}
 PolygonType PDECIMATE( PolygonType Obj, NumericType DecimType,
                        NumericType Threshold )
@\end{verbatim}

 Given a polygonal model, {\bf Obj}, decimate and merge polygons, effectively
 reducing the size of the data subject to a maximal deviation distance as
 controlled via {\bf Threshold} and {\bf DecimType}.  {\bf DecimType} can be
 either TRUE when {\bf Threshold} has a continuous zero to one control over
 the output size or FALSE when {\bf Threshold} prescribes the exact number of
 polygons desired.

 Example:

@\begin{verbatim}
    gcross = cbspline( 3,
                       list( ctlpt( E3, 0.3, 0.0, 0.0 ),
                             ctlpt( E3, 0.1, 0.0, 0.1 ),
                             ctlpt( E3, 0.1, 0.0, 0.4 ),
                             ctlpt( E3, 0.5, 0.0, 0.5 ),
                             ctlpt( E3, 0.6, 0.0, 0.8 ) ),
                       list( KV_OPEN ) );
    resolution = 30;
    glass = surfprev( gcross );
    
    pglass = gpolygon( glass, false );
    
    dglass = PDECIMATE( pglass, false, 0.5 );
@\end{verbatim}

 creates a surface of a glass, approximates it with polygons and then
 decimates the latter.
@See Figure~\ref{fig-decimate} for the original and decimated polygonal glass.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/pdecimat.ps, width=5in}
=    <img  hspace=2 src="user_man/pdecimat.gif">
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A polygonal object (left) can be decimated and reduced (right) to
-      within a given tolerance by using PDECIMATE.
=</b><BR clear=all>
@}
@\label{fig-decimate}
@\end{figure}
$

@\subsubsection{PDOMAIN}
!PDOMAIN

@\begin{verbatim}
 ListType PDOMAIN( FreeformType Freeform )
@\end{verbatim}

   returns the parametric domain of the given {\bf Freeform}.
 See also MESHSIZE, FFCTLPTS, FFKNTVEC, FFMESH, FFMSIZE, FFPTTYPE, FFORDER.

 Example:

@\begin{verbatim}
 circ_domain = PDOMAIN( circle( vector( 0.0, 0.0, 0.0 ), 1.0 ) );
@\end{verbatim}
$

@\subsubsection{PIMPRTNC}
!PIMPRTNC

@\begin{verbatim}
 PolyType PIMPRTNC( PolyType Pl, NumericType GenImprtncPolylines )
@\end{verbatim}

   computes the importance of a local neighborhood in a triangular polygonal
 mesh {bf Pl}, based on the dihedral angles of the edges in that neighborhood.
   If {\bf GenImprtncPolylines} FALSE, every vertex in the returned mesh will
 have a "SilImp" (See the connection of this importance to silhouettes?)
 attribute with its importance.  Otherwise, if {\bf GenImprtncPolylines} TRUE,
 polylines that stylistically convey the importance of the different regions
 in this mesh are returned.

  Example:

@\begin{verbatim}
   Pl = triangl( box( vector( 0, 0, 0 ), 1, 2, 3 ), 1 );
   PlImp = PIMPRTNC( Pl, 0 );
@\end{verbatim}
$

@\subsubsection{PLANE}
!PLANE

@\begin{verbatim}
 PointType PLANE( NumericType A, NumericType B, NumericType C, NumericType D )
@\end{verbatim}

   creates a plane type object, using the four provided NumericType
 coefficients. See also VECTOR, POINT.
$

@\subsubsection{PLANECLIP}
!PLANECLIP

@\begin{verbatim}
 ListType PLANECLIP( PolyType Poly, PlaneType Pln )
@\end{verbatim}

   clips a polygonal model {\bf Poly} against a plane {\bf Pln}.
 Three polygonal objects are returned in a list: polygons on the positive side
 of the plane, polygons that intersect the plane, and polygons on the negative
 side of the plane, in this order.
   If one of these lists is empty, a numeric zero is substituted.

 Example:

@\begin{verbatim}
 Pls = PLANECLIP( Pl, plane( 1, 1, 0, 0 ) );
@\end{verbatim}

 clips polygonal object {\bf Pl} against the plane X+Y=0.
$

@\subsubsection{PLN3PTS}
!PLN3PTS

@\begin{verbatim}
 PlaneType PLN3PTS( PointType Pt1, PointType Pt2, PointType Pt3 )
@\end{verbatim}

   computes a plane out of three points.

 Example:

@\begin{verbatim}
 Pl1 = PLN3PTS( point( 0, 0, 0 ), point( 0, 1, 0 ), point( 1, 0, 0 ) );
@\end{verbatim}
$

@\subsubsection{PMORPH}
!PMORPH

@\begin{verbatim}
 PlaneType PMORPH( PolyType Pl1, PolyType Pl2, NumericType Blend )
@\end{verbatim}

 creates a new polygonal object which is a {\em metamorph} of the two given
 polygonal objects that share the same topology.  That is, {\bf Pl1} and {\bf Pl2}
 must share the same number of polygons and the i'th polygon in {\bf Pl1} must
 be equal in its number of vertices to the i'th polygon of {\bf Pl2}.
   This is very useful if a sequence that "morphs" one polygonal model to
 another is to be created.


 Example:

@\begin{verbatim}
 Pl1 = con2( vector( 0.0, -0.5, -0.5 ), vector( 0.0, 0.0, 1.0 ), 0.4, 0.1, 3 );
 Pl2 = con2( vector( 0.0, 0.5, 0.0 ), vector( 0.0, 0.0, 1.0 ), 0.1, 0.4, 3 );
 Pl = PMORPH( Pl1, Pl2, 0.5 );
@\end{verbatim}

 creates a cylinder out of two truncated cones, using PMORPH.  See also
 CMORPH and SMORPH.
$

@\subsubsection{PNORMAL}
!PNORMAL

@\begin{verbatim}
 PointType PNORMAL( PolyType Poly, NumericType Index, VectorType Normal )
@\end{verbatim}

   provides a mechanism to set/get the normal of vertex number {\bf Index}
 in a polygon {\bf Poly}.  {\bf Index} starts at zero for the first vertex.
   {\bf Normal} replaces the current normal that is also returned.  If
 {\bf Normal} is not a VectorType, no new normal is set but the current
 normal is still returned, allowing normals to be queried.

 For example,

@\begin{verbatim}
    PNORMAL( Tri, 0, vector( 1, 0, 0 ) );
    PNORMAL( Tri, 1, vector( 0, 1, 0 ) );
@\end{verbatim}

 sets the normals of the first two vertices in triangle {\bf Tri} to be
 the X and Y axes, respectively.

 See also PATTRIB.
$

@\subsubsection{POINT}
!POINT

@\begin{verbatim}
 PointType POINT( NumericType X, NumericType Y, NumericType Z )
@\end{verbatim}

   creates a point type object, using the three provided NumericType scalars.
   See also VECTOR, PLANE.
$

@\subsubsection{POLARSIL}
!POLARSIL

@\begin{verbatim}
 PolygonType POLARSIL( SurfaceType Srf, VectorType ViewDir,
                       NumericType EuclideanSpace )
@\end{verbatim}

    computes the polar silhouettes of surface {\bf Srf} from view direction
 {\bf ViewDir}.  if {\bf EuclideanSpace} TRUE, the polar silhouettes are
 returned in Euclidean space, over {\bf Srf}.  Otherwise, the polar silhouettes
 are returned in the parametric domain of {\bf Srf}.

 Example:

@\begin{verbatim}
   pSil = polarsil( glass, vector( 1, 0, 0 ), true );
@\end{verbatim}

@See Figure~\ref{fig-polarsil} for this example.
=See figure for this example.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/polarsil.ps, width=3in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/polarsil.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Polar silhouette computed for this glass shaped surface using the
-      POLARSIL 
=</b><BR clear=all>
@}
@\label{fig-polarsil}
@\end{figure}
$

@\subsubsection{POLY}
!POLY

@\begin{verbatim}
 PolygonType POLY( ListType VrtxList, NumericType IsPolyline )
@\end{verbatim}

   creates a single polygon/polyline (and therefore open) object, defined by
 the vertices in {\bf VrtxList} (see LIST). All elements in {\bf VrtxList}
 must be one of PointType, VectorType, CtlPtType, or PolygonType types.
 If {\bf IsPolyline}, a polyline is created; otherwise, a polygon.

 Example:

@\begin{verbatim}
    V1  = vector( 0.0, 0.0, 0.0 );
    V2  = vector( 0.3, 0.0, 0.0 );
    V3  = vector( 0.3, 0.0, 0.1 );
    V4  = vector( 0.2, 0.0, 0.1 );
    V5  = vector( 0.2, 0.0, 0.5 );
    V6  = vector( 0.3, 0.0, 0.5 );
    V7  = vector( 0.3, 0.0, 0.6 );
    V8  = vector( 0.0, 0.0, 0.6 );
    V9  = vector( 0.0, 0.0, 0.5 );
    V10 = vector( 0.1, 0.0, 0.5 );
    V11 = vector( 0.1, 0.0, 0.1 );
    V12 = vector( 0.0, 0.0, 0.1 );
    I = POLY( list( V1, V2, V3, V4, V5, V6, V7, V8, V9, V10, V11, V12 ),
              FALSE );
@\end{verbatim}

 constructs an object with a single polygon in the shape of the letter I.
@See Figure~\ref{fig-poly}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/poly.ps, width=3in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/poly.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Polygons or polylines can be manually constructed using the
-      POLY constructor.
=</b><BR clear=all>
@}
@\label{fig-poly}
@\end{figure}
$

@\subsubsection{PPINTER}
!PPINTER

@\begin{verbatim}
 ListType PPINTER( PolyType Pl1, PolyType Pl2 )
@\end{verbatim}

 computes the intersection of two individual polygons in R3, {\bf Pl1} and
 {\bf Pl2}.  Similar results can also be obtained via Boolean operations.

 Example:

@\begin{verbatim}
    Pl1 = poly( list( point( -1, -1, 0 ),
                      point( -1,  1, 0 ),
                      point(  1,  1, 0 ),
                      point(  1, -1, 0 ) ), false );
    Pl2 = Pl1 * rx( 70 ) * tx( 0.5 );

    Inter1 = PPINTER( Pl1, Pl2 );

    iritstate( "intercrv", true );
    Inter2 = Pl1 * Pl2;
@\end{verbatim}

 computes the intersection edge of two polygons in two different ways. Note,
 however, that while {\bf PPINTER} considers only the first polygon in a
 polygonal object, the Boolean operations considers them all. 
$

@\subsubsection{PPROPFTCH}
!PPROPFTCH

@\begin{verbatim}
 PolyType PPROPFTCH( PolyType Pl, NumericType PropType, ListType PropParam )
@\end{verbatim}

   computes piecwise linear curves over polygonal mesh {\bf Pl}.  The extracted
 curves could be one of,
# 16 3 0 1
 Property
  {\bf PropType}
  {\bf PropParam}
 Attribute Value
  0
  list( AttrName, AttrValue )
 Isophotes
  1
  list( ViewDir, InclinationAngle )
 Gaussian Crvtr
  2
  list( NumRingCrvtrAprx, CrvtrVal )
 Mean Crvtr
  3
  list( NumRingCrvtrAprx, CrvtrVal )
#

   The NumRingCrvtrAprx specifies how many rings around a vertex should be
 considered when the curvature of the vertex is estimated.  Typically 1.

 Example:

@\begin{verbatim}
  Pl1 = PPropFtch( Srf, 1, list( normalize( vector( 1,  1, 1 ) ), 90 ) );
  Pl2 = PPropFtch( Srf, 1, list( normalize( vector( 1, -1, 1 ) ), 90 ) );
  Pl3 = PPropFtch( Srf, 1, list( normalize( vector( 1,  0, 1 ) ), 90 ) );
@\end{verbatim}

 extracts silhouettes from surface {\bf Srf} (note an InclinationAngle of 90
 degrees extract silhouettes), from three different viewing direction.
   See also PCRVTR, SILHOUETTE, ISOCLINE, PPROPFTCH and SASPCTGRPH.
$

@\subsubsection{PRINTER}
! PRINTER

@\begin{verbatim}
 ListType PRINTER( PolyType Pl, NumericType RayPt, NumericType RayDir )
@\end{verbatim}

   computes the number of XY planar intersection of ray ({\bf RayPt, RayDir})
 with a single polygon {\bf Pl}.  Returned is the number of interesections
 found.
$

@\subsubsection{PRISA}
!PRISA

@\begin{verbatim}
 ListType PRISA( SurfaceType Srfs, NumericType SamplesPerCurve,
                 NumericType Epsilon, ConstantType Dir, VectorType Space,
                 NumericType CrossSecs )
 
 or
 
 ListType PRISA( TrimSrfType TrimSrfs, NumericType SamplesPerCurve,
                 NumericType Epsilon, ConstantType Dir, VectorType Space,
                 NumericType CrossSecs )
@\end{verbatim}

   compute a layout (prisa) of the given surface(s) {\bf Srfs} or {TrimSrfs},
 and return a list of (trimmed) surface objects representing the layout.
   The surface is approximated to within {\bf Epsilon} in direction {\bf Dir}
 into a set of ruled surfaces, and then developable surfaces that are laid out
 flat onto the $XY$ plane. If {\bf Epsilon} is negative, the piecewise ruled
 surface approximation in 3-space is returned. 
   {\bf SamplesPerCurve} controls the piecewise linear approximation of the
 boundary of the ruled/developable surfaces. {\bf Space} is a vector whose
 X component controls the space between the different surfaces' layout, and
 whose Y component controls the space between different layout pieces.
   If {\bf CrossSecs} is not zero, the 3D cross sections, approximated as
 planar, of each laid out region are also provided.

 Example:

@\begin{verbatim}
 cross = cbspline( 3,
                   list( ctlpt( E3, 0.7, 0.0, 0. ),
                         ctlpt( E3, 0.7, 0.0, 0.06 ),
                         ctlpt( E3, 0.1, 0.0, 0.1 ),
                         ctlpt( E3, 0.1, 0.0, 0.6 ),
                         ctlpt( E3, 0.6, 0.0, 0.6 ),
                         ctlpt( E3, 0.8, 0.0, 0.8 ),
                         ctlpt( E3, 0.8, 0.0, 1.4 ),
                         ctlpt( E3, 0.6, 0.0, 1.6 ) ),
                   list( KV_OPEN ) );
 wglass = surfrev( cross );
 wgl_ruled = PRISA( wglass, 6, -0.1, COL, vector( 0, 0.25, 0.0 ), false );
 wgl_prisa = PRISA( wglass, 6, 0.1, COL, vector( 0, 0.25, 0.0 ), true );
@\end{verbatim}

 computes a layout of a wine glass in {\bf wgl\_prisa} and a three-dimensional
 ruled surface approximation of wglass in {\bf wgl\_ruled}.
@See Figure~\ref{fig-prisa}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/prisa.ps, width=6in}
=    <img  hspace=2 src="user_man/prisa.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-   The layout (prisa in hebrew...) of a freeform surface can be approximated
-   using the PRISA function.
=</b><BR clear=all>
@}
@\label{fig-prisa}
@\end{figure}
$

@\subsubsection{PT3BARY}
!PT3BARY

@\begin{verbatim}
 VectorType PT3BARY( PointType Pt1, PointType Pt2, PointType Pt3,
                     PointType InteriorPt )
@\end{verbatim}

   computes the barycentric coordinates of {\bf InterPt} with respect
 to the triangle defined by {\bf Pt1}, {\bf Pt2}, {\bf Pt3}.  
 A vector of three coefficents, which are the weights of the three
 points of the triangle, are returned. {\bf InteriorPt} is assumed to be in the
 triangle.

 Example:

@\begin{verbatim}
 Coeffs = PT3BARY( point( 0, 0, 0 ),
                   point( 1, 0, 0 ),
                   point( 0, 1, 0 ),
                   point( 0.25, 0.25, 0.0 ) );
@\end{verbatim}
$

@\subsubsection{PTHMSPR}
!PTHMSPR

@\begin{verbatim}
 ListType PTHMSPR( NumericType Size )
@\end{verbatim}

 computes a fairly uniform distribution of points on a hemisphere.
 {\bf Size} hints at the distance between adjacent placed points.

 Example:

@\begin{verbatim}
 Pts = PTHMSPR( 0.1 );
@\end{verbatim}
$

@\subsubsection{PTLNPLN}
!PTLNPLN

@\begin{verbatim}
 VectorType PTLNPLN( PointType LineOrig, VectorType LineRay, PlaneType Plane )
@\end{verbatim}

   computes the point of intersection of given line {\bf LineOrig},
 {\bf LineRay} with plane {\bf Plane}.

 Example:

@\begin{verbatim}
 InterPt = PtLnPln( point( 1, 0, 1 ), vector( 1, 1, 1 ), Plane( 0, 0, 1, 0 ) );
@\end{verbatim}
$

@\subsubsection{PTPTLN}
!PTPTLN

@\begin{verbatim}
 VectorType PTPTLN( PointType Point, PointType LineOrig, VectorType LineRay )
@\end{verbatim}

   computes the point on line {\bf LineOrig}, {\bf LineRay} that is closest
 to point {\bf Point}.  See also DSTPTLN.

 Example:

@\begin{verbatim}
 ClosestPt = PTPTLN( point( 0, 0, 0 ), point( 1, 1, 0 ), vector( 1, 1, 1 ) );

@\end{verbatim}
$

@\subsubsection{PTREGISTER}
!PTREGISTER

@\begin{verbatim}
 MatrixType PTREGISTER( ListType PtSet1, ListType PtSet2,
                        NumericType StepSize, NumericType Tolerance )
@\end{verbatim}

   registers one points set, {\bf PtSet1}, with another, {\bf PtSet2}.
 The two points sets are assumed to be rigid motion of one another.
 {\bf StepSize} controls the step size of the numerical process and must be
 a positive real less than 1.0.  The larger  {\bf StepSize} is, the faster the
 convergance with less stability. Finally, {\bf Tolerance} prescribes the
 necessary accuraacy in L-infinity sense.  This function will converge for
 small rotational deviations only.

@\begin{verbatim}
    Pt1 = nil();
    for (i = 0, 1, 15,
        Pt = point( random( -.7, .7 ), random( -.7, .7 ), random( -.7, .7 ) ):
        snoc( Pt * tx( 0 ), Pt1 ) );
    Pt2 = Pt1 * rx( 13 ) * ry( 5 ) * rz( 11 )
              * tx( 0.1 ) * ty( 0.03 ) * tz( -0.05 );
    Tr = PTREGISTER( Pt1, Pt2, 1, 1e-6 );
@\end{verbatim}
$

@\subsubsection{PTS2PLLN}
!PTS2PLLN

@\begin{verbatim}
 ListType PTS2PLLN( ListType Points, NumericType MaxMatchDist )
@\end{verbatim}

   matches the given cloud of points in a list of polylines.
 {\bf MaxMatchDist} is used as the maximal distance between two adjacent
 points to connect.

 Example:

@\begin{verbatim}
    Pts = nil();
    for ( i = 0, 1, 100,
        t = random( 0, 2 * Pi ):
        snoc( point( cos( t ), sin( t ), 0 ), Pts ) );
    Pll = PTS2PLLN( Pts, 0.1 );
@\end{verbatim}

   connects 100 random points on the unit circle into a polyline
 approximating an (almost) complete circle.
$

@\subsubsection{PTSLNLN}
!PTSLNLN

@\begin{verbatim}
 ListType PTSLNLN( PointType Line1Orig, VectorType Line1Ray,
                   PointType Line2Orig, VectorType Line2Ray )
@\end{verbatim}

   computes the closest two points on the two lines defined by point
 {\bf LineiOrig} and ray {\bf LineiRay}. See also DSTLNLN.  
 A list object with the two points is returned.

 Example:

@\begin{verbatim}
 ClosestPts = PtsLnLn( point( 1, 0, 0 ), vector( 0, 1, 0 ),
                       point( 0, 1, 0 ), vector( 1, 0, 0 ) );
@\end{verbatim}
$

@\subsubsection{QUADCRVS}
!QUADCRVS

@\begin{verbatim}
 ListType QUADCRVS( CurveType Crv, NumericType Tolerance, NumericType MaxLen )
@\end{verbatim}

   approximates given curve {\bf Crv} using piecewise quadratic curves upto
 the prescribed tolerance {\bf Tolerance}.  If {\bf MaxLen} is positive it
 is used to limit the arc length of the cubic curves segments.

 Example:

@\begin{verbatim}
    PQaudCrv = QUADCRVS( Crv, 0.01, 0.5 );
@\end{verbatim}

 creates a piecewise quadratic approximation to curve {\bf Crv} upto tolerance
 0.01 and maximal arc length of cubic segments of 0.5.
   See also CUBICCRVS, CBIARC.
$

@\subsubsection{QUADRIC}
!QUADRIC

@\begin{verbatim}
 ListType QUADRIC( ListType ABCDEFGHIJ ) )

 or

 ListType QUADRIC( ListType ABCDEFZ ) )
@\end{verbatim}

   in the first form, constructs a quadric parametric surface whose
 coefficients are the ten coefficients in the list {\bf ABCDEFGHIJ}:
^     A x^2 + B y^2 + C z^2 + D xy + E xz + F yz + G x + H y + I z + J = 0.
@\begin{equation}
@     A x^2 + B y^2 + C z^2 + D xy + E xz + F yz + G x + H y + I z + J = 0.
@\end{equation}
   In the second form, promotes the given conic curve whose coefficients
 are the first six coefficients in the list {\bf ABCDEFZ}:
^     A x^2 + B xy + C y^2 + D x + E y + F = 0.
@\begin{equation}
@     A x^2 + B xy + C y^2 + D x + E y + F = 0.
@\end{equation}
 into a quadric surface with height in z of Z amount, the seven'th list
 element.

 Example:

@\begin{verbatim}
   Sph   = QUADRIC( list( 1,  1 , 1 , 0,  0,  0,  0,  0,  0, -1 ) );
   Hyp1s = QUADRIC( list( 1,  1, -1,  0,  0,  0,  0,  0,  0, -1 ) );
   Hyp2s = QUADRIC( list( 1, -1, -1,  0,  0,  0,  0,  0,  0, -1 ) );
   Ellipse = list( 1, 0, 2, 0, 0, -1 ):
   Ellipsoid = QUADRIC( Ellipse + list( 0.1 ) );
@\end{verbatim}

 constructs four quadric surfaces, a sphere, a portion of a hyperboloid of
 one sheet, a portion of a hyperboloid of two sheets, and promotes an
 ellipse to an ellipsoid of Z height of 0.1.
   Note only elliptic surfaces are compact and are reconstructed in whole.
   Because the parametrization of the quadric is predetermined, one might need
 to use SREGION and SMOEBIUS to extract subregions and/or reparametrize the
 surface.

 See also CONICSEC, IMPLCTTRANS, ELLIPSE3PT.
$

@\subsubsection{RAYTRAPS}
!RAYTRAPS

@\begin{verbatim}
 ListType RAYTRAPS( ListType Crvs,
                    NumericType SubdivTol, NumericType NumerTol )
@\end{verbatim}

    computes locations on the given planar curves that would bounce rays
 from one curve to the next, in an infinite cycle.  Such traps are denoted
 {\em ray traps}.  Ray-traps are computed for the given list of
 {\bf Crvs}, in the given order.  The ray-trap problem is posed as a
 set of n multivariate algebraic constraints with n variables, given
 n curves prescribed in {\bf Crvs}.  The simultaneous solution of these
 constraints is computed using the MZERO function.  See MZERO for the
 meaning of the {\bf SubdivTol} and {\bf NumerTol} tolerances.

 Example:

@\begin{verbatim}
    Crv1 = pcircle( vector( -0.75, -0.75, 0 ), 0.5 );
    Crv2 = Crv1 * sc( 1.5 ) * tx( 2 );
    Crv3 = Crv1 * sc( 0.5 ) * tx( 0.2 ) * ty( 0.6 );

    Tris = RayTraps( list( Crv1, Crv2, Crv3 ), 0.1, -1e-6 );
@\end{verbatim}

  computes the ray-traps between three circles.
@See Figure~\ref{fig-raytraps}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/raytrap.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/raytrap.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Computes all ray-traps between three circles, using RAYTRAPS.
=</b><BR clear=all>
@}
@\label{fig-raytraps}
@\end{figure}
$

@\subsubsection{RFLCTLN}
!RFLCTLN

@\begin{verbatim}
 ListType RFLCTLN( SurfaceType Srf, VectorType ViewDir,
                   ListType LinesSprs, NumericType Euclidean )
@\end{verbatim}

   computes reflection lines/ovals to the given surface {\bf Srf} as
 seen from view direction {\bf ViewDir}.  The resulting piecewise linear
 curves are in Euclidean space if {\bf Euclidean} is TRUE and in {\bf Srf}
 parameter space, otherwise.

   The reflection/ovals themselves are defined via {\bf LinesSprs}.
 For reflection lines, {\bf LinesSprs} consists of
@\begin{verbatim}
 list( LineDir, list( LinePos1, LinePos2, ... , LinePosN ) );
@\end{verbatim}
 defining n parallel lines with direction {\bf LineDir} through
 point {\bf LinePos1} to {\bf LinePosN}.

 For reflection ovals, {\bf LinesSprs} consists of
@\begin{verbatim}
 list( SprCntr, list( Rad1, Rad2, ... , RadN ) );
@\end{verbatim}
 defining n co-spherical spheres, all located at {\bf SprCntr} with
 radii of {\bf Rad1} to {\bf RadN}.

 Example:

@\begin{verbatim}
    resolution = 20;
    RefLns = RflctLn( Srf,
                      vector( 0, 1, 2 ),
                      list( vector( 0, 0, 1 ),
                            list( point( -3.0, 2, 0 ),
                                  point( -1.5, 2, 0 ),
                                  point(  0.0, 2, 0 ),
                                  point(  1.5, 2, 0 ),
                                  point(  3.0, 2, 0 ) ) ),
                      true );
    RefOvals = RflctLn( Srf,
                        vector( 1, 1, 0 ),
                        list( point( 0, 2, 0 ),
                              list( 5, 25, 45, 65, 85 ) ),
                        true );
@\end{verbatim}

 computes the reflection lines of surface {\bf Srf} from viewing
 direction ( 0, 1, 2 ) having five reflected lines and computes five
 reflection ovals from viewing direction ( 0, 1, 2 ).
 See also ReflectLns attributes in the display devices.
$

@\subsubsection{RRINTER}
!RRINTER

@\begin{verbatim}
 ListType RRINTER( CurveType Srf1Crv1, CurveType Srf1Crv2,
                   CurveType Srf2Crv1, CurveType Srf2Crv2,
                   NumericType Tolerance, NumericType ZeroSetFunc )
@\end{verbatim}

    computes the intersection curves of the given two ruled surfaces,
  defined as 
^
^        SrfiCrv1 * v + SrfiCrv2 * (1 - v)", i = 1, 2, v in [0,1].
^
@\begin{equation}
@     SrfiCrv1 * v~ +~ SrfiCrv2 * (1 - v),~~ i = 1, 2,~~v \in [0,1].
@\end{equation}
   The ruled ruled intersection (RRI) problem is tranformed into a zero set
 finding on another function.  If {\bf ZeroSetFunc} is true, the function
 whose zero set provides the RRIsolution is returned.  Otherwise, if
 {\bf ZeroSetFunc} is false, the RRI solution itself is returned.  The zero
 set is computed via numerical zero set finding methods and {\bf Tolerance}
 controls the fineness of the approximated solution.  If {\bf Tolerance} is
 negative, the absolute value is employed as {\bf Tolerance} but the
 intersection curves are computed as if the two ruled surfaces are infinite
 (i.e. v is unbounded).
@See Figure~\ref{fig-rrinter}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/rrinter1.ps, width=3in} &
@    \epsfig{file=user_man/rrinter2.ps, width=3.3in}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/rrinter1.gif">
=        <img hspace=2 width=250 src="user_man/rrinter2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Computation of the intersection curve between two ruled surfaces via
-      the RRINTER command.  On the left, the four intersection curves are
-      shown, while (right) shows the computed function whose zero set
-      provides the request RRI solution.
=</b><BR clear=all>
@}
@\label{fig-rrinter}
@\end{figure}

 Example:

@\begin{verbatim}
    c1 = cbezier( list( ctlpt( E3, -1.0,  -1.0, -1.0 ),
                        ctlpt( E3, -0.5,   8.0, -1.0 ),
                        ctlpt( E3,  0.0, -15.0, -1.0 ),
                        ctlpt( E3,  0.5,   8.0, -1.0 ),
                        ctlpt( E3,  1.0,  -1.0, -1.0 ) ) );
    c2 = c1 * sc( 0.7 ) * tz( 1.7 );
    r1 = ruledSrf( c1, c2 );
    
    c1 = pcircle( vector( 0, 0, 0 ), 0.3 ) * tz( 2 );
    c2 = c1 * sc( 0.5 ) * tz( -3 );
    r2 = ruledSrf( c1, c2 ) * ry( 90 );
    
    c = RRINTER( cMesh( r1, row, 0 ),
                 cMesh( r1, row, 1 ),
                 cMesh( r2, row, 0 ),
                 cMesh( r2, row, 1 ),
                 25, false );
    
    interact( list( r1, r2, nth( c, 1 ) ) );
@\end{verbatim}
$

@\subsubsection{RULEDSRF}
!RULEDSRF

@\begin{verbatim}
 SurfaceType RULEDSRF( CurveType Crv1, CurveType Crv2 )

 or

 PolygonType RULEDSRF( PolygonType Poly1, PolygonType Poly2 )
@\end{verbatim}

   construct a ruled surface between the two curves {\bf Crv1} and {\bf Crv2}
 or two polylines {\bf Poly1} and {\bf Poly2}.
   The curves do not have to have the same order or type, and will be promoted
 to their least common denominator.  The polys must have the same number of
 points and both must be either polygons or polylines.

 Example:

@\begin{verbatim}
    c1 = cbspline( 3,
                 list( ctlpt(E3, 1.7, 0.0 , 0  ),
                       ctlpt(E3, 0.7, 0.7 , 0  ),
                       ctlpt(E3, 1.7, 0.3 , 0  ),
                       ctlpt(E3, 1.5, 0.8 , 0  ),
                       ctlpt(E3, 1.6, 1.0 , 0  ) ),
            list( KV_OPEN ) );
    c2 = cbspline( 3,
                 list( ctlpt(E3, 0.7, 0.0 , 0  ),
                       ctlpt(E3,-0.7, 0.2 , 0  ),
                       ctlpt(E3, 0.7, 0.5 , 0  ),
                       ctlpt(E3,-0.7, 0.7 , 0  ),
                       ctlpt(E3, 0.7, 1.0 , 0  ) ) ,
            list( KV_OPEN ) );
    
    srf1 = RULEDSRF( c1, c2 );
    interact( list( c1, c2, srf1 ), on );
    
    c2a = ffmatch( c1, c2, 50, 100, 2, false, 1 );
    srf2 = RULEDSRF( c1, c2a );
    interact( list( c1, c2, srf2 ), on );
@\end{verbatim}

 constructs a planar ruled surface between two curves, {\bf c1} and {\bf c2}.
 The naive construction causes self intersection, but by employing FFMATCH
 the self intersection can be resolved.
@See Figure~\ref{fig-ruledsrf}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/ruledsrf.ps, width=4.5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/ruledsrf.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A naive construction of a ruled surface (left) using RULEDSRF
-      results in self intersection. FFMATCH is employed (right) to
-      automatically resolve this self intersection.
=</b><BR clear=all>
@}
@\label{fig-ruledsrf}
@\end{figure}

 See also FFMATCH.
$

@\subsubsection{RULEDTV}
!RULEDTV

@\begin{verbatim}
 TrivarType RULEDTV( SurfaceType Srf1, SurfaceType Srf2 )
@\end{verbatim}

   constructs a ruled trivariate between the two surfaces {\bf Srf1} and
 {\bf Srf2}.
   The surfaces do not have to have the same order or type, and will be
 promoted to their least common denominator.

 Example:

@\begin{verbatim}
    s1 = boolone( pcircle( vector( 0, 0, 0 ), 1 ) );
    s2 = boolone( pcircle( vector( 0, 0, 1 ), 0.5 ) );

    tv = RULEDTV( s1, s2 );
@\end{verbatim}

 constructs a truncated cone-volume as a ruled trivariate between two surfaces,
 {\bf s1} and {\bf s2}.
@See Figure~\ref{fig-ruledtv}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/ruledtv.ps, width=5in}
=    <img  hspace=2 src="user_man/ruledtv.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A ruled volume as a trivariate between two disc surfaces, created via
-     the RULEDTV function.
=</b><BR clear=all>
@}
@\label{fig-ruledtv}
@\end{figure}

 See also EXTRUDE, TFROMSRFS.
$

@\subsubsection{SACCESS}
!SACCESS

@\begin{verbatim}
 ListType SACCESS( SurfaceType AccessSrf,
                   AnyType OrientFieldSrf,
                   SurfaceType CheckSrf,
                   AnyType AccessLimitDir,
                   NumericType SubdivTol,
                   NumericType NumericTol )
@\end{verbatim}

 computes the domain on the {\bf AccessSrf} surface that is accessible from the
 orientation that is optionally prescribed by {\bf OrientFieldSrf}, without
 gouging into the {\bf CheckSrf} surface.  If {\bf OrientFieldSrf} is not
 a surface, the normal field of {\bf AccessSrf} is employed.  
 {\bf AccessSrf} and {\bf OrientFieldSrf} must share a (u, v) domain,
 whereas {\bf CheckSrf} can present a different (s, t) domain.

 If {\bf AccessLimitDir} is indeed a vector, the access is limited for
 direction V such that the inner product of V and {\bf AccessLimitDir} is
 positive.

 The accuracy of the computation is governed by a two stage solution,
 a subdivision stage with tolerance {\bf SubdivTol} followed by a numerical
 improvement stage with {\bf NumericTol} accuracy.  The second, numeric,
 stage is invoked only if {\bf NumericTol < SubdivTol}.

 The returned results are a set of points on the boundary of the accessible
 region.  The points are in E4 space as (u, v, s, t) 4-tuples.

 Example:

@\begin{verbatim}
    c = cregion( pcircle( vector( 0, 0, 0 ), 1 ), 1, 3 ) * ry( 90 );
    pSphere = surfPRev( c ) * sc( 0.3 ) * tz( 1 );

    Pln = ruledSrf( ctlpt( E3, -1, -1, 0 ) + ctlpt( E3, -1,  1, 0 ),
                    ctlpt( E3,  1, -1, 0 ) + ctlpt( E3,  1,  1, 0 ) );

    Pts = SACCESS( Pln, 0, pSphere, 0, 0.1, 1e-5 );

    sPts = nil();
    sPtsErr = nil();
    for ( i = 1, 1, sizeof( Pts ),
        Pt = nth( Pts, i ):
        Err = getAttr( Pt, "Error"):
        if ( Err > 1e-5,
             snoc( seval( Pln, coord( Pt, 1 ), coord( Pt, 2 ) ), sPtsErr ),
             snoc( seval( Pln, coord( Pt, 1 ), coord( Pt, 2 ) ), sPts ) ) );
    color( sPts, green );
    color( sPtsErr, red );

    interact( list( pSphere, Pln, sPts, sPtsErr ) );
@\end{verbatim}

 computes the access domain of plane {\bf Pln} along the normal, Z, direction
 while preventing gouging into the check surface {\bf pSphere}.
@See Figure~\ref{fig-saccess}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/saccess.ps, width=5in}
=    <img  hspace=2 src="user_man/saccess.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      The limit of the accessible area of the plane along the normal
-      direction, without gouging into the sphere is computed and presented
-      using the SACCESS function.
=</b><BR clear=all>
@}
@\label{fig-saccess}
@\end{figure}
 See MZERO for the meaning of {\bf SubdivTol} and {\bf NumerTol}.
$

@\subsubsection{SASPCTGRPH}
!SASPCTGRPH

@\begin{verbatim}
 PolyType SASPCTGRPH( SurfaceType Srf )
@\end{verbatim}

   approximates the aspect graph of surface {\bf Srf} by computing the
 principal directions with zero curvature at the parabolic points of {\bf Srf}.
   The aspect graph is defined over the unit sphere and identifies all
 direction from which the silhouette curves of {\bf Srf} change topology.

 Example:

@\begin{verbatim}
   AG = SAspctGrph( Srf );
@\end{verbatim}

 See also SILHOUETTE.
$

@\subsubsection{SASYMPEVAL}
!SASYMPEVAL

@\begin{verbatim}
 ListType SASYMPEVAL( SurfaceType Srf, NumericType U, NumericType V,
                      NumericType Euclidean )
@\end{verbatim}

   evalutes the asymptotic direction of surface {\bf Srf} at parametric
 location ({\bf U, V}), if any.  If {\bf Euclidean} is not zero, the directions
 are returned in Euclidean space, otherwise, in parametric space.  Returned
 is a list of upto two vectors.

 Example:

@\begin{verbatim}
   AsympDir = SAsympEval( Srf, u, v, true );
@\end{verbatim}

 See also SCRVTR.
$

@\subsubsection{SBEZIER}
!SBEZIER

@\begin{verbatim}
 SurfaceType SBEZIER( ListType CtlMesh )
@\end{verbatim}

   creates a Bezier surface using the provided control mesh. {\bf CtlMesh} is a
 list of rows, each of which is a list of control points. All control points
 must be of type (E1-E9, P1-P9), or regular PointType defining the surface's
 control mesh. The surface's point type will be of a space which is the
 union of the spaces of all points.
@
@The created surface is the piecewise polynomial (or rational) surface,
@\begin{equation}
@     S(u, v) = \sum_{i=0}^m \sum_{j=0}^n P_{ij} B_i(u) B_j(v)
@\end{equation}
@where $P_{ij}$ are the control points {\bf CtlMesh}, and $m$ and $n$ are the
@degrees of the surface, which are one less than the number of points in the
@appropriate direction.

 Example:

@\begin{verbatim}
   Srf = SBEZIER( list ( list( ctlpt( E3, 0.0, 0.0, 1.0 ),
                               ctlpt( E3, 0.0, 1.0, 0.0 ),
                               ctlpt( E3, 0.0, 2.0, 1.0 ) ),
                         list( ctlpt( E3, 1.0, 0.0, 0.0 ),
                               ctlpt( E3, 1.0, 1.0, 2.0 ),
                               ctlpt( E3, 1.0, 2.0, 0.0 ) ),
                         list( ctlpt( E3, 2.0, 0.0, 2.0 ),
                               ctlpt( E3, 2.0, 1.0, 0.0 ),
                               ctlpt( E3, 2.0, 2.0, 2.0 ) ),
                         list( ctlpt( E3, 3.0, 0.0, 0.0 ),
                               ctlpt( E3, 3.0, 1.0, 2.0 ),
                               ctlpt( E3, 3.0, 2.0, 0.0 ) ),
                         list( ctlpt( E3, 4.0, 0.0, 1.0 ),
                               ctlpt( E3, 4.0, 1.0, 0.0 ),
                               ctlpt( E3, 4.0, 2.0, 1.0 ) ) ) );
@\end{verbatim}
@See Figure~\ref{fig-surface}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/surface.ps, width=4.5in}
=    <img  hspace=2 src="user_man/surface.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A Bezier surface (left) of degree 3 by 5 and a B-spline surface (right)
-      of degree 3 by 3 (bi-quadratic). Both share the same control mesh.
=</b><BR clear=all>
@}
@\label{fig-surface}
@\end{figure}

 See also CBEZIER, SBSPLINE and SPOWER.
$

@\subsubsection{SBISECTOR}
!SBISECTOR

@\begin{verbatim}
 SurfaceType SBISECTOR( SurfaceType Srf, PointType Pt )
@\end{verbatim}

    computes the bisector surface of a given surface to a point.
 See also CBISECTOR2D, CBISECTOR3D.

 Example:

@\begin{verbatim}
    s = ruledSrf( ctlpt( E3, -1.0, -1.0, 0.0 ) + ctlpt( E3,  1.0, -1.0, 0.0 ),
                  ctlpt( E3, -1.0,  1.0, 0.0 ) + ctlpt( E3,  1.0,  1.0, 0.0 ) );
    
    pt = point( 0.0, 0.0, 1.0 );
    
    bisect = SBISECTOR( s, pt );

    interact( list( s, pt, bisect ) );
@\end{verbatim}

 computes the bisector surface of a plane and a point.
@See Figure~\ref{fig-sbisector}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sbisect.ps, width=5in} \\
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/sbisect.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     (a) Bisector surface of a plane and a point computed using the
-      SBISECTOR command.
=</b><BR clear=all>
@}
@\label{fig-sbisector}
@\end{figure}
$

@\subsubsection{SBSPLINE}
!SBSPLINE

@\begin{verbatim}
 SurfaceType SBSPLINE( NumericType UOrder, NumericType VOrder,
                       ListType CtlMesh, ListType KnotVectors )
@\end{verbatim}

   creates a B-spline surface from the provided {\bf UOrder} and {\bf VOrder}
 orders, the control mesh {\bf CtlMesh}, and the two knot vectors {\bf KnotVectors}.
 {\bf CtlMesh} is a list of rows, each of which is a list of control points.
 All control points must be of point type (E1-E9, P1-P9), or regular
 PointType defining the surface's control mesh. The surface's point type will
 be of a space which is the union of the spaces of all points.
   {\bf KnotVectors} is a list of two knot vectors. Each knot vector is a
 list of NumericType knots of length {\bf \#CtlPtList} plus the {\bf Order}.
 If, however, the length of the knot vector is equal to {\bf \#CtlPtList +
 Order + Order - 1}, the curve is assumed to be {\em periodic.} 
   The knot vector may also be a list of a single constant KV\_OPEN or
 KV\_FLOAT or KV\_PERIODIC, in which a uniform knot vector with the
 appropriate length and with an open, floating or periodic end condition
 will be constructed automatically.
@
@The created surface is the piecewise polynomial (or rational) surface,
@\begin{equation}
@     S(u, v) = \sum_{i=0}^m \sum_{j=0}^n P_{ij} B_{i,\chi}(u) B_{j,\xi}(v)
@\end{equation}
@where $P_{ij}$ are the control points {\bf CtlMesh}, and $m$ and $n$ are the
@degrees of the surface, which are one less than {\bf UOrder} and {\bf VOrder}.
@$\chi$ and $\xi$ are the two knot vectors of the surface.

 Example:

@\begin{verbatim}
    Mesh = list ( list( ctlpt( E3, 0.0, 0.0, 1.0 ),
                        ctlpt( E3, 0.0, 1.0, 0.0 ),
                        ctlpt( E3, 0.0, 2.0, 1.0 ) ),
                  list( ctlpt( E3, 1.0, 0.0, 0.0 ),
                        ctlpt( E3, 1.0, 1.0, 2.0 ),
                        ctlpt( E3, 1.0, 2.0, 0.0 ) ),
                  list( ctlpt( E3, 2.0, 0.0, 2.0 ),
                        ctlpt( E3, 2.0, 1.0, 0.0 ),
                        ctlpt( E3, 2.0, 2.0, 2.0 ) ),
                  list( ctlpt( E3, 3.0, 0.0, 0.0 ),
                        ctlpt( E3, 3.0, 1.0, 2.0 ),
                        ctlpt( E3, 3.0, 2.0, 0.0 ) ),
                  list( ctlpt( E3, 4.0, 0.0, 1.0 ),
                        ctlpt( E3, 4.0, 1.0, 0.0 ),
                        ctlpt( E3, 4.0, 2.0, 1.0 ) ) );
    Srf = SBSPLINE( 3, 3, Mesh, list( list( KV_OPEN ),
                                      list( 3, 3, 3, 4, 5, 6, 6, 6 ) ) );
@\end{verbatim}

 constructs a bi-quadratic B-spline surface with its first knot vector
 having a uniform knot spacing with open end conditions.
@See Figure~\ref{fig-surface}.

 See also CBSPLINE, SBEZIER and SPOWER.
$

@\subsubsection{SCRVTR}
!SCRVTR

@\begin{verbatim}
 SurfaceType SCRVTR( SurfaceType Srf, ConstType PtType, ConstType Dir )
@\end{verbatim}

   symbolically computes the extreme curvature bound on {\bf Srf}.
   If {\bf Dir} is either ROW or COL, then the normal curvature square
 of {\bf Srf} in {\bf Dir} is computed symbolically and returned.
   Otherwise, an upper bound on the sum of the squares of the two
 principle curvatures is symbolically computed and returned.
   
   The returned value is a surface that can be evaluated to the curvature
 bound, given a UV location. The returned surface value is a scalar field
 of point type P1 (scalar rational).
   However, if {\bf PtType} is one of E1, P1, E3, or P3, the returned surface
 is coerced to this given type. If the types are one of E3, or P3, then the
 Y and Z axes are set to be equivalent to the U and V parametric domains.

@   This function computes the square of the normal curvature scalar
@ field for surfaces as (in the U parametric direction, same for V),
@\begin{equation}
@      \kappa_n^u(u, v) = \frac{\inner{n}{\frac{\partial^2 S}{\partial u^2}}}
@                              {\inner{\frac{\partial S}{\partial u}}
@                                     {\frac{\partial S}{\partial u}}}
@\end{equation}
@ and computes $\xi(u, v) = k_1(u, v)^2 + k_2(u, v)^2$ as the scalar field of
@\begin{equation}
@       \xi(u, v) = \frac{(g_{11} l_{22} + l_{11} g_{22} - 2 g_{12}
@                l_{12}) ^ 2 - 2 \left| G \right| \left| L \right|}
@               {\left| G \right|^2 \| n \|^2},
@\end{equation}
@ where $g_{ij}$ and $l_{ij}$ are the coefficients of the first and second
@ fundamental forms G and L.
^   This function computes the square of the normal curvature scalar
^ field for surfaces as (in the U parametric direction, same for V),
^                     2  
^                    d S
^              < n , --- >
^                      2
^    u               du
^   k (u, v) = ------------
^    n         
^                 dS   ds
^               < -- , -- >
^                 du   du
^
^ and computes the sum of the squares of the principle curvatures as,
^
^  2    2  ( g11 l22 + g22 l11 - 2 g12 l12 )^2 - 2 |G| |L|
^ k  + k = -----------------------------------------------
^  1    2                   |G|^2 ||n||^2
^

 See also CCRVTR, SASYMPEVAL.

 Example:
 
@\begin{verbatim}
 cross = cbspline( 3,
                   list( ctlpt( E2,  0.0,  0.0 ),
                         ctlpt( E2,  0.8,  0.0 ),
                         ctlpt( E2,  0.8,  0.2 ),
                         ctlpt( E2,  0.07, 1.4 ),
                         ctlpt( E2, -0.07, 1.4 ),
                         ctlpt( E2, -0.8,  0.2 ),
                         ctlpt( E2, -0.8,  0.0 ),
                         ctlpt( E2,  0.0,  0.0 ) ),
                   list( KV_OPEN ) );
 cross = coerce( cross, e3 );
 s = sFromCrvs( list( cross,
                      cross * trans( vector( 0.5, 0, 1 ) ),
                      cross * trans( vector( 0, 0, 2 ) ) ), 3, KV_OPEN );
 view( list( s, axes ), on );
 
 UCrvtrZXY = scrvtr( s, E3, row );
 VCrvtrZXY = scrvtr( s, E3, col );
 UCrvtrXYZ = UCrvtrZXY * rotx( -90 ) * roty( -90 ) * scale( vector( 1, 1, 0.001 ) );
 VCrvtrXYZ = VCrvtrZXY * rotx( -90 ) * roty( -90 ) * scale( vector( 1, 1, 10 ) );
 color( UCrvtrXYZ, red );
 color( VCrvtrXYZ, magenta );
 
 view( list( UCrvtrXYZ, VCrvtrXYZ ), off );
 
 CrvtrZXY = scrvtr( s, E3, off );
 CrvtrXYZ = CrvtrZXY * rotx( -90 ) * roty( -90 ) * scale( vector( 1, 1, 0.001 ) );
 color( CrvtrXYZ, green );
 
 view( CrvtrXYZ, off );
@\end{verbatim}

 computes the square of the normal curvature in the U and V directions, flips
 its scalar value from X to Z using rotations and scales the fields to
 reasonable values, and then displays them.
   It also displays a total bound on the normal curvature.

 Due to the large degree of the resulting fields, be aware that rational
 surfaces will compute into large degree curvature bound fields. See also
 IRITSTATE "InterpProd" option for faster symbolic computation.
@See Figure~\ref{fig-scrvtr}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/scrvtr.ps, width=6in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/scrvtr.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     From left to right: original surface, normal curvature in the U
-     direction, normal curvature in the V direction, sum of the square of
-     principle curvatures (different scales).
-     All computed using SCRVTR.
=</b><BR clear=all>
@}
@\label{fig-scrvtr}
@\end{figure}
$

@\subsubsection{SCRVTREVAL}
!SCRVTREVAL

@\begin{verbatim}
 ListType SCRVTREVAL( SurfaceType Srf, NumericType U, NumericType V,
                      NumericType Euclidean )
@\end{verbatim}

   computes the principle curvatures and directions of surface {\bf Srf}
 at parametric location {\bf (U, V)}.  A list of four elements
  (k1, V1, k2, V2), with k1/V1 being the first principle curvature/direction
 and k2/V2 being the second, is returned.  If {\bf Euclidean} is TRUE then
 the principle curvatures are returned in Euclidean space.
   Consecutive calls with the same surface {\bf Srf} to SCRVTREVAL will yield
 more efficient evaluations as derivative data is cached.

   Example:

@\begin{verbatim}
    Crvtr = SCRVTREVAL( Srf, 0.5, 0.5, True );
    K = nth( Crvtr, 1 ) * nth( Crvtr, 3 );
@\end{verbatim}

 computes the Total (Gaussian) curvatures, K = k1 * k2, of Srf at (0.5, 0.5).
 See also SCRVTR.
$

@\subsubsection{SDDMMAP}
!SDDMMAP

@\begin{verbatim}
 PolyType SDDMMAP( SurfaceType BaseSrf, PolyType Bump,
                   NumericType UDup, NumericTye VDup, NumericTye LclUVs )
@\end{verbatim}

   Tiles a composition of {\bf Bump} over surface {\bf BaseSrf}
 {\bf UDup} by {\bf VDup} times, creating a detailed bump geometry. {\bf Bump}
 can be any polygonal geometry whatsoever with XY coordinates that are
 contained in the unit square [0, 1] x [0, 1], while Z serves as the elevation
 above the surface.  The composed geometry could inherit the UV texture
 ccordinates from the UV coordinates found in {\bf Bump} if {\bf LclUVs} is TRUE
 or inherit {\bf BaseSrf} UV coordinates if {\bf LclUVs} is FALSE.

 Example:

@\begin{verbatim}
 BaseTorus = torusSrf( 1, 0.2 );
 BumpTorus = SDDMMAP( BaseTorus, BumpPolyObj, 6, 8, on );
@\end{verbatim}

  constructs a bumpy {\bf BumpTorus} with a bump tiled 6 x 8 times over the
 surface.
@See Figure~\ref{fig-bumpsrf}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{ccccc}
@    \epsfig{file=user_man/sbump1.ps, width=1.0in} &
@        \begin{minipage}{5mm} {\mbox{\vspace{0.1in}} \\[0.1in]
@                                \huge + \\[0.95in]} \end{minipage} &
@        \epsfig{file=user_man/sbump2.ps, width=2.0in} &
@        \begin{minipage}{5mm} {\mbox{\vspace{0.1in}} \\[0.1in]
@                                \huge = \\[0.95in]} \end{minipage} &
@        \epsfig{file=user_man/sbump3.ps, width=2.0in}
=    <BR clear=all>
=    <img hspace=2 src="user_man/sbump1.gif">
=    <b> + </b> 
=        <img hspace=2 src="user_man/sbump2.gif">
=    <b> = </b>
=        <img hspace=2 width=250 src="user_man/sbump3.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Polygonal geometry (left) could be tiled over arbitrary surface,
-      torus in this case (middle), to yield a bumpy shape (right)
-      using the SDDMMAP function.
=</b><BR clear=all>
@}
@\label{fig-bumpsrf}
@\end{figure}
$

@\subsubsection{SDERIVE}
!SDERIVE

@\begin{verbatim}
 SurfaceType SDERIVE( SurfaceType Srf, NumericType Dir )
@\end{verbatim}

   returns a vector field surface representing the differentiated surface
 in the given direction (ROW or COL). Evaluation of the returned surface at
 a given parameter value will return a vector {\em tangent} to {\bf Srf} in
 {\bf Dir} at that parameter value.

@\begin{verbatim}
 DuSrf = SDERIVE( Srf, ROW );
 DvSrf = SDERIVE( Srf, COL );
 Normal = coerce( seval( DuSrf, 0.5, 0.5 ), VECTOR_TYPE ) ^
          coerce( seval( DvSrf, 0.5, 0.5 ), VECTOR_TYPE );
@\end{verbatim}
 
 computes the two partial derivatives of the surface {\bf Srf} and computes
 its normal as their cross product, at the parametric location (0.5, 0.5).
 See also CDERIVE, TDERIVE, and MDERIVE.
$

@\subsubsection{SDIVIDE}
!SDIVIDE

@\begin{verbatim}
 SurfaceType SDIVIDE( SurfaceType Srf, ConstantType Direction,
                                                          NumericType Param )

 or

 TrimSrfType SDIVIDE( TrimSrfType Srf, ConstantType Direction,
                                                          NumericType Param )
@\end{verbatim}

   subdivide a (possibly trimmed) surface into two at the specified parameter
 value {\bf Param} in the specified {\bf Direction} (ROW or COL). {\bf Srf}
 can be either a B-spline surface in which {\bf Param} must be contained in
 the parametric domain of the surface, or a Bezier surface in which {\bf
 Param} can be arbitrary, extrapolating if not in the range of zero to one.

   It returns a list of upto two sub-surfaces. The individual surfaces may be
 extracted from the list using the {\bf NTH} command. If {\bf Srf} is a trimmed
 surface, it may be the case that one of the two subdivided surfaces is
 completely trimmed out, and hence only one surface will be returned.

 Example:

@\begin{verbatim}
    SrfLst = SDIVIDE( Srf, ROW, 0.5 );
    Srf1 = nth( SrfLst, 1 );
    Srf2 = nth( SrfLst, 2 );
@\end{verbatim}

 subdivides {\bf Srf} at the parameter value of 0.5 in the ROW direction.
@See Figure~\ref{fig-sdivide}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sdivide.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/sdivide.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A surface can be subdivided into two distinct regions using SDIVIDE.
=</b><BR clear=all>
@}
@\label{fig-sdivide}
@\end{figure}
 See also CDIVIDE, TDIVIDE, and MDIVIDE
$

@\subsubsection{SETCOVER}
!SETCOVER

@\begin{verbatim}
 ListType SETCOVER( ListType RangesSet, NumericType OverlapTolerance )
@\end{verbatim}

   computes the minimal subset of the given set {\bf RangesSet}, that covers
 the entire domain spanned by {\bf RangesSet}.  A range is a list object with
 two numeric values, the start and end of this specific range.  Each element
 in {\bf RangesSet} can be either a range, or a list of ranges.
   {\bf OverlapTolerance} specifies the tolerance to use in overlapping
 ranges.
   Returned is a list of indices (first element zero) that prescribe the
 minimal coverage.
   Note that the former case of a single range per element is solved in an
 almost linear time whereas the later case of multiple ranges per element is
 exponential.  Hence, do not attempt to find minimal coverage of more than a
 few elements in the later case.

   Example:

@\begin{verbatim}
    Ranges = list( list( 0.0, 0.4 ),
                   list( 0.1, 0.4 ),
                   list( 0.3, 1.0 ),
                   list( 0.1, 0.9 ) );
    Indcs = SETCOVER( Ranges, 1e-7 );
@\end{verbatim}

   and SETCOVER should return "list( 0, 2 )", the two indices of the ranges
 that cover this domain of [0, 1].  See also CVISIBLE.
$

@\subsubsection{SEDITPT}
!SEDITPT

@\begin{verbatim}
 SurfaceType SEDITPT( SurfaceType Srf, CtlPtType CPt, NumericType UIndex,
                                                      NumericType VIndex )
@\end{verbatim}

   provides a simple mechanism to manually modify a single control point number
 {\bf UIndex} and {\bf VIndex} (base count is 0) in the control mesh of {\bf Srf}
 by substituting {\bf CtlPt} instead. CtlPt must have the same point type as
 the control points of {\bf Srf}. The original surface {\bf Srf} is not modified.

 Example:

@\begin{verbatim}
    CPt = ctlpt( E3, 1, 2, 3 );
    NewSrf = SEDITPT( Srf, CPt, 0, 0 );
@\end{verbatim}

 constructs a {\bf NewSrf} with the first control point of {\bf Srf} being
 {\bf CPt}.
$

@\subsubsection{SEVAL}
!SEVAL

@\begin{verbatim}
 CtlPtType SEVAL( SurfaceType Srf, NumericType UParam, NumericType VParam )

 or

 CtlPtType SEVAL( TrimSrfType Srf, NumericType UParam, NumericType VParam )
@\end{verbatim}

   evaluates the provided (possibly trimmed) surface {\bf Srf} at the given
 {\bf UParam} and {\bf VParam} parameters. Both {\bf UParam} and {\bf VParam}
 should be contained in the surface parametric domain if {\bf Srf} is a
 B-spline surface, or between zero and one if {\bf Srf} is a Bezier surface.
 The returned control point has the same type as the control points of
 {\bf Srf}.

 Example:

@\begin{verbatim}
    CPt = SEVAL( Srf, 0.25, 0.22 );
@\end{verbatim}

 evaluates {\bf Srf} at the parameter values of (0.25, 0.22).
 See also CEVAL, MEVAL, TEVAL.
$

@\subsubsection{SFLECNODAL}
!SFLECNODAL

@\begin{verbatim}
 SurfaceType SFLECNODAL( SurfaceType Srf, NumericType SubdivTol,
                         NumericType NumericTol, NumericType MergeTol,
                         NumericType ContactOrder )
@\end{verbatim}

   computes the flecnodal curves over a given freeform geometry, {\bf Srf}.
 The flecnodal curves are curves of contact of order four with a line in an
 asymptotic direction.  {\bf SubdivTol} and {\bf NumericTol} controls the
 subdivision and numeric tolerances of the approximation.  Typically the
 subdivision tolerance is fairly coarse.  {\bf MergeTol} prescribes the
 tolerance of merging individual points into polylines.  A negative value
 will prescribe no merge.  The {\bf ContactOrder} should be 3 to compute
 flecnodal curves and 4 to compute flecnodal points.

 Example:

@\begin{verbatim}
 flecs = SFlecnodal( srf, 0.05, -1e-6, 1e-1, 3 );
@\end{verbatim}
 See MZERO for the meaning of {\bf SubdivTol} and {\bf NumerTol}.
$

@\subsubsection{SFOCAL}
!SFOCAL

@\begin{verbatim}
 SurfaceType SFOCAL( SurfaceType Srf, NumericType Dir )
@\end{verbatim}

   evaluates the focal surface field of surface {\bf Srf} using the normal
 curvature in the isoparametric direction as given by {\bf Dir} (either
 ROW or COL). Note this function is not using the principal curvatures as
 is generaly the case for focal surfaces.

 Example:

@\begin{verbatim}
    gcross = cbspline( 3,
                       list( ctlpt( E3, 0.3, 0.0, 0.0 ),
                             ctlpt( E3, 0.1, 0.0, 0.1 ),
                             ctlpt( E3, 0.1, 0.0, 0.4 ),
                             ctlpt( E3, 0.5, 0.0, 0.5 ),
                             ctlpt( E3, 0.6, 0.0, 0.8 ) ),
                       list( KV_OPEN ) );
    glass = surfprev( gcross );
    color( glass, red );
    
    gfocal = SFOCAL(glass, col);
@\end{verbatim}

 evaluates the focal surface using the COL isoparametric direction's
 normal curvature of the glass surface.
@See Figure~\ref{fig-sfocal}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sfocal.ps, width=5in}
=    <img  hspace=2 src="user_man/sfocal.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A focal surface (right) of a glass surface (left) can be computed
-      using SFOCAL.
=</b><BR clear=all>
@}
@\label{fig-sfocal}
@\end{figure}
$

@\subsubsection{SFROMCRVS}
!SFROMCRVS

@\begin{verbatim}
 SurfaceType SFROMCRVS( ListType CrvList,
                        NumericType OtherOrder,
                        NumericType OtherEndCond )
@\end{verbatim}

   constructs a surface by substituting the curves in {\bf CrvList} as rows
 in a control mesh of a surface. The curves in {\bf CrvList} are made compatible
 by promoting Bezier curves to B-splines if necessary, and raising the degrees
 and refining as required before substituting the control polygons of the
 curves as rows in the mesh. The other direction order is set by
 {\bf OtherOrder}, which cannot be larger than the number of curves.
 If B-spline ({\bf OtherOrder} is smaller than number of curves) end
 conditions are set via {\bf OtherEndCond} and can be one of {\bf KV\_OPEN},
 {\bf KV\_FLOAT} or {\bf KV\_PERIODIC}.

   The surface interpolates the first and last curves only, if a Bezier
 or open end conditions are selected; otherwise, no curve is interpolated.

 Example:

@\begin{verbatim}
    Crv1 = cbspline( 3,
                     list( ctlpt( E3, 0.0, 0.0, 0.0 ),
                           ctlpt( E3, 1.0, 0.0, 0.0 ),
                           ctlpt( E3, 1.0, 1.0, 0.0 ) ),
                     list( KV_OPEN ) );
    Crv2 = Crv1 * trans( vector( 0.0, 0.0, 1.0 ) );
    Crv3 = Crv2 * trans( vector( 0.0, 1.0, 0.0 ) );
    Srf = SFROMCRVS( list( Crv1, Crv2, Crv3 ), 3, KV_OPEN );
@\end{verbatim}
@See Figure~\ref{fig-sfromcrvs}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sfromcrvs.ps, width=3in}
=    <img  hspace=2 src="user_man/sfromcrvs.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A surface can be constructed from a list of curves substituted
-      as rows into its mesh using SFROMCRVS. The surface does not
-      necessarily interpolate the curves.
=</b><BR clear=all>
@}
@\label{fig-sfromcrvs}
@\end{figure}
$

@\subsubsection{SGAUSS}
!SGAUSS

@\begin{verbatim}
 SurfaceType SGAUSS( SurfaceType Srf, NumericType NumerOnly )
@\end{verbatim}

   evaluates the Gaussian curvature (K) field of surface {\bf Srf}.  If
 {\bf NumerOnly} is TRUE, only the numerator of the Gaussian curvature
 is derived.  Otherwise, if {\bf NumerOnly} is FALSE, the full exact
 Gaussian field is derived.  {\bf NumerOnly} TRUE may be used in cases
 where the zero set of K is needed (parabolic lines).

 Example:

@\begin{verbatim}
    Srf1 = hermite( cbezier( list( ctlpt( E3, 0.0, 0.0, 0.0 ),
                                   ctlpt( E3, 0.5, 0.2, 0.0 ),
                                   ctlpt( E3, 1.0, 0.0, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 1.0, 0.0 ),
                                   ctlpt( E3, 0.5, 0.8, 0.0 ),
                                   ctlpt( E3, 1.0, 1.0, 0.5 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ) ) ) );

    SGauss = SGAUSS( Srf1, false );
@\end{verbatim}

 evaluates the Gaussian curvaure of {\bf Srf1}.
@See Figure~\ref{fig-sgauss}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/sgauss.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/sgauss.gif">
=  <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      The Gaussian curvature field (right) of the quadratic by
-      cubic surface (left) is computed using SGAUSS. The Gaussian
-      curvature field is scaled down to \%1 to fit into the figure.
-      Compare with figure~\protect\ref{fig-smean}.
=</b><BR clear=all>
@}
@\label{fig-sgauss}
@\end{figure}
 See also EVOLUTE and SMEAN.
$

@\subsubsection{SILHOUETTE}
!SILHOUETTE

@\begin{verbatim}
 PolyType SILHOUETTE( SurfaceType Srf, VectorType ViewDir, NumericType Euc )

 or
 
 PolyType SILHOUETTE( PolyType Pl, VectorType ViewDir, NumericType Euc )
@\end{verbatim}

   compute the silhouette edges of the given {\bf Srf} or {\bf Pl} from the
 prescribed viewing direction {\bf ViewDir}.  The end result is a piecewise
 linear approximation of the exact silhouette, and its accuracy is controlled
 via the RESOLUTION variable, in the case of a freeform surface {\bf Srf}.
   If {\bf Euc} is TRUE, the silhouette curves are returned on the surface,
 in Euclidean space.  Otherwise, the silhouette curves are returned in the
 parametric space of {\bf Srf}.
   Both {\bf Euc} and the RESOLUTION variables have no affect in the case of
 a polygonal model {\bf Pl}.

 Example:

@\begin{verbatim}
 Resolution = 10;
 Sils = SILHOUETTE( glass, vector( 1, -2, 1 ), true );
@\end{verbatim}

 computes the silhouette curves of surface {\bf glass} as viewed from
 viewing direction {\bf (1, -2, 1)}, and returns the silhouette curves
 in Euclidean space.  See also ISOCLINE, PPROPFTCH and SASPCTGRPH.
$

@\subsubsection{SINTERP}
!SINTERP

@\begin{verbatim}
 SurfaceType SINTERP( ListType PtList, NumericType UOrder, NumericType VOrder,
                      NumericType USize, NumericType VSize,
                      ConstantType Param)
@\end{verbatim}
 
   computes a B-spline polynomial surface that interpolates or approximates
 the rectangular grid or scattered set of points in {\bf PtList}. The
 B-spline surface will have orders {\bf UOrder} and {\bf VOrder} and mesh
 of size {\bf USize} by {\bf VSize} control points. If the data is on a grid,
 the knots will be spaced according to {\bf Param} which can be one of
 PARAM\_UNIFORM, PARAM\_CHORD, PARAM\_CENTRIP or PARAM\_NEILFOL. Currently,
 only PARAM\_UNIFORM is supported. For a scattered point set, the {\bf Param}
 parameter is ignored.
   {\bf PtList} is a list of points for grid data in which all
 lists carry the same amount of points, thereby defining a
 rectangular grid.  For scattered data, {\bf PtList} is a linear list
 of points. All points in {\bf PtList} must be of type (E1-E9, P1-P9)
 control point, or regular PointType.  If {\bf USize} and {\bf VSize}
 are equal to the number of points in the grid data set of {\bf PtList},
 the resulting surface will {\em interpolate} the data set. Otherwise,
 if {\bf USize} or {\bf VSize} is less than the number of points in
 the grid of {\bf PtList}, the point data set will be least square
 approximated.  At no time can {\bf USize} or {\bf VSize} be larger that the
 number of points in {\bf PtList} or lower than {\bf UOrder} and {\bf VOrder},
 respectively. If {\bf USize} or {\bf VSize} are zero, the grid size
 is used, forcing an interpolation of the data set.
   If {\bf PtList} contains a linear list of points, these points are
 treated as scattered.  Each scattered point is assumed to be holding the
 parameteric location at which to interpolate its first two coefficients.
 The other coefficients are the interpolation values.  In other words,
 to interpolate scattered data of type E3, E5 control points in a linear
 list must be provided in (u, v, x, y, z) format.  Scattered data is
 interpolated over a unit square (0 to 1) parameteric domain in both u
 and v.
  
   All interior knots will be distinctly preserving maximal continuity.
 The resulting B-spline surface will have open end conditions.

 Example:
 
@\begin{verbatim}
    pl = nil();
    pll = nil();
    for ( x = -5, 1, 5,
          pl = nil():
          for ( y = -5, 1, 5,
                snoc( point( x, y, sin( x * Pi / 2 ) * cos( y * Pi / 2 ) ),
                      pl )
          ):
          snoc( pl, pll ) );

    s1 = SINTERP( pll, 3, 3, 8, 8, PARAM_UNIFORM );
    s2 = SINTERP( pll, 3, 3, 11, 11, PARAM_UNIFORM );
@\end{verbatim}

 samples an explicit surface sin(x) * cos(y) at a grid of 11 by 11 points,
 least square fit with a grid of size of 8 by 8 surface {\bf s1}, and
 interpolates surface {\bf s2} using this data set.   See also CINTERP and
 LINTERP.
@See Figure~\ref{fig-sinterp}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sinterp.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/sinterp.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A surface least square fitting a data set with insufficient
-      degrees of freedom (left) and actually interpolating the data
-      set (right), all using SINTERP.
=</b><BR clear=all>
@}
@\label{fig-sinterp}
@\end{figure}
$

@\subsubsection{SKEL2DINT}
!SKEL2DINT

@\begin{verbatim}
 ListType SKEL2DINT( CurveType Crv1 | PointType Pt1 | CtlPtType Pt1,
                     CurveType Crv2 | PointType Pt2 | CtlPtType Pt1,
                     CurveType Crv3 | PointType Pt3 | CtlPtType Pt1,
                     NumericType OutExtent, NumericType Epsilon,
                     NumericType FineNess )
@\end{verbatim}

    computes locations in the plane of points that are equadistant from the
 three given entities.  Entities can be points or control points or curves,
 all in the XY plane.  The equadistant points are computed as the mutual
 intersection of the bisectors of the entities.  Infinite bisectors (such
 as the bisector of two points) are extended up to {\bf OutExtent}.
 {\bf Epsilon} controls the tolerances while {\bf FineNess} controls the
 subdivision fineness in the bisector intersection computations.

 Exanple:

@\begin{verbatim}
    Crv1 = pcircle( vector( -0.5,  0.7, 0.0 ), 0.3 );
    Crv2 = pcircle( vector( -0.4, -0.6, 0.0 ), 0.5 );
    Crv3 = pcircle( vector(  0.3,  0.2, 0.0 ), 0.4 );

    EquaPt = SKEL2DINT( Crv1, Crv2, Crv3, 100, 0.1, 150 ):
@\end{verbatim}

  computes the eight points that are equadistant to three circles.
@See Figure~\ref{fig-skel2dint}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/skel2dint.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/skel2dint.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    Computes the eight points that are equadistant to three circles,
-    using SKEL2DINT.
=</b><BR clear=all>
@}
@\label{fig-skel2dint}
@\end{figure}
 See also CRC2CRVTAN.
$

@\subsubsection{SMEAN}
!SMEAN

@\begin{verbatim}
 SurfaceType SMEAN( SurfaceType Srf, NumericType NumerOnly )
@\end{verbatim}

   evaluates the mean curvature field of surface {\bf Srf} as follows:
 if {\bf NumerOnly} is true, it computes the numerator of only the Mean curvature.
 Otherwise, if {\bf NumerOnly} is false, the square of the exact Mean
 curvature field is derived.  {\bf NumerOnly} TRUE may be used in cases
 where the zero set of H is needed (k1 == -k2 points).

 Example:

@\begin{verbatim}
    Srf1 = hermite( cbezier( list( ctlpt( E3, 0.0, 0.0, 0.0 ),
                                   ctlpt( E3, 0.5, 0.2, 0.0 ),
                                   ctlpt( E3, 1.0, 0.0, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 1.0, 0.0 ),
                                   ctlpt( E3, 0.5, 0.8, 0.0 ),
                                   ctlpt( E3, 1.0, 1.0, 0.5 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ),
                                   ctlpt( E3, 0.0, 2.0, 0.0 ) ) ) );

    SMean = SMEAN( Srf1, false );
@\end{verbatim}

 evaluates the square of the mean curvature of {\bf Srf1}.
@See Figure~\ref{fig-smean}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/smean.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/smean.gif">
=  <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     The square of the mean curvature field (right) of the quadratic by
-     cubic surface (left) is computed using SMEAN. The square of the
-     mean curvature field is scaled down to \%1 to fit into the figure.
-     Compare with figure~\protect\ref{fig-sgauss}.
=</b><BR clear=all>
@}
@\label{fig-smean}
@\end{figure}
 See also EVOLUTE and SGAUSS.
$

@\subsubsection{SMERGE}
!SMERGE

@\begin{verbatim}
 SurfaceType SMERGE( SurfaceType Srf1, SurfaceType Srf2,
                     NumericType Dir, NumericType SameEdge )
@\end{verbatim}

 merges two surfaces along the requested direction (ROW or COL). If
 SameEdge is non-zero (ON or TRUE), then the common edge is assumed to be
 identical and copied only once. Otherwise (OFF or FALSE), a ruled surface
 is constructed between the two surfaces along the (not) common edge.

 Example:

@\begin{verbatim}
 MergedSrf = SMERGE( Srf1, Srf2, ROW, TRUE );
@\end{verbatim}

 See also MMERGE.
$

@\subsubsection{SMESH}
!SMESH

@\begin{verbatim}
 SurfaceType SMESH( TrivarType TV, MumericType Dir, NumericType Index )
@\end{verbatim}

 extracts a surface out of a trivariate, {\bf TV}, as the {\bf Index}'s plane
 of the control mesh of {\bf TV} in direction {\bf Dir}. {\bf Dir} can be
 one of COL, ROW, DEPTH.

 Example:

@\begin{verbatim}
 tv = tbezier( list( list( list( ctlpt( E3, 0.1, 0.0, 0.8 ),
                                 ctlpt( E3, 0.2, 0.1, 2.4 ) ),
                           list( ctlpt( E3, 0.3, 2.2, 0.2 ),
                                 ctlpt( E3, 0.4, 2.3, 2.0 ) ) ),
                     list( list( ctlpt( E3, 2.4, 0.8, 0.1 ),
                                 ctlpt( E3, 2.2, 0.7, 2.3 ) ),
                           list( ctlpt( E3, 2.3, 2.6, 0.5 ),
                                 ctlpt( E3, 2.1, 2.5, 2.7) ) ) ) );
 s0 = SMESH( tv, col, 0 );
 s1 = SMESH( tv, col, 1 );
@\end{verbatim}

 extracts the two (first and last) planes in direction {\bf col} out of
 trivariate {\bf tv}.

 See also STRIVAR, CMESH, MFROMMESH.
$

@\subsubsection{SMOEBIUS}
!SMOEBIUS

@\begin{verbatim}
 CurveType SMOEBIUS( CurveType Crv, NumericType Ratio, NumericType Dir )
@\end{verbatim}

   rebalances the weights of a rational surface using the Moebius
 transformation.  The shape of the surface remains identical, while the
 speed is modified in the direction {\bf Dir}.
 {\bf Ratio} controls the ratio between the last and first weights of
 the first row/column. If {\bf Ratio} = 0, the first and last weights are
 made equal.

 See also CMOEBIUS.
$

@\subsubsection{SMOOTHNRML}
!SMOOTHNRML

@\begin{verbatim}
 ListType SMOOTHNRML( ListType Obj, NumericType MaxAngle )

 or

 PolygonType SMOOTHNRML( PolygonType Obj, NumericType MaxAngle )
@\end{verbatim}

 Given a (list of) polygonal object(s), {\bf Obj}, compute normals to
 the vertices by averaging the normals of the polygons that share the
 vertices.  Only vertices where the deviation between the polygons' normals
 and the averaged normal is less than {\bf MaxAngle} are updated.
   If {\bf MaxAngle} is negative, all vertices normals are cleared and all
 polygon normals reevaluated.
   This is useful for polygonal data sets that have no vertex normals.

 Example:

@\begin{verbatim}
    A = box( vector( -1, -1, -1 ), 2, 2, 2 );
    B = SMOOTHNRML( A, 90 );
@\end{verbatim}

 computes average normals to a curve resulting in the smoothly shaded display
 of a cube.
$

@\subsubsection{SMOMENTS}
!SMOMENTS

@\begin{verbatim}
 SurfaceType SMOMENTS( SurfaceType Srf, NumericType Moment,
                       NumericType Axis1, NumericType Axis2,
                       NumericType Eval )

 or

 NumericType SMOMENTS( SurfaceType Srf, NumericType Moment,
                       NumericType Axis1, NumericType Axis2,
                       NumericType Eval )
@\end{verbatim}

   compute the integral moment surface, {\em MSrf}, of the given surface
 {\bf Srf}, up to a sign.  The computed moment can be either a first order
 moment when {\bf Moment} = 1, or a second order moment when {\bf Moment} = 2.
   If {\bf Srf} is a closed surface with domain (u0, v0) to (u1, v1), then
 the difference of {\em MSrf}(u1, v1) - {\em MSrf}(u0, v0) is the requested
 moment.  Otherwise, the computation is for the volume occupied between the
 surface {\bf Srf} and the XY plane.
   If {\bf Eval} is TRUE, the actual numerical value of the moment is returned.
 The moment integral surface is returned if {\bf Eval} is FALSE.
   {\bf Axis1} and {\bf Axis2} prescribe the two axes to compute the moments
 for a second order moment computation.  For a first order moment
 computation only {\bf Axis1} is considered.

 Example:

@\begin{verbatim}
    Spr = surfPRev( cregion( pcircle( vector( 0, 0, 0 ), 1 ), 1, 3 )
                    * ry( 90 ) );
    SMOMENTS( Spr, 2, 1, 1, 2, 1 );
@\end{verbatim}
 computes the second order XX moment of a polynomial approximation of a
 unit sphere, using method one.  See also SVOLUME and CAREA.
$

@\subsubsection{SMORPH}
!SMORPH

@\begin{verbatim}
 SurfaceType SMORPH( SurfaceType Srf1, SurfaceType Srf2, NumericType Blend )
@\end{verbatim}

 creates a new surface which is a {\em convex blend} of the two given surfaces.
 The two given surfaces must be compatible (see FFCOMPAT) before this blend
 is invoked. This is very useful if a sequence that "morphs" one surface to
 another is to be created.

 Example:

@\begin{verbatim}
 for ( i = 0.0, 1.0, 11.0,
        Msrf = SMORPH( Srf1, Srf2, i / 11.0 ):
        color( Msrf, white ):
        attrib( Msrf, "rgb", "255,255,255" ):
        attrib( Msrf, "reflect", "0.7" ):
        save( "morp1-" + i, Msrf )
 );
@\end{verbatim}

 creates a sequence of 12 surfaces, morphed from {\bf Srf1} to {\bf Srf2}
 and saves them in the files "morph-0.itd" to "morph-11.itd".
 See also PMORPH, CMORPH and TMORPH.
@See Figure~\ref{fig-smorph}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/smorph.ps, width=5.5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/smorph.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    A morphing sequence between a bottle and a glass. Snapshots computed
-    using SMORPH.
=</b><BR clear=all>
@}
@\label{fig-smorph}
@\end{figure}
$

@\subsubsection{SNORMAL}
!SNORMAL

@\begin{verbatim}
 VectorType SNORMAL( SurfaceType Srf, NumericType UParam, NumericType VParam )

 or

 VectorType SNORMAL( TrimSrfType Srf, NumericType UParam, NumericType VParam )
@\end{verbatim}

   compute the normal vector to (possibly trimmed) surface {\bf Srf} at the
 parameter values {\bf UParam} and {\bf VParam}. The returned vector has a
 unit length.

 Example:

@\begin{verbatim}
    Normal = SNORMAL( Srf, 0.5, 0.5 );
@\end{verbatim}

 computes the normal to {\bf Srf} at the parameter values (0.5, 0.5).
 See also SNRMLSRF.
$

@\subsubsection{SNRMLSRF}
!SNRMLSRF

@\begin{verbatim}
 SurfaceType SNRMLSRF( SurfaceType Srf )
@\end{verbatim}

 symbolically computes a vector field surface representing the non-normalized
 normals of the given surface. That is, the normal surface, evaluated at
 $(u, v)$, provides a vector in the direction of the normal of the original
 surface at $(u, v)$. The normal surface is computed as the symbolic cross
 product of the two surfaces representing the partial derivatives of the
 original surface.

 Example:

@\begin{verbatim}
 NrmlSrf = SNRMLSRF( Srf );
@\end{verbatim}
@See Figure~\ref{fig-snrmlsrf}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{c}
@    \epsfig{file=user_man/snrmlsrf.ps, width=5in}
=    <img  hspace=2 src="user_man/snrmlsrf.gif">
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    A vector field normal (right) computed for a unit sphere (left) using
-    SNRMLSRF.  The normal field degenerates at the north and south 
-    poles because the surface is not regular there.
=</b><BR clear=all>
@}
@\label{fig-snrmlsrf}
@\end{figure}
$

@\subsubsection{SPARABOLC}
!SPARABOLC

@\begin{verbatim}
 ListType SPARABOLC( SurfaceType Srf, NumericType Euclidean )
@\end{verbatim}

   computes the parabolic edges of a freeform surface, {\bf Srf}, as
 the zero set of the Gaussian curvature.  A scalar field with the sign of
 the Gauss curvature is computed and its zero is derived.
   If {\bf Euclidean} is false, the list of (piecewise linear) parabolic
 curves is returned in the parametric space of {\bf Srf}.  Otherwise, if
 {\bf Euclidean} is true, the parabolic curves are mapped onto {\bf Srf}.

 Example:

@\begin{verbatim}
 pl = nil();
 pll = nil();
 for ( x = -3, 1, 3,
       pl = nil():
       for ( y = -3, 1, 3,
           snoc( point( x, y, sin( x * Pi / 2 ) * cos( y * Pi / 2 ) ),
                 pl ) ):
     snoc( pl, pll ) );
 EggBase = sinterp( pll, 4, 4, 0, 0, PARAM_UNIFORM );

 Resolution = 15;
 Parab = SPARABOLC( EggBase, true );
@\end{verbatim}

 constructs a surface in the shape of an egg carton's base and then derives its
 parabolic edges in Euclidean space.
$

@\subsubsection{SPHERE}
!SPHERE

@\begin{verbatim}
 PolygonType SPHERE( VectorType Center, NumericType Radius )
@\end{verbatim}

   creates a SPHERE geometric object, defined by {\bf Center} as the center of
 the SPHERE, and with {\bf Radius} as the radius of the SPHERE.
   See RESOLUTION for accuracy of SPHERE approximation as a polygonal model. 
   See IRITSTATE's "PrimRatSrfs" and "PrimRatSrfs" state variables.
$

@\subsubsection{SPLITLST}
!SPLITLST

@\begin{verbatim}
 ListType SPLITLST( AnyType LinkedListObj )
@\end{verbatim}

   splits an objected of several linked list data elements such as polygons,
 curves, or suraces, into a list object that contains an object for each of
 the individual objects.

 Example:

@\begin{verbatim}
 ObjLst = SPLITLST( axes );
@\end{verbatim}

 splits the axes object into a list object of several objects each holding
 a single polyline.
$

@\subsubsection{SPOWER}
!SPOWER

@\begin{verbatim}
 SurfaceType SPOWER( ListType CtlMesh )
@\end{verbatim}

   creates a polynomial/rational surface out of the provided control mesh.
 The created surface employs the monomial power basis. {\bf CtlMesh} is a
 list of rows, each of which is a list of control points. All control points
 must be of type (E1-E9, P1-P9), or regular PointType defining the surface's
 control mesh. The surface's point type will be of a space which is the
 union of the spaces of all points.
@The created surface is the polynomial (or rational),
@\begin{equation}
@     C(u, v) = \sum_{i=0}^m \sum_{j=0}^n P_{ij} u^i v^i
@\end{equation}
@where $P_{ij}$ are the control points {\bf CtlMesh}. and $m$ and $n$ are the
@degrees of the surface, which are one less than the number of points in the
@appropriate direction.

 Example:

@\begin{verbatim}
 s = SPOWER( list( list( ctlpt( E3, 1, 0, 1 ),
                         ctlpt( E3, 0, 1, 1 ) ),
                   list( ctlpt( E3, 0, 0, 1 ),
                         ctlpt( E3, 0, 0, 1 ) ) ) );
 s == coerce( coerce( s, bezier_type ), power_type );
@\end{verbatim}

 constructs a bilinear power basis surface, coerces it to a Bezier form,
 coerces the Bezier form back to a power basis, and then compares the result
 for equality.

 See also CBEZIER, SBSPLINE and SPOWER.
$

@\subsubsection{SRADCRVTR}
!SRADCRVTR

@\begin{verbatim}
 SurfaceType SRADCRVTR( SurfaceType Srf, VectorType ViewDir,
                        NumericType SubdivTol, NumericType SubdivTol,
                        NUmericType MergeTol )
@\end{verbatim}

   computes the radial curvature of surface {\bf Srf}, as viewed from view
 direction {\bf ViewDir}.  See MZERO for the meaning of the {\bf SubdivTol}
 and {\bf NumerTol} tolerances. {\bf MergeTol} specifies the tolerance to
 use to merge points into polygons,
$

@\subsubsection{SRAISE}
!SRAISE

@\begin{verbatim}
 SurfaceType SRAISE( SurfaceType Srf, ConstantType Direction,
                                                      NumericType NewOrder )
@\end{verbatim}

   raises {\bf Srf} to the specified {\bf NewOrder} in the specified
 {\bf Direction}.

 Example:

@\begin{verbatim}
    Srf = ruledSrf( cbezier( list( ctlpt( E3, -0.5, -0.5, 0.0 ),
                                   ctlpt( E3,  0.5, -0.5, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, -0.5,  0.5, 0.0 ),
                                   ctlpt( E3,  0.5,  0.5, 0.0 ) ) ) );
    Srf = SRAISE( SRAISE( Srf, ROW, 3 ), COL, 3 );
@\end{verbatim}

 constructs a bilinear flat-ruled surface and raises both its directions to be
 a bi-quadratic surface.
 See also TRAISE, MRAISE, and CRAISE.
$

@\subsubsection{SRAYCLIP}
!SRAYCLIP

@\begin{verbatim}
 ListType SRAYCLIP( PointType Pt, VectorType Dir, SurfaceType Srf )
@\end{verbatim}

   computes the intersection of ray ({\bf Pt}, {\bf Dir}) with Bezier surface
 {\bf Srf}, using the Bezier clipping scheme.  The returned list is of the
 form "list( NumInters, UV0, EucPt0, ..., UVn, EucPtn )".

 Example:

@\begin{verbatim}
    InterPts = SRayClip( point( 0, 0, 0 ), vector( 0, 0, 1 ), Srf );
@\end{verbatim}

 computes the intersection of surface {\bf Srf} with the positive Z axis.
$


@\subsubsection{SREFINE}
!SREFINE

@\begin{verbatim}
 SurfaceType SREFINE( SurfaceType Srf, ConstantType Direction,
                      NumericType Replace, ListType KnotList )
@\end{verbatim}

   provides the ability to {\bf Replace} a knot vector of {\bf Srf} or refine 
 it in the specified direction {\bf Direction} (ROW or COL).
   {\bf KnotList} is a list of knots at which to refine {\bf Srf}. All knots should
 be contained in the parametric domain of {\bf Srf} in {\bf Direction}. If the knot
 vector is replaced, the length of {\bf KnotList} should be identical to the
 length of the original knot vector of {\bf Srf} in {\bf Direction}. If {\bf Srf}
 is a Bezier surface, it is automatically promoted to be a B-spline surface.

 Example:

@\begin{verbatim}
    Srf = SREFINE( SREFINE( Srf,
                            ROW, FALSE, list( 0.333, 0.667 ) ),
                   COL, FALSE, list( 0.333, 0.667 ) );
@\end{verbatim}

 refines {\bf Srf} in both directions by adding two more knots at 0.333 and
 0.667.   See also CREFINE, TREFINE, and MREFINE.
$

@\subsubsection{SREGION}
!SREGION

@\begin{verbatim}
 SurfaceType SREGION( SurfaceType Srf, ConstantType Direction,
                                  NumericType MinParam, NumericType MaxParam )
 or

 TrimSrfType SREGION( TrimSrfType Srf, ConstantType Direction,
                                  NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   extract a region of {\bf Srf} between {\bf MinParam} and {\bf MaxParam}
 in the specified {\bf Direction}. Both {\bf MinParam} and {\bf MaxParam}
 should be contained in the parametric domain of {\bf Srf} in {\bf Direction},
 except for Bezier surfaces when {\bf MinParam} and {\bf MaxParam} can be
 arbitrary (extrapolating if not between zero and one).

 Example:

@\begin{verbatim}
    Srf = ruledSrf( cbezier( list( ctlpt( E3, -0.5, -0.5, 0.5 ),
                                   ctlpt( E3,  0.0,  0.5, 0.0 ),
                                   ctlpt( E3,  0.5, -0.5, 0.0 ) ) ),
                    cbezier( list( ctlpt( E3, -0.5,  0.5, 0.0 ),
                                   ctlpt( E3,  0.0,  0.0, 0.0 ),
                                   ctlpt( E3,  0.5,  0.5, 0.5 ) ) ) );
    SubSrf = SREGION( Srf, ROW, 0.3, 0.6 );
@\end{verbatim}

 extracts the region of {\bf Srf} from the parameter value 0.3 to the
 parameter value 0.6 along the ROW direction. The COLumn direction is
 extracted as a whole.
@See Figure~\ref{fig-sregion}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sregion.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/sregion.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    A region can be extracted from a freeform surface using SREGION.
=</b><BR clear=all>
@}
@\label{fig-sregion}
@\end{figure}
 See also CREGION, TREGION, and MREGION.
$

@\subsubsection{SREPARAM}
!SREPARAM

@\begin{verbatim}
 SurfaceType SREPARAM( SurfaceType Srf, ConstantType Direction,
                                  NumericType MinParam, NumericType MaxParam )
 or

 TrimSrfType SREPARAM( TrimSrfType Srf, ConstantType Direction,
                                  NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   reparametrize {\bf Srf} over a new domain from {\bf MinParam} to {\bf MaxParam},
 in the prescribed {\bf Direction}. This operation does not affect the geometry
 of the (trimmed) surface and only affine transforms its knot vectors. A
 Bezier (trimmed) surface will automatically be promoted into a B-spline
 surface by this function.

   If {\bf MinParam} equals {\bf MaxParam} and both equates with one of the
 parameterization keywords of PARAM\_CENTRIP, PARAM\_CENTRIP, PARAM\_CHORD, or
 PARAM\_NIELFOL, then that parametrization is approximated for the surface, by
 changing the knot sequence.  Note this last operation affects the geometry
 of the surface.

 Example:

@\begin{verbatim}
    srf = sbspline( 2, 4,
                     list( list( ctlpt( E3, 0.0, 0.0, 1.0 ),
                                 ctlpt( E2, 0.0, 1.0 ),
                                 ctlpt( E3, 0.0, 2.0, 1.0 ) ),
                           list( ctlpt( E2, 1.0, 0.0 ),
                                 ctlpt( E3, 1.0, 1.0, 2.0 ),
                                 ctlpt( E2, 1.0, 2.0 ) ),
                           list( ctlpt( E3, 2.0, 0.0, 2.0 ),
                                 ctlpt( E2, 2.0, 1.0 ),
                                 ctlpt( E3, 2.0, 2.0, 2.0 ) ),
                           list( ctlpt( E2, 3.0, 0.0 ),
                                 ctlpt( E3, 3.0, 1.0, 2.0 ),
                                 ctlpt( E2, 3.0, 2.0 ) ),
                           list( ctlpt( E3, 4.0, 0.0, 1.0 ),
                                 ctlpt( E2, 4.0, 1.0 ),
                                 ctlpt( E3, 4.0, 2.0, 1.0 ) ) ),
                     list( list( KV_OPEN ),
                           list( KV_OPEN ) ) );
    
    srf = sreparam( sreparam( srf, ROW, 0, 1 ), COL, 0, 1 );
@\end{verbatim}

 ensures that the (trimmed) B-spline surface is defined over the unit size
 parametric domain.  See also CREPARAM, TREPARAM, and MREPARAM.
$

@\subsubsection{SREVERSE}
!SREVERSE

@\begin{verbatim}
 SurfaceType SREVERSE( SurfaceType Srf )

 or

 TrimSrfType SREVERSE( TrimSrfType Srf )
@\end{verbatim}

   reverse {\bf Srf} by flipping the U and V parametric directions.
 Note that the unary minus (i.e -{\bf Srf}) also reverses the surface by
 reversing the U parametric direction.  If the surface is a trimmed surface,
 the trimming curves are flipped accordingly to yield the same shape.

@\begin{verbatim}
  RevSrf = SREVERSE( Srf );
@\end{verbatim}

  See also MREVERSE.
$

@\subsubsection{SRF2TANS}
!SRF2TANS

@\begin{verbatim}
 ListType SRF2TANS( SurfaceType Srfs, NumericType Orientation,
                    NumericType SubdivTol, NumericType NumericTol,
                    NumericType MergeTol )
@\end{verbatim}

   computes the developable sheet(s) bi-tangent to given two surfaces
 {\bf Srfs}.  {\bf Srfs} can be either a list of two surfaces or a single
 surface in which self bi-tangencies are being sought.  
   If Orientation is 0 all bi-tangent sheet(s) are returned.  Otherwise, if
 Orientation equal +1 or -1, bi-tangent sheets(s) with same or different 
 tangency orienation are returned, respectively.  See MZERO for the meaning
 of the {\bf SubdivTol} and {\bf NumerTol} tolerances.
   Returns are lists, one per developable sheet, of sample points in E4, having
 two pairs of parameter values of the bi-tangent points in the two surfaces,
 in their parametric domain.

  Example:

@\begin{verbatim}
  c1 = cbspline( 3, 
                 list( ctlpt( E2, -1, -1 ),
                       ctlpt( E2,  1, -1 ),
                       ctlpt( E2,  1,  1 ),
                       ctlpt( E2, -1,  1 ) ),
                 list( kv_periodic ) );
  c1 = coerce( c1, kv_open );
  c2 = cbspline( 3,
                 list( ctlpt( E3,  0.8,  -0.2,  -0.3 ),
                       ctlpt( E3,  0.5,   0.0,  -0.2 ),
                       ctlpt( E2, -0.45, -0.21 ),
                       ctlpt( E2, -0.45,  0.32 ),
                       ctlpt( E3,  0.5,  -0.0,   0.2 ),
                       ctlpt( E3,  0.8,   0.28,  0.3 ) ),
                 list( kv_open ) );
  s = sregion( sweepSrf( c1 * sc( 0.1 ), c2, off ), col, 0, 0.5 );

  BiTans = SRF2TANS( list( s, s ), 0, 0.1, -1e-6, 1e-1 );
@\end{verbatim}

   computes the self bi-tangencies of a given bottle-like surface.
@See Figure~\ref{fig-srf2tans}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/srf2tans.ps, height=3.5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/srf2tans.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Extracts self bi-tangent developable out of the given surface
-     using SRF2TANS.
=</b><BR clear=all>
@}
@\label{fig-srf2tans}
@\end{figure}
 See also SRF3TANS.
$

@\subsubsection{SRF3TANS}
!SRF3TANS

@\begin{verbatim}
 ListType SRF3TANS( ListType Srfs, NumericType Orientation,
                    NumericType SubdivTol, NumericType NumericTol )
@\end{verbatim}

   computes the plane(s) tri-tangent to given three surfaces {\bf Srfs}.
 {\bf Srfs} can be either a list of three surfaces or a list of one
 surface in which self bi-tangencies are being sought.
   If Orientation is 0 all tri-tangent planes are returned. Otherwise, if
 Orientation equal +1 or -1, tri-tangent sheets(s)with same or different
 tangency orienation are returned, respectively.  See MZERO for the meaning
 of the {\bf SubdivTol} and {\bf NumerTol} tolerances.
   Returns are lists, one per developable sheet, of sample points in E6, having
 three pairs of parameter values of the tri-tangent points in the three
 surfaces, in their parametric domain.

  Example:

@\begin{verbatim}
  c2 = cbspline( 3,
                 list( ctlpt( E3,  0.8,  -0.2,  -0.3 ),
                       ctlpt( E3,  0.5,   0.0,  -0.2 ),
                       ctlpt( E2, -0.45, -0.21 ),
                       ctlpt( E2, -0.45,  0.32 ),
                       ctlpt( E3,  0.5,  -0.0,   0.2 ),
                       ctlpt( E3,  0.8,   0.28,  0.3 ) ),
                 list( kv_open ) );
  s1 = sFromCrvs( list( c2 * sc( 0.001 ),
                        c2,
                        c2 * tz( 1.0 ),
                        c2 * sc( 0.001 ) * tz( 1.0 ) ),
                  3, kv_open ) * sc( 0.1 );
  s2 = s1 * ry( 14 ) * tx( 0.6 ) * tz( 0.02 );
  s3 = s1 * rx( 12 ) * ty( 0.6 ) * tx( 0.3 ) * tz( 0.01 );

  TriTans = SRF3TANS( list( s1, s2, s3 ) * sz( 1 ), 1, 0.5, -1e-6 );
  Edges = nil();
  for ( i = 1, 1, sizeof( TriTans ),
        Pt = nth( TriTans, i ):
        snoc( seval( s1, coord( Pt, 1 ), coord( Pt, 2 ) ) +
              seval( s2, coord( Pt, 3 ), coord( Pt, 4 ) ), Edges ):
        snoc( seval( s1, coord( Pt, 1 ), coord( Pt, 2 ) ) +
              seval( s3, coord( Pt, 5 ), coord( Pt, 6 ) ), Edges ):
        snoc( seval( s2, coord( Pt, 3 ), coord( Pt, 4 ) ) +
              seval( s3, coord( Pt, 5 ), coord( Pt, 6 ) ), Edges ) );
@\end{verbatim}

   computes the two outer oriented tri-tangencies to three approximate
 ellipsoids.  Extract and draw the two tri-tangent triangles.
@See Figure~\ref{fig-srf3tans}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/srf3tans.ps, width=5in}
=    <img  hspace=2 src="user_man/srf3tans.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Extracts tri-tangent planes out of the given three approximate
-     ellipsoids using SRF3TANS.
=</b><BR clear=all>
@}
@\label{fig-srf3tans}
@\end{figure}
 See also SRF2TANS.
$

@\subsubsection{SRFFFORM}
!SRFFFORM

@\begin{verbatim}
 ListType SRFFFORM( SurfaceType Srf, NumericType Form )
@\end{verbatim}

   derives the four coefficients of the 1st, 2nd or 3rd surface fundamental
 forms.  {\bf Form} can be one of 1, 2, or 3 only, designating the requested
 form.  Since this 2x2 matrix is symmetric, only three coefficients are
 returned as a list of three scalar surfaces as (A11, A12 == A21, A22).

  Example:

@\begin{verbatim}
  FFF = SRFFFORM( Srf, 1 );
  SFF = SRFFFORM( Srf, 2 );
  TFF = SRFFFORM( Srf, 3 );
@\end{verbatim}

  computes the three fundamental forms of {\bf Srf}.
$

@\subsubsection{SRFLNDST}
!SRFLNDST

@\begin{verbatim}
 PointType SRFLNDST( SurfaceType Srf, PointType LnPt, VectorType LnDir,
                     NumericType IsMinDist, NumericType SubdivTol,
                     NumericType NumerTol )
@\end{verbatim}

   compute the minimal ({\bf IsMinDist} TRUE) or maximal ({\bf IsMinDist} FALSE) 
 distance betweeb surface {\bf Srf} and the line defined by {\bf LnPt}, a point
 on the line, and {\bf LnDir}, the direction of the line.
   See MZERO for the meaning of the {\bf SubdivTol} and {\bf NumerTol}
 tolerances.

  Example:

@\begin{verbatim}
  Dst = SRFLNDST( Srf, LnPoint, vector( 1, 1, 1 ), TRUE, 0.1, 1e-6 );
@\end{verbatim}

  computes the minimal distance between Srf and line LnPoint/Vector( 1, 1, 1 ).
 See also SRFPTDST, CRVLNDST.
$

@\begin{verbatim}
 PolyType SRFKERNEL( SurfaceType Srf, NumericType Fineness,
                     NumericType SkipRate )
@\end{verbatim}

@\subsubsection{SRFKERNEL}
!SRFKERNEL

@\begin{verbatim}
 PolyType SRFKERNEL( SurfaceType Srf, NumericType Fineness,
                     NumericType SkipRate )
@\end{verbatim}

   approximates the kernel of (closed and continuous) surface {\bf Srf} by
 deriving the parabolic points of {\bf Srf} and intersecting half planes
 tangent to {\bf Srf} and placed at a sampled set of parabolic locations.  The
 fineness of the parabolic curves' approximation is governed by {\bf Fineness}
 and the sampling rate is controled by {\bf SkipRate}.

  Example:

@\begin{verbatim}
  Krnl = SRFKERNEL( Srf, 40, 15 );
@\end{verbatim}

 estimates the kernel of {\bf Srf} with {\bf Fineness} of 40 and {\bf SkipRate}
 of 15.
$

@\subsubsection{SRFPTDST}
!SRFLNDST

@\begin{verbatim}
 PointType SRFLNDST( SurfaceType Srf, PointType Pt
                     NumericType IsMinDist, NumericType SubdivTol,
                     NumericType NumerTol )
@\end{verbatim}

   compute the minimal ({\bf IsMinDist} TRUE) or maximal ({\bf IsMinDist} FALSE) 
 distance between surface {\bf Srf} and point {\bf Pt}.
   See MZERO for the meaning of the {\bf SubdivTol} and {\bf NumerTol}
 tolerances.

  Example:

@\begin{verbatim}
  Dst = SRFPTDST( Srf, Pt1, FALSE, 0.1, 1e-6 );
@\end{verbatim}

  computes the maximal distance between Srf and point Pt1.
 See also SRFLNDST, CRVPTDST.
$

@\subsubsection{SRINTER}
!SRINTER

@\begin{verbatim}
 PointType SRINTER( SurfaceType Srf, PointType RayOrigin,
                    VectorType RayDirection )
@\end{verbatim}

   computes the first intersection, if any, of the prescribed ray originating
 from {\bf RayOrigin} in direction {\bf RayDirection} with surface {\bf Srf}.
   It returns the intersection point in the parametric space of {\bf Srf} with
 the U and V coordinates as the X and Y coefficients of the returned value.
   The intersection is computed between the ray and a polygonal approximation
 of the surface {\bf Srf} as set via the RESOLUTION variable.

 Example:

@\begin{verbatim}
    RayOrigin = point( 2, 0.1, 0.3 );
    RayDir = vector( -4, 0, 0 );

    RayLine = coerce( RayOrigin, E3 ) + coerce( RayOrigin + RayDir, E3 );
    color( RayLine, magenta );
    attrib( RayLine, "dwidth", 2 );

    resolution = 5;
    InterPt = SRINTER( glass, RayOrigin, RayDir );
    InterPtE3 = seval( glass, coord( InterPt, 0 ), coord( InterPt, 1 ) );
    color( InterPtE3, cyan );
    attrib( InterPtE3, "dwidth", 3 );
    view( list( InterPtE3, RayLine, glass, axes ), 1 );

    resolution = 80;
    InterPt = SRINTER( glass, RayOrigin, RayDir );
    InterPtE3 = seval( glass, coord( InterPt, 0 ), coord( InterPt, 1 ) );
    color( InterPtE3, cyan );
    attrib( InterPtE3, "dwidth", 3 );
    view( list( InterPtE3, RayLine, glass, axes ), 1 );
@\end{verbatim}

 This is a complete example of constructing a ray and intersecting it against a
 surface of a glass at two different resolutions, resulting in two different
 accuracies. See also RESOLUTION.
$

@\subsubsection{SSINTER}
!SSINTER

@\begin{verbatim}
 ListType SSINTER( SurfaceType Srf1, SurfaceType Srf2,
                   NumericType Euclidean, NumericType Epsilon,
                   NumericType Alignment )
@\end{verbatim}

   computes the intersection curve of two surfaces, {\bf Srf1} and {\bf Srf2},
 up to {\bf Epsilon} accuracy.  The returned data is in Euclidean space if
 {\bf Euclidean} is true; otherwise it is in the parametric space.
   A list of two lists (for the two surfaces) of n curves each,
 where n is the number of intersection curves, is returned.
   If {\bf Alignment} is true, the surfaces are rotated to that one bbox
 of one surface whose axes are aligned, increasing the probability of detecting
 disjoint cases.

 Example:

@\begin{verbatim}
    s1 = sphereSrf( 0.35 ) * trans( vector( 0.0, 0.1, 0.2 ) );
    s2 = coneSrf( 1, 0.5 );
 
    Inter = nth( SSINTER( s1, s2, true, 0.1, false ), 1 );
@\end{verbatim}

 computes the Euclidean intersection curves of a cone and a sphere,
 in general positions.  The Euclidean curves on the first surface are
 extracted while purging the Euclidean curves on the second surface.
$

@\subsubsection{STANGENT}
!STANGENT

@\begin{verbatim}
 VectorType STANGENT( SurfaceType Srf, ConstantType Direction,
                      NumericType UParam, NumericType VParam )

 or

 VectorType STANGENT( TrimSrfType Srf, ConstantType Direction,
                      NumericType UParam, NumericType VParam )
@\end{verbatim}

   compute the tangent vector to the (possibly trimmed) surface {\bf Srf} at the
 parameter values {\bf UParam} and {\bf VParam} in {\bf Direction}. The
 returned vector has a unit length.

 Example:

@\begin{verbatim}
    Tang = STANGENT( Srf, ROW, 0.5, 0.6 );
@\end{verbatim}

 computes the tangent to {\bf Srf} in the ROW direction at the parameter
 values (0.5, 0.6).
$

@\subsubsection{STRIMSRF}
!STRIMSRF

@\begin{verbatim}
 SurfaceType STRIMSRF( TrimSrfType TSrf )
@\end{verbatim}

   extracts the surface of a trimmed surface {\bf TSrf}.

 Example:

@\begin{verbatim}
    Srf = STRIMSRF( TrimSrf ); 
@\end{verbatim}

 extracts the surface of {\bf TrimSrf}.
$

@\subsubsection{STRIVAR}
!STRIVAR

@\begin{verbatim}
 SurfaceType STRIVAR( TrivarType TV, ConstantType Direction,
                                                          NumericType Param ) )
@\end{verbatim}

   extracts an iso surface from a trivariate function {\bf TV} in the specified
 {\bf Direction} (ROW or COL or DEPTH) at the specified parameter value
 {\bf Param}.
   {\bf Param} must be contained in the parametric domain of {\bf TV} in
 {\bf Direction} direction.
 The returned surface is {\em in} the trivariate {\bf TV}.

 Example:

@\begin{verbatim}
    TV1 = tbezier( list( list( list( ctlpt( E3, 0.1, 0.0, 0.8 ),
                                     ctlpt( E3, 0.2, 0.1, 2.4 ) ),
                               list( ctlpt( E3, 0.3, 2.2, 0.2 ),
                                     ctlpt( E3, 0.4, 2.3, 2.0 ) ) ),
                         list( list( ctlpt( E3, 2.4, 0.8, 0.1 ),
                                     ctlpt( E3, 2.2, 0.7, 2.3 ) ),
                               list( ctlpt( E3, 2.3, 2.6, 0.5 ),
                                     ctlpt( E3, 2.1, 2.5, 2.7) ) ) ) );
    Srf = STRIVAR( TV1, col, 0.4 ); 
@\end{verbatim}

 extracts an iso surface of {\bf TV1}, in the {\bf col} direction at
 parameter value 0.4.
@See Figure~\ref{fig-strivar}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/strivar.ps, width=5in}
=    <img  hspace=2 src="user_man/strivar.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Extracts an iso bilinear surface from a trilinear function,
-     using STRIVAR.
=</b><BR clear=all>
@}
@\label{fig-strivar}
@\end{figure}
 See also SMESH, CSURFACE, MFROMMV.
$

@\subsubsection{SURFPREV}
!SURFPREV

@\begin{verbatim}
 SurfaceType SURFPREV( CurveType Object )
@\end{verbatim}

 This is the same as SURFREV but approximates the surface of revolution as a
 {\em polynomial} surface. The object must be a polynomial curve.
 See SURFREV.
$

@\subsubsection{SURFREV}
!SURFREV

@\begin{verbatim}
 PolygonType SURFREV( PolygonType Object )

 or
 
 SurfaceType SURFREV( CurveType Object )
@\end{verbatim}

   create a surface of revolution by rotating the first polygon/curve of the
 given {\bf Object}, around the Z axis. Use the linear transformation functions
 to position a surface of revolution in a different orientation.

 Example:

@\begin{verbatim}
    VTailAntn = SURFREV( ctlpt( E3, 0.001, 0.0, 1.0 ) +
                         ctlpt( E3, 0.01,  0.0, 1.0 ) +
                         ctlpt( E3, 0.01,  0.0, 0.8 ) +
                         ctlpt( E3, 0.03,  0.0, 0.7 ) +
                         ctlpt( E3, 0.03,  0.0, 0.3 ) +
                         ctlpt( E3, 0.001, 0.0, 0.0 ) );
@\end{verbatim}

 constructs a piecewise linear B-spline curve in the XZ plane and uses it to
 construct a surface of revolution by rotating it around the Z axis.
   See also SURFPREV, SURFREVAXS, SURFREV2, SURFREVAX2.
@See Figure~\ref{fig-surfrev}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/surfrev.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/surfrev.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A surface of revolution, VTailAntn in surfrev documentation, can be
-     constructed using SURFREV or SURFPREV.
=</b><BR clear=all>
@}
@\label{fig-surfrev}
@\end{figure}
$

@\subsubsection{SURFREVAXS}
!SURFREVAXS

@\begin{verbatim}
 PolygonType SURFREVAXS( PolygonType Object, VectorType Axis )

 or
 
 SurfaceType SURFREVAXS( CurveType Object, VectorType Axis )
@\end{verbatim}

   create a surface of revolution by rotating the first polygon/curve of the
 given {\bf Object}, around the {\bf Axis} axis. Use the linear transformation
 functions to position a surface of revolution in a different location.

 Example:

@\begin{verbatim}
    Glass = SURFREVAXS( GCross, vector( 1, 0, 1 ) );
@\end{verbatim}

 constructs a surface of revolution by rotating {\bf GCross} around the axis of (1, 0, 1).
   See also SURFPREV, SURFREV, SURFREV2, SURFREVAX2.
$

@\subsubsection{SURFREV2}
!SURFREV2

@\begin{verbatim}
 PolygonType SURFREV2( PolygonType Object,
                       NumericType StartAngle,
                       NumericType EndAngle )

 or
 
 SurfaceType SURFREV2( CurveType Object,
                       NumericType StartAngle,
                       NumericType EndAngle )
@\end{verbatim}

   create a surface of revolution by rotating the first polygon/curve of the
 given {\bf Object}, around the Z axis.  The rotation does not form a complete
 circle and is from the {\bf StartAngle} to the {\bf EndAngle} only, in degrees,
 starting from the X axis toward the Y axis, in the XY plane.  Use the linear
 transformation functions to position a surface of revolution in a different
 orientation.

 Example:

@\begin{verbatim}
    Glass = SURFREV2( GCross, 45, 180 );
@\end{verbatim}

 constructs a surface of revolution by rotating it around the Z axis from 45
 to 180 degrees.
   See also SURFPREV, SURFREVAXS, SURFREV, SURFREVAX2.
$

@\subsubsection{SURFREVAX2}
!SURFREVAX2

@\begin{verbatim}
 PolygonType SURFREVAX2( PolygonType Object,
                         NumericType StartAngle,
                         NumericType EndAngle,
                         VectorType Axis )

 or
 
 SurfaceType SURFREVAX2( CurveType Object,
                         NumericType StartAngle,
                         NumericType EndAngle,
                         VectorType Axis )
@\end{verbatim}

   create a surface of revolution by rotating the first polygon/curve of the
 given {\bf Object}, around the {\bf Axis} axis.  The rotation does not form
 a complete circle and is from the {\bf StartAngle} to the {\bf EndAngle} only, in
 degrees, starting from the X axis toward the Y axis, in the XY plane.
 Use the linear transformation functions to position a surface of revolution
 in a different location.

 Example:

@\begin{verbatim}
    T4 = SURFREVAX2( PolyCross, 90, 360, vector( 1, 0, 1 ) );
@\end{verbatim}

 constructs a polygonal surface of revolution by rotating PolygonType
 {\bf PolyCross} around the axis (1, 0, 1), from 45 to 180 degrees.
   See also SURFPREV, SURFREVAXS, SURFREV2, SURFREV.
$

@\subsubsection{SVISIBLE}
!SVISIBLE

@\begin{verbatim}
 ListType SVISIBLE( SurfaceType Srf,
                    NumericType Resolution,
                    NumericType ConeSize )
@\end{verbatim}

 computes a decomposition of a freeform surface {\bf Srf} into regions, each
 visible with a cone visibility of {\bf ConeSize} degrees from one direction.
 In other words, all points in one region have angular deviation of their
 surface normal of less than {\bf ConeSize} degrees from the set viewing
 direction. {\bf Resolution} controls the accuracy of the computation; the higher
 this value is, more exact the result. 20 is a good starting value.  Each
 returned region is a trimmed surface that has a "ViewDir" attribute that
 contains the viewing direction of this region.

 Example:

@\begin{verbatim}
    c1 = cbezier( list( ctlpt( E3, 1.0, 0.0,  0.5 ),
                        ctlpt( E3, 1.1, 0.0,  0.0 ),
                        ctlpt( E3, 1.0, 0.0, -0.5 ) ) );
    Simp = sregion( surfPRev( c1 ), col, 0.0, 1.0 ) * rz( 45 ) * rx( 90 );
    Decomp = SVISIBLE( Simp, 20, 30 * pi / 180 );
    
    SimDecomp = nil();
    Mod = 5;
    for ( i = 1, 1, sizeof( Decomp ),
        o = nth( Decomp, i ):
        v = getattr( o, "ViewDir" ):
        l = ( ctlpt( E3, 0, 0, 0 ) + coerce( v, e3 ) ) * sc( 1.5 ):
        j = floor( ( i - 1 ) / Mod ):
        snoc( list( o, Simp, l, axes )
                    * view_mat * tx( ( i - 1 - j * Mod ) * 2 - 4 )
                               * ty( -j * 2 ),
              SimDecomp ) );

    view( SimDecomp, on );
@\end{verbatim}

 decomposes a given surface {\bf Simp} into regions of 30 degrees at most,
 goes over the decomposed regions and orders them five in a row.
@See Figure~\ref{fig-svisible}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/svisible.ps, width=5.5in}
=    <img  hspace=2 src="user_man/svisible.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A decomposition of a freeform surface into cone visible regions
-     of 30 degrees.  The direction of visibility is also presented.
-     Computed using the SVISIBLE command.
=</b><BR clear=all>
@}
@\label{fig-svisible}
@\end{figure}
$

@\subsubsection{SVOLUME}
!SVOLUME

@\begin{verbatim}
 SurfaceType SVOLUME( SurfaceType Srf, NumericType Method, NumericType Eval )

 or

 NumericType SVOLUME( SurfaceType Srf, NumericType Method, NumericType Eval )
@\end{verbatim}

   computes the integral volume surface, {\em VSrf}, of the given surface
 {\bf Srf}, up to a sign.
   If {\bf Srf} is a closed surface with domain (u0, v0) to (u1, v1), then
 the difference of {\em VSrf}(u1, v1) - {\em VSrf}(u0, v0) is the requested
 volume.  Otherwise, the computation is for the volume occupied between the
 surface {\bf Srf} and the XY plane if {\bf Method} equals one, and the
 volume occupied between the surface {\bf Srf} and the
 origin if {\bf Method} equals two.
   If {\bf Eval} is TRUE, the actual numerical value of the volume is returned.
 The volume integral surface is returned if {\bf Eval} is FALSE.

 Example:

@\begin{verbatim}
    Spr = surfPRev( cregion( pcircle( vector( 0, 0, 0 ), 1 ), 1, 3 )
                    * ry( 90 ) );
    SVOLUME( Spr, 1, 1 ) * 3 / 4;
    SVOLUME( Spr, 2, 1 ) * 3 / 4;
@\end{verbatim}
 are yet another two ways of approximating the value of Pi.
 See also SMOMENTS and CAREA.
$

@\subsubsection{SWEEPSRF}
!SWEEPSRF

@\begin{verbatim}
 SurfaceType SWEEPSRF( CurveType CrossSection | ListType CrossSectionList,
                       CurveType Axis,
                       CurveType FrameCrv | VectorType FrameVec
                                                           | ConstType OFF )
@\end{verbatim}

   constructs a generalized cylinder surface. This function sweeps a specified
 cross section {\bf CrossSection} along the provided {\bf Axis}.  If a list
 of curves {\bf CrossSectionList} is specified instead, the cross sections
 are blended along the {\bf Axis} of the curve so that the first/last cross
 section in the list fits the first/last location on the {\bf Axis}.
   By default, when frame specification is {\bf OFF}, the orientation
 of the cross section is computed using the {\bf Axis} curve tangent and
 normal. However, unlike the Frenet frame, attempt is made to minimize
 the normal change, as can happen along inflection points in {\bf Axis}.
   If a VectorType {\bf FrameVec} is provided as a frame orientation setting,
 it is used to fix the binormal direction to this value. In other words, the
 orientation frame has a fixed binormal. If a CurveType {\bf FrameCrv} is
 specified as a frame orientation setting, this vector field curve is
 evaluated at each placement of the cross section to yield the needed binormal.

   The resulting sweep is only an approximation of the real sweep. The
 resulting sweep surface will not be exact, in general.
   Refinement of the axis curve at the proper location, where accuracy is
 important, should improve the accuracy of the output. The parametric domains
 of {\bf FrameCrv} do not have to match the parametric domain of {\bf Axis},
 and its parametric domain is automatically made compatible by this function.

 Example:

@\begin{verbatim}
    Cross = arc( vector( 0.2, 0.0, 0.0 ),
                 vector( 0.2, 0.2, 0.0 ),
                 vector( 0.0, 0.2, 0.0 ) ) +
            arc( vector( 0.0, 0.4, 0.0 ),
                 vector( 0.1, 0.4, 0.0 ),
                 vector( 0.1, 0.5, 0.0 ) ) +
            arc( vector( 0.8, 0.5, 0.0 ),
                 vector( 0.8, 0.3, 0.0 ),
                 vector( 1.0, 0.3, 0.0 ) ) +
            arc( vector( 1.0, 0.1, 0.0 ),
                 vector( 0.9, 0.1, 0.0 ),
                 vector( 0.9, 0.0, 0.0 ) ) +
            ctlpt( E2, 0.2, 0.0 );
    Axis = arc( vector( -1.0, 0.0, 0.0 ),
                vector(  0.0, 0.0, 0.1 ),
                vector(  1.0, 0.0, 0.0 ) );
    Axis = crefine( Axis, FALSE, list( 0.25, 0.5, 0.75 ) );
    Srf1 = SWEEPSRF( Cross, Axis, OFF );
    Srf2 = SWEEPSRF( Cross, Axis, vector( 0.0, 1.0, 1.0 ) );
    Srf3 = SWEEPSRF( Cross, Axis,
                     cbezier( list( ctlpt( E3,  1.0, 0.0, 0.0 ),
                                    ctlpt( E3,  0.0, 1.0, 0.0 ),
                                    ctlpt( E3, -1.0, 0.0, 0.0 ) ) ) );
@\end{verbatim}

 constructs a rounded rectangle cross section and sweeps it along an arc,
 while orienting it several ways. The axis curve {\bf Axis} is manually
 refined to better approximate the requested shape.

 See also SWPSCLSRF for sweep with scale.
@See Figure~\ref{fig-sweepsrf}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/sweepsrf.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/sweepsrf.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Three examples of the use of SWEEPSRF (Srf1, Srf2, Srf3 from left to
-     right in sweepsrf documentation).
=</b><BR clear=all>
@}
@\label{fig-sweepsrf}
@\end{figure}
$

@\subsubsection{SWPSCLSRF}
!SWPSCLSRF

@\begin{verbatim}
 SurfaceType SWPSCLSRF( CurveType CrossSection | ListType CrossSectionList,
                        CurveType Axis, NumericType Scale | CurveType ScaleCrv,
                        CurveType FrameCrv | VectorType FrameVec
                                                          | ConstType OFF,
                        NumericType ScaleRefine )
@\end{verbatim}

   constructs a generalized cylinder surface. This function sweeps a specified
 cross section {\bf CrossSection} along the provided {\bf Axis}.  If a list
 of curves {\bf CrossSectionList} is specified instead, the cross sections
 are blended along the {\bf Axis} of the curve so that the first/last cross
 section in the list fits the first/last location on the {\bf Axis}.
   The cross section may be scaled by a constant value {\bf Scale}, or scaled
 along the {\bf Axis} parametric direction via a scaling curve {\bf ScaleCrv}.
   By default, when frame specification is {\bf OFF}, the orientation
 of the cross section is computed using the {\bf Axis} curve tangent and
 normal. However, unlike the Frenet frame, attempt is made to minimize
 the normal change, as can happen along inflection points in {\bf Axis}.
   If a VectorType {\bf FrameVec} is provided as a frame orientation setting,
 it is used to fix the binormal direction to this value. In other words, the
 orientation frame has a fixed binormal. If a CurveType {\bf FrameCrv} is
 specified as a frame orientation setting, this vector field curve is
 evaluated at each placement of the cross section to yield the needed binormal.
   {\bf ScaleRefine} is an integer value to define possible refinement of the
 {\bf Axis} to reflect the information in {\bf ScalingCrv}. A value of zero will
 force no refinement while a value of $n > 0$ will insert $n$ times the
 number of control points in {\bf ScaleCrv} into {\bf Axis}, better emulating
 the scaling requested.
   The resulting sweep is only an approximation of the real sweep. The
 scaling and axis placement will not be exact, in general.
   Manual refinement (in addition to {\bf ScaleRefine}) of the axis curve at
 the proper location, where accuracy is important, should improve the accuracy
 of the output. The parametric domains of {\bf ScaleCrv} and {\bf FrameCrv} do
 not have to match the parametric domain of {\bf Axis}, and their domains are
 made compatible by this function.

 Example:

@\begin{verbatim}
    Cross = arc( vector( -0.11, -0.1,  0.0 ),
                 vector( -0.1,  -0.1,  0.0 ),
                 vector( -0.1,  -0.11, 0.0 ) ) +
            arc( vector(  0.1,  -0.11, 0.0 ),
                 vector(  0.1,  -0.1,  0.0 ),
                 vector(  0.11, -0.1,  0.0 ) ) +
            arc( vector(  0.11,  0.1,  0.0 ),
                 vector(  0.1,   0.1,  0.0 ),
                 vector(  0.1,   0.11, 0.0 ) ) +
            arc( vector( -0.1,   0.11, 0.0 ),
                 vector( -0.1,   0.1,  0.0 ),
                 vector( -0.11,  0.1,  0.0 ) ) +
            ctlpt( E2, -0.11, -0.1 );
    scaleCrv = cbspline( 3,
                         list( ctlpt( E2, 0.05, 1.0 ),
                               ctlpt( E2, 0.1,  0.0 ),
                               ctlpt( E2, 0.2,  2.0 ),
                               ctlpt( E2, 0.3,  0.0 ),
                               ctlpt( E2, 0.4,  2.0 ),
                               ctlpt( E2, 0.5,  0.0 ),
                               ctlpt( E2, 0.6,  2.0 ),
                               ctlpt( E2, 0.7,  0.0 ),
                               ctlpt( E2, 0.8,  2.0 ),
                               ctlpt( E2, 0.85, 1.0 ) ),
                         list( KV_OPEN ) );
    Axis = circle( vector( 0, 0, 0 ), 1 );
    Frame = circle( vector( 0, 0, 0 ), 1 )
            * rotx( 90 ) * trans( vector( 1.5, 0.0, 0.0 ) );

    Srf1 = SWPSCLSRF( Cross, Axis, scaleCrv, off, 0 );
    Srf2 = SWPSCLSRF( Cross, Axis, scaleCrv, off, 2 );
    Srf3 = SWPSCLSRF( Cross, Axis, 1.0, Frame, 0 );
@\end{verbatim}

 constructs a rounded rectangle cross section and sweeps it along a circle,
 while scaling and orienting in several ways. The axis curve {\bf Axis} is
 automatically refined in {\bf Srf2} to better approximate the requested
 scaling.

 See also SWEEPSRF for sweep with no scale.
@See Figure~\ref{fig-swpsclsrf}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/swpsclsrf.ps, width=6.5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/swpsclsrf.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Three examples of the use of SWPSCLSRF (Srf1, Srf2, Srf3 from left
-     to right in SWPSCLSRF documentation).
=</b><BR clear=all>
@}
@\label{fig-swpsclsrf}
@\end{figure}
$

@\subsubsection{SWUNGASUM}
!SWUNGASUM

@\begin{verbatim}
 SurfaceType SWUNGASUM( CurveType Crv1, CurveType Crv2 )
@\end{verbatim}

 Given two curves, compute a swung surface that equals:
^
^                       S(r, t) = (x1(r) x2(t), x1(r) y2(t), y1(r))
^
@\begin{equation}
@    S(r, t) = \left(x_1(r) x_2(t), x_1(r) y_2(t), y_1(r) \right)
@\end{equation}

 Example:

@\begin{verbatim}
 circ = circle( vector( 0.0, 0.0, 0.0 ), 1.5 ) * ry( 90 );
 arc1 = arc( vector( 0.0, 1.0, 0.0 ),
             vector( 0.0, 0.0, 0.0 ),
             vector( 1.0, 0.0, 0.0 ) );
 as1 = SWUNGASUM( circ * ry( -90 ), arc1 );

 arc1 = cregion( circle( vector( 0.0, 0.0, 0.0 ), 1.5 ), 0, 2 ) * rz( 90 );
 c2 = coerce( cbspline( 3,
                        list( ctlpt( E2,  1.0,  0.0 ),
                              ctlpt( E2,  0.2,  0.2 ),
                              ctlpt( E2,  0.0,  1.0 ),
                              ctlpt( E2, -0.2,  0.2 ),
                              ctlpt( E2, -1.0,  0.0 ),
                              ctlpt( E2, -0.2, -0.2 ),
                              ctlpt( E2,  0.0, -1.0 ),
                              ctlpt( E2,  0.2, -0.2 ) ),
                        list( KV_PERIODIC ) ),
              KV_OPEN );
 as2 = SWUNGASUM( arc1, c2 );
@\end{verbatim}

 creates two algebraic sum surfaces, one in the shape of a cylinder as
 a sum of a line and a circle, and one circular sweep.
@See Figure~\ref{fig-swung}.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/swung1.ps, width=3.0in} &
@        \epsfig{file=user_man/swung2.ps, width=3.0in}
=    <BR clear=all>
=        <img hspace=2 width=250 src="user_man/swung1.gif">
=        <img hspace=2 width=250 src="user_man/swung2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     An algebraic swung sum of a circle and a line creating a portion
-     of a sphere (left) and a general swung surface between a circle and
-     a periodic curve (right), both using SWUNGASUM.
=</b><BR clear=all>
@}
@\label{fig-swung}
@\end{figure}
$

@\subsubsection{SYMBCPROD}
!SYMBCPROD

@\begin{verbatim}
 CurveType SYMBCPROD( CurveType Crv1, CurveType Crv2 )

 or

 SurfaceType SYMBCPROD( SurfaceType Srf1, SurfaceType Srf2 )

 or

 MultivarType SYMBCPROD( MultivarType MV1, MultivarType MV2 )
@\end{verbatim}

 compute the symbolic cross product of the two given 
 curves/surfaces/multivariates as a curve, surface or multivariate.

 Example:

@\begin{verbatim}
 NrmlSrf = SYMBCPROD( sderive( Srf, ROW ), sderive( Srf, COL ) )
@\end{verbatim}

 computes a normal surface as the cross product of the two surface partial
 derivatives (see SNRMLSRF).
   See also SYMBIPROD, SYMBDPROD, SYMBPROD, SYMBSUM, SYMBDIFF.
$

@\subsubsection{SYMBDIFF}
!SYMBDIFF

@\begin{verbatim}
 CurveType SYMBDIFF( CurveType Crv1, CurveType Crv2 )

 or

 SurfaceType SYMBDIFF( SurfaceType Srf1, SurfaceType Srf2 )

 or

 MultivarType SYMBDIFF( MultivarType MV1, MultivarType MV2 )
@\end{verbatim}

 compute the symbolic difference of the two given 
 curves/surfaces/multivariates as a curve, surface or multivariate.
 The difference is computed coordinate-wise.

 Example:

@\begin{verbatim}
 DiffCrv = SYMBDIFF( Crv1, Crv2 )
 DistSqrCrv = symbdprod( DiffCrv, DiffCrv )
@\end{verbatim}
   See also SYMBCPROD, SYMBDPROD, SYMBIPROD, SYMBPROD, SYMBSUM.
$

@\subsubsection{SYMBDPROD}
!SYMBDPROD

@\begin{verbatim}
 CurveType SYMBDPROD( CurveType Crv1, CurveType Crv2 )

 or

 CurveType SYMBDPROD( CurveType Crv1, VectorType Vec2 )

 or

 SurfaceType SYMBDPROD( SurfaceType Srf1, SurfaceType Srf2 )

 or

 SurfaceType SYMBDPROD( SurfaceType Srf1, VectorType Vec2 )

 or

 MultivarType SYMBDPROD( MultivarType MV1, MultivarType MV2 )

 or

 MultivarType SYMBDPROD( MultivarType MV1, VectorType Vec2 )
@\end{verbatim}

 compute the symbolic dot (inner) product of the two given 
 curves/surfaces/multivariates as a {\em scalar}
 curve/surface/multivariate.  As an alternative, one parameter can
 also be a regular vector.

 Example:

@\begin{verbatim}
 DiffCrv = symbdiff( Crv1, Crv2 )
 DistSqrCrv = SYMBDPROD( DiffCrv, DiffCrv )
@\end{verbatim}

 computes a scalar curve that at parameter $t$ is equal to the distance
 square between Crv1 at $t$ and Crv2.
   See also SYMBCPROD, SYMBIPROD, SYMBPROD, SYMBSUM, SYMBDIFF.
$

@\subsubsection{SYMBIPROD}
!SYMBIPROD

@\begin{verbatim}
 NumericType SYMBIPROD( CurveType Crv, NumericType Order1, NumericType Order2 )

 or

 NumericType SYMBIPROD( NumericType Dummy, NumericType Idx1, NumericType Idx2 )
@\end{verbatim}

 compute the inner product of two B-spline basis functions.  The first form
 defines the function space to be the same as the function space of {\bf Crv}
 of order {\bf Order1} (first basis function) by {\bf Order2}. The second
 basis function in the inner product is defined as,
^     _
^    |
^    | Bi,o1(t) Bj,o2(t) dt.
^    |
^   -
@\begin{equation}
@    \int B_{i,o_1}(t) B_{j,o_2}(t) dt.
@\end{equation}

 The second form prescribes the indices of the two basis functions,
 $i$ and $j$.  The first form returns zero in case of an error.  The second
 form returns the result of the inner product.

 Example:

@\begin{verbatim}
    SYMBIPROD( Crv = pcircle( vector( 0, 0, 0 ), 1 ), 4, 4 );
    for ( i = 0, 1, nth( ffmsize( Crv ), 1 ) - 1,
        for ( j = 0, 1, nth( ffmsize( Crv ), 1 ) - 2,
            printf( "%3.3f ", list( SYMBIPROD( 0, i, j ) ) ) ):
        printf( "\\n", nil() ) );
@\end{verbatim}

 prints all possible inner products of the B-spline function space of
 {\bf pcircle}, of cubics vs. cubics. 
   See also SYMBCPROD, SYMBDPROD, SYMBPROD, SYMBSUM, SYMBDIFF.
$

@\subsubsection{SYMBPROD}
!SYMBPROD

@\begin{verbatim}
 CurveType SYMBPROD( CurveType Crv1, CurveType Crv2 )

 or

 SurfaceType SYMBPROD( SurfaceType Srf1, SurfaceType Srf2 )

 or

 MultivarType SYMBPROD( MultivarType MV1, MultivarType MV2 )
@\end{verbatim}

 compute the symbolic product of the two given curves/surfaces/multivariates
 as a curve, surface or multivariate. The product is computed coordinate-wise.

 Example:

@\begin{verbatim}
 ProdSrf = SYMBPROD( Srf1, Srf2 )
@\end{verbatim}
   See also SYMBCPROD, SYMBDPROD, SYMBIPROD, SYMBSUM, SYMBDIFF.
$

@\subsubsection{SYMBSUM}
!SYMBSUM

@\begin{verbatim}
 CurveType SYMBSUM( CurveType Crv1, CurveType Crv2 )

 or

 SurfaceType SYMBSUM( SurfaceType Srf1, SurfaceType Srf2 )

 or

 MultivarType SYMBSUM( MultivarType MV1, MultivarType MV2 )
@\end{verbatim}

 compute the symbolic sum of the two given curves/surfaces/multivariates as
 a curve, surface or multivariate. The sum is computed coordinate-wise.

 Example:

@\begin{verbatim}
 SumCrv = SYMBSUM( Crv1, Crv2 )
@\end{verbatim}

   See also SYMBCPROD, SYMBDPROD, SYMBIPROD, SYMBPROD, SYMBDIFF.
$

@\subsubsection{TBEZIER}
!TBEZIER

@\begin{verbatim}
 TrivarType TBEZIER( ListType CtlMesh )
@\end{verbatim}

   creates a Bezier trivariate using the provided control mesh. {\bf CtlMesh}
 is a list of planes, each of which is a list of rows, each of which is a list
 of control points. All control points must be of type (E1-E9, P1-P9), or
 regular PointType defining the trivariate's control mesh. The surface point
 type will be of a space which is the union of the spaces of all points.
@
@The created trivariate is the piecewise polynomial (or rational) function,
@\begin{equation}
@     T(u, v, w) = \sum_{i=0}^m \sum_{j=0}^n \sum_{k=0}^l
@                                               P_{ijk} B_i(u) B_j(v) B_k(w)
@\end{equation}
@where $P_{ijk}$ are the control points {\bf CtlMesh}, and $l$, $m$ and $n$
@are the degrees of the trivariate, which are one less than the number of
@points in the appropriate direction.

 Example:

@\begin{verbatim}
   TV = TBEZIER( list( list( list( ctlpt( E3, 0.1, 0.1, 0.0 ),
                                   ctlpt( E3, 0.2, 0.5, 1.1 ),
                                   ctlpt( E3, 0.3, 0.1, 2.2 ) ),
                             list( ctlpt( E3, 0.4, 1.3, 0.5 ),
                                   ctlpt( E3, 0.5, 1.7, 1.7 ),
                                   ctlpt( E3, 0.6, 1.3, 2.9 ) ),
                             list( ctlpt( E3, 0.7, 2.4, 0.5 ),
                                   ctlpt( E3, 0.8, 2.6, 1.4 ),
                                   ctlpt( E3, 0.9, 2.8, 2.3 ) ) ),
                       list( list( ctlpt( E3, 1.1, 0.1, 0.5 ),
                                   ctlpt( E3, 1.3, 0.2, 1.7 ),
                                   ctlpt( E3, 1.5, 0.3, 2.9 ) ),
                             list( ctlpt( E3, 1.7, 1.2, 0.0 ),
                                   ctlpt( E3, 1.9, 1.4, 1.2 ),
                                   ctlpt( E3, 1.2, 1.6, 2.4 ) ),
                             list( ctlpt( E3, 1.4, 2.3, 0.9 ),
                                   ctlpt( E3, 1.6, 2.5, 1.7 ),
                                   ctlpt( E3, 1.8, 2.7, 2.5 ) ) ) ) );
@\end{verbatim}
 
 creates a trivariate Bezier which is linear in the first direction, and
 quadratic in the second and third.
@See Figure~\ref{fig-tbezier}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tbezier.ps, width=5in}
=    <img  hspace=2 src="user_man/tbezier.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A trivariate Bezier of degree 2 by 3 by 3 (left) and a trilinear
-     B-spline (right). Both share the same control mesh.
=</b><BR clear=all>
@}
@\label{fig-tbezier}
@\end{figure}
$

@\subsubsection{TBSPLINE}
!TBSPLINE

@\begin{verbatim}
 TrivarType TBSPLINE( NumericType UOrder,
                      NumericType VOrder,
                      NumericType WOrder,
                      ListType CtlMesh,
                      ListType KnotVectors )
@\end{verbatim}

   creates a B-spline trivariate with the provided {\bf UOrder}, {\bf VOrder}
 and {\bf WOrder} orders, the control mesh {\bf CtlMesh}, and the three knot
 vectors in {\bf KnotVectors}.
   {\bf CtlMesh} is a list of planes, each of which is a list of rows, each
 of which is a list of control points. All control points must be of point
 type (E1-E9, P1-P9), or regular PointType defining the trivariate's control
 mesh. Trivariate point type will be of a space which is the union of the
 spaces of all points.
   {\bf KnotVectors} is a list of three knot vectors. Each knot vector is a
 list of NumericType knots of length {\bf \#CtlPtList} plus the {\bf Order}.
 If, however, the length of the knot vector is equal to {\bf \#CtlPtList +
 Order + Order - 1}, the curve is assumed to be {\em periodic.} 
   The knot vector may also be a list of a single constant, KV\_OPEN,
 KV\_FLOAT or KV\_PERIODIC, in which a uniform knot vector with the
 appropriate length and with open, floating or periodic end conditions
 will be constructed automatically.
@
@The created surface is the piecewise polynomial (or rational) surface,
@\begin{equation}
@     T(u, v, w) = \sum_{i=0}^m \sum_{j=0}^n \sum_{k=0}^l P_{ijk}
@                               B_{i,\chi}(u) B_{j,\xi}(v) B_{k,\phi}(w)
@\end{equation}
@where $P_{ijk}$ are the control points {\bf CtlMesh}, and $l$, $m$ and $n$
@are the degrees of the surface, which are one less than {\bf UOrder},
@{\bf VOrder} and {\bf WOrder} and $\chi$, $\xi$ and $\phi$ are the three
@knot vectors of the trivariate.

 Example:

@\begin{verbatim}
   TV = TBSPLINE( 2, 2, 2,
                  list( list( list( ctlpt( E3, 0.1, 0.1, 0.0 ),
                                    ctlpt( E3, 0.2, 0.5, 1.1 ),
                                    ctlpt( E3, 0.3, 0.1, 2.2 ) ),
                              list( ctlpt( E3, 0.4, 1.3, 0.5 ),
                                    ctlpt( E3, 0.5, 1.7, 1.7 ),
                                    ctlpt( E3, 0.6, 1.3, 2.9 ) ),
                              list( ctlpt( E3, 0.7, 2.4, 0.5 ),
                                    ctlpt( E3, 0.8, 2.6, 1.4 ),
                                    ctlpt( E3, 0.9, 2.8, 2.3 ) ) ),
                        list( list( ctlpt( E3, 1.1, 0.1, 0.5 ),
                                    ctlpt( E3, 1.3, 0.2, 1.7 ),
                                    ctlpt( E3, 1.5, 0.3, 2.9 ) ),
                              list( ctlpt( E3, 1.7, 1.2, 0.0 ),
                                    ctlpt( E3, 1.9, 1.4, 1.2 ),
                                    ctlpt( E3, 1.2, 1.6, 2.4 ) ),
                              list( ctlpt( E3, 1.4, 2.3, 0.9 ),
                                    ctlpt( E3, 1.6, 2.5, 1.7 ),
                                    ctlpt( E3, 1.8, 2.7, 2.5 ) ) ) ),
                  list( list( KV_OPEN ),
                        list( KV_OPEN ),
                        list( KV_OPEN ) ) );
@\end{verbatim}

 constructs a trilinear B-spline trivariate with open end conditions.
@See Figure~\ref{fig-tbezier}.
$
 TCRVTR

@\subsubsection{TCRVTR}
!TCRVTR

@\begin{verbatim}
 AnyType TCRVTR( TrivarType TV, PointType Pos, NumericType ComputeWhat )
@\end{verbatim}

 computes differential curvature properties of an isosurface of
 the given trivariate {\bf TV} at the given (parameteric) location
 {\bf Pos}. Following the value of {\bf ComputeWhat}, the result equals,
# 14 2 0 1
 -1
  Initialization (a must prelude)
 0
  Conclusion (a must postlude)
 1
  Returns a vector hold of the gradient
 2
  Returns a list of three vectors

  equal to the Hessian of this location
 3
  Returns a list of two scalar values

  (Principle curvatures) and two vectors

  (Principal directions).
#

  Every evaluation must start with an invocation of {\bf ComputeWhat}
 equal to -1 and terminate with {\bf ComputeWhat} 0.  In both cases, 1 is
 returned in case of success.

 Example:

@\begin{verbatim}
 TCRVTR( TV, point( 0, 0, 0 ), -1 ); # Prelude
 Grad1 = TCRVTR( TV, point( 0, 0, 0 ),  1 );
 Grad2 = TCRVTR( TV, point( 0, 0, 1 ),  1 );
 Grad3 = TCRVTR( TV, point( 0, 1, 0 ),  1 );
 Grad4 = TCRVTR( TV, point( 1, 0, 0 ),  1 );
 TCRVTR( TV, point( 0, 0, 0 ), 0 ); #Postlude
@\end{verbatim}
$

@\subsubsection{TDERIVE}
!TDERIVE

@\begin{verbatim}
 TrivarType TDERIVE( TrivarType TV, NumericType Dir )
@\end{verbatim}

   returns a vector field trivariate representing the differentiated 
 trivariate in the given direction (ROW, COL, or DEPTH). Evaluation of the
 returned trivariate at a given parameter value will return a vector
 representing the partial derivative of {\bf TV} in {\bf Dir} at that
 parameter value.

@\begin{verbatim}
 TV = tbezier( list( list( list( ctlpt( E1, 0.1 ),
                                 ctlpt( E1, 0.2 ) ),
                           list( ctlpt( E1, 0.3 ),
                                 ctlpt( E1, 0.4 ) ) ),
                     list( list( ctlpt( E1, 2.4 ),
                                 ctlpt( E1, 2.2 ) ),
                           list( ctlpt( E1, 2.3 ),
                                 ctlpt( E1, 2.1 ) ) ) ) );

 DuTV = TDERIVE( TV, ROW );
 DvTV = TDERIVE( TV, COL );
 DwTV = TDERIVE( TV, DEPTH );
@\end{verbatim}
 
 computes the gradiate of a scalar trivariate field, by computing its
 partials with respect to u, v, and w.
 See also CDERIVE, SDERIVE, and MDERIVE.
$

@\subsubsection{TDIVIDE}
!TDIVIDE

@\begin{verbatim}
 TrivarType TDIVIDE( TrivarType TV, ConstantType Direction,
                                                          NumericType Param )
@\end{verbatim}

   subdivides a trivariate into two at the specified parameter value {\bf Param}
 in the specified {\bf Direction} (ROW, COL, or DEPTH). {\bf TV} can be either
 a B-spline trivariate in which {\bf Param} must be contained in the parametric
 domain of the trivariate, or a Bezier trivariate in which {\bf Param} must be
 in the range of zero to one.

   It returns a list of the two sub-trivariates. The individual trivariates
 may be extracted from the list using the {\bf NTH} command.

 Example:

@\begin{verbatim}
    TvDiv = TDIVIDE( Tv2, depth, 0.3 );
    Tv2a = nth( TvDiv, 1 ) * tx( -2.2 );
    Tv2b = nth( TvDiv, 2 ) * tx( 2.0 );
@\end{verbatim}

 subdivides {\bf Tv2} at the parameter value of 0.3 in the DEPTH direction,
@See Figure~\ref{fig-tdivide}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tdivide.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/tdivide.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      A trivariate can be subdivided into two distinct regions using
-      TDIVIDE.
=</b><BR clear=all>
@}
@\label{fig-tdivide}
@\end{figure}
 See also CDIVIDE, SDIVIDE, and MDIVIDE
$

@\subsubsection{TEDITPT}
!TEDITPT

@\begin{verbatim}
 TrivarType TEDITPT( TrivarType TV, CtlPtType CPt, NumericType UIndex,
                                                   NumericType VIndex )
                                                   NumericType WIndex )
@\end{verbatim}

   provides a simple mechanism to manually modify a single control point number
 {\bf UIndex}, {\bf VIndex} and {\bf WIndex} (base count is 0) in the control mesh
 of {\bf Srf} by substituting {\bf CtlPt} instead. CtlPt must have the same
 point type as the control points of {\bf Srf}. Original surface {\bf Srf} is
 not modified.

 Example:

@\begin{verbatim}
    CPt = ctlpt( E3, 1, 2, 3 );
    NewTV = TEDITPT( TV, CPt, 0, 0, 0 );
@\end{verbatim}

 constructs a {\bf NewTV} with the first control point of {\bf TV} being
 {\bf CPt}.
$

@\subsubsection{TEVAL}
!TEVAL

@\begin{verbatim}
 CtlPtType TEVAL( TrivarType TV,
                  NumericType UParam,
                  NumericType VParam,
                  NumericType WParam )
@\end{verbatim}

   evaluates the provided trivariate {\bf TV} at the given {\bf UParam},
 {\bf VParam} and {\bf WParam} values. {\bf UParam}, {\bf VParam},
 {\bf WParam} must be contained in the surface parametric domain if {\bf TV}
 is a B-spline trivariate, or between zero and one if {\bf TV} is a Bezier
 trivariate. The returned control point has the same type as the control
 points of {\bf TV}.

 Example:

@\begin{verbatim}
    CPt = TEVAL( TV1, 0.25, 0.22, 0.7 );
@\end{verbatim}

 evaluates {\bf TV} at the parameter values of (0.25, 0.22, 0.7).
 See also CEVAL, SEVAL, MEVAL.
$

@\subsubsection{TEXTGEOM}
!TEXTGEOM

@\begin{verbatim}
 AnyType TEXTGEOM( StringType Str, VectorType Spacing, NumericType Scaling )
@\end{verbatim}

 creates a displayable geometry that represents the text in {\bf Str}, with
 {\bf Spacing} space between individual characters. Each character is scaled
 by {\bf Scaling} where scaling of one generates a close to unit size
 character.

 Example:

@\begin{verbatim}
    a = TEXTGEOM("Text", vector( 0.12, 0, 0 ), 0.1 );
    b = TEXTGEOM("IRIT", vector( 0, -0.12, 0 ), 0.1 );
@\end{verbatim}

 creates a horizontal {\bf Text} and a vertical top to bottom {\em IRIT},
 both as geometrical objects.  See TEXTWARP and IRITSTATE's "LoadFont"
 state variable.
$

@\subsubsection{TEXTWARP}
!TEXTWARP

@\begin{verbatim}
 AnyType TEXTWARP( Surface Srf, StringType Text, NumericType HSpace,
                   NumericType VBase, NumericType VTop, NumericType Ligature )
@\end{verbatim}

 warps the given text, {\bf Text}, using surface {\bf Srf} as warping
 function with {\bf HSpace} setting the horizontal spacing between
 characters, {\bf VBase} and {\bf VTop} controls the vertical spacing
 of the characters in {\bf Srf}, and {\bf Ligature}, if not zero, sets
 the amount to contract the distance between two adjacent characters.

@\begin{figure}
@\begin{center}
@   \epsfig{file=user_man/textwarp.ps, width=5in}
=   <img  hspace=2 src="user_man/textwarp.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    Font and text warping using the TEXTWARP function.
=</b><BR clear=all>
@}
@\label{fig-textwarp}
@\end{figure}

 Example:

@\begin{verbatim}
    c = cbezier( list( ctlpt( e2, -1.5, -0.5 ),
                       ctlpt( e2, -2,    0 ),
                       ctlpt( e2, -1,    1 ),
                       ctlpt( e2,  0,   -2 ),
                       ctlpt( e2,  1,    0 ) ) );
    s = sreparam( ruledSrf( c, offset( c, -0.4, 0.02, off ) ), col, 0, 6 );
    Txt = TEXTWARP( s, "Text Warping Toolkit", 0.08, 0.25, 0.75, 0 );
@\end{verbatim}

 See also TEXTGEOM and IRITSTATE's "LoadFont" state variable.
$

@\subsubsection{TFROMSRFS}
!TFROMSRFS

@\begin{verbatim}
 TrivarType TFROMSRFS( ListType SrfList, NumericType OtherOrder,
                       NumericType OtherEndCond )
@\end{verbatim}

   constructs a trivariate by substituting the surfaces in {\bf SrfList} as
 planes in a control mesh of a trivariate. Surfaces in {\bf SrfList} are
 made compatible by promoting Bezier surfaces to B-splines if necessary,
 and raising degree and refining as required before substituting the
 control meshes of the surfaces as planes in the mesh of the trivariate.
   The other, third, direction order is controlled by {\bf OtherOrder} and
 {\bf OtherEndCond}. {\bf OtherOrder} cannot be larger than the number of
 surfaces, and {\bf OtherEndCond} prescribes the desired end conditions as
 one of {\bf KV\_OPEN}, {\bf KV\_FLOAT} or {\bf KV\_PERIODIC}.

   The trivariate interpolates the first and last surfaces only.

 Example:

@\begin{verbatim}
    s1 = sbezier( list( list( ctlpt( E3, -0.5, -0.5, 0 ),
                              ctlpt( E3, -0.5,  0.5, 0 ) ),
                        list( ctlpt( E3,  0.5, -0.5, 0 ),
                              ctlpt( E3,  0.5,  0.5, 0 ) ) ) ) * sc( 0.3 );
    Srfs = list( s1 * sc( 2.0 ),
                 s1 * sx( 1.4 ) * ry( 45 ) * tz( 1.0 ),
                 s1 * ry( 90 ) * trans( vector( 1.0, 0.0, 1.1 ) ),
                 s1 * sx( 1.4 ) * ry( 135 ) * trans( vector( 2.0, 0.0, 1.0 ) ),
                 s1 * sc( 2.0 ) * ry( 180 ) * trans( vector( 2.0, 0.0, 0.0 ) ) );
    color( Srfs, red );

    ts = TFROMSRFS( Srfs, 3, kv_open );
    color( ts, green );
    view( list( Srfs, ts ), on );
@\end{verbatim}

 constructs a trivariate from five planar surfaces and displays both the
 trivariate and the five planar surfaces, in different colors.
@See Figure~\ref{fig-tfromsrfs}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tfromsrf.ps, width=5in}
=    <img  hspace=2 src="user_man/tfromsrf.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A trivariate (thin lines) is constructed via five planar surfaces
-     (thick lines) using the TFROMSRFS constructor...
=</b><BR clear=all>
@}
@\label{fig-tfromsrfs}
@\end{figure}

 See also EXTRUDE, RULEDTV, SFROMCRVS.
$

@\subsubsection{TINTERP}
!TINTERP

@\begin{verbatim}
 TrivarType TINTERP( TrivarType TV,
                 NumericType ULength, NumericType VLength, NumericType WLength,
                 NumericType UOrder, NumericType VOrder, NumericType WOrder );

 or

 TrivarType TINTERP( ListType PtList,
                 NumericType ULength, NumericType VLength, NumericType WLength,
                 NumericType UOrder, NumericType VOrder, NumericType WOrder );
@\end{verbatim}

   Given a trivariate data structure or a list of points in R3, the above
 computes a fitted trivariate in the prescribed function space (i.e.
 U/V/WLength and U/V/WOrder) that interpolates/least squares approximates the
 given trivariate, {\bf TV}, at the node parameter values.
   {\bf PtList} is a list of points in Rn, n > 3.  The first three coordinates
 of each points in {\bf PtList} prescribes the (u, v, w) parametric value and
 the rest, the interpolation values.  To construct a mapping from R3 to R3,
 the points of {\bf PtList} should be in R6.  To construct a scalar trivariate
 function, R4 points are expected.  The (u, v, w) points are assumed to be
 containted in a unit curve paramteric space - zero to one in all three
 dimensions.
   If {\bf U/V/WOrder} are zero and the first parameter is a trivariate, the
 respective order is taken for {\bf TV}.
   If {\bf U/V/WLength} are zero and the first parameter is a trivariate, the
 respective length is taken for {\bf TV}.

 Example:

@\begin{verbatim}
     tv = tbspline( 3, 3, 2,
                    list( list( list( ctlpt( E3, 0.1, 0.1, 0.0 ),
                                      ctlpt( E3, 0.2, 0.5, 1.1 ),
                                      ctlpt( E3, 0.3, 0.1, 2.2 ) ),
                                list( ctlpt( E3, 0.4, 1.3, 0.5 ),
                                      ctlpt( E3, 0.5, 1.7, 1.7 ),
                                      ctlpt( E3, 0.6, 1.3, 2.9 ) ),
                                list( ctlpt( E3, 0.7, 2.4, 0.5 ),
                                      ctlpt( E3, 0.8, 2.6, 1.4 ),
                                      ctlpt( E3, 0.9, 2.8, 2.3 ) ) ),
                          list( list( ctlpt( E3, 1.1, 0.1, 0.5 ),
                                      ctlpt( E3, 1.3, 0.2, 1.7 ),
                                      ctlpt( E3, 1.5, 0.3, 2.9 ) ),
                                list( ctlpt( E3, 1.7, 1.2, 0.0 ),
                                      ctlpt( E3, 1.9, 1.4, 1.2 ),
                                      ctlpt( E3, 1.2, 1.6, 2.4 ) ),
                                list( ctlpt( E3, 1.4, 2.3, 0.9 ),
                                      ctlpt( E3, 1.6, 2.5, 1.7 ),
                                      ctlpt( E3, 1.8, 2.7, 2.5 ) ) ),
                          list( list( ctlpt( E3, 2.8, 0.1, 0.4 ),
                                      ctlpt( E3, 2.6, 0.7, 1.3 ),
                                      ctlpt( E3, 2.4, 0.2, 2.2 ) ),
                                list( ctlpt( E3, 2.2, 1.1, 0.4 ),
                                      ctlpt( E3, 2.9, 1.2, 1.5 ),
                                      ctlpt( E3, 2.7, 1.3, 2.6 ) ),
                                list( ctlpt( E3, 2.5, 2.9, 0.7 ),
                                      ctlpt( E3, 2.3, 2.8, 1.7 ),
                                      ctlpt( E3, 2.1, 2.7, 2.7 ) ) ) ),
                    list( list( KV_OPEN ),
                          list( KV_OPEN ),
                          list( KV_OPEN ) ) );
    tvi = TINTERP( tv, 0, 0, 0, 0, 0, 0 );
@\end{verbatim}

 creates a quadratic by quaratic by linear trivariate {\bf tvi} that
 interpolates the control points of {\bf tv} at the node parameter values.
$

@\subsubsection{TMORPH}
!TMORPH

@\begin{verbatim}
 TrivarType TMORPH( TrivarType TV1, SurfaceType TV2, NumericType Blend )
@\end{verbatim}

 creates a new trivariate which is a {\em convex blend} of the two given
 trivariates.  The two given trivariates must be compatible (see FFCOMPAT)
 before this blend is invoked. This isv ery useful if a sequence that "morphs"
 one trivariate to another is to be created and in combination with MRCHCUBE.

 Example:

@\begin{verbatim}
    Size = 0.05;
    for ( i = 0, step, 1.0,
        Tv = TMORPH( Tv1, Tv2, i ):
        view( mrchcube( list( Tv, 1, off ),
                        point( Size, Size, Size ), 1, IsoVal ), on ) );
@\end{verbatim}

 creates a sequence of {\bf 1/step} trivariates, morphed from {\bf Tv1} to {\bf Tv2}
 and displays an extracted iso surface at level {\bf IsoVal}.
 See also MRCHCUBE, PMORPH, CMORPH and SMORPH.
$

@\subsubsection{TNSCRCR}
!TNSCRCR

@\begin{verbatim}
 ListType TNSCRCR( PointType Cntr1, NumericType Rad1,
                   PointType Cntr2, NumericType Rad2, NumericType OuterTans )
@\end{verbatim}

 computes the two outer, if {\bf OuterTans} TRUE, or the two inner
 if {\bf OuterTans} FALSE, bitangents between the prescribed two circles.
   Note the bitangents might no exist of one circle is containt in the other.

 Example:

@\begin{verbatim}
   T1 = TnsCrCr( point( -2, 0.3, 0 ), 0.7, point( 1, 0, 0 ), 1, 0 );
   T2 = TnsCrCr( point( -2, 0.3, 0 ), 0.7, point( 1, 0, 0 ), 1, 1 );
@\end{verbatim}

 See also CRC2CRVTAN.
$

@\subsubsection{TOFFSET}
!TOFFSET

@\begin{verbatim}
 ListType TOFFSET( CurveType Crv, CurveType OffCrv, NumericType Tolerance,
                   NumericType TrimAmount, NumericType NumerTol )
@\end{verbatim}

   trims local and global self intersections in curve {\bf OffCrv} that
 is an offset approximation to curve {\bf Crv} with tolerance {\bf Tolerance}
 Curve {\bf OffCrv} is trimmed if found closer than {\bf TrimAmount} to
 {\bf Crv}. {\bf OffCrv} could be computed from {\bf Crv} using any available
 offset approximation method such as OFFSET, AOFFSET, LOFFSET and MOFFSET.
   If {\bf NumerTol} is positive, a numerical step is applied to the
 end points of the trimmed pieces to match them with greater
 precision.

 Example:

@\begin{verbatim}
 c0 = cbspline( 3,
                list( ctlpt( E2, -1,   3 ),
                      ctlpt( E2, -0.3, 0 ),
                      ctlpt( E2,  0.3, 0 ),
                      ctlpt( E2,  1,   3 ) ),
                list( kv_open ) );
 for ( i = -5, 1, 5,
     if ( i != 0,
         ofst = 0.15 * i:
         co = offset( c0, ofst, 0.0001, off ):
         none = TOFFSET( c0, co, 15, abs( ofst * 0.999 ), 0.001 ):
         color( none, i + 6 ):
         viewobj( none ) ) );
@\end{verbatim}

 approximates several offset curves at offset amounts of {\bf 0.15 * i} to
 curve {\bf c0} and trim the self intersections detected in them.
@See Figure~\ref{fig-trim-offset}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/trim_off.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/trim_off.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Properly trimmed offsets could be created using the TOFFSET function.
=</b><BR clear=all>
@}
@\label{fig-trim-offset}
@\end{figure}
$

@\subsubsection{TORUS}
!TORUS

@\begin{verbatim}
 PolygonType TORUS( VectorType Center, VectorType Normal,
                    NumericType MRadius, NumericType mRadius )
@\end{verbatim}

   creates a TORUS geometric object, defined by {\bf Center} as the center
 of the TORUS, {\bf Normal} as the normal to the main plane of the TORUS,
 {\bf MRadius} and {\bf mRadius} as the major and minor radii of the TORUS.
   See RESOLUTION for the accuracy of the TORUS approximation as a polygonal
 model. See IRITSTATE's "PrimRatSrfs" and "PrimRatSrfs" state variables.

 Example:

@\begin{verbatim}
    T = TORUS( vector( 0.0, 0.0, 0.0), vector( 0.0, 0.0, 1.0), 0.5, 0.2 );
@\end{verbatim}

 constructs a torus with its major plane as the $XY$ plane, major radius of
 0.5, and minor radius of 0.2.
@See Figure~\ref{fig-torus}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/torus.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/torus.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A torus primitive can be constructed using a TORUS constructor...
=</b><BR clear=all>
@}
@\label{fig-torus}
@\end{figure}
$

@\subsubsection{TRAISE}
!TRAISE

@\begin{verbatim}
 TrivarType TRAISE( TrivarType TV, ConstantType Direction,
                      NumericType NewOrder )
@\end{verbatim}

   raises {\bf TV} to the specified {\bf NewOrder} in the specified
 {\bf Direction}.

 Example:

@\begin{verbatim}
    tv1r = TRAISE( traise( traise( tv1, row, 4 ), col, 4 ), depth, 4 );
@\end{verbatim}

 ensures that the trivariate is a tricubic.
 See also MRAISE, SRAISE, and CRAISE.
$

@\subsubsection{TREFINE}
!TREFINE

@\begin{verbatim}
 TrivarType TREFINE( TrivarType TV, ConstantType Direction,
                     NumericType Replace, ListType KnotList )
@\end{verbatim}

   provides the ability to {\bf Replace} a knot vector of {\bf TV} or refine 
 it in the specified direction {\bf Direction} (ROW, COL, or DEPTH).
   {\bf KnotList} is a list of knots at which to refine {\bf TV}. All knots should be
 contained in the parametric domain of {\bf TV} in {\bf Direction}. If the knot
 vector is replaced, the length of {\bf KnotList} should be identical to the
 length of the original knot vector of {\bf TV} in the {\bf Direction}. If {\bf TV}
 is a Bezier trivariate, it is automatically promoted to be a B-spline
 trivariate.

 Example:

@\begin{verbatim}
    TV = TREFINE( TREFINE( TREFINE( TV,
                                    ROW, FALSE, list( 0.333, 0.667 ) ),
                           COL, FALSE, list( 0.333, 0.667 ) ),
                  DEPTH, FALSE, list( 0.333, 0.667 ) );
@\end{verbatim}

 refines {\bf TV} in all directions by adding two more knots at 0.333 and
 0.667.   See also CREFINE, SREFINE, and MREFINE.
$

@\subsubsection{TREGION}
!TREGION

@\begin{verbatim}
 TrivarType TREGION( TrivarType TV, ConstantType Direction,
                     NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   extracts a region of {\bf TV} between {\bf MinParam} and {\bf MaxParam}
 in the specified {\bf Direction}. Both {\bf MinParam} and {\bf MaxParam}
 should be contained in the parametric domain of {\bf TV} in the {\bf Direction}.

 Example:

@\begin{verbatim}
    Tv1 = tbezier( list( list( list( ctlpt( E3, 0.1, 0.0, 0.8 ),
                                     ctlpt( E3, 0.2, 0.1, 2.4 ) ),
                               list( ctlpt( E3, 0.3, 2.2, 0.2 ),
                                     ctlpt( E3, 0.4, 2.3, 2.0 ) ) ),
                         list( list( ctlpt( E3, 2.4, 0.8, 0.1 ),
                                     ctlpt( E3, 2.2, 0.7, 2.3 ) ),
                               list( ctlpt( E3, 2.3, 2.6, 0.5 ),
                                     ctlpt( E3, 2.1, 2.5, 2.7) ) ) ) );

    Tv1r1 = TREGION( Tv1, row, 0.1, 0.2 );
    Tv1r2 = TREGION( Tv1, row, 0.4, 0.6 );
    Tv1r3 = TREGION( Tv1, row, 0.99, 1.0 );
@\end{verbatim}

 extracts three regions of {\bf Tv1} along the ROW direction.
@See Figure~\ref{fig-tregion}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tregion.ps, width=5in}
=    <img  hspace=2 src="user_man/tregion.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    A region can be extracted from a freeform trivariate using TREGION.
=</b><BR clear=all>
@}
@\label{fig-tregion}
@\end{figure}
 See also CREGION, SREGION, and MREGION.
$

@\subsubsection{TREPARAM}
!TREPARAM

@\begin{verbatim}
 TrivarType TREPARAM( TrivarType TV, ConstantType Direction,
                      NumericType MinParam, NumericType MaxParam )
@\end{verbatim}

   reparametrizes {\bf TV} over a new domain from {\bf MinParam} to {\bf MaxParam},
 in the prescribed {\bf Direction}. This operation does not affect the geometry
 of the trivariate and only affine transforms its knot vectors. A Bezier
 trivariate will automatically be promoted into a B-spline surface by this
 function.

 Example:

@\begin{verbatim}
    Tv = TREPARAM( TREPARAM( TREPARAM( tv, row, 0, 1 ),
                             col, 0, 1 ),
                   depth, 0, 1 );
@\end{verbatim}

 ensures that the trivariate is defined over the unit size parametric
 cube.   See also CREPARAM, SREPARAM, and MREPARAM.
$

@\subsubsection{TRIANGL}
!TRIANGL

@\begin{verbatim}
 PolygonType TRIANGL( PolygonType Model, NumericType Regular ) 
@\end{verbatim}

 converts {\bf Model} into a new model with exactly the same shape that holds
 only triangles.  If the {\bf Regular} is not zero, the object is regularized as
 well.
 Example:

@\begin{verbatim}
    final2 = triangl( final, false ); 
@\end{verbatim}
$

@\subsubsection{TRIMSRF}
!TRIMSRF

@\begin{verbatim}
 TrimSrfType TRIMSRF( SurfaceType Srf,
                      CurveType TrimCrv,
                      NumericType HasUpperLevel )
 
 or
 
 TrimSrfType TRIMSRF( SurfaceType Srf,
                      ListType TrimCrvs,
                      NumericType HasUpperLevel )
@\end{verbatim}

   create a trimmed surface from the provided surface {\bf Srf} and the
 trimming curve {\bf TrimCrv} or curves {\bf TrimCrvs}. If {\bf HasUpperLevel}
 is FALSE, an additional trimming curve is automatically added that
 contains the entire parametric domain of {\bf Srf}. No validity test is
 performed on the trimming curves which are assumed to be two-dimensional
 curves contained in the parametric domain of {\bf Srf}.

 Example:

@\begin{verbatim}
    spts = list( list( ctlpt( E3, 0.1, 0.0, 1.0 ),
                       ctlpt( E3, 0.3, 1.0, 0.0 ),
                       ctlpt( E3, 0.0, 2.0, 1.0 ) ),
                 list( ctlpt( E3, 1.1, 0.0, 0.0 ),
                       ctlpt( E3, 1.3, 1.5, 2.0 ),
                       ctlpt( E3, 1.0, 2.1, 0.0 ) ),
                 list( ctlpt( E3, 2.1, 0.0, 2.0 ),
                       ctlpt( E3, 2.3, 1.0, 0.0 ),
                       ctlpt( E3, 2.0, 2.0, 2.0 ) ),
                 list( ctlpt( E3, 3.1, 0.0, 0.0 ),
                       ctlpt( E3, 3.3, 1.5, 2.0 ),
                       ctlpt( E3, 3.0, 2.1, 0.0 ) ),
                 list( ctlpt( E3, 4.1, 0.0, 1.0 ),
                       ctlpt( E3, 4.3, 1.0, 0.0 ),
                       ctlpt( E3, 4.0, 2.0, 1.0 ) ) );
    sb = sbspline( 3, 3, spts, list( list( KV_OPEN ), list( KV_OPEN ) ) );
    
    TCrv1 = cbspline( 2,
                      list( ctlpt( E2, 0.3, 0.3 ),
                            ctlpt( E2, 0.7, 0.3 ),
                            ctlpt( E2, 0.7, 0.7 ),
                            ctlpt( E2, 0.3, 0.7 ),
                            ctlpt( E2, 0.3, 0.3 ) ),
                      list( KV_OPEN ) );
    TCrv2 = circle( vector( 0.5, 0.5, 0.0 ), 0.25 );
    TCrv3 = cbspline( 3,
                      list( ctlpt( E2, 0.3, 0.3 ),
                            ctlpt( E2, 0.7, 0.3 ),
                            ctlpt( E2, 0.7, 0.7 ),
                            ctlpt( E2, 0.3, 0.7 ) ),
                      list( KV_PERIODIC ) );
    
    TSrf1 = TRIMSRF( sb, TCrv1, false );
    TSrf2 = TRIMSRF( sb, TCrv1, true );
    TSrf3 = TRIMSRF( sb, list( TCrv1, TcRv2 * ty( 1 ), TCrv3 * ty( 2 ) ),
                     false );
@\end{verbatim}

 constructs three trimmed surfaces. {\bf Tsrf1} contains the outer boundary
 and excludes what is inside {\bf TCrv1}, {\bf TSrf2} contains only the
 domain inside {\bf TCrv1}. {\bf TCrv3} has three holes corresponding to the
 three trimming curves.  See also TRMSRFS.
@See Figure~\ref{fig-trimsrf}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/trimsrf.ps, width=5in}
=    <img  hspace=2 src="user_man/trimsrf.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Three trimmed surfaces created from the same B-spline surface. 
-     The original surface is outline by thin lines and the trimmed
-     surfaces are outlined by thick lines.
=</b><BR clear=all>
@}
@\label{fig-trimsrf}
@\end{figure}
$

@\subsubsection{TRMSRFS}
!TRMSRFS

@\begin{verbatim}
 TrimSrfType TRMSRFS( SurfaceType Srf, CurveType Cntrs )
 
 or
 
 TrimSrfType TRMSRFS( SurfaceType Srf, PolyType Cntrs )
 
 or
 
 TrimSrfType TRMSRFS( SurfaceType Srf, ListType Cntrs )
@\end{verbatim}

   create a set of trimmed surfaces from the provided surface {\bf Srf} and
 the set of contours {\bf Cntrs} in {\bf Srf}'s parametric domain.

   The contours in {\bf Cntrs} can be polylines, curves, or a list of
 such entities.  The contours in {\bf Cntrs} must be either closed or start
 and end on the boundary of the parametric domain of {\bf Srf}.  Further,
 these contours must be (self) intersection free.

   The returned result is a (list of) trimmed surfaces, each defining one
 sub-region that results from {\bf Cntrs}'s trimming.

 Example:

@\begin{verbatim}
    tsrfs = TRMSRFS( srf,
                     list( poly( list( point( 0.0, 0.2, 0.0 ),
                                       point( 1.0, 0.5, 0.0 ) ), true ),
                           cbezier( list( ctlpt( E2, 0.0, 2.5 ),
                                          ctlpt( E2, 0.5, 2.5 ),
                                          ctlpt( E2, 0.5, 3.0 ) ) ) ) );
    interact( list( nth( tsrfs, 1 ) * tz( -0.2 ),
                    nth( tsrfs, 2 ) * tz(  0.0 ),
                    nth( tsrfs, 3 ) * tz(  0.2 ) ) );
@\end{verbatim}

 constructs trimmed surfaces using two contours. One contour is a polyline
 with two points, and the other is a quadratic Bezier curve. See also TRIMSRF.
@See Figure~\ref{fig-trmsrfs}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/trmsrfs.ps, width=5in}
=  <BR clear=all>
=    <img  hspace=2 src="user_man/trmsrfs.gif">
=  <BR clear=all>
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Three trimmed surfaces created from the same B-spline surface using
-     the TRMSRFS and two prescribed contour in the surface's parametric
-     domain.
=</b><BR clear=all>
@}
@\label{fig-trmsrfs}
@\end{figure}
$

@\subsubsection{TSBEZIER}
!TSBEZIER

@\begin{verbatim}
 SurfaceType TSBEZIER( NumericType Order, ListType CtlMesh )
@\end{verbatim}

   creates a triangular Bezier surface of order {\bf Order} using the
 provided control mesh. {\bf CtlMesh} is a list of control points of
 size ({\bf Order} + 1) * {\bf Order} / 2. All control points
 must be of type (E1-E9, P1-P9), or regular PointType defining the surface's
 control polygon. The surface point type will be of a space which is the union
 of the spaces of all points.
@
@The created surface is the piecewise polynomial (or rational) surface,
@\begin{equation}
@     S(u, v) = \sum_{i,j,k=0}^m \frac{n!}{i! j! k!} u^i v^j w^k P_{ijk}
@\end{equation}
@where $P_{ijk}$ are the control points {\bf CtlMesh}, and $i+j+k = m$ and $m$
@are the degree of the surface, which are one less than {\bf Order}.

 Example:

@\begin{verbatim}
    b = TSBEZIER( 3,
                  list( ctlpt( E3, 0.0,  0.0,  0.4 ),
                        ctlpt( E3, 0.3,  0.0,  0.3 ),
                        ctlpt( E3, 0.7,  0.0,  0.8 ),
     
                        ctlpt( E3, 0.2,  0.4,  1.0 ),
                        ctlpt( E3, 0.4,  0.5,  1.0 ),
     
                        ctlpt( E3, 0.5,  1.0,  0.7 ) ) );
@\end{verbatim}
@See Figure~\ref{fig-tri-surface}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tsbezier.ps, width=5in}
=    <img  hspace=2 src="user_man/tsbezier.gif">
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     A triangular Bezier surface of degree 2 or order 3.
=</b><BR clear=all>
@}
@\label{fig-tri-surface}
@\end{figure}
  See also TSGREGORY and TSBSPLINE.
$

@\subsubsection{TSBSPLINE}
!TSBSPLINE

@\begin{verbatim}
 TriSrfType TSBSPLINE( NumericType Order, NumericType Length,
                       ListType CtlMesh, ListType KnotVector )
@\end{verbatim}

   creates a B-spline surface from the provided {\bf Order} and {\bf Length},
 the control mesh {\bf CtlMesh}, and the knot vector {\bf KnotVector}.
 {\bf CtlMesh} is a list of control points of size ({\bf Length} + 1) *
 {\bf Length} / 2.  All control points must be of point type (E1-E9,
 P1-P9), or regular PointType defining the surface's control mesh.
 The surface point type will be of a space which is the union of the spaces
 of all points.
   {\bf KnotVector} is a list of NumericType knots of length {\bf Length}
 plus the {\bf Order}.
   The knot vector may also be a list of a single constant KV\_OPEN or
 KV\_FLOAT, in which a uniform knot vector with the appropriate length
 and with an open or floating end condition will be constructed automatically.

 Not fully supported at this time.   See also TSBEZIER and TSGREGORY.
$

@\subsubsection{TSDERIVE}
!TSDERIVE

@\begin{verbatim}
 TriSrfType TSDERIVE( TriSrfType Srf, NumericType Dir )
@\end{verbatim}

   returns a vector field surface representing the differentiated triangular
 surface in the given direction (ROW, COL, or DEPTH). Evaluation of
 the returned surface at a given parameter value will return a vector
 {\em tangent} to {\bf Srf} in {\bf Dir} at that parameter value.

@\begin{verbatim}
 DuSrf = TSDERIVE( Srf, ROW );
 DvSrf = TSDERIVE( Srf, COL );
 Normal = coerce( tseval( DuSrf, 0.5, 0.25, 0.25 ), VECTOR_TYPE ) ^
          coerce( tseval( DvSrf, 0.5, 0.25, 0.25 ), VECTOR_TYPE );
@\end{verbatim}
 
 computes two partial derivatives of the surface {\bf Srf} and computes
 its normal as their cross product, at the parametric location
 (0.5, 0.25, 0.25).

 See also TSNORMAL
$

@\subsubsection{TSEVAL}
!TSEVAL

@\begin{verbatim}
 CtlPtType TSEVAL( TriSrfType Srf,
                   NumericType UParam, NumericType VParam, NumericType WParam )
@\end{verbatim}

   evaluates the provided triangular surface {\bf Srf} at the given
 {\bf UParam}, {\bf VParam}, {\bf WParam} parameters.
 {\bf UParam}, {\bf VParam}, and {\bf WParam} must all be non negative
 and must sum to one for a Bezier triangular surface or to the maximum
 domain, if a B-spline surface.

 Example:

@\begin{verbatim}
    CPt = TSEVAL( Srf, u, v, 1.0 - u - v );
@\end{verbatim}

 evaluates {\bf Srf} at the parameter values prescribed by {\bf u} and {\bf v}.
$

@\subsubsection{TSGREGORY}
!TSGREGORY

@\begin{verbatim}
 SurfaceType TSGREGORY( NumericType Order, ListType CtlMesh )
@\end{verbatim}

  cCreates a triangular Gregory surface of order {\bf Order} using the
 provided control mesh. {\bf CtlMesh} is a list of control points of
 size ({\bf Order} + 1) * {\bf Order} / 2 + 3. All control points
 must be of type (E1-E9, P1-P9), or regular PointType defining the surface's
 control polygon.  The surface point type will be of a space which is the union
 of the spaces of all points.
@
@The created surface is the polynomial (or rational) surface,
@\begin{equation}
@     S(u, v) = \sum_{i,j,k=0}^m \frac{n!}{i! j! k!} u^i v^j w^k P_{ijk}
@\end{equation}
@where $P_{ijk}$ are the control points {\bf CtlMesh}, and $i+j+k = m$ and $m$
@are the degree of the surface, which are one less than {\bf Order}, where
@$P_{ijk}$ for $i = j = 1$, or $i = k = 1$, or $j = k = 1$ are
@the three Gregory, double points.

 Example:

@\begin{verbatim}
    Srf = tsgregory( 5,
        list( ctlpt( E3, 2, -1, 0 ),
              ctlpt( E3, 2.3, -1, 0.25 ),
              ctlpt( E3, 2.6, -1, 0.25 ),
              ctlpt( E3, 2.8, -1, 0.13 ),
              ctlpt( E3, 3, -1, 0 ),
              ctlpt( E3, 2.25, -0.7, 0.25 ),
              ctlpt( E3, 2.5, -0.7, -0.25 ),
              ctlpt( E3, 2.6, -0.7, -0.15 ),
              ctlpt( E3, 2.75, -0.7, 0.25 ),
              ctlpt( E3, 2.4, -0.4, 0.25 ),
              ctlpt( E3, 2.5, -0.4, 0 ),
              ctlpt( E3, 2.6, -0.4, -0.25 ),
              ctlpt( E3, 2.45, -0.2, 0.12 ),
              ctlpt( E3, 2.55, -0.2, -0.12 ),
              ctlpt( E3, 2.5, 0, 0 ),
              ctlpt( E3, 2.5, -0.7, -0.25 ),
              ctlpt( E3, 2.6, -0.7, -0.15 ),
              ctlpt( E3, 2.5, -0.4, 0 ) ) );
@\end{verbatim}

  Not fully supported at this time.   See also TSBEZIER and TSBSPLINE.
$

@\subsubsection{TSNORMAL}
!TSNORMAL

@\begin{verbatim}
 VectorType TSNORMAL( TriSrfType Srf,
                      NumericType UParam, NumericType VParam, NumericType WParam)
@\end{verbatim}

   computes the normal vector to a triangular surface {\bf Srf} at the
 parameter values {\bf UParam}, {\bf VParam}, {\bf WParam}. The returned
 vector has a unit length.

   {\bf UParam}, {\bf VParam}, and {\bf WParam} must all be non
 negative and must sum to one for a Bezier triangular surface or to
 the maximum domain, if a B-spline surface.

 Example:

@\begin{verbatim}
    Normal = TSNORMAL( Srf, 0.5, 0.5, 0.0 );
@\end{verbatim}

 computes the normal to {\bf Srf} at the parameter values (0.5, 0.5, 0.0).
$

@\subsubsection{TVLOAD}
!TVLOAD

@\begin{verbatim}
 TrivarType TVLOAD( StringType FileName,
                    NumericType DataType,
                    VectorType VolSize,
                    VectorType Orders )
@\end{verbatim}

 loads a volumetric data set from file {\bf FileName} in as a
 trivariate of orders {\bf Orders}.  {\bf DataType} can be one of:
# 10 2 1 1
 1
  Regular ASCII (separated by white spaces).
 2
  Two bytes short integer.
 3
  Four bytes long integer.
 4
  One byte (char) integer.
 5
  Four bytes float.
 6
  Eight bytes double.
#
 Beware of the little vs big Endian problem! We assume here you have read the
 volume in the same machine type in which this file was written.

 {\bf VolSize} provides the dimensions of the volume, with width first and
 depth last.  Uniform open end condition knot vectors are constructed to all
 three axes.

 Example:

@\begin{verbatim}
    Tv = TVLOAD( "3dhead", 1, vector( 32, 32, 13 ), vector( 3, 3, 3 ) );
@\end{verbatim}

 loads the data set {\bf "3dhead"} of size (32, 32, 13) as a triquadratic
 function.  THe sata set is assumed to contain ASCII numeric values.

 See also MRCHCUBE.
$

@\subsubsection{TVZRJACOB}
!TVZRJACOB

@\begin{verbatim}
 PolyType TVZRJACOB( TrivarType TV,
                     NumericType Euclidean,
                     NumericType SkipRate,
                     NumericType Fineness )
@\end{verbatim}

 computes the zero set of the Jacobian of the given trivariate, {\bf TV}.
 This zero set is the implicit boundary of the trivariate and, for example,
 equals the envelop of the sweep of a bivariate surface in space (see
 example below).  The zero set is returned as a polygonal data set
 approximation with {\bf Fineness} tolerance.  If {\bf Euclidean}, the
 resulting polygons are in Euclidean space.  Otherwise, the polygons are
 returned in the trivariate's parametric domain. Finally, {\bf SkipRate}
 provides a mechanism to skip to every {\bf SkipRate} row, column and plane
 while a {\bf SkipRate} skips nothing.

@Let $T(u, v, w) = (x_T(u, v, w), y_T(u, v, w), z_T(u, v, w))$.  Then,
@the zero of the Jacobian equals,
@\begin{equation}
@     0 = \left|
@        \begin{array}{ccc}
@            \frac{\partial x_T}{\partial u} &
@            \frac{\partial x_T}{\partial v} &
@            \frac{\partial x_T}{\partial w} \\
@            \frac{\partial y_T}{\partial u} &
@            \frac{\partial y_T}{\partial v} &
@            \frac{\partial y_T}{\partial w} \\
@            \frac{\partial z_T}{\partial u} &
@            \frac{\partial z_T}{\partial v} &
@            \frac{\partial z_T}{\partial w}
@        \end{array}
@        \right| = \inner{x_T}{y_T \times z_T}.
@\end{equation}

 Example:

@\begin{verbatim}
    Tv = tfromsrfs( list( Srf,
                           Srf * tx( 3 ) * ty( 3 ),
                           Srf * tx( 6 ) ), 3 );
    Tv1ZeroJacobian = TVZRJACOB( Tv, 1, 1, 0 );
@\end{verbatim}

 A trivariate {\bf TV} is constructed as a sweep of surface {\bf Srf}
 along a quadratic Bezier curve with (0, 0), (3, 3), (6, 0) as control points,
 and then the zero set of the Jacobian is derived to yield the envelope of
 this motion of {\bf Srf}.
@See Figure~\ref{fig-trivar-zero-jacobian}.
@\begin{figure}
@\begin{center}
@    \epsfig{file=user_man/tvzrjaco.ps, width=5in}
=  <BR clear=all> 
=    <img  hspace=2 src="user_man/tvzrjaco.gif">
=  <BR clear=all> 
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-       The envelope of the motion of the wine glass surface in space can
-       be derived with the aid of the TvZrJacob function.
=</b><BR clear=all>
@}
@\label{fig-trivar-zero-jacobian}
@\end{figure}
$

@\subsubsection{UVPOLY}
!UVPOLY

@\begin{verbatim}
 PolyType UVPOLY( PolyType Obj, ListType Scales );
@\end{verbatim}

 Sets UV coordinates to polygonal object {\bf Obj}.  The UV coordinates
 are set using the XY Euclidean coordinates if {\bf Scales} is a list that
 holds two scaling factors (XScale, YScale), or the UV coordinates are
 set via the two largest span in XYZ for each polygon, if {\bf Scales} is
 a list of three scaling factors (XScale, YScale, ZScale).

 Needless to say, the ?Scale factors scales the Euclidean coordinates before
 being sets as UV texture coordinates.


 Example:

@\begin{verbatim}
    UVCube = UVPOLY( Cube, scale( 1, 1, 1 ) );
@\end{verbatim}

 sets UV coordinates to the six faces of the cube, each face with UV
 values between zero and one.
$

@\subsubsection{ZCOLLIDE}
!ZCOLLIDE

@\begin{verbatim}
 NumericType ZCOLLIDE( GeometricTreeType Obj1,
                       GeometricTreeType Obj2,
                       NumericType Fineness,
                       NumericType NumOfIters );
@\end{verbatim}

 Given two objects, {\bf Obj1} and {\bf Obj2}, where {\bf Obj1} is assumed to
 be above (in the Z direction) {\bf Obj2}, this function computes the amount
 that {\bf Obj1} could be moved down, the -Z direction, until it collides with
 {\bf Obj2}.  The collision detection is considered using a polygonal
 approximation that has a {\bf Fineness} resolution (see RESOLUTION variable).
 The computation cost is linear in {\bf NumOfIters} with quadratic accuracy
 convergence.  Values of ten for both {\bf Fineness} and {\bf NumOfIters} are
 reasonable selections.  While {\bf Obj1} is considered in its exact form, in
 {\bf Obj2}, only the bbox of the shape is considered.

 Example:

@\begin{verbatim}
    view( chair, 1 );
    for ( x = 0, 1, 5,
        b = box( vector( x / 10, 0, 2 ), 0.1, 0.1, 0.1 ):
        view( b * tz( ZCOLLIDE( chair, b, 10, 10 ) ), 0 ) );
@\end{verbatim}

 places and draws six different cubes on top of the object called chair.
$
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Object transformation functions}
!Object transformation functions

 All the routines in this section construct a 4 by 4 homogeneous
 transformation matrix representing the required transform. These matrices
 may be concatenated to achieve more complex transforms using the matrix
 multiplication operator $*$. For example, the expression

@\begin{verbatim}
    m = trans( vector( -1, 0, 0 ) ) * rotx( 45 ) * trans( vector( 1, 0, 0 ) );
@\end{verbatim}

 constructs a transform to rotate an object around the X = 1 line, 45 degrees.
 A matrix representing the inverse transformation can be computed as:
@\begin{verbatim}
    InvM = m ^ -1
@\end{verbatim}
 See also overloading of the - operator.
$

@\subsubsection{HOMOMAT}
!HOMOMAT

@\begin{verbatim}
 MatrixType HOMOMAT( ListType MatData )
@\end{verbatim}

   creates an arbitrary homogeneous transformation matrix by manually providing
 its 16 coefficients.

 Example:

@\begin{verbatim}
 step = 10;
 for ( a = 1, 1, 720 / step,
       view_mat = save_mat *
                  HOMOMAT( list( list( 1, 0, 0, 0 ),
                                 list( 0, 1, 0, 0 ),
                                 list( 0, 0, 1, -a * step / 500 ),
                                 list( 0, 0, 0, 1 ) ) ):
       view( list( view_mat, axes ), on )
 );
@\end{verbatim}

 looping and viewing through a sequence of perspective transforms, created
 using the HOMOMAT constructor.  See also RFLCTMAT and PROJMAP.
$

@\subsubsection{MAP3PT2EQL}
!MAP3PT2EQL

@\begin{verbatim}
 MatrixType MAP3PT2EQL( PointType Pt1, PointType Pt2, PointType Pt3 )
@\end{verbatim}

   computes the transofrmation matrix in the XY plane that takes the given
 three planar points into an equilateral triangle around the origin.

  Example:

@\begin{verbatim}
    Mat = MAP3PT2EQL( Pt1, Pt2, Pt3 );
@\end{verbatim}

  See also ELLIPSE3PT, CONICSEC.
$

@\subsubsection{MATPOSDIR}
!MATPOSDIR

@\begin{verbatim}
 MatrixType MATPOSDIR( PointType Pos, VectorType Dir, VectorType UpDir )
@\end{verbatim}

   creates a viewing transformation matrix of a viewer at {\bf Pos}, looking
 at direction {\bf Dir} and upper view of {\bf UpDir}.

 Example:

@\begin{verbatim}
 step = 10;
 for ( a = 1, 1, 720 / step,
       view_mat = MATPOSDIR( point( 0.5, 0.1, 0.5 ),
                             vector( 0.0, 1.0, 0.0 ),
                             vector( cos( a * step * Pi / 360 ), 0,
                                     sin( a * step * Pi / 360 ) ) ):
       view( list( view_mat, axes ), on )
 );
@\end{verbatim}

 looping and viewing through a sequence of transforms, created
 using the MATPOSDIR constructor.
$

@\subsubsection{PROJMAT}
!PROJMAT

@\begin{verbatim}
 MatrixType PROJMAT( PlaneType ProjPlane,
                     VectorType EyePos,
                     NumericType EyeInf )
@\end{verbatim}

   constructs a projection matrix to project the universe onto the given
 projection plane {\bf ProjPlane}, with the eye position at {\bf EyePos}
 (divided by {\bf EyeInf}).  Note that if {\bf EyeInf} is zero, the eye is
 at infinity.

 Example:

@\begin{verbatim}
  PMat = PROJMAT( plane( 0, 0, 1, -0.1 ), vector( 1, 1, 1 ), 0 );
@\end{verbatim}

 contstructs a projection matrix {\bf PMat} onto the Z = -0.1 plane
 with a view direction of ( 1, 1, 1 ).  See also RFLCTMAP, HOMOMAT.
$

@\subsubsection{RFLCTMAT}
!RFLCTMAT

@\begin{verbatim}
 MatrixType RFLCTMAT( PlaneType RflctPlane )
@\end{verbatim}

   constructs a reflection matrix to reflect the universe along the given
 reflection plane {\bf RflctPlane}.

 Example:

@\begin{verbatim}
  PMat = RFLCTMAT( plane( 0, 0, 1, 0 ) );
@\end{verbatim}

 constructs a reflection matrix {\bf PMat} around the Z = 0 plane.
 See also PROJMAP, HOMOMAT.
$

@\subsubsection{ROTV2V}
!ROTV2V

@\begin{verbatim}
 MatrixType ROTV2V( VectorType Vec1, VectorType Vec2 )
@\end{verbatim}

   creates a rotation that takes vector {\bf Vec1} to vector {\bf Vec2}.
   See also ROTVEC, ROTZ2V, ROTZ2V2.
$

@\subsubsection{ROTVEC}
!ROTVEC

@\begin{verbatim}
 MatrixType ROTVEC( VectorType Vec, NumericType Angle )
@\end{verbatim}

   creates a rotation around the vector {\bf Vec} matrix with {\bf Angle} degrees.
   See also ROTV2V, ROTZ2V, ROTZ2V2.
$

@\subsubsection{ROTX}
!ROTX

@\begin{verbatim}
 MatrixType ROTX( NumericType Angle )
@\end{verbatim}

   creates a rotation around the X transformation matrix with {\bf Angle} degrees.
$

@\subsubsection{ROTY}
!ROTY

@\begin{verbatim}
 MatrixType ROTY( NumericType Angle )
@\end{verbatim}

   creates a rotation around the Y transformation matrix with {\bf Angle} degrees.
$

@\subsubsection{ROTZ}
!ROTZ

@\begin{verbatim}
 MatrixType ROTZ( NumericType Angle )
@\end{verbatim}

   creates a rotation around the Z transformation matrix with {\bf Angle} degrees.
$

@\subsubsection{ROTZ2V}
!ROTZ2V

@\begin{verbatim}
 MatrixType ROTZ2V( VectorType Dir )
@\end{verbatim}

   creates a rotation matrix that takes Z axis into {\bf Dir}. Length of {\bf Dir}
 is ignored.
   See also ROTV2V, ROTVEC, ROTZ2V2.
$

@\subsubsection{ROTZ2V2}
!ROTZ2V2

@\begin{verbatim}
 MatrixType ROTZ2V2( VectorType Dir, VectorType Dir2 )
@\end{verbatim}

   creates a rotation matrix that takes the Z axis into {\bf Dir}, while the X
 axis is aligned with {\bf Dir2}. The lengths of {\bf Dir} and {\bf Dir2} are
 ignored.
   See also ROTV2V, ROTVEC, ROTZ2V, ROTVEC.
$

@\subsubsection{SCALE}
!SCALE

@\begin{verbatim}
 MatrixType SCALE( VectorType ScaleFactors )
@\end{verbatim}

   creates a scaling by the {\bf ScaleFactors} transformation matrix.
$

@\subsubsection{TRANS}
!TRANS

@\begin{verbatim}
 MatrixType TRANS( VectorType TransFactors )
@\end{verbatim}

   creates a translation by the {\bf TransFactors} transformation matrix.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{General purpose functions}
!General purpose functions  
$

@\subsubsection{ADWIDTH}
!ADWIDTH

@\begin{verbatim}
 ADWIDTH( GeometricType Object, NumericType DWidth )
@\end{verbatim}

   sets the width of the object.  This display width is used in pixels in
 display devices for width of line drawing, if supported by the display device.
   See also ATTRIB, COLOR, and AWIDTH.

   This function is equivalent to using,

                         ATTRIB( {\bf Object}, "dwidth", {\bf Width} );
$

@\subsubsection{ATTRIB}
!ATTRIB

@\begin{verbatim}
 ATTRIB( AnyType Object, StringType Name, AnyType Value )
@\end{verbatim}

   provides a mechanism to add an attribute of any type to an {\bf Object},
 with name {\bf Name} and value {\bf Value}. This ATTRIB function is tuned
 and optimized toward numeric values or strings as {\bf Value} although any
 other object type can be saved as attribute.

   These attributes may be used to pass information to other programs about
 this object, and are saved with the objects in data files.
 Attributes placed on a list object or even a whole hierarchy of
 objects will be propagated into all items in the list or hierarchy.
   There are a few exception to this propagation. The "animation" attribute 
 is not propagated and is kept in the internal nodes, forming a hierachy of
 animation commands for all the objects contained in the list/hierarchy.
 The "invisible" attribute is saved at all levels of the hierarchy, used to
 denote a complete sub tree that is invisible (yet can serve as a source at
 which instances can point).

 For example,

@\begin{verbatim}
    ATTRIB(Glass, "rgb", "255,0,0");
    ATTRIB(Glass, "refract", "1.4");
        .
        .
        .
    RmAttr(Glass, "rgb");   # Removes "rgb" attribute.
@\end{verbatim}

 sets the RGB color and refraction index of the {\bf Glass} object and
 later removes the RGB attribute.

   Attribute names are case insensitive. Spaces are allowed in the {\bf Value}
 string, as well as the double quote itself, although the latter must be
 escaped:

@\begin{verbatim}
    ATTRIB(Glass, "text", "Say \"this is me\"");
@\end{verbatim}

   See also RMATTR for removal of attributes, CPATTR for copying them,
 GETATTR to get an attribute, ATTRPROP for setting attributes on all
 subtrees of parts, as well as AWIDTH, ADWIDTH, COLOR and PATTRIB.
$

@\subsubsection{ATTRPROP}
!ATTRPROP

@\begin{verbatim}
 ATTRPROP( AnyType Object, StringType Name, AnyType Value )
@\end{verbatim}

   Same as ATTRIB but propagates the attributes to all sub-parts of the
 object.

 Example:

@\begin{verbatim}
    Glass1 = list( Base, Handle, Wine );
    Glass2 = list( Base, Handle, Wine );
    attrib( Glass1, "ptexture", "marble1.gif" );
    ATTRPROP( Glass2, "ptexture", "marble1.gif" );
@\end{verbatim}

 In {\bf Glass1}, only {\bf Glass1} will be set with "texture" while in
 {\bf Glass2}, the "texture" attribute will propagate to the sub-parts of
 {\bf Glass2}, namely to the {\bf Base}, {\bf Handle}, {\bf Wine}.
$

@\subsubsection{AWIDTH}
!AWIDTH

@\begin{verbatim}
 AWIDTH( GeometricType Object, NumericType Width )
@\end{verbatim}

   sets the width of the object to one of those specified below.  This width
 is used in real object side dimensions in tools such as scan converters and
 rendering tools for rendering lines and curves, as well as postscript.
   See also ATTRIB, COLOR, and ADWIDTH.

   This function is equivament to using,

                         ATTRIB( {\bf Object}, "width", {\bf Width} );
$

@\subsubsection{CHDIR}
!CHDIR

@\begin{verbatim}
 CHDIR( StringType NewDir )
@\end{verbatim}

   sets the current working directory to be {\bf NewDir}.
$

@\subsubsection{CLNTCLOSE}
!CLNTCLOSE

@\begin{verbatim}
 CLNTCLOSE( NumericType Handler, NumericType Kill )
@\end{verbatim}

   closes a communication channel to a client. {\bf Handler} contains the
 index of the communication channel opened via CLNTEXEC. If {\bf Kill}, the
 client is sent an  exit request for it to die. Otherwise, the communication
 is closed and the client runs standing alone.  See also VIEWOBJ, VIEWSET,
 CLNTREAD, CLNTWRITE, and CLNTEXEC.
 
 Example:

@\begin{verbatim}
   h2 = clntexec( "nuldrvs -s-" );
       .
       .
       .

   CLNTCLOSE( h2,TRUE );
@\end{verbatim}

 closes the connection to the nuldrvs client, opened via CLNTEXEC.
$

@\subsubsection{CLNTWRITE}
!CLNTWRITE

@\begin{verbatim}
 CLNTWRITE( NumericType Handler, AnyType Object )
@\end{verbatim}

   writes one object {\bf Object} to a communication channel of a client.
 {\bf Handler} contains the index of the communication channel opened via
 CLNTEXEC.  If the {\bf Handler} equals -1, the regular display device
 (forked via, for example, VIEWOBJ command) is used.  If {\bf Handler} equals
 CLIENTS\_ALL, a broadcast of {\bf Object} to all clients is performed.
 See also VIEWOBJ, VIEWSET, CLNTREAD, CLNTCLOSE, and CLNTEXEC.
 
 Example:

@\begin{verbatim}
   h2 = clntexec( "nuldrvs -s-" );
       .
       .

   CLNTWRITE( h2, Model );
       .
       .

   clntclose( h2,TRUE );
@\end{verbatim}

 writes the object named Model to client through communication channel h2.
$

@\subsubsection{COLOR}
!COLOR

@\begin{verbatim}
 COLOR( GeometricType Object, NumericType Color )
@\end{verbatim}

   sets the color of the object to one of those specified below. Note that an
 object has a default color (see {\bf irit.cfg} file) according to its origin -
 loaded with the LOAD command, PRIMITIVE, or a BOOLEAN operation result.
   The system internally supports colors (although you may have a B\verb+&+W
 system) and the colors recognized are:
 {\bf BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, and WHITE}.

   See the ATTRIB command for more fine control of colors using the RGB
 attribute. See also AWIDTH and AWIDTH.

   This function is equivament to using,

                         ATTRIB( {\bf Object}, "color", {\bf Width} );
$

@\subsubsection{COMMENT}
!COMMENT

@\begin{verbatim}
 COMMENT
@\end{verbatim}

 Two types of comments are allowed:

 1. One-line comment: starts anywhere in a line at the '\#' character, up to
    the end of the line.

 2. Block comment: starts at the COMMENT keyword followed by a unique
    character (anything but white space), up to the second occurrence of that
    character. This is a fast way to comment out large blocks.

 Example:

@\begin{verbatim}
    COMMENT $
      This is a comment
    $
@\end{verbatim}
$

@\subsubsection{CPATTR}
!CPATTR

@\begin{verbatim}
 CPATTR( AnyType DestObj, AnyType SrcObj )
@\end{verbatim}

   copies all attribute from object {\bf SrcObj} into object {\bf DestObj}. All
 attributes, if any, in {\bf DestObj} are purged.  Needless to say, both objects
 must exist at the time of attribute copy.

 See also ATTRIB, ATTRPROP, GETATTR, RMATTR.
$

@\subsubsection{ERROR}
!ERROR

@\begin{verbatim}
 ERROR( StringType Message);
@\end{verbatim}

 breaks the execution and returns to the IRIT main loop, after printing a
 {\bf Message} to the screen. This may be useful in user defined functions to
 break execution in cases of fatal errors.
$

@\subsubsection{EXEC}
!EXEC

@\begin{verbatim}
 EXEC( StringType Command );
@\end{verbatim}

   executes a string {\bf Command} in the IRIT interepreter, indirectly.

 Example:

@\begin{verbatim}
    Univariate2Bezier = function( Polynom, Deg ): x: f:
    return = nil():
    f = 1:
    for ( x = 0, 0.05 / Deg, 1,
        EXEC( "f = " + Polynom ):
        snoc( ctlpt( E1, f ), return ) ):
    return = coerce( cinterp( return, Deg + 1, Deg + 1, PARAM_UNIFORM, FALSE ),
                     bezier_type );
@\end{verbatim}

 defines a function that converts univariate expressions into explicit, E1,
 Bezier curves.  For example 
    "Univariate2Bezier( "3 * x \verb-^- 2 - 2 * x + 5", 3 );"
 would return a cubic Bezier curve representing "3 * x \verb-^- 2 - 2 * x + 5".
$

@\subsubsection{EXIT}
!EXIT

@\begin{verbatim}
 EXIT()
@\end{verbatim}

   exits from the solid modeler. NO warning is given!
$

@\subsubsection{FOR}
!FOR

@\begin{verbatim}
 FOR( NumericType Start, NumericType Increment, NumericType End, AnyType Body )
@\end{verbatim}

   executes the {\bf Body} (see below), while the FOR loop conditions hold.
   {\bf Start, Increment, End} are evaluated first, and the loop is executed
 while {\bf $<=$ End} if {\bf Increment $>$ 0}, or while {\bf $>=$ End} if {\bf Increment $<$ 0}.
   If {\bf Start} is of the form "Variable = Expression", then that variable is
 updated on each iteration, and can be used within the body.
   The body may consist of any number of regular commands, separated by
 COLONs, including nesting FOR loops to an arbitrary level.

 Example:

@\begin{verbatim}
 step = 10;
 rotstepx = rotx(step);
 FOR ( a = 1, 1, 360 / step,
     view_mat = rotstepx * view_mat:
     view( list( view_mat, axes ), ON )
 );
@\end{verbatim}

 displays axes with a view direction that is rotated 10 degrees at a
 time around the X axis.
$

@\subsubsection{HELP}
!HELP

@\begin{verbatim}
 HELP( StringType Subject )
@\end{verbatim}

   provides help on the specified Subject.

 Example:

@\begin{verbatim}
    HELP("");
@\end{verbatim}

 will list all {\em IRIT} help subjects.
$

@\subsubsection{FNFREE}
!FNFREE

@\begin{verbatim}
 FNFREE( StringType UserFuncName )
@\end{verbatim}

   frees a user defined function named {\bf UserFuncName}. See also FREE.
$

@\subsubsection{FREE}
!FREE

@\begin{verbatim}
 FREE( GeometricType Object )
@\end{verbatim}

   Because of the usually huge size of geometric objects, this procedure
 may be used to free them. Reassigning a value (even of different type)
 to a variable automatically releases the old variable's allocated space
 as well.  See also FNFREE.
$

@\subsubsection{FUNCTION}
!FUNCTION

@\begin{verbatim}
 FuncName = FUNCTION(Prm1, Prm2, ... , PrmN):LclVal1:LclVar2: ... :LclVarM:
     FuncBody;
@\end{verbatim}

 defines a function named FuncName with N parameters and M local variables
 $(N, M >= 0)$. Here is a (simple) example of a function with no local variables
 and a single parameter that computes the square of a number:

@\begin{verbatim}
 sqr = FUNCTION(x):
    return = x * x;
@\end{verbatim}

   Functions can be defined with optional parameters and optional local
 variables. A function's body may contain an arbitrary set of expressions
 including for/while loops, (user) function calls, or even recursive function
 calls, all separated by colons.
   The returned value of the function is the value of an automatically defined
 local variable named return. The return variable is a regular local variable
 within the scope of the function and can be used as any other variable.

   If a variable's name is found in neither the local variable list nor
 the parameter list, it is searched for in the global variable list (outside
 the scope of the function). Binding of names of variables is static as in the
 C programming language.

   Because binding of variables is performed in execution time, there is a
 somewhat less restrictive type checking of parameters of functions that are
 invoked within a user's defined function.

   A function can invoke itself, i.e., it can be recursive. However, since a
 function should be defined when it is called, a dummy function should be
 defined before the recursive one is defined:

@\begin{verbatim}
 factorial = function(x):return = x; # Dummy function.
 factorial = function(x):
     if (x <= 1, return = 1, return = x * factorial(x - 1));
@\end{verbatim}

   Overloading is valid inside a function as it is outside. For example, for

@\begin{verbatim}
 add = FUNCTION(x, y):
    return = x + y;
@\end{verbatim}

 the following function calls are all valid:

@\begin{verbatim}
 add(1, 2);
 add(vector(1,2,3), point(1,2,3));
 add(box(vector(-3, -2, -1), 6, 4, 2), box(vector(-4, -3, -2), 2, 2, 4));
@\end{verbatim}

 Finally, here is a more interesting example that computes an approximation
 of the length of a curve, using the sqr function defined above:

@\begin{verbatim}
 distptpt = FUNCTION(pt1, pt2):
     return = sqrt(sqr(coord(pt1, 1) - coord(pt2, 1)) +
                   sqr(coord(pt1, 2) - coord(pt2, 2)) +
                   sqr(coord(pt1, 3) - coord(pt2, 3)));

 crvlength = FUNCTION(crv, n):pd:t:t1:t2:dt:pt1:pt2:i:
     return = 0.0:
     pd = pdomain(crv):
     t1 = nth(pd, 1):
     t2 = nth(pd, 2):
     dt = (t2 - t1) / n:
     pt1 = coerce(ceval(crv, t1), e3):
     for (i = 1, 1, n,
          pt2 = coerce(ceval(crv, t1 + dt * i), e3):
          return = return + distptpt(pt1, pt2):
          pt1 = pt2);
@\end{verbatim}

 Try, for example:

@\begin{verbatim}
 crvlength(circle(vector(0.0, 0.0, 0.0), 1.0), 30) / 2;
 crvlength(circle(vector(0.0, 0.0, 0.0), 1.0), 100) / 2;
 crvlength(circle(vector(0.0, 0.0, 0.0), 1.0), 300) / 2;
@\end{verbatim}

 See PROCEDURE and IRITSTATE's "DebugFunc" for more.
$

@\subsubsection{IF}
!IF

@\begin{verbatim}
 IF( NumericType Cond, AnyType TrueBody { , AnyType FalseBody } )
@\end{verbatim}

   executes {\bf TrueBody} (a group of regular commands, separated by COLONs -
 see FOR loop) if the {\bf Cond} holds, i.e., it is a numeric value other than
 zero, or optionally, if it exists, executes {\bf FalseBody}. If the {\bf Cond}
 does not hold, i.e., it evaluates to a numeric value equal to zero.

 Examples:

@\begin{verbatim}
    IF ( machine == IBMOS2, resolution = 5, resolution = 10 );
    IF ( a > b, max = a, max = b );
@\end{verbatim}

 sets the resolution to 10, unless running on an IBMOS2 system, in which
 case the RESOLUTION variable will be set to 5 in the first statement, and
 set to max to the maximum of a and b in the second statement.
$

@\subsubsection{INCLUDE}
!INCLUDE

@\begin{verbatim}
 INCLUDE( StringType FileName )
@\end{verbatim}

   executes the script file {\bf FileName}. Nesting of an include file is allowed
 up to 10 levels deep. If an error occurs, all open files in all nested files
 are closed and data are waited for at the top level (standard input).  Files
 are searched for inclusion in the current directory.  If not found, and the
 inclusion is from a different file at some directory, that directory is
 searched as well.  Finally, if all the above fails, the directories specified
 via the IRIT\_INCLUDE environment variable are also searched.

   A script file can contain any command the solid modeler supports.

 Example:

@\begin{verbatim}
    INCLUDE( "/tmp/general.irt" );
@\end{verbatim}

 includes the file "/tmp/general.irt".  Any inclusion inside general.irt will
 search for the included file in the current directory, then in /tmp, and then
 in the directories specified via IRIT\_INCLUDE.
$

@\subsubsection{INSERTPOLY}
!INSERTPOLY

@\begin{verbatim}
 INSERTPOLY( PolyType Poly, PolyType Polys )
@\end{verbatim}

   inserts, in place, {\bf Poly} as a new polygon of object {\bf Polys}.
 After the completion of this function {\bf Poly} is unmodified but {\bf Polys}
 has a new polygon in it.

 Example:

@\begin{verbatim}
    X = poly( list( point( 0, 0, 0 ),
                    point( 0, 1, 0 ),
                    point( 1, 1, 0 ),
                    point( 1, 0, 0 ) ), false );
    Y = X * tz( 1 );
    INSERTPOLY( Y, X );
@\end{verbatim}

 At the end of the execution of this sequence of command, {\bf X} contains
 two polygons, one at Z = 0 and one at Z = 1. See also MERGEPOLY, SPLITLST.
$

@\subsubsection{INTERACT}
!INTERACT

@\begin{verbatim}
 INTERACT( GeometryTreeType Object )
@\end{verbatim}

   This is a user-defined function (see {\bf iritinit.irt}) that does the
 following, in order outlined:
@\begin{enumerate}
@\item
 Clear the display device.
@\item
 Display the given {\bf Object}.
@\item
 Pause for a keystroke.
@\end{enumerate}

   This user-defined function in version 4.0 of {\em IRIT} is an
 emulation of the INTERACT function that used to exist in previous versions.

 Example:

@\begin{verbatim}
 INTERACT( list( view_mat, Axes, Obj ) );
@\end{verbatim}

 displays and interacts with the object {\bf Obj} and the predefined object
 {\bf Axes}. VIEW\_MAT will be used to set the starting transformation.

   See VIEW and VIEWOBJ for more.
$

@\subsubsection{IQUERY}
!IQUERY

@\begin{verbatim}
 IQUERY( NumericType QueryType )
@\end{verbatim}

  A low level query tool for checking the current state of the IRIT internal
 tables.  According to the values of {\bf QueryType} the following is printed
 to stdout:

#15 2 0 1
 QueryType
  Printed content
 1
  All the known functions/user defined functions/constants
 
  and parameters/returned values (if any).
 2
  All the knwon keywords
#
$

@\subsubsection{LIST}
!LIST

@\begin{verbatim}
 ListType LIST( AnyType Elem1, AnyType Elem2, ... )
@\end{verbatim}

   constructs an object as a list of several other objects. Only a reference
 is made to the Elements, so modifying Elem1 after being included in the list
 will affect Elem1 in that list next time list is used!

   Each inclusion of an object in a list increases its internal {\bf used}
 reference. The object is freed iff the{\bf used} reference is zero.
   As a result, attempt to delete a variable (using FREE) which is referenced
 in a list removes the variable, but the object itself is freed only when the
 list is freed.
$

@\subsubsection{LOAD}
!LOAD

@\begin{verbatim}
 AnyType LOAD( StringType FileName )
@\end{verbatim}

   loads an object from the given {\bf FileName}. The object may be any object
 defined in the system, including lists, in which the structure is recovered
 and reconstructed as well (internal objects are inserted into the global
 system object list if they have names). If no file type is provided, ".itd"
 is assumed.

   This command can also be used to load binary files. ASCII regular data
 files usually take longer to load than binary files due to  
 the required parsing. Binary data files can be loaded directly, like ASCII
 files in {\em IRIT}, but can only be inspected through {\em IRIT} tools such
 as dat2irit. A binary data file must have a ".ibd" (IRIT Binary Data) type in
 its name.

   Compressed files can be loaded if the given file name has a postfix
 of ".Z" or .".gz". The gnu utility "gzip" will be invoked via a pipe
 for that purpose. 
 
   See also IRITSTATE's option "FlatLoad" for optioanl flattening of the object
 hierarechy during a load.
$

@\subsubsection{LOGFILE}
!LOGFILE

@\begin{verbatim}
 LOGFILE( NumericType Set )

 or

 LOGFILE( StringType FileName )
@\end{verbatim}

   If {\bf Set} is non zero (see TRUE/FALSE and ON/OFF), then everything
 printed in the input window will go to the log file specified in the
 {\bf irit.cfg} configuration file. This file will be created the first time
 logfile is turned ON. If a string {\bf FileName} is provided, it will
 be used as a log file name from now on. It also closes the current log
 file. A "LOGFILE( on );" must be issued after a log file name change.

 Example:

@\begin{verbatim}
    LOGFILE( "Data1" );    
    LOGFILE( on );    
    printf( "Resolution = %lf\\n", list( resolution ) );
    LOGFILE( off );    
@\end{verbatim}

 to print the current resolution level into file Data1.
$

@\subsubsection{MSLEEP}
!MSLEEP

@\begin{verbatim}
 MSLEEP( NumericType MilliSeconds )
@\end{verbatim}

 causes the solid modeller to sleep for the prescribed time in milliseconds.

 Example:

@\begin{verbatim}
 for ( i = 1, 1, sizeof( crvs ),
     c = nth( crvs, i ):
     color( c, yellow ):
     msleep(20):
     viewobj( c )
 );
@\end{verbatim}

 displays an animation sequence and sleeps for 20 milliseconds between
 iterations.
$

@\subsubsection{NREF}
!NREF

@\begin{verbatim}
 AnyType NREF( ListType ListObject, NumericType Index )
@\end{verbatim}

 returns a reference to the {\bf Index} (base count 1) element of the
 list {\bf ListObject}.  The reference points to the original object and
 hence can be used to modify (add attributes for example) to objects in
 lists.  Assignment of this reference to a new object would result in a copy
 of the object.  In contrast, a FREE of a reference to an object would have
 an undefined result.

 Example:

@\begin{verbatim}
    Lst = list( a, b, c );
    attrib( NREF( Lst, 2 ), "NewAttr", on );
@\end{verbatim}

 adds a new attribute to the second element of {\bf Lst}.  See also NTH.
$

@\subsubsection{NRMLCONE}
!NRMLCONE

@\begin{verbatim}
 ListType NRMLCONE( SurfaceType Srf )
@\end{verbatim}

 computes a cone that bounds all normals of surface {\bf Srf}.  A
 list of two objects, the axis vector of the cone and the opening radius,
 in radians, is returned.

 Example:

@\begin{verbatim}
    NCone = NRMLCONE( Srf );
    Cn = Cone( vector( 0, 0, 0 ), normalize( nth( NCone, 1 ) ),
               nth( NCone, 2 ), 0 ) * tz( 1.0 ) * sc( 0.75 );
@\end{verbatim}

 computes a normals' cone for surface {\bf Srf} and builds a real cone following
 these limits.
$

@\subsubsection{NTH}
!NTH

@\begin{verbatim}
 AnyType NTH( ListType ListObject, NumericType Index )
@\end{verbatim}

 returns the {\bf Index} (base count 1) element of the list {\bf ListObject}.

 Example:

@\begin{verbatim}
    Lst = list( a, list( b, c ), d );
    Lst2 = NTH( Lst, 2 );
@\end{verbatim}

 and now {\bf Lst2} is equal to 'list( b, c )'.  See also NREF.
$

@\subsubsection{PAUSE}
!PAUSE

@\begin{verbatim}
 PAUSE( NumericType Flush )
@\end{verbatim}

   waits for a keystroke. This is nice to have if a temporary stop in a middle
 of an included file (see INCLUDE) is required. If {\bf Flush} is TRUE, then
 the input is first flushed to guarantee that the actual stop will occur.
$

@\subsubsection{PRINTF}
!PRINTF

@\begin{verbatim}
 PRINTF( StringType CtrlStr, ListType Data )
@\end{verbatim}

 This results in a formatted printing routine, following the concepts of the C
 programming language's {\em printf} routine. {\bf CtrlStr} is a string object
 for which the following special '\%' commands are supported:
#15 2 0 1
 \%d, \%i, \%u
  Prints the numeric object as an integer or unsigned integer.
 \%o, \%x, \%X
  Prints the numeric object as an octal or hexadecimal integer.
 \%e, \%f, \%g,
  Prints the numeric object in several formats of
 \%E, \%F
  floating point numbers.
 \%s
  Prints the string object as a string.
 \%pe, \%pf, \%pg
  Prints the three coordinates of the point object.
 \%ve, \%vf, \%vg
  Prints the three coordinates of the vector object.
 \%Pe, \%Pf, \%Pg,
  Prints the four coordinates of the plane object.
 \%De, \%Df, \%Dg,
  Prints the given object in IRIT's data file format.
#

 All the '\%' commands can include any modifier that is valid in the C
 programming language PRINTF routine, including l (long), prefix
 character(s), size, etc. The point, vector, plane, and object commands
 can also be modified in a similar way, to set the format of the
 numeric data printed.

 Also supported are the newline and tab using the backslash escape
 character:

@\begin{verbatim}
* PRINTF("\\tThis is the char \"\\%\"\\n", nil());
@\end{verbatim}

 Backslashes should be escaped themselves as can be seen in the above example.
 Here are few more examples:

@\begin{verbatim}
* PRINTF("this is a string \"%s\" and this is an integer %8d.\\n",
*       list("STRING", 1987));
* PRINTF("this is a vector [%8.5lvf]\\n", list(vector(1,2,3)));
* IritState("DumpLevel", 9);
* PRINTF("this is a object %8.6lDf...\\n", list(axes));
* PRINTF("this is a object %10.8lDg...\\n", list(axes));
@\end{verbatim}

 This implementation of PRINTF is somewhat different than the C programming
 language's version, because the backslash {\em always} escapes the next
 character during the processing stage of IRIT's parser. That is, the string

@\begin{verbatim}
*        '\\tThis is the char \"\\%\"\\n'
@\end{verbatim}

 is actually parsed by the IRIT's parser into

@\begin{verbatim}
*        '\tThis is the char "\%"\n'
@\end{verbatim}

 because this is the way the IRIT parser processes strings. The latter
 string is the one that PRINTF actually sees.

 See also PRINTFILE for ways to redirect PRINTF to a file..
$

@\subsubsection{PRINTFILE}
!PRINTFILE

@\begin{verbatim}
 PRINTFILE( StringType FileName );
@\end{verbatim}

 Sets the file PRINTF prints to to FileName.  Any newer call to
 PRINTFILE will close the current file used so far.  If FileName is
 an empty string, PRINTF will print to stdout.
$

@\subsubsection{PROCEDURE}
!PROCEDURE

@\begin{verbatim}
 ProcName = PROCEDURE(Prm1, Prm2, ... , PrmN):LclVal1:LclVar2: ... :LclVarM:
     ProcBody;
@\end{verbatim}

 A procedure is a function that does not return a value, and therefore the
 returned variable (see FUNCTION) should not be used. A procedure is
 identical to a function in every other way. See FUNCTION for more.
$

@\subsubsection{RESET}
!RESET

@\begin{verbatim}
 RESET()
@\end{verbatim}

   clears all variables and initializes the environment to the starting state.
 User defined functions, however, are kept intact.
$

@\subsubsection{RMATTR}
!RMATTR

@\begin{verbatim}
 RMATTR( AnyType Object, StringType Name )
@\end{verbatim}

   removes attribute named {\bf Name} from object {\bf Object}. This function
 will have no affect on the {\bf Object} if the {\bf Object} has no attribute named
 {\bf Name}.

 See also ATTRIB, ATTRPROP, GETATTR, CPATTR.
$

@\subsubsection{SAVE}
!SAVE

@\begin{verbatim}
 SAVE( StringType FileName, AnyType Object )
@\end{verbatim}

   saves the provided {\bf Object} in the specified file name {\bf FileName}.
 No extension type is needed (ignored if specified), and ".itd" is supplied
 by default. The {\bf Object} can be any object type, including list, in which
 the structure is saved recursively. See also LOAD. If a display device is
 actively running at the time SAVE is invoked, its transformation matrix
 will be saved with the same name but with extension type of ".imd" instead
 of ".itd".

   This command can also be used to save binary files. ASCII regular data
 files usually take longer to load than binary files due to  
 the required parsing. Binary data files can be loaded directly like ASCII
 files in {\em IRIT}, but must be inspected through {\em IRIT} tools such
 as dat2irit. A binary data file must have a ".ibd" (IRIT Binary Data) type in
 its name.

   Files will be saved compressed if the given file name has a postfix of 
 ".Z" or ".gz". The gnu "gzip" utility will be invoked via a pipe for that
 purpose.

   Example:

@\begin{verbatim}
 SAVE( "Obj1.ibd.Z", Obj1 );
@\end{verbatim}

 Saves Obj1 in the file Obj1.ibd.Z as compressed binary file.
$

@\subsubsection{SETNAME}
!SETNAME

@\begin{verbatim}
 SETNAME( ListType ListObj, NumericType Index, StringType NewName )
@\end{verbatim}

   sets the name of a sub object of index {\bf Index} in list object
 {\bf ListObj} to a new name {\bf NewName}.  The index of the first element is
 zero.

 Example:

@\begin{verbatim}
    A = list( 1, 2, 3 );
    SETNAME( A, 0, "First" );
@\end{verbatim}

 sets the name of the first element in object {\bf A} to {\bf "First"}.

 While it is not a good idea to modify names of objects in the top level
 global space, one can use this function to do exactly that.  To rename
 the object "Axes" to "XYZ", do:

@\begin{verbatim}
    SETNAME( list( Axes ), 0, "XYZ" );
@\end{verbatim}

 See also GETNAME.
$

@\subsubsection{SNOC}
!SNOC

@\begin{verbatim}
 SNOC( AnyType Object, ListType ListObject )
@\end{verbatim}

   This is similar to the lisp cons operator but puts the new {\bf Object} in
 the {\em end} of the list {\bf ListObject} instead of at the beginning.

 Example:

@\begin{verbatim}
    Lst = list( axes );
    SNOC( Srf, Lst );
@\end{verbatim}

 and now {\bf Lst} is equal to the list 'list( axes, Srf )'.
$

@\subsubsection{SYSTEM}
!SYSTEM

@\begin{verbatim}
 SYSTEM( StringType Command )
@\end{verbatim}

   executes a system command {\bf Command}. For example,

@\begin{verbatim}
    SYSTEM( "ls -l" );
@\end{verbatim}
$

@\subsubsection{TIME}
!TIME

@\begin{verbatim}
 TIME( NumericType Reset )
@\end{verbatim}

   returns the time in seconds from the last time TIME was called with
 {\bf Reset} TRUE. This time is CPU time if such support is available
 from the system (times function), and otherwise, is real time (time
 function).
   The time is automatically reset at the beginning of the execution of this
 program.

 Example:

@\begin{verbatim}
    Dummy = TIME( TRUE );
      .
      .
      .
    TIME( FALSE );
@\end{verbatim}

 prints the time in seconds between the above two time function calls.
$

@\subsubsection{VARLIST}
!VARLIST

@\begin{verbatim}
 VARLIST()
@\end{verbatim}

   lists all the currently defined objects in the system.
$

@\subsubsection{VECTOR}
!VECTOR

@\begin{verbatim}
 VectorType VECTOR( NumericType X, NumericType Y, NumericType Z )
@\end{verbatim}

   sreates a vector type object, using the three provided NumericType scalars.
   See also PLANE, POINT.
$

@\subsubsection{VIEW}
!VIEW

@\begin{verbatim}
 VIEW( GeometricTreeType Object, NumericType ClearWindow )
@\end{verbatim}

   displays the (geometric) object(s) as given in {\bf Object}.

   If {\bf ClearWindow} is non zero (see TRUE/FALSE and ON/OFF), the window is
 first cleared (before drawing the objects).

 Example:

@\begin{verbatim}
    VIEW( Axes, FALSE );
@\end{verbatim}

 displays the predefined object {\bf Axes} in the viewing window on top of
 what is drawn already.

 In version 4.0, this function is emulated (see {\bf iritinit.irt}) using the
 VIEWOBJ function. In order to use the current viewing matrix, VIEW\_MAT
 should be provided as an additional parameter. For example,

@\begin{verbatim}
    VIEW( list( view_mat, Obj ), TRUE );
@\end{verbatim}

 However, since VIEW is a user defined function, the following will not
 use VIEW\_MAT as one would expect:

@\begin{verbatim}
    VIEW( view_mat, TRUE );
@\end{verbatim}

 because VIEW\_MAT will be renamed inside the VIEW user defined function to
 a local (to the user defined function) variable.

 In {\bf iritinit.irt} one can find several other useful VIEW related functions:
# 15 2 0 1
 VIEWCLEAR
  Clears all data displayed on the display device.
 VIEWREMOVE
  Removes the object specified by name from display.
 VIEWDISC
  Disconnects from display device (which is still running)
 
  while allowing IRIT to connect to a new device.
 VIEWEXIT
  Forces the display device to exit.
 VIEWSAVE
  Requests the display device to save transformation matrix.
 BEEP
  An emulation of the BEEP command of versions prior to 4.0.
 VIEWSTATE
  Allows change to the state of the display device.
#

   For the above VIEW related functions, only VIEWREMOVE, VIEWSAVE, and
 VIEWSTATE require parameters, which are the file name and view state,
 respectively. The view state can be one of several commands. See the
 display device section for more.

 Examples:

@\begin{verbatim}
    VIEWCLEAR();
    VIEW( axes, off );
    VIEWSTATE( "LngrVecs" );
    VIEWSTATE( "DrawStyle" );
    VIEWSAVE( "matrix1" );
    VIEWREMOVE( "axes" );
    VIEWDISC();
@\end{verbatim}
$

@\subsubsection{VIEWOBJ}
!VIEWOBJ

@\begin{verbatim}
 VIEWOBJ( GeometricTreeType Object )
@\end{verbatim}

   displays the (geometric) object(s) as given in {\bf Object}.
 {\bf Object} may be any GeometricType or a list of other
 GeometricTypes nested to an arbitrary level.

   Unlike {\em IRIT} versions prior to 4.0, VIEW\_MAT is not explicitly used
 as the transformation matrix. In order to display with a VIEW\_MAT view,
 VIEW\_MAT should be listed as an argument (in that exact name) to
 VIEWOBJ. The same is true for the perspective matrix PRSP\_MAT.

 Example:

@\begin{verbatim}
    VIEWOBJ( list( view_mat, Axes ) );
@\end{verbatim}

 displays the predefined object {\bf Axes} in the viewing window using the
 viewing matrix VIEW\_MAT.
$

@\subsubsection{VIEWSET}
!VIEWSET

@\begin{verbatim}
 VIEWSET( NumericType DispHandle )
@\end{verbatim}

   sets the current display device to be {\bf DispHandle}. {\bf DispHandle} is
 returned by the CLNTEXEC command.  The use of the reserved constant of
 CLIENTS\_ALL would broadcast the viewing commands to all objects.

 Example:

@\begin{verbatim}
    h1 = clntexec( DispDeviceName );
    h2 = clntexec( DispDeviceName );

    clntwrite( h1, sphere( vector( 0, 0, 0 ), 1 ) );
    clntwrite( h2, axes );

    pause();

    VIEWSET( h1 );
    viewclear();
    viewobj( list( sphere( vector( 0, 0, 0 ), 1 ), axes ) );

    VIEWSET( h2 );
    viewclear();
    viewobj( list( sphere( vector( 0, 0, 0 ), 1 ), axes ) );

    pause();

    VIEWSET( CLIENTS_ALL );

    viewobj( axes );

    pause();

    viewexit();
@\end{verbatim}

 opens two display devices, and displays a unit sphere to the first, and the
 axes object, to the second.  After a pause, displays both objects on both
 display devices, then pauses and exits from both.

 See also VIEWOBJ, CLNTEXEC, CLNTCLOSE, CLNTREAD, CLNTWRITE.
$

@\subsubsection{WHILE}
!WHILE

@\begin{verbatim}
 WHILE( NumericType Cond, AnyType Body )
@\end{verbatim}

   executes the {\bf Body} (see below), while the WHILE loop condition
 {\bf Cond} is evaluated into a non zero value. {\bf Cond} is 
 evaluated before each iteration.

   The body may consist of any number of regular commands, separated by
 COLONs, including nesting loops to an arbitrary level.

 Example:

@\begin{verbatim}
 deg = 0;
 rotstepx = rotx( 10 );
 WHILE ( deg < 360,
     deg = deg + 10:
     view_mat = rotstepx * view_mat:
     view( list( view_mat, axes ), ON )
 );
@\end{verbatim}

 displays axes with a view direction that is rotated 10 degrees at a
 time around the X axis.
$


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{System variables}
!System variables
$

 System variables are predefined objects in the system. Any time {\em IRIT} is
 executed, these variable are automatically defined and set to values which
 are sometimes machine dependent. These are {\em regular} objects in any other
 sense, including the ability to be deleted or overwritten. One can modify,
 delete, or introduce other objects using the {\bf iritinit.irt} file.

@\subsubsection{AXES}
!AXES
   Predefined polyline object (PolylineType) that describes the $XYZ$ axes.
$

@\subsubsection{DRAWCTLPT}
!DRAWCTLPT
   Predefined Boolean variable (NumericType) that controls whether curves'
 control polygons and surfaces' control meshes are drawn (TRUE) or not
 (FALSE). Default is FALSE.
$

@\subsubsection{FLAT4PLY}
!FLAT4PLY
   Predefined Boolean object (NumericType) that controls the way almost flat
 surface patches are converted to polygons: four polygons (TRUE) or only
 two polygons (FALSE). Default value is FALSE.
$

@\subsubsection{MACHINE}
!MACHINE
   Predefined numeric object (NumericType) holding the machine type as one of
 the following constants: MSDOS, SGI, HP, SUN, APOLLO, UNIX, IBMOS2, IBMNT,
 and AMIGA.
$

@\subsubsection{POLY\_APPROX\_OPT}
!POLY_APPROX_OPT
   A variable controlling the algorithm to tesselate surfaces into polygons.
 If FALSE, that is, uniform, in parametric space, sampling is used.  If TRUE,
 maximal deviation between the polygonal approximation and the surface is
 used, with distance as prescribed by POLY\_APPROX\_TOL.
$

@\subsubsection{POLY\_APPROX\_UV}
!POLY_APPROX_UV
   A Boolean predefined variable. If TRUE, UV values of surface polygonal
 approximation are placed on the attribute lists of vertices.
$

@\subsubsection{POLY\_APPROX\_TOL}
!POLY_APPROX_TOL
   A numeric predefined tesselation control on the distance between the surface
 and its polygonal approximation in POLY\_APPROX\_OPT settings.
$

@\subsubsection{POLY\_APPROX\_TRI}
!POLY_APPROX_TRI
   A numeric predefined tesselation control.  If TRUE, only triangles are
 generated in surface tesselations.
$

@\subsubsection{POLY\_MERGE\_COPLANAR}
!POLY_MERGE_COPLANAR
   A numeric predefined surface tesselation control.  If TRUE, coplanar
 adjacent polygons are merged into one.
$

@\subsubsection{PRSP\_MAT}
!PRSP_MAT
   Predefined matrix object (MatrixType) to hold the perspective matrix
 used/set by VIEW and/or INTERACT commands. See also VIEW\_MAT.
$

@\subsubsection{RESOLUTION}
!RESOLUTION
   Predefined numeric object (NumericType) that sets the accuracy of the
 polygonal primitive geometric objects and the approximation of curves and
 surfaces. It holds the number of divisions into which a circle is divided
 (with minimum value of 4). If, for example, RESOLUTION is set to 6, then a
 generated CONE will effectively be a six-sided pyramid.
   It also controls the fineness of freeform curves and surfaces when they are
 approximated as piecewise linear polylines, and the fineness of freeform
 surfaces when they are approximated as polygons.
$

@\subsubsection{VIEW\_MAT}
!VIEW_MAT
   Predefined matrix object (MatrixType) to hold the viewing matrix used/set
 by VIEW and/or INTERACT commands. See also PRSP\_MAT.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{System constants}
!System constants

 The following constants are used by the various functions of the system to
 signal certain conditions. Internally, they are represented numerically,
 although, in general, their exact value is unimportant and may be changed
 in future versions. In the rare circumstance that you need to know their
 values, simply type the constant as an expression.

 Example:

@\begin{verbatim}
    MAGENTA;
@\end{verbatim}

$

@\subsubsection{AMIGA}
!AMIGA
 A constant designating an AMIGA system, in the MACHINE variable.
$

@\subsubsection{APOLLO}
!APOLLO
 A constant designating an APOLLO system, in the MACHINE variable.
$

@\subsubsection{BEZIER\_TYPE}
!BEZIER_TYPE
 A constant defining a Bezier freeform geometry.
$

@\subsubsection{BLACK}
!BLACK
 A constant defining a BLACK color.
$

@\subsubsection{BLUE}
!BLUE
 A constant defining a BLUE color.
$

@\subsubsection{BSPLINE\_TYPE}
!BSPLINE_TYPE
 A constant defining a B-spline freeform geometry.
$

@\subsubsection{CLIENTS\_ALL}
!CLIENTS_ALL
 A constant defining a request to address (broadcast to) all clients.
$

@\subsubsection{COL}
!COL
 A constant defining the COLumn or U direction of a surface or a
 trivariate mesh.
$

@\subsubsection{CTLPT\_TYPE}
!CTLPT_TYPE
 A constant defining an object of type control point.
$

@\subsubsection{CURVE\_TYPE}
!CURVE_TYPE
 A constant defining an object of type curve.
$

@\subsubsection{CYAN}
!CYAN
 A constant defining a CYAN color.
$

@\subsubsection{DEPTH}
!DEPTH
  A constant defining the DEPTH direction of a trivariate mesh.
 See TBEZIER, TBSPLINE.
$

@\subsubsection{E1}
!E1
 A constant defining an E1 (X only coordinate) control point type.
$

@\subsubsection{E2}
!E2
 A constant defining an E2 (X and Y coordinates) control point type.
$

@\subsubsection{E3}
!E3
 A constant defining an E3 (X, Y and Z coordinates) control point type.
$

@\subsubsection{E4}
!E4
 A constant defining an E4 control point type.
$

@\subsubsection{E5}
!E5
 A constant defining an E5 control point type.
$

@\subsubsection{E6}
!E6
 A constant defining an E6 control point type.
$

@\subsubsection{E7}
!E7
 A constant defining an E7 control point type.
$

@\subsubsection{E8}
!E8
 A constant defining an E8 control point type.
$

@\subsubsection{E9}
!E9
 A constant defining an E9 control point type.
$

@\subsubsection{FALSE}
!FALSE
 A zero constant. May be used as a Boolean operand.
$

@\subsubsection{GEOM\_CONST}
!GEOM_CONST
 Designates a constant shape.

@\subsubsection{GEOM\_LINEAR}
!GEOM_LINEAR
 Designates a shape of a (piecewise) linear curve.

@\subsubsection{GEOM\_CIRCULAR}
!GEOM_CIRCULAR
 Designates a shape of a circle/arc.

@\subsubsection{GEOM\_PLANAR}
!GEOM_PLANAR
 Designates a planar shape.

@\subsubsection{GEOM\_SPHERICAL}
!GEOM_SPHERICAL
 Designates a spherical shape.

@\subsubsection{GEOM\_SRF\_OF\_REV}
!GEOM_SRF_OF_REV
 Designates a shape that is (a portion of) a surface of revolution..

@\subsubsection{GEOM\_EXTRUSION}
!GEOM_EXTRUSION
 Designates a shape that is an extrusion surface.

@\subsubsection{GEOM\_RULED\_SRF}
!GEOM_RULED_SRF
 Designates a shape that is a ruled surface.

@\subsubsection{GEOM\_DEVELOP\_SRF}
!GEOM_DEVELOP_SRF
 Designates a shape that is a ruled surface.

@\subsubsection{GEOM\_SWEEP}
!GEOM_SWEEP
 Designates a shape that is a sweep surface.

@\subsubsection{GREEN}
!GREEN
 A constant defining a GREEN color.
$

@\subsubsection{HP}
!HP
 A constant designating an HP system, in the MACHINE variable.
$

@\subsubsection{IBMOS2}
!IBMOS
 A constant designating an IBM system running under OS2, in the MACHINE
 variable.
$

@\subsubsection{IBMNT}
!IBMNT
 A constant designating an IBM system running under Windows NT, in the MACHINE
 variable.
$

@\subsubsection{KV\_DISC\_OPEN}
!KV_DISC_OPEN
 A constant defining an open end condition with a discontinuous uniformly
 spaced knot vector.  That is, all interior knots are of multiplicity order -1
 and are equally spaced.
$

@\subsubsection{KV\_FLOAT}
!KV_FLOAT
 A constant defining a floating end condition uniformly spaced knot vector.
$

@\subsubsection{KV\_OPEN}
!KV_OPEN
 A constant defining an open end condition uniformly spaced knot vector.
$

@\subsubsection{KV\_PERIODIC}
!KV_PERIODIC
 A constant defining a periodic end condition with a uniformly spaced knot
 vector.
$

@\subsubsection{LIST\_TYPE}
!LIST_TYPE
 A constant defining an object of type list.
$

@\subsubsection{MAGENTA}
!MAGENTA
 A constant defining a MAGENTA color.
$

@\subsubsection{MATRIX\_TYPE}
!MATRIX_TYPE
 A constant defining an object of type matrix.
$

@\subsubsection{MSDOS}
!MSDOS
 A constant designating an MSDOS system, in the MACHINE variable.
$

@\subsubsection{MULTIVAR\_TYPE}
!MULTIVAR_TYPE
 A constant defining an object of type multivariate function.
$

@\subsubsection{NUMERIC\_TYPE}
!NUMERIC_TYPE
 A constant defining an object of type numeric.
$

@\subsubsection{OFF}
!OFF
 Synonym for FALSE.
$

@\subsubsection{ON}
!ON
 Synonym for TRUE.
$

@\subsubsection{P1}
!P2
 A constant defining a P1 (W and WX coordinates, in that order) rational
 control point type.
$

@\subsubsection{P2}
!P2
 A constant defining a P2 (W, WX, and WY coordinates, in that order) rational
 control point type.
$

@\subsubsection{P3}
!P3
 A constant defining a P3 (W, WX, WY, and WZ coordinates, in that order)
 rational control point type.
$

@\subsubsection{P4}
!P4
 A constant defining a P4 rational control
 point type.
$

@\subsubsection{P5}
!P5
 A constant defining a P5 rational control
 point type.
$

@\subsubsection{P6}
!P6
 A constant defining a P6 rational control
 point type.
$

@\subsubsection{P7}
!P7
 A constant defining a P7 rational control
 point type.
$

@\subsubsection{P8}
!P8
 A constant defining a P8 rational control
 point type.
$

@\subsubsection{P9}
!P9
 A constant defining a P9 rational control
 point type.
$

@\subsubsection{PARAM\_CENTRIP}
!PARAM_CENTRIP
 A constant defining a centripetal length parametrization.
$

@\subsubsection{PARAM\_CHORD}
!PARAM_CHORD
 A constant defining a chord length parametrization.
$

@\subsubsection{PARAM\_NIELFOL}
!PARAM_NIELFOL
 A constant defining a Neilson-Foley parametrization.
$

@\subsubsection{PARAM\_UNIFORM}
!PARAM_UNIFORM
 A constant defining an uniform parametrization.
$

@\subsubsection{PI}
!PI
 The constant of 3.141592...
$

@\subsubsection{PLANE\_TYPE}
!PLANE_TYPE
 A constant defining an object of type plane.
$

@\subsubsection{POINT\_TYPE}
!POINT_TYPE
 A constant defining an object of type point.
$

@\subsubsection{POLY\_TYPE}
!POLY_TYPE
 A constant defining an object of type poly.
$

@\subsubsection{POWER\_TYPE}
!POWER_TYPE
 A constant defining a power basis freeform geometry.
$

@\subsubsection{RED}
!RED
 A constant defining a RED color.
$

@\subsubsection{ROW}
!ROW
  A constant defining the ROW or V direction of a surface or a trivariate mesh.
$

@\subsubsection{SGI}
!SGI
 A constant designating an SGI system, in the MACHINE variable.
$

@\subsubsection{STRING\_TYPE}
!STRING_TYPE
 A constant defining an object of type string.
$

@\subsubsection{SURFACE\_TYPE}
!SURFACE_TYPE
 A constant defining an object of type surface.
$

@\subsubsection{SUN}
!SUN
 A constant designating a SUN system, in the MACHINE variable.
$

@\subsubsection{TRIMSRF\_TYPE}
!TRIMSRF_TYPE
 A constant defining an object of type trimmed surface.
$

@\subsubsection{TRISRF\_TYPE}
!TRIMSRF_TYPE
 A constant defining an object of type triangular surface.
$

@\subsubsection{TRIVAR\_TYPE}
!TRIVAR_TYPE
 A constant defining an object of type trivariate function.
$

@\subsubsection{TRUE}
!TRUE
 A non zero constant. May be used as a Boolean operand.
$

@\subsubsection{UNDEF\_TYPE}
!UNDEF_TYPE
 A constant defining an object of no type (yet).
$

@\subsubsection{UNIX}
!UNIX
 A constant designating a generic UNIX system, in the MACHINE variable.
$

@\subsubsection{VECTOR\_TYPE}
!VECTOR_TYPE
 A constant defining an object of type vector.
$

@\subsubsection{WHITE}
!WHITE
 A constant defining a WHITE color.
$

@\subsubsection{YELLOW}
!YELLOW
 A constant defining a YELLOW color.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Animation}
@\label{sec-animation}
!Animation

 The animation tool adds the capability of animating objects using
 forward kinematics, exploiting animation curves.  Each object has
 different attributes, that prescribe its motion, scale, and visibility
 as a function of time. Every attribute has a name, which designates
 its role. For instance, an attribute animation curve named MOV\_X
 describes a translation motion along the X axis.

@\subsection{How to create animation curves in IRIT}
&How to create animation curves in IRIT

 Let OBJ be an object in IRIT which we want to animate.

 Animation curves are either scalar (E1/P1) curves or three-dimensional
 (E3/P3) curves with one of the following name prefixes:
# 30 2 1 1
  MOV\_X, MOV\_Y, MOV\_Z
   Translation along one axis
  MOV\_XYZ
   Arbitrary translation along all three axes
  ROT\_X, ROT\_Y, ROT\_Z
   Rotating around a single axis (degrees)
  SCL\_X, SCL\_Y, SCL\_Z
   Scale along a single axis
  SCL
   Global scale
  VISIBLE
   Visibility
#

 The visibility curve is a scalar curve that enables the display of
 the object if the visibility curve is positive at time t and disables
 the display (hides) the object if the visibility curve is negative at
 time t.  A positive visibility value between zero and one also hints at
 the opacity of the object, if supported; one means fully opaque.

 The animation curves are all attached as an attribute named "animation"
 to the object OBJ.

 Example:
@\begin{verbatim}
    mov_x = cbezier( list( ctlpt( E1, 0.0 ),
                           ctlpt( E1, 1.0 ) ) );
    scl   = cbezier( list( ctlpt( E1, 1.0 ),
                           ctlpt( E1, 0.1 ) ) );
    rot_y = cbezier( list( ctlpt( E1, 0.0 ),
                           ctlpt( E1, 0.0 ) );
                           ctlpt( E1, 360.0 ) ) );
    attrib(OBJ, "animation", list( mov_x, scl, rot_y ) );
@\end{verbatim}

 The above will animate OBJ between time zero and one (Bezier curves are always
 between zero and one), by moving it a unit size in the X direction,
 scaling it to %10 of its original size and rotating it at increasing
 angular speed from zero to 360 degrees.

 OBJ can now be saved into a file or displayed via one of the regular
 viewing commands in IRIT (i.e. VIEWOBJ).

 Animation is not always between zero and one. To that end, one can
 apply the CREPARAM function to modify the parametric domain of the
 animation curve. The convention is that if the time is below the
 starting value of the parametric domain, the starting value of the
 curve is used.  Similarly, if the time is beyond the end of the
 parameter domain of the animation curve, the end value of the
 animation curve is used.

 Example:
@\begin{verbatim}
    CREPARAM( mov_x, 3.0, 5.0 );
@\end{verbatim}

 to set the time of the motion in the x axis to be from $t = 3$ to
 $t = 5$.  For $t < 3$, use mov\_x(3), and for $t > 5$, use mov\_x(5).
 

 The animation curves are regular objects in the IRIT system. Hence,
 only one object named mov\_x or scl can exist at one time. If you
 create a new object named mov\_x, the old one is overwritten! To
 preserve old animation curves you can detach the old ones by executing
 'free(mov\_x)' which will remove the object named mov\_x from IRIT's object
 list but not from its previously used locations within other list
 objects, if any.  A different way to do this is to call the animation curves
 mov\_x1, mov\_x2 etc. as only the prefix of the name is verified.

 For example:

@\begin{verbatim}
    mov_x = cbezier( list( ctlpt( E1, 0.0 ),
                           ctlpt( E1, 1.0 ) ) );
    attrib(obj1, "animation", list( mov_x ) );
    free(mov_x);

    mov_x1 = cbezier( list( ctlpt( E1, 2.0 ),
                            ctlpt( E1, 3.0 ) ) );
    mov_x2 = cbezier( list( ctlpt( E1, 2.0 ),
                            ctlpt( E1, 3.0 ) ) );
    attrib(obj2, "animation", list( mov_x1, mov_x2 ) );
    free(mov_x);
@\end{verbatim}

 Notice the way we have two animation curves translating {\bf obj2} in x.
 This is somewhat artificial but makes more sense if other
 transformations appear in between.

 One can evaluate an object with animation curves at a certain time, only
 to find the proper expected transformation matrix at that time on the
 object as an "animation\_mat" attribute.  The following example defines
 a user defined {\bf TransformAnim} function that creates a transformed
 object out of object that was evaluated with ANIMEVAL.  Then, a simple loop
 (slowly) animates the scene...

@\begin{verbatim}
 TransformAnim = function( Obj ):
    return = 0;
 TransformAnim = function( Obj ): m: i:
    if ( thisobj( "Obj" ) == list_type,
        return = nil():
        for ( i = 1, 1, sizeof( Obj ),
            snoc( TransformAnim( nth( Obj, i ) ), return ) ),
        return = Obj * tx( 0 ) ):
    m = getattr( Obj, "animation_mat" ):
    if ( thisobj( "m" ) == matrix_type,
        return = return * m );

 for ( t = 0, 0.1, 1,
     ANIMEVAL( t, Object ):
     view( TransformAnim( Object ), 1 ) );
@\end{verbatim}

@\subsection{A more complete animation example}
&A more complete animation example

@\begin{verbatim}
  a = box( vector( 0, 0, 0 ), 1, 1, 1 );
  b = box( vector( 0, 0, 0 ), 1, 1, 1 );
  c = box( vector( 0, 0, 0 ), 1, 1, 1 );
  d = sphere( vector( 0, 0, 0), 0.7 );
  
  pt0   =  ctlpt( e1,  0.0 );
  pt1   =  ctlpt( e1,  1.0 );
  pt2   =  ctlpt( e1,  2.0 );
  pt6   =  ctlpt( e1,  6.0 );
  pt360 =  ctlpt( e1,  360.0 );
  
  pt10 = ctlpt( e1, -4.0 );
  pt11 = ctlpt( e1,  1.0 );
  pt12 = ctlpt( e1,  4.0 );
  pt13 = ctlpt( e1, -1.0 );
  
  visible = creparam( cbezier( list( pt10,  pt11 ) ), 0.0, 5.0 );
  mov_x   = creparam( cbezier( list( pt0, pt6, pt2 ) ), 0.0, 1.2 );
  mov_y   = mov_x;
  mov_z   = mov_x;
  rot_x   = creparam( cbspline( 2,
                                list( pt0, pt360, pt0 ),
                                list( KV_OPEN ) ),
                      1.2, 2.5 ); 
  rot_y   = rot_x;
  rot_z   = rot_x;
  scl     = creparam( cbezier( list( pt1, pt2, pt1, pt2, pt1 ) ),
                      2.5, 4.0 );
  scl_x   = scl;
  scl_y   = scl;
  scl_z   = scl;
  mov_xyz = creparam( circle( vector( 0, 0, 0 ), 2.0 ), 4.0, 5.0 );
  
  attrib( d, "animation", list( mov_xyz, visible ) );
  free( visible );
  
  visible = creparam( cbezier( list( pt12,  pt13 ) ), 0.0, 5.0 );
  
  attrib( a, "animation", list( rot_x, mov_x, scl, scl_x, visible ) );
  attrib( b, "animation", list( rot_y, mov_y, scl, scl_y, visible ) );
  attrib( c, "animation", list( rot_z, mov_z, scl, scl_z, visible ) );
  
  color( a, red );
  color( b, green );
  color( c, blue );
  color( d, cyan );
  
  demo = list( a, b, c, d );
  
  interact( demo );
  viewanim( 0, 5, 0.01 );
@\end{verbatim}

 In this example, we create four objects, three cubes and one sphere.
 Animation curves to translate the three cubes along the three axes for
 time period of t = 0 to t = 1.2 are created. Rotation curves to
 rotate the three cubes along the three axes are then created for time
 period t = 1.2 to t = 2.5. Finally, for time period t = 2.5
 to t = 4.0. the cubes are (not only) unifomly scaled. For time
 period t = 4 to t = 5, the cubes become invisible and the sphere,
 which becomes visible, is rotated along a circle of radius 2.

@\subsection{Another complete animation example}
&Another complete animation example

  This example demonstrates the ability to put "animation" attributes
 on internal nodes of a hierarchy, thereb, affecting the entire set of objects
 in the hierachy.   Herein, we present an robotic arm with three edges
 and two joints.

@\begin{verbatim}
    BoxLength = 2;
    BoxWidth = 2;
    BoxHeight = 10;
    
    LowerBox = box( vector( -BoxLength / 2, -BoxWidth / 2, 0 ),
                    BoxLength, BoxWidth, BoxHeight);
    MiddleBox = box( vector( -BoxLength / 2, -BoxWidth / 2, 0 ),
                     BoxLength, BoxWidth, BoxHeight);
    UpperBox = box( vector( -BoxLength / 2, -BoxWidth / 2, 0 ),
                    BoxLength, BoxWidth, BoxHeight);
    Cn1 = cone( vector( 0, 0, 0 ), vector( 0, BoxHeight / 3, 0 ), 1 );
    
    color( LowerBox, magenta );
    color( MiddleBox, yellow );
    color( UpperBox, cyan );
    color( Cn1, green );
    
    rot_x1 = creparam( cbspline( 3,
                                 list( ctlpt( E1,  0 ),
                                       ctlpt( E1,  -200 ),
                                       ctlpt( E1,  200 ),
                                              ctlpt( E1,  0 ) ),
                                 list( KV_OPEN ) ),
                       0, 3 );
    rot_x2 = creparam( cbspline( 4,
                                 list( ctlpt( E1,  0 ),
                                       ctlpt( E1,  400 ),
                                       ctlpt( E1,  -400 ),
                                              ctlpt( E1,  0 ) ),
                                 list( KV_OPEN ) ),
                       0, 3 );
    rot_y = creparam( cbspline( 2,
                                list( ctlpt( E1,  0 ),
                                      ctlpt( E1,  100 ),
                                      ctlpt( E1, -100 ),
                                      ctlpt( E1,  0 ) ),
                                list( KV_OPEN ) ),
                      0, 3 );
    rot_z = creparam( cbspline( 2,
                                list( ctlpt( E1,  0 ),
                                      ctlpt( E1,  1440 ) ),
                                list( KV_OPEN ) ),
                      0, 3 );
    Translate = trans( vector( 0, 0, BoxHeight ) );
    
    attrib( Cn1, "animation", list( rot_z, Translate ) );
    
    Upr = list( Cn1, UpperBox );
    attrib( Upr, "animation", list( rot_y, Translate ) );
    
    Mid = list( Upr, MiddleBox );
    attrib( Mid, "animation", list( rot_x2, Translate ) );
    
    rbt_hand = list( Mid, LowerBox );
    attrib( rbt_hand, "animation", list( rot_x1 ) );
    
    view( rbt_hand, 1 );
@\end{verbatim}

 In this example, we create four objects, three cubes and one cone,
 simulating a robotic hand with three edges an a gripper (the cone).
 The animation is defined hierarchically, making it very easy to model
 the robot.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Display devices}
!Display devices

 The following display device drivers are available,
# 22 3 0 1
 Device Name
  Invocation
   Environment
 
 
 
 xgldrvs
  xgldrvs -s-
   SGI 4D GL regular driver.
 xogldrvs
  xogldrvs -s-
   SGI 4D Open GL/Motif driver.
 xgladap
  xgladap -s-
   SGI 4D GL adaptive isocurve
 
 
   experimental driver.
 x11drvs
  x11drvs -s-
   X11 driver.
 xmtdrvs
  xmtdrvs -s-
   X11 Motif driver.
 xglmdrvs
  xglmdrvs -s-
   SGI 4D GL and X11/Motif driver.
 wntdrvs
  wntdrvs -s-
   IBM PC Windows NT driver.
 wntgdrvs
  wntgdrvs -s-
   IBM PC Windows NT Open GL driver.
 wntgaiso
  wntgaiso -s-
   IBM PC OGL Adap. Iso. driver.
 os2drvs
  os2drvs -s-
   IBM PC OS2 2.x/3.x driver.
 amidrvs
  amidrvs -s-
   AmigaDOS 2.04+ driver.
 nuldrvs
  nuldrvs -s- [-d] [-D]
   A device to print the
 
 
   object stream to stdout.
#

 All display devices are clients communicating with the ({\em IRIT}) server 
 using IPC (inter process communication). On Unix and Windows NT, sockets are
 used. A Windows NT client can talk to a server ({\em IRIT}) on a Unix host if
 hooked to the same network. On OS2 pipes are used, and both the client and
 server must run on the same machine. On AmigaDOS exec messages are used,
 and both the client and server must run on the same machine.

   While all display devices support object(s) transformations via a
 transformation control window, many of the display devices allow one
 to click and drag on the viewing window to rotate (Left Button) and
 to translate (Right Button).  This mode exploits the mouse's two degrees of
 freedom to provide intuitive dual axis rotation and
 translation.  Most display devices supports two levels of fineness.
 A rough display is used when in the middle of a transformation operation
 (i.e. the mouse button is down/dragged), while a fine object display is
 employed when the display is idle (mouse button is up). See also option
 '-E'.

   The ({\em IRIT}) server will automatically start a client display device
 if the IRIT\_DISPLAY environment variable is set to the name and options of
 the display device to run. For example:

@\begin{verbatim}
    setenv IRIT_DISPLAY xgldrvs -s-
@\end{verbatim}

   The display device must be in a directory that is in the 
 environment variable {\bf path}. Most display devices require the '-s-' flags
 to run in a non-standalone mode, or a client-server mode. Most drivers can
 also be used to display data in a standalone mode (i.e., no server).  For
 example:

@\begin{verbatim}
    xgldrvs -s solid1.itd irit.imd
@\end{verbatim}

    Effectively, all the display devices are also data display programs.
 Therefore, some functionality is not always as expected. For
 example, the Quit button will always force the display device to quit,
 even if popped up from {\em IRIT}, but will not cause {\em IRIT} to
 quit as might logically expected. In fact, the next time {\em IRIT} will
 try to communicate with the display device, it will find the broken
 connection and will start up a new display device.

    Most display devices recognize attributes found on objects. The following
 attributes are usually recognized (depending on the device capability):

@\begin{itemize}
@\item
  {\bf Color}: Selects the drawn color of the object to be one of the 8/16
        predefined colors in the {\em IRIT} system: white, red, green, blue,
        yellow, cyan, magenta, black.
@\item
  {\bf DWidth}: Sets the width in pixels of the drawn object, when drawn as
        a wireframe.
@\item
  {\bf Light\_source}: Mark a points object as a light source.  Such a marked
        object is not rendered but rather used toset a light source position.
        A light source object also honors "index" attribute that sets the
        light source number (between 0 and 9), and "type" which can be either
        "point\_infty" for a light source direction (light source at infinity)
        or "point\_pos" for a point light source.  See also "advanced usage"
        in the irender program.
@\item
  {\bf ReflectLns}: Allows the display of reflection lines off a freeform
        surface.  The "ReflectLns" attribute is a list object of two
        subobjects, a vector and a list of points.  The vector is the
        reflection lines' direction (all reflection lines are parallel)
        and the list of points is a list of points on the different
        reflection lines. For example,
@\begin{verbatim}
    attrib( S, "RflctLines",
            list( vector( 0, 0, 1 ),
                  list( point( -1.6, 2, 0 ),
                        point( -0.8, 2, 0 ),
                        point(  0.0, 2, 0 ),
                        point(  0.8, 2, 0 ),
                        point(  1.6, 2, 0 ) ) ) );        
@\end{verbatim}
        defines five reflection lines to be reflected off surface {\bf S},
        all in the direction of {\bf (0, 0, 1)} and on the plane Y = 2.
        See also RFLCTLN command.
@\item
  {\bf RGB}: Overwrites (if supported) the COLOR attribute (if given) and
        sets the color of the object to the exact prescribed RGB set.
@\item
  {\bf StrScale}, {\bf StrPos}, {\bf StrSpace}: Allows control over string
  drawing, controlling the scale of the string, its position, and the spacing
  between characters in the string.
@\end{itemize}

    All display devices recognize all the command line flags and all the
 configuration options in a configuration file, as described below. The display
 devices will attempt to honor the requests, to the best of their ability.
    For example, only gl and OpenGL devices can render shaded models, and so
 only they will honor all {\bf DrawStyle} configuration options.

@\subsection{Command Line Options}
&Command Line Options

@\begin{verbatim}
 ???drvs [-s] [-u] [-n] [-N] [-i] [-c] [-C] [-m] [-a] [-g "x1,x2,y1,y2"]
         [-G "x1,x2,y1,y2"] [-I #IsoLines] [-F PlgnOpti PlgnFineNess] [-R]
         [-f PllnOpti PllnFineNess] [-E RelLowRes] [-p] [-l LineWidth]
         [-r] [-A Shader] [-B] [-2] [-d] [-D] [-L NormalLen] [-4]
         [-k SketchType Sil Shd Imp] [-b "R,B,G (background)"]
         [-S "x,y,z,w{,a,d,s} (LgtSrcPosADS)"] [-e PickDist]
         [-O PickObjType] [-Z ZMin ZMax] [-M] [-W WireSetup] [-P] [-o]
         [-x ExecAnimCmd] [-X Min,Max,Dt,R{,flags}] [-w InitWidget] [-T]
         [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -s}: Runs the driver in a standalone mode. Otherwise, the driver will
        attempt to communicate with the {\em IRIT} server.
@\item
  {\bf -u}: Forces a unit matrix. That is, input data are {\em not}
        transformed at all.
@\item
  {\bf -n}: Draws normals of vertices.
@\item
  {\bf -N}: Draws normals of polygons.
@\item
  {\bf -i}: Draws internal edges (created by {\em IRIT}) - default is not to
        display them; this option will also force their display.
@\item
  {\bf -c}: Sets depth cueing on. Drawings that are closer to the viewer will
        be drawn in more intense color.
@\item
  {\bf -C}: Caches the piecewise linear geometry so curves and surface can
        be redisplayed faster. Purging it will free memory, on the other hand.
@\item
  {\bf -m}: Provides some more information on the parsed data file(s).
@\item
  {\bf -a}: Activate antialiased lines and shaded display.
@\item
  {\bf -g x1,x2,y1,y2}: Prescribes the position and location of the
        transformation window by prescribing the domain of the window in
        screen space pixels.
@\item
  {\bf -G x1,x2,y1,y2}: Prescribes the position and location of the
        viewing window by prescribing the domain of the window in
        screen space pixels.
@\item
  {\bf -I \#IsoLines}: Specifies the number of isolines per surface, per
        direction.
        A specification of zero isolines is possible only on the command line
        and it denotes the obvious.
@\item
  {\bf -F PolyOpti FineNess}: Controls the method used to approximate surfaces
        into polygons. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4.
@\item
  {\bf -R}:  Use optimized polygonal strips instead of lists of polygons, if
        possible.  This feasibility depends on the support of the underlying
        hardware/graphics libraries.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed dveiation tolerance of the piecewise linear
        approximation from the original curve. 
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -E RelLowRes}:  Sets the relative fineness of curves and surface
        while the input device is active, such as in a drag operation.
@\item
  {\bf -p}:  Sets the width of drawn points.
@\item
  {\bf -l LineWidth}: Sets the linewidth, in pixels. Default is one pixel wide.
@\item
  {\bf -r}: Activate solid Rendering mode. Draws object as shaded solid.
@\item
  {\bf -A Shader}: Shader can be one of 0 (None), 1 (Background), 2 (Flat),
        3 (Gouraud), or 4 (Phong).
@\item
  {\bf -B}: Back face culling of polygons.
@\item
  {\bf -2}: Double buffering. Prevents screen flicker at the possible cost of
        fewer colors.
@\item
  {\bf -d}: Debug objects. Prints to stderr all objects read from the
        communication port with the server {\em IRIT}. 
@\item
  {\bf -D}: Debug input. Prints to stderr all characters read from communcation
        port with the server {\em IRIT}. Lowest level of communication.
@\item
  {\bf -L NormalLen}: Sets the length of the drawn normals in thousandths of
        a unit.
@\item
  {\bf -4}: Forces four polygons per almost flat region in the surface to
        polygon conversion. Otherwise two polygons only.
@\item
  {\bf -k SketchType Sil Shd Imp}: Sets the strokes type (one of 1
        (isoparametric curves), 2 (lines of curvature), 3 (silhoutees)),
        and the silhouette and shader powers (between zero and one) and
        strokes improtance factor, in interactive line art strokes (See -W).
@\item
  {\bf -b BackGround}: Sets the background color as three RGB integers in the
        range of 0 to 255.
@\item
  {\bf -S x,y,z,w\{,a,d,s\} (LgtSrcPosADS)}: Sets the lighting by setting the
        light source position as well as the optional Ambient, Diffuse, and
        Specular intensities.
@\item
  {\bf -e PickDist}: Sets the distance to the near and far Z clipping planes.
@\item
  {\bf -O PickObjType}: A binary mask that controls which object can be
        picked:
        bit 0 - not used, bit 1 - poly, bit 2 - numeric,
        bit 3 - point, bit 4 - vector, bit 5 - Plane, bit 6 - matrix,
        bit 7 - curve, bit 8 - surface, bit 9 - string, bit 10 - list object,
        bit 11 - ctl pt, bit 12 - trimmed srf, bit 13 - trivariate,
        bit 14 - instance, bit 15 - triangular srf, bit 16 - model,
        bit 17 - multivariate.
@\item
  {\bf -Z ZMin ZMax}: Sets the near and far Z clipping planes.
@\item
  {\bf -M}: Draw control mesh/polygon of curves and surfaces, as well.
@\item
  {\bf -W WireSetup}: Controls the line drawing of the freeforms where
        WireSetup is a mask that controls:
        bit 0: Draw curves and surfaces using a set of isocurves (see -I and
               -f),
        bit 1: Draw boundary curves of surfaces,
        bit 2: Draw silhouette curves of surfaces,
        bit 3: Draw surfaces in sketch style line art (see -k).
        bit 4: Draw surfaces' reflection lines (surface also must have a
               "ReflectLns" attribute - see attributes above).
@\item
  {\bf -P}: Draws curves and surfaces using a set of polygons (see -F).
@\item
  {\bf -o}: Reverses the Orientation by flipping all normals (see -n, -N).
@\item
  {\bf -x ExecAnimCmd}: Command to execute as a subprocess every iteration of
        display of an animation sequence. This command can, for example, save
        the display into an image file, saving the animation sequence.
        One parameter, which is an running index starting from one, is passed.
@\item
  {\bf -X Min,Max,Dt,R\{,flags\}}: Executes an animation sequence between
        Min time to Max time in steps of Dt. R repetitions of the animations
        are executed.  Flags could be any combination of:
        's': Flag to specify the saving of the animation as individual
             data files, one per frame, for high quality rendering.
        't': Two way animation - bounce back and forth.
        'b': Reset the animation back to its starting position.
        'x': Flag to force the display device to exit upon completion of the
             animation.
@\item
  {\bf -w InitWidget}: Sets the widgets that are displayed initially
       (as an or'ed mask):
         1 - Environment widget,            2 - Animation widget,
         4 - Curves widget,                 8 - surfaces widget,
        16 - Shading widget,               32 - Pick objects widget,
        64 - Object transforms widget.
@\item
  {\bf -T}: Enable continuous moTion.  Objects continue to move indefinitely
        following the last transformation applied.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

@\subsection{Configuration Options}
!Configuration Options

 The configuration file is read {\em before} the command line options are
 processed. Therefore, all options in this section can be overridden
 by the appropriate command line option, if any.

@\begin{itemize}
@\item
  {\bf TransPrefPos:} Preferred location (Xmin, YMin, Xmax, Ymax) of the
        transformation window.
@\item
  {\bf ViewPrefPos:} Preferred location (Xmin, YMin, Xmax, Ymax) of the
        viewing window.
@\item
  {\bf BackGround:} Background color. Same as '-b'.
@\item
  {\bf Internal:} Draws internal edges. Same as '-i'.
@\item
  {\bf LightSrcPos:} Sets the location of the (first) light source as a
        rational four coefficient location. W of zero sets the light source
        at infinity.
@\item
  {\bf ExecAnimCmd:} Executes a command at each step of the animation. Same as
        '-x'.
@\item
  {\bf ExecAnimation:} Executes an animation sequence on startup. Same as '-X'.
@\item
  {\bf DrawVNormal:} Draws normals of vertices. Same as '-n'.
@\item
  {\bf DrawPNormal:} Draws normals of polygons. Same as '-n'.
@\item
  {\bf MoreVerbose:} Provides some more information on the parsed data file(s).
        Same as '-m'.
@\item
  {\bf UnitMatrix:} Forces a unit matrix. That is, input data are {\em not}
        transformed at all. Same as '-u'.
@\item
  {\bf DrawStyle:} Requests a shaded surface rendering, or isocurve/polyline
        surface rendering, or point rendering.
@\item
  {\bf BFaceCull:} Requests the removal of back facing polygons, for better
        visibility.
@\item
  {\bf DoubleBuffer:} Requests drawing using a double buffer, if any.
@\item
  {\bf DebugObjects:} Debugs objects. Prints to stderr all objects read
        from the communication port with the server {\em IRIT}. Same as '-d'.
@\item
  {\bf DebugEchoInput:} Debugs input. Prints to stderr all characters read
        from the communication port with the server {\em IRIT}. Lowest level of
        communication.
@\item
  {\bf DepthCue:} Sets depth cueing on. Drawings that are closer to the
        viewer will be drawn in more intense color. Same as '-c'.
@\item
  {\bf CacheGeom:} Normally piecewise linear approximation of freefroms is
        cached. By setting this option to FALSE, no such auxiliary data is
        saved, reducing the memory overhead. Same as '-C'.
@\item
  {\bf FourPerFlat:} Forces four polygons per almost flat region in the
        surface to polygon conversion. Otherwise two polygons only. Same as
        '-4'.
@\item
  {\bf AntiAlias:} Requests the drawing of antialiased lines.
@\item
  {\bf DrawSurfaceMesh:} Draws control mesh/polygon of curves and surfaces,
        as well. Same as '-M'.
@\item
  {\bf DrawSurfacePoly:} Draws curves and surfaces (surfaces are drawn using
        a set of isocurves, see -I, or polygons, see -f). Same as '-P'.
@\item
  {\bf StandAlone:} Runs the driver in a standalone mode. Otherwise, the
        driver will attempt to communicate with the {\em IRIT} server. Same
        as '-s'.
@\item
  {\bf PolyStrips:} Renders using polygonal strips, if possible. Same
        as '-R'.
@\item
  {\bf ContMotion:} Renders using continuous motions. Objects continue to
        move indefinitely, following the last transformation applied. Same
        as '-T'.
@\item
  {\bf NumOfIsolines:}  Specifies number of isolines per surface, per
        direction. Same as '-I'.
@\item
  {\bf PllnFineNess:} Specifies the samples per (iso)curve or tolerance of
       approximation. See '-f'.
@\item
  {\bf LineWidth:} Sets the linewidth, in pixels. Default is one pixel
       wide. Same as '-l'
@\item
  {\bf AdapIsoDir:} Selects the direction of the adaptive isoline
        rendering.
@\item
  {\bf PolygonOpti:} Controls the method used to subdivide a surface into
        polygons that approximate it. See '-F'.
@\item
  {\bf PolylineOpti:} Controls the method used to subdivide a curve into
        polylines that approximate it. See '-f'.
@\item
  {\bf ShadingModel:} One of 1 (Flat), 2 (Gouraud), or 3 (Phong). Same as
        '-A'.
@\item
  {\bf TransMode:} Selects between object space transformations and screen
        space transformation.
@\item
  {\bf ViewMode:} Selects between perspective and orthographic views.
@\item
  {\bf NormalLength:} Sets the length of the drawn normals in thousandths of
        a unit. Same as '-L'.
@\item
  {\bf ZClipMin:} Sets the minimal clipping plane in Z. Same as '-Z'.
@\item
  {\bf ZClipMax:} Sets the maximal clipping plane in Z. Same as '-Z'.
@\item
  {\bf PlgnFineNess:} Controls the fineness of the surface to polygon
       subdivision.  See '-F'.
@\end{itemize}

@\subsection{Interactive mode setup}
&Interactive mode setup

   Commands that affect the status of the display device can also be sent
 via the communication port with the {\em IRIT} server. The following commands
 are recognized as string objects with object name of "COMMAND\_":
# 18 2 0 1
 {\bf ANIMATE TMin TMax Dt} 
  Animates current scene from TMin to TMax in Dt
 
  steps.
 {\bf BEEP}
  Makes some sound.
 {\bf CLEAR}
  Clears the display area. All objects are deleted.
 {\bf CLONEOBJ OBJNAME}
  Clone the object OBJNAME.
 {\bf DCLEAR}
  Delays clear. Same as CLEAR but delayed until next
 
  object is sent from the server. Useful for animation.
 {\bf DISCONNECT}
  Closes connection with the server, but does not quit.
 {\bf EDITCRV CRVNAME}
  Requests immediate editing mode of crv CRVNAME.
 {\bf EDITOBJ OBJNAME}
  Requests immediate editing mode of obj OBJNAME.
 {\bf EDITSRF SRFNAME}
  Requests immediate editing mode of srf SRFNAME.
 {\bf EXIT}
  Closes connection with the server and quits.
 {\bf GETOBJ NAME}
  Requests the object named NAME that is returned
 
  in the output channel to the server.
 {\bf HIGHLIGHT1 NAME}
  Color the object named NAME with highlight1 color.
 {\bf HIGHLIGHT2 NAME}
  Color the object named NAME with highlight2 color.
 {\bf IMGSAVE NAME}
  Save the current display in an image file named NAME.
 {\bf MSAVE NAME}
  Save the current matrix in a file named NAME.
 {\bf PICKCRSR}
  Requests to interactively sample mouse/cursor events
 
  for mouse-up, mouse-down, and mouse-move-while-down.
 {\bf PICKDONE}
  Stop interactive pick reports to server.  Stops all
 
  PICKCRSR, PICKNAME and PICKOBJ modes.
 {\bf PICKNAME}
  Requests to interactively pick an object by name that
 
  is returned in the output channel to the server.
 {\bf PICKOBJ}
  Requests to interactively pick an object that is
 
  returned in the output channel to the server.
 {\bf REMOVE NAME}
  Requests the removal of object named NAME from
 
  display.
 {\bf STATE COMMAND}
  Changes the state of the display device. See below.
 {\bf UNHIGHLIGHT}
  Unhighlight all highlighted objects.
#
   The following commands are valid for the STATE COMMAND above,
# 16 2 0 1
 {\bf MouseSense:}
   Mouse sensitivity control.
 {\bf ScrnObjct:}
   Controls screen/object transformation mode.
 {\bf PerspOrtho:}
   Controls perspective/orthographic trans. mode.
 {\bf DepthCue:}
   Controls depth cueing drawing.
 {\bf CacheGeom:}
   Cache the created piecewise linear geometry.
 {\bf DrawStyle:}
   Controls isocurve/shaded solid/points rendering.
 {\bf ShadingMdl:}
   Controls shading model for solid solid drawing.
 {\bf BFaceCull:}
   Cull backfacing polygons.
 {\bf DblBuffer:}
   Controls single/double buffer mode.
 {\bf AntiAlias:}
   Controls antialiased lines.
 {\bf DrawIntrnl:}
   Controls drawing of internal lines.
 {\bf DrawVNrml:}
   Controls drawing of normals of vertices.
 {\bf DrawPNrml:}
   Controls drawing of normals of polygons.
 {\bf DrawPlgns:}
   Controls drawing of polygonal objects as polygons.
 {\bf DSrfMesh:}
   Controls drawing of control meshes/polygons.
 {\bf DSrfWire:}
   Controls drawing of curves/surfaces as wireframes.
 {\bf DSrfBndry:}
   Controls drawing of boundary curves of surfaces.
 {\bf DSrfSilh:}
   Controls drawing of silhouette curves of surfaces.
 {\bf DSrfPoly:}
   Controls drawing of curves/surfaces as polygons.
 {\bf DSrfSktch:}
   Controls drawing of surfaces as sketches.
 {\bf 4PerFlat:}
   Controls 2/4 polygons per flat surface regions.
 {\bf NumIsos:}
   Controls the number of isocurves in a surface.
 {\bf PolyAprx:}
   Controls the surface tesselation fineness.
 {\bf PllnAprx:}
   Controls the curves to polylines fineness.
 {\bf LenVecs:}
   Controls the length of displayed normal vectors.
 {\bf WidthLines:}
   Controls the width of the drawn lines.
 {\bf WidthPts:}
   Controls the width of the cross of drawn points.
 {\bf Front:}
   Selects a front view.
 {\bf Side:}
   Selects a side view.
 {\bf Top:}
   Selects a top view.
 {\bf Isometry:}
   Selects an isometric view.
 {\bf 4Views:}
   Selects a four views mode.
 {\bf Clear:}
   Clears the viewing area.
 {\bf ResAdapIso:}
   Controls the resolution of a number of adaptive isocurves.
 {\bf ResRldSrf:}
   Controls the resolution of ruled srfs in adaptive isocurves.
 {\bf RuledSrfApx:}
   Controls the ruled surface approx. in adaptive isocurves.
 {\bf AdapIsoDir:}
   Controls the row/col direction of adaptive isocurves.
 {\bf LowResRatio:}
   Controls the low/high resolution ratios.
 {\bf ClipAtPoles:}
   Controls the optional clipping of polygons/lines at poles.
#

 Obviously not all state options are valid for all drivers.
   The {\em IRIT} server defines in {\bf iritinit.irt} several user-defined
 functions that exercise some of the above state commands, such as
 VIEWSTATE and VIEWSAVE.  VIEWSTATE accepts a second parameter which
 can be -1 to toggle the value, 0 to reset the value or 1 to set it.
 If the state value is real, 1 doubles its value and 0 halfs it.

   In addition to state modification via communication with the {\em IRIT}
 server, modes can be interactively modified on most of the display devices
 using a pop-up menu that is activated using the {\em right button in the
 transformation window}.
   This pop-up menu is somewhat different in different drivers, but its
 entries closely follow the entries of the above state command table.

   All driver support three special matrices.  The VIEW\_MAT can set
 the current viewing direction and PRSP\_MAT can set the current perspective
 view.  Finally, CONT\_MAT can set the current continuous motion (see also
 '-T' option).

@\subsection{Animation Mode}
&Animation Mode

   All the display drivers are now able to animate objects with animation
 curve attributes on them. For more on the way animation curves can be
 created, see the Animation Section of this manual.
@(Section~\ref{sec-animation}).

   Once a scene with animation curve attributes is being loaded into
 a display device, one can enter "animation" mode using the "Animation"
 button available in all display devices. The user is then prompted (either
 graphically or in a textual based interface) for the starting time,
 termination time and step size of the animation. The parameter space of
 the animation curve serves as the time domain. The default starting
 and terminating times are set as the minimal and maximal parametric
 domain values of all animation curves. An object at time t below the
 minimal parametric value will be placed at the starting value of the
 animation curve. Similarly, an object at time t above the
 maximal parametric value will be placed at the termination value of the
 animation curve. The user can also set a bouncing back and forth mode,
 the number of repetitions, and if desired, request the saving of all
 the different scenes in the animation as separate files so a high quality
 animation can be created.

    A string object can be viewed as the text of selected PS font (See -N). 
 The string position is set via a "StrPos" vector attribute (default to the
 origin), and "StrScale" real attribute to control the string height in
 world unit (default to 0.1).  Text will always be in a plane parallel to
 the XY plane.

@\subsection{Advanced (Programmable) Hardware Graphics Support}
&Advanced (Programmable) Hardware Graphics Support

   Programmable hardware allows us to change the standard pipeline of
 the GPU. This features enables users to create dedicated GPU programs
 (called shaders) to implement advanced rendering algorithms.

   Under Windows, IRIT’S OpenGL display device is able to use
 programmable hardware features.  In order to use these advanced
 hardware rendering features, the GPU must support the proper shader
 model. The display device will ignore advanced hardware features
 attributes if the local GPU does not support the proper shader’s
 requirements.

 The following advanced hardware features are supported by IRIT:

@\subsubsection{HDDM (Hardware Deformation Displacement Mapping)}
&HDDM (Hardware Deformation Displacement Mapping)

 Deformation displacement mapping is a technique that allows us to
 tile the geometry of a given object without the limitations of strict
 displacement mapping.

 Requirements: Shader model 3.0 and above
 Shader file: ddm\_vshd.cg
 Shader Language: CG
 Shader’s compilation:  run time.
 Supported geometries:  All surfaces and polygonal models with UV values

 In order to use DDM texture in an object, a "DTexture" attribute string
 must be defined for the object ([.] are optional):

 "TileFileName, T TilesU TilesV, [S SamplingU SamplingV], [H Shader],
 [Z Scale], [OB/OA], [RU/CU/CRU], [RV/CV/CRV], [M], [NO/NT],
 [A AnimationSamples]"

 where

@\begin{itemize}
@\item
 {\bf TileFileName:} The DDM Tile.
@\item
 {\bf T TilesU TilesV:} Number of tiles to place.
@\item
 {\bf S SamplingU SamplingV:} Number of samples to take on the original
        object (default S=T).
@\item
 {\bf H Shader:} Shader filename (default: ddm\_vshd.cg).
@\item
 {\bf Z Scale:} Z Scale factor on tile’s Z axes (default = 1).
@\item
 {\bf OB/OA:} Draw the original object before the tiles (OB) or draw the
        original object after the tiles (OA). This matters when using tiles
        with transparency (Default: don’t draw original object).
@\item
 {\bf RU/CU/CRU, RV/CV/CRV:} How the tiles should be handled when overlapping
        the object’s UV domain:
 {\bf RU, RV:} Repeat end conditions.
 {\bf CU, CV:} Clamp end conditions.
 {\bf CRU, CRV:} Clamp to tile size - simulates repeat with clamping (handles
        the stretch side effect in the background of objects with only 1 side
        when using simple repeat.  (Default: RU, RV)
@\item
 {\bf M:} Use multitiles (see below).
@\item
 {\bf NO/NT:} Normal calculation methods offset (NO), or tangent plane mapping
        (NT)  (Default: NO).
@\item
 {\bf Animation Samples:} The number of samples from a continuous animation
        sequence that is defined on an object (default: 1).
@\end{itemize}

   Examples:

@\begin{verbatim}
 [DTexture "horn.itd, H ddm_vshd.cg, T 4 16, S 32 64, CRU, CV, Z 0.7, NT"]
 [DTexture "stone-t1.itd, H ddm_vshd.cg, T 6 1, S 64 64, CU, RV, Z -0.1, M, NO"]
@\end{verbatim}

   DDM supports usage of more than one tile per object.  When using
 {\em multitiles}, tiles are placed randomly on the object.  To use
 multitiles, an 'M’ flag should placed in the dtexture attribute.
 Furthermore, an additional "DTextureFiles" attributes must be defined
 for the object with the following string: "Tilefile1, tilefile2,
 tilefile3...".  The maximum number of supported tiles is 10.

   Example:

@\begin{verbatim}
  [DTextureFiles "stone-t4.itd stone-t3.itd stone-t2.itd stone-t6.itd"]
@\end{verbatim}

   The tile geometry also supports some attributes such as animation.
 The following animations are supported:
@\begin{itemize}
@\item
 {\bf MORPH:}
   Morphing between two compatible tiles (same number of vertices)
 according to the curve. The morphing is between the DDM tiles
 ("DTexture" attribute) and the first tile in the "DTextureFiles" attribute
 (hence, using morph requires multitiles).  
@\item
 {\bf SCL\_Z:} Z scale of the tile (in tile space) according to the animation
 curve (see also animation in IRIT and the display device).
@\item
 {\bf MOV\_U/MOV\_V:} Change the UV placement of the tile in the parametric
 space of the base, textured, surface, according to the animation curve.
@\item
 {\bf RECT\_TILE}, or {\bf HEX\_TILE} or {\bf TRIG\_TILE} or {\bf TRIG\_TILE\_REV:}
 DDM supports four types of tiles:
# 20 2 1 1
 Rectangle:
  Creates square tiling.
 Hexagon:
  Creates honeycomb tiling.
 Triangle:
  Tiles the surfaces using triangles.
 Reversed Triangle:
  Tiles the surfaces using reversed triangles.
#
 In order to define the type of tiling, one of the above attributes should
 be added to the tile object:
@\end{itemize}

@\subsubsection{HFFD (Hardware Free Form Deformation)}
&HFFD (Hardware Free Form Deformation)

 FFD is a technique which deforms objects by deforming the space in
 which the object is embedded.

 Requirements: Shader model 3.0 and above
 Shader file: ddm\_vshd.cg
 Shader Language: CG
 Shader’s compilation:  run time.
 Supported geometries:  All surfaces and polygonal models with UV values

 In order to use FFD in an object, an "FFD\_texture" attribute must be
 added to the object with the following string:

 "ObjectFile, ShaderType, DrawTV, ScaleX, ScaleY, ScaleZ, AnimationSamples,
  OffsetX, OffsetY, OffsetZ, NormalCalcMethod"

 where

@\begin{itemize}
@\item
 {\bf Objectfile:} The file of the object to use with TV.
@\item
 {\bf ShaderType:} 0 - Single Phase Shader (Limited shader), 1 - Double Phase
        Shader
@\item
 {\bf DrawTV:} 0 - Don’t draw the trivariate object. 1 - Draw the trivariate
        object.
@\item
 {\bf ScaleX, ScaleY, ScaleZ:} The scale of the object in xyz.
@\item
 {\bf AnimationSamples:} Number of times to sample object when object has
        animation, along the animation.
@\item
 {\bf OffsetX, OffsetY, OffsetZ:} The offset of the object in xyz axes.
@\item
 {\bf NormalCalcMethod:} 0 - No shading (use original normal values),
        1 - Normal offset calculation, 2 - Tangent plane mapping
@\end{itemize}

   Examples:

@\begin{verbatim}
  [FFD_texture "porschesc.itd, 1, 0, 1.8, 0.15, 1.8, 0, 0, 0, 0, 2"]
@\end{verbatim}

@\subsection{Specific Comments}
&Specific Comments

@\begin{itemize}
@\item
   The x11drvs supports the following X Defaults (searched at ~/.Xdefaults):
@\begin{verbatim}
        #ifndef COLOR
        irit*MaxColors:                    1
        irit*Trans*BackGround:             Black
        irit*Trans*BorderColor:            White
        irit*Trans*TextColor:              White
        irit*Trans*SubWin*BackGround:      Black
        irit*Trans*SubWin*BorderColor:     White
        irit*Trans*CursorColor:            White
        irit*View*BackGround:              Black
        irit*View*BorderColor:             White
        irit*View*CursorColor:             White
        #else
        irit*MaxColors:                    15
        irit*Trans*BackGround:             NavyBlue
        irit*Trans*BorderColor:            Red
        irit*Trans*TextColor:              Yellow
        irit*Trans*SubWin*BackGround:      DarkGreen
        irit*Trans*SubWin*BorderColor:     Magenta
        irit*Trans*CursorColor:            Green
        irit*View*BackGround:              NavyBlue
        irit*View*BorderColor:             Red
        irit*View*CursorColor:             Red
        #endif
        irit*Trans*BorderWidth:            3
        irit*Trans*Geometry:               =150x500+510+0
        irit*View*BorderWidth:             3
        irit*View*Geometry:                =500x500+0+0
@\end{verbatim}
@\item
 The Motif-based display drivers contain three types of gadgets which can be
 operated in the following manner. Scales: can be dragged or clicked outside
 for single (mouse's middle button) or continuous (mouse's left
 button) action. Pushbuttons: activated by clicking the mouse's left button.
 The control panel: allows rotation, translation of the objects in three
 axes, determining of the perspective ratio, viewing an object from top, side,
 front or isometrically, determining scale factor and clipping settings, and
 operating the matrix stack. 

   The environment window toggles between screen or object transformation,
 depth cue on or off, orthographic or perspective projection, wireframe or
 solid display, single or double buffering, showing or hiding normals,
 including or excluding the surface's mesh and curve's control polygon,
 surface drawing using isolines or polygons, and four or two polygons per
 flat patch. Some display devices allow for the inclusion or exclusion of
 internal edges, and enable or disable of antialiased lines.
 Scales in the X11/Motif based devices set normals length, lines width,
 control sensitivity, the number of islolines and samples, etc.
@\item
   The locations of windows as set via [-g] and [-G] and/or via the
 configuration file overwrite in x11drvs the Geometry X11 defaults.
 To use the Geometry X11 default, use '-G " "' and '-g " "' or set the
 string to empty size in the configuration file.
@\item
   In os2drvs, only -G is used to specify the dimensions of the parent window
 that holds both the viewing and the transformation window.
@\item
   In os2drvs, the following key strokes are available as shortcuts:
# 10 2 1 1
 Key
  Function
 \verb+^+x
  Quit
 \verb+^+s
  Save
 \verb+^+f
  Front View
 \verb+^+d
  Side View
 \verb+^+t
  Top View
 \verb+^+i
  Isometric VIew
 \verb+^+p
  Perspetive/Orthographic
 \verb+^+n
  View Internal Edges
 \verb+^+v
  View Vertices' Normals
 \verb+^+g
  View Polygons' Normals
 \verb+^+b
  Backface Culling
 \verb+^+c
  Depth Cue
 \verb+^+m
  View Control Mesh/Poly
#
@\end{itemize}
 
@\subsection{Examples}
&Examples

@\begin{verbatim}
 xglmdrvs -z
@\end{verbatim}

 prints all the options and their current values.

@\begin{verbatim}
 xglmdrvs -B -i -l 3 solid1.itd
@\end{verbatim}

 displays the model of solid1.itd using backface culling ('-B'), with
 internal edges ('-i'), and line width of 3.

@\begin{verbatim}
 xglmdrvs -r -A flat wiggle.itd
@\end{verbatim}

 displays the model of wiggle.itd shaded ('-r') using flat shading ('-A').

@\begin{verbatim}
 xglmdrvs -I 40 -u -b 255 255 255 wiggle.itd
@\end{verbatim}

 displays the model of wiggle.itd using isolines' density of 40 ('-I'), using
 unit matrix to begin with ('-u'), and a white background ('-b').

@\begin{verbatim}
 xglmdrvs -X 0,2,0.1,sx -r anim.itd
@\end{verbatim}

 executes the animation in anim.itd, from time 0 to time 2 in steps of 0.1.
 The animation is saved in one frame per file (flag 's' in '-X') and
 the display device exists once the animation has terminated (flag 'x'
 in '-X')).  The animation will be shaded ('-r').
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Utilities - General Usage}
!Utilities - General Usage

   The {\em IRIT} Solid Modeler is accompanied by quite a few utilities. They
 can be subdivided into two major groups. The first includes auxiliary tools
 such as illustrt and poly3d-h. The second includes filters such as irit2ray
 and irit2ps.

   All these tools operate on input files, and most of the time produce
 data files. In all utilities that read files, the dash ('-') can be used
 to read stdin.

 Example:

@\begin{verbatim}
 poly3d-h solid1.itd | irit2ps - > solid1.ps
@\end{verbatim}

   All the utilities have command line options. If an option is set by a '-x',
 then '-x-' resets the option. The command line options overwrite the settings
 in config files, and the reset option is useful for cases where the option
 is set by default, in the configuration file.

   All utilities can read a sequence of data files. However, the {\em last}
 transformation matrices found (VIEW\_MAT and PRSP\_MAT) are actually used.

 Example:

@\begin{verbatim}
 poly3d-h solid1.itd | x11drvs solid1.itd - solid1.imd 
@\end{verbatim}

 x11drvs will display the original solid1.itd file with its hidden version,
 as computed by poly3d-h, all with the solid1.imd, ignoring all other matrices
 in the data stream.

 Compressed files with a postfix ".Z" or ".gz" will be {\em automatically}
 uncompressed on read and write. The following is legal:

@\begin{verbatim}
 poly3d-h solid1.itd.Z | x11drvs solid1.itd.Z - solid1.imd
@\end{verbatim}

 where solid1.itd.Z was saved from within IRIT using the command

@\begin{verbatim}
 save( "solid1.itd.Z", solid1 );
@\end{verbatim}

 or similarly. The gnu utility "gzip" is used for the purpose of
 (un)compressing the data via pipes.  See also SAVE and LOAD.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Poly3d-h - Hidden Line Removing Program}
!Poly3d-h - Hidden Line Removing Program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


@\subsection{Introduction}
&Introduction

    poly3d-h is a program to remove hidden lines from a given polygonal model.
 Freeform objects are preprocessed into polygons with controlled fineness.
@See Figure~\ref{fig-poly3dh} for some output examples which use this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{ccc}
@    \epsfig{file=user_man/solid2h.ps, width=2.0in} &
@    \epsfig{file=user_man/molecule.ps, width=2.0in} &
@    \epsfig{file=user_man/dodechdr.ps, width=2.0in}
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/solid2h.gif">
=    <img hspace=2 width=250 src="user_man/molecule.gif">
=    <img hspace=2 width=250 src="user_man/dodechdr.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Some examples of the use of the hidden line removal tool, poly3d-h,
-      to remove hidden lines.
=</b><BR clear=all>
@}
@\label{fig-poly3dh}
@\end{figure}

    The program performs 4 passes over the input:

 1. Preprocesses and maps all polygons in a scene, and sorts them.

 2. Generates edges out of the polygonal model and sorts them (preprocessing
    for the scan line algorithm) into buckets.

 3. Intersects edges, and splits edges with non-homogeneous visibility (the
    scan line algorithm).

 4. Applies a visibility test on each edge.
 
        This program can handle CONVEX polygons only. From {\em IRIT} one can
 ensure that a model consists of convex polygons only, using the CONVEX
 command:
@\begin{verbatim}
  CnvxObj = convex( Obj );
@\end{verbatim}
 just before saving it into a file. Surfaces are always decomposed into
 triangles.

    poly3d-h output is in the form of polylines. It is a regular {\em IRIT}
 data file that can be viewed using any of the display devices, for example.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
 poly3d-h [-b] [-m] [-i] [-e #Edges] [-H] [-4] [-W Width]
        [-F PolyOpti FineNess] [-q] [-o OutName] [-t AnimTime]
        [-c] [-z] DFiles > OutFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -b}: BackFacing - if an object is closed (such as most models created by
       {\em IRIT}), backfacing polygons can be deleted, thereby speeding up
       the process by at least a factor of two.
@\item
  {\bf -m}: More - provides some more information on the parsed data file(s).
@\item
  {\bf -i}: Internal edges (created by {\em IRIT}) - default is not to
       display them, and this option will force their display, as well.
@\item
  {\bf -e n}: Number of edges to use from each given polygon (default all).
       Handy as '-e 1 -4' for freeform data.
@\item
  {\bf -H}: Dumps both visible lines and hidden lines as separated objects.
       Hidden lines will be dumped using a different (dimmer) color and (a
       narrower) line width.
@\item
  {\bf -4}: Forces four polygons per almost flat region in the surface to
       polygon conversion. Otherwise two polygons only.
@\item
  {\bf -W Width}: Selects a default width for visible lines in inches.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -q}: Quiet mode. No printing aside from fatal errors. Disables -m.
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\item
  {\bf -c}: Clips data to screen (default). If disabled ('-c-'), data
       outside the view screen ([-1, 1] in x and y) are also processed.
@\end{itemize}

   Some of the options may be turned on in poly3d-h.cfg. They can then be 
 turned off in the command line as '-?-'.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Configuration}
&Configuration
 
   The program can be configured using a configuration file named poly3d-h.cfg.
   This is a plain ASCII file you can edit directly and set the parameters
 according to the comments there. 'poly3d-h -z' will display the current
 configuration as read from the configuration file.

   The configuration file is searched in the directory specified by the
 IRIT\_PATH environment variable. For example,
 'setenv IRIT\_PATH /u/gershon/irit/bin/'.
   If the IRIT\_PATH variable is not set, the current directory is searched.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

   As this program is not interactive, usage is quite simple, and the only
 control available is the command line options.

@The images in Figure~\ref{fig-poly3dh} were created using the following
@commands:
@\begin{verbatim}
@    poly3d-h -W 0.01 -H -q molecule.itd view1.itd | irit2ps - > molecule.ps
@    poly3d-h -W 0.02 -q solid2h.itd view2.itd | irit2ps - > solid2h.ps
@    poly3d-h -W 0.02 -H -q dodechdr.itd view3.itd |
@                                      irit2ps -d -0.59 0.59 - > dodechdr.ps
@\end{verbatim}

   If a certain surface should be polygonized into a finer/coarser
 set of polygons than the rest of the scene, one can set a "resolution"
 attribute which specifies the {\em relative} FineNess resolution of this
 specific surface. Further, "u\_resolution" and "v\_resolution" might be
 similarly used to set relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines.  The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

   See also IHidden.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Poly3d-r - A Simple Data Rendering Program}
!Poly3d-r - A Simple Data Rendering Program

 Retired. Sources can be found in the contrib directory, but this program is
 no longer supported. See irender program instead.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Illustrt - Simple line illustration filter}
!Illustrt - Simple line illustration filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Introduction}
&Introduction

 illustrt is a filter that processes {\em IRIT} data files and dumps out modified
 {\em IRIT} data files. illustrt can be used to make simple, nice illustrations of
 data. The features of illustrt include depth sorting, hidden line clipping 
 at intersection points, and vertex enhancements. illustrt is designed to
 closely interact with irit2ps, although it is not neceessary to use irit2ps
 on illustrt output.

@See Figure~\ref{fig-illustrt} for some output examples which use this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/solid1.ps, width=3.0in} &
@    \epsfig{file=user_man/icosahdr.ps, width=3.0in}
=    <BR clear=all>
=    <img hspace=2 src="user_man/solid1.gif">
=    <img hspace=2 src="user_man/icosahdr.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-    Some examples of the use of the illustration tool, illustrt.
=</b><BR clear=all>
@}
@\label{fig-illustrt}
@\end{figure}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   illustrt [-I #UIso[:#VIso[:#WIso]]] [-f PolyOpti SampTol] [-s] [-M] [-P]
            [-p] [-O] [-l MaxLnLen] [-a] [-t TrimInter] [-o OutName]
            [-Z InterSameZ] [-m] [-T AnimTime] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
        surface/trivariate, per direction. If \#VIso is not specified,
        \#UIso is used for \#VIso as well and so no.
@\item
  {\bf -f PolyOpti SampTol}:  Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve. 
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -s}: sorts the data in Z depth order that emulates hidden line removal
        once the data are drawn.
@\item
  {\bf -M}: Dumps the control mesh/polygon as well.
@\item
  {\bf -P}: Dumps the curve/surface as isocurves.
@\item
  {\bf -p}: Dumps vertices of polygons/lines as points.
@\item
  {\bf -O}: Handles polygonal objects as possibly open.  This will generate
        two identical edges for an edge shared by two adjacent polygons.
        This can be useful for open or isolated polygons.
@\item
  {\bf -l MaxLnLen}: Breaks long lines into shorter ones with maximal length
        of MaxLnLen. This option is necessary to achieve good depth depending
        on line width in the '-d' option of irit2ps.
@\item
  {\bf -a}: Takes into account the angle between the two (poly)lines that
        intersect when computing how much to trim. See also -t.
@\item
  {\bf -t TrimInter}: Each time two (poly)line segments intersect in the
        projection plane, the (poly)line that is farther away from the
        viewer is clipped by the TrimInter amount from both sides. See also -a.
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -Z InterSameZ}: The maximal Z depth difference of intersection curves
        to be be considered invalid.
@\item
  {\bf -m}: More talkative mode. Prints processing information.
@\item
  {\bf -T AnimTime}: If the data contain animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    illustrt is a simple line illustration tool. It processes geometry such
 as polylines and surfaces and dumps geometry with attributes that will make
 nice line illustrations. illustrt is geared mainly toward its use with
 irit2ps to create postscript illustrations. Here is a simple example:

@\begin{verbatim}
 illustrt -s -l 0.1 solid1.itd | irit2ps -W 0.05 -d 0.2 0.6 -u - > solid.ps
@\end{verbatim}

 makes sure all segments piped into irit2ps are shorter than 0.1 and sorts them
 in order to make sure hidden surface removal is correctly applied. Irit2ps
 is invoked with depth cueing activated, and a default width of 0.05.

    illustrt dumps out regular {\em IRIT} data files, so output can be handled
 like any other data set. illustrt does the following processing to the input
 data set:

@\begin{itemize}
@\item
  Converts surfaces to isocurves ('-I' flag) and isocurves and curves to
  polylines ('-S' flag), and converts polygons to polylines.
    Polygonal objects are considered closed and even though each edge is
  shared by two polygons, only a single one is generated.
@\item
  Finds the intersection location in the projection plane of all segments in
  the input data set and trims away the far segment at both sides of the
  intersection point by an amount controlled by the '-t' and '-a' flags.
@\item
  Breaks polylines and long lines into short segments, as specified via the
  '-l' flag, so that width depth cueing can be applied more accurately
  (see irit2ps's '-d' flag) as well as the Z sorting.
@\item
  Generates vertices of polygons in the input data set as points in output data
  controlled via the '-p' flag.
  set.
@\item
  Applies a Z sort to the output data, if '-s', so drawing in order of the data
  will produce a properly hidden surface removal drawing.
@\end{itemize}

 Here is a more complex example. Make sure tubular is properly set via
 "attrib(solid1, "tubular", 0.7);" and invoke:
 
@\begin{verbatim}
 illustrt -s -p -l 0.1 -t 0.05 solid1.itd |
     irit2ps -W 0.05 -d 0.2 0.6 -p h 0.05 -u - > solid.ps
@\end{verbatim}

 makes sure all segments piped into irit2ps are shorter than 0.1, generates
 points for the vertices, sorts the data in order to make sure hidden surface
 removal is correctly applied, and trims the far edge by 0.05 at an
 intersection point. Irit2ps is invoked with depth cueing activated and a
 default width of 0.05, points are drawn as hollowed circles of default
 size 0.05, and lines are drawn tubular.

 Objects in the input stream that have an attribute by the name of
 "IllustrtNoProcess" are passed to the output unmodified.
   Objects in the input stream that have an attribute by the name of
 "SpeedWave" will have a linear segment added that emulates fast
 motion with the following attributes,
@\begin{verbatim}
 "Randomness,DirX,DirY,DirZ,Len,Dist,LenRandom,DistRandom, width".
@\end{verbatim}
   Objects in the input stream that have an attribute by the name of
 "HeatWave" will have a spiral curves added that emulate a heat wave
 in the +Z axis with the following attributes,
@\begin{verbatim}
 "Randomness,Len,Dist,LenRandom,DistRandom, width".
@\end{verbatim}
 Examples:

@\begin{verbatim}
 attrib(Axis, "IllustrtNoProcess", "");
 attrib(Obj, "SpeedWave", "0.0005,1,0,0,5,3,3,2,0.05");
 attrib(Obj, "HeatWave", "0.015,0.1,0.03,0.06,0.03,0.002");
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Aisoshad - Simple line illustration filter}
!Aisoshad - Simple line illustration filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Introduction}
&Introduction

 Aisoshad is a filter that processes {\em IRIT} data files of freeform shapes
 and dumps out modified {\em IRIT} data files in the form of short
 univariate strokes. Aisoshad can be used to make simple yet nice line
 art illustrations of geometry that is based solely on isoparametric
 curves.

 Aisoshad employs a simple shader to determine the density of the
 isoparametric strokes as well as the thickness etc.  Output of aisoshad
 can be piped into the irit2ps postscript postprocessor.

@See Figure~\ref{fig-aisoshad} for output examples of using this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/wglass1.ps, width=3.0in} &
@        \epsfig{file=user_man/wglass2.ps, width=3.0in} 
=    <BR clear=all>
=    <img hspace=2 src="user_man/wglass1.gif">
=    <img hspace=2 src="user_man/wglass2.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Examples of the use of the aisoshad illustration tool to
-     line art illustrative drawing using isoparametric curves.  In (left),
-     silhouettes are emphasized, while in (right) a light source above and to
-     the right is placed using a cosine shader.
=</b><BR clear=all>
@}
@\label{fig-aisoshad}
@\end{figure}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   aisoshad [-o OutName] [-m] [-i] [-F PolyOpti FineNess]
            [-f PolyOpti SampTol] [-r RndrMdl] [-c CosPwr] [-s SdrPwr]
            [-l Lx Ly Lz] [-R Random] [-d AdapDir] [-t SrfZTrans]
            [-M MinSubdiv] [-D AdapDist] [-w AdapIsoWidth] [-S WidthScale]
            [-W] [-u] [-Z ZbufSize] [-b] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -m}: More talkative mode. Prints processing information.
@\item
  {\bf -i}: Solve symbolic products using interpolations.  Faster but the
        generated output is not as compact as possible.
@\item
  {\bf -I \#IsoLines}: Specifies number of isolines per surface, per direction.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. Default is 0 and 20.0 (no optimal sampling with fineness
        of 20.0 (real number)).
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve. 
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -r}: Selects the rendering model of the shader as follows:
@   \begin{enumerate}
@   \item[]
        1. Cosine shader, diffuse only, light source regular.
@   \item[]
        2. Cosine shader, diffuse only, light source as two lights from
                                                         opposite directions.
@   \item[]
        3. Cosine shader, has specular term, light source regular.
@   \item[]
        4. Cosine shader, has specular term, light source as two lights.
@   \item[]
        5. Shader emphasizing the silhouette areas of the model.
@   \item[]
        6. Shader estimating distance decay from a point light source.
@   \end{enumerate}
@\item
  {\bf -c CosPower}: Controls the cosine shader's power.
@\item
  {\bf -s SdrPower}: Controls the shader's relative influence.
@\item
  {\bf -l Lx Ly Lz}: Sets the light source position/direction.
@\item
  {\bf -R Random}: Controls the levels of randomness that the isoparametric
        curves perturb.  Low levels of randomness would leave visible
        artifacts while too high levels would disturb the shading.  Should be
        greater than one or negative one to disable.
@\item
  {\bf -d AdapDir}: Sets the isoparametric directions of the strokes. Either
        0, 1, or 2 for U direction, V direction or both U and V directions,
        respectively.
@\item
  {\bf -t SrfZTrans}: The amount to translate the created line strokes in Z,
        in order to prevent Z fighting with the rendered object itself.
@\item
  {\bf -M MinSubdiv}: Sets the minimal number of subdivision to enforce
        during the isoparametric strokes' construction.  This flag should be
        used rarely and typically MinSubdiv should be low and close to one.
@\item
  {\bf -D AdapDist}: Sets the distance between adjacent isocurves. The smaller
        AdapDist is, the denser the coverage of the strokes will be.
@\item
  {\bf -w AdapIsoWidth}: Sets the default width attribute of the generated
        strokes.
@\item
  {\bf -S WidthScale}:  Controls the relative variance of the width of the
        strokes in variable width strokes.
@\item
  {\bf -W}: If set, enables variable width strokes.
@\item
  {\bf -u}: If set, maps the strokes to screen space. Otherwise, strokes
        are mapped back to object space.
@\item
  {\bf -Z ZbufSize}: Sets the size of the (square) Z buffer to set.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
        strokes.  Otherwise, {\em IRIT} text file will be created.
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Aisoshad is a simple line art illustration tool that generates strokes
 that follow the isoparametric curves. It processes freeform geometry such
 as surfaces and dumps geometry with attributes that makes
 nice line illustrations. Aisoshad is geared mainly toward its use with
 irit2ps to create postscript illustrations. Here is a simple example:

@\begin{verbatim}
 aisoshad -Z -500 -F 0 50 -s 10 -c 1 -D 0.3 -r 5 wglass.itd view.imd |
 irit2ps -W 0.05 -d 0.2 0.6 -u - > wglass1.ps
@\end{verbatim}

 that creates line art illustrations of a wine glass {\bf wglass.itd} with
 hidden strokes removed via a Z-buffer of size 500 that will be displayed on
 screen, polygonal fineness of 50 for the surface of the glass, shader power
 of 10 and cosine power of 1, isoparametric curves maximal distance of 0.3,
 and shader number 5 that emphasizes silhouettes.  The output of the shader
 is piped to a irit2ps filter to postscript that sets the width of the strokes
 to be a function of depth.
@Figure~\ref{fig-aisoshad}~(a) shows the result of this example.

 Here is another example: 
@\begin{verbatim}
 aisoshad -Z 700 -R 4 -F 0 50 -l 1 1 1 -D 0.02 -r 2 wglass.itd view.imd
 irit2ps -W 0.005 -d 0.2 0.6 -u - > wglass2.ps
@\end{verbatim}

 that creates line art illustrations of a wine glass {\bf wglass.itd} with
 hidden strokes removal via a Z-buffer of size 700 that is allocated off-line
 in core memory, polygonal fineness of 50 for the surface of the glass,
 a light source at (1, 1, 1), isoparametric curves maximal distance of 0.02,
 and a cosine shader number 2.  The output of the shader is piped to a irit2ps
 filter to postscript that sets the width of the strokes to be a function of
 depth.
@Figure~\ref{fig-aisoshad}~(b) shows the result of this example.

 Transparent objects, or objects with the "transp" attribute, would generate
 strokes as regular surfaces but would not participate in the hidden strokes
 removal.  An "AdapIsoDir" attribute that is found on some surface object
 would override the global isoparametric direction's setup of strokes as is
 set via the 'd' option.

 See also the {\bf illustrt}, {\bf izebra}, {\bf lineshad}, and
 {\bf irit2ps} tools.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{IZebra - Simple zebra style, parallel curve based rendering}
!IZebra - Simple zebra style, parallel curve based rendering

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Introduction}
&Introduction

 Izebra is a filter that processes {\em IRIT} data files into a 2D striped,
 zebra style illustration that gives the user an illusionary depth cue.  The
 output is also an {\em IRIT} data file in the form of freeform curves.  Izebra
 can be used to make simple yet nice art illustrations of geometry that is
 based on a specific style inspired by the artist Victor Vasarely.

 Izebra employs a Z buffer to determine the density and warping of the
 stripes.  Output of izebra can be piped into the irit2ps postscript
 postprocessor.

@See Figure~\ref{fig-izebra} for output examples which use this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \mbox{\hspace{-0.1in}}
@    \epsfig{file=user_man/iz_tpot.ps, width=4.5in} &
@       \mbox{\hspace{-0.2in}}
@       \epsfig{file=user_man/iz_pawn.ps, width=2.1in}
=    <BR clear=all>
=    <img hspace=2 width=400 src="user_man/iz_tpot.gif">
=    <img hspace=2 width=400 src="user_man/iz_pawn.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Examples of the use of the izebra illustration tool toward
-     line art illustrative drawings.  On the left, the Utah teapot is
-     rendered, while on the right, a chess piece, a pawn, is portrayed.
=</b><BR clear=all>
@}
@\label{fig-izebra}
@\end{figure}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
    IZebra [-o OutName] [-m] [-O ImgOper] [-F PolyOpti FineNess] [-u]
           [-I NumIters] [-Z ZbufSize] [-B CbcBspSize] [-D DataSrf]
           [-A StripeAngle] [-b] [-s Stripes] [-S ZScale] [-d ZInitDepth]
           [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -m}: More talkative mode. Prints processing information.
@\item
  {\bf -O ImgOper}: By default, the Z buffer is employed directly.  However,
        once the Z buffer is fully evaluated and before beginning the stripes
        processing, one can apply a filter to the Z map of the Z buffer. The
        filter can be a first order Roberts derivative if "-O 1", a second
        order Laplacian if "-O 2", or an inverted depth if "-O 3".
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. Default is 0 and 20.0 (no optimal sampling with fineness
        of 20.0 (real number)).
@\item
  {\bf -u}: Forces a unit matrix. That is, input data are {\em not}
        transformed at all.
@\item
  {\bf -I NumIters}: Puts a bound on the number of iterations in the
        numerical processing stage.
@\item
  {\bf -Z ZbufSize}: ZbufSize sets the size of the (square) Z buffer to set.
@\item
  {\bf -B CbcBspSize}: Sets the mesh size of the constructed uniform cubic
        B-spline grid, if no data surface is specified by '-D'.
@\item
  {\bf -D DataSrf}: If specified, provides the name of the uniform cubic
        B-spline to load and warp.  Overrides the '-B' option.
@\item
  {\bf -A StripeAngle}: Sets the angle of the stripes with respect to the
        horizontal line, in degrees.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
        stripes.  Otherwise, an {\em IRIT} text file will be created.
@\item
  {\bf -s Stripes}: If set, prescribes the number of strips to extract as iso
        parametric curves of the warped B-spline surface.  Otherwise, the
        warped B-spline surface itself is dumped out.
@\item
  {\bf -S ZScale}: A relative factor to control the effect of the depth
        on the warping amount.  This should be around one.
@\item
  {\bf -d ZInitDepth}: By default, the Z buffer is initialized to a depth of
        zero which amounts to no warping of the B-spline surface.  Here is
        a proper way to prescribe a different background depth (which will
        cause warping in the surface).
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Izebra is a simple stripes art illustration tool that generates stripes
 that follow a warped B-spline surface as its isoparametric curves. It
 processes the given geometry, such as surfaces, into a Z map of a Z buffer
 and warps a B-spline surface that is placed over it, with a warping amount
 that is a function of the locally detected depth.  IZebra dumps out stripes
 geometry that makes nice illusionary illustrations.  IZebra is geared
 mainly toward its use with irit2ps to create postscript illustrations.
 Here is a simple example:

@\begin{verbatim}
 izebra -m -Z 500 -B 150 -I 10 -F 0 100 -A 140 -S 0.35 pawn.itd |
 irit2ps -f 0 300 -u -B -0.45 -0.75 0.65 0.75 -W 0.004 -I 0:250 - > pawn.ps
@\end{verbatim}
 creates striped illustrations of a pawn chess piece, with the aid
 of a Z-buffer of size 500 by 500, a uniform cubic B-spline surface with mesh
 size of 150 by 150, polygonal fineness of 100 for the surface of the pawn,
 rotation of stripes of 140 degrees and Z scale factor of 0.35.  Ten iterations
 will be conducted during the numerical processing of the data.
 The output of izebra is piped by the irit2ps filter to postscript that
 extracts 250 isoparametric curves out of the dumped warped surface and sets
 the width of the strokes to be 0.004.
@Figure~\ref{fig-izebra}~(a) shows the result of this example.

 Here is another example: 
@\begin{verbatim}
 izebra -m -Z 500 -B 200 -I 10 -F 0 100 -A -90 -S 0.4 teapot.itd |
 irit2ps -f 0 200 -u -B -0.55 -0.35 0.55 0.35 -W 0.007 -I 0:150 - > teapot.ps
@\end{verbatim}
 creates striped illustrations of the Utah Teapot, with the aid
 of a Z-buffer of size 500 by 500, a uniform cubic B-spline surface with mesh
 size of 200 by 200, polygonal fineness of 100 for the surface of the teapot,
 rotation of stripes of -90 degrees and Z scale factor of 0.4.  Ten iterations
 will be conducted during the numerical processing of the data.
 The output of izebra is piped by the irit2ps filter to postscript that
 extracts 150 isoparametric curves out of the dumped warped surface and sets
 the width of the strokes to be 0.007.

@Figure~\ref{fig-izebra}~(b) shows the result of this example.

 See also the {\bf illustrt}, {\bf aisoshad}, {\bf lineshad}, and
 {\bf irit2ps} tools.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{LineShad - Simple line illustration filter}
!LineShad - Simple line illustration filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Introduction}
&Introduction

 Lineshad is a filter that processes {\em IRIT} data files of freeform shapes
 and dumps out modified {\em IRIT} data files in the form of short
 univariate strokes. Lineshad can be used to make simple yet nice line
 art illustrations of geometry that is based on arbitrarily stroked
 curves on the surfaces.

 Lineshad employs a simple shader to determine the density of the
 isoparametric strokes as well as the thickness etc.  Output of lineshad
 can be piped into the irit2ps postscript postprocessor.

@See Figure~\ref{fig-lineshad} for output examples using this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/wglass3.ps, width=3.0in} &
@        \epsfig{file=user_man/wglass4.ps, width=3.0in}
=    <BR clear=all>
=    <img hspace=2 src="user_man/wglass3.gif">
=    <img hspace=2 src="user_man/wglass4.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-     Examples of the use of the lineshad illustration tool to
-     line art illustrative drawing using isoparametric curves.  On the left,
-     silhouettes are emphasized, while on the right, a light source above
-     and to the right is placed using a cosine shader.
=</b><BR clear=all>
@}
@\label{fig-lineshad}
@\end{figure}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   lineshad [-o OutName] [-m] [-F PolyOpti FineNess] [-R RelStepSize]
            [-f PolyOpti SampTol] [-r RndrMdl] [-c CosPwr] [-s SdrPwr]
            [-i Intensity] [-l Lx Ly Lz] [-v Vx Vy Vz] [-w Width]
            [-d Density] [-t SrfZTrans] [-S WidthScale] [-T Texture]
            [-Z ZbufSize] [-b] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -m}: More talkative mode. Prints processing information.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. Default is 0 and 20.0 (no optimal sampling with fineness
        of 20.0 (real number)).
@\item
  {\bf -R RelStepSize}:  Relative control (default to 1.0) on the step size
        taken during the numerical marching on the surfaces in the different
        strokes' patterns.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve. 
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -r}: Selects the rendering model of the shader as follows:
@   \begin{enumerate}
@   \item[]
        1. Dumps only the uniform point distribution.
@   \item[]
        2. Cosine shader, diffuse only, light source regular.
@   \item[]
        3. Cosine shader, diffuse only, light source as two lights from
                                                         opposite directions.
@   \item[]
        4. Cosine shader, has specular term, light source regular.
@   \item[]
        5. Cosine shader, has specular term, light source as two lights.
@   \item[]
        6. Shader emphasizing the silhouette areas of the model.
@   \item[]
        7. Shader estimating distance decay from a point light source.
@   \end{enumerate}
@\item
  {\bf -c CosPower}: Controls the cosine shader's power.
@\item
  {\bf -s SdrPower}: Controls the shader's relative influence.
  {\bf -i Intensity}: Controls the global density of the constructed line art.
        The larger Intensity is, the denser the drawing becomes.
@\item
  {\bf -l Lx Ly Lz}: Sets the light source position/direction.
@\item
  {\bf -v Vx Vy Vz}: Sets the viewing direction; typically, the Z axis.
@\item
  {\bf -w Width}: Sets the width of the generated strokes.
@\item
  {\bf -d Density}: Relative control (default to 1.0) of the density of the
        uniform point distribution from which the strokes are developed.
@\item
  {\bf -t SrfZTrans}: Amount of created line strokes in Z to translate,
        in order to prevent Z from fighting with the rendered object itself.
@\item
  {\bf -S WidthScale}:  Controls the relative variance of the width of the
        strokes in variable width strokes.
@\item
  {\bf -T Textures}:  Selects the pattern of the strokes. Texture can be one
        of:
@    \begin{enumerate}
@    \item[]
            1. "isoparam[,{0,1,2}w]":  Isoparametric curves will be created in
               a similar way to the aisoshad tool.  Following the "isoparam"
               string, one can optionally specify the isoparametric direction
               as 0, 1 or 2 for U, V, or both, and a second 'w' character for
               optional variable width.  This option extracts exact
               isoparametric curves from the given surface.
@    \item[]
            2. "wood[,Dx,Dy,Dz]":  A strokes' style following layers of wood
               will be used.  Optionally, a direction normal to the layers
               can be specified, with a default being the Z axis.
@    \item[]
            3. "vood[,Ry,Rz]":  A variation on the wood texture, this time with
               a layered orientation set via two rotation angles around Y and
               Z.
@    \item[]
            4. "isomarch[,{0,1,2}]":  Similar to "isparam" but numerically
               march on the surface in the isoparametric direction.  Again,
               0, 1, or 2 stands for U, V, or both isoparametric directions.
@    \item[]
            5. "silhouette[,{t,n,tn}]":  Extract strokes emphasizing the
               silhoeutte areas from the given viewing direction.  Strokes
               can be extracted in the direction of the surface normal near
               the silhouette area if option ",n" is given, tangent along
               the surface if ",t", or both if ",tn".
@    \item[]
            6. "iTexture":  Employ a raster image as a texture image on the
               surface with the gradient of the image serving as the strokes
               direction. The name of the image itself (must be in urt rle
               format) is expected in a "iTexture" attribute on the specific
               object.
@    \item[]
            7. "curvature[,{0,1,2}]":  Develop strokes along lines of
               curvatures.  Strokes are developed along the minimal curvature
               if ",0", the maximal curvature if ",1", and both if ",2".
@    \item[]
            8. "CurveStroke":  An XY curve object is expected as a
               "CurveStroke" attribute on the same object and serves as a
               specification of motion in the parametric space of the surface
               for each given point.              
@    \end{enumerate}
@\item
  {\bf -Z ZbufSize}: ZbufSize sets the size of the (square) Z buffer to set.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
        strokes.  Otherwise, an {\em IRIT} text file will be created.
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    lineshad is a simple line art illustration tool that generates strokes
 that follow the isoparametric curves. It processes freeform geometry such
 as surfaces, and dumps geometry with attributes that makes
 nice line illustrations. lineshad is geared mainly toward its use with
 irit2ps to create postscript illustrations. Here is a simple example:

@\begin{verbatim}
 lineshad -Z -500 -F 0 50 -T "isoparam" -d 0.5 -c 10 -r 2 wglass.itd view.imd |
 irit2ps -W 0.002 -u - > wglass3.ps
@\end{verbatim}

 creates line art illustrations of a wine glass {\bf wglass.itd} with
 hidden strokes removal via a Z-buffer of size 500 that will be displayed on
 screen, polygonal fineness of 50 for the surface of the glass, shader that
 employs isoparametric curves, relative density of distribution of 0.5, and
 cosine power of 10 of the cosine shader number 2.
@Figure~\ref{fig-lineshad}~(a) shows the result of this example.

 Here is another example: 
@\begin{verbatim}
 lineshad -Z -500 -F 0 50 -T "wood,1,1,1" -d 6 -c 10 -r 2 wglass.itd view.imd |
 irit2ps -W 0.002 -u - > wglass4.ps
@\end{verbatim}

 creates line art illustrations of a wine glass {\bf wglass.itd} with
 hidden strokes removal via a Z-buffer of size 500 that is allocated off-line
 in core memory, polygonal fineness of 50 for the surface of the glass,
 a light source at (1, 1, 1) for the wood strokes' style, relative point
 distribution of 6, and a cosine power of 10 for the cosine shader number 2.
@Figure~\ref{fig-lineshad}~(b) shows the result of this example.

 Transparent objects, or objects with the "transp" attribute, will generate
 strokes as regular surfaces but will not participate in the hidden strokes
 removal.   A string "itexture" attribute is expected if "itexture" strokes'
 style is used.  A curve object as the "CurveStroke" attribute is expected if
 "CurveStroke" is employed.  One can override the strokes' style as it is set
 via the '-T' command line option by setting an "lTexture" string attribute
 with the prefered strokes' style of this object.  One can modify the relative
 density of some specific object by placing a real number attribute named
 "PtsDensity" on the object.

 See also the {\bf illustrt}, {\bf izebra}, {\bf aisoshad}, and
 {\bf irit2ps} tools.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{ihidden - Hidden Curve Removing Program}
!ihidden - Hidden Curve Removing Program

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


@\subsection{Introduction}
&Introduction

    ihidden is a program to remove hidden curves from a given surface model.
 Only freeform objects are processed in ihidden.
@See Figure~\ref{fig-ihidden} for some output examples which use this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/hglass.ps, width=2.7in} &
@    \epsfig{file=user_man/halgsum.ps, width=3.5in}
=    <BR clear=all>
=    <img hspace=2 width=250 src="user_man/hglass.gif">
=    <img hspace=2 width=250 src="user_man/halgsum.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all>  FIGURE:
-      Some examples of the use of hidden curve removal tool, ihidden, to
-      remove hidden curves.
=</b><BR clear=all>
@}
@\label{fig-ihidden}
@\end{figure}

    The program performs 3 passes over the input:

 1. Preprocesses and extracts the different curves in a scene, boundary curves,
    silhouette curves, isoparametric curves and discontinuity curves.

 2. Solves for all the intersections of the different curves in the parametric
    space, and at that point splits the curves into curve segments.

 3. Applies a visibility test to each segment of curve.
 
    This program can handle non self interesecting surfaces only.  Further,
 surfaces that intersect other surfaces and are not properly trimmed into
 a model are likely to result in the wrong answer as well.

    The output of ihidden is in the form of curves. It is a regular
 {\em IRIT} data file that can be viewed using any of the display
 devices, for example.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
 ihidden [-q] [-H] [-I #UIso[:#VIso[:#WIso]]] [-s Stage] [-b]
         [-o OutName] [-C CCTTol] [-S RSITol] [-Z ZBufSz] [-t AnimTime]
         [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -q}: Quiet - provides no information on the progress if TRUE.
@\item
  {\bf -H}: Dumps both visible lines and hidden curves as separated objects.
       Hidden curves will be dumped using a narrower line width.
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
       surface/trivariate, per direction. If \#VIso is not specified,
       \#UIso is used for \#VIso as well and so on.
@\item
  {\bf -s}: Specifies the step at which to stop this process, where step 3, as
       described above, will complete the entire hidden curve removal
       process and is the default.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
       strokes.  Otherwise, an {\em IRIT} text file will be created.
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -C CCTTol}: Tolerance of the curve curve intersection (CCI) process.
@\item
  {\bf -S RSITol}: Tolerance of the surface fineness in the ray surface
       intersection (RSI) and visibility testing process as well as in the
       silhouette extraction.
@\item
  {\bf -Z ZBufSz}: Size of the Z buffer in the visibility testing process.
@\item
  {\bf -c}: Clips data to screen (default). If disabled ('-c-'), data
       outside the view screen ([-1, 1] in x and y) are also processed.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

   Some of the options may be turned on in ihidden.cfg. They can then be
 turned off in the command line as '-?-'.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Configuration}
&Configuration
 
   The program can be configured using a configuration file named ihidden.cfg.
   This is a plain ASCII file you can edit directly and set the parameters
 according to the comments there. 'ihidden -z' will display the current
 configuration as read from the configuration file.

   The configuration file is searched in the directory specified by the
 IRIT\_PATH environment variable. For example,
 'setenv IRIT\_PATH /u/gershon/irit/bin/'.
   If the IRIT\_PATH variable is not set, the current directory is searched.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

   As this program is not interactive, usage is quite simple, and the only
 control available is using the command line options.

@The images in Figure~\ref{fig-ihidden} were created using the following
@commands:
@\begin{verbatim}
@    ihidden ih_glass.itd | irit2ps -d -W 0.02 - > ih_glass.ps
@    ihidden -H ih_wiggl.itd | irit2ps -d -W 0.02 - > ih_wiggl.ps
@\end{verbatim}

   If a certain surface should contain more or less isoparametric curves,
 a relative change could be applied to some specific object via the
 "num\_of\_isolines" attribute.  If a "transp" attribute is found on some
 object, it will generate all the curves but will not affect the visibility
 (i.e. be fully transparent).

   See also Poly3d-h.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\section{Irender - Simple Scan Line Renderer}
!Irender - Simple Scan Line Renderer

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@\subsection{Introduction}
&Introduction

    irender is a program to render {\em IRIT} scenes into images. It is
 a software based Z buffer that is able to create images in few formats.
 Several of its features includes parametric and volumetric texture mapping,
 shadow computations, transparency and antialiasing.

 Freeform objects are preprocessed into polygons with controlled fineness.
@See Figure~\ref{fig-irender} for some output examples of using this tool.
@\begin{figure}
@\begin{center}
@\begin{tabular}{cc}
@    \epsfig{file=user_man/molecul2.ps, width=2.7in} &
@    \epsfig{file=user_man/glass.ps, width=2.7in} 
=    <BR clear=all>
=    <img hspace=2 src="user_man/molecul2.gif">
=    <img hspace=2 src="user_man/glass.gif">
=    <BR clear=all>
@\end{tabular}
@\end{center}
@\caption{
=<b><BR clear=all> FIGURE:
-       Some examples of the use of irender scan convertion tool to render
-       images of {\em IRIT} scenes.  Highlights can be seen in the
-       molecule image while the glass is rendered transparent.
=</b><BR clear=all>
@}
@\label{fig-irender}
@\end{figure}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irender [-v] [-s XSize YSize] [-Z Znear Zfar] [-a Ambient] [-b R G B] 
          [-B] [-F PolyOpti FineNess] [-f PolyOpti SampPerCrv]
          [-M Flat/Gouraud/Phong/None] [-p PtRad] [-P WMin [WMax]] [-S]
          [-T] [-t AnimTime] [-N ClrQuant SilWidth [SilR SilG SilB]]
          [-A FilterName] [-d] [-l] [-n] [-i rle/ppm{3,6}] 
          [-o OutName] [-z] files
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -v}: Verbose mode. Prints informative messages as it progresses.
@\item
  {\bf -s XSize YSize}: Sets the size of the output image, in pixels.
        Default to 512x512.
@\item
  {\bf -Z Znear Zfar}: Sets the near and far cliping planes with default
        of no clipping.
@\item
  {\bf -a Ambient}: Sets the ambient lighting fraction. Between zero (no
        ambient lighting) and one. Default to 0.2.
@\item
  {\bf -b R G B}: Sets the background color. Each of thre R,G,B colors is
        an integer value between zero and 255. Default to black.
@\item
  {\bf -B}: Apply back face culling. Somewhat faster, but only correct for
        closed objects. Default is no back face culling.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. Default is 0 and 20.0 (no optimal sampling with fineness
        of 20.0 (real number)).
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve. 
        Default is 0 64 (uniform sampling with 64 samples). 
@\item
  {\bf -M Flat/Gouraud/Phong/None}: Selects the shader to be used. Default to
        Phong if has normals of vertices, Flat if no normals are found.
        The None options exactly paints the objects with the given color,
        applying no shader.
@\item
  {\bf -p PtRad]}: Width of rendered points (as spheres).
@\item
  {\bf -P WMin [WMax]}: Width of rendered polyline, in world units. If only
        WMin is specified, all polylines are set to have WMin width. Otherwise,
        if WMax is prescribed as well, polylines' width is set to be
        proportional to their depth with WMax is the width of closest polyline
        and WMin the farest polyline.  Polylines and curves will be
        {\em ignored} without the setting of this option.
@\item
  {\bf -S}: Enable shadow computation. No shadows will be rendered without -S.
        The is no shadow support for this release of irender.
@\item
  {\bf -T}: Enable transparency computation. No transparent object will be
        processed without -T.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
        process the scene at time AnimTime.
@\item
  {\bf -N ClrQuant SilWidth [SilR SilG SilB]}: Requests cartooN style
        NPR rendering.  Two effects could be activated using this option:
        the colors could be quantized into {\bf ClrQuant} levels or,
        alternatively a value of zero for {\bf ClrQuant} denotes no
        quantization.  Also, open boundaries and silhouettes could be
        rendered if {\bf SilWidth} > 0.0 at {\bf SilWidth} polyline
        width and optional color {\bf SilR SilG SilB}.
@\item
  {\bf -A FilterName}: Selects an antialiasing filter. FilterName can be one
        of 'none', 'box', 'triangle', 'quadratic', 'cubic', 'catrom',
        'mitchell', 'gaussian', 'sinc, and 'bessel'. Default is 'none'.
@\item
  {\bf -d}: Output will be in the form of Z depth instead of a color image.
        Output will be 32 bits depth instead of RGBA.
@\item
  {\bf -n}: Reverses the normals of vertices and planes, globally.
@\item
  {\bf -i rle/ppm\verb+{+3,6\verb+}+}: Selects output image type. Currently the
        Utah Raster Toolkit's (URT) rle format is being supported as well as
        the PPM format.  PPM can be either P6 or P3 style.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
        stdout.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

   Some of the options may be turned on in irender.cfg. They can be then
 turned off in the command line as '-?-'.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Configuration}
&Configuration
 
   The program can be configured using a configuration file named irender.cfg.
   This is a plain ASCII file you can edit directly and set the parameters
 according to the comments there. 'irender -z' will display the current
 configuration as read from the configuration file.

   The configuration file is searched in the directory specified by the
 IRIT\_PATH environment variable. For example,
 'setenv IRIT\_PATH /u/gershon/irit/bin/'.
   If the IRIT\_PATH variable is not set, the current directory is searched.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

   As this program is not interactive, usage is quite simple, and the only
 control available is using the command line options.

@The images in Figure~\ref{fig-irender} were created using the following
@commands:
@\begin{verbatim}
@    irender -s 350 350 -b 255 255 255 -S -A sinc -i rle lightsrc.itd
@                                     molecule.itd view_mat.itd > molecule.rle
@    irender -s 700 700 -F 0 64 -M Flat -b 255 255 255 -T -A sinc -i rle
@                                     glass.itd view_mat.itd > glass.rle
@\end{verbatim}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify several attributes that affect the way the scene is
 rendered. The attributes can be generated within {\em IRIT}.
 See also the ATTRIB {\em IRIT} command.

   Surface color is controlled on two levels. If the object has an RGB
 attribute, it is used. Otherwise, a color as set via the {\em IRIT}
 COLOR command.  If a vertex of a poly object has an RGB attribute it
 will overwrite the object's RGB color for that vertex.

   If a certain surface should be finer/coarser than the rest of the
 scene, one can set a "resolution" attribute which specifies the
 {\em relative} FineNess resolution of this specific surface. Further,
 "u\_resolution" and "v\_resolution" might be similarly used to set
 relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.
   Points are rendered as small spheres with size (radius) that is controlled
 by the "width" attribute found on the object or the radius that is specified
 by the '-p' option as default size.

   Objects are rendered with no shading if "NoShading" attribute is found on
 them.

 Example:

@\begin{verbatim}
 attrib( Ball, "rgb", "255,0,0" );
 color( Sphere, white );
@\end{verbatim}

    The cosine exponent of the phong shader can be set for a specific
 object via the SRF\_COSINE attribute, with 128 as default value.
 An object can affect its diffuse and specular components via the
 DIFFUSE and SPECULAR real attributes, with 0.4 as default value.

 Example:

@\begin{verbatim}
 attrib( Ball, "srf_cosine", 16 );
 attrib( Ball, "diffuse", 0.7 );
 attrib( Ball, "specular", 1.0 );
@\end{verbatim}

    An object can be drawn transparent instead of opaque, if it has a
 "transp" attribute. A transparent value of one denotes a completely
 transparent object, while a value of zero means a completely opaque
 object. Transparent objects will be rendered as such if and only if the '-T'
 command line option is set.

 Example:

@\begin{verbatim}
 attrib( final, "transp", 0.5 );
@\end{verbatim}

    An object can have its silhouettes (and boundary curves) rendered if a
 real "SilWidth" attribute with width larger than zero is specified. 
 "SilColor" will then set the color of the rendered outline curves.  See
 also '-N' which sets this option globally.

    Several types of texture mapping are supported. Parametric texture may be
 attached to a parametric surface where the prescribed image is mapped onto
 the rectangular parametric domain of the surface.

 The parametric texture may be applied with the following options:
# 16 2 0 1
 'D' x y z
  Vector that will be rotated to Z along with the
 
  texture coordinates. Applies to 'T' 1, 2 or 3.
 
  Default to the Z axis.
 'O' x y z
  a point to which that texture Origin will be translated.
 
  Applies to 'T' 1, 2 or 3. Default to origin.
 'S' Su Sv \{Sw\}
  Scales the coordinates in u and v.  Scale
 
  factors of 1.0 would cover the entire surface
 
  once.  Default to scale factors of 1.0.  If Sw is
 
  specified for a polygonal object, each polygonal is
 
  {\em locally} scaled based on its maximal projection on
 
  one of the main, XY XZ or YZ, planes.
 'A' a
  Angle of rotation in degrees of texture map with
 
  respect to main axis.  Applies to 'T' 1, 2 or 3.
 
  Default to no rotations.
 'T' TextureType
  with 0 denotes regular parametric texture,
 
       1 denotes spherical coordinates,
 
       2 denotes spherical bijective coordinates,
 
       3 denotes cylinderical coordinates,
 
       4 denotes planar coordinates.
#

 Regular parametric texture employs the inherited surface parametrization
 of the freeform surface and can only be used on parametric surfaces.

 Spherical, cylinderical, and planar coordinate transformations are useable
 for all types of geometry from polygons to freeform surfaces and is
 fairly straightforward with the origin as set by 'O' being the center
 of the mapping while the direction set by 'D' controls the north pole
 of the sphere,  the axis of the cylinder, and the normal of the plane.
 Finally, the angle set by 'A' rotates the texture around this 'D' prescribed
 axis.

 The spherical bijective mapping is more complex.  An object identical 
 to the textured object should be found as an "PTextureBijectObj" that
 contains the identical topology of the original object.  The original
 object must be genus zero non convex, while the attribute object must be
 a genus zero convex object with the origin as set via 'O', inside this
 convex object.   It is likely that both the original object and its attribute
 object will be a polygonal object.  Both objects must contain triangles only.

 A bijective mapping is then conducted from every point on the original
 non convex object to the convex attribute object and from there through
 spherical mapping to the texture map.


 Example:

@\begin{verbatim}
 attrib( Srf1,        "ptexture", "checker.ppm, S 1 1, A 45" );
 attrib( Srf2,        "ptexture", "checker.ppm, S 1 3, T 1, O 1 1 1, D 0 0 1" );
 attrib( Srf3Triangs, "ptexture", "checker.ppm, S 1 2, T 1, O 1 1 1, D 0 0 1" );
 attrib( Srf3Triangs, "PTextureBijectObj", Srf3ConvexTriangles );
@\end{verbatim}

 {\bf Srf1} is a parametrically textured map using spherical mapping,
 {\bf Srf2} is a parametrically textured map using cylinderical
 mapping and {\bf Srf3Triangs} is a parametrically textured map using 
 spherical bijective mapping and Srf3ConvexTriangles is the convex
 topologically equivalent object.

 The program will automatically detect a ppm file from an rle according to
 the file's name.  Note that regular parametric texture may be applied to
 parametric surfaces only, whereas the spherical, cylinderical and planar
 parametric textures may be used on all types of geometry.

 A second type of texture mapping can be applied to all geometric objects.
 Herein, a procedural texture mapping is employed. The currently supported
 textures are

# 14 2 0 1
 camouf
  Camouflage style
 checker
  Checker style
 chocolate
  Chocolate chips style
 contour
  Parallel plane contouring
 curvature
  Gaussian/Mean etc. curvature
 marble
  Marble style
 ncontour
  Constant normal angle to major axis
 orange
  Bump mapping orange style
 wood
  Wood style
 punky
  Colorful punky style
#

 A second parameter that must be provided for procedural textures is the
 scaling factor of the texture, which can be either one parameter of uniform
 scaling or a vector of three coefficients for scaling in x, y, and z.
 For {\bf contour} style, the scale denotes the spacing of the contouring
 planes in X, Y and Z.  For {\bf ncontour} style, the scale also denotes
 the spacing of the adjacent constant normal contours.  Related attributes
 are "texture\_color" and "texture\_width" that support the color and the
 width of the textured strokes.

 Example:

@\begin{verbatim}
 attrib( Obj1, "texture", "marble, 2" );
 attrib( Obj2, "texture", "wood, 1 0.5 2.5" );
@\end{verbatim}

 which sets {\bf Obj1} to have a marble procedural texture with a uniform
 scaling factor of 2 and a wood texture for {\bf Obj2} with scaling factors
 of (1, 0.5, 2.5) in x, y, and z.

 In addition, the appearance of each procedural texture can be controlled by
 optional parameters which are different for each texture. Each texture
 parameter is recognized by a letter; to enter a parameter, add to the
 attribute string the paramter letter followed by the value or values. Each
 parameter should be separated by a comma.

 Example:

@\begin{verbatim}
 attrib( Obj1, "texture", "wood, 2, b 0.3, o 5 5 5" );
@\end{verbatim}

 sets {\bf Obj1} to have a wood procedural texture with a scaling factor
 of 2, a Brightness level of 0.3, and the Origin point at (5,5,5).

 The optional parameters are:

 {\bf checker:}
# 14 2 0 1
 'z' x y z
  a vector to which the Z axis will be rotated.
 'o' x y z
  a point to which the Origin will be translated.
 'b' x
  the brightness of the checker color scaling,
 
  should be between 0 and 1.
 'CP' f
  To force a 2D checker plane orthogonal to the
 
  vector that is specified via the 'z' option.
 'C1' r g b
  A second optional color for the checkerboard.
 'C2' r g b
  A third optional color for the checkerboard,
 
  used in the second layer of the checker volume.
 'C3' r g b
  A fourth optional color for the checkerboard,
 
  used in the second layer of the checker volume.
#

 {\bf chocolate:}
# 14 2 0 1
 'W' w
  the 'width' of chocolate piece (zero to half).
 'd' x
  the 'depth' of the bumps on the bump-mapping.
#

 {\bf contour:}
# 14 2 0 1
 'W' w
  the 'width' of contour.
 'C' r g b
  the color of the contour in RGB betweeo zero
 
  and one ("C 1 1 1" fully is white).
#

 {\bf curvature:}

 The curvature texture has no optional parameter, but the first scale
 parameter has a special meaning.  A scale of
# 10 2 0 1
 0
  Paints convex regions in red, concave in
 
  green, and saddle-like in yellow.
 $>$0
  Paints the Gaussian curvature in convex regions
 
  in red to magenta, in concave regions in yellow
 
  to green, and in saddle-like in cyan to blue.
 $<$0
  Paints the Mean curvature in positive mean
 
  curvature regions in yellow to green and in
 
  negative Mean curvature in red to magenta.
#
 If this first scale parameter is non zero, its absolute value is used to
 modify the blending speeds between the different colors.

 {\bf marble:}
# 14 2 0 1
 'z' x y z
  a vector to which the Z axis will be rotated.
 'o' x y z
  a point to which the Origin will be translated.
 't' f s
  the scale of the turbulence noise, and the
 
  factor to multiply that noise.
 'f' x
  the 'frequency' of the marble layers.
#

 {\bf ncontour:}
# 14 2 0 1
 'W' w
  the 'width' of contour.
 'C' r g b
  the color of the contour in RGB betweeo zero
 
  and one ("C 1 1 1" fully is white).
#

 {\bf orange:}
# 14 2 0 1
 'd' x
  the 'depth' of the bumps on the bump-mapping.
#

 {\bf wood:}
# 14 2 0 1
 'z' x y z
  a vector to which Z axis will be rotated.
 'o' x y z
  a point to which the Origin will be translated.
 'b' x
  the brightness of the wood color scaling,
 
  should be between 0 and 1.
 'c' f s
  the scale of the noise in the wood center axis
 
  and the factor by which to multiply that noise.
 'w' n f
  the number of angles to sample noise when creating
 
  distortion in the circle shape of the wood
 
  cylinders, and the factor by which to multiply that noise.
 'f' x
  the 'frequency' of the wood cylinders.
 'r' f s
  the scale of the wood-fibers noise, and the
 
  factor by which to multiply that noise.
#

 {\bf punky:}
# 14 2 0 1
 'b' x
  the brightness/saturation of the punky color.
#

 More Examples:

@\begin{verbatim}
 attrib( Obj1, "texture", "marble, 2, t 3.0 12.0, f 7.0" );
 attrib( Obj2, "texture", "contour, 1 0.5 2.5, W 0.004, C 1 1 0" );
@\end{verbatim}

 sets {\bf Obj1} to have a marble procedural texture with a uniform
 scaling factor of 2, and new turbulance and frequency factors.
 This also sets a contouring texture for {\bf Obj2} with scaling
 factors of (1, 0.5, 2.5) in x, y, and z, in yellow color and width 0.004.

 In addition, a scalar surface spanning the same parameteric domain as an
 original surface may be used as a texture mapping function.  Herein, the
 scalar function texture is evaluated at each UV parameter value and is mapped
 through a color scale to yield the output color.  This type of texture is
 useful for stress maps or analysis maps on top of freeform surfaces.
   Several related attributes are supported: "stexture\_scale" which prescribes
 the color scale image (only its first column is employed), and
 "stexture\_bound" that sets the domain that will be clipped to the min max
 values. Funally, "stexture\_func" can hold the functions "sqrt" or "abs"
 to be applied to the evaluated surface value.

 Example:

@\begin{verbatim}
 attrib( Srf, "stexture", scrvtr( Srf, P1, off ) );
 attrib( Srf, "stexture_scale", "color_scale.ppm" );
 attrib( Srf, "stexture_func", "sqrt" );
 attrib( Srf, "stexture_bound", "0.0 100.0" );
@\end{verbatim}

 where scrvtr computes a scalar field to {\bf Srf} that represents the
 sum of the squares of the principle curvatures.  The evaluated scalar
 texture surface's value is piped through a sqrt function.
 The first column of the image of {\bf color\_scale.ppm} is used to set
 the coloring scale for curvature bounds values between 0.0 and 100.0.

 Both "stexture\_scale" and "stexture\_bound" are optional.  The default
 color scale maps the min/max values from blue to red through green. The
 default scalar surface texture bound is computed as the extreme values of
 the "stexture" surface.

 While the program has a default for lighting which is two light sources
 at opposite directions at (1, 1, 1) and (-1, -1, -1), one can overwrite
 this default. A POINT\_TYPE object with LIGHT\_SOURCE attribute denotes
 a light source.  If irender detects one or more light sources in the
 input stream, the default light sources are not created. Two types of
 light sources may be prescribed, a parallel at infinity or a point at a
 finite distance light source, distinguished by a TYPE attribute of
 either POINT\_POS or POINT\_INFTY. A point light source can be colored;
 an RGB attribute will set its color. A point light source will cast
 shadows, if and only if, it has a SHADOW attribute (one needs to apply the
 '-S' command line option as well for rendering shadows). Finally, one can
 construct two mirrored light sources at opposite directions if the TWOLIGHT
 attribute is added to the light source object.

 Example:

@\begin{verbatim}
    Light1 = point( 0, 0, 10 );
    attrib( Light1, "light_source", on );
    attrib( Light1, "shadow", on );
    attrib( Light1, "rgb", "255,0,0" );
    attrib( Light1, "type", "point_pos" );

    Light2 = point( 1, 1, 1 );
    attrib( Light2, "light_source", on );
    attrib( Light2, "twolight", on );
    attrib( Light2, "type", "point_infty" );
@\end{verbatim}

 constructs two lights sources with {\bf Light1} with red color positioned
 at (0, 0, 10) and casting shadows, while {\bf Light2} will create two
 mirrored white parallel lights sources in the direction of (1, 1, 1) and
 (-1, -1, -1), as its irender's default.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{3DS2Irit - AutoCad 3DS Data To IRIT file filter}
!3DS2IRIT - AutoCad 3DS Data To IRIT file filter

  Converts '.3ds' data files to '.itd' {\em IRIT} data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   3ds2Irit [-m] [-c ClrScale] [-o OutName] [-b] [-z] 3DSFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -m}: More information flag.
@\item
  {\bf -c ClrScale}:  Scaling the color values (intensity control).
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
        stdout.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
        strokes.  Otherwise, an {\em IRIT} text file will be created.
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    3ds2irit converts Autocad's 3DS data files into {\em IRIT} data files.  The
 current version provides only partial support, mainly due to lack of
 documentation examples on the dxf format and the convoluted way
 freeform surfaces are saved.

 Example:

@\begin{verbatim}
    3ds2irit file.3ds > file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Dat2Bin - Data To Binary Data file filter}
!DAT2BIN - Data To Binary Data file filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   dat2bin [-t] [-z] {[-c QuantVal]} DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -t}: Dumps data to stdout as text instead of binary.
  {\bf -z}: Print version number and current defaults.
  {\bf -c}: Optional option that is available only if compressed binary files
            are supported.  Dumps data to stdout as compressed binary file
            with a quanitization level of QuantVal.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    The user may sometimes wish to convert .itd data files into a binary form,
 for example, for fast loading of files with large geometry. Binary files can
 be somewhat larger and are unreadable in editors but are much faster to load.
 A binary file must have a '.ibd' file type.

 Example:

@\begin{verbatim}
   dat2bin b58polys.itd > b58polys.ibd
   dat2bin -t b58polys.ibd | more
@\end{verbatim}

 The above converts a text file b58polys.itd into a binary file b58polys.ibd
 and shows the content of the binary file by converting it back to text. At
 this time data through pipes must be in text. That is, the following is
 {\em illegal}:

@\begin{verbatim}
   dat2bin b58polys.itd | xglmdrvs -
@\end{verbatim}

 It should be remembered that the binary format is not documented and
 it might change in the future. Moreover, it is machine dependent and can
 very well may be unreadable between different platforms.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Dat2Irit - Data To IRIT file filter}
!DAT2IRIT - Data To IRIT file filter

  Converts '.itd' and '.ibd' data files to '.irt' {\em IRIT} scripts.
  Optionally, if compressed binary files are supported, also handle
 '.icd' compressed data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   dat2irit [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Users may sometimes wish to convert .itd data files into a form that
 can be fed back to {\em IRIT} - a '.irt' file. This filter does exactly that.

 Example:

@\begin{verbatim}
   dat2irit b58.itd > b58-new.irt
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Dxf2Irit - DXF (Autocad) To IRIT filter}
!DXF2IRIT - DXF (Autocad) To IRIT filter

 Converts Autocad's, DXF data files into IRIT data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
   dxf2irit [-m] [-f] [-o OutName] [-z] DXFFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -m}: Provides some more information on the data file(s) parsed.
@\item
  {\bf -f}: Coerces floating end conditions to constructed freeform surfaces.
        Default is open end conditions.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    dxf2irit converts Autocad's DXF data files into {\em IRIT} data files.
 The current version provides only partial support for the conversion of
 freeform surfaces, mainly due to lack of documentation examples on the
 dxf format and the convoluted way freeform surfaces are saved.

 Example:

@\begin{verbatim}
 dxf2irit file.dxf > file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{IGS2Irit - IGES Data To IRIT file filter}
!IGS2IRIT - IGES Data To IRIT file filter

  Converts '.igs' data files to '.itd' {\em IRIT} data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   IGS2Irit [-m] [-M] [-c] [-a] [-s] [-o OutName] [-b] [-z] IGSFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -m}: More information flag.
@\item
  {\bf -M}: Even more information flag - dumps all parsed entities.
@\item
  {\bf -c}: Clips trimmed surfaces to the minimal domain as prescribed by the
       trimming curves.
@\item
  {\bf -a}: Dumps all.  Without this flag setting, only top level objects,
       that are referenced by no other object, will be dumped out.
@\item
  {\bf -s}: Dumps surfaces only.  When set only (trimmed) surfaces are dumped.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -b}: If set, generates a binary {\em IRIT} data file that holds the
        strokes.  Otherwise, an {\em IRIT} text file will be created.
@\item
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    igs2irit converts IGES data files into {\em IRIT} data files.

 Example:

@\begin{verbatim}
    igs2irit file.igs > file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Dxf - IRIT To DXF (Autocad) filter}
!IRIT2DXF - IRIT To DXF (Autocad) filter
 
 Converts IRIT data files into Autocad's, DXF data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
    irit2dxf [-s Scale] [-t Tx Ty Tz] [-i] [-f] [-F PolyOpti FineNess]
             [-4] [-o OutName] [-T] [-a AnimTime] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -s Scale}: Global scaling factor of the converted geometry.
@\item
  {\bf -t Tx Ty Tz}: a Vector of size three of translation factors along
        the X, Y, and Z axes.
@\item
  {\bf -i}: Shows internal edges as well.
@\item
  {\bf -f}: Dumps freeforms as converted polygonal geometry.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -4}: Forces four polygons per almost flat region in the surface to
       polygon conversion. Otherwise two polygons only.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -a AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    irit2dxf converts {\em IRIT} data files into Autocad's DXF data files.  The
 current version provides only partial support for the direct conversion of
 freeform surfaces, mainly due to lack of documentation examples on the
 dxf format and the convoluted way freeform surfaces are saved.  Nonetheless,
 freeform surfaces can be converted into polygons using the '-f' flag.

 Example:

@\begin{verbatim}
 irit2dxf -z -t 1 2 3 -F 0 20 -4 -o file.dxf file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Hgl - IRIT To HPGL filter}
!IRIT2Hgl - IRIT To HPGL filter
 
 Converts IRIT geometry into the HL Graphics Language used by HP's plotters.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
  irit2hgl [-t XTrans YTrans] [-I #UIso[:#VIso[:#WIso]]]
       [-f PolyOpti SampTol] [-F PolyOpti FineNess] [-M] [-G] [-T]
       [-a AnimTime] [-i] [-o OutName] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -t XTrans YTrans}: X and Y translation. of the image. Default is (0, 0).
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
        surface/trivariate, per direction. If \#VIso is not specified,
        \#UIso is used for \#VIso as well and so no.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples). 
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4. This enforces the dump of freefrom geometry
        as polygons.
@\item
  {\bf -M}: Dumps the control mesh/polygon as well.
@\item
  {\bf -G}: Dumps the freeform geometry.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -a AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -i}: Internal edges (created by {\em IRIT}) - default is not to
       display them, and this option will force their display.
@\item
  {\bf -o OutName}: Name of output file. By default the name of the first data
       file from {\em DFiles} list is used.  See below on the output files.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Hgl converts freeform surfaces and polygons into polylines in a format
 that can be used by HPGL.
  
 Example:
 
@\begin{verbatim}
 irit2Hgl -M -f 0 16 saddle.itd > saddle.hgl
@\end{verbatim}

   However, one can overwrite the viewing matrix by appending a new matrix
 in the end of the command line, created by the display devices:

@\begin{verbatim}
 x11drvs b58.itd
 irit2Hgl -M -f 0 16 b58.itd irit.imd > saddle.hgl
@\end{verbatim}

 where irit.imd is the viewing matrix created by x11drvs.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2IGS - IRIT To IGES filter}
!Irit2IGS - IRIT To IGES filter
 
 Converts {\em IRIT} data files into IGES/IGS data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
     Irit2igs [-m] [-o OutName] [-t AnimTime] [-u] [-z] IritFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -m}: More information flag.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -t AnimTime}: If has animation data, time of dump.
@\item
  {\bf -u}: Forces a unit transformation matrix.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2IGS converts {\em IRIT} data files into IGES data files.

 Example:

@\begin{verbatim}
    Irit2IGS -u -o file.igs file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Iv - IRIT To SGI's Inventor filter}
!IRIT2IV - {\em IRIT} To SGI's Inventor filter

 IV is the format used by the Inventor modeling/rendering package from SGI.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2iv [-l] [-4] [-P] [-F PolyOpti FineNess] [-f PolyOpti SampTol]
                                              [-T] [-t AnimTime] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       by a single polygon along their linear direction.
       Although most of the time linear direction can be represented exactly
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
       Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -P}: Polygonize freeform shapes. Default is to leave freeform curves
       and surfaces as is.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples). 
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Iv converts freeform surfaces and polygons into polygons and
 saved in iv Inventor's ASCII file format.
  
 Example:
 
@\begin{verbatim}
 irit2iv solid1.itd > solid1.iv
@\end{verbatim}

    Surfaces are converted to polygons with fineness control:
  
@\begin{verbatim}
 irit2iv -F 0 16 - view.imd < saddle.itd > saddle.iv
@\end{verbatim}

    Note the use of '-' for stdin.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Nff - IRIT To NFF filter}
!IRIT2NFF - {\em IRIT} To NFF filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2nff [-l] [-4] [-c] [-F PolyOpti FineNess] [-o OutName] [-T]
                                           [-t AnimTime] [-g] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       by a single polygon along their linear direction.
       Although most of the time linear direction can be represented exactly 
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
       Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -c}: Output files should be filtered by cpp. When set, the usually
       huge geometry file is separated from the main nff file that contains
       the surface properties and view parameters. By default all data,
       including the geometry, are saved into a single file with type extension
       '.nff'. Use of '-c' will pull out all the geometry into a file with
       the same name but a '.geom' extension, which will be included using the
       '\#include' command. The '.nff' file should, in that case, be
       preprocessed using cpp before being piped into the nff renderer.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -o OutName}: Name of output file. By default the name of the first data
       file from the {\em DFiles} list is used.  See below on the output files.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -g}: Generates the geometry file only. See below.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Nff converts freeform surfaces into polygons in a format that can
 be used by an NFF renderer. Usually, one file is created with the '.nff' type
 extension. Since the number of polygons can be extremely large, a '-c'
 option is provided, which separates the geometry from the surface
 properties and view specification, but requires preprocessing by cpp.
 The geometry is isolated in a file with the extension '.geom' and included
 (via '\#include') in the main '.nff' file. The latter holds the surface
 properties for all the geometry as well as the viewing specification.
 This allows for the changing of the shading or viewing properties while
 editing small ('.nff') files.
 
    If '-g' is specified, only the '.geom' file is created, preserving the
 current '.nff' file. The '-g' flag can be specified only with '-c'.
 
    In practice, it may be useful to create a low resolution approximation
 of the model, change viewing/shading parameters in the '.nff' file until
 a good view and/or surface quality is found, and then run Irit2Nff once more
 to create a high resolution approximation of the geometry using '-g'.
 
 Example:
 
@\begin{verbatim}
 irit2nff -c -l -F 0 8 b58.itd
@\end{verbatim}

 creates b58.nff and b58.geom with low resolution (FineNess of 5).

 Once done with parameter setting, a fine approximation of the model can
 be created with:

@\begin{verbatim}
 irit2nff -c -l -g -F 0 64 b58.itd
@\end{verbatim}

 which will only recreate b58.geom (because of the -g option).

 One can overwrite the viewing matrix by appending a new matrix in the
 end of the command line, created by a display device:

@\begin{verbatim}
 xgldrvs b58.itd
 irit2nff -l -F 0 32 b58.itd irit.imd
@\end{verbatim}

 where irit.imd is the viewing matrix created by xgldrvs.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify surface qualities for individual surfaces of a model.
 Several such attributes are supported by Irit2Nff and can be set within
 {\em IRIT}. See also the ATTRIB {\em IRIT} command.

   If a certain surface should be finer/coarser than the rest of the
 scene, one can set a "resolution" attribute which specifies the
 {\em relative} FineNess resolution of this specific surface. Further,
 "u\_resolution" and "v\_resolution" might be similarly used to set
 relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

 Example:

@\begin{verbatim}
 attrib( srf1, "resolution", 2 );
@\end{verbatim}

 will force srf1 to have twice the default resolution, as set via the '-f'
 flag.

   Almost flat patches are converted to polygons. The rectangle can be
 converted into two polygons (by subdividing along one of its diagonals) or
 into four by introducing a new point at the center of the patch. This
 behavior is controlled by the '-4' flag, but can be overwritten for
 individual surfaces by setting a "twoperflat" or a "fourperflat" attribute.

   NFF specific properties are controlled via the following attributes:
 "kd", "ks", "shine", "trans", "index". Refer to the NFF manual for detail.

 Example:

@\begin{verbatim}
 attrib( srf1, "kd", 0.3 );
 attrib( srf1, "shine", 30 );
@\end{verbatim}

   Surface color is controlled on two levels. If the object has an RGB
 attribute, it is used. Otherwise, a color, as set via the {\em IRIT} COLOR
 command, is used if set.

 Example:

@\begin{verbatim}
 attrib( tankBody, "rgb", "244,164,96" );
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Off - IRIT To OFF filter}
!Irit2Off - IRIT To OFF filter
 
 Converts {\em IRIT} data files into OFF data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
     Irit2Off [-l] [-4] [-n] [-F PolyOpti FineNess] [-E VrtxEps] [-o OutName]
                                                           [-m] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       by a single polygon along their linear direction.
       Although most of the time linear direction can be represented exactly 
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
       Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -n}: Vertex Normals - Dumps the normals of the vertices with the
       coordinates.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -E VrtxEps}: Epsilon to consider two vertices same.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -m}: More information flag.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Off converts {\em IRIT} data files into Geom View OFF data files.

 Example:

@\begin{verbatim}
    Irit2Off -m -o file.off file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Plg - IRIT To PLG (REND386) filter}
!IRIT2PLG - IRIT To PLG (REND386) filter

 PLG is the format used by the rend386 real time renderer for the IBM PC.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2plg [-l] [-4] [-F PolyOpti FineNess] [-T] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       by a single polygon along their linear direction.
       Although most of the time linear direction can be represented exactly 
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
       Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Plg converts freeform surfaces and polygons into polygons in a
 format that can be used by the REND386 renderer. 
  
 Example:
 
@\begin{verbatim}
 irit2plg solid1.itd > solid1.plg
@\end{verbatim}

    Surfaces are converted to polygons with fineness control:
  
@\begin{verbatim}
 irit2plg -F 0 16 - view.imd < saddle.itd > saddle.plg
@\end{verbatim}

    Note the use of '-' for stdin.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2pov - IRIT To POVRAY raytracer filter}
!IRIT2POV - IRIT To POVRAY raytracer filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2pov [-l] [-4] [-C] [-F PolyOpti FineNess] [-f PolyOpti SampTol]
           [-o OutName] [-g] [-p Zmin Zmax] [-P] [-M] [-T] [-t AnimTime]
           [-I #UIso[:#VIso[:#WIso]]] [-s ObjSeq#] [-i Includes] [-z] DFiles
@\end{verbatim}
 
@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
        by a single polygon along their linear direction.
         Although most of the time linear direction can be represented exactly 
        using a single polygon, even a bilinear surface can have a freeform
        shape (saddle-like) that is not representable using a single polygon.
          Note that although this option will better emulate the surface shape,
        it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -C}: Constructs bicubic Bezier patches whenever possible as POVRAY
        supports this type of surface.  Polynomial Bezier surfaces of
        orders up to and including bicubic (order 4, degree 3) are degree
        raised to bicubic.  Piecewise polynomials B-spline surfaces are
        split into Bezier patches.  Higher order surfaces and rational
        surfaces are always converted into polygons.
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4, -C, and -l.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples). 
@\item
  {\bf -o OutName}: Name of output file. By default the name of the first data
        file from the {\em DFiles} list is used.  See below on the output
        files.
@\item
  {\bf -g}: Generates the geometry file only. See below.
@\item
  {\bf -p Zmin Zmax}: Sets the ratios between the depth cue and the width of
        the dumped {\em polylines}. See also -P. Closer lines will be drawn
        wider.
@\item
  {\bf -P}: Forces dumping polygons as polylines with thickness controlled
        by -p.
@\item
  {\bf -M}: If -P (see -P and -p), then convert the control mesh/polygon
        to polylines which are represented as a sequence of truncated
        cones.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
        surface/trivariate, per direction. If \#VIso or \#WIso is not
        specified, \#UIso is used for \#VIso etc.
@\item
  {\bf -s ObjSeq\#}: Sets object sequence number if there is no object name.
        Default 1.
@\item
  {\bf -i Includes}: Expands the comma's separated list of POVRAY include
        file names into POVRAY include commands at the beginning of the
        created POVRAY output file.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2pov converts freeform surfaces into polygons in a format that can
 be used by the POVRAY ray tracing program.
 Two files are created, one with a '.geom' extension and
 one with a '.pov' extension. Since the number of polygons can be extremely
 large, the geometry is isolated in the '.geom' file and is included
 (via '\#include') in the main '.pov' file. The latter holds the surface
 properties for all the geometry as well as viewing and POVRAY specific
 commands. This allows for the changing of the shading or the viewing
 properties while editing small ('.pov') files.
 
    If '-g' is specified, only the '.geom' file is created, preserving the
 current, possibly manually modified, '.pov' file.
 
    In practice, it may be useful to create a low resolution approximation
 of the model, change the viewing/shading parameters in the '.pov' file until
 a good view and/or surface quality is found, and then run Irit2pov once more
 to create a high resolution approximation of the geometry using '-g'.
 
 Example:
 
@\begin{verbatim}
 irit2pov -l -F 0 5 b58.itd
@\end{verbatim}

 creates b58.pov and b58.geom with low resolution (FineNess of 5).
   At such low resolution it may very well happen that triangles will have
 normals "over the edge" since a single polygon may approximate a highly
 curved surface.
   One can ray trace this scene using a command similar to:

@\begin{verbatim}
 POVRAY -Q0 +Ib58
@\end{verbatim}

 Once done with a parameter setting for POVRAY, a fine approximation of the
 model can be created with:

@\begin{verbatim}
 irit2pov -l -g -F 0 64 b58.itd
@\end{verbatim}

 which will only recreate b58.geom (because of the -g option).

 Interesting effects can be created using the depth cue support and polyline
 conversion of irit2pov. For example,
 
@\begin{verbatim}
 irit2pov -P -p -0.0 0.5 solid1.itd
@\end{verbatim}
 
 will dump solid1 as a set of polylines (represented as truncated cones in
 POVRAY) with varying thickness according to the $z$ depth. Another example
 is
 
@\begin{verbatim}
 irit2pov -P -p -0.1 1.0 saddle.itd
@\end{verbatim}

 which dumps the isolines extracted from the saddle surface with varying
 thickness.

   Each time a data file is saved in {\em IRIT}, it can be saved with the
 viewing matrix of the last INTERACT by saving the VIEW\_MAT object as well.
 I.e.:

@\begin{verbatim}
 save( "b58", b58 );
@\end{verbatim}

   However, one can overwrite the viewing matrix by appending a new matrix
 in the end of the command line, created by the display devices:

@\begin{verbatim}
 xglmdrvs b58.itd                        // Also creates irit.imd
 irit2pov -l -F 0 16 b58.itd irit.imd
@\end{verbatim}

 where irit.imd is the viewing matrix created by xglmdrvs. The output name,
 by default, is the last input file name, so you might want to provide an
 explicit name with the -o flag.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify surface qualities for individual surfaces of a model.
 Several such attributes are supported by Irit2pov and can be set within
 {\em IRIT}. See also the ATTRIB {\em IRIT} command.

   If a certain surface should be finer/coarser than the rest of the
 scene, one can set a "resolution" attribute which specifies the
 {\em relative} FineNess resolution of this specific surface. Further,
 "u\_resolution" and "v\_resolution" might be similarly used to set
 relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

 Example:

@\begin{verbatim}
 attrib( srf1, "resolution", 2 );
@\end{verbatim}

 will force srf1 to have twice the default resolution as set via the '-f'
 flag.

   Almost flat patches are converted to polygons. The rectangle can be
 converted into two polygons (by subdividing along one of its diagonals) or
 into four by introducing a new point at the patch center. This behavior is
 controlled by the '-4' flag, but can be overwritten for individual surfaces
 by setting "twoperflat" or "fourperflat".

   POVRAY also supports bicubic Bezier patches and the '-C' option of 
 irit2pov supports that.  In such a case, the resolution that is requested
 from POVRAY to polygonize these patches approximately follows the resolution
 as selected via the '-F' flag of irit2pov.  Nevertheless, one can
 override the requested resolution via the "steps", "u\_steps", and "v\_steps"
 attributes to irit2pov data files that are transferred directly to
 POVRAY's bicubic Bezier patches.  The "steps" attributes sets both
 "u\_steps" and "v\_steps".

   While the program has a default for lighting which is a point light
 source at (1, 2, 10), one can overwrite this default.  A POINT\_TYPE
 object with LIGHT\_SOURCE attribute in the data stream denotes a
 light source.  If irit2pov detects one or more light sources in the
 input stream, the default light sources are not created.  A point
 light source can be colored, when an RGB attribute will set its
 color.

  Example:

@\begin{verbatim}
 l1 - point( 5, 5, 5 );
 attrib( l1, "rgb", "255, 0, 0" );
@\end{verbatim}

  creates a red light source at (5, 5, 5).

   POVRAY specific properties are controlled via the following attributes:
 "ambient", "diffuse", "brilliance", "phong", "phong\_size", "specular",
 "roughness", "metallic", "reflection", "crand", "conserve\_energy",
 "irid", "ior", "caustics", "dispersion", "dispersion\_samples",
 "fade\_distance", "fade\_power", "fade\_color".
   One can prescribe a whole property block of POV attributes via the
 "texture", "pigment", "finish", "halo", and "normal".  The values of this
 attributes must be strings as they are copied verbatim.  Refer to POVRAY's
 manual for their exact meaning.

  Example:

@\begin{verbatim}
 attrib( legs, "ambient", 0.1 );
 attrib( pot, "matallic", "" );
 attrib( table, "ior", 1.4 );
 attrib( bird, "finish", "ambient 0 diffuse 1 specular 1" );
@\end{verbatim}

   Surface color is controlled on two levels. If the object has an RGB
 attribute, it is used. Otherwise a color as set via the {\em IRIT} COLOR
 command is used, if set.

 Example:

@\begin{verbatim}
 attrib( tankBody, "rgb", "244,164,96" );
@\end{verbatim}

   Transparency is controlled via the "transp" attribute, with values
 between zero and one.

 Example:

@\begin{verbatim}
 attrib( Glass, "transp", 0.9 );
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Ps - IRIT To PS filter}
!IRIT2PS - IRIT To PS filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2ps [-l] [-4] [-s Size] [-I #UIso[:#VIso[:#WIso]]] [-F PolyOpti FineNess]
          [-f PolyOpti SampTol] [-M] [-G] [-P] [-W LineWidth]
          [-w WidenLen WidenWidth] [-b R G B] [-B X1 Y1 X2 Y2] [-c] [-C]
          [-T] [-t AnimTime] [-N FontName] [-i] [-o OutName] [-d [Zmin Zmax]]
          [-D [Zmin Zmax]] [-p PtType PtSize] [-u] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
        by a single polygon along their linear direction.
         Although most of the time linear direction can be represented exactly 
        using a single polygon, even a bilinear surface can have a freeform
        shape (saddle-like) that is not representable using a single polygon.
          Note that although this option will better emulate the surface shape,
        it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -s Size}: Controls the size of the postscript output in inches.
        Default is to fill the entire screen.
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
        surface/trivariate, per direction. If \#VIso or \#WIso is not
        specified, \#UIso is used for \#VIso etc.
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples). 
@\item
  {\bf -M}: Dumps the control mesh/polygon as well.
@\item
  {\bf -G}: Dumps the curve/surface (as freeform geometry). Default. See -I,
        -C, -f for control on polyline approximation.
@\item
  {\bf -P}: Dumps the curve/surface (as polygons). See -F, -l, -4 for control
        on polygonal approximation.
@\item
  {\bf -W \#LineWidth}: Sets the line drawing width in inches. Default is
        as thin as possible. This option will overwrite only those objects
        that do {\em not} have a "width" attribute. See also -d. If LineWidth
        is negative, its absolute value is used to scale the current width
        of the object if it has one, or the default width otherwise.
@\item
  {\bf -w WidenLen WidenWidth}: Widens the end points of polylines if they
        should be made wider, and if so, to what width.
@\item
  {\bf -b R G B}: Sets a colored background. RGB are three integers prescribing
        the Red, Green, and Blue coefficients. If there is no -c (i.e. a gray
        level drawing), this color is converted to a gray level using RGB to
        T.V. Y(IQ) channel conversion.
@\item
  {\bf -B X1 Y1 X2 Y2}: Clips the drawing area outsize the bounding box
       from (X1, Y1) to (X2, Y2).
@\item
  {\bf -c}: Creates a {\em color} postscript file.
@\item
  {\bf -C}: Curve mode. Dumps freeform curves and surfaces as cubic
       Bezier curves. Higher order curves and surfaces and/or rationals are
       approximated by cubic Bezier curves. This option generates data
       files that are roughly a third of piecewise linear postscript files
       (by disabling this feature, -C-), but it takes a longer time to compute.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -N FontName}: Sets the font to use when dumping text out of string
       objects.
@\item
  {\bf -i}: Internal edges (created by {\em IRIT}) - the default is not to
       display them, and this option will force displaying them as well.
@\item
  {\bf -o OutName}: Name of output file. Default is stdout.
@\item
  {\bf -d [Zmin Zmax]}: Sets the ratios between the depth cue and the width of
        the dumped data. See also -W, -p. Closer lines/points will be drawn
        wider/larger. Zmin and Zmax are optional. The object's bounding
        box is otherwise computed and used.
@\item
  {\bf -D [Zmin Zmax]}: Same as -d, but depth cue the color or gray scale
        instead of width. You might need to consider the sorting option
        of the illustrt tool (-s of illustrt) for proper drawings.
        Only one of -d and -D can be used.
@\item
  {\bf -p PtType PtSize}: Specifies the way points are drawn.
        PtType can be one of H, F, C for Hollow circle, Full Circle, or
        Cross. PtSize specifies the size of the point to be drawn, in inches.
        Vectors will also be drawn as points, but with an additional thin
        line to the origin. See also -d.
@\item
  {\bf -u}: Forces a unit matrix transformation, i.e. no transformation.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Ps converts freeform surfaces and polygons into a postscript file.
  
 Example:
 
@\begin{verbatim}
 irit2ps solid1.itd > solid1.ps
@\end{verbatim}

    Surfaces are converted to polygons with fineness control:
  
@\begin{verbatim}
 irit2ps -f 0 32 -c -W 0.01 saddle.itd > saddle.ps
@\end{verbatim}

 creates a postscript file for the saddle model, in color, and with
 lines 0.01 inch thick.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify several attributes that affect the way the postscript
 file is generated. The attributes can be generated within {\em IRIT}.
 See also the ATTRIB {\em IRIT} command.

   If a certain object should be thinner or thicker than the rest of the scene,
 one can set a "width" attribute which specifies the line width in inches of
 this specific object.

 Example:

@\begin{verbatim}
 attrib( srf1, "width", 0.02 );
@\end{verbatim}

 will force srf1 to have this width, instead of the default as set via the
 '-W' flag.

 If a (closed) object, a polygon, for example, needs to be filled, a "fill"
 attribute should be set.

 Example:
 
@\begin{verbatim}
 attrib( poly, "fill", true );
@\end{verbatim}
 
 will fill poly.
 
 If an object, a polygon, for example, needs to be painted/filled in a gray
 level instead of black, a "gray" attribute should be set, with a value equal
 to the gray level desired.

 Example:
 
@\begin{verbatim}
 attrib( poly, "gray", 0.5 );
@\end{verbatim}
 
 will draw/fill poly with \%50 gray.
 
 Dotted or dashed line effects can be created using a "dash" attribute which
 is a direct postScript dash string. A simple form of this string is "[a b]"
 in which a is the drawing portion (black) in inches, followed by b inches
 of white space. See the postScript manual for more about the format of this
 string. Here is an example for a dotted-dash line.
 
@\begin{verbatim}
 attrib( poly, "dash", "[0.006 0.0015 0.001 0.0015] 0" );
@\end{verbatim}

   Surface color is controlled (for color postscript only - see -c) on two
 levels. If the object has an RGB attribute, it is used. Otherwise, a color as
 set via the {\em IRIT} COLOR command is used.

 Example:

@\begin{verbatim}
 attrib( Ball, "rgb", "255,0,0" );
@\end{verbatim}

   An object can be drawn as "tubes" instead of full lines. The ratio
 between the inner and the outer radii of the tube is provided as the
 TUBULAR attribute:

@\begin{verbatim}
 attrib( final, "tubular", 0.7 );
@\end{verbatim}

   The depth cueing option of irit2ps could be disabled for individual
 objects by placing an integer attribute "DepthCue" with the FALSE value:

@\begin{verbatim}
 attrib( final, "DepthCue", FALSE );
@\end{verbatim}

   The "resolution" attribute controls the relative fineness of polygonal
 approximation of surfaces, and "u\_resolution" and "v\_resolution" similarly
 control this relative fineness along one parametric direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

   A string object can be dumped as text of a selected PS font (See -N).  The
 string position is set via a "StrPos" vector attribute (default to the
 origin), and "StrScale" real attribute to control the string height in
 world unit (default to 0.1).  Text will always be dumped horizontally.

 Example:

@\begin{verbatim}
 Text = "Some text";
 attrib( Text, "StrPos", vector( 1, 2, 3 ) );
 attrib( Text, "StrScale", 0.1 );
@\end{verbatim}

 Will print the {\bf Text} "Some text" at location (1, 2, 3).  The text
 height be be 0.1.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Ray - IRIT To RAYSHADE filter}
!IRIT2RAY - IRIT To RAYSHADE filter

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2ray [-l] [-4] [-G GridSize] [-F PolyOpti FineNess]
           [-f PolyOpti SampTol] [-o OutName] [-g] [-p Zmin Zmax] [-P]
           [-M] [-T] [-t AnimTime] [-I #UIso[:#VIso[:#WIso]]] [-s ObjSeq#]
           [-z] DFiles
@\end{verbatim}
 
@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
        by a single polygon along their linear direction.
         Although most of the time linear direction can be represented exactly 
        using a single polygon, even a bilinear surface can have a freeform
        shape (saddle-like) that is not representable using a single polygon.
          Note that although this option will better emulate the surface shape,
        it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -G GridSize}: Usually objects are grouped as {\em lists} of polygons.
        This flag will coerce the usage of the RAYSHADE {\em grid} structure,
        with {\em GridSize} being used as the grid size along the object
        bounding box's largest dimension.
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -o OutName}: Name of output file. By default, the name of the first data
        file from the {\em DFiles} list is used.  See below on the output
        files.
@\item
  {\bf -g}: Generates the geometry file only. See below.
@\item
  {\bf -p Zmin Zmax}: Sets the ratios between the depth cue and the width of
        the dumped {\em polylines}. See also -P. Closer lines will be drawn
        wider.
@\item
  {\bf -P}: Forces dumping polygons as polylines with thickness controlled
        by -p.
@\item
  {\bf -M}: If -P (see -P and -p), will then convert the control mesh/polygon
        to polylines which are represented as a sequence of truncated
        cones.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -I \#UIso[:\#VIso[:\#WIso]]}: Specifies the number of isolines per
        surface/trivariate, per direction. If \#VIso or \#WIso is not
        specified, \#UIso is used for \#VIso etc.
@\item
  {\bf -s ObjSeq\#}: Sets object sequence number if no object name. Default 1.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Ray converts freeform surfaces into polygons in a format that can
 be used by the RAYSHADE ray tracing program.
 Two files are created, one with a '.geom' extension and
 one with a '.ray' extension. Since the number of polygons can be extremely
 large, the geometry is isolated in the '.geom' file and is included
 (via '\#include') in the main '.ray' file. The latter holds the surface
 properties for all the geometry as well as viewing and RAYSHADE specific
 commands. This allows for the changing of the shading or viewing
 properties while editing small ('.ray') files.
 
    If '-g' is specified, only the '.geom' file is created, preserving the
 current '.ray' file.
 
    In practice, it may be useful to create a low resolution approximation
 of the model, change the viewing/shading parameters in the '.ray' file until
 a good view and/or surface quality is found, and then run Irit2Ray once more
 to create a high resolution approximation of the geometry using '-g'.
 
 Example:
 
@\begin{verbatim}
 irit2ray -l -F 0 5 b58.itd
@\end{verbatim}

 creates b58.ray and b58.geom with low resolution (FineNess of 5).
   At such low resolution it may very well happen that triangles will have
 normals "over the edge" since a single polygon may approximate a highly
 curved surface. That will cause RAYSHADE to issue an
 "Inconsistent triangle normals" warning. This problem will not arise if
 high fineness is used.
   One can ray trace this scene using a command similar to:

@\begin{verbatim}
 RAYSHADE -p -W 256 256 b58.ray > b58.rle
@\end{verbatim}

 Once done with the parameter setting for RAYSHADE, a fine approximation of the
 model can be created with:

@\begin{verbatim}
 irit2ray -l -g -F 0 64 b58.itd
@\end{verbatim}

 which will only recreate b58.geom (because of the -g option).

 Interesting effects can be created using the depth cue support and polyline
 conversion of irit2ray. For example,
 
@\begin{verbatim}
 irit2ray -G 5 -P -p -0.0 0.5 solid1.itd
@\end{verbatim}
 
 will dump solid1 as a set of polylines (represented as truncated cones in
 RAYSHADE) with varying thickness according to the $z$ depth. Another example
 is
 
@\begin{verbatim}
 irit2ray -G 5 -P -p -0.1 1.0 saddle.itd
@\end{verbatim}

 which dumps the isolines extracted from the saddle surface with varying
 thickness.

   Each time a data file is saved in {\em IRIT}, it can be saved with the
 viewing matrix of the last INTERACT by saving the VIEW\_MAT object as well.
 I.e.:

@\begin{verbatim}
 save( "b58", b58 );
@\end{verbatim}

   However, one can overwrite the viewing matrix by appending a new matrix
 in the end of the command line, created by the display devices:

@\begin{verbatim}
 os2drvs b58.itd                        // Also creates irit.imd
 irit2ray -l -F 0 16 b58.itd irit.imd
@\end{verbatim}

 where irit.imd is the viewing matrix created by os2drvs. The output name,
 by default, is the last input file name, so you might want to provide an
 explicit name with the -o flag.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify surface qualities for individual surfaces of a model.
 Several such attributes are supported by Irit2Ray and can be set within
 {\em IRIT}. See also the ATTRIB {\em IRIT} command.

   If a certain surface should be finer/coarser than the rest of the
 scene, one can set a "resolution" attribute which specifies the
 {\em relative} FineNess resolution of this specific surface. Further,
 "u\_resolution" and "v\_resolution" might be similarly used to set
 relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

 Example:

@\begin{verbatim}
 attrib( srf1, "resolution", 2 );
@\end{verbatim}

 will force srf1 to have twice the default resolution, as set via the '-f'
 flag.

   Almost flat patches are converted to polygons. The rectangle can be
 converted into two polygons (by subdividing along one of its diagonals) or
 into four by introducing a new point at the patch center. This behavior is
 controlled by the '-4' flag, but can be overwritten for individual surfaces
 bu setting "twoperflat" or "fourperflat".

   RAYSHADE specific properties are controlled via the following attributes:
 "specpow", "reflect", "transp", "body", "index", and "texture". The value of
 these attributes must be strings as it is copied verbatim. Refer to
 RAYSHADE's manual for their meaning.

  Example:

@\begin{verbatim}
 attrib( legs, "transp", "0.3" );
 attrib( legs, "texture", "wood,2" );
 attrib( table, "texture", "marble" );
 attrib( table, "reflect", "0.5" );
@\end{verbatim}

   An optional scale can be prescribed to textures. In the above example
 wooden legs' (that are also transparent...) texture is selected with
 a texture scaling factor of 2.

   Surface color is controlled on two levels. If the object has an RGB
 attribute, it is used. Otherwise a color as set via the {\em IRIT} COLOR
 command is used, if set.

 Example:

@\begin{verbatim}
 attrib( tankBody, "rgb", "244,164,96" );
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Scn - IRIT To SCENE (RTrace) filter}
!IRIT2Scn - IRIT To SCENE (RTrace) filter

 SCENE is the format used by the RTrace ray tracer. This filter was donated
 by Antonio Costa (acc@asterix.inescn.pt), the author of RTrace.
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
  irit2scn [-l] [-4] [-F PolyOpti FineNess] [-o OutName] [-g] [-T]
           [-t AnimTime] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       as a single polygon along their linear direction.
         Although most of the time linear direction can be represented exactly 
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
         Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -o OutName}: Name of output file. By default the name of the first data
       file from {\em DFiles} list is used.  See below on the output files.
@\item
  {\bf -g}: Generates the geometry file only. See below.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -t AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Scn converts freeform surfaces and polygons into polygons in a format
 that can be used by RTrace. Two files are created, one with a '.geom'
 extension and one with a '.scn' extension. Since the number of polygons can
 be extremely large, the geometry is isolated in the '.geom' file and is
 included (via '\#include') in the main '.scn' file. The latter holds the
 surface properties for all the geometry as well as viewing and RTrace specific
 commands. This allows for the changing of the shading or viewing
 properties while editing small ('.scn') files.
 
    If '-g' is specified, only the '.geom' file is created, preserving the
 current '.scn' file.
 
    In practice, it may be useful to create a low resolution approximation
 of the model, adjust the viewing/shading parameters in the '.scn' file
 until a good view and/or surface quality is found, and then run Irit2Scn once
 more to create a high resolution approximation of the geometry using '-g'.
 
 Example:
 
@\begin{verbatim}
 irit2scn -l -F 0 8 b58.itd
@\end{verbatim}

 creates b58.scn and b58.geom with low resolution (FineNess of 5).

   One can ray trace this scene after converting the scn file to a sff file,
 using scn2sff provided with the RTrace package.

 Once done with the parameter setting of RTrace, a fine approximation of the
 model can be created with:

@\begin{verbatim}
 irit2scn -l -g -F 0 64 b58.itd
@\end{verbatim}

 which will only recreate b58.geom (because of the -g option).

   One can overwrite the viewing matrix by appending a new matrix
 at the end of the command line, created by the display devices:

@\begin{verbatim}
 wntdrvs b58.itd
 irit2scn -l -F 0 8 b58.itd irit.imd
@\end{verbatim}

 where irit.imd is the viewing matrix created by wntdrvs. The output name,
 by default, is the last input file name, so you might want to provide an
 explicit name with the -o flag.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Advanced Usage}
&Advanced Usage

   One can specify surface qualities for individual surfaces of a model.
 Several such attributes are supported by Irit2Scn and can be set within 
 {\em IRIT}. See also the ATTRIB {\em IRIT} command.

   If a certain surface should be finer/coarser than the rest of the
 scene, one can set a "resolution" attribute which specifies the
 {\em relative} FineNess resolution of this specific surface. Further,
 "u\_resolution" and "v\_resolution" might be similarly used to set
 relative resolution for the u or v direction only.
   The "crv\_resolution" attribute controls the relative fineness of curves
 as polylines. The "num\_of\_isolines" attribute controls the relative number
 of isoparametric curves.

 Example:

@\begin{verbatim}
 attrib( srf1, "resolution", 2 );
@\end{verbatim}

 will force srf1 to have twice the default resolution, as set via the '-f'
 flag.

   Almost flat patches are converted to polygons. The patch can be converted
 into two polygons (by subdividing along one of its diagonals) or into four
 by introducing a new point at the patch center. This behavior is controlled
 by the '-4' flag, but can be overwritten for individual surfaces by setting
 "twoperflat" or "fourperflat".

   RTrace specific properties are controlled via the following attributes:
 "SCNrefraction", "SCNtexture", "SCNsurface. Refer to the RTrace manual for
 their meaning.

 Example:

@\begin{verbatim}
 attrib( srf1, "SCNrefraction", 0.3 );
@\end{verbatim}

   Surface color is controlled on two levels. If the object has an RGB
 attribute, it is used. Otherwise a color as set via {\em IRIT} COLOR command
 is used, if set.

 Example:

@\begin{verbatim}
 attrib( tankBody, "rgb", "244,164,96" );
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Stl - IRIT To STL filter}
!IRIT2Stl - IRIT To STL filter
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
  irit2stl [-l] [-4] [-r] [-F PolyOpti FineNess] [-E VrtxEps] [-s] [-S] 
           [-o OutName] [-m] [-u] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
        by a single polygon along their linear direction.
         Although most of the time linear direction can be represented exactly 
        using a single polygon, even a bilinear surface can have a freeform
        shape (saddle-like) that is not representable using a single polygon.
          Note that although this option will better emulate the surface shape,
        it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -r}: Regularize and triangulate the input data if not regularized
        and with triangles only to begin with.
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4.
@\item
  {\bf -E VrtxEps}:  Tolerance of two adjacent verices to be considered the
        same.  Vertices that are considered the same are collapsed to an
        identical location.
@\item
  {\bf -s}: Dumps each object as a separated "solid" - "endsolid" brackets.
@\item
  {\bf -S}: Dumps each object as a separated "solid" - "endsolid" brackets in
        a separated stl file, with file name appended with numeric index.
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -m}: More information flag.
@\item
  {\bf -u}: Forces a unit matrix. That is, input data are {\em not}
        transformed at all.
@\item
  {\bf -z}: Prints version number and current defaults.

@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Stl converts freeform surfaces and polygons into the STL
 (Stereolithography) file format.  The STL data should be a closed solid in
 general but no such validity check is conducted by irit2stl.
  
 Example:
 
@\begin{verbatim}
 irit2stl -u solid2.itd > solid2.stl
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Wrl - IRIT To IGES filter}
!Irit2Wrl - IRIT To IGES filter
 
 Converts {\em IRIT} data files into IGS data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
    irit2wrl [-l] [-4] [-u] [-F PolyOpti FineNess] [-f PolyOpti SampTol]
                                                 [-o OutName] [-T] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -l}: Linear - forces linear (degree two) surfaces to be approximated
       by a single polygon along their linear direction.
       Although most of the time linear direction can be represented exactly 
       using a single polygon, even a bilinear surface can have a freeform
       shape (saddle-like) that is not representable using a single polygon.
       Note that although this option will better emulate the surface shape,
       it will create unnecessary polygons in cases where one is enough.
@\item
  {\bf -4}: Four - Generates four polygons per flat patch. Default is 2.
@\item
  {\bf -u}: Forces a unit matrix. That is, input data are {\em not}
        transformed at all.
@\item
  {\bf -F PolyOpti FineNess}: Optimality of polygonal approximation of
       surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
       FineNess. See also -4.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -T}: More talkative/information flag.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Wrl converts {\em IRIT} data files into Geom View OFF data files.

 Example:

@\begin{verbatim}
    Irit2Wrl -m -o file.off file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Irit2Xfg - IRIT To XFIG filter}
!IRIT2Xfg - IRIT To XFIG filter
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
  irit2xfg [-s Size] [-t XTrans YTrans] [-I #UIso[:#VIso[:#WIso]]]
       [-f PolyOpti SampTol] [-F PolyOpti FineNess] [-M] [-G] [-T]
       [-a AnimTime] [-i] [-o OutName] [-z] DFiles
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -s Size}: Size in inches of the page. Default is 7 inches.
@\item
  {\bf -t XTrans YTrans}: X and Y translation. of the image. Default is (0, 0).
@\item
  {\bf -I \#UIso[:\#VIso]}: Specifies the number of isolines per surface, per
        direction. If \#VIso is not specified, \#UIso is used for \#VIso as
        well.
@\item
  {\bf -f PolyOpti SampTol}: Controls the method used to approximate curves
        into polylines. If PolyOpti == 0, equally spaced intervals are
        used.  For PolyOpti == 1, SampTol (real number) specifies the
        maximal allowed deviation tolerance of the piecewise linear
        approximation from the original curve.
        Default is 0 64 (uniform sampling with 64 samples).
@\item
  {\bf -F PolygonOpti FineNess}: Optimality of polygonal approximation of
        surfaces. See the variable POLY\_APPROX\_OPT for the meaning of
        FineNess. See also -4. This enforces the dump of freefrom geometry
        as polygons.
@\item
  {\bf -M}: Dumps the control mesh/polygon as well.
@\item
  {\bf -G}: Dumps the freeform geometry.
@\item
  {\bf -T}: Talkative mode. Prints processing information.
@\item
  {\bf -a AnimTime}: If the data contains animation curves, evaluate and
       process the scene at time AnimTime.
@\item
  {\bf -i}: Internal edges (created by {\em IRIT}) - default is not to
       display them, and this option will force their display.
@\item
  {\bf -o OutName}: Name of output file. By default, the name of the first data
       file from {\em DFiles} list is used.  See output files below.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Irit2Xfg converts freeform surfaces and polygons into polylines in a format
 that can be used by XFIG.
  
 Example:
 
@\begin{verbatim}
 irit2Xfg -T -f 0 16 saddle.itd > saddle.xfg
@\end{verbatim}

   However, one can overwrite the viewing matrix by appending a new matrix
 at the end of the command line, created by the display devices:

@\begin{verbatim}
 x11drvs b58.itd
 irit2Xfg -T -f 0 16 b58.itd irit.imd > saddle.xfg
@\end{verbatim}

 where irit.imd is the viewing matrix created by x11drvs.
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Obj2irit - Wavefront OBJ format To IRIT data files}
!OBJ2IRIT - Wavefront OBJ format To IRIT data files
 
 converts Waverfront's OBJ data files into {\em IRIT} data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
    obj2irit [-m] [-r] [-o OutName] [-z] OBJFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -m}: Provides some more information on the data file(s) parsed.
@\item
  {\bf -r}: Reverses all polygons' orientation in generated data.
@\item
  {\bf -o OutName}: Name of output file. By default, the output goes to
       stdout.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    obj2irit converts Wavefront's OBJ data files into {\em IRIT} data files.
 The current version provides only partial support for the direct conversion
 of freeform surfaces, mainly due to luck of examples of freeform surfaces
 in obj format.

 Example:

@\begin{verbatim}
 obj2irit -o file.itd file.obj
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Off2irit - Geom View Off format To IRIT data files}
!Off2IRIT - Geom View Off format To IRIT data files
 
 Converts Geom View's Off data files into {\em IRIT} data files.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options
 
@\begin{verbatim}
    Off2irit [-o OutName] [-z] OffFile
@\end{verbatim}

@\begin{itemize}
@\item
  {\bf -o OutName}: Name of output file. By default the output goes to
       stdout.
@\item
  {\bf -z}: Prints version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    Off2irit converts Geom View's Off data files into {\em IRIT} data files.

 Example:

@\begin{verbatim}
    Off2irit - < file.off > file.itd
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Stl2Irit - Stl (stereo lithograph) data To IRIT file filter}
!STL2IRIT - Stl (stereo lithograph) data To IRIT file filter

  Converts '.stl' stereolithography data files to '.irt' {\em IRIT} scripts.
 Both binary and text STL files are supported.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Command Line Options}
&Command line options

@\begin{verbatim}
   stl2irit [-b] [-w] [-n] [-o OutName] [-z] STLFile
@\end{verbatim}

@\begin{itemize}
@\item
  
@\item
  {\bf -b}: The stl file is a binary stl.
  {\bf -w}: Perform an endian swap on all read data.  Little vs. Big
            Endian is supported for binary STL files only.
  {\bf -n}: Flip orientation of all polygons by flipping their normals.
  {\bf -o OutName}: Name of output file. By default, the output goes to
       stdout.
  {\bf -z}: Print version number and current defaults.
@\end{itemize}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\subsection{Usage}
&Usage

    stl2irit converts stereo-lithography STL data files into {\em IRIT} data
 files.

 Example:

@\begin{verbatim}
 stl2irit -o file.itd file.stl
@\end{verbatim}
$

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@\section{Data File Format}
!DATAFILE Format

   This section describes the data file format used to exchange data between
 {\em IRIT} and its accompanying tools.

@\begin{verbatim}
 [OBJECT {ATTRS} OBJNAME
     [NUMBER n]

   | [POINT x y z]

   | [VECTOR x y z]

   | [CTLPT POINT_TYPE {w} x y {z}]

   | [STRING "a string"]

   | [MATRIX m00 ... m03
             m10 ... m13
             m20 ... m23
             m30 ... m33]

     ;A polyline should be drawn from first point to last. Nothing is drawn
     ;from last to first (in a closed polyline, last point is equal to first).
   | [POLYLINE {ATTRS} #PTS                   ;#PTS = number of points.
         [{ATTRS} x y z]
         [{ATTRS} x y z]
            .
            .
            .
         [{ATTRS} x y z]
     ]
 
     ;Defines a closed planar region. Last point is NOT equal to first,
     ;and a line from last point to first should be drawn when the boundary
     ;of the polygon is drawn.
   | [POLYGON {ATTRS} #PTS
         [{ATTRS} x y z]
         [{ATTRS} x y z]
            .
            .
            .
         [{ATTRS} x y z]
     ]
 
     ;Defines a "cloud" of points.
   | [POINTLIST {ATTRS} #PTS
         [{ATTRS} x y z]
         [{ATTRS} x y z]
            .
            .
            .
         [{ATTRS} x y z]
     ]
 
     ;Defines a polygon triangle strip.  At list 3 vertices are expected.
     ;Last point is NOT equal to first, and a line from last point to first
     ;should be drawn when the boundary of the polygon is drawn.
   | [POLYSTRIP {ATTRS} #PTS
         [{ATTRS} x y z]
         [{ATTRS} x y z]
            .
            .
            .
         [{ATTRS} x y z]
     ]
 
     ;Defines an instance - a geometric reference (by name, SRF13 below)
     ;and a transformation matrix to apply to this geoemtry
   | [INSTANCE SRF13
             m00 ... m03
             m10 ... m13
             m20 ... m23
             m30 ... m33]

     ;Defines a Bezier curve with #PTS control points. If the curve is
     ;rational, the rational component is introduced first.
   | [CURVE BEZIER {ATTRS} #PTS POINT_TYPE
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a Bezier surface with #UPTS * #VPTS control points. If the
     ;surface is rational, the rational component is introduced first.
     ;Points are printed row after row (#UPTS per row), #VPTS rows.
   | [SURFACE BEZIER {ATTRS} #UPTS #VPTS POINT_TYPE
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a Bezier triangular surface with (#PTS + 1) * #PTS / 2 control
     ;points, of order ORDER. If the surface is rational, the rational
     ;component is introduced first. Note #PTS holds number of points along
     ;an edge and is exactly equal to ORDER. Points are printed sequentially.
   | [TRISRF BEZIER {ATTRS} #PTS POINT_TYPE
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]

     ;Defines a Bezier trivariate with #UPTS * #VPTS * #WPTS control
     ;points. If the trivariate is rational, the rational component is
     ;introduced first. Points are printed row after row (#UPTS per row),
     ;#VPTS rows, #WPTS layers (depth).
   | [TRIVAR BEZIER {ATTRS} #UPTS #VPTS #WPTS POINT_TYPE
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a Bezier multivariate of #Dim dimensions (#Dim = 1 for a 
     ;curve, #Dim = 2 for a surface, #Dim = 3 for a trivariate, etc.)
     ;with (Dim1#PTS * ... * Dim1#PTS) control points. If the multivariate
     ;is rational, the rational component is introduced first.
   | [MULTIVAR BEZIER {ATTRS} #Dim Dim1#PTS ... DimN#PTS POINT_TYPE
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a B-spline curve of order ORDER with #PTS control points. If the
     ;curve is rational, the rational component is introduced first.
     ;Note that the length of knot vector is equal to #PTS + ORDER.
     ;If the curve is periodic, KVP prefix the knot vector that has length of
     ;'Length + Order + Order - 1'.
   | [CURVE BSPLINE {ATTRS} #PTS ORDER POINT_TYPE
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                    ;Knot vector
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a B-spline surface with #UPTS * #VPTS control points, of order
     ;UORDER by VORDER. If the surface is rational, the rational component
     ;is introduced first.
     ;Points are printed row after row (#UPTS per row), #VPTS rows.
     ;If the surface is periodic in some direction, KVP prefix the knot vector
     ;that has length of 'Length + Order + Order - 1'.
   | [SURFACE BSPLINE {ATTRS} #UPTS #VPTS UORDER VORDER POINT_TYPE
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;U Knot vector
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;V Knot vector
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]

     ;Defines a B-spline triangular surface with (#PTS + 1) * #PTS / 2 control
     ;points, of order ORDER. If the surface is rational, the rational
     ;component is introduced first.
     ;Points are printed sequentially.
   | [TRISRF BSPLINE {ATTRS} #PTS ORDER POINT_TYPE
         [KV {ATTRS} kv0 kv1 kv2 ...]                   ;Knot vector
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]

     ;Defines a B-spline trivariate with #UPTS * #VPTS * #WPTS control
     ;points. If the trivariate is rational, the rational component is
     ;introduced first. Points are printed row after row (#UPTS per row),
     ;#VPTS rows, #WPTS layers (depth).
     ;If trivariate is periodic in some direction, KVP prefix the knot vector
     ;that has length of 'Length + Order + Order - 1'.
   | [TRIVAR BSPLINE {ATTRS} #UPTS #VPTS #WPTS UORDER VORDER WORDER POINT_TYPE
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;U Knot vector
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;V Knot vector
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;W Knot vector
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
 
     ;Defines a B-spline multivariate of #Dim dimensions (#Dim = 1 for a 
     ;curve, #Dim = 2 for a surface, #Dim = 3 for a trivariate, etc.)
     ;with (Dim1#PTS * ... * Dim1#PTS) control points. If the multivariate
     ;is rational, the rational component is introduced first.
   | [MULTIVAR BSPLINE {ATTRS} #Dim Dim1#PTS ... DimN#PTS POINT_TYPE
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;Dim1 Knot vector
             .
             .
             .
         [KV{P} {ATTRS} kv0 kv1 kv2 ...]                ;DimN Knot vector
         [{ATTRS} {w} x y z ...]
         [{ATTRS} {w} x y z ...]
            .
            .
            .
         [{ATTRS} {w} x y z ...]
     ]
  
     ;Defines a trimmed surface. Encapsulates a surface (can be either a
     ;B-spline or a Bezier surface) and prescribes its trimming curves.
     ;There can be an arbitrary number of trimming curves (either Bezier
     ; or B-spline). Each trimming curve contains an arbitrary number of
     ;trimming curve segments, while each trimming curve segment contains
     ;a parameteric representation optionally followed by a Euclidean
     ;representation of the trimming curve segment.
   | [TRIMSRF
         [SURFACE ...
         ]
         [TRIMCRV
             [TRIMCRVSEG
                 [CURVE ...
                 ]
             ]
                .
                .
                .
             [TRIMCRVSEG
                 [CURVE ...
                 ]
             ]
         ]
             .
             .
             .
         [TRIMCRV
             [TRIMCRVSEG
                 [CURVE ...
                 ]
             ]
                .
                .
                .
             [TRIMCRVSEG
                 [CURVE ...
                 ]
             ]
         ]
     ]

     ;Defines a model. A model contains a set of (trimmed) surfaces along
     ;with a set of trimming curves that are shared by (at most) two
     ;surfaces each.
     ;The trimming curves must form closed loops in each surface.
   | [MODEL #TrimSrfs #TrimSegs
         ;A surface in the model holds a regular surface and a set of
         ;closed loops that defines the trimming loops of the surface.
         [MDLTSRF #Loops                        ;Number of trimming loops
             [SURFACE ...
             ]
             ;Each trimming loop is a list of trimming curve segments.
             ;If the index is negative, it denotes the traversal of the
             ;curve in reverse order.
             [MDLLOOP trim seg's indices]        ;Negative index - reversed
                 .
                 .
                 .
             [MDLLOOP trim seg's indices]        ;Negative index - reversed
         ]
             .
             .
             .
         [MDLTSRF #Loops                         ;Number of trimming loops
             [SURFACE ...
             ]
             [MDLLOOP trim seg's indices]        ;Negative index - reversed
                 .
                 .
                 .
             [MDLLOOP trim seg's indices]        ;Negative index - reversed
         ]

         ;The trimming curve segments can hold a parameteric curve of the
         ;in first surface, a parametric curve in the second surface, and a
         ;a Euclidean representation, in this order. A 3 bits mask 'CurveMask'
         ;says what is available, as one bit per curve type.
         ;'#1stSrf' and '#2ndSrf' specify the two surfaces that share
         ;this boundary trimming curve, with 0 denoting no surface.
         [MDLTSEG CurveMask #1stSrf #2ndSrf        ;CurveMask = 5
             [CURVE ...
             ]
             [CURVE ...
             ]
         ]
             .
             .
             .
         [MDLTSEG CurveMask #1stSrf #2ndSrf        ;CurveMask = 7
             [CURVE ...
             ]
             [CURVE ...
             ]
             [CURVE ...
             ]
         ]
     ]
 ]

 POINT_TYPE -> E1 | E2 | E3 | E4 | E5 | E6 | E7 | E8 | E9 |
               P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9

 ATTRS -> [ATTRNAME ATTRVALUE]
          | [ATTRNAME]
          | [ATTRNAME ATTRVALUE] ATTRS

@\end{verbatim}

 Some notes:

 * This definition for the text file is designed to minimize the
   reading time and space. All information can be read without backward
   or forward referencing.

 * An OBJECT must never hold different geometry types or other entities.
   I.e. CURVEs, SURFACEs, and POLYGONs must all be in different OBJECTs.

 * Attributes should be ignored if not needed. The attribute list may have
   any length and is always terminated by a token that is NOT '\verb+[+'. This
   simplifies and disambiguates the parsing.

 * Comments may appear between '\verb+[+OBJECT ...\verb+]+' blocks, or
   immediately after OBJECT OBJNAME, and only there.

   A comment body can be anything not containing the '\verb+[+' or the
   '\verb+]+' tokens (signals start/end of block). Some of the comments in
   the above definition are {\em illegal} and appear there only for the sake
   of clarity.

 * It is preferable that geometric attributes such as NORNALs be saved on
   the geometric structure level (POLYGON, CURVE or vertices) while graphical
   and other attribures such as COLORs will be saved on the OBJECT level.

 * Objects may be contained in other objects to an arbitrary level.

 Here is an example that exercises most of the data format:

@\begin{verbatim}
 This is a legal comment in a data file.
 [OBJECT DEMO
     [OBJECT REAL_NUM
         And this is also a legal comment.
         [NUMBER 4]
     ]
 
     [OBJECT A_POINT
         [POINT 1 2 3]
     ]
 
     [OBJECT A_VECTOR
         [VECTOR 1 2 3]
     ]
 
     [OBJECT CTL_POINT
         [CTLPT E3 1 2 3]
     ]
 
     [OBJECT STR_OBJ
         [STRING "string"]
     ]
 
     [OBJECT UNIT_MAT
         [MATRIX
            1 0 0 0
            0 1 0 0
            0 0 1 0
            0 0 0 1
         ]
     ]
 
     [OBJECT [COLOR 4] POLY1OBJ
         [POLYGON [PLANE 1 0 0 0.5] 4
             [-0.5 0.5 0.5]
             [-0.5 -0.5 0.5]
             [-0.5 -0.5 -0.5]
             [-0.5 0.5 -0.5]
         ]
         [POLYGON [PLANE 0 -1 0 0.5] 4
             [0.5 0.5 0.5]
             [-0.5 0.5 0.5]
             [-0.5 0.5 -0.5]
             [0.5 0.5 -0.5]
         ]
     ]
 
     [OBJECT [COLOR 63] ACURVE
         [CURVE BSPLINE 16 4 E2
             [KV 0 0 0 0 1 1 1 2 3 4 5 6 7 8 9 10 11 11 11 11]
             [0.874 0]
             [0.899333 0.0253333]
             [0.924667 0.0506667]
             [0.95 0.076]
             [0.95 0.76]
             [0.304 1.52]
             [0.304 1.9]
             [0.494 2.09]
             [0.722 2.242]
             [0.722 2.318]
             [0.38 2.508]
             [0.418 2.698]
             [0.57 2.812]
             [0.57 3.42]
             [0.19 3.572]
             [0 3.572]
         ]
     ]
 
     [OBJECT [COLOR 2] SOMESRF
         [SURFACE BEZIER 3 3 E3
             [0 0 0]
             [0.05 0.2 0.1]
             [0.1 0.05 0.2]
 
             [0.1 -0.2 0]
             [0.15 0.05 0.1]
             [0.2 -0.1 0.2]
 
             [0.2 0 0]
             [0.25 0.2 0.1]
             [0.3 0.05 0.2]
         ]
     ]
 ]
@\end{verbatim}
$

@\section{Bugs and Limitations}
!BUGS and LIMITATIONS

   As with any program of more than one line, this is far from perfect.
 Some limitations, as well as simplifications, are laid out below.

 *  If the intersection curve of two objects falls exactly on polygon
    boundaries, for all polygons, the system will scream that the two objects
    do not intersect at all. Try to move one by EPSILON into the other.
    I probably should fix this one - it is supposed to be relatively easy.

 *  Avoid degenerate intersections that result in a point or a line.
    They will probably cause wrong propagation of the inner and outer parts of
    one object relative to another. Always extend your object beyond the
    other object.

 *  If two objects have no intersection in their boundary, {\em IRIT} assumes
    they are disjoint: a union simply combines them, and the other Boolean
    operators return a NULL object. One should find a FAST way (3D Jordan
    theorem) to find the relation between the two (A in B, B in A, A
    disjoint B) and according to that, make a decision.

 *  Since the Boolean sum implementation constructs ruled surfaces with
    uniform speed, it might return a somewhat incorrect answer, given
    non-uniform input curves.

 *  The parser is out of hand and difficult to maintain. There are several
    memory leaks there that one should fix.

 *  The X11 driver has no menu support (any easy way to have menus using
    Xlib!?).

 *  IBM R6000 fails to run the drivers in -s- mode.

 *  Rayshade complains a lot about degenerate polygons on irit2ray output.
    To alleviate the problem, change the 'equal' macro in common.h in libcommon
    of rayshade from EPSILON (1e-5) to 1e-7 or even lower.

 *  On the motif-based drivers (xmtdrvs etc.) clicking the mouse left and
    right of the scale's button produces stepped transformations. This
    step size is constant, and is not proportional to the distance between
    the mouse's position and the position of the button. The reason for the
    flaw is incorrect callback information returned from the scale in
    repetitive mode.

 *  Binary data files are not documented, nor will they be. They might
    change in the future and are in fact machine dependend. Hence, one
    platform might fail to read another's binary data file.
$

@\end{document}

