Gui: Reset UVW coordinate system in transform when rotation changes

This commit is contained in:
Kacper Donat
2024-12-15 18:15:19 +01:00
parent d08810c649
commit fe96e7e194
2 changed files with 92 additions and 27 deletions

View File

@@ -101,7 +101,8 @@ TaskTransform::TaskTransform(Gui::ViewProviderDragger* vp,
vp->resetTransformOrigin();
originalPlacement = vp->getObjectPlacement();
referencePlacement = vp->getObjectPlacement();
globalOrigin = vp->getObjectPlacement() * App::GeoFeature::getGlobalPlacement(vp->getObject()).inverse();
setupGui();
}
@@ -119,7 +120,7 @@ TaskTransform::~TaskTransform()
savePreferences();
}
void TaskTransform::dragStartCallback(void*, SoDragger*)
void TaskTransform::dragStartCallback(void* data, SoDragger*)
{
// This is called when a manipulator is about to manipulating
if (firstDrag) {
@@ -127,13 +128,24 @@ void TaskTransform::dragStartCallback(void*, SoDragger*)
QT_TRANSLATE_NOOP("Command", "Transform"));
firstDrag = false;
}
auto task = static_cast<TaskTransform*>(data);
task->referenceRotation = task->vp->getDraggerPlacement().getRotation();
}
void TaskTransform::dragMotionCallback(void* data, SoDragger* dragger)
{
auto task = static_cast<TaskTransform*>(data);
task->updatePositionAndRotationUi();
const auto currentRotation = task->referencePlacement.getRotation();
const auto updatedRotation = task->vp->getDraggerPlacement().getRotation();
if (!updatedRotation.isSame(currentRotation, tolerance)) {
task->resetReferencePlacement();
} else {
task->updatePositionAndRotationUi();
}
}
void TaskTransform::loadPlacementModeItems() const
@@ -157,7 +169,7 @@ void TaskTransform::loadPositionModeItems() const
{
ui->positionModeComboBox->clear();
ui->positionModeComboBox->addItem(tr("Local"), QVariant::fromValue(PositionMode::Local));
ui->positionModeComboBox->addItem(tr("Absolute"), QVariant::fromValue(PositionMode::Absolute));
ui->positionModeComboBox->addItem(tr("Global"), QVariant::fromValue(PositionMode::Global));
}
void TaskTransform::setupGui()
@@ -236,8 +248,8 @@ void TaskTransform::setupGui()
connect(rotationSpinBox,
qOverload<double>(&QuantitySpinBox::valueChanged),
this,
[this](double) {
onRotationChange();
[=](double) {
onRotationChange(rotationSpinBox);
});
}
@@ -271,9 +283,14 @@ void TaskTransform::savePreferences()
void TaskTransform::updatePositionAndRotationUi() const
{
auto referencePlacement = currentCoordinateSystem().origin;
if (positionMode == PositionMode::Local) {
referencePlacement.setRotation(referenceRotation);
}
const auto xyzPlacement = vp->getDraggerPlacement();
const auto uvwPlacement = currentCoordinateSystem().origin.inverse() * xyzPlacement;
const auto uvwPlacement = referencePlacement.inverse() * xyzPlacement;
auto fixNegativeZero = [](const double value) {
return std::fabs(value) < Base::Precision::Confusion() ? 0.0 : value;
@@ -336,7 +353,7 @@ void TaskTransform::updateInputLabels() const
void TaskTransform::updateDraggerLabels() const
{
auto coordinateSystem =
isDraggerAlignedToCoordinateSystem() ? absoluteCoordinateSystem() : localCoordinateSystem();
isDraggerAlignedToCoordinateSystem() ? globalCoordinateSystem() : localCoordinateSystem();
auto [xLabel, yLabel, zLabel] = coordinateSystem.labels;
@@ -398,24 +415,21 @@ TaskTransform::SelectionMode TaskTransform::getSelectionMode() const
TaskTransform::CoordinateSystem TaskTransform::localCoordinateSystem() const
{
auto origin = originalPlacement * vp->getTransformOrigin();
auto origin = referencePlacement;
origin.setRotation(vp->getDraggerPlacement().getRotation());
return {{"U", "V", "W"}, origin};
}
TaskTransform::CoordinateSystem TaskTransform::absoluteCoordinateSystem() const
TaskTransform::CoordinateSystem TaskTransform::globalCoordinateSystem() const
{
return {
{"X", "Y", "Z"},
Base::Placement {},
};
return {{"X", "Y", "Z"}, globalOrigin};
}
TaskTransform::CoordinateSystem TaskTransform::currentCoordinateSystem() const
{
return ui->positionModeComboBox->currentIndex() == 0 ? localCoordinateSystem()
: absoluteCoordinateSystem();
: globalCoordinateSystem();
}
void TaskTransform::onSelectionChanged(const SelectionChanges& msg)
@@ -472,8 +486,7 @@ void TaskTransform::onSelectionChanged(const SelectionChanges& msg)
vp->setDraggerPlacement(vp->getObjectPlacement() * selectedObjectPlacement);
if (msg.Type == SelectionChanges::AddSelection) {
vp->updateTransformFromDragger();
vp->updatePlacementFromDragger();
moveObjectToDragger();
setSelectionMode(SelectionMode::None);
}
@@ -503,6 +516,17 @@ void TaskTransform::onAlignToOtherObject()
setSelectionMode(SelectionMode::SelectAlignTarget);
}
void TaskTransform::moveObjectToDragger()
{
vp->updateTransformFromDragger();
vp->updatePlacementFromDragger();
resetReferenceRotation();
resetReferencePlacement();
updatePositionAndRotationUi();
}
void TaskTransform::onFlip()
{
auto placement = vp->getDraggerPlacement();
@@ -512,8 +536,7 @@ void TaskTransform::onFlip()
vp->setDraggerPlacement(placement);
vp->updateTransformFromDragger();
vp->updatePlacementFromDragger();
moveObjectToDragger();
}
void TaskTransform::onPickTransformOrigin()
@@ -557,18 +580,31 @@ void TaskTransform::updateTransformOrigin()
auto transformOrigin = getTransformOrigin(placementMode);
if (isDraggerAlignedToCoordinateSystem()) {
transformOrigin.setRotation(
(vp->getObjectPlacement().inverse() * absoluteCoordinateSystem().origin).getRotation());
(vp->getObjectPlacement().inverse() * globalCoordinateSystem().origin).getRotation());
}
vp->setTransformOrigin(transformOrigin);
resetReferencePlacement();
resetReferenceRotation();
updatePositionAndRotationUi();
updateDraggerLabels();
}
void TaskTransform::resetReferencePlacement()
{
referencePlacement = vp->getDraggerPlacement();
}
void TaskTransform::resetReferenceRotation()
{
referenceRotation = vp->getDraggerPlacement().getRotation();
}
bool TaskTransform::isDraggerAlignedToCoordinateSystem() const
{
return positionMode == PositionMode::Absolute && ui->alignRotationCheckBox->isChecked();
return positionMode == PositionMode::Global && ui->alignRotationCheckBox->isChecked();
}
void TaskTransform::onTransformOriginReset()
@@ -604,14 +640,32 @@ void TaskTransform::onPositionChange()
vp->updatePlacementFromDragger();
}
void TaskTransform::onRotationChange()
void TaskTransform::onRotationChange(QuantitySpinBox* changed)
{
if (positionMode == PositionMode::Local) {
for (auto rotationSpinBox : {ui->xRotationSpinBox,
ui->yRotationSpinBox,
ui->zRotationSpinBox}) {
QSignalBlocker blocker(rotationSpinBox);
// if any other spinbox contains non-zero value we need to reset rotation reference first
if (std::fabs(rotationSpinBox->rawValue()) > tolerance && rotationSpinBox != changed) {
resetReferenceRotation();
rotationSpinBox->setValue(0.0);
}
}
}
const auto uvwRotation = Base::Rotation::fromEulerAngles(Base::Rotation::Intrinsic_XYZ,
ui->xRotationSpinBox->rawValue(),
ui->yRotationSpinBox->rawValue(),
ui->zRotationSpinBox->rawValue());
const auto xyzRotation = currentCoordinateSystem().origin.getRotation() * uvwRotation;
auto referenceRotation = positionMode == PositionMode::Local
? this->referenceRotation
: currentCoordinateSystem().origin.getRotation();
const auto xyzRotation = referenceRotation * uvwRotation;
const auto placement = vp->getDraggerPlacement();
@@ -619,6 +673,8 @@ void TaskTransform::onRotationChange()
vp->updateTransformFromDragger();
vp->updatePlacementFromDragger();
resetReferencePlacement();
}
TaskCSysDragger::TaskCSysDragger(ViewProviderDragger* vp, SoFCCSysDragger* dragger)

View File

@@ -49,10 +49,12 @@ class TaskTransform : public Gui::TaskView::TaskBox, public Gui::SelectionObserv
{
Q_OBJECT
static constexpr double tolerance = 1e-7;
public:
enum class SelectionMode { None, SelectTransformOrigin, SelectAlignTarget };
enum class PlacementMode { ObjectOrigin, Centroid, Custom };
enum class PositionMode { Local, Absolute };
enum class PositionMode { Local, Global };
struct CoordinateSystem
{
@@ -76,7 +78,7 @@ public:
void setSelectionMode(SelectionMode mode);
SelectionMode getSelectionMode() const;
CoordinateSystem absoluteCoordinateSystem() const;
CoordinateSystem globalCoordinateSystem() const;
CoordinateSystem localCoordinateSystem() const;
CoordinateSystem currentCoordinateSystem() const;
@@ -96,7 +98,7 @@ private Q_SLOTS:
void onCoordinateSystemChange(int mode);
void onPositionChange();
void onRotationChange();
void onRotationChange(QuantitySpinBox* changed);
private:
static inline bool firstDrag = true;
@@ -117,6 +119,11 @@ private:
void updateIncrements() const;
void updateTransformOrigin();
void resetReferencePlacement();
void resetReferenceRotation();
void moveObjectToDragger();
bool isDraggerAlignedToCoordinateSystem() const;
ViewProviderDragger* vp;
@@ -133,7 +140,9 @@ private:
PositionMode positionMode { PositionMode::Local };
std::optional<Base::Placement> customTransformOrigin {};
Base::Placement originalPlacement {};
Base::Placement referencePlacement {};
Base::Placement globalOrigin {};
Base::Rotation referenceRotation {};
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/History/Dragger");
};