gts

`PyGTS is a python binding for the GNU Triangulated Surface (GTS)
Library, which may be used to build, manipulate, and perform
computations on triangulated surfaces.
The following geometric primitives are provided:
Point - a point in 3D space
Vertex - a Point in 3D space that may be used to define a Segment
Segment - a line defined by two Vertex end-points
Edge - a Segment that may be used to define the edge of a Triangle
Triangle - a triangle defined by three Edges
Face - a Triangle that may be used to define a face on a Surface
Surface - a surface composed of Faces
A tetrahedron is assembled from these primitives as follows. First,
create Vertices for each of the tetrahedron's points:
import gts
v1 = gts.Vertex(1,1,1)
v2 = gts.Vertex(-1,-1,1)
v3 = gts.Vertex(-1,1,-1)
v4 = gts.Vertex(1,-1,-1)
Next, connect the four vertices to create six unique Edges:
e1 = gts.Edge(v1,v2)
e2 = gts.Edge(v2,v3)
e3 = gts.Edge(v3,v1)
e4 = gts.Edge(v1,v4)
e5 = gts.Edge(v4,v2)
e6 = gts.Edge(v4,v3)
The four triangular faces are composed using three edges each:
f1 = gts.Face(e1,e2,e3)
f2 = gts.Face(e1,e4,e5)
f3 = gts.Face(e2,e5,e6)
f4 = gts.Face(e3,e4,e6)
Finally, the surface is assembled from the faces:
s = gts.Surface()
for face in [f1,f2,f3,f4]:
s.add(face)
Some care must be taken in the orientation of the faces. In the above
example, the surface normals are pointing inward, and so the surface
technically defines a void, rather than a solid. To create a
tetrahedron with surface normals pointing outward, use the following
instead:
f1.revert()
s = Surface()
for face in [f1,f2,f3,f4]:
if not face.is_compatible(s):
face.revert()
s.add(face)
Once the Surface is constructed, there are many different operations that
can be performed. For example, the volume can be calculated using:
s.volume()
The difference between two Surfaces s1 and s2 is given by:
s3 = s2.difference(s1)
Etc.
It is also possible to read in GTS data files and plot surfaces to
the screen. See the example programs packaged with PyGTS for
more information.`

Classes

``

__builtin__.object
  Object
    Point
      Vertex
    Segment
      Edge
    Surface
    Triangle
      Face

class Edge(Segment)
`` | `Edge object`

Method resolution order:
  Edge
  Segment
  Object
  __builtin__.object

Methods defined here:

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

belongs_to_tetrahedron(...)
  `Returns True if this Edge e belongs to a tetrahedron.
  Otherwise False.
  Signature: e.belongs_to_tetrahedron()`

contacts(...)
  `Returns number of sets of connected triangles share this Edge e
  as a contact Edge.
  Signature: e.contacts()`

face_number(...)
  `Returns number of faces using this Edge e on Surface s.
  Signature: e.face_number(s)`

is_boundary(...)
  `Returns True if this Edge e is a boundary on Surface s.
  Otherwise False.
  Signature: e.is_boundary(s)`

is_ok(...)
  `True if this Edge e is not degenerate or duplicate.
  False otherwise. Degeneracy implies e.v1.id == e.v2.id.
  Signature: e.is_ok()`

is_unattached(...)
  `True if this Edge e is not part of any Triangle.
  Signature: e.is_unattached()`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c780>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Segment:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

connects(...)
  `Returns True if this Segment s1 connects Vertices v1 and v2.
  False otherwise.
  Signature: s1.connects(v1,v2).`

intersection(...)
  `Returns the intersection of Segment s with Triangle t
  This function is geometrically robust in the sense that it will
  return None if s and t do not intersect and will return a
  Vertex if they do. However, the point coordinates are subject
  to round-off errors. None will be returned if s is contained
  in the plane defined by t.
  Signature: s.intersection(t) or s.intersection(t,boundary).
  If boundary is True (default), the boundary of s is taken into
  account.
  Returns a summit of t (if boundary is True), one of the endpoints
  of s, a new Vertex at the intersection of s with t, or None if
  s and t don't intersect.`

intersects(...)
  `Checks if this Segment s1 intersects with Segment s2.
  Returns 1 if they intersect, 0 if an endpoint of one Segment lies
  on the other Segment, -1 otherwise
  Signature: s1.intersects(s2).`

midvertex(...)
  `Returns a new Vertex at the mid-point of this Segment s.
  Signature: s.midvertex().`

touches(...)
  `Returns True if this Segment s1 touches Segment s2
  (i.e., they share a common Vertex). False otherwise.
  Signature: s1.touches(s2).`

Data descriptors inherited from Segment:

v1
  `Vertex 1`

v2
  `Vertex 2`

Data descriptors inherited from Object:

id
  `GTS object id`

class Face(Triangle)
`` | `Face object`

Method resolution order:
  Face
  Triangle
  Object
  __builtin__.object

Methods defined here:

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

is_compatible(...)
  `True if Face f is compatible with all neighbors in Surface s.
  False otherwise.
  Signature: f.is_compatible(s).`

is_ok(...)
  `True if this Face f is non-degenerate and non-duplicate.
  False otherwise.
  Signature: f.is_ok()`

is_on(...)
  `True if this Face f is on Surface s. False otherwise.
  Signature: f.is_on(s).`

is_unattached(...)
  `True if this Face f is not part of any Surface.
  Signature: f.is_unattached().`

neighbor_number(...)
  `Returns the number of neighbors of Face f belonging to Surface s.
  Signature: f.neighbor_number(s).`

neighbors(...)
  `Returns a tuple of neighbors of this Face f belonging to Surface s.
  Signature: f.neighbors(s).`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75cb00>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Triangle:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

angle(...)
  `Returns the angle (radians) between Triangles t1 and t2
  Signature: t1.angle(t2)`

area(...)
  `Returns the area of Triangle t.
  Signature: t.area()`

circumcenter(...)
  `Returns a Vertex at the center of the circumscribing circle of
  this Triangle t, or None if the circumscribing circle is not
  defined.
  Signature: t.circumcircle_center()`

common_edge(...)
  `Returns Edge common to both this Triangle t1 and other t2.
  Returns None if the triangles do not share an Edge.
  Signature: t1.common_edge(t2)`

interpolate_height(...)
  `Returns the height of the plane defined by Triangle t at Point p.
  Only the x- and y-coordinates of p are considered.
  Signature: t.interpolate_height(p)`

is_stabbed(...)
  `Returns the component of this Triangle t that is stabbed by a
  ray projecting from Point p to z=infinity. The result
  can be this Triangle t, one of its Edges or Vertices, or None.
  If the ray is contained in the plan of this Triangle then None is
  also returned.
  Signature: t.is_stabbed(p)`

normal(...)
  `Returns a tuple of coordinates of the oriented normal of Triangle t
  as the cross-product of two edges, using the left-hand rule. The
  normal is not normalized. If this triangle is part of a closed and
  oriented surface, the normal points to the outside of the surface.
  Signature: t.normal()`

opposite(...)
  `Returns Vertex opposite to Edge e or Edge opposite to Vertex v
  for this Triangle t.
  Signature: t.opposite(e) or t.opposite(v)`

orientation(...)
  `Determines orientation of the plane (x,y) projection of Triangle t
  Signature: t.orientation()
  Returns a positive value if Points p1, p2 and p3 in Triangle t
  appear in counterclockwise order, a negative value if they appear
  in clockwise order and zero if they are colinear.`

perimeter(...)
  `Returns the perimeter of Triangle t.
  Signature: t.perimeter()`

quality(...)
  `Returns the quality of Triangle t.
  The quality of a triangle is defined as the ratio of the square
  root of its surface area to its perimeter relative to this same
  ratio for an equilateral triangle with the same area. The quality
  is then one for an equilateral triangle and tends to zero for a
  very stretched triangle.
  Signature: t.quality()`

revert(...)
  `Changes the orientation of triangle t, turning it inside out.
  Signature: t.revert()`

vertex(...)
  `Returns the Vertex of this Triangle t not in t.e1.
  Signature: t.vertex()`

vertices(...)
  `Returns the three oriented set of vertices in Triangle t.
  Signature: t.vertices()`

Data descriptors inherited from Triangle:

e1
  `Edge 1`

e2
  `Edge 2`

e3
  `Edge 3`

Data descriptors inherited from Object:

id
  `GTS object id`

class Object(__builtin__.object)
`` | `Base object`

Methods defined here:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

is_unattached(...)
  `True if this Object o is not attached to another Object.
  Otherwise False.
  Trace: o.is_unattached().`

Data descriptors defined here:

id
  `GTS object id`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c0e0>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

class Point(Object)
`` | `Point object`

Method resolution order:
  Point
  Object
  __builtin__.object

Methods defined here:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

closest(...)
  `Set the coordinates of Point p to the Point on Segment s
  or Triangle t closest to the Point p2
  Signature: p.closest(s,p2) or p.closest(t,p2)
  Returns the (modified) Point p.`

coords(...)
  `Returns a tuple of the x, y, and z coordinates for this Point p.
  Signature: p.coords(x,y,z)`

distance(...)
  `Returns Euclidean distance between this Point p and other Point p2,
  Segment s, or Triangle t.
  Signature: p.distance(p2), p.distance(s) or p.distance(t)`

distance2(...)
  `Returns squared Euclidean distance between Point p and Point p2,
  Segment s, or Triangle t.
  Signature: p.distance2(p2), p.distance2(s), or p.distance2(t)`

is_in(...)
  `Tests if this Point p is inside or outside Triangle t.
  The planar projection (x,y) of Point p is tested against the
  planar projection of Triangle t.
  Signature: p.in_circle(p1,p2,p3) or p.in_circle(t)
  Returns a +1 if p lies inside, -1 if p lies outside, and 0
  if p lies on the triangle.`

is_in_circle(...)
  `Tests if this Point p is inside or outside circumcircle.
  The planar projection (x,y) of Point p is tested against the
  circumcircle defined by the planar projection of p1, p2 and p3,
  or alternatively the Triangle t
  Signature: p.in_circle(p1,p2,p3) or p.in_circle(t)
  Returns +1 if p lies inside, -1 if p lies outside, and 0 if p lies
  on the circle. The Points p1, p2, and p3 must be in
  counterclockwise order, or the sign of the result will be reversed.`

is_in_rectangle(...)
  `True if this Point p is in box with bottom-left and upper-right
  Points p1 and p2.
  Signature: p.is_in_rectange(p1,p2)`

is_inside(...)
  `True if this Point p is inside or outside Surface s.
  False otherwise.
  Signature: p.in_inside(s)`

is_ok(...)
  `True if this Point p is OK. False otherwise.
  This method is useful for unit testing and debugging.
  Signature: p.is_ok().`

orientation_3d(...)
  `Determines if this Point p is above, below or on plane of 3 Points
  p1, p2 and p3.
  Signature: p.orientation_3d(p1,p2,p3)
  Below is defined so that p1, p2 and p3 appear in counterclockwise
  order when viewed from above the plane.
  The return value is positive if p4 lies below the plane, negative
  if p4 lies above the plane, and zero if the four points are
  coplanar. The value is an approximation of six times the signed
  volume of the tetrahedron defined by the four points.`

orientation_3d_sos(...)
  `Determines if this Point p is above, below or on plane of 3 Points
  p1, p2 and p3.
  Signature: p.orientation_3d_sos(p1,p2,p3)
  Below is defined so that p1, p2 and p3 appear in counterclockwise
  order when viewed from above the plane.
  The return value is +1 if p4 lies below the plane, and -1 if p4
  lies above the plane. Simulation of Simplicity (SoS) is used to
  break ties when the orientation is degenerate (i.e. the point lies
  on the plane definedby p1, p2 and p3).`

rotate(...)
  `Rotates Point p around vector dx,dy,dz by angle a.
  The sense of the rotation is given by the right-hand-rule.
  Signature: p.rotate(dx=0,dy=0,dz=0,a=0)`

scale(...)
  `Scales Point p by vector dx,dy,dz.
  Signature: p.scale(dx=1,dy=1,dz=1)`

set(...)
  `Sets x, y, and z coordinates of this Point p.
  Signature: p.set(x,y,z)`

translate(...)
  `Translates Point p by vector dx,dy,dz.
  Signature: p.translate(dx=0,dy=0,dz=0)`

Data descriptors defined here:

x
  `x value`

y
  `y value`

z
  `z value`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c200>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Object:

is_unattached(...)
  `True if this Object o is not attached to another Object.
  Otherwise False.
  Trace: o.is_unattached().`

Data descriptors inherited from Object:

id
  `GTS object id`

class Segment(Object)
`` | `Segment object`

Method resolution order:
  Segment
  Object
  __builtin__.object

Methods defined here:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

connects(...)
  `Returns True if this Segment s1 connects Vertices v1 and v2.
  False otherwise.
  Signature: s1.connects(v1,v2).`

intersection(...)
  `Returns the intersection of Segment s with Triangle t
  This function is geometrically robust in the sense that it will
  return None if s and t do not intersect and will return a
  Vertex if they do. However, the point coordinates are subject
  to round-off errors. None will be returned if s is contained
  in the plane defined by t.
  Signature: s.intersection(t) or s.intersection(t,boundary).
  If boundary is True (default), the boundary of s is taken into
  account.
  Returns a summit of t (if boundary is True), one of the endpoints
  of s, a new Vertex at the intersection of s with t, or None if
  s and t don't intersect.`

intersects(...)
  `Checks if this Segment s1 intersects with Segment s2.
  Returns 1 if they intersect, 0 if an endpoint of one Segment lies
  on the other Segment, -1 otherwise
  Signature: s1.intersects(s2).`

is_ok(...)
  `True if this Segment s is not degenerate or duplicate.
  False otherwise. Degeneracy implies s.v1.id == s.v2.id.
  Signature: s.is_ok().`

midvertex(...)
  `Returns a new Vertex at the mid-point of this Segment s.
  Signature: s.midvertex().`

touches(...)
  `Returns True if this Segment s1 touches Segment s2
  (i.e., they share a common Vertex). False otherwise.
  Signature: s1.touches(s2).`

Data descriptors defined here:

v1
  `Vertex 1`

v2
  `Vertex 2`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c600>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Object:

is_unattached(...)
  `True if this Object o is not attached to another Object.
  Otherwise False.
  Trace: o.is_unattached().`

Data descriptors inherited from Object:

id
  `GTS object id`

class Surface(Object)
`` | `Surface object`

Method resolution order:
  Surface
  Object
  __builtin__.object

Methods defined here:

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

__iter__(...)
  `x.__iter__() <==> iter(x)`

add(...)
  `Adds a Face f or Surface s2 to Surface s1.
  Signature: s1.add(f) or s2.add(f)`

area(...)
  `Returns the area of Surface s.
  The area is taken as the sum of the signed areas of the Faces of s.
  Signature: s.area()`

boundary(...)
  `Returns a tuple of boundary Edges of Surface s.
  Signature: s.boundary()`

center_of_area(...)
  `Returns the coordinates of the center of area of Surface s.
  Signature: s.center_of_area()`

center_of_mass(...)
  `Returns the coordinates of the center of mass of Surface s.
  Signature: s.center_of_mass()`

cleanup(...)
  `Cleans up the Vertices, Edges, and Faces on a Surface s.
  Signature: s.cleanup() or s.cleanup(threhold)
  If threhold is given, then Vertices that are spaced less than
  the threshold are merged. Degenerate Edges and Faces are also
  removed.`

coarsen(...)
  `Reduces the number of vertices on Surface s.
  Signature: s.coarsen(n) and s.coarsen(amin)
  n is the smallest number of desired edges (but you may get fewer).
  amin is the smallest angle between Faces.`

copy(...)
  `Copys all Faces, Edges and Vertices of Surface s2 to Surface s1.
  Signature: s1.copy(s2)
  Returns s1.`

difference(...)
  `Returns the difference of this Surface s1 with Surface s2.
  Signature: s1.difference(s2)`

distance(...)
  `Calculates the distance between the faces of this Surface s1 and
  the nearest Faces of other s2, and (if applicable) the distance
  between the boundary of this Surface s1 and the nearest boundary
  Edges of other s2.
  One or two dictionaries are returned (where applicable), the first
  for the face range and the second for the boundary range. The
  fields in each dictionary describe statistical results for each
  population: {min,max,sum,sum2,mean,stddev,n}.
  Signature: s1.distance(s2) or s1.distance(s2,delta)
  The value delta is a spatial increment defined as the percentage
  of the diagonal of the bounding box of s2 (default 0.1).`

edges(...)
  `Returns tuple of Edges on Surface s that have Vertex in list.
  If a list is not given then all of the Edges are returned.
  Signature: s.edges(list) or s.edges()`

face_indices(...)
  `Returns a tuple of 3-tuples containing Vertex indices for each Face
  in Surface s. The index for each Vertex in a face corresponds to
  where it is found in the Vertex tuple vs.
  Signature: s.face_indices(vs)`

faces(...)
  `Returns tuple of Faces on Surface s that have Edge in list.
  If a list is not given then all of the Faces are returned.
  Signature: s.faces(list) s.faces()`

fan_oriented(...)
  `Returns a tuple of outside Edges of the Faces fanning from
  Vertex v on this Surface s. The Edges are given in
  counter-clockwise order.
  Signature: s.fan_oriented(v)`

intersection(...)
  `Returns the intersection of this Surface s1 with Surface s2.
  Signature: s1.intersection(s2)`

is_closed(...)
  `True if Surface s is closed, False otherwise.
  Note that a closed Surface is also a manifold.
  Signature: s.is_closed()`

is_manifold(...)
  `True if Surface s is a manifold, False otherwise.
  Signature: s.is_manifold()`

is_ok(...)
  `True if this Surface s is OK. False otherwise.
  Signature: s.is_ok()`

is_orientable(...)
  `True if Faces in Surface s have compatible orientation,
  False otherwise.
  Note that a closed surface is also a manifold. Note that an
  orientable surface is also a manifold.
  Signature: s.is_orientable()`

is_self_intersecting(...)
  `Returns True if this Surface s is self-intersecting.
  False otherwise.
  Signature: s.is_self_intersecting()`

manifold_faces(...)
  `Returns the 2 manifold Faces of Edge e on this Surface s
  if they exist, or None.
  Signature: s.manifold_faces(e)`

next(...)
  `x.next() -> the next value, or raise StopIteration`

parent(...)
  `Returns Face on this Surface s that has Edge e, or None
  if the Edge is not on this Surface.
  Signature: s.parent(e)`

quality_stats(...)
  `Returns quality statistics for this Surface f in a dict.
  The statistics include the {min, max, sum, sum2, mean, stddev,
  and n} for populations of face_quality, face_area, edge_length,
  and edge_angle. Each of these names are dictionary keys.
  See Triangle.quality() for an explanation of the face_quality.
  Signature: s.quality_stats()`

remove(...)
  `Removes Face f from this Surface s.
  Signature: s.remove(f)`

rotate(...)
  `Rotates Surface s about vector dx,dy,dz and angle a.
  The sense of the rotation is given by the right-hand-rule.
  Signature: s.rotate(dx,dy,dz,a)`

scale(...)
  `Scales Surface s by vector dx,dy,dz.
  Signature: s.scale(dx=1,dy=1,dz=1)`

split(...)
  `Splits a surface into a tuple of connected and manifold components.
  Signature: s.split()`

stats(...)
  `Returns statistics for this Surface f in a dict.
  The stats include n_faces, n_incompatible_faces,, n_boundary_edges,
  n_non_manifold_edges, and the statisics {min, max, sum, sum2, mean,
  stddev, and n} for populations of edges_per_vertex and
  faces_per_edge. Each of these names are dictionary keys.
  Signature: s.stats()`

strip(...)
  `Returns a tuple of strips, where each strip is a tuple of Faces
  that are successive and have one edge in common.
  Signature: s.split()`

tessellate(...)
  `Tessellate each face of this Surface s with 4 triangles.
  The number of triangles is increased by a factor of 4.
  Signature: s.tessellate()`

translate(...)
  `Translates Surface s by vector dx,dy,dz.
  Signature: s.translate(dx=0,dy=0,dz=0)`

union(...)
  `Returns the union of this Surface s1 with Surface s2.
  Signature: s1.union(s2)`

vertices(...)
  `Returns a tuple containing the vertices of Surface s.
  Signature: s.vertices()`

volume(...)
  `Returns the signed volume of the domain bounded by the Surface s.
  Signature: s.volume()`

write(...)
  `Saves Surface s to File f in GTS ascii format.
  All the lines beginning with #! are ignored.
  Signature: s.write(f)`

write_oogl(...)
  `Saves Surface s to File f in OOGL (Geomview) format.
  Signature: s.write_oogl(f)`

write_oogl_boundary(...)
  `Saves boundary of Surface s to File f in OOGL (Geomview) format.
  Signature: s.write_oogl_boundary(f)`

write_vtk(...)
  `Saves Surface s to File f in VTK format.
  Signature: s.write_vtk(f)`

Data descriptors defined here:

Nedges
  `The number of unique edges`

Nfaces
  `The number of unique faces`

Nvertices
  `The number of unique vertices`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75cc40>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Object:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

is_unattached(...)
  `True if this Object o is not attached to another Object.
  Otherwise False.
  Trace: o.is_unattached().`

Data descriptors inherited from Object:

id
  `GTS object id`

class Triangle(Object)
`` | `Triangle object`

Method resolution order:
  Triangle
  Object
  __builtin__.object

Methods defined here:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

angle(...)
  `Returns the angle (radians) between Triangles t1 and t2
  Signature: t1.angle(t2)`

area(...)
  `Returns the area of Triangle t.
  Signature: t.area()`

circumcenter(...)
  `Returns a Vertex at the center of the circumscribing circle of
  this Triangle t, or None if the circumscribing circle is not
  defined.
  Signature: t.circumcircle_center()`

common_edge(...)
  `Returns Edge common to both this Triangle t1 and other t2.
  Returns None if the triangles do not share an Edge.
  Signature: t1.common_edge(t2)`

interpolate_height(...)
  `Returns the height of the plane defined by Triangle t at Point p.
  Only the x- and y-coordinates of p are considered.
  Signature: t.interpolate_height(p)`

is_compatible(...)
  `True if this triangle t1 and other t2 are compatible;
  otherwise False.
  Checks if this triangle t1 and other t2, which share a common
  Edge, can be part of the same surface without conflict in the
  surface normal orientation.
  Signature: t1.is_compatible(t2)`

is_ok(...)
  `True if this Triangle t is non-degenerate and non-duplicate.
  False otherwise.
  Signature: t.is_ok()`

is_stabbed(...)
  `Returns the component of this Triangle t that is stabbed by a
  ray projecting from Point p to z=infinity. The result
  can be this Triangle t, one of its Edges or Vertices, or None.
  If the ray is contained in the plan of this Triangle then None is
  also returned.
  Signature: t.is_stabbed(p)`

normal(...)
  `Returns a tuple of coordinates of the oriented normal of Triangle t
  as the cross-product of two edges, using the left-hand rule. The
  normal is not normalized. If this triangle is part of a closed and
  oriented surface, the normal points to the outside of the surface.
  Signature: t.normal()`

opposite(...)
  `Returns Vertex opposite to Edge e or Edge opposite to Vertex v
  for this Triangle t.
  Signature: t.opposite(e) or t.opposite(v)`

orientation(...)
  `Determines orientation of the plane (x,y) projection of Triangle t
  Signature: t.orientation()
  Returns a positive value if Points p1, p2 and p3 in Triangle t
  appear in counterclockwise order, a negative value if they appear
  in clockwise order and zero if they are colinear.`

perimeter(...)
  `Returns the perimeter of Triangle t.
  Signature: t.perimeter()`

quality(...)
  `Returns the quality of Triangle t.
  The quality of a triangle is defined as the ratio of the square
  root of its surface area to its perimeter relative to this same
  ratio for an equilateral triangle with the same area. The quality
  is then one for an equilateral triangle and tends to zero for a
  very stretched triangle.
  Signature: t.quality()`

revert(...)
  `Changes the orientation of triangle t, turning it inside out.
  Signature: t.revert()`

vertex(...)
  `Returns the Vertex of this Triangle t not in t.e1.
  Signature: t.vertex()`

vertices(...)
  `Returns the three oriented set of vertices in Triangle t.
  Signature: t.vertices()`

Data descriptors defined here:

e1
  `Edge 1`

e2
  `Edge 2`

e3
  `Edge 3`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c8c0>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Object:

is_unattached(...)
  `True if this Object o is not attached to another Object.
  Otherwise False.
  Trace: o.is_unattached().`

Data descriptors inherited from Object:

id
  `GTS object id`

class Vertex(Point)
`` | `Vertex object`

Method resolution order:
  Vertex
  Point
  Object
  __builtin__.object

Methods defined here:

__init__(...)
  `x.__init__(...) initializes x; see x.__class__.__doc__ for signature`

contacts(...)
  `Returns the number of sets of connected Triangles sharing this
  Vertex v.
  Signature: v.contacts().
  If sever is True (default: False) and v is a contact vertex then
  the vertex is replaced in each Triangle with clones.`

encroaches(...)
  `Returns True if this Vertex v is strictly contained in the
  diametral circle of Edge e. False otherwise.
  Only the projection onto the x-y plane is considered.
  Signature: v.encroaches(e)`

faces(...)
  `Returns a tuple of Faces that have this Vertex v.
  If a Surface s is given, only Vertices on s are considered.
  Signature: v.faces() or v.faces(s).`

is_boundary(...)
  `True if this Vertex v is used by a boundary Edge of Surface s.
  Signature: v.is_boundary().`

is_connected(...)
  `Return True if this Vertex v1 is connected to Vertex v2
  by a Segment.
  Signature: v1.is_connected().`

is_ok(...)
  `True if this Vertex v is OK. False otherwise.
  This method is useful for unit testing and debugging.
  Signature: v.is_ok().`

is_unattached(...)
  `True if this Vertex v is not the endpoint of any Segment.
  Signature: v.is_unattached().`

neighbors(...)
  `Returns a tuple of Vertices attached to this Vertex v
  by a Segment.
  If a Surface s is given, only Vertices on s are considered.
  Signature: v.neighbors() or v.neighbors(s).`

replace(...)
  `Replaces this Vertex v1 with Vertex v2 in all Segments that have v1.
  Vertex v1 itself is left unchanged.
  Signature: v1.replace(v2).`

triangles(...)
  `Returns a list of Triangles that have this Vertex v.
  Signature: v.triangles()`

Data and other attributes defined here:

__new__ = <built-in method __new__ of type object at 0x75c480>
  `T.__new__(S, ...) -> a new object with type S, a subtype of T`

Methods inherited from Point:

__cmp__(...)
  `x.__cmp__(y) <==> cmp(x,y)`

closest(...)
  `Set the coordinates of Point p to the Point on Segment s
  or Triangle t closest to the Point p2
  Signature: p.closest(s,p2) or p.closest(t,p2)
  Returns the (modified) Point p.`

coords(...)
  `Returns a tuple of the x, y, and z coordinates for this Point p.
  Signature: p.coords(x,y,z)`

distance(...)
  `Returns Euclidean distance between this Point p and other Point p2,
  Segment s, or Triangle t.
  Signature: p.distance(p2), p.distance(s) or p.distance(t)`

distance2(...)
  `Returns squared Euclidean distance between Point p and Point p2,
  Segment s, or Triangle t.
  Signature: p.distance2(p2), p.distance2(s), or p.distance2(t)`

is_in(...)
  `Tests if this Point p is inside or outside Triangle t.
  The planar projection (x,y) of Point p is tested against the
  planar projection of Triangle t.
  Signature: p.in_circle(p1,p2,p3) or p.in_circle(t)
  Returns a +1 if p lies inside, -1 if p lies outside, and 0
  if p lies on the triangle.`

is_in_circle(...)
  `Tests if this Point p is inside or outside circumcircle.
  The planar projection (x,y) of Point p is tested against the
  circumcircle defined by the planar projection of p1, p2 and p3,
  or alternatively the Triangle t
  Signature: p.in_circle(p1,p2,p3) or p.in_circle(t)
  Returns +1 if p lies inside, -1 if p lies outside, and 0 if p lies
  on the circle. The Points p1, p2, and p3 must be in
  counterclockwise order, or the sign of the result will be reversed.`

is_in_rectangle(...)
  `True if this Point p is in box with bottom-left and upper-right
  Points p1 and p2.
  Signature: p.is_in_rectange(p1,p2)`

is_inside(...)
  `True if this Point p is inside or outside Surface s.
  False otherwise.
  Signature: p.in_inside(s)`

orientation_3d(...)
  `Determines if this Point p is above, below or on plane of 3 Points
  p1, p2 and p3.
  Signature: p.orientation_3d(p1,p2,p3)
  Below is defined so that p1, p2 and p3 appear in counterclockwise
  order when viewed from above the plane.
  The return value is positive if p4 lies below the plane, negative
  if p4 lies above the plane, and zero if the four points are
  coplanar. The value is an approximation of six times the signed
  volume of the tetrahedron defined by the four points.`

orientation_3d_sos(...)
  `Determines if this Point p is above, below or on plane of 3 Points
  p1, p2 and p3.
  Signature: p.orientation_3d_sos(p1,p2,p3)
  Below is defined so that p1, p2 and p3 appear in counterclockwise
  order when viewed from above the plane.
  The return value is +1 if p4 lies below the plane, and -1 if p4
  lies above the plane. Simulation of Simplicity (SoS) is used to
  break ties when the orientation is degenerate (i.e. the point lies
  on the plane definedby p1, p2 and p3).`

rotate(...)
  `Rotates Point p around vector dx,dy,dz by angle a.
  The sense of the rotation is given by the right-hand-rule.
  Signature: p.rotate(dx=0,dy=0,dz=0,a=0)`

scale(...)
  `Scales Point p by vector dx,dy,dz.
  Signature: p.scale(dx=1,dy=1,dz=1)`

set(...)
  `Sets x, y, and z coordinates of this Point p.
  Signature: p.set(x,y,z)`

translate(...)
  `Translates Point p by vector dx,dy,dz.
  Signature: p.translate(dx=0,dy=0,dz=0)`

Data descriptors inherited from Point:

x
  `x value`

y
  `y value`

z
  `z value`

Data descriptors inherited from Object:

id
  `GTS object id`

Functions

``

isosurface(...)
  `Adds to surface new faces defining the isosurface data[x,y,z] = c
  Signature: isosurface(data, c, ...)
  data is a 3D numpy array.
  c is the isovalue defining the surface
  Keyword arguments:
  extents= [xmin, xmax, ymin, ymax, zmin, zmax]
  A numpy array defining the extent of the data cube.
  Default is the cube with corners at (-1,-1,-1) and (1,1,1)
  Data is assumed to be regularly sampled in the cube.
  method= ['cube'|'tetra'|'dual'|'bounded']
  String (only the first character counts) specifying the
  method.
  cube -- marching cubes (default)
  tetra -- marching tetrahedra
  dual -- maching tetrahedra producing dual 'body-centred'
  faces relative to 'tetra'
  bounded -- marching tetrahedra ensuring the surface is
  bounded by adding a border of large negative
  values around the domain.
  By convention, the normals to the surface are pointing towards
  positive values of data[x,y,z] - c.`

merge(...)
  `Merges list of Vertices that are within a box of side-length
  epsilon of each other.
  Signature: merge(list,epsilon)`

read(...)
  `Returns the data read from File f as a Surface.
  The File data must be in GTS format (e.g., as written using
  Surface.write())
  Signature: read(f)`

segments(...)
  `Returns tuple of Segments from a list or tuple of Vertices.
  Signature: segments(list)`

sphere(...)
  `Returns a unit sphere generated by recursive subdivision.
  First approximation is an isocahedron; each level of refinement
  (geodesation_order) increases the number of triangles by a factor
  of 4.
  Signature: sphere(geodesation_order)`

triangle_enclosing(...)
  `Returns a Triangle that encloses the plane projection of a list
  or tuple of Points. The Triangle is equilateral and encloses a
  rectangle defined by the maximum and minimum x and y coordinates
  of the points.
  Signature: triangles(list)`

triangles(...)
  `Returns tuple of Triangles from a list or tuple of Edges.
  Signature: triangles(list)`

vertices(...)
  `Returns tuple of Vertices from a list or tuple of Segments.
  Signature: vertices(list)`