Generate space from walls refactor and cleaning around

This commit is contained in:
Massimo Fabbro
2023-04-24 15:52:50 +02:00
parent 08a6fe5748
commit 98d96fdd7c
@@ -194,8 +194,8 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
# In order to run, the active objct must be a wall and # In order to run, the active objct must be a wall and
# have to be selected walls # have to be selected walls
props = context.scene.BIMModelProperties props = context.scene.BIMModelProperties
active_obj = bpy.context.active_object active_obj = bpy.context.active_object
if not active_obj: if not active_obj:
self.report({'ERROR'}, "No active object. Please select a wall") self.report({'ERROR'}, "No active object. Please select a wall")
return return
@@ -224,13 +224,47 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
x, y, z = active_obj.matrix_world.translation.xyz x, y, z = active_obj.matrix_world.translation.xyz
mat = active_obj.matrix_world mat = active_obj.matrix_world
h = active_obj.dimensions.z h = active_obj.dimensions.z
selected_objects = bpy.context.selected_objects
boundary_elements = self.get_boundary_elements(selected_objects)
polys = self.get_polygons(boundary_elements)
converted_tolerance = self.get_converted_tolerance(tolerance = 0.03)
union = shapely.ops.unary_union(polys).buffer(converted_tolerance, cap_style = 2, join_style = 2)
i=0
for linear_ring in union.interiors:
poly = Polygon(linear_ring)
poly = poly.buffer(converted_tolerance, single_sided=True, cap_style = 2, join_style = 2)
bm = self.get_bmesh_from_polygon(poly, mat, h)
name = "Space" + str(i)
mesh = bpy.data.meshes.new(name = name)
bm.to_mesh(mesh)
bm.free()
obj = bpy.data.objects.new(name, mesh)
obj.matrix_world = mat
collection.objects.link(obj)
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSpace")
i+=1
return {"FINISHED"}
def get_boundary_elements(self, selected_objects):
boundary_elements = [] boundary_elements = []
for obj in bpy.context.selected_objects: for obj in selected_objects:
subelement = tool.Ifc.get_entity(obj) subelement = tool.Ifc.get_entity(obj)
if subelement.is_a("IfcWall"): if subelement.is_a("IfcWall"):
boundary_elements.append(subelement) boundary_elements.append(subelement)
return boundary_elements
def get_polygons(self, boundary_elements):
polys = [] polys = []
for boundary_element in boundary_elements: for boundary_element in boundary_elements:
obj = tool.Ifc.get_object(boundary_element) obj = tool.Ifc.get_object(boundary_element)
@@ -243,14 +277,23 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
points.append(point) points.append(point)
polys.append(Polygon(points)) polys.append(Polygon(points))
return polys
def get_obj_base_points(self, obj):
x_values = [(obj.matrix_world @ Vector(v)).x for v in obj.bound_box]
y_values = [(obj.matrix_world @ Vector(v)).y for v in obj.bound_box]
return {
"low_left": (x_values[0], y_values[0]),
"high_left": (x_values[3], y_values[3]),
"low_right": (x_values[4], y_values[4]),
"high_right": (x_values[7], y_values[7]),
}
def get_converted_tolerance(self, tolerance):
model = tool.Ifc.get() model = tool.Ifc.get()
project_unit = ifcopenshell.util.unit.get_project_unit(model, "LENGTHUNIT") project_unit = ifcopenshell.util.unit.get_project_unit(model, "LENGTHUNIT")
prefix=getattr(project_unit, "Prefix", None) prefix=getattr(project_unit, "Prefix", None)
tolerance = 0.03
converted_tolerance = ifcopenshell.util.unit.convert( converted_tolerance = ifcopenshell.util.unit.convert(
value = tolerance, value = tolerance,
from_prefix = None, from_prefix = None,
@@ -258,16 +301,9 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
to_prefix = prefix, to_prefix = prefix,
to_unit = project_unit.Name, to_unit = project_unit.Name,
) )
return tolerance
def get_bmesh_from_polygon(self, poly, mat, h):
union = shapely.ops.unary_union(polys).buffer(converted_tolerance, cap_style = 2, join_style = 2)
i=0
for linear_ring in union.interiors:
poly = Polygon(linear_ring)
poly = poly.buffer(converted_tolerance, single_sided=True, cap_style = 2, join_style = 2)
bm = bmesh.new() bm = bmesh.new()
bm.verts.index_update() bm.verts.index_update()
bm.edges.index_update() bm.edges.index_update()
@@ -291,29 +327,4 @@ class GenerateSpacesFromWalls(bpy.types.Operator, tool.Ifc.Operator):
bmesh.ops.recalc_face_normals(bm, faces = bm.faces) bmesh.ops.recalc_face_normals(bm, faces = bm.faces)
name = "Space" + str(i) return bm
mesh = bpy.data.meshes.new(name = name)
bm.to_mesh(mesh)
bm.free()
obj = bpy.data.objects.new(name, mesh)
obj.matrix_world = mat
collection.objects.link(obj)
bpy.ops.bim.assign_class(obj=obj.name, ifc_class="IfcSpace")
i+=1
return {"FINISHED"}
def get_obj_base_points(self, obj):
x_values = [(obj.matrix_world @ Vector(v)).x for v in obj.bound_box]
y_values = [(obj.matrix_world @ Vector(v)).y for v in obj.bound_box]
return {
"low_left": (x_values[0], y_values[0]),
"high_left": (x_values[3], y_values[3]),
"low_right": (x_values[4], y_values[4]),
"high_right": (x_values[7], y_values[7]),
}