PartDesign: Fix hole centered on point edge case (#21257)
* Light refactor of getTopoShape function * Fix hole edge case * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Update src/Mod/Part/App/PartFeature.cpp Co-authored-by: Kacper Donat <kadet1090@gmail.com> * Update src/Mod/Part/App/PartFeature.cpp Co-authored-by: Kacper Donat <kadet1090@gmail.com> * Update src/Mod/Part/App/PartFeature.cpp Co-authored-by: Kacper Donat <kadet1090@gmail.com> * Update src/Mod/Part/App/PartFeature.cpp Co-authored-by: Kacper Donat <kadet1090@gmail.com> * Refactor simplifyCompound() * Use Base::Flags<GetShapeOption> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Shorten enum name and move it from class scope to namespace scope * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Kacper Donat <kadet1090@gmail.com>
This commit is contained in:
@@ -69,7 +69,7 @@ App::DocumentObjectExecReturn* FeatureBase::execute()
|
||||
QT_TRANSLATE_NOOP("Exception", "BaseFeature must be a Part::Feature"));
|
||||
}
|
||||
|
||||
auto shape = Part::Feature::getTopoShape(BaseFeature.getValue());
|
||||
auto shape = Part::Feature::getTopoShape(BaseFeature.getValue(), Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
|
||||
if (!shape.countSubShapes(TopAbs_SOLID)) {
|
||||
shape = shape.makeElementSolid();
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ App::DocumentObjectExecReturn *Boolean::execute()
|
||||
std::vector<TopoShape> shapes;
|
||||
shapes.push_back(baseTopShape);
|
||||
for(auto it=tools.begin(); it<tools.end(); ++it) {
|
||||
auto shape = getTopoShape(*it);
|
||||
auto shape = getTopoShape(*it, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
|
||||
if (shape.isNull())
|
||||
return new App::DocumentObjectExecReturn(QT_TRANSLATE_NOOP("Exception","Tool shape is null"));
|
||||
shapes.push_back(shape);
|
||||
|
||||
@@ -514,7 +514,12 @@ App::DocumentObjectExecReturn* FeatureExtrude::buildExtrusion(ExtrudeOptions opt
|
||||
if (sub.empty() && subs.size() > 1) {
|
||||
continue;
|
||||
}
|
||||
TopoShape shape = Part::Feature::getTopoShape(obj, sub.c_str(), true);
|
||||
TopoShape shape = Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
sub.c_str());
|
||||
|
||||
if (shape.isNull()) {
|
||||
FC_ERR(getFullName()
|
||||
<< ": failed to get profile shape " << obj->getFullName() << "." << sub);
|
||||
|
||||
@@ -1855,7 +1855,11 @@ static gp_Pnt toPnt(gp_Vec dir)
|
||||
|
||||
App::DocumentObjectExecReturn* Hole::execute()
|
||||
{
|
||||
TopoShape profileshape = getProfileShape();
|
||||
TopoShape profileshape =
|
||||
getProfileShape( Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform
|
||||
| Part::ShapeOption::DontSimplifyCompound);
|
||||
|
||||
// Find the base shape
|
||||
TopoShape base;
|
||||
|
||||
@@ -77,13 +77,17 @@ Loft::getSectionShape(const char *name,
|
||||
auto subName = subs.empty() ? "" : subs.front();
|
||||
auto useEntireSketch = obj->isDerivedFrom<Part::Part2DObject>() && subName.find("Vertex") != 0;
|
||||
if (subs.empty() || std::ranges::find(subs, std::string()) != subs.end() || useEntireSketch ) {
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj));
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform));
|
||||
if (shapes.back().isNull())
|
||||
FC_THROWM(Part::NullShapeException, "Failed to get shape of "
|
||||
<< name << " " << App::SubObjectT(obj, "").getSubObjectFullName(obj->getDocument()->getName()));
|
||||
} else {
|
||||
for (const auto &sub : subs) {
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj, sub.c_str(), /*needSubElement*/true));
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
sub.c_str()));
|
||||
if (shapes.back().isNull())
|
||||
FC_THROWM(Part::NullShapeException, "Failed to get shape of " << name << " "
|
||||
<< App::SubObjectT(obj, sub.c_str()).getSubObjectFullName(obj->getDocument()->getName()));
|
||||
|
||||
@@ -184,13 +184,18 @@ TopoShape ProfileBased::getTopoShapeVerifiedFace(bool silent,
|
||||
TopoShape shape;
|
||||
if (AllowMultiFace.getValue()) {
|
||||
if (subs.empty()) {
|
||||
shape = Part::Feature::getTopoShape(obj);
|
||||
shape = Part::Feature::getTopoShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
|
||||
}
|
||||
else {
|
||||
std::vector<TopoShape> shapes;
|
||||
for (auto& sub : subs) {
|
||||
auto subshape =
|
||||
Part::Feature::getTopoShape(obj, sub.c_str(), /*needSubElement*/ true);
|
||||
auto subshape = Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
sub.c_str());
|
||||
|
||||
|
||||
if (subshape.isNull()) {
|
||||
FC_THROWM(Base::CADKernelError,
|
||||
"Sub shape not found: " << obj->getFullName() << "." << sub);
|
||||
@@ -207,7 +212,11 @@ TopoShape ProfileBased::getTopoShapeVerifiedFace(bool silent,
|
||||
sub = subs[0];
|
||||
}
|
||||
}
|
||||
shape = Part::Feature::getTopoShape(obj, sub.c_str(), !sub.empty());
|
||||
shape = Part::Feature::getTopoShape(obj,
|
||||
(sub.empty() ? Part::ShapeOption::NoFlag : Part::ShapeOption::NeedSubElement)
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
sub.c_str());
|
||||
}
|
||||
if (shape.isNull()) {
|
||||
if (silent) {
|
||||
@@ -404,19 +413,20 @@ TopoDS_Shape ProfileBased::getVerifiedFace(bool silent) const {
|
||||
return TopoDS_Face();
|
||||
}
|
||||
|
||||
TopoShape ProfileBased::getProfileShape() const
|
||||
TopoShape ProfileBased::getProfileShape(Part::ShapeOptions subShapeOptions) const
|
||||
{
|
||||
TopoShape shape;
|
||||
const auto& subs = Profile.getSubValues();
|
||||
auto profile = Profile.getValue();
|
||||
if (subs.empty()) {
|
||||
shape = Part::Feature::getTopoShape(profile);
|
||||
shape = Part::Feature::getTopoShape(profile, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
|
||||
}
|
||||
else {
|
||||
std::vector<TopoShape> shapes;
|
||||
for (auto& sub : subs) {
|
||||
shapes.push_back(
|
||||
Part::Feature::getTopoShape(profile, sub.c_str(), /* needSubElement */ true));
|
||||
shapes.push_back(Part::Feature::getTopoShape(profile,
|
||||
subShapeOptions,
|
||||
sub.c_str()));
|
||||
}
|
||||
shape = TopoShape(shape.Tag).makeElementCompound(shapes);
|
||||
}
|
||||
@@ -567,9 +577,11 @@ TopoShape ProfileBased::getTopoShapeSupportFace() const
|
||||
const auto& Support = sketch->AttachmentSupport;
|
||||
App::DocumentObject* ref = Support.getValue();
|
||||
shape = Part::Feature::getTopoShape(
|
||||
ref,
|
||||
Support.getSubValues().size() ? Support.getSubValues()[0].c_str() : "",
|
||||
true);
|
||||
ref,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
Support.getSubValues().empty() ? "" : Support.getSubValues()[0].c_str());
|
||||
}
|
||||
if (!shape.isNull()) {
|
||||
if (shape.shapeType(true) != TopAbs_FACE) {
|
||||
@@ -663,7 +675,13 @@ void ProfileBased::getUpToFaceFromLinkSub(TopoShape& upToFace, const App::Proper
|
||||
}
|
||||
|
||||
const auto& subs = refFace.getSubValues();
|
||||
upToFace = Part::Feature::getTopoShape(ref, subs.size() ? subs[0].c_str() : nullptr, true);
|
||||
upToFace = Part::Feature::getTopoShape(
|
||||
ref,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
subs.empty() ? nullptr : subs[0].c_str());
|
||||
|
||||
if (!upToFace.hasSubShape(TopAbs_FACE)) {
|
||||
throw Base::ValueError("SketchBased: Up to face: Failed to extract face");
|
||||
}
|
||||
@@ -687,7 +705,12 @@ int ProfileBased::getUpToShapeFromLinkSubList(TopoShape& upToShape, const App::P
|
||||
|
||||
auto subStrings = subSet.second;
|
||||
if (subStrings.empty() || subStrings[0].empty()) {
|
||||
TopoShape baseShape = Part::Feature::getTopoShape(ref, nullptr, true);
|
||||
TopoShape baseShape = Part::Feature::getTopoShape(ref,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform);
|
||||
|
||||
|
||||
for (auto face : baseShape.getSubTopoShapes(TopAbs_FACE)){
|
||||
faceList.push_back(face);
|
||||
ret ++;
|
||||
@@ -695,7 +718,13 @@ int ProfileBased::getUpToShapeFromLinkSubList(TopoShape& upToShape, const App::P
|
||||
}
|
||||
else {
|
||||
for (auto &subString : subStrings){
|
||||
auto shape = Part::Feature::getTopoShape(ref, subString.c_str(), true);
|
||||
auto shape = Part::Feature::getShape(
|
||||
ref,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
subString.c_str());
|
||||
|
||||
TopoShape face = shape;
|
||||
face = face.makeElementFace();
|
||||
if (face.isNull()) {
|
||||
@@ -1419,7 +1448,7 @@ Base::Vector3d ProfileBased::getProfileNormal() const {
|
||||
|
||||
if (shape.hasSubShape(TopAbs_EDGE)) {
|
||||
// Find the first planar face that contains the edge, and return the plane normal
|
||||
TopoShape objShape = Part::Feature::getTopoShape(obj);
|
||||
TopoShape objShape = Part::Feature::getTopoShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
|
||||
for (int idx : objShape.findAncestors(shape.getSubShape(TopAbs_EDGE, 1), TopAbs_FACE)) {
|
||||
if (objShape.getSubTopoShape(TopAbs_FACE, idx).findPlane(pln)) {
|
||||
gp_Dir dir = pln.Axis().Direction();
|
||||
|
||||
@@ -131,7 +131,11 @@ public:
|
||||
|
||||
virtual Base::Vector3d getProfileNormal() const;
|
||||
|
||||
TopoShape getProfileShape() const;
|
||||
// Use Part::ShapeOptions enum to pass flags
|
||||
TopoShape getProfileShape(Part::ShapeOptions subShapeOptions =
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform) const;
|
||||
|
||||
/// retrieves the number of axes in the linked sketch (defined as construction lines)
|
||||
int getSketchAxisCount() const;
|
||||
|
||||
@@ -670,7 +670,11 @@ void SubShapeBinder::update(SubShapeBinder::UpdateOption options) {
|
||||
for (const auto& sub : subs) {
|
||||
++subidx;
|
||||
try {
|
||||
auto shape = Part::Feature::getTopoShape(obj, sub.c_str(), true);
|
||||
auto shape = Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
sub.c_str());
|
||||
if (!shape.isNull()) {
|
||||
shapes.push_back(shape);
|
||||
shapeOwners.emplace_back(sidx, subidx);
|
||||
|
||||
@@ -151,7 +151,8 @@ void TaskDressUpParameters::addAllEdges(QListWidget* widget)
|
||||
if (!base) {
|
||||
return;
|
||||
}
|
||||
int count = Part::Feature::getTopoShape(base).countSubShapes(TopAbs_EDGE);
|
||||
int count = Part::Feature::getTopoShape(base, Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform).countSubShapes(TopAbs_EDGE);
|
||||
auto subValues = pcDressUp->Base.getSubValues(false);
|
||||
std::size_t len = subValues.size();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
|
||||
Reference in New Issue
Block a user