-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Gui: Add Part variant logic #19735
base: main
Are you sure you want to change the base?
Gui: Add Part variant logic #19735
Conversation
This commit does not do anything but just adds logic to intercept getters and setters to properties. This is used to compute shapes from document objects. In particular for document objects, it creates a stack of document objects that is used to write and read properties to and from when executing a document object that is the target of a variant.
This commit makes use of the logic from the previous commit to intercept access to properties by context document objects. This is used to compute shapes from document objects. Since there is no logic to actually set a context, all calls to acquire a context will fail, so effectively all is a no-op currently.
This adds Part::Variant based on an App::VariantExtension that makes use of DocumentObject contexts to compute shapes from document objects.
In the Property View, exposed properties are colored purple and there is a menu action to expose or unexpose properties.
- add a command and button for variants - adopt support icon for a variant with an overlay - hide context document objects and add them to the group
for (const auto& id : exp->getIdentifiers()) { | ||
Property* prop = id.first.getProperty(); | ||
if (prop) { | ||
DocumentObject* obj = dynamic_cast<DocumentObject*>(prop->getContainer()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic_cast
is slow. I don't believe we can use that here for a function that might be called very often. Consider using isDerivedFrom
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe Base::freecad_dynamic_cast
would be fine there? It essentially is doing the isDerivedFrom call and static cast so it should be pretty cheap.
std::vector<Property*> propsObj; | ||
obj->getPropertyList(propsObj); | ||
for (auto prop : propsObj) { | ||
auto link = dynamic_cast<PropertyLinkBase*>(prop); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic_cast
:(
bool DocumentObject::isExposed(const Property* prop) const | ||
{ | ||
return prop->testStatus(Property::Exposed); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would one call DocumentObject::isExposed(prop)
and not just prop->testStatus(Exposed)
directly?
bool include = true; | ||
if (excludeExposed) { | ||
auto propNames = dep.second; | ||
include = !std::all_of(propNames.begin(), propNames.end(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will this cause performance issues? Hmmm
throw NoContextException(); | ||
} | ||
|
||
auto derivedProp = dynamic_cast<const DerivedType*>(prop); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic_cast
:(
static_assert(std::is_member_function_pointer_v<FuncType>, | ||
"Func must be a member function pointer."); | ||
|
||
auto* derivedProp = dynamic_cast<DerivedType*>(getContextProperty(CreatePropOption::Create)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic_cast
:(
{ | ||
Property* prop = this->getContextProperty(option); | ||
if (prop) { | ||
return dynamic_cast<PropertyListsT<T, ListT, ParentT>*>(prop); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dynamic_cast
:(
set_difference(currentAdoptedExposedProps, | ||
adoptedExposedProps, | ||
std::inserter(propsToRemove, propsToRemove.end())); | ||
for_each(propsToRemove, [this](const App::Property* prop) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use normal for(const auto& x : xs)
?
@@ -176,6 +177,56 @@ bool StdCmdVarSet::isActive() | |||
return hasActiveDocument(); | |||
} | |||
|
|||
|
|||
//=========================================================================== | |||
// Std_VarSet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// Std_VarSet | |
// Std_Variant |
@@ -24,6 +24,7 @@ | |||
#include "PreCompiled.h" | |||
|
|||
#ifndef _PreComp_ | |||
#include <boost/algorithm/cxx11/all_of.hpp> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused?
@pieterhijma Great ! |
Yes, sorry, cyclic dependencies (the forum refers to this and this should refer to the forum).... The description now points to the forum in which I describe the implementation. I've also added a link to the video there (for quick reference). |
@benj5378, Thanks for the review. As this is a prototype and a draft, I haven't looked very much into your comments but I think you have a point in all your cases. I think for now, it is much more helpful to look at the bigger picture, such as the design and the implication of adding this to FreeCAD. See the forum topic that I link to in the discussion. Would you be able to comment on that as well? Would be appreciated! |
This PR is an outcome of FPA grant proposal Research Variant Parts.
This PR mainly adds GUI support and improves the
Part::Variant
introduced in #19733.This builds on (and currently also includes) #19733.
This PR is not meant to be merged as is but it contains a prototype with a potential option to have Variant Parts in FreeCAD. I discuss the implementation in detail in this forum post and beyond.
How it can be used is explained in this forum post.