(GeoFeature)GroupExtension: track children visibility

The future patch will introduce Part::getTopoShape() to construct a
compound shape from a group. It will rely on the children visibility to
determine whether to include the child shape or not. This patch adds
children visibility tracking capability to group, and makes sure that
the group object will be marked for recomputation in case of any change
in group member, and their visibility status.

* Remove Prop_Output from 'Group' property.

* Added hidden property _GroupTouched to help propagate children change.

* Track children visibility change using signal

* GeoFeatureGroupExtension uses new PropertyLinkBase interface for
  scope checking.
This commit is contained in:
Zheng, Lei
2019-07-06 15:20:16 +08:00
committed by wmayer
parent 94c228973d
commit c5112ecdc5
5 changed files with 86 additions and 88 deletions

View File

@@ -191,9 +191,10 @@ std::vector<DocumentObject*> GeoFeatureGroupExtension::removeObjects(std::vector
void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) {
//objects are only allowed in a single GeoFeatureGroup
if((strcmp(p->getName(), "Group")==0)) {
if(p == &Group && !Group.testStatus(Property::User3)) {
if(!getExtendedObject()->getDocument()->isPerformingTransaction()) {
if(!getExtendedObject()->isRestoring() &&
!getExtendedObject()->getDocument()->isPerformingTransaction()) {
bool error = false;
auto corrected = Group.getValues();
@@ -215,6 +216,7 @@ void GeoFeatureGroupExtension::extensionOnChanged(const Property* p) {
//if an error was found we need to correct the values and inform the user
if(error) {
Base::ObjectStatusLocker<Property::Status, Property> guard(Property::User3, &Group);
Group.setValues(corrected);
throw Base::RuntimeError("Object can only be in a single GeoFeatureGroup");
}
@@ -252,35 +254,14 @@ std::vector< DocumentObject* > GeoFeatureGroupExtension::getScopedObjectsFromLin
return std::vector< DocumentObject* >();
std::vector< App::DocumentObject* > result;
auto link = Base::freecad_dynamic_cast<PropertyLinkBase>(prop);
if(link && link->getScope()==scope)
link->getLinks(result);
if(prop->getTypeId().isDerivedFrom(App::PropertyLink::getClassTypeId()) &&
static_cast<App::PropertyLink*>(prop)->getScope() == scope) {
result.push_back(static_cast<App::PropertyLink*>(prop)->getValue());
}
if(prop->getTypeId().isDerivedFrom(App::PropertyLinkList::getClassTypeId()) &&
static_cast<App::PropertyLinkList*>(prop)->getScope() == scope) {
auto vec = static_cast<App::PropertyLinkList*>(prop)->getValues();
result.insert(result.end(), vec.begin(), vec.end());
}
if(prop->getTypeId().isDerivedFrom(App::PropertyLinkSub::getClassTypeId()) &&
static_cast<App::PropertyLinkSub*>(prop)->getScope() == scope) {
result.push_back(static_cast<App::PropertyLinkSub*>(prop)->getValue());
}
if(prop->getTypeId().isDerivedFrom(App::PropertyLinkSubList::getClassTypeId()) &&
static_cast<App::PropertyLinkSubList*>(prop)->getScope() == scope) {
auto vec = static_cast<App::PropertyLinkSubList*>(prop)->getValues();
result.insert(result.end(), vec.begin(), vec.end());
}
//getLinks() guarantees no nullptrs
//
//it is important to remove all nullptrs
result.erase(std::remove(result.begin(), result.end(), nullptr), result.end());
// result.erase(std::remove(result.begin(), result.end(), nullptr), result.end());
return result;
}