summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: e21d4ac)
raw | patch | inline | side by side (parent: e21d4ac)
author | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Fri, 8 Aug 2008 22:28:49 +0000 (22:28 +0000) | ||
committer | dvlierop2 <dvlierop2@users.sourceforge.net> | |
Fri, 8 Aug 2008 22:28:49 +0000 (22:28 +0000) |
src/attributes-test.h | patch | blob | history | |
src/attributes.cpp | patch | blob | history | |
src/attributes.h | patch | blob | history | |
src/object-snapper.cpp | patch | blob | history | |
src/snap.cpp | patch | blob | history | |
src/snap.h | patch | blob | history | |
src/snapped-curve.cpp | [new file with mode: 0644] | patch | blob |
src/snapped-curve.h | [new file with mode: 0644] | patch | blob |
src/snapper.h | patch | blob | history | |
src/sp-namedview.cpp | patch | blob | history | |
src/ui/dialog/document-properties.cpp | patch | blob | history |
diff --git a/src/attributes-test.h b/src/attributes-test.h
index c8287f76935945f8c4a7b0f52fbeae00fe252b9d..25167e75be6912b9617ffc3b91066f6f25337a53 100644 (file)
--- a/src/attributes-test.h
+++ b/src/attributes-test.h
{"inkscape:snap-guide", true},
{"inkscape:snap-center", true},
{"inkscape:snap-intersection-grid-guide", true},
- {"inkscape:snap-intersection-line-segments", true},
+ {"inkscape:snap-intersection-paths", true},
{"inkscape:pageopacity", true},
{"inkscape:pageshadow", true},
{"inkscape:transform-center-x", true},
diff --git a/src/attributes.cpp b/src/attributes.cpp
index c671446923c03fcd9bee320c99d390645a10b2ab..e64cedf36a6d5cdf0be1766439ce0b4a54466281 100644 (file)
--- a/src/attributes.cpp
+++ b/src/attributes.cpp
{SP_ATTR_INKSCAPE_SNAP_GUIDE, "inkscape:snap-guide"},
{SP_ATTR_INKSCAPE_SNAP_CENTER, "inkscape:snap-center"},
{SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE, "inkscape:snap-intersection-grid-guide"},
- {SP_ATTR_INKSCAPE_SNAP_INTERS_LINESEGM, "inkscape:snap-intersection-line-segments"},
+ {SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS, "inkscape:snap-intersection-paths"},
{SP_ATTR_INKSCAPE_OBJECT_PATHS, "inkscape:object-paths"},
{SP_ATTR_INKSCAPE_OBJECT_NODES, "inkscape:object-nodes"},
{SP_ATTR_INKSCAPE_BBOX_PATHS, "inkscape:bbox-paths"},
diff --git a/src/attributes.h b/src/attributes.h
index c1c4dcadc7ff8f2179b59f30755ad7913148aa11..82fba18a93ec2405c21b91fbd6975a1f32d9097a 100644 (file)
--- a/src/attributes.h
+++ b/src/attributes.h
SP_ATTR_INKSCAPE_SNAP_GUIDE,
SP_ATTR_INKSCAPE_SNAP_CENTER,
SP_ATTR_INKSCAPE_SNAP_INTERS_GRIDGUIDE,
- SP_ATTR_INKSCAPE_SNAP_INTERS_LINESEGM,
+ SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS,
SP_ATTR_INKSCAPE_OBJECT_PATHS,
SP_ATTR_INKSCAPE_OBJECT_NODES,
SP_ATTR_INKSCAPE_BBOX_PATHS,
diff --git a/src/object-snapper.cpp b/src/object-snapper.cpp
index 3bebc7b22586a789cdc45c60caa44cc1bd47d5b7..a3f7383db64808ffe63bacaae052480efef0fd38 100644 (file)
--- a/src/object-snapper.cpp
+++ b/src/object-snapper.cpp
/* FIXME: this seems like a hack. Perhaps Snappers should be
** in SPDesktop rather than SPNamedView?
*/
+ // TODO Diederik: shouldn't we just make all snapping code use document
+ // coordinates instead? Then we won't need a pointer to the desktop any longer
+ // At least we should define a clear boundary between those different coordinates,
+ // now this is not well defined
+
SPDesktop const *desktop = SP_ACTIVE_DESKTOP;
Geom::Point const p_doc = desktop->dt2doc(p);
for (std::vector<Geom::PathVector*>::const_iterator it_p = _paths_to_snap_to->begin(); it_p != _paths_to_snap_to->end(); it_p++) {
bool const being_edited = (node_tool_active && (*it_p) == _paths_to_snap_to->back());
-
//if true then this pathvector it_pv is currently being edited in the node tool
- SnappedPoint s;
- bool success = false;
// char * svgd = sp_svg_write_path(**it_p);
// std::cout << "Dumping the pathvector: " << svgd << std::endl;
NR::Coord const dist = Geom::distance(sp_doc, p_doc);
if (dist < getSnapperTolerance()) {
double t = MIN(*np, (*it_pv).size()); // make sure that t is within bounds;
- //Geom::Curve const & curve = (*it_pv).at_index(int(t));
- if(is_straight_curve((*it_pv).at_index(int(t)))) {
- // if we snap to a line segment, then return this line segment (leaves 1 DOF for snapping)
- sc.lines.push_back(Inkscape::SnappedLineSegment(sp_dt, dist, getSnapperTolerance(), getSnapperAlwaysSnap(), start_pt, end_pt));
- } else {
- // for curves other than line segments, we'll return just the closest snapped point
- // (this is a fully constrained snap, no degrees of freedom left)
- if (dist < s.getDistance()) {
- // If this curve has multiple segments, then we will return only
- // a single snapped point
- s = SnappedPoint(sp_dt, SNAPTARGET_PATH, dist, getSnapperTolerance(), getSnapperAlwaysSnap());
- success = true;
- }
- }
+ Geom::Curve const *curve = &((*it_pv).at_index(int(t)));
+ sc.curves.push_back(Inkscape::SnappedCurve(from_2geom(sp_dt), dist, getSnapperTolerance(), getSnapperAlwaysSnap(), curve));
}
}
}
- } // End of: for (Geom::PathVector::iterator ....)
-
- // Return a snap point for each path in our collection.
- // (unless we've already snapped to a line segment, see above)
- if (success) {
- sc.points.push_back(s);
- }
-
+ } // End of: for (Geom::PathVector::iterator ....)
}
}
diff --git a/src/snap.cpp b/src/snap.cpp
index 9c9a69a989ea08058978475c449f5dfeb7279689..7782947111374fd0d129730ee4551e8bcf7c2d25 100644 (file)
--- a/src/snap.cpp
+++ b/src/snap.cpp
#include "sp-namedview.h"
#include "snap.h"
#include "snapped-line.h"
+#include "snapped-curve.h"
#include <libnr/nr-point-fns.h>
#include <libnr/nr-scale-ops.h>
@@ -785,17 +786,17 @@ Inkscape::SnappedPoint SnapManager::findBestSnap(NR::Point const &p, SnappedCons
sp_list.push_back(closestPoint);
}
- // search for the closest snapped line segment
- Inkscape::SnappedLineSegment closestLineSegment;
- if (getClosestSLS(sc.lines, closestLineSegment)) {
- sp_list.push_back(Inkscape::SnappedPoint(closestLineSegment));
+ // search for the closest snapped curve
+ Inkscape::SnappedCurve closestCurve;
+ if (getClosestCurve(sc.curves, closestCurve)) {
+ sp_list.push_back(Inkscape::SnappedPoint(closestCurve));
}
- if (_intersectionLS) {
- // search for the closest snapped intersection of line segments
- Inkscape::SnappedPoint closestLineSegmentIntersection;
- if (getClosestIntersectionSLS(sc.lines, closestLineSegmentIntersection)) {
- sp_list.push_back(closestLineSegmentIntersection);
+ if (_intersectionCS) {
+ // search for the closest snapped intersection of curves
+ Inkscape::SnappedPoint closestCurvesIntersection;
+ if (getClosestIntersectionCS(sc.curves, p, closestCurvesIntersection)) {
+ sp_list.push_back(closestCurvesIntersection);
}
}
diff --git a/src/snap.h b/src/snap.h
index 981e91ecdfaba1e7fcf665622753633d058c5145..2ed786a633f5dfb38eab02ccd902cbfecab0c5c3 100644 (file)
--- a/src/snap.h
+++ b/src/snap.h
bool getSnapModeGuide() const;
void setSnapIntersectionGG(bool enabled) {_intersectionGG = enabled;}
- void setSnapIntersectionLS(bool enabled) {_intersectionLS = enabled;}
+ void setSnapIntersectionCS(bool enabled) {_intersectionCS = enabled;}
bool getSnapIntersectionGG() {return _intersectionGG;}
- bool getSnapIntersectionLS() {return _intersectionLS;}
+ bool getSnapIntersectionCS() {return _intersectionCS;}
void setIncludeItemCenter(bool enabled) {
_include_item_center = enabled;
bool _include_item_center; //If true, snapping nodes will also snap the item's center
bool _intersectionGG;
- bool _intersectionLS;
+ bool _intersectionCS;
bool _snap_enabled_globally; //Toggles ALL snapping
std::vector<SPItem const *> *_items_to_ignore;
diff --git a/src/snapped-curve.cpp b/src/snapped-curve.cpp
--- /dev/null
+++ b/src/snapped-curve.cpp
@@ -0,0 +1,146 @@
+/**\r
+ * \file src/snapped-curve.cpp\r
+ * \brief SnappedCurve class.\r
+ *\r
+ * Authors:\r
+ * Diederik van Lierop <mail@diedenrezi.nl>\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information.\r
+ */\r
+\r
+#include "snapped-curve.h"\r
+#include "libnr/nr-values.h"\r
+#include <2geom/crossing.h>\r
+#include <2geom/path-intersection.h>\r
+#include <libnr/nr-convert2geom.h>\r
+\r
+// These two are needed for SP_ACTIVE_DESKTOP; this is a dirty hack\r
+#include "desktop.h"\r
+#include "inkscape.h"\r
+\r
+Inkscape::SnappedCurve::SnappedCurve(NR::Point const &snapped_point, NR::Coord const &snapped_distance, NR::Coord const &snapped_tolerance, bool const &always_snap, Geom::Curve const *curve)\r
+{\r
+ _distance = snapped_distance;\r
+ _tolerance = snapped_tolerance;\r
+ _always_snap = always_snap;\r
+ _curve = curve;\r
+ _second_distance = NR_HUGE;\r
+ _second_tolerance = 0;\r
+ _second_always_snap = false;\r
+ _point = snapped_point;\r
+ _at_intersection = false;\r
+}\r
+\r
+Inkscape::SnappedCurve::SnappedCurve() \r
+{\r
+ _distance = NR_HUGE;\r
+ _tolerance = 0;\r
+ _always_snap = false;\r
+ _curve = NULL;\r
+ _second_distance = NR_HUGE;\r
+ _second_tolerance = 0;\r
+ _second_always_snap = false;\r
+ _point = NR::Point(0,0);\r
+ _at_intersection = false;\r
+}\r
+\r
+Inkscape::SnappedCurve::~SnappedCurve()\r
+{\r
+}\r
+\r
+Inkscape::SnappedPoint Inkscape::SnappedCurve::intersect(SnappedCurve const &curve, NR::Point const &p) const \r
+{\r
+ // Calculate the intersections of two curves, which are both within snapping range, and\r
+ // return only the closest intersection\r
+ // The point of intersection should be considered for snapping, but might be outside the snapping range\r
+ // PS: We need p (the location of the mouse pointer) for find out which intersection is the\r
+ // closest, as there might be multiple intersections of two curves\r
+ Geom::SimpleCrosser xr;\r
+ Geom::Crossings cs = xr.crossings(*(this->_curve), *(curve._curve));\r
+ \r
+ if (cs.size() > 0) {\r
+ // There might be multiple intersections: find the closest\r
+ Geom::Coord best_dist = NR_HUGE;\r
+ Geom::Point best_p = Geom::Point(NR_HUGE, NR_HUGE);\r
+ for (std::vector<Geom::Crossing>::const_iterator i = cs.begin(); i != cs.end(); i++) {\r
+ Geom::Point p_ix = this->_curve->pointAt((*i).ta);\r
+ Geom::Coord dist = Geom::distance(p_ix, p);\r
+ if (dist < best_dist) {\r
+ best_dist = dist;\r
+ best_p = p_ix;\r
+ }\r
+ }\r
+ \r
+ // Now we've found the closests intersection, return it as a SnappedPoint\r
+ bool const use_this_as_primary = _distance < curve.getDistance();\r
+ Inkscape::SnappedCurve const *primaryC = use_this_as_primary ? this : &curve;\r
+ Inkscape::SnappedCurve const *secondaryC = use_this_as_primary ? &curve : this;\r
+ // The intersection should in fact be returned in desktop coordinates, but for this\r
+ // we need a desktop: this is a dirty hack\r
+ SPDesktop const *desktop = SP_ACTIVE_DESKTOP;\r
+ best_p = desktop->dt2doc(best_p);\r
+ // TODO: Investigate whether it is possible to use document coordinates everywhere\r
+ // in the snapper code. Only the mouse position should be in desktop coordinates, I guess.\r
+ // All paths are already in document coords and we are certainly not going to change THAT.\r
+ return SnappedPoint(from_2geom(best_p), Inkscape::SNAPTARGET_PATH_INTERSECTION, primaryC->getDistance(), primaryC->getTolerance(), primaryC->getAlwaysSnap(), true, \r
+ secondaryC->getDistance(), secondaryC->getTolerance(), secondaryC->getAlwaysSnap());\r
+ }\r
+ \r
+ // No intersection\r
+ return SnappedPoint(NR::Point(NR_HUGE, NR_HUGE), SNAPTARGET_UNDEFINED, NR_HUGE, 0, false, false, NR_HUGE, 0, false);\r
+}\r
+\r
+// search for the closest snapped line\r
+bool getClosestCurve(std::list<Inkscape::SnappedCurve> const &list, Inkscape::SnappedCurve &result) \r
+{\r
+ bool success = false;\r
+ \r
+ for (std::list<Inkscape::SnappedCurve>::const_iterator i = list.begin(); i != list.end(); i++) {\r
+ if ((i == list.begin()) || (*i).getDistance() < result.getDistance()) {\r
+ result = *i;\r
+ success = true;\r
+ } \r
+ }\r
+ \r
+ return success; \r
+}\r
+\r
+// search for the closest intersection of two snapped curves, which are both member of the same collection\r
+bool getClosestIntersectionCS(std::list<Inkscape::SnappedCurve> const &list, NR::Point const &p, Inkscape::SnappedPoint &result)\r
+{\r
+ bool success = false;\r
+ \r
+ for (std::list<Inkscape::SnappedCurve>::const_iterator i = list.begin(); i != list.end(); i++) {\r
+ std::list<Inkscape::SnappedCurve>::const_iterator j = i;\r
+ j++;\r
+ for (; j != list.end(); j++) {\r
+ Inkscape::SnappedPoint sp = (*i).intersect(*j, p);\r
+ if (sp.getAtIntersection()) {\r
+ // if it's the first point\r
+ bool const c1 = !success;\r
+ // or, if it's closer \r
+ bool const c2 = sp.getDistance() < result.getDistance();\r
+ // or, if it's just then look at the other distance \r
+ // (only relevant for snapped points which are at an intersection\r
+ bool const c3 = (sp.getDistance() == result.getDistance()) && (sp.getSecondDistance() < result.getSecondDistance()); \r
+ // then prefer this point over the previous one\r
+ if (c1 || c2 || c3) { \r
+ result = sp;\r
+ success = true;\r
+ }\r
+ } \r
+ }\r
+ }\r
+ \r
+ return success; \r
+}\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
diff --git a/src/snapped-curve.h b/src/snapped-curve.h
--- /dev/null
+++ b/src/snapped-curve.h
@@ -0,0 +1,55 @@
+#ifndef SEEN_SNAPPEDCURVE_H\r
+#define SEEN_SNAPPEDCURVE_H\r
+\r
+/**\r
+ * \file src/snapped-curve.h\r
+ * \brief SnappedCurve class.\r
+ *\r
+ * Authors:\r
+ * Diederik van Lierop <mail@diedenrezi.nl>\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information.\r
+ */\r
+\r
+#include <vector>\r
+#include <list>\r
+#include "libnr/nr-coord.h"\r
+#include "libnr/nr-point.h"\r
+#include <libnr/nr-point-fns.h>\r
+#include "snapped-point.h"\r
+#include <2geom/forward.h>\r
+\r
+namespace Inkscape\r
+{\r
+\r
+/// Class describing the result of an attempt to snap to a curve.\r
+class SnappedCurve : public SnappedPoint\r
+{\r
+public:\r
+ SnappedCurve();\r
+ SnappedCurve(NR::Point const &snapped_point, NR::Coord const &snapped_distance, NR::Coord const &snapped_tolerance, bool const &always_snap, Geom::Curve const *curve);\r
+ ~SnappedCurve();\r
+ Inkscape::SnappedPoint intersect(SnappedCurve const &curve, NR::Point const &p) const; //intersect with another SnappedCurve\r
+ \r
+private:\r
+ Geom::Curve const *_curve;\r
+};\r
+\r
+}\r
+\r
+bool getClosestCurve(std::list<Inkscape::SnappedCurve> const &list, Inkscape::SnappedCurve &result);\r
+bool getClosestIntersectionCS(std::list<Inkscape::SnappedCurve> const &list, NR::Point const &p, Inkscape::SnappedPoint &result);\r
+\r
+\r
+#endif /* !SEEN_SNAPPEDCURVE_H */\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
diff --git a/src/snapper.h b/src/snapper.h
index cf2732b2426c2f58c8246c35c58e5b4f61f937d7..a63ea14c5950dafacb6ffbf4b59af1c51e233b27 100644 (file)
--- a/src/snapper.h
+++ b/src/snapper.h
#include "snapped-point.h"
#include "snapped-line.h"
+#include "snapped-curve.h"
struct SnappedConstraints {
std::list<Inkscape::SnappedPoint> points;
std::list<Inkscape::SnappedLineSegment> lines;
std::list<Inkscape::SnappedLine> grid_lines;
std::list<Inkscape::SnappedLine> guide_lines;
+ std::list<Inkscape::SnappedCurve> curves;
};
struct SPNamedView;
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index 7caa9407cfef05de719503749dd831bae9ebb9eb..7783c334d04e87814657f5fe85c6a74afb40a6c1 100644 (file)
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -252,7 +252,7 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
sp_object_read_attr(object, "inkscape:snap-guide");
sp_object_read_attr(object, "inkscape:snap-center");
sp_object_read_attr(object, "inkscape:snap-intersection-grid-guide");
- sp_object_read_attr(object, "inkscape:snap-intersection-line-segments");
+ sp_object_read_attr(object, "inkscape:snap-intersection-paths");
sp_object_read_attr(object, "inkscape:object-paths");
sp_object_read_attr(object, "inkscape:object-nodes");
sp_object_read_attr(object, "inkscape:bbox-paths");
@@ -481,8 +481,8 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
nv->snap_manager.setSnapIntersectionGG(value ? sp_str_to_bool(value) : TRUE);
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
- case SP_ATTR_INKSCAPE_SNAP_INTERS_LINESEGM:
- nv->snap_manager.setSnapIntersectionLS(value ? sp_str_to_bool(value) : FALSE);
+ case SP_ATTR_INKSCAPE_SNAP_INTERS_PATHS:
+ nv->snap_manager.setSnapIntersectionCS(value ? sp_str_to_bool(value) : FALSE);
object->requestModified(SP_OBJECT_MODIFIED_FLAG);
break;
case SP_ATTR_INKSCAPE_OBJECT_PATHS:
index 519f795db1527929601125d5eaded7ff16fb5e2f..a69e8858f8c0b70fca8b1845f2b6e3096ffc111e 100644 (file)
//Applies to both nodes and guides, but not to bboxes, that's why its located here
_rcbic( _("Rotation _center"), _("Consider the rotation center of an object when snapping"), "inkscape:snap-center", _wr),
_rcbsigg(_("_Grid with guides"), _("Snap to grid-guide intersections"), "inkscape:snap-intersection-grid-guide", _wr),
- _rcbsils(_("_Line segments"), _("Snap to intersections of line segments ('snap to paths' must be enabled, see the previous tab)"),
- "inkscape:snap-intersection-line-segments", _wr),
+ _rcbsils(_("_Paths"), _("Snap to intersections of paths ('snap to paths' must be enabled, see the previous tab)"),
+ "inkscape:snap-intersection-paths", _wr),
//---------------------------------------------------------------
_grids_label_crea("", Gtk::ALIGN_LEFT),
//TRANSLATORS: In Grid|_New translate only the word _New. It ref to grid
_rcbsng.setActive (nv->snap_manager.getSnapModeGuide());
_rcbic.setActive (nv->snap_manager.getIncludeItemCenter());
_rcbsigg.setActive (nv->snap_manager.getSnapIntersectionGG());
- _rcbsils.setActive (nv->snap_manager.getSnapIntersectionLS());
+ _rcbsils.setActive (nv->snap_manager.getSnapIntersectionCS());
_rcbsnop.setActive(nv->snap_manager.object.getSnapToItemPath());
_rcbsnon.setActive(nv->snap_manager.object.getSnapToItemNode());
_rcbsnbbp.setActive(nv->snap_manager.object.getSnapToBBoxPath());