2. formex
— Formex algebra in Python¶
This module defines the Formex
class, which is one of the two
major classes for representing geometry in pyFormex (the other one being
Mesh
). The Formex class represents geometry as a simple
3dim Coords array. This allows an implementation of most functionality
of Formex algebra with a consistent and easy to use syntax.

class
formex.
Formex
(data=[], prop=None, eltype=None)[source]¶ A structured collection of points in 3D space.
A Formex is a collection of points in a 3D cartesian space. The collection is structured into a set of elements all having the same number of points (e.g. a collection triangles all having three points).
As the Formex class is derived from
Geometry
, a Formex object has acoords
attribute which is aCoords
object. In a Formex this is always an array with 3 axes (numbered 0,1,2). Each scalar element of this array represents a coordinate. A row along the last axis (2) is a set of 3 coordinates and represents a point (aka. node, vertex).For simplicity’s sake, the current implementation only deals with points in a 3dimensional space. This means that the length of axis 2 always equals 3. The user can create Formices (plural of Formex) in a 2D space, but internally these will be stored with 3 coordinates, by adding a third value 0. All operations work with 3D coordinate sets. However, it is easy to extract only a limited set of coordinates from the results, permitting to return to a 2D environment
A plane of the array along the axes 2 and 1 is a set of points: we call this an element. This can be thought of as a geometrical shape (2 points form a line segment, 3 points make a triangle, …) or as an element in Finite Element terms. But it really is up to the user as to how this set of points is to be interpreted. He can set an element type on the Formex to make this clear (see below).
The whole Formex then represents a collection of such elements. The Formex concept and layout is made more clear in Formex data model in the pyFormex tutorial.
Additionally, a Formex may have a property set, which is an 1D array of integers. The length of the array is equal to the length of axis 0 of the Formex data (i.e. the number of elements in the Formex). Thus, a single integer value may be attributed to each element. It is up to the user to define the use of this integer (e.g. it could be an index in a table of element property records). If a property set is defined, it will be copied together with the Formex data whenever copies of the Formex (or parts thereof) are made. Properties can be specified at creation time, and they can be set, modified or deleted at any time. Of course, the properties that are copied in an operation are those that exist at the time of performing the operation.
Finally, a Formex object can have an element type, because plexitude alone does not uniquely define what the geometric entities are, and how they should be rendered. By default, pyFormex will render plex1 as points, plex2 as line segments, plex3 as triangles and any higher plexitude as polygons. But the user could e.g. set
eltype = 'tet4'
on a plex4 Formex, and then that would be rendered as tetraeders.Parameters:  data (Formex, Coords, arraylike or string) – Data to initalize the coordinates attribute
coords
in the Formex. See more details below.  prop (int arraylike, optional) – 1dim int array with nonnegative element property numbers.
If provided,
setProp()
will be called to assign the specified properties.  eltype (str or
ElementType
, optional) – The element type of the geometric entities (elements). If provided, it should be one of theElementType
subclasses or the element name of such a subclass. If not provided, the pyFormex default is used when needed and is based on the plexitude: 1 = point, 2 = line segment, 3 = triangle, 4 or more is a polygon.
The Formex coordinate data can be initialized by another
Formex
, by aCoords
, by a 1D, 2D or 3D arraylike, or by a string to be used in one of the pattern functions to create a coordinate list. If 2D coordinates are given, a 3rd coordinate 0.0 is added. Internally, Formices always work with 3D coordinates. Thus:F = Formex([[[1,0],[0,1]],[[0,1],[1,2]]])
creates a Formex with two elements, each having 2 points in the global zplane. The innermost level of brackets group the coordinates of a point, the next level groups the points in an element, and the outermost brackets group all the elements of the Formex. Because the coordinates are stored in an array with 3 axes, all the elements in a Formex must contain the same number of points. This number is called the plexitude of the Formex.
A Formex may be initialized with a string instead of the numerical coordinate data. The string has the format #:data where # is a leader specifying the plexitude of the elements to be created. The data part of the string is passed to the
pattern()
function to generate a list of points on a regular grid of unit distances. Then the generated points are grouped in elements. If # is a number it just specifies the plexitude:F = Formex('3:012034')
This creates six points, grouped by 3, thus leading to two elements (triangles). The leader can als be the character l. In that case each generated point is turned into a 2point (line) element, by connecting it to the previous point. The following are two equivalent definitions of (the circumference of) a triangle:
F = Formex('2:010207') G = Formex('l:127')
Note
The legacy variant of initializing a Formex with a string without the leading ‘#:’ is no longer accepted.
Because the
Formex
class is derived fromGeometry
, it has the following attributes:Furthermore it has the following properties and methods that are applied on the
coords
attribute.xyz
,x
,y
,z
,xy
,yz
,xz
,points()
,bbox()
,center()
,bboxPoint()
,centroid()
,sizes()
,dsize()
,bsphere()
,bboxes()
,inertia()
,principalCS()
,principalSizes()
,distanceFromPlane()
,distanceFromLine()
,distanceFromPoint()
,directionalSize()
,directionalWidth()
,directionalExtremes()
.
Also, the following Coords transformation methods can be directly applied to a
Formex
object. The return value is a new Formex identical to the original, except for the coordinates, which are transformed by the specified method. Refer to the correspondingCoords
method for the usage of these methods:scale()
,adjust()
,translate()
,centered()
,align()
,rotate()
,shear()
,reflect()
,affine()
,toCS()
,fromCS()
,transformCS()
,position()
,cylindrical()
,hyperCylindrical()
,toCylindrical()
,spherical()
,superSpherical()
,toSpherical()
,bump()
,flare()
,map()
,map1()
,mapd()
,copyAxes()
,swapAxes()
,rollAxes()
,projectOnPlane()
,projectOnSphere()
,projectOnCylinder()
,isopar()
,addNoise()
,rot()
,trl()
.
Examples
>>> print(Formex([[0,1],[2,3]])) {[0.0,1.0,0.0], [2.0,3.0,0.0]} >>> print(Formex('1:0123')) {[0.0,0.0,0.0], [1.0,0.0,0.0], [1.0,1.0,0.0], [0.0,1.0,0.0]} >>> print(Formex('4:0123')) {[0.0,0.0,0.0; 1.0,0.0,0.0; 1.0,1.0,0.0; 0.0,1.0,0.0]} >>> print(Formex('2:0123')) {[0.0,0.0,0.0; 1.0,0.0,0.0], [1.0,1.0,0.0; 0.0,1.0,0.0]} >>> F = Formex('l:1234') >>> print(F) {[0.0,0.0,0.0; 1.0,0.0,0.0], [1.0,0.0,0.0; 1.0,1.0,0.0], [1.0,1.0,0.0; 0.0,1.0,0.0], [0.0,1.0,0.0; 0.0,0.0,0.0]} >>> print(F.info()) shape = (4, 2, 3) bbox[lo] = [ 0. 0. 0.] bbox[hi] = [ 1. 1. 0.] center = [ 0.5 0.5 0. ] maxprop = 1 <BLANKLINE> >>> F.nelems() 4 >>> F.level() 1 >>> F.x array([[ 0., 1.], [ 1., 1.], [ 1., 0.], [ 0., 0.]], dtype=float32) >>> F.center() Coords([ 0.5, 0.5, 0. ]) >>> F.bboxPoint('+++') Coords([ 1., 1., 0.])
The Formex class defines the following attributes above the ones inherited from Geometry:

eltype
¶ Type: None or ElementType

shape
¶ Return the shape of the Formex.
The shape of a Formex is the shape of its coords array.
Returns: tuple of ints – A tuple (nelems, nplex, ndim). Examples
>>> Formex('l:1234').shape (4, 2, 3) >>> Formex('1:1234').shape (4, 1, 3)

nelems
()[source]¶ Return the number of elements of the
Formex
.The number of elements is the length of the first axis of the
coords
array.Returns: int – The number of elements in the Formex Examples
>>> Formex('l:1234').nelems() 4

nplex
()[source]¶ Return the plexitude of the
Formex
.The plexitude is the number of points per element. This is the length of the second axis of the coords array.
Examples:
 unconnected points,
 straight line elements,
 triangles or quadratic line elements,
 tetraeders or quadrilaterals or cubic line elements.
Returns: int – The plexitude of the elements in the Formex Examples
>>> Formex('l:1234').nplex() 2

ndim
()[source]¶ Return the number of dimensions.
This is the number of coordinates for each point. In the current implementation this is always 3, though you can define 2D Formices by given only two coordinates: the third will automatically be set to zero.
Returns: int – The number of coordinates per point: currently, this is always 3. Examples
>>> Formex('l:1234').ndim() 3

npoints
()[source]¶ Return the number of points in the Formex.
This is the product of the number of elements in the Formex with the plexitude of the elements.
Returns: int – The total number of points in the Formex Notes
ncoords
is an alias fornpoints
Examples
>>> Formex('l:1234').npoints() 8

ncoords
()¶ Return the number of points in the Formex.
This is the product of the number of elements in the Formex with the plexitude of the elements.
Returns: int – The total number of points in the Formex Notes
ncoords
is an alias fornpoints
Examples
>>> Formex('l:1234').npoints() 8

elType
()[source]¶ Return the element type of the Formex.
Returns: ElementType
or None – If an element type was defined for the Formex, returns the corresponding ElementType; else returns None.See also
elName()
 Return the name of the ElementType
Examples
>>> Formex('l:1234').elType() >>> Formex('l:1234',eltype='line2').elType() <class 'pyformex.elements.Line2'>

elName
()[source]¶ Return the element name of the Formex.
Returns: str or None – If an element type was defined for the Formex, returns the name of the ElementType ; else returns None. See also
elType()
 Return the ElementType subclass
Examples
>>> Formex('l:1234').elName() >>> Formex('l:1234',eltype='line2').elName() 'line2'

level
()[source]¶ Return the level (dimensionality) of the Formex.
The level or dimensionality of a geometrical object is the minimum number of parametric directions required to describe the object. Thus we have the following values:
0: points 1: lines 2: surfaces 3: volumes
Because the geometrical meaning of a Formex is not always defined, the level may be unknown. In that case, 1 is returned.
If the Formex has an ‘eltype’ set, the value is determined from the Element database. Else, the value is equal to the plexitude minus one for plexitudes up to 3, and equal to 2 for any higher plexitude (since the default is to interprete a higher plexitude as a polygon).
Returns: int – An int 0..3 giving the number of parametric dimensions of the geometric entities in the Formex. Examples
>>> Formex('1:123').level() 0 >>> Formex('l:123').level() 1 >>> Formex('3:123').level() 2 >>> Formex('3:123',eltype='line3').level() 1

view
()[source]¶ Return the Formex coordinates as a numpy array (ndarray).
Returns a view to the Coords array as an ndarray. The use of this method is deprecated: use the
xyz
property instead.

element
(i)[source]¶ Return element i of the Formex.
Parameters: i (int) – The index of the element to return. Returns: Coords object – A Coords with shape (self.nplex(), 3) Examples
>>> Formex('l:12').element(0) Coords([[ 0., 0., 0.], [ 1., 0., 0.]]) >>> Formex('l:12').select(0) Formex([[[ 0., 0., 0.], [ 1., 0., 0.]]])

point
(i, j)[source]¶ Return point j of element i.
Parameters:  i (int) – The index of the element from which to return a point.
 j (int) – The index in element i of the point to be returned.
Returns: Coords object – A Coords with shape (3,), being point j of element i.
Examples
>>> Formex('l:12').point(0,1) Coords([ 1., 0., 0.])

coord
(i, j, k)[source]¶ Return coordinate k of point j of element i.
Parameters:  i (int) – The index of the element from which to return a point.
 j (int) – The index in element i of the point for which to return a coordinate.
 k (int) – The index in point (i,j) of the coordinate to be returned.
Returns: float – The value of coordinate k of point j of element i.
Examples
>>> Formex('l:12').coord(0,1,0) 1.0

centroids
()[source]¶ Return the centroids of all elements of the Formex.
The centroid of an element is the point whose coordinates are the average values of all points of the element.
Returns: Coords – A Coords object with shape ( nelems()
, 3), holding the centroids of all the elements in the Formex.Examples
>>> Formex('l:123').centroids() Coords([[ 0.5, 0. , 0. ], [ 1. , 0.5, 0. ], [ 0.5, 1. , 0. ]])

toMesh
(**kargs)[source]¶ Convert a Formex to a Mesh.
Converts a geometry in Formex model to the equivalent Mesh model. In the Mesh model, all points with nearly identical coordinates are fused into a single point (using
fuse()
), and elements are defined by a connectivity table with integers pointing to the corresponding vertex.Parameters: kargs – Keyword parameters to be passed to fuse()
.Returns: Mesh – A Mesh representing the same geometrical model as the input Formex. Property numbers prop
and element typeeltype
are also set to the same values as in the Formex.Examples
>>> F = Formex('l:12') >>> F Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 1., 0., 0.], [ 1., 1., 0.]]]) >>> M = F.toMesh() >>> print(M) Mesh: nnodes: 3, nelems: 2, nplex: 2, level: 1, eltype: line2 BBox: [ 0. 0. 0.], [ 1. 1. 0.] Size: [ 1. 1. 0.]

toSurface
()[source]¶ Convert a Formex to a Surface.
Tries to convert the Formex to a TriSurface. First the Formex is converted to a Mesh, and then the resulting Mesh is converted to a TriSurface.
Returns: TriSurface – A TriSurface if the conversion is succesful, else an error is raised. Notes
The conversion will only work if the Formex represents a surface and its elements are triangles or quadrilaterals. If the plexitude of the Formex is 3, the element type is ‘tri3’ or None, the returned TriSurface is equivalent with the Formex. If the Formex contains higher order triangles or quadrilaterals, The new geometry will be an approximation of the input. Any other input geometry will fail to convert.
Examples
>>> F = Formex('3:.12.34') >>> F Formex([[[ 0., 0., 0.], [ 1., 0., 0.], [ 1., 1., 0.]], <BLANKLINE> [[ 1., 1., 0.], [ 0., 1., 0.], [ 0., 0., 0.]]]) >>> print(F.toSurface()) Mesh: nnodes: 4, nelems: 2, nplex: 3, level: 2, eltype: tri3 BBox: [ 0. 0. 0.], [ 1. 1. 0.] Size: [ 1. 1. 0.]

info
()[source]¶ Return information about a Formex.
Returns:  A multiline string with some basic information about the Formex
 its shape, bounding box, center and maxprop.
Examples
>>> print(Formex('3:.12.34').info()) shape = (2, 3, 3) bbox[lo] = [ 0. 0. 0.] bbox[hi] = [ 1. 1. 0.] center = [ 0.5 0.5 0. ] maxprop = 1 <BLANKLINE>

classmethod
point2str
(point)[source]¶ Return a string representation of a point
Parameters: elem (float arraylike (3,)) – The coordinates of athe point to return as a string. Returns: str – A string with the representation of a single point. Examples
>>> Formex.point2str([1.,2.,3.]) '1.0,2.0,3.0'

classmethod
element2str
(elem)[source]¶ Return a string representation of an element
Parameters: elem (float arraylike (nplex,3)) – The element to return as a string. Returns: str – A string with the representation of a single element. Examples
>>> Formex.element2str([[1.,2.,3.],[4.,5.,6.]]) '[1.0,2.0,3.0; 4.0,5.0,6.0]'

asFormex
()[source]¶ Return string representation of all the coordinates in a Formex.
Returns: str – A single string with all the coordinates of the Formex. Coordinates are separated by commas, points are separated by semicolons and grouped between brackets, elements are separated by commas and grouped between braces. Examples
>>> F = Formex([[[1,0],[0,1]],[[0,1],[1,2]]]) >>> F.asFormex() '{[1.0,0.0,0.0; 0.0,1.0,0.0], [0.0,1.0,0.0; 1.0,2.0,0.0]}'

asFormexWithProp
()[source]¶ Return string representation as Formex with properties.
Returns: str – The string representation as done by asFormex()
, followed by the words “with prop” and a list of the properties.Examples
>>> F = Formex([[[1,0],[0,1]],[[0,1],[1,2]]]).setProp([1,2]) >>> F.asFormexWithProp() '{[1.0,0.0,0.0; 0.0,1.0,0.0], [0.0,1.0,0.0; 1.0,2.0,0.0]} with prop [1 2]'

asCoords
()[source]¶ Return string representation as a Coords.
Returns: str – A multiline string with the coordinates of the Formex as formatted by the meth:coords.Coords.__repr__ method. Examples
>>> F = Formex([[[1,0],[0,1]],[[0,1],[1,2]]]) >>> print(F.asCoords()) Formex([[[ 1., 0., 0.], [ 0., 1., 0.]], <BLANKLINE> [[ 0., 1., 0.], [ 1., 2., 0.]]])

asArray
()[source]¶ Return string representation as a numpy array.
Returns: str – A multiline string with the coordinates of the Formex as formatted by the meth:coords.Coords.__str__ method. Examples
>>> F = Formex([[[1,0],[0,1]],[[0,1],[1,2]]]) >>> print(F.asArray()) [[[ 1. 0. 0.] [ 0. 1. 0.]] <BLANKLINE> [[ 0. 1. 0.] [ 1. 2. 0.]]]

classmethod
setPrintFunction
(func)[source]¶ Choose the default formatting for printing formices.
This sets how formices will be formatted by a print statement. Currently there are two available functions: asFormex, asArray. The user may create his own formatting method. This is a class method. It should be used asfollows: Formex.setPrintFunction(Formex.asArray).

classmethod
concatenate
(Flist)[source]¶ Concatenate a list of Formices.
All the Formices in the list should have the same plexitude, If any of the Formices has property numbers, the resulting Formex will inherit the properties. In that case, any Formices without properties will be assigned property 0. If all Formices are without properties, so will be the result. The eltype of the resulting Formex will be that of the first Formex in the list.
Parameters: Flist (list of Formex objects) – A list of Formices all having the same plexitude. Returns: Formex – The concatenation of all the Formices in the list. The number of elements in the Formex is the sum of the number of elements in all the Formices. Note
This is a class method, not an instance method. It is commonly invoked as
Formex.concatenate
.See also
__add__()
 implements concatenation as simple addition (F+G)
Examples
>>> F = Formex([1.,1.,1.]).setProp(1) >>> G = Formex([2.,2.,2.]) >>> H = Formex([3.,3.,3.]).setProp(3) >>> K = Formex.concatenate([F,G,H]) >>> print(K.asFormexWithProp()) {[1.0,1.0,1.0], [2.0,2.0,2.0], [3.0,3.0,3.0]} with prop [1 0 3]

__add__
(F)[source]¶ Concatenate two formices.
Parameters: F (Formex) – A Formex with the same plexitude as self. Returns: Formex – The concatenation of the Formices self and F. Note
This method implements the addition operation and allows to write simple expressions as F+G to concatenate the Formices F and G. When concatenating many Formices,
concatenate()
is more efficient however, because all the Formices in the list are concatenated in one operation.See also
concatenate()
 concatenate a list of Formices
Examples
>>> F = Formex([1.,1.,1.]).setProp(1) >>> G = Formex([2.,2.,2.]) >>> H = Formex([3.,3.,3.]).setProp(3) >>> K = F+G+H >>> print(K.asFormexWithProp()) {[1.0,1.0,1.0], [2.0,2.0,2.0], [3.0,3.0,3.0]} with prop [1 0 3]

split
(n=1)[source]¶ Split a Formex in Formices containing n elements.
Parameters: n (int) – Number of elements per Formex Returns: list of Formices – A list of Formices all containing n elements, except for the last, which may contain less. Examples
>>> Formex('l:111').split(2) [Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 1., 0., 0.], [ 2., 0., 0.]]]), Formex([[[ 2., 0., 0.], [ 3., 0., 0.]]])]

selectNodes
(idx)[source]¶ Extract a Formex holding only some points of the parent.
This creates subentities of all elements in the Formex. The returned Formex inherits the properties of the parent.
Parameters: idx (list of ints) – Indices of the points to retain in the new Formex. Notes
For example, if F is a plex3 Formex representing triangles, the sides of the triangles are given by F.selectNodes([0,1]) + F.selectNodes([1,2]) + F.selectNodes([2,0])
See also
select()
 Select elements from a Formex
Examples
>>> F = Formex('3:.12.34') >>> print(F.selectNodes((0,1))) {[0.0,0.0,0.0; 1.0,0.0,0.0], [1.0,1.0,0.0; 0.0,1.0,0.0]}

asPoints
()[source]¶ Reduce the Formex to a simple set of points.
This removes the element structure of the Formex.
Returns: Formex – A Formex with plexitude 1 and number of elements (points) equal to self.nelems() * self.nplex()
. The Formex shares the coordinate data with the parent. If the parent has properties, they are multiplexed so that each point has the property of its parent element. The eltype of the returned Formex is None.See also
points()
 returns the list of points as a Coords object
Examples
>>> F = Formex('3:.12.34',prop=[1,2]).asPoints() >>> print(F.asFormexWithProp()) {[0.0,0.0,0.0], [1.0,0.0,0.0], [1.0,1.0,0.0], [1.0,1.0,0.0], [0.0,1.0,0.0], [0.0,0.0,0.0]} with prop [1 1 1 2 2 2]

remove
(F, permutations='roll', rtol=1e05, atol=1e05)[source]¶ Remove elements that also occur in another Formex.
Parameters:  F (Formex) – Another Formex with the same plexitude as self.
 permutations (bool, optional) – If True, elements consisting of the
 is also the subtraction of the current Formex with F. (This) –
 are only removed if they have the same nodes in the same (Elements) –
 order. –
Examples
>>> F = Formex('l:111') >>> G = Formex('l:1') >>> print(F.remove(G)) {[1.0,0.0,0.0; 2.0,0.0,0.0], [2.0,0.0,0.0; 3.0,0.0,0.0]}

removeDuplicate
(permutations='all', rtol=1e05, atol=1e08)[source]¶ Return a Formex which holds only the unique elements.
Parameters:  permutations (str) –
Defines which permutations of the element points are allowed while still considering the elements equal. Possible values are:
 ’none’: no permutations are allowed: elements must have matching points at all locations. This is the default;
 ’roll’: rolling is allowed. Elements that can be transformed into each other by rolling their points are considered equal;
 ’all’: any permutation of the same points will be considered an equal element.
 rtol (float, optional) – Relative tolerance used when considering two points being equal.
 atol (float, optional) – Absolute tolerance used when considering two points being equal.
Notes
rtol
andatol
are passed tocoords.Coords.fuse()
to find equal points.permutation
is passed toarraytools.unique()
to remove the duplicates.Examples
>>> F = Formex('l:111') + Formex('l:1') >>> print(F.removeDuplicate()) {[0.0,0.0,0.0; 1.0,0.0,0.0], [1.0,0.0,0.0; 2.0,0.0,0.0], [2.0,0.0,0.0; 3.0,0.0,0.0]}
 permutations (str) –

test
(nodes='all', dir=0, min=None, max=None, atol=0.0)[source]¶ Flag elements having coordinates between min and max.
This is comparable with
coords.Coords.test()
but operates at the Formex element level. It tests the position of one or more points of the elements of theFormex
with respect to one or two parallel planes. This is very useful in clipping a Formex in a specified direction. In most cases the clipping direction is one of the global coordinate axes, but a general direction may be used as well.Testing along global axis directions is highly efficient. It tests whether the corresponding coordinate is above or equal to the min value and/or below or equal to the max value. Testing in a general direction tests whether the distance to the min plane is positive or zero and/or the distance to the max plane is negative or zero.
Parameters:  nodes (int, list of ints or string) –
Specifies which points of the elements are taken into account in the tests. It should be one of the following:
 a single point index (smaller than self.nplex()),
 a list of point numbers ( all smaller than < self.nplex()),
 one of the special strings: ‘all’, ‘any’, ‘none’.
The default (‘all’) will flag 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.
 dir (a single int or a float arraylike (3,)) – The direction in which to measure distances. If an int, it is one of the global axes (0,1,2). Else it is a vector with 3 components. The default direction is the global xaxis.
 min (float or pointlike, optional) – Position of the minimal clipping plane. If dir is an int, this is a single float giving the coordinate along the specified global axis. If dir is a vector, this must be a point and the minimal clipping plane is defined by this point and the normal vector dir. If not provided, there is no clipping at the minimal side.
 max (float or pointlike.) – Position of the maximal clipping plane. If dir is an int, this is a single float giving the coordinate along the specified global axis. If dir is a vector, this must be a point and the maximal clipping plane is defined by this point and the normal vector dir. If not provided, there is no clipping at the maximal side.
 atol (float) – Tolerance value added to the tests to account for accuracy and rounding errors. A min test will be ok if the point’s distance from the min clipping plane is > atol and/or the distance from the max clipping plane is < atol. Thus a positive atol widens the clipping planes.
Returns: 1dim bool array – Array with length
self.nelems()
flagging the elements that pass the test(s). The return value can directly be used as an index inselect()
or cselect to obtain aFormex
with the elements satisfying the test or not. Or you can usewhere(result)[0]
to get the indices of the elements passing the test.Raises: ValueError: At least one of min or max have to be specified – If neither min nor max are provided.
See also
select()
 return only the selected elements
cselect()
 return all but the selected elements
Examples
>>> F = Formex('l:1122') >>> print(F) {[0.0,0.0,0.0; 1.0,0.0,0.0], [1.0,0.0,0.0; 2.0,0.0,0.0], [2.0,0.0,0.0; 2.0,1.0,0.0], [2.0,1.0,0.0; 2.0,2.0,0.0]} >>> F.test(min=0.0,max=1.0) array([ True, False, False, False], dtype=bool) >>> F.test(nodes=[0],min=0.0,max=1.0) array([ True, True, False, False], dtype=bool) >>> F.test(dir=[1.,1.,0.],min=[1.,1.,0.]) array([False, True, True, False], dtype=bool) >>> F.test(nodes='any',dir=[1.,1.,0.],min=[1.,1.,0.]) array([ True, True, True, True], dtype=bool)
 nodes (int, list of ints or string) –

shrink
(factor)[source]¶ Scale all elements with respect to their own center.
Parameters: factor (float) – Scaling factor for the elements. A value < 1.0 will shrink the elements, while a facter > 1.0 will enlarge them. Returns: Formex – A Formex where each element has been scaled with the specified factor in local axes with origin at the element’s center. Notes
This operation is called ‘shrink’ because it is commonly used with a factor smaller that 1 (often around 0.9) to draw an exploded view where touching elements are disconnected.
Examples
>>> Formex('l:12').shrink(0.8) Formex([[[ 0.1, 0. , 0. ], [ 0.9, 0. , 0. ]], <BLANKLINE> [[ 1. , 0.1, 0. ], [ 1. , 0.9, 0. ]]])

circulize1
()[source]¶ Transforms the first octant of the 01 plane into 1/6 of a circle.
Points on the 0axis keep their position. Lines parallel to the 1axis are transformed into circular arcs. The bisector of the first quadrant is transformed in a straight line at an angle Pi/6. This function is especially suited to create circular domains where all bars have nearly same length. See the Diamatic example.

reverse
()[source]¶ Return a Formex where all elements have been reversed.
Reversing an element means reversing the order of its points.
Returns: Formex – A Formex with same shape, where the points of all elements are in reverse order. Notes
This is equivalent to
self.selectNodes(arange(self.nplex()1,1,1))
.Examples
>>> F = Formex('l:11') >>> F.reverse() Formex([[[ 1., 0., 0.], [ 0., 0., 0.]], <BLANKLINE> [[ 2., 0., 0.], [ 1., 0., 0.]]])

mirror
(dir=0, pos=0.0, keep_orig=True)[source]¶ Add a reflection in one of the coordinate directions.
This method is like
reflect()
, but by default adds the reflected part to the original.Parameters:  dir (int (0,1,2)) – Global axis direction of the reflection (default 0 or xaxis).
 pos (float) – Offset of the mirror plane from origin (default 0.0)
 keep_orig (bool, optional) – If True (default) the original plus the mirrored geometry is
returned. Setting it to False will only return the mirror, and
thus behaves just like
reflect()
.
Returns: Formex – A Formex with the original and the mirrored elements, or only the mirrored elements if
keep_orig
is False.Examples
>>> F = Formex('l:11') >>> F.mirror() Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 1., 0., 0.], [ 2., 0., 0.]], <BLANKLINE> [[ 0., 0., 0.], [1., 0., 0.]], <BLANKLINE> [[1., 0., 0.], [2., 0., 0.]]]) >>> F.mirror(keep_orig=False) Formex([[[ 0., 0., 0.], [1., 0., 0.]], <BLANKLINE> [[1., 0., 0.], [2., 0., 0.]]])

translatem
(*args)[source]¶ Multiple subsequent translations in axis directions.
Parameters: *args (one or more tuples (axis, step)) – Each argument is a tuple (axis, step) which will do a translation over a length step
in the direction of the global axisaxis
.Returns: Formex – The input Formex translated over the combined translation vector of the arguments. Notes
This function is especially convenient to translate over computed steps.
See also
translate()
 translate a Formex
Examples
>>> F = Formex('l:11') >>> d = random.random(3) >>> allclose(F.translatem((0,d[0]),(2,d[2]),(1,d[1])).coords, F.translate(d).coords) True

replicate
(n, dir=0, step=1.0)[source]¶ Create copies at regular distances along a straight line.
Parameters:  n (int) – Number of copies to create
 dir (int (0,1,2) or float arraylike (3,)) – The translation vector. If an int, it specifies a global axis and the translation is in the direction of that axis.
 step (float) – If
dir
is an int, this is the length of the translation. Else, it is a multiplying factor applied to the translation vector.
Returns: Formex – A Formex with the concatenation of n copies of the original. Each copy is equal to the previous one translated over a distance
step * length(dir)
in the directiondir
. The first of the copies is equal to the original.See also
Examples
>>> Formex('l:1').replicate(4,1) Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 0., 1., 0.], [ 1., 1., 0.]], <BLANKLINE> [[ 0., 2., 0.], [ 1., 2., 0.]], <BLANKLINE> [[ 0., 3., 0.], [ 1., 3., 0.]]])

repm
(n, dir=(0, 1, 2), step=(1.0, 1.0, 1.0))[source]¶ Repeatedly replication in different directions
This repeatedly applies
replicate()
a number of times. The parameters are lists of values like those for replicate.Parameters:  n (list of int) – Number of copies to create in the subsequent replications.
 dir (list of int (0,1,2) or list of float arraylike (3,)) – Subsequent translation vectors. See
replicate()
.  step (list of floats) – The step for the subsequent replications.
Returns: Formex – A Formex with the concatenation of prod(n) copies of the original, translated as specified by the dir and step parameters. The first of the copies is equal to the original.
Note
If the parameter lists
n
,dir
,step
have different lengths, the operation is executed only for the shortest of the three.See also
replicate()
 replicate in a single direction
replic2()
 replicate in two directions with bias and taper
Examples
>>> Formex('l:1').repm((2,2),(1,2)) Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 0., 1., 0.], [ 1., 1., 0.]], <BLANKLINE> [[ 0., 0., 1.], [ 1., 0., 1.]], <BLANKLINE> [[ 0., 1., 1.], [ 1., 1., 1.]]])
>>> print(Formex([origin()]).repm((2,2))) {[0.0,0.0,0.0], [1.0,0.0,0.0], [0.0,1.0,0.0], [1.0,1.0,0.0]}

replic
(n, step=1.0, dir=0)[source]¶ Return a Formex with n replications in direction dir with step.
Note
This works exactly like
replicate()
but has another order of the parameters. It is kept for historical reasons, but should not be used in new code.

replic2
(n1, n2, t1=1.0, t2=1.0, d1=0, d2=1, bias=0, taper=0)[source]¶ Replicate in two directions with bias and taper.
Parameters:  n1 (int) – Number of replications in first direction
 n2 (int) – Number of replications in second direction
 t1 (float) – Step length in the first direction
 t2 (float) – Step length in the second direction
 d1 (int) – Global axis of the first direction
 d2 (int) – Global axis of the second direction
 bias (float) – Extra translation in direction d1 for each step in direction d2
 taper (int) – Extra number of copies generated in direction d1 for each step in direction d2
Note
If no bias nor taper is needed, the use of
repm()
is recommended.See also
replicate()
 replicate in a single direction
repm()
 replicate in multiple directions
Examples
>>> print(Formex([origin()]).replic2(2,2)) {[0.0,0.0,0.0], [1.0,0.0,0.0], [0.0,1.0,0.0], [1.0,1.0,0.0]} >>> print(Formex([origin()]).replic2(2,2,bias=0.2)) {[0.0,0.0,0.0], [1.0,0.0,0.0], [0.2,1.0,0.0], [1.2,1.0,0.0]} >>> print(Formex([origin()]).replic2(2,2,taper=1)) {[0.0,0.0,0.0], [1.0,0.0,0.0], [0.0,1.0,0.0]}

replicm
(n, step=(1.0, 1.0, 1.0), dir=(0, 1, 2))[source]¶ Replicate in multiple global axis directions.
Note
This works exactly like
repm()
but has another order of the parameters. It is kept for historical reasons, but should not be used in new code.

rosette
(n, angle, axis=2, around=(0.0, 0.0, 0.0), angle_spec=0.017453292519943295, **kargs)[source]¶ Create rotational replications of a Formex.
Parameters:  n (int) – Number of copies to create
 angle (float) – Angle between successive copies.
 axis (int or (3,) float arraylike) – The rotation axis. If an int one of 0,1,2, specifying a global axis, or a vector with 3 components specifying an axis through the origin. The returned matrix is 3D.
 around (float arraylike (3,)) – If provided, it species a point on the rotation axis. If not, the rotation axis goes through the origin of the global axes.
 angle_spec (float, DEG or RAD, optional) – The default (DEG) interpretes the angle in degrees. Use RAD to specify the angle in radians.
Returns: Formex – A Formex with n rotational replications with given angular step. The original Formex is the first of the n replicas.
Examples
>>> Formex('l:1').rosette(4,90.) Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 0., 0., 0.], [ 0., 1., 0.]], <BLANKLINE> [[ 0., 0., 0.], [1., 0., 0.]], <BLANKLINE> [[ 0., 0., 0.], [0., 1., 0.]]]) >>> Formex('l:1').rosette(3,90.,around=(0.,1.,0.)) Formex([[[ 0., 0., 0.], [ 1., 0., 0.]], <BLANKLINE> [[ 1., 1., 0.], [ 1., 2., 0.]], <BLANKLINE> [[ 0., 2., 0.], [1., 2., 0.]]])

extrude
(*args, **kargs)[source]¶ Extrude a Formex along a straight line.
The Formex is extruded over a given length in the given direction. This operates by converting the Formex to a
Mesh
, extruding the Mesh with the given parameters, and converting the result back to a Formex.Parameters: see
extrude()
.Returns:  Formex – The Formex obtained by extruding the input Formex over the given length in direction dir, subdividing this length according
 to the seeds specified by dir. The plexitude of the result will be
 double that of the input.
 This method works by converting the Formex to a
Mesh
,  using the
Mesh.extrude()
and then converting the result  back to a Formex.
See also
connect()
 create a higher plexitude Formex by connecting Formices
Examples
>>> Formex(origin()).extrude(4,dir=0,length=3) Formex([[[ 0. , 0. , 0. ], [ 0.75, 0. , 0. ]], <BLANKLINE> [[ 0.75, 0. , 0. ], [ 1.5 , 0. , 0. ]], <BLANKLINE> [[ 1.5 , 0. , 0. ], [ 2.25, 0. , 0. ]], <BLANKLINE> [[ 2.25, 0. , 0. ], [ 3. , 0. , 0. ]]])

interpolate
(G, div, swap=False)[source]¶ Create linear interpolations between two Formices.
A linear interpolation of two equally shaped Formices F and G at parameter value t is an equally shaped Formex H where each coordinate is obtained from: Hijk = Fijk + t * (GijkFijk). Thus, a
F.interpolate(G,[0.,0.5,1.0])
will contain all elements of F and G and all elements with mean coordinates between those of F and G.Parameters:  G (Formex) – A Formex with same shape as self.
 div (int or list of floats) –
The list of parameter values for which to compute the interpolation. Usually, they are in the range 0.0 (self) to 1.0 (X). Values outside the range can be used however and result in linear extrapolations.
If an int is provided, a list with
(div+1)
parameter values is used, obtained by dividing the interval [0..1] into div equal segments. Then, specifyingdiv=n
is equivalent to specifyingdiv=arange(n+1)/float(n))
.  swap (bool, optional) – If swap=True, the returned Formex will have the elements of the interpolation Formices interleaved. The default is to return a simple concatenation.
Returns: Formex – A Formex with the concatenation of all generated interpolations, if swap is False (default). With swap=True, the elements of the interpolations are interleaved: first all the first elements from all the interpolations, then all the second elements, etc. The elements inherit the property numbers from self, if any. The Formex has the same eltype as self, if it is set.
See also
Notes
See also example Interpolate.
Examples
>>> F = Formex([[[0.0,0.0,0.0],[1.0,0.0,0.0]]]) >>> G = Formex([[[1.5,1.5,0.0],[4.0,3.0,0.0]]]) >>> F.interpolate(G,div=3) Formex([[[ 0. , 0. , 0. ], [ 1. , 0. , 0. ]], <BLANKLINE> [[ 0.5, 0.5, 0. ], [ 2. , 1. , 0. ]], <BLANKLINE> [[ 1. , 1. , 0. ], [ 3. , 2. , 0. ]], <BLANKLINE> [[ 1.5, 1.5, 0. ], [ 4. , 3. , 0. ]]]) >>> F = Formex([[[0.0,0.0,0.0]],[[1.0,0.0,0.0]]]) >>> G = Formex([[[1.5,1.5,0.0]],[[4.0,3.0,0.0]]]) >>> F.interpolate(G,div=3) Formex([[[ 0. , 0. , 0. ]], <BLANKLINE> [[ 1. , 0. , 0. ]], <BLANKLINE> [[ 0.5, 0.5, 0. ]], <BLANKLINE> [[ 2. , 1. , 0. ]], <BLANKLINE> [[ 1. , 1. , 0. ]], <BLANKLINE> [[ 3. , 2. , 0. ]], <BLANKLINE> [[ 1.5, 1.5, 0. ]], <BLANKLINE> [[ 4. , 3. , 0. ]]]) >>> F.interpolate(G,div=3,swap=True) Formex([[[ 0. , 0. , 0. ]], <BLANKLINE> [[ 0.5, 0.5, 0. ]], <BLANKLINE> [[ 1. , 1. , 0. ]], <BLANKLINE> [[ 1.5, 1.5, 0. ]], <BLANKLINE> [[ 1. , 0. , 0. ]], <BLANKLINE> [[ 2. , 1. , 0. ]], <BLANKLINE> [[ 3. , 2. , 0. ]], <BLANKLINE> [[ 4. , 3. , 0. ]]])

subdivide
(div)[source]¶ Subdivide a plex2 Formex at the parameter values in div.
Replaces each element of the plex2 Formex (line segments) by a sequence of elementsobtained by subdividing the Formex at the specified parameter values.
Parameters: div (int or list of floats) – The list of parameter values at which to subdivide the elements. Usually, they are in the range 0.0 to 1.0.
If an int is provided, a list with
(div+1)
parameter values is used, obtained by dividing the interval [0..1] into div equal segments. Thus, specifyingdiv=n
is equivalent to specifyingdiv=arange(n+1)/float(n))
.Examples
>>> Formex('l:1').subdivide(4) Formex([[[ 0. , 0. , 0. ], [ 0.25, 0. , 0. ]], <BLANKLINE> [[ 0.25, 0. , 0. ], [ 0.5 , 0. , 0. ]], <BLANKLINE> [[ 0.5 , 0. , 0. ], [ 0.75, 0. , 0. ]], <BLANKLINE> [[ 0.75, 0. , 0. ], [ 1. , 0. , 0. ]]]) >>> Formex('l:1').subdivide([0.1,0.3,0.7,1.1]) Formex([[[0.1, 0. , 0. ], [ 0.3, 0. , 0. ]], <BLANKLINE> [[ 0.3, 0. , 0. ], [ 0.7, 0. , 0. ]], <BLANKLINE> [[ 0.7, 0. , 0. ], [ 1.1, 0. , 0. ]]])

intersectionWithPlane
(p, n, atol=0.0)[source]¶ Compute the intersection of a Formex with a plane.
Note
This is currently only available for plexitude 2 (lines) and 3 (triangles).
Parameters:  p (arraylike (3,)) – A point in the plane
 n (arraylike (3,)) – The normal vector on the plane.
 atol (float) – A tolerance value: points whose distance from the plane is less
than
atol
are considered to be lying in the plane.
Returns: Formex – A Formex of plexitude self.nplex()1 holding the intersection with the plane (p,n). For a plex2 Formex (lines), the returned Formex has plexitude 1 (points). For a plex3 Formex (triangles) the returned Formex has plexitude 2 (lines).
See also
cutWithPlane()
 return parts of Formex after cutting with a plane
Examples
>>> Formex('l:1212').intersectionWithPlane([0.5,0.,0.],[1.,1.,0.]) Formex([[[ 0.5, 0. , 0. ]], <BLANKLINE> [[ 1. , 0.5, 0. ]], <BLANKLINE> [[ 1.5, 1. , 0. ]], <BLANKLINE> [[ 2. , 1.5, 0. ]]]) >>> Formex('3:.12.34').intersectionWithPlane([0.5,0.,0.],[1.,0.,0.]) Formex([[[ 0.5, 0. , 0. ], [ 0.5, 0.5, 0. ]], <BLANKLINE> [[ 0.5, 0.5, 0. ], [ 0.5, 1. , 0. ]]])

cutWithPlane
(p, n, side='', atol=None, newprops=None)[source]¶ Cut a Formex with the plane (p,n).
Note
This is currently only available for plexitude 2 (lines) and 3 (triangles).
Parameters:  p (arraylike (3,)) – A point in the cutting plane.
 n (arraylike (3,)) – The normal vector to the cutting plane.
 side (str, one of '', '+' or '') – Specifies which side of the plane should be returned. If an empty string (default), both sides are returned. If ‘+’ or ‘‘, only the part at the positive, resp. negative side of the plane (as defined by its normal) is returned.
Returns:  Fpos (Formex) – Formex with the part of the Formex at the positive side of the plane. This part is not returned is side==’‘.
 Fneg (Formex) – Formex with the part of the Formex at the negative side of the plane. This part is not returned is side==’+’.
Notes
Elements of the input Formex that are lying completely on one side of the plane will return unaltered. Elements that are cut by the plane are split up into multiple parts.
See also
intersectionWithPlane()
 return intersection of Formex and plane

lengths
()[source]¶ Compute the length of all elements of a 2plex Formex.
The length of an element is the distance between its two points.
Returns: float array (self.nelem(),) – An array with the length of each element. Raises: ValueError
– If the Formex is not of plexitude 2.Examples
>>> Formex('l:127').lengths() array([ 1. , 1. , 1.41], dtype=float32)

areas
()[source]¶ Compute the areas of all elements of a 3plex Formex.
The area of an element is the area of the triangle formed by its three points.
Returns: float array (self.nelem(),) – An array with the area of each element. Raises: ValueError
– If the Formex is not of plexitude 3.Examples
>>> Formex('3:.12.34').areas() array([ 0.5, 0.5], dtype=float32)

volumes
()[source]¶ Compute the volume of all elements of a 4plex Formex.
The volume of an element is the volume of the tetraeder formed by its 4 points.
Returns: float array (self.nelem(),) – An array with the volume of each element. Raises: ValueError
– If the Formex is not of plexitude 4.Examples
>>> Formex('4:164I').volumes() array([ 0.17], dtype=float32)

classmethod
fromstring
(s, sep=' ', nplex=1, ndim=3, count=1)[source]¶ Create a
Formex
reading coordinates from a string.This uses the
Coords.fromstring()
method to read coordinates from a string and restructures them into a Formex of the specified plexitude.Parameters:  s (str) – A string containing a single sequence of float numbers separated by whitespace and a possible separator string.
 sep (str, optional) – The separator used between the coordinates. If not a space, all extra whitespace is ignored.
 nplex (int, optional) – Plexitude of the elements to be read.
 ndim (int, optional) – Number of coordinates per point. Should be 1, 2 or 3 (default). If 1, resp. 2, the coordinate string only holds x, resp. x,y values.
 count (int, optional) – Total number of coordinates to read. This should be a multiple of ndim. The default is to read all the coordinates in the string.
Returns: Formex – A Formex object of the given plexitude, with the coordinates read from the string.
Raises: ValueError
– If count was provided and the string does not contain that exact number of coordinates. If the number of points read is not a multiple of nplex.Examples
>>> Formex.fromstring('4 0 0 3 1 2 6 5 7',nplex=3) Formex([[[ 4., 0., 0.], [ 3., 1., 2.], [ 6., 5., 7.]]])

classmethod
fromfile
(fil, nplex=1, **kargs)[source]¶ Read the coordinates of a Formex from a file
This uses
Coords.fromfile()
to read coordinates from a file and create a Formex of the specified plexitude. Coordinates X, Y and Z for subsequent points are read from the file. The total number of coordinates on the file should be a multiple of 3.Parameters:  fil (str or file) – If str, it is a file name. An open file object can also be passed
 nplex (int, optional) – Plexitude of the elements to be read.
 **kargs – Arguments to be passed to
numpy.fromfile()
.
Returns: Formex – A Formex object of the given plexitude, with the coordinates read from the specified file.
Raises: ValueError
– If the number of coordinates read is not a multiple of 3 * nplex.See also
Coords.fromfile()
 read a Coords object from file
numpy.fromfile()
 read an array to file
 data (Formex, Coords, arraylike or string) – Data to initalize the coordinates attribute
2.1. Functions defined in module formex¶

formex.
connect
(Flist, nodid=None, bias=None, loop=False, eltype=None)[source]¶ Return a Formex which connects the Formices in list.
Creates a Formex of any plexitude by combining corresponding points from a number of Formices.
Parameters:  Flist (list of Formices) – The Formices to connect. The number of Formices in the list will be the plexitude of the newly created Formex. One point of an element in each Formex is taken to create a new element in the output Formex.
 nodid (list of int, optional) – List of point indices to be used from each of the input Formices.
If provided, the list should have the same length as
Flist
. The default is to use the first point of each element.  bias (list of int, optional) – List of element bias values for each of the input Formices. Element
iteration in the Formices will start at this number.
If provided,, the list should have the same length as
Flist
. The default is to start at element 0.  loop (bool) – If False (default), element generation will stop when the first input Formex runs out of elements. If True, element iteration in the shorted Formices will wrap around until all elements in all Formices have been used.
Returns: Formex – A Formex with plexitude equal to
len(Flist)
. Each element of the Formex consists of a point from the corresponding element of each of the Formices in list. By default this is the first point of that element, but anodid
list may specify another point index. Corresponding elements in the Formices are by default those with the same element index; thebias
argument may specify another value to start the element indexing for each of the input Formices.If loop is False (default), the number of elements is the minimum over all Formices of the number of elements minus the corresponding bias. If loop is True, the number of elements is the maximum of the number of elements of all input Formices.
Notes
See also example Connect.
Examples
>>> F = Formex('1:1111') >>> G = Formex('l:222') >>> connect([F,G]) Formex([[[ 1., 0., 0.], [ 0., 0., 0.]], <BLANKLINE> [[ 2., 0., 0.], [ 0., 1., 0.]], <BLANKLINE> [[ 3., 0., 0.], [ 0., 2., 0.]]]) >>> connect([F,G],nodid=[0,1]) Formex([[[ 1., 0., 0.], [ 0., 1., 0.]], <BLANKLINE> [[ 2., 0., 0.], [ 0., 2., 0.]], <BLANKLINE> [[ 3., 0., 0.], [ 0., 3., 0.]]]) >>> connect([F,F],bias=[0,1]) Formex([[[ 1., 0., 0.], [ 2., 0., 0.]], <BLANKLINE> [[ 2., 0., 0.], [ 3., 0., 0.]], <BLANKLINE> [[ 3., 0., 0.], [ 4., 0., 0.]]]) >>> connect([F,F],bias=[0,1],loop=True) Formex([[[ 1., 0., 0.], [ 2., 0., 0.]], <BLANKLINE> [[ 2., 0., 0.], [ 3., 0., 0.]], <BLANKLINE> [[ 3., 0., 0.], [ 4., 0., 0.]], <BLANKLINE> [[ 4., 0., 0.], [ 1., 0., 0.]]])