diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2014-11-15 17:34:32 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2014-11-15 17:34:32 +0000 |
| commit | 69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4 (patch) | |
| tree | dcaafc31c93eaaf606e1260d99c83b963aba4822 /src | |
| parent | ignore this commit (diff) | |
| download | inkscape-69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4.tar.gz inkscape-69ef82447f23d5ebd3abc6a5903b10bbdb1b12f4.zip | |
ignore this commit
(bzr r13682.1.10)
Diffstat (limited to 'src')
| -rw-r--r-- | src/knotholder.cpp | 6 | ||||
| -rw-r--r-- | src/live_effects/effect.cpp | 10 | ||||
| -rw-r--r-- | src/live_effects/effect.h | 2 | ||||
| -rw-r--r-- | src/live_effects/lpe-bendpath.cpp | 4 | ||||
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.cpp | 76 | ||||
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.h | 4 | ||||
| -rw-r--r-- | src/live_effects/lpe-mirror_symmetry.cpp | 230 | ||||
| -rw-r--r-- | src/live_effects/lpe-mirror_symmetry.h | 24 | ||||
| -rw-r--r-- | src/live_effects/lpegroupbbox.cpp | 12 | ||||
| -rw-r--r-- | src/live_effects/parameter/filletchamferpointarray.cpp | 32 | ||||
| -rw-r--r-- | src/selection-chemistry.cpp | 2 | ||||
| -rw-r--r-- | src/sp-item-group.cpp | 9 | ||||
| -rw-r--r-- | src/ui/clipboard.cpp | 7 | ||||
| -rw-r--r-- | src/ui/dialog/livepatheffect-editor.cpp | 35 | ||||
| -rw-r--r-- | src/ui/dialog/lpe-fillet-chamfer-properties.cpp | 15 | ||||
| -rw-r--r-- | src/ui/dialog/lpe-fillet-chamfer-properties.h | 1 |
16 files changed, 146 insertions, 323 deletions
diff --git a/src/knotholder.cpp b/src/knotholder.cpp index 28f6f5748..f46daa09e 100644 --- a/src/knotholder.cpp +++ b/src/knotholder.cpp @@ -69,12 +69,6 @@ KnotHolder::KnotHolder(SPDesktop *desktop, SPItem *item, SPKnotHolderReleasedFun } KnotHolder::~KnotHolder() { - if(SP_IS_LPE_ITEM(item)){ - Inkscape::LivePathEffect::Effect *effect = SP_LPE_ITEM(item)->getCurrentLPE(); - if(effect){ - effect->removeHandles(); - } - } sp_object_unref(item); for (std::list<KnotHolderEntity *>::iterator i = entity.begin(); i != entity.end(); ++i) diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 9997b1662..e49a15dd0 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -106,6 +106,7 @@ const Util::EnumData<EffectType> LPETypeData[] = { {EXTRUDE, N_("Extrude"), "extrude"}, {LATTICE, N_("Lattice Deformation"), "lattice"}, {LINE_SEGMENT, N_("Line Segment"), "line_segment"}, + {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, {OFFSET, N_("Offset"), "offset"}, {PARALLEL, N_("Parallel"), "parallel"}, {PATH_LENGTH, N_("Path length"), "path_length"}, @@ -152,7 +153,6 @@ const Util::EnumData<EffectType> LPETypeData[] = { {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, - {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, }; const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -613,7 +613,7 @@ Effect::registerParameter(Parameter * param) void Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { using namespace Inkscape::LivePathEffect; - knot_holder = knotholder; + // add handles provided by the effect itself addKnotHolderEntities(knotholder, desktop, item); @@ -623,12 +623,6 @@ Effect::addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { } } -void -Effect::removeHandles(){ - if(knot_holder){ - knot_holder = NULL; - } -} /** * Return a vector of PathVectors which contain all canvas indicators for this effect. * This is the function called by external code to get all canvas indicators (effect and its parameters) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 5d715c7f2..7da76b267 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -101,7 +101,6 @@ public: // (but spiro lpe still needs it!) virtual LPEPathFlashType pathFlashType() const { return DEFAULT; } void addHandles(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); - void removeHandles(); std::vector<Geom::PathVector> getCanvasIndicators(SPLPEItem const* lpeitem); inline bool providesOwnFlashPaths() const { @@ -161,7 +160,6 @@ protected: SPLPEItem * sp_lpe_item; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. Glib::ustring const * defaultUnit; // these get stored in doBeforeEffect_impl, and derived classes may do as they please with them. - KnotHolder *knot_holder; double current_zoom; std::vector<Geom::Point> selectedNodesPoints; SPCurve * sp_curve; diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 968e12518..33171b184 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -137,9 +137,7 @@ LPEBendPath::resetDefaults(SPItem const* item) Geom::Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); Geom::Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); - std::cout << start << "start\n"; - std::cout << start << "end\n"; - std::cout << boundingbox_X.min() << "boundingbox_X.min\n"; + if ( Geom::are_near(start,end) ) { end += Geom::Point(1.,0.); } diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index c89bfbd37..78e24f0b8 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -79,7 +79,7 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : radius.param_set_range(0., infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); - chamfer_steps.param_set_range(0, infinity()); + chamfer_steps.param_set_range(0, 999); chamfer_steps.param_set_increments(1, 1); chamfer_steps.param_set_digits(0); helper_size.param_set_range(0, infinity()); @@ -116,7 +116,7 @@ Gtk::Widget *LPEFilletChamfer::newWidget() } } else if (param->param_key == "chamfer_steps") { Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg)); - widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamferSubdivisions)); widg = widgRegistered; if (widg) { Gtk::HBox *scalarParameter = dynamic_cast<Gtk::HBox *>(widg); @@ -153,21 +153,26 @@ Gtk::Widget *LPEFilletChamfer::newWidget() ++it; } - - Gtk::VBox *buttonsContainer = Gtk::manage(new Gtk::VBox(true, 0)); + Gtk::HBox *filletContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); fillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); - buttonsContainer->pack_start(*fillet, true, true, 2); - Gtk::Button *inverse = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); - inverse->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); - buttonsContainer->pack_start(*inverse, true, true, 2); - + filletContainer->pack_start(*fillet, true, true, 2); + Gtk::Button *inverseFillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverseFillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseFillet)); + filletContainer->pack_start(*inverseFillet, true, true, 2); + + Gtk::HBox *chamferContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); chamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); - buttonsContainer->pack_start(*chamfer, true, true, 2); - vbox->pack_start(*buttonsContainer, true, true, 2); + chamferContainer->pack_start(*chamfer, true, true, 2); + Gtk::Button *inverseChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer")))); + inverseChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseChamfer)); + chamferContainer->pack_start(*inverseChamfer, true, true, 2); + + vbox->pack_start(*filletContainer, true, true, 2); + vbox->pack_start(*chamferContainer, true, true, 2); return vbox; } @@ -232,17 +237,31 @@ void LPEFilletChamfer::fillet() doChangeType(path_from_piecewise(pwd2, tolerance), 1); } -void LPEFilletChamfer::inverse() +void LPEFilletChamfer::inverseFillet() { Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), 2); } +void LPEFilletChamfer::chamferSubdivisions() +{ + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); + Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 5000); +} + void LPEFilletChamfer::chamfer() { - fillet_chamfer_values.set_chamfer_steps(chamfer_steps + 3); + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); - doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3000); +} + +void LPEFilletChamfer::inverseChamfer() +{ + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); + Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 4000); } void LPEFilletChamfer::refreshKnots() @@ -333,6 +352,13 @@ void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_path toggle = false; } if (toggle) { + if(type >= 5000){ + if(filletChamferData[counter][Y] >= 3000 && filletChamferData[counter][Y] < 4000){ + type = type - 2000; + } else if (filletChamferData[counter][Y] >= 4000 && filletChamferData[counter][Y] < 5000){ + type = type - 1000; + } + } result.push_back(Point(filletChamferData[counter][X], type)); } else { result.push_back(filletChamferData[counter]); @@ -552,8 +578,8 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) } else { type = std::abs(filletChamferData[counter + 1][Y]); } - if (type >= 3) { - unsigned int chamferSubs = type-2; + if (type >= 3000 && type < 4000) { + unsigned int chamferSubs = type-2999; Geom::Path path_chamfer; path_chamfer.start(path_out.finalPoint()); if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ @@ -567,6 +593,22 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) path_out.appendNew<Geom::LineSegment>(chamferStep); } path_out.appendNew<Geom::LineSegment>(endArcPoint); + } else if (type >= 4000 && type < 5000) { + unsigned int chamferSubs = type-3999; + Geom::Path path_chamfer; + path_chamfer.start(path_out.finalPoint()); + if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ + ccwToggle = ccwToggle?0:1; + path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); + }else{ + path_chamfer.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); + } + double chamfer_stepsTime = 1.0/chamferSubs; + for(unsigned int i = 1; i < chamferSubs; i++){ + Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i); + path_out.appendNew<Geom::LineSegment>(chamferStep); + } + path_out.appendNew<Geom::LineSegment>(endArcPoint); } else if (type == 2) { if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ ccwToggle = ccwToggle?0:1; @@ -574,7 +616,7 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) }else{ path_out.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); } - } else { + } else if (type == 1){ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); } else { diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h index e3589197c..0d6a1ff17 100644 --- a/src/live_effects/lpe-fillet-chamfer.h +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -56,8 +56,10 @@ public: void toggleHide(); void toggleFlexFixed(); void chamfer(); + void chamferSubdivisions(); + void inverseChamfer(); void fillet(); - void inverse(); + void inverseFillet(); void updateFillet(); void doUpdateFillet(std::vector<Geom::Path> const& original_pathv, double power); void doChangeType(std::vector<Geom::Path> const& original_pathv, int type); diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index dc9a94b1b..0bb67a4a2 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -19,48 +19,23 @@ #include <sp-path.h> #include <display/curve.h> #include <svg/path-string.h> -#include "helper/geom.h" + #include <2geom/path.h> -#include <2geom/path-intersection.h> #include <2geom/transforms.h> #include <2geom/affine.h> -#include "knot-holder-entity.h" -#include "knotholder.h" namespace Inkscape { namespace LivePathEffect { -namespace MS { - -class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { -public: - KnotHolderEntityCenterMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect) {}; - virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); - virtual Geom::Point knot_get() const; -}; - -} // namespace MS - LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : Effect(lpeobject), discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), - fusionPaths(_("Fusioned symetry"), _("Fusion right side whith symm"), "fusionPaths", &wr, this, true), - reverseFusion(_("Reverse fusion"), _("Reverse fusion"), "reverseFusion", &wr, this, false), - forceX(_("Force horizontal"), _("Force horizontal"), "forceX", &wr, this, false), - forceY(_("Force vertical"), _("Force vertical"), "forceY", &wr, this, false), - reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L1,0"), - center(_("Center of mirroring (X or Y)"), _("Center of the mirror"), "center", &wr, this, "Adjust the center of mirroring") + reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L100,100") { show_orig_path = true; registerParameter( dynamic_cast<Parameter *>(&discard_orig_path) ); - registerParameter( dynamic_cast<Parameter *>(&fusionPaths) ); - registerParameter( dynamic_cast<Parameter *>(&reverseFusion) ); - registerParameter( dynamic_cast<Parameter *>(&forceX) ); - registerParameter( dynamic_cast<Parameter *>(&forceY) ); registerParameter( dynamic_cast<Parameter *>(&reflection_line) ); - registerParameter( dynamic_cast<Parameter *>(¢er) ); - } LPEMirrorSymmetry::~LPEMirrorSymmetry() @@ -70,36 +45,7 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() void LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) { - using namespace Geom; - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - std::vector<Geom::Path> mline(reflection_line.get_pathvector()); - double dist = distance(mline[0].initialPoint(),mline[0].finalPoint()); - if( !forceX && !forceY ){ - center.param_setValue(mline[0].pointAt(0.5)); - } - Point A(0,0); - Point B(0,0); - if(forceX){ - A = Geom::Point(center[X]+(dist/2.0),center[Y]); - B = Geom::Point(center[X]-(dist/2.0),center[Y]); - } - if(forceY){ - A = Geom::Point(center[X],center[Y]+(dist/2.0)); - B = Geom::Point(center[X],center[Y]-(dist/2.0)); - } - if( forceX || forceY ){ - lineSeparation.setPoints(A,B); - Piecewise<D2<SBasis> > rline = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); - reflection_line.set_new_value(rline, true); - } else { - lineSeparation.setPoints(mline[0].initialPoint(),mline[0].finalPoint()); - } - //Geom::Point const q = lineSeparation.pointAt(0.5)* lpeitem->i2dt_affine().inverse(); - if(knot_holder){ - knot_holder->update_knots(); - } - //e->knot_set(q, e->knot->drag_origin * lpeitem->i2dt_affine().inverse(), (guint)1); item->apply_to_clippath(item); item->apply_to_mask(item); } @@ -109,22 +55,19 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { using namespace Geom; - original_bbox(lpeitem); + // fixme: what happens if the bbox is empty? + // fixme: this is probably wrong + Geom::Affine t = lpeitem->i2dt_affine(); + Geom::Rect bbox = *lpeitem->desktopVisualBounds(); - Point A(boundingbox_X.max(), boundingbox_Y.max()); - Point B(boundingbox_X.max(), boundingbox_Y.min()); + Point A(bbox.left(), bbox.bottom()); + Point B(bbox.left(), bbox.top()); + A *= t; + B *= t; Piecewise<D2<SBasis> > rline = Piecewise<D2<SBasis> >(D2<SBasis>(Linear(A[X], B[X]), Linear(A[Y], B[Y]))); reflection_line.set_new_value(rline, true); } -int -LPEMirrorSymmetry::pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X) -{ - //http://stackoverflow.com/questions/1560492/how-to-tell-whether-a-point-is-to-the-right-or-left-side-of-a-line - double pos = (B[Geom::X]-A[Geom::X])*(X[Geom::Y]-A[Geom::Y]) - (B[Geom::Y]-A[Geom::Y])*(X[Geom::X]-A[Geom::X]); - return (pos < 0) ? -1 : (pos > 0); -} - std::vector<Geom::Path> LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in) { @@ -132,20 +75,15 @@ LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in) if ( reflection_line.get_pathvector().empty() ) { return path_in; } - Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); - std::vector<Geom::Path> path_out; - Geom::Path mlineExpanded; - Geom::Point lineStart = lineSeparation.pointAt(-100000.0); - Geom::Point lineEnd = lineSeparation.pointAt(100000.0); - mlineExpanded.start( lineStart); - mlineExpanded.appendNew<Geom::LineSegment>( lineEnd); - if (!discard_orig_path && !fusionPaths) { + std::vector<Geom::Path> path_out; + if (!discard_orig_path) { path_out = path_in; } - Geom::Point A(lineStart); - Geom::Point B(lineEnd); + std::vector<Geom::Path> mline(reflection_line.get_pathvector()); + Geom::Point A(mline.front().initialPoint()); + Geom::Point B(mline.back().finalPoint()); Geom::Affine m1(1.0, 0.0, 0.0, 1.0, A[0], A[1]); double hyp = Geom::distance(A, B); @@ -159,146 +97,14 @@ LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in) m = m * sca; m = m * m2.inverse(); m = m * m1; - - if(fusionPaths && !discard_orig_path){ - for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()){ - continue; - } - std::vector<Geom::Path> temp_path; - double timeStart = 0.0; - int position = 0; - bool end_open = false; - if (path_it->closed()) { - const Geom::Curve &closingline = path_it->back_closed(); - if (!are_near(closingline.initialPoint(), closingline.finalPoint())) { - end_open = true; - } - } - Geom::Path original = (Geom::Path)(*path_it); - if(end_open && path_it->closed()){ - original.close(false); - original.appendNew<Geom::LineSegment>( original.initialPoint() ); - original.close(true); - } - Geom::Crossings cs = crossings(original, mlineExpanded); - for(unsigned int i = 0; i < cs.size(); i++) { - double timeEnd = cs[i].ta; - Geom::Path portion = original.portion(timeStart, timeEnd); - Geom::Point middle = portion.pointAt((double)portion.size()/2.0); - position = pointSideOfLine(lineStart, lineEnd, middle); - if(reverseFusion){ - position *= -1; - } - if(position == -1){ - Geom::Path mirror = portion.reverse() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - if(i!=0){ - portion.setFinal(portion.initialPoint()); - portion.close(); - } - temp_path.push_back(portion); - } - portion.clear(); - timeStart = timeEnd; - } - position = pointSideOfLine(lineStart, lineEnd, original.finalPoint()); - if(reverseFusion){ - position *= -1; - } - if(cs.size()!=0 && position == -1){ - Geom::Path portion = original.portion(timeStart, original.size()); - portion = portion.reverse(); - Geom::Path mirror = portion.reverse() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - portion = portion.reverse(); - if (!original.closed()){ - temp_path.push_back(portion); - } else { - if(cs.size() >1 ){ - portion.setFinal(temp_path[0].initialPoint()); - portion.setInitial(temp_path[0].finalPoint()); - temp_path[0].append(portion); - } else { - temp_path.push_back(portion); - } - temp_path[0].close(); - } - portion.clear(); - } - if(cs.size() == 0 && position == -1){ - temp_path.push_back(original); - temp_path.push_back(original * m); - } - path_out.insert(path_out.end(), temp_path.begin(), temp_path.end()); - temp_path.clear(); - } - } - - if (!fusionPaths || discard_orig_path) { - for (int i = 0; i < static_cast<int>(path_in.size()); ++i) { - path_out.push_back(path_in[i] * m); - } - } - return path_out; -} - -void -LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) -{ - using namespace Geom; - - PathVector pathv; - Geom::Path mlineExpanded; - Geom::Point lineStart = lineSeparation.pointAt(-100000.0); - Geom::Point lineEnd = lineSeparation.pointAt(100000.0); - mlineExpanded.start( lineStart); - mlineExpanded.appendNew<Geom::LineSegment>( lineEnd); - pathv.push_back(mlineExpanded); - hp_vec.push_back(pathv); -} - -void -LPEMirrorSymmetry::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { - { - KnotHolderEntity *e = new MS::KnotHolderEntityCenterMirrorSymmetry(this); - e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, - _("Adjust the center") ); - knotholder->add(e); + for (int i = 0; i < static_cast<int>(path_in.size()); ++i) { + path_out.push_back(path_in[i] * m); } -}; - -namespace MS { - -using namespace Geom; - -void -KnotHolderEntityCenterMirrorSymmetry::knot_set(Geom::Point const &p, Geom::Point const &origin, guint state) -{ - LPEMirrorSymmetry* lpe = dynamic_cast<LPEMirrorSymmetry *>(_effect); - - Geom::Point const s = snap_knot_position(p, state); - - lpe->center.param_setValue(s); - - // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. - sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); -} - -Geom::Point -KnotHolderEntityCenterMirrorSymmetry::knot_get() const -{ - LPEMirrorSymmetry const *lpe = dynamic_cast<LPEMirrorSymmetry const*>(_effect); - return lpe->center; + return path_out; } -} // namespace CR - } //namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 4b2c9aea0..a4a2b86c0 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -20,17 +20,10 @@ #include "live_effects/parameter/point.h" #include "live_effects/parameter/path.h" -#include "live_effects/lpegroupbbox.h" - namespace Inkscape { namespace LivePathEffect { -namespace MS { - // we need a separate namespace to avoid clashes with LPEPerpBisector - class KnotHolderEntityCenterMirrorSymmetry; -} - -class LPEMirrorSymmetry : public Effect, GroupBBoxEffect{ +class LPEMirrorSymmetry : public Effect { public: LPEMirrorSymmetry(LivePathEffectObject *lpeobject); virtual ~LPEMirrorSymmetry(); @@ -39,26 +32,11 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual int pointSideOfLine(Geom::Point A, Geom::Point B, Geom::Point X); - virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in); - /* the knotholder entity classes must be declared friends */ - friend class MS::KnotHolderEntityCenterMirrorSymmetry; - void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); - -protected: - virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); - private: BoolParam discard_orig_path; - BoolParam fusionPaths; - BoolParam reverseFusion; - BoolParam forceX; - BoolParam forceY; PathParam reflection_line; - Geom::Line lineSeparation; - PointParam center; LPEMirrorSymmetry(const LPEMirrorSymmetry&); LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 78545e9c5..2a1b70a6a 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -8,7 +8,6 @@ #include "live_effects/lpegroupbbox.h" #include "sp-item.h" -#include "sp-item-group.h" namespace Inkscape { namespace LivePathEffect { @@ -35,20 +34,9 @@ void GroupBBoxEffect::original_bbox(SPLPEItem const* lpeitem, bool absolute) } Geom::OptRect bbox = lpeitem->geometricBounds(transform); - std::cout << bbox->hasZeroArea() << "=AREA\n"; - if(bbox->hasZeroArea() && SP_IS_GROUP(lpeitem)){ - bbox = (Geom::OptRect)SP_GROUP(lpeitem)->bbox(transform, SPLPEItem::GEOMETRIC_BBOX); - //GSList const *items = sp_item_group_item_list(SPGroup * group); - //for ( GSList const *i = items ; i != NULL ; i = i->next ) { - // bbox.unionWith(SP_ITEM(i->data)->desktopGeometricBounds()); - //} - } - std::cout << bbox->hasZeroArea() << "=AREA222\n"; if (bbox) { boundingbox_X = (*bbox)[Geom::X]; boundingbox_Y = (*bbox)[Geom::Y]; - std::cout << boundingbox_X << "=BBOXX\n"; - std::cout << boundingbox_Y << "=BBOXY\n"; } else { boundingbox_X = Geom::Interval(); boundingbox_Y = Geom::Interval(); diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index cf9ef3132..4e2be6e88 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -723,7 +723,7 @@ FilletChamferPointArrayParamKnotHolderEntity( void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p, Point const &/*origin*/, - guint /*state*/) + guint state) { using namespace Geom; @@ -733,7 +733,7 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p, /// @todo how about item transforms??? Piecewise<D2<SBasis> > const &pwd2 = _pparam->get_pwd2(); //todo: add snapping - //Geom::Point const s = snap_knot_position(p, state); + Geom::Point const s = snap_knot_position(p, state); double t = nearest_point(p, pwd2[_index]); if (t == 1) { t = 0.9999; @@ -777,13 +777,21 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) }else{ using namespace Geom; int type = (int)_pparam->_vector.at(_index)[Y]; - + if (type >=3000 && type < 4000){ + type = 3; + } + if (type >=4000 && type < 5000){ + type = 4; + } switch(type){ case 1: type = 2; break; case 2: - type = _pparam->chamfer_steps; + type = _pparam->chamfer_steps + 3000; + break; + case 3: + type = _pparam->chamfer_steps + 4000; break; default: type = 1; @@ -793,8 +801,12 @@ void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) _pparam->param_set_and_write_new_value(_pparam->_vector); sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); const gchar *tip; - if (type >= 3) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + if (type >=3000 && type < 4000){ + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (type >=4000 && type < 5000) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (type == 2) { @@ -850,8 +862,12 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, continue; } const gchar *tip; - if (_vector[i][Y] >= 3) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + if (_vector[i][Y] >=3000 && _vector[i][Y] < 4000){ + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (_vector[i][Y] >=4000 && _vector[i][Y] < 5000) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toogle type, " "<b>Shift+Click</b> open dialog, " "<b>Ctrl+Alt+Click</b> reset"); } else if (_vector[i][Y] == 2) { diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index d00e8d702..ffa149cee 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1643,7 +1643,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons item->doWriteTransform(item->getRepr(), move, &move, compensate); } else if (prefs_unmoved) { - //if (SP_IS_USE(sp_use_get_original(SP_USE(item)))) + //if (dynamic_cast<SPUse *>(sp_use_get_original(dynamic_cast<SPUse *>(item)))) // clone_move = Geom::identity(); Geom::Affine move = result * clone_move; item->doWriteTransform(item->getRepr(), move, &t, compensate); diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp index 613ace5c1..992bca631 100644 --- a/src/sp-item-group.cpp +++ b/src/sp-item-group.cpp @@ -662,8 +662,13 @@ void SPGroup::scaleChildItemsRec(Geom::Scale const &sc, Geom::Point const &p, bo { if ( hasChildren() ) { for (SPObject *o = firstChild() ; o ; o = o->getNext() ) { - SPItem *item = dynamic_cast<SPItem *>(o); - if ( item ) { + if ( SPDefs *defs = dynamic_cast<SPDefs *>(o) ) { // select symbols from defs, ignore clips, masks, patterns + for (SPObject *defschild = defs->firstChild() ; defschild ; defschild = defschild->getNext() ) { + SPGroup *defsgroup = dynamic_cast<SPGroup *>(defschild); + if (defsgroup) + defsgroup->scaleChildItemsRec(sc, p, false); + } + } else if ( SPItem *item = dynamic_cast<SPItem *>(o) ) { SPGroup *group = dynamic_cast<SPGroup *>(item); if (group && !dynamic_cast<SPBox3D *>(item)) { /* Using recursion breaks clipping because transforms are applied diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 931a295d8..153ed9830 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -330,6 +330,13 @@ void ClipboardManagerImpl::copySymbol(Inkscape::XML::Node* symbol, gchar const* use->setAttribute("xlink:href", id.c_str() ); // Set a default style in <use> rather than <symbol> so it can be changed. use->setAttribute("style", style ); + + Inkscape::XML::Node *nv_repr = sp_desktop_namedview(inkscape_active_desktop())->getRepr(); + gdouble scale_units = Inkscape::Util::Quantity::convert(1, nv_repr->attribute("inkscape:document-units"), "px"); + gchar *transform_str = sp_svg_transform_write(Geom::Scale(scale_units, scale_units)); + use->setAttribute("transform", transform_str); + g_free(transform_str); + _root->appendChild(use); // This min and max sets offsets, we don't have any so set to zero. diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp index e9c012ff5..eb3857ee7 100644 --- a/src/ui/dialog/livepatheffect-editor.cpp +++ b/src/ui/dialog/livepatheffect-editor.cpp @@ -292,11 +292,8 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel) effectlist_store->clear(); current_lpeitem = NULL; - if ( sel && (sel->isEmpty() || sel->singleItem())) { - SPItem * item= SP_ITEM(current_desktop->currentRoot()); - if(!sel->isEmpty()){ - item = sel->singleItem(); - } + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); if ( item ) { SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); if ( lpeitem ) { @@ -425,11 +422,8 @@ void LivePathEffectEditor::onAdd() { Inkscape::Selection *sel = _getSelection(); - if ( sel && (sel->isEmpty() || sel->singleItem())) { - SPItem * item= SP_ITEM(current_desktop->currentRoot()); - if(!sel->isEmpty()){ - item = sel->singleItem(); - } + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); if (item) { if ( dynamic_cast<SPLPEItem *>(item) ) { // show effectlist dialog @@ -506,11 +500,8 @@ void LivePathEffectEditor::onRemove() { Inkscape::Selection *sel = _getSelection(); - if ( sel && (sel->isEmpty() || sel->singleItem())) { - SPItem * item= SP_ITEM(current_desktop->currentRoot()); - if(!sel->isEmpty()){ - item = sel->singleItem(); - } + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); if ( lpeitem ) { lpeitem->removeCurrentPathEffect(false); @@ -527,11 +518,8 @@ LivePathEffectEditor::onRemove() void LivePathEffectEditor::onUp() { Inkscape::Selection *sel = _getSelection(); - if ( sel && (sel->isEmpty() || sel->singleItem())) { - SPItem * item= SP_ITEM(current_desktop->currentRoot()); - if(!sel->isEmpty()){ - item = sel->singleItem(); - } + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); if ( lpeitem ) { lpeitem->upCurrentPathEffect(); @@ -547,11 +535,8 @@ void LivePathEffectEditor::onUp() void LivePathEffectEditor::onDown() { Inkscape::Selection *sel = _getSelection(); - if ( sel && (sel->isEmpty() || sel->singleItem())) { - SPItem * item= SP_ITEM(current_desktop->currentRoot()); - if(!sel->isEmpty()){ - item = sel->singleItem(); - } + if ( sel && !sel->isEmpty() ) { + SPItem *item = sel->singleItem(); SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item); if ( lpeitem ) { lpeitem->downCurrentPathEffect(); diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp index e55c9f8df..55a19fc51 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.cpp +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.cpp @@ -79,12 +79,15 @@ FilletChamferPropertiesDialog::FilletChamferPropertiesDialog() _fillet_chamfer_type_inverse_fillet.set_group(_fillet_chamfer_type_group); _fillet_chamfer_type_chamfer.set_label(_("Chamfer")); _fillet_chamfer_type_chamfer.set_group(_fillet_chamfer_type_group); + _fillet_chamfer_type_inverse_chamfer.set_label(_("Inverse chamfer")); + _fillet_chamfer_type_inverse_chamfer.set_group(_fillet_chamfer_type_group); mainVBox->pack_start(_layout_table, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_inverse_fillet, true, true, 4); mainVBox->pack_start(_fillet_chamfer_type_chamfer, true, true, 4); + mainVBox->pack_start(_fillet_chamfer_type_inverse_chamfer, true, true, 4); // Buttons _close_button.set_use_stock(true); @@ -158,8 +161,10 @@ void FilletChamferPropertiesDialog::_apply() d_width = 1; } else if (_fillet_chamfer_type_inverse_fillet.get_active() == true) { d_width = 2; + } else if (_fillet_chamfer_type_inverse_chamfer.get_active() == true) { + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 4000; } else { - d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3; + d_width = _fillet_chamfer_chamfer_subdivisions.get_value() + 3000; } if (_flexible) { if (d_pos > 99.99999 || d_pos < 0) { @@ -229,8 +234,12 @@ void FilletChamferPropertiesDialog::_set_knot_point(Geom::Point knotpoint) _fillet_chamfer_type_fillet.set_active(true); } else if (knotpoint.y() == 2) { _fillet_chamfer_type_inverse_fillet.set_active(true); - } else if (knotpoint.y() >= 3) { - _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3); + } else if (knotpoint.y() >= 3000 && knotpoint.y() < 4000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 3000); + _fillet_chamfer_type_chamfer.set_active(true); + } else if (knotpoint.y() >= 4000 && knotpoint.y() < 5000) { + _fillet_chamfer_chamfer_subdivisions.set_value(knotpoint.y() - 4000); + _fillet_chamfer_type_inverse_chamfer.set_active(true); } } diff --git a/src/ui/dialog/lpe-fillet-chamfer-properties.h b/src/ui/dialog/lpe-fillet-chamfer-properties.h index ec87addc5..3807e98c8 100644 --- a/src/ui/dialog/lpe-fillet-chamfer-properties.h +++ b/src/ui/dialog/lpe-fillet-chamfer-properties.h @@ -47,6 +47,7 @@ protected: Gtk::RadioButton _fillet_chamfer_type_fillet; Gtk::RadioButton _fillet_chamfer_type_inverse_fillet; Gtk::RadioButton _fillet_chamfer_type_chamfer; + Gtk::RadioButton _fillet_chamfer_type_inverse_chamfer; Gtk::Label _fillet_chamfer_chamfer_subdivisions_label; Gtk::SpinButton _fillet_chamfer_chamfer_subdivisions; |
