32. trisurface — 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.

Classes defined in module trisurface

class trisurface.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.

areas()

area of elements

For surface element the faces’ area is returned. For volume elements the sum of the faces’areas is returned.

nedges()

Return the number of edges of the TriSurface.

nfaces()

Return the number of faces of the TriSurface.

vertices()

Return the coordinates of the nodes of the TriSurface.

shape()

Return the number of points, edges, faces of the TriSurface.

getElemEdges()

Get the faces’ edge numbers.

setCoords(coords)

Change the coords.

setElems(elems)

Change the elems.

setEdgesAndFaces(edges, faces)

Change the edges and faces.

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.

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.

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()

Return the area of the surface triangles.

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.

surfaceType()

Check whether the TriSurface is a manifold and if it’s closed.

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()

Check whether the TriSurface is a manifold.

A surface is a manifold if a small sphere exists that cuts the surface to a surface that can continously be deformed to an open disk.

nonManifoldEdges()

Finds edges and faces that are not Manifold.

It returns the edges that connect 3 or more faces and the faces.

isClosedManifold()

Check whether the TriSurface is a closed manifold.

checkBorder()

Return the border of TriSurface as a set of segments.

border()

Return the border(s) of TriSurface.

The complete border of the surface is returned as a list of plex-2 Meshes. Each Mesh constitutes a continuous part of the border.

fillBorder(method='radial', merge=False)

Fill the border areas of a surface to make it closed.

Returns a list of surfaces, each of which fills a singly connected part of the border of the input surface. Adding these surfaces to the original will create a closed surface. If the surface is already closed, an empty list is returned.

There are two methods, corresponding with the methods of the surfaceInsideBorder.

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). It is the angle (0 to 180) between 2 face normals.

aspectRatio()

Return the apect ratio of the triangles of the surface.

The aspect ratio of a triangle is the ratio of the longest edge over the smallest altitude of the triangle.

Equilateral triangles have the smallest edge ratio (2 over square root 3).

smallestAltitude()

Return the smallest altitude of the triangles of the surface.

longestEdge()

Return the longest edge of the triangles of the surface.

shortestEdge()

Return the shortest edge of the triangles of the surface.

stats()

Return a text with full statistics.

distanceOfPoints(X, return_points=False, method='bary')

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.

offset(distance=1.0)

Offset a surface with a certain distance.

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

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.

walkEdgeFront(startat=0, nsteps=-1, okedges=None, front_increment=1)

Grow a selection using a frontal method.

Starting from element startat, grow a selection nsteps times following the common edges of the triangles.

The property of each new front is augmented by front_increment.

growSelection(sel, mode='node', nsteps=1)

Grow 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)

Detect 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

partitionByAngle(angle=60.0, firstprop=0, sortedbyarea=None)

Partition the surface by splitting it at sharp edges.

The surface is partitioned in parts in which all elements can be reach without ever crossing a sharp edge angle. More precisely, any two elements that can be connected by a line not crossing an edge between two elements having their normals differ more than angle (in degrees), will belong to the same 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.

If sortedbyarea is ‘up’ or ‘down’ the parts will be ordered by increasing or decreasign area.

cutWithPlane(*args, **kargs)

Cut a surface with a plane or a set of planes.

Cuts the surface with one or more plane and returns either one side or both.

Parameters:

  • p,`n`: a point and normal vector defining the cutting plane. p and n can be sequences of points and vector, allowing to cut with multiple planes. Both p and n have shape (3) or (npoints,3).

The parameters are the same as in Formex.CutWithPlane(). The returned surface will have its normals fixed wherever possible.

connectedElements(target, elemlist=None)

Return the elements from list connected with target

intersectionWithPlane(p, n)

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.

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)

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 intersectionWithPlane() return values, i.e. a list of Meshes, one for every cutting plane. In each Mesh the simply connected parts are identified by property number.

smooth(method='lowpass', iterations=1, lambda_value=0.5, neighbourhood=1, alpha=0.0, beta=0.20000000000000001, verbose=False)

Smooth the surface.

Returns a TriSurface which is a smoothed version of the original. Three smoothing methods are available: ‘lowpass’, ‘laplace’, and ‘gts’. The first two are built-in, the latter uses the external command gtssmooth.

Parameters:

  • method: ‘lowpass’, ‘laplace’, or ‘gts’
  • iterations: int: number of iterations
  • lambda_value: float: lambda value used in the filters

Extra parameters for ‘lowpass’ and ‘laplace’:

  • neighbourhood: int: maximum number of edges to follow to define node neighbourhood

Extra parameters for ‘laplace’:

  • alpha, beta: float: parameters for the laplace method.

Extra parameters for ‘gts’:

  • verbose: boolean: requests more verbose output of the gtssmooth command

Returns: the smoothed TriSurface

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

Apply a low pass smoothing to the surface.

smoothLaplaceHC(iterations=2, lambda_value=0.5, alpha=0.0, beta=0.20000000000000001, neighbours=1)

Apply Laplace smoothing with shrinkage compensation to the surface.

fixNormals()

Fix the orientation of the normals.

Some surface operations may result in improperly oriented normals. This tries to reverse improperly oriented normals so that a single oriented surface is achieved. It only works on a closed surface.

In the current version, this uses the external program admesh, so this should be installed on the machine.

If the surface was a (possibly non-orientable) manifold, the result will be an orientable manifold. This is a necessary condition for the gts methods to be applicable.

check(verbose=False, matched=True)

Check the surface using gtscheck.

Checks whether the surface is an orientable, non self-intersecting manifold.

For the use of the gts methods (split, coarsen, refine, boolean), this is a necessary condition; additionally, the surface has to be closed (can be checked with isClosedManifold()).

Returns 0 if the surface passes the test, nonzero if not. A full report is printed out.

If surface is not an orientable manifold returns 512. The fixNormals() and reverse() methods may be used to fix the normals of an otherwise correct closed manifold.

If surface is an orientable manifold but is self-intersecting, returns 768 and the self intersecting triangles. If matched is True, the intersecting triangles are returned as element indices of self.

checkSelfIntersectionsWithTetgen(verbose=False)

check self intersections using tetgen

Returns couples of intersecting triangles

split(base, verbose=False)

Split the surface using gtssplit.

Splits the surface into connected and manifold components. This uses the external program gtssplit. The surface should be a closed orientable non-intersecting manifold. Use the check() method to find out.

This method creates a series of files with given base name, each file contains a single connected manifold.

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.

Construct a coarsened version of the surface. This uses the external program gtscoarsen. The surface should be a closed orientable non-intersecting manifold. Use the check() method to find out.

Parameters:

  • min_edges: int: stops the coarsening process if the number of edges was to fall below it
  • max_cost: float: stops the coarsening process if the cost of collapsing an edge is larger
  • mid_vertex: boolean: use midvertex as replacement vertex instead of the default, which is a volume optimized point
  • length_cost: boolean: use length^2 as cost function instead of the default optimized point cost
  • max_fold: float: maximum fold angle in degrees
  • volume_weight: float: weight used for volume optimization
  • boundary_weight: float: weight used for boundary optimization
  • shape_weight: float: weight used for shape optimization
  • progressive: boolean: write progressive surface file
  • log: boolean: log the evolution of the cost
  • verbose: boolean: print statistics about the surface
refine(max_edges=None, min_cost=None, log=False, verbose=False)

Refine the surface using gtsrefine.

Construct a refined version of the surface. This uses the external program gtsrefine. The surface should be a closed orientable non-intersecting manifold. Use the check() method to find out.

Parameters:

  • max_edges: int: stop the refining process if the number of edges exceeds this value
  • min_cost: float: stop the refining process if the cost of refining an edge is smaller
  • log: boolean: log the evolution of the cost
  • verbose: boolean: print statistics about the surface
boolean(surf, op, intersection_curve=False, check=False, verbose=False)

Perform a boolean operation with another surface.

Boolean operations between surfaces are a basic operation in free surface modeling. Both surfaces should be closed orientable non-intersecting manifolds. Use the check() method to find out.

The boolean operations are set operations on the enclosed volumes: union(‘+’), difference(‘-‘) or intersection(‘*’).

Parameters:

  • intersection_curve: boolean: output an OOGL (Geomview) representation of the curve intersection of the surfaces
  • check: boolean: check that the surfaces are not self-intersecting; if one of them is, the set of self-intersecting faces is written (as a GtsSurface) on standard output
  • verbose: boolean: print statistics about the surface
report()

Create a report on the Mesh shape and size.

The report contains the number of nodes, number of elements, plexitude, element type, bbox and size.

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.

partitionByNodeFront(firstprop=0, startat=0)

Detects different parts of the Mesh using a frontal method.

okedges flags the edges where the two adjacent elems are to be in the same part of the Mesh. 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()

Detect the connected parts of a Mesh.

The Mesh is partitioned in parts in which all elements are connected. Two elements are connected if it is possible to draw a continuous (poly)line from a point in one element to a point in the other element without leaving the Mesh. The partitioning is returned as a property type array having a value corresponding to the part number. The lowest property number will be firstprop.

splitByConnection()

Split the Mesh into connected parts.

Returns a list of Meshes that each form a connected part.

affine(*args, **kargs)

Apply ‘affine’ transformation to the Geometry object.

See coords.Coords.affine() for details.

align(*args, **kargs)

Apply ‘align’ transformation to the Geometry object.

See coords.Coords.align() for details.

bump(*args, **kargs)

Apply ‘bump’ transformation to the Geometry object.

See coords.Coords.bump() for details.

bump1(*args, **kargs)

Apply ‘bump1’ transformation to the Geometry object.

See coords.Coords.bump1() for details.

bump2(*args, **kargs)

Apply ‘bump2’ transformation to the Geometry object.

See coords.Coords.bump2() for details.

cylindrical(*args, **kargs)

Apply ‘cylindrical’ transformation to the Geometry object.

See coords.Coords.cylindrical() for details.

egg(*args, **kargs)

Apply ‘egg’ transformation to the Geometry object.

See coords.Coords.egg() for details.

flare(*args, **kargs)

Apply ‘flare’ transformation to the Geometry object.

See coords.Coords.flare() for details.

hyperCylindrical(*args, **kargs)

Apply ‘hyperCylindrical’ transformation to the Geometry object.

See coords.Coords.hyperCylindrical() for details.

isopar(*args, **kargs)

Apply ‘isopar’ transformation to the Geometry object.

See coords.Coords.isopar() for details.

map(*args, **kargs)

Apply ‘map’ transformation to the Geometry object.

See coords.Coords.map() for details.

map1(*args, **kargs)

Apply ‘map1’ transformation to the Geometry object.

See coords.Coords.map1() for details.

mapd(*args, **kargs)

Apply ‘mapd’ transformation to the Geometry object.

See coords.Coords.mapd() for details.

projectOnCylinder(*args, **kargs)

Apply ‘projectOnCylinder’ transformation to the Geometry object.

See coords.Coords.projectOnCylinder() for details.

projectOnPlane(*args, **kargs)

Apply ‘projectOnPlane’ transformation to the Geometry object.

See coords.Coords.projectOnPlane() for details.

projectOnSphere(*args, **kargs)

Apply ‘projectOnSphere’ transformation to the Geometry object.

See coords.Coords.projectOnSphere() for details.

replace(*args, **kargs)

Apply ‘replace’ transformation to the Geometry object.

See coords.Coords.replace() for details.

rollAxes(*args, **kargs)

Apply ‘rollAxes’ transformation to the Geometry object.

See coords.Coords.rollAxes() for details.

rot(*args, **kargs)

Apply ‘rotate’ transformation to the Geometry object.

See coords.Coords.rotate() for details.

rotate(*args, **kargs)

Apply ‘rotate’ transformation to the Geometry object.

See coords.Coords.rotate() for details.

scale(*args, **kargs)

Apply ‘scale’ transformation to the Geometry object.

See coords.Coords.scale() for details.

shear(*args, **kargs)

Apply ‘shear’ transformation to the Geometry object.

See coords.Coords.shear() for details.

spherical(*args, **kargs)

Apply ‘spherical’ transformation to the Geometry object.

See coords.Coords.spherical() for details.

superSpherical(*args, **kargs)

Apply ‘superSpherical’ transformation to the Geometry object.

See coords.Coords.superSpherical() for details.

swapAxes(*args, **kargs)

Apply ‘swapAxes’ transformation to the Geometry object.

See coords.Coords.swapAxes() for details.

toCylindrical(*args, **kargs)

Apply ‘toCylindrical’ transformation to the Geometry object.

See coords.Coords.toCylindrical() for details.

toSpherical(*args, **kargs)

Apply ‘toSpherical’ transformation to the Geometry object.

See coords.Coords.toSpherical() for details.

transformCS(*args, **kargs)

Apply ‘transformCS’ transformation to the Geometry object.

See coords.Coords.transformCS() for details.

translate(*args, **kargs)

Apply ‘translate’ transformation to the Geometry object.

See coords.Coords.translate() for details.

trl(*args, **kargs)

Apply ‘translate’ transformation to the Geometry object.

See coords.Coords.translate() for details.

largestByConnection()

Return the largest connected part of the Mesh.

rings(sources, nrings)

It finds the rings of elems connected to sources by node.

Sources is a list of elem indices. A list of rings is returned, from zero (equal to sources) to step. If step is -1, all rings are returned.

setType(eltype=None)

Set the eltype from a character string.

This function allows the user to change the element type of the Mesh. The input is a character string with the name of one of the element defined in elements.py. The function will only allow to set a type matching the plexitude of the Mesh.

This method is seldom needed, because the applications should normally set the element type at creation time.

correctNegativeVolumes()

Modify the connectivity of negative-volume elements to make positive-volume elements.

Negative-volume elements (hex or tet with inconsistent face orientation) may appear by error during geometrical trnasformations (e.g. reflect, sweep, extrude, revolve). This function fixes those elements. Currently it only works with linear tet and hex.

setProp(prop=None)

Create or destroy the property array for the Mesh.

A property array is a rank-1 integer array with dimension equal to the number of elements in the Mesh. You can specify a single value or a list/array of integer values. If the number of passed values is less than the number of elements, they wil be repeated. If you give more, they will be ignored.

If a value None is given, the properties are removed from the Mesh.

scaledJacobian(scaled=True)

Returns a quality measure for volume meshes.

If scaled if False, it returns the Jacobian at the corners of each element. If scaled is True, it returns a quality metrics, being the minumum value of the scaled Jacobian in each element (at one corner, the Jacobian divided by the volume of a perfect brick). Each tet or hex element gives a value between -1 and 1. Acceptable elements have a positive scaled Jacobian. However, good quality requires a minimum of 0.2. Quadratic meshes are first converted to linear. If the mesh contain mainly negative Jacobians, it probably has negative volumes and can be fixed with the correctNegativeVolumes.

getProp()

Return the properties as a numpy array (ndarray)

maxProp()

Return the highest property value used, or None

propSet()

Return a list with unique property values.

copy()

Return a copy using the same data arrays

toFormex()

Convert a Mesh to a Formex.

The Formex inherits the element property numbers and eltype from the Mesh. Node property numbers however can not be translated to the Formex data model.

centroids()

Return the centroids of all elements of the Mesh.

The centroid of an element is the point whose coordinates are the mean values of all points of the element. The return value is a Coords object with nelems points.

getCoords()

Get the coords data.

Returns the full array of coordinates stored in the Mesh object. Note that this may contain points that are not used in the mesh. compact() will remove the unused points.

getElems()

Get the elems data.

Returns the element connectivity data as stored in the object.

getLowerEntities(level=-1, unique=False)

Get the entities of a lower dimensionality.

If the element type is defined in the elements module, this returns a Connectivity table with the entities of a lower dimensionality. The full list of entities with increasing dimensionality 0,1,2,3 is:

['points', 'edges', 'faces', 'cells' ]

If level is negative, the dimensionality returned is relative to that of the caller. If it is positive, it is taken absolute. Thus, for a Mesh with a 3D element type, getLowerEntities(-1) returns the faces, while for a 2D element type, it returns the edges. For both meshes however, getLowerEntities(+1) returns the edges.

By default, all entities for all elements are returned and common entities will appear multiple times. Specifying unique=True will return only the unique ones.

The return value may be an empty table, if the element type does not have the requested entities (e.g. the ‘point’ type). If the eltype is not defined, or the requested entity level is outside the range 0..3, the return value is None.

getNodes()

Return the set of unique node numbers in the Mesh.

This returns only the node numbers that are effectively used in the connectivity table. For a compacted Mesh, it is equal to `arange(self.nelems)`. This function also stores the result internally so that future requests can return it without the need for computing it again.

getPoints()

Return the nodal coordinates of the Mesh.

This returns only those points that are effectively used in the connectivity table. For a compacted Mesh, it is equal to the coords attribute.

getEdges()

Return the unique edges of all the elements in the Mesh.

This is a convenient function to create a table with the element edges. It is equivalent to `self.getLowerEntities(1,unique=True)`, but this also stores the result internally so that future requests can return it without the need for computing it again.

getFaces()

Return the unique faces of all the elements in the Mesh.

This is a convenient function to create a table with the element faces. It is equivalent to `self.getLowerEntities(2,unique=True)`, but this also stores the result internally so that future requests can return it without the need for computing it again.

getCells()

Return the cells of the elements.

This is a convenient function to create a table with the element cells. It is equivalent to `self.getLowerEntities(3,unique=True)`, but this also stores the result internally so that future requests can return it without the need for computing it again.

getFreeEntities(return_indices=False, level=-1)

Return the border of the Mesh.

This returns a Connectivity table with the border of the Mesh. The border entities are of a lower hierarchical level than the mesh itself. These entities become part of the border if they are connected to only one element.

If return_indices==True, it returns also an (nborder,2) index for inverse lookup of the higher entity (column 0) and its local border part number (column 1).

The returned Connectivity can be used together with the Mesh.coords to construct a Mesh of the border geometry. See also getBorderMesh().

getFreeEntitiesMesh(compact=True, level=-1)

Return a Mesh with the border elements.

Returns a Mesh representing the border of the Mesh. The returned Mesh is of the next lower hierarchical level. If the Mesh has property numbers, the border elements inherit the property of the element to which they belong.

By default, the resulting Mesh is compacted. Compaction can be switched off by setting compact=False.

reverse()

Return a Mesh where all elements have been reversed.

Reversing an element has the following meaning:

  • for 1D elements: reverse the traversal direction,
  • for 2D elements: reverse the direction of the positive normal,
  • for 3D elements: reverse inside and outside directions of the element’s border surface

The reflect() method by default calls this method to undo the element reversal caused by the reflection operation.

reflect(dir=0, pos=0.0, reverse=True, **kargs)

Reflect the coordinates in one of the coordinate directions.

Parameters:

  • dir: int: direction of the reflection (default 0)
  • pos: float: offset of the mirror plane from origin (default 0.0)
  • reverse: boolean: if True, the Mesh.reverse() method is called after the reflection to undo the element reversal caused by the reflection of its coordinates. This will in most cases have the desired effect. If not however, the user can set this to False to skip the element reversal.
nodeConnections()

Find and store the elems connected to nodes.

nNodeConnected()

Find the number of elems connected to nodes.

edgeConnections()

Find and store the elems connected to edges.

nEdgeConnected()

Find the number of elems connected to edges.

nodeAdjacency()

Find the elems adjacent to each elem via one or more nodes.

nNodeAdjacent()

Find the number of elems which are adjacent by node to each elem.

edgeAdjacency()

Find the elems adjacent to elems via an edge.

nEdgeAdjacent()

Find the number of adjacent elems.

fuse(**kargs)

Fuse the nodes of a Meshes.

All nodes that are within the tolerance limits of each other are merged into a single node.

The merging operation can be tuned by specifying extra arguments that will be passed to Coords:fuse().

matchCoords(mesh, **kargs)

Match nodes of Mesh with nodes of self.

This is a convenience function equivalent to:

self.coords.match(mesh.coords,**kargs)

See also Coords.match()

matchCentroids(mesh, **kargs)

Match elems of Mesh with elems of self.

self and Mesh are same eltype meshes and are both without Doubles.

Elems are matched by their centroids.

matchFaces(mesh)

Match faces of mesh with faces of self.

self and Mesh can be same eltype meshes or different eltype but of the same hierarchical type (i.e. hex8-quad4 or tet4 - tri3) and are both without Doubles.

Returns the indices array of the elems of self that matches the faces of mesh

compact()

Remove unconnected nodes and renumber the mesh.

Returns a mesh where all nodes that are not used in any element have been removed, and the nodes are renumbered to a compacter scheme.

select(selected, compact=True)

Return a Mesh only holding the selected elements.

  • selected: an object that can be used as an index in the elems array, e.g. a list of (integer) element numbers, or a boolean array with the same length as the elems array.
  • compact: boolean. If True (default), the returned Mesh will be compacted, i.e. the unused nodes are removed and the nodes are renumbered from zero. If False, returns the node set and numbers unchanged.

Returns a Mesh (or subclass) with only the selected elements.

See cselect for the complementary operation.

cselect(selected, compact=True)

Return a mesh without the selected elements.

  • selected: an object that can be used as an index in the elems array, e.g. a list of (integer) element numbers, or a boolean array with the same length as the elems array.
  • compact: boolean. If True (default), the returned Mesh will be compacted, i.e. the unused nodes are removed and the nodes are renumbered from zero. If False, returns the node set and numbers unchanged.

Returns a Mesh with all but the selected elements.

This is the complimentary operation of select.

meanNodes(nodsel)

Create nodes from the existing nodes of a mesh.

nodsel is a local node selector as in selectNodes() Returns the mean coordinates of the points in the selector as (nelems*nnod,3) array of coordinates, where nnod is the length of the node selector.

addNodes(newcoords, eltype=None)

Add new nodes to elements.

newcoords is an (nelems,nnod,3) or`(nelems*nnod,3)` array of coordinates. Each element gets exactly nnod extra nodes from this array. The result is a Mesh with plexitude self.nplex() + nnod.

addMeanNodes(nodsel, eltype=None)

Add new nodes to elements by averaging existing ones.

nodsel is a local node selector as in selectNodes() Returns a Mesh where the mean coordinates of the points in the selector are added to each element, thus increasing the plexitude by the length of the items in the selector. The new element type should be set to correct value.

selectNodes(nodsel, eltype=None)

Return a mesh with subsets of the original nodes.

nodsel is an object that can be converted to a 1-dim or 2-dim array. Examples are a tuple of local node numbers, or a list of such tuples all having the same length. Each row of nodsel holds a list of local node numbers that should be retained in the new connectivity table.

withProp(val)

Return a Mesh which holds only the elements with property val.

val is either a single integer, or a list/array of integers. The return value is a Mesh holding all the elements that have the property val, resp. one of the values in val. The returned Mesh inherits the matching properties.

If the Mesh has no properties, a copy with all elements is returned.

withoutProp(val)

Return a Mesh without the elements with property val.

This is the complementary method of Mesh.withProp(). val is either a single integer, or a list/array of integers. The return value is a Mesh holding all the elements that do not have the property val, resp. one of the values in val. The returned Mesh inherits the matching properties.

If the Mesh has no properties, a copy with all elements is returned.

splitProp()

Partition a Mesh according to its propery values.

Returns a dict with the property values as keys and the corresponding partitions as values. Each value is a Mesh instance. It the Mesh has no props, an empty dict is returned.

splitRandom(n, compact=True)

Split a mesh in n parts, distributing the elements randomly.

Returns a list of n Mesh objects, constituting together the same Mesh as the original. The elements are randomly distributed over the subMeshes.

By default, the Meshes are compacted. Compaction may be switched off for efficiency reasons.

convert(totype, fuse=False)

Convert a Mesh to another element type.

Converting a Mesh from one element type to another can only be done if both element types are of the same dimensionality. Thus, 3D elements can only be converted to 3D elements.

The conversion is done by splitting the elements in smaller parts and/or by adding new nodes to the elements.

Not all conversions between elements of the same dimensionality are possible. The possible conversion strategies are implemented in a table. New strategies may be added however.

The return value is a Mesh of the requested element type, representing the same geometry (possibly approximatively) as the original mesh.

If the requested conversion is not implemented, an error is raised.

..warning: Conversion strategies that add new nodes may produce
double nodes at the common border of elements. The fuse() method can be used to merge such coincident nodes. Specifying fuse=True will also enforce the fusing. This option become the default in future.
convertRandom(choices)

Convert choosing randomly between choices

reduceDegenerate(eltype=None)

Reduce degenerate elements to lower plexitude elements.

This will try to reduce the degenerate elements of the mesh to elements of a lower plexitude. If a target element type is given, only the matching recuce scheme is tried. Else, all the target element types for which a reduce scheme from the Mesh eltype is available, will be tried.

The result is a list of Meshes of which the last one contains the elements that could not be reduced and may be empty. Property numbers propagate to the children.

splitDegenerate(autofix=True)

Split a Mesh in degenerate and non-degenerate elements.

If autofix is True, the degenerate elements will be tested against known degeneration patterns, and the matching elements will be transformed to non-degenerate elements of a lower plexitude.

The return value is a list of Meshes. The first holds the non-degenerate elements of the original Mesh. The last holds the remaining degenerate elements. The intermediate Meshes, if any, hold elements of a lower plexitude than the original. These may still contain degenerate elements.

removeDegenerate(eltype=None)

Remove the degenerate elements from a Mesh.

Returns a Mesh with all degenerate elements removed.

renumber(order='elems')

Renumber the nodes of a Mesh in the specified order.

order is an index with length equal to the number of nodes. The index specifies the node number that should come at this position. Thus, the order values are the old node numbers on the new node number positions.

order can also be a predefined value that will generate the node index automatically:

  • ‘elems’: the nodes are number in order of their appearance in the Mesh connectivity.
renumberElems(order='nodes')

Renumber the elements of a Mesh.

Parameters:

  • order: either a 1-D integer array with a permutation of arange(self.nelems()), specifying the requested order, or one of the following predefined strings:
    • ‘nodes’: order the elements in increasing node number order.
    • ‘random’: number the elements in a random order.
    • ‘reverse’: number the elements in.
Returns:
A Mesh equivalent with self but with the elements ordered as specified.

See also: Connectivity.reorder()

connect(mesh1, div=1, eltype=None)

Connect a Mesh with another one to form a hypermesh.

Parameters:

  • mesh1: a Mesh with the same element type and shape (number of elements and plexitude) as self. The two Meshes usually also have the same topology. Both Meshes are connected to form a hypermesh. The plexitude of the new Mesh is two times that of the original Mesh.
  • div: Either an integer, or a sequence of numbers (usually between 0.0 and 1.0). This parameter has the same meaning as in Coords.interpolate. If an int is given, div will be set to (div+1) equally spaced values in the range [0.0..1.0].
  • eltype: the element type of the constructed hypermesh. If not given it is set from the element type database. Otherwise, the extrude element type will be created first, and then a conversion to the rewuested element is attempted.
extrude(n, step=1.0, dir=0, eltype=None)

Extrude a Mesh in one of the axes directions.

Returns a new Mesh obtained by extruding the given Mesh over n steps of length step in direction of axis dir.

This is a convenience function equivalent to:

self.connect(self.translate(dir,n*step),n,eltype=eltype)
revolve(n, axis=0, angle=360.0, around=None, autofix=True)

Revolve a Mesh around an axis.

Returns a new Mesh obtained by revolving the given Mesh over an angle around an axis in n steps, while extruding the mesh from one step to the next.

This function is usually used to extrude points into lines, lines into surfaces and surfaces into volumes. By default it will try to fix the connectivity ordering where appropriate. If autofix is switched off, the connectivities are merely stacked, and the user may have to fix it himself.

Currently, this function correctly transforms: point1 to line2, line2 to quad4, tri3 to wedge6, quad4 to hex8.

sweep(path, eltype=None, **kargs)

Sweep a mesh along a path, creating an extrusion

Returns a new Mesh obtained by sweeping the given Mesh over a path. The returned Mesh has double plexitude of the original. The operation is similar to the extrude() method, but the path can be any 3D curve.

This function is usually used to extrude points into lines, lines into surfaces and surfaces into volumes. By default it will try to fix the connectivity ordering where appropriate. If autofix is switched off, the connectivities are merely stacked, and the user may have to fix it himself.

Currently, this function produces the correct element type, but the geometry .

classmethod concatenate(clas, meshes, **kargs)

Concatenate a list of meshes of the same plexitude and eltype

Merging of the nodes can be tuned by specifying extra arguments that will be passed to Coords:fuse().

test(nodes='all', dir=0, min=None, max=None, atol=0.0)

Flag elements having nodal coordinates between min and max.

This function is very convenient in clipping a Mesh in a specified direction. It returns a 1D integer array flagging (with a value 1 or True) the elements having nodal coordinates in the required range. Use where(result) to get a list of element numbers passing the test. Or directly use clip() or cclip() to create the clipped Mesh

The test plane can be defined in two ways, depending on the value of dir. If dir == 0, 1 or 2, it specifies a global axis and min and max are the minimum and maximum values for the coordinates along that axis. Default is the 0 (or x) direction.

Else, dir should be compaitble with a (3,) shaped array and specifies the direction of the normal on the planes. In this case, min and max are points and should also evaluate to (3,) shaped arrays.

nodes specifies which nodes are taken into account in the comparisons. It should be one of the following:

  • a single (integer) point number (< the number of points in the Formex)
  • a list of point numbers
  • one of the special strings: ‘all’, ‘any’, ‘none’

The default (‘all’) will flag all the elements that have all their nodes between the planes x=min and x=max, i.e. the elements that fall completely between these planes. One of the two clipping planes may be left unspecified.

clip(t, compact=False)

Return a Mesh with all the elements where t>0.

t should be a 1-D integer array with length equal to the number of elements of the Mesh. The resulting Mesh will contain all elements where t > 0.

cclip(t, compact=False)

This is the complement of clip, returning a Mesh where t<=0.

clipAtPlane(p, n, nodes='any', side='+')

Return the Mesh clipped at plane (p,n).

This is a convenience function returning the part of the Mesh at one side of the plane (p,n)

volumes()

Return the signed volume of all the mesh elements

For a ‘tet4’ tetraeder Mesh, the volume of the elements is calculated as 1/3 * surface of base * height.

For other Mesh types the volumes are calculated by first splitting the elements into tetraeder elements.

The return value is an array of float values with length equal to the number of elements. If the Mesh conversion to tetraeder does not succeed, the return value is None.

Functions defined in module trisurface

trisurface.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).

trisurface.read_gts(fn)

Read a GTS surface mesh.

Return a coords,edges,faces tuple.

trisurface.read_off(fn)

Read an OFF surface mesh.

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

trisurface.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.

trisurface.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.

trisurface.write_stla(f, x)

Export an x[n,3,3] float array as an ascii .stl file.

trisurface.write_smesh(fn, nodes, elems)

Write a tetgen surface model to .node and .smesh files.

The provided file name is the .node or the .smesh filename.

trisurface.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.

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

Calculate curvature parameters at the nodes.

Algorithms based on 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.

trisurface.surfaceInsideBorder(border, method='radial')

Create a surface inside a closed curve defined by a 2-plex Mesh.

border is a 2-plex Mesh representing a closed polyline.

The return value is a TriSurface filling the hole inside the border.

There are two fill methods:

  • ‘radial’: this method adds a central point and connects all border segments with the center to create triangles. It is fast and works well if the border is smooth, nearly convex and nearly planar.
  • ‘border’: this method creates subsequent triangles by connecting the endpoints of two consecutive border segments and thus works its way inwards until the hole is closed. Triangles are created at the segments that form the smallest angle. This method is slower, but works also for most complex borders. Also, because it does not create any new points, the returned surface uses the same point coordinate array as the input Mesh.
trisurface.read_error(cnt, line)

Raise an error on reading the stl file.

trisurface.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.

trisurface.read_stla(fn, dtype=<type 'numpy.float32'>, 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.

trisurface.read_ascii_large(fn, dtype=<type 'numpy.float32'>)

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.

trisurface.off_to_tet(fn)

Transform an .off model to tetgen (.node/.smesh) format.

trisurface.find_row(mat, row, nmatch=None)

Find all rows in matrix matching given row.

trisurface.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.

trisurface.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.

trisurface.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.

trisurface.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.

trisurface.Rectangle(nx, ny)

Create a plane rectangular surface consisting of a nx,ny grid.

trisurface.Cube()

Create the surface of a cube

Returns a TriSurface representing the surface of a unit cube. Each face of the cube is represented by two triangles.

trisurface.Sphere(level=4, verbose=False, filename=None)

Create a spherical surface by calling 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.

Documentation

Previous topic

31. mesh_ext — Extended functionality of the Mesh class.

Next topic

33. geomtools — Basic geometrical operations.