CSG

The basic operations of constructive solid geometry (CSG in short) are union, intersection, difference.

We have already seen how to make a compound object. Now we see the intersection and difference.

Intersection and difference

The difference of A and B is defined by amputed_by. The intersection is defined by intersected_by Note that the cutting shape marks the amputed object with its color.

In practice, A is cut by a copy of B, so that you can move A or B afterwards independently : the hole that you made will not move.

../../../../_images/difference.png
wall=Cube(2,2,2) # The two opposite corners of the cube are origin and point(1,2,3)
wall.color="Brown"
wall.move_at(origin+1.5*Z) # the cube is moved above the plane

cyl=Cylinder(start=origin,end=origin+5*Z,radius=0.5) # a vertical Cylinder
cyl.color='SpicyPink'

axis=Segment(point(0,0,0),point(0,0,1))
cyl2=ICylinder(axis,0.25) #an infinite cylinder of radius 0.5
cyl2.color='Yellow'

# Using amputations : corresponds to the yellow and pink marks
cyl.amputed_by(cyl2)
wall.amputed_by(cyl)

# Using intersection : corresponds to the black marks
axis.translate(3,0,0)
cyl3=ICylinder(axis,3.2)
axis.translate(-6,0,0)
cyl4=ICylinder(axis,3.5)
wall.intersected_by([cyl3,cyl4])
wall.rotate(Segment(origin,Z),.5)

camera=Camera()
camera.file="difference.pov"
camera.filmAllActors=True
#camera.actors=[yellowTorus]
camera.location=origin-4*X+5.2*Z
camera.zoom(0.4)
camera.lookAt=(origin+Z)
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.

In the above, we put

camera.filmAllActors=True

Nevertheless, the cylinders used to cut the cube do not appear. The reason is that the tool used to cut is declared invisible. This is usually what is wanted : we throw the tool away after the cut. If this not the case, replace as follows

# A.amputed_by(B) # Here, B is not seen
A.amputed_by(B,throwShapeAway=False) # Here, B is kept in the    image.

The intersection and difference is not recursive, ie. does not include the children. To intersect A with B and its children:

for tool in B.descendants_and_myself():
A.intersect(tool)