Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
lpe-attach-path.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) Theodore Janeczko 2012 <flutterguy317@gmail.com>
4 *
5 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
6 */
7
8#include "lpe-attach-path.h"
9
10#include <cmath>
11
12#include <2geom/path-sink.h>
13
14#include "object/sp-lpe-item.h"
15
16// TODO due to internal breakage in glibmm headers, this must be last:
17#include <glibmm/i18n.h>
18
19namespace Inkscape {
20namespace LivePathEffect {
21
23 Effect(lpeobject),
24 start_path(_("Start path:"), _("Path to attach to the start of this path"), "startpath", &wr, this),
25 start_path_position(_("Start path position:"), _("Position to attach path start to"), "startposition", &wr, this, 0.0),
26 start_path_curve_start(_("Start path curve start:"), _("Starting curve"), "startcurvestart", &wr, this, Geom::Point(20,0)/*, true*/),
27 start_path_curve_end(_("Start path curve end:"), _("Ending curve"), "startcurveend", &wr, this, Geom::Point(20,0)/*, true*/),
28 end_path(_("End path:"), _("Path to attach to the end of this path"), "endpath", &wr, this),
29 end_path_position(_("End path position:"), _("Position to attach path end to"), "endposition", &wr, this, 0.0),
30 end_path_curve_start(_("End path curve start:"), _("Starting curve"), "endcurvestart", &wr, this, Geom::Point(20,0)/*, true*/),
31 end_path_curve_end(_("End path curve end:"), _("Ending curve"), "endcurveend", &wr, this, Geom::Point(20,0)/*, true*/)
32{
37
42
43 //perceived_path = true;
44 show_orig_path = true;
49}
50
52
59
60void
62{
63 if (is_load) {
67 end_path.setUpdating(false);
70 if (auto item = end_path.getObject()) {
71 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
72 }
73 if (auto item = start_path.getObject()) {
74 item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
75 }
76 }
77}
78
79
80bool
94
96{
97 if (sp_lpe_item && !curve.empty()) {
98 auto p = Geom::Path(curve.initialPoint());
99
102
104
107
108 if ( !linked_pathv.empty() )
109 {
110 Geom::Path transformedpath = linked_pathv.front() * linkedtransform;
111 start_path_curve_start.setOrigin(curve.initialPoint());
112
113 std::vector<Geom::Point> derivs = curve.front().front().pointAndDerivatives(0, 3);
114
115 for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) {
116 Geom::Coord length = derivs[deriv_n].length();
118 if (set_start_end) {
120 }
121 if (start_path_position > transformedpath.size()) {
122 start_path_position.param_set_value(transformedpath.size());
123 } else if (start_path_position < 0) {
125 }
126 Geom::Curve const *c = start_path_position >= transformedpath.size() ?
127 &transformedpath.back() : &transformedpath.at((int)start_path_position);
128
129 std::vector<Geom::Point> derivs_2 = c->pointAndDerivatives(start_path_position >= transformedpath.size() ? 1 : (start_path_position - (int)start_path_position), 3);
130 for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) {
131 Geom::Coord length_2 = derivs[deriv_n_2].length();
132 if ( ! Geom::are_near(length_2, 0) ) {
133 start_path_curve_end.setOrigin(derivs_2[0]);
135
138 double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x());
139 double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x());
140 Geom::Point pt1 = Geom::Point(start_path_curve_start.getVector().length() * cos(startangle + startderiv), start_path_curve_start.getVector().length() * sin(startangle + startderiv));
141 Geom::Point pt2 = Geom::Point(start_path_curve_end.getVector().length() * cos(endangle + endderiv), start_path_curve_end.getVector().length() * sin(endangle + endderiv));
142 p = Geom::Path(derivs_2[0]);
143 p.appendNew<Geom::CubicBezier>(-pt2 + derivs_2[0], -pt1 + curve.initialPoint(), curve.initialPoint());
144 break;
145
146 }
147 }
148 break;
149 }
150 }
151 }
152 }
153
154 p.append(curve.front());
155
157
160
161 if ( !linked_pathv.empty() )
162 {
163 Geom::Path transformedpath = linked_pathv.front() * linkedtransform;
164 Geom::Curve *last_seg_reverse = curve.front().back().reverse();
165
166 end_path_curve_start.setOrigin(last_seg_reverse->initialPoint());
167
168 std::vector<Geom::Point> derivs = last_seg_reverse->pointAndDerivatives(0, 3);
169 for (unsigned deriv_n = 1; deriv_n < derivs.size(); deriv_n++) {
170 Geom::Coord length = derivs[deriv_n].length();
172 if (set_end_end) {
174 }
175
176 if (end_path_position > transformedpath.size()) {
177 end_path_position.param_set_value(transformedpath.size());
178 } else if (end_path_position < 0) {
180 }
181 const Geom::Curve *c = end_path_position >= transformedpath.size() ?
182 &transformedpath.back() : &transformedpath.at((int)end_path_position);
183
184 std::vector<Geom::Point> derivs_2 = c->pointAndDerivatives(end_path_position >= transformedpath.size() ? 1 : (end_path_position - (int)end_path_position), 3);
185 for (unsigned deriv_n_2 = 1; deriv_n_2 < derivs_2.size(); deriv_n_2++) {
186 Geom::Coord length_2 = derivs[deriv_n_2].length();
187 if ( ! Geom::are_near(length_2, 0) ) {
188
189 end_path_curve_end.setOrigin(derivs_2[0]);
191
194 double startderiv = atan2(derivs[deriv_n].y(), derivs[deriv_n].x());
195 double endderiv = atan2(derivs_2[deriv_n_2].y(), derivs_2[deriv_n_2].x());
196 Geom::Point pt1 = Geom::Point(end_path_curve_start.getVector().length() * cos(startangle + startderiv), end_path_curve_start.getVector().length() * sin(startangle + startderiv));
197 Geom::Point pt2 = Geom::Point(end_path_curve_end.getVector().length() * cos(endangle + endderiv), end_path_curve_end.getVector().length() * sin(endangle + endderiv));
198 p.appendNew<Geom::CubicBezier>(-pt1 + curve.front().finalPoint(), -pt2 + derivs_2[0], derivs_2[0]);
199
200 break;
201
202 }
203 }
204 break;
205 }
206 }
207 delete last_seg_reverse;
208 }
209 }
210 curve = std::move(p);
211 }
212}
213
214} // namespace LivePathEffect
215} /* namespace Inkscape */
216
217/*
218 Local Variables:
219 mode:c++
220 c-file-style:"stroustrup"
221 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
222 indent-tabs-mode:nil
223 fill-column:99
224 End:
225*/
226// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
3x3 matrix representing an affine transformation.
Definition affine.h:70
Bezier curve with compile-time specified order.
Abstract continuous curve on a plane defined on [0,1].
Definition curve.h:78
virtual Point initialPoint() const =0
Retrieve the start of the curve.
virtual std::vector< Point > pointAndDerivatives(Coord t, unsigned n) const =0
Evaluate the curve and its derivatives.
Sequence of subpaths.
Definition pathvector.h:122
bool empty() const
Check whether the vector contains any paths.
Definition pathvector.h:145
Sequence of contiguous curves, aka spline.
Definition path.h:353
Curve const & back() const
Access the last curve in the path.
Definition path.h:447
PathTime nearestTime(Point const &p, Coord *dist=NULL) const
Definition path.cpp:733
size_type size() const
Natural size of the path.
Definition path.h:490
Curve const & at(size_type i) const
Access a curve by index.
Definition path.h:438
Two-dimensional point that doubles as a vector.
Definition point.h:66
Coord length() const
Compute the distance from origin.
Definition point.h:118
constexpr Coord y() const noexcept
Definition point.h:106
constexpr Coord x() const noexcept
Definition point.h:104
void registerParameter(Parameter *param)
Definition effect.cpp:1704
virtual void resetDefaults(SPItem const *item)
Sets all parameters to their default values and writes them to SVG.
Definition effect.cpp:2008
bool doOnOpen(SPLPEItem const *lpeitem) override
Is performed on load document or revert If the item is fixed legacy return true.
void resetDefaults(SPItem const *item) override
Sets all parameters to their default values and writes them to SVG.
LPEAttachPath(LivePathEffectObject *lpeobject)
void doBeforeEffect(SPLPEItem const *lpeitem) override
Is performed each time before the effect is updated.
void doEffect(Geom::PathVector &curve) override
void setUpdating(bool updating)
Definition parameter.h:73
Geom::PathVector const & get_pathvector() const
Definition path.cpp:99
void start_listening(SPObject *to)
Definition path.cpp:409
void setOrigin(Geom::Point const &new_origin)
Geom::Point getVector() const
Definition vector.h:41
void setOrigin(Geom::Point const &new_origin)
Definition vector.h:45
Geom::Point getOrigin() const
Definition vector.h:42
Base class for visual SVG elements.
Definition sp-item.h:109
Geom::Affine getRelativeTransform(SPObject const *obj) const
Definition sp-item.cpp:1820
SPObject * _tmpsuccessor
Definition sp-object.h:731
void requestDisplayUpdate(unsigned int flags)
Queues an deferred update of this object's display.
double c[8][4]
double Coord
Floating point type used to store coordinates.
Definition coord.h:76
SPItem * item
Various utility functions.
Definition affine.h:22
SBasisN< n > cos(LinearN< n > bo, int k)
Coord length(LineSegment const &seg)
double atan2(Point const &p)
SBasisN< n > sin(LinearN< n > bo, int k)
bool are_near(Affine const &a1, Affine const &a2, Coord eps=EPSILON)
Helper class to stream background task notifications as a series of messages.
callback interface for SVG path data
Base class for live path effect items.
Coord asFlatTime() const
Definition path.h:173
Definition curve.h:24
unsigned length
Definition curve.h:26