mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-29 11:46:33 +00:00
cobie24 - implement Coordinate tab #5926
This commit is contained in:
@@ -49,6 +49,7 @@ __version__ = version = "0.0.0"
|
|||||||
|
|
||||||
|
|
||||||
ParserPreset = Literal["basic", "cobie24", "cobie24legacy"]
|
ParserPreset = Literal["basic", "cobie24", "cobie24legacy"]
|
||||||
|
GetElementDataCallBack = Callable[[ifcopenshell.file, ifcopenshell.entity_instance], dict[str, Any]]
|
||||||
_parser_presets_configs = {}
|
_parser_presets_configs = {}
|
||||||
|
|
||||||
|
|
||||||
@@ -69,9 +70,7 @@ def get_presets_configs() -> dict[ParserPreset, dict[str, Any]]:
|
|||||||
class Parser:
|
class Parser:
|
||||||
config: dict[str, Any]
|
config: dict[str, Any]
|
||||||
categories: defaultdict[str, dict[str, Any]]
|
categories: defaultdict[str, dict[str, Any]]
|
||||||
get_custom_element_data: dict[
|
get_custom_element_data: dict[str, Union[GetElementDataCallBack, dict[str, Any]]]
|
||||||
str, Union[Callable[[ifcopenshell.file, ifcopenshell.entity_instance], dict[str, Any]], dict[str, Any]]
|
|
||||||
]
|
|
||||||
duplicate_keys: list[tuple[dict[str, Any], dict[str, Any]]]
|
duplicate_keys: list[tuple[dict[str, Any], dict[str, Any]]]
|
||||||
|
|
||||||
def __init__(self, preset: Union[str, ParserPreset, dict[str, Any]] = "basic"):
|
def __init__(self, preset: Union[str, ParserPreset, dict[str, Any]] = "basic"):
|
||||||
@@ -93,6 +92,7 @@ class Parser:
|
|||||||
def parse(self, ifc_file: ifcopenshell.file, name=None):
|
def parse(self, ifc_file: ifcopenshell.file, name=None):
|
||||||
for category_name, category_config in self.config["categories"].items():
|
for category_name, category_config in self.config["categories"].items():
|
||||||
for element in category_config["get_category_elements"](ifc_file):
|
for element in category_config["get_category_elements"](ifc_file):
|
||||||
|
get_element_data: Union[GetElementDataCallBack, dict[str, Any]]
|
||||||
get_element_data = category_config["get_element_data"]
|
get_element_data = category_config["get_element_data"]
|
||||||
|
|
||||||
if isinstance(get_element_data, dict):
|
if isinstance(get_element_data, dict):
|
||||||
|
|||||||
+103
-6
@@ -17,13 +17,16 @@
|
|||||||
# along with IfcFM. If not, see <http://www.gnu.org/licenses/>.
|
# along with IfcFM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
import ifcopenshell.geom
|
||||||
import ifcopenshell.util.classification
|
import ifcopenshell.util.classification
|
||||||
import ifcopenshell.util.date
|
import ifcopenshell.util.date
|
||||||
import ifcopenshell.util.element
|
import ifcopenshell.util.element
|
||||||
import ifcopenshell.util.fm
|
import ifcopenshell.util.fm
|
||||||
import ifcopenshell.util.placement
|
import ifcopenshell.util.placement
|
||||||
|
import ifcopenshell.util.shape
|
||||||
import ifcopenshell.util.system
|
import ifcopenshell.util.system
|
||||||
from typing import Any, Union, Optional
|
from ifcopenshell.util.shape_builder import np_matrix_to_euler
|
||||||
|
from typing import Any, Union, Optional, Generator
|
||||||
|
|
||||||
|
|
||||||
# The original BIMServer plugin has a function called ifcToCOBie:
|
# The original BIMServer plugin has a function called ifcToCOBie:
|
||||||
@@ -163,7 +166,7 @@ def get_documents(
|
|||||||
|
|
||||||
|
|
||||||
def get_attributes(ifc_file: ifcopenshell.file) -> list[dict[str, Any]]:
|
def get_attributes(ifc_file: ifcopenshell.file) -> list[dict[str, Any]]:
|
||||||
results = []
|
results: list[dict[str, Any]] = []
|
||||||
history = get_history(ifc_file)
|
history = get_history(ifc_file)
|
||||||
created_by = get_email_from_history(history) if history else None
|
created_by = get_email_from_history(history) if history else None
|
||||||
created_on = ifcopenshell.util.date.ifc2datetime(history.CreationDate).isoformat() if history else None
|
created_on = ifcopenshell.util.date.ifc2datetime(history.CreationDate).isoformat() if history else None
|
||||||
@@ -850,12 +853,81 @@ def get_document_data(ifc_file: ifcopenshell.file, element: ifcopenshell.entity_
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_attribute_data(
|
def pass_category_elements_as_data(ifc_file: ifcopenshell.file, element: dict[str, Any]) -> dict[str, Any]:
|
||||||
ifc_file: ifcopenshell.file, element: ifcopenshell.entity_instance
|
|
||||||
) -> ifcopenshell.entity_instance:
|
|
||||||
return element
|
return element
|
||||||
|
|
||||||
|
|
||||||
|
def get_coordinate_elements(ifc_file: ifcopenshell.file) -> list[dict[str, Any]]:
|
||||||
|
elements = get_floors(ifc_file) + get_spaces(ifc_file)
|
||||||
|
results: list[dict[str, Any]] = []
|
||||||
|
for element in elements:
|
||||||
|
for data in get_coordinate_data_(element):
|
||||||
|
results.append(data)
|
||||||
|
return results
|
||||||
|
|
||||||
|
|
||||||
|
def get_coordinate_data_(element: ifcopenshell.entity_instance) -> Generator[dict[str, Any], None, None]:
|
||||||
|
M_TRANSLATION = (slice(0, 3), 3)
|
||||||
|
element_name = val(element.Name)
|
||||||
|
element_class = element.is_a()
|
||||||
|
|
||||||
|
base_data = {
|
||||||
|
"CreatedBy": get_created_by(element),
|
||||||
|
"CreatedOn": get_created_on(element),
|
||||||
|
"RowName": element_name,
|
||||||
|
"ExtSystem": "IfcFm",
|
||||||
|
"ExtObject": element_class,
|
||||||
|
"ExtIdentifier": element.GlobalId,
|
||||||
|
}
|
||||||
|
|
||||||
|
if element_class == "IfcBuildingStorey":
|
||||||
|
matrix = ifcopenshell.util.placement.get_local_placement(element.ObjectPlacement)
|
||||||
|
categories = ("points",)
|
||||||
|
rotation = np_matrix_to_euler(matrix)
|
||||||
|
translation = matrix[M_TRANSLATION]
|
||||||
|
# Rotation axes as explained in https://www.nibs.org/nbims/v3/cobie.
|
||||||
|
points_data = {
|
||||||
|
"Name": element_name,
|
||||||
|
"Category": "point",
|
||||||
|
"SheetName": "Floor",
|
||||||
|
"CoordinateXAxis": translation[0],
|
||||||
|
"CoordinateYAxis": translation[1],
|
||||||
|
"CoordinateZAxis": translation[2],
|
||||||
|
"ClockwiseRotation": rotation[2] * 180,
|
||||||
|
"ElevationalRotation": rotation[0] * 180,
|
||||||
|
"YawRotation": rotation[1] * 180,
|
||||||
|
}
|
||||||
|
yield base_data | points_data
|
||||||
|
return
|
||||||
|
|
||||||
|
# IfcSpaces.
|
||||||
|
if element.Representation is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
settings = ifcopenshell.geom.settings()
|
||||||
|
shape: ifcopenshell.geom.ShapeElementType
|
||||||
|
shape = ifcopenshell.geom.create_shape(settings, element)
|
||||||
|
verts = ifcopenshell.util.shape.get_shape_vertices(shape, shape.geometry)
|
||||||
|
categories = ("box-lowerleft", "box-upperright")
|
||||||
|
bbox = ifcopenshell.util.shape.get_bbox(verts)
|
||||||
|
base_data = base_data | {
|
||||||
|
"Category": "point",
|
||||||
|
"SheetName": "Space",
|
||||||
|
# Spaces don't need rotation as box points are already in world space.
|
||||||
|
"ClockwiseRotation": None,
|
||||||
|
"ElevationalRotation": None,
|
||||||
|
"YawRotation": None,
|
||||||
|
}
|
||||||
|
for category, point in zip(categories, bbox):
|
||||||
|
box_point_data = {
|
||||||
|
"Name": element_name + category,
|
||||||
|
"CoordinateXAxis": point[0],
|
||||||
|
"CoordinateYAxis": point[1],
|
||||||
|
"CoordinateZAxis": point[2],
|
||||||
|
}
|
||||||
|
yield base_data | box_point_data
|
||||||
|
|
||||||
|
|
||||||
def get_unit_type_name(ifc_file: ifcopenshell.file, unit_type: str) -> Union[str, None]:
|
def get_unit_type_name(ifc_file: ifcopenshell.file, unit_type: str) -> Union[str, None]:
|
||||||
for unit in ifc_file.by_type("IfcUnitAssignment")[0].Units:
|
for unit in ifc_file.by_type("IfcUnitAssignment")[0].Units:
|
||||||
if unit.is_a("IfcNamedUnit") and unit.UnitType == unit_type:
|
if unit.is_a("IfcNamedUnit") and unit.UnitType == unit_type:
|
||||||
@@ -936,6 +1008,7 @@ def get_facility_parent(
|
|||||||
|
|
||||||
|
|
||||||
def val(x: Any) -> Any:
|
def val(x: Any) -> Any:
|
||||||
|
"""Replace n/a and empty strings with `None`."""
|
||||||
return x if x not in ("", "n/a") else None
|
return x if x not in ("", "n/a") else None
|
||||||
|
|
||||||
|
|
||||||
@@ -1428,7 +1501,31 @@ config = {
|
|||||||
"colours": "ririiirreeeoo",
|
"colours": "ririiirreeeoo",
|
||||||
"sort": [{"name": "Category", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
"sort": [{"name": "Category", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
"get_category_elements": get_attributes,
|
"get_category_elements": get_attributes,
|
||||||
"get_element_data": get_attribute_data,
|
"get_element_data": pass_category_elements_as_data,
|
||||||
|
},
|
||||||
|
"Coordinate": {
|
||||||
|
"keys": ["Name", "SheetName", "RowName"],
|
||||||
|
"headers": (
|
||||||
|
"Name",
|
||||||
|
"CreatedBy",
|
||||||
|
"CreatedOn",
|
||||||
|
"Category",
|
||||||
|
"SheetName",
|
||||||
|
"RowName",
|
||||||
|
"CoordinateXAxis",
|
||||||
|
"CoordinateYAxis",
|
||||||
|
"CoordinateZAxis",
|
||||||
|
"ExtSystem",
|
||||||
|
"ExtObject",
|
||||||
|
"ExtIdentifier",
|
||||||
|
"ClockwiseRotation",
|
||||||
|
"ElevationalRotation",
|
||||||
|
"YawRotation",
|
||||||
|
),
|
||||||
|
"colours": "ririiirrreeerrr",
|
||||||
|
"sort": [{"name": "Category", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||||
|
"get_category_elements": get_coordinate_elements,
|
||||||
|
"get_element_data": pass_category_elements_as_data,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user