diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 858e0354dd..a15ad2bd61 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -257,6 +257,10 @@ void AssemblyObject::doDragStep() Base::Placement AssemblyObject::getMbdPlacement(std::shared_ptr mbdPart) { + if (!mbdPart) { + return Base::Placement(); + } + double x, y, z; mbdPart->getPosition3D(x, y, z); Base::Vector3d pos = Base::Vector3d(x, y, z); @@ -407,12 +411,19 @@ void AssemblyObject::redrawJointPlacements(std::vector joi { // Notify the joint objects that the transform of the coin object changed. for (auto* joint : joints) { + if (!joint) { + continue; + } redrawJointPlacement(joint); } } void AssemblyObject::redrawJointPlacement(App::DocumentObject* joint) { + if (!joint) { + return; + } + // Notify the joint object that the transform of the coin object changed. auto* pPlc = dynamic_cast(joint->getPropertyByName("Placement1")); if (pPlc) { @@ -429,6 +440,10 @@ void AssemblyObject::recomputeJointPlacements(std::vector { // The Placement1 and Placement2 of each joint needs to be updated as the parts moved. for (auto* joint : joints) { + if (!joint) { + continue; + } + App::PropertyPythonObject* proxy = joint ? dynamic_cast(joint->getPropertyByName("Proxy")) : nullptr; @@ -467,6 +482,10 @@ std::shared_ptr AssemblyObject::makeMbdAssembly() App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::DocumentObject* part, std::string& name) { + if (!part) { + return nullptr; + } + std::vector joints = getJointsOfPart(part); for (auto joint : joints) { @@ -494,6 +513,10 @@ App::DocumentObject* AssemblyObject::getJointOfPartConnectingToGround(App::Docum JointGroup* AssemblyObject::getJointGroup(const App::Part* part) { + if (!part) { + return nullptr; + } + App::Document* doc = part->getDocument(); std::vector jointGroups = @@ -614,6 +637,10 @@ std::vector AssemblyObject::getGroundedJoints() std::vector AssemblyObject::getJointsOfObj(App::DocumentObject* obj) { + if (!obj) { + return {}; + } + std::vector joints = getJoints(false); std::vector jointsOf; @@ -630,6 +657,10 @@ std::vector AssemblyObject::getJointsOfObj(App::DocumentOb std::vector AssemblyObject::getJointsOfPart(App::DocumentObject* part) { + if (!part) { + return {}; + } + std::vector joints = getJoints(false); std::vector jointsOf; @@ -693,6 +724,10 @@ void AssemblyObject::fixGroundedPart(App::DocumentObject* obj, Base::Placement& plc, std::string& name) { + if (!obj) { + return; + } + std::string markerName1 = "marker-" + obj->getFullName(); auto mbdMarker1 = makeMbdMarker(markerName1, plc); mbdAssembly->addMarker(mbdMarker1); @@ -717,11 +752,14 @@ void AssemblyObject::fixGroundedPart(App::DocumentObject* obj, bool AssemblyObject::isJointConnectingPartToGround(App::DocumentObject* joint, const char* propname) { - if (!isJointTypeConnecting(joint)) { + if (!joint || !isJointTypeConnecting(joint)) { return false; } App::DocumentObject* part = getMovingPartFromRef(joint, propname); + if (!part) { + return false; + } // Check if the part is grounded. bool isGrounded = isPartGrounded(part); @@ -765,6 +803,10 @@ bool AssemblyObject::isJointConnectingPartToGround(App::DocumentObject* joint, c bool AssemblyObject::isJointTypeConnecting(App::DocumentObject* joint) { + if (!joint) { + return false; + } + JointType jointType = getJointType(joint); return jointType != JointType::RackPinion && jointType != JointType::Screw && jointType != JointType::Gears && jointType != JointType::Belt; @@ -773,6 +815,10 @@ bool AssemblyObject::isJointTypeConnecting(App::DocumentObject* joint) bool AssemblyObject::isObjInSetOfObjRefs(App::DocumentObject* obj, const std::vector& set) { + if (!obj) { + return false; + } + for (const auto& pair : set) { if (pair.obj == obj) { return true; @@ -835,7 +881,12 @@ std::vector AssemblyObject::getConnectedParts(App::DocumentObject* part, const std::vector& joints) { + if (!part) { + return {}; + } + std::vector connectedParts; + for (auto joint : joints) { if (!isJointTypeConnecting(joint)) { continue; @@ -865,6 +916,10 @@ AssemblyObject::getConnectedParts(App::DocumentObject* part, bool AssemblyObject::isPartGrounded(App::DocumentObject* obj) { + if (!obj) { + return false; + } + std::vector groundedObjs = getGroundedParts(); for (auto* groundedObj : groundedObjs) { @@ -878,6 +933,10 @@ bool AssemblyObject::isPartGrounded(App::DocumentObject* obj) bool AssemblyObject::isPartConnected(App::DocumentObject* obj) { + if (!obj) { + return false; + } + std::vector groundedObjs = getGroundedParts(); std::vector joints = getJoints(false); @@ -1186,6 +1245,10 @@ std::shared_ptr AssemblyObject::makeMbdJointDistance(App::DocumentObj std::vector> AssemblyObject::makeMbdJoint(App::DocumentObject* joint) { + if (!joint) { + return {}; + } + JointType jointType = getJointType(joint); std::shared_ptr mbdJoint = makeMbdJointOfType(joint, jointType); @@ -1547,6 +1610,10 @@ AssemblyObject::MbDPartData AssemblyObject::getMbDData(App::DocumentObject* part std::shared_ptr AssemblyObject::getMbDPart(App::DocumentObject* part) { + if (!part) { + return nullptr; + } + return getMbDData(part).part; } @@ -1606,6 +1673,10 @@ std::shared_ptr AssemblyObject::makeMbdMarker(std::string& name, Bas std::vector AssemblyObject::getDownstreamParts(App::DocumentObject* part, App::DocumentObject* joint) { + if (!part) { + return {}; + } + // First we deactivate the joint bool state = false; if (joint) { @@ -1628,59 +1699,17 @@ std::vector AssemblyObject::getDownstreamParts(App::DocumentObject* part if (joint) { AssemblyObject::setJointActivated(joint, state); } - /*if (limit > 1000) { // Infinite loop protection - return {}; - } - limit++; - Base::Console().Warning("limit %d\n", limit); - std::vector downstreamParts = {part}; - std::string name; - App::DocumentObject* connectingJoint = - getJointOfPartConnectingToGround(part, - name); // ?????????????????????????????? if we remove - // connection to ground then it can't work for tom - std::vector jointsOfPart = getJointsOfPart(part); - - // remove connectingJoint from jointsOfPart - auto it = std::remove(jointsOfPart.begin(), jointsOfPart.end(), connectingJoint); - jointsOfPart.erase(it, jointsOfPart.end()); - for (auto joint : jointsOfPart) { - App::DocumentObject* part1 = getMovingPartFromRef(joint, "Reference1"); - App::DocumentObject* part2 = getMovingPartFromRef(joint, "Reference2"); - bool firstIsDown = part->getFullName() == part2->getFullName(); - App::DocumentObject* downstreamPart = firstIsDown ? part1 : part2; - - Base::Console().Warning("looping\n"); - // it is possible that the part is connected to ground by this joint. - // In which case we should not select those parts. To test we disconnect : - auto* propObj = dynamic_cast(joint->getPropertyByName("Part1")); - if (!propObj) { - continue; - } - propObj->setValue(nullptr); - bool isConnected = isPartConnected(downstreamPart); - propObj->setValue(part1); - if (isConnected) { - Base::Console().Warning("continue\n"); - continue; - } - - std::vector subDownstreamParts = - getDownstreamParts(downstreamPart, limit); - for (auto downPart : subDownstreamParts) { - if (std::find(downstreamParts.begin(), downstreamParts.end(), downPart) - == downstreamParts.end()) { - downstreamParts.push_back(downPart); - } - } - }*/ return downstreamParts; } std::vector AssemblyObject::getUpstreamParts(App::DocumentObject* part, int limit) { + if (!part) { + return {}; + } + if (limit > 1000) { // Infinite loop protection return {}; } @@ -1704,7 +1733,7 @@ App::DocumentObject* AssemblyObject::getUpstreamMovingPart(App::DocumentObject* App::DocumentObject*& joint, std::string& name) { - if (isPartGrounded(part)) { + if (!part || isPartGrounded(part)) { return nullptr; } @@ -1721,6 +1750,10 @@ App::DocumentObject* AssemblyObject::getUpstreamMovingPart(App::DocumentObject* double AssemblyObject::getObjMass(App::DocumentObject* obj) { + if (!obj) { + return 0.0; + } + for (auto& pair : objMasses) { if (pair.first == obj) { return pair.second; @@ -1809,6 +1842,10 @@ void AssemblyObject::ensureIdentityPlacements() void AssemblyObject::swapJCS(App::DocumentObject* joint) { + if (!joint) { + return; + } + auto pPlc1 = dynamic_cast(joint->getPropertyByName("Placement1")); auto pPlc2 = dynamic_cast(joint->getPropertyByName("Placement2")); if (pPlc1 && pPlc2) { @@ -1833,7 +1870,11 @@ bool AssemblyObject::isEdgeType(App::DocumentObject* obj, std::string& elName, GeomAbs_CurveType type) { - PartApp::Feature* base = static_cast(obj); + auto* base = dynamic_cast(obj); + if (!base) { + return false; + } + const PartApp::TopoShape& TopShape = base->Shape.getShape(); // Check for valid face types @@ -1851,8 +1892,12 @@ bool AssemblyObject::isFaceType(App::DocumentObject* obj, std::string& elName, GeomAbs_SurfaceType type) { - auto base = static_cast(obj); - PartApp::TopoShape TopShape = base->Shape.getShape(); + auto* base = dynamic_cast(obj); + if (!base) { + return false; + } + + const PartApp::TopoShape TopShape = base->Shape.getShape(); // Check for valid face types TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(elName.c_str())); @@ -1867,7 +1912,11 @@ bool AssemblyObject::isFaceType(App::DocumentObject* obj, double AssemblyObject::getFaceRadius(App::DocumentObject* obj, std::string& elt) { - auto base = static_cast(obj); + auto* base = dynamic_cast(obj); + if (!base) { + return 0.0; + } + const PartApp::TopoShape& TopShape = base->Shape.getShape(); // Check for valid face types @@ -1886,7 +1935,11 @@ double AssemblyObject::getFaceRadius(App::DocumentObject* obj, std::string& elt) double AssemblyObject::getEdgeRadius(App::DocumentObject* obj, std::string& elt) { - auto base = static_cast(obj); + auto* base = dynamic_cast(obj); + if (!base) { + return 0.0; + } + const PartApp::TopoShape& TopShape = base->Shape.getShape(); // Check for valid face types @@ -1902,6 +1955,10 @@ double AssemblyObject::getEdgeRadius(App::DocumentObject* obj, std::string& elt) DistanceType AssemblyObject::getDistanceType(App::DocumentObject* joint) { + if (!joint) { + return DistanceType::Other; + } + std::string type1 = getElementTypeFromProp(joint, "Reference1"); std::string type2 = getElementTypeFromProp(joint, "Reference2"); std::string elt1 = getElementFromProp(joint, "Reference1"); @@ -2119,6 +2176,10 @@ DistanceType AssemblyObject::getDistanceType(App::DocumentObject* joint) void AssemblyObject::setJointActivated(App::DocumentObject* joint, bool val) { + if (!joint) { + return; + } + auto* propActivated = dynamic_cast(joint->getPropertyByName("Activated")); if (propActivated) { propActivated->setValue(val); @@ -2127,6 +2188,10 @@ void AssemblyObject::setJointActivated(App::DocumentObject* joint, bool val) bool AssemblyObject::getJointActivated(App::DocumentObject* joint) { + if (!joint) { + return false; + } + auto* propActivated = dynamic_cast(joint->getPropertyByName("Activated")); if (propActivated) { return propActivated->getValue(); @@ -2137,6 +2202,9 @@ bool AssemblyObject::getJointActivated(App::DocumentObject* joint) double AssemblyObject::getJointDistance(App::DocumentObject* joint) { double distance = 0.0; + if (!joint) { + return distance; + } auto* prop = dynamic_cast(joint->getPropertyByName("Distance")); if (prop) { @@ -2149,6 +2217,9 @@ double AssemblyObject::getJointDistance(App::DocumentObject* joint) double AssemblyObject::getJointDistance2(App::DocumentObject* joint) { double distance = 0.0; + if (!joint) { + return distance; + } auto* prop = dynamic_cast(joint->getPropertyByName("Distance2")); if (prop) { @@ -2161,6 +2232,9 @@ double AssemblyObject::getJointDistance2(App::DocumentObject* joint) JointType AssemblyObject::getJointType(App::DocumentObject* joint) { JointType jointType = JointType::Fixed; + if (!joint) { + return jointType; + } auto* prop = dynamic_cast(joint->getPropertyByName("JointType")); if (prop) { @@ -2186,6 +2260,10 @@ std::vector AssemblyObject::getSubAsList(App::PropertyXLinkSub* pro std::vector AssemblyObject::getSubAsList(App::DocumentObject* obj, const char* pName) { + if (!obj) { + return {}; + } + auto* prop = dynamic_cast(obj->getPropertyByName(pName)); return getSubAsList(prop); @@ -2193,6 +2271,10 @@ std::vector AssemblyObject::getSubAsList(App::DocumentObject* obj, std::string AssemblyObject::getElementFromProp(App::DocumentObject* obj, const char* pName) { + if (!obj) { + return ""; + } + std::vector names = getSubAsList(obj, pName); if (names.empty()) { @@ -2216,6 +2298,10 @@ std::string AssemblyObject::getElementTypeFromProp(App::DocumentObject* obj, con App::DocumentObject* AssemblyObject::getObjFromProp(App::DocumentObject* joint, const char* pName) { + if (!joint) { + return nullptr; + } + auto* propObj = dynamic_cast(joint->getPropertyByName(pName)); if (!propObj) { return nullptr; @@ -2323,6 +2409,10 @@ App::DocumentObject* AssemblyObject::getObjFromRef(App::PropertyXLinkSub* prop) App::DocumentObject* AssemblyObject::getObjFromRef(App::DocumentObject* joint, const char* pName) { + if (!joint) { + return nullptr; + } + auto* prop = dynamic_cast(joint->getPropertyByName(pName)); return getObjFromRef(prop); @@ -2397,6 +2487,10 @@ App::DocumentObject* AssemblyObject::getMovingPartFromRef(App::PropertyXLinkSub* App::DocumentObject* AssemblyObject::getMovingPartFromRef(App::DocumentObject* joint, const char* pName) { + if (!joint) { + return nullptr; + } + auto* prop = dynamic_cast(joint->getPropertyByName(pName)); return getMovingPartFromRef(prop); @@ -2405,6 +2499,10 @@ App::DocumentObject* AssemblyObject::getMovingPartFromRef(App::DocumentObject* j App::DocumentObject* AssemblyObject::getLinkedObjFromRef(App::DocumentObject* joint, const char* pObj) { + if (!joint) { + return nullptr; + } + auto* obj = getObjFromRef(joint, pObj); if (obj) { return obj->getLinkedObject(true);