diff options
| author | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-04-12 04:52:48 +0000 |
|---|---|---|
| committer | Liam P. White <inkscapebronyat-signgmaildotcom> | 2014-04-12 04:52:48 +0000 |
| commit | a354238633c206078acc11a60d02382cee572740 (patch) | |
| tree | 95ff6c23022d538d5f138bf26f5d98e60b5ec031 /src | |
| parent | Updaet to trunk (diff) | |
| download | inkscape-a354238633c206078acc11a60d02382cee572740.tar.gz inkscape-a354238633c206078acc11a60d02382cee572740.zip | |
Wonderful code optimizations
(bzr r13090.1.50)
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-taperstroke.cpp | 153 | ||||
| -rw-r--r-- | src/live_effects/pathoutlineprovider.cpp | 79 | ||||
| -rw-r--r-- | src/live_effects/pathoutlineprovider.h | 6 |
3 files changed, 46 insertions, 192 deletions
diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index 901abff70..ce07ed962 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -180,77 +180,15 @@ void LPETaperStroke::doOnRemove(SPLPEItem const* lpeitem) //actual effect impl here -Geom::Path return_at_first_cusp (Geom::Path const & path_in, double smooth_tolerance = 0.05) +Geom::Path return_at_first_cusp (Geom::Path const & path_in, double /*smooth_tolerance*/ = 0.05) { - Geom::Path path_out = Geom::Path(); - - for (unsigned i = 0; i < path_in.size(); i++) { - path_out.append(path_in[i]); - if (path_in.size() == 1) - break; - - //determine order of curve - int order = Outline::bezierOrder(&path_in[i]); - - Geom::Point start_point; - Geom::Point cross_point = path_in[i].finalPoint(); - Geom::Point end_point; - - g_assert(path_in[i].finalPoint() == path_in[i+1].initialPoint()); - - //can you tell that the following expressions have been shaped by - //repeated compiler errors? ;) - switch (order) { - case 3: - start_point = (static_cast<const Geom::CubicBezier*>(&path_in[i]))->operator[] (2); - //major league b***f***ing - if (are_near(start_point, cross_point, 0.0000001)) { - start_point = (static_cast<const Geom::CubicBezier*>(&path_in[i]))->operator[] (1); - } - break; - case 2: - //this never happens - start_point = (static_cast<const Geom::QuadraticBezier*>(&path_in[i]))->operator[] (1); - break; - case 1: - default: - start_point = path_in[i].initialPoint(); - } - - order = Outline::bezierOrder(&path_in[i+1]); - - switch (order) { - case 3: - end_point = (static_cast<const Geom::CubicBezier*>(&path_in[i+1]))->operator[] (1); - if (are_near(end_point, cross_point, 0.0000001)) { - end_point = (static_cast<const Geom::CubicBezier*>(&path_in[i+1]))->operator[] (2); - } - break; - case 2: - end_point = (static_cast<const Geom::QuadraticBezier*>(&path_in[i+1]))->operator[] (1); - break; - case 1: - default: - end_point = path_in[i+1].finalPoint(); - } - - //clearly it's collinear if two occupy the same point - if (are_near(start_point, cross_point, 0.0000001) || - are_near(cross_point, end_point, 0.0000001) || - are_near(start_point, end_point, 0.0000001) ) { - g_critical("Holy crap, something went wrong! %s:%d\n", __FILE__, __LINE__); - } - - if (!are_collinear(start_point, cross_point, end_point, smooth_tolerance)) - break; - } - return path_out; + return Geom::split_at_cusps(path_in)[0]; } Geom::Piecewise<Geom::D2<Geom::SBasis> > stretch_along(Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in, Geom::Path pattern, double width); //references to pointers, because magic -void subdivideCurve(const Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); +void subdivideCurve(Geom::Curve * curve_in, Geom::Coord t, Geom::Curve *& val_first, Geom::Curve *& val_second); Geom::PathVector LPETaperStroke::doEffect_path(Geom::PathVector const& path_in) { @@ -378,34 +316,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa trimmed_start.append(path_in[0] [i]); } - - //this is pretty annoying - //previously I wrote a function for this but it wasted a lot of time - //so I optimized it back into here. - unsigned order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_start); - std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide((attach_start - loc)); - trimmed_start.append(cb_pair.first); - curve_start = cb_pair.second.duplicate(); //goes out of scope - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_start); - std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide((attach_start - loc)); - trimmed_start.append(qb_pair.first); - curve_start = qb_pair.second.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_start); - std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide((attach_start - loc)); - trimmed_start.append(lb_pair.first); - curve_start = lb_pair.second.duplicate(); - break; - } - } + Geom::Curve * temp; + subdivideCurve(curve_start, attach_start - loc, temp, curve_start); + trimmed_start.append(*temp); //special case: path is one segment long //special case: what if the two knots occupy the same segment? @@ -416,31 +329,9 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa //we have to do some shifting here because the value changed when we reduced the length //of the previous segment. - order = Outline::bezierOrder(curve_start); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_start); - std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); - curve_start = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_start); - std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); - curve_start = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_start); - std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); - curve_start = lb_pair.first.duplicate(); - break; - } - } - + subdivideCurve(curve_start, t, curve_start, temp); + trimmed_end.append(*temp); + for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); } @@ -468,30 +359,8 @@ Geom::PathVector LPETaperStroke::doEffect_simplePath(Geom::PathVector const & pa Geom::Coord t = Geom::nearest_point(end_attach_point, *curve_end); - order = Outline::bezierOrder(curve_end); - switch (order) { - case 3: { - Geom::CubicBezier *cb = static_cast<Geom::CubicBezier * >(curve_end); - std::pair<Geom::CubicBezier, Geom::CubicBezier> cb_pair = cb->subdivide(t); - trimmed_end.append(cb_pair.second); - curve_end = cb_pair.first.duplicate(); - break; - } - case 2: { - Geom::QuadraticBezier *qb = static_cast<Geom::QuadraticBezier * >(curve_end); - std::pair<Geom::QuadraticBezier, Geom::QuadraticBezier> qb_pair = qb->subdivide(t); - trimmed_end.append(qb_pair.second); - curve_end = qb_pair.first.duplicate(); - break; - } - case 1: { - Geom::BezierCurveN<1> *lb = static_cast<Geom::BezierCurveN<1> * >(curve_end); - std::pair<Geom::BezierCurveN<1>, Geom::BezierCurveN<1> > lb_pair = lb->subdivide(t); - trimmed_end.append(lb_pair.second); - curve_end = lb_pair.first.duplicate(); - break; - } - } + subdivideCurve(curve_end, t, curve_end, temp); + trimmed_end.append(*temp); for (unsigned j = (size - attach_end) + 1; j < size; j++) { trimmed_end.append(path_in[0] [j]); diff --git a/src/live_effects/pathoutlineprovider.cpp b/src/live_effects/pathoutlineprovider.cpp index a696728d6..5a95da75d 100644 --- a/src/live_effects/pathoutlineprovider.cpp +++ b/src/live_effects/pathoutlineprovider.cpp @@ -9,6 +9,7 @@ #include <2geom/shape.h>
#include <2geom/transforms.h>
#include <2geom/path-sink.h>
+#include "helper/geom-nodetype.h"
#include <svg/svg.h>
namespace Geom {
@@ -99,21 +100,25 @@ static Circle touching_circle( D2<SBasis> const &curve, double t, double tol=0.0 return Geom::Circle(center, fabs(radius));
}
-static std::vector<Geom::Path> split_at_cusps(const Geom::Path& in)
+std::vector<Geom::Path> split_at_cusps(const Geom::Path& in)
{
- Geom::PathVector out = Geom::PathVector();
- Geom::Path temp = Geom::Path();
-
- for (unsigned path_descr = 0; path_descr < in.size(); path_descr++) {
- temp = Geom::Path();
- temp.append(in[path_descr]);
+ PathVector out = PathVector();
+ Path temp = Path();
+
+ for (unsigned i = 0; i < in.size(); i++) {
+ temp.append(in[i]);
+ if ( get_nodetype(in[i], in[i + 1]) != Geom::NODE_SMOOTH ) {
+ out.push_back(temp);
+ temp = Path();
+ }
+ }
+ if (temp.size() > 0) {
out.push_back(temp);
}
-
return out;
}
-static Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in)
+Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in)
{
std::vector<Geom::Point> temp;
sbasis_to_bezier(temp, sbasis_in, 4);
@@ -140,13 +145,9 @@ typedef Geom::Piecewise<D2SB> PWD2; unsigned bezierOrder (const Geom::Curve* curve_in)
{
using namespace Geom;
- //cast it
- const CubicBezier *cbc = dynamic_cast<const CubicBezier*>(curve_in);
- if (cbc) return 3;
- const QuadraticBezier * qbc = dynamic_cast<const QuadraticBezier*>(curve_in);
- if (qbc) return 2;
- const BezierCurveN<1U> * lbc = dynamic_cast<const BezierCurveN<1U> *>(curve_in);
- if (lbc) return 1;
+ if ( const BezierCurve* bz = dynamic_cast<const BezierCurve*>(curve_in) ) {
+ return bz->order();
+ }
return 0;
}
@@ -154,8 +155,6 @@ unsigned bezierOrder (const Geom::Curve* curve_in) //is >180 clockwise, otherwise false.
bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2)
{
- unsigned order = bezierOrder(&cbc1);
-
Geom::Point start_point;
Geom::Point cross_point = cbc1.finalPoint();
Geom::Point end_point;
@@ -167,38 +166,18 @@ bool outside_angle (const Geom::Curve& cbc1, const Geom::Curve& cbc2) "By default we are going to say that this is an inside join, so we cannot make a line join for it.\n", __LINE__, __FILE__);
return false;
}
- switch (order) {
- case 3:
- start_point = (static_cast<const Geom::CubicBezier*>(&cbc1))->operator[] (2);
- //major league b***f***ing
- if (are_near(start_point, cross_point, 0.0000001)) {
- start_point = (static_cast<const Geom::CubicBezier*>(&cbc1))->operator[] (1);
- }
- break;
- case 2:
- //this never happens
- start_point = (static_cast<const Geom::QuadraticBezier*>(&cbc1))->operator[] (1);
- break;
- case 1:
- default:
- start_point = cbc1.initialPoint();
+
+ //let's try:
+ Geom::CubicBezier cubicBezier = Geom::sbasis_to_cubicbezier(cbc1.toSBasis());
+ start_point = cubicBezier [2];
+ //stupid thing Inkscape does:
+ if (are_near(start_point, cross_point, 0.0000001)) {
+ start_point = cubicBezier [1];
}
-
- order = Outline::bezierOrder(&cbc2);
-
- switch (order) {
- case 3:
- end_point = (static_cast<const Geom::CubicBezier*>(&cbc2))->operator[] (1);
- if (are_near(end_point, cross_point, 0.0000001)) {
- end_point = (static_cast<const Geom::CubicBezier*>(&cbc2))->operator[] (2);
- }
- break;
- case 2:
- end_point = (static_cast<const Geom::QuadraticBezier*>(&cbc2))->operator[] (1);
- break;
- case 1:
- default:
- end_point = cbc2.finalPoint();
+ cubicBezier = Geom::sbasis_to_cubicbezier(cbc2.toSBasis());
+ end_point = cubicBezier [1];
+ if (are_near(end_point, cross_point, 0.0000001)) {
+ end_point = cubicBezier [2];
}
//got our three points, now let's see what their clockwise angle is
@@ -391,7 +370,7 @@ Geom::Path doAdvHalfOutline(const Geom::Path& path_in, double line_width, double Geom::Path path_builder = Geom::Path(); //the path to store the result in
Geom::PathVector * path_vec; //needed because livarot returns a goddamn pointer
- const unsigned k = path_in.size();
+ const unsigned k = pv.size();
for (unsigned u = 0; u < k; u+=2) {
to_outline = Path();
diff --git a/src/live_effects/pathoutlineprovider.h b/src/live_effects/pathoutlineprovider.h index 27bc62d45..0ee0f261e 100644 --- a/src/live_effects/pathoutlineprovider.h +++ b/src/live_effects/pathoutlineprovider.h @@ -12,6 +12,12 @@ enum LineJoinType { LINEJOIN_EXTRAPOLATED }; +namespace Geom +{ + Geom::CubicBezier sbasis_to_cubicbezier(Geom::D2<Geom::SBasis> const & sbasis_in); + std::vector<Geom::Path> split_at_cusps(const Geom::Path& in); +} + namespace Outline { unsigned bezierOrder (const Geom::Curve* curve_in); |
