32. trisurface — Operations on triangulated surfaces. — pyFormex v0.8.6 documentation

### Navigation

- index
- modules |
- next |
- previous |
- pyFormex v0.8.6 documentation >
- pyFormex reference manual >

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

    Returns a tuple of:

    - the edges that connect 3 or more faces,
    - the faces connected to these edges.
  `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')

    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. The surfaces will have property values set above those used in the parent surface. If the surface is already closed, an empty list is returned.

    There are two methods, ‘radial’ and ‘border’ 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 adjacent to only one element get cosangles = 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)

    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, sort='number', 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.

    By default the parts are assigned property numbers in decreasing order of the number of triangles in the part. Setting the sort argument to ‘area’ will sort the parts according to decreasing area. Any other value will return the parts unsorted.

  `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.2, 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.2, 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`(matched=True)

    Check the surface using gtscheck.

    Uses gtscheck to check whether the surface is an orientable, non self-intersecting manifold.

    This is a necessary condition the gts methods: split, coarsen, refine, boolean. (Additionally, the surface should be closed, wich can be checked with `isClosedManifold()`).

    Returns a tuple of:

    - an integer return code with the value:
      - 0: the surface is an orientable, non self-intersecting manifold.
      - 2: the surface is not an orientable manifold. This may be due to misoriented normals. The `fixNormals()` and `reverse()` methods may be used to help fixing the problem in such case.
      - 3: the surface is an orientable manifold but is self-intersecting. The self intersecting triangles are returned as the second return value.
    - the intersecting triangles in the case of a return code 3, else None. If matched==True, intersecting triangles are returned as element indices of self, otherwise as a separate TriSurface object.
  `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.

  `addNoise`(*args, **kargs)

    Apply ‘addNoise’ transformation to the Geometry object.

    See `coords.Coords.addNoise()` for details.

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

  `centered`(*args, **kargs)

    Apply ‘centered’ transformation to the Geometry object.

    See `coords.Coords.centered()` 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.

  `position`(*args, **kargs)

    Apply ‘position’ transformation to the Geometry object.

    See `coords.Coords.position()` 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.

  `splitByConnection`()

    Split the Mesh into connected parts.

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

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

  `largestByConnection`()

    Return the largest connected part of the Mesh.

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

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

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

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

  `resized`(size=1.0, tol=1e-05)

    Return a scaled copy of the Formex with given size in all directions.

    If a direction has zero size, it is not rescaled.

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

  `toSurface`()

    Convert a Mesh to a Surface.

    If the plexitude of the mesh is 3, returns a TriSurface equivalent with the Mesh. Else, an error is raised.

  `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`(level=-1, return_indices=False)

    Return the border of the Mesh.

    Returns a Connectivity table with the free entities of the specified level of the Mesh. Free entities are entities that are only connected with a single element.

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

  `getFreeEntitiesMesh`(level=-1, compact=True)

    Return a Mesh with lower entities.

    Returns a Mesh representing the lower entities of the specified level. If the Mesh has property numbers, the lower entities 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.

  `getBorder`(return_indices=False)

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

    This is a convenient shorthand for

        self.getFreeEntities(level=-1,return_indices=return_indices)

  `getBorderMesh`(compact=True)

    Return a Mesh with the border elements.

    The returned Mesh is of the next lower hierarchical level and contains all the free entitites of that 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.

    This is a convenient shorthand for

        self.getFreeEntitiesMesh(level=-1,compact=compact)

  `getFreeEdgesMesh`(compact=True)

    Return a Mesh with the free edge elements.

    The returned Mesh is of the hierarchical level 1 (no mather what the level of the parent Mesh is) and contains all the free entitites of that 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.

    This is a convenient shorthand for

        self.getFreeEntitiesMesh(level=1,compact=compact)

  `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 duplicates.

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

    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.

  `avgNodes`(nodsel, wts=None)

    Create average nodes from the existing nodes of a mesh.

    nodsel is a local node selector as in `selectNodes()` Returns the (weighted) average coordinates of the points in the selector as (nelems*nnod,3) array of coordinates, where nnod is the length of the node selector. wts is a 1-D array of weights to be attributed to the points. Its length should be equal to that of nodsel.

  `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 reduce 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.

  `removeDuplicate`(permutations=True)

    Remove the duplicate elements from a Mesh.

    Duplicate elements are elements that consist of the same nodes, by default in no particular order. Setting permutations=False will only consider elements with the same nodes in the same order as duplicates.

    Returns a Mesh with all duplicate 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`(coordslist, div=1, degree=1, loop=False, eltype=None)

    Connect a sequence of toplogically congruent Meshes into a hypermesh.

    Parameters:

    - coordslist: either a list of Coords instances, all having the same shape as self.coords, or a single Mesh instance whose coords attribute has the same shape.

      If it is a list of Coords, consider a list of Meshes obtained by combining each Coords object with the connectivity table, element type and property numbers of the current Mesh. The return value then is the hypermesh obtained by connecting each consecutive slice of (degree+1) of these meshes. The hypermesh has a dimensionality that is one higher than the original Mesh (i.e. points become lines, lines become surfaces, surfaces become volumes). The resulting elements will be of the given degree in the direction of the connection. Notice that the coords of the current Mesh are not used, unless these coords are explicitely included into the specified coordslist. In many cases self.coords will be the first item in coordslist, but it could occur anywhere in the list or even not at all. The number of Coords items in the list should be a multiple of degree plus 1.

      Specifying a single Mesh instead of a list of Coords is just a convenience for the often occurring situation of connecting a Mesh (self) with another one (mesh) having the same connectivity: in this case the list of Coords will automatically be set to `[ self.coords, mesh.coords ]`. The degree should be 1 in this case.

    - degree: degree of the connection. Currently only degree 1 and 2 are supported.

      - If degree is 1, every Coords from the coordslist is connected with hyperelements of a linear degree in the connection direction.
      - If degree is 2, quadratic hyperelements are created from one Coords item and the next two in the list. Note that all Coords items should contain the same number of nodes, even for higher order elements where the intermediate planes contain less nodes.

    - loop: if True, the connections with loop around the list and connect back to the first. This is accomplished by adding the first Coords item back at the end of the list.

    - div: Either an integer, or a sequence of float numbers (usually in the range ]0.0..1.0]). With this parameter the generated elements can be further subdivided along the connection direction. If an int is given, the connected elements will be divided into this number of elements along the connection direction. If a sequence of float numbers is given, the numbers specify the relative distance along the connection direction where the elements should end. If the last value in the sequence is not equal to 1.0, there will be a gap between the consecutive connections.

    - eltype: the element type of the constructed hypermesh. Normally, this is set automatically from the base element type and the connection degree. If a different element type is specified, a final conversion to the requested element type is attempted.

  `extrude`(n, step=1.0, dir=0, degree=1, 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.

  `revolve`(n, axis=0, angle=360.0, around=None, loop=False, eltype=None)

    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 extrudes points into lines, lines into surfaces and surfaces into volumes.

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

    This is a class method, and should be invoked as follows:

        Mesh.concatenate([mesh0,mesh1,mesh2])

  `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.` `fillBorder`(border, method='radial')

  Create a surface inside a given closed border line.

  The border line is a closed polygonal line and can be specified as one of the following:

  - a closed PolyLine,
  - a 2-plex Mesh, with a Connectivity table such that the elements in order form a closed polyline,
  - a simple Coords specifying the subsequent vertices of the polygonal border line.

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

  There are currently two fill methods available:

  - ‘radial’: this method adds a central point and connects all border segments with the center to create triangles.
  - ‘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 line segments that form the smallest angle.

  The ‘radial’ method produces nice results if the border is relative smooth, nearly convex and nearly planar. It adds an extra point though, which may be unwanted. On irregular 3D borders there is a high change that the result contains intersecting triangles.

  This ‘border’ method is slower on large borders, does not introduce any new point and has a better chance of avoiding intersecting triangles on irregular 3D borders.

  The resulting surface can be checked for intersecting triangles by the `check()` method.

  ..note :: Because the ‘border’ does not create any new points, the
    returned surface will use the same point coordinate array as the input object.

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

### Navigation

- index
- modules |
- next |
- previous |
- pyFormex v0.8.6 documentation >
- pyFormex reference manual >