[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)
This commit is contained in:
paul
2025-06-05 20:01:06 +08:00
committed by GitHub
parent 1f11be1059
commit b5131f0a9f
2 changed files with 40 additions and 4 deletions

View File

@@ -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

View File

@@ -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()