Advertisement
Guest User

BSpline LPE Inkscape

a guest
Mar 3rd, 2013
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.37 KB | None | 0 0
  1. void
  2. LPEBSpline::doEffect(SPCurve * curve)
  3. {
  4.     if(curve->get_segment_count() < 2)
  5.         return;
  6.     // Make copy of old path as it is changed during processing
  7.     Geom::PathVector const original_pathv = curve->get_pathvector();
  8.     curve->reset();
  9.  
  10.     //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo
  11.     for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
  12.         //Si está vacío...
  13.         if (path_it->empty())
  14.             continue;
  15.         //Itreadores
  16.        
  17.         Geom::Path::const_iterator curve_it1 = path_it->begin();      // incoming curve
  18.         Geom::Path::const_iterator curve_it2 = ++(path_it->begin());         // outgoing curve
  19.         Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
  20.         //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán
  21.         //los puntos clave para los manejadores.
  22.         //Esto hace que la curva BSpline no pierda su condición aunque se trasladen
  23.         //dichos manejadores
  24.         SPCurve *nCurve = new SPCurve();
  25.         Geom::Point startNode(0,0);
  26.         Geom::Point previousNode(0,0);
  27.         Geom::Point node(0,0);
  28.         Geom::Point pointAt1(0,0);
  29.         Geom::Point pointAt2(0,0);
  30.         Geom::Point nextPointAt1(0,0);
  31.         Geom::Point nextPointAt2(0,0);
  32.         Geom::Point nextPointAt3(0,0);
  33.         Geom::D2< Geom::SBasis > SBasisIn;
  34.         Geom::D2< Geom::SBasis > SBasisOut;
  35.         Geom::D2< Geom::SBasis > SBasisHelper;
  36.         Geom::CubicBezier const *cubic = NULL;
  37.         //Si la curva está cerrada calculamos el punto donde
  38.         //deveria estar el nodo BSpline de cierre/inicio de la curva
  39.         //en posible caso de que se cierre con una linea recta creando un nodo BSPline
  40.  
  41.         if (path_it->closed()) {
  42.             //Calculamos el nodo de inicio BSpline
  43.             const Geom::Curve &closingline = path_it->back_closed();
  44.             if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
  45.                 curve_endit = path_it->end_open();
  46.             }
  47.  
  48.             SPCurve * in = new SPCurve();
  49.             in->moveto(curve_it1->initialPoint());
  50.             in->lineto(curve_it1->finalPoint());
  51.             SBasisIn = in->first_segment()->toSBasis();
  52.  
  53.             SPCurve *lineHelper = new SPCurve();
  54.             cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
  55.             if(cubic){
  56.                 lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment())));
  57.             }else{
  58.                 lineHelper->moveto(in->first_segment()->initialPoint());
  59.             }
  60.             in->reset();
  61.             delete in;
  62.  
  63.             SPCurve * end = new SPCurve();
  64.             end->moveto(curve_endit->initialPoint());
  65.             end->lineto(curve_endit->finalPoint());
  66.             Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
  67.             //Geom::BezierCurve const *bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_endit);
  68.             cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_endit);
  69.             if(cubic){
  70.                 lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
  71.             }else{
  72.                 lineHelper->lineto(end->first_segment()->finalPoint());
  73.             }
  74.             end->reset();
  75.             delete end;
  76.             SBasisHelper = lineHelper->first_segment()->toSBasis();
  77.             lineHelper->reset();
  78.             delete lineHelper;
  79.             //Guardamos el principio de la curva
  80.             startNode = SBasisHelper.valueAt(0.5);
  81.             //Definimos el punto de inicio original de la curva resultante
  82.             node = startNode;
  83.         }else{
  84.             //Guardamos el principio de la curva
  85.             SPCurve * in = new SPCurve();
  86.             in->moveto(curve_it1->initialPoint());
  87.             in->lineto(curve_it1->finalPoint());
  88.             startNode = in->first_segment()->initialPoint();
  89.             in->reset();
  90.             delete in;
  91.             //Definimos el punto de inicio original de la curva resultante
  92.             node = startNode;
  93.         }
  94.         //Recorremos todos los segmentos menos el último
  95.         while ( curve_it2 != curve_endit )
  96.         {
  97.             //previousPointAt3 = pointAt3;
  98.             //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida
  99.             SPCurve * in = new SPCurve();
  100.             in->moveto(curve_it1->initialPoint());
  101.             in->lineto(curve_it1->finalPoint());
  102.             cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
  103.             if(cubic){
  104.                 SBasisIn = in->first_segment()->toSBasis();
  105.                 pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()));
  106.                 pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment()));
  107.             }else{
  108.                 pointAt1 = in->first_segment()->initialPoint();
  109.                 pointAt2 = in->first_segment()->finalPoint();
  110.             }
  111.             in->reset();
  112.             delete in;
  113.             //Y hacemos lo propio con el path de salida
  114.             //nextPointAt0 = curveOut.valueAt(0);
  115.             SPCurve * out = new SPCurve();
  116.             out->moveto(curve_it2->initialPoint());
  117.             out->lineto(curve_it2->finalPoint());
  118.             cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
  119.             if(cubic){
  120.                 SBasisOut = out->first_segment()->toSBasis();
  121.                 nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment()));
  122.                 nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));;
  123.                 nextPointAt3 = (*cubic)[3];
  124.             }else{
  125.                 nextPointAt1 = out->first_segment()->initialPoint();
  126.                 nextPointAt2 = out->first_segment()->finalPoint();
  127.                 nextPointAt3 = out->first_segment()->finalPoint();
  128.             }
  129.             out->reset();
  130.             delete out;
  131.             //La curva BSpline se forma calculando el centro del segmanto de unión
  132.             //de el punto situado en las 2/3 partes de el segmento de entrada
  133.             //con el punto situado en la posición 1/3 del segmento de salida
  134.             //Estos dos puntos ademas estan posicionados en el lugas correspondiente de
  135.             //los manejadores de la curva
  136.             SPCurve *lineHelper = new SPCurve();
  137.             lineHelper->moveto(pointAt2);
  138.             lineHelper->lineto(nextPointAt1);
  139.             SBasisHelper  = lineHelper->first_segment()->toSBasis();
  140.             lineHelper->reset();
  141.             delete lineHelper;
  142.             //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva
  143.             previousNode = node;
  144.             //Y este hará de final de curva
  145.             node = SBasisHelper.valueAt(0.5);
  146.             SPCurve *curveHelper = new SPCurve();
  147.             curveHelper->moveto(previousNode);
  148.             curveHelper->curveto(pointAt1, pointAt2, node);
  149.             //añadimos la curva generada a la curva pricipal
  150.             nCurve->append_continuous(curveHelper, 0.0625);
  151.             curveHelper->reset();
  152.             delete curveHelper;
  153.             //aumentamos los valores para el siguiente paso en el bucle
  154.             ++curve_it1;
  155.             ++curve_it2;
  156.         }
  157.         //Aberiguamos la ultima parte de la curva correspondiente al último segmento
  158.         SPCurve *curveHelper = new SPCurve();
  159.         curveHelper->moveto(node);
  160.         //Si está cerrada la curva, la cerramos sobre  el valor guardado previamente
  161.         //Si no finalizamos en el punto final
  162.         if (path_it->closed()) {
  163.             curveHelper->curveto(nextPointAt1, nextPointAt2, startNode);
  164.         }else{
  165.             curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
  166.         }
  167.         //añadimos este último segmento
  168.         nCurve->append_continuous(curveHelper, 0.0625);
  169.         curveHelper->reset();
  170.         delete curveHelper;
  171.         //y cerramos la curva
  172.         if (path_it->closed()) {
  173.             nCurve->closepath_current();
  174.         }
  175.         curve->append(nCurve,false);
  176.         nCurve->reset();
  177.         delete nCurve;
  178.     }
  179. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement