From 2501296c95f10ce14a2ec3de68eb88dc9beba00a Mon Sep 17 00:00:00 2001 From: Alexey Chernov <4ernov@gmail.com> Date: Tue, 9 Jul 2024 23:18:57 +0300 Subject: [PATCH 1/3] Apply result of copy on change properties Copy on change properties propagated to SubShapeBinder can be changed there and then updated in the base body (support). On the other hand, they might be used in calculation of some other properties in the base body which could also be copy on change and propagated to the same SubShapeBinder. It looks natural that these latter properties should be updated with the calculation results as well. Example: Body has copy on change properties A = 200 mm and B = 3 * A = 600 mm. SubShapeBinder with support of Body has A changed to 300 mm and expects B = 3 * 300 mm = 900 mm. Without this change B is not updated and equals to 600 mm in SubShapeBinder as well. --- src/Mod/PartDesign/App/ShapeBinder.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 3bd829afab..020526b221 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -620,6 +620,20 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { } if (recomputeCopy && !copied->recomputeFeature(true)) copyerror = 2; + if (!copyerror) { + for (auto prop : props) { + if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) + continue; + auto p = copied->getPropertyByName(prop->getName()); + if (p && p->getContainer() == copied + && p->getTypeId() == prop->getTypeId() + && !p->isSame(*prop)) + { + std::unique_ptr pcopy(p->Copy()); + prop->Paste(*pcopy); + } + } + } } obj = copied; _CopiedLink.setValue(copied, l.getSubValues(false)); From 4db7cd52e63198d1c29d4de3ccc3441d92f032d7 Mon Sep 17 00:00:00 2001 From: Alexey Chernov <4ernov@gmail.com> Date: Thu, 25 Jul 2024 03:09:52 +0300 Subject: [PATCH 2/3] Use lambda to prevent code duplication --- src/Mod/PartDesign/App/ShapeBinder.cpp | 34 ++++++++++++-------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index 020526b221..cb1e58af6f 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -605,22 +605,8 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { if (!copyerror) { std::vector props; getPropertyList(props); - for (auto prop : props) { - if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) - continue; - auto p = copied->getPropertyByName(prop->getName()); - if (p && p->getContainer() == copied - && p->getTypeId() == prop->getTypeId() - && !p->isSame(*prop)) - { - recomputeCopy = true; - std::unique_ptr pcopy(prop->Copy()); - p->Paste(*pcopy); - } - } - if (recomputeCopy && !copied->recomputeFeature(true)) - copyerror = 2; - if (!copyerror) { + // lambda for copying values of copy-on-change properties + const auto copyPropertyValues = [this, &recomputeCopy, &props, copied](const bool to_parent) { for (auto prop : props) { if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) continue; @@ -629,11 +615,21 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { && p->getTypeId() == prop->getTypeId() && !p->isSame(*prop)) { - std::unique_ptr pcopy(p->Copy()); - prop->Paste(*pcopy); + recomputeCopy = true; + auto* const from = to_parent ? prop : p; + auto* const to = to_parent ? p : prop; + + std::unique_ptr pcopy(from->Copy()); + to->Paste(*pcopy); } } - } + }; + + copyPropertyValues(true); + if (recomputeCopy && !copied->recomputeFeature(true)) + copyerror = 2; + if (!copyerror) + copyPropertyValues(false); } obj = copied; _CopiedLink.setValue(copied, l.getSubValues(false)); From 66e1c0154d81e165e5ebe7df6af1ff07df542230 Mon Sep 17 00:00:00 2001 From: Alexey Chernov <4ernov@gmail.com> Date: Tue, 30 Jul 2024 23:16:10 +0300 Subject: [PATCH 3/3] Require read-only and output attributes on updated properties Require the property to be both read-only and output for it to be updated back from support to binder when calculated with expression in support. --- src/Mod/PartDesign/App/ShapeBinder.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Mod/PartDesign/App/ShapeBinder.cpp b/src/Mod/PartDesign/App/ShapeBinder.cpp index cb1e58af6f..31040e5001 100644 --- a/src/Mod/PartDesign/App/ShapeBinder.cpp +++ b/src/Mod/PartDesign/App/ShapeBinder.cpp @@ -606,18 +606,21 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) { std::vector props; getPropertyList(props); // lambda for copying values of copy-on-change properties - const auto copyPropertyValues = [this, &recomputeCopy, &props, copied](const bool to_parent) { + const auto copyPropertyValues = [this, &recomputeCopy, &props, copied](const bool to_support) { for (auto prop : props) { if (!App::LinkBaseExtension::isCopyOnChangeProperty(this, *prop)) continue; + // we only copy read-only and output properties from support to binder + if (!to_support && !(prop->testStatus(App::Property::Output) && prop->testStatus(App::Property::ReadOnly))) + continue; auto p = copied->getPropertyByName(prop->getName()); if (p && p->getContainer() == copied && p->getTypeId() == prop->getTypeId() && !p->isSame(*prop)) { recomputeCopy = true; - auto* const from = to_parent ? prop : p; - auto* const to = to_parent ? p : prop; + auto* const from = to_support ? prop : p; + auto* const to = to_support ? p : prop; std::unique_ptr pcopy(from->Copy()); to->Paste(*pcopy);