From 60e73b408dce0302b269be0ae8ab38c5804595fd Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Tue, 12 Mar 2024 13:52:20 +0100 Subject: [PATCH] Arch: Fixed export of quantities to IFC and support arrays --- src/Mod/Arch/exportIFC.py | 50 +++++++++++---------------------- src/Mod/Arch/exportIFCHelper.py | 34 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/Mod/Arch/exportIFC.py b/src/Mod/Arch/exportIFC.py index ccca6c1c90..8443963086 100644 --- a/src/Mod/Arch/exportIFC.py +++ b/src/Mod/Arch/exportIFC.py @@ -406,6 +406,13 @@ def export(exportList, filename, colors=None, preferences=None): preferences ) assemblyElements.append(subproduct) + exportIFCHelper.writeQuantities(ifcfile, + obj.Base, + subproduct, + history, + preferences['SCALE_FACTOR'] + ) + elif ifctype in ["IfcApp::Part","IfcPart::Compound","IfcElementAssembly"]: if hasattr(obj,"Group"): group = obj.Group @@ -740,7 +747,9 @@ def export(exportList, filename, colors=None, preferences=None): #if preferences['DEBUG'] : print(" adding ifc attributes") props = [] for key in obj.IfcData: - if not (key in ["attributes", "complex_attributes", "IfcUID", "FlagForceBrep"]): + if not (key in ["attributes", "complex_attributes", "IfcUID", "FlagForceBrep", + "ExportHeight", "ExportWidth", "ExportLength", "ExportHorizontalArea", + "ExportVerticalArea", "ExportVolume"]): # (deprecated) properties in IfcData dict are stored as "key":"type(value)" @@ -789,35 +798,7 @@ def export(exportList, filename, colors=None, preferences=None): # Quantities - if hasattr(obj,"IfcData"): - quantities = [] - if ("ExportHeight" in obj.IfcData) and obj.IfcData["ExportHeight"] and hasattr(obj,"Height"): - quantities.append(ifcfile.createIfcQuantityLength('Height',None,None,obj.Height.Value*preferences['SCALE_FACTOR'])) - if ("ExportWidth" in obj.IfcData) and obj.IfcData["ExportWidth"] and hasattr(obj,"Width"): - quantities.append(ifcfile.createIfcQuantityLength('Width',None,None,obj.Width.Value*preferences['SCALE_FACTOR'])) - if ("ExportLength" in obj.IfcData) and obj.IfcData["ExportLength"] and hasattr(obj,"Length"): - quantities.append(ifcfile.createIfcQuantityLength('Length',None,None,obj.Length.Value*preferences['SCALE_FACTOR'])) - if ("ExportHorizontalArea" in obj.IfcData) and obj.IfcData["ExportHorizontalArea"] and hasattr(obj,"HorizontalArea"): - quantities.append(ifcfile.createIfcQuantityArea('HorizontalArea',None,None,obj.HorizontalArea.Value*(preferences['SCALE_FACTOR']**2))) - if ("ExportVerticalArea" in obj.IfcData) and obj.IfcData["ExportVerticalArea"] and hasattr(obj,"VerticalArea"): - quantities.append(ifcfile.createIfcQuantityArea('VerticalArea',None,None,obj.VerticalArea.Value*(preferences['SCALE_FACTOR']**2))) - if ("ExportVolume" in obj.IfcData) and obj.IfcData["ExportVolume"] and obj.isDerivedFrom("Part::Feature"): - quantities.append(ifcfile.createIfcQuantityVolume('Volume',None,None,obj.Shape.Volume*(preferences['SCALE_FACTOR']**3))) - if quantities: - eltq = ifcfile.createIfcElementQuantity( - ifcopenshell.guid.new(), - history, - "ElementQuantities", - None, - "FreeCAD",quantities - ) - ifcfile.createIfcRelDefinesByProperties( - ifcopenshell.guid.new(), - history, - None, - None, - [product],eltq - ) + exportIFCHelper.writeQuantities(ifcfile, obj, product, history, preferences['SCALE_FACTOR']) if preferences['FULL_PARAMETRIC']: @@ -2362,7 +2343,7 @@ def getRepresentation( representation = [ifcfile.createIfcShapeRepresentation(context,'Body',solidType,shapes)] # additional representations? if Draft.getType(obj) in ["Wall","Structure"]: - addrepr = createAxis(ifcfile,obj,preferences) + addrepr = createAxis(ifcfile,obj,preferences, forceclone) if addrepr: representation = representation + [addrepr] productdef = ifcfile.createIfcProductDefinitionShape(None,None,representation) @@ -2467,12 +2448,15 @@ def getAxisContext(ifcfile): return nctx -def createAxis(ifcfile,obj,preferences): +def createAxis(ifcfile,obj,preferences, delta=None): """Creates an axis for a given wall, if applicable""" shape = None + pla = FreeCAD.Placement(obj.Placement) + if isinstance(delta,FreeCAD.Vector): + pla.Base += delta if getattr(obj,"Nodes",None): - shape = Part.makePolygon([obj.Placement.multVec(v) for v in obj.Nodes]) + shape = Part.makePolygon([pla.multVec(v) for v in obj.Nodes]) elif hasattr(obj,"Base") and hasattr(obj.Base,"Shape") and obj.Base.Shape: shape = obj.Base.Shape if shape: diff --git a/src/Mod/Arch/exportIFCHelper.py b/src/Mod/Arch/exportIFCHelper.py index cd2f6c0304..a0a8a41ef2 100644 --- a/src/Mod/Arch/exportIFCHelper.py +++ b/src/Mod/Arch/exportIFCHelper.py @@ -56,6 +56,40 @@ def writeUnits(ifcfile,unit="metre"): return ifcfile +def writeQuantities(ifcfile, obj, product, history, scale): + "append quantities to the given object" + + if hasattr(obj,"IfcData"): + quantities = [] + if ("ExportHeight" in obj.IfcData) and obj.IfcData["ExportHeight"] and hasattr(obj,"Height"): + quantities.append(ifcfile.createIfcQuantityLength('Height',None,None,obj.Height.Value*scale)) + if ("ExportWidth" in obj.IfcData) and obj.IfcData["ExportWidth"] and hasattr(obj,"Width"): + quantities.append(ifcfile.createIfcQuantityLength('Width',None,None,obj.Width.Value*scale)) + if ("ExportLength" in obj.IfcData) and obj.IfcData["ExportLength"] and hasattr(obj,"Length"): + quantities.append(ifcfile.createIfcQuantityLength('Length',None,None,obj.Length.Value*scale)) + if ("ExportHorizontalArea" in obj.IfcData) and obj.IfcData["ExportHorizontalArea"] and hasattr(obj,"HorizontalArea"): + quantities.append(ifcfile.createIfcQuantityArea('HorizontalArea',None,None,obj.HorizontalArea.Value*(scale**2))) + if ("ExportVerticalArea" in obj.IfcData) and obj.IfcData["ExportVerticalArea"] and hasattr(obj,"VerticalArea"): + quantities.append(ifcfile.createIfcQuantityArea('VerticalArea',None,None,obj.VerticalArea.Value*(scale**2))) + if ("ExportVolume" in obj.IfcData) and obj.IfcData["ExportVolume"] and obj.isDerivedFrom("Part::Feature"): + quantities.append(ifcfile.createIfcQuantityVolume('Volume',None,None,obj.Shape.Volume*(scale**3))) + if quantities: + eltq = ifcfile.createIfcElementQuantity( + ifcopenshell.guid.new(), + history, + "ElementQuantities", + None, + "FreeCAD",quantities + ) + ifcfile.createIfcRelDefinesByProperties( + ifcopenshell.guid.new(), + history, + None, + None, + [product],eltq + ) + + class SIUnitCreator: def __init__(self, file, text, type): self.prefixes = [