mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 06:58:56 +00:00
214 lines
8.1 KiB
Python
214 lines
8.1 KiB
Python
import bpy
|
|
import numpy as np
|
|
import ifcopenshell
|
|
import logging
|
|
import blenderbim.bim.module.geometry.add_object_placement as add_object_placement
|
|
import blenderbim.bim.module.geometry.add_representation as add_representation
|
|
import blenderbim.bim.module.geometry.assign_styles as assign_styles
|
|
import blenderbim.bim.module.geometry.assign_representation as assign_representation
|
|
import blenderbim.bim.module.geometry.remove_representation as remove_representation
|
|
from blenderbim.bim.ifc import IfcStore
|
|
from blenderbim.bim import import_ifc
|
|
from blenderbim.bim.module.geometry.data import Data
|
|
|
|
|
|
class AddRepresentation(bpy.types.Operator):
|
|
bl_idname = "bim.add_representation"
|
|
bl_label = "Add Representation"
|
|
|
|
def execute(self, context):
|
|
obj = bpy.context.active_object
|
|
self.file = IfcStore.get_file()
|
|
self.context_id = bpy.context.scene.BIMProperties.contexts
|
|
|
|
element = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
|
usecase = add_representation.Usecase(
|
|
self.file,
|
|
{
|
|
"context": self.file.by_id(int(self.context_id)),
|
|
"geometry": obj.data,
|
|
"total_items": max(1, len(obj.material_slots)),
|
|
},
|
|
)
|
|
result = usecase.execute()
|
|
if not result:
|
|
print("Failed to write shape representation")
|
|
return {"FINISHED"}
|
|
|
|
usecase = assign_styles.Usecase(
|
|
self.file,
|
|
{
|
|
"shape_representation": result,
|
|
"styles": [
|
|
self.file.by_id(s.material.BIMMaterialProperties.ifc_style_id)
|
|
for s in obj.material_slots
|
|
if s.material
|
|
],
|
|
},
|
|
)
|
|
usecase.execute()
|
|
|
|
usecase = assign_representation.Usecase(
|
|
self.file, {"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id), "representation": result}
|
|
)
|
|
usecase.execute()
|
|
|
|
existing_mesh = obj.data
|
|
existing_mesh.use_fake_user = True
|
|
mesh = obj.data.copy()
|
|
mesh.name = "{}/{}".format(self.context_id, result.id())
|
|
mesh.BIMMeshProperties.ifc_definition_id = int(result.id())
|
|
obj.data = mesh
|
|
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
|
return {"FINISHED"}
|
|
|
|
|
|
class SwitchRepresentation(bpy.types.Operator):
|
|
bl_idname = "bim.switch_representation"
|
|
bl_label = "Switch Representation"
|
|
ifc_definition_id: bpy.props.IntProperty()
|
|
|
|
def execute(self, context):
|
|
self.obj = bpy.context.active_object
|
|
|
|
self.file = IfcStore.get_file()
|
|
context_of_items = self.file.by_id(self.ifc_definition_id).ContextOfItems
|
|
self.mesh_name = "{}/{}".format(context_of_items.id(), self.ifc_definition_id)
|
|
|
|
mesh = bpy.data.meshes.get(self.mesh_name)
|
|
if mesh:
|
|
self.obj.data.user_remap(mesh)
|
|
self.pull_mesh_from_ifc()
|
|
return {"FINISHED"}
|
|
|
|
def pull_mesh_from_ifc(self):
|
|
self.file = IfcStore.get_file()
|
|
logger = logging.getLogger("ImportIFC")
|
|
ifc_import_settings = import_ifc.IfcImportSettings.factory(bpy.context, IfcStore.path, logger)
|
|
element = self.file.by_id(self.obj.BIMObjectProperties.ifc_definition_id)
|
|
settings = ifcopenshell.geom.settings()
|
|
settings.set(settings.INCLUDE_CURVES, True)
|
|
shape = ifcopenshell.geom.create_shape(settings, self.file.by_id(self.ifc_definition_id))
|
|
ifc_importer = import_ifc.IfcImporter(ifc_import_settings)
|
|
ifc_importer.file = self.file
|
|
mesh = ifc_importer.create_mesh(element, shape)
|
|
mesh.name = self.mesh_name
|
|
mesh.BIMMeshProperties.ifc_definition_id = self.ifc_definition_id
|
|
self.obj.data.user_remap(mesh)
|
|
material_creator = import_ifc.MaterialCreator(ifc_import_settings, ifc_importer)
|
|
material_creator.create(element, self.obj, mesh)
|
|
|
|
|
|
class RemoveRepresentation(bpy.types.Operator):
|
|
bl_idname = "bim.remove_representation"
|
|
bl_label = "Remove Representation"
|
|
ifc_definition_id: bpy.props.IntProperty()
|
|
|
|
def execute(self, context):
|
|
self.file = IfcStore.get_file()
|
|
representation = self.file.by_id(self.ifc_definition_id)
|
|
obj = bpy.context.active_object
|
|
mesh = bpy.data.meshes.get("{}/{}".format(representation.ContextOfItems.id(), representation.id()))
|
|
if mesh:
|
|
if obj.data == mesh:
|
|
# TODO we can do better than this
|
|
void_mesh = bpy.data.meshes.get("Void")
|
|
if not void_mesh:
|
|
void_mesh = bpy.data.meshes.new("Void")
|
|
obj.data = void_mesh
|
|
bpy.data.meshes.remove(mesh)
|
|
usecase = remove_representation.Usecase(self.file, {"representation": representation})
|
|
result = usecase.execute()
|
|
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
|
return {"FINISHED"}
|
|
|
|
|
|
class BakeParametricGeometry(bpy.types.Operator):
|
|
bl_idname = "bim.bake_parametric_geometry"
|
|
bl_label = "Bake Parametric Geometry"
|
|
|
|
def execute(self, context):
|
|
obj = bpy.context.active_object
|
|
self.file = IfcStore.get_file()
|
|
|
|
usecase = add_object_placement.Usecase(
|
|
self.file,
|
|
{
|
|
"product": self.file.by_id(obj.BIMObjectProperties.ifc_definition_id),
|
|
"matrix": np.array(obj.matrix_world),
|
|
},
|
|
)
|
|
result = usecase.execute()
|
|
|
|
element = self.file.by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
|
usecase = add_representation.Usecase(
|
|
self.file,
|
|
{
|
|
"context": element.ContextOfItems,
|
|
"geometry": obj.data,
|
|
"total_items": max(1, len(obj.material_slots)),
|
|
},
|
|
)
|
|
result = usecase.execute()
|
|
if not result:
|
|
print("Failed to write shape representation")
|
|
return {"FINISHED"}
|
|
|
|
usecase = assign_styles.Usecase(
|
|
self.file,
|
|
{
|
|
"shape_representation": result,
|
|
"styles": [
|
|
self.file.by_id(s.material.BIMMaterialProperties.ifc_style_id)
|
|
for s in obj.material_slots
|
|
if s.material
|
|
],
|
|
},
|
|
)
|
|
usecase.execute()
|
|
|
|
for inverse in self.file.get_inverse(element):
|
|
ifcopenshell.util.element.replace_attribute(inverse, element, result)
|
|
obj.data.BIMMeshProperties.ifc_definition_id = int(result.id())
|
|
Data.load(obj.BIMObjectProperties.ifc_definition_id)
|
|
return {"FINISHED"}
|
|
|
|
|
|
class UpdateIfcRepresentation(bpy.types.Operator):
|
|
bl_idname = "bim.update_ifc_representation"
|
|
bl_label = "Update IFC Representation"
|
|
index: bpy.props.IntProperty()
|
|
|
|
def execute(self, context):
|
|
self.file = IfcStore.get_file()
|
|
obj = bpy.context.active_object
|
|
props = obj.data.BIMMeshProperties
|
|
parameter = props.ifc_parameters[self.index]
|
|
element = IfcStore.get_file().by_id(parameter.step_id)[parameter.index] = parameter.value
|
|
bpy.ops.bim.switch_representation(ifc_definition_id=props.ifc_definition_id)
|
|
return {"FINISHED"}
|
|
|
|
|
|
class GetRepresentationIfcParameters(bpy.types.Operator):
|
|
bl_idname = "bim.get_representation_ifc_parameters"
|
|
bl_label = "Get Representation IFC Parameters"
|
|
|
|
def execute(self, context):
|
|
self.file = IfcStore.get_file()
|
|
obj = bpy.context.active_object
|
|
props = obj.data.BIMMeshProperties
|
|
elements = IfcStore.get_file().traverse(IfcStore.get_file().by_id(props.ifc_definition_id))
|
|
for element in elements:
|
|
if not element.is_a("IfcRepresentationItem"):
|
|
continue
|
|
for i in range(0, len(element)):
|
|
if element.attribute_type(i) == "DOUBLE":
|
|
new = props.ifc_parameters.add()
|
|
new.name = "{}/{}".format(element.is_a(), element.attribute_name(i))
|
|
new.step_id = element.id()
|
|
new.type = element.attribute_type(i)
|
|
new.index = i
|
|
if element[i]:
|
|
new.value = element[i]
|
|
return {"FINISHED"}
|