mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 01:47:55 +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 = (
|
classes = (
|
||||||
operator.AddCurvelikeItem,
|
operator.AddCurvelikeItem,
|
||||||
|
operator.AddHalfSpaceSolidItem,
|
||||||
operator.AddMeshlikeItem,
|
operator.AddMeshlikeItem,
|
||||||
operator.AddRepresentation,
|
operator.AddRepresentation,
|
||||||
operator.AddSweptAreaSolidItem,
|
operator.AddSweptAreaSolidItem,
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ class ItemDecorator:
|
|||||||
verts = []
|
verts = []
|
||||||
edges = []
|
edges = []
|
||||||
tris = []
|
tris = []
|
||||||
|
special_verts = []
|
||||||
|
special_edges = []
|
||||||
|
|
||||||
if len(obj.data.loop_triangles) > 0:
|
if len(obj.data.loop_triangles) > 0:
|
||||||
verts = [tuple(obj.matrix_world @ v.co) for v in obj.data.vertices]
|
verts = [tuple(obj.matrix_world @ v.co) for v in obj.data.vertices]
|
||||||
@@ -81,7 +83,26 @@ class ItemDecorator:
|
|||||||
]
|
]
|
||||||
edges = bbox_edges
|
edges = bbox_edges
|
||||||
verts.extend(bbox_verts)
|
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
|
@classmethod
|
||||||
def uninstall(cls):
|
def uninstall(cls):
|
||||||
@@ -157,11 +178,14 @@ class ItemDecorator:
|
|||||||
continue
|
continue
|
||||||
self.draw_batch("LINES", data["verts"], selected_elements_color, data["edges"])
|
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("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]:
|
elif self.obj_is_boolean[obj_name]:
|
||||||
self.draw_batch("LINES", data["verts"], special_elements_color, data["edges"])
|
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("TRIS", data["verts"], transparent_color(special_elements_color), data["tris"])
|
||||||
|
self.draw_batch("LINES", data["special_verts"], special_elements_color, data["special_edges"])
|
||||||
else:
|
else:
|
||||||
self.draw_batch(
|
self.draw_batch(
|
||||||
"LINES", data["verts"], transparent_color(unselected_elements_color, alpha=0.2), data["edges"]
|
"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("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)
|
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):
|
class OverrideMoveAggregateMacro(bpy.types.Macro):
|
||||||
bl_idname = "bim.override_move_aggregate_macro"
|
bl_idname = "bim.override_move_aggregate_macro"
|
||||||
bl_label = "IFC Move Aggregate"
|
bl_label = "IFC Move Aggregate"
|
||||||
|
|||||||
@@ -309,6 +309,8 @@ class BIM_MT_add_representation_item(Menu):
|
|||||||
"ICOSPHERE"
|
"ICOSPHERE"
|
||||||
)
|
)
|
||||||
self.layout.operator("bim.add_meshlike_item", icon="MESH_CYLINDER", text="Mesh Cylinder").shape = "CYLINDER"
|
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"):
|
if ItemData.data["representation_type"] in ("SolidModel", "SweptSolid"):
|
||||||
self.layout.operator(
|
self.layout.operator(
|
||||||
@@ -317,6 +319,8 @@ class BIM_MT_add_representation_item(Menu):
|
|||||||
self.layout.operator(
|
self.layout.operator(
|
||||||
"bim.add_swept_area_solid_item", icon="MESH_CYLINDER", text="Extruded Area Solid Cylinder"
|
"bim.add_swept_area_solid_item", icon="MESH_CYLINDER", text="Extruded Area Solid Cylinder"
|
||||||
).shape = "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"):
|
if ItemData.data["representation_type"] in ("Annotation2D"):
|
||||||
self.layout.operator("bim.add_curvelike_item", icon="IPO_CONSTANT", text="Polycurve").shape = "LINE"
|
self.layout.operator("bim.add_curvelike_item", icon="IPO_CONSTANT", text="Polycurve").shape = "LINE"
|
||||||
|
|||||||
Reference in New Issue
Block a user