# 10. `geometry` — A generic interface to the Coords transformation methods

This module defines a generic Geometry superclass which adds all the possibilities of coordinate transformations offered by the Coords class to the derived classes.

class `geometry.``Geometry`

  A generic geometry class allowing manipulation of large coordinate sets.

  The Geometry class is a generic parent class for all geometry classes. It is not intended to be used directly, but only through derived classes. Examples of derived classes are `Formex`, `Mesh` and its subclass `TriSurface`, `Curve`.

  The basic entity of geometry is the point, defined by its coordinates. The Geometry class expects these to be stored in a `Coords` object assigned to the `coords` attribute (it is the responsability of the derived class object initialisation to do this).

  The Geometry class exposes the following attributes of the `coords` attribute, so that they can be directly used on the Geometry object: `xyz`, `x`, `y`, `z`, `xy`, `yz`, `xz`.

  The Geometry class exposes a large set of Coords methods for direct used on the derived class objects. These methods are automatically executed on the `coords` attribute of the object. One set of such methods are those returning some information about the Coords: `points()`, `bbox()`, `center()`, `bboxPoint()`, `centroid()`, `sizes()`, `dsize()`, `bsphere()`, `bboxes()`, `inertia()`, `principalCS()`, `principalSizes()`, `distanceFromPlane()`, `distanceFromLine()`, `distanceFromPoint()`, `directionalSize()`, `directionalWidth()`, `directionalExtremes()`. Thus, if F is an instance of class `Formex`, then one can use `F.center()` as a convenient shorthand for `F.coords.center()`.

  Likewise, most of the transformation methods of the :class:~coords.Coords` class are exported through the Geometry class to the derived classes. When called, they will return a new object identical to the original, except for the coordinates, which are transformed by the specified method. Refer to the correponding `Coords` method for the precise arguments of these methods: `scale()`, `adjust()`, `translate()`, `centered()`, `align()`, `rotate()`, `shear()`, `reflect()`, `affine()`, `toCS()`, `fromCS()`, `transformCS()`, `position()`, `cylindrical()`, `hyperCylindrical()`, `toCylindrical()`, `spherical()`, `superSpherical()`, `toSpherical()`, `circulize()`, `bump()`, `flare()`, `map()`, `map1()`, `mapd()`, `copyAxes()`, `swapAxes()`, `rollAxes()`, `projectOnPlane()`, `projectOnSphere()`, `projectOnCylinder()`, `isopar()`, `addNoise()`, `rot()`, `trl()`.

  Geometry is a lot more than points however. Therefore the Geometry and its derived classes can represent higher level entities, such as lines, planes, circles, triangles, cubes,… These entities are often represented by multiple points: a line segment would e.g. need two points, a triangle three. Geometry subclasses can implement collections of many such entities, just like the `Coords` can hold many points. We call these geometric entities ‘elements’. The subclass must at least define a method `nelems()` returning the number of elements in the object, even if there is only one.

  The Geometry class allows the attribution of a property number per element. This is an integer number that can be used as the subclass or user wants. It could be just the element number, or a key into a database with lots of more element attributes. The Geometry class provides methods to handle these property numbers.

  The Geometry class provides a separate mechanism to store attributes related to how the geometry should be rendered. For this purpose the class defines an `attrib` attribute which is an object of class `Attributes`. This attribute is callable to set any key/value pairs in its dict. For example, `F.attrib(color=yellow)` will make the object F always be drawn in yellow.

  The Geometry class provides for adding fields to instances of the derived classes. Fields are numerical data (scalar or vectorial) that are defined over the geometry. For example, if the geometry represents a surface, the gaussian curvature of that surface is a field defined over the surface. Field data are stored in `Field` objects and the Geometry object stores them internally in a dict object with the field name as key. The dict is kept in an attribute `fields` that is only created when the first Field is added to the object.

  Finally, the Geometry class also provides the interface for storing the Geometry object on a file in pyFormex’s own ‘pgf’ format.

  Note

  When subclassing the Geometry class, care should be taken to obey some rules in order for all the above to work properly. See UserGuide.

  `coords`

    A Coords object that holds the coordinates of the points required to describe the type of geometry.

    Type: | `Coords`

  `prop`

    Element property numbers. This is a 1-dim int array with length `nelems()`. Each element of the Geometry can thus be assigned an integer value. It is up the the subclass to define if and how its instances are divided into elements, and how to use this element property number.

    Type: | int array

  `attrib`

    An Attributes object that is primarily used to define persisting drawing attributes (like color) for the Geometry object.

    Type: | `Attributes`

  `fields`

    A dict with the Fields defined on the object. This atribute only exists when at least one Field has been defined. See `addField()`.

    Type: | OrderedDict

  `xyz`

    Return the `xyz` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.xyz` for details.

  `x`

    Return the `x` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.x` for details.

  `y`

    Return the `y` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.y` for details.

  `z`

    Return the `z` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.z` for details.

  `xy`

    Return the `xy` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.xy` for details.

  `yz`

    Return the `yz` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.yz` for details.

  `xz`

    Return the `xz` property of the `coords` attribute of the Geometry object.

    See `coords.Coords.xz` for details.

  `nelems`()

    Return the number of elements in the Geometry.

    Returns: | int – The number of elements in the Geometry. This is an abstract method that should be reimplemented by the derived class.

  `level`()

    Return the dimensionality of the Geometry

    The level of a `Geometry` is the dimensionality of the geometric object(s) represented:

    - 0: points
    - 1: line objects
    - 2: surface objects
    - 3: volume objects

    Returns: | int – The level of the Geometry, or -1 if it is unknown. This should be implemented by the derived class. The Geometry base class always returns -1.

  `info`()

    Return a short string representation about the object

  `points`(*args, **kargs)

    Call `points()` method on the `coords` attribute of the Geometry object.

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

  `bbox`(*args, **kargs)

    Call `bbox()` method on the `coords` attribute of the Geometry object.

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

  `center`(*args, **kargs)

    Call `center()` method on the `coords` attribute of the Geometry object.

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

  `bboxPoint`(*args, **kargs)

    Call `bboxPoint()` method on the `coords` attribute of the Geometry object.

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

  `centroid`(*args, **kargs)

    Call `centroid()` method on the `coords` attribute of the Geometry object.

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

  `sizes`(*args, **kargs)

    Call `sizes()` method on the `coords` attribute of the Geometry object.

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

  `dsize`(*args, **kargs)

    Call `dsize()` method on the `coords` attribute of the Geometry object.

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

  `bsphere`(*args, **kargs)

    Call `bsphere()` method on the `coords` attribute of the Geometry object.

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

  `bboxes`(*args, **kargs)

    Call `bboxes()` method on the `coords` attribute of the Geometry object.

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

  `inertia`(*args, **kargs)

    Call `inertia()` method on the `coords` attribute of the Geometry object.

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

  `principalCS`(*args, **kargs)

    Call `principalCS()` method on the `coords` attribute of the Geometry object.

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

  `principalSizes`(*args, **kargs)

    Call `principalSizes()` method on the `coords` attribute of the Geometry object.

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

  `distanceFromPlane`(*args, **kargs)

    Call `distanceFromPlane()` method on the `coords` attribute of the Geometry object.

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

  `distanceFromLine`(*args, **kargs)

    Call `distanceFromLine()` method on the `coords` attribute of the Geometry object.

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

  `distanceFromPoint`(*args, **kargs)

    Call `distanceFromPoint()` method on the `coords` attribute of the Geometry object.

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

  `directionalSize`(*args, **kargs)

    Call `directionalSize()` method on the `coords` attribute of the Geometry object.

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

  `directionalWidth`(*args, **kargs)

    Call `directionalWidth()` method on the `coords` attribute of the Geometry object.

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

  `directionalExtremes`(*args, **kargs)

    Call `directionalExtremes()` method on the `coords` attribute of the Geometry object.

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

  `convexHull`(dir=None, return_mesh=True)

    Return the convex hull of a Geometry.

    This is the `convexHull()` applied to the `coords` attribute, but it has `return_mesh=True` as default.

    Returns: | Mesh – The convex hull of the geometry.

  `testBbox`(bb, dirs=(0, 1, 2), nodes='any', atol=0.0)

    Test which part of a Formex or Mesh is inside a given bbox.

    The Geometry object needs to have a `test()` method, This is the case for the `Formex` and `Mesh` classes. The test can be applied in 1, 2 or 3 viewing directions.

    Parameters: | bb (Coords (2,3) or alike) – The bounding box to test for. dirs (tuple of ints (0,1,2)) – The viewing directions in which to check the bbox bounds. nodes – Same as in `formex.Formex.test()` or `mesh.Mesh.test()`.
    Returns: | bool array – The array flags the elements that are inside the given bounding box.

  `scale`(*args, **kargs)

    Apply the `scale` transformation to the Geometry object.

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

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

    Return a copy of the Geometry scaled to the given size.

    size can be a single value or a list of three values for the three coordinate directions. If it is a single value, all directions are scaled to the same size. Directions for which the geometry has a size smaller than tol times the maximum size are not rescaled.

  `adjust`(*args, **kargs)

    Apply the `adjust` transformation to the Geometry object.

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

  `translate`(*args, **kargs)

    Apply the `translate` transformation to the Geometry object.

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

  `centered`(*args, **kargs)

    Apply the `centered` transformation to the Geometry object.

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

  `align`(*args, **kargs)

    Apply the `align` transformation to the Geometry object.

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

  `rotate`(*args, **kargs)

    Apply the `rotate` transformation to the Geometry object.

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

  `shear`(*args, **kargs)

    Apply the `shear` transformation to the Geometry object.

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

  `reflect`(*args, **kargs)

    Apply the `reflect` transformation to the Geometry object.

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

  `affine`(*args, **kargs)

    Apply the `affine` transformation to the Geometry object.

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

  `toCS`(*args, **kargs)

    Apply the `toCS` transformation to the Geometry object.

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

  `fromCS`(*args, **kargs)

    Apply the `fromCS` transformation to the Geometry object.

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

  `transformCS`(*args, **kargs)

    Apply the `transformCS` transformation to the Geometry object.

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

  `position`(*args, **kargs)

    Apply the `position` transformation to the Geometry object.

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

  `cylindrical`(*args, **kargs)

    Apply the `cylindrical` transformation to the Geometry object.

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

  `hyperCylindrical`(*args, **kargs)

    Apply the `hyperCylindrical` transformation to the Geometry object.

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

  `toCylindrical`(*args, **kargs)

    Apply the `toCylindrical` transformation to the Geometry object.

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

  `spherical`(*args, **kargs)

    Apply the `spherical` transformation to the Geometry object.

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

  `superSpherical`(*args, **kargs)

    Apply the `superSpherical` transformation to the Geometry object.

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

  `toSpherical`(*args, **kargs)

    Apply the `toSpherical` transformation to the Geometry object.

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

  `circulize`(*args, **kargs)

    Apply the `circulize` transformation to the Geometry object.

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

  `bump`(*args, **kargs)

    Apply the `bump` transformation to the Geometry object.

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

  `flare`(*args, **kargs)

    Apply the `flare` transformation to the Geometry object.

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

  `map`(*args, **kargs)

    Apply the `map` transformation to the Geometry object.

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

  `map1`(*args, **kargs)

    Apply the `map1` transformation to the Geometry object.

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

  `mapd`(*args, **kargs)

    Apply the `mapd` transformation to the Geometry object.

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

  `copyAxes`(*args, **kargs)

    Apply the `copyAxes` transformation to the Geometry object.

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

  `swapAxes`(*args, **kargs)

    Apply the `swapAxes` transformation to the Geometry object.

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

  `rollAxes`(*args, **kargs)

    Apply the `rollAxes` transformation to the Geometry object.

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

  `projectOnPlane`(*args, **kargs)

    Apply the `projectOnPlane` transformation to the Geometry object.

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

  `projectOnSphere`(*args, **kargs)

    Apply the `projectOnSphere` transformation to the Geometry object.

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

  `projectOnCylinder`(*args, **kargs)

    Apply the `projectOnCylinder` transformation to the Geometry object.

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

  `isopar`(*args, **kargs)

    Apply the `isopar` transformation to the Geometry object.

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

  `addNoise`(*args, **kargs)

    Apply the `addNoise` transformation to the Geometry object.

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

  `rot`(*args, **kargs)

    Apply the `rotate` transformation to the Geometry object.

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

  `trl`(*args, **kargs)

    Apply the `translate` transformation to the Geometry object.

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

  `setProp`(prop=None)

    Create or destroy the property array for the Geometry.

    A property array is a 1-dim integer array with length equal to the number of elements in the Geometry. Each element thus has its own property number. These numbers can be used for any purpose. In derived classes like `Formex` and :class`~mesh.Mesh` they play an import role when creating new geometry: new elements inherit the property number of their parent element. Properties are also preserved on pure coordinate transformations.

    Because elements with different property numbers can be drawn in different colors, the property numbers are also often used to impose color.

    Parameters: | prop (int, int array-like or 'range') – The property number(s) to assign to the elements. If a single int, all elements get the same property value. If the number of passed values is less than the number of elements, the list will be repeated. If more values are passed than the number of elements, the excess ones are ignored. A special value `'range'` may be given to set the property numbers equal to the element number. This is equivalent to passing `arange(self.nelems())`. A value None (default) removes the properties from the Geometry.
    Returns: | The calling object `self`, with the new properties inserted or with the properties deleted if argument is None.

    Note

    This is one of the few operations that change the object in-place. It still returns the object itself, so that this operation can be used in a chain with other operations.

    See also

    `toProp()`
      Create a valid set of properties for the object
    `whereProp()`
      Find the elements having some property value
  `toProp`(prop)

    Create a valid set of properties for the object.

    Parameters: | prop (int or int array-like) – The property values to turn into a valid set for the object. If a single int, all elements get the same property value. If the number of passed values is less than the number of elements, the list will be repeated. If more values are passed than the number of elements, the excess ones are ignored.
    Returns: | int array – A 1-dim int array that is valid as a property array for the Geometry object. The length of the array will is `self.nelems()` and the dtype is `Int`.

    See also

    `setProp()`
      Set the properties for the object
    `whereProp()`
      Find the elements having some property value

    Note

    When you set the properties (using `setProp()`) you do not need to call this method to validate the properties. It is implicitely called from `setProp()`.

  `maxProp`()

    Return the highest property value used.

    Returns: | int – The highest value used in the properties array, or -1 if there are no properties.

  `propSet`()

    Return a list with unique property values in use.

    Returns: | int array – The unique values in the properties array. If no properties are defined, an empty array is returned.

  `whereProp`(prop)

    Find the elements having some property value.

    Parameters: | prop (int or int array-like) – The property value(s) to be found.
    Returns: | int array – A 1-dim int array with the indices of all the elements that have the property value `prop`, or one of the values in `prop`. If the object has no properties, an empty array is returned.

    See also

    `setProp()`
      Set the properties for the object
    `toProp()`
      Create a valid set of properties for the object
    `selectProp()`
      Return a Geometry object with only the matching elements
  `copy`()

    Return a deep copy of the Geometry object.

    Returns: | Geometry (or subclass) object – An object of the same class as the caller, having all the same data (for `coords`, `prop`, `attrib`, `fields`, and any other attributes possibly set by the subclass), but not sharing any data with the original object.

    Note

    This is seldomly used, because it may cause wildly superfluous copying of data. Only used it if you absolutely require data that are independent of those of the caller.

  `select`(**_kargs)

    Select some element(s) from a Geometry.

    Parameters: | sel (index-like) – The index of element(s) to be selected. This can be anything that can be used as an index in an array: a single element number a list, or array, of element numbers a bool list, or array, of length self.nelems(), where True values flag the elements to be selected compact (bool, optional) – This option is only useful for subclasses that have a `compact` method, such as `mesh.Mesh` and its subclasses. If True, the returned object will be compacted, i.e. unused nodes are removed and the nodes are renumbered from zero. If False (default), the node set and numbers are returned unchanged.
    Returns: | Geometry (or subclass) object – An object of the same class as the caller, but only containing the selected elements.

    See also

    `cselect()`
      Return all but the selected elements.
    `clip()`
      Like select, but with compact=True as default.
  `cselect`(**_kargs)

    Return the Geometry with the selected elements removed.

    Parameters: | sel (index-like) – The index of element(s) to be selected. This can be anything that can be used as an index in an array: a single element number a list, or array, of element numbers a bool list, or array, of length self.nelems(), where True values flag the elements to be selected compact (bool, optional) – This option is only useful for subclasses that have a `compact` method, such as `mesh.Mesh` and its subclasses. If True, the returned object will be compacted, i.e. unused nodes are removed and the nodes are renumbered from zero. If False (default), the node set and numbers are returned unchanged.
    Returns: | Geometry (or subclass) object – An object of the same class as the caller, but containing all but the selected elements.

    See also

    `select()`
      Return a Geometry with only the selected elements.
    `cclip()`
      Like cselect, but with compact=True as default.
  `clip`(**_kargs)

    Return a Geometry only containing the selected elements.

    This is equivalent with `select()` but having `compact=True` as default.

    See also

    `select()`
      Return a Geometry with only the selected elements.
    `cclip()`
      The complement of clip, returning all but the selected elements.
  `cclip`(**_kargs)

    Return a Geometry with the selected elements removed.

    This is equivalent with `select()` but having `compact=True` as default.

    See also

    `cselect()`
      Return a Geometry with only the selected elements.
    `clip()`
      The complement of cclip, returning only the selected elements.
  `selectProp`(prop, compact=False)

    Select elements by their property value.

    Parameters: | prop (int or int array-like) – The property value(s) for which the elements should be selected.
    Returns: | Geometry (or subclass) object – An object of the same class as the caller, but only containing the elements that have a property value equal to `prop`, or one of the values in `prop`. If the input object has no properties, a copy containing all elements is returned.

    See also

    `cselectProp()`
      Return all but the elements with property `prop`.
    `whereProp()`
      Get the numbers of the elements having a specified property.
    `select()`
      Select the elements with the specified indices.
  `cselectProp`(prop, compact=False)

    Return an object without the elements with property val.

    Parameters: | prop (int or int array-like) – The property value(s) of the elements that should be left out.
    Returns: | Geometry (or subclass) object – An object of the same class as the caller, with all but the elements that have a property value equal to `prop`, or one of the values in `prop`. If the input object has no properties, a copy containing all elements is returned.

    See also

    `selectProp()`
      Return only the elements with property `prop`.
    `whereProp()`
      Get the numbers of the elements having a specified property.
    `cselect()`
      Remove elements by their index.
  `splitProp`(prop=None, compact=True)

    Partition a Geometry according to the values in prop.

    Parameters: | prop (int array-like, optional) – A 1-dim int array with length `self.nelems()` to be used in place of the objects own `prop` attribute. If None (default), the latter will be used.
    Returns: | `List` of Geometry objects – A list of objects of the same class as the caller. Each object in the list contains all the elements having the same value of prop. The number of objects in the list is equal to the number of unique values in prop. The list is sorted in ascending order of the prop value. If prop is None and the the object has no prop attribute, an empty list is returned.

  `fields`

    Return the Fields dict of the Geometry.

    If the Geometry has no Fields, an empty dict is returned.

  `addField`(fldtype, data, fldname)

    Add `Field` data to the `Geometry`.

    Field data are scalar or vectorial data defined over the Geometry. This convenience function creates a `Field` object with the specified data and adds it to the Geometry object’s `fields` dict.

    Parameters: | fldtype (str) – The field type. See `Field` for details. data (array-like) – The field data. See `Field` for details. fldname (str) – The field name. See `Field` for details. This name is also used as key to store the Field in the `fields` dict.
    Returns: | `Field` – The constructed and stored Field object.

    Note

    Whenever a Geometry object is exported to a PGF file, all Fields stored inside the Geometry object are included in the PGF file.

    See also

    `getField()`
      Retrieve a Field by its name.
    `delField()`
      Deleted a Field.
    `convertField()`
      Convert the Field to another Field type.
    `fieldReport()`
      Return a short report of the stored Fields
  `getField`(fldname)

    Get the data field with the specified name.

    Parameters: | fldname (str) – The name of the Field to retrieve.
    Returns: | `Field` – The data field with the specified name, if it exists in the Geometry object’s `fields`. Returns None if no such key exists.

  `delField`(fldname)

    Delete the Field with the specified name.

    Parameters: | fldname (str) – The name of the Field to delete from the Geometry object. A nonexisting name is silently ignored.
    Returns: | None

  `convertField`(fldname, totype, toname)

    Convert the data field with the specified name to another type.

    Parameters: | fldname (str) – The name of the data Field to convert to another type. A nonexisting name is silently ignored. totype (str) – The field type to convert to. See `Field` for details. toname (str) – The name of the new (converted) Field (and key to store it). If the same name is specified as the old Field, that one will be overwritten by the new. Otherwise, both will be kept in the Geometry object’s `fields` dict.
    Returns: | `Field` – The converted and stored data field. Returns None if the original data field does not exist.

  `fieldReport`()

    Return a short report of the stored fields

    Returns: | str – A multiline string with the stored Fields’ attributes: name, type, dtype and shape.

  `write`(filename, sep=' ', mode='w', **kargs)

    Write a Geometry to a PGF file.

    This writes the Geometry to a pyFormex Geometry File (PGF) with the specified name.

    It is a convenient shorthand for:

        writeGeomFile(filename, self, sep=sep, mode=mode, **kargs)

    See `writeGeomFile()` for details.

  classmethod `read`(filename)

    Read a Geometry from a PGF file.

    This reads a single object (the object) from a PGF file and returns it.

    It is a convenient shorthand for:

        next(readGeomFile(filename, 1).values())

    See `readGeomFile()` for details.