From 5cd23a678891adcf1fa75c2bb2abaa74b8a01b13 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Krzysztof=20Kosi=C5=84ski?= Date: Wed, 3 Mar 2010 01:10:54 +0100 Subject: [PATCH] Node tool: implement sculpting --- src/ui/tool/control-point-selection.cpp | 41 ++++++++++++++++++------ src/ui/tool/control-point-selection.h | 8 +++-- src/ui/tool/selectable-control-point.cpp | 4 +-- 3 files changed, 39 insertions(+), 14 deletions(-) diff --git a/src/ui/tool/control-point-selection.cpp b/src/ui/tool/control-point-selection.cpp index df27c2a72..f880d2ddf 100644 --- a/src/ui/tool/control-point-selection.cpp +++ b/src/ui/tool/control-point-selection.cpp @@ -266,28 +266,51 @@ void ControlPointSelection::toggleTransformHandlesMode() } } -void ControlPointSelection::_pointGrabbed() +void ControlPointSelection::_pointGrabbed(SelectableControlPoint *point) { hideTransformHandles(); _dragging = true; + _grabbed_point = point; + _farthest_point = point; + double maxdist = 0; + for (iterator i = _points.begin(); i != _points.end(); ++i) { + _original_positions.insert(std::make_pair(*i, (*i)->position())); + double dist = Geom::distance(*_grabbed_point, **i); + if (dist > maxdist) { + maxdist = dist; + _farthest_point = *i; + } + } } -void ControlPointSelection::_pointDragged(Geom::Point const &old_pos, Geom::Point &new_pos, - GdkEventMotion */*event*/) +void ControlPointSelection::_pointDragged(Geom::Point &new_pos, GdkEventMotion *event) { - Geom::Point delta = new_pos - old_pos; - for (iterator i = _points.begin(); i != _points.end(); ++i) { - SelectableControlPoint *cur = (*i); - cur->move(cur->position() + delta); + Geom::Point abs_delta = new_pos - _original_positions[_grabbed_point]; + double fdist = Geom::distance(_original_positions[_grabbed_point], _original_positions[_farthest_point]); + if (held_alt(*event) && fdist > 0) { + // sculpting + for (iterator i = _points.begin(); i != _points.end(); ++i) { + SelectableControlPoint *cur = (*i); + double dist = Geom::distance(_original_positions[cur], _original_positions[_grabbed_point]); + double deltafrac = 0.5 + 0.5 * cos(M_PI * dist/fdist); + cur->move(_original_positions[cur] + abs_delta * deltafrac); + } + } else { + Geom::Point delta = new_pos - _grabbed_point->position(); + for (iterator i = _points.begin(); i != _points.end(); ++i) { + SelectableControlPoint *cur = (*i); + cur->move(_original_positions[cur] + abs_delta); + } + _handles->rotationCenter().move(_handles->rotationCenter().position() + delta); } - _handles->rotationCenter().move(_handles->rotationCenter().position() + delta); signal_update.emit(); } void ControlPointSelection::_pointUngrabbed() { + _original_positions.clear(); _dragging = false; - _grabbed_point = NULL; + _grabbed_point = _farthest_point = NULL; _updateBounds(); restoreTransformHandles(); signal_commit.emit(COMMIT_MOUSE_MOVE); diff --git a/src/ui/tool/control-point-selection.h b/src/ui/tool/control-point-selection.h index dde9ef218..b3c2f422b 100644 --- a/src/ui/tool/control-point-selection.h +++ b/src/ui/tool/control-point-selection.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include <2geom/forward.h> #include <2geom/point.h> @@ -110,8 +111,8 @@ private: // The functions below are invoked from SelectableControlPoint. // Previously they were connected to handlers when selecting, but this // creates problems when dragging a point that was not selected. - void _pointGrabbed(); - void _pointDragged(Geom::Point const &, Geom::Point &, GdkEventMotion *); + void _pointGrabbed(SelectableControlPoint *); + void _pointDragged(Geom::Point &, GdkEventMotion *); void _pointUngrabbed(); bool _pointClicked(SelectableControlPoint *, GdkEventButton *); void _pointChanged(SelectableControlPoint *, bool); @@ -129,11 +130,12 @@ private: set_type _points; set_type _all_points; + boost::unordered_map _original_positions; boost::optional _rot_radius; boost::optional _mouseover_rot_radius; Geom::OptRect _bounds; TransformHandleSet *_handles; - SelectableControlPoint *_grabbed_point; + SelectableControlPoint *_grabbed_point, *_farthest_point; unsigned _dragging : 1; unsigned _handles_visible : 1; unsigned _one_node_handles : 1; diff --git a/src/ui/tool/selectable-control-point.cpp b/src/ui/tool/selectable-control-point.cpp index 1835f0008..76028dd82 100644 --- a/src/ui/tool/selectable-control-point.cpp +++ b/src/ui/tool/selectable-control-point.cpp @@ -59,13 +59,13 @@ bool SelectableControlPoint::grabbed(GdkEventMotion *) if (!selected()) { _takeSelection(); } - _selection._pointGrabbed(); + _selection._pointGrabbed(this); return false; } void SelectableControlPoint::dragged(Geom::Point &new_pos, GdkEventMotion *event) { - _selection._pointDragged(position(), new_pos, event); + _selection._pointDragged(new_pos, event); } void SelectableControlPoint::ungrabbed(GdkEventButton *) -- 2.30.2