Genealogy and Compounds

There are two ways to make objects attached one to an other: a genealogy relationship parent/childre or a compound aggregate. In this note, we shall learn the basics of the two notions and compare them.

Genealogy

We recall our Rubik’s cube construction.

../../../../_images/rubik.png
 # a plane with normal the vector Z=vector(0,0,1)
ground=plane(Z,origin) .colored('Gray' )
basket=point(0,0,0)
cub=Cube(.91,.91,.91)
for a in range(3):
    for b in range(3):
        for c in range(3):
             d=cub.copy()
             d.color=" rgb <"+",".join([str(c),str(b),str(a)])+">"
             d.move_at(point(a,b,c+0.5))
             d.glued_on(basket)
# we copy the basket. The elements glued on it are also copied
#recursivly
basket2=basket.copy()
basket2.rotate(Segment(origin,origin+X+Y+Z),3.14/3)
basket2.translate(6*X+Z).glued_on(ground)
camera=Camera()
camera.file="rubik.pov"
camera.location=origin-10*Y+4*Z
camera.filmAllActors=False
camera.actors=[ground,basket,basket2] # what is seen by the camera wiht the children
camera.lookAt=.5*(basket2+basket)
camera.lookAt=basket2
camera.zoom(.12512)
camera.shoot # takes the photo, ie. creates the povray file, and stores it in camera.file
camera.show # show the photo, ie calls povray.

Thus we see that the declaration

d.glued_on(basket)

made d a child of basket. An object may have many children but only one parent. When the parent moves, the child follows (and recursivly, the grand child follows if it exists, and so on...) In our Rubik’s cube situation, we have moved the basket, and the 27 cubes followed because they were glued on the basket, they are children.

However, when the children move, the parent stays fixed. Thus this is an asymetric relation.

Cameras and the genealogy system

Remark that the line camera.actors does not mention the 27 small cubes : only the basket. Since they are children of the basket, they are seen by the camera. If any, the camera will include automatically the children, the children of the children... in the photo.

Finally, remark that when an object is copied, all its children are copied too (and recursivly, the children of the children... )

Compounds

The parent/children realtion is asymetric. The Compound notion brings object together in aymmetric way. It is called as

Compound (slavesList=[o1,o2,...])

Each entry of slavesList is

  • an object in World with no genealogy
  • or a sublist [name,objectInworld], where name is a string.

In the second case, the subobject will be accessible with self.name

Here is an example where we access to the cylinder subpart to move from the plane Z=0 to the plane Z=-1. Moreover, we see that the color applied to the compound overwrites the colors of the components ( the individual colors of the components remain if we don’t overwrite).

../../../../_images/union.png
g=plane(Z,origin-Z).colored("Grey")
c=Cube(1,1,1).colored("Red")
d=Cube(2,2,2)
d.move_at(3,3,0).colored("Yellow")
e=Cylinder(start=origin,end=origin+3*X,radius=0.1)
o=Compound([c,d,["cylinder",e]]).colored("Green")
o.cylinder.translate(-Z)

camera=Camera()
camera.file="union.pov"
camera.filmAllActors=True
camera.zoom(0.4)
camera.lookAt=e.center
camera.povraylights="light_source {<-2,0,6.8> color White " + "}\n\n"
camera.shoot # takes the photo, ie. creates the povray file, and stores it in camera.file
camera.show # show the photo, ie calls povray.

Genealogy versus Compound

When a compound is moved, all the objects in the slavesList are moved simultaneously, thus this is symmetric. Moreover, a color on the compound is affected to each object, thus the compound really behaves like a unique object. In particular, when you intersect with a compound, you intersect with all objects in the compound.

A compound is is a less granular notion than a genealogy relationship. If you often use subcomponents ( to intersect for instance. or for coloring), it is more convenient with parent/children. If you often use, the whole object, a compound is preferable. For small projects, using only parent/children gives quick access to the objects. For large projects, the notation compound1.subcompoundname.componentName avoids a collision of the names of the objects. This is in particular very useful to build libraries since the names of the parts of the objects imported from different libraries will not collide.

Technically, there are conditions to use the notions of genealogy and compound simultaneaously A compound is a union of elements without genealogy. It is not allowed that you declare elements in the slaves list to have children or parents, otherwise moving the objects may give unpredictable results. The compound itself may have children and a genealogy, in which case moving the compound implies a move of its children. Similarly, the compound may be glued on an other object. It is only the components of the compound which cannot be included in a genealogy..