diff --git a/src/Mod/Assembly/App/AssemblyObject.cpp b/src/Mod/Assembly/App/AssemblyObject.cpp index 84ad387cf7..0dabd5b998 100644 --- a/src/Mod/Assembly/App/AssemblyObject.cpp +++ b/src/Mod/Assembly/App/AssemblyObject.cpp @@ -1142,25 +1142,34 @@ AssemblyObject::makeMbdJoint(App::DocumentObject* joint) mbdJoint->setMarkerJ(fullMarkerNameJ); // Add limits if needed. - auto* prop = dynamic_cast(joint->getPropertyByName("EnableLimits")); - if (prop && prop->getValue()) { - if (jointType == JointType::Slider || jointType == JointType::Cylindrical) { - auto* propLenMin = - dynamic_cast(joint->getPropertyByName("LengthMin")); - auto* propLenMax = - dynamic_cast(joint->getPropertyByName("LengthMax")); + if (jointType == JointType::Slider || jointType == JointType::Cylindrical) { + auto* pLenMin = dynamic_cast(joint->getPropertyByName("LengthMin")); + auto* pLenMax = dynamic_cast(joint->getPropertyByName("LengthMax")); + auto* pMinEnabled = + dynamic_cast(joint->getPropertyByName("EnableLengthMin")); + auto* pMaxEnabled = + dynamic_cast(joint->getPropertyByName("EnableLengthMax")); - if (propLenMin && propLenMax) { - // Swap the values if necessary. - double minLength = propLenMin->getValue(); - double maxLength = propLenMax->getValue(); - if (minLength > maxLength) { - propLenMin->setValue(maxLength); - propLenMax->setValue(minLength); - minLength = maxLength; - maxLength = propLenMax->getValue(); - } + if (pLenMin && pLenMax && pMinEnabled && pMaxEnabled) { // Make sure properties do exist + // Swap the values if necessary. + bool minEnabled = pMinEnabled->getValue(); + bool maxEnabled = pMaxEnabled->getValue(); + double minLength = pLenMin->getValue(); + double maxLength = pLenMax->getValue(); + if ((minLength > maxLength) && minEnabled && maxEnabled) { + pLenMin->setValue(maxLength); + pLenMax->setValue(minLength); + minLength = maxLength; + maxLength = pLenMax->getValue(); + + pMinEnabled->setValue(maxEnabled); + pMaxEnabled->setValue(minEnabled); + minEnabled = maxEnabled; + maxEnabled = pMaxEnabled->getValue(); + } + + if (minEnabled) { auto limit = ASMTTranslationLimit::With(); limit->setName(joint->getFullName() + "-LimitLenMin"); limit->setMarkerI(fullMarkerNameI); @@ -1169,7 +1178,9 @@ AssemblyObject::makeMbdJoint(App::DocumentObject* joint) limit->setlimit(std::to_string(minLength)); limit->settol("1.0e-9"); mbdAssembly->addLimit(limit); + } + if (maxEnabled) { auto limit2 = ASMTTranslationLimit::With(); limit2->setName(joint->getFullName() + "-LimitLenMax"); limit2->setMarkerI(fullMarkerNameI); @@ -1180,23 +1191,34 @@ AssemblyObject::makeMbdJoint(App::DocumentObject* joint) mbdAssembly->addLimit(limit2); } } - if (jointType == JointType::Revolute || jointType == JointType::Cylindrical) { - auto* propRotMin = - dynamic_cast(joint->getPropertyByName("AngleMin")); - auto* propRotMax = - dynamic_cast(joint->getPropertyByName("AngleMax")); + } + if (jointType == JointType::Revolute || jointType == JointType::Cylindrical) { + auto* pRotMin = dynamic_cast(joint->getPropertyByName("AngleMin")); + auto* pRotMax = dynamic_cast(joint->getPropertyByName("AngleMax")); + auto* pMinEnabled = + dynamic_cast(joint->getPropertyByName("EnableAngleMin")); + auto* pMaxEnabled = + dynamic_cast(joint->getPropertyByName("EnableAngleMax")); - if (propRotMin && propRotMax) { - // Swap the values if necessary. - double minAngle = propRotMin->getValue(); - double maxAngle = propRotMax->getValue(); - if (minAngle > maxAngle) { - propRotMin->setValue(maxAngle); - propRotMax->setValue(minAngle); - minAngle = maxAngle; - maxAngle = propRotMax->getValue(); - } + if (pRotMin && pRotMax && pMinEnabled && pMaxEnabled) { // Make sure properties do exist + // Swap the values if necessary. + bool minEnabled = pMinEnabled->getValue(); + bool maxEnabled = pMaxEnabled->getValue(); + double minAngle = pRotMin->getValue(); + double maxAngle = pRotMax->getValue(); + if ((minAngle > maxAngle) && minEnabled && maxEnabled) { + pRotMin->setValue(maxAngle); + pRotMax->setValue(minAngle); + minAngle = maxAngle; + maxAngle = pRotMax->getValue(); + pMinEnabled->setValue(maxEnabled); + pMaxEnabled->setValue(minEnabled); + minEnabled = maxEnabled; + maxEnabled = pMaxEnabled->getValue(); + } + + if (minEnabled) { auto limit = ASMTRotationLimit::With(); limit->setName(joint->getFullName() + "-LimitRotMin"); limit->setMarkerI(fullMarkerNameI); @@ -1205,7 +1227,9 @@ AssemblyObject::makeMbdJoint(App::DocumentObject* joint) limit->setlimit(std::to_string(minAngle) + "*pi/180.0"); limit->settol("1.0e-9"); mbdAssembly->addLimit(limit); + } + if (maxEnabled) { auto limit2 = ASMTRotationLimit::With(); limit2->setName(joint->getFullName() + "-LimiRotMax"); limit2->setMarkerI(fullMarkerNameI); diff --git a/src/Mod/Assembly/Gui/Resources/panels/TaskAssemblyCreateJoint.ui b/src/Mod/Assembly/Gui/Resources/panels/TaskAssemblyCreateJoint.ui index 58b40dcba6..1a71b19688 100644 --- a/src/Mod/Assembly/Gui/Resources/panels/TaskAssemblyCreateJoint.ui +++ b/src/Mod/Assembly/Gui/Resources/panels/TaskAssemblyCreateJoint.ui @@ -137,96 +137,107 @@ - - + + Limits - - false - + + + + + Min length + + + false + + + + + + + + 0 + 0 + + + + mm + + + + + + + Max length + + + false + + + + + + + + 0 + 0 + + + + mm + + + + + + + Min angle + + + false + + + + + + + + 0 + 0 + + + + deg + + + + + + + Max angle + + + false + + + + + + + + 0 + 0 + + + + deg + + + + - - - Length min - - - - - - - - 0 - 0 - - - - mm - - - - - - - Length max - - - - - - - - 0 - 0 - - - - mm - - - - - - - Angle min - - - - - - - - 0 - 0 - - - - deg - - - - - - - Angle max - - - - - - - - 0 - 0 - - - - deg - - - - Reverse rotation diff --git a/src/Mod/Assembly/JointObject.py b/src/Mod/Assembly/JointObject.py index 4ef2c223e4..20a340b52d 100644 --- a/src/Mod/Assembly/JointObject.py +++ b/src/Mod/Assembly/JointObject.py @@ -370,17 +370,53 @@ class Joint: ) joint.Activated = True - if not hasattr(joint, "EnableLimits"): + if not hasattr(joint, "EnableLengthMin"): joint.addProperty( "App::PropertyBool", - "EnableLimits", + "EnableLengthMin", "Limits", QT_TRANSLATE_NOOP( "App::Property", - "Is this joint using limits.", + "Enable the minimum length limit of the joint.", ), ) - joint.EnableLimits = False + joint.EnableLengthMin = False + + if not hasattr(joint, "EnableLengthMax"): + joint.addProperty( + "App::PropertyBool", + "EnableLengthMax", + "Limits", + QT_TRANSLATE_NOOP( + "App::Property", + "Enable the maximum length limit of the joint.", + ), + ) + joint.EnableLengthMax = False + + if not hasattr(joint, "EnableAngleMin"): + joint.addProperty( + "App::PropertyBool", + "EnableAngleMin", + "Limits", + QT_TRANSLATE_NOOP( + "App::Property", + "Enable the minimum angle limit of the joint.", + ), + ) + joint.EnableAngleMin = False + + if not hasattr(joint, "EnableAngleMax"): + joint.addProperty( + "App::PropertyBool", + "EnableAngleMax", + "Limits", + QT_TRANSLATE_NOOP( + "App::Property", + "Enable the minimum length of the joint.", + ), + ) + joint.EnableAngleMax = False if not hasattr(joint, "LengthMin"): joint.addProperty( @@ -1268,7 +1304,11 @@ class TaskAssemblyCreateJoint(QtCore.QObject): self.form.offsetSpinbox.valueChanged.connect(self.onOffsetChanged) self.form.rotationSpinbox.valueChanged.connect(self.onRotationChanged) self.form.PushButtonReverse.clicked.connect(self.onReverseClicked) - self.form.LimitCheckbox.stateChanged.connect(self.adaptUi) + + self.form.limitCheckbox1.stateChanged.connect(self.adaptUi) + self.form.limitCheckbox2.stateChanged.connect(self.adaptUi) + self.form.limitCheckbox3.stateChanged.connect(self.adaptUi) + self.form.limitCheckbox4.stateChanged.connect(self.adaptUi) self.form.limitLenMinSpinbox.valueChanged.connect(self.onLimitLenMinChanged) self.form.limitLenMaxSpinbox.valueChanged.connect(self.onLimitLenMaxChanged) self.form.limitRotMinSpinbox.valueChanged.connect(self.onLimitRotMinChanged) @@ -1545,37 +1585,42 @@ class TaskAssemblyCreateJoint(QtCore.QObject): needLengthLimits = jType in JointUsingLimitLength needAngleLimits = jType in JointUsingLimitAngle - showLimits = False if needLengthLimits or needAngleLimits: - self.form.LimitCheckbox.show() - showLimits = True - else: - self.form.LimitCheckbox.hide() + self.form.groupBox_limits.show() - showLimits = showLimits and self.form.LimitCheckbox.isChecked() - self.joint.EnableLimits = showLimits + self.joint.EnableLengthMin = self.form.limitCheckbox1.isChecked() + self.joint.EnableLengthMax = self.form.limitCheckbox2.isChecked() + self.joint.EnableAngleMin = self.form.limitCheckbox3.isChecked() + self.joint.EnableAngleMax = self.form.limitCheckbox4.isChecked() - if needLengthLimits and showLimits: - self.form.limitLenMinSpinboxLabel.show() - self.form.limitLenMaxSpinboxLabel.show() - self.form.limitLenMinSpinbox.show() - self.form.limitLenMaxSpinbox.show() - else: - self.form.limitLenMinSpinboxLabel.hide() - self.form.limitLenMaxSpinboxLabel.hide() - self.form.limitLenMinSpinbox.hide() - self.form.limitLenMaxSpinbox.hide() + if needLengthLimits: + self.form.limitCheckbox1.show() + self.form.limitCheckbox2.show() + self.form.limitLenMinSpinbox.show() + self.form.limitLenMaxSpinbox.show() + self.form.limitLenMinSpinbox.setEnabled(self.joint.EnableLengthMin) + self.form.limitLenMaxSpinbox.setEnabled(self.joint.EnableLengthMax) + else: + self.form.limitCheckbox1.hide() + self.form.limitCheckbox2.hide() + self.form.limitLenMinSpinbox.hide() + self.form.limitLenMaxSpinbox.hide() + + if needAngleLimits: + self.form.limitCheckbox3.show() + self.form.limitCheckbox4.show() + self.form.limitRotMinSpinbox.show() + self.form.limitRotMaxSpinbox.show() + self.form.limitRotMinSpinbox.setEnabled(self.joint.EnableAngleMin) + self.form.limitRotMaxSpinbox.setEnabled(self.joint.EnableAngleMax) + else: + self.form.limitCheckbox3.hide() + self.form.limitCheckbox4.hide() + self.form.limitRotMinSpinbox.hide() + self.form.limitRotMaxSpinbox.hide() - if needAngleLimits and showLimits: - self.form.limitRotMinSpinboxLabel.show() - self.form.limitRotMaxSpinboxLabel.show() - self.form.limitRotMinSpinbox.show() - self.form.limitRotMaxSpinbox.show() else: - self.form.limitRotMinSpinboxLabel.hide() - self.form.limitRotMaxSpinboxLabel.hide() - self.form.limitRotMinSpinbox.hide() - self.form.limitRotMaxSpinbox.hide() + self.form.groupBox_limits.hide() def updateTaskboxFromJoint(self): self.current_selection = [] @@ -1617,7 +1662,10 @@ class TaskAssemblyCreateJoint(QtCore.QObject): self.form.offsetSpinbox.setProperty("rawValue", self.joint.Offset.z) self.form.rotationSpinbox.setProperty("rawValue", self.joint.Rotation) - self.form.LimitCheckbox.setChecked(self.joint.EnableLimits) + self.form.limitCheckbox1.setChecked(self.joint.EnableLengthMin) + self.form.limitCheckbox2.setChecked(self.joint.EnableLengthMax) + self.form.limitCheckbox3.setChecked(self.joint.EnableAngleMin) + self.form.limitCheckbox4.setChecked(self.joint.EnableAngleMax) self.form.limitLenMinSpinbox.setProperty("rawValue", self.joint.LengthMin) self.form.limitLenMaxSpinbox.setProperty("rawValue", self.joint.LengthMax) self.form.limitRotMinSpinbox.setProperty("rawValue", self.joint.AngleMin)