Merge pull request #14202 from bgbsww/bgbsww-toponamingFixSubShapeBinder
Toponaming fix sub shape binder and restore multishape tests
This commit is contained in:
@@ -1206,10 +1206,10 @@ class AppExport PropertyXLinkSubList: public PropertyLinkBase
|
||||
{
|
||||
TYPESYSTEM_HEADER_WITH_OVERRIDE();
|
||||
|
||||
public:
|
||||
using atomic_change = typename AtomicPropertyChangeInterface<PropertyXLinkSubList>::AtomicPropertyChange;
|
||||
friend atomic_change;
|
||||
|
||||
public:
|
||||
PropertyXLinkSubList();
|
||||
~PropertyXLinkSubList() override;
|
||||
|
||||
|
||||
@@ -198,6 +198,9 @@ App::DocumentObjectExecReturn *Chamfer::execute()
|
||||
shape = refineShapeIfActive(shape);
|
||||
shape = getSolid(shape);
|
||||
}
|
||||
if (!isSingleSolidRuleSatisfied(shape.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
this->Shape.setValue(shape);
|
||||
if (failed) {
|
||||
return new App::DocumentObjectExecReturn(
|
||||
|
||||
@@ -717,8 +717,10 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
return new App::DocumentObjectExecReturn(
|
||||
QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
}
|
||||
|
||||
solRes = refineShapeIfActive(solRes);
|
||||
if (!isSingleSolidRuleSatisfied(solRes.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
this->Shape.setValue(getSolid(solRes));
|
||||
}
|
||||
else if (prism.hasSubShape(TopAbs_SOLID)) {
|
||||
@@ -726,10 +728,17 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
prism.makeElementFuse(prism.getSubTopoShapes(TopAbs_SOLID));
|
||||
}
|
||||
prism = refineShapeIfActive(prism);
|
||||
this->Shape.setValue(getSolid(prism));
|
||||
prism = getSolid(prism);
|
||||
if (!isSingleSolidRuleSatisfied(prism.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
this->Shape.setValue(prism);
|
||||
}
|
||||
else {
|
||||
prism = refineShapeIfActive(prism);
|
||||
if (!isSingleSolidRuleSatisfied(prism.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
this->Shape.setValue(prism);
|
||||
}
|
||||
|
||||
|
||||
@@ -114,6 +114,9 @@ App::DocumentObjectExecReturn *Fillet::execute()
|
||||
shape = refineShapeIfActive(shape);
|
||||
shape = getSolid(shape);
|
||||
}
|
||||
if (!isSingleSolidRuleSatisfied(shape.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
this->Shape.setValue(shape);
|
||||
|
||||
if (failed) {
|
||||
|
||||
@@ -352,7 +352,11 @@ App::DocumentObjectExecReturn *Groove::execute()
|
||||
return new App::DocumentObjectExecReturn("Resulting shape is not a solid");
|
||||
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
boolOp = getSolid(boolOp);
|
||||
if (!isSingleSolidRuleSatisfied(boolOp.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
Shape.setValue(boolOp);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
@@ -532,7 +532,11 @@ App::DocumentObjectExecReturn *Loft::execute(void)
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Resulting shape is not a solid"));
|
||||
|
||||
boolOp = refineShapeIfActive(boolOp);
|
||||
Shape.setValue(getSolid(boolOp));
|
||||
boolOp = getSolid(boolOp);
|
||||
if (!isSingleSolidRuleSatisfied(boolOp.getShape())) {
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception", "Result has multiple solids: that is not currently supported."));
|
||||
}
|
||||
Shape.setValue(boolOp);
|
||||
return App::DocumentObject::StdReturn;
|
||||
}
|
||||
catch (Standard_Failure& e) {
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
#include <Mod/Part/App/TopoShape.h>
|
||||
|
||||
#include "ShapeBinder.h"
|
||||
#include "Mod/Part/App/TopoShapeOpCode.h"
|
||||
#include "Base/Tools.h"
|
||||
|
||||
FC_LOG_LEVEL_INIT("PartDesign",true,true)
|
||||
|
||||
@@ -486,6 +488,7 @@ void SubShapeBinder::clearCopiedObjects() {
|
||||
void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
Part::TopoShape result;
|
||||
std::vector<Part::TopoShape> shapes;
|
||||
std::vector<std::pair<int,int> > shapeOwners;
|
||||
std::vector<const Base::Matrix4D*> shapeMats;
|
||||
|
||||
bool forced = (Shape.getValue().IsNull() || (options & UpdateForced)) ? true : false;
|
||||
@@ -519,7 +522,9 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
|
||||
bool first = false;
|
||||
std::unordered_map<const App::DocumentObject*, Base::Matrix4D> mats;
|
||||
int idx = -1;
|
||||
for (auto& l : Support.getSubListValues()) {
|
||||
++idx;
|
||||
auto obj = l.getValue();
|
||||
if (!obj || !obj->isAttachedToDocument())
|
||||
continue;
|
||||
@@ -631,16 +636,20 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
|
||||
const auto& subvals = copied ? _CopiedLink.getSubValues() : l.getSubValues();
|
||||
std::set<std::string> subs(subvals.begin(), subvals.end());
|
||||
int sidx = copied?-1:idx;
|
||||
int subidx = -1;
|
||||
static std::string none;
|
||||
if (subs.empty())
|
||||
subs.insert(none);
|
||||
else if (subs.size() > 1)
|
||||
subs.erase(none);
|
||||
for (const auto& sub : subs) {
|
||||
++subidx;
|
||||
try {
|
||||
auto shape = Part::Feature::getTopoShape(obj, sub.c_str(), true);
|
||||
if (!shape.isNull()) {
|
||||
shapes.push_back(shape);
|
||||
shapeOwners.emplace_back(sidx, subidx);
|
||||
shapeMats.push_back(&res.first->second);
|
||||
}
|
||||
}
|
||||
@@ -695,7 +704,28 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
if (hit)
|
||||
return;
|
||||
}
|
||||
#ifdef FC_USE_TNP_FIX
|
||||
std::ostringstream ss;
|
||||
int idx = -1;
|
||||
for(auto &shape : shapes) {
|
||||
++idx;
|
||||
if(shape.Hasher
|
||||
&& shape.getElementMapSize()
|
||||
&& shape.Hasher != getDocument()->getStringHasher())
|
||||
{
|
||||
ss.str("");
|
||||
ss << Data::POSTFIX_EXTERNAL_TAG
|
||||
<< Data::ComplexGeoData::elementMapPrefix()
|
||||
<< Part::OpCodes::Shapebinder << ':' << shapeOwners[idx].first
|
||||
<< ':' << shapeOwners[idx].second;
|
||||
shape.reTagElementMap(-getID(),
|
||||
getDocument()->getStringHasher(),ss.str().c_str());
|
||||
}
|
||||
if (!shape.hasSubShape(TopAbs_FACE) && shape.hasSubShape(TopAbs_EDGE))
|
||||
shape = shape.makeElementCopy();
|
||||
}
|
||||
|
||||
#endif
|
||||
if (shapes.size() == 1 && !Relative.getValue())
|
||||
shapes.back().setPlacement(Base::Placement());
|
||||
else {
|
||||
@@ -867,6 +897,68 @@ void SubShapeBinder::onDocumentRestored() {
|
||||
inherited::onDocumentRestored();
|
||||
}
|
||||
|
||||
void SubShapeBinder::collapseGeoChildren()
|
||||
{
|
||||
// Geo children, i.e. children of GeoFeatureGroup may group some tool
|
||||
// features under itself but does not function as a container. In addition,
|
||||
// its parent group can directly reference the tool feature grouped without
|
||||
// referencing the child. The purpose of this function is to remove any
|
||||
// intermediate Non group features in the object path to avoid unnecessary
|
||||
// dependencies.
|
||||
if (Support.testStatus(App::Property::User3))
|
||||
return;
|
||||
|
||||
Base::ObjectStatusLocker<App::Property::Status, App::Property>
|
||||
guard(App::Property::User3, &Support);
|
||||
App::PropertyXLinkSubList::atomic_change guard2(Support, false);
|
||||
|
||||
std::vector<App::DocumentObject*> removes;
|
||||
std::map<App::DocumentObject*, std::vector<std::string> > newVals;
|
||||
std::ostringstream ss;
|
||||
for(auto &l : Support.getSubListValues()) {
|
||||
auto obj = l.getValue();
|
||||
if(!obj || !obj->getNameInDocument())
|
||||
continue;
|
||||
auto subvals = l.getSubValues();
|
||||
if (subvals.empty())
|
||||
continue;
|
||||
bool touched = false;
|
||||
for (auto itSub=subvals.begin(); itSub!=subvals.end();) {
|
||||
auto &sub = *itSub;
|
||||
App::SubObjectT sobjT(obj, sub.c_str());
|
||||
if (sobjT.normalize(App::SubObjectT::NormalizeOption::KeepSubName)) {
|
||||
touched = true;
|
||||
auto newobj = sobjT.getObject();
|
||||
sub = sobjT.getSubName();
|
||||
if (newobj != obj) {
|
||||
newVals[newobj].push_back(std::move(sub));
|
||||
itSub = subvals.erase(itSub);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++itSub;
|
||||
}
|
||||
if (touched)
|
||||
removes.push_back(obj);
|
||||
if (!subvals.empty() && touched) {
|
||||
auto &newSubs = newVals[obj];
|
||||
if (newSubs.empty())
|
||||
newSubs = std::move(subvals);
|
||||
else
|
||||
newSubs.insert(newSubs.end(),
|
||||
std::make_move_iterator(subvals.begin()),
|
||||
std::make_move_iterator(subvals.end()));
|
||||
}
|
||||
}
|
||||
|
||||
if (removes.size() || newVals.size())
|
||||
guard2.aboutToChange();
|
||||
for (auto obj : removes)
|
||||
Support.removeValue(obj);
|
||||
if (newVals.size())
|
||||
setLinks(std::move(newVals));
|
||||
}
|
||||
|
||||
void SubShapeBinder::onChanged(const App::Property* prop) {
|
||||
if (prop == &Context || prop == &Relative) {
|
||||
if (!Context.getValue() || !Relative.getValue()) {
|
||||
@@ -884,6 +976,7 @@ void SubShapeBinder::onChanged(const App::Property* prop) {
|
||||
}
|
||||
else if (!isRestoring()) {
|
||||
if (prop == &Support) {
|
||||
collapseGeoChildren();
|
||||
clearCopiedObjects();
|
||||
setupCopyOnChange();
|
||||
if (!Support.getSubListValues().empty()) {
|
||||
|
||||
@@ -138,6 +138,8 @@ protected:
|
||||
|
||||
void checkPropertyStatus();
|
||||
|
||||
void collapseGeoChildren();
|
||||
|
||||
void slotRecomputedObject(const App::DocumentObject& Obj);
|
||||
|
||||
using Connection = boost::signals2::scoped_connection;
|
||||
|
||||
Reference in New Issue
Block a user