mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-11 02:02:22 +00:00
See #5972. You can now add half space solid items in item mode.
This commit is contained in:
@@ -22,6 +22,7 @@ from bpy.app.handlers import persistent
|
||||
|
||||
classes = (
|
||||
operator.AddCurvelikeItem,
|
||||
operator.AddHalfSpaceSolidItem,
|
||||
operator.AddMeshlikeItem,
|
||||
operator.AddRepresentation,
|
||||
operator.AddSweptAreaSolidItem,
|
||||
|
||||
@@ -57,6 +57,8 @@ class ItemDecorator:
|
||||
verts = []
|
||||
edges = []
|
||||
tris = []
|
||||
special_verts = []
|
||||
special_edges = []
|
||||
|
||||
if len(obj.data.loop_triangles) > 0:
|
||||
verts = [tuple(obj.matrix_world @ v.co) for v in obj.data.vertices]
|
||||
@@ -81,7 +83,26 @@ class ItemDecorator:
|
||||
]
|
||||
edges = bbox_edges
|
||||
verts.extend(bbox_verts)
|
||||
return {"verts": verts, "edges": edges, "tris": tris}
|
||||
|
||||
if "HalfSpaceSolid" in obj.name:
|
||||
# Arrow shape
|
||||
special_verts = [
|
||||
tuple(obj.matrix_world @ Vector((0, 0, 0))),
|
||||
tuple(obj.matrix_world @ Vector((0, 0, 0.5))),
|
||||
tuple(obj.matrix_world @ Vector((0.05, 0, 0.45))),
|
||||
tuple(obj.matrix_world @ Vector((-0.05, 0, 0.45))),
|
||||
tuple(obj.matrix_world @ Vector((0, 0.05, 0.45))),
|
||||
tuple(obj.matrix_world @ Vector((0, -0.05, 0.45))),
|
||||
]
|
||||
special_edges = [(0, 1), (1, 2), (1, 3), (1, 4), (1, 5)]
|
||||
|
||||
return {
|
||||
"verts": verts,
|
||||
"edges": edges,
|
||||
"tris": tris,
|
||||
"special_verts": special_verts,
|
||||
"special_edges": special_edges,
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def uninstall(cls):
|
||||
@@ -157,11 +178,14 @@ class ItemDecorator:
|
||||
continue
|
||||
self.draw_batch("LINES", data["verts"], selected_elements_color, data["edges"])
|
||||
self.draw_batch("TRIS", data["verts"], transparent_color(selected_elements_color), data["tris"])
|
||||
self.draw_batch("LINES", data["special_verts"], selected_elements_color, data["special_edges"])
|
||||
elif self.obj_is_boolean[obj_name]:
|
||||
self.draw_batch("LINES", data["verts"], special_elements_color, data["edges"])
|
||||
self.draw_batch("TRIS", data["verts"], transparent_color(special_elements_color), data["tris"])
|
||||
self.draw_batch("LINES", data["special_verts"], special_elements_color, data["special_edges"])
|
||||
else:
|
||||
self.draw_batch(
|
||||
"LINES", data["verts"], transparent_color(unselected_elements_color, alpha=0.2), data["edges"]
|
||||
)
|
||||
self.draw_batch("TRIS", data["verts"], transparent_color(special_elements_color), data["tris"])
|
||||
self.draw_batch("LINES", data["special_verts"], special_elements_color, data["special_edges"])
|
||||
|
||||
@@ -2933,6 +2933,64 @@ class AddCurvelikeItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
tool.Geometry.import_item_attributes(obj)
|
||||
|
||||
|
||||
class AddHalfSpaceSolidItem(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_idname = "bim.add_half_space_solid_item"
|
||||
bl_label = "Add Half Space Solid Item"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
if (
|
||||
not tool.Blender.get_selected_objects()
|
||||
or not (active_obj := tool.Blender.get_active_object())
|
||||
or not tool.Geometry.is_representation_item(active_obj)
|
||||
):
|
||||
# In theory we can have half space solid as a top level item but let's not go there today.
|
||||
self.report({"ERROR"}, "Select an item to apply the half space solid to.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
props = context.scene.BIMGeometryProperties
|
||||
mesh = bpy.data.meshes.new("Tmp")
|
||||
obj = bpy.data.objects.new("Tmp", mesh)
|
||||
scene = bpy.context.scene
|
||||
scene.collection.objects.link(obj)
|
||||
bpy.context.view_layer.objects.active = obj
|
||||
obj.select_set(True)
|
||||
new = props.item_objs.add()
|
||||
new.obj = obj
|
||||
|
||||
matrix = props.representation_obj.matrix_world.copy()
|
||||
matrix.translation = context.scene.cursor.location
|
||||
local_matrix = props.representation_obj.matrix_world.inverted() @ matrix
|
||||
|
||||
obj.show_in_front = True
|
||||
obj.matrix_world = matrix
|
||||
tool.Geometry.record_object_position(obj)
|
||||
|
||||
ifc_file = tool.Ifc.get()
|
||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(ifc_file)
|
||||
local_z = ifc_file.createIfcDirection((0.0, 0.0, 1.0))
|
||||
local_x = ifc_file.createIfcDirection((1.0, 0.0, 0.0))
|
||||
point = ifc_file.createIfcCartesianPoint((np.array(local_matrix.translation) / unit_scale).tolist())
|
||||
placement = ifc_file.createIfcAxis2Placement3D(point, local_z, local_x)
|
||||
plane = ifc_file.createIfcPlane(placement)
|
||||
item = ifc_file.createIfcHalfSpaceSolid(plane, AgreementFlag=False)
|
||||
|
||||
representation = tool.Geometry.get_active_representation(props.representation_obj)
|
||||
representation = ifcopenshell.util.representation.resolve_representation(representation)
|
||||
|
||||
representation.Items = list(representation.Items) + [item]
|
||||
tool.Geometry.reload_representation(bpy.context.scene.BIMGeometryProperties.representation_obj)
|
||||
|
||||
obj.name = obj.data.name = f"Item/{item.is_a()}/{item.id()}"
|
||||
obj.data.BIMMeshProperties.ifc_definition_id = item.id()
|
||||
tool.Geometry.import_item(obj)
|
||||
|
||||
# TODO refactor to core and not rely on selection
|
||||
tool.Blender.select_and_activate_single_object(context, active_obj)
|
||||
tool.Blender.select_object(obj)
|
||||
bpy.ops.bim.add_boolean()
|
||||
|
||||
|
||||
class OverrideMoveAggregateMacro(bpy.types.Macro):
|
||||
bl_idname = "bim.override_move_aggregate_macro"
|
||||
bl_label = "IFC Move Aggregate"
|
||||
|
||||
@@ -309,6 +309,8 @@ class BIM_MT_add_representation_item(Menu):
|
||||
"ICOSPHERE"
|
||||
)
|
||||
self.layout.operator("bim.add_meshlike_item", icon="MESH_CYLINDER", text="Mesh Cylinder").shape = "CYLINDER"
|
||||
self.layout.separator()
|
||||
self.layout.operator("bim.add_half_space_solid_item", icon="ORIENTATION_NORMAL", text="Half Space Solid")
|
||||
|
||||
if ItemData.data["representation_type"] in ("SolidModel", "SweptSolid"):
|
||||
self.layout.operator(
|
||||
@@ -317,6 +319,8 @@ class BIM_MT_add_representation_item(Menu):
|
||||
self.layout.operator(
|
||||
"bim.add_swept_area_solid_item", icon="MESH_CYLINDER", text="Extruded Area Solid Cylinder"
|
||||
).shape = "CYLINDER"
|
||||
self.layout.separator()
|
||||
self.layout.operator("bim.add_half_space_solid_item", icon="ORIENTATION_NORMAL", text="Half Space Solid")
|
||||
|
||||
if ItemData.data["representation_type"] in ("Annotation2D"):
|
||||
self.layout.operator("bim.add_curvelike_item", icon="IPO_CONSTANT", text="Polycurve").shape = "LINE"
|
||||
|
||||
Reference in New Issue
Block a user