mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Add AddWallsFromSlab operator.
This operator allows users to create walls from a slab. When the wall tool is active, pressing `Shift + A` will generate walls based on the exterior polygon of the selected slab.
This commit is contained in:
@@ -69,6 +69,7 @@ classes = (
|
||||
wall.ChangeExtrusionDepth,
|
||||
wall.ChangeExtrusionXAngle,
|
||||
wall.ChangeLayerLength,
|
||||
wall.AddWallsFromSlab,
|
||||
wall.DrawPolylineWall,
|
||||
wall.FlipWall,
|
||||
wall.MergeWall,
|
||||
|
||||
@@ -280,6 +280,39 @@ class ChangeLayerLength(bpy.types.Operator, tool.Ifc.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class AddWallsFromSlab(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.draw_walls_from_slab"
|
||||
bl_label = "Draw Slab From Wall"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.space_data.type == "VIEW_3D"
|
||||
|
||||
def __init__(self):
|
||||
self.relating_type = None
|
||||
props = bpy.context.scene.BIMModelProperties
|
||||
relating_type_id = props.relating_type_id
|
||||
if relating_type_id:
|
||||
self.relating_type = tool.Ifc.get().by_id(int(relating_type_id))
|
||||
|
||||
def _execute(self, context):
|
||||
if not self.relating_type:
|
||||
return {"FINISHED"}
|
||||
slab = tool.Ifc.get_entity(context.active_object)
|
||||
if not slab.is_a("IfcSlab"):
|
||||
self.report(
|
||||
{"WARNING"},
|
||||
"Please select a slab.",
|
||||
)
|
||||
return {"FINISHED"}
|
||||
walls = DumbWallGenerator(self.relating_type).generate("SLAB")
|
||||
|
||||
if walls:
|
||||
for wall1, wall2 in zip(walls, walls[1:] + [walls[0]]):
|
||||
DumbWallJoiner().join_V(wall2["obj"], wall1["obj"])
|
||||
|
||||
|
||||
class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
||||
bl_idname = "bim.draw_polyline_wall"
|
||||
bl_label = "Draw Polyline Wall"
|
||||
@@ -305,7 +338,7 @@ class DrawPolylineWall(bpy.types.Operator, PolylineOperator):
|
||||
direction_sense = model_props.direction_sense
|
||||
offset = model_props.offset
|
||||
|
||||
walls, is_polyline_closed = DumbWallGenerator(self.relating_type).generate(True)
|
||||
walls, is_polyline_closed = DumbWallGenerator(self.relating_type).generate("POLYLINE")
|
||||
for wall in walls:
|
||||
model = IfcStore.get_file()
|
||||
element = tool.Ifc.get_entity(wall["obj"])
|
||||
@@ -515,7 +548,7 @@ class DumbWallGenerator:
|
||||
self.relating_type = relating_type
|
||||
self.unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
|
||||
def generate(self, draw_from_polyline=False):
|
||||
def generate(self, insertion_type="CURSOR"):
|
||||
self.file = IfcStore.get_file()
|
||||
self.layers = tool.Model.get_material_layer_parameters(self.relating_type)
|
||||
if not self.layers["thickness"]:
|
||||
@@ -539,9 +572,11 @@ class DumbWallGenerator:
|
||||
self.location = Vector((0, 0, 0))
|
||||
self.x_angle = 0 if tool.Cad.is_x(props.x_angle, 0, tolerance=0.001) else props.x_angle
|
||||
|
||||
if draw_from_polyline:
|
||||
if insertion_type == "POLYLINE":
|
||||
return self.derive_from_polyline()
|
||||
else:
|
||||
elif insertion_type == "SLAB":
|
||||
return self.derive_from_slab()
|
||||
elif insertion_type == "CURSOR":
|
||||
return self.derive_from_cursor()
|
||||
|
||||
def has_sketch(self):
|
||||
@@ -570,6 +605,26 @@ class DumbWallGenerator:
|
||||
walls.append(self.create_wall_from_2_points(coords))
|
||||
return walls, is_polyline_closed
|
||||
|
||||
def derive_from_slab(self):
|
||||
slab_obj = bpy.context.active_object
|
||||
slab = tool.Ifc.get_entity(slab_obj)
|
||||
container = ifcopenshell.util.element.get_container(slab)
|
||||
self.container_obj = tool.Ifc.get_object(container)
|
||||
elevation = self.container_obj.location.z
|
||||
representation = ifcopenshell.util.representation.get_representation(slab, "Model", "Body", "MODEL_VIEW")
|
||||
extrusion = tool.Model.get_extrusion(representation)
|
||||
polyline_points = extrusion.SweptArea.OuterCurve.Points.CoordList
|
||||
polyline_points = [[(v * self.unit_scale) for v in p] for p in polyline_points]
|
||||
polyline_points = [slab_obj.matrix_world @ Vector((p[0], p[1], elevation)) for p in polyline_points]
|
||||
is_polyline_closed = True
|
||||
walls = []
|
||||
for i in range(len(polyline_points) - 1):
|
||||
vec1 = polyline_points[i]
|
||||
vec2 = polyline_points[i+1]
|
||||
coords = (vec1, vec2)
|
||||
walls.append(self.create_wall_from_2_points(coords))
|
||||
return walls
|
||||
|
||||
def derive_from_sketch(self):
|
||||
objs = []
|
||||
strokes = []
|
||||
|
||||
@@ -963,6 +963,7 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if bpy.context.scene.BIMGeometryProperties.mode == "ITEM":
|
||||
bpy.ops.wm.call_menu(name="BIM_MT_add_representation_item")
|
||||
else:
|
||||
# Slab from walls
|
||||
walls = False
|
||||
for obj in bpy.context.selected_objects:
|
||||
walls = tool.Ifc.get_entity(obj).is_a("IfcWall")
|
||||
@@ -973,6 +974,16 @@ class Hotkey(bpy.types.Operator, tool.Ifc.Operator):
|
||||
):
|
||||
bpy.ops.bim.draw_slab_from_wall("INVOKE_DEFAULT")
|
||||
return {"FINISHED"}
|
||||
# Walls from slab
|
||||
slab = tool.Ifc.get_entity(bpy.context.active_object)
|
||||
if (
|
||||
slab
|
||||
and slab.is_a("IfcSlab")
|
||||
and relating_type_id
|
||||
and tool.Model.get_usage_type(tool.Ifc.get().by_id(int(relating_type_id))) == "LAYER2"
|
||||
):
|
||||
bpy.ops.bim.draw_walls_from_slab("INVOKE_DEFAULT")
|
||||
return {"FINISHED"}
|
||||
|
||||
for obj in tool.Blender.get_selected_objects():
|
||||
obj.select_set(False)
|
||||
|
||||
Reference in New Issue
Block a user