Documentation on the Public Domain Geometry Library (GPD) - Version 5
---------------------------------------------------------------------

Though there is a corresponding binary format, only the ASCII format
is described.

In previous versions of Houdini source was distributed for a simple
library to load and save .[b]geo files.  This code is no longer
distributed as its antiquated interface had become outdated.  Instead,
we recommend file converters be written using the HDK.  Support can
provide at your request a copy of the source to the current GPD
library.  Be warned its functionality does not exceed loading and
saving files and can only act as a rough template of how to work with
.[b]geo files.  

At the end of this document are several example files (uuencoded)
used for illustration.

FILE FORMAT
-----------

1) Header Section
   --------------

    Magic Number:	PGEOMETRY V#
    Point/Prim Counts:	NPoints # NPrims #
    Group Counts:	NPointGroups # NPrimGroups #
    Attribute Counts:	NPointAttrib # NVertexAttrib # NPrimAttrib # NAttrib #

    In each of these cases, the # represents the number of the element
    described.

    V# is the version of the geo file format.

    Groups are named and may be defined to contain either points or primitives.
    Each point or primitive can be a member of any number of groups, thus
    membership is not exclusive to one group.

    Attributes in GPD have been generalized.  Attributes can be assigned
    per point, per vertex, per primitive or on the detail.  Therefore, the
    number of attributes is declared at the top of the file.  Later, each
    of these attributes will be defined in full.


2) Attribute Definitions
   ---------------------

    Internally, there are "dictionaries" to define the attributes associated
    with each element.  These dictionaries define the name of the attribute,
    the type of the attribute and the size of the attribute.  Also, the
    default value of the attribute is stored in the dictionary.

    When the dictionary is saved, each attribute (in a specific order)
    is defined.  The definition is basically as follows:
	Name Size Type Default
    For example, the attribute name for normals is "N", so the attribute
    definition would look like:
	N 3 float 0 0 0
    Specifying the attribute name "N", that there are 3 elements in this
    attribute and the type is float.  The default value would be (0, 0, 0)

    Following the element definition is the attribute data associated
    with the element.  There are braces delineating the attribute data.
    The attribute data appears in the order that the dictionary for the
    element was defined.

    For example, a dictionary might look like:

	PointAttrib
	Cd 3 float 0 0 0	# Color attribute, 3 floats, default 0 0 0
	Alpha 1 float 1		# Alpha attribute, 1 float, default 1
	N 3 float 0 0 0		# Normal attribute
	uv 2 float 0 0		# Texture coordinate

    The data for the point might look like:
	0 0 0 1  (1 0 0  1  0 0 1  .5 .5)
	^^^^^^^	 ^^^^^^^^^^^^^^^^^^^^^^^^
	Position	Attributes
    The point would have:
	Cd = (1, 0, 0)
	Alpha = 1
	N = (0 0 1)
	uv = (.5, .5)

    The types of attribute data supported are:  integer, float, string and
    index.  The "string" type is stored as a 32 character string since
    each attribute must have a fixed length.  The integer and float types
    are pretty self-explanatory.  The index attribute type is used
    for specifying things like material.  It contains a list of strings
    which are indexed by integer values.  Thus the storage for an index
    attribute is an integer.  In the definition of the index attribute,
    the attribute values are defined as well.
	mat 1 index 3 marble gold crystal_glass3
    The default value for all index attributes is -1 indicating that
    the attribute has not been assigned.

3)  Point Definitions
    -----------------

    If there are point attributes, the attribute dictionary is saved
    before the definition of the points.
	Dictionary Name:		PointAttrib
	Dictionary Data:		-- Attribute Definition --

    Following the attribute dictionary, is the point data for the points.
    Each point is stored with 4 components (x, y, z & w).  The positions
    are not true homogeneous coordinates.  To get the homogeneous coord,
    simply multiply each x, y & z by w.

    If (and only if) there is attribute data, the attribute data is
    defined following the point position.  The attribute data is enclosed
    in parenthesis "()".

4)  Primitive/Vertex Definitions
    ----------------------------

    If (and only if) there are vertex attributes, the attribute dictionary
    is found here.

    Following the vertex attribute dictionary is the primitive attribute
    dictionary (iff there are attributes for primitives).

    Since every primitive may have local information which needs to be
    saved, the format of every primitive is different.  In general, the
    format is:

	PrimKey <local_information> [attributes]

    Here, the local_information is primitive specific.

    As part of the local information, a vertex or multiple vertices are
    specified.  Each vertex is saved in the same format, which is:

	point_number attribute_data

    The point numbers start at 0 and go through NPoints - 1.
    If there is vertex attribute data, the data is delimited by
    parenthesis "()".

    If there is primitive attribute data, it is delimited by brackets "[]".

    Each primitive has a unique identifier.  The current primitives and
    their identifiers are:

	Polygon:		"Poly"
	NURBS Curve:		"NURBCurve"
	Rational Bezier Curve:	"BezierCurve"
	Linear Patch:		"Mesh"
	NURBS Surface		"NURBMesh"
	Rational Bezier Patch:	"BezierMesh"
	Paste Hierarchy:	"PasteSurf"
	Ellipse/Circle:		"Circle"
	Ellipsoid/Sphere:	"Sphere"
	Tube/Cone:		"Tube"
	Metaball		"MetaBall"
	Meta Super-Quadric	"MetaSQuad"
	Particle System:	"Part"
	Triangle Strips:	"TriStrip"
	Triangle Fans:		"TriFan"
	Triangular Beziers:	"TriBezier"

    The primitive keys are case sensitive.

    For example:

	VertexAttrib
	uv 3 float 0 0 0
	PrimitiveAttrib
	Cd 3 float 0 0 0
	Poly 3 < 0 (1 0.5 0) 1 (0 0 0) 2 (0 1 0) [1 1 0 .5]

    Would specify a closed polygon (see below) which has 3 vertices
    referencing points 0, 1 & 2.  Each vertex has 3D texture coordinates
    specified in (), the polygon has Color and Alpha specified in [].
    The color is yellow, with 50% alpha coverage.

    When there are two or more consecutive primitives of the same type,
    this is specified as a run of primitives.  In this case, the
    following should appear in the file:

	Run # PrimKey

    Where # is the number of primitives in the run.  In this case, the
    following primitives are not saved with the PrimKey identifier since
    it is implicit in the run.

4a) Local Primitive Information
    ---------------------------

    POLYGON Local Information Format
    -------
	#Vtx OpenClose Vertex_List

	#Vtx		= Number of vertices in the polygon
	OpenClose	= A single character flag:
				"<" = Closed face
				":" = Open face

    
    NURBS/BEZIER CURVE Local Information Format
    ------------------
	#Vtx OpenClose Basis Vertex_List

	The basis definition for both NURBS and Bezier primitives starts with:

	    Keyword Order

	Where:
	    Keyword		= "Basis"
	    Order		= The order of the basis (degree + 1)

	The NURBS Basis
	---------------
	The NURBS basis requires an end condition flag and a list of knots
	sorted in increasing order. The complete definition of the NURBS basis
	is:

	    Keyword Order EndCondition Knots
	
	Where:
	    EndCondition	= "end" to touch the end CVs, "noend" otherwise.
	    Knots		= Floating point numbers in increasing order.

	The number of knots in the list is determined by the order of the
	basis, its end conditions, the number of CVs in the Vertex_List, and 
	the OpenClose flag. 

	Let #K be the number of expected knots, and #Vtx the number of CVs. 
	Then, if the EndCondition is false (ie. "noend"),
	    #K = #Vtx + Order - 2 
	The two missing end knots (and the periodicity knots if closed) are
	generated internally.

	If theEndCondition is true (ie. "end), then:
	    if the curve is open	#K = #Vtx - Order + 2
	    if the curve is closed	#K = #Vtx - Order + 3

	The Bezier Basis
	----------------
	The Bezier basis does not require a list of knots if the knots start
	at 0 and grow with unit increments (e.g. 0 1 2 3 ...)
	The complete definition of the Bezier basis is:

	    Keyword Order Knots
	
	The number of knots in the list is determined by the order of the
	basis, the number of CVs in the Vertex_List, and the OpenClose flag.

	Let #K be the number of expected knots, #Vtx the number of CVs. Then:
	    if the curve is open	#K = (#Vtx-1) / (Order-1) + 1
	    if the curve is closed	#K = (#Vtx  ) / (Order-1)

	If the curve is closed, the periodicity knot is generated internally.


    MESH Local Information Format
    ----
	#Cols #Rows UWrap VWrap connectivity

	UWrap / VWrap:		"open" or "wrap" columns or rows respectively
	connectivity:		"rows"		- Rows only
				"cols"		- Columns only
				"rowcol"	- Rows & Columns
				"quad"		- Quad
				"tri"		- Triangulated quads
				"atri"		- Alternate triangulated
				"revtri"	- Reverse triangulated

	The connectivity is ignored in many cases, but is critical for
	operations like sweeping or conversion to polygons.

	Default triangulated ("tri") meshes are structured like:
		+-+-+
		|/|/|
		+-+-+
		|/|/|
		+-+-+

	Alternate triangulation looks like:
		+-+-+
		|\|/|
		+-+-+
		|/|\|
		+-+-+

	Reverse triangulated ("revtri") meshes are structured like:
		+-+-+
		|\|\|
		+-+-+
		|\|\|
		+-+-+

    NURBS/BEZIER SURFACE Local Information Format
    --------------------
	#Cols #Rows UWrap VWrap connectivity UBasis VBasis Vertex_List Profiles

	#Cols, #Rows, UWrap, VWrap, connectivity, and Vertex_List are the same
	as for MESH. UBasis and VBasis are the same as for NURBS/BEZIER CURVE.

	Profiles is an optional list of profile curves (curves on surfaces).
	The structure of the profiles section is very similar to that of the
	main geometry, including a header section, points, primitives, point 
	and primitive groups. The differences are that this section doesn't
	contain any attributes and has only three profile types: polygon,
	NURBS curve, and Bezier curve.

	The profile token is "Profiles:". It is followed by " none" if there
	are no profiles. If there are profiles, the profile section has the
	following structure:

	    Point/Prim Counts:	NPoints # NPrims # NLoops #
	    Group Counts:	NPointGroups # NPrimGroups #
	    Nested trim level:	TrimLevel #
	    Point list:		u v w  triplets
	    Primitive list	polygons, NURBS/Bezier curves
	    Trim Regions
	    Point group definitions
	    Profile group definitions

	a. Header section
	-----------------
	Point/Prim Counts:	NPoints # NPrims # NLoops #
	Group Counts:		NPointGroups # NPrimGroups #

	In each of these cases, the # represents the number of the element
	described.

	Nested trim level:	TrimLevel #

	In this case, # represents the sea-level for nested trimmed loops,
	and can be either positive or negative. Usually it is 0.

	A primitive is a 2D profile: a polygon, a Bezier curve, or a NURBS 
	curve living within the domain of the spline surface. The points are
	2D locations (i.e. uv pairs with a third, w (weight) component) in
	the surface domain.

	The loops are trimming loops, also know as "trim regions", defined
	by the primitive profiles mentioned above. It is possible to have
	several profiles on a surface and yet no trim loops.

	Groups are named and may be defined to contain either points or
	profiles. Each point or primitive can be a member of any number of
	groups, thus membership is not exclusive to one group.

	b. Point section
	----------------
	Each point is stored with 3 components (x, y, w).  The positions
	are not true homogeneous coordinates.  To get the homogeneous coord,
	simply multiply each x, y by w.

	c. Primitive section
	--------------------
	Since every profile may have local information which needs to be
	saved, the format of every primitive is different.  In general, the
	format is:

	    ProfileKey <local_information>

	Here, the local_information is profile specific.

	As part of the local information, a vertex or multiple vertices are
	specified.  Each vertex is saved in the same format, which is:

	    point_number

	The point numbers start at 0 and go through NPoints - 1.

	Each profile has a unique identifier. The current profiles and
	their identifiers are identical to their 3D counterparts:

	    Polygon:			"Poly"
	    NURBS Curve:		"NURBCurve"
	    Rational Bezier Curve:	"BezierCurve"

	The profile keys are case sensitive.

	For example:

	    Poly 3 < 0 1 2

	Would specify a closed polygon (see below) which has 3 vertices
	referencing 2D points 0, 1 & 2.

	When there are two or more consecutive profiles of the same type,
	this is specified as a run of profiles.  In this case, the following
	should appear in the file:

	    Run # ProfileKey

	Where # is the number of profiles in the run.  In this case, the
	following profiles are not saved with the ProfileKey identifier since
	it is implicit in the run.

	The format of the three profile types - polygon, NURBS curve, and
	Bezier curve - is identical to that of the 3D primitives and won't
	be listed again here.

	d. Trimming section
	-------------------
	If NLoops is not zero, the surface will contain one or more trim 
	regions. Each region can contain one or more profiles.
	
	Typically, the profiles should intersect to form a closed loop.
	Sometimes, though, as in the case of a loop that intersects the domain
	boundaries, the loop is partially defined by the domain boundaries and
	need not be explicitly closed.

	Single profile loops that are open and do not intersect the domain
	boundaries will be closed straight by houdini.

	The trimming section contains one or more lines like the one below,
	one line per trim region:

	TrimRegion [natural] #Profiles <profile_number ustart uend> ...

	If "natural" is specified, open profiles are treated casually, i.e.
	their parametric direction is not checked and will not be reversed.

	profile_number is the index of each profile in the current trim region.

	ustart and uend are the parametric values defining the beginning and
	end of the profile. It is thus possible to use only a section of a
	profile for trimming.

	To reverse the direction of the trim curve without reversing the
	vertices of the profile itself, specify a ustart greater than ustop.
	A profile can therefore used in more than one trim region, and can have
	different orientations and lengths in each region.

	When punching holes in a surface, an outer profile is needed to specify
	the area of the surface to be kept. Usually, the outer profile is a
	closed polygon that envelops the perimeter of the domain.

	Example: TrimRegion 2   0  1 0   5 -3.5 8

	The trim region has two profiles: 0 and 5. Profile 0 is reversed
	by evaluating between 1 and 0. Profile 5 is used between -3.5 and 8.

	e. Groups section
	-------------------
	The point groups are saved first, followed by the profile groups.
	There is no identifier indicating the groups.  The format for
	a group depends on whether it is ordered or unordered:

	    GroupName Type NElements BitMask ElementList

	GroupName	- is the name of the group.
	Type		- is "unordered" or "ordered".
	
	NElements	- Specifies the total number of bits in the BitMask.
			  This is equivalent to NPrims in the profile header.
	BitMask		- A string of 0's and 1's, where 1 indicates membership
			  in the group.
	ElementList	- If the groups is ordered, the element list contains
			  the index of each selected point or profile in
			  selection order. The first element of the list is the
			  number of ordered elements in the list.

    PASTE HIERARCHY Local Information Format
    ---------------
	#Features

	 followed by as many lines as feature surfaces, in the order in which
	 the surfaces are pasted. Each feature line has the format:

	 Feature prim_number height up_or_down <domain_xform>

	 prim_number is the index of the spline surface in the list of 
	 primitives. height is the elevation of the pasted surface from its
	 base. up_or_down is 1 is pasted upward, 0 if downward.

	 The domain transformation is either linear or bilinear.

	 Linear transformation format:
	 -----------------------------
	 Linear tx ty
	 UT_Matrix2 m00 m01 m10 m11

	 The translation in the domain is given by (tx,ty). The rotation
	 and scaling components are captured in the 2x2 matrix.

	 Bilinear transformation format:
	 -------------------------------
	 Bilinear origUL origUR origLR origLL warpUL warpUR warpLR warpLL

	 L,U,L,R stand for Lower, Upper, Left and Right respectively. Each of
	 the eight locations is a (u,v) pair in the surface domain.

	 Example of a paste hierarchy with three surfaces:

	 PasteSurf 3
	 Feature 0  0 1
	 Linear 0 0
	 UT_Matrix2 1 0 0 1 
	 Feature 2  0.02 1  
	 Bilinear
	 0 0.6
	 0.6 0.6 
	 0.6 0
	 0 0 
	 100.1 -22
	 100.4 -22
	 100.4 -28
	 100.1 -28
	 Feature 3  0.07 0  
	 Bilinear
	 0 1
	 1 1 
	 1 0 
	 0 0 
	 100.2 -21
	 100.45 -21
	 100.45 -26
	 100.2 -26

    CIRCLE Local Information Format
    ------
	Vertex_Info Matrix33

	There is always only one vertex for a Circle.
	The 3x3 matrix contains scaling and rotation transformations about
	the center of the circle. Sheared circles are thus allowed.
	circle.

    SPHERE Local Information Format
    ------
	Vertex_Info Matrix33

	There is always only one vertex for a Sphere.
	The 3x3 matrix contains scaling and rotation transformations about
	the center of the sphere. Sheared spheres are thus allowed.

    TUBE/CONE Local Information Format
    ---------
	Vertex_Info Taper Closure Matrix33

	There is always only one vertex for a Tube/Cone. The vertex lies in
	the center of the tube (along the axis connecting the centers of the
	top and bottom circles/ellipses). The taper value affects the radius
	of the top circle. A regular tube has a taper value of 1. A cone's
	taper is 0. The closure - "closed" or "open" - indicates whether the
	tube is end-capped.
	The 3x3 matrix contains scaling and rotation transformations about
	the center of the tube. Sheared tubes are thus allowed.

    METABALL Local Information Format
    --------
	Vertex_Info Kernel_Function Weight Matrix33

	There is always only one vertex for a metaball.
	The kernel function is one of: "wyvill", "quartic", "blinn" or "links".
	The 3x3 matrix contains scaling and rotation transformations about
	the center of the metaball. Sheared metaballs are thus allowed.

    META SUPER-QUADRIC Local Information Format
    ------------------
	Vertex_Info XY_Exponent Z_Exponent Kernel_Function Weight Matrix33

	There is always only one vertex for a meta super-quadric.
	The exponents are float values.
	The kernel function is one of: "wyvill", "quartic", "blinn" or "links".
	The 3x3 matrix contains scaling and rotation transformations about
	the center of the metaball. Sheared metaballs are thus allowed.

    PARTICLE SYSTEM Local Information Format
    ---------------
	Part_Count Vertex_List

	Where Part_Count is the number of particles in the system.

    TRIANGLE STRIPS Local Information Format
    ---------------
	Vertex_Count Vertex_List

	Where Vertex_Count is the number of points in the triangle
	strip.
	        1-3
	       /|/| 
	      0-2-4

    TRIANGLE FANS Local Information Format
    -------------
	Vertex_Count Anchor_Vertex Vertex_List

	Where Vertex_Count is the number of vertices in the triangle
	fan.  The first vertex forms the anchor and each successive
	vertex forms a point on a successive triangle:

	      1-2-3
               \|/|
	        0-4

    TRIANGULAR BEZIERS Local Information Format
    ------------------
	Order Vertex_List

	The order is the order of the triangular patch.  There are
	order*(order+1)/2 vertices forming the patch.  The order of
	the vertices is, for a degree 3 patch:

	      Column
        Row +--------
	 0  | 6 7 8 9
	 1  | 3 4 5
	 2  | 1 2
	 3  | 0

	The vertex index of the vertex in row/column (r,c) is found by
	calling the GEO_PrimTriBezier::getRawIndex() function.

5)  Detail Attributes
    -----------------

	The Detail Attribute Dictionary is saved after the Primitives
	and before the group information.

6)  Point/Primitive Group Definitions
    ---------------------------------

    The Point groups are saved first, followed by the primitive groups.
    There is no identifier indicating the groups.  The format for
    a group depends on whether it is ordered or unordered:

	GroupName Type NElements BitMask ElementList

    GroupName	- is the name of the group.
    Type	- is "unordered" or "ordered".
    
    NElements	- Specifies the total number of bits in the BitMask. This 
		  is equivalent to the number of elements in the detail.
    BitMask	- In the ASCII format, this is a string of 0's and 1's, where
		  1 indicates membership in the group.
    ElementList	- If the groups is ordered, the element list contains the
		  index of each selected point or primitive in selection order.
		  The first element of the list is the number of ordered 
		  elements in the list. In the case of primitive lists 
		  a second profile element may be described by appending
		  a period and a secondary index number to each element.
		  For example 5 specified the fifth primitive while 5.12
		  specifies the twelfth profile curve of the fifth primitive.
		  The list must be empty if the group is unordered.

7)  Other Information
    -----------------

	This is meant for saving information such as metaball expressions and
	surface hierarchies. Currently this section contains only the 
	delimiting tokens, one per line:

		beginExtra
		endExtra
		
	For now the Extra body is empty because all the metaballs are merged 
	("add"-ed implicitly) and there is no support for surface hierarchies.


Example File
-------------

To extract the information:
    save to a file
    run uudecode on the file
    This should generate all.geo.Z
    Run "uncompress all.geo.Z" which will create "all.geo" - a file containing
    all the primitives, groups, and attributes.

--- Begin UUENCODED data --
begin 664 all.geo.Z
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
2!B)"$<`#.2$,*(!8]S%#I@(`
`
end
--- End UUENCODED data --
