summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMaximilian Albert <maximilian.albert@gmail.com>2007-08-07 14:20:02 +0000
committercilix42 <cilix42@users.sourceforge.net>2007-08-07 14:20:02 +0000
commit9bf886f095ec2bd6af5bebc658430fe4de3cbf63 (patch)
tree1febcd9ced3a1c1a50dd630a22cce268a8cba215
parentCompute the correct visible front corner (also for 'upended' boxes) and set t... (diff)
downloadinkscape-9bf886f095ec2bd6af5bebc658430fe4de3cbf63.tar.gz
inkscape-9bf886f095ec2bd6af5bebc658430fe4de3cbf63.zip
Fix behaviour of toggle buttons (for VP states) in 3D box toolbar; reshape boxes when state of a VP changes
(bzr r3412)
-rw-r--r--src/box3d.cpp39
-rw-r--r--src/box3d.h1
-rw-r--r--src/perspective3d.cpp10
-rw-r--r--src/perspective3d.h1
-rw-r--r--src/vanishing-point.cpp2
-rw-r--r--src/widgets/toolbox.cpp29
6 files changed, 59 insertions, 23 deletions
diff --git a/src/box3d.cpp b/src/box3d.cpp
index 0f71a99a8..966d762a1 100644
--- a/src/box3d.cpp
+++ b/src/box3d.cpp
@@ -581,12 +581,51 @@ sp_3dbox_move_corner_in_Z_direction (SP3DBox *box, guint id, NR::Point pt, bool
box->corners[id ^ Box3D::Y] = pl_one.meet(pl_two);
}
+static void
+sp_3dbox_reshape_edge_after_VP_toggling (SP3DBox *box, const guint corner, const Box3D::Axis axis, Box3D::Perspective3D *persp)
+{
+ /* Hmm, perhaps we should simply use one of the corners as the pivot point.
+ But this way we minimize the amount of reshaping.
+ On second thought, we need to find a way to ensure that all boxes sharing the same
+ perspective are updated consistently _as a group_. That is, they should also retain
+ their relative positions towards each other. */
+ NR::Maybe<NR::Point> pt = sp_3dbox_get_midpoint_between_corners (box, corner, corner ^ axis);
+ g_return_if_fail (pt);
+
+ Box3D::Axis axis2 = ((axis == Box3D::Y) ? Box3D::X : Box3D::Y);
+
+ Box3D::PerspectiveLine line1 (box->corners[corner], axis2, persp);
+ Box3D::PerspectiveLine line2 (box->corners[corner ^ axis], axis2, persp);
+
+ Box3D::PerspectiveLine line3 (*pt, axis, persp);
+
+ NR::Point new_corner1 = line1.meet (line3);
+ NR::Point new_corner2 = line2.meet (line3);
+
+ box->corners[corner] = new_corner1;
+ box->corners[corner ^ axis] = new_corner2;
+}
+
+void
+sp_3dbox_reshape_after_VP_toggling (SP3DBox *box, Box3D::Axis axis)
+{
+ Box3D::Perspective3D *persp = Box3D::get_persp_of_box (box);
+ std::pair<Box3D::Axis, Box3D::Axis> dirs = Box3D::get_remaining_axes (axis);
+
+ sp_3dbox_reshape_edge_after_VP_toggling (box, 0, axis, persp);
+ sp_3dbox_reshape_edge_after_VP_toggling (box, 0 ^ dirs.first, axis, persp);
+ sp_3dbox_reshape_edge_after_VP_toggling (box, 0 ^ dirs.first ^ dirs.second, axis, persp);
+ sp_3dbox_reshape_edge_after_VP_toggling (box, 0 ^ dirs.second, axis, persp);
+}
+
NR::Maybe<NR::Point>
sp_3dbox_get_center (SP3DBox *box)
{
return sp_3dbox_get_midpoint_between_corners (box, 0, 7);
}
+// TODO: The following function can probably be rewritten in a much more elegant and robust way
+// by using projective coordinates for all points and using the cross ratio.
NR::Maybe<NR::Point>
sp_3dbox_get_midpoint_between_corners (SP3DBox *box, guint id_corner1, guint id_corner2)
{
diff --git a/src/box3d.h b/src/box3d.h
index aecc40462..ed563a42e 100644
--- a/src/box3d.h
+++ b/src/box3d.h
@@ -67,6 +67,7 @@ void sp_3dbox_set_ratios (SP3DBox *box, Box3D::Axis axes = Box3D::XYZ);
void sp_3dbox_switch_front_face (SP3DBox *box, Box3D::Axis axis);
void sp_3dbox_move_corner_in_XY_plane (SP3DBox *box, guint id, NR::Point pt, Box3D::Axis axes = Box3D::XY);
void sp_3dbox_move_corner_in_Z_direction (SP3DBox *box, guint id, NR::Point pt, bool constrained = true);
+void sp_3dbox_reshape_after_VP_toggling (SP3DBox *box, Box3D::Axis axis);
NR::Maybe<NR::Point> sp_3dbox_get_center (SP3DBox *box);
NR::Maybe<NR::Point> sp_3dbox_get_midpoint_between_corners (SP3DBox *box, guint id_corner1, guint id_corner2);
diff --git a/src/perspective3d.cpp b/src/perspective3d.cpp
index 421725bdb..c7592a06f 100644
--- a/src/perspective3d.cpp
+++ b/src/perspective3d.cpp
@@ -321,6 +321,16 @@ Perspective3D::reshape_boxes (Box3D::Axis axes)
}
void
+Perspective3D::toggle_boxes (Box3D::Axis axis)
+{
+ get_vanishing_point (axis)->toggle_parallel();
+ for (GSList *i = this->boxes; i != NULL; i = i->next) {
+ sp_3dbox_reshape_after_VP_toggling (SP_3DBOX (i->data), axis);
+ }
+ update_box_reprs();
+}
+
+void
Perspective3D::update_box_reprs ()
{
for (GSList *i = this->boxes; i != NULL; i = i->next) {
diff --git a/src/perspective3d.h b/src/perspective3d.h
index 6c7e77446..4dd309b1f 100644
--- a/src/perspective3d.h
+++ b/src/perspective3d.h
@@ -40,6 +40,7 @@ public:
bool has_box (const SP3DBox *box) const;
inline guint number_of_boxes () { return g_slist_length (boxes); }
void reshape_boxes (Box3D::Axis axes);
+ void toggle_boxes (Box3D::Axis axes); // update the shape of boxes after a VP's state was toggled
void update_box_reprs ();
void update_z_orders ();
diff --git a/src/vanishing-point.cpp b/src/vanishing-point.cpp
index 0b4140a8b..9b2c45b56 100644
--- a/src/vanishing-point.cpp
+++ b/src/vanishing-point.cpp
@@ -749,7 +749,7 @@ VPDrag::drawLinesForFace (const SP3DBox *box, Box3D::Axis axis) //, guint corner
}
} else {
// TODO: Draw infinite PLs
- g_warning ("Perspective lines for infinite vanishing points are not supported yet.\n");
+ //g_warning ("Perspective lines for infinite vanishing points are not supported yet.\n");
}
}
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 25c5d2417..b0c8a9b7b 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -2117,26 +2117,8 @@ static void sp_3dbox_toggle_vp_changed( GtkToggleAction *act, gpointer data )
{
Box3D::Axis axis = (Box3D::Axis) GPOINTER_TO_INT(data);
- GString *pstring;
- switch (axis) {
- case Box3D::X:
- pstring = g_string_new("togglevpx");
- break;
- case Box3D::Y:
- pstring = g_string_new("togglevpy");
- break;
- case Box3D::Z:
- pstring = g_string_new("togglevpz");
- break;
- default:
- g_warning ("Only single axis directions may be used to toggle VPs!\n");
- break;
- }
-
if (Box3D::Perspective3D::current_perspective) {
- Box3D::VanishingPoint *vp = Box3D::Perspective3D::current_perspective->get_vanishing_point(axis);
- vp->toggle_parallel();
- prefs_set_int_attribute( "tools.shapes.3dbox", pstring->str, vp->is_finite() ? 0 : 1);
+ Box3D::Perspective3D::current_perspective->toggle_boxes (axis);
}
}
@@ -2206,11 +2188,12 @@ 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 ) );
- g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::X));
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 );
+ /* we connect the signal after setting the state to avoid switching the state again */
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::X));
}
/* toggle VP in Y direction */
@@ -2221,11 +2204,12 @@ 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 ) );
- g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Y));
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 );
+ /* we connect the signal after setting the state to avoid switching the state again */
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Y));
}
/* toggle VP in Z direction */
@@ -2236,11 +2220,12 @@ 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 ) );
- g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Z));
if (Box3D::Perspective3D::current_perspective) {
toggled = !Box3D::Perspective3D::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 );
+ g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Z));
}