From 5162f4e578c84edd70efc839b52cb8f64cc09380 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Wed, 1 Aug 2018 15:50:14 -0300 Subject: [PATCH] Arch: support of stacked groups in IFC and added Internal property to Spaces --- src/Mod/Arch/ArchSpace.py | 3 +++ src/Mod/Arch/importIFC.py | 43 ++++++++++++++++++++++++++++++++++----- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/Mod/Arch/ArchSpace.py b/src/Mod/Arch/ArchSpace.py index 4aac2ab801..6c765be87b 100644 --- a/src/Mod/Arch/ArchSpace.py +++ b/src/Mod/Arch/ArchSpace.py @@ -299,6 +299,9 @@ class _Space(ArchComponent.Component): if not "Conditioning" in pl: obj.addProperty("App::PropertyEnumeration","Conditioning", "Space",QT_TRANSLATE_NOOP("App::Property","The type of air conditioning of this space")) obj.Conditioning = ConditioningTypes + if not "Internal" in pl: + obj.addProperty("App::PropertyBool", "Internal", "Space",QT_TRANSLATE_NOOP("App::Property","Specifies if this space is internal or external")) + obj.Internal = True self.Type = "Space" obj.setEditorMode("HorizontalArea",2) diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index fe0201949e..a2a73b92a1 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -1016,6 +1016,7 @@ def insert(filename,docname,skip=[],only=[],root=None): # processing remaining (normal) groups + swallowed = [] for host,children in groups.items(): if ifcfile[host].is_a("IfcGroup"): if ifcfile[host].Name: @@ -1024,10 +1025,12 @@ def insert(filename,docname,skip=[],only=[],root=None): if DEBUG: print("no group name specified for entity: #", ifcfile[host].id(), ", entity type is used!") grp_name = ifcfile[host].is_a() + "_" + str(ifcfile[host].id()) grp = FreeCAD.ActiveDocument.addObject("App::DocumentObjectGroup",grp_name.encode("utf8")) + grp.Label = grp_name objects[host] = grp for child in children: if child in objects.keys(): grp.addObject(objects[child]) + swallowed.append(child) else: if DEBUG: print("unable to add object: #", child, " to group: #", ifcfile[host].id(), ", ", grp_name) @@ -1082,7 +1085,11 @@ def insert(filename,docname,skip=[],only=[],root=None): for host,children in additions.items(): if host in objects.keys(): - cobs = [objects[child] for child in children if child in objects.keys()] + cobs = [] + for child in children: + if child in objects.keys(): + if not child in swallowed: # don't add objects already in groups + cobs.append(objects[child]) if cobs: if DEBUG and first: print("") @@ -1449,6 +1456,7 @@ def export(exportList,filename): groups = {} # { Host: [Child,Child,...] } profiledefs = {} # { ProfileDefString:profiledef,...} shapedefs = {} # { ShapeDefString:[shapes],... } + spatialelements = {} # {Name:IfcEntity, ... } # reusable entity system @@ -1611,9 +1619,20 @@ def export(exportList,filename): kwargs.update({"OverallHeight": l/1000.0, "OverallWidth": obj.Shape.BoundBox.ZLength/1000.0}) elif ifctype == "IfcSpace": - kwargs.update({"CompositionType": "ELEMENT", - "InteriorOrExteriorSpace": "INTERNAL", - "ElevationWithFlooring": obj.Shape.BoundBox.ZMin/1000.0}) + internal = "NOTDEFINED" + if hasattr(obj,"Internal"): + if obj.Internal: + internal = "INTERNAL" + else: + internal = "EXTERNAL" + if schema == "IFC2X3": + kwargs.update({"CompositionType": "ELEMENT", + "InteriorOrExteriorSpace": internal, + "ElevationWithFlooring": obj.Shape.BoundBox.ZMin/1000.0}) + else: + kwargs.update({"CompositionType": "ELEMENT", + "PredefinedType": internal, + "ElevationWithFlooring": obj.Shape.BoundBox.ZMin/1000.0}) elif ifctype == "IfcBuildingElementProxy": if ifcopenshell.schema_identifier == "IFC4": kwargs.update({"PredefinedType": "ELEMENT"}) @@ -1635,6 +1654,8 @@ def export(exportList,filename): #print(obj.Label," : ",ifctype," : ",kwargs) product = getattr(ifcfile,"create"+ifctype)(**kwargs) products[obj.Name] = product + if ifctype in ["IfcBuilding","IfcBuildingStorey","IfcSite","IfcSpace"]: + spatialelements[obj.Name] = product # additions @@ -2009,7 +2030,7 @@ def export(exportList,filename): for g in groups.keys(): okay = True for c in groups[g]: - if Draft.getType(FreeCAD.ActiveDocument.getObject(c)) == "Group": + if Draft.getType(FreeCAD.ActiveDocument.getObject(c)) in ["Group","VisGroup"]: okay = False for s in sortedgroups: if s[0] == c: @@ -2020,6 +2041,7 @@ def export(exportList,filename): if g[0] in groups.keys(): del groups[g[0]] #print "sorted groups:",sortedgroups + containers = {} for g in sortedgroups: if g[1]: children = [] @@ -2030,7 +2052,18 @@ def export(exportList,filename): name = str(FreeCAD.ActiveDocument.getObject(g[0]).Label.encode("utf8")) grp = ifcfile.createIfcGroup(ifcopenshell.guid.compress(uuid.uuid1().hex),history,name,'',None) products[g[0]] = grp + spatialelements[g[0]] = grp ass = ifcfile.createIfcRelAssignsToGroup(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'GroupLink','',children,None,grp) + # stack groups inside containers + stack = {} + for g in sortedgroups: + go = FreeCAD.ActiveDocument.getObject(g[0]) + for parent in go.InList: + if hasattr(parent,"Group") and (go in parent.Group): + if (parent.Name in spatialelements) and (g[0] in spatialelements): + stack.setdefault(parent.Name,[]).append(spatialelements[g[0]]) + for k,v in stack.items(): + ifcfile.createIfcRelAggregates(ifcopenshell.guid.compress(uuid.uuid1().hex),history,'GroupStackLink','',spatialelements[k],v) # 2D objects