mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-29 16:22:53 +00:00
You can now add type instances, and mapped representations are enforced.
This commit is contained in:
@@ -7,6 +7,7 @@ classes = (
|
|||||||
operator.EnableEditingType,
|
operator.EnableEditingType,
|
||||||
operator.DisableEditingType,
|
operator.DisableEditingType,
|
||||||
operator.SelectSimilarType,
|
operator.SelectSimilarType,
|
||||||
|
operator.AddTypeInstance,
|
||||||
prop.BIMTypeProperties,
|
prop.BIMTypeProperties,
|
||||||
ui.BIM_PT_type,
|
ui.BIM_PT_type,
|
||||||
)
|
)
|
||||||
@@ -14,7 +15,9 @@ classes = (
|
|||||||
|
|
||||||
def register():
|
def register():
|
||||||
bpy.types.Object.BIMTypeProperties = bpy.props.PointerProperty(type=prop.BIMTypeProperties)
|
bpy.types.Object.BIMTypeProperties = bpy.props.PointerProperty(type=prop.BIMTypeProperties)
|
||||||
|
bpy.types.VIEW3D_MT_mesh_add.append(ui.add_object_button)
|
||||||
|
|
||||||
|
|
||||||
def unregister():
|
def unregister():
|
||||||
del bpy.types.Object.BIMTypeProperties
|
del bpy.types.Object.BIMTypeProperties
|
||||||
|
bpy.types.VIEW3D_MT_mesh_add.remove(ui.add_object_button)
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
import bpy
|
import bpy
|
||||||
import ifcopenshell.util.schema
|
import ifcopenshell.util.schema
|
||||||
|
import ifcopenshell.util.type
|
||||||
import blenderbim.bim.module.type.assign_type as assign_type
|
import blenderbim.bim.module.type.assign_type as assign_type
|
||||||
import blenderbim.bim.module.type.unassign_type as unassign_type
|
import blenderbim.bim.module.type.unassign_type as unassign_type
|
||||||
import blenderbim.bim.module.type.get_related_objects as get_related_objects
|
import blenderbim.bim.module.type.get_related_objects as get_related_objects
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from blenderbim.bim.module.type.data import Data
|
from blenderbim.bim.module.type.data import Data
|
||||||
|
from blenderbim.bim.module.type.prop import getIfcTypes, getAvailableTypes, updateTypeInstanceIfcClass
|
||||||
|
from mathutils import Vector
|
||||||
|
|
||||||
|
|
||||||
class AssignType(bpy.types.Operator):
|
class AssignType(bpy.types.Operator):
|
||||||
@@ -12,7 +15,6 @@ class AssignType(bpy.types.Operator):
|
|||||||
bl_label = "Assign Type"
|
bl_label = "Assign Type"
|
||||||
relating_type: bpy.props.IntProperty()
|
relating_type: bpy.props.IntProperty()
|
||||||
related_object: bpy.props.StringProperty()
|
related_object: bpy.props.StringProperty()
|
||||||
should_map_representations: bpy.props.BoolProperty()
|
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
self.file = IfcStore.get_file()
|
||||||
@@ -29,7 +31,7 @@ class AssignType(bpy.types.Operator):
|
|||||||
).execute()
|
).execute()
|
||||||
Data.load(oprops.ifc_definition_id)
|
Data.load(oprops.ifc_definition_id)
|
||||||
|
|
||||||
if self.should_map_representations:
|
if self.file.by_id(relating_type).RepresentationMaps:
|
||||||
bpy.ops.bim.map_representations(product_id=oprops.ifc_definition_id, type_product_id=relating_type)
|
bpy.ops.bim.map_representations(product_id=oprops.ifc_definition_id, type_product_id=relating_type)
|
||||||
|
|
||||||
bpy.ops.bim.disable_editing_type(obj=related_object.name)
|
bpy.ops.bim.disable_editing_type(obj=related_object.name)
|
||||||
@@ -98,3 +100,47 @@ class SelectSimilarType(bpy.types.Operator):
|
|||||||
if obj.BIMObjectProperties.ifc_definition_id in related_objects:
|
if obj.BIMObjectProperties.ifc_definition_id in related_objects:
|
||||||
obj.select_set(True)
|
obj.select_set(True)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class AddTypeInstance(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.add_type_instance"
|
||||||
|
bl_label = "Add Type Instance"
|
||||||
|
ifc_class: bpy.props.EnumProperty(items=getIfcTypes, name="IFC Class", update=updateTypeInstanceIfcClass)
|
||||||
|
relating_type: bpy.props.EnumProperty(items=getAvailableTypes, name="Relating Type")
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
if not self.ifc_class or not self.relating_type:
|
||||||
|
return {"FINISHED"}
|
||||||
|
# A cube
|
||||||
|
verts = [
|
||||||
|
Vector((-1, -1, -1)),
|
||||||
|
Vector((-1, -1, 1)),
|
||||||
|
Vector((-1, 1, -1)),
|
||||||
|
Vector((-1, 1, 1)),
|
||||||
|
Vector((1, -1, -1)),
|
||||||
|
Vector((1, -1, 1)),
|
||||||
|
Vector((1, 1, -1)),
|
||||||
|
Vector((1, 1, 1)),
|
||||||
|
]
|
||||||
|
edges = []
|
||||||
|
faces = [
|
||||||
|
[0, 2, 3, 1],
|
||||||
|
[2, 3, 7, 6],
|
||||||
|
[4, 5, 7, 6],
|
||||||
|
[0, 1, 5, 4],
|
||||||
|
[1, 3, 7, 5],
|
||||||
|
]
|
||||||
|
mesh = bpy.data.meshes.new(name="Instance")
|
||||||
|
mesh.from_pydata(verts, edges, faces)
|
||||||
|
obj = bpy.data.objects.new("Instance", mesh)
|
||||||
|
obj.location = context.scene.cursor.location
|
||||||
|
context.view_layer.active_layer_collection.collection.objects.link(obj)
|
||||||
|
self.file = IfcStore.get_file()
|
||||||
|
instance_class = ifcopenshell.util.type.get_applicable_entities(self.ifc_class, self.file.schema)[0]
|
||||||
|
bpy.ops.bim.assign_class(obj=obj.name, ifc_class=instance_class)
|
||||||
|
bpy.ops.bim.assign_type(relating_type=int(self.relating_type), related_object=obj.name)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
def invoke(self, context, event):
|
||||||
|
wm = context.window_manager
|
||||||
|
return wm.invoke_props_dialog(self)
|
||||||
|
|||||||
@@ -16,6 +16,40 @@ from bpy.props import (
|
|||||||
|
|
||||||
applicable_types_enum = []
|
applicable_types_enum = []
|
||||||
relating_types_enum = []
|
relating_types_enum = []
|
||||||
|
type_classes_enum = []
|
||||||
|
available_types_enum = []
|
||||||
|
|
||||||
|
|
||||||
|
def getIfcTypes(self, context):
|
||||||
|
global type_classes_enum
|
||||||
|
file = IfcStore.get_file()
|
||||||
|
if len(type_classes_enum) < 1 and file:
|
||||||
|
declaration = IfcStore.get_schema().declaration_by_name("IfcElementType")
|
||||||
|
|
||||||
|
def get_classes(declaration):
|
||||||
|
results = []
|
||||||
|
if not declaration.is_abstract():
|
||||||
|
results.append(declaration.name())
|
||||||
|
for subtype in declaration.subtypes():
|
||||||
|
results.extend(get_classes(subtype))
|
||||||
|
return results
|
||||||
|
|
||||||
|
classes = get_classes(declaration)
|
||||||
|
type_classes_enum.extend([(c, c, "") for c in sorted(classes)])
|
||||||
|
return type_classes_enum
|
||||||
|
|
||||||
|
|
||||||
|
def getAvailableTypes(self, context):
|
||||||
|
global available_types_enum
|
||||||
|
if len(available_types_enum) < 1:
|
||||||
|
elements = IfcStore.get_file().by_type(self.ifc_class)
|
||||||
|
available_types_enum.extend((str(e.id()), e.Name, "") for e in elements)
|
||||||
|
return available_types_enum
|
||||||
|
|
||||||
|
|
||||||
|
def updateTypeInstanceIfcClass(self, context):
|
||||||
|
global available_types_enum
|
||||||
|
available_types_enum.clear()
|
||||||
|
|
||||||
|
|
||||||
def getApplicableTypes(self, context):
|
def getApplicableTypes(self, context):
|
||||||
@@ -48,4 +82,3 @@ class BIMTypeProperties(PropertyGroup):
|
|||||||
relating_type: EnumProperty(items=getRelatingTypes, name="Relating Type")
|
relating_type: EnumProperty(items=getRelatingTypes, name="Relating Type")
|
||||||
# This is purely a UX thing
|
# This is purely a UX thing
|
||||||
blank_relating_type: EnumProperty(items=[("None", "No Types Found", "")], name="Relating Type")
|
blank_relating_type: EnumProperty(items=[("None", "No Types Found", "")], name="Relating Type")
|
||||||
should_map_representations: BoolProperty(name="Should Map Representations")
|
|
||||||
|
|||||||
@@ -35,14 +35,10 @@ class BIM_PT_type(Panel):
|
|||||||
row.prop(props, "relating_type_class", text="")
|
row.prop(props, "relating_type_class", text="")
|
||||||
if props.relating_type:
|
if props.relating_type:
|
||||||
row.prop(props, "relating_type", text="")
|
row.prop(props, "relating_type", text="")
|
||||||
op = row.operator("bim.assign_type", icon="CHECKMARK", text="")
|
row.operator("bim.assign_type", icon="CHECKMARK", text="")
|
||||||
op.should_map_representations = props.should_map_representations
|
|
||||||
else:
|
else:
|
||||||
row.prop(props, "blank_relating_type", text="")
|
row.prop(props, "blank_relating_type", text="")
|
||||||
row.operator("bim.disable_editing_type", icon="X", text="")
|
row.operator("bim.disable_editing_type", icon="X", text="")
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
|
||||||
row.prop(props, "should_map_representations")
|
|
||||||
else:
|
else:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
name = "{}/{}".format(
|
name = "{}/{}".format(
|
||||||
@@ -57,3 +53,7 @@ class BIM_PT_type(Panel):
|
|||||||
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
|
row.operator("bim.enable_editing_type", icon="GREASEPENCIL", text="")
|
||||||
if name != "None/None":
|
if name != "None/None":
|
||||||
row.operator("bim.unassign_type", icon="X", text="")
|
row.operator("bim.unassign_type", icon="X", text="")
|
||||||
|
|
||||||
|
|
||||||
|
def add_object_button(self, context):
|
||||||
|
self.layout.operator("bim.add_type_instance", icon="PLUGIN")
|
||||||
|
|||||||
Reference in New Issue
Block a user