Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 51 additions & 31 deletions source/MRViewer/MRObjectTransformWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "MRMesh/MRIntersection.h"
#include "MRMesh/MR2to3.h"
#include "MRMesh/MRAffineXfDecompose.h"
#include <GLFW/glfw3.h>

namespace
{
Expand Down Expand Up @@ -207,7 +206,7 @@ void ObjectTransformWidget::reset()
width_ = -1.0f;
radius_ = -1.0f;

axisTransformMode_ = Translation;
axisTransformMode_ = AxisTranslation;

thresholdDot_ = 0.f;
}
Expand Down Expand Up @@ -357,25 +356,26 @@ void ObjectTransformWidget::draw_()
if ( currentIndex < 0 )
return;

// translation
if ( currentIndex < 3 )
switch ( activeEditMode_ )
{
if ( axisTransformMode_ == Translation && translateTooltipCallback_ )
case TranslationMode:
if ( translateTooltipCallback_ )
{
auto xf = controlsRoot_->xf();
auto axis = xf( translateLines_[currentIndex]->polyline()->points.vec_[1] ) -
xf( translateLines_[currentIndex]->polyline()->points.vec_[0] );
xf( translateLines_[currentIndex]->polyline()->points.vec_[0] );
translateTooltipCallback_( dot( prevTranslation_ - startTranslation_, axis.normalized() ) );
}
else if ( axisTransformMode_ == Scaling && scaleTooltipCallback_ )
{
break;
case ScalingMode:
case UniformScalingMode:
if ( scaleTooltipCallback_ )
scaleTooltipCallback_( sumScale_ );
}
}
else // rotation
{
break;
case RotationMode:
if ( rotateTooltipCallback_ )
rotateTooltipCallback_( accumAngle_ );
break;
}
}

Expand Down Expand Up @@ -559,17 +559,42 @@ void ObjectTransformWidget::activeMove_( bool press )

int currentObjIndex = findCurrentObjIndex_();

// we now know who is picked
if ( currentObjIndex < 3 )
if ( press )
{
if ( axisTransformMode_ == AxisTransformMode::Scaling )
processScaling_( Axis( currentObjIndex ), press );
// we now know who is picked
if ( currentObjIndex < 3 )
{
switch ( axisTransformMode_ )
{
case AxisTranslation:
activeEditMode_ = TranslationMode;
break;
case AxisScaling:
activeEditMode_ = ScalingMode;
break;
case UniformScaling:
activeEditMode_ = UniformScalingMode;
break;
}
}
else
processTranslation_( Axis( currentObjIndex ), press );
{
activeEditMode_ = RotationMode;
}
}
else

switch ( activeEditMode_ )
{
case TranslationMode:
processTranslation_( Axis( currentObjIndex ), press );
break;
case ScalingMode:
case UniformScalingMode:
processScaling_( Axis( currentObjIndex ), press );
break;
case RotationMode:
processRotation_( Axis( currentObjIndex - 3 ), press );
break;
}
}

Expand All @@ -581,11 +606,6 @@ void ObjectTransformWidget::processScaling_( ObjectTransformWidget::Axis ax, boo
auto line = viewport.unprojectPixelRay( Vector2f( viewportPoint.x, viewportPoint.y ) );
auto xf = controlsRoot_->xf();
auto newScaling = findClosestPointOfSkewLines(
translateLines_[int( ax )]->polyline()->points.vec_[0],
translateLines_[int( ax )]->polyline()->points.vec_[1],
line.p, line.p + line.d
);
auto newTranslation = findClosestPointOfSkewLines(
xf( translateLines_[int( ax )]->polyline()->points.vec_[0] ),
xf( translateLines_[int( ax )]->polyline()->points.vec_[1] ),
line.p, line.p + line.d
Expand All @@ -594,19 +614,19 @@ void ObjectTransformWidget::processScaling_( ObjectTransformWidget::Axis ax, boo
if ( press )
{
prevScaling_ = newScaling;
prevTranslation_ = newTranslation;
sumScale_ = 1.f;
}

auto scale = ( newScaling - prevScaling_ );
auto direction = dot( prevTranslation_ - xf( center_ ), newTranslation - prevTranslation_ ) >= 0.f ? 1.f : -1.f;
for ( auto i = 0; i < Vector3f::elements; i++ )
scale[i] = 1.f + std::abs( scale[i] ) * direction;
auto scaleFactor = ( newScaling - xf( center_ ) ).length() / ( prevScaling_ - xf( center_ ) ).length();
auto scale = Vector3f::diagonal( 1.f );
if ( activeEditMode_ == UniformScalingMode )
scale *= scaleFactor;
else
scale[int( ax )] = scaleFactor;
auto addXf = xf * AffineXf3f::xfAround( Matrix3f::scale( scale ), center_ ) * xf.inverse();
addXf_( addXf );
prevScaling_ = newScaling;
prevTranslation_ = newTranslation;
sumScale_ *= scale.x * scale.y * scale.z;
sumScale_ *= scaleFactor;
}

void ObjectTransformWidget::processTranslation_( Axis ax, bool press )
Expand Down Expand Up @@ -757,7 +777,7 @@ void ObjectTransformWidget::addXf_( const AffineXf3f& addXf )
approvedChange_ = true;
if ( addXfCallback_ )
addXfCallback_( addXf );
if ( findCurrentObjIndex_() >= 3 || axisTransformMode_ == Translation )
if ( activeEditMode_ == TranslationMode || activeEditMode_ == RotationMode )
controlsRoot_->setXf( addXf * controlsRoot_->xf() );
approvedChange_ = false;
}
Expand Down
19 changes: 15 additions & 4 deletions source/MRViewer/MRObjectTransformWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,15 @@ class MRVIEWER_CLASS ObjectTransformWidget : public MultiListener<MouseDownListe
void setPickThrough( bool on ) { pickThrough_ = on; }
bool getPickThrough() const { return pickThrough_; }

// Transform operation applying to object while dragging an axis
// Transform operation applying to object while dragging an axis. This parameter does not apply to active operation.
enum AxisTransformMode
{
// object moves along an axis
Translation,
AxisTranslation,
// object inflates or deflates along an axis depending on drag direction (away from center or toward center respectively)
Scaling,
AxisScaling,
Comment on lines 59 to +62
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we have three options here instead of uniformScaling_ flag?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented.

// object inflates or deflates along all axes depending on drag direction (away from center or toward center respectively)
UniformScaling,
};
// Returns current axis transform mode (translate/scale object while dragging an axis)
AxisTransformMode getAxisTransformMode() const { return axisTransformMode_; };
Expand Down Expand Up @@ -139,7 +141,16 @@ class MRVIEWER_CLASS ObjectTransformWidget : public MultiListener<MouseDownListe

Vector3f center_;

AxisTransformMode axisTransformMode_{ Translation };
AxisTransformMode axisTransformMode_{ AxisTranslation };

enum ActiveEditMode
{
TranslationMode,
ScalingMode,
UniformScalingMode,
RotationMode,
};
ActiveEditMode activeEditMode_{ TranslationMode };

float sumScale_ = 1;
Vector3f prevScaling_;
Expand Down