mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
You can now duplicate or linked duplicate objects in IFC. Neat. See #1222.
This commit is contained in:
@@ -10,12 +10,13 @@ class Usecase:
|
|||||||
self.settings[key] = value
|
self.settings[key] = value
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.get_mapping_source()
|
|
||||||
|
|
||||||
self.zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
self.zero = self.file.createIfcCartesianPoint((0.0, 0.0, 0.0))
|
||||||
self.x_axis = self.file.createIfcDirection((1.0, 0.0, 0.0))
|
self.x_axis = self.file.createIfcDirection((1.0, 0.0, 0.0))
|
||||||
self.y_axis = self.file.createIfcDirection((0.0, 1.0, 0.0))
|
self.y_axis = self.file.createIfcDirection((0.0, 1.0, 0.0))
|
||||||
self.z_axis = self.file.createIfcDirection((0.0, 0.0, 1.0))
|
self.z_axis = self.file.createIfcDirection((0.0, 0.0, 1.0))
|
||||||
|
|
||||||
|
self.get_mapping_source()
|
||||||
|
|
||||||
mapping_target = self.file.createIfcCartesianTransformationOperator3D(
|
mapping_target = self.file.createIfcCartesianTransformationOperator3D(
|
||||||
self.x_axis, self.y_axis, self.zero, 1, self.z_axis
|
self.x_axis, self.y_axis, self.zero, 1, self.z_axis
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -179,20 +179,23 @@ class MapRepresentation(bpy.types.Operator):
|
|||||||
bl_idname = "bim.map_representation"
|
bl_idname = "bim.map_representation"
|
||||||
bl_label = "Map Representation"
|
bl_label = "Map Representation"
|
||||||
obj: bpy.props.StringProperty()
|
obj: bpy.props.StringProperty()
|
||||||
target_obj: bpy.props.StringProperty()
|
obj_data: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
objs = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects
|
objs = [bpy.data.objects.get(self.obj)] if self.obj else bpy.context.selected_objects
|
||||||
target_obj = bpy.data.objects.get(self.obj) if self.obj else bpy.context.active_object
|
obj_data = bpy.data.meshes.get(self.obj_data) if self.obj_data else bpy.context.active_object.data
|
||||||
objs = [o for o in objs if o != target_obj]
|
objs = [o for o in objs if o.data != obj_data]
|
||||||
self.file = IfcStore.get_file()
|
self.file = IfcStore.get_file()
|
||||||
|
|
||||||
for obj in objs:
|
for obj in objs:
|
||||||
bpy.ops.bim.edit_object_placement(obj=obj.name)
|
bpy.ops.bim.edit_object_placement(obj=obj.name)
|
||||||
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
product = self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||||
old_representation = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
if obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
target_representation = self.file.by_id(target_obj.data.BIMMeshProperties.ifc_definition_id)
|
old_representation = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
obj.data = target_obj.data
|
else:
|
||||||
|
old_representation = None
|
||||||
|
target_representation = self.file.by_id(obj_data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
obj.data = obj_data
|
||||||
result = map_representation.Usecase(
|
result = map_representation.Usecase(
|
||||||
self.file,
|
self.file,
|
||||||
{
|
{
|
||||||
@@ -201,7 +204,8 @@ class MapRepresentation(bpy.types.Operator):
|
|||||||
},
|
},
|
||||||
).execute()
|
).execute()
|
||||||
assign_representation.Usecase(self.file, {"product": product, "representation": result}).execute()
|
assign_representation.Usecase(self.file, {"product": product, "representation": result}).execute()
|
||||||
bpy.ops.bim.remove_representation(ifc_definition_id=old_representation.id())
|
if old_representation:
|
||||||
|
bpy.ops.bim.remove_representation(ifc_definition_id=old_representation.id())
|
||||||
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ classes = (
|
|||||||
operator.AssignClass,
|
operator.AssignClass,
|
||||||
operator.UnassignClass,
|
operator.UnassignClass,
|
||||||
operator.UnlinkObject,
|
operator.UnlinkObject,
|
||||||
|
operator.CopyClass,
|
||||||
prop.BIMRootProperties,
|
prop.BIMRootProperties,
|
||||||
ui.BIM_PT_class,
|
ui.BIM_PT_class,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import ifcopenshell
|
||||||
|
|
||||||
|
|
||||||
|
class Usecase:
|
||||||
|
def __init__(self, file, settings=None):
|
||||||
|
self.file = file
|
||||||
|
self.settings = {"product": None}
|
||||||
|
for key, value in settings.items():
|
||||||
|
self.settings[key] = value
|
||||||
|
|
||||||
|
def execute(self):
|
||||||
|
result = self.file.create_entity(self.settings["product"].is_a())
|
||||||
|
self.schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self.file.schema)
|
||||||
|
self.copy_attributes(self.settings["product"], result)
|
||||||
|
for inverse in self.file.get_inverse(self.settings["product"]):
|
||||||
|
for i, value in enumerate(inverse):
|
||||||
|
if value == self.settings["product"]:
|
||||||
|
new_inverse = self.file.create_entity(inverse.is_a())
|
||||||
|
self.copy_attributes(inverse, new_inverse)
|
||||||
|
new_inverse[i] = result
|
||||||
|
elif isinstance(value, (tuple, list)) and self.settings["product"] in value:
|
||||||
|
new_value = list(value)
|
||||||
|
new_value.append(result)
|
||||||
|
inverse[i] = new_value
|
||||||
|
if result.is_a("IfcProduct"):
|
||||||
|
result.Representation = None
|
||||||
|
elif result.is_a("IfcTypeProduct"):
|
||||||
|
result.RepresentationMaps = None
|
||||||
|
return result
|
||||||
|
|
||||||
|
def copy_attributes(self, from_element, to_element):
|
||||||
|
declaration = self.schema.declaration_by_name(from_element.is_a())
|
||||||
|
for attribute in declaration.all_attributes():
|
||||||
|
if attribute.name() == "GlobalId":
|
||||||
|
setattr(to_element, attribute.name(), ifcopenshell.guid.new())
|
||||||
|
else:
|
||||||
|
setattr(to_element, attribute.name(), getattr(from_element, attribute.name()))
|
||||||
@@ -5,6 +5,7 @@ import ifcopenshell.util.schema
|
|||||||
import blenderbim.bim.module.root.create_product as create_product
|
import blenderbim.bim.module.root.create_product as create_product
|
||||||
import blenderbim.bim.module.root.remove_product as remove_product
|
import blenderbim.bim.module.root.remove_product as remove_product
|
||||||
import blenderbim.bim.module.root.reassign_class as reassign_class
|
import blenderbim.bim.module.root.reassign_class as reassign_class
|
||||||
|
import blenderbim.bim.module.root.copy_class as copy_class
|
||||||
from blenderbim.bim.module.owner.api import create_owner_history
|
from blenderbim.bim.module.owner.api import create_owner_history
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
|
|
||||||
@@ -203,3 +204,32 @@ class UnlinkObject(bpy.types.Operator):
|
|||||||
if obj.BIMObjectProperties.ifc_definition_id:
|
if obj.BIMObjectProperties.ifc_definition_id:
|
||||||
obj.BIMObjectProperties.ifc_definition_id = 0
|
obj.BIMObjectProperties.ifc_definition_id = 0
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
class CopyClass(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.copy_class"
|
||||||
|
bl_label = "Copy Class"
|
||||||
|
obj: bpy.props.StringProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
self.file = IfcStore.get_file()
|
||||||
|
if self.obj:
|
||||||
|
objects = [bpy.data.objects.get(self.obj)]
|
||||||
|
else:
|
||||||
|
objects = bpy.context.selected_objects
|
||||||
|
for obj in objects:
|
||||||
|
if not obj.BIMObjectProperties.ifc_definition_id:
|
||||||
|
continue
|
||||||
|
result = copy_class.Usecase(self.file, {
|
||||||
|
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id)
|
||||||
|
}).execute()
|
||||||
|
obj.BIMObjectProperties.ifc_definition_id = result.id()
|
||||||
|
if obj.data.users == 1:
|
||||||
|
bpy.ops.bim.add_representation(obj=obj.name)
|
||||||
|
else:
|
||||||
|
obj_data = obj.data.name
|
||||||
|
temporary_mesh = bpy.data.meshes.new("Temporary Mesh")
|
||||||
|
obj.data = temporary_mesh
|
||||||
|
bpy.ops.bim.map_representation(obj=obj.name, obj_data=obj_data)
|
||||||
|
bpy.data.meshes.remove(temporary_mesh)
|
||||||
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ class BIM_PT_class(Panel):
|
|||||||
name += "[{}]".format(data["PredefinedType"])
|
name += "[{}]".format(data["PredefinedType"])
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text=name)
|
row.label(text=name)
|
||||||
|
row.operator("bim.copy_class", icon="DUPLICATE", text="").obj = context.active_object.name
|
||||||
row.operator("bim.unlink_object", icon="UNLINKED", text="").obj = context.active_object.name
|
row.operator("bim.unlink_object", icon="UNLINKED", text="").obj = context.active_object.name
|
||||||
row.operator("bim.enable_reassign_class", icon="GREASEPENCIL", text="")
|
row.operator("bim.enable_reassign_class", icon="GREASEPENCIL", text="")
|
||||||
row.operator("bim.unassign_class", icon="X", text="").obj = context.active_object.name
|
row.operator("bim.unassign_class", icon="X", text="").obj = context.active_object.name
|
||||||
|
|||||||
Reference in New Issue
Block a user