diff --git a/src/spray-context.cpp b/src/spray-context.cpp
index 71dc9648a7f7092be73209618afd409c705b517b..6d19cbce429f662e0d6dfa55f82c133045340a11 100644 (file)
--- a/src/spray-context.cpp
+++ b/src/spray-context.cpp
-#define __SP_SPRAY_CONTEXT_C__
-
/*
* Spray Tool
*
* Authors:
* Pierre-Antoine MARC
* Pierre CACLIN
- * Aurel-Aimé MARMION
+ * Aurel-Aimé MARMION
* Julien LERAY
* Benoît LAVORATA
* Vincent MONTAGNE
* Pierre BARBRY-BLOT
+ * Steren GIANNINI (steren.giannini@gmail.com)
+ * Jon A. Cruz <jon@joncruz.org>
+ * Abhishek Sharma
*
* Copyright (C) 2009 authors
*
#include <numeric>
#include "svg/svg.h"
-#include "display/canvas-bpath.h"
#include <glib/gmem.h>
#include "macros.h"
#include "desktop-style.h"
#include "message-context.h"
#include "pixmaps/cursor-spray.xpm"
-#include "pixmaps/cursor-spray-move.xpm"
-#include "pixmaps/cursor-thin.xpm"
-#include "pixmaps/cursor-thicken.xpm"
-#include "pixmaps/cursor-attract.xpm"
-#include "pixmaps/cursor-repel.xpm"
-#include "pixmaps/cursor-push.xpm"
-#include "pixmaps/cursor-roughen.xpm"
-#include "pixmaps/cursor-color.xpm"
#include <boost/optional.hpp>
#include "libnr/nr-matrix-ops.h"
#include "libnr/nr-scale-translate-ops.h"
#include "path-chemistry.h"
#include "sp-gradient.h"
#include "sp-stop.h"
-#include "sp-stop-fns.h"
#include "sp-gradient-reference.h"
#include "sp-linear-gradient.h"
#include "sp-radial-gradient.h"
#include "gradient-chemistry.h"
#include "sp-text.h"
#include "sp-flowtext.h"
+#include "display/sp-canvas.h"
#include "display/canvas-bpath.h"
#include "display/canvas-arena.h"
#include "display/curve.h"
#include "livarot/Shape.h"
-#include <2geom/isnan.h>
+#include <2geom/isnan.h>
#include <2geom/transforms.h>
#include "preferences.h"
#include "style.h"
#include "helper/action.h"
#include <iostream>
+
+using Inkscape::DocumentUndo;
using namespace std;
static void sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val);
static gint sp_spray_context_root_handler(SPEventContext *ec, GdkEvent *event);
-static SPEventContextClass *parent_class;
-
-
-
-// The following code implements NormalDistribution wich is used for the density of the spray
+static SPEventContextClass *parent_class = 0;
-/*
- RAND is a macro which returns a pseudo-random numbers from a uniform
- distribution on the interval [0 1]
-*/
-#define RAND ((double) rand())/((double) RAND_MAX)
-
-/*
- TWOPI = 2.0*pi
-*/
-#define TWOPI 2.0*3.141592653589793238462643383279502884197169399375
-
-/*
- RANDN is a macro which returns a pseudo-random numbers from a normal
- distribution with mean zero and standard deviation one. This macro uses Box
- Muller's algorithm
-*/
-#define RANDN sqrt(-2.0*log(RAND))*cos(TWOPI*RAND)
-
-
-double NormalDistribution(double mu,double sigma)
+/**
+ * This function returns pseudo-random numbers from a normal distribution
+ * @param mu : mean
+ * @param sigma : standard deviation ( > 0 )
+ */
+inline double NormalDistribution(double mu,double sigma)
{
-/*
- This function returns a pseudo-random numbers from a normal distribution with
- mean equal at mu and standard deviation equal at sigma > 0
-*/
-
- return (mu+sigma*RANDN);
-
+ // use Box Muller's algorithm
+ return mu + sigma * sqrt( -2.0 * log(g_random_double_range(0, 1)) ) * cos( 2.0*M_PI*g_random_double_range(0, 1) );
}
-//Fin de la création de NormalDistribution
-GtkType
-sp_spray_context_get_type(void)
+GtkType sp_spray_context_get_type(void)
{
static GType type = 0;
if (!type) {
return type;
}
-static void
-sp_spray_context_class_init(SPSprayContextClass *klass)
+static void sp_spray_context_class_init(SPSprayContextClass *klass)
{
GObjectClass *object_class = (GObjectClass *) klass;
SPEventContextClass *event_context_class = (SPEventContextClass *) klass;
event_context_class->set = sp_spray_context_set;
event_context_class->root_handler = sp_spray_context_root_handler;
}
-/*Method to rotate items*/
-void
-sp_spray_rotate_rel(Geom::Point c,SPDesktop *desktop,SPItem *item, Geom::Rotate const &rotation)
-{
+/* Method to rotate items */
+void sp_spray_rotate_rel(Geom::Point c,SPDesktop */*desktop*/,SPItem *item, Geom::Rotate const &rotation)
+{
Geom::Point center = c;
Geom::Translate const s(c);
Geom::Matrix affine = Geom::Matrix(s).inverse() * Geom::Matrix(rotation) * Geom::Matrix(s);
-
// Rotate item.
- sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * (Geom::Matrix)affine);
+ item->set_i2d_affine(item->i2d_affine() * (Geom::Matrix)affine);
// Use each item's own transform writer, consistent with sp_selection_apply_affine()
- sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
-
+ item->doWriteTransform(SP_OBJECT_REPR(item), item->transform);
// Restore the center position (it's changed because the bbox center changed)
if (item->isCenterSet()) {
item->setCenter(c);
item->updateRepr();
}
}
-/*Method to scale items*/
-void
-sp_spray_scale_rel (Geom::Point c, SPDesktop *desktop, SPItem *item, Geom::Scale const &scale)
-{
- Geom::Translate const s(c);
-
-
- sp_item_set_i2d_affine(item, sp_item_i2d_affine(item) * s.inverse() * scale * s );
- sp_item_write_transform(item, SP_OBJECT_REPR(item), item->transform);
-
+/* Method to scale items */
+void sp_spray_scale_rel(Geom::Point c, SPDesktop */*desktop*/, SPItem *item, Geom::Scale const &scale)
+{
+ Geom::Translate const s(c);
+ item->set_i2d_affine(item->i2d_affine() * s.inverse() * scale * s );
+ item->doWriteTransform(SP_OBJECT_REPR(item), item->transform);
}
-static void
-sp_spray_context_init(SPSprayContext *tc)
-{
- SPEventContext *event_context = SP_EVENT_CONTEXT(tc);
-
+static void sp_spray_context_init(SPSprayContext *tc)
+{
+ SPEventContext *event_context = SP_EVENT_CONTEXT(tc);
event_context->cursor_shape = cursor_spray_xpm;
event_context->hot_x = 4;
tc->ratio = 0;
tc->tilt=0;
tc->mean = 0.2;
- tc->rot_min=0;
- tc->rot_max=0;
+ tc->rotation_variation=0;
tc->standard_deviation=0.2;
tc->scale=1;
- tc->scale_min = 1;
- tc->scale_max=1;
+ tc->scale_variation = 1;
tc->pressure = TC_DEFAULT_PRESSURE;
tc->is_dilating = false;
new (&tc->style_set_connection) sigc::connection();
}
-static void
-sp_spray_context_dispose(GObject *object)
+static void sp_spray_context_dispose(GObject *object)
{
SPSprayContext *tc = SP_SPRAY_CONTEXT(object);
G_OBJECT_CLASS(parent_class)->dispose(object);
}
-bool is_transform_modes (gint mode)
+bool is_transform_modes(gint mode)
{
return (mode == SPRAY_MODE_COPY ||
mode == SPRAY_MODE_CLONE ||
mode == SPRAY_OPTION);
}
-void
-sp_spray_update_cursor (SPSprayContext *tc, bool with_shift)
+void sp_spray_update_cursor(SPSprayContext *tc, bool /*with_shift*/)
{
SPEventContext *event_context = SP_EVENT_CONTEXT(tc);
SPDesktop *desktop = event_context->desktop;
- guint num = 0;
- gchar *sel_message = NULL;
- if (!desktop->selection->isEmpty()) {
- num = g_slist_length((GSList *) desktop->selection->itemList());
- sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num);
- } else {
- sel_message = g_strdup_printf(_("<b>Nothing</b> selected"));
- }
+ guint num = 0;
+ gchar *sel_message = NULL;
+ if (!desktop->selection->isEmpty()) {
+ num = g_slist_length((GSList *) desktop->selection->itemList());
+ sel_message = g_strdup_printf(ngettext("<b>%i</b> object selected","<b>%i</b> objects selected",num), num);
+ } else {
+ sel_message = g_strdup_printf(_("<b>Nothing</b> selected"));
+ }
switch (tc->mode) {
case SPRAY_MODE_SINGLE_PATH:
tc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Drag, click or scroll to spray in a <b>single path</b> of the initial selection"), sel_message);
break;
- case SPRAY_OPTION:
- tc->_message_context->setF(Inkscape::NORMAL_MESSAGE, _("%s. Modify <b>spray</b> options"), sel_message);
+ default:
break;
}
sp_event_context_update_cursor(event_context);
g_free(sel_message);
}
-static void
-sp_spray_context_setup(SPEventContext *ec)
+static void sp_spray_context_setup(SPEventContext *ec)
{
SPSprayContext *tc = SP_SPRAY_CONTEXT(ec);
tc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack());
- sp_event_context_read(ec, "distrib");
+ sp_event_context_read(ec, "distrib");
sp_event_context_read(ec, "width");
sp_event_context_read(ec, "ratio");
sp_event_context_read(ec, "tilt");
- sp_event_context_read(ec, "rot_min");
- sp_event_context_read(ec, "rot_max");
- sp_event_context_read(ec, "scale_min");
- sp_event_context_read(ec, "scale_max");
+ sp_event_context_read(ec, "rotation_variation");
+ sp_event_context_read(ec, "scale_variation");
sp_event_context_read(ec, "mode");
sp_event_context_read(ec, "population");
sp_event_context_read(ec, "force");
sp_event_context_read(ec, "mean");
sp_event_context_read(ec, "standard_deviation");
sp_event_context_read(ec, "usepressure");
- sp_event_context_read(ec, "Rotation min");
- sp_event_context_read(ec, "Rotation max");
sp_event_context_read(ec, "Scale");
sp_event_context_read(ec, "doh");
sp_event_context_read(ec, "dol");
}
}
-static void
-sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val)
+static void sp_spray_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val)
{
SPSprayContext *tc = SP_SPRAY_CONTEXT(ec);
Glib::ustring path = val->getEntryName();
if (path == "width") {
- tc->width = CLAMP(val->getDouble(0.1), -1000.0, 1000.0);
+ tc->width = 0.01 * CLAMP(val->getInt(10), 1, 100);
} else if (path == "mode") {
tc->mode = val->getInt();
sp_spray_update_cursor(tc, false);
} else if (path == "distribution") {
tc->distrib = val->getInt(1);
} else if (path == "population") {
- tc->population = CLAMP(val->getDouble(), 0.0, 1.0);
+ tc->population = 0.01 * CLAMP(val->getInt(10), 1, 100);
} else if (path == "tilt") {
tc->tilt = CLAMP(val->getDouble(0.1), 0, 1000.0);
} else if (path == "ratio") {
tc->ratio = CLAMP(val->getDouble(), 0.0, 0.9);
} else if (path == "force") {
tc->force = CLAMP(val->getDouble(1.0), 0, 1.0);
- } else if (path == "rot_min") {
- tc->rot_min = CLAMP(val->getDouble(0), 0, 10.0);
- } else if (path == "rot_max") {
- tc->rot_max = CLAMP(val->getDouble(0), 0, 10.0);
- } else if (path == "scale_min") {
- tc->scale_min = CLAMP(val->getDouble(1.0), 0, 10.0);
- } else if (path == "scale_max") {
- tc->scale_max = CLAMP(val->getDouble(1.0), 0, 10.0);
+ } else if (path == "rotation_variation") {
+ tc->rotation_variation = CLAMP(val->getDouble(0.0), 0, 100.0);
+ } else if (path == "scale_variation") {
+ tc->scale_variation = CLAMP(val->getDouble(1.0), 0, 100.0);
} else if (path == "mean") {
- tc->mean = CLAMP(val->getDouble(1.0), 0, 1.0);
+ tc->mean = 0.01 * CLAMP(val->getInt(10), 1, 100);
} else if (path == "standard_deviation") {
- tc->standard_deviation = CLAMP(val->getDouble(1.0), 0, 1.0);
+ tc->standard_deviation = 0.01 * CLAMP(val->getInt(10), 1, 100);
} else if (path == "usepressure") {
tc->usepressure = val->getBool();
} else if (path == "doh") {
}
}
-static void
-sp_spray_extinput(SPSprayContext *tc, GdkEvent *event)
+static void sp_spray_extinput(SPSprayContext *tc, GdkEvent *event)
{
if (gdk_event_get_axis (event, GDK_AXIS_PRESSURE, &tc->pressure))
tc->pressure = CLAMP (tc->pressure, TC_MIN_PRESSURE, TC_MAX_PRESSURE);
tc->pressure = TC_DEFAULT_PRESSURE;
}
-double
-get_dilate_radius (SPSprayContext *tc)
+double get_dilate_radius(SPSprayContext *tc)
{
return 250 * tc->width/SP_EVENT_CONTEXT(tc)->desktop->current_zoom();
}
-double
-get_path_force (SPSprayContext *tc)
+double get_path_force(SPSprayContext *tc)
{
double force = 8 * (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE)
/sqrt(SP_EVENT_CONTEXT(tc)->desktop->current_zoom());
return force * tc->force;
}
-double
-get_path_mean (SPSprayContext *tc)
+double get_path_mean(SPSprayContext *tc)
{
return tc->mean;
}
-double
-get_path_standard_deviation (SPSprayContext *tc)
+double get_path_standard_deviation(SPSprayContext *tc)
{
return tc->standard_deviation;
}
-double
-get_move_force (SPSprayContext *tc)
+double get_move_force(SPSprayContext *tc)
{
double force = (tc->usepressure? tc->pressure : TC_DEFAULT_PRESSURE);
return force * tc->force;
}
-double
-get_move_mean (SPSprayContext *tc)
+double get_move_mean(SPSprayContext *tc)
{
return tc->mean;
}
-double
-get_move_standard_deviation (SPSprayContext *tc)
+double get_move_standard_deviation(SPSprayContext *tc)
{
return tc->standard_deviation;
}
-/* Method to handle the distribution of the items */
+/**
+ * Method to handle the distribution of the items
+ * @param[out] radius : radius of the position of the sprayed object
+ * @param[out] angle : angle of the position of the sprayed object
+ * @param[in] a : mean
+ * @param[in] s : standard deviation
+ * @param[in] choice :
-
-void random_position( double &r, double &p, double &a, double &s, int choix)
+ */
+void random_position( double &radius, double &angle, double &a, double &s, int /*choice*/)
{
- if (choix == 0) // Mode 1 : uniform repartition
- {
- r = (1-pow(g_random_double_range(0, 1),2));
- p = g_random_double_range(0, M_PI*2);
- }
- if (choix == 1) //Mode 0 : gaussian repartition
+ // angle is taken from an uniform distribution
+ angle = g_random_double_range(0, M_PI*2.0);
+
+ // radius is taken from a Normal Distribution
+ double radius_temp =-1;
+ while(!((radius_temp>=0)&&(radius_temp<=1)))
{
- double r_temp =-1;
-while(!((r_temp>=0)&&(r_temp<=1)))
-{
- r_temp = NormalDistribution(a,s/4);
-}
-// generates a number following a normal distribution
- p = g_random_double_range(0, M_PI*2);
- r=r_temp;
- /* if (r_temp<=0) r=0;
- else
- {
- if (r_temp>1) r=1;
- else r = r_temp;
- }*/
+ radius_temp = NormalDistribution( a, s );
}
+ // Because we are in polar coordinates, a special treatment has to be done to the radius.
+ // Otherwise, positions taken from an uniform repartition on radius and angle will not seam to
+ // be uniformily distributed on the disk (more at the center and less at the boundary).
+ // We counter this effect with a 0.5 exponent. This is empiric.
+ radius = pow( radius_temp, 0.5);
+
}
-bool
-sp_spray_dilate_recursive (SPDesktop *desktop, Inkscape::Selection *selection, SPItem *item, Geom::Point p, Geom::Point vector, gint mode, double radius, double force, double population, double &scale, double scale_min, double scale_max, bool reverse, double mean, double standard_deviation, double ratio,double tilt, double rot_min, double rot_max, gint _distrib )
+bool sp_spray_recursive(SPDesktop *desktop,
+ Inkscape::Selection *selection,
+ SPItem *item,
+ Geom::Point p,
+ Geom::Point /*vector*/,
+ gint mode,
+ double radius,
+ double /*force*/,
+ double population,
+ double &scale,
+ double scale_variation,
+ bool /*reverse*/,
+ double mean,
+ double standard_deviation,
+ double ratio,
+ double tilt,
+ double rotation_variation,
+ gint _distrib )
{
-
-
-
bool did = false;
-
- if (SP_IS_BOX3D(item) /*&& !is_transform_modes(mode)*/) {
+
+ if (SP_IS_BOX3D(item) ) {
// convert 3D boxes to ordinary groups before spraying their shapes
item = SP_ITEM(box3d_convert_to_group(SP_BOX3D(item)));
selection->add(item);
}
-/*if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
- GSList *items = g_slist_prepend (NULL, item);
- GSList *selected = NULL;
- GSList *to_select = NULL;
- SPDocument *doc = SP_OBJECT_DOCUMENT(item);
- sp_item_list_to_curves (items, &selected, &to_select);
- g_slist_free (items);
- SPObject* newObj = doc->getObjectByRepr((Inkscape::XML::Node *) to_select->data);
- g_slist_free (to_select);
- item = (SPItem *) newObj;
- // selection->add(item);
- }
-*/
- /*if (SP_IS_GROUP(item) && !SP_IS_BOX3D(item)) {
- for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
- if (SP_IS_ITEM(child)) {
- if (sp_spray_dilate_recursive (desktop,selection, SP_ITEM(child), p, vector, mode, radius, force, population, scale, scale_min, scale_max, reverse, mean, standard_deviation,ratio,tilt, rot_min, rot_max,_distrib))
- did = true;
+ double _fid = g_random_double_range(0,1);
+ double angle = g_random_double_range( - rotation_variation / 100.0 * M_PI , rotation_variation / 100.0 * M_PI );
+ double _scale = g_random_double_range( 1.0 - scale_variation / 100.0, 1.0 + scale_variation / 100.0 );
+ double dr; double dp;
+ random_position( dr, dp, mean, standard_deviation, _distrib );
+ dr=dr*radius;
+
+ if (mode == SPRAY_MODE_COPY) {
+ Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ if (a) {
+ SPItem *item_copied;
+ if(_fid<=population)
+ {
+ // duplicate
+ SPDocument *doc = SP_OBJECT_DOCUMENT(item);
+ Inkscape::XML::Document* xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(item);
+ Inkscape::XML::Node *parent = old_repr->parent();
+ Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
+ parent->appendChild(copy);
+
+ SPObject *new_obj = doc->getObjectByRepr(copy);
+ item_copied = (SPItem *) new_obj; //convertion object->item
+ Geom::Point center=item->getCenter();
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
+
+ sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
+ //Move the cursor p
+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
+ sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
+ did = true;
}
}
+ } else if (mode == SPRAY_MODE_SINGLE_PATH) {
- } else {*/
- if (mode == SPRAY_MODE_COPY) {
-
- Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item));
- if (a) {
- double dr; double dp;
- random_position(dr,dp,mean,standard_deviation,_distrib);
- dr=dr*radius;
- double _fid = g_random_double_range(0,1);
- SPItem *item_copied;
- double angle = g_random_double_range(rot_min, rot_max);
- double _scale = g_random_double_range(scale_min, scale_max);
- if(_fid<=population)
- {
- // duplicate
- SPDocument *doc = SP_OBJECT_DOCUMENT(item);
- Inkscape::XML::Document* xml_doc = sp_document_repr_doc(doc);
- Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(item);
- Inkscape::XML::Node *parent = old_repr->parent();
- Inkscape::XML::Node *copy = old_repr->duplicate(xml_doc);
- parent->appendChild(copy);
-
- SPObject *new_obj = doc->getObjectByRepr(copy);
- item_copied = (SPItem *) new_obj; //convertion object->item
- Geom::Point center=item->getCenter();
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
-
- sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());//Move the cursor p
- sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
-
-
-
-
-
- did = true;
- }
- }
+ SPItem *father; //initial Object
+ SPItem *item_copied; //Projected Object
+ SPItem *unionResult; //previous union
+ SPItem *son; //father copy
- } else if (mode == SPRAY_MODE_SINGLE_PATH) {
+ int i=1;
+ for (GSList *items = g_slist_copy((GSList *) selection->itemList());
+ items != NULL;
+ items = items->next) {
-
- SPItem *Pere; //Objet initial
- SPItem *item_copied;//Objet projeté
- SPItem *Union;//Union précédente
- SPItem *fils;//Copie du père
-
- // GSList *items = g_slist_copy((GSList *) selection->itemList()); //Récupère la liste des objects sélectionnés
-//Pere = (SPItem *) items->data;//Le premier objet est le père du spray
-
- int i=1;
- for (GSList *items = g_slist_copy((GSList *) selection->itemList());
- items != NULL;
- items = items->next) {
-
- SPItem *item1 = (SPItem *) items->data;
- if (i==1) {
- Pere=item1;
- }
- if (i==2) {
- Union=item1;
- }
- i++;
+ SPItem *item1 = (SPItem *) items->data;
+ if (i==1) {
+ father=item1;
}
- SPDocument *doc = SP_OBJECT_DOCUMENT(Pere);
- Inkscape::XML::Document* xml_doc = sp_document_repr_doc(doc);
- Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(Pere);
- //SPObject *old_obj = doc->getObjectByRepr(old_repr);
- Inkscape::XML::Node *parent = old_repr->parent();
-
- Geom::OptRect a = Pere->getBounds(sp_item_i2doc_affine(Pere));
- if (a) {
- double dr; double dp; //initialisation des variables
- random_position(dr,dp,mean,standard_deviation,_distrib);
- dr=dr*radius;
- double _fid = g_random_double_range(0,1);
- double angle = (g_random_double_range(rot_min, rot_max));
- double _scale = g_random_double_range(scale_min, scale_max);
- if (i==2) {
- Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
- parent->appendChild(copy1);
- SPObject *new_obj1 = doc->getObjectByRepr(copy1);
- fils = (SPItem *) new_obj1; //conversion object->item
- Union=fils;
- Inkscape::GC::release(copy1);
- }
-
- if (_fid<=population) { //Rules the population of objects sprayed
- // duplicates the father
- Inkscape::XML::Node *copy2 = old_repr->duplicate(xml_doc);
- parent->appendChild(copy2);
- SPObject *new_obj2 = doc->getObjectByRepr(copy2);
- item_copied = (SPItem *) new_obj2;
-
- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());//Move around the cursor
-
- Geom::Point center=Pere->getCenter();
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
- sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
- sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
-
-//UNION et surduplication
- selection->clear();
- selection->add(item_copied);
- selection->add(Union);
- sp_selected_path_union(selection->desktop());
- selection->add(Pere);
- Inkscape::GC::release(copy2);
- did = true;
- }
-
+ if (i==2) {
+ unionResult=item1;
}
- } else if (mode == SPRAY_MODE_CLONE) {
-
- Geom::OptRect a = item->getBounds(sp_item_i2doc_affine(item));
- if (a) {
- double dr; double dp;
- random_position(dr,dp,mean,standard_deviation,_distrib);
- dr=dr*radius;
- double _fid = g_random_double_range(0,1);
- double angle = (g_random_double_range(rot_min, rot_max));
- double _scale = g_random_double_range(scale_min, scale_max);
-
- if(_fid<=population)
- {
- SPItem *item_copied;
- SPDocument *doc = SP_OBJECT_DOCUMENT(item);
- Inkscape::XML::Document* xml_doc = sp_document_repr_doc(doc);
- Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(item);
- Inkscape::XML::Node *parent = old_repr->parent();
-
- //Creation of the clone
- Inkscape::XML::Node *clone = xml_doc->createElement("svg:use");
- parent->appendChild(clone); //Ajout du clone à la liste d'enfants du père (selection initiale
- clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false); //Génère le lien entre les attributs du père et du fils
-
- SPObject *clone_object = doc->getObjectByRepr(clone);
- item_copied = (SPItem *) clone_object;//conversion object->item
- Geom::Point center=item->getCenter();
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
- sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
- sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
- Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
- sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
-
- Inkscape::GC::release(clone);
-
- did = true;
- } }}
- return did;
-
-}
+ i++;
+ }
+ SPDocument *doc = SP_OBJECT_DOCUMENT(father);
+ Inkscape::XML::Document* xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(father);
+ Inkscape::XML::Node *parent = old_repr->parent();
+
+ Geom::OptRect a = father->getBounds(father->i2doc_affine());
+ if (a) {
+ if (i==2) {
+ Inkscape::XML::Node *copy1 = old_repr->duplicate(xml_doc);
+ parent->appendChild(copy1);
+ SPObject *new_obj1 = doc->getObjectByRepr(copy1);
+ son = (SPItem *) new_obj1; // conversion object->item
+ unionResult=son;
+ Inkscape::GC::release(copy1);
+ }
+ if (_fid<=population) { // Rules the population of objects sprayed
+ // duplicates the father
+ Inkscape::XML::Node *copy2 = old_repr->duplicate(xml_doc);
+ parent->appendChild(copy2);
+ SPObject *new_obj2 = doc->getObjectByRepr(copy2);
+ item_copied = (SPItem *) new_obj2;
+
+ // Move around the cursor
+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
+
+ Geom::Point center=father->getCenter();
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
+ sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
+ sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
+
+ // union and duplication
+ selection->clear();
+ selection->add(item_copied);
+ selection->add(unionResult);
+ sp_selected_path_union_skip_undo(selection->desktop());
+ selection->add(father);
+ Inkscape::GC::release(copy2);
+ did = true;
+ }
+ }
+ } else if (mode == SPRAY_MODE_CLONE) {
+ Geom::OptRect a = item->getBounds(item->i2doc_affine());
+ if (a) {
+ if(_fid<=population) {
+ SPItem *item_copied;
+ SPDocument *doc = SP_OBJECT_DOCUMENT(item);
+ Inkscape::XML::Document* xml_doc = doc->getReprDoc();
+ Inkscape::XML::Node *old_repr = SP_OBJECT_REPR(item);
+ Inkscape::XML::Node *parent = old_repr->parent();
+
+ // Creation of the clone
+ Inkscape::XML::Node *clone = xml_doc->createElement("svg:use");
+ // Ad the clone to the list of the father's sons
+ parent->appendChild(clone);
+ // Generates the link between father and son attributes
+ clone->setAttribute("xlink:href", g_strdup_printf("#%s", old_repr->attribute("id")), false);
+
+ SPObject *clone_object = doc->getObjectByRepr(clone);
+ // conversion object->item
+ item_copied = (SPItem *) clone_object;
+ Geom::Point center=item->getCenter();
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(_scale,_scale));
+ sp_spray_scale_rel(center,desktop,item_copied, Geom::Scale(scale,scale));
+ sp_spray_rotate_rel(center,desktop,item_copied, Geom::Rotate(angle));
+ Geom::Point move = (Geom::Point(cos(tilt)*cos(dp)*dr/(1-ratio)+sin(tilt)*sin(dp)*dr/(1+ratio),-sin(tilt)*cos(dp)*dr/(1-ratio)+cos(tilt)*sin(dp)*dr/(1+ratio)))+(p-a->midpoint());
+ sp_item_move_rel(item_copied, Geom::Translate(move[Geom::X], -move[Geom::Y]));
+
+ Inkscape::GC::release(clone);
-bool
-sp_spray_color_recursive (guint mode, SPItem *item, SPItem *item_at_point,
- guint32 fill_goal, bool do_fill,
- guint32 stroke_goal, bool do_stroke,
- float opacity_goal, bool do_opacity,
- bool do_blur, bool reverse,
- Geom::Point p, double radius, double force,
- bool do_h, bool do_s, bool do_l, bool do_o)
-{
- bool did = false;
+ did = true;
+ }
+ }
+ }
return did;
}
-
-bool
-sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::Point vector, bool reverse)
+bool sp_spray_dilate(SPSprayContext *tc, Geom::Point /*event_p*/, Geom::Point p, Geom::Point vector, bool reverse)
{
Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop);
SPDesktop *desktop = SP_EVENT_CONTEXT(tc)->desktop;
@@ -738,23 +627,6 @@ sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::P
guint32 stroke_goal = sp_desktop_get_color_tool(desktop, "/tools/spray", false, &do_stroke);
double opacity_goal = sp_desktop_get_master_opacity_tool(desktop, "/tools/spray", &do_opacity);
if (reverse) {
-#if 0
- // HSL inversion
- float hsv[3];
- float rgb[3];
- sp_color_rgb_to_hsv_floatv (hsv,
- SP_RGBA32_R_F(fill_goal),
- SP_RGBA32_G_F(fill_goal),
- SP_RGBA32_B_F(fill_goal));
- sp_color_hsv_to_rgb_floatv (rgb, hsv[0]<.5? hsv[0]+.5 : hsv[0]-.5, 1 - hsv[1], 1 - hsv[2]);
- fill_goal = SP_RGBA32_F_COMPOSE(rgb[0], rgb[1], rgb[2], 1);
- sp_color_rgb_to_hsv_floatv (hsv,
- SP_RGBA32_R_F(stroke_goal),
- SP_RGBA32_G_F(stroke_goal),
- SP_RGBA32_B_F(stroke_goal));
- sp_color_hsv_to_rgb_floatv (rgb, hsv[0]<.5? hsv[0]+.5 : hsv[0]-.5, 1 - hsv[1], 1 - hsv[2]);
- stroke_goal = SP_RGBA32_F_COMPOSE(rgb[0], rgb[1], rgb[2], 1);
-#else
// RGB inversion
fill_goal = SP_RGBA32_U_COMPOSE(
(255 - SP_RGBA32_R_U(fill_goal)),
@@ -766,7 +638,6 @@ sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::P
(255 - SP_RGBA32_G_U(stroke_goal)),
(255 - SP_RGBA32_B_U(stroke_goal)),
(255 - SP_RGBA32_A_U(stroke_goal)));
-#endif
opacity_goal = 1 - opacity_goal;
}
@@ -793,21 +664,11 @@ sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::P
SPItem *item = (SPItem *) items->data;
- /*if (is_color_modes (tc->mode)) {
- if (do_fill || do_stroke || do_opacity) {
- if (sp_spray_color_recursive (tc->mode, item, item_at_point,
- fill_goal, do_fill,
- stroke_goal, do_stroke,
- opacity_goal, do_opacity,
- tc->mode == SPRAY_MODE_BLUR, reverse,
- p, radius, color_force, tc->do_h, tc->do_s, tc->do_l, tc->do_o))
- did = true;
- }
- }else*/ if (is_transform_modes(tc->mode)) {
- if (sp_spray_dilate_recursive (desktop,selection, item, p, vector, tc->mode, radius, move_force, tc->population,tc->scale, tc->scale_min, tc->scale_max, reverse, move_mean, move_standard_deviation,tc->ratio,tc->tilt, tc->rot_min, tc->rot_max, tc->distrib))
+ if (is_transform_modes(tc->mode)) {
+ if (sp_spray_recursive (desktop,selection, item, p, vector, tc->mode, radius, move_force, tc->population,tc->scale, tc->scale_variation, reverse, move_mean, move_standard_deviation,tc->ratio,tc->tilt, tc->rotation_variation, tc->distrib))
did = true;
} else {
- if (sp_spray_dilate_recursive (desktop,selection, item, p, vector, tc->mode, radius, path_force, tc->population,tc->scale, tc->scale_min, tc->scale_max, reverse, path_mean, path_standard_deviation,tc->ratio,tc->tilt, tc->rot_min, tc->rot_max, tc->distrib))
+ if (sp_spray_recursive (desktop,selection, item, p, vector, tc->mode, radius, path_force, tc->population,tc->scale, tc->scale_variation, reverse, path_mean, path_standard_deviation,tc->ratio,tc->tilt, tc->rotation_variation, tc->distrib))
did = true;
}
}
@@ -815,8 +676,7 @@ sp_spray_dilate (SPSprayContext *tc, Geom::Point event_p, Geom::Point p, Geom::P
return did;
}
-void
-sp_spray_update_area (SPSprayContext *tc)
+void sp_spray_update_area(SPSprayContext *tc)
{
double radius = get_dilate_radius(tc);
Geom::Matrix const sm ( Geom::Scale(radius/(1-tc->ratio), radius/(1+tc->ratio)) );
sp_canvas_item_show(tc->dilate_area);
}
-void
-sp_spray_switch_mode (SPSprayContext *tc, gint mode, bool with_shift)
+void sp_spray_switch_mode(SPSprayContext *tc, gint mode, bool with_shift)
{
- SP_EVENT_CONTEXT(tc)->desktop->setToolboxSelectOneValue ("spray_tool_mode", mode); //sélectionne le bouton numéro "mode"
+ // select the button mode
+ SP_EVENT_CONTEXT(tc)->desktop->setToolboxSelectOneValue ("spray_tool_mode", mode);
// need to set explicitly, because the prefs may not have changed by the previous
tc->mode = mode;
sp_spray_update_cursor (tc, with_shift);
}
-void
-sp_spray_switch_mode_temporarily (SPSprayContext *tc, gint mode, bool with_shift)
+void sp_spray_switch_mode_temporarily(SPSprayContext *tc, gint mode, bool with_shift)
{
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
// Juggling about so that prefs have the old value but tc->mode and the button show new mode:
@@ -847,8 +706,7 @@ sp_spray_switch_mode_temporarily (SPSprayContext *tc, gint mode, bool with_shift
sp_spray_update_cursor (tc, with_shift);
}
-gint
-sp_spray_context_root_handler(SPEventContext *event_context,
+gint sp_spray_context_root_handler(SPEventContext *event_context,
GdkEvent *event)
{
SPSprayContext *tc = SP_SPRAY_CONTEXT(event_context);
sp_spray_dilate (tc, motion_w, motion_doc, motion_doc - tc->last_push, event->button.state & GDK_SHIFT_MASK? true : false);
//tc->last_push = motion_doc;
tc->has_dilated = true;
-
+
// it's slow, so prevent clogging up with events
gobble_motion_events(GDK_BUTTON1_MASK);
return TRUE;
Geom::Point const scroll_w(event->button.x,event->button.y);
Geom::Point const scroll_dt = desktop->point();;
Geom::Point motion_doc(desktop->dt2doc(scroll_dt));
- switch (event->scroll.direction)
+ switch (event->scroll.direction)
{
case GDK_SCROLL_UP:
{
tc->is_dilating = true;
tc->has_dilated = false;
if(tc->is_dilating && !event_context->space_panning)
-
+
sp_spray_dilate (tc, scroll_w, desktop->dt2doc(scroll_dt), Geom::Point(0,0),false);
-
+
tc->has_dilated=true;
tc->population=temp;
desktop->setToolboxAdjustmentValue ("population", tc->population * 100);
-
+
ret = TRUE;
}
break;
tc->has_dilated = false;
switch (tc->mode) {
case SPRAY_MODE_COPY:
- sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
- SP_VERB_CONTEXT_SPRAY, _("Spray with copies"));
+ DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
+ SP_VERB_CONTEXT_SPRAY, _("Spray with copies"));
break;
case SPRAY_MODE_CLONE:
- sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
- SP_VERB_CONTEXT_SPRAY, _("Spray with clones"));
+ DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
+ SP_VERB_CONTEXT_SPRAY, _("Spray with clones"));
break;
case SPRAY_MODE_SINGLE_PATH:
- sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
- SP_VERB_CONTEXT_SPRAY, _("Spray in single path"));
+ DocumentUndo::done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop),
+ SP_VERB_CONTEXT_SPRAY, _("Spray in single path"));
break;
}
}
case GDK_j: if (MOD__SHIFT_ONLY) {
sp_spray_switch_mode(tc, SPRAY_MODE_COPY, MOD__SHIFT);
ret = TRUE;
- }
+ }
case GDK_J: if (MOD__SHIFT_ONLY) {
sp_spray_switch_mode(tc, SPRAY_MODE_COPY, MOD__SHIFT);
ret = TRUE;
}
-
+
break;
case GDK_m:
case GDK_M:
case GDK_0:
-
+
break;
case GDK_i:
case GDK_I:
ret = TRUE;
}
break;
-
+
case GDK_l: if (MOD__SHIFT_ONLY) {
sp_spray_switch_mode(tc, SPRAY_MODE_CLONE, MOD__SHIFT);
ret = TRUE;
}
-
+
case GDK_L:
if (MOD__SHIFT_ONLY) {
sp_spray_switch_mode(tc, SPRAY_MODE_CLONE, MOD__SHIFT);
fill-column:99
End:
*/
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :