From 79ba082c556fea5a0b9e83d729c735d77820598c Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Sat, 1 Dec 2018 12:14:00 -0200 Subject: [PATCH] Arch: Fixed IFC export of arch structures with several solids / holes --- src/Mod/Arch/ArchStructure.py | 56 ++++++++++++++++++++++++++++------- src/Mod/Arch/importIFC.py | 37 ++++++++++++----------- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/src/Mod/Arch/ArchStructure.py b/src/Mod/Arch/ArchStructure.py index 30b0a6fa0c..dc51365fee 100644 --- a/src/Mod/Arch/ArchStructure.py +++ b/src/Mod/Arch/ArchStructure.py @@ -526,17 +526,41 @@ class _Structure(ArchComponent.Component): pl = obj.Placement extdata = self.getExtrusionData(obj) if extdata: - base = extdata[0] - base.Placement = extdata[2].multiply(base.Placement) - extv = extdata[2].Rotation.multVec(extdata[1]) - if obj.Tool: - try: - base = obj.Tool.Shape.copy().makePipe(obj.Base.Shape.copy()) - except Part.OCCError: - FreeCAD.Console.PrintError(translate("Arch","Error: The base shape couldn't be extruded along this tool object")+"\n") - return + sh = extdata[0] + if not isinstance(sh,list): + sh = [sh] + ev = extdata[1] + if not isinstance(ev,list): + ev = [ev] + pla = extdata[2] + if not isinstance(pla,list): + pla = [pla] + base = [] + for i in range(len(sh)): + shi = sh[i] + if i < len(ev): + evi = ev[i] + else: + evi = FreeCAD.Vector(ev[-1]) + if i < len(pla): + pli = pla[i] + else: + pli = pla[-1].copy() + shi.Placement = pli.multiply(shi.Placement) + extv = pli.Rotation.multVec(evi) + if obj.Tool: + try: + shi = obj.Tool.Shape.copy().makePipe(obj.Base.Shape.copy()) + except Part.OCCError: + FreeCAD.Console.PrintError(translate("Arch","Error: The base shape couldn't be extruded along this tool object")+"\n") + return + else: + shi = shi.extrude(extv) + base.append(shi) + if len(base) == 1: + base = base[0] else: - base = base.extrude(extv) + base = Part.makeCompound(base) if obj.Base: if obj.Base.isDerivedFrom("Part::Feature"): if obj.Base.Shape.isNull(): @@ -600,6 +624,16 @@ class _Structure(ArchComponent.Component): base,placement = self.rebase(obj.Base.Shape) normal = obj.Base.Shape.Faces[0].normalAt(0,0) normal = placement.inverse().Rotation.multVec(normal) + if (len(obj.Shape.Solids) > 1) and (len(obj.Shape.Solids) == len(obj.Base.Shape.Faces)): + # multiple extrusions + b = [] + p = [] + for f in obj.Base.Shape.Faces: + bf,pf = self.rebase(f) + b.append(bf) + p.append(pf) + base = b + placement = p elif obj.Base.Shape.Wires: baseface = None if hasattr(obj,"FaceMaker"): @@ -683,7 +717,7 @@ class _Structure(ArchComponent.Component): # ResetNodes is not a property but it allows us to use this function to force reset the nodes nodes = None extdata = self.getExtrusionData(obj) - if extdata: + if extdata and not isinstance(extdata[0],list): nodes = extdata[0] nodes.Placement = nodes.Placement.multiply(extdata[2]) if role not in ["Slab"]: diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 5a34310fa7..9860a0afef 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -625,7 +625,7 @@ def insert(filename,docname,skip=[],only=[],root=None): pass # IfcOpenShell will yield an error if a given product has no shape, but we don't care, we're brave enough if brep: - if DEBUG: print(" "+str(len(brep)/1000)+"k ",end="") + if DEBUG: print(" "+str(int(len(brep)/1000))+"k ",end="") shape = Part.Shape() shape.importBrepFromString(brep,False) @@ -2642,6 +2642,7 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess if hasattr(obj.Proxy,"getExtrusionData"): extdata = obj.Proxy.getExtrusionData(obj) if extdata: + #print(extdata) # convert to meters p = extdata[0] if not isinstance(p,list): @@ -2656,14 +2657,14 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess pi = p[i] pi.scale(0.001) if i < len(ev): - evi = ev[i] + evi = FreeCAD.Vector(ev[i]) else: - evi = ev[-1] + evi = FreeCAD.Vector(ev[-1]) evi.multiply(0.001) if i < len(pl): - pli = pl[i] + pli = pl[i].copy() else: - pli = pl[-1] + pli = pl[-1].copy() pli.Base = pli.Base.multiply(0.001) pstr = str([v.Point for v in p[i].Vertexes]) if pstr in profiledefs: @@ -2690,19 +2691,19 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess shapes.append(shape) solidType = "SweptSolid" shapetype = "extrusion" - elif hasattr(obj.Proxy,"getRebarData"): - # export rebars as IfcSweptDiskSolid - rdata = obj.Proxy.getRebarData(obj) - if rdata: - # convert to meters - r = rdata[1] * 0.001 - for w in rdata[0]: - w.scale(0.001) - cur = createCurve(ifcfile,w) - shape = ifcfile.createIfcSweptDiskSolid(cur,r) - shapes.append(shape) - solidType = "SweptSolid" - shapetype = "extrusion" + elif hasattr(obj.Proxy,"getRebarData"): + # export rebars as IfcSweptDiskSolid + rdata = obj.Proxy.getRebarData(obj) + if rdata: + # convert to meters + r = rdata[1] * 0.001 + for w in rdata[0]: + w.scale(0.001) + cur = createCurve(ifcfile,w) + shape = ifcfile.createIfcSweptDiskSolid(cur,r) + shapes.append(shape) + solidType = "SweptSolid" + shapetype = "extrusion" if not shapes: