From a98d7da87dea01e6c39b3df95b78fc6a397dd685 Mon Sep 17 00:00:00 2001 From: bgk Date: Tue, 15 Apr 2008 08:07:29 +0000 Subject: [PATCH] - Clean up LPE bounding box computing code - Initial work to make the Perspective Path effect work with groups. Still not working correctly due to a bug in the bounding box code. --- src/live_effects/lpe-bendpath.cpp | 67 +++++---------------- src/live_effects/lpe-bendpath.h | 2 +- src/live_effects/lpe-perspective_path.cpp | 27 +++++++-- src/live_effects/lpe-perspective_path.h | 7 ++- src/live_effects/lpegroupbbox.cpp | 72 +++++++++++++++-------- src/live_effects/lpegroupbbox.h | 14 +++-- 6 files changed, 102 insertions(+), 87 deletions(-) diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 49569d4b5..c37f34ce7 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -86,21 +86,8 @@ LPEBendPath::doBeforeEffect (SPLPEItem *lpeitem) { groupSpecialBehavior = true; - using namespace Geom; - Piecewise > pwd2; - std::vector temppath; - - recursive_original_bbox(SP_GROUP(lpeitem), pwd2, temppath); - - for (unsigned int i=0; i < temppath.size(); i++) { - pwd2.concat( temppath[i].toPwSb() ); - } - - D2 > d2pw = make_cuts_independant(pwd2); - boundingbox_X = bounds_exact(d2pw[0]); - boundingbox_Y = bounds_exact(d2pw[1]); + original_bbox(lpeitem); } - } Geom::Piecewise > @@ -125,8 +112,8 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise > const & pwd boundingbox_X = bounds_exact(x); boundingbox_Y = bounds_exact(y); } - x-= boundingbox_X.min(); - y-= boundingbox_Y.middle(); + x-= vertical_pattern.get_value() ? boundingbox_Y.min() : boundingbox_X.min(); + y-= vertical_pattern.get_value() ? boundingbox_X.middle() : boundingbox_Y.middle(); double scaling = uskeleton.cuts.back()/boundingbox_X.extent(); @@ -148,43 +135,19 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise > const & pwd void LPEBendPath::resetDefaults(SPItem * item) { - if (SP_IS_PATH(item) || SP_IS_GROUP(item)) - { - // set the bend path to run horizontally in the middle of the bounding box of the original path - using namespace Geom; - Piecewise > pwd2; - std::vector temppath; - - if (SP_IS_PATH(item)) - { - //TODO : this won't work well with LPE stacking - temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d")); - } - else if (SP_IS_GROUP(item)) - { - recursive_original_bbox(SP_GROUP(item), pwd2, temppath); - } - - for (unsigned int i=0; i < temppath.size(); i++) { - pwd2.concat( temppath[i].toPwSb() ); - } - - D2 > d2pw = make_cuts_independant(pwd2); - boundingbox_X = bounds_exact(d2pw[0]); - boundingbox_Y = bounds_exact(d2pw[1]); - - Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2); - Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2); - - if ( Geom::are_near(start,end) ) { - end += Point(1.,0.); - } - - Geom::Path path; - path.start( start ); - path.appendNew( end ); - bend_path.param_set_and_write_new_value( path.toPwSb() ); + original_bbox(SP_LPE_ITEM(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); + + if ( Geom::are_near(start,end) ) { + end += Geom::Point(1.,0.); } + + Geom::Path path; + path.start( start ); + path.appendNew( end ); + bend_path.param_set_and_write_new_value( path.toPwSb() ); } void diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 47a26ac83..e05112de9 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -28,7 +28,7 @@ namespace Inkscape { namespace LivePathEffect { //for Bend path on group : we need information concerning the group Bounding box -class LPEBendPath : public Effect, LivePathEffect_group_bbox { +class LPEBendPath : public Effect, GroupBBoxEffect { public: LPEBendPath(LivePathEffectObject *lpeobject); virtual ~LPEBendPath(); diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 1418f1892..eb05b5702 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -28,6 +28,7 @@ #include "live_effects/lpe-perspective_path.h" #include "display/curve.h" #include +#include "sp-item-group.h" #include "inkscape.h" @@ -58,6 +59,8 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Proj::TransfMat3x4 pmat = persp->tmat; pmat.copy_tmat(tmat); + + groupSpecialBehavior = false; } LPEPerspectivePath::~LPEPerspectivePath() @@ -65,6 +68,17 @@ LPEPerspectivePath::~LPEPerspectivePath() } +void +LPEPerspectivePath::doBeforeEffect (SPLPEItem *lpeitem) +{ + if(SP_IS_GROUP(lpeitem)) + { + groupSpecialBehavior = true; + original_bbox(lpeitem); + } +} + + Geom::Piecewise > LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -79,15 +93,18 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > cons D2 > B = make_cuts_independant(path_a_pw); Piecewise preimage[4]; - Geom::Interval bounds_X = bounds_fast(pwd2_in)[0]; - Geom::Interval bounds_Y = bounds_fast(pwd2_in)[1]; + if(!groupSpecialBehavior) + { + boundingbox_X = bounds_fast(pwd2_in)[0]; + boundingbox_Y = bounds_fast(pwd2_in)[1]; + } - Geom::Point orig = Geom::Point(uses_plane_xy ? bounds_X.max() : bounds_X.min(), - bounds_Y.middle()); + Geom::Point orig = Geom::Point(uses_plane_xy ? boundingbox_X.max() : boundingbox_X.min(), + boundingbox_Y.middle()); //Geom::Point orig = Geom::Point(bounds_X.min(), bounds_Y.middle()); //orig = Geom::Point(orig[X], sp_document_height(inkscape_active_document()) - orig[Y]); - double offset = uses_plane_xy ? bounds_X.extent() : 0.0; + //double offset = uses_plane_xy ? boundingbox_X.extent() : 0.0; /** g_print ("Orig: (%8.2f, %8.2f)\n", orig[X], orig[Y]); diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index dc4a9969e..a2f451e65 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -17,6 +17,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/parameter.h" #include "live_effects/parameter/bool.h" +#include "live_effects/lpegroupbbox.h" #include #include "2geom/point.h" @@ -24,10 +25,12 @@ namespace Inkscape { namespace LivePathEffect { -class LPEPerspectivePath : public Effect { +class LPEPerspectivePath : public Effect, GroupBBoxEffect { public: LPEPerspectivePath(LivePathEffectObject *lpeobject); virtual ~LPEPerspectivePath(); + + virtual void doBeforeEffect (SPLPEItem *lpeitem); virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); @@ -45,6 +48,8 @@ private: std::vector handles; double tmat[3][4]; + + bool groupSpecialBehavior; }; } //namespace LivePathEffect diff --git a/src/live_effects/lpegroupbbox.cpp b/src/live_effects/lpegroupbbox.cpp index 64bdef465..588d3ec0f 100644 --- a/src/live_effects/lpegroupbbox.cpp +++ b/src/live_effects/lpegroupbbox.cpp @@ -33,32 +33,58 @@ namespace Inkscape { namespace LivePathEffect { void -LivePathEffect_group_bbox::recursive_original_bbox(SPGroup *group, Geom::Piecewise > & pwd2, std::vector & temppath) +GroupBBoxEffect::recursive_original_bbox(SPGroup *group, Geom::Piecewise > & pwd2, std::vector & temppath) { - std::vector tempsubpath; - GSList const *item_list = sp_item_group_item_list(group); - - for ( GSList const *iter = item_list; iter; iter = iter->next ) - { - SPObject *subitem = static_cast(iter->data); - if (SP_IS_PATH(subitem)) - { - //if there is not an original-d, just take the d - if(SP_OBJECT_REPR(subitem)->attribute("inkscape:original-d") != NULL) - tempsubpath = SVGD_to_2GeomPath(SP_OBJECT_REPR(subitem)->attribute("inkscape:original-d")); - else - tempsubpath = SVGD_to_2GeomPath(SP_OBJECT_REPR(subitem)->attribute("d")); - - temppath.insert(temppath.end(), tempsubpath.begin(), tempsubpath.end()); - }else - if (SP_IS_GROUP(subitem)) - { - recursive_original_bbox(SP_GROUP(subitem), pwd2, temppath); - } - - } + std::vector tempsubpath; + GSList const *item_list = sp_item_group_item_list(group); + + for ( GSList const *iter = item_list; iter; iter = iter->next ) + { + SPObject *subitem = static_cast(iter->data); + if (SP_IS_PATH(subitem)) + { + //if there is not an original-d, just take the d + if(SP_OBJECT_REPR(subitem)->attribute("inkscape:original-d") != NULL) + tempsubpath = SVGD_to_2GeomPath(SP_OBJECT_REPR(subitem)->attribute("inkscape:original-d")); + else + tempsubpath = SVGD_to_2GeomPath(SP_OBJECT_REPR(subitem)->attribute("d")); + + temppath.insert(temppath.end(), tempsubpath.begin(), tempsubpath.end()); + } + else if (SP_IS_GROUP(subitem)) + { + recursive_original_bbox(SP_GROUP(subitem), pwd2, temppath); + } + } } +void +GroupBBoxEffect::original_bbox(SPLPEItem *lpeitem) +{ + + using namespace Geom; + Piecewise > pwd2; + std::vector temppath; + + + if (SP_IS_PATH(lpeitem)) + { + //TODO : this won't work well with LPE stacking + temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(lpeitem)->attribute("inkscape:original-d")); + } + else if (SP_IS_GROUP(lpeitem)) + { + recursive_original_bbox(SP_GROUP(lpeitem), pwd2, temppath); + } + + for (unsigned int i=0; i < temppath.size(); i++) { + pwd2.concat( temppath[i].toPwSb() ); + } + + D2 > d2pw = make_cuts_independant(pwd2); + boundingbox_X = bounds_exact(d2pw[0]); + boundingbox_Y = bounds_exact(d2pw[1]); +} } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpegroupbbox.h b/src/live_effects/lpegroupbbox.h index cc56ed9a7..bf1fa0902 100644 --- a/src/live_effects/lpegroupbbox.h +++ b/src/live_effects/lpegroupbbox.h @@ -1,5 +1,5 @@ #ifndef INKSCAPE_LPEGROUPBBOX_H -#define INKSCAPE_LPEGROUPBBOXP_H +#define INKSCAPE_LPEGROUPBBOX_H /* * Inkscape::LivePathEffect_group_bbox @@ -23,15 +23,19 @@ namespace Inkscape { namespace LivePathEffect { -class LivePathEffect_group_bbox { +class GroupBBoxEffect { protected: //if we need information concerning the group Bounding box and coordinates of each subshapes. Geom::Interval boundingbox_X; Geom::Interval boundingbox_Y; -//Here is a recursive function to get the bbox of a group - void -recursive_original_bbox(SPGroup *group, Geom::Piecewise > & pwd2, std::vector & temppath); +//This set boundingbox_X and boundingbox_Y + void original_bbox(SPLPEItem *lpeitem); + +//Here is a recursive function to calculate the bbox of a group + void recursive_original_bbox(SPGroup *group, Geom::Piecewise > & pwd2, std::vector & temppath); + + }; -- 2.30.2