diff --git a/src/Mod/Arch/ArchComponent.py b/src/Mod/Arch/ArchComponent.py index 7993f5487..4dabc84a5 100644 --- a/src/Mod/Arch/ArchComponent.py +++ b/src/Mod/Arch/ArchComponent.py @@ -311,31 +311,6 @@ class Component: for o in obj.Fixtures: o.Placement.move(delta) - def getSubVolume(self,base,width,plac=None): - "returns a subvolume from a base object" - import Part,DraftVecUtils - - # finding biggest wire in the base shape - max_length = 0 - f = None - for w in base.Shape.Wires: - if w.BoundBox.DiagonalLength > max_length: - max_length = w.BoundBox.DiagonalLength - f = w - if f: - f = Part.Face(f) - n = f.normalAt(0,0) - v1 = DraftVecUtils.scaleTo(n,width*1.1) # we extrude a little more to avoid face-on-face - f.translate(v1) - v2 = v1.negative() - v2 = Vector(v1).multiply(-2) - f = f.extrude(v2) - if plac: - f.Placement = plac - return f - return None - - def hideSubobjects(self,obj,prop): "Hides subobjects when a subobject lists change" if prop in ["Additions","Subtractions"]: @@ -363,22 +338,10 @@ class Component: base = base.fuse(add) elif (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")): - if base: - # windows can be additions or subtractions, treated the same way - if hasattr(self,"Width"): - width = self.Width - else: - b = base.BoundBox - width = max(b.XLength,b.YLength,b.ZLength) - if Draft.isClone(o,"Window"): - window = o.Objects[0] - else: - window = o - if window.Base and width: - f = self.getSubVolume(window.Base,width) - if f: - if base.Solids and f.Solids: - base = base.cut(f) + f = o.Proxy.getSubVolume(o) + if f: + if base.Solids and f.Solids: + base = base.cut(f) elif o.isDerivedFrom("Part::Feature"): if o.Shape: @@ -400,20 +363,10 @@ class Component: if base: if (Draft.getType(o) == "Window") or (Draft.isClone(o,"Window")): # windows can be additions or subtractions, treated the same way - if hasattr(self,"Width"): - width = self.Width - else: - b = base.BoundBox - width = max(b.XLength,b.YLength,b.ZLength) - if Draft.isClone(o,"Window"): - window = o.Objects[0] - else: - window = o - if window.Base and width: - f = self.getSubVolume(window.Base,width) - if f: - if base.Solids and f.Solids: - base = base.cut(f) + f = o.Proxy.getSubVolume(o) + if f: + if base.Solids and f.Solids: + base = base.cut(f) elif o.isDerivedFrom("Part::Feature"): if o.Shape: diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py index 194201c43..88810551b 100644 --- a/src/Mod/Arch/ArchWindow.py +++ b/src/Mod/Arch/ArchWindow.py @@ -117,18 +117,21 @@ class _Window(ArchComponent.Component): ArchComponent.Component.__init__(self,obj) obj.addProperty("App::PropertyStringList","WindowParts","Arch", str(translate("Arch","the components of this window"))) + obj.addProperty("App::PropertyDistance","HoleDepth","Arch", + str(translate("Arch","The depth of the hole that this window makes in its host wall. Keep 0 for automatic."))) self.Type = "Window" obj.Proxy = self - - def execute(self,obj): - self.createGeometry(obj) - + def onChanged(self,obj,prop): self.hideSubobjects(obj,prop) if prop in ["Base","WindowParts"]: - self.createGeometry(obj) + self.execute(obj) + elif prop == "HoleDepth": + for o in obj.InList: + if Draft.getType(o) == "Wall": + o.Proxy.execute(o) - def createGeometry(self,obj): + def execute(self,obj): import Part, DraftGeomUtils pl = obj.Placement base = None @@ -182,6 +185,59 @@ class _Window(ArchComponent.Component): if base: if not base.isNull(): obj.Shape = base + + def getSubVolume(self,obj,plac=None): + "returns a subvolume for cutting in a base wall" + + # getting extrusion depth + base = None + if obj.Base: + base = obj.Base + width = 0 + if hasattr(obj,"HoleDepth"): + if obj.HoleDepth: + width = obj.HoleDepth + if not width: + if base: + b = base.Shape.BoundBox + width = max(b.XLength,b.YLength,b.ZLength) + if not width: + if Draft.isClone(obj,"Window"): + orig = obj.Objects[0] + if orig.Base: + base = orig.Base + if hasattr(orig,"HoleDepth"): + if orig.HoleDepth: + width = orig.HoleDepth + if not width: + if base: + b = base.Shape.BoundBox + width = max(b.XLength,b.YLength,b.ZLength) + if not width: + width = 1.1112 # some weird value to have little chance to overlap with an existing face + if not base: + return None + + # finding biggest wire in the base shape + max_length = 0 + f = None + for w in base.Shape.Wires: + if w.BoundBox.DiagonalLength > max_length: + max_length = w.BoundBox.DiagonalLength + f = w + if f: + import Part + f = Part.Face(f) + n = f.normalAt(0,0) + v1 = DraftVecUtils.scaleTo(n,width) + f.translate(v1) + v2 = v1.negative() + v2 = Vector(v1).multiply(-2) + f = f.extrude(v2) + if plac: + f.Placement = plac + return f + return None class _ViewProviderWindow(ArchComponent.ViewProviderComponent): "A View Provider for the Window object"