From 6a0050d709e571878779776fff122507dde662a3 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sun, 9 Jun 2019 19:48:38 -0300 Subject: [PATCH] Arch: Added IFC pref option to export without adding a default building --- src/Mod/Arch/Resources/ui/preferences-ifc.ui | 29 ++++- src/Mod/Arch/importIFC.py | 129 +++++++++++++------ 2 files changed, 119 insertions(+), 39 deletions(-) diff --git a/src/Mod/Arch/Resources/ui/preferences-ifc.ui b/src/Mod/Arch/Resources/ui/preferences-ifc.ui index b8caadfcd4..7c1ebc3df5 100644 --- a/src/Mod/Arch/Resources/ui/preferences-ifc.ui +++ b/src/Mod/Arch/Resources/ui/preferences-ifc.ui @@ -7,7 +7,7 @@ 0 0 463 - 829 + 883 @@ -532,8 +532,11 @@ + + When exporting an IFC file, if no site if found in the FreeCAD document, a default one will be added. A site is not mandatory by the IFC standard, but it is a common practice to always have at least one in the file. + - Add default site if no site is present in the document + Add default site if none is found in the document IfcAddDefaultSite @@ -543,8 +546,30 @@ + + + + When exporting an IFC file, if no building if found in the FreeCAD document, a default one will be added.<br/><b>Warning</b>: The IFC standard asks for at least one building in each file. By turning this option off, you will produce a non-standard IFC file. However, at FreeCAD, we believe having a building should not be mandatory, and this option is there so we have a chance to show our point of view to the world and try to convince others. + + + Add default building if no ne is found in the document (no standard) + + + true + + + IfcAddDefaultBuilding + + + Mod/Arch + + + + + When exporting an IFC file, if no building storey if found in the FreeCAD document, a default one will be added. A building storey is not mandatory by the IFC standard, but it is a common practice to always have at least one in the file. + Add default building storey if none is found in the document diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index fbf5892605..010410bdb7 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -228,7 +228,7 @@ def getPreferences(): global MERGE_MODE_ARCH, MERGE_MODE_STRUCT, CREATE_CLONES global FORCE_BREP, IMPORT_PROPERTIES, STORE_UID, SERIALIZE global SPLIT_LAYERS, EXPORT_2D, FULL_PARAMETRIC, FITVIEW_ONIMPORT - global ADD_DEFAULT_SITE, ADD_DEFAULT_STOREY + global ADD_DEFAULT_SITE, ADD_DEFAULT_STOREY, ADD_DEFAULT_BUILDING p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Arch") if FreeCAD.GuiUp and p.GetBool("ifcShowDialog",False): import FreeCADGui @@ -258,6 +258,7 @@ def getPreferences(): FITVIEW_ONIMPORT = p.GetBool("ifcFitViewOnImport",False) ADD_DEFAULT_SITE = p.GetBool("IfcAddDefaultSite",False) ADD_DEFAULT_STOREY = p.GetBool("IfcAddDefaultStorey",False) + ADD_DEFAULT_BUILDING = p.GetBool("IfcAddDefaultBuilding",True) # ************************************************************************************************ # ********** open and import IFC **************** @@ -2149,7 +2150,7 @@ def export(exportList,filename): subs ) - # floors/buildingparts + # storeys for floor in Draft.getObjectsOfType(objectslist,"Floor")+Draft.getObjectsOfType(objectslist,"BuildingPart"): if (Draft.getType(floor) == "Floor") or (hasattr(floor,"IfcType") and floor.IfcType == "Building Storey"): @@ -2232,6 +2233,8 @@ def export(exportList,filename): treated.append(c.Name) sites.append(products[site.Name]) + # add default site, building and storey as required + if not sites: if ADD_DEFAULT_SITE: if DEBUG: print("No site found. Adding default site") @@ -2259,21 +2262,22 @@ def export(exportList,filename): project,sites ) if not buildings: - if DEBUG: print("No building found. Adding default building") - buildings = [ifcfile.createIfcBuilding( - ifcopenshell.guid.new(), - history, - "Default Building", - '', - None, - None, - None, - None, - "ELEMENT", - None, - None, - None - )] + if ADD_DEFAULT_BUILDING: + if DEBUG: print("No building found. Adding default building") + buildings = [ifcfile.createIfcBuilding( + ifcopenshell.guid.new(), + history, + "Default Building", + '', + None, + None, + None, + None, + "ELEMENT", + None, + None, + None + )] if buildings and (not sites): ifcfile.createIfcRelAggregates( ifcopenshell.guid.new(), @@ -2299,10 +2303,13 @@ def export(exportList,filename): sites[0], buildings ) + + # treat objects that are not related to any site, building or storey + untreated = [] for k,v in products.items(): if not(k in treated): - if k != buildings[0].Name: + if (not buildings) or (k != buildings[0].Name): if not(Draft.getType(FreeCAD.ActiveDocument.getObject(k)) in ["Site","Building","Floor","BuildingPart"]): untreated.append(v) elif Draft.getType(FreeCAD.ActiveDocument.getObject(k)) == "BuildingPart": @@ -2310,34 +2317,82 @@ def export(exportList,filename): untreated.append(v) if untreated: if not defaulthost: - defaulthost = ifcfile.createIfcBuildingStorey( + if ADD_DEFAULT_STOREY: + defaulthost = ifcfile.createIfcBuildingStorey( + ifcopenshell.guid.new(), + history, + "Default Storey", + '', + None, + None, + None, + None, + "ELEMENT", + None + ) + # if ADD_DEFAULT_STOREY is on, we need a building to host it, regardless of ADD_DEFAULT_BUILDING + if not buildings: + if DEBUG: print("No building found. Adding default building") + buildings = [ifcfile.createIfcBuilding( + ifcopenshell.guid.new(), + history, + "Default Building", + '', + None, + None, + None, + None, + "ELEMENT", + None, + None, + None + )] + if sites: + ifcfile.createIfcRelAggregates( + ifcopenshell.guid.new(), + history, + 'SiteLink', + '', + sites[0], + buildings + ) + else: + ifcfile.createIfcRelAggregates( + ifcopenshell.guid.new(), + history, + 'ProjectLink', + '', + project,buildings + ) + ifcfile.createIfcRelAggregates( + ifcopenshell.guid.new(), + history, + 'DefaultStoreyLink', + '', + buildings[0], + [defaulthost] + ) + elif buildings: + defaulthost = buildings[0] + if defaulthost: + ifcfile.createIfcRelContainedInSpatialStructure( ifcopenshell.guid.new(), history, - "Default Storey", + 'UnassignedObjectsLink', '', - None, - None, - None, - None, - "ELEMENT", - None + untreated, + defaulthost ) + else: + # no default host: aggregate unassigned objects directly under the IfcProject - WARNING: NON STANDARD + if DEBUG: print("WARNING - Default building generation is disabled. You are producing a non-standard file.") ifcfile.createIfcRelAggregates( ifcopenshell.guid.new(), history, - 'DefaultStoreyLink', + 'ProjectLink', '', - buildings[0], - [defaulthost] + project,untreated ) - ifcfile.createIfcRelContainedInSpatialStructure( - ifcopenshell.guid.new(), - history, - 'UnassignedObjectsLink', - '', - untreated, - defaulthost - ) # materials