From d35d3a025bddd7a17a182c0a7616f410dd0db0c1 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 b66d413debc57198ce4c83c569ad0ca2152e130e 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 be7a16fc5b32f4d3ad76a71574329c65884fcbbd 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);