Code

- Clean up LPE bounding box computing code
authorbgk <bgk@users.sourceforge.net>
Tue, 15 Apr 2008 08:07:29 +0000 (08:07 +0000)
committerbgk <bgk@users.sourceforge.net>
Tue, 15 Apr 2008 08:07:29 +0000 (08:07 +0000)
- 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
src/live_effects/lpe-bendpath.h
src/live_effects/lpe-perspective_path.cpp
src/live_effects/lpe-perspective_path.h
src/live_effects/lpegroupbbox.cpp
src/live_effects/lpegroupbbox.h

index 49569d4b52d854ceb5a00566478f25e23b3e08a7..c37f34ce7a73dd2beb7d03d131fabda110d42d95 100644 (file)
@@ -86,21 +86,8 @@ LPEBendPath::doBeforeEffect (SPLPEItem *lpeitem)
     {
         groupSpecialBehavior = true;
 
-        using namespace Geom;
-        Piecewise<D2<SBasis> > pwd2;
-        std::vector<Geom::Path> temppath;
-
-        recursive_original_bbox(SP_GROUP(lpeitem), pwd2, temppath);
-
-        for (unsigned int i=0; i < temppath.size(); i++) {
-            pwd2.concat( temppath[i].toPwSb() );
-        }
-
-        D2<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
-        boundingbox_X = bounds_exact(d2pw[0]);
-        boundingbox_Y = bounds_exact(d2pw[1]);
+        original_bbox(lpeitem);
     }
-
 }
 
 Geom::Piecewise<Geom::D2<Geom::SBasis> >
@@ -125,8 +112,8 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > 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<Geom::D2<Geom::SBasis> > 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<D2<SBasis> > pwd2;
-        std::vector<Geom::Path> 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<Piecewise<SBasis> > 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<Geom::LineSegment>( 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<Geom::LineSegment>( end );
+    bend_path.param_set_and_write_new_value( path.toPwSb() );
 }
 
 void
index 47a26ac831a11f66c7161d31eaf6493195c95d0b..e05112de9fc1da46c2759413a873c620f34648c0 100644 (file)
@@ -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();
index 1418f1892c71ae30b99e6fbd455293edc38a017b..eb05b5702f33dc4af4f0fad91419000ae095469e 100644 (file)
@@ -28,6 +28,7 @@
 #include "live_effects/lpe-perspective_path.h"
 #include "display/curve.h"
 #include <libnr/n-art-bpath.h>
+#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<Geom::D2<Geom::SBasis> >
 LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
 {
@@ -79,15 +93,18 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > cons
     D2<Piecewise<SBasis> > B = make_cuts_independant(path_a_pw);
     Piecewise<SBasis> 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]);
index dc4a9969ec08b2119220cab92a837dab65e830a6..a2f451e6558d412e0348a2cae18f75ac6b984c9e 100644 (file)
@@ -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 <vector>
 #include "2geom/point.h"
 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<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
 
@@ -45,6 +48,8 @@ private:
 
     std::vector<Geom::Point> handles;
     double tmat[3][4];
+    
+    bool groupSpecialBehavior;
 };
 
 } //namespace LivePathEffect
index 64bdef465c444022021a9f14d6aade2fd83e929f..588d3ec0fa6a767f9827216177deb390d1bd15b3 100644 (file)
@@ -33,32 +33,58 @@ namespace Inkscape {
 namespace LivePathEffect {
 
 void
-LivePathEffect_group_bbox::recursive_original_bbox(SPGroup *group, Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2, std::vector<Geom::Path> & temppath)
+GroupBBoxEffect::recursive_original_bbox(SPGroup *group, Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2, std::vector<Geom::Path> & temppath)
 {
-            std::vector<Geom::Path> 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<SPObject *>(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<Geom::Path> 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<SPObject *>(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<D2<SBasis> > pwd2;
+    std::vector<Geom::Path> 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<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
+    boundingbox_X = bounds_exact(d2pw[0]);
+    boundingbox_Y = bounds_exact(d2pw[1]);
+}
 
 } // namespace LivePathEffect
 } /* namespace Inkscape */
index cc56ed9a7bb418ec48c40a8283385292d3730427..bf1fa09027dcd6f78cd34048fdf82f2fb2a19225 100644 (file)
@@ -1,5 +1,5 @@
 #ifndef INKSCAPE_LPEGROUPBBOX_H
-#define INKSCAPE_LPEGROUPBBOXP_H
+#define INKSCAPE_LPEGROUPBBOX_H
 
 /*
  * Inkscape::LivePathEffect_group_bbox
 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<Geom::D2<Geom::SBasis> > & pwd2, std::vector<Geom::Path> & 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<Geom::D2<Geom::SBasis> > & pwd2, std::vector<Geom::Path> & temppath);
+
+
 
 };