From 8487ec7e1d2a957e317d9db3d480bf37c9457d06 Mon Sep 17 00:00:00 2001 From: Roy-043 Date: Mon, 7 Apr 2025 18:44:52 +0200 Subject: [PATCH] BIM: Hidden objects used for variant Links should not be hosted If a window is a variant Link there will be a hidden source object in the document. That hidden object shares properties with the visible Link object. The Hosts property may be one of them, yet the hidden object should never be hosted. Forum topics: https://forum.freecad.org/viewtopic.php?p=817743#p817743 (sample file) https://forum.freecad.org/viewtopic.php?t=96115 (code discussion) To test the code: 1. Open the mentioned sample file. 2. Change the Hosts property of Window001 to Wall. 3. Recompute. --- src/Mod/BIM/ArchComponent.py | 42 +++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/src/Mod/BIM/ArchComponent.py b/src/Mod/BIM/ArchComponent.py index 0eee795199..ec4f19f6f2 100644 --- a/src/Mod/BIM/ArchComponent.py +++ b/src/Mod/BIM/ArchComponent.py @@ -767,12 +767,11 @@ class Component(ArchIFC.IfcProduct): # treat subtractions subs = obj.Subtractions for link in obj.InListRecursive: - if hasattr(link,"Hosts"): - if link.Hosts: - if obj in link.Hosts: - subs.append(link) - elif hasattr(link,"Host") and Draft.getType(link) != "Rebar": - if link.Host == obj: + if hasattr(link,"Host"): + if Draft.getType(link) != "Rebar" and link.Host == obj and not self._objectInInternalLinkgroup(link): + subs.append(link) + elif hasattr(link,"Hosts"): + if obj in link.Hosts and not self._objectInInternalLinkgroup(link): subs.append(link) for o in subs: if base: @@ -1143,13 +1142,11 @@ class Component(ArchIFC.IfcProduct): for link in obj.InListRecursive: if hasattr(link,"Host"): - if link.Host: - if link.Host == obj: - hosts.append(link) + if link.Host == obj and not self._objectInInternalLinkgroup(link): + hosts.append(link) elif hasattr(link,"Hosts"): - if link.Hosts: - if obj in link.Hosts: - hosts.append(link) + if obj in link.Hosts and not self._objectInInternalLinkgroup(link): + hosts.append(link) return hosts def ensureBase(self, obj): @@ -1170,6 +1167,27 @@ class Component(ArchIFC.IfcProduct): FreeCAD.Console.PrintError(obj.Label+": "+t+"\n") return False + def _isInternalLinkgroup(self, obj): + """Returns True if obj is an internal LinkGroup. Such a group is used to + store hidden objects used for variant Links that should not be hosted.""" + + # based on code by bdm + # https://forum.freecad.org/viewtopic.php?p=820487#p820428 + if obj.TypeId != "App::LinkGroup": + return False + for inObj in obj.InList: + if getattr(inObj, "LinkCopyOnChangeGroup", None) is obj: + return True + return False + + def _objectInInternalLinkgroup(self, obj): + """Returns True if obj is a hidden object in an internal LinkGroup.""" + + for inObj in obj.InList: + if self._isInternalLinkgroup(inObj): + return True + return False + class ViewProviderComponent: """A default View Provider for Component objects.