Skip to content

Commit

Permalink
custom extension capability
Browse files Browse the repository at this point in the history
  • Loading branch information
Licini committed Oct 25, 2024
1 parent 1621302 commit 62b8f2b
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 7 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* Added `extensions` keyword argument to `Model` to for inserting custom extensions to IFC classes.

### Changed

### Removed
Expand Down
23 changes: 23 additions & 0 deletions scripts/6.1_custom_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from compas_ifc.entities.generated.IFC4 import IfcBuildingElement
from compas_ifc.model import Model


class ExtendedIfcBuildingElement(IfcBuildingElement):
@property
def volume(self):
return self.geometry.volume


model = Model("data/Duplex_A_20110907.ifc", use_occ=True, extensions={"IfcBuildingElement": ExtendedIfcBuildingElement})

total_wall_volume = 0
for wall in model.get_entities_by_type("IfcWall"):
total_wall_volume += wall.volume

print("Total wall volume:", total_wall_volume, f"{model.unit}³")

total_slab_volume = 0
for slab in model.get_entities_by_type("IfcSlab"):
total_slab_volume += slab.volume

print("Total slab volume:", total_slab_volume, f"{model.unit}³")
19 changes: 16 additions & 3 deletions src/compas_ifc/entities/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Base(Data):
file : Ifcfile
"""

def __new__(cls, entity: entity_instance, file: "IFCFile" = None):
def __new__(cls, entity: entity_instance, file: "IFCFile" = None, extensions: dict = None):
if file is None:
schema = "IFC4"
else:
Expand All @@ -48,11 +48,24 @@ def __new__(cls, entity: entity_instance, file: "IFCFile" = None):
cls_name = entity.is_a()
ifc_cls = getattr(classes, cls_name, None)
if ifc_cls:
return super(Base, cls).__new__(ifc_cls)
matched_extensions = []
if extensions:
for name, extension_class in extensions.items():
if entity.is_a(name):
matched_extensions.append(extension_class)
if matched_extensions:
# Create a new class that inherits from the original IFC class and all matched extensions
extension_name = f"Extended{cls_name}"
bases = tuple([ifc_cls] + matched_extensions)
extended_cls = type(extension_name, bases, {})
return super(Base, extended_cls).__new__(extended_cls)
else:
# If no extensions matched, use the original IFC class
return super(Base, ifc_cls).__new__(ifc_cls)
elif hasattr(entity, "wrappedValue"):
return TypeDefinition(entity, file)

def __init__(self, entity: entity_instance = None, file=None):
def __init__(self, entity: entity_instance = None, file=None, **kwargs):
super().__init__()
self.file = file
self.entity = entity
Expand Down
5 changes: 3 additions & 2 deletions src/compas_ifc/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@


class IFCFile(object):
def __init__(self, model, filepath=None, schema="IFC4", use_occ=False, load_geometries=True, verbose=True):
def __init__(self, model, filepath=None, schema="IFC4", use_occ=False, load_geometries=True, verbose=True, extensions=None):
self.extensions = extensions
self.verbose = verbose
self.ensure_classes_generated()
self._entitymap = {}
Expand Down Expand Up @@ -96,7 +97,7 @@ def from_entity(self, entity):
if _id in self._entitymap and _id != 0:
return self._entitymap[_id]
else:
entity = Base(entity, self)
entity = Base(entity, file=self, extensions=self.extensions)
if _id != 0:
self._entitymap[_id] = entity
return entity
Expand Down
4 changes: 2 additions & 2 deletions src/compas_ifc/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@


class Model(Data):
def __init__(self, filepath=None, schema=None, use_occ=False, load_geometries=True, verbose=True):
self.file = IFCFile(self, filepath=filepath, schema=schema, use_occ=use_occ, load_geometries=load_geometries, verbose=verbose)
def __init__(self, filepath=None, schema=None, use_occ=False, load_geometries=True, verbose=True, extensions=None):
self.file = IFCFile(self, filepath=filepath, schema=schema, use_occ=use_occ, load_geometries=load_geometries, verbose=verbose, extensions=extensions)
if filepath:
self.update_linear_deflection()

Expand Down

0 comments on commit 62b8f2b

Please sign in to comment.