PD: Fix crash in Loft::getSectionShape
The passed DocumentObject pointer can be null which is nowhere checked.
This fixes issue 19545
Fixes: 256ad7a01a ("PartDesign: Loft Intelligence - Select the whole sketch if the selected shape is ...")
This commit is contained in:
@@ -65,32 +65,55 @@ short Loft::mustExecute() const
|
||||
return ProfileBased::mustExecute();
|
||||
}
|
||||
|
||||
std::vector<Part::TopoShape>
|
||||
Loft::getSectionShape(const char *name,
|
||||
App::DocumentObject *obj,
|
||||
const std::vector<std::string> &subs,
|
||||
size_t expected_size)
|
||||
std::vector<Part::TopoShape> Loft::getSectionShape(const char* name,
|
||||
App::DocumentObject* obj,
|
||||
const std::vector<std::string>& subs,
|
||||
size_t expected_size)
|
||||
{
|
||||
auto useSketch = [](App::DocumentObject* obj, const std::vector<std::string>& subs) {
|
||||
// Be smart. If part of a sketch is selected, use the entire sketch unless it is a single
|
||||
// vertex - backward compatibility (#16630)
|
||||
if (!obj) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto subName = subs.empty() ? "" : subs.front();
|
||||
return obj->isDerivedFrom<Part::Part2DObject>() && subName.find("Vertex") != 0;
|
||||
};
|
||||
|
||||
std::vector<TopoShape> shapes;
|
||||
// Be smart. If part of a sketch is selected, use the entire sketch unless it is a single vertex -
|
||||
// backward compatibility (#16630)
|
||||
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, 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) {
|
||||
auto useEntireSketch = useSketch(obj, subs);
|
||||
if (subs.empty() || std::ranges::find(subs, std::string()) != subs.end() || useEntireSketch) {
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform));
|
||||
if (shapes.back().isNull()) {
|
||||
std::stringstream str;
|
||||
str << "Failed to get shape of " << name;
|
||||
if (obj) {
|
||||
auto doc = obj->getDocument();
|
||||
str << " " << App::SubObjectT(obj, "").getSubObjectFullName(doc->getName());
|
||||
}
|
||||
THROWM(Part::NullShapeException, str.str());
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (const auto& sub : subs) {
|
||||
shapes.push_back(Part::Feature::getTopoShape(obj,
|
||||
Part::ShapeOption::NeedSubElement
|
||||
| Part::ShapeOption::ResolveLink
|
||||
| Part::ShapeOption::Transform,
|
||||
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()));
|
||||
if (shapes.back().isNull()) {
|
||||
std::stringstream str;
|
||||
str << "Failed to get shape of " << name;
|
||||
if (obj) {
|
||||
auto doc = obj->getDocument();
|
||||
App::SubObjectT subObj(obj, sub.c_str());
|
||||
str << " " << subObj.getSubObjectFullName(doc->getName());
|
||||
}
|
||||
THROWM(Part::NullShapeException, str.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
auto compound = TopoShape(0).makeElementCompound(shapes, "", TopoShape::SingleShapeCompoundCreationPolicy::returnShape);
|
||||
|
||||
Reference in New Issue
Block a user