Skip to content

Programming documentation

DeepSOIC edited this page Jan 29, 2016 · 6 revisions

How are arrays of placements stored

Arrays of placements have shape, and the actual array is stored inside the shape.

The array's shape is a compound of shapes. The kind of shapes does not matter, but they must not be another compound (because Lattice automatically traverses nesting when reading out the placements).

Placements are stored to and extracted from compound children's Placement attributes. That is, to create a shape to be read out by Lattice:

  1. Prepare the shapes
  2. Set shapes' Placement properties
  3. Part.makeCompound(shapes)

It was tested, that as of OCC 6.7.1, shells and solids don't lose placements even after saving-restoring a file. Vertexes, however, do lose placements.

This leads to constraints on the type of marker shapes that can be used. Marker can be any single thing: a line, an edge, a wire, a face, a shell, a solid, or a compsolid (and not Vertex, because those lose placements, and not compounds, because they will be scanned inside).

To obtain the array of placements given a shape, do this:

import lattice2BaseFeature
list_of_placements = lattice2BaseFeature.getPlacementsList(shape)

Identifying Lattice Array objects

Lattice workbench recognizes arrays of placements by testing for property 'isLattice' of the document object. If the string value read out from that property contains "On", it is considered to be an array of placements. If the property is absent, or returned string does not contain "On", the object is recognized as a generic shape by Lattice.

This identification way provides easy compatibility between Lattice v1 and Lattice v2, and (hopefully) easy compatibility from other workbenches, without even having to import Lattice2.

import Lattice2

The whole Lattice2 workbench can be imported by import Lattice2. This is not particularly useful at the moment, because Lattice2 doesn't run on GUI-less FreeCAD (although that might be changed - drop me a message if you are interested in that).

Lattice doesn't expose a rich API, because it is mostly a collection of features, most having relatively simple code. Nevertheless, there are a few modules that might come in handy, for example:

  • lattice2GeomUtils.py contains a routine to construct FreeCAD.Rotation by aligning axed to directions supplied as vectors. This is used extensively inside Lattice itself.
  • lattice2CompoundExplorer.py has an iterator object for recursively traversing nested compounds.
  • lattice2InterpolatorUtil.py is a hack around Part.BSplineCurve, that allows to BSpline-interpolate an f(x)-style functions. It is used by Resample feature.

Brief guide to creating your own Lattice feature

It is assumed that you are interested in creating a feature that can output an array of placements.

It is a good idea to derive your feature from LatticeBaseFeature (declared in lattice2BaseFeature.py). It provides quite a bit of functionality out of the box, such as the ability to select markers, exposing the placement as Placement property, etc.

It is important to not override some of the methods of LatticeBaseFeature. If you do, the basic functionality of LatticeBaseFeature will be broken, and the whole point of deriving from it will be gone. The methods to NOT override are:

  • instead of __init__, define derivedInit.
  • instead of execute, define derivedExecute. derivedExecute can return the list of placements (which will automatically switch 'isLattice' to 'On' if it is in auto mode), or None (which will switch the feature to become generic shape).
  • if you override onChanged, make sure to call the original onChanged (otherwise, automatic coloring of arrays will stop working)

All these rules apply to document object's proxy. As for ViewProvider, LatticeBaseFeature currently provides almost no special functionality, so it can be replaced completely.

Clone this wiki locally