From 209527815f6ad1b81d21bb3188947aef3d845010 Mon Sep 17 00:00:00 2001 From: cilix42 Date: Thu, 9 Aug 2007 23:49:05 +0000 Subject: [PATCH] Hold perspectives on document level rather than globally; this corrects the changes made in commit #15681 --- src/box3d-context.cpp | 27 +++++++------- src/box3d-face.cpp | 3 +- src/box3d-face.h | 2 +- src/box3d.cpp | 39 ++++++++++++--------- src/document.cpp | 78 +++++++++++++++++++++++++++++++++++++++++ src/document.h | 20 +++++++++++ src/inkscape.cpp | 16 --------- src/perspective3d.cpp | 78 +++++++++-------------------------------- src/perspective3d.h | 15 ++------ src/vanishing-point.cpp | 49 +++++++++++--------------- src/vanishing-point.h | 4 +-- src/widgets/toolbox.cpp | 18 +++++----- 12 files changed, 186 insertions(+), 163 deletions(-) diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp index 0ef2277ea..667bfca61 100644 --- a/src/box3d-context.cpp +++ b/src/box3d-context.cpp @@ -192,7 +192,7 @@ void sp_3dbox_context_selection_changed(Inkscape::Selection *selection, gpointer sp_repr_add_listener(shape_repr, &ec_shape_repr_events, ec); } if (SP_IS_3DBOX (item)) { - Box3D::Perspective3D::current_perspective = Box3D::get_persp_of_box (SP_3DBOX (item)); + bc->_vpdrag->document->current_perspective = bc->_vpdrag->document->get_persp_of_box (SP_3DBOX (item)); } } else { /* If several boxes sharing the same perspective are selected, @@ -200,11 +200,11 @@ void sp_3dbox_context_selection_changed(Inkscape::Selection *selection, gpointer std::set perspectives; for (GSList *i = (GSList *) selection->itemList(); i != NULL; i = i->next) { if (SP_IS_3DBOX (i->data)) { - perspectives.insert (Box3D::get_persp_of_box (SP_3DBOX (i->data))); + perspectives.insert (bc->_vpdrag->document->get_persp_of_box (SP_3DBOX (i->data))); } } if (perspectives.size() == 1) { - Box3D::Perspective3D::current_perspective = *(perspectives.begin()); + bc->_vpdrag->document->current_perspective = *(perspectives.begin()); } // TODO: What to do if several boxes with different perspectives are selected? } @@ -234,7 +234,7 @@ static void sp_3dbox_context_setup(SPEventContext *ec) sigc::bind(sigc::ptr_fun(&sp_3dbox_context_selection_changed), (gpointer)bc) ); - bc->_vpdrag = new Box3D::VPDrag(ec->desktop); + bc->_vpdrag = new Box3D::VPDrag(sp_desktop_document (ec->desktop)); if (prefs_get_int_attribute("tools.shapes", "selcue", 0) != 0) { ec->enableSelectionCue(); @@ -375,18 +375,18 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven // Without Ctrl, motion of the extruded corner is constrained to the // perspective line from drag_ptB to vanishing point Y. if (!bc->ctrl_dragged) { - bc->drag_ptC = Box3D::perspective_line_snap (bc->drag_ptB, Box3D::Z, motion_dt, Box3D::Perspective3D::current_perspective); + bc->drag_ptC = Box3D::perspective_line_snap (bc->drag_ptB, Box3D::Z, motion_dt, bc->_vpdrag->document->current_perspective); } else { bc->drag_ptC = motion_dt; } bc->drag_ptC = m.freeSnap(Inkscape::Snapper::SNAPPOINT_NODE, bc->drag_ptC, bc->item).getPoint(); if (bc->ctrl_dragged) { - Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Y, Box3D::Perspective3D::current_perspective); - Box3D::PerspectiveLine pl2 (bc->drag_ptB, Box3D::X, Box3D::Perspective3D::current_perspective); + Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Y, bc->_vpdrag->document->current_perspective); + Box3D::PerspectiveLine pl2 (bc->drag_ptB, Box3D::X, bc->_vpdrag->document->current_perspective); NR::Point corner1 = pl1.meet(pl2); - Box3D::PerspectiveLine pl3 (corner1, Box3D::X, Box3D::Perspective3D::current_perspective); - Box3D::PerspectiveLine pl4 (bc->drag_ptC, Box3D::Z, Box3D::Perspective3D::current_perspective); + Box3D::PerspectiveLine pl3 (corner1, Box3D::X, bc->_vpdrag->document->current_perspective); + Box3D::PerspectiveLine pl4 (bc->drag_ptC, Box3D::Z, bc->_vpdrag->document->current_perspective); bc->drag_ptB = pl3.meet(pl4); } } @@ -477,8 +477,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven case GDK_X: { if (MOD__CTRL) break; // Don't catch Ctrl+X ('cut') and Ctrl+Shift+X ('open XML editor') - // FIXME: Shouldn't we access _vpdrag->selection instead? - Inkscape::Selection *selection = sp_desktop_selection (bc->_vpdrag->desktop); + Inkscape::Selection *selection = sp_desktop_selection (inkscape_active_desktop()); for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { if (!SP_IS_3DBOX (i->data)) continue; sp_3dbox_switch_front_face (SP_3DBOX (i->data), Box3D::X); @@ -492,8 +491,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven case GDK_Y: { if (MOD__CTRL) break; // Don't catch Ctrl+Y ("redo") - // FIXME: Shouldn't we access _vpdrag->selection instead? - Inkscape::Selection *selection = sp_desktop_selection (bc->_vpdrag->desktop); + Inkscape::Selection *selection = sp_desktop_selection (inkscape_active_desktop()); for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { if (!SP_IS_3DBOX (i->data)) continue; sp_3dbox_switch_front_face (SP_3DBOX (i->data), Box3D::Y); @@ -507,8 +505,7 @@ static gint sp_3dbox_context_root_handler(SPEventContext *event_context, GdkEven case GDK_Z: { if (MOD__CTRL) break; // Don't catch Ctrl+Z ("undo") - // FIXME: Shouldn't we access _vpdrag->selection instead? - Inkscape::Selection *selection = sp_desktop_selection (bc->_vpdrag->desktop); + Inkscape::Selection *selection = sp_desktop_selection (inkscape_active_desktop()); for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { if (!SP_IS_3DBOX (i->data)) continue; sp_3dbox_switch_front_face (SP_3DBOX (i->data), Box3D::Z); diff --git a/src/box3d-face.cpp b/src/box3d-face.cpp index 55dc9b60a..096e7d7a6 100644 --- a/src/box3d-face.cpp +++ b/src/box3d-face.cpp @@ -121,6 +121,7 @@ Box3DFace::Box3DFace(Box3DFace const &box3dface) * * Note that several other functions rely on this precise order. */ +/*** void Box3DFace::set_face (NR::Point const A, NR::Point const C, Box3D::Axis const axis1, Box3D::Axis const axis2) { @@ -149,7 +150,7 @@ Box3DFace::set_face (NR::Point const A, NR::Point const C, Box3D::Axis const axi this->dir1 = axis1; this->dir2 = axis2; } - +***/ NR::Point Box3DFace::operator[](unsigned int i) { diff --git a/src/box3d-face.h b/src/box3d-face.h index 0e911cccf..e69c81e24 100644 --- a/src/box3d-face.h +++ b/src/box3d-face.h @@ -40,7 +40,7 @@ public: bool align_along_PL = false); ***/ void set_corners (NR::Point &A, NR::Point &B, NR::Point &C, NR::Point &D); - void set_face (NR::Point const A, NR::Point const C, Box3D::Axis const dir1, Box3D::Axis const dir2); + //void set_face (NR::Point const A, NR::Point const C, Box3D::Axis const dir1, Box3D::Axis const dir2); void hook_path_to_3dbox(SPPath * existing_path = NULL); void set_path_repr(); diff --git a/src/box3d.cpp b/src/box3d.cpp index 966d762a1..c9c03ea9c 100644 --- a/src/box3d.cpp +++ b/src/box3d.cpp @@ -110,19 +110,21 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr box->front_bits = 0x0; + if (repr->attribute ("inkscape:perspective") == NULL) { // we are creating a new box; link it to the current perspective - Box3D::Perspective3D::current_perspective->add_box (box); + document->current_perspective->add_box (box); } else { // create a new perspective that we can compare with existing ones Box3D::Perspective3D *persp = new Box3D::Perspective3D (Box3D::VanishingPoint (0,0), Box3D::VanishingPoint (0,0), - Box3D::VanishingPoint (0,0)); + Box3D::VanishingPoint (0,0), + document); sp_3dbox_update_perspective (persp, repr->attribute ("inkscape:perspective")); - Box3D::Perspective3D *comp = Box3D::Perspective3D::find_perspective (persp); + Box3D::Perspective3D *comp = document->find_perspective (persp); if (comp == NULL) { // perspective doesn't exist yet - Box3D::Perspective3D::add_perspective (persp); + document->add_perspective (persp); persp->add_box (box); } else { // link the box to the existing perspective and delete the temporary one @@ -166,7 +168,7 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr // document (e.g., after a 'redo' operation or after opening a file) and do so if necessary. sp_3dbox_link_to_existing_paths (box, repr); - sp_3dbox_set_ratios (box); + sp_3dbox_set_ratios (box, Box3D::XYZ); } static void @@ -181,7 +183,7 @@ sp_3dbox_release (SPObject *object) // FIXME: We do not duplicate perspectives if they are the same for several boxes. // Thus, don't delete the perspective when deleting a box but rather unlink the box from it. - Box3D::get_persp_of_box (box)->remove_box (box); + SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box)->remove_box (box); if (((SPObjectClass *) parent_class)->release) { ((SPObjectClass *) parent_class)->release (object); @@ -201,8 +203,11 @@ static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value) sp_3dbox_update_corner_with_value_from_svg (object, 5, value); break; case SP_ATTR_INKSCAPE_3DBOX_PERSPECTIVE: - sp_3dbox_update_perspective (Box3D::get_persp_of_box (SP_3DBOX (object)), value); + { + SP3DBox *box = SP_3DBOX (object); + sp_3dbox_update_perspective (SP_OBJECT_DOCUMENT (object)->get_persp_of_box (box), value); break; + } default: if (((SPObjectClass *) (parent_class))->set) { ((SPObjectClass *) (parent_class))->set(object, key, value); @@ -283,7 +288,7 @@ sp_3dbox_description(SPItem *item) void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes) { - Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D *persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); NR::Point pt; if (axes & Box3D::X) { @@ -305,7 +310,7 @@ void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes) void sp_3dbox_switch_front_face (SP3DBox *box, Box3D::Axis axis) { - if (Box3D::get_persp_of_box (box)->get_vanishing_point (axis)->is_finite()) { + if (SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box)->get_vanishing_point (axis)->is_finite()) { box->front_bits = box->front_bits ^ axis; } } @@ -386,7 +391,7 @@ normalized_angle (double angle) { static gdouble sp_3dbox_corner_angle_to_VP (SP3DBox *box, Box3D::Axis axis, guint extreme_corner) { - Box3D::VanishingPoint *vp = Box3D::get_persp_of_box (box)->get_vanishing_point (axis); + Box3D::VanishingPoint *vp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box)->get_vanishing_point (axis); NR::Point dir; if (vp->is_finite()) { @@ -403,7 +408,7 @@ bool sp_3dbox_recompute_z_orders (SP3DBox *box) { guint new_z_orders[6]; - Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D *persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); // TODO: Determine the front corner depending on the distance from VPs and/or the user presets guint front_corner = sp_3dbox_get_front_corner_id (box); @@ -523,7 +528,7 @@ sp_3dbox_link_to_existing_paths (SP3DBox *box, Inkscape::XML::Node *repr) { void sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes) { - Box3D::Perspective3D * persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D * persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); NR::Point A (box->corners[id ^ Box3D::XY]); if (Box3D::is_single_axis_direction (axes)) { @@ -563,7 +568,7 @@ sp_3dbox_move_corner_in_Z_direction (SP3DBox *box, guint id, NR::Point pt, bool { if (!constrained) sp_3dbox_move_corner_in_XY_plane (box, id, pt, Box3D::XY); - Box3D::Perspective3D * persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D * persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); /* set the four corners of the face containing corners[id] */ box->corners[id] = Box3D::PerspectiveLine (box->corners[id], Box3D::Z, persp).closest_to(pt); @@ -609,7 +614,7 @@ sp_3dbox_reshape_edge_after_VP_toggling (SP3DBox *box, const guint corner, const void sp_3dbox_reshape_after_VP_toggling (SP3DBox *box, Box3D::Axis axis) { - Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D *persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); std::pair dirs = Box3D::get_remaining_axes (axis); sp_3dbox_reshape_edge_after_VP_toggling (box, 0, axis, persp); @@ -641,7 +646,7 @@ sp_3dbox_get_midpoint_between_corners (SP3DBox *box, guint id_corner1, guint id_ if (!adjacent_face_center) return NR::Nothing(); - Box3D::Perspective3D * persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D * persp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box); Box3D::PerspectiveLine pl (*adjacent_face_center, orth_dir, persp); return pl.intersect(Box3D::PerspectiveLine(box->corners[id_corner1], corner_axes, persp)); @@ -685,7 +690,7 @@ static gchar * sp_3dbox_get_perspective_string (SP3DBox *box) { - return sp_3dbox_get_svg_descr_of_persp (Box3D::get_persp_of_box (box)); + return sp_3dbox_get_svg_descr_of_persp (SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box)); } gchar * @@ -779,7 +784,7 @@ sp_3dbox_get_corner_id_along_edge (const SP3DBox *box, guint corner, Box3D::Axis { guint result; guint other_corner = corner ^ axis; - Box3D::VanishingPoint *vp = Box3D::get_persp_of_box (box)->get_vanishing_point(axis); + Box3D::VanishingPoint *vp = SP_OBJECT_DOCUMENT (G_OBJECT (box))->get_persp_of_box (box)->get_vanishing_point(axis); if (vp->is_finite()) { result = ( NR::L2 (vp->get_pos() - box->corners[corner]) < NR::L2 (vp->get_pos() - box->corners[other_corner]) ? other_corner : corner); diff --git a/src/document.cpp b/src/document.cpp index 252c9b173..2a482648f 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -53,6 +53,7 @@ #include "libavoid/router.h" #include "libnr/nr-rect.h" #include "sp-item-group.h" +#include "perspective3d.h" #include "display/nr-arena-item.h" @@ -96,6 +97,23 @@ SPDocument::SPDocument() { // Don't use the Consolidate moves optimisation. router->ConsolidateMoves = false; + perspectives = NULL; + + /* Create an initial perspective, make it current and append it to the list of existing perspectives */ + current_perspective = new Box3D::Perspective3D ( + // VP in x-direction + Box3D::VanishingPoint( NR::Point(-50.0, 600.0), + NR::Point( -1.0, 0.0), Box3D::VP_FINITE), + // VP in y-direction + Box3D::VanishingPoint( NR::Point(500.0,1000.0), + NR::Point( 0.0, 1.0), Box3D::VP_INFINITE), + // VP in z-direction + Box3D::VanishingPoint( NR::Point(700.0, 600.0), + NR::Point(sqrt(3.0),1.0), Box3D::VP_FINITE), + this); + + add_perspective (current_perspective); + p = new SPDocumentPrivate(); p->serial = next_serial++; @@ -184,6 +202,66 @@ SPDocument::~SPDocument() { } //delete this->_whiteboard_session_manager; + + current_perspective = NULL; + // TODO: Do we have to delete the perspectives? + /*** + for (GSList *i = perspectives; i != NULL; ++i) { + delete ((Box3D::Perspective3D *) i->data); + } + g_slist_free (perspectives); + ***/ +} + +void SPDocument::add_perspective (Box3D::Perspective3D * const persp) +{ + // FIXME: Should we handle the case that the perspectives have equal VPs but are not identical? + // If so, we need to take care of relinking the boxes, etc. + if (persp == NULL || g_slist_find (perspectives, persp)) return; + perspectives = g_slist_prepend (perspectives, persp); +} + +void SPDocument::remove_perspective (Box3D::Perspective3D * const persp) +{ + if (persp == NULL || !g_slist_find (perspectives, persp)) return; + perspectives = g_slist_remove (perspectives, persp); +} + +// find an existing perspective whose VPs are equal to those of persp +Box3D::Perspective3D * SPDocument::find_perspective (const Box3D::Perspective3D * persp) +{ + for (GSList *p = perspectives; p != NULL; p = p->next) { + if (*((Box3D::Perspective3D *) p->data) == *persp) { + return ((Box3D::Perspective3D *) p->data); + } + } + return NULL; // perspective was not found +} + +Box3D::Perspective3D * SPDocument::get_persp_of_box (const SP3DBox *box) +{ + for (GSList *p = perspectives; p != NULL; p = p->next) { + if (((Box3D::Perspective3D *) p->data)->has_box (box)) + return (Box3D::Perspective3D *) p->data; + } + g_warning ("Stray 3D box!\n"); + g_assert_not_reached(); +} + +Box3D::Perspective3D * SPDocument::get_persp_of_VP (const Box3D::VanishingPoint *vp) +{ + Box3D::Perspective3D *persp; + for (GSList *p = perspectives; p != NULL; p = p->next) { + persp = (Box3D::Perspective3D *) p->data; + // we compare the pointers, not the position/state of the VPs; is this correct? + if (persp->get_vanishing_point (Box3D::X) == vp || + persp->get_vanishing_point (Box3D::Y) == vp || + persp->get_vanishing_point (Box3D::Z) == vp) + return persp; + } + + g_warning ("Stray vanishing point!\n"); + g_assert_not_reached(); } unsigned long SPDocument::serial() const { diff --git a/src/document.h b/src/document.h index 16300d170..c04ed5441 100644 --- a/src/document.h +++ b/src/document.h @@ -51,6 +51,13 @@ namespace Inkscape { } } +class SP3DBox; + +namespace Box3D { + class Perspective3D; + class VanishingPoint; +} + class SPDocumentPrivate; /// Typed SVG document implementation. @@ -92,6 +99,19 @@ struct SPDocument : public Inkscape::GC::Managed<>, // Instance of the connector router Avoid::Router *router; + GSList *perspectives; + Box3D::Perspective3D *current_perspective; + + // FIXME: Perspectives should be linked to the list of existing ones automatically in the constructor + // and removed in the destructor! + void add_perspective (Box3D::Perspective3D * const persp); + void remove_perspective (Box3D::Perspective3D * const persp); + /* find an existing perspective whose VPs are equal to those of persp */ + Box3D::Perspective3D * find_perspective (const Box3D::Perspective3D * persp); + + Box3D::Perspective3D * get_persp_of_box (const SP3DBox *box); + Box3D::Perspective3D * get_persp_of_VP (const Box3D::VanishingPoint *vp); + sigc::connection connectModified(ModifiedSignal::slot_type slot); sigc::connection connectURISet(URISetSignal::slot_type slot); sigc::connection connectResized(ResizedSignal::slot_type slot); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index 8f76edddf..c167be493 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -59,7 +59,6 @@ using Inkscape::Extension::Internal::PrintWin32; #include "prefs-utils.h" #include "xml/repr.h" #include "io/sys.h" -#include "perspective3d.h" #include "extension/init.h" @@ -598,21 +597,6 @@ inkscape_application_init (const gchar *argv0, gboolean use_gui) /* Initialize the extensions */ Inkscape::Extension::init(); - /* Create an initial perspective, append it to the list of existing perspectives and make it current */ - Box3D::Perspective3D *initial_persp = new Box3D::Perspective3D ( - // VP in x-direction - Box3D::VanishingPoint( NR::Point(-50.0, 600.0), - NR::Point( -1.0, 0.0), Box3D::VP_FINITE), - // VP in y-direction - Box3D::VanishingPoint( NR::Point(500.0,1000.0), - NR::Point( 0.0, 1.0), Box3D::VP_INFINITE), - // VP in z-direction - Box3D::VanishingPoint( NR::Point(700.0, 600.0), - NR::Point(sqrt(3.0),1.0), Box3D::VP_FINITE)); - - Box3D::Perspective3D::current_perspective = initial_persp; - Box3D::Perspective3D::add_perspective (initial_persp); - return; } diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp index c7592a06f..0d4877f37 100644 --- a/src/perspective3d.cpp +++ b/src/perspective3d.cpp @@ -16,6 +16,7 @@ #include "perspective-line.h" #include #include "perspective3d.h" +#include "desktop-handles.h" // can probably be removed later #include "inkscape.h" @@ -23,36 +24,6 @@ namespace Box3D { gint Perspective3D::counter = 0; -GSList * Perspective3D::perspectives = NULL; -Perspective3D * Perspective3D::current_perspective = NULL; - -Perspective3D * -get_persp_of_box (const SP3DBox *box) -{ - for (GSList *p = Perspective3D::perspectives; p != NULL; p = p->next) { - if (((Perspective3D *) p->data)->has_box (box)) - return (Perspective3D *) p->data; - } - g_warning ("Stray 3D box!\n"); - g_assert_not_reached(); -} - -Perspective3D * -get_persp_of_VP (const VanishingPoint *vp) -{ - Perspective3D *persp; - for (GSList *p = Perspective3D::perspectives; p != NULL; p = p->next) { - persp = (Perspective3D *) p->data; - // we compare the pointers, not the position/state of the VPs; is this correct? - if (persp->get_vanishing_point (Box3D::X) == vp || - persp->get_vanishing_point (Box3D::Y) == vp || - persp->get_vanishing_point (Box3D::Z) == vp) - return persp; - } - - g_warning ("Stray vanishing point!\n"); - g_assert_not_reached(); -} /** * Computes the intersection of the two perspective lines from pt1 and pt2 to the respective @@ -80,14 +51,19 @@ perspective_line_snap (NR::Point line_pt, Box3D::Axis dir, NR::Point ext_pt, Per return PerspectiveLine(line_pt, dir, persp).closest_to(ext_pt); } -Perspective3D::Perspective3D (VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z) - : boxes (NULL) +Perspective3D::Perspective3D (VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z, SPDocument *doc) + : boxes (NULL), + document (doc) { vp_x = new VanishingPoint (pt_x); vp_y = new VanishingPoint (pt_y); vp_z = new VanishingPoint (pt_z); my_counter = Perspective3D::counter++; + + if (document == NULL) { + g_warning ("What to do now?\n"); + } } Perspective3D::Perspective3D (Perspective3D &other) @@ -98,11 +74,17 @@ Perspective3D::Perspective3D (Perspective3D &other) vp_z = new VanishingPoint (*other.vp_z); my_counter = Perspective3D::counter++; + + document = other.document; } Perspective3D::~Perspective3D () { - Perspective3D::remove_perspective (this); + if (document) { + document->remove_perspective (this); + } else { + g_warning ("No document found!\n"); + } // Remove the VPs from their draggers SPEventContext *ec = inkscape_active_event_context(); @@ -368,39 +350,11 @@ Perspective3D::svg_string () } ***/ -void -Perspective3D::add_perspective (Box3D::Perspective3D * const persp) -{ - // FIXME: Should we handle the case that the perspectives have equal VPs but are not identical? - // If so, we need to take care of relinking the boxes, etc. - if (persp == NULL || g_slist_find (Perspective3D::perspectives, persp)) return; - Perspective3D::perspectives = g_slist_prepend (Perspective3D::perspectives, persp); -} - -void -Perspective3D::remove_perspective (Box3D::Perspective3D * const persp) -{ - if (persp == NULL || !g_slist_find (Perspective3D::perspectives, persp)) return; - Perspective3D::perspectives = g_slist_remove (Perspective3D::perspectives, persp); -} - -// find an existing perspective whose VPs are equal to those of persp -Box3D::Perspective3D * -Perspective3D::find_perspective (Box3D::Perspective3D * const persp) -{ - for (GSList *p = Perspective3D::perspectives; p != NULL; p = p->next) { - if (*((Box3D::Perspective3D *) p->data) == *persp) { - return ((Box3D::Perspective3D *) p->data); - } - } - return NULL; // perspective was not found -} - void Perspective3D::print_debugging_info () { g_print ("====================================================\n"); - for (GSList *i = Perspective3D::perspectives; i != NULL; i = i->next) { + for (GSList *i = sp_desktop_document (inkscape_active_desktop())->perspectives; i != NULL; i = i->next) { Perspective3D *persp = (Perspective3D *) i->data; g_print ("Perspective %d:\n", persp->my_counter); diff --git a/src/perspective3d.h b/src/perspective3d.h index 4dd309b1f..a56003393 100644 --- a/src/perspective3d.h +++ b/src/perspective3d.h @@ -24,7 +24,7 @@ class PerspectiveLine; class Perspective3D { public: - Perspective3D(VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z); + Perspective3D(VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z, SPDocument *document); Perspective3D(Perspective3D &other); ~Perspective3D(); @@ -53,15 +53,6 @@ public: static gint counter; // for testing only gint my_counter; // for testing only - static GSList * perspectives; // All existing 3D perspectives - // FIXME: Perspectives should be linked to the list of existing ones automatically in the constructor - // and removed in the destructor! - static void add_perspective (Box3D::Perspective3D * const persp); - static void remove_perspective (Box3D::Perspective3D * const persp); - - /* find an existing perspective whose VPs are equal to those of persp */ - static Box3D::Perspective3D * find_perspective (Box3D::Perspective3D * const persp); - static void print_debugging_info(); static Perspective3D * current_perspective; @@ -70,11 +61,9 @@ private: VanishingPoint *vp_y; VanishingPoint *vp_z; GSList * boxes; // holds a list of boxes sharing this specific perspective + SPDocument * document; }; -Perspective3D * get_persp_of_box (const SP3DBox *box); -Perspective3D * get_persp_of_VP (const VanishingPoint *vp); - NR::Point perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point pt2, Box3D::Axis dir2, Perspective3D *persp); NR::Point perspective_line_snap (NR::Point pt, Box3D::Axis dir, NR::Point ext_pt, Perspective3D *persp); diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp index 5cd8332a3..ac7300b15 100644 --- a/src/vanishing-point.cpp +++ b/src/vanishing-point.cpp @@ -178,7 +178,7 @@ have_VPs_of_same_perspective (VPDragger *dr1, VPDragger *dr2) { Perspective3D *persp; for (GSList *i = dr1->vps; i != NULL; i = i->next) { - persp = get_persp_of_VP ((VanishingPoint *) i->data); + persp = dr1->parent->document->get_persp_of_VP ((VanishingPoint *) i->data); if (dr2->hasPerspective (persp)) { return true; } @@ -195,7 +195,7 @@ vp_knot_moved_handler (SPKnot *knot, NR::Point const *ppointer, guint state, gpo NR::Point p = *ppointer; // FIXME: take from prefs - double snap_dist = SNAP_DIST / drag->desktop->current_zoom(); + double snap_dist = SNAP_DIST / inkscape_active_desktop()->current_zoom(); if (!(state & GDK_SHIFT_MASK)) { // without Shift; see if we need to snap to another dragger @@ -302,7 +302,7 @@ vp_knot_grabbed_handler (SPKnot *knot, unsigned int state, gpointer data) for (GSList *i = boxes_to_do; i != NULL; i = i->next) { SP3DBox *box = SP_3DBOX (i->data); - Perspective3D *persp = get_persp_of_box (box); + Perspective3D *persp = drag->document->get_persp_of_box (box); VanishingPoint *vp = dr_new->getVPofPerspective (persp); if (vp == NULL) { g_warning ("VP is NULL. We should be okay, though.\n"); @@ -318,7 +318,7 @@ vp_knot_grabbed_handler (SPKnot *knot, unsigned int state, gpointer data) /* otherwise the unselected boxes need to stay linked to dr_new; thus we create a new perspective and link the VPs to the correct draggers */ Perspective3D *persp_new = new Perspective3D (*persp); - Perspective3D::add_perspective (persp_new); + drag->document->add_perspective (persp_new); Axis vp_axis = persp->get_axis_of_VP (vp); dragger->addVP (persp_new->get_vanishing_point (vp_axis)); @@ -382,7 +382,7 @@ VPDragger::VPDragger(VPDrag *parent, NR::Point p, VanishingPoint *vp) this->point_original = p; // create the knot - this->knot = sp_knot_new (parent->desktop, NULL); + this->knot = sp_knot_new (inkscape_active_desktop(), NULL); this->knot->setMode(SP_KNOT_MODE_XOR); this->knot->setFill(VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL, VP_KNOT_COLOR_NORMAL); this->knot->setStroke(0x000000ff, 0x000000ff, 0x000000ff); @@ -523,7 +523,7 @@ bool VPDragger::hasBox(const SP3DBox *box) { for (GSList *i = this->vps; i != NULL; i = i->next) { - if (get_persp_of_VP ((VanishingPoint *) i->data)->has_box (box)) return true; + if (parent->document->get_persp_of_VP ((VanishingPoint *) i->data)->has_box (box)) return true; } return false; } @@ -533,7 +533,7 @@ VPDragger::numberOfBoxes () { guint num = 0; for (GSList *i = this->vps; i != NULL; i = i->next) { - num += get_persp_of_VP ((VanishingPoint *) i->data)->number_of_boxes (); + num += parent->document->get_persp_of_VP ((VanishingPoint *) i->data)->number_of_boxes (); } return num; } @@ -542,7 +542,7 @@ bool VPDragger::hasPerspective (const Perspective3D *persp) { for (GSList *i = this->vps; i != NULL; i = i->next) { - if (*persp == *get_persp_of_VP ((VanishingPoint *) i->data)) { + if (*persp == *parent->document->get_persp_of_VP ((VanishingPoint *) i->data)) { return true; } } @@ -555,11 +555,11 @@ VPDragger::mergePerspectives () Perspective3D *persp1, *persp2; GSList * successor = NULL; for (GSList *i = this->vps; i != NULL; i = i->next) { - persp1 = get_persp_of_VP ((VanishingPoint *) i->data); + persp1 = parent->document->get_persp_of_VP ((VanishingPoint *) i->data); for (GSList *j = i->next; j != NULL; j = successor) { // if the perspective is deleted, the VP is invalidated, too, so we must store its successor beforehand successor = j->next; - persp2 = get_persp_of_VP ((VanishingPoint *) j->data); + persp2 = parent->document->get_persp_of_VP ((VanishingPoint *) j->data); if (*persp1 == *persp2) { persp1->absorb (persp2); // persp2 is deleted; hopefully this doesn't screw up the list of vanishing points and thus the loops } @@ -576,9 +576,9 @@ VPDragger::reshapeBoxes (NR::Point const &p, Box3D::Axis axes) // TODO: We can extract the VP directly from the box's perspective. Is that vanishing point identical to 'vp'? // Or is there duplicated information? If so, remove it and simplify the whole construction! vp->set_pos(p); - persp = get_persp_of_VP (vp); + persp = parent->document->get_persp_of_VP (vp); Box3D::Axis axis = persp->get_axis_of_VP (vp); - get_persp_of_VP (vp)->reshape_boxes (axis); // FIXME: we should only update the direction of the VP + parent->document->get_persp_of_VP (vp)->reshape_boxes (axis); // FIXME: we should only update the direction of the VP } parent->updateBoxHandles(); } @@ -587,7 +587,7 @@ void VPDragger::updateBoxReprs () { for (GSList *i = this->vps; i != NULL; i = i->next) { - Box3D::get_persp_of_VP ((VanishingPoint *) i->data)->update_box_reprs (); + parent->document->get_persp_of_VP ((VanishingPoint *) i->data)->update_box_reprs (); } } @@ -595,14 +595,14 @@ void VPDragger::updateZOrders () { for (GSList *i = this->vps; i != NULL; i = i->next) { - Box3D::get_persp_of_VP ((VanishingPoint *) i->data)->update_z_orders (); + parent->document->get_persp_of_VP ((VanishingPoint *) i->data)->update_z_orders (); } } -VPDrag::VPDrag (SPDesktop *desktop) +VPDrag::VPDrag (SPDocument *document) { - this->desktop = desktop; - this->selection = sp_desktop_selection(desktop); + this->document = document; + this->selection = sp_desktop_selection(inkscape_active_desktop()); this->draggers = NULL; this->lines = NULL; @@ -695,13 +695,7 @@ VPDrag::updateDraggers () if (!SP_IS_3DBOX (item)) continue; SP3DBox *box = SP_3DBOX (item); - // FIXME: Get the VPs from the selection!!!! - //addDragger (Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::X)); - //addDragger (Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Y)); - //addDragger (Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Z)); - - //Box3D::Perspective3D *persp = box->perspective; - Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box); + Box3D::Perspective3D *persp = document->get_persp_of_box (box); addDragger (persp->get_vanishing_point(Box3D::X)); addDragger (persp->get_vanishing_point(Box3D::Y)); addDragger (persp->get_vanishing_point(Box3D::Z)); @@ -777,8 +771,7 @@ VPDrag::drawLinesForFace (const SP3DBox *box, Box3D::Axis axis) //, guint corner NR::Point corner1, corner2, corner3, corner4; sp_3dbox_corners_for_perspective_lines (box, axis, corner1, corner2, corner3, corner4); - //VanishingPoint *vp = box->perspective->get_vanishing_point (axis); - VanishingPoint *vp = Box3D::get_persp_of_box (box)->get_vanishing_point (axis); + VanishingPoint *vp = document->get_persp_of_box (box)->get_vanishing_point (axis); if (vp->is_finite()) { NR::Point pt = vp->get_pos(); if (this->front_or_rear_lines & 0x1) { @@ -805,7 +798,7 @@ bool VPDrag::allBoxesAreSelected (VPDragger *dragger) { GSList *selected_boxes = (GSList *) dragger->parent->selection->itemList(); for (GSList *i = dragger->vps; i != NULL; i = i->next) { - if (!get_persp_of_VP ((VanishingPoint *) i->data)->all_boxes_occur_in_list (selected_boxes)) { + if (!document->get_persp_of_VP ((VanishingPoint *) i->data)->all_boxes_occur_in_list (selected_boxes)) { return false; } } @@ -860,7 +853,7 @@ Create a line from p1 to p2 and add it to the lines list void VPDrag::addLine (NR::Point p1, NR::Point p2, guint32 rgba) { - SPCanvasItem *line = sp_canvas_item_new(sp_desktop_controls(this->desktop), SP_TYPE_CTRLLINE, NULL); + SPCanvasItem *line = sp_canvas_item_new(sp_desktop_controls(inkscape_active_desktop()), SP_TYPE_CTRLLINE, NULL); sp_ctrlline_set_coords(SP_CTRLLINE(line), p1, p2); if (rgba != VP_LINE_COLOR_FILL) // fill is the default, so don't set color for it to speed up redraw sp_ctrlline_set_rgba32 (SP_CTRLLINE(line), rgba); diff --git a/src/vanishing-point.h b/src/vanishing-point.h index 70b473024..7d53fa89d 100644 --- a/src/vanishing-point.h +++ b/src/vanishing-point.h @@ -110,7 +110,7 @@ public: struct VPDrag { public: - VPDrag(SPDesktop *desktop); + VPDrag(SPDocument *document); ~VPDrag(); VPDragger *getDraggerFor (VanishingPoint const &vp); @@ -119,7 +119,7 @@ public: bool local_change; - SPDesktop *desktop; + SPDocument *document; GList *draggers; GSList *lines; diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 95decde95..7f4f637b4 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -2129,10 +2129,11 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions static void sp_3dbox_toggle_vp_changed( GtkToggleAction *act, gpointer data ) { + SPDocument *document = sp_desktop_document (inkscape_active_desktop ()); Box3D::Axis axis = (Box3D::Axis) GPOINTER_TO_INT(data); - if (Box3D::Perspective3D::current_perspective) { - Box3D::Perspective3D::current_perspective->toggle_boxes (axis); + if (document->current_perspective) { + document->current_perspective->toggle_boxes (axis); } } @@ -2193,6 +2194,7 @@ static void sp_3dboxtb_handles_state_changed( EgeSelectOneAction *act, GObject * static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { + SPDocument *document = sp_desktop_document (desktop); bool toggled = false; /* toggle VP in X direction */ { @@ -2202,8 +2204,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction "toggle_vp_x", Inkscape::ICON_SIZE_DECORATION ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - if (Box3D::Perspective3D::current_perspective) { - toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::X)->is_finite(); + if (document->current_perspective) { + toggled = !document->current_perspective->get_vanishing_point(Box3D::X)->is_finite(); } gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled ); /* we connect the signal after setting the state to avoid switching the state again */ @@ -2218,8 +2220,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction "toggle_vp_y", Inkscape::ICON_SIZE_DECORATION ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - if (Box3D::Perspective3D::current_perspective) { - toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Y)->is_finite(); + if (document->current_perspective) { + toggled = !document->current_perspective->get_vanishing_point(Box3D::Y)->is_finite(); } gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled ); /* we connect the signal after setting the state to avoid switching the state again */ @@ -2234,8 +2236,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction "toggle_vp_z", Inkscape::ICON_SIZE_DECORATION ); gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - if (Box3D::Perspective3D::current_perspective) { - toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Z)->is_finite(); + if (document->current_perspective) { + toggled = !document->current_perspective->get_vanishing_point(Box3D::Z)->is_finite(); } /* we connect the signal after setting the state to avoid switching the state again */ gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled ); -- 2.30.2