Assembly: Add validation step during dragging to ignore steps where grounded objects moved.
This commit is contained in:
committed by
Chris Hennes
parent
4d5eb39762
commit
47c22bec65
@@ -221,14 +221,57 @@ void AssemblyObject::doDragStep()
|
||||
|
||||
auto dragPartsVec = std::make_shared<std::vector<std::shared_ptr<ASMTPart>>>(dragMbdParts);
|
||||
mbdAssembly->runDragStep(dragPartsVec);
|
||||
setNewPlacements();
|
||||
redrawJointPlacements(getJoints());
|
||||
if (validateNewPlacements()) {
|
||||
setNewPlacements();
|
||||
redrawJointPlacements(getJoints());
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// We do nothing if a solve step fails.
|
||||
}
|
||||
}
|
||||
|
||||
Base::Placement AssemblyObject::getMbdPlacement(std::shared_ptr<ASMTPart> mbdPart)
|
||||
{
|
||||
double x, y, z;
|
||||
mbdPart->getPosition3D(x, y, z);
|
||||
Base::Vector3d pos = Base::Vector3d(x, y, z);
|
||||
|
||||
double q0, q1, q2, q3;
|
||||
mbdPart->getQuarternions(q3, q0, q1, q2);
|
||||
Base::Rotation rot = Base::Rotation(q0, q1, q2, q3);
|
||||
|
||||
return Base::Placement(pos, rot);
|
||||
}
|
||||
|
||||
bool AssemblyObject::validateNewPlacements()
|
||||
{
|
||||
// First we check if a grounded object has moved. It can happen that they flip.
|
||||
for (auto* obj : getGroundedParts()) {
|
||||
auto* propPlacement =
|
||||
dynamic_cast<App::PropertyPlacement*>(obj->getPropertyByName("Placement"));
|
||||
if (propPlacement) {
|
||||
Base::Placement oldPlc = propPlacement->getValue();
|
||||
|
||||
auto it = objectPartMap.find(obj);
|
||||
if (it != objectPartMap.end()) {
|
||||
std::shared_ptr<MbD::ASMTPart> mbdPart = it->second;
|
||||
Base::Placement newPlacement = getMbdPlacement(mbdPart);
|
||||
if (!oldPlc.isSame(newPlacement)) {
|
||||
Base::Console().Warning(
|
||||
"Assembly : Ignoring bad solve, a grounded object moved.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: We could do further tests
|
||||
// For example check if the joints connectors are correctly aligned.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AssemblyObject::postDrag()
|
||||
{
|
||||
mbdAssembly->runPostDrag(); // Do this after last drag
|
||||
@@ -320,31 +363,7 @@ void AssemblyObject::setNewPlacements()
|
||||
continue;
|
||||
}
|
||||
|
||||
double x, y, z;
|
||||
mbdPart->getPosition3D(x, y, z);
|
||||
// Base::Console().Warning("in set placement : (%f, %f, %f)\n", x, y, z);
|
||||
Base::Vector3d pos = Base::Vector3d(x, y, z);
|
||||
|
||||
// TODO : replace with quaternion to simplify
|
||||
auto& r0 = mbdPart->rotationMatrix->at(0);
|
||||
auto& r1 = mbdPart->rotationMatrix->at(1);
|
||||
auto& r2 = mbdPart->rotationMatrix->at(2);
|
||||
Base::Vector3d row0 = Base::Vector3d(r0->at(0), r0->at(1), r0->at(2));
|
||||
Base::Vector3d row1 = Base::Vector3d(r1->at(0), r1->at(1), r1->at(2));
|
||||
Base::Vector3d row2 = Base::Vector3d(r2->at(0), r2->at(1), r2->at(2));
|
||||
Base::Matrix4D mat;
|
||||
mat.setRow(0, row0);
|
||||
mat.setRow(1, row1);
|
||||
mat.setRow(2, row2);
|
||||
Base::Rotation rot = Base::Rotation(mat);
|
||||
|
||||
/*double q0, q1, q2, q3;
|
||||
mbdPart->getQuarternions(q0, q1, q2, q3);
|
||||
Base::Rotation rot = Base::Rotation(q0, q1, q2, q3);*/
|
||||
|
||||
Base::Placement newPlacement = Base::Placement(pos, rot);
|
||||
|
||||
propPlacement->setValue(newPlacement);
|
||||
propPlacement->setValue(getMbdPlacement(mbdPart));
|
||||
obj->purgeTouched();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +155,8 @@ public:
|
||||
|
||||
void exportAsASMT(std::string fileName);
|
||||
|
||||
Base::Placement getMbdPlacement(std::shared_ptr<MbD::ASMTPart> mbdPart);
|
||||
bool validateNewPlacements();
|
||||
void setNewPlacements();
|
||||
void recomputeJointPlacements(std::vector<App::DocumentObject*> joints);
|
||||
void redrawJointPlacements(std::vector<App::DocumentObject*> joints);
|
||||
|
||||
Reference in New Issue
Block a user