Skip to content

Commit

Permalink
add unit getter setter
Browse files Browse the repository at this point in the history
  • Loading branch information
Licini committed Jul 17, 2024
1 parent 1f335c8 commit 6a10c65
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 34 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Added `export` method to `IFCFile` and `Model` to export selected list of entities.
* Added `update_linear_deflection` to `Model`.
* Added `unit` attribute to `Model`.
* Added `unit` keyword argument to `Model.template()`.

### Changed

Expand Down
12 changes: 5 additions & 7 deletions scripts/4.2_create_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@
from compas_ifc.model import Model


model = Model.template(storey_count=1)
model = Model.template(storey_count=1, unit="m")

# Default unit is mm
box = Box.from_width_height_depth(5000, 5000, 50)
sphere = Sphere(2000)
box = Box.from_width_height_depth(5, 5, 0.05)
sphere = Sphere(2)
mesh = Mesh.from_obj(compas.get("tubemesh.obj"))
mesh.scale(1000)

storey = model.building_storeys[0]

element1 = model.create("IfcWall", geometry=box, frame=Frame([0, 0, 0]), name="Wall", parent=storey)
element2 = model.create("IfcRoof", geometry=mesh, frame=Frame([0, 0, 5000]), name="Roof", parent=storey)
element3 = model.create(geometry=sphere, frame=Frame([0, 5000, 0]), name="Sphere", parent=storey, properties={"Custom_Pset": {"Custom_Property": "Custom Value"}})
element2 = model.create("IfcRoof", geometry=mesh, frame=Frame([0, 0, 5]), name="Roof", parent=storey)
element3 = model.create(geometry=sphere, frame=Frame([0, 5, 0]), name="Sphere", parent=storey, properties={"Custom_Pset": {"Custom_Property": "Custom Value"}})

model.print_spatial_hierarchy(max_depth=5)
model.show()
Expand Down
16 changes: 5 additions & 11 deletions src/compas_ifc/entities/extensions/IfcProject.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,30 +52,24 @@ def units(self):
units_in_context = self.UnitsInContext or self.file.get_entities_by_type("IfcUnitAssignment")[0]
for unit in units_in_context.Units:
if unit.is_a("IfcSIUnit"):
units.append(
{
"type": unit.UnitType,
"name": unit.Name,
"prefix": unit.Prefix,
}
)
units.append(unit)
return units

@property
def length_unit(self):
for unit in self.units:
if unit["type"] == "LENGTHUNIT":
if unit["UnitType"] == "LENGTHUNIT":
return unit

@property
def length_scale(self):
unit = self.length_unit
if unit:
if unit["name"] == "METRE" and not unit["prefix"]:
if unit.Name == "METRE" and not unit.Prefix:
return 1.0
if unit["name"] == "METRE" and unit["prefix"] == "CENTI":
if unit.Name == "METRE" and unit.Prefix == "CENTI":
return 1e-2
if unit["name"] == "METRE" and unit["prefix"] == "MILLI":
if unit.Name == "METRE" and unit.Prefix == "MILLI":
return 1e-3
return 1.0

Expand Down
1 change: 0 additions & 1 deletion src/compas_ifc/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ def __init__(self, model, filepath=None, schema="IFC4", use_occ=False, load_geom
else:
self._file = ifcopenshell.open(filepath)
print("IFC file loaded: {}".format(filepath))
self.model.update_linear_deflection()

self._schema = ifcopenshell.ifcopenshell_wrapper.schema_by_name(self._file.schema)

Expand Down
45 changes: 30 additions & 15 deletions src/compas_ifc/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
class Model(Data):
def __init__(self, filepath=None, schema=None, use_occ=False, load_geometries=True):
self.file = IFCFile(self, filepath=filepath, schema=schema, use_occ=use_occ, load_geometries=load_geometries)
if filepath:
self.update_linear_deflection()

@property
def schema(self):
Expand Down Expand Up @@ -53,6 +55,27 @@ def building_storeys(self) -> list["IfcBuildingStorey"]:
def building_elements(self) -> list["IfcBuildingElement"]:
return self.file.get_entities_by_type("IfcBuildingElement")

@property
def unit(self):
length_unit = self.project.length_unit
if length_unit.Name == "METRE" and length_unit.Prefix == "MILLI":
return "mm"
elif length_unit.Name == "METRE" and length_unit.Prefix == "CENTI":
return "cm"
elif length_unit.Name == "METRE" and not length_unit.Prefix:
return "m"

@unit.setter
def unit(self, value):
if value == "mm":
self.project.length_unit.Prefix = "MILLI"
elif value == "cm":
self.project.length_unit.Prefix = "CENTI"
elif value == "m":
self.project.length_unit.Prefix = None
else:
raise ValueError("Invalid unit. Use 'mm', 'cm', or 'm'.")

def get_entities_by_type(self, type_name) -> list["Base"]:
return self.file.get_entities_by_type(type_name)

Expand Down Expand Up @@ -103,16 +126,8 @@ def show(self, entity=None):
raise ImportError("The show method requires compas_viewer to be installed.")

viewer = Viewer()
length_unit = self.project.length_unit
print(f"Using length unit: {length_unit}")
if length_unit["name"] == "METRE" and length_unit["prefix"] == "MILLI":
viewer.unit = "mm"
elif length_unit["name"] == "METRE" and length_unit["prefix"] == "CENTI":
viewer.unit = "cm"
elif length_unit["name"] == "METRE" and not length_unit["prefix"]:
viewer.unit = "m"
else:
raise ValueError(f"Unsupported length unit: {length_unit}")
print(f"Unit: {self.unit}")
viewer.unit = self.unit

entity_map = {}

Expand Down Expand Up @@ -151,16 +166,15 @@ def create(self, cls="IfcBuildingElementProxy", parent=None, geometry=None, fram
return self.file.create(cls=cls, parent=parent, geometry=geometry, frame=frame, properties=properties, **kwargs)

def update_linear_deflection(self):
length_unit = self.project.length_unit
if length_unit["name"] == "METRE" and length_unit["prefix"] == "MILLI":
if self.unit == "mm":
TOL.lineardeflection = 1
elif length_unit["name"] == "METRE" and length_unit["prefix"] == "CENTI":
elif self.unit == "cm":
TOL.lineardeflection = 1e-1
elif length_unit["name"] == "METRE" and not length_unit["prefix"]:
elif self.unit == "m":
TOL.lineardeflection = 1e-3

@classmethod
def template(cls, schema="IFC4", building_count=1, storey_count=1):
def template(cls, schema="IFC4", building_count=1, storey_count=1, unit="mm"):
model = cls(schema=schema)
project = model.file.default_project
site = model.create("IfcSite", parent=project, Name="Default Site")
Expand All @@ -169,6 +183,7 @@ def template(cls, schema="IFC4", building_count=1, storey_count=1):
for j in range(storey_count):
model.create("IfcBuildingStorey", parent=building, Name=f"Default Storey {j+1}")

model.unit = unit
model.update_linear_deflection()
return model

Expand Down

0 comments on commit 6a10c65

Please sign in to comment.