31. surface — Operations on triangulated surfaces.

Operations on triangulated surfaces.

A triangulated surface is a surface consisting solely of triangles. Any surface in space, no matter how complex, can be approximated with a triangulated surface.

class surface.TriSurface(*args, **kargs)

A class representing a triangulated 3D surface.

The surface contains ntri triangles, each having 3 vertices with 3 coordinates. The surface can be initialized from one of the following:

  • a (ntri,3,3) shaped array of floats
  • a Formex with plexitude 3
  • a Mesh with plexitude 3
  • an (ncoords,3) float array of vertex coordinates and an (ntri,3) integer array of vertex numbers
  • an (ncoords,3) float array of vertex coordinates, an (nedges,2) integer array of vertex numbers, an (ntri,3) integer array of edges numbers.

Additionally, a keyword argument prop= may be specified to set property values.

Methods

Create a new surface.

Methods

TriSurface objects have the following methods:

nedges()
nfaces()
vertices()
shape()
Return the number of points, edges, faces of the TriSurface.
getEdges()
Get the edges data.
getFaces()
Get the faces data.
setCoords(coords)
Change the coords.
setElems(elems)
Change the elems.
setEdgesAndFaces(edges, faces)
Change the edges and faces.
refresh()
append(S)

Merge another surface with self.

This just merges the data sets, and does not check whether the surfaces intersect or are connected! This is intended mostly for use inside higher level functions.

copy()
Return a (deep) copy of the surface.
select(idx, compact=True)

Return a TriSurface which holds only elements with numbers in ids.

idx can be a single element number or a list of numbers or any other index mechanism accepted by numpy’s ndarray By default, the vertex list will be compressed to hold only those used in the selected elements. Setting compress==False will keep all original nodes in the surface.

pointNormals()

Compute the normal vectors at the points.

The normal vector in a point is the average of the normal vectors of all the neighbouring triangles. The normal vectors are normalized before they are returned.

offset(distance=1.)

Offset a surface with a certain distance.

All the nodes of the surface are translated over a specified distance along their normal vector.

classmethod read(clas, fn, ftype=None)

Read a surface from file.

If no file type is specified, it is derived from the filename extension. Currently supported file types:

  • .stl (ASCII or BINARY)
  • .gts
  • .off
  • .neu (Gambit Neutral)
  • .smesh (Tetgen)
write(fname, ftype=None)

Write the surface to file.

If no filetype is given, it is deduced from the filename extension. If the filename has no extension, the ‘gts’ file type is used.

reflect(None)

Reflect the coordinates in direction dir against plane at pos.

Default position of the plane is through the origin. Default mirror direction is the z-direction.

avgVertexNormals()
Compute the average normals at the vertices.
areaNormals()

Compute the area and normal vectors of the surface triangles.

The normal vectors are normalized. The area is always positive.

The values are returned and saved in the object.

facetArea()
area()
Return the area of the surface
volume()

Return the enclosed volume of the surface.

This will only be correct if the surface is a closed manifold.

curvature(neighbours=1)

Return the curvature parameters at the nodes.

This uses the nodes that are connected to the node via a shortest path of ‘neighbours’ edges. Eight values are returned: the Gaussian and mean curvature, the shape index, the curvedness, the principal curvatures and the principal directions.

inertia()

Return inertia related quantities of the surface.

This returns the center of gravity, the principal axes of inertia, the principal moments of inertia and the inertia tensor.

edgeConnections()
Find the elems connected to edges.
nodeConnections()
Find the elems connected to nodes.
nEdgeConnected()
Find the number of elems connected to edges.
nNodeConnected()
Find the number of elems connected to nodes.
edgeAdjacency()
Find the elems adjacent to elems via an edge.
nEdgeAdjacent()
Find the number of adjacent elems.
nodeAdjacency()
Find the elems adjacent to elems via one or two nodes.
nNodeAdjacent()
Find the number of adjacent elems.
surfaceType()
borderEdges()

Detect the border elements of TriSurface.

The border elements are the edges having less than 2 connected elements. Returns True where edge is on the border.

borderEdgeNrs()
Returns the numbers of the border edges.
borderNodeNrs()

Detect the border nodes of TriSurface.

The border nodes are the vertices belonging to the border edges. Returns a list of vertex numbers.

isManifold()
isClosedManifold()
checkBorder()
Return the border of TriSurface as a set of segments.
fillBorder(method=0)

If the surface has a single closed border, fill it.

Filling the border is done by adding a single point inside the border and connectin it with all border segments. This works well if the border is smooth and nearly planar.

border()
Return the border of TriSurface as a Plex-2 Formex.
edgeCosAngles()

Return the cos of the angles over all edges.

The surface should be a manifold (max. 2 elements per edge). Edges with only one element get angles = 1.0.

edgeAngles()
Return the angles over all edges (in degrees).
aspectRatio()
smallestAltitude()
longestEdge()
shortestEdge()
stats()
Return a text with full statistics.
distanceOfPoints(X, return_points=False)

Find the distances of points X to the TriSurface.

The distance of a point is either: - the closest perpendicular distance to the facets; - the closest perpendicular distance to the edges; - the closest distance to the vertices.

X is a (nX,3) shaped array of points. If return_points = True, a second value is returned: an array with the closest (foot)points matching X.

edgeFront(startat=0, okedges=None, front_increment=1)

Generator function returning the frontal elements.

startat is an element number or list of numbers of the starting front. On first call, this function returns the starting front. Each next() call returns the next front. front_increment determines how the property increases at each frontal step. There is an extra increment +1 at each start of a new part. Thus, the start of a new part can always be detected by a front not having the property of the previous plus front_increment.

nodeFront(startat=0, front_increment=1)

Generator function returning the frontal elements.

startat is an element number or list of numbers of the starting front. On first call, this function returns the starting front. Each next() call returns the next front.

walkEdgeFront(startat=0, nsteps=1, okedges=None, front_increment=1)
walkNodeFront(startat=0, nsteps=1, front_increment=1)
growSelection(sel, mode='node', nsteps=1)

Grows a selection of a surface.

p is a single element number or a list of numbers. The return value is a list of element numbers obtained by growing the front nsteps times. The mode argument specifies how a single frontal step is done:

  • ‘node’ : include all elements that have a node in common,
  • ‘edge’ : include all elements that have an edge in common.
partitionByEdgeFront(okedges, firstprop=0, startat=0)

Detects different parts of the surface using a frontal method.

okedges flags the edges where the two adjacent triangles are to be in the same part of the surface. startat is a list of elements that are in the first part. The partitioning is returned as a property type array having a value corresponding to the part number. The lowest property number will be firstprop

partitionByNodeFront(firstprop=0, startat=0)

Detects different parts of the surface using a frontal method.

okedges flags the edges where the two adjacent triangles are to be in the same part of the surface. startat is a list of elements that are in the first part. The partitioning is returned as a property type array having a value corresponding to the part number. The lowest property number will be firstprop

partitionByConnection()
partitionByAngle(angle=180., firstprop=0, startat=0)
cutWithPlane(None)
Cut a surface with a plane.
connectedElements(target, elemlist=None)
Return the elements from list connected with target
intersectionWithPlane(p, n, atol=0., ignoreErrors=False)

Return the intersection lines with plane (p,n).

Returns a plex-2 mesh with the line segments obtained by cutting all triangles of the surface with the plane (p,n) p is a point specified by 3 coordinates. n is the normal vector to a plane, specified by 3 components. atol is a tolerance factor defining whether an edge is intersected by the plane.

The return value is a plex-2 Mesh where the line segments defining the intersection are sorted to form continuous lines. The Mesh has property numbers such that all segments forming a single continuous part have the same property value. The splitProp() method can be used to get a list of Meshes.

slice(dir=0, nplanes=20, ignoreErrors=False)

Intersect a surface with a sequence of planes.

A sequence of nplanes planes with normal dir is constructed at equal distances spread over the bbox of the surface.

The return value is a list of intersectionWithPlanes() return values, i.e. a list of list of meshes.

smoothLowPass(n_iterations=2, lambda_value=0.5, neighbours=1)

Smooth the surface using a low-pass filter.

This uses the nodes that are connected to the node via a shortest path of minimum 1 and maximum ‘neighbours’ edges.

smoothLaplaceHC(n_iterations=2, lambda_value=0.5, alpha=0., beta=0.2, neighbours=1)

Smooth the surface using a Laplace filter and HC algorithm.

This uses the nodes that are connected to the node via a shortest path of minimum 1 and maximum ‘neighbours’ edges.

check(verbose=False)
Check the surface using gtscheck.
split(base, verbose=False)
Check the surface using gtscheck.
coarsen(min_edges=None, max_cost=None, mid_vertex=False, length_cost=False, max_fold=1.0, volume_weight=0.5, boundary_weight=0.5, shape_weight=0.0, progressive=False, log=False, verbose=False)
Coarsen the surface using gtscoarsen.
refine(max_edges=None, min_cost=None, log=False, verbose=False)
Refine the surface using gtsrefine.
smooth(lambda_value=0.5, n_iterations=2, fold_smoothing=None, verbose=False)
Smooth the surface using gtssmooth.
boolean(surf, op, inter=False, check=False, verbose=False)
Perform a boolean operation with surface surf.

Functions defined in the module surface

surface.areaNormals(x)

Compute the area and normal vectors of a collection of triangles.

x is an (ntri,3,3) array of coordinates.

Returns a tuple of areas,normals. The normal vectors are normalized. The area is always positive.

surface.stlConvert(stlname, outname=None, options='-d')

Transform an .stl file to .off or .gts format.

If outname is given, it is either ‘.off’ or ‘.gts’ or a filename ending on one of these extensions. If it is only an extension, the stlname will be used with extension changed.

If the outname file exists and its mtime is more recent than the stlname, the outname file is considered uptodate and the conversion programwill not be run.

The conversion program will be choosen depending on the extension. This uses the external commands ‘admesh’ or ‘stl2gts’.

The return value is a tuple of the output file name, the conversion program exit code (0 if succesful) and the stdout of the conversion program (or a ‘file is already uptodate’ message).

surface.read_gts(fn)

Read a GTS surface mesh.

Return a coords,edges,faces tuple.

surface.read_off(fn)

Read an OFF surface mesh.

The mesh should consist of only triangles! Returns a nodes,elems tuple.

surface.read_stl(fn, intermediate=None)

Read a surface from .stl file.

This is done by first coverting the .stl to .gts or .off format. The name of the intermediate file may be specified. If not, it will be generated by changing the extension of fn to ‘.gts’ or ‘.off’ depending on the setting of the ‘surface/stlread’ config setting.

Return a coords,edges,faces or a coords,elems tuple, depending on the intermediate format.

surface.read_gambit_neutral(fn)

Read a triangular surface mesh in Gambit neutral format.

The .neu file nodes are numbered from 1! Returns a nodes,elems tuple.

surface.write_gts(fn, nodes, edges, faces)
surface.write_stla(f, x)
Export an x[n,3,3] float array as an ascii .stl file.
surface.write_stlb(f, x)
Export an x[n,3,3] float array as an binary .stl file.
surface.write_gambit_neutral(fn, nodes, elems)
surface.write_off(fn, nodes, elems)
surface.write_smesh(fn, nodes, elems)
surface.surface_volume(x, pt=None)

Return the volume inside a 3-plex Formex.

  • x: an (ntri,3,3) shaped float array, representing ntri triangles.
  • pt: a point in space. If unspecified, it is taken equal to the center() of the coordinates x.

Returns an (ntri) shaped array with the volume of the tetraeders formed by the triangles and the point pt. If x represents a closed surface, the sum of this array will represent the volume inside the surface.

surface.curvature(coords, elems, edges, neighbours=1)

Calculate curvature parameters at the nodes

(according to Dong and Wang 2005; Koenderink and Van Doorn 1992). This uses the nodes that are connected to the node via a shortest path of ‘neighbours’ edges. Eight values are returned: the Gaussian and mean curvature, the shape index, the curvedness, the principal curvatures and the principal directions.

surface.surfaceInsideLoop(coords, elems)

Create a surface inside a closed curve defined by coords and elems.

coords is a set of coordinates. elems is an (nsegments,2) shaped connectivity array defining a set of line segments forming a closed loop.

The return value is coords,elems tuple where coords has one more point: the center of th original coords elems is (nsegment,3) and defines triangles describing a surface inside the original curve.

surface.fillHole(coords, elems)

Fill a hole surrounded by the border defined by coords and elems.

Coords is a (npoints,3) shaped array of floats. Elems is a (nelems,2) shaped array of integers representing the border element numbers and must be ordered.

surface.create_border_triangle(coords, elems)

Create a triangle within a border.

The triangle is created from the two border elements with the sharpest angle. Coords is a (npoints,3) shaped array of floats. Elems is a (nelems,2) shaped array of integers representing the border element numbers and must be ordered. A list of two objects is returned: the new border elements and the triangle.

surface.read_error(cnt, line)
Raise an error on reading the stl file.
surface.degenerate(area, norm)

Return a list of the degenerate faces according to area and normals.

A face is degenerate if its surface is less or equal to zero or the normal has a nan.

surface.read_stla(fn, dtype=Float, large=False, guess=True)

Read an ascii .stl file into an [n,3,3] float array.

If the .stl is large, read_ascii_large() is recommended, as it is a lot faster.

surface.read_ascii_large(fn, dtype=Float)

Read an ascii .stl file into an [n,3,3] float array.

This is an alternative for read_ascii, which is a lot faster on large STL models. It requires the ‘awk’ command though, so is probably only useful on Linux/UNIX. It works by first transforming the input file to a .nodes file and then reading it through numpy’s fromfile() function.

surface.off_to_tet(fn)
Transform an .off model to tetgen (.node/.smesh) format.
surface.find_row(mat, row, nmatch=None)
Find all rows in matrix matching given row.
surface.find_nodes(nodes, coords)

Find nodes with given coordinates in a node set.

nodes is a (nnodes,3) float array of coordinates. coords is a (npts,3) float array of coordinates.

Returns a (n,) integer array with ALL the node numbers matching EXACTLY ALL the coordinates of ANY of the given points.

surface.find_first_nodes(nodes, coords)

Find nodes with given coordinates in a node set.

nodes is a (nnodes,3) float array of coordinates. coords is a (npts,3) float array of coordinates.

Returns a (n,) integer array with THE FIRST node number matching EXACTLY ALL the coordinates of EACH of the given points.

surface.find_triangles(elems, triangles)

Find triangles with given node numbers in a surface mesh.

elems is a (nelems,3) integer array of triangles. triangles is a (ntri,3) integer array of triangles to find.

Returns a (ntri,) integer array with the triangles numbers.

surface.remove_triangles(elems, remove)

Remove triangles from a surface mesh.

elems is a (nelems,3) integer array of triangles. remove is a (nremove,3) integer array of triangles to remove.

Returns a (nelems-nremove,3) integer array with the triangles of nelems where the triangles of remove have been removed.

surface.Rectangle(nx, ny)
Create a plane rectangular surface consisting of a nx,ny grid.
surface.Cube()
Create a surface in the form of a cube
surface.Sphere(level=4, verbose=False, filename=None)

Create a spherical surface by caling the gtssphere command.

If a filename is given, it is stored under that name, else a temporary file is created. Beware: this may take a lot of time if level is 8 or higher.

surface.checkDistanceLinesPointsTreshold(p, q, m, dtresh)
p are np points, q m are nl lines, dtresh are np distances. It returns the indices of lines, points which are in a distance < dtresh. The distance point-line is calculated using Pitagora as it seems the fastest way.
surface.intersectLineWithPlaneOne2One(q, m, p, n)
it returns for each pair of line(q,m) and plane (p,n) the point of intersection. plane: (x-p)n=0, line: x=q+t m. It find the scalar t and returns the point.
surface.checkPointInsideTriangleOne2One(tpi, pi, atol=1.e-5)
return a 1D boolean with the same dimension of tpi and pi. The value [i] is True if the point pi[i] is inside the triangle tpi[i]. It uses areas to check it.
surface.intersectSurfaceWithLines(ts, qli, mli)
it takes a TriSurface ts and a set of lines ql,ml and intersect the lines with the TriSurface. It returns the points of intersection and the indices of the intersected line and triangle. TODO: the slowest part is computing the distances of lines from triangles, can it be faster?
surface.intersectSurfaceWithSegments(s1, segm, atol=1.e-5)
it takes a TriSurface ts and a set of segments (-1,2,3) and intersect the segments with the TriSurface. It returns the points of intersections and, for each point, the indices of the intersected segment and triangle

Documentation

Previous topic

30. mesh — mesh.py

Next topic

32. geomtools — Basic geometrical operations.

This Page