From b5131f0a9fcef1bb8b0637f04cf030229afc72b6 Mon Sep 17 00:00:00 2001 From: paul <40677073+paullee0@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:01:06 +0800 Subject: [PATCH] [ArchWindow] Bug-fix Changing Sill _&_ SketchArch Support Sill Property (#21726) * [ArchWindow] Bug-fix Changing Sill _&_ SketchArch Support Sill Property 1. Bug found in https://github.com/FreeCAD/FreeCAD/pull/21005 (Allow changing Sill parameter) self.baseSill self.basePos : - need to be restored as 'initial' settings in onDocumentRestored() as corresponding codes in onChanged() does upon object creation 2. ArchWindow with SketchArch add-on to support above 'Allow changing Sill paramemeter' feature - Update to ArchWindow following groundworks in https://github.com/FreeCAD/FreeCAD/pull/21568/ * [ArchWindow] Bug-fix Changing Sill _&_ SketchArch Support Sill Property (rev) --- src/Mod/BIM/ArchWindow.py | 35 ++++++++++++++++++++++++++-- src/Mod/BIM/bimcommands/BimWindow.py | 9 +++++-- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/Mod/BIM/ArchWindow.py b/src/Mod/BIM/ArchWindow.py index 42d68f642f..54af545600 100644 --- a/src/Mod/BIM/ArchWindow.py +++ b/src/Mod/BIM/ArchWindow.py @@ -188,6 +188,13 @@ class _Window(ArchComponent.Component): # Add features in the SketchArch External Add-on self.addSketchArchFeatures(obj, mode='ODR') + # Need to restore 'initial' settings as corresponding codes in onChanged() does upon object creation + self.baseSill = obj.Sill.Value + self.basePos = obj.Base.Placement.Base + self.atthOff = None + if hasattr(obj, 'AttachmentOffsetXyzAndRotation'): + self.atthOff = obj.AttachmentOffsetXyzAndRotation.Base + def onBeforeChange(self,obj,prop): if prop in ["Base","WindowParts","Placement","HoleDepth","Height","Width","Hosts"]: @@ -200,12 +207,36 @@ class _Window(ArchComponent.Component): self.hideSubobjects(obj,prop) if prop == "Sill": val = getattr(obj,prop).Value - if getattr(self, 'baseSill', None) is None and getattr(self, 'basePos', None) is None: + + if (getattr(self, 'baseSill', None) is None and + getattr(self, 'basePos', None) is None and + getattr(self, 'atthOff', None) is None): # TODO Any cases only 1 or 2 are not None? self.baseSill = val self.basePos = obj.Base.Placement.Base + self.atthOff = None + if hasattr(obj, 'AttachmentOffsetXyzAndRotation'): + self.atthOff = obj.AttachmentOffsetXyzAndRotation.Base return - obj.Base.Placement.Base.z = self.basePos.z + (obj.Sill.Value - self.baseSill) + import ArchSketchObject # Need to import per method + host = None + if obj.Hosts: + host = obj.Hosts[0] + if (hasattr(obj, 'AttachToAxisOrSketch') and + obj.AttachToAxisOrSketch == "Host" and + host and Draft.getType(host.Base) == "ArchSketch" and + hasattr(ArchSketchObject, 'updateAttachmentOffset')): + SketchArch = True + else: + SketchArch = False + + if SketchArch: + objAttOff = obj.AttachmentOffsetXyzAndRotation + objAttOff.Base.z = self.atthOff.z + (obj.Sill.Value - self.baseSill) + obj.AttachmentOffsetXyzAndRotation = objAttOff + else: + obj.Base.Placement.Base.z = self.basePos.z + (obj.Sill.Value - self.baseSill) + elif not "Restore" in obj.State: if prop in ["Base","WindowParts","Placement","HoleDepth","Height","Width","Hosts","Shape"]: # anti-recursive loops, bc the base sketch will touch the Placement all the time diff --git a/src/Mod/BIM/bimcommands/BimWindow.py b/src/Mod/BIM/bimcommands/BimWindow.py index 451d97b566..05ab3d0e00 100644 --- a/src/Mod/BIM/bimcommands/BimWindow.py +++ b/src/Mod/BIM/bimcommands/BimWindow.py @@ -210,7 +210,6 @@ class Arch_Window: break FreeCADGui.doCommand("win = FreeCAD.ActiveDocument.getObject('" + o.Name + "')") FreeCADGui.doCommand("win.Base.Placement = pl") - # 2025.5.25 # Historically, this normal was deduced by the orientation of the Base Sketch and hardcoded in the Normal property. # Now with the new AutoNormalReversed property/flag, set True as default, the auto Normal previously in opposite direction to is now consistent with that previously hardcoded. # With the normal set to 'auto', window object would not suffer weird shape if the Base Sketch is rotated by some reason. @@ -240,7 +239,11 @@ class Arch_Window: FreeCAD.ArchSketchLock): if self.Include: # Window base sketch's placement stay at orgin is good if addon exists and self.Include - FreeCADGui.doCommand("win = Arch.makeWindowPreset('" + WindowPresets[self.Preset] + "' " + wp + ", window_sill=" + str(self.Sill.Value) + ")") + # Window object triggers onChanged() upon setting/changing Window.Sill to move Window's z position + # For Window with SketchArch add-on, attachToHost() is to be run below below to set the 'initial' Window's placement first before triggering onChanged() below, + # so window_sill parameter is not used here at the moment, see 'if self.Include' below. + #FreeCADGui.doCommand("win = Arch.makeWindowPreset('" + WindowPresets[self.Preset] + "' " + wp + ", window_sill=" + str(self.Sill.Value) + ")") + FreeCADGui.doCommand("win = Arch.makeWindowPreset('" + WindowPresets[self.Preset] + "' " + wp + ")") else: # Window base sketch's placement follow getPoint placement if addon exists but NOT self.Include FreeCADGui.doCommand("win = Arch.makeWindowPreset('" + WindowPresets[self.Preset] + "' " + wp + ", placement=pl, window_sill=" + str(self.Sill.Value) + ")") @@ -262,6 +265,8 @@ class Arch_Window: FreeCADGui.doCommand("win.Hosts = win.Hosts + [FreeCAD.ActiveDocument." + sibling.Name + "]") if SketchArch: ArchSketchObject.attachToHost(w, target=host, pl=wPl) + # Trigger onChanged() in the window object by setting Window.Sill, after setting the Window's 'initial' placement by attachToHost() above + FreeCADGui.doCommand("win.Sill = " + str(self.Sill.Value)) self.doc.commitTransaction() self.doc.recompute()