Hi everyone,
I am using ifc openshell to create an IFC model from custom geometry data.
Everything works fine but one error occasionally appears randomly.
The two buildings are created in exactly the same manner but the placement of the one roof appears to be the other way round and it's hard to debug it. Does someone maybe know why?
Or what also might help: Would it be possible to set the top elevation of the element in the code using ifc openshell?
That's the only thing that is different from the two roofs when I open the model in BIM collab.
My code for making the roofs:
def make_roof(ifcfile, owner_history, context, storey, roof, index, height, roofThickness=0.001, z_pos=0.0):
roof_curve = roof['data']['roofCurves'][index]
rel_pts = roof['data']['options']['relativePts'][index]
rel_pts = convert_points(rel_pts)
inclination = roof['data']['options']['inclinations'][index]
x_dir = roof['data']['options']['xDirs'][index]
x_vec = mathutils.Vector((x_dir['data']['x'], x_dir['data']['y'], x_dir['data']['z']))
z_rot = calculate_rotation_angle(mathutils.Vector((1.0, 0.0, 0.0)), x_vec)
roof_placement = hf.create_ifclocalplacement(ifcfile, point=(0.,0.,0.))
polyline = hf.create_ifcpolyline(ifcfile, rel_pts)
axis_representation = ifcfile.createIfcShapeRepresentation(context, "Axis", "Curve2D", [polyline])
rotation_matrix = Matrix.Rotation(np.radians(90 - inclination), 4, 'X')
rotated_vector = rotation_matrix @ mathutils.Vector((0, 1, 0))
extrusion_dir = (float(rotated_vector[0]), float(rotated_vector[1]), float(rotated_vector[2]))
height = height * (-1)
height = height * (-1)
extrusion_placement = hf.create_ifcaxis2placement(ifcfile, (0.0, 0.0, float(height + z_pos)), (0., 0., 1.0), (1., 0., 0.))
solid = hf.create_ifcextrudedareasolid(ifcfile, rel_pts, extrusion_placement, extrusion_dir, -roofThickness)
body_representation = ifcfile.createIfcShapeRepresentation(context, "Body", "SweptSolid", [solid])
product_shape = ifcfile.createIfcProductDefinitionShape(None, None, [axis_representation, body_representation])
roof_element = ifcfile.createIfcSlab(hf.create_guid(), owner_history, "Slab", "Roof", None, roof_placement, product_shape, None)
ifcopenshell.api.run("spatial.assign_container", ifcfile, relating_structure=storey, product=roof_element)
# Rotation matrix around the X axis
matrixRotX = np.eye(4)
matrixRotX[1][1] = np.cos(inclination * np.pi / 180)
matrixRotX[1][2] = -np.sin(inclination * np.pi / 180)
matrixRotX[2][1] = np.sin(inclination * np.pi / 180)
matrixRotX[2][2] = np.cos(inclination * np.pi / 180)
# Rotation matrix around the Z axis
matrixRotZ = np.eye(4)
matrixRotZ[0][0] = np.cos(z_rot * np.pi / 180)
matrixRotZ[0][1] = -np.sin(z_rot * np.pi / 180)
matrixRotZ[1][0] = np.sin(z_rot * np.pi / 180)
matrixRotZ[1][1] = np.cos(z_rot * np.pi / 180)
roof_pt0 = convert_points(roof['data']['pts'], two_d=False)[0]
roof_curve_pt0 = convert_points(roof_curve['data']['pts'], two_d=False)[0]
z = roof_curve_pt0[2] - roof_pt0[2]
vec1 = mathutils.Vector((0.0, 0.0, 0.0))
roof_pt0 = convert_points(roof_curve['data']['pts'], two_d=False)[0]
# vec2 = mathutils.Vector((roof_pt0[0], roof_pt0[1], height))
vec2 = mathutils.Vector((roof_pt0[0], roof_pt0[1], z))
# Translation matrix
matrixTransl = np.eye(4)
matrixTransl[0][3] = vec2[0] - vec1[0]
matrixTransl[1][3] = vec2[1] - vec1[1]
matrixTransl[2][3] = vec2[2] - vec1[2]
matrix_combined = np.matmul(np.matmul(matrixTransl, matrixRotZ), matrixRotX)
ifcopenshell.api.run("geometry.edit_object_placement",
ifcfile, product=roof_element, matrix=matrix_combined
)
Thank you in advance!