BIM: Smart removal of wall bases (#24550)
* BIM: Implement smart base removal for Walls Previously, removing the Base object from an Arch Wall would cause the wall to reset its position to the document origin and could lead to unintended geometric changes for complex walls. This commit introduces a "smart debasing" mechanism integrated into the Component Task Panel's "Remove" button: - For walls based on a single straight line, the operation now preserves the wall's global position and parametric `Length`, making it an independent object. - For walls with complex bases (multi-segment, curved), a warning dialog is now presented to the user, explaining the consequences (shape alteration and position reset) before allowing the operation to proceed. This is supported by new API functions `Arch.is_debasable()` and `Arch.debaseWall()`, which contain the core logic for the feature. Fixes: https://github.com/FreeCAD/FreeCAD/issues/24453 * BIM: Move wall debasing logic into ArchWall proxy The logic for handling the removal of a wall's base object was previously implemented directly within the generic `ComponentTaskPanel` in `ArchComponent.py`. This created a tight coupling, forcing the generic component UI to have specific knowledge about the `ArchWall` type. This commit refactors the implementation to follow a more object-oriented and polymorphic design: 1. A new overridable method, `handleComponentRemoval(subobject)`, has been added to the base `ArchComponent` proxy class. Its default implementation maintains the standard removal behavior. 2. The `_Wall` proxy class in `ArchWall.py` now overrides this method. All wall-specific debasing logic, including the eligibility check and the user-facing warning dialog, now resides entirely within this override. 3. The `ComponentTaskPanel.removeElement` method has been simplified. It is now a generic dispatcher that calls `handleComponentRemoval` on the proxy of the object being edited, with no specific knowledge of object types. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * BIM: Correct user warning The operation can indeed be undone. Co-authored-by: Roy-043 <70520633+Roy-043@users.noreply.github.com> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Roy-043 <70520633+Roy-043@users.noreply.github.com>
This commit is contained in:
@@ -835,6 +835,13 @@ class Component(ArchIFC.IfcProduct):
|
||||
if o:
|
||||
o.ViewObject.hide()
|
||||
|
||||
def handleComponentRemoval(self, obj, subobject):
|
||||
"""
|
||||
Default handler for when a component is removed via the Task Panel.
|
||||
Subclasses can override this to provide special behavior.
|
||||
"""
|
||||
removeFromComponent(obj, subobject)
|
||||
|
||||
def processSubShapes(self, obj, base, placement=None):
|
||||
"""Add Additions and Subtractions to a base shape.
|
||||
|
||||
@@ -2284,18 +2291,24 @@ class ComponentTaskPanel:
|
||||
self.update()
|
||||
|
||||
def removeElement(self):
|
||||
"""This method is run as a callback when the user selects the remove button.
|
||||
|
||||
Get the object selected in the tree widget. If there is an object in
|
||||
the document with the same Name as the selected item in the tree,
|
||||
remove it from the object being edited, with the removeFromComponent()
|
||||
function.
|
||||
"""
|
||||
This method is run as a callback when the user selects the remove button.
|
||||
It calls a handler on the object's proxy to perform the removal.
|
||||
"""
|
||||
element_selected = self.tree.currentItem()
|
||||
if not element_selected:
|
||||
return
|
||||
|
||||
element_to_remove = FreeCAD.ActiveDocument.getObject(str(element_selected.toolTip(0)))
|
||||
|
||||
# Call the polymorphic handler on the object's proxy.
|
||||
# This is generic and works for any Arch object.
|
||||
if hasattr(self.obj.Proxy, "handleComponentRemoval"):
|
||||
self.obj.Proxy.handleComponentRemoval(self.obj, element_to_remove)
|
||||
else:
|
||||
# Fallback for older proxies that might not have the method
|
||||
removeFromComponent(self.obj, element_to_remove)
|
||||
|
||||
it = self.tree.currentItem()
|
||||
if it:
|
||||
comp = FreeCAD.ActiveDocument.getObject(str(it.toolTip(0)))
|
||||
removeFromComponent(self.obj, comp)
|
||||
self.update()
|
||||
|
||||
def accept(self):
|
||||
|
||||
Reference in New Issue
Block a user