This commit is contained in:
Andrej730
2026-09-02 14:44:41 +05:00
parent 66126d21bc
commit 6b62723aae
5 changed files with 27 additions and 12 deletions
+2 -1
View File
@@ -31,6 +31,7 @@ import ifcopenshell.guid
import ifcopenshell.util.brick import ifcopenshell.util.brick
import ifcopenshell.util.element import ifcopenshell.util.element
import ifcopenshell.util.system import ifcopenshell.util.system
from brickschema.persistent import Changeset
import bonsai.core.brick import bonsai.core.brick
import bonsai.core.tool import bonsai.core.tool
@@ -580,7 +581,7 @@ class BrickStore:
@classmethod @classmethod
@contextmanager @contextmanager
def new_changeset(cls) -> Generator[Any, None, None]: def new_changeset(cls) -> Generator[Changeset]:
cls.current_changesets += 1 cls.current_changesets += 1
with BrickStore.graph.new_changeset("PROJECT") as cs: with BrickStore.graph.new_changeset("PROJECT") as cs:
yield cs yield cs
@@ -15,14 +15,21 @@
# #
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from typing import TYPE_CHECKING
import ifcopenshell import ifcopenshell
if TYPE_CHECKING:
from ifcopenshell.util.unit import DimensionalExponents
def add_context_dependent_unit( def add_context_dependent_unit(
file: ifcopenshell.file, file: ifcopenshell.file,
unit_type: str = "USERDEFINED", unit_type: str = "USERDEFINED",
name: str = "THINGAMAJIG", name: str = "THINGAMAJIG",
dimensions: tuple[int, int, int, int, int, int, int] = (0, 0, 0, 0, 0, 0, 0), dimensions: DimensionalExponents = (0, 0, 0, 0, 0, 0, 0),
) -> ifcopenshell.entity_instance: ) -> ifcopenshell.entity_instance:
"""Add a new arbitrary unit that can only be interpreted in a project specific context """Add a new arbitrary unit that can only be interpreted in a project specific context
+3 -2
View File
@@ -123,7 +123,7 @@ class sqlite(file):
# For creating C++ instances so that some of the calls here work # For creating C++ instances so that some of the calls here work
self.shadow_file = ifcopenshell.file(schema_identifier=self.schema) self.shadow_file = ifcopenshell.file(schema_identifier=self.schema)
# But we only create them once per type because we basically only need access to 'semi-static' such as get_attribute_category() # But we only create them once per type because we basically only need access to 'semi-static' such as get_attribute_category()
self.instance_map = {} self.instance_map: dict[str, ifcopenshell.entity_instance] = {}
self.cursor.execute("SELECT ifc_id, ifc_class FROM id_map") self.cursor.execute("SELECT ifc_id, ifc_class FROM id_map")
self.id_map: dict[int, str] = {} self.id_map: dict[int, str] = {}
@@ -186,7 +186,7 @@ class sqlite(file):
"""Not supported for sqlite database.""" """Not supported for sqlite database."""
assert False, "Not supported for sqlite database." assert False, "Not supported for sqlite database."
def _create_entity(self, type): def _create_entity(self, type: str) -> ifcopenshell.entity_instance:
if inst := self.instance_map.get(type): if inst := self.instance_map.get(type):
return inst return inst
else: else:
@@ -348,6 +348,7 @@ class sqlite(file):
class sqlite_entity: class sqlite_entity:
sqlite_wrapper: sqlite_wrapper sqlite_wrapper: sqlite_wrapper
wrapped_data: ifcopenshell.entity_instance
def __init__(self, id: int, ifc_class: str, file: sqlite = None): def __init__(self, id: int, ifc_class: str, file: sqlite = None):
if not ifc_class: if not ifc_class:
@@ -188,13 +188,13 @@ try:
# For creating C++ instances so that some of the calls here work # For creating C++ instances so that some of the calls here work
self.shadow_file = ifcopenshell.file(schema=self.schema) self.shadow_file = ifcopenshell.file(schema=self.schema)
# But we only create them once per type because we basically only need access to 'semi-static' such as get_attribute_category() # But we only create them once per type because we basically only need access to 'semi-static' such as get_attribute_category()
self.instance_map = {} self.instance_map: dict[str, ifcopenshell.entity_instance] = {}
offset += len(line) + newline_character offset += len(line) + newline_character
self.preprocess_schema() self.preprocess_schema()
def _create_entity(self, type): def _create_entity(self, type: str) -> ifcopenshell.entity_instance:
if inst := self.instance_map.get(type): if inst := self.instance_map.get(type):
return inst return inst
else: else:
@@ -328,6 +328,7 @@ try:
class stream_entity: class stream_entity:
stream_wrapper: stream_wrapper stream_wrapper: stream_wrapper
wrapped_data: ifcopenshell.entity_instance
def __init__(self, id: int, ifc_class: str, file: stream = None): def __init__(self, id: int, ifc_class: str, file: stream = None):
if not ifc_class: if not ifc_class:
@@ -16,14 +16,19 @@
# You should have received a copy of the GNU Lesser General Public License # You should have received a copy of the GNU Lesser General Public License
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>. # along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
from __future__ import annotations
from collections.abc import Generator from collections.abc import Generator
from fractions import Fraction from fractions import Fraction
from math import pi from math import pi
from typing import Literal, Optional, Union from typing import TYPE_CHECKING, Literal, Optional, TypeAlias, Union
import ifcopenshell import ifcopenshell
import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper import ifcopenshell.ifcopenshell_wrapper as ifcopenshell_wrapper
if TYPE_CHECKING:
DimensionalExponents: TypeAlias = tuple[int, int, int, int, int, int, int]
prefixes = { prefixes = {
"EXA": 1e18, "EXA": 1e18,
"PETA": 1e15, "PETA": 1e15,
@@ -76,7 +81,7 @@ unit_names = [
"WEBER", "WEBER",
] ]
si_dimensions = { si_dimensions: dict[str, DimensionalExponents] = {
"METRE": (1, 0, 0, 0, 0, 0, 0), "METRE": (1, 0, 0, 0, 0, 0, 0),
"SQUARE_METRE": (2, 0, 0, 0, 0, 0, 0), "SQUARE_METRE": (2, 0, 0, 0, 0, 0, 0),
"CUBIC_METRE": (3, 0, 0, 0, 0, 0, 0), "CUBIC_METRE": (3, 0, 0, 0, 0, 0, 0),
@@ -146,7 +151,7 @@ si_type_names = {
# See IfcDimensionalExponents: # See IfcDimensionalExponents:
# (Length, Mass, Time, ElectricCurrent, ThermodynamicTemperature, AmountOfSubstance, LuminousIntensity) # (Length, Mass, Time, ElectricCurrent, ThermodynamicTemperature, AmountOfSubstance, LuminousIntensity)
named_dimensions = { named_dimensions: dict[str, DimensionalExponents] = {
"ABSORBEDDOSEUNIT": (2, 0, -2, 0, 0, 0, 0), "ABSORBEDDOSEUNIT": (2, 0, -2, 0, 0, 0, 0),
"AMOUNTOFSUBSTANCEUNIT": (0, 0, 0, 0, 0, 1, 0), "AMOUNTOFSUBSTANCEUNIT": (0, 0, 0, 0, 0, 1, 0),
"AREAUNIT": (2, 0, 0, 0, 0, 0, 0), "AREAUNIT": (2, 0, 0, 0, 0, 0, 0),
@@ -398,15 +403,15 @@ def get_full_unit_name(unit: ifcopenshell.entity_instance) -> str:
return prefix + unit.Name.upper() return prefix + unit.Name.upper()
def get_si_dimensions(name): def get_si_dimensions(name: str) -> DimensionalExponents:
return si_dimensions.get(name, si_dimensions["OTHERWISE"]) return si_dimensions.get(name, si_dimensions["OTHERWISE"])
def get_named_dimensions(name): def get_named_dimensions(name: str) -> DimensionalExponents:
return named_dimensions.get(name, (0, 0, 0, 0, 0, 0, 0)) return named_dimensions.get(name, (0, 0, 0, 0, 0, 0, 0))
def get_unit_dimensions(unit: ifcopenshell.entity_instance) -> tuple[int, int, int, int, int, int, int]: def get_unit_dimensions(unit: ifcopenshell.entity_instance) -> DimensionalExponents:
"""Get the dimensional exponents of a unit, per IfcDimensionalExponents. """Get the dimensional exponents of a unit, per IfcDimensionalExponents.
Supports IfcSIUnit, IfcConversionBasedUnit, IfcContextDependentUnit, and Supports IfcSIUnit, IfcConversionBasedUnit, IfcContextDependentUnit, and