1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
| [[nodiscard]] StatusOr<mesh::EditMesh> ifc_object_to_mesh(const express::runtime::Entity& root,
express::runtime::Runtime& runtime) {
mesh::EditMesh out;
std::stack<std::reference_wrapper<const ert::Entity>> stack;
stack.emplace(root);
while (!stack.empty()) {
const ert::Entity& current = stack.top();
stack.pop();
if (current.is_type("IfcRelAggregates")) {
for (const ert::Entity& related_object :
current.get_collection_attribute<ert::Entity>("RelatedObjects")) {
stack.emplace(related_object);
}
} else if (current.is_type("IfcObjectDefinition")) {
for (const ert::Entity& decomposed_by :
current.get_inverse_attribute("IsDecomposedBy", runtime)) {
stack.emplace(decomposed_by);
}
if (current.is_type("IfcSpatialElement")) {
for (const ert::Entity& element :
current.get_inverse_attribute("ContainsElements", runtime)) {
assert(element.is_type("IfcRelContainedInSpatialStructure"));
for (const auto& related_element :
element.get_collection_attribute<ert::Entity>("RelatedElements")) {
stack.emplace(related_element);
}
}
}
if (current.is_type("IfcProduct")) {
// a product can have a placement
glm::mat4x4 product_local_to_world_transform =
ifc_product_get_local_to_world_transform(current);
// a product can have a representation
if (const ert::Entity* product_representation =
current.get_attribute<ert::Entity>("Representation")) {
assert(product_representation->is_type("IfcProductRepresentation"));
// iterate over representations in product representation
for (const auto& representation :
product_representation->get_collection_attribute<ert::Entity>("Representations")) {
assert(representation.is_type("IfcRepresentation"));
// IfcRepresentation can either be a geometric representation or topology representation
// iterate over items in representation
for (const auto& item : representation.get_collection_attribute<ert::Entity>("Items")) {
assert(item.is_type("IfcRepresentationItem"));
if (item.is_type("IfcFacetedBrep")) {
StatusOr<IfcFacetedBrep> result = read_ifc_faceted_brep(item, runtime);
if (!result.has_value()) {
return error(result.error());
}
// convert to mesh
mesh::EditMesh brep_mesh = ifc_faceted_brep_to_mesh(result.value());
const glm::mat4x4 flip_y_z{1, 0, 0, 0, 0, 0, -1, 0, 0, 1, 0, 0, 0, 0, 0, 1};
mesh::edit_mesh_transform_vertices(brep_mesh,
flip_y_z * product_local_to_world_transform);
out.insert_mesh(brep_mesh);
}
}
}
}
}
}
}
return out;
}
|