mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-01 20:49:44 +00:00
ifccityjson: temporary fix until CJIO can build its LOD dictionary again
This commit is contained in:
@@ -15,12 +15,14 @@
|
|||||||
#
|
#
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with ifccityjson. If not, see <http://www.gnu.org/licenses/>.
|
# along with ifccityjson. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
import os
|
||||||
|
import copy
|
||||||
|
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
import ifcopenshell.api
|
import ifcopenshell.api
|
||||||
from geometry import GeometryIO
|
from geometry import GeometryIO
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import os
|
|
||||||
|
|
||||||
JSON_TO_IFC = {
|
JSON_TO_IFC = {
|
||||||
"Building": ["IfcBuilding"],
|
"Building": ["IfcBuilding"],
|
||||||
@@ -126,20 +128,9 @@ class Cityjson2ifc:
|
|||||||
|
|
||||||
if not self.city_model.has_metadata() or "presentLoDs" not in self.city_model.j["metadata"]:
|
if not self.city_model.has_metadata() or "presentLoDs" not in self.city_model.j["metadata"]:
|
||||||
self.city_model.update_metadata()
|
self.city_model.update_metadata()
|
||||||
self.IFC_representation_sub_contexts = {}
|
|
||||||
for lod in self.city_model.j["metadata"]["presentLoDs"]:
|
# create IFC representation subcontexts from lods
|
||||||
# TODO in ifcopenshell.api.context.add_context add support for UserDefinedTargetView
|
self.create_representation_sub_contexts()
|
||||||
# self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.run("context.add_context", self.IFC_model,
|
|
||||||
# **{"context": "Model",
|
|
||||||
# "subcontext": "Body",
|
|
||||||
# "target_view": "USERDEFINED",
|
|
||||||
# "UserDefinedTargetView":str(lod)})
|
|
||||||
self.IFC_representation_sub_contexts[str(lod)] = self.IFC_model.create_entity("IfcGeometricRepresentationSubContext",
|
|
||||||
**{"ContextType": "Model",
|
|
||||||
"ContextIdentifier": "Body",
|
|
||||||
"TargetView": "USERDEFINED",
|
|
||||||
"ParentContext": self.IFC_representation_context,
|
|
||||||
"UserDefinedTargetView": "LOD" + str(lod)})
|
|
||||||
|
|
||||||
self.IFC_site = ifcopenshell.api.run("root.create_entity", self.IFC_model,
|
self.IFC_site = ifcopenshell.api.run("root.create_entity", self.IFC_model,
|
||||||
**{"ifc_class": "IfcSite",
|
**{"ifc_class": "IfcSite",
|
||||||
@@ -149,6 +140,25 @@ class Cityjson2ifc:
|
|||||||
"RelatedObjects": [self.IFC_site],
|
"RelatedObjects": [self.IFC_site],
|
||||||
"RelatingObject": self.IFC_project})
|
"RelatingObject": self.IFC_project})
|
||||||
|
|
||||||
|
def create_representation_sub_contexts(self):
|
||||||
|
self.IFC_representation_sub_contexts = {}
|
||||||
|
for lod in self.city_model.j["metadata"]["presentLoDs"]:
|
||||||
|
self.IFC_representation_sub_contexts[str(lod)] = self.create_representation_sub_context(lod)
|
||||||
|
|
||||||
|
def create_representation_sub_context(self, lod):
|
||||||
|
# TODO in ifcopenshell.api.context.add_context add support for UserDefinedTargetView
|
||||||
|
# self.IFC_representation_sub_contexts[str(lod)] = ifcopenshell.api.run("context.add_context", self.IFC_model,
|
||||||
|
# **{"context": "Model",
|
||||||
|
# "subcontext": "Body",
|
||||||
|
# "target_view": "USERDEFINED",
|
||||||
|
# "UserDefinedTargetView":str(lod)})
|
||||||
|
return self.IFC_model.create_entity("IfcGeometricRepresentationSubContext",
|
||||||
|
**{"ContextType": "Model",
|
||||||
|
"ContextIdentifier": "Body",
|
||||||
|
"TargetView": "USERDEFINED",
|
||||||
|
"ParentContext": self.IFC_representation_context,
|
||||||
|
"UserDefinedTargetView": "LOD" + str(lod)})
|
||||||
|
|
||||||
def create_owner_history(self):
|
def create_owner_history(self):
|
||||||
actor = self.IFC_model.createIfcActorRole("ENGINEER", None, None)
|
actor = self.IFC_model.createIfcActorRole("ENGINEER", None, None)
|
||||||
person = self.IFC_model.createIfcPerson("Oostwegel", None, "L.J.N.", None, None, None, (actor,))
|
person = self.IFC_model.createIfcPerson("Oostwegel", None, "L.J.N.", None, None, None, (actor,))
|
||||||
@@ -178,24 +188,27 @@ class Cityjson2ifc:
|
|||||||
file = self.properties["file_destination"] + lod + self.properties["file_extension"]
|
file = self.properties["file_destination"] + lod + self.properties["file_extension"]
|
||||||
self.IFC_model.write(file)
|
self.IFC_model.write(file)
|
||||||
IFC_copied_model = ifcopenshell.open(file)
|
IFC_copied_model = ifcopenshell.open(file)
|
||||||
|
|
||||||
IFC_copied_model_sub_contexts = IFC_copied_model.by_type('IfcGeometricRepresentationSubContext')
|
IFC_copied_model_sub_contexts = IFC_copied_model.by_type('IfcGeometricRepresentationSubContext')
|
||||||
for sub_context in IFC_copied_model_sub_contexts:
|
for sub_context in IFC_copied_model_sub_contexts:
|
||||||
|
print(sub_context)
|
||||||
if sub_context.id() == sub_context_id:
|
if sub_context.id() == sub_context_id:
|
||||||
continue
|
continue
|
||||||
else:
|
|
||||||
elements = IFC_copied_model.get_inverse(sub_context)
|
representations_in_context = sub_context.RepresentationsInContext
|
||||||
for element in elements:
|
for element in representations_in_context:
|
||||||
IFC_copied_model.remove(element)
|
IFC_copied_model.remove(element)
|
||||||
IFC_copied_model.remove(sub_context)
|
# slow:
|
||||||
|
# ifcopenshell.api.run("geometry.remove_representation", IFC_copied_model, representation=element)
|
||||||
|
|
||||||
|
ifcopenshell.api.run("context.remove_context", IFC_copied_model, context=sub_context)
|
||||||
|
|
||||||
IFC_copied_model.write(file)
|
IFC_copied_model.write(file)
|
||||||
del IFC_copied_model
|
del IFC_copied_model
|
||||||
|
|
||||||
def create_IFC_classes(self):
|
def create_IFC_classes(self):
|
||||||
parents_children_relations = {"IfcSite": {'Parent': self.IFC_site, 'Children': []}}
|
parents_children_relations = {"IfcSite": {'Parent': self.IFC_site, 'Children': []}}
|
||||||
|
geometries = {}
|
||||||
for obj_id, obj in self.city_model.get_cityobjects().items():
|
for obj_id, obj in self.city_model.get_cityobjects().items():
|
||||||
|
|
||||||
# CityJSON type to class
|
# CityJSON type to class
|
||||||
mapping = JSON_TO_IFC[obj.type]
|
mapping = JSON_TO_IFC[obj.type]
|
||||||
IFC_class = mapping[0]
|
IFC_class = mapping[0]
|
||||||
@@ -210,9 +223,6 @@ class Cityjson2ifc:
|
|||||||
if "name_attribute" in self.properties and self.properties["name_attribute"] in obj.attributes:
|
if "name_attribute" in self.properties and self.properties["name_attribute"] in obj.attributes:
|
||||||
IFC_name = obj.attributes[self.properties["name_attribute"]]
|
IFC_name = obj.attributes[self.properties["name_attribute"]]
|
||||||
|
|
||||||
# geometry_lod
|
|
||||||
lod = 0
|
|
||||||
geometry = None
|
|
||||||
if len(obj.geometry) == 0:
|
if len(obj.geometry) == 0:
|
||||||
print(f"Warning: Object {obj_id} has no geometry.")
|
print(f"Warning: Object {obj_id} has no geometry.")
|
||||||
|
|
||||||
@@ -220,11 +230,16 @@ class Cityjson2ifc:
|
|||||||
IFC_shape_representations = []
|
IFC_shape_representations = []
|
||||||
for geometry in obj.geometry:
|
for geometry in obj.geometry:
|
||||||
lod = geometry.lod
|
lod = geometry.lod
|
||||||
|
if str(lod) != '1.3': # TODO: split LODS
|
||||||
|
continue
|
||||||
|
if str(lod) not in self.IFC_representation_sub_contexts:
|
||||||
|
self.IFC_representation_sub_contexts[str(lod)] = self.create_representation_sub_context(lod)
|
||||||
|
|
||||||
IFC_geometry, shape_representation_type = None, None
|
IFC_geometry, shape_representation_type = None, None
|
||||||
# representation = self.create_IFC_LOD_representation(obj, geometry)
|
|
||||||
if geometry and geometry.surfaces:
|
if geometry and geometry.surfaces:
|
||||||
IFC_semantic_surface_children = self.create_IFC_semantic_surface_children(geometry, lod)
|
IFC_semantic_surface_children.extend(self.create_IFC_semantic_surface_children(geometry, lod))
|
||||||
if geometry:
|
elif geometry:
|
||||||
IFC_geometry, shape_representation_type = self.geometry.create_IFC_geometry(self.IFC_model,
|
IFC_geometry, shape_representation_type = self.geometry.create_IFC_geometry(self.IFC_model,
|
||||||
geometry)
|
geometry)
|
||||||
if IFC_geometry:
|
if IFC_geometry:
|
||||||
@@ -264,17 +279,10 @@ class Cityjson2ifc:
|
|||||||
self.create_property_set(obj.attributes, IFC_object)
|
self.create_property_set(obj.attributes, IFC_object)
|
||||||
|
|
||||||
for parent, parent_children in parents_children_relations.items():
|
for parent, parent_children in parents_children_relations.items():
|
||||||
if parent == "IfcSite":
|
self.IFC_model.create_entity("IfcRelAggregates",
|
||||||
self.IFC_model.create_entity("IfcRelAggregates",
|
|
||||||
**{"GlobalId": ifcopenshell.guid.new(),
|
|
||||||
"RelatedObjects": parent_children['Children'],
|
|
||||||
"RelatingObject": parent_children['Parent']})
|
|
||||||
continue
|
|
||||||
|
|
||||||
self.IFC_model.create_entity("IfcRelContainedInSpatialStructure",
|
|
||||||
**{"GlobalId": ifcopenshell.guid.new(),
|
**{"GlobalId": ifcopenshell.guid.new(),
|
||||||
"RelatedElements": parent_children['Children'],
|
"RelatedObjects": parent_children['Children'],
|
||||||
"RelatingStructure": parent_children['Parent']}
|
"RelatingObject": parent_children['Parent']}
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_IFC_semantic_surface_children(self, geometry, lod):
|
def create_IFC_semantic_surface_children(self, geometry, lod):
|
||||||
@@ -289,6 +297,7 @@ class Cityjson2ifc:
|
|||||||
surface_geometry = self.geometry.create_IFC_surface(self.IFC_model, geometry, surface_id)
|
surface_geometry = self.geometry.create_IFC_surface(self.IFC_model, geometry, surface_id)
|
||||||
if surface_geometry:
|
if surface_geometry:
|
||||||
IFC_shape_representation =self.create_IFC_shape_representation(surface_geometry, 'brep', lod)
|
IFC_shape_representation =self.create_IFC_shape_representation(surface_geometry, 'brep', lod)
|
||||||
|
|
||||||
child_data["Representation"] = self.IFC_model.create_entity("IfcProductDefinitionShape",
|
child_data["Representation"] = self.IFC_model.create_entity("IfcProductDefinitionShape",
|
||||||
Representations=[IFC_shape_representation])
|
Representations=[IFC_shape_representation])
|
||||||
IFC_semantic_surface_children.append(self.IFC_model.create_entity(IFC_child_class, **child_data))
|
IFC_semantic_surface_children.append(self.IFC_model.create_entity(IFC_child_class, **child_data))
|
||||||
@@ -306,31 +315,8 @@ class Cityjson2ifc:
|
|||||||
return shape_representation
|
return shape_representation
|
||||||
|
|
||||||
def create_property_set(self, CJ_attributes, IFC_entity):
|
def create_property_set(self, CJ_attributes, IFC_entity):
|
||||||
IFC_object_properties = []
|
if len(CJ_attributes) == 0:
|
||||||
for property, val in CJ_attributes.items():
|
return
|
||||||
if val == None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
if type(val) == int:
|
pset = ifcopenshell.api.run("pset.add_pset", self.IFC_model, product=IFC_entity, name="CityJSON_attributes")
|
||||||
IFC_type = "IfcInteger"
|
ifcopenshell.api.run("pset.edit_pset", self.IFC_model, pset=pset, properties=CJ_attributes)
|
||||||
elif type(val) == float:
|
|
||||||
IFC_type = "IfcReal"
|
|
||||||
elif type(val) == bool:
|
|
||||||
IFC_type = "IfcBoolean"
|
|
||||||
else:
|
|
||||||
IFC_type = "IfcText"
|
|
||||||
|
|
||||||
IFC_object_properties.append(
|
|
||||||
self.IFC_model.createIfcPropertySingleValue(property, property,
|
|
||||||
self.IFC_model.create_entity(IFC_type, val), None)
|
|
||||||
)
|
|
||||||
property_set = self.IFC_model.createIfcPropertySet(ifcopenshell.guid.new(),
|
|
||||||
self.properties["owner_history"],
|
|
||||||
"CityJSON_attributes",
|
|
||||||
None,
|
|
||||||
IFC_object_properties)
|
|
||||||
|
|
||||||
self.IFC_model.createIfcRelDefinesByProperties(ifcopenshell.guid.new(),
|
|
||||||
self.properties["owner_history"],
|
|
||||||
None, None, [IFC_entity],
|
|
||||||
property_set)
|
|
||||||
Reference in New Issue
Block a user