Toponaming: bring in missing code fragments in Part

This commit is contained in:
bgbsww
2024-05-11 22:12:21 -04:00
parent 40ee6c7e45
commit d3c5df86ee
9 changed files with 827 additions and 105 deletions

View File

@@ -72,6 +72,7 @@
#include "PartFeaturePy.h"
#include "PartPyCXX.h"
#include "TopoShapePy.h"
#include "Base/Tools.h"
using namespace Part;
namespace sp = std::placeholders;
@@ -872,6 +873,7 @@ static TopoShape _getTopoShape(const App::DocumentObject* obj,
std::set<std::string> nextHiddens = hiddens;
const App::DocumentObject* nextLink = lastLink;
// Todo: This might belong.
// Toponaming project March 2024: This appears to be a non toponaming feature:
// if (!checkLinkVisibility(nextHiddens, true, nextLink, owner, sub.c_str())) {
// cacheable = false;
@@ -967,6 +969,7 @@ TopoShape Feature::getTopoShape(const App::DocumentObject* obj,
const App::DocumentObject* lastLink = 0;
std::set<std::string> hiddens;
// Toponaming project March 2024: This appears to be a non toponaming feature:
// Todo is this a cause behind #13886 ?
// if (!checkLinkVisibility(hiddens, false, lastLink, obj, subname)) {
// return TopoShape();
// }
@@ -1068,11 +1071,132 @@ App::DocumentObject *Feature::getShapeOwner(const App::DocumentObject *obj, cons
return owner;
}
struct Feature::ElementCache
{
TopoShape shape;
mutable std::vector<std::string> names;
mutable bool searched;
};
void Feature::registerElementCache(const std::string& prefix, PropertyPartShape* prop)
{
if (prop) {
_elementCachePrefixMap.emplace_back(prefix, prop);
return;
}
for (auto it = _elementCachePrefixMap.begin(); it != _elementCachePrefixMap.end();) {
if (it->first == prefix) {
_elementCachePrefixMap.erase(it);
break;
}
}
}
void Feature::onBeforeChange(const App::Property* prop)
{
PropertyPartShape* propShape = nullptr;
const std::string* prefix = nullptr;
if (prop == &Shape) {
propShape = &Shape;
}
else {
for (const auto& v : _elementCachePrefixMap) {
if (prop == v.second) {
prefix = &v.first;
propShape = v.second;
}
}
}
if (propShape) {
if (_elementCachePrefixMap.empty()) {
_elementCache.clear();
}
else {
for (auto it = _elementCache.begin(); it != _elementCache.end();) {
bool remove;
if (prefix) {
remove = boost::starts_with(it->first, *prefix);
}
else {
remove = true;
for (const auto& v : _elementCache) {
if (boost::starts_with(it->first, v.first)) {
remove = false;
break;
}
}
}
if (remove) {
it = _elementCache.erase(it);
}
else {
++it;
}
}
}
if (getDocument() && !getDocument()->testStatus(App::Document::Restoring)
&& !getDocument()->isPerformingTransaction()) {
std::vector<App::DocumentObject*> objs;
std::vector<std::string> subs;
for (auto prop : App::PropertyLinkBase::getElementReferences(this)) {
if (!prop->getContainer()) {
continue;
}
objs.clear();
subs.clear();
prop->getLinks(objs, true, &subs, false);
for (auto& sub : subs) {
auto element = Data::findElementName(sub.c_str());
if (!element || !element[0] || Data::hasMissingElement(element)) {
continue;
}
if (prefix) {
if (!boost::starts_with(element, *prefix)) {
continue;
}
}
else {
bool found = false;
for (const auto& v : _elementCachePrefixMap) {
if (boost::starts_with(element, v.first)) {
found = true;
break;
}
}
if (found) {
continue;
}
}
auto res =
_elementCache.insert(std::make_pair(std::string(element), ElementCache()));
if (res.second) {
res.first->second.searched = false;
res.first->second.shape = propShape->getShape().getSubTopoShape(
element + (prefix ? prefix->size() : 0),
true);
}
}
}
}
}
GeoFeature::onBeforeChange(prop);
}
void Feature::onChanged(const App::Property* prop)
{
// if the placement has changed apply the change to the point data as well
if (prop == &this->Placement) {
#ifdef FC_USE_TNP_FIX
TopoShape shape = this->Shape.getShape();
shape.setTransform(this->Placement.getValue().toMatrix());
Base::ObjectStatusLocker<App::Property::Status, App::Property> guard(
App::Property::NoRecompute,
&this->Shape);
this->Shape.setValue(shape);
#else
this->Shape.setTransform(this->Placement.getValue().toMatrix());
#endif
}
// if the point data has changed check and adjust the transformation as well
else if (prop == &this->Shape) {
@@ -1085,8 +1209,9 @@ void Feature::onChanged(const App::Property* prop)
if (!this->Shape.getValue().IsNull()) {
try {
p.fromMatrix(this->Shape.getShape().getTransform());
if (p != this->Placement.getValue())
if (p != this->Placement.getValue()) {
this->Placement.setValue(p);
}
}
catch (const Base::ValueError&) {
}
@@ -1097,6 +1222,51 @@ void Feature::onChanged(const App::Property* prop)
GeoFeature::onChanged(prop);
}
#ifdef FC_USE_TNP_FIX
const std::vector<std::string>& Feature::searchElementCache(const std::string& element,
Data::SearchOptions options,
double tol,
double atol) const
{
static std::vector<std::string> none;
if (element.empty()) {
return none;
}
auto it = _elementCache.find(element);
if (it == _elementCache.end() || it->second.shape.isNull()) {
return none;
}
if (!it->second.searched) {
auto propShape = &Shape;
const std::string* prefix = nullptr;
for (const auto& v : _elementCachePrefixMap) {
if (boost::starts_with(element, v.first)) {
propShape = v.second;
prefix = &v.first;
break;
}
}
it->second.searched = true;
propShape->getShape().findSubShapesWithSharedVertex(it->second.shape,
&it->second.names,
static_cast<CheckGeometry>(options),
tol,
atol);
if (prefix) {
for (auto& name : it->second.names) {
if (auto dot = strrchr(name.c_str(), '.')) {
name.insert(dot + 1 - name.c_str(), *prefix);
}
else {
name.insert(0, *prefix);
}
}
}
}
return it->second.names;
}
#endif
TopLoc_Location Feature::getLocation() const
{
Base::Placement pl = this->Placement.getValue();
@@ -1702,6 +1872,5 @@ std::pair<std::string, std::string> Feature::getElementName(const char* name,
}
}
}
return App::GeoFeature::getElementName(name, type);
return App::GeoFeature::_getElementName(name, mapped);
}