From d54db8c223548b1a717bba40290b5f03214a98da Mon Sep 17 00:00:00 2001 From: Paul Lee Date: Wed, 3 Sep 2025 08:12:45 +0800 Subject: [PATCH] [ArchComponent] Fix 1st Addition Placment & MovableChildren Includes Railings I. Fix 1st Addition Placement 1. Arch Object can have no Base. 2. ArchComponent.processSubShapes() would keep the placement of Additions by treating with inverse placement when the parent Arch Object placemnet is changed. 3. However, when there is not base/Base, 1st Addition becomes 'base' and the placement is not treated by inverse placement and the displacement is doubled 4. This commit identify the above case and apply same inverse placment II. MovableChildren Includes Railings 1. getMovableChildren() does not includes Railing (on top of Additions/Subtraction) 2. This commit fix the behaviour to make it consisteny Other Associated Inconsistency - Other visibility default behaviour as discussed in https://forum.freecad.org/viewtopic.php?p=844965#p844920 would be added in subsequent PR Last associated PR/commit - https://github.com/FreeCAD/FreeCAD/pull/23556 --- src/Mod/BIM/ArchComponent.py | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Mod/BIM/ArchComponent.py b/src/Mod/BIM/ArchComponent.py index 02dfd059ae..3ee2cb4ad7 100644 --- a/src/Mod/BIM/ArchComponent.py +++ b/src/Mod/BIM/ArchComponent.py @@ -365,6 +365,14 @@ class Component(ArchIFC.IfcProduct): elif hasattr(o,"Host"): if obj == o.Host: ilist.append(o) + + # Stairs railings should be considered as children + # (RailingLeft and RailingRight property) + if hasattr(obj, "RailingLeft") and obj.RailingLeft: + ilist.append(obj.RailingLeft) + if hasattr(obj, "RailingRight") and obj.RailingRight: + ilist.append(obj.RailingRight) + ilist2 = [] for o in ilist: if hasattr(o,"MoveWithHost"): @@ -727,14 +735,25 @@ class Component(ArchIFC.IfcProduct): # treat additions for o in obj.Additions: - if not base: + # Arch Objects can have no Base, but Additions only + # If there is no base/base isNull, 1st Addition becomes 'base', + # placement should be treated as rest of Additions. + #if not base: + if not base or base.isNull(): if hasattr(o,'Shape'): - base = o.Shape + base = Part.Shape(o.Shape) #base = o.Shape + # Base is first Addition, treat placement as other Additions + if placement: + # see https://forum.freecad.org/viewtopic.php?p=579754#p579754 + base.Placement = placement.multiply(base.Placement) else: - if base.isNull(): - if hasattr(o,'Shape'): - base = o.Shape - else: + # base.isNull() case grouped into if condition above, no need + # if/else below. Remarked out 2025.9.2 + # + #if base.isNull(): + # if hasattr(o,'Shape'): + # base = o.Shape + #else: # special case, both walls with coinciding endpoints import ArchWall js = ArchWall.mergeShapes(o,obj) @@ -746,7 +765,7 @@ class Component(ArchIFC.IfcProduct): base = base.fuse(add) elif hasattr(o,'Shape'): if o.Shape and not o.Shape.isNull() and o.Shape.Solids: - ## TODO use Part.Shape() instead? + # TODO use Part.Shape() instead? s = o.Shape.copy() if placement: # see https://forum.freecad.org/viewtopic.php?p=579754#p579754