From db6d44b1da5fb5a994757da9567f545b26bd700b Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 26 Jan 2023 15:49:13 +0100 Subject: [PATCH] Part: fix crash in SectionCutting dialog It segfauls when executing the script below: doc = App.ActiveDocument box = doc.addObject("Part::Box", "SectionCutBoxX") comp = doc.addObject("Part::Compound", "SectionCutCompound") comp.Links = box grp = doc.addObject("App::DocumentObjectGroup", "SectionCutX") grp.addObject(comp) doc.recompute() --- src/Mod/Part/Gui/SectionCutting.cpp | 65 ++++++++++++++++++----------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/src/Mod/Part/Gui/SectionCutting.cpp b/src/Mod/Part/Gui/SectionCutting.cpp index 47c1a36419..15c3a69c38 100644 --- a/src/Mod/Part/Gui/SectionCutting.cpp +++ b/src/Mod/Part/Gui/SectionCutting.cpp @@ -153,11 +153,13 @@ SectionCut::SectionCut(QWidget* parent) pcCompound->Links.getLinks(compoundObjects); for (auto aCompoundObj : compoundObjects) { App::Link* pcLink = dynamic_cast(aCompoundObj); - auto LinkedObject = pcLink->getLink(); - // only if not already visible - if (!(LinkedObject->Visibility.getValue())) { - LinkedObject->Visibility.setValue(true); - ObjectsListVisible.emplace_back(LinkedObject); + auto LinkedObject = pcLink ? pcLink->getLink() : nullptr; + if (LinkedObject) { + // only if not already visible + if (!(LinkedObject->Visibility.getValue())) { + LinkedObject->Visibility.setValue(true); + ObjectsListVisible.emplace_back(LinkedObject); + } } } } @@ -415,9 +417,14 @@ void SectionCut::startCutting(bool isInitial) std::vector ObjectsListCut; bool isLinkAssembly = false; for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) { + App::DocumentObject* object = it->getObject(); + if (!object) { + continue; + } + // we need all Link objects in App::Part for example for Assembly 4 - if (it->getObject()->getTypeId() == Base::Type::fromName("App::Part")) { - App::Part* pcPart = static_cast(it->getObject()); + if (object->getTypeId() == Base::Type::fromName("App::Part")) { + App::Part* pcPart = static_cast(object); // collect all its link objects auto groupObjects = pcPart->Group.getValue(); @@ -430,27 +437,27 @@ void SectionCut::startCutting(bool isInitial) } } // get all shapes that are also Part::Features - if (it->getObject()->getPropertyByName("Shape") - && it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature"))) { + if (object->getPropertyByName("Shape") + && object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature"))) { // sort out 2D objects, datums, App:Parts, compounds and objects that are // part of a PartDesign body - if (!it->getObject()->getTypeId().isDerivedFrom( + if (!object->getTypeId().isDerivedFrom( Base::Type::fromName("Part::Part2DObject")) - && !it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Datum")) - && !it->getObject()->getTypeId().isDerivedFrom( + && !object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Datum")) + && !object->getTypeId().isDerivedFrom( Base::Type::fromName("PartDesign::Feature")) - && !it->getObject()->getTypeId().isDerivedFrom( + && !object->getTypeId().isDerivedFrom( Base::Type::fromName("Part::Compound")) - && it->getObject()->getTypeId() != Base::Type::fromName("App::Part")) - ObjectsListCut.push_back(it->getObject()); + && object->getTypeId() != Base::Type::fromName("App::Part")) + ObjectsListCut.push_back(object); } // get Links that are derived from Part objects - if (it->getObject()->getTypeId() == Base::Type::fromName("App::Link")) { - App::Link* pcLink = static_cast(it->getObject()); + if (object->getTypeId() == Base::Type::fromName("App::Link")) { + App::Link* pcLink = static_cast(object); auto linkedObject = doc->getObject(pcLink->LinkedObject.getObjectName()); if (linkedObject && linkedObject->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature"))) - ObjectsListCut.push_back(it->getObject()); + ObjectsListCut.push_back(object); } } @@ -471,14 +478,19 @@ void SectionCut::startCutting(bool isInitial) std::vector::iterator it3; // check list of visible objects and not cut list because we want to repove from the cut list for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) { - if (it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Boolean")) - || it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiCommon")) - || it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiFuse")) - || it->getObject()->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Thickness")) - || it->getObject()->getTypeId().isDerivedFrom( + App::DocumentObject* object = it->getObject(); + if (!object) { + continue; + } + + if (object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Boolean")) + || object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiCommon")) + || object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::MultiFuse")) + || object->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Thickness")) + || object->getTypeId().isDerivedFrom( Base::Type::fromName("Part::FilletBase"))) { // get possible links - auto subObjectList = it->getObject()->getOutList(); + auto subObjectList = object->getOutList(); // if there are links, delete them if (!subObjectList.empty()) { for (it2 = subObjectList.begin(); it2 != subObjectList.end(); ++it2) { @@ -622,7 +634,10 @@ void SectionCut::startCutting(bool isInitial) // make all objects invisible so that only the compound remains for (it = ObjectsListVisible.begin(); it != ObjectsListVisible.end(); ++it) { - it->getObject()->Visibility.setValue(false); + App::DocumentObject* object = it->getObject(); + if (object) { + object->Visibility.setValue(false); + } } // the area in which we can cut is the size of the compound