diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py index 674f0a48ad..5de7ce2c7d 100644 --- a/src/Mod/Arch/ArchWindow.py +++ b/src/Mod/Arch/ArchWindow.py @@ -965,24 +965,22 @@ class _Window(ArchComponent.Component): ArchComponent.Component.onDocumentRestored(self,obj) self.setProperties(obj) + def onBeforeChange(self,obj,prop): + + if prop in ["Base","WindowParts","Placement","HoleDepth","Height","Width","Hosts"]: + setattr(self,prop,getattr(obj,prop)) + def onChanged(self,obj,prop): self.hideSubobjects(obj,prop) if not "Restore" in obj.State: if prop in ["Base","WindowParts","Placement","HoleDepth","Height","Width","Hosts"]: # anti-recursive loops, bc the base sketch will touch the Placement all the time - ok = True - if prop == "Placement": - if hasattr(self,"Placement"): - if self.Placement == obj.Placement: - ok = False - self.Placement = FreeCAD.Placement(obj.Placement) - elif prop == "Hosts": - if hasattr(self,"Hosts"): - if self.Hosts == obj.Hosts: - ok = False - self.Hosts = obj.Hosts - if ok and hasattr(obj,"Hosts"): + touchhosts = False + if hasattr(self,prop): + if getattr(self,prop) != getattr(obj,prop): + touchhosts = True + if touchhosts and hasattr(obj,"Hosts"): for host in obj.Hosts: # mark host to recompute so it can detect this object host.touch() @@ -1007,12 +1005,206 @@ class _Window(ArchComponent.Component): ArchComponent.Component.onChanged(self,obj,prop) + def buildShapes(self,obj): + + import Part,DraftGeomUtils,math + self.sshapes = [] + self.vshapes = [] + shapes = [] + rotdata = None + for i in range(int(len(obj.WindowParts)/5)): + wires = [] + hinge = None + omode = None + ssymbols = [] + vsymbols = [] + wstr = obj.WindowParts[(i*5)+2].split(',') + for s in wstr: + if "Wire" in s: + j = int(s[4:]) + if obj.Base.Shape.Wires: + if len(obj.Base.Shape.Wires) >= j: + wires.append(obj.Base.Shape.Wires[j]) + elif "Edge" in s: + hinge = int(s[4:])-1 + elif "Mode" in s: + omode = int(s[-1]) + if wires: + max_length = 0 + for w in wires: + if w.BoundBox.DiagonalLength > max_length: + max_length = w.BoundBox.DiagonalLength + ext = w + wires.remove(ext) + shape = Part.Face(ext) + norm = shape.normalAt(0,0) + if hasattr(obj,"Normal"): + if obj.Normal: + if not DraftVecUtils.isNull(obj.Normal): + norm = obj.Normal + if hinge and omode: + opening = None + if hasattr(obj,"Opening"): + if obj.Opening: + opening = obj.Opening/100.0 + e = obj.Base.Shape.Edges[hinge] + ev1 = e.Vertexes[0].Point + ev2 = e.Vertexes[-1].Point + if (ev2.z - ev1.z) < 0.1**Draft.precision(): + if ev2.y < ev1.y: + ev1,ev2 = ev2,ev1 + elif ev2.z < ev1.z: + ev1,ev2 = ev2,ev1 + p = None + d = 0 + for v in shape.Vertexes: + dist = v.Point.distanceToLine(ev1,ev2.sub(ev1)) + if dist > d: + d = dist + p = v.Point + if p: + chord = p.sub(ev1) + enorm = ev2.sub(ev1) + proj = DraftVecUtils.project(chord,enorm) + v1 = ev1 + if proj.Length > 0: + chord = p.sub(ev1.add(proj)) + p = v1.add(chord) + v4 = p.add(DraftVecUtils.scale(enorm,0.5)) + if omode == 1: # Arc 90 + v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),90*opening] + elif omode == 2: # Arc -90 + v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),-90*opening] + elif omode == 3: # Arc 45 + v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/8,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),45*opening] + elif omode == 4: # Arc -45 + v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/8,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),-45*opening] + elif omode == 5: # Arc 180 + v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,math.pi,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),180*opening] + elif omode == 6: # Arc -180 + v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) + v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi,enorm)) + ssymbols.append(Part.Arc(p,v2,v3).toShape()) + ssymbols.append(Part.LineSegment(v3,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [ev1,ev2.sub(ev1),-180*opening] + elif omode == 7: # tri + v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) + ssymbols.append(Part.LineSegment(p,v2).toShape()) + ssymbols.append(Part.LineSegment(v2,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),90*opening] + elif omode == 8: # -tri + v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) + ssymbols.append(Part.LineSegment(p,v2).toShape()) + ssymbols.append(Part.LineSegment(v2,v1).toShape()) + vsymbols.append(Part.LineSegment(v1,v4).toShape()) + vsymbols.append(Part.LineSegment(v4,ev2).toShape()) + if opening: + rotdata = [v1,ev2.sub(ev1),-90*opening] + elif omode == 9: # sliding + pass + elif omode == 10: # -sliding + pass + V = 0 + thk = obj.WindowParts[(i*5)+3] + if "+V" in thk: + thk = thk[:-2] + V = obj.Frame.Value + thk = float(thk) + V + if thk: + exv = DraftVecUtils.scaleTo(norm,thk) + shape = shape.extrude(exv) + for w in wires: + f = Part.Face(w) + f = f.extrude(exv) + shape = shape.cut(f) + if obj.WindowParts[(i*5)+4]: + V = 0 + zof = obj.WindowParts[(i*5)+4] + if "+V" in zof: + zof = zof[:-2] + V = obj.Offset.Value + zof = float(zof) + V + if zof: + zov = DraftVecUtils.scaleTo(norm,zof) + shape.translate(zov) + for symb in ssymbols: + symb.translate(zov) + for symb in vsymbols: + symb.translate(zov) + if rotdata and hinge and omode: + rotdata[0] = rotdata[0].add(zov) + if obj.WindowParts[(i*5)+1] == "Louvre": + if hasattr(obj,"LouvreWidth"): + if obj.LouvreWidth and obj.LouvreSpacing: + bb = shape.BoundBox + bb.enlarge(10) + step = obj.LouvreWidth.Value+obj.LouvreSpacing.Value + if step < bb.ZLength: + box = Part.makeBox(bb.XLength,bb.YLength,obj.LouvreWidth.Value) + boxes = [] + for i in range(int(bb.ZLength/step)+1): + b = box.copy() + b.translate(FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMin+i*step)) + boxes.append(b) + self.boxes = Part.makeCompound(boxes) + #rot = obj.Base.Placement.Rotation + #self.boxes.rotate(self.boxes.BoundBox.Center,rot.Axis,math.degrees(rot.Angle)) + self.boxes.translate(shape.BoundBox.Center.sub(self.boxes.BoundBox.Center)) + shape = shape.cut(self.boxes) + if rotdata: + shape.rotate(rotdata[0],rotdata[1],rotdata[2]) + shapes.append(shape) + self.sshapes.extend(ssymbols) + self.vshapes.extend(vsymbols) + return shapes + def execute(self,obj): if self.clone(obj): clonedProxy = obj.CloneOf.Proxy if not (hasattr(clonedProxy, "sshapes") and hasattr(clonedProxy, "vshapes")): - clonedProxy.execute(obj.CloneOf) + clonedProxy.buildShapes(obj.CloneOf) self.sshapes = clonedProxy.sshapes self.vshapes = clonedProxy.vshapes if hasattr(clonedProxy, "boxes"): @@ -1028,193 +1220,7 @@ class _Window(ArchComponent.Component): if obj.Base.isDerivedFrom("Part::Feature"): if hasattr(obj,"WindowParts"): if obj.WindowParts and (len(obj.WindowParts)%5 == 0): - shapes = [] - rotdata = None - for i in range(int(len(obj.WindowParts)/5)): - wires = [] - hinge = None - omode = None - ssymbols = [] - vsymbols = [] - wstr = obj.WindowParts[(i*5)+2].split(',') - for s in wstr: - if "Wire" in s: - j = int(s[4:]) - if obj.Base.Shape.Wires: - if len(obj.Base.Shape.Wires) >= j: - wires.append(obj.Base.Shape.Wires[j]) - elif "Edge" in s: - hinge = int(s[4:])-1 - elif "Mode" in s: - omode = int(s[-1]) - if wires: - max_length = 0 - for w in wires: - if w.BoundBox.DiagonalLength > max_length: - max_length = w.BoundBox.DiagonalLength - ext = w - wires.remove(ext) - shape = Part.Face(ext) - norm = shape.normalAt(0,0) - if hasattr(obj,"Normal"): - if obj.Normal: - if not DraftVecUtils.isNull(obj.Normal): - norm = obj.Normal - if hinge and omode: - opening = None - if hasattr(obj,"Opening"): - if obj.Opening: - opening = obj.Opening/100.0 - e = obj.Base.Shape.Edges[hinge] - ev1 = e.Vertexes[0].Point - ev2 = e.Vertexes[-1].Point - if (ev2.z - ev1.z) < 0.1**Draft.precision(): - if ev2.y < ev1.y: - ev1,ev2 = ev2,ev1 - elif ev2.z < ev1.z: - ev1,ev2 = ev2,ev1 - p = None - d = 0 - for v in shape.Vertexes: - dist = v.Point.distanceToLine(ev1,ev2.sub(ev1)) - if dist > d: - d = dist - p = v.Point - if p: - chord = p.sub(ev1) - enorm = ev2.sub(ev1) - proj = DraftVecUtils.project(chord,enorm) - v1 = ev1 - if proj.Length > 0: - chord = p.sub(ev1.add(proj)) - p = v1.add(chord) - v4 = p.add(DraftVecUtils.scale(enorm,0.5)) - if omode == 1: # Arc 90 - v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),90*opening] - elif omode == 2: # Arc -90 - v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),-90*opening] - elif omode == 3: # Arc 45 - v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/8,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,math.pi/4,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),45*opening] - elif omode == 4: # Arc -45 - v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/8,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi/4,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),-45*opening] - elif omode == 5: # Arc 180 - v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,math.pi,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),180*opening] - elif omode == 6: # Arc -180 - v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) - v3 = v1.add(DraftVecUtils.rotate(chord,-math.pi,enorm)) - ssymbols.append(Part.Arc(p,v2,v3).toShape()) - ssymbols.append(Part.LineSegment(v3,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [ev1,ev2.sub(ev1),-180*opening] - elif omode == 7: # tri - v2 = v1.add(DraftVecUtils.rotate(chord,math.pi/2,enorm)) - ssymbols.append(Part.LineSegment(p,v2).toShape()) - ssymbols.append(Part.LineSegment(v2,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),90*opening] - elif omode == 8: # -tri - v2 = v1.add(DraftVecUtils.rotate(chord,-math.pi/2,enorm)) - ssymbols.append(Part.LineSegment(p,v2).toShape()) - ssymbols.append(Part.LineSegment(v2,v1).toShape()) - vsymbols.append(Part.LineSegment(v1,v4).toShape()) - vsymbols.append(Part.LineSegment(v4,ev2).toShape()) - if opening: - rotdata = [v1,ev2.sub(ev1),-90*opening] - elif omode == 9: # sliding - pass - elif omode == 10: # -sliding - pass - V = 0 - thk = obj.WindowParts[(i*5)+3] - if "+V" in thk: - thk = thk[:-2] - V = obj.Frame.Value - thk = float(thk) + V - if thk: - exv = DraftVecUtils.scaleTo(norm,thk) - shape = shape.extrude(exv) - for w in wires: - f = Part.Face(w) - f = f.extrude(exv) - shape = shape.cut(f) - if obj.WindowParts[(i*5)+4]: - V = 0 - zof = obj.WindowParts[(i*5)+4] - if "+V" in zof: - zof = zof[:-2] - V = obj.Offset.Value - zof = float(zof) + V - if zof: - zov = DraftVecUtils.scaleTo(norm,zof) - shape.translate(zov) - for symb in ssymbols: - symb.translate(zov) - for symb in vsymbols: - symb.translate(zov) - if rotdata and hinge and omode: - rotdata[0] = rotdata[0].add(zov) - if obj.WindowParts[(i*5)+1] == "Louvre": - if hasattr(obj,"LouvreWidth"): - if obj.LouvreWidth and obj.LouvreSpacing: - bb = shape.BoundBox - bb.enlarge(10) - step = obj.LouvreWidth.Value+obj.LouvreSpacing.Value - if step < bb.ZLength: - box = Part.makeBox(bb.XLength,bb.YLength,obj.LouvreWidth.Value) - boxes = [] - for i in range(int(bb.ZLength/step)+1): - b = box.copy() - b.translate(FreeCAD.Vector(bb.XMin,bb.YMin,bb.ZMin+i*step)) - boxes.append(b) - self.boxes = Part.makeCompound(boxes) - #rot = obj.Base.Placement.Rotation - #self.boxes.rotate(self.boxes.BoundBox.Center,rot.Axis,math.degrees(rot.Angle)) - self.boxes.translate(shape.BoundBox.Center.sub(self.boxes.BoundBox.Center)) - shape = shape.cut(self.boxes) - if rotdata: - shape.rotate(rotdata[0],rotdata[1],rotdata[2]) - shapes.append(shape) - self.sshapes.extend(ssymbols) - self.vshapes.extend(vsymbols) + shapes = self.buildShapes(obj) if shapes: base = Part.makeCompound(shapes) elif not obj.WindowParts: