From ac0268c904d094f43f4266d142b6937341eb7d64 Mon Sep 17 00:00:00 2001 From: alafr Date: Sun, 16 Feb 2020 13:13:43 +0100 Subject: [PATCH] Export Arch Structure as Ifc Brep if not a simple extrusion --- src/Mod/Arch/ArchComponent.py | 2 +- src/Mod/Arch/ArchStructure.py | 46 ++++++++++++-------- src/Mod/Arch/exportIFC.py | 81 +++++++++++++++++++---------------- 3 files changed, 71 insertions(+), 58 deletions(-) diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index efc7d92d02..181c9bec64 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -318,7 +318,7 @@ class Component(ArchIFC.IfcProduct): def getExtrusionData(self,obj): - "returns (shape,extrusion vector,placement) or None" + "returns (shape,extrusion vector or path,placement) or None" if hasattr(obj,"CloneOf"): if obj.CloneOf: if hasattr(obj.CloneOf,"Proxy"): diff --git a/src/Mod/Arch/ArchStructure.py b/src/Mod/Arch/ArchStructure.py index 32fc97823e..dc78284e7a 100644 --- a/src/Mod/Arch/ArchStructure.py +++ b/src/Mod/Arch/ArchStructure.py @@ -669,14 +669,14 @@ class _Structure(ArchComponent.Component): else: pli = pla[-1].copy() shi.Placement = pli.multiply(shi.Placement) - extv = pla[0].Rotation.multVec(evi) - if obj.Tool: + if not isinstance(evi, FreeCAD.Vector): try: - shi = obj.Tool.Shape.copy().makePipe(shi) + shi = evi.makePipe(shi) except Part.OCCError: FreeCAD.Console.PrintError(translate("Arch","Error: The base shape couldn't be extruded along this tool object")+"\n") return else: + extv = pla[0].Rotation.multVec(evi) shi = shi.extrude(extv) base.append(shi) if len(base) == 1: @@ -807,23 +807,31 @@ class _Structure(ArchComponent.Component): baseface = Part.Face(Part.makePolygon([v1,v2,v3,v4,v1])) base,placement = self.rebase(baseface) if base and placement: - if obj.Normal.Length: - normal = Vector(obj.Normal) - if isinstance(placement,list): - normal = placement[0].inverse().Rotation.multVec(normal) - else: - normal = placement.inverse().Rotation.multVec(normal) - if not normal: - normal = Vector(0,0,1) - if not normal.Length: - normal = Vector(0,0,1) - extrusion = normal - if (length > height) and (IfcType != "Slab"): - if length: - extrusion = normal.multiply(length) + if obj.Tool: + if obj.Tool.Shape: + edges = obj.Tool.Shape.Edges + if len(edges) == 1 and DraftGeomUtils.geomType(edges[0]) == "Line": + extrusion = DraftGeomUtils.vec(edges[0]) + else: + extrusion = obj.Tool.Shape.copy() else: - if height: - extrusion = normal.multiply(height) + if obj.Normal.Length: + normal = Vector(obj.Normal) + if isinstance(placement,list): + normal = placement[0].inverse().Rotation.multVec(normal) + else: + normal = placement.inverse().Rotation.multVec(normal) + if not normal: + normal = Vector(0,0,1) + if not normal.Length: + normal = Vector(0,0,1) + extrusion = normal + if (length > height) and (IfcType != "Slab"): + if length: + extrusion = normal.multiply(length) + else: + if height: + extrusion = normal.multiply(height) return (base,extrusion,placement) return None diff --git a/src/Mod/Arch/exportIFC.py b/src/Mod/Arch/exportIFC.py index c5f2717310..89cc676afa 100644 --- a/src/Mod/Arch/exportIFC.py +++ b/src/Mod/Arch/exportIFC.py @@ -1812,44 +1812,49 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess pl = extdata[2] if not isinstance(pl,list): pl = [pl] - for i in range(len(p)): - pi = p[i] - pi.scale(preferences['SCALE_FACTOR']) - if i < len(ev): - evi = FreeCAD.Vector(ev[i]) - else: - evi = FreeCAD.Vector(ev[-1]) - evi.multiply(preferences['SCALE_FACTOR']) - if i < len(pl): - pli = pl[i].copy() - else: - pli = pl[-1].copy() - pli.Base = pli.Base.multiply(preferences['SCALE_FACTOR']) - pstr = str([v.Point for v in p[i].Vertexes]) - if pstr in profiledefs: - profile = profiledefs[pstr] - shapetype = "reusing profile" - else: - profile = getProfile(ifcfile,pi) - if profile: - profiledefs[pstr] = profile - if profile and not(DraftVecUtils.isNull(evi)): - #ev = pl.Rotation.inverted().multVec(evi) - #print("evi:",evi) - if not tostore: - # add the object placement to the profile placement. Otherwise it'll be done later at map insert - pl2 = obj.getGlobalPlacement() - pl2.Base = pl2.Base.multiply(preferences['SCALE_FACTOR']) - pli = pl2.multiply(pli) - xvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(1,0,0)))) - zvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(0,0,1)))) - ovc = ifcbin.createIfcCartesianPoint(tuple(pli.Base)) - lpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc) - edir = ifcbin.createIfcDirection(tuple(FreeCAD.Vector(evi).normalize())) - shape = ifcfile.createIfcExtrudedAreaSolid(profile,lpl,edir,evi.Length) - shapes.append(shape) - solidType = "SweptSolid" - shapetype = "extrusion" + simpleExtrusion = True + for evi in ev: + if not isinstance(evi, FreeCAD.Vector): + simpleExtrusion = False + if simpleExtrusion: + for i in range(len(p)): + pi = p[i] + pi.scale(preferences['SCALE_FACTOR']) + if i < len(ev): + evi = FreeCAD.Vector(ev[i]) + else: + evi = FreeCAD.Vector(ev[-1]) + evi.multiply(preferences['SCALE_FACTOR']) + if i < len(pl): + pli = pl[i].copy() + else: + pli = pl[-1].copy() + pli.Base = pli.Base.multiply(preferences['SCALE_FACTOR']) + pstr = str([v.Point for v in p[i].Vertexes]) + if pstr in profiledefs: + profile = profiledefs[pstr] + shapetype = "reusing profile" + else: + profile = getProfile(ifcfile,pi) + if profile: + profiledefs[pstr] = profile + if profile and not(DraftVecUtils.isNull(evi)): + #ev = pl.Rotation.inverted().multVec(evi) + #print("evi:",evi) + if not tostore: + # add the object placement to the profile placement. Otherwise it'll be done later at map insert + pl2 = obj.getGlobalPlacement() + pl2.Base = pl2.Base.multiply(preferences['SCALE_FACTOR']) + pli = pl2.multiply(pli) + xvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(1,0,0)))) + zvc = ifcbin.createIfcDirection(tuple(pli.Rotation.multVec(FreeCAD.Vector(0,0,1)))) + ovc = ifcbin.createIfcCartesianPoint(tuple(pli.Base)) + lpl = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc) + edir = ifcbin.createIfcDirection(tuple(FreeCAD.Vector(evi).normalize())) + shape = ifcfile.createIfcExtrudedAreaSolid(profile,lpl,edir,evi.Length) + shapes.append(shape) + solidType = "SweptSolid" + shapetype = "extrusion" if not shapes: