mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 22:50:04 +00:00
Generate space from walls refactor and cleaning around
This commit is contained in:
@@ -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]),
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user