Gui: Zero out rotation only if more than 1 axis changed
This commit is contained in:
@@ -128,24 +128,39 @@ void TaskTransform::dragStartCallback(void* data, 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);
|
||||
|
||||
const auto currentRotation = task->referencePlacement.getRotation();
|
||||
const auto currentRotation = task->vp->getOriginalDraggerPlacement().getRotation();
|
||||
const auto updatedRotation = task->vp->getDraggerPlacement().getRotation();
|
||||
|
||||
const auto rotationAxisHasChanged = [task](auto first, auto second) {
|
||||
double alpha, beta, gamma;
|
||||
|
||||
(first.inverse() * second).getEulerAngles(task->eulerSequence(), alpha, beta, gamma);
|
||||
|
||||
auto angles = {alpha, beta, gamma};
|
||||
const int changed = std::count_if(angles.begin(), angles.end(), [](double angle) {
|
||||
return std::fabs(angle) > tolerance;
|
||||
});
|
||||
|
||||
// if representation of both differs by more than one axis the axis of rotation must be
|
||||
// different
|
||||
return changed > 1;
|
||||
};
|
||||
|
||||
if (!updatedRotation.isSame(currentRotation, tolerance)) {
|
||||
task->resetReferencePlacement();
|
||||
} else {
|
||||
task->updatePositionAndRotationUi();
|
||||
|
||||
if (rotationAxisHasChanged(task->referenceRotation, updatedRotation)) {
|
||||
task->referenceRotation = currentRotation;
|
||||
}
|
||||
}
|
||||
|
||||
task->updatePositionAndRotationUi();
|
||||
}
|
||||
|
||||
void TaskTransform::loadPlacementModeItems() const
|
||||
@@ -283,11 +298,7 @@ void TaskTransform::savePreferences()
|
||||
|
||||
void TaskTransform::updatePositionAndRotationUi() const
|
||||
{
|
||||
auto referencePlacement = currentCoordinateSystem().origin;
|
||||
|
||||
if (positionMode == PositionMode::Local) {
|
||||
referencePlacement.setRotation(referenceRotation);
|
||||
}
|
||||
const auto referencePlacement = currentCoordinateSystem().origin;
|
||||
|
||||
const auto xyzPlacement = vp->getDraggerPlacement();
|
||||
const auto uvwPlacement = referencePlacement.inverse() * xyzPlacement;
|
||||
@@ -317,24 +328,17 @@ void TaskTransform::updatePositionAndRotationUi() const
|
||||
z->setValue(fixNegativeZero(gamma));
|
||||
};
|
||||
|
||||
auto setValues = [&](const Base::Placement& placement,
|
||||
auto* px,
|
||||
auto* py,
|
||||
auto* pz,
|
||||
auto* rx,
|
||||
auto* ry,
|
||||
auto* rz) {
|
||||
setPositionValues(placement.getPosition(), px, py, pz);
|
||||
setRotationValues(placement.getRotation(), rx, ry, rz);
|
||||
};
|
||||
setPositionValues(uvwPlacement.getPosition(),
|
||||
ui->xPositionSpinBox,
|
||||
ui->yPositionSpinBox,
|
||||
ui->zPositionSpinBox);
|
||||
|
||||
setValues(uvwPlacement,
|
||||
ui->xPositionSpinBox,
|
||||
ui->yPositionSpinBox,
|
||||
ui->zPositionSpinBox,
|
||||
ui->xRotationSpinBox,
|
||||
ui->yRotationSpinBox,
|
||||
ui->zRotationSpinBox);
|
||||
setRotationValues(positionMode == PositionMode::Local
|
||||
? referenceRotation.inverse() * xyzPlacement.getRotation()
|
||||
: uvwPlacement.getRotation(),
|
||||
ui->xRotationSpinBox,
|
||||
ui->yRotationSpinBox,
|
||||
ui->zRotationSpinBox);
|
||||
}
|
||||
|
||||
void TaskTransform::updateInputLabels() const
|
||||
|
||||
@@ -75,15 +75,6 @@ public:
|
||||
Base::provideService<App::CenterOfMassProvider>());
|
||||
~TaskTransform() override;
|
||||
|
||||
void setSelectionMode(SelectionMode mode);
|
||||
SelectionMode getSelectionMode() const;
|
||||
|
||||
CoordinateSystem globalCoordinateSystem() const;
|
||||
CoordinateSystem localCoordinateSystem() const;
|
||||
CoordinateSystem currentCoordinateSystem() const;
|
||||
|
||||
Base::Rotation::EulerSequence eulerSequence() const;
|
||||
|
||||
private:
|
||||
void onSelectionChanged(const SelectionChanges& msg) override;
|
||||
|
||||
@@ -107,6 +98,15 @@ private:
|
||||
static void dragStartCallback(void* data, SoDragger* d);
|
||||
static void dragMotionCallback(void* data, SoDragger* d);
|
||||
|
||||
void setSelectionMode(SelectionMode mode);
|
||||
SelectionMode getSelectionMode() const;
|
||||
|
||||
CoordinateSystem globalCoordinateSystem() const;
|
||||
CoordinateSystem localCoordinateSystem() const;
|
||||
CoordinateSystem currentCoordinateSystem() const;
|
||||
|
||||
Base::Rotation::EulerSequence eulerSequence() const;
|
||||
|
||||
void setupGui();
|
||||
|
||||
void loadPreferences();
|
||||
|
||||
@@ -308,6 +308,11 @@ Base::Placement ViewProviderDragger::getDraggerPlacement() const
|
||||
);
|
||||
}
|
||||
|
||||
Base::Placement ViewProviderDragger::getOriginalDraggerPlacement() const
|
||||
{
|
||||
return draggerPlacement;
|
||||
}
|
||||
|
||||
void ViewProviderDragger::setDraggerPlacement(const Base::Placement& placement)
|
||||
{
|
||||
csysDragger->translation.setValue(Base::convertTo<SbVec3f>(placement.getPosition()));
|
||||
|
||||
@@ -56,10 +56,16 @@ public:
|
||||
/// destructor.
|
||||
~ViewProviderDragger() override;
|
||||
|
||||
/// Origin used when object is transformed. It temporarily changes the origin of object.
|
||||
/// Dragger is normally placed at the transform origin, unless explicitly overridden via
|
||||
/// ViewProviderDragger#setDraggerPlacement() method.
|
||||
App::PropertyPlacement TransformOrigin;
|
||||
|
||||
/// Convenience method to obtain the transform origin
|
||||
Base::Placement getTransformOrigin() const { return TransformOrigin.getValue(); }
|
||||
/// Convenience method to set the transform origin
|
||||
void setTransformOrigin(const Base::Placement& placement);
|
||||
/// Resets transform origin to the object origin
|
||||
void resetTransformOrigin();
|
||||
|
||||
public:
|
||||
@@ -74,11 +80,18 @@ public:
|
||||
/*! synchronize From FC placement to Coin placement*/
|
||||
static void updateTransform(const Base::Placement &from, SoTransform *to);
|
||||
|
||||
/// updates placement of object based on dragger position
|
||||
void updatePlacementFromDragger();
|
||||
/// updates transform of object based on dragger position, can be used to preview movement
|
||||
void updateTransformFromDragger();
|
||||
|
||||
/// Gets object placement relative to its coordinate system
|
||||
Base::Placement getObjectPlacement() const;
|
||||
/// Gets current dragger placement, including current dragger movement
|
||||
Base::Placement getDraggerPlacement() const;
|
||||
/// Gets original dragger placement, without current dragger movement
|
||||
Base::Placement getOriginalDraggerPlacement() const;
|
||||
/// Sets placement of dragger relative to objects origin
|
||||
void setDraggerPlacement(const Base::Placement& placement);
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user