PropertyLink: InList and OutList

Other languages:

See Properties before this section.

PropertyLink

In addition to the scalar Properties of an feature, the features themselves contain pointers to one another. These pointers define a directed acyclic graph that determines the set and ordering of objects that are recomputed in response to a change in one object. Only those features that depend on a changed feature are recomputed.

The dependencies are expressed via a special class of Property types, namely the PropertyLink:

The following are similar properties for linking features of different documents. This is the core part for assemblies.

Example

Consider a class BoxDimension that provides basic dimensions for another class Box. We would like a Box object to be recomputed whenever its associated BoxDimension is changed:

import FreeCAD
import Part

class BoxDimension:
  def __init__(self, obj):
    obj.addProperty("App::PropertyLength", "Length").Length = 1
    obj.addProperty("App::PropertyLength", "Width").Width = 1
    obj.addProperty("App::PropertyLength", "Height").Height = 1
    obj.Proxy = self

class Box:
  def __init__(self, obj):
    obj.addProperty("App::PropertyLink", "Dimensions").Dimensions = None
    obj.Proxy = self
  def execute(self, obj):
    if obj.Dimensions is None:
      return
    l = obj.Dimensions.Length
    w = obj.Dimensions.Width
    h = obj.Dimensions.Height
    obj.Shape = Part.makeBox(l, w, h)

Note that it is a Box object that contains the PropertyLink to the BoxDimension object. Usage is as follows:

doc = App.newDocument()
dim = doc.addObject("App::FeaturePython", "BoxDimension")
box = doc.addObject("Part::FeaturePython", "Box")
dim_proxy = BoxDimension(dim)
box_proxy = Box(box)
box.ViewObject.Proxy = None
box.Dimensions = dim

dim.Length = 5
dim.Width = 3
dim.Height = 7
doc.recompute()

Because our box depends on the dim object, it will be recomputed.

InList and OutList

PropertyLink objects can be accessed using a Python property using the name that they are registered with using .addObject(). However there is another way. Every feature has a pair of lazily-generated lists called InList and OutList that describe the outgoing and incoming edges of the DAG, respectively:

Note that InList and OutList have nothing to do with the tree view of the document model that is presented in the GUI. At any time, a parent in that tree view may contain children that are part of the InList, the OutList, or neither.