mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Merge remote-tracking branch 'origin/v0.8.0' into ifcviewer-wgpu
This commit is contained in:
@@ -100,6 +100,9 @@ del _patch_swig_comparisons
|
||||
# End hacks!
|
||||
from .sql import sqlite, sqlite_entity
|
||||
|
||||
get_log = ifcopenshell_wrapper.get_log
|
||||
logger = getattr(ifcopenshell_wrapper, "logger", None)
|
||||
|
||||
# explicitly specify available imported symbols
|
||||
# (it's a requirement for a typed library)
|
||||
__all__ = [
|
||||
@@ -150,10 +153,20 @@ class SchemaError(Error):
|
||||
|
||||
@overload
|
||||
def open(
|
||||
path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[False] = False
|
||||
path: Union[os.PathLike, str],
|
||||
format: SupportedFormat = None,
|
||||
*,
|
||||
should_stream: Literal[False] = False,
|
||||
logger: Optional[logger] = None,
|
||||
) -> Union[_file, sqlite]: ...
|
||||
@overload
|
||||
def open(path: Union[os.PathLike, str], format: SupportedFormat = None, *, should_stream: Literal[True]) -> _stream: ...
|
||||
def open(
|
||||
path: Union[os.PathLike, str],
|
||||
format: SupportedFormat = None,
|
||||
*,
|
||||
should_stream: Literal[True],
|
||||
logger: Optional[logger] = None,
|
||||
) -> _stream: ...
|
||||
@overload
|
||||
def open(
|
||||
path: Union[os.PathLike, str],
|
||||
@@ -161,6 +174,7 @@ def open(
|
||||
*,
|
||||
should_stream: bool = False,
|
||||
readonly: bool = False,
|
||||
logger: Optional[logger] = None,
|
||||
) -> Union[_file, sqlite, _stream]: ...
|
||||
def open(
|
||||
path: Union[os.PathLike, str],
|
||||
@@ -169,11 +183,13 @@ def open(
|
||||
readonly: bool = False,
|
||||
mmap: bool = False,
|
||||
bypass_types: Optional[Sequence[str]] = None,
|
||||
logger: Optional[logger] = None,
|
||||
) -> Union[_file, sqlite, _stream]:
|
||||
"""Loads an IFC dataset from a filepath
|
||||
|
||||
:param should_stream: Whether to open the file in streaming mode. Could be useful
|
||||
for reading large files.
|
||||
:param logger: Logger that receives native parser messages.
|
||||
|
||||
You can specify a file format. If no format is given, it is guessed from
|
||||
its extension.
|
||||
@@ -198,8 +214,10 @@ def open(
|
||||
raise FileNotFoundError(f"Path does not exist: '{path}'.")
|
||||
if format is None:
|
||||
format = guess_format(path)
|
||||
if logger is None and (logger_type := getattr(ifcopenshell_wrapper, "logger", None)):
|
||||
logger = logger_type.Root()
|
||||
if format == ".ifcXML":
|
||||
f = ifcopenshell_wrapper.parse_ifcxml(str(path.absolute()))
|
||||
f = ifcopenshell_wrapper.parse_ifcxml(str(path.absolute()), *((logger,) if logger is not None else ()))
|
||||
if f:
|
||||
return file(f)
|
||||
raise OSError(f"Failed to parse .ifcXML file from {path}")
|
||||
@@ -208,7 +226,7 @@ def open(
|
||||
with zipfile.ZipFile(path) as zf:
|
||||
for name in zf.namelist():
|
||||
if Path(name).suffix.lower() in (".ifc", ".ifcxml"):
|
||||
return open(zf.extract(name, unzipped_path))
|
||||
return open(zf.extract(name, unzipped_path), logger=logger)
|
||||
else:
|
||||
raise LookupError(f"No .ifc or .ifcXML file found in {path}")
|
||||
if format == ".ifcSQLite":
|
||||
@@ -216,9 +234,11 @@ def open(
|
||||
if should_stream:
|
||||
return stream(path)
|
||||
if readonly: # Temporary conditional see #7131. Remove once newer builds don't segfault on Linux.
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), readonly=readonly)
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), readonly, *((logger,) if logger is not None else ()))
|
||||
elif bypass_types:
|
||||
f = ifcopenshell_wrapper.file(ifcopenshell_wrapper.uninitialized_tag())
|
||||
f = ifcopenshell_wrapper.file(
|
||||
ifcopenshell_wrapper.uninitialized_tag(), *((logger,) if logger is not None else ())
|
||||
)
|
||||
for ty in bypass_types:
|
||||
f.bypass_type(ty)
|
||||
if mmap:
|
||||
@@ -228,9 +248,12 @@ def open(
|
||||
f.initialize(str(path.absolute()))
|
||||
elif mmap:
|
||||
# mmap parameter is only available for builds with USE_MMAP, not used in our main builds
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), mmap=mmap) # ty: ignore[unknown-argument]
|
||||
kwargs = {"mmap": mmap}
|
||||
if logger is not None:
|
||||
kwargs["logger"] = logger
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), **kwargs) # ty: ignore[unknown-argument]
|
||||
else:
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()))
|
||||
f = ifcopenshell_wrapper.open(str(path.absolute()), False, *((logger,) if logger is not None else ()))
|
||||
|
||||
f.post_init()
|
||||
|
||||
@@ -416,4 +439,3 @@ def convert_path_to_rocksdb(
|
||||
|
||||
version_core = ifcopenshell_wrapper.version()
|
||||
__version__ = version = "0.0.0"
|
||||
get_log = ifcopenshell_wrapper.get_log
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
# 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 numpy as np
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.placement
|
||||
from ifcopenshell import entity_instance
|
||||
@@ -36,7 +34,7 @@ def update_fallback_position(file: ifcopenshell.file, lp: entity_instance):
|
||||
if not lp.CartesianPosition:
|
||||
lp.CartesianPosition = file.createIfcAxis2Placement3D(Location=file.createIfcCartesianPoint((0.0, 0.0, 0.0)))
|
||||
|
||||
p = np.array(ifcopenshell.util.placement.get_axis2placement(lp.RelativePlacement))
|
||||
p = ifcopenshell.util.placement.get_local_placement(lp)
|
||||
|
||||
x = float(p[0, 3])
|
||||
y = float(p[1, 3])
|
||||
|
||||
@@ -16,10 +16,15 @@
|
||||
# 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.api.cost
|
||||
import ifcopenshell.api.control
|
||||
import ast
|
||||
import operator
|
||||
from typing import Any
|
||||
|
||||
import ifcopenshell.api.control
|
||||
import ifcopenshell.api.cost
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def assign_cost_item_quantity(
|
||||
@@ -27,6 +32,8 @@ def assign_cost_item_quantity(
|
||||
cost_item: ifcopenshell.entity_instance,
|
||||
products: list[ifcopenshell.entity_instance],
|
||||
prop_name: str = "",
|
||||
formula: str = "",
|
||||
ifc_class: str = "IfcQuantityLength",
|
||||
) -> None:
|
||||
"""Adds a cost item quantity that is parametrically connected to a product
|
||||
|
||||
@@ -57,6 +64,12 @@ def assign_cost_item_quantity(
|
||||
:param prop_name: The name of the quantity. If this is not specified,
|
||||
then it is assumed that there is no calculated quantity, and the
|
||||
number of objects are counted instead.
|
||||
:param formula: The string that contains the formula
|
||||
:param ifc_class: The quantity class of the calculated value if the formula is
|
||||
specified. Can be ['IfcQuantityCount', 'IfcQuantityNumber',
|
||||
'IfcQuantityLength', 'IfcQuantityArea', 'IfcQuantityVolume',
|
||||
'IfcQuantityWeight', 'IfcQuantityTime']. Check
|
||||
ifcopenshell.util.unit.QUANTITY_CLASS for more info.
|
||||
:return: None
|
||||
|
||||
Example:
|
||||
@@ -84,6 +97,18 @@ def assign_cost_item_quantity(
|
||||
# item.
|
||||
ifcopenshell.api.cost.assign_cost_item_quantity(model,
|
||||
cost_item=item, products=[slab], prop_name="NetVolume")
|
||||
|
||||
# Now let's use the formula in order to calculate the quantity value.
|
||||
# For example, let's say that a IfcWall has the reinfocement volume ratio
|
||||
# stored in the Pset_ConcreteElementGeneral.ReinforcementVolumeRatio
|
||||
# and of course it has also the gross volume stored in the
|
||||
# Qto_WallBaseQuantities.GrossVolume. So we can add an IfcQuantity that stores the
|
||||
# reinforcement volume calculated with reinfocement volume ratio * gross volume.
|
||||
ifcopenshell.api.cost.assign_cost_item_quantity(model,
|
||||
cost_item=item, products=[wall],
|
||||
formula="Pset_ConcreteElementGeneral.ReinforcementVolumeRatio * NetVolume"
|
||||
ifc_class="IfcQuantityVolume")
|
||||
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
@@ -91,6 +116,8 @@ def assign_cost_item_quantity(
|
||||
"cost_item": cost_item,
|
||||
"products": products or [],
|
||||
"prop_name": prop_name,
|
||||
"formula": formula,
|
||||
"ifc_class" : ifc_class
|
||||
}
|
||||
return usecase.execute()
|
||||
|
||||
@@ -100,12 +127,50 @@ class Usecase:
|
||||
settings: dict[str, Any]
|
||||
|
||||
def execute(self):
|
||||
if self.settings["prop_name"]:
|
||||
if self.settings["prop_name"] or self.settings["formula"]:
|
||||
self.quantities = set(self.settings["cost_item"].CostQuantities or [])
|
||||
for product in self.settings["products"]:
|
||||
if product.is_a("IfcSpatialElement"):
|
||||
continue
|
||||
self.assign_cost_control(related_object=product, cost_item=self.settings["cost_item"])
|
||||
if self.settings["formula"]:
|
||||
tree = ast.parse(self.settings["formula"], mode = "eval")
|
||||
collector = VariableExtractor()
|
||||
collector.visit(tree)
|
||||
variables = collector.variables
|
||||
|
||||
for variable in variables:
|
||||
getter = self.get_value_from_pset if "." in variable else self.get_value_from_qset
|
||||
value = getter(product, variable)
|
||||
|
||||
if value is None:
|
||||
print(
|
||||
f"WARNING: Variable '{variable}' in product '{product.Name}' "
|
||||
f"is missing (None). Check Pset/Qset or property name."
|
||||
)
|
||||
elif value == 0:
|
||||
print(
|
||||
f"WARNING: Variable '{variable}' in product '{product.Name}' "
|
||||
f"has value 0. Verify if this is correct."
|
||||
)
|
||||
|
||||
evaluator = FormulaEvaluator(values)
|
||||
result = evaluator.visit(tree.body)
|
||||
|
||||
new_quantity = None
|
||||
for quantity in self.quantities:
|
||||
if quantity.Formula == self.settings["formula"] and len(self.settings["products"]) == 1: #Todo improve it
|
||||
new_quantity = quantity
|
||||
self.settings["ifc_class"] = quantity.is_a()
|
||||
continue
|
||||
if new_quantity is None:
|
||||
new_quantity = self.file.create_entity(self.settings["ifc_class"], Name="Unnamed")
|
||||
new_quantity.Formula = self.settings["formula"]
|
||||
self.quantities.add(new_quantity)
|
||||
|
||||
new_quantity[3] = result
|
||||
continue
|
||||
|
||||
if self.settings["prop_name"]:
|
||||
if (
|
||||
self.settings["cost_item"].CostQuantities
|
||||
@@ -113,11 +178,30 @@ class Usecase:
|
||||
):
|
||||
continue
|
||||
self.add_quantity_from_related_object(product)
|
||||
if self.settings["prop_name"]:
|
||||
if self.settings["prop_name"] or self.settings["formula"]:
|
||||
self.settings["cost_item"].CostQuantities = list(self.quantities)
|
||||
else:
|
||||
self.update_cost_item_count()
|
||||
|
||||
def get_value_from_pset(
|
||||
self,
|
||||
product:ifcopenshell.entity_instance,
|
||||
v: str,
|
||||
) -> float:
|
||||
pset_name = v.split(".")[0]
|
||||
pset = ifcopenshell.util.element.get_pset(product, pset_name)
|
||||
pset_property_name = v.split(".")[1]
|
||||
return (pset or {}).get(pset_property_name,None)
|
||||
|
||||
def get_value_from_qset(
|
||||
self,
|
||||
product:ifcopenshell.entity_instance,
|
||||
v: str,
|
||||
) -> float:
|
||||
qtos = ifcopenshell.util.element.get_psets(product, qtos_only = True)
|
||||
quantities = next(iter(qtos.values()), {})
|
||||
return (quantities or {}).get(v,None)
|
||||
|
||||
def assign_cost_control(
|
||||
self, related_object: ifcopenshell.entity_instance, cost_item: ifcopenshell.entity_instance
|
||||
) -> ifcopenshell.entity_instance:
|
||||
@@ -158,3 +242,55 @@ class Usecase:
|
||||
if not obj.is_a("IfcConstructionResource"):
|
||||
count += 1
|
||||
quantity[3] = count
|
||||
|
||||
OPERATORS = {
|
||||
ast.Add: operator.add,
|
||||
ast.Sub: operator.sub,
|
||||
ast.Mult: operator.mul,
|
||||
ast.Div: operator.truediv,
|
||||
ast.Pow: operator.pow,
|
||||
ast.USub: operator.neg,
|
||||
}
|
||||
|
||||
def build_full_name(node):
|
||||
#used for variables with dots
|
||||
parts = []
|
||||
while isinstance(node, ast.Attribute):
|
||||
parts.append(node.attr)
|
||||
node = node.value
|
||||
|
||||
if isinstance(node, ast.Name):
|
||||
parts.append(node.id)
|
||||
|
||||
return ".".join(reversed(parts))
|
||||
|
||||
class VariableExtractor(ast.NodeVisitor):
|
||||
def __init__(self):
|
||||
self.variables = set()
|
||||
|
||||
def visit_Name(self, node):
|
||||
self.variables.add(node.id)
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
self.variables.add(build_full_name(node))
|
||||
|
||||
class FormulaEvaluator(ast.NodeVisitor):
|
||||
def __init__(self, values):
|
||||
self.values = values
|
||||
|
||||
def visit_BinOp(self, node):
|
||||
left = self.visit(node.left)
|
||||
right = self.visit(node.right)
|
||||
return OPERATORS[type(node.op)](left, right)
|
||||
|
||||
def visit_Name(self, node):
|
||||
return self.values[node.id]
|
||||
|
||||
def visit_Attribute(self, node):
|
||||
return self.values[build_full_name(node)]
|
||||
|
||||
def visit_Constant(self, node):
|
||||
return node.value
|
||||
|
||||
def generic_visit(self, node):
|
||||
raise ValueError(f"Operation not permitted: {type(node).__name__}")
|
||||
|
||||
@@ -44,7 +44,7 @@ def regenerate_wall_representation(
|
||||
length: float = 1.0,
|
||||
height: float = 1.0,
|
||||
angle: Optional[float] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
) -> Optional[ifcopenshell.entity_instance]:
|
||||
"""
|
||||
Regenerate the body representation of a wall taking into account connections.
|
||||
|
||||
@@ -94,7 +94,10 @@ def regenerate_wall_representation(
|
||||
default height in SI units.
|
||||
:param angle: If the wall doesn't already have a slope, this is the default
|
||||
angle in radians. Left as none or 0 defines no slope.
|
||||
:return: The newly generated body IfcShapeRepresentation
|
||||
:return: The newly generated body IfcShapeRepresentation, or ``None`` if
|
||||
the wall has no ``IfcMaterialLayerSet`` (the layer-set rebuild is the
|
||||
only mode this function knows; without layers there is nothing to
|
||||
regenerate and callers should leave the existing representation alone).
|
||||
"""
|
||||
return Regenerator(file).regenerate(wall, length=length, height=height, angle=angle)
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import ifcopenshell.api.owner
|
||||
import ifcopenshell.api.type
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.type
|
||||
|
||||
|
||||
def assign_type(
|
||||
@@ -189,6 +190,32 @@ class Usecase:
|
||||
if not related_objects:
|
||||
return
|
||||
|
||||
# The EXPRESS schema has no WHERE rule pairing RelatingType /
|
||||
# RelatedObjects classes; the canonical class pairing per schema
|
||||
# is a buildingSMART implementer agreement, enforced here.
|
||||
allowed_occurrences = set(
|
||||
ifcopenshell.util.type.get_applicable_entities(relating_type.is_a(), schema=self.file.schema)
|
||||
)
|
||||
# The implementer agreement map has no entry for the abstract
|
||||
# IfcTypeProduct, which Bonsai uses for annotation types. The schema
|
||||
# itself defines IfcTypeProduct.ApplicableOccurrence for exactly this
|
||||
# purpose, so honor it when the leading class token is a valid entity.
|
||||
if applicable_occurrence := getattr(relating_type, "ApplicableOccurrence", None):
|
||||
occurrence_class = applicable_occurrence.split("/", 1)[0]
|
||||
schema = ifcopenshell.schema_by_name(self.file.schema)
|
||||
try:
|
||||
schema.declaration_by_name(occurrence_class)
|
||||
allowed_occurrences.add(occurrence_class)
|
||||
except RuntimeError:
|
||||
pass
|
||||
mismatched_classes = sorted({o.is_a() for o in related_objects if o.is_a() not in allowed_occurrences})
|
||||
if mismatched_classes:
|
||||
raise TypeError(
|
||||
f"{relating_type.is_a()} cannot type {', '.join(mismatched_classes)} "
|
||||
f"in schema {self.file.schema} (allowed occurrence classes: "
|
||||
f"{', '.join(sorted(allowed_occurrences)) or '<none>'})"
|
||||
)
|
||||
|
||||
ifc2x3 = self.file.schema == "IFC2X3"
|
||||
related_objects_set = set(related_objects)
|
||||
if ifc2x3:
|
||||
|
||||
@@ -104,7 +104,10 @@ def main(
|
||||
iterators: Sequence[ifcopenshell.geom.iterator] = (),
|
||||
merge_projection: bool = True,
|
||||
progress_function: Callable = DO_NOTHING,
|
||||
logger=None,
|
||||
):
|
||||
if logger is None and ifcopenshell.logger is not None:
|
||||
logger = ifcopenshell.logger.Root()
|
||||
|
||||
def by_guid(g):
|
||||
for f in files:
|
||||
@@ -146,7 +149,7 @@ def main(
|
||||
iterator_kwargs["include"] = list(
|
||||
filter(has_selected_parent, sum((f.by_type(x) for x in iterator_kwargs["include"]), []))
|
||||
)
|
||||
return ifcopenshell.geom.iterator(geom_settings, f, **iterator_kwargs)
|
||||
return ifcopenshell.geom.iterator(geom_settings, f, logger=logger, **iterator_kwargs)
|
||||
|
||||
# We have to keep the iterator in memory because otherwise
|
||||
# the styles are cleared up.
|
||||
@@ -448,7 +451,6 @@ def main(
|
||||
g1.appendChild(g2)
|
||||
|
||||
if settings.arrange_spaces or settings.arrange_zones:
|
||||
|
||||
if settings.storey_filter:
|
||||
# delete storey groups not selected by filter
|
||||
# sometimes happens in case of elements protruding multiple stories
|
||||
@@ -531,6 +533,7 @@ def main(
|
||||
arranged = W.arrange_polygons(
|
||||
*filter(None, (ARRANGE_POLYGON_SETTINGS,)),
|
||||
polies, # ty: ignore[too-many-positional-arguments]
|
||||
*((logger,) if logger is not None else ()),
|
||||
)
|
||||
svg_data_3 = W.polygons_to_svg(arranged, False)
|
||||
dom3 = parseString(svg_data_3)
|
||||
|
||||
@@ -213,8 +213,11 @@ class entity_instance_mixin:
|
||||
return value
|
||||
|
||||
def __eq__(self, other: entity_instance_mixin) -> bool:
|
||||
if other is None or not isinstance(other, entity_instance_mixin):
|
||||
return False
|
||||
if not isinstance(other, entity_instance_mixin):
|
||||
if not self.is_entity():
|
||||
return self[0] == other
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
raise NotImplementedError
|
||||
|
||||
@@ -305,7 +308,7 @@ class entity_instance_mixin:
|
||||
)
|
||||
)
|
||||
|
||||
def get_info(
|
||||
def get_info_py(
|
||||
self,
|
||||
include_identifier: bool = True,
|
||||
recursive: bool = False,
|
||||
@@ -382,64 +385,22 @@ class entity_instance_mixin:
|
||||
|
||||
__dict__ = property(get_info)
|
||||
|
||||
def get_info_2(
|
||||
def get_info(
|
||||
self,
|
||||
include_identifier: bool = True,
|
||||
recursive: bool = False,
|
||||
return_type: type[dict] = dict,
|
||||
ignore: Sequence[str] = (),
|
||||
) -> dict[str, Any]:
|
||||
"""More perfomant version of `.get_info()` but with limited arguments values.\n
|
||||
Method has exactly the same signature as `.get_info()` but it doesn't support getting information non-recursively.
|
||||
|
||||
Currently supported arguments values:
|
||||
* recursive: `True` (will fail with default `False` value from `.get_info()`)
|
||||
* return_type: `dict`
|
||||
* ignore: `()` (empty tuple)
|
||||
"""More perfomant version of `.get_info()`.\n
|
||||
Method has exactly the same signature as `.get_info()`, but the fast C++
|
||||
path only implements ``recursive=True``, ``return_type=dict`` and
|
||||
``ignore=()``. Any other combination falls back to the pure Python
|
||||
`.get_info()`, where no meaningful performance gain is possible anyway
|
||||
as the cost is dominated by the recursive traversal.
|
||||
"""
|
||||
|
||||
assert return_type is dict
|
||||
assert len(ignore) == 0
|
||||
return ifcopenshell_wrapper.get_info_cpp(self, recursive, include_identifier)
|
||||
|
||||
|
||||
# Alias for backwards compatibility — external code imports this name.
|
||||
entity_instance = entity_instance_mixin
|
||||
|
||||
|
||||
# Monkey-patch SWIG's __eq__, __ne__, __lt__ on the generated entity_instance
|
||||
# class to guard against None / non-entity arguments. SWIG generates these
|
||||
# directly on the class (overriding the mixin), and they pass arguments straight
|
||||
# to C++ which rejects null references.
|
||||
# Deferred until after ifcopenshell_wrapper finishes loading to avoid circular import.
|
||||
_swig_comparisons_patched = False
|
||||
|
||||
|
||||
def _patch_swig_comparisons():
|
||||
global _swig_comparisons_patched
|
||||
if _swig_comparisons_patched:
|
||||
return
|
||||
_swig_cls = ifcopenshell_wrapper.entity_instance
|
||||
_orig_eq = _swig_cls.__eq__
|
||||
_orig_ne = _swig_cls.__ne__
|
||||
_orig_lt = _swig_cls.__lt__
|
||||
|
||||
def _safe_eq(self, other):
|
||||
if other is None or not isinstance(other, _swig_cls):
|
||||
return NotImplemented
|
||||
return _orig_eq(self, other)
|
||||
|
||||
def _safe_ne(self, other):
|
||||
if other is None or not isinstance(other, _swig_cls):
|
||||
return NotImplemented
|
||||
return _orig_ne(self, other)
|
||||
|
||||
def _safe_lt(self, other):
|
||||
if other is None or not isinstance(other, _swig_cls):
|
||||
return NotImplemented
|
||||
return _orig_lt(self, other)
|
||||
|
||||
_swig_cls.__eq__ = _safe_eq
|
||||
_swig_cls.__ne__ = _safe_ne
|
||||
_swig_cls.__lt__ = _safe_lt
|
||||
_swig_comparisons_patched = True
|
||||
if recursive and return_type is dict and not ignore:
|
||||
return ifcopenshell_wrapper.get_info_cpp(self.wrapped_data, include_identifier)
|
||||
return self.get_info_py(
|
||||
include_identifier=include_identifier, recursive=recursive, return_type=return_type, ignore=ignore
|
||||
)
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import operator
|
||||
import itertools
|
||||
|
||||
@@ -158,6 +156,7 @@ actions = {
|
||||
to_emit = set(id for id, expr in express)
|
||||
emitted = set()
|
||||
to_combine = set(["simple_id"])
|
||||
to_original_text = set(["simple_string_literal"])
|
||||
statements = []
|
||||
|
||||
terminals = reduce(lambda x, y: x | y, (find_bytype(e, Terminal) for id, e in express))
|
||||
@@ -176,6 +175,9 @@ while True:
|
||||
stmt = "(%s)" % expr
|
||||
if id in to_combine:
|
||||
stmt = " + ".join(itertools.chain(negated_keywords, ("originalTextFor(Combine%s)" % stmt,)))
|
||||
elif id in to_original_text:
|
||||
# We use lower() because it better matches the previous default of the CaselessLiterals for individual lexemes and express dictates case-insensitive comparisons anyway
|
||||
stmt = "(originalTextFor%s).addParseAction(tokenMap(str.lower))" % stmt
|
||||
if id not in no_action and not isinstance(expr.contents, Keyword) and not id in to_combine:
|
||||
node_type = "ListNode" if "ZeroOrMore" in stmt else "Node"
|
||||
action = actions.get(id, 'lambda s, loc, t: %s(s, loc, t, rule="%s")' % (node_type, id))
|
||||
@@ -193,6 +195,8 @@ for id in to_emit:
|
||||
stmt = "(%s)" % expr
|
||||
if id in to_combine:
|
||||
stmt = "Suppress%s" % stmt
|
||||
elif id in to_original_text:
|
||||
stmt = "(originalTextFor%s).addParseAction(tokenMap(str.lower))" % stmt
|
||||
if id not in no_action and not isinstance(expr.contents, Keyword):
|
||||
children = list(map(operator.attrgetter('contents'), reduce(lambda x, y: x | y, (find_bytype(e, Keyword) for e in [expr]))))
|
||||
has_duplicates = len(children) > len(set(children))
|
||||
@@ -204,7 +208,8 @@ for id in to_emit:
|
||||
statements.append("%s << %s" % (id, stmt))
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(r"""
|
||||
print(
|
||||
r"""
|
||||
# This file is generated by IfcOpenShell ifcexpressparser bootstrap.py
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -243,5 +248,6 @@ if __name__ == "__main__":
|
||||
mdl = importlib.import_module(output)
|
||||
mdl.Generator(m).emit()
|
||||
sys.stdout.write(m.schema.name)
|
||||
""" % ("\n ".join(statements))
|
||||
"""
|
||||
% ("\n ".join(statements))
|
||||
)
|
||||
|
||||
@@ -153,8 +153,8 @@ def parse(fn: str) -> mapping.Mapping:
|
||||
special = ((not_paren_star_quote_special | CaselessLiteral("(") | CaselessLiteral(")") | CaselessLiteral("*") | CaselessLiteral("\"\""))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="special"))("special")
|
||||
binary_literal = ((CaselessLiteral("%") + bit + ZeroOrMore(bit))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="binary_literal"))("binary_literal")
|
||||
integer_literal = (digits)("integer_literal")
|
||||
simple_id = ~CaselessKeyword("generic") + ~CaselessKeyword("value") + ~CaselessKeyword("case") + ~CaselessKeyword("for") + ~CaselessKeyword("sin") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("extensible") + ~CaselessKeyword("tan") + ~CaselessKeyword("local") + ~CaselessKeyword("string") + ~CaselessKeyword("procedure") + ~CaselessKeyword("derive") + ~CaselessKeyword("end_if") + ~CaselessKeyword("supertype") + ~CaselessKeyword("entity") + ~CaselessKeyword("oneof") + ~CaselessKeyword("constant") + ~CaselessKeyword("end_case") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("unknown") + ~CaselessKeyword("total_over") + ~CaselessKeyword("div") + ~CaselessKeyword("type") + ~CaselessKeyword("true") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("unique") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("number") + ~CaselessKeyword("end_function") + ~CaselessKeyword("where") + ~CaselessKeyword("self") + ~CaselessKeyword("usedin") + ~CaselessKeyword("end_type") + ~CaselessKeyword("logical") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("xor") + ~CaselessKeyword("until") + ~CaselessKeyword("to") + ~CaselessKeyword("in") + ~CaselessKeyword("inverse") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("var") + ~CaselessKeyword("value_in") + ~CaselessKeyword("const_e") + ~CaselessKeyword("use") + ~CaselessKeyword("exists") + ~CaselessKeyword("exp") + ~CaselessKeyword("while") + ~CaselessKeyword("if") + ~CaselessKeyword("fixed") + ~CaselessKeyword("subtype") + ~CaselessKeyword("format") + ~CaselessKeyword("as") + ~CaselessKeyword("and") + ~CaselessKeyword("rule") + ~CaselessKeyword("function") + ~CaselessKeyword("lobound") + ~CaselessKeyword("length") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("log2") + ~CaselessKeyword("reference") + ~CaselessKeyword("skip") + ~CaselessKeyword("with") + ~CaselessKeyword("integer") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("insert") + ~CaselessKeyword("nvl") + ~CaselessKeyword("log") + ~CaselessKeyword("boolean") + ~CaselessKeyword("from") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("hibound") + ~CaselessKeyword("abs") + ~CaselessKeyword("like") + ~CaselessKeyword("pi") + ~CaselessKeyword("alias") + ~CaselessKeyword("not") + ~CaselessKeyword("repeat") + ~CaselessKeyword("based_on") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("asin") + ~CaselessKeyword("optional") + ~CaselessKeyword("list") + ~CaselessKeyword("abstract") + ~CaselessKeyword("mod") + ~CaselessKeyword("false") + ~CaselessKeyword("log10") + ~CaselessKeyword("loindex") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("end_constant") + ~CaselessKeyword("end") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("remove") + ~CaselessKeyword("acos") + ~CaselessKeyword("set") + ~CaselessKeyword("renamed") + ~CaselessKeyword("end_local") + ~CaselessKeyword("of") + ~CaselessKeyword("escape") + ~CaselessKeyword("begin") + ~CaselessKeyword("select") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("else") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("cos") + ~CaselessKeyword("real") + ~CaselessKeyword("query") + ~CaselessKeyword("odd") + ~CaselessKeyword("andor") + ~CaselessKeyword("return") + ~CaselessKeyword("then") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("array") + ~CaselessKeyword("blength") + ~CaselessKeyword("or") + ~CaselessKeyword("typeof") + ~CaselessKeyword("binary") + ~CaselessKeyword("atan") + ~CaselessKeyword("by") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("bag") + ~CaselessKeyword("schema") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
|
||||
simple_string_literal = ((CaselessLiteral("'") + ZeroOrMore(((CaselessLiteral("'") + CaselessLiteral("'")) | not_quote)) + CaselessLiteral("'")))("simple_string_literal")
|
||||
simple_id = ~CaselessKeyword("format") + ~CaselessKeyword("loindex") + ~CaselessKeyword("in") + ~CaselessKeyword("where") + ~CaselessKeyword("by") + ~CaselessKeyword("subtype") + ~CaselessKeyword("local") + ~CaselessKeyword("sin") + ~CaselessKeyword("case") + ~CaselessKeyword("false") + ~CaselessKeyword("entity") + ~CaselessKeyword("exp") + ~CaselessKeyword("hiindex") + ~CaselessKeyword("generic_entity") + ~CaselessKeyword("number") + ~CaselessKeyword("end_rule") + ~CaselessKeyword("schema") + ~CaselessKeyword("from") + ~CaselessKeyword("length") + ~CaselessKeyword("insert") + ~CaselessKeyword("real") + ~CaselessKeyword("like") + ~CaselessKeyword("hibound") + ~CaselessKeyword("if") + ~CaselessKeyword("end_schema") + ~CaselessKeyword("generic") + ~CaselessKeyword("extensible") + ~CaselessKeyword("pi") + ~CaselessKeyword("of") + ~CaselessKeyword("logical") + ~CaselessKeyword("rolesof") + ~CaselessKeyword("log") + ~CaselessKeyword("integer") + ~CaselessKeyword("or") + ~CaselessKeyword("odd") + ~CaselessKeyword("list") + ~CaselessKeyword("procedure") + ~CaselessKeyword("renamed") + ~CaselessKeyword("optional") + ~CaselessKeyword("log10") + ~CaselessKeyword("end_function") + ~CaselessKeyword("value_unique") + ~CaselessKeyword("fixed") + ~CaselessKeyword("repeat") + ~CaselessKeyword("rule") + ~CaselessKeyword("mod") + ~CaselessKeyword("exists") + ~CaselessKeyword("with") + ~CaselessKeyword("nvl") + ~CaselessKeyword("end_repeat") + ~CaselessKeyword("not") + ~CaselessKeyword("type") + ~CaselessKeyword("otherwise") + ~CaselessKeyword("lobound") + ~CaselessKeyword("query") + ~CaselessKeyword("function") + ~CaselessKeyword("reference") + ~CaselessKeyword("enumeration") + ~CaselessKeyword("oneof") + ~CaselessKeyword("bag") + ~CaselessKeyword("then") + ~CaselessKeyword("end_if") + ~CaselessKeyword("sizeof") + ~CaselessKeyword("end_procedure") + ~CaselessKeyword("end_type") + ~CaselessKeyword("string") + ~CaselessKeyword("end_case") + ~CaselessKeyword("return") + ~CaselessKeyword("end_entity") + ~CaselessKeyword("log2") + ~CaselessKeyword("end_alias") + ~CaselessKeyword("inverse") + ~CaselessKeyword("derive") + ~CaselessKeyword("select") + ~CaselessKeyword("for") + ~CaselessKeyword("set") + ~CaselessKeyword("aggregate") + ~CaselessKeyword("self") + ~CaselessKeyword("array") + ~CaselessKeyword("abs") + ~CaselessKeyword("tan") + ~CaselessKeyword("subtype_constraint") + ~CaselessKeyword("remove") + ~CaselessKeyword("to") + ~CaselessKeyword("acos") + ~CaselessKeyword("skip") + ~CaselessKeyword("end_subtype_constraint") + ~CaselessKeyword("end_local") + ~CaselessKeyword("use") + ~CaselessKeyword("abstract") + ~CaselessKeyword("sqrt") + ~CaselessKeyword("var") + ~CaselessKeyword("until") + ~CaselessKeyword("while") + ~CaselessKeyword("end") + ~CaselessKeyword("typeof") + ~CaselessKeyword("supertype") + ~CaselessKeyword("based_on") + ~CaselessKeyword("true") + ~CaselessKeyword("alias") + ~CaselessKeyword("total_over") + ~CaselessKeyword("andor") + ~CaselessKeyword("cos") + ~CaselessKeyword("div") + ~CaselessKeyword("and") + ~CaselessKeyword("const_e") + ~CaselessKeyword("unique") + ~CaselessKeyword("as") + ~CaselessKeyword("boolean") + ~CaselessKeyword("constant") + ~CaselessKeyword("escape") + ~CaselessKeyword("atan") + ~CaselessKeyword("unknown") + ~CaselessKeyword("asin") + ~CaselessKeyword("usedin") + ~CaselessKeyword("xor") + ~CaselessKeyword("else") + ~CaselessKeyword("blength") + ~CaselessKeyword("value_in") + ~CaselessKeyword("value") + ~CaselessKeyword("begin") + ~CaselessKeyword("binary") + ~CaselessKeyword("end_constant") + originalTextFor(Combine((letter + ZeroOrMore((letter | digit | CaselessLiteral("_"))))))("simple_id")
|
||||
simple_string_literal = (originalTextFor((CaselessLiteral("'") + ZeroOrMore(((CaselessLiteral("'") + CaselessLiteral("'")) | not_quote)) + CaselessLiteral("'")))).addParseAction(tokenMap(str.lower))("simple_string_literal")
|
||||
abstract_entity_declaration = (ABSTRACT)("abstract_entity_declaration")
|
||||
abstract_supertype = ((ABSTRACT + SUPERTYPE + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype"))("abstract_supertype")
|
||||
add_like_op = ((CaselessLiteral("+") | CaselessLiteral("-") | OR | XOR)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="add_like_op"))("add_like_op")
|
||||
@@ -251,224 +251,224 @@ def parse(fn: str) -> mapping.Mapping:
|
||||
constructed_types = ((enumeration_type | select_type)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constructed_types"))("constructed_types")
|
||||
reference_clause = ((REFERENCE + FROM + schema_ref + Optional((CaselessLiteral("(") + resource_or_rename + ZeroOrMore((CaselessLiteral(",") + resource_or_rename)) + CaselessLiteral(")"))) + CaselessLiteral(";"))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="reference_clause"))("reference_clause")
|
||||
interface_specification = ((reference_clause | use_clause)).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="interface_specification"))("interface_specification")
|
||||
supertype_factor = Forward()("supertype_factor")
|
||||
interval_item = Forward()("interval_item")
|
||||
subtype_constraint = Forward()("subtype_constraint")
|
||||
repeat_stmt = Forward()("repeat_stmt")
|
||||
subsuper = Forward()("subsuper")
|
||||
increment = Forward()("increment")
|
||||
remark = Forward()("remark")
|
||||
increment_control = Forward()("increment_control")
|
||||
local_variable = Forward()("local_variable")
|
||||
until_control = Forward()("until_control")
|
||||
while_control = Forward()("while_control")
|
||||
parameter = Forward()("parameter")
|
||||
width = Forward()("width")
|
||||
string_type = Forward()("string_type")
|
||||
array_type = Forward()("array_type")
|
||||
if_stmt = Forward()("if_stmt")
|
||||
index = Forward()("index")
|
||||
repetition = Forward()("repetition")
|
||||
index_qualifier = Forward()("index_qualifier")
|
||||
bound_1 = Forward()("bound_1")
|
||||
procedure_decl = Forward()("procedure_decl")
|
||||
entity_constructor = Forward()("entity_constructor")
|
||||
inverse_clause = Forward()("inverse_clause")
|
||||
function_head = Forward()("function_head")
|
||||
formal_parameter = Forward()("formal_parameter")
|
||||
interval_high = Forward()("interval_high")
|
||||
entity_decl = Forward()("entity_decl")
|
||||
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
|
||||
index_1 = Forward()("index_1")
|
||||
general_aggregation_types = Forward()("general_aggregation_types")
|
||||
real_type = Forward()("real_type")
|
||||
type_decl = Forward()("type_decl")
|
||||
stmt = Forward()("stmt")
|
||||
declaration = Forward()("declaration")
|
||||
explicit_attr = Forward()("explicit_attr")
|
||||
compound_stmt = Forward()("compound_stmt")
|
||||
aggregation_types = Forward()("aggregation_types")
|
||||
simple_factor = Forward()("simple_factor")
|
||||
where_clause = Forward()("where_clause")
|
||||
entity_head = Forward()("entity_head")
|
||||
underlying_type = Forward()("underlying_type")
|
||||
subtype_constraint_decl = Forward()("subtype_constraint_decl")
|
||||
logical_expression = Forward()("logical_expression")
|
||||
case_label = Forward()("case_label")
|
||||
expression = Forward()("expression")
|
||||
general_list_type = Forward()("general_list_type")
|
||||
actual_parameter_list = Forward()("actual_parameter_list")
|
||||
width_spec = Forward()("width_spec")
|
||||
selector = Forward()("selector")
|
||||
syntax = Forward()("syntax")
|
||||
aggregate_source = Forward()("aggregate_source")
|
||||
return_stmt = Forward()("return_stmt")
|
||||
embedded_remark = Forward()("embedded_remark")
|
||||
parameter_type = Forward()("parameter_type")
|
||||
term = Forward()("term")
|
||||
derived_attr = Forward()("derived_attr")
|
||||
repeat_control = Forward()("repeat_control")
|
||||
assignment_stmt = Forward()("assignment_stmt")
|
||||
bag_type = Forward()("bag_type")
|
||||
inverse_attr = Forward()("inverse_attr")
|
||||
constant_body = Forward()("constant_body")
|
||||
precision_spec = Forward()("precision_spec")
|
||||
general_bag_type = Forward()("general_bag_type")
|
||||
qualifiable_factor = Forward()("qualifiable_factor")
|
||||
bound_2 = Forward()("bound_2")
|
||||
instantiable_type = Forward()("instantiable_type")
|
||||
general_set_type = Forward()("general_set_type")
|
||||
supertype_rule = Forward()("supertype_rule")
|
||||
factor = Forward()("factor")
|
||||
list_type = Forward()("list_type")
|
||||
one_of = Forward()("one_of")
|
||||
aggregate_type = Forward()("aggregate_type")
|
||||
entity_body = Forward()("entity_body")
|
||||
generalized_types = Forward()("generalized_types")
|
||||
case_stmt = Forward()("case_stmt")
|
||||
binary_type = Forward()("binary_type")
|
||||
local_decl = Forward()("local_decl")
|
||||
alias_stmt = Forward()("alias_stmt")
|
||||
simple_expression = Forward()("simple_expression")
|
||||
general_array_type = Forward()("general_array_type")
|
||||
interval = Forward()("interval")
|
||||
procedure_head = Forward()("procedure_head")
|
||||
function_decl = Forward()("function_decl")
|
||||
supertype_expression = Forward()("supertype_expression")
|
||||
set_type = Forward()("set_type")
|
||||
primary = Forward()("primary")
|
||||
procedure_call_stmt = Forward()("procedure_call_stmt")
|
||||
simple_types = Forward()("simple_types")
|
||||
query_expression = Forward()("query_expression")
|
||||
index_2 = Forward()("index_2")
|
||||
constant_decl = Forward()("constant_decl")
|
||||
case_action = Forward()("case_action")
|
||||
schema_body = Forward()("schema_body")
|
||||
element = Forward()("element")
|
||||
numeric_expression = Forward()("numeric_expression")
|
||||
aggregate_initializer = Forward()("aggregate_initializer")
|
||||
schema_decl = Forward()("schema_decl")
|
||||
supertype_term = Forward()("supertype_term")
|
||||
algorithm_head = Forward()("algorithm_head")
|
||||
supertype_constraint = Forward()("supertype_constraint")
|
||||
interval_low = Forward()("interval_low")
|
||||
domain_rule = Forward()("domain_rule")
|
||||
rule_decl = Forward()("rule_decl")
|
||||
supertype_term = Forward()("supertype_term")
|
||||
alias_stmt = Forward()("alias_stmt")
|
||||
subtype_constraint_decl = Forward()("subtype_constraint_decl")
|
||||
real_type = Forward()("real_type")
|
||||
until_control = Forward()("until_control")
|
||||
remark = Forward()("remark")
|
||||
syntax = Forward()("syntax")
|
||||
derived_attr = Forward()("derived_attr")
|
||||
subtype_constraint = Forward()("subtype_constraint")
|
||||
aggregation_types = Forward()("aggregation_types")
|
||||
width = Forward()("width")
|
||||
simple_expression = Forward()("simple_expression")
|
||||
explicit_attr = Forward()("explicit_attr")
|
||||
precision_spec = Forward()("precision_spec")
|
||||
general_list_type = Forward()("general_list_type")
|
||||
concrete_types = Forward()("concrete_types")
|
||||
qualifier = Forward()("qualifier")
|
||||
subtype_constraint_body = Forward()("subtype_constraint_body")
|
||||
function_call = Forward()("function_call")
|
||||
bound_spec = Forward()("bound_spec")
|
||||
while_control = Forward()("while_control")
|
||||
aggregate_type = Forward()("aggregate_type")
|
||||
increment_control = Forward()("increment_control")
|
||||
index_qualifier = Forward()("index_qualifier")
|
||||
supertype_rule = Forward()("supertype_rule")
|
||||
subsuper = Forward()("subsuper")
|
||||
interval_low = Forward()("interval_low")
|
||||
bound_2 = Forward()("bound_2")
|
||||
index_1 = Forward()("index_1")
|
||||
return_stmt = Forward()("return_stmt")
|
||||
type_decl = Forward()("type_decl")
|
||||
increment = Forward()("increment")
|
||||
factor = Forward()("factor")
|
||||
underlying_type = Forward()("underlying_type")
|
||||
declaration = Forward()("declaration")
|
||||
function_decl = Forward()("function_decl")
|
||||
entity_constructor = Forward()("entity_constructor")
|
||||
derive_clause = Forward()("derive_clause")
|
||||
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
|
||||
interval_item << (simple_expression)
|
||||
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
|
||||
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
|
||||
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
|
||||
increment << (numeric_expression)
|
||||
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
|
||||
increment_control << (((variable_id + CaselessLiteral(":=") + bound_1 + TO + bound_2 + Optional((BY + increment))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="increment_control"))
|
||||
local_variable << (((variable_id + ZeroOrMore((CaselessLiteral(",") + variable_id)) + CaselessLiteral(":") + parameter_type + Optional((CaselessLiteral(":=") + expression)) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_variable"))
|
||||
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
|
||||
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
|
||||
parameter << (expression)
|
||||
width << (numeric_expression)
|
||||
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
|
||||
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
|
||||
if_stmt << (((IF + logical_expression + THEN + stmt + ZeroOrMore(stmt) + Optional((ELSE + stmt + ZeroOrMore(stmt))) + END_IF + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="if_stmt"))
|
||||
index << (numeric_expression)
|
||||
repetition << (numeric_expression)
|
||||
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
|
||||
bound_1 << (numeric_expression)
|
||||
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
|
||||
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
|
||||
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
|
||||
function_head << (((FUNCTION + function_id + Optional((CaselessLiteral("(") + formal_parameter + ZeroOrMore((CaselessLiteral(";") + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(":") + parameter_type + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="function_head"))
|
||||
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
|
||||
interval_high << (simple_expression)
|
||||
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
|
||||
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
|
||||
index_1 << (index)
|
||||
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
|
||||
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
|
||||
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
|
||||
stmt << (((alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="stmt"))
|
||||
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
|
||||
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
|
||||
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
|
||||
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
|
||||
simple_factor << (((aggregate_initializer | interval | query_expression | (Optional(unary_op) + ((CaselessLiteral("(") + expression + CaselessLiteral(")")) | primary)) | entity_constructor | enumeration_reference))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="simple_factor"))
|
||||
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
|
||||
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
|
||||
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
|
||||
subtype_constraint_decl << (((subtype_constraint_head + subtype_constraint_body + END_SUBTYPE_CONSTRAINT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_decl"))
|
||||
logical_expression << (expression)
|
||||
case_label << (expression)
|
||||
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
|
||||
general_list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_list_type"))
|
||||
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
|
||||
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
|
||||
selector << (expression)
|
||||
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
|
||||
aggregate_source << (simple_expression)
|
||||
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
|
||||
embedded_remark << (((CaselessLiteral("(*") + Optional(remark_tag) + ZeroOrMore(((not_paren_star + ZeroOrMore(not_paren_star)) | lparen_then_not_lparen_star | (CaselessLiteral("*") + ZeroOrMore(CaselessLiteral("*"))) | not_rparen_star_then_rparen | embedded_remark)) + CaselessLiteral("*)")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="embedded_remark"))
|
||||
parameter_type << (((generalized_types | simple_types | named_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="parameter_type"))
|
||||
term << (((factor + ZeroOrMore((multiplication_like_op + factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="term"))
|
||||
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
|
||||
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
|
||||
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
|
||||
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
|
||||
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
|
||||
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
|
||||
precision_spec << (numeric_expression)
|
||||
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
|
||||
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
|
||||
bound_2 << (numeric_expression)
|
||||
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
|
||||
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
|
||||
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
|
||||
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
|
||||
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
|
||||
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
|
||||
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
|
||||
entity_body << (((ZeroOrMore(explicit_attr) + Optional(derive_clause) + Optional(inverse_clause) + Optional(unique_clause) + Optional(where_clause)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_body"))
|
||||
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
|
||||
case_stmt << (((CASE + selector + OF + ZeroOrMore(case_action) + Optional((OTHERWISE + CaselessLiteral(":") + stmt)) + END_CASE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_stmt"))
|
||||
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
|
||||
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
|
||||
alias_stmt << (((ALIAS + variable_id + FOR + general_ref + ZeroOrMore(qualifier) + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_ALIAS + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="alias_stmt"))
|
||||
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
|
||||
general_array_type << (((ARRAY + Optional(bound_spec) + OF + Optional(OPTIONAL) + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_array_type"))
|
||||
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
|
||||
procedure_head << (((PROCEDURE + procedure_id + Optional((CaselessLiteral("(") + Optional(VAR) + formal_parameter + ZeroOrMore((CaselessLiteral(";") + Optional(VAR) + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_head"))
|
||||
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
|
||||
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
|
||||
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
|
||||
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
|
||||
procedure_call_stmt << ((((built_in_procedure | procedure_ref) + actual_parameter_list + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="procedure_call_stmt"))
|
||||
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
|
||||
query_expression << (((QUERY + CaselessLiteral("(") + variable_id + CaselessLiteral("<*") + aggregate_source + CaselessLiteral("|") + logical_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="query_expression"))
|
||||
index_2 << (index)
|
||||
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
|
||||
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
|
||||
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
|
||||
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
|
||||
numeric_expression << (simple_expression)
|
||||
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
|
||||
schema_decl << (((SCHEMA + schema_id + Optional(schema_version_id) + CaselessLiteral(";") + schema_body + END_SCHEMA + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="schema_decl"))
|
||||
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
|
||||
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
|
||||
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
|
||||
interval_low << (simple_expression)
|
||||
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
|
||||
interval_item = Forward()("interval_item")
|
||||
stmt = Forward()("stmt")
|
||||
repeat_control = Forward()("repeat_control")
|
||||
abstract_supertype_declaration = Forward()("abstract_supertype_declaration")
|
||||
bound_spec = Forward()("bound_spec")
|
||||
entity_decl = Forward()("entity_decl")
|
||||
bound_1 = Forward()("bound_1")
|
||||
inverse_clause = Forward()("inverse_clause")
|
||||
logical_expression = Forward()("logical_expression")
|
||||
numeric_expression = Forward()("numeric_expression")
|
||||
string_type = Forward()("string_type")
|
||||
formal_parameter = Forward()("formal_parameter")
|
||||
generalized_types = Forward()("generalized_types")
|
||||
function_head = Forward()("function_head")
|
||||
constant_decl = Forward()("constant_decl")
|
||||
actual_parameter_list = Forward()("actual_parameter_list")
|
||||
subtype_constraint_body = Forward()("subtype_constraint_body")
|
||||
procedure_decl = Forward()("procedure_decl")
|
||||
case_action = Forward()("case_action")
|
||||
term = Forward()("term")
|
||||
general_aggregation_types = Forward()("general_aggregation_types")
|
||||
function_call = Forward()("function_call")
|
||||
where_clause = Forward()("where_clause")
|
||||
local_variable = Forward()("local_variable")
|
||||
aggregate_initializer = Forward()("aggregate_initializer")
|
||||
binary_type = Forward()("binary_type")
|
||||
index = Forward()("index")
|
||||
case_stmt = Forward()("case_stmt")
|
||||
general_set_type = Forward()("general_set_type")
|
||||
procedure_call_stmt = Forward()("procedure_call_stmt")
|
||||
instantiable_type = Forward()("instantiable_type")
|
||||
general_array_type = Forward()("general_array_type")
|
||||
set_type = Forward()("set_type")
|
||||
supertype_factor = Forward()("supertype_factor")
|
||||
index_2 = Forward()("index_2")
|
||||
qualifiable_factor = Forward()("qualifiable_factor")
|
||||
algorithm_head = Forward()("algorithm_head")
|
||||
parameter_type = Forward()("parameter_type")
|
||||
one_of = Forward()("one_of")
|
||||
compound_stmt = Forward()("compound_stmt")
|
||||
primary = Forward()("primary")
|
||||
schema_decl = Forward()("schema_decl")
|
||||
embedded_remark = Forward()("embedded_remark")
|
||||
width_spec = Forward()("width_spec")
|
||||
assignment_stmt = Forward()("assignment_stmt")
|
||||
element = Forward()("element")
|
||||
schema_body = Forward()("schema_body")
|
||||
procedure_head = Forward()("procedure_head")
|
||||
general_bag_type = Forward()("general_bag_type")
|
||||
entity_head = Forward()("entity_head")
|
||||
entity_body = Forward()("entity_body")
|
||||
list_type = Forward()("list_type")
|
||||
expression = Forward()("expression")
|
||||
parameter = Forward()("parameter")
|
||||
simple_types = Forward()("simple_types")
|
||||
bag_type = Forward()("bag_type")
|
||||
repetition = Forward()("repetition")
|
||||
constant_body = Forward()("constant_body")
|
||||
if_stmt = Forward()("if_stmt")
|
||||
inverse_attr = Forward()("inverse_attr")
|
||||
interval = Forward()("interval")
|
||||
query_expression = Forward()("query_expression")
|
||||
array_type = Forward()("array_type")
|
||||
simple_factor = Forward()("simple_factor")
|
||||
case_label = Forward()("case_label")
|
||||
domain_rule = Forward()("domain_rule")
|
||||
repeat_stmt = Forward()("repeat_stmt")
|
||||
supertype_expression = Forward()("supertype_expression")
|
||||
supertype_constraint = Forward()("supertype_constraint")
|
||||
interval_high = Forward()("interval_high")
|
||||
local_decl = Forward()("local_decl")
|
||||
selector = Forward()("selector")
|
||||
aggregate_source = Forward()("aggregate_source")
|
||||
qualifier = Forward()("qualifier")
|
||||
rule_decl << (((rule_head + algorithm_head + ZeroOrMore(stmt) + where_clause + END_RULE + CaselessLiteral(";")))).setParseAction(RuleDeclaration)
|
||||
supertype_term << (((one_of | (CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")) | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_term"))
|
||||
alias_stmt << (((ALIAS + variable_id + FOR + general_ref + ZeroOrMore(qualifier) + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_ALIAS + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="alias_stmt"))
|
||||
subtype_constraint_decl << (((subtype_constraint_head + subtype_constraint_body + END_SUBTYPE_CONSTRAINT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_decl"))
|
||||
real_type << (((REAL + Optional((CaselessLiteral("(") + precision_spec + CaselessLiteral(")")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="real_type"))
|
||||
until_control << (((UNTIL + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="until_control"))
|
||||
remark << (((embedded_remark | tail_remark))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="remark"))
|
||||
syntax << (((schema_decl + ZeroOrMore(schema_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="syntax"))
|
||||
derived_attr << (((attribute_decl + CaselessLiteral(":") + parameter_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="derived_attr"))
|
||||
subtype_constraint << (((OF + CaselessLiteral("(") + supertype_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint"))
|
||||
aggregation_types << (((array_type | bag_type | list_type | set_type))).setParseAction(AggregationType)
|
||||
width << (numeric_expression)
|
||||
simple_expression << (((term + ZeroOrMore((add_like_op + term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="simple_expression"))
|
||||
explicit_attr << (((attribute_decl + ZeroOrMore((CaselessLiteral(",") + attribute_decl)) + CaselessLiteral(":") + Optional(OPTIONAL) + parameter_type + CaselessLiteral(";")))).setParseAction(ExplicitAttribute)
|
||||
precision_spec << (numeric_expression)
|
||||
general_list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_list_type"))
|
||||
concrete_types << (((aggregation_types | simple_types | type_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="concrete_types"))
|
||||
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
|
||||
subtype_constraint_body << (((Optional(abstract_supertype) + Optional(total_over) + Optional((supertype_expression + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_body"))
|
||||
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
|
||||
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
|
||||
while_control << (((WHILE + logical_expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="while_control"))
|
||||
aggregate_type << (((AGGREGATE + Optional((CaselessLiteral(":") + type_label)) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="aggregate_type"))
|
||||
increment_control << (((variable_id + CaselessLiteral(":=") + bound_1 + TO + bound_2 + Optional((BY + increment))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="increment_control"))
|
||||
index_qualifier << (((CaselessLiteral("[") + index_1 + Optional((CaselessLiteral(":") + index_2)) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="index_qualifier"))
|
||||
supertype_rule << (((SUPERTYPE + subtype_constraint))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="supertype_rule"))
|
||||
subsuper << (((Optional(supertype_constraint) + Optional(subtype_declaration)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subsuper"))
|
||||
interval_low << (simple_expression)
|
||||
bound_2 << (numeric_expression)
|
||||
index_1 << (index)
|
||||
return_stmt << (((RETURN + Optional((CaselessLiteral("(") + expression + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="return_stmt"))
|
||||
type_decl << (((TYPE + type_id + CaselessLiteral("=") + underlying_type + CaselessLiteral(";") + Optional(where_clause) + END_TYPE + CaselessLiteral(";")))).setParseAction(TypeDeclaration)
|
||||
increment << (numeric_expression)
|
||||
factor << (((simple_factor + Optional((CaselessLiteral("**") + simple_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="factor"))
|
||||
underlying_type << (((constructed_types | concrete_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="underlying_type"))
|
||||
declaration << (((entity_decl | function_decl | procedure_decl | subtype_constraint_decl | type_decl))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="declaration"))
|
||||
function_decl << (((function_head + algorithm_head + stmt + ZeroOrMore(stmt) + END_FUNCTION + CaselessLiteral(";")))).setParseAction(FunctionDeclaration)
|
||||
entity_constructor << (((entity_ref + CaselessLiteral("(") + Optional((expression + ZeroOrMore((CaselessLiteral(",") + expression)))) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_constructor"))
|
||||
derive_clause << (((DERIVE + derived_attr + ZeroOrMore(derived_attr)))).setParseAction(AttributeList)
|
||||
interval_item << (simple_expression)
|
||||
stmt << (((alias_stmt | assignment_stmt | case_stmt | compound_stmt | escape_stmt | if_stmt | null_stmt | procedure_call_stmt | repeat_stmt | return_stmt | skip_stmt))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="stmt"))
|
||||
repeat_control << (((Optional(increment_control) + Optional(while_control) + Optional(until_control)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="repeat_control"))
|
||||
abstract_supertype_declaration << (((ABSTRACT + SUPERTYPE + Optional(subtype_constraint)))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="abstract_supertype_declaration"))
|
||||
bound_spec << (((CaselessLiteral("[") + bound_1 + CaselessLiteral(":") + bound_2 + CaselessLiteral("]")))).setParseAction(BoundSpecification)
|
||||
entity_decl << (((entity_head + entity_body + END_ENTITY + CaselessLiteral(";")))).setParseAction(EntityDeclaration)
|
||||
bound_1 << (numeric_expression)
|
||||
inverse_clause << (((INVERSE + inverse_attr + ZeroOrMore(inverse_attr)))).setParseAction(AttributeList)
|
||||
logical_expression << (expression)
|
||||
numeric_expression << (simple_expression)
|
||||
string_type << (((STRING + Optional(width_spec)))).setParseAction(StringType)
|
||||
formal_parameter << (((parameter_id + ZeroOrMore((CaselessLiteral(",") + parameter_id)) + CaselessLiteral(":") + parameter_type))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="formal_parameter"))
|
||||
generalized_types << (((aggregate_type | general_aggregation_types | generic_entity_type | generic_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="generalized_types"))
|
||||
function_head << (((FUNCTION + function_id + Optional((CaselessLiteral("(") + formal_parameter + ZeroOrMore((CaselessLiteral(";") + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(":") + parameter_type + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="function_head"))
|
||||
constant_decl << (((CONSTANT + constant_body + ZeroOrMore(constant_body) + END_CONSTANT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="constant_decl"))
|
||||
actual_parameter_list << (((CaselessLiteral("(") + Optional(parameter) + ZeroOrMore((CaselessLiteral(",") + parameter)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="actual_parameter_list"))
|
||||
subtype_constraint_body << (((Optional(abstract_supertype) + Optional(total_over) + Optional((supertype_expression + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="subtype_constraint_body"))
|
||||
procedure_decl << (((procedure_head + algorithm_head + ZeroOrMore(stmt) + END_PROCEDURE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_decl"))
|
||||
case_action << (((case_label + ZeroOrMore((CaselessLiteral(",") + case_label)) + CaselessLiteral(":") + stmt))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_action"))
|
||||
term << (((factor + ZeroOrMore((multiplication_like_op + factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="term"))
|
||||
general_aggregation_types << (((general_array_type | general_bag_type | general_list_type | general_set_type))).setParseAction(AggregationType)
|
||||
function_call << ((((built_in_function | function_ref) + actual_parameter_list))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="function_call"))
|
||||
where_clause << (((WHERE + domain_rule + CaselessLiteral(";") + ZeroOrMore((domain_rule + CaselessLiteral(";")))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="where_clause"))
|
||||
local_variable << (((variable_id + ZeroOrMore((CaselessLiteral(",") + variable_id)) + CaselessLiteral(":") + parameter_type + Optional((CaselessLiteral(":=") + expression)) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_variable"))
|
||||
aggregate_initializer << (((CaselessLiteral("[") + Optional((element + ZeroOrMore((CaselessLiteral(",") + element)))) + CaselessLiteral("]")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="aggregate_initializer"))
|
||||
binary_type << (((BINARY + Optional(width_spec)))).setParseAction(BinaryType)
|
||||
index << (numeric_expression)
|
||||
case_stmt << (((CASE + selector + OF + ZeroOrMore(case_action) + Optional((OTHERWISE + CaselessLiteral(":") + stmt)) + END_CASE + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="case_stmt"))
|
||||
general_set_type << (((SET + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_set_type"))
|
||||
procedure_call_stmt << ((((built_in_procedure | procedure_ref) + actual_parameter_list + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="procedure_call_stmt"))
|
||||
instantiable_type << (((concrete_types | entity_ref))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="instantiable_type"))
|
||||
general_array_type << (((ARRAY + Optional(bound_spec) + OF + Optional(OPTIONAL) + Optional(UNIQUE) + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_array_type"))
|
||||
set_type << (((SET + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="set_type"))
|
||||
supertype_factor << (((supertype_term + ZeroOrMore((AND + supertype_term))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_factor"))
|
||||
index_2 << (index)
|
||||
qualifiable_factor << (((function_call | attribute_ref | constant_factor | general_ref | population))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifiable_factor"))
|
||||
algorithm_head << (((ZeroOrMore(declaration) + Optional(constant_decl) + Optional(local_decl)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="algorithm_head"))
|
||||
parameter_type << (((generalized_types | simple_types | named_types))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="parameter_type"))
|
||||
one_of << (((ONEOF + CaselessLiteral("(") + supertype_expression + ZeroOrMore((CaselessLiteral(",") + supertype_expression)) + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="one_of"))
|
||||
compound_stmt << (((BEGIN + stmt + ZeroOrMore(stmt) + END + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="compound_stmt"))
|
||||
primary << (((literal | (qualifiable_factor + ZeroOrMore(qualifier))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="primary"))
|
||||
schema_decl << (((SCHEMA + schema_id + Optional(schema_version_id) + CaselessLiteral(";") + schema_body + END_SCHEMA + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="schema_decl"))
|
||||
embedded_remark << (((CaselessLiteral("(*") + Optional(remark_tag) + ZeroOrMore(((not_paren_star + ZeroOrMore(not_paren_star)) | lparen_then_not_lparen_star | (CaselessLiteral("*") + ZeroOrMore(CaselessLiteral("*"))) | not_rparen_star_then_rparen | embedded_remark)) + CaselessLiteral("*)")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="embedded_remark"))
|
||||
width_spec << (((CaselessLiteral("(") + width + CaselessLiteral(")") + Optional(FIXED)))).setParseAction(WidthSpec)
|
||||
assignment_stmt << (((general_ref + ZeroOrMore(qualifier) + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="assignment_stmt"))
|
||||
element << (((expression + Optional((CaselessLiteral(":") + repetition))))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="element"))
|
||||
schema_body << (((ZeroOrMore(interface_specification) + Optional(constant_decl) + ZeroOrMore((declaration | rule_decl))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="schema_body"))
|
||||
procedure_head << (((PROCEDURE + procedure_id + Optional((CaselessLiteral("(") + Optional(VAR) + formal_parameter + ZeroOrMore((CaselessLiteral(";") + Optional(VAR) + formal_parameter)) + CaselessLiteral(")"))) + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="procedure_head"))
|
||||
general_bag_type << (((BAG + Optional(bound_spec) + OF + parameter_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="general_bag_type"))
|
||||
entity_head << (((ENTITY + entity_id + subsuper + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="entity_head"))
|
||||
entity_body << (((ZeroOrMore(explicit_attr) + Optional(derive_clause) + Optional(inverse_clause) + Optional(unique_clause) + Optional(where_clause)))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="entity_body"))
|
||||
list_type << (((LIST + Optional(bound_spec) + OF + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="list_type"))
|
||||
expression << (((simple_expression + Optional((rel_op_extended + simple_expression))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="expression"))
|
||||
parameter << (expression)
|
||||
simple_types << (((binary_type | boolean_type | integer_type | logical_type | number_type | real_type | string_type))).setParseAction(SimpleType)
|
||||
bag_type << (((BAG + Optional(bound_spec) + OF + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="bag_type"))
|
||||
repetition << (numeric_expression)
|
||||
constant_body << (((constant_id + CaselessLiteral(":") + instantiable_type + CaselessLiteral(":=") + expression + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="constant_body"))
|
||||
if_stmt << (((IF + logical_expression + THEN + stmt + ZeroOrMore(stmt) + Optional((ELSE + stmt + ZeroOrMore(stmt))) + END_IF + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="if_stmt"))
|
||||
inverse_attr << (((attribute_decl + CaselessLiteral(":") + Optional(((SET | BAG) + Optional(bound_spec) + OF)) + entity_ref + FOR + Optional((entity_ref + CaselessLiteral("."))) + attribute_ref + CaselessLiteral(";")))).setParseAction(InverseAttribute)
|
||||
interval << (((CaselessLiteral("{") + interval_low + interval_op + interval_item + interval_op + interval_high + CaselessLiteral("}")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="interval"))
|
||||
query_expression << (((QUERY + CaselessLiteral("(") + variable_id + CaselessLiteral("<*") + aggregate_source + CaselessLiteral("|") + logical_expression + CaselessLiteral(")")))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="query_expression"))
|
||||
array_type << (((ARRAY + bound_spec + OF + Optional(OPTIONAL) + Optional(UNIQUE) + instantiable_type))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="array_type"))
|
||||
simple_factor << (((aggregate_initializer | interval | query_expression | (Optional(unary_op) + ((CaselessLiteral("(") + expression + CaselessLiteral(")")) | primary)) | entity_constructor | enumeration_reference))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="simple_factor"))
|
||||
case_label << (expression)
|
||||
domain_rule << (((Optional((rule_label_id + CaselessLiteral(":"))) + expression))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="domain_rule"))
|
||||
repeat_stmt << (((REPEAT + repeat_control + CaselessLiteral(";") + stmt + ZeroOrMore(stmt) + END_REPEAT + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="repeat_stmt"))
|
||||
supertype_expression << (((supertype_factor + ZeroOrMore((ANDOR + supertype_factor))))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="supertype_expression"))
|
||||
supertype_constraint << (((abstract_supertype_declaration | abstract_entity_declaration | supertype_rule))).setParseAction(SuperTypeExpression)
|
||||
interval_high << (simple_expression)
|
||||
local_decl << (((LOCAL + local_variable + ZeroOrMore(local_variable) + END_LOCAL + CaselessLiteral(";")))).setParseAction(lambda s, loc, t: ListNode(s, loc, t, rule="local_decl"))
|
||||
selector << (expression)
|
||||
aggregate_source << (simple_expression)
|
||||
qualifier << (((attribute_qualifier | group_qualifier | index_qualifier))).setParseAction(lambda s, loc, t: Node(s, loc, t, rule="qualifier"))
|
||||
|
||||
syntax.ignore("--" + restOfLine)
|
||||
syntax.ignore(Regex(r"\((?:\*(?:[^*]*\*+)+?\))"))
|
||||
|
||||
@@ -695,6 +695,14 @@ codegen_rule("MOD", lambda context: "%")
|
||||
codegen_rule("TRUE", lambda context: "True")
|
||||
codegen_rule("FALSE", lambda context: "False")
|
||||
|
||||
def _dotted_name(node: ast.AST):
|
||||
"""Return dotted name for Name/Attribute chains, else None."""
|
||||
if isinstance(node, ast.Name):
|
||||
return node.id
|
||||
if isinstance(node, ast.Attribute):
|
||||
base = _dotted_name(node.value)
|
||||
return f"{base}.{node.attr}" if base else node.attr
|
||||
return None
|
||||
|
||||
class AttributeGetattrTransformer(ast.NodeTransformer):
|
||||
def visit_Attribute(self, node):
|
||||
@@ -712,7 +720,7 @@ class AttributeGetattrTransformer(ast.NodeTransformer):
|
||||
if isinstance(node.ctx, ast.Store):
|
||||
return node
|
||||
|
||||
if node.attr == "create_entity":
|
||||
if _dotted_name(node) in ('ifcopenshell.create_entity', 'str.lower'):
|
||||
return node
|
||||
|
||||
if node.attr.startswith("__"):
|
||||
|
||||
@@ -4686,7 +4686,7 @@ class IfcCurveStyle_WR11:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc2x3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc2x3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc2x3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc2x3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyleFontPattern_WR01:
|
||||
SCOPE = 'entity'
|
||||
@@ -4947,7 +4947,7 @@ class IfcDraughtingPreDefinedColour_WR31:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_WR31:
|
||||
SCOPE = 'entity'
|
||||
@@ -4956,7 +4956,7 @@ class IfcDraughtingPreDefinedCurveFont_WR31:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedTextFont_WR31:
|
||||
SCOPE = 'entity'
|
||||
@@ -4965,7 +4965,7 @@ class IfcDraughtingPreDefinedTextFont_WR31:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['iso3098-1fonta', 'iso3098-1fontb']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['iso 3098-1 font a', 'iso 3098-1 font b']) is not False
|
||||
|
||||
class IfcDuctFittingType_WR2:
|
||||
SCOPE = 'entity'
|
||||
@@ -5795,7 +5795,7 @@ class IfcPreDefinedDimensionSymbol_WR31:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['arclength', 'conicaltaper', 'counterbore', 'countersink', 'depth', 'diameter', 'plusminus', 'radius', 'slope', 'sphericaldiameter', 'sphericalradius', 'square']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['arc length', 'conical taper', 'counterbore', 'countersink', 'depth', 'diameter', 'plus minus', 'radius', 'slope', 'spherical diameter', 'spherical radius', 'square']) is not False
|
||||
|
||||
class IfcPreDefinedPointMarkerSymbol_WR31:
|
||||
SCOPE = 'entity'
|
||||
@@ -5813,7 +5813,7 @@ class IfcPreDefinedTerminatorSymbol_WR31:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['blankedarrow', 'blankedbox', 'blankeddot', 'dimensionorigin', 'filledarrow', 'filledbox', 'filleddot', 'integralsymbol', 'openarrow', 'slash', 'unfilledarrow']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['blanked arrow', 'blanked box', 'blanked dot', 'dimension origin', 'filled arrow', 'filled box', 'filled dot', 'integral symbol', 'open arrow', 'slash', 'unfilled arrow']) is not False
|
||||
|
||||
class IfcProcedure_WR1:
|
||||
SCOPE = 'entity'
|
||||
@@ -6799,7 +6799,7 @@ class IfcStructuredDimensionCallout_WR31:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
contents = express_getattr(self, 'Contents', INDETERMINATE)
|
||||
assert (sizeof([ato for ato in [con for con in express_getattr(self, 'contents', INDETERMINATE) if 'ifc2x3.ifcannotationtextoccurrence' in typeof(con)] if not express_getattr(express_getattr(ato, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['dimensionvalue', 'tolerancevalue', 'unittext', 'prefixtext', 'suffixtext']]) == 0) is not False
|
||||
assert (sizeof([ato for ato in [con for con in express_getattr(self, 'contents', INDETERMINATE) if 'ifc2x3.ifcannotationtextoccurrence' in typeof(con)] if not express_getattr(express_getattr(ato, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['dimension value', 'tolerance value', 'unit text', 'prefix text', 'suffix text']]) == 0) is not False
|
||||
|
||||
class IfcStyledItem_WR11:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -6331,7 +6331,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -6593,7 +6593,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -6602,7 +6602,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -6422,7 +6422,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -6684,7 +6684,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -6693,7 +6693,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -6633,7 +6633,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -6905,7 +6905,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -6914,7 +6914,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7403,7 +7403,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyleFontPattern_VisibleLengthGreaterEqualZero:
|
||||
SCOPE = 'entity'
|
||||
@@ -7725,7 +7725,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7734,7 +7734,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7352,7 +7352,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_add1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_add1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_add1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_add1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyleFontPattern_VisibleLengthGreaterEqualZero:
|
||||
SCOPE = 'entity'
|
||||
@@ -7674,7 +7674,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7683,7 +7683,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7356,7 +7356,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_add2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_add2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_add2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_add2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyleFontPattern_VisibleLengthGreaterEqualZero:
|
||||
SCOPE = 'entity'
|
||||
@@ -7678,7 +7678,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7687,7 +7687,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7263,7 +7263,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -7577,7 +7577,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7586,7 +7586,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7351,7 +7351,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc2.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc2.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -7665,7 +7665,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7674,7 +7674,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7354,7 +7354,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc3.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc3.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -7698,7 +7698,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7707,7 +7707,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7370,7 +7370,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc4.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc4.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_rc4.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_rc4.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyle_IdentifiableCurveStyle:
|
||||
SCOPE = 'entity'
|
||||
@@ -7714,7 +7714,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7723,7 +7723,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -7329,7 +7329,7 @@ class IfcCurveStyle_MeasureOfWidth:
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
curvewidth = express_getattr(self, 'CurveWidth', INDETERMINATE)
|
||||
assert (not exists(curvewidth) or 'ifc4x3_tc1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_tc1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'bylayer')) is not False
|
||||
assert (not exists(curvewidth) or 'ifc4x3_tc1.ifcpositivelengthmeasure' in typeof(curvewidth) or ('ifc4x3_tc1.ifcdescriptivemeasure' in typeof(curvewidth) and curvewidth == 'by layer')) is not False
|
||||
|
||||
class IfcCurveStyleFontPattern_VisibleLengthGreaterEqualZero:
|
||||
SCOPE = 'entity'
|
||||
@@ -7651,7 +7651,7 @@ class IfcDraughtingPreDefinedColour_PreDefinedColourNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['black', 'red', 'green', 'blue', 'yellow', 'magenta', 'cyan', 'white', 'by layer']) is not False
|
||||
|
||||
class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
SCOPE = 'entity'
|
||||
@@ -7660,7 +7660,7 @@ class IfcDraughtingPreDefinedCurveFont_PreDefinedCurveFontNames:
|
||||
|
||||
@staticmethod
|
||||
def __call__(self):
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chaindoubledash', 'dashed', 'dotted', 'bylayer']) is not False
|
||||
assert (express_getattr(express_getattr(self, 'Name', INDETERMINATE), 'lower', INDETERMINATE)() in ['continuous', 'chain', 'chain double dash', 'dashed', 'dotted', 'by layer']) is not False
|
||||
|
||||
class IfcDuctFitting_CorrectPredefinedType:
|
||||
SCOPE = 'entity'
|
||||
|
||||
@@ -145,7 +145,8 @@ class configuration:
|
||||
config.set(
|
||||
"snippets",
|
||||
"print all wall ids",
|
||||
self.config_encode("""
|
||||
self.config_encode(
|
||||
"""
|
||||
###########################################################################
|
||||
# A simple script that iterates over all walls in the current model #
|
||||
# and prints their Globally unique IDs (GUIDS) to the console window #
|
||||
@@ -153,13 +154,15 @@ class configuration:
|
||||
|
||||
for wall in model.by_type("IfcWall"):
|
||||
print ("wall with global id: "+str(wall.GlobalId))
|
||||
""".lstrip()),
|
||||
""".lstrip()
|
||||
),
|
||||
)
|
||||
|
||||
config.set(
|
||||
"snippets",
|
||||
"print properties of current selection",
|
||||
self.config_encode("""
|
||||
self.config_encode(
|
||||
"""
|
||||
###########################################################################
|
||||
# A simple script that iterates over all IfcPropertySets of the currently #
|
||||
# selected object and prints them to the console #
|
||||
@@ -177,7 +180,8 @@ if selection:
|
||||
for prop in relDefinesByProperties.RelatingPropertyDefinition.HasProperties:
|
||||
print ("{:<20} :{}".format(prop.Name,prop.NominalValue.wrappedValue))
|
||||
print ("\\n")
|
||||
""".lstrip()),
|
||||
""".lstrip()
|
||||
),
|
||||
)
|
||||
with open(conf_file, "w") as configfile:
|
||||
config.write(configfile)
|
||||
|
||||
@@ -300,13 +300,16 @@ class iterator(ifcopenshell_wrapper.Iterator):
|
||||
include: Optional[Union[list[entity_instance], list[str]]] = None,
|
||||
exclude: Optional[Union[list[entity_instance], list[str]]] = None,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger=None,
|
||||
):
|
||||
self.settings = settings
|
||||
if logger is None and (logger_type := getattr(ifcopenshell_wrapper, "logger", None)):
|
||||
logger = logger_type.Root()
|
||||
if isinstance(file_or_filename, file):
|
||||
self.file = file
|
||||
file_or_filename = file_or_filename
|
||||
else:
|
||||
file_or_filename = self.file = open(file_or_filename)
|
||||
file_or_filename = self.file = open(file_or_filename, logger=logger)
|
||||
|
||||
if include is not None and exclude is not None:
|
||||
raise ValueError("include and exclude cannot be specified simultaneously")
|
||||
@@ -334,13 +337,18 @@ class iterator(ifcopenshell_wrapper.Iterator):
|
||||
else:
|
||||
initializer = ifcopenshell_wrapper.construct_iterator_with_include_exclude
|
||||
|
||||
self.this = initializer(
|
||||
geometry_library, self.settings, file_or_filename, include_or_exclude, include is not None, num_threads
|
||||
args = (
|
||||
geometry_library,
|
||||
self.settings,
|
||||
file_or_filename,
|
||||
include_or_exclude,
|
||||
include is not None,
|
||||
num_threads,
|
||||
)
|
||||
self.this = initializer(*args, *((logger,) if logger is not None else ()))
|
||||
else:
|
||||
self.this = ifcopenshell_wrapper.construct_iterator(
|
||||
geometry_library, self.settings, file_or_filename, num_threads
|
||||
)
|
||||
args = (geometry_library, self.settings, file_or_filename, num_threads)
|
||||
self.this = ifcopenshell_wrapper.construct_iterator(*args, *((logger,) if logger is not None else ()))
|
||||
|
||||
if has_occ:
|
||||
|
||||
@@ -454,6 +462,7 @@ def create_shape(
|
||||
inst: entity_instance,
|
||||
repr: Optional[entity_instance] = None,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger: Optional[ifcopenshell.logger] = None,
|
||||
) -> Union[ShapeType, ShapeElementType, ifcopenshell_wrapper.Transformation, utils.shape_tuple, TopoDS.TopoDS_Shape]:
|
||||
"""
|
||||
Returns a geometric interpretation of the IFC entity instance
|
||||
@@ -500,9 +509,9 @@ def create_shape(
|
||||
return wrap_shape_creation(
|
||||
settings,
|
||||
(
|
||||
ifcopenshell_wrapper.create_shape(settings, inst, repr, geometry_library)
|
||||
ifcopenshell_wrapper.create_shape(settings, inst, repr, geometry_library, *((logger,) if logger is not None else ()),)
|
||||
if repr
|
||||
else ifcopenshell_wrapper.create_shape(settings, inst, geometry_library)
|
||||
else ifcopenshell_wrapper.create_shape(settings, inst, geometry_library, *((logger,) if logger is not None else ()),)
|
||||
),
|
||||
)
|
||||
|
||||
@@ -556,6 +565,7 @@ def iterate(
|
||||
*,
|
||||
with_progress: Literal[False] = False,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger=None,
|
||||
) -> Generator[IteratorOutput, None, None]: ...
|
||||
@overload
|
||||
def iterate(
|
||||
@@ -567,6 +577,7 @@ def iterate(
|
||||
*,
|
||||
with_progress: Literal[True] = True,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger=None,
|
||||
) -> Generator[tuple[int, IteratorOutput], None, None]: ...
|
||||
@overload
|
||||
def iterate(
|
||||
@@ -578,6 +589,7 @@ def iterate(
|
||||
*,
|
||||
with_progress: bool = False,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger=None,
|
||||
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]: ...
|
||||
def iterate(
|
||||
settings: settings,
|
||||
@@ -588,6 +600,7 @@ def iterate(
|
||||
*,
|
||||
with_progress: bool = False,
|
||||
geometry_library: GEOMETRY_LIBRARY = "opencascade",
|
||||
logger=None,
|
||||
) -> Generator[Union[IteratorOutput, tuple[int, IteratorOutput]], None, None]:
|
||||
"""Get a geometry iterator for the provided file."""
|
||||
it = iterator(settings, file_or_filename, num_threads, include, exclude, geometry_library)
|
||||
|
||||
@@ -355,7 +355,8 @@ def get_cost_rate(
|
||||
|
||||
class CostValueUnserialiser:
|
||||
def parse(self, formula: str):
|
||||
l = lark.Lark("""start: formula
|
||||
l = lark.Lark(
|
||||
"""start: formula
|
||||
formula: operand (operator operand)*
|
||||
operand: value | category "(" formula ")"
|
||||
value: NUMBER?
|
||||
@@ -392,7 +393,8 @@ class CostValueUnserialiser:
|
||||
NEWLINE: (CR? LF)+
|
||||
|
||||
%ignore WS // Disregard spaces in text
|
||||
""")
|
||||
"""
|
||||
)
|
||||
start = l.parse(formula)
|
||||
return self.get_formula(start.children[0])
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
# 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 functools
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
@@ -148,6 +149,57 @@ def get_subtypes(
|
||||
return get_classes(declaration)
|
||||
|
||||
|
||||
def _enum_value_outside_target(attribute: ifcopenshell_wrapper.attribute, value: Any) -> bool:
|
||||
"""``True`` when ``attribute`` is an enumeration and the string ``value``
|
||||
is not in its declared items. Used by the Migrator to silently skip enum
|
||||
values that exist in the source schema but not the target — without
|
||||
parsing C++ wrapper error strings."""
|
||||
if not isinstance(value, str):
|
||||
return False
|
||||
try:
|
||||
enum_items = ifcopenshell.util.attribute.get_enum_items(attribute)
|
||||
except (AssertionError, AttributeError):
|
||||
return False
|
||||
return value not in enum_items
|
||||
|
||||
|
||||
@functools.cache
|
||||
def geometry_classes_introduced_after(target_schema: IFC_SCHEMA, source_schema: IFC_SCHEMA = "IFC4") -> frozenset[str]:
|
||||
"""``IfcRepresentationItem`` subclasses present in ``source_schema`` but
|
||||
missing in ``target_schema``.
|
||||
|
||||
Derived from the loaded schema declarations once per (source, target) pair
|
||||
and cached. The result is the canonical set of geometry classes a
|
||||
downgrade from ``source_schema`` to ``target_schema`` must convert
|
||||
(``IfcPolygonalFaceSet``, ``IfcTriangulatedFaceSet``, ``IfcAdvancedBrep``,
|
||||
B-splines, advanced surfaces, alignment curves on IFC4X3 → 2X3, …) or
|
||||
purge. Defaults match the IFC4 → IFC2X3 case for backwards compatibility
|
||||
with the original caller."""
|
||||
source = ifcopenshell_wrapper.schema_by_name(source_schema)
|
||||
target = ifcopenshell_wrapper.schema_by_name(target_schema)
|
||||
target_names = {decl.name() for decl in target.entities()}
|
||||
result: set[str] = set()
|
||||
for decl in source.entities():
|
||||
if decl.name() in target_names:
|
||||
continue
|
||||
cursor: Any = decl
|
||||
while cursor is not None:
|
||||
if cursor.name() == "IfcRepresentationItem":
|
||||
result.add(decl.name())
|
||||
break
|
||||
cursor = cursor.supertype()
|
||||
return frozenset(result)
|
||||
|
||||
|
||||
def ifc4_only_geometry_classes() -> frozenset[str]:
|
||||
"""Backwards-compatible alias for the IFC4 → IFC2X3 geometry-gap set.
|
||||
|
||||
New code should call :func:`geometry_classes_introduced_after` with the
|
||||
explicit (target, source) pair so IFC4X3 → IFC2X3 downgrades pick up the
|
||||
additional IFC4X3-only geometry classes."""
|
||||
return geometry_classes_introduced_after("IFC2X3", "IFC4")
|
||||
|
||||
|
||||
def reassign_class(
|
||||
ifc_file: Union[ifcopenshell.file, None], element: ifcopenshell.entity_instance, new_class: str
|
||||
) -> ifcopenshell.entity_instance:
|
||||
@@ -263,7 +315,20 @@ class Migrator:
|
||||
migrated_ids: dict[int, int]
|
||||
attribute_overrides: dict[int, dict[int, str]]
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, *, fallback_element_to_proxy: bool = False) -> None:
|
||||
"""Construct a schema migrator.
|
||||
|
||||
:param fallback_element_to_proxy: When ``True`` and the target schema is
|
||||
IFC2X3, IFC4 entity classes that have no direct IFC2X3 equivalent
|
||||
but inherit from ``IfcElement`` / ``IfcElementType`` are migrated as
|
||||
``IfcBuildingElementProxy`` / ``IfcBuildingElementProxyType``
|
||||
respectively, instead of raising. Caller code is then responsible
|
||||
for preserving the lost original class information out-of-band (the
|
||||
``Migrate`` ifcpatch recipe encodes it into ``ObjectType``).
|
||||
Defaults to ``False`` so non-recipe callers keep the strict
|
||||
failure-on-unmappable contract.
|
||||
"""
|
||||
self.fallback_element_to_proxy = fallback_element_to_proxy
|
||||
self.migrated_ids = {}
|
||||
self.attribute_overrides = {}
|
||||
self.class_4_to_2x3 = json.load(open(os.path.join(cwd, "class_4_to_2x3.json"), "r"))
|
||||
@@ -379,6 +444,17 @@ class Migrator:
|
||||
self.migrated_ids[element.id()] = new_element.id()
|
||||
return new_element
|
||||
|
||||
@staticmethod
|
||||
def _is_subclass_of(ifc_class: str, ancestor: str, source_file: ifcopenshell.file) -> bool:
|
||||
schema = ifcopenshell_wrapper.schema_by_name(source_file.schema_identifier)
|
||||
try:
|
||||
return is_a(schema.declaration_by_name(ifc_class), ancestor)
|
||||
except RuntimeError:
|
||||
# Class doesn't exist in the source schema — happens for cross-schema
|
||||
# introspection of an entity created with a name the wrapper doesn't
|
||||
# recognise. Treat as "not a subclass".
|
||||
return False
|
||||
|
||||
def migrate_class(
|
||||
self, element: ifcopenshell.entity_instance, new_file: ifcopenshell.file
|
||||
) -> ifcopenshell.entity_instance:
|
||||
@@ -389,15 +465,44 @@ class Migrator:
|
||||
if isinstance(value, float):
|
||||
ifc_class = "IfcQuantityNumber"
|
||||
try:
|
||||
new_element = new_file.create_entity(ifc_class)
|
||||
return new_file.create_entity(ifc_class)
|
||||
except:
|
||||
# The element does not exist in this schema
|
||||
# Complex migration is not yet supported (e.g. polygonal face set to faceted brep)
|
||||
if new_file.schema == "IFC2X3":
|
||||
new_element = new_file.create_entity(self.class_4_to_2x3[ifc_class])
|
||||
elif new_file.schema == "IFC4":
|
||||
new_element = new_file.create_entity(self.class_2x3_to_4[ifc_class])
|
||||
return new_element
|
||||
pass
|
||||
|
||||
# The class does not exist in the target schema — look up an equivalent.
|
||||
# The lookup tables use empty-string as a sentinel meaning "no direct
|
||||
# equivalent, needs geometric translation" (e.g. polygonal face set →
|
||||
# faceted brep). Callers that want a clean downgrade are expected to
|
||||
# preprocess such carriers before calling the Migrator; see the
|
||||
# `Migrate` ifcpatch recipe.
|
||||
if new_file.schema == "IFC2X3":
|
||||
equivalent = self.class_4_to_2x3.get(ifc_class, None)
|
||||
elif new_file.schema == "IFC4":
|
||||
equivalent = self.class_2x3_to_4.get(ifc_class, None)
|
||||
else:
|
||||
equivalent = None
|
||||
|
||||
# IfcBuildingElementProxy fallback is opt-in (see constructor) — only
|
||||
# the IfcElement / IfcElementType subtrees have a meaningful generic
|
||||
# IFC2X3 stand-in; non-element IFC4-only classes (rels, geometry items,
|
||||
# materials, times) still raise below.
|
||||
if not equivalent and new_file.schema == "IFC2X3" and self.fallback_element_to_proxy:
|
||||
if self._is_subclass_of(ifc_class, "IfcElement", element.wrapped_data.file):
|
||||
equivalent = "IfcBuildingElementProxy"
|
||||
elif self._is_subclass_of(ifc_class, "IfcElementType", element.wrapped_data.file):
|
||||
equivalent = "IfcBuildingElementProxyType"
|
||||
|
||||
if not equivalent:
|
||||
inverses = element.wrapped_data.file.get_inverse(element)
|
||||
inverse_hint = ", ".join(f"#{i.id()}={i.is_a()}" for i in list(inverses)[:3])
|
||||
if len(inverses) > 3:
|
||||
inverse_hint += f", … (+{len(inverses) - 3} more)"
|
||||
raise NotImplementedError(
|
||||
f"Cannot migrate #{element.id()}={ifc_class} to schema "
|
||||
f"{new_file.schema}: no direct equivalent exists. "
|
||||
f"Referenced by: {inverse_hint or '(no inverses)'}."
|
||||
)
|
||||
return new_file.create_entity(equivalent)
|
||||
|
||||
def migrate_attributes(
|
||||
self,
|
||||
@@ -526,11 +631,40 @@ class Migrator:
|
||||
new_value.append(self.migrate(item, new_file))
|
||||
value = new_value
|
||||
if value is not None:
|
||||
if _enum_value_outside_target(attribute, value):
|
||||
# Enum value present in source schema but missing in target
|
||||
# (typically a downgrade after a cross-class fallback, e.g.
|
||||
# IfcLamp.PredefinedType=COMPACTFLUORESCENT copied onto
|
||||
# IfcBuildingElementProxy.CompositionType whose enum is
|
||||
# IfcElementCompositionEnum). Leave the attribute unset rather
|
||||
# than abort the whole entity's migration. Detected
|
||||
# structurally so other RuntimeError causes (type mismatches,
|
||||
# invalid values) still propagate.
|
||||
return
|
||||
setattr(new_element, attribute.name(), value)
|
||||
|
||||
def generate_default_value(self, attribute: ifcopenshell_wrapper.attribute, new_file: ifcopenshell.file) -> Any:
|
||||
if attribute.name() in self.default_values:
|
||||
return self.default_values[attribute.name()]
|
||||
elif attribute.name() == "Position":
|
||||
# IFC4 relaxed Position to OPTIONAL for many profile defs; IFC2X3
|
||||
# still requires it. Synthesize a unit placement at origin so
|
||||
# IfcIShapeProfileDef and friends downgrade without crashing
|
||||
# downstream validators.
|
||||
try:
|
||||
type_name = attribute.type_of_attribute().as_named_type().declared_type().name()
|
||||
except Exception:
|
||||
type_name = None
|
||||
if type_name == "IfcAxis2Placement2D":
|
||||
return new_file.create_entity(
|
||||
"IfcAxis2Placement2D",
|
||||
Location=new_file.create_entity("IfcCartesianPoint", (0.0, 0.0)),
|
||||
)
|
||||
if type_name == "IfcAxis2Placement3D":
|
||||
return new_file.create_entity(
|
||||
"IfcAxis2Placement3D",
|
||||
Location=new_file.create_entity("IfcCartesianPoint", (0.0, 0.0, 0.0)),
|
||||
)
|
||||
elif attribute.name() == "OwnerHistory":
|
||||
self.default_entities[attribute.name()] = new_file.create_entity(
|
||||
"IfcOwnerHistory",
|
||||
|
||||
@@ -39,7 +39,8 @@ import ifcopenshell.util.shape
|
||||
import ifcopenshell.util.system
|
||||
import ifcopenshell.util.unit
|
||||
|
||||
filter_elements_grammar = lark.Lark("""start: filter_group
|
||||
filter_elements_grammar = lark.Lark(
|
||||
"""start: filter_group
|
||||
filter_group: facet_list ("+" facet_list)*
|
||||
facet_list: facet ("," facet)*
|
||||
|
||||
@@ -110,9 +111,11 @@ filter_elements_grammar = lark.Lark("""start: filter_group
|
||||
NEWLINE: (CR? LF)+
|
||||
|
||||
%ignore WS // Disregard spaces in text
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
get_element_grammar = lark.Lark("""start: keys
|
||||
get_element_grammar = lark.Lark(
|
||||
"""start: keys
|
||||
|
||||
keys: key ("." key)*
|
||||
key: quoted_string | regex_string | unquoted_string
|
||||
@@ -127,9 +130,11 @@ get_element_grammar = lark.Lark("""start: keys
|
||||
WS: /[ \\t\\f\\r\\n]/+
|
||||
|
||||
%ignore WS // Disregard spaces in text
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
format_grammar = lark.Lark("""start: expression
|
||||
format_grammar = lark.Lark(
|
||||
"""start: expression
|
||||
|
||||
?expression: add_sub
|
||||
?add_sub: mul_div
|
||||
@@ -188,7 +193,8 @@ format_grammar = lark.Lark("""start: expression
|
||||
NEWLINE: (CR? LF)+
|
||||
|
||||
%ignore WS // Disregard spaces in text
|
||||
""")
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
class FormatTransformer(lark.Transformer):
|
||||
|
||||
@@ -21,7 +21,7 @@ from __future__ import annotations
|
||||
import collections.abc
|
||||
from collections.abc import Sequence
|
||||
from itertools import chain
|
||||
from math import atan, cos, degrees, pi, radians, sin, sqrt, tan
|
||||
from math import atan, atan2, cos, degrees, hypot, isclose, pi, radians, sin, sqrt, tan
|
||||
from typing import TYPE_CHECKING, Any, Literal, Optional, Union
|
||||
|
||||
import numpy as np
|
||||
@@ -301,6 +301,130 @@ def intersect_x_axis_2d(p1: VectorType, p2: VectorType, y=0) -> Optional[float]:
|
||||
return x1 + t * (x2 - x1)
|
||||
|
||||
|
||||
def arc_to_polyline_points(
|
||||
start: VectorType, mid: VectorType, end: VectorType, subdivisions: int = 16
|
||||
) -> list[tuple[float, ...]]:
|
||||
"""Approximate a circular arc through (start, mid, end) with chord points.
|
||||
|
||||
The arc is determined uniquely by three points — a circle is fit in the
|
||||
XY plane and the angle is walked from start through mid to end, sampling
|
||||
``subdivisions + 1`` points inclusive of the endpoints. Falls back to a
|
||||
straight chord ``[start, end]`` for collinear / degenerate inputs.
|
||||
|
||||
Only planar arcs in the XY plane are supported. For 3D inputs (length 3
|
||||
tuples), the Z coordinate of each output point is held constant at
|
||||
``start[2]``. Inputs where start/mid/end have differing Z values raise
|
||||
``ValueError`` rather than silently project — caller should rotate the
|
||||
arc into the XY plane first if it lives in a non-axis-aligned plane.
|
||||
|
||||
:raises ValueError: if subdivisions < 1, or if 3D inputs have mismatched
|
||||
Z coordinates (non-planar arc).
|
||||
"""
|
||||
if subdivisions < 1:
|
||||
raise ValueError(f"subdivisions must be >= 1, got {subdivisions}")
|
||||
if len(start) >= 3:
|
||||
# Tolerance accommodates floating-point noise from kernel transforms
|
||||
# — IFC point coordinates that the author wrote as the same Z value
|
||||
# may diverge by ~1e-15 after placement-matrix round-trips.
|
||||
z_tol = 1e-9
|
||||
if not (isclose(start[2], mid[2], abs_tol=z_tol) and isclose(start[2], end[2], abs_tol=z_tol)):
|
||||
raise ValueError(
|
||||
f"arc_to_polyline_points only handles arcs in the XY plane; "
|
||||
f"got mismatched Z coordinates ({start[2]}, {mid[2]}, {end[2]})."
|
||||
)
|
||||
sx, sy = start[0], start[1]
|
||||
mx, my = mid[0], mid[1]
|
||||
ex, ey = end[0], end[1]
|
||||
d = 2 * (sx * (my - ey) + mx * (ey - sy) + ex * (sy - my))
|
||||
if abs(d) < 1e-12:
|
||||
return [tuple(start), tuple(end)]
|
||||
cx = ((sx**2 + sy**2) * (my - ey) + (mx**2 + my**2) * (ey - sy) + (ex**2 + ey**2) * (sy - my)) / d
|
||||
cy = ((sx**2 + sy**2) * (ex - mx) + (mx**2 + my**2) * (sx - ex) + (ex**2 + ey**2) * (mx - sx)) / d
|
||||
a_start = atan2(sy - cy, sx - cx)
|
||||
a_mid = atan2(my - cy, mx - cx)
|
||||
a_end = atan2(ey - cy, ex - cx)
|
||||
sweep = _signed_sweep_through_mid(a_start, a_mid, a_end)
|
||||
radius = hypot(sx - cx, sy - cy)
|
||||
pts: list[tuple[float, ...]] = []
|
||||
for i in range(subdivisions + 1):
|
||||
t = i / subdivisions
|
||||
angle = a_start + sweep * t
|
||||
x = cx + radius * cos(angle)
|
||||
y = cy + radius * sin(angle)
|
||||
if len(start) == 2:
|
||||
pts.append((x, y))
|
||||
else:
|
||||
pts.append((x, y, start[2]))
|
||||
return pts
|
||||
|
||||
|
||||
def _signed_sweep_through_mid(a_start: float, a_mid: float, a_end: float) -> float:
|
||||
"""Total angle (radians) from a_start to a_end going through a_mid."""
|
||||
two_pi = 2 * pi
|
||||
ccw_total = (a_end - a_start) % two_pi
|
||||
ccw_to_mid = (a_mid - a_start) % two_pi
|
||||
if ccw_to_mid <= ccw_total:
|
||||
return ccw_total
|
||||
return -((a_start - a_end) % two_pi)
|
||||
|
||||
|
||||
def polygonal_face_set_to_faceted_brep(face_set: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
"""Convert an ``IfcPolygonalFaceSet`` or ``IfcTriangulatedFaceSet`` into an
|
||||
``IfcFacetedBrep`` in the same file, preserving vertex coordinates and face
|
||||
topology (including inner voids on ``IfcIndexedPolygonalFaceWithVoids``).
|
||||
|
||||
The returned brep is the canonical IFC2X3-compatible form of these IFC4
|
||||
tessellated representations. The caller is responsible for rewiring inverse
|
||||
references and removing the source face set when downgrading.
|
||||
|
||||
:raises TypeError: if ``face_set`` is not an ``IfcPolygonalFaceSet`` or
|
||||
``IfcTriangulatedFaceSet``.
|
||||
:raises ValueError: if ``face_set.Coordinates`` is missing or any face's
|
||||
coordinate index references a vertex outside the coordinate list.
|
||||
"""
|
||||
if not (face_set.is_a("IfcPolygonalFaceSet") or face_set.is_a("IfcTriangulatedFaceSet")):
|
||||
raise TypeError(
|
||||
f"polygonal_face_set_to_faceted_brep expected IfcPolygonalFaceSet or "
|
||||
f"IfcTriangulatedFaceSet, got {face_set.is_a()}."
|
||||
)
|
||||
if face_set.Coordinates is None:
|
||||
raise ValueError(f"{face_set.is_a()} #{face_set.id()} has no Coordinates point list.")
|
||||
ifc_file = face_set.file
|
||||
coords = face_set.Coordinates.CoordList
|
||||
vertex_count = len(coords)
|
||||
ifc_points = [ifc_file.createIfcCartesianPoint(tuple(c)) for c in coords]
|
||||
|
||||
def _resolve(indices: Sequence[int]) -> list[ifcopenshell.entity_instance]:
|
||||
# IfcIndexedPolygonalFace.CoordIndex / IfcTriangulatedFaceSet.CoordIndex
|
||||
# are 1-based. Out-of-range hits early with a clear message rather
|
||||
# than the cryptic IndexError from list[i-1].
|
||||
out = []
|
||||
for index in indices:
|
||||
if not 1 <= index <= vertex_count:
|
||||
raise ValueError(
|
||||
f"{face_set.is_a()} #{face_set.id()} face references vertex {index}, "
|
||||
f"outside CoordList range 1..{vertex_count}."
|
||||
)
|
||||
out.append(ifc_points[index - 1])
|
||||
return out
|
||||
|
||||
ifc_faces: list[ifcopenshell.entity_instance] = []
|
||||
if face_set.is_a("IfcTriangulatedFaceSet"):
|
||||
for triangle in face_set.CoordIndex:
|
||||
loop = ifc_file.createIfcPolyLoop(_resolve(triangle))
|
||||
ifc_faces.append(ifc_file.createIfcFace([ifc_file.createIfcFaceOuterBound(loop, True)]))
|
||||
else: # IfcPolygonalFaceSet
|
||||
for indexed_face in face_set.Faces:
|
||||
outer_loop = ifc_file.createIfcPolyLoop(_resolve(indexed_face.CoordIndex))
|
||||
bounds = [ifc_file.createIfcFaceOuterBound(outer_loop, True)]
|
||||
if indexed_face.is_a("IfcIndexedPolygonalFaceWithVoids"):
|
||||
for inner in indexed_face.InnerCoordIndices or ():
|
||||
bounds.append(ifc_file.createIfcFaceBound(ifc_file.createIfcPolyLoop(_resolve(inner)), True))
|
||||
ifc_faces.append(ifc_file.createIfcFace(bounds))
|
||||
|
||||
return ifc_file.createIfcFacetedBrep(ifc_file.createIfcClosedShell(ifc_faces))
|
||||
|
||||
|
||||
# Note: using ShapeBuilder try not to reuse IFC elements in the process
|
||||
# otherwise you might run into situation where builder.mirror or other operation
|
||||
# is applied twice during one run to the same element
|
||||
|
||||
@@ -912,6 +912,13 @@ def convert_file_length_units(ifc_file: ifcopenshell.file, target_units: str = "
|
||||
new_value = convert_value(val)
|
||||
setattr(element, attr.name(), new_value)
|
||||
|
||||
# IfcGeometricRepresentationContext.Precision is typed as a plain IfcReal
|
||||
# but is interpreted in the project length unit, so it must be scaled too.
|
||||
# Subcontexts derive Precision from their parent and cannot be set.
|
||||
for context in file_patched.by_type("IfcGeometricRepresentationContext", include_subtypes=False):
|
||||
if context.Precision is not None:
|
||||
context.Precision = convert_unit(context.Precision, old_length, new_length)
|
||||
|
||||
has_map_unit = False
|
||||
if (
|
||||
ifc_file.schema == "IFC2X3"
|
||||
|
||||
Reference in New Issue
Block a user