summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 67afcef)
raw | patch | inline | side by side (parent: 67afcef)
author | cilix42 <cilix42@users.sourceforge.net> | |
Wed, 19 Mar 2008 10:37:50 +0000 (10:37 +0000) | ||
committer | cilix42 <cilix42@users.sourceforge.net> | |
Wed, 19 Mar 2008 10:37:50 +0000 (10:37 +0000) |
12 files changed:
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index 9ee920c1b21ab5c26823b75b1d60791798489a7d..7414fcd770e406977c1b858096008c7649023c35 100644 (file)
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -186,10 +186,6 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g
ec->shape_repr = 0;
}
- SPDocument *doc = sp_desktop_document(bc->desktop);
- doc->persps_sel.clear();
- doc->persps_sel = persp3d_currently_selected_persps();
-
SPItem *item = selection->singleItem();
if (item) {
ec->shape_knot_holder = sp_item_knot_holder(item, ec->desktop);
@@ -201,9 +197,9 @@ static void sp_box3d_context_selection_changed(Inkscape::Selection *selection, g
}
}
- if (doc->persps_sel.size() == 1) {
+ if (selection->perspList().size() == 1) {
// selecting a single box changes the current perspective
- doc->current_persp3d = *(doc->persps_sel.begin());
+ ec->desktop->doc()->current_persp3d = selection->perspList().front();
}
}
@@ -509,7 +505,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
ret = TRUE;
}
if (MOD__SHIFT_ONLY) {
- persp3d_toggle_VPs(persp3d_currently_selected_persps(), Proj::X);
+ persp3d_toggle_VPs(selection->perspList(), Proj::X);
bc->_vpdrag->updateLines(); // FIXME: Shouldn't this be done automatically?
ret = true;
}
@@ -518,7 +514,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
case GDK_y:
case GDK_Y:
if (MOD__SHIFT_ONLY) {
- persp3d_toggle_VPs(persp3d_currently_selected_persps(), Proj::Y);
+ persp3d_toggle_VPs(selection->perspList(), Proj::Y);
bc->_vpdrag->updateLines(); // FIXME: Shouldn't this be done automatically?
ret = true;
}
@@ -527,7 +523,7 @@ static gint sp_box3d_context_root_handler(SPEventContext *event_context, GdkEven
case GDK_z:
case GDK_Z:
if (MOD__SHIFT_ONLY) {
- persp3d_toggle_VPs(persp3d_currently_selected_persps(), Proj::Z);
+ persp3d_toggle_VPs(selection->perspList(), Proj::Z);
bc->_vpdrag->updateLines(); // FIXME: Shouldn't this be done automatically?
ret = true;
}
diff --git a/src/box3d-side.cpp b/src/box3d-side.cpp
index c20b7a8646f2172603aba0cb15463a2daa6771c6..4cd3765c90967aeda7cbb4adf28988a263ccf7b4 100644 (file)
--- a/src/box3d-side.cpp
+++ b/src/box3d-side.cpp
static void box3d_side_set_shape (SPShape *shape);
-static Proj::Pt3 box3d_side_corner (Box3DSide *side, guint index);
-static std::vector<Proj::Pt3> box3d_side_corners (Box3DSide *side);
+static void box3d_side_compute_corner_ids(Box3DSide *side, unsigned int corners[4]);
static SPShapeClass *parent_class;
return;
}
- if (!SP_IS_BOX3D(SP_OBJECT(side)->parent)) {
+ SPObject *parent = SP_OBJECT(side)->parent;
+ if (!SP_IS_BOX3D(parent)) {
g_warning ("Parent of 3D box side is not a 3D box.\n");
return;
}
+ SPBox3D *box = SP_BOX3D(parent);
Persp3D *persp = box3d_side_perspective(side);
if (!persp) {
// compute the coordinates of the corners in P^3, project them onto the canvas, and draw the
// resulting path.
- std::vector<Proj::Pt3> corners = box3d_side_corners (side);
+ unsigned int corners[4];
+ box3d_side_compute_corner_ids(side, corners);
- NR::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(shape)));
-
- // FIXME: This can better be implemented by using box3d_get_corner
- sp_curve_moveto (c, persp->tmat.image(corners[0]).affine() * i2d);
- sp_curve_lineto (c, persp->tmat.image(corners[1]).affine() * i2d);
- sp_curve_lineto (c, persp->tmat.image(corners[2]).affine() * i2d);
- sp_curve_lineto (c, persp->tmat.image(corners[3]).affine() * i2d);
+ sp_curve_moveto (c, box3d_get_corner_screen(box, corners[0]));
+ sp_curve_lineto (c, box3d_get_corner_screen(box, corners[1]));
+ sp_curve_lineto (c, box3d_get_corner_screen(box, corners[2]));
+ sp_curve_lineto (c, box3d_get_corner_screen(box, corners[3]));
sp_curve_closepath (c);
sp_shape_perform_path_effect(c, SP_SHAPE (side));
return pstring->str;
}
-static Proj::Pt3
-box3d_side_corner (Box3DSide *side, guint index) {
- SPBox3D *box = SP_BOX3D(SP_OBJECT_PARENT(side));
- return Proj::Pt3 ((index & 0x1) ? box->orig_corner7[Proj::X] : box->orig_corner0[Proj::X],
- (index & 0x2) ? box->orig_corner7[Proj::Y] : box->orig_corner0[Proj::Y],
- (index & 0x4) ? box->orig_corner7[Proj::Z] : box->orig_corner0[Proj::Z],
- 1.0);
-}
-
-static std::vector<Proj::Pt3>
-box3d_side_corners (Box3DSide *side) {
- std::vector<Proj::Pt3> corners;
+static void
+box3d_side_compute_corner_ids(Box3DSide *side, unsigned int corners[4]) {
Box3D::Axis orth = Box3D::third_axis_direction (side->dir1, side->dir2);
- unsigned int i0 = (side->front_or_rear ? orth : 0);
- unsigned int i1 = i0 ^ side->dir1;
- unsigned int i2 = i0 ^ side->dir1 ^ side->dir2;
- unsigned int i3 = i0 ^ side->dir2;
-
- corners.push_back (box3d_side_corner (side, i0));
- corners.push_back (box3d_side_corner (side, i1));
- corners.push_back (box3d_side_corner (side, i2));
- corners.push_back (box3d_side_corner (side, i3));
- return corners;
+
+ corners[0] = (side->front_or_rear ? orth : 0);
+ corners[1] = corners[0] ^ side->dir1;
+ corners[2] = corners[0] ^ side->dir1 ^ side->dir2;
+ corners[3] = corners[0] ^ side->dir2;
}
Persp3D *
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 5beee4accab9e3fb439ddb846bdadb88c99ea5fd..f5745210171ed19dc8d9c940177817d4b7f51559 100644 (file)
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
#include "prefs-utils.h"
#include "desktop.h"
+#include "desktop-handles.h"
#include "macros.h"
static void box3d_class_init(SPBox3DClass *klass);
Persp3D *transf_persp;
if (!persp3d_has_all_boxes_in_selection (persp)) {
- std::list<SPBox3D *> sel = persp3d_selected_boxes (persp);
+ std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
/* create a new perspective as a copy of the current one and link the selected boxes to it */
transf_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp);
- for (std::list<SPBox3D *>::iterator b = sel.begin(); b != sel.end(); ++b) {
+ for (std::list<SPBox3D *>::iterator b = selboxes.begin(); b != selboxes.end(); ++b) {
box3d_switch_perspectives(*b, persp, transf_persp);
}
} else {
}
NR::Point
-box3d_get_corner_screen (SPBox3D const *box, guint id) {
+box3d_get_corner_screen (SPBox3D const *box, guint id, bool item_coords) {
Proj::Pt3 proj_corner (box3d_get_proj_corner (box, id));
if (!box3d_get_perspective(box)) {
return NR::Point (NR_HUGE, NR_HUGE);
}
- return box3d_get_perspective(box)->tmat.image(proj_corner).affine();
+ NR::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box)));
+ if (item_coords) {
+ return box3d_get_perspective(box)->tmat.image(proj_corner).affine() * i2d.inverse();
+ } else {
+ return box3d_get_perspective(box)->tmat.image(proj_corner).affine();
+ }
}
Proj::Pt3
if (!box3d_get_perspective(box)) {
return NR::Point (NR_HUGE, NR_HUGE);
}
- return box3d_get_perspective(box)->tmat.image(proj_center).affine();
+ NR::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(box)));
+ return box3d_get_perspective(box)->tmat.image(proj_center).affine() * i2d.inverse();
}
/*
box3d_XY_axes_are_swapped (SPBox3D *box) {
Persp3D *persp = box3d_get_perspective(box);
g_return_val_if_fail(persp, false);
- Box3D::PerspectiveLine l1(box3d_get_corner_screen(box, 3), Proj::X, persp);
- Box3D::PerspectiveLine l2(box3d_get_corner_screen(box, 3), Proj::Y, persp);
+ Box3D::PerspectiveLine l1(box3d_get_corner_screen(box, 3, false), Proj::X, persp);
+ Box3D::PerspectiveLine l2(box3d_get_corner_screen(box, 3, false), Proj::Y, persp);
NR::Point v1(l1.direction());
NR::Point v2(l2.direction());
v1.normalize();
box3d_set_new_z_orders_case2 (SPBox3D *box, int z_orders[6], Box3D::Axis central_axis, Box3D::Axis /*infinite_axis*/) {
Persp3D *persp = box3d_get_perspective(box);
- NR::Point c3(box3d_get_corner_screen(box, 3));
+ NR::Point c3(box3d_get_corner_screen(box, 3, false));
NR::Point xdir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::X));
NR::Point ydir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::Y));
NR::Point zdir(persp3d_get_PL_dir_from_pt(persp, c3, Proj::Z));
int z_orders[6];
- NR::Point c3(box3d_get_corner_screen(box, 3));
+ NR::Point c3(box3d_get_corner_screen(box, 3, false));
// determine directions from corner3 to the VPs
int num_finite = 0;
Geom::Point vpy(vp_y[NR::X], vp_y[NR::Y]);
Geom::Point vpz(vp_z[NR::X], vp_z[NR::Y]);
- NR::Point c3 = box3d_get_corner_screen(box, 3);
+ NR::Point c3 = box3d_get_corner_screen(box, 3, false);
Geom::Point corner3(c3[NR::X], c3[NR::Y]);
if (box3d_half_line_crosses_joining_line (corner3, vpx, vpy, vpz)) {
central_corner = central_corner ^ Box3D::XYZ;
}
- NR::Point c1(box3d_get_corner_screen(box, 1));
- NR::Point c2(box3d_get_corner_screen(box, 2));
- NR::Point c7(box3d_get_corner_screen(box, 7));
+ NR::Point c1(box3d_get_corner_screen(box, 1, false));
+ NR::Point c2(box3d_get_corner_screen(box, 2, false));
+ NR::Point c7(box3d_get_corner_screen(box, 7, false));
Geom::Point corner1(c1[NR::X], c1[NR::Y]);
Geom::Point corner2(c2[NR::X], c2[NR::Y]);
@@ -1185,8 +1192,8 @@ box3d_pt_lies_in_PL_sector (SPBox3D const *box, NR::Point const &pt, int id1, in
Persp3D *persp = box3d_get_perspective(box);
// the two corners
- NR::Point c1(box3d_get_corner_screen(box, id1));
- NR::Point c2(box3d_get_corner_screen(box, id2));
+ NR::Point c1(box3d_get_corner_screen(box, id1, false));
+ NR::Point c2(box3d_get_corner_screen(box, id2, false));
int ret = 0;
if (persp3d_VP_is_finite(persp, Box3D::toProj(axis))) {
@@ -1201,7 +1208,7 @@ box3d_pt_lies_in_PL_sector (SPBox3D const *box, NR::Point const &pt, int id1, in
if (pl1.lie_on_same_side(pt, c2) && pl2.lie_on_same_side(pt, c1)) {
// test whether pt lies "towards" or "away from" the VP
Box3D::Line edge(c1,c2);
- NR::Point c3(box3d_get_corner_screen(box, id1 ^ axis));
+ NR::Point c3(box3d_get_corner_screen(box, id1 ^ axis, false));
if (edge.lie_on_same_side(pt, c3)) {
ret = 1;
} else {
persp3d_set_box_transformed(persp, box, true);
}
+static void
+box3d_extract_boxes_rec(SPObject *obj, std::list<SPBox3D *> &boxes) {
+ if (SP_IS_BOX3D(obj)) {
+ boxes.push_back(SP_BOX3D(obj));
+ } else if (SP_IS_GROUP(obj)) {
+ for (SPObject *child = sp_object_first_child(obj); child != NULL; child = SP_OBJECT_NEXT(child) ) {
+ box3d_extract_boxes_rec(child, boxes);
+ }
+ }
+}
+
+std::list<SPBox3D *>
+box3d_extract_boxes(SPObject *obj) {
+ std::list<SPBox3D *> boxes;
+ box3d_extract_boxes_rec(obj, boxes);
+ return boxes;
+}
+
Persp3D *
box3d_get_perspective(SPBox3D const *box) {
return box->persp_ref->getObject();
@@ -1316,8 +1341,8 @@ box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp,
box->orig_corner7.normalize();
double z0 = box->orig_corner0[Proj::Z];
double z7 = box->orig_corner7[Proj::Z];
- NR::Point corner0_screen = box3d_get_corner_screen(box, 0);
- NR::Point corner7_screen = box3d_get_corner_screen(box, 7);
+ NR::Point corner0_screen = box3d_get_corner_screen(box, 0, false);
+ NR::Point corner7_screen = box3d_get_corner_screen(box, 7, false);
box->orig_corner0 = new_persp->tmat.preimage(corner0_screen, z0, Proj::Z);
box->orig_corner7 = new_persp->tmat.preimage(corner7_screen, z7, Proj::Z);
static inline void
box3d_push_back_corner_pair(SPBox3D *box, std::list<std::pair<Geom::Point, Geom::Point> > &pts, int c1, int c2) {
- pts.push_back(std::make_pair(box3d_get_corner_screen(box, c1).to_2geom(),
- box3d_get_corner_screen(box, c2).to_2geom()));
+ pts.push_back(std::make_pair(box3d_get_corner_screen(box, c1, false).to_2geom(),
+ box3d_get_corner_screen(box, c2, false).to_2geom()));
}
void
diff --git a/src/box3d.h b/src/box3d.h
index d9fd540b68d9217087a11b6c89678f44a9032fb6..bc88e6257931375ae667bf50abd4fe96c7ba0ee9 100644 (file)
--- a/src/box3d.h
+++ b/src/box3d.h
void box3d_position_set (SPBox3D *box);
Proj::Pt3 box3d_get_proj_corner (SPBox3D const *box, guint id);
-NR::Point box3d_get_corner_screen (SPBox3D const *box, guint id);
+NR::Point box3d_get_corner_screen (SPBox3D const *box, guint id, bool item_coords = true);
Proj::Pt3 box3d_get_proj_center (SPBox3D *box);
NR::Point box3d_get_center_screen (SPBox3D *box);
void box3d_remove_from_selection(SPBox3D *box);
void box3d_mark_transformed(SPBox3D *box);
+std::list<SPBox3D *> box3d_extract_boxes(SPObject *obj);
+
Persp3D *box3d_get_perspective(SPBox3D const *box);
void box3d_switch_perspectives(SPBox3D *box, Persp3D *old_persp, Persp3D *new_persp, bool recompute_corners = false);
diff --git a/src/document.h b/src/document.h
index 8a4e65bb373fe57541f868a79aca6c9aafcf1838..b0d6afecb1be9b8dafce41b7afe1c778ac4af2be 100644 (file)
--- a/src/document.h
+++ b/src/document.h
GSList *perspectives;
Persp3D *current_persp3d; // "currently active" perspective (e.g., newly created boxes are attached to this one)
- std::set<Persp3D *> persps_sel; // perspectives associated to currently selected boxes
void add_persp3d (Persp3D * const persp);
void remove_persp3d (Persp3D * const persp);
diff --git a/src/object-edit.cpp b/src/object-edit.cpp
index da5672ca261de302afa06c558f0e90eb575d2b7a..b3d661586a2b08b2f2e012052f8779e6706bb1e7 100644 (file)
--- a/src/object-edit.cpp
+++ b/src/object-edit.cpp
static NR::Point box3d_knot_get(SPItem *item, guint knot_id)
{
- g_assert(item != NULL);
- SPBox3D *box = SP_BOX3D(item);
-
- NR::Matrix const i2d (sp_item_i2d_affine (item));
- return box3d_get_corner_screen(box, knot_id) * i2d;
+ return box3d_get_corner_screen(SP_BOX3D(item), knot_id);
}
static void box3d_knot_set(SPItem *item, guint knot_id, NR::Point const &new_pos, NR::Point const &/*origin*/, guint state)
@@ -559,8 +555,7 @@ static void box3d_knot_set(SPItem *item, guint knot_id, NR::Point const &new_pos
static NR::Point box3d_knot_center_get (SPItem *item)
{
- NR::Matrix const i2d (sp_item_i2d_affine (item));
- return box3d_get_center_screen (SP_BOX3D(item)) * i2d;
+ return box3d_get_center_screen (SP_BOX3D(item));
}
static void box3d_knot_center_set(SPItem *item, NR::Point const &new_pos, NR::Point const &origin, guint state)
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index e5cade661d151f3efb1c12e6417fdc221ca529ab..e647af6987499fd793c039b99d3e13cf51cfa0de 100644 (file)
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
/* toggle VPs for the same axis in all perspectives of a given list */
void
-persp3d_toggle_VPs (std::set<Persp3D *> p, Proj::Axis axis) {
- for (std::set<Persp3D *>::iterator i = p.begin(); i != p.end(); ++i) {
+persp3d_toggle_VPs (std::list<Persp3D *> p, Proj::Axis axis) {
+ for (std::list<Persp3D *>::iterator i = p.begin(); i != p.end(); ++i) {
persp3d_toggle_VP((*i), axis, false);
}
sp_document_done(sp_desktop_document(inkscape_active_desktop()), SP_VERB_CONTEXT_3DBOX,
persp3d_update_box_displays (persp);
}
-/* returns a std::set() of all perspectives of the currently selected boxes */
-std::set<Persp3D *>
-persp3d_currently_selected_persps () {
- Inkscape::Selection *selection = sp_desktop_selection(inkscape_active_desktop());
-
- std::set<Persp3D *> p;
- for (GSList *i = (GSList *) selection->itemList(); i != NULL; i = i->next) {
- if (SP_IS_BOX3D (i->data)) {
- p.insert(box3d_get_perspective(SP_BOX3D(i->data)));
- }
- }
- return p;
-}
-
/* checks whether all boxes linked to this perspective are currently selected */
bool
persp3d_has_all_boxes_in_selection (Persp3D *persp) {
- const GSList *selection = sp_desktop_selection (inkscape_active_desktop())->itemList();
+ std::list<SPBox3D *> selboxes = sp_desktop_selection(inkscape_active_desktop())->box3DList();
for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
- if (g_slist_find((GSList *) selection, *i) == NULL) {
+ if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) {
// we have an unselected box in the perspective
return false;
}
return true;
}
-std::list<SPBox3D *>
-persp3d_selected_boxes (Persp3D *persp) {
- const GSList *selection = sp_desktop_selection (inkscape_active_desktop())->itemList();
- std::list<SPBox3D *> sel;
+// TODO: Check where we can use pass-by-reference (or so) instead of recreating all the lists afresh.
+std::map<Persp3D *, std::list<SPBox3D *> >
+persp3d_unselected_boxes(Inkscape::Selection *selection) {
+ std::list<Persp3D *> plist = selection->perspList();
+ std::map<Persp3D *, std::list<SPBox3D *> > punsel;
+
+ std::list<Persp3D *>::iterator i;
+ std::vector<SPBox3D *>::iterator j;
+ // for all perspectives in the list ...
+ for (i = plist.begin(); i != plist.end(); ++i) {
+ Persp3D *persp = *i;
+ // ... and each box associated to it ...
+ for (j = persp->boxes.begin(); j != persp->boxes.end(); ++j) {
+ SPBox3D *box = *j;
+ // ... check whether it is unselected, and if so add it to the list
+ if (persp->boxes_transformed.find(box) == persp->boxes_transformed.end()) {
+ punsel[persp].push_back(box);
+ }
+ }
+ }
+ return punsel;
+}
- for (std::vector<SPBox3D *>::iterator i = persp->boxes.begin(); i != persp->boxes.end(); ++i) {
- if (g_slist_find((GSList *) selection, *i) != NULL) {
- sel.push_back(SP_BOX3D(*i));
+void
+persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection) {
+ std::map<Persp3D *, std::list<SPBox3D *> > punsel = persp3d_unselected_boxes(selection);
+
+ std::map<Persp3D *, std::list<SPBox3D *> >::iterator i;
+ std::list<SPBox3D *>::iterator j;
+ // for all perspectives in the list ...
+ for (i = punsel.begin(); i != punsel.end(); ++i) {
+ Persp3D *persp = (*i).first;
+ // ... if the perspective has unselected boxes ...
+ if (!(*i).second.empty()) {
+ // create a new perspective and move these boxes over
+ Persp3D * new_persp = persp3d_create_xml_element (SP_OBJECT_DOCUMENT(persp), persp);
+ for (j = (*i).second.begin(); j != (*i).second.end(); ++j) {
+ SPBox3D *box = *j;
+ box3d_switch_perspectives(box, persp, new_persp);
+ }
}
}
- return sel;
}
/* some debugging stuff follows */
g_print ("\n======================================\n");
g_print ("Selected perspectives and their boxes:\n");
- std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps();
+ std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList();
- for (std::set<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) {
+ for (std::list<Persp3D *>::iterator j = sel_persps.begin(); j != sel_persps.end(); ++j) {
Persp3D *persp = SP_PERSP3D(*j);
g_print (" %s (%d): ", SP_OBJECT_REPR(persp)->attribute("id"), persp->my_counter);
for (std::map<SPBox3D *, bool>::iterator i = persp->boxes_transformed.begin();
diff --git a/src/persp3d.h b/src/persp3d.h
index 4819a52e997073aa29131d4a76b69310dbb3bc35..271b42459fd971caf6874b96a965a37b0c17f598 100644 (file)
--- a/src/persp3d.h
+++ b/src/persp3d.h
#define SP_IS_PERSP3D(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SP_TYPE_PERSP3D))
#define SP_IS_PERSP3D_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SP_TYPE_PERSP3D))
-#include <set>
+#include <list>
#include <vector>
#include <map>
#include "sp-item.h"
double persp3d_get_infinite_angle (Persp3D *persp, Proj::Axis axis);
bool persp3d_VP_is_finite (Persp3D *persp, Proj::Axis axis);
void persp3d_toggle_VP (Persp3D *persp, Proj::Axis axis, bool set_undo = true);
-void persp3d_toggle_VPs (std::set<Persp3D *>, Proj::Axis axis);
+void persp3d_toggle_VPs (std::list<Persp3D *>, Proj::Axis axis);
void persp3d_set_VP_state (Persp3D *persp, Proj::Axis axis, Proj::VPState state);
void persp3d_rotate_VP (Persp3D *persp, Proj::Axis axis, double angle, bool alt_pressed); // angle is in degrees
void persp3d_update_with_point (Persp3D *persp, Proj::Axis const axis, Proj::Pt2 const &new_image);
Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3D *dup = NULL);
Persp3D * persp3d_document_first_persp (SPDocument *document);
-std::set<Persp3D *> persp3d_currently_selected_persps();
bool persp3d_has_all_boxes_in_selection (Persp3D *persp);
-std::list<SPBox3D *> persp3d_selected_boxes (Persp3D *persp);
+std::map<Persp3D *, std::list<SPBox3D *> > persp3d_unselected_boxes(Inkscape::Selection *selection);
+void persp3d_split_perspectives_according_to_selection(Inkscape::Selection *selection);
void persp3d_print_debugging_info (Persp3D *persp);
void persp3d_print_debugging_info_all(SPDocument *doc);
diff --git a/src/selection.cpp b/src/selection.cpp
index d3b667a128a0e76cdd5650ed276898bc41af71ba..41540c95c99b982333230c8fbafd614b8da70113 100644 (file)
--- a/src/selection.cpp
+++ b/src/selection.cpp
#include "sp-path.h"
#include "sp-item-group.h"
#include "box3d.h"
+#include "box3d.h"
+#include "persp3d.h"
#include <sigc++/functors/mem_fun.h>
@@ -159,6 +161,27 @@ void Selection::add(SPObject *obj, bool persist_selection_context/* = false */)
_emitChanged(persist_selection_context);
}
+void Selection::add_box_perspective(SPBox3D *box) {
+ Persp3D *persp = box3d_get_perspective(box);
+ std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
+ if (p != _persps.end()) {
+ (*p).second++;
+ } else {
+ _persps[persp] = 1;
+ }
+}
+
+void Selection::add_3D_boxes_recursively(SPObject *obj) {
+ std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
+
+ for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
+ SPBox3D *box = *i;
+ box3d_add_to_selection(box);
+ _3dboxes.push_back(box);
+ add_box_perspective(box);
+ }
+}
+
void Selection::_add(SPObject *obj) {
// unselect any of the item's ancestors and descendants which may be selected
// (to prevent double-selection)
_objs = g_slist_prepend(_objs, obj);
- if (SP_IS_BOX3D(obj)) {
- // keep track of selected boxes for transformations
- box3d_add_to_selection(SP_BOX3D(obj));
- }
+ add_3D_boxes_recursively(obj);
_release_connections[obj] = obj->connectRelease(sigc::mem_fun(*this, (void (Selection::*)(SPObject *))&Selection::remove));
_modified_connections[obj] = obj->connectModified(sigc::mem_fun(*this, &Selection::_schedule_modified));
_emitChanged();
}
+void Selection::remove_box_perspective(SPBox3D *box) {
+ Persp3D *persp = box3d_get_perspective(box);
+ std::map<Persp3D *, unsigned int>::iterator p = _persps.find(persp);
+ if (p == _persps.end()) {
+ g_print ("Warning! Trying to remove unselected perspective from selection!\n");
+ return;
+ }
+ if ((*p).second > 1) {
+ _persps[persp]--;
+ } else {
+ _persps.erase(p);
+ }
+}
+
+void Selection::remove_3D_boxes_recursively(SPObject *obj) {
+ std::list<SPBox3D *> boxes = box3d_extract_boxes(obj);
+
+ for (std::list<SPBox3D *>::iterator i = boxes.begin(); i != boxes.end(); ++i) {
+ SPBox3D *box = *i;
+ box3d_remove_from_selection(box);
+ std::list<SPBox3D *>::iterator b = std::find(_3dboxes.begin(), _3dboxes.end(), box);
+ if (b == _3dboxes.end()) {
+ g_print ("Warning! Trying to remove unselected box from selection.\n");
+ return;
+ }
+ _3dboxes.erase(b);
+ remove_box_perspective(box);
+ }
+}
+
void Selection::_remove(SPObject *obj) {
_modified_connections[obj].disconnect();
_modified_connections.erase(obj);
_release_connections[obj].disconnect();
_release_connections.erase(obj);
- if (SP_IS_BOX3D(obj)) {
- // keep track of selected boxes for transformations
- box3d_remove_from_selection(SP_BOX3D(obj));
- }
+ remove_3D_boxes_recursively(obj);
_objs = g_slist_remove(_objs, obj);
}
return _reprs;
}
+std::list<Persp3D *> const Selection::perspList() {
+ std::list<Persp3D *> pl;
+ for (std::map<Persp3D *, unsigned int>::iterator p = _persps.begin(); p != _persps.end(); ++p) {
+ pl.push_back((*p).first);
+ }
+ return pl;
+}
+
+std::list<SPBox3D *> const Selection::box3DList() {
+ return _3dboxes;
+}
+
SPObject *Selection::single() {
if ( _objs != NULL && _objs->next == NULL ) {
return reinterpret_cast<SPObject *>(_objs->data);
diff --git a/src/selection.h b/src/selection.h
index 58204160b7de9e1972728912f3f4e27c7a4670bc..3d45c171d95021093c98eba4aef4c098a1f61777 100644 (file)
--- a/src/selection.h
+++ b/src/selection.h
#include <vector>
#include <map>
+#include <list>
#include <sigc++/sigc++.h>
#include "libnr/nr-rect.h"
#include "sp-item.h"
class SPItem;
+class SPBox3D;
+class Persp3D;
namespace Inkscape {
namespace XML {
/// method for that
GSList const *reprList();
+ /* list of all perspectives which have a 3D box in the current selection
+ (these may also be nested in groups) */
+ std::list<Persp3D *> const perspList();
+
+ std::list<SPBox3D *> const box3DList();
+
/** @brief Returns the number of layers in which there are selected objects */
guint numberOfLayers();
mutable GSList *_reprs;
mutable GSList *_items;
+ void add_box_perspective(SPBox3D *box);
+ void add_3D_boxes_recursively(SPObject *obj);
+ void remove_box_perspective(SPBox3D *box);
+ void remove_3D_boxes_recursively(SPObject *obj);
+
+ std::map<Persp3D *, unsigned int> _persps;
+ std::list<SPBox3D *> _3dboxes;
+
GC::soft_ptr<SPDesktop> _desktop;
SPObject* _selection_context;
guint _flags;
diff --git a/src/sp-item-group.cpp b/src/sp-item-group.cpp
index 5ae5713ca429fcac4a87b29ba05b02fc77ca38bf..7969c1bc106c5e66168c77ab89473c6d8bf5b66d 100644 (file)
--- a/src/sp-item-group.cpp
+++ b/src/sp-item-group.cpp
#include "sp-mask.h"
#include "sp-path.h"
#include "box3d.h"
+#include "persp3d.h"
+#include "inkscape.h"
+#include "desktop-handles.h"
+#include "selection.h"
static void sp_group_class_init (SPGroupClass *klass);
static void sp_group_init (SPGroup *group);
static void sp_group_bbox(SPItem const *item, NRRect *bbox, NR::Matrix const &transform, unsigned const flags);
static void sp_group_print (SPItem * item, SPPrintContext *ctx);
static gchar * sp_group_description (SPItem * item);
+static NR::Matrix sp_group_set_transform(SPItem *item, NR::Matrix const &xform);
static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int key, unsigned int flags);
static void sp_group_hide (SPItem * item, unsigned int key);
static void sp_group_snappoints (SPItem const *item, SnapPointsIter p);
item_class->bbox = sp_group_bbox;
item_class->print = sp_group_print;
item_class->description = sp_group_description;
+ item_class->set_transform = sp_group_set_transform;
item_class->show = sp_group_show;
item_class->hide = sp_group_hide;
item_class->snappoints = sp_group_snappoints;
return SP_GROUP(item)->group->getDescription();
}
+static NR::Matrix
+sp_group_set_transform(SPItem *item, NR::Matrix const &xform)
+{
+ SPGroup *group = SP_GROUP(item);
+
+ Inkscape::Selection *selection = sp_desktop_selection(inkscape_active_desktop());
+ persp3d_split_perspectives_according_to_selection(selection);
+
+ NR::Matrix last_trans;
+ sp_svg_transform_read(SP_OBJECT_REPR(item)->attribute("transform"), &last_trans);
+ NR::Matrix inc_trans = last_trans.inverse()*xform;
+
+ std::list<Persp3D *> plist = selection->perspList();
+ for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) {
+ persp3d_apply_affine_transformation(*i, inc_trans);
+ }
+
+ return xform;
+}
+
static void sp_group_set(SPObject *object, unsigned key, char const *value) {
SPGroup *group=SP_GROUP(object);
index 8ac019cb7921b5b829de8ec2d1ec215ec7f10828..5718c6cf272ea16188d2f51e4dbb5c7c3b6030c3 100644 (file)
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -2614,12 +2614,12 @@ box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis ax
g_object_set_data(dataKludge, "freeze_angle", GINT_TO_POINTER(TRUE));
//Persp3D *persp = document->current_persp3d;
- std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps();
+ std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList();
if (sel_persps.empty()) {
// this can happen when the document is created; we silently ignore it
return;
}
- Persp3D *persp = *(sel_persps.begin());
+ Persp3D *persp = sel_persps.front();
persp->tmat.set_infinite_direction (axis, adj->value);
SP_OBJECT(persp)->updateRepr();
static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction */*box3d_angle*/, Proj::Axis axis )
{
// TODO: Take all selected perspectives into account
- std::set<Persp3D *> sel_persps = persp3d_currently_selected_persps();
+ std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList();
if (sel_persps.empty()) {
// this can happen when the document is created; we silently ignore it
return;
}
- Persp3D *persp = *(sel_persps.begin());
+ Persp3D *persp = sel_persps.front();
bool set_infinite = gtk_toggle_action_get_active(act);
persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE);