Inheritance diagram of woo.triangulated
woo.triangulated.box(dim, center, which=Vector6i(1, 1, 1, 1, 1, 1), **kw)[source]

Return box created from facets. **kw args are passed to woo.dem.Facet.make. If facets have thickness, node masses and inertia will be computed automatically.

  • dim (Vector3) – dimensions along x, y, z axes;
  • center – a Vector3 (box aligned with global axes) or woo.core.Node (local coordinate system) giving the center of the box;
  • which (Vector6i) – select walls which are to be included (all by default); the order is -x, -y, -z, +x, +y, +z. Thuus, e.g., to make box without top, say which=(1,1,1,1,1,0).
woo.triangulated.cylinder(A, B, radius, div=20, axDiv=1, capA=False, capB=False, masks=None, wallCaps=False, angVel=0, realRot=False, fixed=True, **kw)[source]

Return triangulated cylinder, as list of facets to be passed to woo.dem.ParticleContainer.append. **kw arguments are passed to woo.pack.gtsSurface2Facets (and thus to woo.utils.facet).

  • angVel – axial angular velocity of the cylinder
  • realRot – if true, impose StableCircularOrbit on all cylinder nodes; if false, only assign woo.dem.Facet.fakeVel is assigned. In both cases, angVel is set on cap walls (with wallCaps).
  • axDiv – divide the triangulation axially as well; the default creates facets spanning between both bases. If negative, it will attempt to have that ratio with circumferential division, e.g. specifying -1 will give nearly-square division.
  • wallCaps – create caps as walls (with woo.dem.wall.glAB properly set) rather than triangulation; cylinder axis must be aligned with some global axis in this case, otherwise and error is raised.
  • masks – mask values for cylinder, capA and capB respectively; it must be either None or a 3-tuple (regardless of whether caps are created or not); **kw can be used to specify mask which is passed to woo.dem.Facet.make, but masks will override this, if given.

List of particles building up the cylinder. Caps (if any) are always at the beginning of the list, triangulated perimeter is at the end.

woo.triangulated.quadrilateral(A, B, C, D, size=0, div=Vector2i(0, 0), **kw)[source]

Return triangulated quadrilateral (or a skew quadrilateral), when points are not co-planar), where division size is at most size (absolute length) or div (number of subdivisions in the AB–CD and AC–BD directions).

woo.triangulated.ribbedMill(A, B, radius, majNum, majHt, majTipAngle, minNum=0, minHt=0, minTipAngle=0, div=20, **kw)[source]
  • majNum – number of major ribs (parallel with rotation axis)
  • majHt – height of major ribs
  • majTipAngle – angle on the major rib tip
  • minNum – number of minor ribs (around the cylinder, in plane perpendicular to the rotation axis)
  • minHt – height of minor ribs
  • minTipAngle – angle on the minor rib tip

tuple [particles],centralNode, which can be directly used in S.dem.par.addClumped(*woo.triangulated.ribbedMill(...)). centralNode is local coordinate system positioned in A and of which \(x\)-axis is rotation axis of the mill. Assigning dem.angVel=centralNode.ori*(0,0,w) will make the mill rotate around the axis with the angular velocity w. centralNode has automatically ClumpData assigned, with blocked equal to ``xyzXYZ`.

woo.triangulated.sweep2d(pts, zz, node=None, fakeVel=0.0, halfThick=0.0, shift=True, shorten=False, **kw)[source]

Build surface by perpendicularly sweeping list of 2d points along the 3rd axis (in global/local coordinates).

  • pts – list of Vector2 containing \(xy\) coordinates of points in local axes. If the point is (nan,nan) or None, the line is split at this point. If the point contains (nan,i), then it refers to i-th point which has been constructed up to now: positive number from the beginning of the line, negative from the end.
  • zz – tuple or Vector2 containing (z0,z1) coordinates for all points.
  • node – optional instance of woo.core.Node defining local coordinate system; if not given, global coordinates are used.
  • fakeVel (float) – assign fakeVel to facets, in the sweeping direction at every face
  • halfThick – if given and halfThick is True, shift points so that pts give points of the outer surface (and nodes are shifted inwards); in this case, the ordering of pts is important.
  • shift – activate point shifting, in conjunction with halfThick;
  • shorten – move endpoints away from the endpoint (along the segment) by halfThick;
class woo.triangulated.MeshImport(**kw)[source]

User interface for importing meshes from external files , so that all import parameters are kept together. Currently supported formats are:

  • STL: both ascii and binary formats; tagged not supported (meaningless)
  • nastran: subset, GRID and CTRIA3 tags are recognized, others ignored; tagged is supported, nodal numbers are preserved.


file(= '')

Mesh file to be imported (STL)

[type: str, existing filename]

preScale(= 1.0)

Scaling, applied before other transformations.

[type: float]

node(= None)

Node defining local coordinate system for importing (already prescaled) mesh; if not given, global coordinate system is assumed.

[type: Node]

halfThick(= 0.0)

Half thickness (woo.dem.Facet.halfThick) assigned to all created facets. If zero, don’t assign halfThick.

[type: float, unit: m, preferred unit: mm]

fakeVel(= Vector3(0, 0, 0))

Fake surface velocity set (as-is) on all imported facets; if (0,0,0) (default), nothing is set.

[type: Vector3, unit: m/s]

tessMaxBox(= 0.0)

Some importers (STL) can tesselated triangles so that their bounding box dimension does not exceed tessMaxBox. If non-positive, no tesselation will be done.

[type: float, unit: m, preferred unit: mm]

tagged(= False)

Use woo.dem.DemDataTagged to keep information about node number at input; this is only supported for some formats, and exception will be raise if used with format not supporting it }e.g. STL does not store vertices)

[type: bool]


The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

doImport(mat, mask=11, **kw)[source]

Do the actual import. Nastern: **kw is passed to woo.dem.Facet.make. STL: some values from **kw used (color) and passed to woo.utils.importSTL.



This module is imported into the woo.triangulated module automatically; refer to its objects through woo.triangulated.

woo._triangulated.facetsToSTL((str)stl, (DemField)dem, (str)solid[, (int)mask=0[, (bool)append=False]]) → int :

Export facets to STL file. Periodic boundaries are not handled in any special way.

woo._triangulated.porosity((DemField)dem, (AlignedBox3)box) → list :

Return list of (id,position,porosity), where porosity is computed as 1-Vs/Vv, where Vs is particle volume (sphere, capsule, ellipsoid only) and Vv is cell volume using radical Voronoi tesselation around particles. Highly experimental and subject to further changes.

woo._triangulated.spheroidsToSTL((str)stl, (DemField)dem, (float)tol[, (str)solid='woo_export'[, (int)mask=0[, (bool)append=False[, (bool)cellClip=False[, (bool)merge=False]]]]]) → int :

Export spheroids (spheres, capsules, ellipsoids) to STL file. tol is the maximum distance between triangulation and smooth surface; if negative, it is relative to the smallest equivalent radius of particles for export. mask (if non-zero) only selects particles with matching woo.dem.Particle.mask. The exported STL ist ASCII.

Spheres and ellipsoids are exported as tesselated icosahedra, with tesselation level determined from tol. The maximum error is \(e=r\left(1-\cos \frac{2\pi}{5}\frac{1}{2}\frac{1}{n}\right)\) for given tesselation level \(n\) (1 for icosahedron, each level quadruples the number of triangles), with \(r\) being the sphere’s radius (or ellipsoid’s smallest semiAxis); it follows that \(n=\frac{\pi}{5\arccos\left(1-\frac{e}{r}\right)}\), where \(n\) will be rounded up.

Capsules are triangulated in polar coordinates (slices, stacks). The error for regular \(n\)-gon is \(e=r\left(1-\cos\frac{2\pi}{2n}\right)\) and it follows that \(n=\frac{\pi}{\arccos\left(1-\frac{e}{r}\right)}\); the minimum is restricted to be 4, to avoid degenerate shapes.

The number of facets written to the STL file is returned.

With periodic boundaries, clipCell will cause all triangles entirely outside of the periodic cell to be discarded.

solid specified name of solid inside the STL file; this is useful in conjunction with append (which writes at the end of the file) when writing multi-part STL suitable e.g. for snappyHexMesh.

merge will attempt to remove any inner surfaces so that only the external surface is output. Note that this might take considerable time for many particles.

woo._triangulated.surfParticleIdNormals((DemField)dem, (AlignedBox3)box, (float)r) → dict :

Return map of ID->[normal,normal,…] of normals of cell faces belonging to particle #ID which have no neighbors. [EXPERIMENTAL].


Got questions? Ask at ask.woodem.org. Report issues to github.