First Commit
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2022 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
"""Define units (length, area, monetary, pressure, etc)
|
||||
|
||||
Units can be defined as a default project unit or used specifically for certain
|
||||
properties. Units may be especially complex when dealing with services and
|
||||
equipment.
|
||||
"""
|
||||
|
||||
from .. import wrap_usecases
|
||||
from .add_context_dependent_unit import add_context_dependent_unit
|
||||
from .add_conversion_based_unit import add_conversion_based_unit
|
||||
from .add_derived_unit import add_derived_unit
|
||||
from .add_monetary_unit import add_monetary_unit
|
||||
from .add_si_unit import add_si_unit
|
||||
from .assign_unit import assign_unit
|
||||
from .edit_derived_unit import edit_derived_unit
|
||||
from .edit_monetary_unit import edit_monetary_unit
|
||||
from .edit_named_unit import edit_named_unit
|
||||
from .remove_unit import remove_unit
|
||||
from .unassign_unit import unassign_unit
|
||||
|
||||
wrap_usecases(__path__, __name__)
|
||||
|
||||
__all__ = [
|
||||
"add_context_dependent_unit",
|
||||
"add_conversion_based_unit",
|
||||
"add_derived_unit",
|
||||
"add_monetary_unit",
|
||||
"add_si_unit",
|
||||
"assign_unit",
|
||||
"edit_derived_unit",
|
||||
"edit_monetary_unit",
|
||||
"edit_named_unit",
|
||||
"remove_unit",
|
||||
"unassign_unit",
|
||||
]
|
||||
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,61 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def add_context_dependent_unit(
|
||||
file: ifcopenshell.file,
|
||||
unit_type: str = "USERDEFINED",
|
||||
name: str = "THINGAMAJIG",
|
||||
dimensions: tuple[int, int, int, int, int, int, int] = (0, 0, 0, 0, 0, 0, 0),
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new arbitrary unit that can only be interpreted in a project specific context
|
||||
|
||||
Occasionally the construction industry uses arbitrary units to quantify
|
||||
objects, like "pairs" of door hardware, "palettes" or "boxes" of fixings
|
||||
or equipment.
|
||||
|
||||
:param unit_type: Typically should be left as USERDEFINED, unless for
|
||||
some bizarre reason you are redefining something you could use a
|
||||
sensible normal unit for. In that case, firstly stop whatever you're
|
||||
doing and have a hard think about your life, and then if life really
|
||||
is going that badly for you, check out the IFC docs for IfcUnitEnum.
|
||||
:param name: Give your unit a name. X what? X bananas?
|
||||
:param dimensions: Units typically measure one of 7 fundamental physical
|
||||
dimensions: length, mass, time, electric current, temperature,
|
||||
substance amount, or luminous intensity. These are represented as a
|
||||
list of 7 integers, representing the exponents of each one of these
|
||||
dimensions. For example, a length unit is (1, 0, 0, 0, 0, 0, 0),
|
||||
where as an area unit is (2, 0, 0, 0, 0, 0, 0). A unit of meters per
|
||||
second is (1, 0, -1, 0, 0, 0, 0). For context dependent units, it is
|
||||
recommended to leave this as the default of (0, 0, 0, 0, 0, 0, 0).
|
||||
:return: The new IfcContextDependentUnit
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Boxes of things
|
||||
ifcopenshell.api.unit.add_context_dependent_unit(model, name="BOXES")
|
||||
"""
|
||||
return file.create_entity(
|
||||
"IfcContextDependentUnit",
|
||||
Dimensions=file.createIfcDimensionalExponents(*dimensions),
|
||||
UnitType=unit_type,
|
||||
Name=name,
|
||||
)
|
||||
@@ -0,0 +1,86 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def add_conversion_based_unit(
|
||||
file: ifcopenshell.file, name: str = "foot", conversion_offset: Optional[float] = None
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a conversion based unit
|
||||
|
||||
If you're in one of those countries who don't use SI units, you're
|
||||
probably simply using SI units converted into another unit. If you want
|
||||
to use _those_ units, you can create a conversion based unit with this
|
||||
function. You can choose from one of: inch, foot, yard, mile, square
|
||||
inch, square foot, square yard, acre, square mile, cubic inch, cubic
|
||||
foot, cubic yard, litre, fluid ounce UK, fluid ounce US, pint UK, pint
|
||||
US, gallon UK, gallon US, degree, ounce, pound, ton UK, ton US, tonne, lbf,
|
||||
kip, psi, ksi, minute, hour, day, btu, and fahrenheit.
|
||||
|
||||
:param name: A converted name chosen from the list above.
|
||||
:param conversion_offset: If you want to offset the conversion further
|
||||
by a set number, you may specify it here. For example, fahrenheit is
|
||||
1.8 * kelvin - 459.67. The -459.67 is the conversion offset. Note
|
||||
that this is just an example and you don't actually need to specify
|
||||
that for fahrenheit as it's built into this API function. For
|
||||
advanced users only.
|
||||
:return: The new IfcConversionBasedUnit or
|
||||
IfcConversionBasedUnitWithOffset
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Some common imperial measurements
|
||||
length = ifcopenshell.api.unit.add_conversion_based_unit(model, name="inch")
|
||||
area = ifcopenshell.api.unit.add_conversion_based_unit(model, name="square foot")
|
||||
|
||||
# Make it our default units, if we are doing an imperial building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
"""
|
||||
|
||||
unit_type = ifcopenshell.util.unit.imperial_types.get(name, "USERDEFINED")
|
||||
dimensions = ifcopenshell.util.unit.named_dimensions[unit_type]
|
||||
exponents = file.createIfcDimensionalExponents(*dimensions)
|
||||
si_name = ifcopenshell.util.unit.si_type_names[unit_type]
|
||||
|
||||
if unit_type == "MASSUNIT":
|
||||
si_unit = file.createIfcSIUnit(UnitType=unit_type, Name=si_name, Prefix="KILO")
|
||||
else:
|
||||
si_unit = file.createIfcSIUnit(UnitType=unit_type, Name=si_name)
|
||||
|
||||
conversion_real = ifcopenshell.util.unit.si_conversions.get(name, 1)
|
||||
value_component = file.create_entity("IfcReal", **{"wrappedValue": conversion_real})
|
||||
conversion_factor = file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||
|
||||
if not conversion_offset:
|
||||
conversion_offset = ifcopenshell.util.unit.si_offsets.get(name, 0)
|
||||
|
||||
if conversion_offset:
|
||||
return file.createIfcConversionBasedUnitWithOffset(
|
||||
exponents,
|
||||
unit_type,
|
||||
name,
|
||||
conversion_factor,
|
||||
conversion_offset,
|
||||
)
|
||||
return file.createIfcConversionBasedUnit(exponents, unit_type, name, conversion_factor)
|
||||
@@ -0,0 +1,77 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def add_derived_unit(
|
||||
file: ifcopenshell.file, unit_type: str, userdefinedtype: str, attributes: dict[ifcopenshell.entity_instance, int]
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new Derive unit
|
||||
|
||||
The supported types are ANGULARVELOCITYUNIT, AREADENSITYUNIT, COMPOUNDPLANEANGLEUNIT,
|
||||
DYNAMICVISCOSITYUNIT, HEATFLUXDENSITYUNIT, INTEGERCOUNTRATEUNIT, ISOTHERMALMOISTURECAPACITYUNIT,
|
||||
KINEMATICVISCOSITYUNIT, LINEARVELOCITYUNIT, MASSDENSITYUNIT, MASSFLOWRATEUNIT, MOISTUREDIFFUSIVITYUNIT,
|
||||
MOLECULARWEIGHTUNIT, SPECIFICHEATCAPACITYUNIT, THERMALADMITTANCEUNIT, THERMALCONDUCTANCEUNIT,
|
||||
THERMALRESISTANCEUNIT, THERMALTRANSMITTANCEUNIT, VAPORPERMEABILITYUNIT, VOLUMETRICFLOWRATEUNIT,
|
||||
ROTATIONALFREQUENCYUNIT, TORQUEUNIT, MOMENTOFINERTIAUNIT, LINEARMOMENTUNIT, LINEARFORCEUNIT,
|
||||
PLANARFORCEUNIT, MODULUSOFELASTICITYUNIT, SHEARMODULUSUNIT, LINEARSTIFFNESSUNIT, ROTATIONALSTIFFNESSUNIT,
|
||||
MODULUSOFSUBGRADEREACTIONUNIT, ACCELERATIONUNIT, CURVATUREUNIT, HEATINGVALUEUNIT, IONCONCENTRATIONUNIT,
|
||||
LUMINOUSINTENSITYDISTRIBUTIONUNIT, MASSPERLENGTHUNIT, MODULUSOFLINEARSUBGRADEREACTIONUNIT,
|
||||
MODULUSOFROTATIONALSUBGRADEREACTIONUNIT, PHUNIT, ROTATIONALMASSUNIT, SECTIONAREAINTEGRALUNIT,
|
||||
SECTIONMODULUSUNIT, SOUNDPOWERLEVELUNIT, SOUNDPOWERUNIT, SOUNDPRESSURELEVELUNIT, SOUNDPRESSUREUNIT,
|
||||
TEMPERATUREGRADIENTUNIT, TEMPERATURERATEOFCHANGEUNIT, THERMALEXPANSIONCOEFFICIENTUNIT, WARPINGCONSTANTUNIT,
|
||||
WARPINGMOMENTUNIT, USERDEFINED.
|
||||
|
||||
In case of choosing USERDEFINED, the UserDefinedType parameter needs to be provided
|
||||
|
||||
:param unit_type: A type of unit chosen from the list above. For
|
||||
example, choosing THERMALCONDUCTANCEUNIT will give you a Thermal conductance.
|
||||
:param userdefinedtype: The user defined type in case of choosing USERDEFINED, or None for no
|
||||
user defined type.
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: The newly created IfcDerivedUnit
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Linear velocity in m/s
|
||||
length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT")
|
||||
#2=IfcSIUnit(*,.LENGTHUNIT.,$,.METRE.)
|
||||
|
||||
time = ifcopenshell.api.unit.add_si_unit(model, unit_type="TIMEUNIT")
|
||||
#4=IfcSIUnit(*,.TIMEUNIT.,$,.SECOND.)
|
||||
|
||||
linear_velocity = ifcopenshell.api.unit.add_derived_unit(model, 'LINEARVELOCITY', None, {length : 1, time : -1})
|
||||
#10=IfcDerivedUnitElement(#2, 1)
|
||||
#11=IfcDerivedUnitElement(#4, -1)
|
||||
#12=IfcDerivedUnit((#10,#11),.LINEARVELOCITY.,$)
|
||||
|
||||
"""
|
||||
derive_unit_elements = []
|
||||
|
||||
for named_unit in attributes:
|
||||
derive_unit_elements.append(
|
||||
file.create_entity("IfcDerivedUnitElement", Unit=named_unit, Exponent=attributes[named_unit])
|
||||
)
|
||||
|
||||
return file.create_entity(
|
||||
"IfcDerivedUnit", Elements=derive_unit_elements, UnitType=unit_type, UserDefinedType=userdefinedtype
|
||||
)
|
||||
@@ -0,0 +1,42 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def add_monetary_unit(file: ifcopenshell.file, currency: str = "DOLLARYDOO") -> ifcopenshell.entity_instance:
|
||||
"""Add a new currency
|
||||
|
||||
Currency units are useful in cost plans to know in what currency the
|
||||
costs are calculated in. The currencies should follow ISO 4217, like
|
||||
USD, GBP, AUD, MYR, etc.
|
||||
|
||||
:param currency: The currency code
|
||||
:return: The newly created IfcMonetaryUnit
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# If you do all your cost plans in Zimbabwean dollars then nobody
|
||||
# knows how accurate the numbers are.
|
||||
zwl = ifcopenshell.api.unit.add_monetary_unit(model, currency="ZWL")
|
||||
|
||||
# Make it our default currency
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[zwl])
|
||||
"""
|
||||
return file.create_entity("IfcMonetaryUnit", currency)
|
||||
@@ -0,0 +1,60 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Optional
|
||||
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def add_si_unit(
|
||||
file: ifcopenshell.file, unit_type: str = "LENGTHUNIT", prefix: Optional[str] = None
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new SI unit
|
||||
|
||||
The supported types are ABSORBEDDOSEUNIT, AMOUNTOFSUBSTANCEUNIT,
|
||||
AREAUNIT, DOSEEQUIVALENTUNIT, ELECTRICCAPACITANCEUNIT,
|
||||
ELECTRICCHARGEUNIT, ELECTRICCONDUCTANCEUNIT, ELECTRICCURRENTUNIT,
|
||||
ELECTRICRESISTANCEUNIT, ELECTRICVOLTAGEUNIT, ENERGYUNIT, FORCEUNIT,
|
||||
FREQUENCYUNIT, ILLUMINANCEUNIT, INDUCTANCEUNIT, LENGTHUNIT,
|
||||
LUMINOUSFLUXUNIT, LUMINOUSINTENSITYUNIT, MAGNETICFLUXDENSITYUNIT,
|
||||
MAGNETICFLUXUNIT, MASSUNIT, PLANEANGLEUNIT, POWERUNIT, PRESSUREUNIT,
|
||||
RADIOACTIVITYUNIT, SOLIDANGLEUNIT, THERMODYNAMICTEMPERATUREUNIT,
|
||||
TIMEUNIT, VOLUMEUNIT.
|
||||
|
||||
Prefixes supported are ATTO, CENTI, DECA, DECI, EXA, FEMTO, GIGA, HECTO,
|
||||
KILO, MEGA, MICRO, MILLI, NANO, PETA, PICO, TERA.
|
||||
|
||||
:param unit_type: A type of unit chosen from the list above. For
|
||||
example, choosing LENGTHUNIT will give you a metre.
|
||||
:param prefix: A prefix chosen from the list above, or None for no
|
||||
prefix.
|
||||
:return: The newly created IfcSIUnit
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Millimeters and square meters
|
||||
length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
area = ifcopenshell.api.unit.add_si_unit(model, unit_type="AREAUNIT")
|
||||
|
||||
# Make it our default units, if we are doing a metric building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
"""
|
||||
name = ifcopenshell.util.unit.si_type_names.get(unit_type, None)
|
||||
return file.create_entity("IfcSIUnit", UnitType=unit_type, Name=name, Prefix=prefix)
|
||||
@@ -0,0 +1,168 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def assign_unit(
|
||||
file: ifcopenshell.file,
|
||||
units: Optional[list[ifcopenshell.entity_instance]] = None,
|
||||
length: Optional[dict] = None,
|
||||
area: Optional[dict] = None,
|
||||
volume: Optional[dict] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assign default project units
|
||||
|
||||
Whenever a unitised quantity is specified, such as a length, area,
|
||||
voltage, pressure, etc, these project units are used by default.
|
||||
|
||||
It is also possible to override units for specific properties. For
|
||||
example, generally you might want square metres for area measurements,
|
||||
but you might want square millimeters for the measurements of the cross
|
||||
sectional area of cables in cable trays. However, this function only
|
||||
deals with the default project units.
|
||||
|
||||
:param units: A list of units to assign as project defaults. See
|
||||
ifcopenshell.api.unit.add_si_unit, unit.add_conversion_based_unit,
|
||||
and unit.add_monetary_unit for information on how to create units.
|
||||
:return: The IfcUnitAssignment element
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# You need a project before you can assign units.
|
||||
ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject")
|
||||
|
||||
# Millimeters and square meters
|
||||
length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
area = ifcopenshell.api.unit.add_si_unit(model, unit_type="AREAUNIT")
|
||||
|
||||
# Optionally, add mass and time units
|
||||
mass = ifcopenshell.api.unit.add_si_unit(model, unit_type="MASSUNIT", prefix="KILO")
|
||||
time = ifcopenshell.api.unit.add_si_unit(model, unit_type="TIMEUNIT")
|
||||
|
||||
# Make these the default units for the project
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area, mass, time])
|
||||
|
||||
# Alternatively, you may specify without any arguments to
|
||||
# automatically create millimeters, square meters, and cubic meters
|
||||
# as a convenience for testing purposes. Sorry imperial folks, we
|
||||
# prioritise metric here.
|
||||
ifcopenshell.api.unit.assign_unit(model)
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"units": units}
|
||||
# This is a convenience function, likely to be deprecated in the future.
|
||||
usecase.settings["length"] = length or {"is_metric": True, "raw": "MILLIMETERS"}
|
||||
usecase.settings["area"] = area or {"is_metric": True, "raw": "METERS"}
|
||||
usecase.settings["volume"] = volume or {"is_metric": True, "raw": "METERS"}
|
||||
return usecase.execute()
|
||||
|
||||
|
||||
class Usecase:
|
||||
file: ifcopenshell.file
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
# We're going to refactor this to split unit creation and assignment
|
||||
if self.settings["units"]:
|
||||
units = self.settings["units"]
|
||||
else:
|
||||
del self.settings["units"] # TODO refactor
|
||||
units = []
|
||||
for unit_type, data in self.settings.items():
|
||||
if data["is_metric"]:
|
||||
units.append(self.create_metric_unit(unit_type, data))
|
||||
else:
|
||||
units.append(self.create_imperial_unit(unit_type, data))
|
||||
|
||||
unit_assignment = self.get_unit_assignment()
|
||||
self.assign_units(unit_assignment, units)
|
||||
return unit_assignment
|
||||
|
||||
def get_unit_assignment(self) -> ifcopenshell.entity_instance:
|
||||
if not (unit_assignment := ifcopenshell.util.unit.get_unit_assignment(self.file)):
|
||||
unit_assignment = self.file.createIfcUnitAssignment()
|
||||
self.file.by_type("IfcProject")[0].UnitsInContext = unit_assignment
|
||||
return unit_assignment
|
||||
|
||||
def assign_units(
|
||||
self, unit_assignment: ifcopenshell.entity_instance, new_units: list[ifcopenshell.entity_instance]
|
||||
) -> None:
|
||||
new_unit_types = [u.UnitType if not u.is_a("IfcMonetaryUnit") else u.is_a() for u in new_units]
|
||||
units = set(
|
||||
[
|
||||
u
|
||||
for u in (unit_assignment.Units or [])
|
||||
if u.is_a() not in new_unit_types and getattr(u, "UnitType", None) not in new_unit_types
|
||||
]
|
||||
)
|
||||
for unit in new_units:
|
||||
units.add(unit)
|
||||
unit_assignment.Units = list(units)
|
||||
|
||||
def create_metric_unit(self, unit_type: str, data: dict) -> ifcopenshell.entity_instance:
|
||||
type_prefix = ""
|
||||
if unit_type == "area":
|
||||
type_prefix = "SQUARE_"
|
||||
elif unit_type == "volume":
|
||||
type_prefix = "CUBIC_"
|
||||
return self.file.createIfcSIUnit(
|
||||
None,
|
||||
"{}UNIT".format(unit_type.upper()),
|
||||
ifcopenshell.util.unit.get_prefix(data["raw"]),
|
||||
type_prefix + ifcopenshell.util.unit.get_unit_name(data["raw"]),
|
||||
)
|
||||
|
||||
def create_imperial_unit(self, unit_type: str, data: dict) -> ifcopenshell.entity_instance:
|
||||
if unit_type == "length":
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(1, 0, 0, 0, 0, 0, 0)
|
||||
name_prefix = ""
|
||||
elif unit_type == "area":
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(2, 0, 0, 0, 0, 0, 0)
|
||||
name_prefix = "square"
|
||||
elif unit_type == "volume":
|
||||
dimensional_exponents = self.file.createIfcDimensionalExponents(3, 0, 0, 0, 0, 0, 0)
|
||||
name_prefix = "cubic"
|
||||
|
||||
si_unit = self.file.createIfcSIUnit(
|
||||
None,
|
||||
"{}UNIT".format(unit_type.upper()),
|
||||
None,
|
||||
"{}METRE".format(name_prefix.upper() + "_" if name_prefix else ""),
|
||||
)
|
||||
if data["raw"] == "INCHES":
|
||||
name = "{}inch".format(name_prefix + " " if name_prefix else "")
|
||||
elif data["raw"] == "FEET":
|
||||
name = "{}foot".format(name_prefix + " " if name_prefix else "")
|
||||
elif data["raw"] == "MILES":
|
||||
name = "{}mile".format(name_prefix + " " if name_prefix else "")
|
||||
elif data["raw"] == "THOU":
|
||||
name = "{}thou".format(name_prefix + " " if name_prefix else "")
|
||||
value_component = self.file.create_entity(
|
||||
"IfcReal", **{"wrappedValue": ifcopenshell.util.unit.si_conversions[name]}
|
||||
)
|
||||
conversion_factor = self.file.createIfcMeasureWithUnit(value_component, si_unit)
|
||||
return self.file.createIfcConversionBasedUnit(
|
||||
dimensional_exponents, "{}UNIT".format(unit_type.upper()), name, conversion_factor
|
||||
)
|
||||
@@ -0,0 +1,34 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
from typing import Any
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def edit_derived_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcDerivedUnit
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
IfcDerivedUnit, consult the IFC documentation.
|
||||
|
||||
:param unit: The IfcDerivedUnit entity you want to edit
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: None
|
||||
"""
|
||||
for name, value in attributes.items():
|
||||
setattr(unit, name, value)
|
||||
@@ -0,0 +1,45 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
from typing import Any
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def edit_monetary_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcMonetaryUnit
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
IfcMonetaryUnit, consult the IFC documentation.
|
||||
|
||||
:param unit: The IfcMonetaryUnit entity you want to edit
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# If you do all your cost plans in Zimbabwean dollars then nobody
|
||||
# knows how accurate the numbers are.
|
||||
zwl = ifcopenshell.api.unit.add_monetary_unit(model, currency="ZWL")
|
||||
|
||||
# Ah who are we kidding
|
||||
ifcopenshell.api.unit.edit_monetary_unit(model, unit=zwl, attributes={"Currency": "USD"})
|
||||
"""
|
||||
for name, value in attributes.items():
|
||||
setattr(unit, name, value)
|
||||
@@ -0,0 +1,55 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
from typing import Any
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def edit_named_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcNamedUnit
|
||||
|
||||
Named units include SI units, conversion based units (imperial units),
|
||||
and context dependent units.
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
IfcNamedUnit, consult the IFC documentation.
|
||||
|
||||
:param unit: The IfcNamedUnit entity you want to edit
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Boxes of things
|
||||
unit = ifcopenshell.api.unit.add_context_dependent_unit(model, name="BOXES")
|
||||
|
||||
# Uh, crates? Boxes? Whatever.
|
||||
ifcopenshell.api.unit.edit_named_unit(model, unit=unit, attibutes={"Name": "CRATES"})
|
||||
"""
|
||||
for name, value in attributes.items():
|
||||
if name == "Dimensions":
|
||||
dimensions = unit.Dimensions
|
||||
if file.get_total_inverses(dimensions) > 1:
|
||||
unit.Dimensions = file.createIfcDimensionalExponents(*value)
|
||||
else:
|
||||
for i, exponent in enumerate(value):
|
||||
dimensions[i] = exponent
|
||||
continue
|
||||
setattr(unit, name, value)
|
||||
@@ -0,0 +1,51 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
|
||||
def remove_unit(file: ifcopenshell.file, unit: ifcopenshell.entity_instance) -> None:
|
||||
"""Remove a unit
|
||||
|
||||
Be very careful when a unit is removed, as it may mean that previously
|
||||
defined quantities in the model completely lose their meaning.
|
||||
|
||||
:param unit: The unit element to remove
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# What?
|
||||
unit = ifcopenshell.api.unit.add_context_dependent_unit(model, name="HANDFULS")
|
||||
|
||||
# Yeah maybe not.
|
||||
ifcopenshell.api.unit.remove_unit(model, unit=unit)
|
||||
"""
|
||||
unit_assignment = ifcopenshell.util.unit.get_unit_assignment(file)
|
||||
if unit_assignment and unit in unit_assignment.Units:
|
||||
units = list(unit_assignment.Units)
|
||||
units.remove(unit)
|
||||
if units:
|
||||
unit_assignment.Units = units
|
||||
else:
|
||||
file.remove(unit_assignment)
|
||||
# TODO handle other possible unit inverses
|
||||
ifcopenshell.util.element.remove_deep2(file, unit)
|
||||
@@ -0,0 +1,55 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
from typing import Optional
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def unassign_unit(file: ifcopenshell.file, units: Optional[list[ifcopenshell.entity_instance]] = None) -> None:
|
||||
"""Unassigns units as default units for the project
|
||||
|
||||
:param units: A list of units to unassign as project defaults.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# You need a project before you can assign units.
|
||||
ifcopenshell.api.root.create_entity(model, ifc_class="IfcProject")
|
||||
|
||||
# Millimeters and square meters
|
||||
length = ifcopenshell.api.unit.add_si_unit(model, unit_type="LENGTHUNIT", prefix="MILLI")
|
||||
area = ifcopenshell.api.unit.add_si_unit(model, unit_type="AREAUNIT")
|
||||
|
||||
# Make it our default units, if we are doing a metric building
|
||||
ifcopenshell.api.unit.assign_unit(model, units=[length, area])
|
||||
|
||||
# Actually, we don't need areas.
|
||||
ifcopenshell.api.unit.unassign_unit(model, units=[area])
|
||||
"""
|
||||
unit_assignments = file.by_type("IfcUnitAssignment")
|
||||
if not unit_assignments:
|
||||
return
|
||||
unit_assignment = unit_assignments[0]
|
||||
units_set = set(unit_assignment.Units or [])
|
||||
units_set = units_set - set(units or [])
|
||||
if units_set:
|
||||
unit_assignment.Units = list(units_set)
|
||||
return
|
||||
file.remove(unit_assignment)
|
||||
Reference in New Issue
Block a user