Boolean difference or union not working python

Hi folks!
I have a python file with classes and a certain point I’m createing the model() method that takes care of the modeling in grasshopper. It’s a very simple representation of an apartment with a balcony.
After some tries, i find out that he indented block which starts with

if self.balcony == “Half-inpandig Balkon”:

should be the problem.
I tried a lot but didn’t find a solution.
Can you please help me with it?
The problems lays in the Boolean difference or union: I’m pretty sure about it. Thanks in advance!

def model(self):
    apartment = rs.AddBox([(0, 0, 0), (self.width(), 0, 0), (self.width(), self.depth(), 0), (0, self.depth(), 0),
        (0, 0, FLOOR_HEIGHT), (self.width(), 0, FLOOR_HEIGHT), (self.width(), self.depth(), FLOOR_HEIGHT), (0, self.depth(), FLOOR_HEIGHT)])
    # balcony measurements - CAUTION! for now I'm using dummy numbers.. in the future I'm going to extract it from a database
    b_width = 2
    b_depth = 1.5
    b_height = 1.1
    b_thickness = 0.1
    offset = 0.2
    # balcony modeling
    b_box_1 = rs.AddBox([(0, 0, 0), (0, -b_depth, 0), (b_width, -b_depth, 0), (b_width, 0, 0),
        (0, 0, b_height), (0, -b_depth, b_height), (b_width, -b_depth, b_height), (b_width, 0, b_height)])
    b_box_2 = rs.AddBox([(b_thickness, b_thickness, b_thickness), (b_thickness, b_thickness-b_depth, b_thickness), (b_width-b_thickness, b_thickness-b_depth, b_thickness), (b_width-b_thickness, b_thickness, b_thickness),
        (b_thickness, b_thickness, b_thickness+b_height), (b_thickness, b_thickness-b_depth, b_thickness+b_height), (b_width-b_thickness, b_thickness-b_depth, b_thickness+b_height), (b_width-b_thickness, b_thickness, b_thickness+b_height)])
    b_final = rs.BooleanDifference(b_box_1, b_box_2)
    balcony = rs.MoveObject(b_final, (offset, 0, 0))
    # volume to subtract for half-inpanding balkon
    # 3.2 because it's bigger than FLOOR HEIGHT
    # b_depth/2 because the volume to cut has to be in the center of the apartment
    volume = rs.AddBox([(offset, 0, -0.1), (b_width + offset, 0, -0.1), (b_width + offset, b_depth/2, -0.1), (offset, b_depth/2, -0.1),
        (offset, 0, 3.2), (b_width + offset, 0, 3.2), (b_width + offset, b_depth/2, 3.2), (offset, b_depth/2, 3.2)])
    # rules for apartment models - the model i outputted with the links entrance on the north side
    if self.floor_n == 1:
        final_b = None
        if self.function == "Wonen":
            if self.balcony == "Half-inpandig Balkon":
                if self.position == "Hoek":
                    volume_m = rs.MoveObject(rs.RotateObject(volume, (0, 0, 0), -90), (0, self.depth(), 0))
                else:
                    volume_m = volume
                final_a = rs.BooleanDifference(apartment, volume_m)
            else:
                final_a = apartment
        else:
            final_a = apartment
    elif self.floor_n >= self.n_floors - 1 and self.position == "Setback Hoek":
        if str(self.unit) == "2.7":
            t_width = 2.09
        else:
            t_width = 2.0
        t_height = 1.5
        t_offset = 0.34
        terras_box_1 = rs.AddBox([(0, 0, 0), (t_width, 0, 0), (t_width, self.depth(), 0), (0, self.depth(), 0),
            (0, 0, t_height), (t_width, 0, t_height), (t_width, self.depth(), t_height), (0, self.depth(), t_height)])
        terras_box_2 = rs.CopyObject(terras_box_1, (t_offset, t_offset, t_offset))
        final_b = rs.BooleanDifference(terras_box_1, terras_box_2)
        final_a = rs.MoveObject(apartment, (t_width, 0, 0))
    else:
        if self.balcony == "Half-inpandig Balkon":
            if self.position == "Hoek":
                volume_m = rs.MoveObject(rs.RotateObject(volume, (0, 0, 0), -90), (0, self.depth(), 0))
                final_b = rs.MoveObject(rs.RotateObject(balcony, (0, 0, 0), -90), (b_depth/2, self.depth(), 0))
            else:
                volume_m = volume
                final_b = rs.MoveObject(balcony, (0, b_depth/2, 0))
            final_a = rs.BooleanDifference(apartment, volume_m)
        elif self.balcony == "Uitpandig Balkon":
            if self.position == "Hoek":
                if self.balcony_pos == 1:
                    final_b = rs.MoveObject(rs.RotateObject(balcony, (0, 0, 0), -90), (0, self.depth(), 0))
                elif self.balcony_pos == 2:
                    final_b = rs.MoveObject(rs.RotateObject(balcony, (0, 0, 0), -90), (0, 2*(b_width+offset), 0))
                else:
                    final_b = balcony
            else:
                final_b = balcony
            final_a = apartment
        else:
            final_a = apartment
            final_b = None
    return rs.BooleanUnion([final_a, final_b]) if final_b is not None else final_a

Can you post the full definition so we can play around with it? Much easier that way than trying to figure it out purely from a code excerpt.

Hi @Matt_Harwood! Thanks for your reply!
Unfortunately I can’t share the full definition and it’s way too long (ca 1200 lines) but I find the issue: Boolean Difference and Union return a list. Sometimes I need to add [0] after, sometimes it works without. It’s not crystal clear for me yet. Do you know more about it?

The problem lies with these two lines, since Boolean Difference returns a list, you will need final_a[0] to access the first item, however these final_a and final_b are a single item so it doesn’t require [0] to access.
if you change them all to:

final_a = [apartment]
final_b = [balcony]

you will then be able to use [0] for them all.

1 Like