From b533c643611fa3bc3a9b727f8160fa638b398c99 Mon Sep 17 00:00:00 2001 From: Yorik van Havre Date: Tue, 19 Mar 2019 19:54:51 -0300 Subject: [PATCH] Arch: Fixed IFC export of rebars --- src/Mod/Arch/ArchCommands.py | 6 ++++- src/Mod/Arch/ArchRebar.py | 14 ++++++---- src/Mod/Arch/importIFC.py | 50 +++++++++++++++++++++--------------- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Mod/Arch/ArchCommands.py b/src/Mod/Arch/ArchCommands.py index 24d3d72ac6..22277cc74d 100644 --- a/src/Mod/Arch/ArchCommands.py +++ b/src/Mod/Arch/ArchCommands.py @@ -737,7 +737,11 @@ def pruneIncluded(objectslist,strict=False): if parent.isDerivedFrom("Part::Feature") and not (Draft.getType(parent) in ["Facebinder","Window","Roof"]): if not parent.isDerivedFrom("Part::Part2DObject"): # don't consider 2D objects based on arch elements - if hasattr(parent,"CloneOf"): + if hasattr(parent,"Host") and (parent.Host == obj): + pass + elif hasattr(parent,"Hosts") and (obj in parent.Hosts): + pass + elif hasattr(parent,"CloneOf"): if parent.CloneOf: if parent.CloneOf.Name != obj.Name: toplevel = False diff --git a/src/Mod/Arch/ArchRebar.py b/src/Mod/Arch/ArchRebar.py index 436e86eaf3..5a47162cb2 100644 --- a/src/Mod/Arch/ArchRebar.py +++ b/src/Mod/Arch/ArchRebar.py @@ -226,11 +226,11 @@ class _Rebar(ArchComponent.Component): def getRebarData(self,obj): - if len(obj.InList) != 1: + if not obj.Host: return - if Draft.getType(obj.InList[0]) != "Structure": + if Draft.getType(obj.Host) != "Structure": return - if not obj.InList[0].Shape: + if not obj.Host.Shape: return if not obj.Base: return @@ -242,9 +242,13 @@ class _Rebar(ArchComponent.Component): return if not obj.Amount: return - father = obj.InList[0] + father = obj.Host wire = obj.Base.Shape.Wires[0] - axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1)) + if Draft.getType(obj.Base) == "Wire": # Draft Wires can have "wrong" placement + import DraftGeomUtils + axis = DraftGeomUtils.getNormal(obj.Base.Shape) + else: + axis = obj.Base.Placement.Rotation.multVec(FreeCAD.Vector(0,0,-1)) size = (ArchCommands.projectToVector(father.Shape.copy(),axis)).Length if hasattr(obj,"Direction"): if not DraftVecUtils.isNull(obj.Direction): diff --git a/src/Mod/Arch/importIFC.py b/src/Mod/Arch/importIFC.py index 2af6c978b2..6a4b0f3624 100644 --- a/src/Mod/Arch/importIFC.py +++ b/src/Mod/Arch/importIFC.py @@ -2535,27 +2535,36 @@ def createCurve(ifcfile,wire): edges = Part.__sortEdges__(wire.Edges) for e in edges: if isinstance(e.Curve,Part.Circle): + xaxis = e.Curve.XAxis + zaxis = e.Curve.Axis follow = True if last: if not DraftVecUtils.equals(last,e.Vertexes[0].Point): follow = False last = e.Vertexes[0].Point + prev = e.Vertexes[-1].Point else: last = e.Vertexes[-1].Point + prev = e.Vertexes[0].Point else: last = e.Vertexes[-1].Point - p1 = math.degrees(-DraftVecUtils.angle(e.Vertexes[0].Point.sub(e.Curve.Center))) - p2 = math.degrees(-DraftVecUtils.angle(e.Vertexes[-1].Point.sub(e.Curve.Center))) - da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),e.Vertexes[0].Point.sub(e.Curve.Center)) + prev = e.Vertexes[0].Point + p1 = math.degrees(-DraftVecUtils.angle(prev.sub(e.Curve.Center),xaxis,zaxis)) + p2 = math.degrees(-DraftVecUtils.angle(last.sub(e.Curve.Center),xaxis,zaxis)) + da = DraftVecUtils.angle(e.valueAt(e.FirstParameter+0.1).sub(e.Curve.Center),prev.sub(e.Curve.Center)) + #print("curve params:",p1,",",p2,"da=",da) if p1 < 0: p1 = 360 + p1 if p2 < 0: p2 = 360 + p2 if da > 0: - follow = not(follow) - xvc = ifcbin.createIfcDirection((1.0,0.0)) + #follow = not(follow) # now we always draw segments in the correct order, so follow is always true + pass + #print(" circle from",prev,"to",last,"a1=",p1,"a2=",p2) ovc = ifcbin.createIfcCartesianPoint(tuple(e.Curve.Center)) - plc = ifcbin.createIfcAxis2Placement2D(ovc,xvc) + zvc = ifcbin.createIfcDirection(tuple(zaxis)) + xvc = ifcbin.createIfcDirection(tuple(xaxis)) + plc = ifcbin.createIfcAxis2Placement3D(ovc,zvc,xvc) cir = ifcfile.createIfcCircle(plc,e.Curve.Radius) curve = ifcfile.createIfcTrimmedCurve(cir,[ifcfile.createIfcParameterValue(p1)],[ifcfile.createIfcParameterValue(p2)],follow,"PARAMETER") else: @@ -2568,6 +2577,7 @@ def createCurve(ifcfile,wire): last = e.Vertexes[-1].Point else: last = e.Vertexes[-1].Point + #print(" polyline:",verts) pts = [ifcbin.createIfcCartesianPoint(tuple(v)) for v in verts] curve = ifcbin.createIfcPolyline(pts) segment = ifcfile.createIfcCompositeCurveSegment("CONTINUOUS",True,curve) @@ -2705,7 +2715,20 @@ def getRepresentation(ifcfile,context,obj,forcebrep=False,subtraction=False,tess profile = None ev = FreeCAD.Vector() if hasattr(obj,"Proxy"): - if hasattr(obj.Proxy,"getExtrusionData"): + if 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) and hasattr(obj.Proxy,"getExtrusionData"): extdata = obj.Proxy.getExtrusionData(obj) if extdata: #print(extdata) @@ -2757,19 +2780,6 @@ 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" if not shapes: