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:
theo-vt
2025-05-29 16:37:54 -04:00
committed by GitHub
parent 17e56f6570
commit 13e7952ccc
52 changed files with 449 additions and 223 deletions

View File

@@ -345,7 +345,7 @@ bool DimensionAutoCorrect::findExactEdge3d(ReferenceEntry& refToFix, const Part:
// no match in refObj, so now search the cached objects
for (auto& objectName : m_3dObjectCache) {
auto object3d = getDimension()->getDocument()->getObject(objectName.c_str());
auto shape3d = Part::Feature::getShape(object3d);
auto shape3d = Part::Feature::getShape(object3d, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
auto edgesAll = getDimension()->getEdges(shape3d);
size_t iEdge {1};
for (auto& edge : edgesAll) {
@@ -531,7 +531,7 @@ ReferenceEntry DimensionAutoCorrect::searchObjForEdge(App::DocumentObject* obj,
{
// Base::Console().message("DAC::searchObjForEdge(%s)\n", obj->Label.getValue());
(void)exact;
auto shape3d = Part::Feature::getShape(obj);
auto shape3d = Part::Feature::getShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (shape3d.IsNull()) {
// how to handle this?
return {};

View File

@@ -309,7 +309,7 @@ bool ReferenceEntry::hasGeometry() const
// 3d reference
// TODO: shouldn't this be ShapeFinder.getLocatedShape?
auto shape = Part::Feature::getTopoShape(getObject());
auto shape = Part::Feature::getTopoShape(getObject(), Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
auto subShape = shape.getSubShape(getSubName().c_str());
return !subShape.IsNull();

View File

@@ -594,7 +594,7 @@ TopoDS_Wire DrawComplexSection::makeProfileWire(App::DocumentObject* toolObj)
return {};
}
TopoDS_Shape toolShape = Part::Feature::getShape(toolObj);
TopoDS_Shape toolShape = Part::Feature::getShape(toolObj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (toolShape.IsNull()) {
return {};
}
@@ -709,7 +709,7 @@ TopoDS_Wire DrawComplexSection::makeSectionLineWire()
App::DocumentObject* toolObj = CuttingToolWireObject.getValue();
DrawViewPart* baseDvp = freecad_cast<DrawViewPart*>(BaseView.getValue());
if (baseDvp) {
TopoDS_Shape toolShape = Part::Feature::getShape(toolObj);
TopoDS_Shape toolShape = Part::Feature::getShape(toolObj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (toolShape.IsNull()) {
// CuttingToolWireObject is likely still restoring and has no shape yet
return {};
@@ -968,7 +968,7 @@ bool DrawComplexSection::canBuild(gp_Ax2 sectionCS, App::DocumentObject* profile
return false;
}
TopoDS_Shape shape = Part::Feature::getShape(profileObject);
TopoDS_Shape shape = Part::Feature::getShape(profileObject, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (BRep_Tool::IsClosed(shape)) {
//closed profiles don't have a profile vector but should always make a section?
return true;
@@ -1090,7 +1090,7 @@ TopoDS_Wire DrawComplexSection::makeNoseToTailWire(const TopoDS_Wire& inWire)
bool DrawComplexSection::isProfileObject(App::DocumentObject* obj)
{
//if the object's shape is a wire or an edge, then it can be a profile object
TopoDS_Shape shape = Part::Feature::getShape(obj);
TopoDS_Shape shape = Part::Feature::getShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (shape.IsNull()) {
return false;
}
@@ -1104,7 +1104,7 @@ bool DrawComplexSection::isProfileObject(App::DocumentObject* obj)
bool DrawComplexSection::isMultiSegmentProfile(App::DocumentObject* obj)
{
//if the object's shape is a wire or an edge, then it can be a profile object
TopoDS_Shape shape = Part::Feature::getShape(obj);
TopoDS_Shape shape = Part::Feature::getShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (shape.IsNull()) {
return false;
}
@@ -1132,7 +1132,7 @@ bool DrawComplexSection::isMultiSegmentProfile(App::DocumentObject* obj)
//check if the profile has curves in it
bool DrawComplexSection::isLinearProfile(App::DocumentObject* obj)
{
TopoDS_Shape shape = Part::Feature::getShape(obj);
TopoDS_Shape shape = Part::Feature::getShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (shape.IsNull()) {
return false;
}

View File

@@ -135,7 +135,7 @@ TopoDS_Shape ShapeExtractor::getShapes(const std::vector<App::DocumentObject*> l
}
}
else {
auto shape = Part::Feature::getShape(obj);
auto shape = Part::Feature::getShape(obj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
// if source obj has a shape, we use that shape.
if(!SU::isShapeReallyNull(shape)) {
if (checkShape(obj, shape)) {
@@ -225,7 +225,8 @@ std::vector<TopoDS_Shape> ShapeExtractor::getXShapes(const App::Link* xLink)
childNeedsTransform = true;
}
}
auto shape = Part::Feature::getShape(l); // TODO: getTopoShape() ?
// TODO: getTopoShape() ?
auto shape = Part::Feature::getShape(l, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
Part::TopoShape ts(shape);
if (ts.isInfinite()) {
shape = ShapeFinder::stripInfiniteShapes(shape);
@@ -280,7 +281,7 @@ TopoDS_Shape ShapeExtractor::getShapeFromXLink(const App::Link* xLink)
App::DocumentObject* linkedObject = xLink->getLink(depth);
if (linkedObject) {
// have a linked object, get the shape
TopoDS_Shape shape = Part::Feature::getShape(linkedObject);
TopoDS_Shape shape = Part::Feature::getShape(linkedObject, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
if (shape.IsNull()) {
// this is where we need to parse the target for objects with a shape??
return TopoDS_Shape();
@@ -465,7 +466,7 @@ Base::Vector3d ShapeExtractor::getLocation3dFromFeat(const App::DocumentObject*
//! get the located and oriented version of docObj shape
TopoDS_Shape ShapeExtractor::getLocatedShape(const App::DocumentObject* docObj)
{
Part::TopoShape shape = Part::Feature::getTopoShape(docObj);
Part::TopoShape shape = Part::Feature::getTopoShape(docObj, Part::ShapeOption::ResolveLink | Part::ShapeOption::Transform);
const Part::Feature* pf = dynamic_cast<const Part::Feature*>(docObj);
if (pf) {
shape.setPlacement(pf->globalPlacement());

View File

@@ -645,7 +645,12 @@ std::pair<Base::Vector3d, Base::Vector3d> DrawGuiUtil::getProjDirFromFace(App::D
projDir = d3Dirs.first;
rotVec = d3Dirs.second;
auto ts = Part::Feature::getShape(obj, faceName.c_str(), true);
auto ts = Part::Feature::getShape(obj,
Part::ShapeOption::NeedSubElement
| Part::ShapeOption::ResolveLink
| Part::ShapeOption::Transform,
faceName.c_str());
if (ts.IsNull() || ts.ShapeType() != TopAbs_FACE) {
Base::Console().warning("getProjDirFromFace(%s) is not a Face\n", faceName.c_str());
return dirs;