summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMaximilian Albert <maximilian.albert@gmail.com>2007-08-06 00:07:25 +0000
committercilix42 <cilix42@users.sourceforge.net>2007-08-06 00:07:25 +0000
commitea6e0e4d2cd55a2b851a8504a68afff34fc6a683 (patch)
treea5529ebcf86551413491b721ab9328d08c6ad1df /src
parentFilter effects dialog: (diff)
downloadinkscape-ea6e0e4d2cd55a2b851a8504a68afff34fc6a683.tar.gz
inkscape-ea6e0e4d2cd55a2b851a8504a68afff34fc6a683.zip
Store a global list of existing perspectives; for each perspective hold a list of associated boxes; explicitly pass perspectives as arguments when creating PLs
(bzr r3380)
Diffstat (limited to 'src')
-rw-r--r--src/box3d-context.cpp26
-rw-r--r--src/box3d-context.h2
-rw-r--r--src/box3d-face.cpp14
-rw-r--r--src/box3d.cpp64
-rw-r--r--src/desktop.cpp45
-rw-r--r--src/desktop.h8
-rw-r--r--src/perspective-line.h3
-rw-r--r--src/perspective3d.cpp75
-rw-r--r--src/perspective3d.h18
-rw-r--r--src/widgets/toolbox.cpp16
10 files changed, 190 insertions, 81 deletions
diff --git a/src/box3d-context.cpp b/src/box3d-context.cpp
index d5d367d81..25f6f78f1 100644
--- a/src/box3d-context.cpp
+++ b/src/box3d-context.cpp
@@ -90,7 +90,7 @@ static void sp_3dbox_context_class_init(SP3DBoxContextClass *klass)
event_context_class->item_handler = sp_3dbox_context_item_handler;
}
-Box3D::Perspective3D * SP3DBoxContext::current_perspective = NULL;
+Box3D::Perspective3D * Box3D::Perspective3D::current_perspective = NULL;
guint SP3DBoxContext::number_of_handles = 3;
static void sp_3dbox_context_init(SP3DBoxContext *box3d_context)
@@ -116,20 +116,6 @@ static void sp_3dbox_context_init(SP3DBoxContext *box3d_context)
box3d_context->ctrl_dragged = false;
box3d_context->extruded = false;
-
- /* create an initial perspective */
- if (!SP3DBoxContext::current_perspective) {
- SP3DBoxContext::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_INFINITE),
- // 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, 500.0),
- NR::Point(sqrt(3.0),1.0), Box3D::VP_INFINITE));
- }
new (&box3d_context->sel_changed_connection) sigc::connection();
}
@@ -371,18 +357,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 (!rc->ctrl_dragged) {
- rc->drag_ptC = Box3D::perspective_line_snap (rc->drag_ptB, Box3D::Z, motion_dt);
+ rc->drag_ptC = Box3D::perspective_line_snap (rc->drag_ptB, Box3D::Z, motion_dt, Box3D::Perspective3D::current_perspective);
} else {
rc->drag_ptC = motion_dt;
}
rc->drag_ptC = m.freeSnap(Inkscape::Snapper::SNAPPOINT_BBOX | Inkscape::Snapper::SNAPPOINT_NODE, rc->drag_ptC, rc->item).getPoint();
if (rc->ctrl_dragged) {
- Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Y);
- Box3D::PerspectiveLine pl2 (rc->drag_ptB, Box3D::X);
+ Box3D::PerspectiveLine pl1 (NR::Point (event_context->xp, event_context->yp), Box3D::Y, Box3D::Perspective3D::current_perspective);
+ Box3D::PerspectiveLine pl2 (rc->drag_ptB, Box3D::X, Box3D::Perspective3D::current_perspective);
NR::Point corner1 = pl1.meet(pl2);
- Box3D::PerspectiveLine pl3 (corner1, Box3D::X);
- Box3D::PerspectiveLine pl4 (rc->drag_ptC, Box3D::Z);
+ Box3D::PerspectiveLine pl3 (corner1, Box3D::X, Box3D::Perspective3D::current_perspective);
+ Box3D::PerspectiveLine pl4 (rc->drag_ptC, Box3D::Z, Box3D::Perspective3D::current_perspective);
rc->drag_ptB = pl3.meet(pl4);
}
}
diff --git a/src/box3d-context.h b/src/box3d-context.h
index c244699b4..763c152ae 100644
--- a/src/box3d-context.h
+++ b/src/box3d-context.h
@@ -54,8 +54,6 @@ struct SP3DBoxContext : public SPEventContext {
/* temporary member until the precise behaviour is sorted out */
static guint number_of_handles;
- static Box3D::Perspective3D *current_perspective;
-
sigc::connection sel_changed_connection;
Inkscape::MessageContext *_message_context;
diff --git a/src/box3d-face.cpp b/src/box3d-face.cpp
index 287e5e205..55dc9b60a 100644
--- a/src/box3d-face.cpp
+++ b/src/box3d-face.cpp
@@ -64,11 +64,11 @@ void Box3DFace::set_shape(NR::Point const ul, NR::Point const lr,
} else {
if (align_along_PL) {
Box3D::Axis dir3 = Box3D::third_axis_direction (dir1, dir2);
- Box3D::Line line1(*SP3DBoxContext::current_perspective->get_vanishing_point(dir1), lr);
- Box3D::Line line2(*pt_align, *SP3DBoxContext::current_perspective->get_vanishing_point(dir3));
+ Box3D::Line line1(*Box3D::Perspective3D::current_perspective->get_vanishing_point(dir1), lr);
+ Box3D::Line line2(*pt_align, *Box3D::Perspective3D::current_perspective->get_vanishing_point(dir3));
corners[2] = *line1.intersect(line2);
} else {
- corners[2] = Box3D::Line(*pt_align, *SP3DBoxContext::current_perspective->get_vanishing_point(dir1)).closest_to(lr);
+ corners[2] = Box3D::Line(*pt_align, *Box3D::Perspective3D::current_perspective->get_vanishing_point(dir1)).closest_to(lr);
}
}
@@ -130,12 +130,12 @@ Box3DFace::set_face (NR::Point const A, NR::Point const C, Box3D::Axis const axi
return;
SP3DBoxContext *bc = SP_3DBOX_CONTEXT(inkscape_active_event_context());
- Box3D::PerspectiveLine line1 (A, axis1);
- Box3D::PerspectiveLine line2 (C, axis2);
+ Box3D::PerspectiveLine line1 (A, axis1, Box3D::Perspective3D::current_perspective);
+ Box3D::PerspectiveLine line2 (C, axis2, Box3D::Perspective3D::current_perspective);
NR::Maybe<NR::Point> B = line1.intersect(line2);
- Box3D::PerspectiveLine line3 (*corners[0], axis2);
- Box3D::PerspectiveLine line4 (*corners[2], axis1);
+ Box3D::PerspectiveLine line3 (*corners[0], axis2, Box3D::Perspective3D::current_perspective);
+ Box3D::PerspectiveLine line4 (*corners[2], axis1, Box3D::Perspective3D::current_perspective);
NR::Maybe<NR::Point> D = line3.intersect(line4);
// FIXME: How to handle the case if one of the intersections doesn't exist?
diff --git a/src/box3d.cpp b/src/box3d.cpp
index dec5e9d17..76dad605b 100644
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
@@ -24,7 +24,7 @@ static void sp_3dbox_class_init(SP3DBoxClass *klass);
static void sp_3dbox_init(SP3DBox *box3d);
static void sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr);
-//static void sp_3dbox_release (SPObject *object);
+static void sp_3dbox_release (SPObject *object);
static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value);
static void sp_3dbox_update(SPObject *object, SPCtx *ctx, guint flags);
static Inkscape::XML::Node *sp_3dbox_write(SPObject *object, Inkscape::XML::Node *repr, guint flags);
@@ -76,7 +76,7 @@ sp_3dbox_class_init(SP3DBoxClass *klass)
sp_object_class->set = sp_3dbox_set;
sp_object_class->write = sp_3dbox_write;
sp_object_class->update = sp_3dbox_update;
- //sp_object_class->release = sp_3dbox_release;
+ sp_object_class->release = sp_3dbox_release;
item_class->description = sp_3dbox_description;
}
@@ -97,6 +97,8 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr
SP3DBox *box = SP_3DBOX (object);
+ Box3D::Perspective3D::current_perspective->add_box (box);
+
sp_object_read_attr(object, "inkscape:box3dcornerA");
sp_object_read_attr(object, "inkscape:box3dcornerB");
sp_object_read_attr(object, "inkscape:box3dcornerC");
@@ -127,22 +129,24 @@ sp_3dbox_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr
sp_3dbox_link_to_existing_paths (box, repr);
}
-/*
static void
sp_3dbox_release (SPObject *object)
{
- SP3DBox *box3d = SP_3DBOX(object);
+ SP3DBox *box = SP_3DBOX(object);
for (int i = 0; i < 6; ++i) {
- if (box3d->faces[i]) {
- delete box3d->faces[i]; // FIXME: Anything else to do? Do we need to clean up the face first?
+ if (box->faces[i]) {
+ delete box->faces[i]; // FIXME: Anything else to do? Do we need to clean up the face first?
}
}
+ // 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);
+
if (((SPObjectClass *) parent_class)->release) {
((SPObjectClass *) parent_class)->release (object);
}
}
-*/
static void sp_3dbox_set(SPObject *object, unsigned int key, const gchar *value)
{
@@ -334,35 +338,37 @@ 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);
+
NR::Point A (box->corners[id ^ Box3D::XY]);
if (Box3D::is_single_axis_direction (axes)) {
- pt = Box3D::PerspectiveLine (box->corners[id], axes).closest_to(pt);
+ pt = Box3D::PerspectiveLine (box->corners[id], axes, persp).closest_to(pt);
}
/* set the 'front' corners */
box->corners[id] = pt;
- Box3D::PerspectiveLine pl_one (A, Box3D::Y);
- Box3D::PerspectiveLine pl_two (pt, Box3D::X);
+ Box3D::PerspectiveLine pl_one (A, Box3D::Y, persp);
+ Box3D::PerspectiveLine pl_two (pt, Box3D::X, persp);
box->corners[id ^ Box3D::X] = pl_one.meet(pl_two);
- pl_one = Box3D::PerspectiveLine (A, Box3D::X);
- pl_two = Box3D::PerspectiveLine (pt, Box3D::Y);
+ pl_one = Box3D::PerspectiveLine (A, Box3D::X, persp);
+ pl_two = Box3D::PerspectiveLine (pt, Box3D::Y, persp);
box->corners[id ^ Box3D::Y] = pl_one.meet(pl_two);
/* set the 'rear' corners */
NR::Point B (box->corners[id ^ Box3D::XYZ]);
- pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::X], Box3D::Z);
- pl_two = Box3D::PerspectiveLine (B, Box3D::Y);
+ pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::X], Box3D::Z, persp);
+ pl_two = Box3D::PerspectiveLine (B, Box3D::Y, persp);
box->corners[id ^ Box3D::XZ] = pl_one.meet(pl_two);
- pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::XZ], Box3D::X);
- pl_two = Box3D::PerspectiveLine (pt, Box3D::Z);
+ pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::XZ], Box3D::X, persp);
+ pl_two = Box3D::PerspectiveLine (pt, Box3D::Z, persp);
box->corners[id ^ Box3D::Z] = pl_one.meet(pl_two);
- pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::Z], Box3D::Y);
- pl_two = Box3D::PerspectiveLine (B, Box3D::X);
+ pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::Z], Box3D::Y, persp);
+ pl_two = Box3D::PerspectiveLine (B, Box3D::X, persp);
box->corners[id ^ Box3D::YZ] = pl_one.meet(pl_two);
}
@@ -372,19 +378,21 @@ 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);
+
/* set the four corners of the face containing corners[id] */
- box->corners[id] = Box3D::PerspectiveLine (box->corners[id], Box3D::Z).closest_to(pt);
+ box->corners[id] = Box3D::PerspectiveLine (box->corners[id], Box3D::Z, persp).closest_to(pt);
- Box3D::PerspectiveLine pl_one (box->corners[id], Box3D::X);
- Box3D::PerspectiveLine pl_two (box->corners[id ^ Box3D::XZ], Box3D::Z);
+ Box3D::PerspectiveLine pl_one (box->corners[id], Box3D::X, persp);
+ Box3D::PerspectiveLine pl_two (box->corners[id ^ Box3D::XZ], Box3D::Z, persp);
box->corners[id ^ Box3D::X] = pl_one.meet(pl_two);
- pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::X], Box3D::Y);
- pl_two = Box3D::PerspectiveLine (box->corners[id ^ Box3D::XYZ], Box3D::Z);
+ pl_one = Box3D::PerspectiveLine (box->corners[id ^ Box3D::X], Box3D::Y, persp);
+ pl_two = Box3D::PerspectiveLine (box->corners[id ^ Box3D::XYZ], Box3D::Z, persp);
box->corners[id ^ Box3D::XY] = pl_one.meet(pl_two);
- pl_one = Box3D::PerspectiveLine (box->corners[id], Box3D::Y);
- pl_two = Box3D::PerspectiveLine (box->corners[id ^ Box3D::YZ], Box3D::Z);
+ pl_one = Box3D::PerspectiveLine (box->corners[id], Box3D::Y, persp);
+ pl_two = Box3D::PerspectiveLine (box->corners[id ^ Box3D::YZ], Box3D::Z, persp);
box->corners[id ^ Box3D::Y] = pl_one.meet(pl_two);
}
@@ -409,8 +417,10 @@ sp_3dbox_get_midpoint_between_corners (SP3DBox *box, guint id_corner1, guint id_
if (!adjacent_face_center) return NR::Nothing();
- Box3D::PerspectiveLine pl (*adjacent_face_center, orth_dir);
- return pl.intersect(Box3D::PerspectiveLine(box->corners[id_corner1], corner_axes));
+ Box3D::Perspective3D * persp = Box3D::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));
} else {
Box3D::Axis dir = Box3D::extract_first_axis_direction (corner_axes);
Box3D::Line diag1 (box->corners[id_corner1], box->corners[id_corner2]);
diff --git a/src/desktop.cpp b/src/desktop.cpp
index e785aab6d..6314621c1 100644
--- a/src/desktop.cpp
+++ b/src/desktop.cpp
@@ -132,6 +132,7 @@ SPDesktop::SPDesktop() :
window_state(0),
interaction_disabled_counter( 0 ),
waiting_cursor( false ),
+ perspectives (NULL),
guides_active( false ),
gr_item( 0 ),
gr_point_type( 0 ),
@@ -309,6 +310,21 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
layer_manager = new Inkscape::LayerManager( this );
grids_visible = true;
+
+ /* Create initial perspective, append it to the list of existing perspectives
+ and make it the current perspective */
+ 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));
+ this->add_perspective (initial_persp);
+ Box3D::Perspective3D::current_perspective = (Box3D::Perspective3D *) perspectives->data;
}
@@ -352,6 +368,11 @@ void SPDesktop::destroy()
g_list_free (zooms_past);
g_list_free (zooms_future);
+
+ for (GSList *p = this->perspectives; p != NULL; p = p->next) {
+ delete ((Box3D::Perspective3D *) p->data);
+ }
+ g_slist_free (perspectives);
}
SPDesktop::~SPDesktop() {}
@@ -694,6 +715,30 @@ void SPDesktop::set_display_area(NR::Rect const &a, NR::Coord b, bool log)
}
/**
+ * Add a perspective to the desktop if it doesn't exist yet
+ */
+void
+SPDesktop::add_perspective (Box3D::Perspective3D * const persp)
+{
+ // FIXME: Should we handle the case that the perspectives have equal VPs but are not identical?
+ if (persp == NULL || g_slist_find (this->perspectives, persp)) return;
+ this->perspectives = g_slist_prepend (this->perspectives, persp);
+ persp->desktop = this;
+}
+
+void SPDesktop::remove_perspective (Box3D::Perspective3D * const persp)
+{
+ if (persp == NULL) return;
+
+ if (!g_slist_find (this->perspectives, persp)) {
+ g_warning ("Could not find perspective in current desktop. Not removed.\n");
+ return;
+ }
+
+ this->perspectives = g_slist_remove (this->perspectives, persp);
+}
+
+/**
* Return viewbox dimensions.
*/
NR::Rect SPDesktop::get_display_area() const
diff --git a/src/desktop.h b/src/desktop.h
index ca2d24204..fa6602651 100644
--- a/src/desktop.h
+++ b/src/desktop.h
@@ -34,6 +34,7 @@
#include "libnr/nr-rect.h"
#include "ui/view/view.h"
#include "ui/view/edit-widget-interface.h"
+#include "perspective3d.h"
class NRRect;
class SPCSSAttr;
@@ -112,6 +113,9 @@ struct SPDesktop : public Inkscape::UI::View::View
unsigned int interaction_disabled_counter;
bool waiting_cursor;
+ // All 3D perspectives that are present in the current desktop
+ GSList *perspectives;
+
/// \todo fixme: This has to be implemented in different way */
guint guides_active : 1;
@@ -202,6 +206,10 @@ struct SPDesktop : public Inkscape::UI::View::View
SPItem *group_at_point (NR::Point const p) const;
NR::Point point() const;
+ // Methods to handle 3D perspective
+ void add_perspective (Box3D::Perspective3D * const persp);
+ void remove_perspective (Box3D::Perspective3D * const persp);
+
NR::Rect get_display_area() const;
void set_display_area (double x0, double y0, double x1, double y1, double border, bool log = true);
void set_display_area(NR::Rect const &a, NR::Coord border, bool log = true);
diff --git a/src/perspective-line.h b/src/perspective-line.h
index a02737692..8f218803b 100644
--- a/src/perspective-line.h
+++ b/src/perspective-line.h
@@ -27,8 +27,7 @@ public:
* PL runs through it; otherwise it has the direction specified by the v_dir vector
* of the VP.
*/
- PerspectiveLine (NR::Point const &pt, Box3D::Axis const axis,
- Perspective3D *perspective = SP3DBoxContext::current_perspective);
+ PerspectiveLine (NR::Point const &pt, Box3D::Axis const axis, Perspective3D *perspective);
NR::Maybe<NR::Point> intersect (Line const &line); // FIXME: Can we make this return only a NR::Point to remove the extra method meet()?
NR::Point meet (Line const &line);
diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp
index 35558e832..2c9a5e61e 100644
--- a/src/perspective3d.cpp
+++ b/src/perspective3d.cpp
@@ -14,18 +14,35 @@
#include "box3d-context.h"
#include "perspective-line.h"
#include <iostream>
+#include "desktop.h"
+
+// can probably be removed later
+#include "inkscape.h"
namespace Box3D {
+Perspective3D *
+get_persp_of_box (const SP3DBox *box)
+{
+ SPDesktop *desktop = inkscape_active_desktop(); // Should we pass the desktop as an argument?
+ for (GSList *p = desktop->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();
+}
+
/**
* Computes the intersection of the two perspective lines from pt1 and pt2 to the respective
* vanishing points in the given directions.
*/
// FIXME: This has been moved to a virtual method inside PerspectiveLine; can probably be purged
-NR::Point perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point pt2, Box3D::Axis dir2)
+NR::Point
+perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point pt2, Box3D::Axis dir2, Perspective3D *persp)
{
- VanishingPoint const *vp1 = SP3DBoxContext::current_perspective->get_vanishing_point(dir1);
- VanishingPoint const *vp2 = SP3DBoxContext::current_perspective->get_vanishing_point(dir2);
+ VanishingPoint const *vp1 = persp->get_vanishing_point(dir1);
+ VanishingPoint const *vp2 = persp->get_vanishing_point(dir2);
NR::Maybe<NR::Point> meet = Line(pt1, *vp1).intersect(Line(pt2, *vp2));
// FIXME: How to handle parallel lines (also depends on the type of the VPs)?
if (!meet) { meet = NR::Point (0.0, 0.0); }
@@ -36,22 +53,30 @@ NR::Point perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point p
* Find the point on the perspective line from line_pt to the
* vanishing point in direction dir that is closest to ext_pt.
*/
-NR::Point perspective_line_snap (NR::Point line_pt, Box3D::Axis dir, NR::Point ext_pt)
+NR::Point
+perspective_line_snap (NR::Point line_pt, Box3D::Axis dir, NR::Point ext_pt, Perspective3D *persp)
{
- return PerspectiveLine(line_pt, dir).closest_to(ext_pt);
+ return PerspectiveLine(line_pt, dir, persp).closest_to(ext_pt);
}
Perspective3D::Perspective3D (VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z)
- : vp_x (pt_x),
- vp_y (pt_y),
- vp_z (pt_z)
+ : desktop (NULL),
+ vp_x (pt_x),
+ vp_y (pt_y),
+ vp_z (pt_z),
+ boxes (NULL)
{
- // Draw the three vanishing points
- vp_x.draw(X);
- vp_y.draw(Y);
- vp_z.draw(Z);
}
+Perspective3D::~Perspective3D ()
+{
+ g_assert (desktop != NULL);
+ desktop->remove_perspective (this);
+
+ g_slist_free (boxes);
+}
+
+
VanishingPoint *Perspective3D::get_vanishing_point (Box3D::Axis const dir)
{
// FIXME: Also handle value 'NONE' in switch
@@ -86,6 +111,32 @@ void Perspective3D::set_vanishing_point (Box3D::Axis const dir, VanishingPoint c
}
}
+void
+Perspective3D::add_box (SP3DBox *box)
+{
+ if (g_slist_find (this->boxes, box) != NULL) {
+ // Don't add the same box twice
+ g_warning ("Box already uses the current perspective. We don't add it again.\n");
+ return;
+ }
+ this->boxes = g_slist_append (this->boxes, box);
+}
+
+void
+Perspective3D::remove_box (const SP3DBox *box)
+{
+ if (!g_slist_find (this->boxes, box)) {
+ g_warning ("Could not find box that is to be removed in the current perspective.\n");
+ }
+ this->boxes = g_slist_remove (this->boxes, box);
+}
+
+bool
+Perspective3D::has_box (const SP3DBox *box)
+{
+ return (g_slist_find (this->boxes, box) != NULL);
+}
+
} // namespace Box3D
/*
diff --git a/src/perspective3d.h b/src/perspective3d.h
index 007b02df1..fa9eda65f 100644
--- a/src/perspective3d.h
+++ b/src/perspective3d.h
@@ -14,26 +14,38 @@
#include "vanishing-point.h"
-namespace Box3D {
+class SP3DBox;
-NR::Point perspective_intersection (NR::Point pt1, Box3D::Axis dir1, NR::Point pt2, Box3D::Axis dir2);
-NR::Point perspective_line_snap (NR::Point pt, Box3D::Axis dir, NR::Point ext_pt);
+namespace Box3D {
class PerspectiveLine;
class Perspective3D {
public:
Perspective3D(VanishingPoint const &pt_x, VanishingPoint const &pt_y, VanishingPoint const &pt_z);
+ ~Perspective3D();
VanishingPoint *get_vanishing_point (Box3D::Axis const dir);
void set_vanishing_point (Box3D::Axis const dir, VanishingPoint const &pt);
+ void add_box (SP3DBox *box);
+ void remove_box (const SP3DBox *box);
+ bool has_box (const SP3DBox *box);
+
+ static Perspective3D * current_perspective; // should current_perspective be moved to desktop.h?
+
+ SPDesktop * desktop; // we need to store the perspective's desktop to be able to access it in the destructor
private:
VanishingPoint vp_x;
VanishingPoint vp_y;
VanishingPoint vp_z;
+ GSList * boxes; // holds a list of boxes sharing this specific perspective
};
+Perspective3D * get_persp_of_box (const SP3DBox *box);
+
+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);
} // namespace Box3D
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index aeab3b45b..8acb08a12 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -2133,8 +2133,8 @@ static void sp_3dbox_toggle_vp_changed( GtkToggleAction *act, gpointer data )
break;
}
- if (SP3DBoxContext::current_perspective) {
- Box3D::VanishingPoint *vp = SP3DBoxContext::current_perspective->get_vanishing_point(axis);
+ if (Box3D::Perspective3D::current_perspective) {
+ Box3D::VanishingPoint *vp = Box3D::Perspective3D::current_perspective->get_vanishing_point(axis);
vp->toggle_parallel();
vp->draw(axis);
prefs_set_int_attribute( "tools.shapes.3dbox", pstring->str, vp->is_finite() ? 0 : 1);
@@ -2208,8 +2208,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
Inkscape::ICON_SIZE_DECORATION );
gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::X));
- if (SP3DBoxContext::current_perspective) {
- toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::X)->is_finite();
+ if (Box3D::Perspective3D::current_perspective) {
+ toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::X)->is_finite();
}
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
}
@@ -2223,8 +2223,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
Inkscape::ICON_SIZE_DECORATION );
gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Y));
- if (SP3DBoxContext::current_perspective) {
- toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::Y)->is_finite();
+ if (Box3D::Perspective3D::current_perspective) {
+ toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Y)->is_finite();
}
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
}
@@ -2238,8 +2238,8 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
Inkscape::ICON_SIZE_DECORATION );
gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Z));
- if (SP3DBoxContext::current_perspective) {
- toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::Z)->is_finite();
+ if (Box3D::Perspective3D::current_perspective) {
+ toggled = !Box3D::Perspective3D::current_perspective->get_vanishing_point(Box3D::Z)->is_finite();
}
gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
}